GPU: Unified DataFormat enum

This unifies vertex and texture data formats
into a single base enum class.

`TextureFormat` and `VertexFormat` then mask
the invalid format for their respective usage.

Having a base enum allows casting between
`TextureFormat` and `VertexFormat` possible
(needed for Buffer Textures).

It also makes it easier to write and read data
to buffers/textures as each format will have an
associated host type.

These enum is generated from MACRO expansion.
This allow to centralize all information about
the formats in one place. This avoid duplicating
the list of enums for each backend.

This only creates the new enum. Porting older enums will
be done in other PRs.

Normalized integer CPU format are missing and waiting for #130640

Rel #130632

Pull Request: https://projects.blender.org/blender/blender/pulls/138069
This commit is contained in:
Clément Foucault
2025-05-13 17:08:32 +02:00
committed by Clément Foucault
parent 83a40ceae2
commit 617858e453
13 changed files with 947 additions and 165 deletions

View File

@@ -645,7 +645,7 @@ static void fill_curve_offsets_vbos(const OffsetIndices<int> points_by_curve,
const IndexRange points = points_by_curve[i];
*(uint *)GPU_vertbuf_raw_step(&data_step) = points.start();
*(ushort *)GPU_vertbuf_raw_step(&seg_step) = points.size() - 1;
*(uint *)GPU_vertbuf_raw_step(&seg_step) = points.size() - 1;
}
}
@@ -658,7 +658,7 @@ static void create_curve_offsets_vbos(const OffsetIndices<int> points_by_curve,
uint data_id = GPU_vertformat_attr_add(&format_data, "data", GPU_COMP_U32, 1, GPU_FETCH_INT);
GPUVertFormat format_seg = {0};
uint seg_id = GPU_vertformat_attr_add(&format_seg, "data", GPU_COMP_U16, 1, GPU_FETCH_INT);
uint seg_id = GPU_vertformat_attr_add(&format_seg, "data", GPU_COMP_U32, 1, GPU_FETCH_INT);
/* Curve Data. */
cache.proc_strand_buf = GPU_vertbuf_create_with_format_ex(
@@ -717,7 +717,7 @@ static void calc_final_indices(const bke::CurvesGeometry &curves,
}
static const GPUVertFormat format = GPU_vertformat_from_attribute(
"dummy", GPU_COMP_U32, 1, GPU_FETCH_INT_TO_FLOAT_UNIT);
"dummy", GPU_COMP_U32, 1, GPU_FETCH_INT);
gpu::VertBuf *vbo = GPU_vertbuf_create_with_format(format);
GPU_vertbuf_data_alloc(*vbo, 1);

View File

@@ -770,7 +770,7 @@ static int particle_batch_cache_fill_strands_data(ParticleSystem *psys,
}
*(uint *)GPU_vertbuf_raw_step(data_step) = curr_point;
*(ushort *)GPU_vertbuf_raw_step(seg_step) = path->segments;
*(uint *)GPU_vertbuf_raw_step(seg_step) = path->segments;
curr_point += path->segments + 1;
if (psmd != nullptr) {
@@ -884,7 +884,7 @@ static void particle_batch_cache_ensure_procedural_strand_data(PTCacheEdit *edit
uint data_id = GPU_vertformat_attr_add(&format_data, "data", GPU_COMP_U32, 1, GPU_FETCH_INT);
GPUVertFormat format_seg = {0};
uint seg_id = GPU_vertformat_attr_add(&format_seg, "data", GPU_COMP_U16, 1, GPU_FETCH_INT);
uint seg_id = GPU_vertformat_attr_add(&format_seg, "data", GPU_COMP_U32, 1, GPU_FETCH_INT);
GPUVertFormat format_uv = {0};
uint uv_id = GPU_vertformat_attr_add(&format_uv, "uv", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
@@ -1086,7 +1086,7 @@ static void particle_batch_cache_ensure_procedural_indices(PTCacheEdit *edit,
GPUPrimType prim_type = (thickness_res == 1) ? GPU_PRIM_LINE_STRIP : GPU_PRIM_TRI_STRIP;
static const GPUVertFormat format = GPU_vertformat_from_attribute(
"dummy", GPU_COMP_U32, 1, GPU_FETCH_INT_TO_FLOAT_UNIT);
"dummy", GPU_COMP_U32, 1, GPU_FETCH_INT);
gpu::VertBuf *vbo = GPU_vertbuf_create_with_format(format);
GPU_vertbuf_data_alloc(*vbo, 1);

View File

@@ -242,7 +242,7 @@ void ui_draw_but_TAB_outline(const rcti *rect,
GPUVertFormat *format = immVertexFormat();
const uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
const uint col = GPU_vertformat_attr_add(
format, "color", GPU_COMP_U8, 3, GPU_FETCH_INT_TO_FLOAT_UNIT);
format, "color", GPU_COMP_U8, 4, GPU_FETCH_INT_TO_FLOAT_UNIT);
/* add a 1px offset, looks nicer */
const int minx = rect->xmin + U.pixelsize, maxx = rect->xmax - U.pixelsize;
const int miny = rect->ymin + U.pixelsize, maxy = rect->ymax - U.pixelsize;
@@ -262,7 +262,7 @@ void ui_draw_but_TAB_outline(const rcti *rect,
immBindBuiltinProgram(GPU_SHADER_3D_SMOOTH_COLOR);
immBeginAtMost(GPU_PRIM_LINE_STRIP, 25);
immAttr3ubv(col, highlight);
immAttr4ub(col, UNPACK3(highlight), 255);
/* start with corner left-top */
if (roundboxtype & UI_CNR_TOP_LEFT) {
@@ -288,7 +288,7 @@ void ui_draw_but_TAB_outline(const rcti *rect,
immVertex2f(pos, maxx, maxy);
}
immAttr3ubv(col, highlight_fade);
immAttr4ub(col, UNPACK3(highlight_fade), 255);
/* corner right-bottom */
if (roundboxtype & UI_CNR_BOTTOM_RIGHT) {
@@ -314,7 +314,7 @@ void ui_draw_but_TAB_outline(const rcti *rect,
immVertex2f(pos, minx, miny);
}
immAttr3ubv(col, highlight);
immAttr4ub(col, UNPACK3(highlight), 255);
/* back to corner left-top */
immVertex2f(pos, minx, (roundboxtype & UI_CNR_TOP_LEFT) ? (maxy - rad) : maxy);

View File

@@ -1196,7 +1196,7 @@ void UI_view2d_multi_grid_draw(
GPUVertFormat *format = immVertexFormat();
const uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
uint color = GPU_vertformat_attr_add(
format, "color", GPU_COMP_U8, 3, GPU_FETCH_INT_TO_FLOAT_UNIT);
format, "color", GPU_COMP_U8, 4, GPU_FETCH_INT_TO_FLOAT_UNIT);
GPU_line_width(1.0f);
@@ -1221,7 +1221,7 @@ void UI_view2d_multi_grid_draw(
immAttrSkip(color);
immVertex2f(pos, start, v2d->cur.ymin);
immAttr3ubv(color, grid_line_color);
immAttr4ub(color, UNPACK3(grid_line_color), 255);
immVertex2f(pos, start, v2d->cur.ymax);
}
@@ -1238,7 +1238,7 @@ void UI_view2d_multi_grid_draw(
immAttrSkip(color);
immVertex2f(pos, v2d->cur.xmin, start);
immAttr3ubv(color, grid_line_color);
immAttr4ub(color, UNPACK3(grid_line_color), 255);
immVertex2f(pos, v2d->cur.xmax, start);
}
@@ -1252,12 +1252,12 @@ void UI_view2d_multi_grid_draw(
immAttrSkip(color);
immVertex2f(pos, 0.0f, v2d->cur.ymin);
immAttr3ubv(color, grid_line_color);
immAttr4ub(color, UNPACK3(grid_line_color), 255);
immVertex2f(pos, 0.0f, v2d->cur.ymax);
immAttrSkip(color);
immVertex2f(pos, v2d->cur.xmin, 0.0f);
immAttr3ubv(color, grid_line_color);
immAttr4ub(color, UNPACK3(grid_line_color), 255);
immVertex2f(pos, v2d->cur.xmax, 0.0f);
immEnd();

View File

@@ -0,0 +1,278 @@
/* SPDX-FileCopyrightText: 2025 Blender Authors
*
* SPDX-License-Identifier: GPL-2.0-or-later */
/** \file
* \ingroup gpu
*/
#pragma once
#include "BLI_assert.h"
#include "BLI_sys_types.h"
namespace blender::gpu {
/* -------------------------------------------------------------------- */
/** \name Standard Formats
* \{ */
/* NOTE: Metal does not support pixel formats with 3 channel. These are aliased to 4 channel types
* and converted on data upload. */
/* clang-format off */
/* type size comps blender_enum vk_enum mtl_pixel_enum mtl_vertex_enum gl_pixel_enum shader_enum */
#define SNORM_8_(impl) impl(/*TODO*/, 1 * 1, 1, SNORM_8, R8_SNORM, R8Snorm, Char1Normalized, R8_SNORM, r8_snorm)
#define SNORM_8_8_(impl) impl(/*TODO*/, 1 * 2, 2, SNORM_8_8, R8G8_SNORM, RG8Snorm, Char2Normalized, RG8_SNORM, rg8_snorm)
#define SNORM_8_8_8_(impl) impl(/*TODO*/, 1 * 3, 3, SNORM_8_8_8, R8G8B8_SNORM, RGBA8Snorm, Char3Normalized, RGB8_SNORM, rgb8_snorm)
#define SNORM_8_8_8_8_(impl) impl(/*TODO*/, 1 * 4, 4, SNORM_8_8_8_8, R8G8B8A8_SNORM, RGBA8Snorm, Char4Normalized, RGBA8_SNORM, rgba8_snorm)
/* type size comps blender_enum vk_enum mtl_pixel_enum mtl_vertex_enum gl_pixel_enum shader_enum */
#define SNORM_16_(impl) impl(/*TODO*/, 2 * 1, 1, SNORM_16, R16_SNORM, R16Snorm, Short1Normalized, R16_SNORM, r16_snorm)
#define SNORM_16_16_(impl) impl(/*TODO*/, 2 * 2, 2, SNORM_16_16, R16G16_SNORM, RG16Snorm, Short2Normalized, RG16_SNORM, rg16_snorm)
#define SNORM_16_16_16_(impl) impl(/*TODO*/, 2 * 3, 3, SNORM_16_16_16, R16G16B16_SNORM, RGBA16Snorm, Short3Normalized, RGB16_SNORM, rgb16_snorm)
#define SNORM_16_16_16_16_(impl) impl(/*TODO*/, 2 * 4, 4, SNORM_16_16_16_16, R16G16B16A16_SNORM, RGBA16Snorm, Short4Normalized, RGBA16_SNORM, rgba16_snorm)
/* type size comps blender_enum vk_enum mtl_pixel_enum mtl_vertex_enum gl_pixel_enum shader_enum */
#define UNORM_8_(impl) impl(/*TODO*/, 1 * 1, 1, UNORM_8, R8_UNORM, R8Unorm, UChar1Normalized, R8, r8_unorm)
#define UNORM_8_8_(impl) impl(/*TODO*/, 1 * 2, 2, UNORM_8_8, R8G8_UNORM, RG8Unorm, UChar2Normalized, RG8, rg8_unorm)
#define UNORM_8_8_8_(impl) impl(/*TODO*/, 1 * 3, 3, UNORM_8_8_8, R8G8B8_UNORM, RGBA8Unorm, UChar3Normalized, RGB8, rgb8_unorm)
#define UNORM_8_8_8_8_(impl) impl(/*TODO*/, 1 * 4, 4, UNORM_8_8_8_8, R8G8B8A8_UNORM, RGBA8Unorm, UChar4Normalized, RGBA8, rgba8_unorm)
/* type size comps blender_enum vk_enum mtl_pixel_enum mtl_vertex_enum gl_pixel_enum shader_enum */
#define UNORM_16_(impl) impl(/*TODO*/, 2 * 1, 1, UNORM_16, R16_UNORM, R16Unorm, UShort1Normalized, R16, r16_unorm)
#define UNORM_16_16_(impl) impl(/*TODO*/, 2 * 2, 2, UNORM_16_16, R16G16_UNORM, RG16Unorm, UShort2Normalized, RG16, rg16_unorm)
#define UNORM_16_16_16_(impl) impl(/*TODO*/, 2 * 3, 3, UNORM_16_16_16, R16G16B16_UNORM, RGBA16Unorm, UShort3Normalized, RGB16, rgb16_unorm)
#define UNORM_16_16_16_16_(impl) impl(/*TODO*/, 2 * 4, 4, UNORM_16_16_16_16, R16G16B16A16_UNORM, RGBA16Unorm, UShort4Normalized, RGBA16, rgba16_unorm)
/* type size comps blender_enum vk_enum mtl_pixel_enum mtl_vertex_enum gl_pixel_enum shader_enum */
#define SINT_8_(impl) impl(int8_t, 1 * 1, 1, SINT_8, R8_SINT, R8Sint, Char1, R8I, r8_sint)
#define SINT_8_8_(impl) impl(char2, 1 * 2, 2, SINT_8_8, R8G8_SINT, RG8Sint, Char2, RG8I, rg8_sint)
#define SINT_8_8_8_(impl) impl(char3, 1 * 3, 3, SINT_8_8_8, R8G8B8_SINT, RGBA8Sint, Char3, RGB8I, rgb8_sint)
#define SINT_8_8_8_8_(impl) impl(char4, 1 * 4, 4, SINT_8_8_8_8, R8G8B8A8_SINT, RGBA8Sint, Char4, RGBA8I, rgba8_sint)
/* type size comps blender_enum vk_enum mtl_pixel_enum mtl_vertex_enum gl_pixel_enum shader_enum */
#define SINT_16_(impl) impl(int16_t, 2 * 1, 1, SINT_16, R16_SINT, R16Sint, Short1, R16I, r16_sint)
#define SINT_16_16_(impl) impl(short2, 2 * 2, 2, SINT_16_16, R16G16_SINT, RG16Sint, Short2, RG16I, rg16_sint)
#define SINT_16_16_16_(impl) impl(short3, 2 * 3, 3, SINT_16_16_16, R16G16B16_SINT, RGBA16Sint, Short3, RGB16I, rgb16_sint)
#define SINT_16_16_16_16_(impl) impl(short4, 2 * 4, 4, SINT_16_16_16_16, R16G16B16A16_SINT, RGBA16Sint, Short4, RGBA16I, rgba16_sint)
/* type size comps blender_enum vk_enum mtl_pixel_enum mtl_vertex_enum gl_pixel_enum shader_enum */
#define SINT_32_(impl) impl(int32_t, 4 * 1, 1, SINT_32, R32_SINT, R32Sint, Int1, R32I, r32_sint)
#define SINT_32_32_(impl) impl(int2, 4 * 2, 2, SINT_32_32, R32G32_SINT, RG32Sint, Int2, RG32I, rg32_sint)
#define SINT_32_32_32_(impl) impl(int3, 4 * 3, 3, SINT_32_32_32, R32G32B32_SINT, RGBA32Sint, Int3, RGB32I, rgb32_sint)
#define SINT_32_32_32_32_(impl) impl(int4, 4 * 4, 4, SINT_32_32_32_32, R32G32B32A32_SINT, RGBA32Sint, Int4, RGBA32I, rgba32_sint)
/* type size comps blender_enum vk_enum mtl_pixel_enum mtl_vertex_enum gl_pixel_enum shader_enum */
#define UINT_8_(impl) impl(uint8_t, 1 * 1, 1, UINT_8, R8_UINT, R8Uint, UChar1, R8U, r8_uint)
#define UINT_8_8_(impl) impl(uhar2, 1 * 2, 2, UINT_8_8, R8G8_UINT, RG8Uint, UChar2, RG8U, rg8_uint)
#define UINT_8_8_8_(impl) impl(uhar3, 1 * 3, 3, UINT_8_8_8, R8G8B8_UINT, RGBA8Uint, UChar3, RGB8U, rgb8_uint)
#define UINT_8_8_8_8_(impl) impl(uhar4, 1 * 4, 4, UINT_8_8_8_8, R8G8B8A8_UINT, RGBA8Uint, UChar4, RGBA8U, rgba8_uint)
/* type size comps blender_enum vk_enum mtl_pixel_enum mtl_vertex_enum gl_pixel_enum shader_enum */
#define UINT_16_(impl) impl(uint16_t, 2 * 1, 1, UINT_16, R16_UINT, R16Uint, UShort1, R16U, r16_uint)
#define UINT_16_16_(impl) impl(ushort2, 2 * 2, 2, UINT_16_16, R16G16_UINT, RG16Uint, UShort2, RG16U, rg16_uint)
#define UINT_16_16_16_(impl) impl(ushort3, 2 * 3, 3, UINT_16_16_16, R16G16B16_UINT, RGBA16Uint, UShort3, RGB16U, rgb16_uint)
#define UINT_16_16_16_16_(impl) impl(ushort4, 2 * 4, 4, UINT_16_16_16_16, R16G16B16A16_UINT, RGBA16Uint, UShort4, RGBA16U, rgba16_uint)
/* type size comps blender_enum vk_enum mtl_pixel_enum mtl_vertex_enum gl_pixel_enum shader_enum */
#define UINT_32_(impl) impl(uint32_t, 4 * 1, 1, UINT_32, R32_UINT, R32Uint, UInt1, R32U, r32_uint)
#define UINT_32_32_(impl) impl(uint2, 4 * 2, 2, UINT_32_32, R32G32_UINT, RG32Uint, UInt2, RG32U, rg32_uint)
#define UINT_32_32_32_(impl) impl(uint3, 4 * 3, 3, UINT_32_32_32, R32G32B32_UINT, RGBA32Uint, UInt3, RGB32U, rgb32_uint)
#define UINT_32_32_32_32_(impl) impl(uint4, 4 * 4, 4, UINT_32_32_32_32, R32G32B32A32_UINT, RGBA32Uint, UInt4, RGBA32U, rgba32_uint)
/* type size comps blender_enum vk_enum mtl_pixel_enum mtl_vertex_enum gl_pixel_enum shader_enum */
#define SFLOAT_16_(impl) impl(/*TODO*/, 2 * 1, 1, SFLOAT_16, R16_SFLOAT, R16Float, Half1, R16F, r16_sfloat)
#define SFLOAT_16_16_(impl) impl(/*TODO*/, 2 * 2, 2, SFLOAT_16_16, R16G16_SFLOAT, RG16Float, Half2, RG16F, rg16_sfloat)
#define SFLOAT_16_16_16_(impl) impl(/*TODO*/, 2 * 3, 3, SFLOAT_16_16_16, R16G16B16_SFLOAT, RGBA16Float, Half3, RGB16F, rgb16_sfloat)
#define SFLOAT_16_16_16_16_(impl) impl(/*TODO*/, 2 * 4, 4, SFLOAT_16_16_16_16, R16G16B16A16_SFLOAT, RGBA16Float, Half4, RGBA16F, rgba16_sfloat)
/* type size comps blender_enum vk_enum mtl_pixel_enum mtl_vertex_enum gl_pixel_enum shader_enum */
#define SFLOAT_32_(impl) impl(float, 4 * 1, 1, SFLOAT_32, R32_SFLOAT, R32Float, Float1, R32F, r32_sfloat)
#define SFLOAT_32_32_(impl) impl(float2, 4 * 2, 2, SFLOAT_32_32, R32G32_SFLOAT, RG32Float, Float2, RG32F, rg32_sfloat)
#define SFLOAT_32_32_32_(impl) impl(float3, 4 * 3, 3, SFLOAT_32_32_32, R32G32B32_SFLOAT, RGBA32Float, Float3, RGB32F, rgb32_sfloat)
#define SFLOAT_32_32_32_32_(impl) impl(float4, 4 * 4, 4, SFLOAT_32_32_32_32, R32G32B32A32_SFLOAT, RGBA32Float, Float4, RGBA32F, rgba32_sfloat)
/* Legacy format unsupported by Metal and Vulkan. To be phased out. */
/* type size comps blender_enum vk_enum mtl_pixel_enum mtl_vertex_enum gl_pixel_enum shader_enum */
#define SINT_TO_FLT_32_(impl) impl(int32_t, 4 * 1, 1, SINT_TO_FLT_32, R32_SFLOAT, /* n/a */, Float1, R32I, /* n/a */)
#define SINT_TO_FLT_32_32_(impl) impl(int2, 4 * 2, 2, SINT_TO_FLT_32_32, R32G32_SFLOAT, /* n/a */, Float2, RG32I, /* n/a */)
#define SINT_TO_FLT_32_32_32_(impl) impl(int3, 4 * 3, 3, SINT_TO_FLT_32_32_32, R32G32B32_SFLOAT, /* n/a */, Float3, RGB32I, /* n/a */)
#define SINT_TO_FLT_32_32_32_32_(impl) impl(int4, 4 * 4, 4, SINT_TO_FLT_32_32_32_32, R32G32B32A32_SFLOAT, /* n/a */, Float4, RGBA32I, /* n/a */)
/* clang-format on */
/** \} */
/* -------------------------------------------------------------------- */
/** \name Special Formats
* \{ */
/* clang-format off */
/* type size comps blender_enum vk_enum mtl_pixel_enum mtl_vertex_enum gl_pixel_enum shader_enum */
#define SNORM_10_10_10_2_(impl) impl(/*TODO*/, 4, 4, SNORM_10_10_10_2, A2R10G10B10_SNORM_PACK32, /* n/a */, Int1010102Normalized, /* n/a */, /* n/a */ )
#define UNORM_10_10_10_2_(impl) impl(/*TODO*/, 4, 4, UNORM_10_10_10_2, A2R10G10B10_UNORM_PACK32, RGB10A2Unorm, UInt1010102Normalized, RGB10_A2, rgb10_a2_unorm )
#define UINT_10_10_10_2_(impl) impl(/*TODO*/, 4, 4, UINT_10_10_10_2, A2R10G10B10_UINT_PACK32, RGB10A2Uint, /* n/a */, RGB10_A2UI, rgb10_a2_uint )
/* type size comps blender_enum vk_enum mtl_pixel_enum mtl_vertex_enum gl_pixel_enum shader_enum */
#define UFLOAT_11_11_10_(impl) impl(/*TODO*/, 4, 3, UFLOAT_11_11_10, B10G11R11_UFLOAT_PACK32, RG11B10Float, FloatRG11B10, R11F_G11F_B10F, r11_g11_b10_ufloat)
#define UFLOAT_9_9_9_EXP_5_(impl) impl(/*TODO*/, 4, 3, UFLOAT_9_9_9_EXP_5, E5B9G9R9_UFLOAT_PACK32, RGB9E5Float, FloatRGB9E5, RGB9_E5, /* n/a */)
/* type size comps blender_enum vk_enum mtl_pixel_enum mtl_vertex_enum gl_pixel_enum shader_enum */
#define SRGBA_8_8_8_8_(impl) impl(/*TODO*/, 4, 4, SRGBA_8_8_8_8, R8G8B8A8_SRGB, RGBA8Unorm_sRGB, /* n/a */, SRGB8_ALPHA8, /* n/a */ )
#define SRGBA_8_8_8_(impl) impl(/*TODO*/, 3, 3, SRGBA_8_8_8, R8G8B8_SRGB, /* n/a */, /* n/a */, SRGB8, /* n/a */ )
/* type size comps blender_enum vk_enum mtl_pixel_enum mtl_vertex_enum gl_pixel_enum shader_enum */
#define UNORM_16_DEPTH_(impl) impl(/*TODO*/, 4, 1, UNORM_16_DEPTH, D16_UNORM, Depth16Unorm, /* n/a */, DEPTH_COMPONENT16, /* n/a */ )
#define UNORM_24_DEPTH_(impl) impl(/*TODO*/, 4, 1, UNORM_24_DEPTH, X8_D24_UNORM_PACK32, Depth24Unorm_Stencil8, /* n/a */, DEPTH_COMPONENT24, /* n/a */ )
#define UNORM_24_DEPTH_UINT_8_(impl) impl(/*TODO*/, 8, 1, UNORM_24_DEPTH_UINT_8, D24_UNORM_S8_UINT, Depth24Unorm_Stencil8, /* n/a */, DEPTH24_STENCIL8, /* n/a */ )
#define SFLOAT_32_DEPTH_(impl) impl(/*TODO*/, 4, 1, SFLOAT_32_DEPTH, D32_SFLOAT, Depth32Float, /* n/a */, DEPTH_COMPONENT32F, /* n/a */ )
#define SFLOAT_32_DEPTH_UINT_8_(impl) impl(/*TODO*/, 8, 1, SFLOAT_32_DEPTH_UINT_8, D32_SFLOAT_S8_UINT, Depth32Float_Stencil8, /* n/a */, DEPTH32F_STENCIL8, /* n/a */ )
/* type size comps blender_enum vk_enum mtl_pixel_enum mtl_vertex_enum gl_pixel_enum shader_enum */
#define SNORM_DXT1_(impl) impl(/* n/a */, 1, 1, SNORM_DXT1, BC1_RGBA_UNORM_BLOCK, BC1_RGBA, /* n/a */, COMPRESSED_RGBA_S3TC_DXT1_EXT, /* n/a */ )
#define SNORM_DXT3_(impl) impl(/* n/a */, 1, 1, SNORM_DXT3, BC2_UNORM_BLOCK, BC2_RGBA, /* n/a */, COMPRESSED_RGBA_S3TC_DXT3_EXT, /* n/a */ )
#define SNORM_DXT5_(impl) impl(/* n/a */, 1, 1, SNORM_DXT5, BC3_UNORM_BLOCK, BC3_RGBA, /* n/a */, COMPRESSED_RGBA_S3TC_DXT5_EXT, /* n/a */ )
#define SRGB_DXT1_(impl) impl(/* n/a */, 1, 1, SRGB_DXT1, BC1_RGBA_SRGB_BLOCK, BC1_RGBA_sRGB, /* n/a */, COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT, /* n/a */ )
#define SRGB_DXT3_(impl) impl(/* n/a */, 1, 1, SRGB_DXT3, BC2_SRGB_BLOCK, BC2_RGBA_sRGB, /* n/a */, COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT, /* n/a */ )
#define SRGB_DXT5_(impl) impl(/* n/a */, 1, 1, SRGB_DXT5, BC3_SRGB_BLOCK, BC3_RGBA_sRGB, /* n/a */, COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT, /* n/a */ )
/* clang-format on */
/** \} */
/* -------------------------------------------------------------------- */
/** \name Data Formats
* \{ */
/**
* Collection of all data formats.
* Vertex formats and Texture formats are both subset of this.
*/
enum class DataFormat : uint8_t {
Invalid = 0,
#define DECLARE(a, b, c, blender_enum, d, e, f, g, h) blender_enum,
#define GPU_DATA_FORMAT_EXPAND(impl) \
SNORM_8_(impl) \
SNORM_8_8_(impl) \
SNORM_8_8_8_(impl) \
SNORM_8_8_8_8_(impl) \
\
SNORM_16_(impl) \
SNORM_16_16_(impl) \
SNORM_16_16_16_(impl) \
SNORM_16_16_16_16_(impl) \
\
UNORM_8_(impl) \
UNORM_8_8_(impl) \
UNORM_8_8_8_(impl) \
UNORM_8_8_8_8_(impl) \
\
UNORM_16_(impl) \
UNORM_16_16_(impl) \
UNORM_16_16_16_(impl) \
UNORM_16_16_16_16_(impl) \
\
SINT_8_(impl) \
SINT_8_8_(impl) \
SINT_8_8_8_(impl) \
SINT_8_8_8_8_(impl) \
\
SINT_16_(impl) \
SINT_16_16_(impl) \
SINT_16_16_16_(impl) \
SINT_16_16_16_16_(impl) \
\
SINT_32_(impl) \
SINT_32_32_(impl) \
SINT_32_32_32_(impl) \
SINT_32_32_32_32_(impl) \
\
UINT_8_(impl) \
UINT_8_8_(impl) \
UINT_8_8_8_(impl) \
UINT_8_8_8_8_(impl) \
\
UINT_16_(impl) \
UINT_16_16_(impl) \
UINT_16_16_16_(impl) \
UINT_16_16_16_16_(impl) \
\
UINT_32_(impl) \
UINT_32_32_(impl) \
UINT_32_32_32_(impl) \
UINT_32_32_32_32_(impl) \
\
SFLOAT_16_(impl) \
SFLOAT_16_16_(impl) \
SFLOAT_16_16_16_(impl) \
SFLOAT_16_16_16_16_(impl) \
\
SFLOAT_32_(impl) \
SFLOAT_32_32_(impl) \
SFLOAT_32_32_32_(impl) \
SFLOAT_32_32_32_32_(impl) \
\
SNORM_10_10_10_2_(impl) \
UNORM_10_10_10_2_(impl) \
UINT_10_10_10_2_(impl) \
\
UFLOAT_11_11_10_(impl) \
UFLOAT_9_9_9_EXP_5_(impl) \
\
UNORM_16_DEPTH_(impl) \
UNORM_24_DEPTH_(impl) /* TODO(fclem): Incompatible with metal, is emulated. To remove. */ \
UNORM_24_DEPTH_UINT_8_(impl) \
SFLOAT_32_DEPTH_(impl) \
SFLOAT_32_DEPTH_UINT_8_(impl) \
\
/* Legacy format unsupported by Metal and Vulkan. To be phased out. */ \
SINT_TO_FLT_32_(impl) \
SINT_TO_FLT_32_32_(impl) \
SINT_TO_FLT_32_32_32_(impl) \
SINT_TO_FLT_32_32_32_32_(impl) \
\
SRGBA_8_8_8_(impl) \
SRGBA_8_8_8_8_(impl) \
\
SNORM_DXT1_(impl) \
SNORM_DXT3_(impl) \
SNORM_DXT5_(impl) \
SRGB_DXT1_(impl) \
SRGB_DXT3_(impl) \
SRGB_DXT5_(impl)
GPU_DATA_FORMAT_EXPAND(DECLARE)
#undef DECLARE
};
/** \} */
/* -------------------------------------------------------------------- */
/** \name Utilities
*
* Allow querying informations about the format enum values.
* \{ */
/* NOTE: Compressed format bytesize are rounded up as their actual value is fractional. */
inline int to_bytesize(const DataFormat format)
{
#define CASE(a, size, c, blender_enum, d, e, f, g, h) \
case DataFormat::blender_enum: \
return size;
switch (format) {
GPU_DATA_FORMAT_EXPAND(CASE)
case DataFormat::Invalid:
break;
}
#undef CASE
BLI_assert_unreachable();
return -1;
}
inline int format_component_len(const DataFormat format)
{
#define CASE(a, b, comp, blender_enum, d, e, f, g, h) \
case DataFormat::blender_enum: \
return comp;
switch (format) {
GPU_DATA_FORMAT_EXPAND(CASE)
case DataFormat::Invalid:
break;
}
#undef CASE
BLI_assert_unreachable();
return -1;
}
/** \} */
} // namespace blender::gpu

View File

@@ -54,16 +54,12 @@ void immAttr2i(uint attr_id, int x, int y);
void immAttr1u(uint attr_id, uint x);
void immAttr2s(uint attr_id, short x, short y);
void immAttr2fv(uint attr_id, const float data[2]);
void immAttr3fv(uint attr_id, const float data[3]);
void immAttr4fv(uint attr_id, const float data[4]);
void immAttr3ub(uint attr_id, unsigned char r, unsigned char g, unsigned char b);
void immAttr4ub(uint attr_id, unsigned char r, unsigned char g, unsigned char b, unsigned char a);
void immAttr3ubv(uint attr_id, const unsigned char data[3]);
void immAttr4ubv(uint attr_id, const unsigned char data[4]);
/* Explicitly skip an attribute.
@@ -80,8 +76,6 @@ void immVertex4f(uint attr_id, float x, float y, float z, float w);
void immVertex2i(uint attr_id, int x, int y);
void immVertex2s(uint attr_id, short x, short y);
void immVertex2fv(uint attr_id, const float data[2]);
void immVertex3fv(uint attr_id, const float data[3]);

View File

@@ -17,10 +17,261 @@
#include "BLI_assert.h"
#include "BLI_utildefines.h"
#include "GPU_format.hh"
namespace blender::gpu {
class VertBuf;
}
namespace blender::gpu {
/* -------------------------------------------------------------------- */
/** \name Texture Formats
* \{ */
/**
* Formats compatible with read-only texture.
*/
enum class TextureFormat : uint8_t {
Invalid = 0,
#define DECLARE(a, b, c, blender_enum, d, e, f, g, h) blender_enum = int(DataFormat::blender_enum),
#define GPU_TEXTURE_FORMAT_EXPAND(impl) \
SNORM_8_(impl) \
SNORM_8_8_(impl) \
SNORM_8_8_8_(impl) /* TODO(fclem): Incompatible with metal, to remove. */ \
SNORM_8_8_8_8_(impl) \
\
SNORM_16_(impl) \
SNORM_16_16_(impl) \
SNORM_16_16_16_(impl) /* TODO(fclem): Incompatible with metal, to remove. */ \
SNORM_16_16_16_16_(impl) \
\
UNORM_8_(impl) \
UNORM_8_8_(impl) \
UNORM_8_8_8_(impl) /* TODO(fclem): Incompatible with metal, to remove. */ \
UNORM_8_8_8_8_(impl) \
\
UNORM_16_(impl) \
UNORM_16_16_(impl) \
UNORM_16_16_16_(impl) /* TODO(fclem): Incompatible with metal, to remove. */ \
UNORM_16_16_16_16_(impl) \
\
SINT_8_(impl) \
SINT_8_8_(impl) \
SINT_8_8_8_(impl) /* TODO(fclem): Incompatible with metal, to remove. */ \
SINT_8_8_8_8_(impl) \
\
SINT_16_(impl) \
SINT_16_16_(impl) \
SINT_16_16_16_(impl) /* TODO(fclem): Incompatible with metal, to remove. */ \
SINT_16_16_16_16_(impl) \
\
SINT_32_(impl) \
SINT_32_32_(impl) \
SINT_32_32_32_(impl) /* TODO(fclem): Incompatible with metal, to remove. */ \
SINT_32_32_32_32_(impl) \
\
UINT_8_(impl) \
UINT_8_8_(impl) \
UINT_8_8_8_(impl) /* TODO(fclem): Incompatible with metal, to remove. */ \
UINT_8_8_8_8_(impl) \
\
UINT_16_(impl) \
UINT_16_16_(impl) \
UINT_16_16_16_(impl) /* TODO(fclem): Incompatible with metal, to remove. */ \
UINT_16_16_16_16_(impl) \
\
UINT_32_(impl) \
UINT_32_32_(impl) \
UINT_32_32_32_(impl) /* TODO(fclem): Incompatible with metal, to remove. */ \
UINT_32_32_32_32_(impl) \
\
SFLOAT_16_(impl) \
SFLOAT_16_16_(impl) \
SFLOAT_16_16_16_(impl) /* TODO(fclem): Incompatible with metal, to remove. */ \
SFLOAT_16_16_16_16_(impl) \
\
SFLOAT_32_(impl) \
SFLOAT_32_32_(impl) \
SFLOAT_32_32_32_(impl) /* TODO(fclem): Incompatible with metal, to remove. */ \
SFLOAT_32_32_32_32_(impl) \
\
UNORM_10_10_10_2_(impl) \
UINT_10_10_10_2_(impl) \
\
UFLOAT_11_11_10_(impl) \
UFLOAT_9_9_9_EXP_5_(impl) \
\
UNORM_16_DEPTH_(impl) \
UNORM_24_DEPTH_(impl) /* TODO(fclem): Incompatible with metal, is emulated. To remove. */ \
UNORM_24_DEPTH_UINT_8_(impl) \
SFLOAT_32_DEPTH_(impl) \
SFLOAT_32_DEPTH_UINT_8_(impl) \
\
SRGBA_8_8_8_(impl) \
SRGBA_8_8_8_8_(impl) \
\
SNORM_DXT1_(impl) \
SNORM_DXT3_(impl) \
SNORM_DXT5_(impl) \
SRGB_DXT1_(impl) \
SRGB_DXT3_(impl) \
SRGB_DXT5_(impl)
GPU_TEXTURE_FORMAT_EXPAND(DECLARE)
#undef DECLARE
};
inline constexpr DataFormat to_data_format(TextureFormat format)
{
return DataFormat(int(format));
}
/**
* Formats compatible with framebuffer attachments.
*/
enum class TextureTargetFormat : uint8_t {
Invalid = 0,
#define DECLARE(a, b, c, blender_enum, d, e, f, g, h) \
blender_enum = int(TextureFormat::blender_enum),
#define GPU_TEXTURE_TARGET_FORMAT_EXPAND(impl) \
UNORM_8_(impl) \
UNORM_8_8_(impl) \
UNORM_8_8_8_8_(impl) \
\
UNORM_16_(impl) \
UNORM_16_16_(impl) \
UNORM_16_16_16_16_(impl) \
\
SINT_8_(impl) \
SINT_8_8_(impl) \
SINT_8_8_8_8_(impl) \
\
SINT_16_(impl) \
SINT_16_16_(impl) \
SINT_16_16_16_16_(impl) \
\
SINT_32_(impl) \
SINT_32_32_(impl) \
SINT_32_32_32_32_(impl) \
\
UINT_8_(impl) \
UINT_8_8_(impl) \
UINT_8_8_8_8_(impl) \
\
UINT_16_(impl) \
UINT_16_16_(impl) \
UINT_16_16_16_16_(impl) \
\
UINT_32_(impl) \
UINT_32_32_(impl) \
UINT_32_32_32_32_(impl) \
\
SFLOAT_16_(impl) \
SFLOAT_16_16_(impl) \
SFLOAT_16_16_16_16_(impl) \
\
SFLOAT_32_(impl) \
SFLOAT_32_32_(impl) \
SFLOAT_32_32_32_32_(impl) \
\
UNORM_10_10_10_2_(impl) \
UINT_10_10_10_2_(impl) \
\
UFLOAT_11_11_10_(impl) \
\
UNORM_16_DEPTH_(impl) \
UNORM_24_DEPTH_(impl) /* TODO(fclem): Incompatible with metal, is emulated. To remove. */ \
UNORM_24_DEPTH_UINT_8_(impl) \
SFLOAT_32_DEPTH_(impl) \
SFLOAT_32_DEPTH_UINT_8_(impl) \
\
SRGBA_8_8_8_8_(impl)
GPU_TEXTURE_TARGET_FORMAT_EXPAND(DECLARE)
#undef DECLARE
};
inline constexpr TextureFormat to_texture_format(TextureTargetFormat format)
{
return TextureFormat(int(format));
}
/**
* Formats compatible with shader load/store.
*/
enum class TextureWriteFormat : uint8_t {
Invalid = 0,
#define DECLARE(a, b, c, blender_enum, d, e, f, g, h) \
blender_enum = int(TextureFormat::blender_enum),
#define GPU_TEXTURE_WRITE_FORMAT_EXPAND(impl) \
UNORM_8_(impl) \
UNORM_8_8_(impl) \
UNORM_8_8_8_8_(impl) \
\
UNORM_16_(impl) \
UNORM_16_16_(impl) \
UNORM_16_16_16_16_(impl) \
\
SINT_8_(impl) \
SINT_8_8_(impl) \
SINT_8_8_8_8_(impl) \
\
SINT_16_(impl) \
SINT_16_16_(impl) \
SINT_16_16_16_16_(impl) \
\
SINT_32_(impl) \
SINT_32_32_(impl) \
SINT_32_32_32_32_(impl) \
\
UINT_8_(impl) \
UINT_8_8_(impl) \
UINT_8_8_8_8_(impl) \
\
UINT_16_(impl) \
UINT_16_16_(impl) \
UINT_16_16_16_16_(impl) \
\
UINT_32_(impl) \
UINT_32_32_(impl) \
UINT_32_32_32_32_(impl) \
\
SFLOAT_16_(impl) \
SFLOAT_16_16_(impl) \
SFLOAT_16_16_16_16_(impl) \
\
SFLOAT_32_(impl) \
SFLOAT_32_32_(impl) \
SFLOAT_32_32_32_32_(impl) \
\
UNORM_10_10_10_2_(impl) \
UINT_10_10_10_2_(impl) \
\
UFLOAT_11_11_10_(impl)
GPU_TEXTURE_WRITE_FORMAT_EXPAND(DECLARE)
#undef DECLARE
};
inline constexpr TextureFormat to_texture_format(TextureWriteFormat format)
{
return TextureFormat(int(format));
}
/** \} */
} // namespace blender::gpu
/* -------------------------------------------------------------------- */
/** \name Sampler State
* \{ */
@@ -397,81 +648,79 @@ struct GPUSamplerState {
enum eGPUTextureFormat {
/* Formats texture & render-buffer. */
GPU_RGBA8UI,
GPU_RGBA8I,
GPU_RGBA8,
GPU_RGBA16UI,
GPU_RGBA16I,
GPU_RGBA16F,
GPU_RGBA16,
GPU_RGBA32UI,
GPU_RGBA32I,
GPU_RGBA32F,
GPU_RGBA8UI = uint8_t(blender::gpu::TextureFormat::UINT_8_8_8_8),
GPU_RGBA8I = uint8_t(blender::gpu::TextureFormat::SINT_8_8_8_8),
GPU_RGBA8 = uint8_t(blender::gpu::TextureFormat::UNORM_8_8_8_8),
GPU_RGBA16UI = uint8_t(blender::gpu::TextureFormat::UINT_16_16_16_16),
GPU_RGBA16I = uint8_t(blender::gpu::TextureFormat::SINT_16_16_16_16),
GPU_RGBA16F = uint8_t(blender::gpu::TextureFormat::SFLOAT_16_16_16_16),
GPU_RGBA16 = uint8_t(blender::gpu::TextureFormat::UNORM_16_16_16_16),
GPU_RGBA32UI = uint8_t(blender::gpu::TextureFormat::UINT_32_32_32_32),
GPU_RGBA32I = uint8_t(blender::gpu::TextureFormat::SINT_32_32_32_32),
GPU_RGBA32F = uint8_t(blender::gpu::TextureFormat::SFLOAT_32_32_32_32),
GPU_RG8UI,
GPU_RG8I,
GPU_RG8,
GPU_RG16UI,
GPU_RG16I,
GPU_RG16F,
GPU_RG16,
GPU_RG32UI,
GPU_RG32I,
GPU_RG32F,
GPU_RG8UI = uint8_t(blender::gpu::TextureFormat::UINT_8_8),
GPU_RG8I = uint8_t(blender::gpu::TextureFormat::SINT_8_8),
GPU_RG8 = uint8_t(blender::gpu::TextureFormat::UNORM_8_8),
GPU_RG16UI = uint8_t(blender::gpu::TextureFormat::UINT_16_16),
GPU_RG16I = uint8_t(blender::gpu::TextureFormat::SINT_16_16),
GPU_RG16F = uint8_t(blender::gpu::TextureFormat::SFLOAT_16_16),
GPU_RG16 = uint8_t(blender::gpu::TextureFormat::UNORM_16_16),
GPU_RG32UI = uint8_t(blender::gpu::TextureFormat::UINT_32_32),
GPU_RG32I = uint8_t(blender::gpu::TextureFormat::SINT_32_32),
GPU_RG32F = uint8_t(blender::gpu::TextureFormat::SFLOAT_32_32),
GPU_R8UI,
GPU_R8I,
GPU_R8,
GPU_R16UI,
GPU_R16I,
GPU_R16F,
GPU_R16,
GPU_R32UI,
GPU_R32I,
GPU_R32F,
GPU_R8UI = uint8_t(blender::gpu::TextureFormat::UINT_8),
GPU_R8I = uint8_t(blender::gpu::TextureFormat::SINT_8),
GPU_R8 = uint8_t(blender::gpu::TextureFormat::UNORM_8),
GPU_R16UI = uint8_t(blender::gpu::TextureFormat::UINT_16),
GPU_R16I = uint8_t(blender::gpu::TextureFormat::SINT_16),
GPU_R16F = uint8_t(blender::gpu::TextureFormat::SFLOAT_16),
GPU_R16 = uint8_t(blender::gpu::TextureFormat::UNORM_16),
GPU_R32UI = uint8_t(blender::gpu::TextureFormat::UINT_32),
GPU_R32I = uint8_t(blender::gpu::TextureFormat::SINT_32),
GPU_R32F = uint8_t(blender::gpu::TextureFormat::SFLOAT_32),
/* Special formats texture & render-buffer. */
GPU_RGB10_A2,
GPU_RGB10_A2UI,
GPU_R11F_G11F_B10F,
GPU_DEPTH32F_STENCIL8,
GPU_DEPTH24_STENCIL8,
GPU_SRGB8_A8,
GPU_RGB10_A2 = uint8_t(blender::gpu::TextureFormat::UNORM_10_10_10_2),
GPU_RGB10_A2UI = uint8_t(blender::gpu::TextureFormat::UINT_10_10_10_2),
GPU_R11F_G11F_B10F = uint8_t(blender::gpu::TextureFormat::UFLOAT_11_11_10),
GPU_DEPTH32F_STENCIL8 = uint8_t(blender::gpu::TextureFormat::SFLOAT_32_DEPTH_UINT_8),
GPU_DEPTH24_STENCIL8 = uint8_t(blender::gpu::TextureFormat::UNORM_24_DEPTH_UINT_8),
GPU_SRGB8_A8 = uint8_t(blender::gpu::TextureFormat::SRGBA_8_8_8_8),
/* Texture only formats. */
GPU_RGBA8_SNORM,
GPU_RGBA16_SNORM,
GPU_RGBA8_SNORM = uint8_t(blender::gpu::TextureFormat::SNORM_8_8_8_8),
GPU_RGB8_SNORM = uint8_t(blender::gpu::TextureFormat::SNORM_8_8_8),
GPU_RG8_SNORM = uint8_t(blender::gpu::TextureFormat::SNORM_8_8),
GPU_R8_SNORM = uint8_t(blender::gpu::TextureFormat::SNORM_8),
GPU_RGBA16_SNORM = uint8_t(blender::gpu::TextureFormat::SNORM_16_16_16_16),
GPU_RGB16_SNORM = uint8_t(blender::gpu::TextureFormat::SNORM_16_16_16),
GPU_RG16_SNORM = uint8_t(blender::gpu::TextureFormat::SNORM_16_16),
GPU_R16_SNORM = uint8_t(blender::gpu::TextureFormat::SNORM_16),
GPU_RGB8UI,
GPU_RGB8I,
GPU_RGB8,
GPU_RGB8_SNORM,
GPU_RGB16UI,
GPU_RGB16I,
GPU_RGB16F,
GPU_RGB16,
GPU_RGB16_SNORM,
GPU_RGB32UI,
GPU_RGB32I,
GPU_RGB32F,
GPU_RG8_SNORM,
GPU_RG16_SNORM,
GPU_R8_SNORM,
GPU_R16_SNORM,
GPU_RGB8UI = uint8_t(blender::gpu::TextureFormat::UINT_8_8_8),
GPU_RGB8I = uint8_t(blender::gpu::TextureFormat::SINT_8_8_8),
GPU_RGB8 = uint8_t(blender::gpu::TextureFormat::UNORM_8_8_8),
GPU_RGB16UI = uint8_t(blender::gpu::TextureFormat::UINT_16_16_16),
GPU_RGB16I = uint8_t(blender::gpu::TextureFormat::SINT_16_16_16),
GPU_RGB16F = uint8_t(blender::gpu::TextureFormat::SFLOAT_16_16_16),
GPU_RGB16 = uint8_t(blender::gpu::TextureFormat::UNORM_16_16_16),
GPU_RGB32UI = uint8_t(blender::gpu::TextureFormat::UINT_32_32_32),
GPU_RGB32I = uint8_t(blender::gpu::TextureFormat::SINT_32_32_32),
GPU_RGB32F = uint8_t(blender::gpu::TextureFormat::SFLOAT_32_32_32),
/* Special formats, texture only. */
GPU_SRGB8_A8_DXT1, /* BC1 */
GPU_SRGB8_A8_DXT3, /* BC2 */
GPU_SRGB8_A8_DXT5, /* BC3 */
GPU_RGBA8_DXT1, /* BC1 */
GPU_RGBA8_DXT3, /* BC2 */
GPU_RGBA8_DXT5, /* BC3 */
GPU_SRGB8,
GPU_RGB9_E5,
GPU_SRGB8_A8_DXT1 = uint8_t(blender::gpu::TextureFormat::SRGB_DXT1),
GPU_SRGB8_A8_DXT3 = uint8_t(blender::gpu::TextureFormat::SRGB_DXT3),
GPU_SRGB8_A8_DXT5 = uint8_t(blender::gpu::TextureFormat::SRGB_DXT5),
GPU_RGBA8_DXT1 = uint8_t(blender::gpu::TextureFormat::SNORM_DXT1),
GPU_RGBA8_DXT3 = uint8_t(blender::gpu::TextureFormat::SNORM_DXT3),
GPU_RGBA8_DXT5 = uint8_t(blender::gpu::TextureFormat::SNORM_DXT5),
GPU_SRGB8 = uint8_t(blender::gpu::TextureFormat::SRGBA_8_8_8),
GPU_RGB9_E5 = uint8_t(blender::gpu::TextureFormat::UFLOAT_9_9_9_EXP_5),
#if 0 /* TODO: Add support for them. */
GPU_COMPRESSED_RG_RGTC2,
GPU_COMPRESSED_SIGNED_RG_RGTC2,
@@ -480,9 +729,9 @@ enum eGPUTextureFormat {
#endif
/* Depth Formats. */
GPU_DEPTH_COMPONENT32F,
GPU_DEPTH_COMPONENT24,
GPU_DEPTH_COMPONENT16,
GPU_DEPTH_COMPONENT32F = uint8_t(blender::gpu::TextureFormat::SFLOAT_32_DEPTH),
GPU_DEPTH_COMPONENT24 = uint8_t(blender::gpu::TextureFormat::UNORM_24_DEPTH),
GPU_DEPTH_COMPONENT16 = uint8_t(blender::gpu::TextureFormat::UNORM_16_DEPTH),
};
/**

View File

@@ -15,6 +15,75 @@
#include "BLI_string_ref.hh"
#include "BLI_sys_types.h"
#include "GPU_format.hh"
namespace blender::gpu {
enum class VertAttrType : uint8_t {
Invalid = 0,
#define DECLARE(a, b, c, blender_enum, d, e, f, g, h) blender_enum = int(DataFormat::blender_enum),
#define GPU_VERTEX_FORMAT_EXPAND(impl) \
SNORM_8_8_8_8_(impl) \
\
SNORM_16_16_(impl) \
SNORM_16_16_16_16_(impl) \
\
UNORM_8_8_8_8_(impl) \
\
UNORM_16_16_(impl) \
UNORM_16_16_16_16_(impl) \
\
SINT_8_8_8_8_(impl) \
\
SINT_16_16_(impl) \
SINT_16_16_16_16_(impl) \
\
SINT_32_(impl) \
SINT_32_32_(impl) \
SINT_32_32_32_(impl) \
SINT_32_32_32_32_(impl) \
\
UINT_8_8_8_8_(impl) \
\
UINT_16_16_(impl) \
UINT_16_16_16_16_(impl) \
\
UINT_32_(impl) \
UINT_32_32_(impl) \
UINT_32_32_32_(impl) \
UINT_32_32_32_32_(impl) \
\
SFLOAT_32_(impl) \
SFLOAT_32_32_(impl) \
SFLOAT_32_32_32_(impl) \
SFLOAT_32_32_32_32_(impl) \
\
SNORM_10_10_10_2_(impl) \
UNORM_10_10_10_2_(impl) \
\
/* Legacy format unsupported by Metal and Vulkan. To be phased out. */ \
SINT_TO_FLT_32_(impl) \
SINT_TO_FLT_32_32_(impl) \
SINT_TO_FLT_32_32_32_(impl) \
SINT_TO_FLT_32_32_32_32_(impl) \
\
/* UFLOAT_11_11_10_(impl) Available on Metal (and maybe VK) but not on GL. */ \
/* UFLOAT_9_9_9_EXP_5_(impl) Available on Metal (and maybe VK) but not on GL. */
GPU_VERTEX_FORMAT_EXPAND(DECLARE)
#undef DECLARE
};
inline constexpr DataFormat to_data_format(VertAttrType format)
{
return DataFormat(int(format));
}
} // namespace blender::gpu
struct GPUShader;
constexpr static int GPU_VERT_ATTR_MAX_LEN = 16;
@@ -49,6 +118,9 @@ enum GPUVertFetchMode {
};
struct GPUVertAttr {
/* To replace fetch_mode, comp_type, comp_len, size. */
blender::gpu::VertAttrType format;
#ifndef NO_LEGACY_VERT_TYPE
/* GPUVertFetchMode */
uint fetch_mode : 2;
/* GPUVertCompType */
@@ -57,10 +129,11 @@ struct GPUVertAttr {
uint comp_len : 5;
/* size in bytes, 1 to 64 */
uint size : 7;
#endif
/* from beginning of vertex, in bytes */
uint offset : 11;
uint8_t offset;
/* up to GPU_VERT_ATTR_MAX_NAMES */
uint name_len : 3;
uint8_t name_len;
uchar names[GPU_VERT_ATTR_MAX_NAMES];
};

View File

@@ -309,25 +309,29 @@ void Immediate::polyline_draw_workaround(uint64_t offset)
const char *name = GPU_vertformat_attr_name_get(&format, a, 0);
if (pos_attr_id == -1 && blender::StringRefNull(name) == "pos") {
int descriptor[2] = {int(format.stride) / 4, int(a->offset) / 4};
BLI_assert(ELEM(a->comp_type, GPU_COMP_F32, GPU_COMP_I32));
BLI_assert(ELEM(a->fetch_mode, GPU_FETCH_FLOAT, GPU_FETCH_INT_TO_FLOAT));
const bool fetch_int = is_fetch_int_to_float(a->format);
BLI_assert(is_fetch_float(a->format) || fetch_int);
BLI_assert_msg((a->offset % 4) == 0, "Only support 4byte aligned attributes");
const bool fetch_int = a->fetch_mode == GPU_FETCH_INT_TO_FLOAT;
GPU_shader_uniform_2iv(imm->shader, "gpu_attr_0", descriptor);
GPU_shader_uniform_1i(imm->shader, "gpu_attr_0_len", a->comp_len);
GPU_shader_uniform_1i(imm->shader, "gpu_attr_0_len", format_component_len(a->format));
GPU_shader_uniform_1b(imm->shader, "gpu_attr_0_fetch_int", fetch_int);
pos_attr_id = a_idx;
}
else if (col_attr_id == -1 && blender::StringRefNull(name) == "color") {
int descriptor[2] = {int(format.stride) / 4, int(a->offset) / 4};
/* Maybe we can relax this if needed. */
BLI_assert_msg((a->comp_type == GPU_COMP_F32) ||
((a->comp_type == GPU_COMP_U8) && (a->comp_len == 4)),
BLI_assert_msg(ELEM(a->format,
VertAttrType::SFLOAT_32,
VertAttrType::SFLOAT_32_32,
VertAttrType::SFLOAT_32_32_32,
VertAttrType::SFLOAT_32_32_32_32,
VertAttrType::UNORM_8_8_8_8),
"Only support float attributes or uchar4");
const bool fetch_unorm8 = a->format == VertAttrType::UNORM_8_8_8_8;
BLI_assert_msg((a->offset % 4) == 0, "Only support 4byte aligned attributes");
GPU_shader_uniform_2iv(imm->shader, "gpu_attr_1", descriptor);
GPU_shader_uniform_1i(imm->shader, "gpu_attr_1_len", a->comp_len);
GPU_shader_uniform_1i(imm->shader, "gpu_attr_1_fetch_unorm8", a->comp_type == GPU_COMP_U8);
GPU_shader_uniform_1i(imm->shader, "gpu_attr_1_len", format_component_len(a->format));
GPU_shader_uniform_1i(imm->shader, "gpu_attr_1_fetch_unorm8", fetch_unorm8);
col_attr_id = a_idx;
}
if (pos_attr_id != -1 && col_attr_id != -1) {
@@ -359,8 +363,7 @@ void immAttr1f(uint attr_id, float x)
{
GPUVertAttr *attr = &imm->vertex_format.attrs[attr_id];
BLI_assert(attr_id < imm->vertex_format.attr_len);
BLI_assert(attr->comp_type == GPU_COMP_F32);
BLI_assert(attr->comp_len == 1);
BLI_assert(ELEM(attr->format, VertAttrType::SFLOAT_32));
BLI_assert(imm->vertex_idx < imm->vertex_len);
BLI_assert(imm->prim_type != GPU_PRIM_NONE); /* make sure we're between a Begin/End pair */
setAttrValueBit(attr_id);
@@ -375,8 +378,7 @@ void immAttr2f(uint attr_id, float x, float y)
{
GPUVertAttr *attr = &imm->vertex_format.attrs[attr_id];
BLI_assert(attr_id < imm->vertex_format.attr_len);
BLI_assert(attr->comp_type == GPU_COMP_F32);
BLI_assert(attr->comp_len == 2);
BLI_assert(ELEM(attr->format, VertAttrType::SFLOAT_32_32));
BLI_assert(imm->vertex_idx < imm->vertex_len);
BLI_assert(imm->prim_type != GPU_PRIM_NONE); /* make sure we're between a Begin/End pair */
setAttrValueBit(attr_id);
@@ -392,8 +394,7 @@ void immAttr3f(uint attr_id, float x, float y, float z)
{
GPUVertAttr *attr = &imm->vertex_format.attrs[attr_id];
BLI_assert(attr_id < imm->vertex_format.attr_len);
BLI_assert(attr->comp_type == GPU_COMP_F32);
BLI_assert(attr->comp_len == 3);
BLI_assert(ELEM(attr->format, VertAttrType::SFLOAT_32_32_32));
BLI_assert(imm->vertex_idx < imm->vertex_len);
BLI_assert(imm->prim_type != GPU_PRIM_NONE); /* make sure we're between a Begin/End pair */
setAttrValueBit(attr_id);
@@ -410,8 +411,7 @@ void immAttr4f(uint attr_id, float x, float y, float z, float w)
{
GPUVertAttr *attr = &imm->vertex_format.attrs[attr_id];
BLI_assert(attr_id < imm->vertex_format.attr_len);
BLI_assert(attr->comp_type == GPU_COMP_F32);
BLI_assert(attr->comp_len == 4);
BLI_assert(ELEM(attr->format, VertAttrType::SFLOAT_32_32_32_32));
BLI_assert(imm->vertex_idx < imm->vertex_len);
BLI_assert(imm->prim_type != GPU_PRIM_NONE); /* make sure we're between a Begin/End pair */
setAttrValueBit(attr_id);
@@ -429,8 +429,7 @@ void immAttr1u(uint attr_id, uint x)
{
GPUVertAttr *attr = &imm->vertex_format.attrs[attr_id];
BLI_assert(attr_id < imm->vertex_format.attr_len);
BLI_assert(attr->comp_type == GPU_COMP_U32);
BLI_assert(attr->comp_len == 1);
BLI_assert(ELEM(attr->format, VertAttrType::UINT_32));
BLI_assert(imm->vertex_idx < imm->vertex_len);
BLI_assert(imm->prim_type != GPU_PRIM_NONE); /* make sure we're between a Begin/End pair */
setAttrValueBit(attr_id);
@@ -444,8 +443,7 @@ void immAttr2i(uint attr_id, int x, int y)
{
GPUVertAttr *attr = &imm->vertex_format.attrs[attr_id];
BLI_assert(attr_id < imm->vertex_format.attr_len);
BLI_assert(attr->comp_type == GPU_COMP_I32);
BLI_assert(attr->comp_len == 2);
BLI_assert(ELEM(attr->format, VertAttrType::SINT_32_32, VertAttrType::SINT_TO_FLT_32_32));
BLI_assert(imm->vertex_idx < imm->vertex_len);
BLI_assert(imm->prim_type != GPU_PRIM_NONE); /* make sure we're between a Begin/End pair */
setAttrValueBit(attr_id);
@@ -456,22 +454,6 @@ void immAttr2i(uint attr_id, int x, int y)
data[1] = y;
}
void immAttr2s(uint attr_id, short x, short y)
{
GPUVertAttr *attr = &imm->vertex_format.attrs[attr_id];
BLI_assert(attr_id < imm->vertex_format.attr_len);
BLI_assert(attr->comp_type == GPU_COMP_I16);
BLI_assert(attr->comp_len == 2);
BLI_assert(imm->vertex_idx < imm->vertex_len);
BLI_assert(imm->prim_type != GPU_PRIM_NONE); /* make sure we're between a Begin/End pair */
setAttrValueBit(attr_id);
short *data = (short *)(imm->vertex_data + attr->offset);
data[0] = x;
data[1] = y;
}
void immAttr2fv(uint attr_id, const float data[2])
{
immAttr2f(attr_id, data[0], data[1]);
@@ -487,30 +469,11 @@ void immAttr4fv(uint attr_id, const float data[4])
immAttr4f(attr_id, data[0], data[1], data[2], data[3]);
}
void immAttr3ub(uint attr_id, uchar r, uchar g, uchar b)
{
GPUVertAttr *attr = &imm->vertex_format.attrs[attr_id];
BLI_assert(attr_id < imm->vertex_format.attr_len);
BLI_assert(attr->comp_type == GPU_COMP_U8);
BLI_assert(attr->comp_len == 3);
BLI_assert(imm->vertex_idx < imm->vertex_len);
BLI_assert(imm->prim_type != GPU_PRIM_NONE); /* make sure we're between a Begin/End pair */
setAttrValueBit(attr_id);
uchar *data = imm->vertex_data + attr->offset;
// printf("%s %td %p\n", __FUNCTION__, data - imm->buffer_data, data);
data[0] = r;
data[1] = g;
data[2] = b;
}
void immAttr4ub(uint attr_id, uchar r, uchar g, uchar b, uchar a)
{
GPUVertAttr *attr = &imm->vertex_format.attrs[attr_id];
BLI_assert(attr_id < imm->vertex_format.attr_len);
BLI_assert(attr->comp_type == GPU_COMP_U8);
BLI_assert(attr->comp_len == 4);
BLI_assert(ELEM(attr->format, VertAttrType::UINT_8_8_8_8, VertAttrType::UNORM_8_8_8_8));
BLI_assert(imm->vertex_idx < imm->vertex_len);
BLI_assert(imm->prim_type != GPU_PRIM_NONE); /* make sure we're between a Begin/End pair */
setAttrValueBit(attr_id);
@@ -524,11 +487,6 @@ void immAttr4ub(uint attr_id, uchar r, uchar g, uchar b, uchar a)
data[3] = a;
}
void immAttr3ubv(uint attr_id, const uchar data[3])
{
immAttr3ub(attr_id, data[0], data[1], data[2]);
}
void immAttr4ubv(uint attr_id, const uchar data[4])
{
immAttr4ub(attr_id, data[0], data[1], data[2], data[3]);
@@ -560,7 +518,7 @@ static void immEndVertex() /* and move on to the next vertex */
#endif
uchar *data = imm->vertex_data + a->offset;
memcpy(data, data - imm->vertex_format.stride, a->size);
memcpy(data, data - imm->vertex_format.stride, to_bytesize(a->format));
/* TODO: consolidate copy of adjacent attributes */
}
}
@@ -595,12 +553,6 @@ void immVertex2i(uint attr_id, int x, int y)
immEndVertex();
}
void immVertex2s(uint attr_id, short x, short y)
{
immAttr2s(attr_id, x, y);
immEndVertex();
}
void immVertex2fv(uint attr_id, const float data[2])
{
immAttr2f(attr_id, data[0], data[1]);

View File

@@ -30,6 +30,228 @@
# include <stdio.h>
#endif
namespace blender::gpu {
/* Used to combine legacy enums into new vertex attribute type. */
static VertAttrType vertex_format_combine(GPUVertCompType component_type,
GPUVertFetchMode fetch_mode,
uint32_t component_len)
{
switch (component_type) {
case GPU_COMP_I8: {
switch (fetch_mode) {
case GPU_FETCH_INT_TO_FLOAT_UNIT:
switch (component_len) {
case 4:
return VertAttrType::SNORM_8_8_8_8;
}
break;
case GPU_FETCH_INT:
switch (component_len) {
case 4:
return VertAttrType::SINT_8_8_8_8;
}
break;
default:
break;
}
break;
}
case GPU_COMP_U8: {
switch (fetch_mode) {
case GPU_FETCH_INT_TO_FLOAT_UNIT:
switch (component_len) {
case 4:
return VertAttrType::UNORM_8_8_8_8;
}
break;
case GPU_FETCH_INT:
switch (component_len) {
case 4:
return VertAttrType::UINT_8_8_8_8;
}
break;
default:
break;
}
break;
}
case GPU_COMP_I16: {
switch (fetch_mode) {
case GPU_FETCH_INT_TO_FLOAT_UNIT:
switch (component_len) {
case 2:
return VertAttrType::SNORM_16_16;
case 4:
return VertAttrType::SNORM_16_16_16_16;
}
break;
case GPU_FETCH_INT:
switch (component_len) {
case 2:
return VertAttrType::SINT_16_16;
case 4:
return VertAttrType::SINT_16_16_16_16;
}
break;
default:
break;
}
break;
}
case GPU_COMP_U16: {
switch (fetch_mode) {
case GPU_FETCH_INT_TO_FLOAT_UNIT:
switch (component_len) {
case 2:
return VertAttrType::UNORM_16_16;
case 4:
return VertAttrType::UNORM_16_16_16_16;
}
break;
case GPU_FETCH_INT:
switch (component_len) {
case 2:
return VertAttrType::UINT_16_16;
case 4:
return VertAttrType::UINT_16_16_16_16;
}
break;
default:
break;
}
break;
}
case GPU_COMP_I32: {
switch (fetch_mode) {
case GPU_FETCH_INT:
switch (component_len) {
case 1:
return VertAttrType::SINT_32;
case 2:
return VertAttrType::SINT_32_32;
case 3:
return VertAttrType::SINT_32_32_32;
case 4:
return VertAttrType::SINT_32_32_32_32;
}
break;
case GPU_FETCH_INT_TO_FLOAT:
switch (component_len) {
case 1:
return VertAttrType::SINT_TO_FLT_32;
case 2:
return VertAttrType::SINT_TO_FLT_32_32;
case 3:
return VertAttrType::SINT_TO_FLT_32_32_32;
case 4:
return VertAttrType::SINT_TO_FLT_32_32_32_32;
}
break;
default:
break;
}
break;
}
case GPU_COMP_U32: {
switch (fetch_mode) {
case GPU_FETCH_INT:
switch (component_len) {
case 1:
return VertAttrType::UINT_32;
case 2:
return VertAttrType::UINT_32_32;
case 3:
return VertAttrType::UINT_32_32_32;
case 4:
return VertAttrType::UINT_32_32_32_32;
}
break;
default:
break;
}
break;
}
case GPU_COMP_F32: {
switch (fetch_mode) {
case GPU_FETCH_FLOAT:
switch (component_len) {
case 1:
return VertAttrType::SFLOAT_32;
case 2:
return VertAttrType::SFLOAT_32_32;
case 3:
return VertAttrType::SFLOAT_32_32_32;
case 4:
return VertAttrType::SFLOAT_32_32_32_32;
}
break;
default:
break;
}
break;
}
case GPU_COMP_I10: {
switch (fetch_mode) {
case GPU_FETCH_INT_TO_FLOAT_UNIT:
return VertAttrType::SNORM_10_10_10_2;
default:
break;
}
break;
}
case GPU_COMP_MAX:
break;
}
return VertAttrType::Invalid;
};
bool is_fetch_normalized(VertAttrType attr_type)
{
switch (attr_type) {
case VertAttrType::SNORM_8_8_8_8:
case VertAttrType::SNORM_16_16:
case VertAttrType::SNORM_16_16_16_16:
case VertAttrType::UNORM_8_8_8_8:
case VertAttrType::UNORM_16_16:
case VertAttrType::UNORM_16_16_16_16:
case VertAttrType::SNORM_10_10_10_2:
case VertAttrType::UNORM_10_10_10_2:
return true;
default:
return false;
}
};
bool is_fetch_int_to_float(VertAttrType attr_type)
{
switch (attr_type) {
case VertAttrType::SINT_TO_FLT_32:
case VertAttrType::SINT_TO_FLT_32_32:
case VertAttrType::SINT_TO_FLT_32_32_32:
case VertAttrType::SINT_TO_FLT_32_32_32_32:
return true;
default:
return false;
}
};
bool is_fetch_float(VertAttrType attr_type)
{
switch (attr_type) {
case VertAttrType::SFLOAT_32:
case VertAttrType::SFLOAT_32_32:
case VertAttrType::SFLOAT_32_32_32:
case VertAttrType::SFLOAT_32_32_32_32:
return true;
default:
return false;
}
};
} // namespace blender::gpu
using blender::StringRef;
using namespace blender::gpu;
using namespace blender::gpu::shader;
@@ -154,6 +376,8 @@ uint GPU_vertformat_attr_add(GPUVertFormat *format,
attr->size = attr_size(attr);
attr->offset = 0; /* offsets & stride are calculated later (during pack) */
attr->fetch_mode = fetch_mode;
attr->format = vertex_format_combine(comp_type, fetch_mode, comp_len);
BLI_assert(attr->format != blender::gpu::VertAttrType::Invalid);
return attr_id;
}

View File

@@ -18,3 +18,21 @@ void VertexFormat_pack(GPUVertFormat *format);
void VertexFormat_texture_buffer_pack(GPUVertFormat *format);
uint padding(uint offset, uint alignment);
uint vertex_buffer_size(const GPUVertFormat *format, uint vertex_len);
namespace blender::gpu {
bool is_fetch_normalized(VertAttrType attr_type);
bool is_fetch_int_to_float(VertAttrType attr_type);
bool is_fetch_float(VertAttrType attr_type);
inline int format_component_len(const VertAttrType format)
{
return format_component_len(DataFormat(int8_t(format)));
}
inline int to_bytesize(const VertAttrType format)
{
return to_bytesize(DataFormat(int8_t(format)));
}
} // namespace blender::gpu

View File

@@ -159,18 +159,13 @@ static void test_vertex_buffer_fetch_mode__GPU_COMP_U16__GPU_FETCH_INT_TO_FLOAT(
GPU_TEST(vertex_buffer_fetch_mode__GPU_COMP_U16__GPU_FETCH_INT_TO_FLOAT);
#endif
/* Legacy format. Uses software workaround. */
static void test_vertex_buffer_fetch_mode__GPU_COMP_I32__GPU_FETCH_INT_TO_FLOAT()
{
vertex_buffer_fetch_mode<GPU_COMP_I32, GPU_FETCH_INT_TO_FLOAT, int4>(int4(4, 5, 6, 1));
}
GPU_TEST(vertex_buffer_fetch_mode__GPU_COMP_I32__GPU_FETCH_INT_TO_FLOAT);
static void test_vertex_buffer_fetch_mode__GPU_COMP_U32__GPU_FETCH_INT_TO_FLOAT()
{
vertex_buffer_fetch_mode<GPU_COMP_U32, GPU_FETCH_INT_TO_FLOAT, uint4>(uint4(4, 5, 6, 1));
}
GPU_TEST(vertex_buffer_fetch_mode__GPU_COMP_U32__GPU_FETCH_INT_TO_FLOAT);
static void test_vertex_buffer_fetch_mode__GPU_COMP_F32__GPU_FETCH_FLOAT()
{
vertex_buffer_fetch_mode<GPU_COMP_F32, GPU_FETCH_FLOAT, float4>(float4(4, 5, 6, 1));

View File

@@ -87,7 +87,6 @@ defs_precalc = {
"immAttr3fv": {1: 3},
"immAttr4fv": {1: 4},
"immAttr3ubv": {1: 3},
"immAttr4ubv": {1: 4},
"immUniform2fv": {1: 2},