diff options
author | Clément Foucault <foucault.clem@gmail.com> | 2022-01-19 13:48:39 +0300 |
---|---|---|
committer | Clément Foucault <foucault.clem@gmail.com> | 2022-01-19 13:59:57 +0300 |
commit | 8a23d91a50923c62be5ed4ce38955dfc60de6e70 (patch) | |
tree | d12eccac344796d0162d5941a643c5b2ff89a10d /source/blender/gpu | |
parent | 952a4fa4561986da467c16a04b1b23530df26b8d (diff) |
GPUShaderCreateInfo: Rework geometry shader layout support
This merge the description into one struct only that can be more easily
copied during `finalize()`.
The in and out layout parameters are better named and extended with the
invocation count (with fallback support)
Diffstat (limited to 'source/blender/gpu')
-rw-r--r-- | source/blender/gpu/intern/gpu_shader_create_info.cc | 1 | ||||
-rw-r--r-- | source/blender/gpu/intern/gpu_shader_create_info.hh | 38 | ||||
-rw-r--r-- | source/blender/gpu/opengl/gl_backend.cc | 3 | ||||
-rw-r--r-- | source/blender/gpu/opengl/gl_context.hh | 1 | ||||
-rw-r--r-- | source/blender/gpu/opengl/gl_shader.cc | 45 | ||||
-rw-r--r-- | source/blender/gpu/shaders/infos/gpu_shader_gpencil_stroke_info.hh | 2 |
6 files changed, 60 insertions, 30 deletions
diff --git a/source/blender/gpu/intern/gpu_shader_create_info.cc b/source/blender/gpu/intern/gpu_shader_create_info.cc index 3d4f27d2278..439eb735c95 100644 --- a/source/blender/gpu/intern/gpu_shader_create_info.cc +++ b/source/blender/gpu/intern/gpu_shader_create_info.cc @@ -85,6 +85,7 @@ void ShaderCreateInfo::finalize() if (!info.geometry_source_.is_empty()) { BLI_assert(geometry_source_.is_empty()); geometry_source_ = info.geometry_source_; + geometry_layout_ = info.geometry_layout_; } if (!info.fragment_source_.is_empty()) { BLI_assert(fragment_source_.is_empty()); diff --git a/source/blender/gpu/intern/gpu_shader_create_info.hh b/source/blender/gpu/intern/gpu_shader_create_info.hh index b4bd58630d5..a1ebdb0ec51 100644 --- a/source/blender/gpu/intern/gpu_shader_create_info.hh +++ b/source/blender/gpu/intern/gpu_shader_create_info.hh @@ -149,7 +149,7 @@ enum class Interpolation { }; /** Input layout for geometry shader. */ -enum class InputLayout { +enum class PrimitiveIn { POINTS = 0, LINES, LINES_ADJACENCY, @@ -158,7 +158,7 @@ enum class InputLayout { }; /** Output layout for geometry shader. */ -enum class OutputLayout { +enum class PrimitiveOut { POINTS = 0, LINE_STRIP, TRIANGLE_STRIP, @@ -233,16 +233,14 @@ struct ShaderCreateInfo { }; Vector<VertIn> vertex_inputs_; - struct GeomIn { - InputLayout layout; + struct GeometryStageLayout { + PrimitiveIn primitive_in; + int invocations; + PrimitiveOut primitive_out; + /** Set to -1 by default to check if used. */ + int max_vertices = -1; }; - GeomIn geom_in_; - - struct GeomOut { - OutputLayout layout; - int max_vertices; - }; - GeomOut geom_out_; + GeometryStageLayout geometry_layout_; struct FragOut { int index; @@ -350,11 +348,21 @@ struct ShaderCreateInfo { return *(Self *)this; } - Self &geometry_layout(InputLayout layout_in, OutputLayout layout_out, int max_vertices) + /** + * IMPORTANT: invocations count is only used if GL_ARB_gpu_shader5 is supported. On + * implementations that do not supports it, the max_vertices will be be multiplied by + * invocations. Your shader needs to account for this fact. Use `#ifdef GPU_ARB_gpu_shader5` + * and make a code path that does not rely on gl_InvocationID. + */ + Self &geometry_layout(PrimitiveIn prim_in, + PrimitiveOut prim_out, + int max_vertices, + int invocations = -1) { - geom_in_.layout = layout_in; - geom_out_.layout = layout_out; - geom_out_.max_vertices = max_vertices; + geometry_layout_.primitive_in = prim_in; + geometry_layout_.primitive_out = prim_out; + geometry_layout_.max_vertices = max_vertices; + geometry_layout_.invocations = invocations; return *(Self *)this; } diff --git a/source/blender/gpu/opengl/gl_backend.cc b/source/blender/gpu/opengl/gl_backend.cc index 33574da9f58..1a445ebd7eb 100644 --- a/source/blender/gpu/opengl/gl_backend.cc +++ b/source/blender/gpu/opengl/gl_backend.cc @@ -246,6 +246,7 @@ static void detect_workarounds() GLContext::debug_layer_support = false; GLContext::direct_state_access_support = false; GLContext::fixed_restart_index_support = false; + GLContext::geometry_shader_invocations = false; GLContext::multi_bind_support = false; GLContext::multi_draw_indirect_support = false; GLContext::shader_draw_parameters_support = false; @@ -435,6 +436,7 @@ bool GLContext::copy_image_support = false; bool GLContext::debug_layer_support = false; bool GLContext::direct_state_access_support = false; bool GLContext::explicit_location_support = false; +bool GLContext::geometry_shader_invocations = false; bool GLContext::fixed_restart_index_support = false; bool GLContext::multi_bind_support = false; bool GLContext::multi_draw_indirect_support = false; @@ -494,6 +496,7 @@ void GLBackend::capabilities_init() GLContext::debug_layer_support = GLEW_VERSION_4_3 || GLEW_KHR_debug || GLEW_ARB_debug_output; GLContext::direct_state_access_support = GLEW_ARB_direct_state_access; GLContext::explicit_location_support = GLEW_VERSION_4_3; + GLContext::geometry_shader_invocations = GLEW_ARB_gpu_shader5; GLContext::fixed_restart_index_support = GLEW_ARB_ES3_compatibility; GLContext::multi_bind_support = GLEW_ARB_multi_bind; GLContext::multi_draw_indirect_support = GLEW_ARB_multi_draw_indirect; diff --git a/source/blender/gpu/opengl/gl_context.hh b/source/blender/gpu/opengl/gl_context.hh index eb365382d53..dd22418972b 100644 --- a/source/blender/gpu/opengl/gl_context.hh +++ b/source/blender/gpu/opengl/gl_context.hh @@ -70,6 +70,7 @@ class GLContext : public Context { static bool debug_layer_support; static bool direct_state_access_support; static bool explicit_location_support; + static bool geometry_shader_invocations; static bool fixed_restart_index_support; static bool multi_bind_support; static bool multi_draw_indirect_support; diff --git a/source/blender/gpu/opengl/gl_shader.cc b/source/blender/gpu/opengl/gl_shader.cc index 9af5aeb3582..cec85abae6f 100644 --- a/source/blender/gpu/opengl/gl_shader.cc +++ b/source/blender/gpu/opengl/gl_shader.cc @@ -127,32 +127,32 @@ static const char *to_string(const Type &type) } } -static const char *to_string(const InputLayout &layout) +static const char *to_string(const PrimitiveIn &layout) { switch (layout) { - case InputLayout::POINTS: + case PrimitiveIn::POINTS: return "points"; - case InputLayout::LINES: + case PrimitiveIn::LINES: return "lines"; - case InputLayout::LINES_ADJACENCY: + case PrimitiveIn::LINES_ADJACENCY: return "lines_adjacency"; - case InputLayout::TRIANGLES: + case PrimitiveIn::TRIANGLES: return "triangles"; - case InputLayout::TRIANGLES_ADJACENCY: + case PrimitiveIn::TRIANGLES_ADJACENCY: return "triangles_adjacency"; default: return "unknown"; } } -static const char *to_string(const OutputLayout &layout) +static const char *to_string(const PrimitiveOut &layout) { switch (layout) { - case OutputLayout::POINTS: + case PrimitiveOut::POINTS: return "points"; - case OutputLayout::LINE_STRIP: + case PrimitiveOut::LINE_STRIP: return "line_strip"; - case OutputLayout::TRIANGLE_STRIP: + case PrimitiveOut::TRIANGLE_STRIP: return "triangle_strip"; default: return "unknown"; @@ -470,11 +470,24 @@ std::string GLShader::fragment_interface_declare(const ShaderCreateInfo &info) c std::string GLShader::geometry_layout_declare(const ShaderCreateInfo &info) const { + int max_verts = info.geometry_layout_.max_vertices; + int invocations = info.geometry_layout_.invocations; + + if (GLContext::geometry_shader_invocations == false && invocations != -1) { + max_verts *= invocations; + invocations = -1; + } + std::stringstream ss; - ss << "\n/* Layout. */\n"; - ss << "layout(" << to_string(info.geom_in_.layout) << ") in;\n"; - ss << "layout(" << to_string(info.geom_out_.layout) - << ", max_vertices = " << info.geom_out_.max_vertices << ") out;\n"; + ss << "\n/* Geometry Layout. */\n"; + ss << "layout(" << to_string(info.geometry_layout_.primitive_in); + if (invocations != -1) { + ss << ", invocations = " << invocations; + } + ss << ") in;\n"; + + ss << "layout(" << to_string(info.geometry_layout_.primitive_out) + << ", max_vertices = " << max_verts << ") out;\n"; ss << "\n"; return ss.str(); } @@ -531,6 +544,10 @@ static char *glsl_patch_default_get() STR_CONCAT(patch, slen, "#extension GL_ARB_shader_draw_parameters : enable\n"); STR_CONCAT(patch, slen, "#define GPU_ARB_shader_draw_parameters\n"); } + if (GLContext::geometry_shader_invocations) { + STR_CONCAT(patch, slen, "#extension GL_ARB_gpu_shader5 : enable\n"); + STR_CONCAT(patch, slen, "#define GPU_ARB_gpu_shader5\n"); + } if (GLContext::texture_cube_map_array_support) { STR_CONCAT(patch, slen, "#extension GL_ARB_texture_cube_map_array : enable\n"); STR_CONCAT(patch, slen, "#define GPU_ARB_texture_cube_map_array\n"); diff --git a/source/blender/gpu/shaders/infos/gpu_shader_gpencil_stroke_info.hh b/source/blender/gpu/shaders/infos/gpu_shader_gpencil_stroke_info.hh index 5c8410baf04..c337c399f59 100644 --- a/source/blender/gpu/shaders/infos/gpu_shader_gpencil_stroke_info.hh +++ b/source/blender/gpu/shaders/infos/gpu_shader_gpencil_stroke_info.hh @@ -35,7 +35,7 @@ GPU_SHADER_CREATE_INFO(gpu_shader_gpencil_stroke) .vertex_in(1, Type::VEC3, "pos") .vertex_in(2, Type::FLOAT, "thickness") .vertex_out(gpencil_stroke_vert_iface) - .geometry_layout(InputLayout::LINES_ADJACENCY, OutputLayout::TRIANGLE_STRIP, 13) + .geometry_layout(PrimitiveIn::LINES_ADJACENCY, PrimitiveOut::TRIANGLE_STRIP, 13) .geometry_out(gpencil_stroke_geom_iface) .fragment_out(0, Type::VEC4, "fragColor") |