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:
@@ -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());
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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")
|
||||
|
||||
|
||||
Reference in New Issue
Block a user