Merge branch 'blender-v3.4-release'

This commit is contained in:
Miguel Pozo 2022-11-24 13:36:48 +01:00
commit 1b7b996e16
9 changed files with 157 additions and 123 deletions

View File

@ -70,6 +70,7 @@ enum {
SHADER_BUFFER_TRIS_MULTIPLE_MATERIALS,
SHADER_BUFFER_NORMALS_ACCUMULATE,
SHADER_BUFFER_NORMALS_FINALIZE,
SHADER_BUFFER_CUSTOM_NORMALS_FINALIZE,
SHADER_PATCH_EVALUATION,
SHADER_PATCH_EVALUATION_FVAR,
SHADER_PATCH_EVALUATION_FACE_DOTS,
@ -88,6 +89,10 @@ enum {
static GPUShader *g_subdiv_shaders[NUM_SHADERS];
#define SHADER_CUSTOM_DATA_INTERP_MAX_DIMENSIONS 4
static GPUShader
*g_subdiv_custom_data_shaders[SHADER_CUSTOM_DATA_INTERP_MAX_DIMENSIONS][GPU_COMP_MAX];
static const char *get_shader_code(int shader_type)
{
switch (shader_type) {
@ -208,7 +213,12 @@ static GPUShader *get_patch_evaluation_shader(int shader_type)
const char *compute_code = get_shader_code(shader_type);
const char *defines = nullptr;
if (shader_type == SHADER_PATCH_EVALUATION_FVAR) {
if (shader_type == SHADER_PATCH_EVALUATION) {
defines =
"#define OSD_PATCH_BASIS_GLSL\n"
"#define OPENSUBDIV_GLSL_COMPUTE_USE_1ST_DERIVATIVES\n";
}
else if (shader_type == SHADER_PATCH_EVALUATION_FVAR) {
defines =
"#define OSD_PATCH_BASIS_GLSL\n"
"#define OPENSUBDIV_GLSL_COMPUTE_USE_1ST_DERIVATIVES\n"
@ -234,9 +244,7 @@ static GPUShader *get_patch_evaluation_shader(int shader_type)
"#define ORCO_EVALUATION\n";
}
else {
defines =
"#define OSD_PATCH_BASIS_GLSL\n"
"#define OPENSUBDIV_GLSL_COMPUTE_USE_1ST_DERIVATIVES\n";
BLI_assert_unreachable();
}
/* Merge OpenSubdiv library code with our own library code. */
@ -258,7 +266,7 @@ static GPUShader *get_patch_evaluation_shader(int shader_type)
return g_subdiv_shaders[shader_type];
}
static GPUShader *get_subdiv_shader(int shader_type, const char *defines)
static GPUShader *get_subdiv_shader(int shader_type)
{
if (ELEM(shader_type,
SHADER_PATCH_EVALUATION,
@ -267,14 +275,86 @@ static GPUShader *get_subdiv_shader(int shader_type, const char *defines)
SHADER_PATCH_EVALUATION_ORCO)) {
return get_patch_evaluation_shader(shader_type);
}
BLI_assert(!ELEM(shader_type,
SHADER_COMP_CUSTOM_DATA_INTERP_1D,
SHADER_COMP_CUSTOM_DATA_INTERP_2D,
SHADER_COMP_CUSTOM_DATA_INTERP_3D,
SHADER_COMP_CUSTOM_DATA_INTERP_4D));
if (g_subdiv_shaders[shader_type] == nullptr) {
const char *compute_code = get_shader_code(shader_type);
const char *defines = nullptr;
if (ELEM(shader_type,
SHADER_BUFFER_LINES,
SHADER_BUFFER_LNOR,
SHADER_BUFFER_TRIS,
SHADER_BUFFER_UV_STRETCH_AREA)) {
defines = "#define SUBDIV_POLYGON_OFFSET\n";
}
else if (shader_type == SHADER_BUFFER_TRIS_MULTIPLE_MATERIALS) {
defines =
"#define SUBDIV_POLYGON_OFFSET\n"
"#define SINGLE_MATERIAL\n";
}
else if (shader_type == SHADER_BUFFER_LINES_LOOSE) {
defines = "#define LINES_LOOSE\n";
}
else if (shader_type == SHADER_BUFFER_EDGE_FAC) {
/* No separate shader for the AMD driver case as we assume that the GPU will not change
* during the execution of the program. */
defines = GPU_crappy_amd_driver() ? "#define GPU_AMD_DRIVER_BYTE_BUG\n" : nullptr;
}
else if (shader_type == SHADER_BUFFER_CUSTOM_NORMALS_FINALIZE) {
defines = "#define CUSTOM_NORMALS\n";
}
g_subdiv_shaders[shader_type] = GPU_shader_create_compute(
compute_code, datatoc_common_subdiv_lib_glsl, defines, get_shader_name(shader_type));
}
return g_subdiv_shaders[shader_type];
}
static GPUShader *get_subdiv_custom_data_shader(int comp_type, int dimensions)
{
BLI_assert(dimensions >= 1 && dimensions <= SHADER_CUSTOM_DATA_INTERP_MAX_DIMENSIONS);
if (comp_type == GPU_COMP_U16) {
BLI_assert(dimensions == 4);
}
GPUShader *&shader = g_subdiv_custom_data_shaders[dimensions - 1][comp_type];
if (shader == nullptr) {
const char *compute_code = get_shader_code(SHADER_COMP_CUSTOM_DATA_INTERP_1D + dimensions - 1);
int shader_type = SHADER_COMP_CUSTOM_DATA_INTERP_1D + dimensions - 1;
std::string defines = "#define SUBDIV_POLYGON_OFFSET\n";
defines += "#define DIMENSIONS " + std::to_string(dimensions) + "\n";
switch (comp_type) {
case GPU_COMP_U16:
defines += "#define GPU_COMP_U16\n";
break;
case GPU_COMP_I32:
defines += "#define GPU_COMP_I32\n";
break;
case GPU_COMP_F32:
/* float is the default */
break;
default:
BLI_assert_unreachable();
break;
}
shader = GPU_shader_create_compute(compute_code,
datatoc_common_subdiv_lib_glsl,
defines.c_str(),
get_shader_name(shader_type));
}
return shader;
}
/* -------------------------------------------------------------------- */
/** Vertex formats used for data transfer from OpenSubdiv, and for data processing on our side.
* \{ */
@ -1475,49 +1555,16 @@ void draw_subdiv_extract_uvs(const DRWSubdivCache *cache,
void draw_subdiv_interp_custom_data(const DRWSubdivCache *cache,
GPUVertBuf *src_data,
GPUVertBuf *dst_data,
int comp_type, /*GPUVertCompType*/
int dimensions,
int dst_offset,
bool compress_to_u16)
int dst_offset)
{
GPUShader *shader = nullptr;
if (!draw_subdiv_cache_need_polygon_data(cache)) {
/* Happens on meshes with only loose geometry. */
return;
}
if (dimensions == 1) {
shader = get_subdiv_shader(SHADER_COMP_CUSTOM_DATA_INTERP_1D,
"#define SUBDIV_POLYGON_OFFSET\n"
"#define DIMENSIONS 1\n");
}
else if (dimensions == 2) {
shader = get_subdiv_shader(SHADER_COMP_CUSTOM_DATA_INTERP_2D,
"#define SUBDIV_POLYGON_OFFSET\n"
"#define DIMENSIONS 2\n");
}
else if (dimensions == 3) {
shader = get_subdiv_shader(SHADER_COMP_CUSTOM_DATA_INTERP_3D,
"#define SUBDIV_POLYGON_OFFSET\n"
"#define DIMENSIONS 3\n");
}
else if (dimensions == 4) {
if (compress_to_u16) {
shader = get_subdiv_shader(SHADER_COMP_CUSTOM_DATA_INTERP_4D,
"#define SUBDIV_POLYGON_OFFSET\n"
"#define DIMENSIONS 4\n"
"#define GPU_FETCH_U16_TO_FLOAT\n");
}
else {
shader = get_subdiv_shader(SHADER_COMP_CUSTOM_DATA_INTERP_4D,
"#define SUBDIV_POLYGON_OFFSET\n"
"#define DIMENSIONS 4\n");
}
}
else {
/* Crash if dimensions are not supported. */
}
GPUShader *shader = get_subdiv_custom_data_shader(comp_type, dimensions);
GPU_shader_bind(shader);
int binding_point = 0;
@ -1545,7 +1592,7 @@ void draw_subdiv_build_sculpt_data_buffer(const DRWSubdivCache *cache,
GPUVertBuf *face_set_vbo,
GPUVertBuf *sculpt_data)
{
GPUShader *shader = get_subdiv_shader(SHADER_BUFFER_SCULPT_DATA, nullptr);
GPUShader *shader = get_subdiv_shader(SHADER_BUFFER_SCULPT_DATA);
GPU_shader_bind(shader);
/* Mask VBO is always at binding point 0. */
@ -1574,7 +1621,7 @@ void draw_subdiv_accumulate_normals(const DRWSubdivCache *cache,
GPUVertBuf *vertex_loop_map,
GPUVertBuf *vertex_normals)
{
GPUShader *shader = get_subdiv_shader(SHADER_BUFFER_NORMALS_ACCUMULATE, nullptr);
GPUShader *shader = get_subdiv_shader(SHADER_BUFFER_NORMALS_ACCUMULATE);
GPU_shader_bind(shader);
int binding_point = 0;
@ -1602,7 +1649,7 @@ void draw_subdiv_finalize_normals(const DRWSubdivCache *cache,
GPUVertBuf *subdiv_loop_subdiv_vert_index,
GPUVertBuf *pos_nor)
{
GPUShader *shader = get_subdiv_shader(SHADER_BUFFER_NORMALS_FINALIZE, nullptr);
GPUShader *shader = get_subdiv_shader(SHADER_BUFFER_NORMALS_FINALIZE);
GPU_shader_bind(shader);
int binding_point = 0;
@ -1626,7 +1673,7 @@ void draw_subdiv_finalize_custom_normals(const DRWSubdivCache *cache,
GPUVertBuf *src_custom_normals,
GPUVertBuf *pos_nor)
{
GPUShader *shader = get_subdiv_shader(SHADER_BUFFER_NORMALS_FINALIZE, "#define CUSTOM_NORMALS");
GPUShader *shader = get_subdiv_shader(SHADER_BUFFER_CUSTOM_NORMALS_FINALIZE);
GPU_shader_bind(shader);
int binding_point = 0;
@ -1658,15 +1705,8 @@ void draw_subdiv_build_tris_buffer(const DRWSubdivCache *cache,
const bool do_single_material = material_count <= 1;
const char *defines = "#define SUBDIV_POLYGON_OFFSET\n";
if (do_single_material) {
defines =
"#define SUBDIV_POLYGON_OFFSET\n"
"#define SINGLE_MATERIAL\n";
}
GPUShader *shader = get_subdiv_shader(
do_single_material ? SHADER_BUFFER_TRIS : SHADER_BUFFER_TRIS_MULTIPLE_MATERIALS, defines);
do_single_material ? SHADER_BUFFER_TRIS : SHADER_BUFFER_TRIS_MULTIPLE_MATERIALS);
GPU_shader_bind(shader);
int binding_point = 0;
@ -1768,7 +1808,7 @@ void draw_subdiv_build_fdots_buffers(const DRWSubdivCache *cache,
void draw_subdiv_build_lines_buffer(const DRWSubdivCache *cache, GPUIndexBuf *lines_indices)
{
GPUShader *shader = get_subdiv_shader(SHADER_BUFFER_LINES, "#define SUBDIV_POLYGON_OFFSET\n");
GPUShader *shader = get_subdiv_shader(SHADER_BUFFER_LINES);
GPU_shader_bind(shader);
int binding_point = 0;
@ -1792,7 +1832,7 @@ void draw_subdiv_build_lines_loose_buffer(const DRWSubdivCache *cache,
GPUVertBuf *lines_flags,
uint num_loose_edges)
{
GPUShader *shader = get_subdiv_shader(SHADER_BUFFER_LINES_LOOSE, "#define LINES_LOOSE\n");
GPUShader *shader = get_subdiv_shader(SHADER_BUFFER_LINES_LOOSE);
GPU_shader_bind(shader);
GPU_indexbuf_bind_as_ssbo(lines_indices, 3);
@ -1812,10 +1852,7 @@ void draw_subdiv_build_edge_fac_buffer(const DRWSubdivCache *cache,
GPUVertBuf *edge_idx,
GPUVertBuf *edge_fac)
{
/* No separate shader for the AMD driver case as we assume that the GPU will not change during
* the execution of the program. */
const char *defines = GPU_crappy_amd_driver() ? "#define GPU_AMD_DRIVER_BYTE_BUG\n" : nullptr;
GPUShader *shader = get_subdiv_shader(SHADER_BUFFER_EDGE_FAC, defines);
GPUShader *shader = get_subdiv_shader(SHADER_BUFFER_EDGE_FAC);
GPU_shader_bind(shader);
int binding_point = 0;
@ -1842,7 +1879,7 @@ void draw_subdiv_build_lnor_buffer(const DRWSubdivCache *cache,
return;
}
GPUShader *shader = get_subdiv_shader(SHADER_BUFFER_LNOR, "#define SUBDIV_POLYGON_OFFSET\n");
GPUShader *shader = get_subdiv_shader(SHADER_BUFFER_LNOR);
GPU_shader_bind(shader);
int binding_point = 0;
@ -1870,8 +1907,7 @@ void draw_subdiv_build_edituv_stretch_area_buffer(const DRWSubdivCache *cache,
GPUVertBuf *coarse_data,
GPUVertBuf *subdiv_data)
{
GPUShader *shader = get_subdiv_shader(SHADER_BUFFER_UV_STRETCH_AREA,
"#define SUBDIV_POLYGON_OFFSET\n");
GPUShader *shader = get_subdiv_shader(SHADER_BUFFER_UV_STRETCH_AREA);
GPU_shader_bind(shader);
int binding_point = 0;
@ -1899,7 +1935,7 @@ void draw_subdiv_build_edituv_stretch_angle_buffer(const DRWSubdivCache *cache,
int uvs_offset,
GPUVertBuf *stretch_angles)
{
GPUShader *shader = get_subdiv_shader(SHADER_BUFFER_UV_STRETCH_ANGLE, nullptr);
GPUShader *shader = get_subdiv_shader(SHADER_BUFFER_UV_STRETCH_ANGLE);
GPU_shader_bind(shader);
int binding_point = 0;

View File

@ -248,9 +248,9 @@ void draw_subdiv_extract_pos_nor(const DRWSubdivCache *cache,
void draw_subdiv_interp_custom_data(const DRWSubdivCache *cache,
struct GPUVertBuf *src_data,
struct GPUVertBuf *dst_data,
int comp_type, /*GPUVertCompType*/
int dimensions,
int dst_offset,
bool compress_to_u16);
int dst_offset);
void draw_subdiv_extract_uvs(const DRWSubdivCache *cache,
struct GPUVertBuf *uvs,

View File

@ -114,9 +114,9 @@ static uint gpu_component_size_for_attribute_type(eCustomDataType type)
static GPUVertFetchMode get_fetch_mode_for_type(eCustomDataType type)
{
switch (type) {
case CD_PROP_INT8:
case CD_PROP_INT32:
return GPU_FETCH_INT_TO_FLOAT;
case CD_PROP_COLOR:
case CD_PROP_BYTE_COLOR:
return GPU_FETCH_INT_TO_FLOAT_UNIT;
default:
@ -127,10 +127,12 @@ static GPUVertFetchMode get_fetch_mode_for_type(eCustomDataType type)
static GPUVertCompType get_comp_type_for_type(eCustomDataType type)
{
switch (type) {
case CD_PROP_INT8:
case CD_PROP_INT32:
return GPU_COMP_I32;
case CD_PROP_COLOR:
case CD_PROP_BYTE_COLOR:
/* This should be u8,
* but u16 is required to store the color in linear space without precission loss */
return GPU_COMP_U16;
default:
return GPU_COMP_F32;
@ -279,16 +281,10 @@ static void extract_attr_generic(const MeshRenderData *mr,
}
}
static void extract_attr_init(
const MeshRenderData *mr, MeshBatchCache *cache, void *buf, void * /*tls_data*/, int index)
static void extract_attr(const MeshRenderData *mr,
GPUVertBuf *vbo,
const DRW_AttributeRequest &request)
{
const DRW_Attributes *attrs_used = &cache->attr_used;
const DRW_AttributeRequest &request = attrs_used->requests[index];
GPUVertBuf *vbo = static_cast<GPUVertBuf *>(buf);
init_vbo_for_attribute(*mr, vbo, request, false, uint32_t(mr->loop_len));
/* TODO(@kevindietrich): float3 is used for scalar attributes as the implicit conversion done by
* OpenGL to vec4 for a scalar `s` will produce a `vec4(s, 0, 0, 1)`. However, following the
* Blender convention, it should be `vec4(s, s, s, 1)`. This could be resolved using a similar
@ -298,10 +294,10 @@ static void extract_attr_init(
extract_attr_generic<bool, float3>(mr, vbo, request);
break;
case CD_PROP_INT8:
extract_attr_generic<int8_t, float3>(mr, vbo, request);
extract_attr_generic<int8_t, int3>(mr, vbo, request);
break;
case CD_PROP_INT32:
extract_attr_generic<int32_t, float3>(mr, vbo, request);
extract_attr_generic<int32_t, int3>(mr, vbo, request);
break;
case CD_PROP_FLOAT:
extract_attr_generic<float, float3>(mr, vbo, request);
@ -313,7 +309,7 @@ static void extract_attr_init(
extract_attr_generic<float3>(mr, vbo, request);
break;
case CD_PROP_COLOR:
extract_attr_generic<MPropCol, gpuMeshCol>(mr, vbo, request);
extract_attr_generic<float4>(mr, vbo, request);
break;
case CD_PROP_BYTE_COLOR:
extract_attr_generic<ColorGeometry4b, gpuMeshCol>(mr, vbo, request);
@ -323,6 +319,19 @@ static void extract_attr_init(
}
}
static void extract_attr_init(
const MeshRenderData *mr, MeshBatchCache *cache, void *buf, void * /*tls_data*/, int index)
{
const DRW_Attributes *attrs_used = &cache->attr_used;
const DRW_AttributeRequest &request = attrs_used->requests[index];
GPUVertBuf *vbo = static_cast<GPUVertBuf *>(buf);
init_vbo_for_attribute(*mr, vbo, request, false, uint32_t(mr->loop_len));
extract_attr(mr, vbo, request);
}
static void extract_attr_init_subdiv(const DRWSubdivCache *subdiv_cache,
const MeshRenderData *mr,
MeshBatchCache *cache,
@ -335,55 +344,26 @@ static void extract_attr_init_subdiv(const DRWSubdivCache *subdiv_cache,
Mesh *coarse_mesh = subdiv_cache->mesh;
GPUVertCompType comp_type = get_comp_type_for_type(request.cd_type);
GPUVertFetchMode fetch_mode = get_fetch_mode_for_type(request.cd_type);
const uint32_t dimensions = gpu_component_size_for_attribute_type(request.cd_type);
/* Prepare VBO for coarse data. The compute shader only expects floats. */
GPUVertBuf *src_data = GPU_vertbuf_calloc();
GPUVertFormat coarse_format = {0};
GPU_vertformat_attr_add(&coarse_format, "data", GPU_COMP_F32, dimensions, GPU_FETCH_FLOAT);
GPU_vertformat_attr_add(&coarse_format, "data", comp_type, dimensions, fetch_mode);
GPU_vertbuf_init_with_format_ex(src_data, &coarse_format, GPU_USAGE_STATIC);
GPU_vertbuf_data_alloc(src_data, uint32_t(coarse_mesh->totloop));
switch (request.cd_type) {
case CD_PROP_BOOL:
extract_attr_generic<bool, float3>(mr, src_data, request);
break;
case CD_PROP_INT8:
extract_attr_generic<int8_t, float3>(mr, src_data, request);
break;
case CD_PROP_INT32:
extract_attr_generic<int32_t, float3>(mr, src_data, request);
break;
case CD_PROP_FLOAT:
extract_attr_generic<float, float3>(mr, src_data, request);
break;
case CD_PROP_FLOAT2:
extract_attr_generic<float2>(mr, src_data, request);
break;
case CD_PROP_FLOAT3:
extract_attr_generic<float3>(mr, src_data, request);
break;
case CD_PROP_COLOR:
extract_attr_generic<MPropCol, gpuMeshCol>(mr, src_data, request);
break;
case CD_PROP_BYTE_COLOR:
extract_attr_generic<ColorGeometry4b, gpuMeshCol>(mr, src_data, request);
break;
default:
BLI_assert_unreachable();
}
extract_attr(mr, src_data, request);
GPUVertBuf *dst_buffer = static_cast<GPUVertBuf *>(buffer);
init_vbo_for_attribute(*mr, dst_buffer, request, true, subdiv_cache->num_subdiv_loops);
/* Ensure data is uploaded properly. */
GPU_vertbuf_tag_dirty(src_data);
draw_subdiv_interp_custom_data(subdiv_cache,
src_data,
dst_buffer,
int(dimensions),
0,
ELEM(request.cd_type, CD_PROP_COLOR, CD_PROP_BYTE_COLOR));
draw_subdiv_interp_custom_data(
subdiv_cache, src_data, dst_buffer, comp_type, int(dimensions), 0);
GPU_vertbuf_discard(src_data);
}

View File

@ -251,7 +251,7 @@ static void extract_pos_nor_init_subdiv(const DRWSubdivCache *subdiv_cache,
dst_custom_normals, get_custom_normals_format(), subdiv_cache->num_subdiv_loops);
draw_subdiv_interp_custom_data(
subdiv_cache, src_custom_normals, dst_custom_normals, 3, 0, false);
subdiv_cache, src_custom_normals, dst_custom_normals, GPU_COMP_F32, 3, 0);
draw_subdiv_finalize_custom_normals(subdiv_cache, dst_custom_normals, vbo);

View File

@ -156,7 +156,7 @@ static void extract_sculpt_data_init_subdiv(const DRWSubdivCache *subdiv_cache,
GPU_vertbuf_init_build_on_device(
subdiv_mask_vbo, &mask_format, subdiv_cache->num_subdiv_loops);
draw_subdiv_interp_custom_data(subdiv_cache, mask_vbo, subdiv_mask_vbo, 1, 0, false);
draw_subdiv_interp_custom_data(subdiv_cache, mask_vbo, subdiv_mask_vbo, GPU_COMP_F32, 1, 0);
}
/* Then, gather face sets. */

View File

@ -303,7 +303,8 @@ static void extract_tan_init_subdiv(const DRWSubdivCache *subdiv_cache,
GPU_vertbuf_tag_dirty(coarse_vbo);
/* Include stride in offset. */
const int dst_offset = int(subdiv_cache->num_subdiv_loops) * 4 * pack_layer_index++;
draw_subdiv_interp_custom_data(subdiv_cache, coarse_vbo, dst_buffer, 4, dst_offset, false);
draw_subdiv_interp_custom_data(
subdiv_cache, coarse_vbo, dst_buffer, GPU_COMP_F32, 4, dst_offset);
}
if (use_orco_tan) {
float(*tan_data)[4] = (float(*)[4])GPU_vertbuf_get_data(coarse_vbo);
@ -318,7 +319,8 @@ static void extract_tan_init_subdiv(const DRWSubdivCache *subdiv_cache,
GPU_vertbuf_tag_dirty(coarse_vbo);
/* Include stride in offset. */
const int dst_offset = int(subdiv_cache->num_subdiv_loops) * 4 * pack_layer_index++;
draw_subdiv_interp_custom_data(subdiv_cache, coarse_vbo, dst_buffer, 4, dst_offset, false);
draw_subdiv_interp_custom_data(
subdiv_cache, coarse_vbo, dst_buffer, GPU_COMP_F32, 4, dst_offset);
}
CustomData_free(&loop_data, mr->loop_len);

View File

@ -187,7 +187,7 @@ static void extract_weights_init_subdiv(const DRWSubdivCache *subdiv_cache,
}
}
draw_subdiv_interp_custom_data(subdiv_cache, coarse_weights, vbo, 1, 0, false);
draw_subdiv_interp_custom_data(subdiv_cache, coarse_weights, vbo, GPU_COMP_F32, 1, 0);
GPU_vertbuf_discard(coarse_weights);
}

View File

@ -3,8 +3,10 @@
layout(std430, binding = 1) readonly restrict buffer sourceBuffer
{
#ifdef GPU_FETCH_U16_TO_FLOAT
#if defined(GPU_COMP_U16)
uint src_data[];
#elif defined(GPU_COMP_I32)
int src_data[];
#else
float src_data[];
#endif
@ -27,8 +29,10 @@ layout(std430, binding = 4) readonly restrict buffer extraCoarseFaceData
layout(std430, binding = 5) writeonly restrict buffer destBuffer
{
#ifdef GPU_FETCH_U16_TO_FLOAT
#if defined(GPU_COMP_U16)
uint dst_data[];
#elif defined(GPU_COMP_I32)
int dst_data[];
#else
float dst_data[];
#endif
@ -48,7 +52,7 @@ void clear(inout Vertex v)
Vertex read_vertex(uint index)
{
Vertex result;
#ifdef GPU_FETCH_U16_TO_FLOAT
#if defined(GPU_COMP_U16)
uint base_index = index * 2;
if (DIMENSIONS == 4) {
uint xy = src_data[base_index];
@ -68,6 +72,11 @@ Vertex read_vertex(uint index)
/* This case is unsupported for now. */
clear(result);
}
#elif defined(GPU_COMP_I32)
uint base_index = index * DIMENSIONS;
for (int i = 0; i < DIMENSIONS; i++) {
result.vertex_data[i] = float(src_data[base_index + i]);
}
#else
uint base_index = index * DIMENSIONS;
for (int i = 0; i < DIMENSIONS; i++) {
@ -79,7 +88,7 @@ Vertex read_vertex(uint index)
void write_vertex(uint index, Vertex v)
{
#ifdef GPU_FETCH_U16_TO_FLOAT
#if defined(GPU_COMP_U16)
uint base_index = dst_offset + index * 2;
if (DIMENSIONS == 4) {
uint x = uint(v.vertex_data[0] * 65535.0);
@ -97,6 +106,11 @@ void write_vertex(uint index, Vertex v)
/* This case is unsupported for now. */
dst_data[base_index] = 0;
}
#elif defined(GPU_COMP_I32)
uint base_index = dst_offset + index * DIMENSIONS;
for (int i = 0; i < DIMENSIONS; i++) {
dst_data[base_index + i] = int(round(v.vertex_data[i]));
}
#else
uint base_index = dst_offset + index * DIMENSIONS;
for (int i = 0; i < DIMENSIONS; i++) {

View File

@ -37,6 +37,8 @@ typedef enum {
GPU_COMP_I10,
/* Warning! adjust GPUVertAttr if changing. */
GPU_COMP_MAX
} GPUVertCompType;
typedef enum {