diff --git a/source/blender/draw/intern/draw_cache_impl_subdivision.cc b/source/blender/draw/intern/draw_cache_impl_subdivision.cc index 35c14f74db0..71215f4cff3 100644 --- a/source/blender/draw/intern/draw_cache_impl_subdivision.cc +++ b/source/blender/draw/intern/draw_cache_impl_subdivision.cc @@ -1571,12 +1571,10 @@ void draw_subdiv_build_edge_fac_buffer(const DRWSubdivCache &cache, GPUShader *shader = DRW_shader_subdiv_get(SubdivShaderType::BUFFER_EDGE_FAC); GPU_shader_bind(shader); - int binding_point = 0; - GPU_vertbuf_bind_as_ssbo(pos_nor, binding_point++); - GPU_vertbuf_bind_as_ssbo(edge_draw_flag, binding_point++); - GPU_vertbuf_bind_as_ssbo(poly_other_map, binding_point++); - GPU_vertbuf_bind_as_ssbo(edge_fac, binding_point++); - BLI_assert(binding_point <= MAX_GPU_SUBDIV_SSBOS); + GPU_vertbuf_bind_as_ssbo(pos_nor, EDGE_FAC_POS_NOR_BUF_SLOT); + GPU_vertbuf_bind_as_ssbo(edge_draw_flag, EDGE_FAC_EDGE_DRAW_FLAG_BUF_SLOT); + GPU_vertbuf_bind_as_ssbo(poly_other_map, EDGE_FAC_POLY_OTHER_MAP_BUF_SLOT); + GPU_vertbuf_bind_as_ssbo(edge_fac, EDGE_FAC_EDGE_FAC_BUF_SLOT); drw_subdiv_compute_dispatch(cache, shader, 0, 0, cache.num_subdiv_quads); diff --git a/source/blender/draw/intern/draw_shader.cc b/source/blender/draw/intern/draw_shader.cc index d2364eca48c..0a2a15643e3 100644 --- a/source/blender/draw/intern/draw_shader.cc +++ b/source/blender/draw/intern/draw_shader.cc @@ -136,6 +136,12 @@ static blender::StringRefNull get_subdiv_shader_info_name(SubdivShaderType shade case SubdivShaderType::BUFFER_TRIS_MULTIPLE_MATERIALS: return "subdiv_tris_multiple_materials"; + case SubdivShaderType::BUFFER_EDGE_FAC: + if (GPU_crappy_amd_driver()) { + return "subdiv_edge_fac_amd_legacy"; + } + return "subdiv_edge_fac"; + case SubdivShaderType::BUFFER_NORMALS_ACCUMULATE: return "subdiv_normals_accumulate"; @@ -348,6 +354,7 @@ GPUShader *DRW_shader_subdiv_get(SubdivShaderType shader_type) SubdivShaderType::BUFFER_LINES_LOOSE, SubdivShaderType::BUFFER_TRIS, SubdivShaderType::BUFFER_TRIS_MULTIPLE_MATERIALS, + SubdivShaderType::BUFFER_EDGE_FAC, SubdivShaderType::BUFFER_NORMALS_ACCUMULATE, SubdivShaderType::BUFFER_NORMALS_FINALIZE, SubdivShaderType::BUFFER_CUSTOM_NORMALS_FINALIZE, @@ -365,13 +372,6 @@ GPUShader *DRW_shader_subdiv_get(SubdivShaderType shader_type) if (ELEM(shader_type, SubdivShaderType::BUFFER_UV_STRETCH_AREA)) { defines = "#define SUBDIV_POLYGON_OFFSET\n"; } - else if (shader_type == SubdivShaderType::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. */ - if (GPU_crappy_amd_driver()) { - defines = "#define GPU_AMD_DRIVER_BYTE_BUG\n"; - } - } e_data.subdiv_sh[uint(shader_type)] = GPU_shader_create_compute( compute_code, datatoc_subdiv_lib_glsl, defines, get_subdiv_shader_name(shader_type)); diff --git a/source/blender/draw/intern/draw_subdiv_defines.hh b/source/blender/draw/intern/draw_subdiv_defines.hh index a719b2cc8d8..f35ed4835b0 100644 --- a/source/blender/draw/intern/draw_subdiv_defines.hh +++ b/source/blender/draw/intern/draw_subdiv_defines.hh @@ -27,6 +27,11 @@ #define TRIS_OUTPUT_TRIS_BUF_SLOT 2 #define TRIS_FACE_MAT_OFFSET 3 +#define EDGE_FAC_POS_NOR_BUF_SLOT 0 +#define EDGE_FAC_EDGE_DRAW_FLAG_BUF_SLOT 1 +#define EDGE_FAC_POLY_OTHER_MAP_BUF_SLOT 2 +#define EDGE_FAC_EDGE_FAC_BUF_SLOT 3 + #define NORMALS_ACCUMULATE_POS_NOR_BUF_SLOT 0 #define NORMALS_ACCUMULATE_FACE_ADJACENCY_OFFSETS_BUF_SLOT 1 #define NORMALS_ACCUMULATE_FACE_ADJACENCY_LISTS_BUF_SLOT 2 diff --git a/source/blender/draw/intern/shaders/CMakeLists.txt b/source/blender/draw/intern/shaders/CMakeLists.txt index a885aff99e2..7e07dab73ce 100644 --- a/source/blender/draw/intern/shaders/CMakeLists.txt +++ b/source/blender/draw/intern/shaders/CMakeLists.txt @@ -33,6 +33,7 @@ set(SRC_GLSL_COMP subdiv_ibo_lines_comp.glsl subdiv_ibo_tris_comp.glsl + subdiv_vbo_edge_fac_comp.glsl subdiv_normals_accumulate_comp.glsl subdiv_normals_finalize_comp.glsl subdiv_vbo_lnor_comp.glsl diff --git a/source/blender/draw/intern/shaders/subdiv_info.hh b/source/blender/draw/intern/shaders/subdiv_info.hh index 22bdd85eed8..1dcc47420e7 100644 --- a/source/blender/draw/intern/shaders/subdiv_info.hh +++ b/source/blender/draw/intern/shaders/subdiv_info.hh @@ -89,6 +89,33 @@ GPU_SHADER_CREATE_END() /** \} */ +/* -------------------------------------------------------------------- */ +/** \name Edge data for object mode wireframe + * \{ */ + +GPU_SHADER_CREATE_INFO(subdiv_edge_fac_base) +ADDITIONAL_INFO(subdiv_base) +STORAGE_BUF(EDGE_FAC_POS_NOR_BUF_SLOT, READ, PosNorLoop, pos_nor[]) +STORAGE_BUF(EDGE_FAC_EDGE_DRAW_FLAG_BUF_SLOT, READ, uint, input_edge_draw_flag[]) +STORAGE_BUF(EDGE_FAC_POLY_OTHER_MAP_BUF_SLOT, READ, int, input_poly_other_map[]) +COMPUTE_SOURCE("subdiv_vbo_edge_fac_comp.glsl") +GPU_SHADER_CREATE_END() + +GPU_SHADER_CREATE_INFO(subdiv_edge_fac) +DO_STATIC_COMPILATION() +STORAGE_BUF(EDGE_FAC_EDGE_FAC_BUF_SLOT, WRITE, uint, output_edge_fac[]) +ADDITIONAL_INFO(subdiv_edge_fac_base) +GPU_SHADER_CREATE_END() + +GPU_SHADER_CREATE_INFO(subdiv_edge_fac_amd_legacy) +DO_STATIC_COMPILATION() +DEFINE("GPU_AMD_DRIVER_BYTE_BUG") +STORAGE_BUF(EDGE_FAC_EDGE_FAC_BUF_SLOT, WRITE, float, output_edge_fac[]) +ADDITIONAL_INFO(subdiv_edge_fac_base) +GPU_SHADER_CREATE_END() + +/** \} */ + /* -------------------------------------------------------------------- */ /** \name Normals * \{ */ diff --git a/source/blender/draw/intern/shaders/subdiv_vbo_edge_fac_comp.glsl b/source/blender/draw/intern/shaders/subdiv_vbo_edge_fac_comp.glsl index a3f7568982d..7633444cf5f 100644 --- a/source/blender/draw/intern/shaders/subdiv_vbo_edge_fac_comp.glsl +++ b/source/blender/draw/intern/shaders/subdiv_vbo_edge_fac_comp.glsl @@ -2,31 +2,15 @@ * * SPDX-License-Identifier: GPL-2.0-or-later */ -/* To be compiled with subdiv_lib.glsl */ +/* Extract edge data for object mode wire frame. */ -layout(std430, binding = 0) readonly buffer inputVertexData -{ - PosNorLoop pos_nor[]; -}; +#include "subdiv_lib.glsl" -layout(std430, binding = 1) readonly buffer inputEdgeDrawFlag -{ - uint input_edge_draw_flag[]; -}; - -layout(std430, binding = 2) readonly buffer inputPolyOtherMap -{ - int input_poly_other_map[]; -}; - -layout(std430, binding = 3) writeonly buffer outputEdgeFactors -{ #ifdef GPU_AMD_DRIVER_BYTE_BUG - float output_edge_fac[]; +COMPUTE_SHADER_CREATE_INFO(subdiv_edge_fac_amd_legacy) #else - uint output_edge_fac[]; +COMPUTE_SHADER_CREATE_INFO(subdiv_edge_fac) #endif -}; void write_vec4(uint index, vec4 edge_facs) { @@ -69,10 +53,13 @@ float compute_line_factor(uint corner_index, vec3 face_normal) return 0.0; } - uint start_coner_index_other = quad_other * 4; - vec3 v0 = subdiv_get_vertex_pos(pos_nor[start_coner_index_other + 0]); - vec3 v1 = subdiv_get_vertex_pos(pos_nor[start_coner_index_other + 1]); - vec3 v2 = subdiv_get_vertex_pos(pos_nor[start_coner_index_other + 2]); + uint start_corner_index_other = quad_other * 4; + PosNorLoop pos_nor0 = pos_nor[start_corner_index_other + 0]; + PosNorLoop pos_nor1 = pos_nor[start_corner_index_other + 1]; + PosNorLoop pos_nor2 = pos_nor[start_corner_index_other + 2]; + vec3 v0 = subdiv_get_vertex_pos(pos_nor0); + vec3 v1 = subdiv_get_vertex_pos(pos_nor1); + vec3 v2 = subdiv_get_vertex_pos(pos_nor2); vec3 face_normal_other = normalize(cross(v1 - v0, v2 - v0)); return loop_edge_factor_get(face_normal, face_normal_other); @@ -82,7 +69,7 @@ void main() { /* We execute for each quad. */ uint quad_index = get_global_invocation_index(); - if (quad_index >= total_dispatch_size) { + if (quad_index >= shader_data.total_dispatch_size) { return; } @@ -90,9 +77,12 @@ void main() uint start_loop_index = quad_index * 4; /* First compute the face normal, we need it to compute the bihedral edge angle. */ - vec3 v0 = subdiv_get_vertex_pos(pos_nor[start_loop_index + 0]); - vec3 v1 = subdiv_get_vertex_pos(pos_nor[start_loop_index + 1]); - vec3 v2 = subdiv_get_vertex_pos(pos_nor[start_loop_index + 2]); + PosNorLoop pos_nor0 = pos_nor[start_loop_index + 0]; + PosNorLoop pos_nor1 = pos_nor[start_loop_index + 1]; + PosNorLoop pos_nor2 = pos_nor[start_loop_index + 2]; + vec3 v0 = subdiv_get_vertex_pos(pos_nor0); + vec3 v1 = subdiv_get_vertex_pos(pos_nor1); + vec3 v2 = subdiv_get_vertex_pos(pos_nor2); vec3 face_normal = normalize(cross(v1 - v0, v2 - v0)); vec4 edge_facs = vec4(0.0);