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)
This commit is contained in:
Clément Foucault
2022-01-19 11:48:39 +01:00
parent 952a4fa456
commit 8a23d91a50
6 changed files with 60 additions and 30 deletions

View File

@@ -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());

View File

@@ -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;
}

View File

@@ -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;

View File

@@ -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;

View File

@@ -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");

View File

@@ -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")