Commit: 2a53e0f4376d8c3f91fb404893b2d4040efe3046 Author: Miguel Pozo Date: Thu Nov 24 13:29:53 2022 +0100 Branches: blender-v3.4-release https://developer.blender.org/rB2a53e0f4376d8c3f91fb404893b2d4040efe3046
FIX T102076: Add support for int attributes to draw manager. Add int attributes interpolation support for GPU subdivision. Ensure cached shaders match their intended defines. (The defines parameter was ignored when requesting a second time the same shader with different defines) De-duplicate the extract_attr_init code for subdiv/non-subdiv. Reviewed By: jbakker, fclem Maniphest Tasks: T102076 Differential Revision: https://developer.blender.org/D16420 =================================================================== M source/blender/draw/intern/draw_cache_impl_subdivision.cc M source/blender/draw/intern/draw_subdivision.h M source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_attributes.cc M source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_pos_nor.cc M source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_sculpt_data.cc M source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_tan.cc M source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_weights.cc M source/blender/draw/intern/shaders/common_subdiv_custom_data_interp_comp.glsl M source/blender/gpu/GPU_vertex_format.h =================================================================== diff --git a/source/blender/draw/intern/draw_cache_impl_subdivision.cc b/source/blender/draw/intern/draw_cache_impl_subdivision.cc index 6a9e6c126e9..b99075b1edd 100644 --- a/source/blender/draw/intern/draw_cache_impl_subdivision.cc +++ b/source/blender/draw/intern/draw_cache_impl_subdivision.cc @@ -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 @@ Diff output truncated at 10240 characters. @@ _______________________________________________ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org List details, subscription details or unsubscribe: https://lists.blender.org/mailman/listinfo/bf-blender-cvs