Skip to content

Commit 7c1e34f

Browse files
GLSL: Fix array of input patch variables.
Hoist out the hack to make array sizes unsized to a place where we can differentiate patch variables from control point variables.
1 parent 363035c commit 7c1e34f

8 files changed

Lines changed: 59 additions & 15 deletions

File tree

reference/opt/shaders/desktop-only/tesc/basic.desktop.sso.tesc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ layout(vertices = 1) out;
44
in gl_PerVertex
55
{
66
vec4 gl_Position;
7-
} gl_in[gl_MaxPatchVertices];
7+
} gl_in[];
88

99
out gl_PerVertex
1010
{

reference/opt/shaders/desktop-only/tese/triangle.desktop.sso.tese

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ layout(triangles, cw, fractional_even_spacing) in;
44
in gl_PerVertex
55
{
66
vec4 gl_Position;
7-
} gl_in[gl_MaxPatchVertices];
7+
} gl_in[];
88

99
out gl_PerVertex
1010
{
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
#version 450
2+
layout(quads, ccw, equal_spacing) in;
3+
4+
layout(location = 0) patch in float P[4];
5+
6+
void main()
7+
{
8+
gl_Position = vec4(P[0], P[1], P[2], P[3]);
9+
}
10+

reference/shaders/desktop-only/tesc/basic.desktop.sso.tesc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ layout(vertices = 1) out;
44
in gl_PerVertex
55
{
66
vec4 gl_Position;
7-
} gl_in[gl_MaxPatchVertices];
7+
} gl_in[];
88

99
out gl_PerVertex
1010
{

reference/shaders/desktop-only/tese/triangle.desktop.sso.tese

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ layout(triangles, cw, fractional_even_spacing) in;
44
in gl_PerVertex
55
{
66
vec4 gl_Position;
7-
} gl_in[gl_MaxPatchVertices];
7+
} gl_in[];
88

99
out gl_PerVertex
1010
{
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
#version 450
2+
layout(quads, ccw, equal_spacing) in;
3+
4+
layout(location = 0) patch in float P[4];
5+
6+
void main()
7+
{
8+
gl_Position = vec4(P[0], P[1], P[2], P[3]);
9+
}
10+
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
#version 450
2+
3+
layout(quads) in;
4+
layout(location = 0) patch in float P[4];
5+
6+
void main()
7+
{
8+
gl_Position = vec4(P[0], P[1], P[2], P[3]);
9+
}

spirv_glsl.cpp

Lines changed: 26 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2104,9 +2104,32 @@ void CompilerGLSL::emit_interface_block(const SPIRVariable &var)
21042104
else
21052105
{
21062106
add_resource_name(var.self);
2107+
2108+
// Tessellation control and evaluation shaders must have either gl_MaxPatchVertices or unsized arrays for input arrays.
2109+
// Opt for unsized as it's the more "correct" variant to use.
2110+
bool control_point_input_array = type.storage == StorageClassInput &&
2111+
!type.array.empty() && !has_decoration(var.self, DecorationPatch) &&
2112+
(get_entry_point().model == ExecutionModelTessellationControl ||
2113+
get_entry_point().model == ExecutionModelTessellationEvaluation);
2114+
2115+
uint32_t old_array_size = 0;
2116+
bool old_array_size_literal = true;
2117+
2118+
if (control_point_input_array)
2119+
{
2120+
swap(type.array.back(), old_array_size);
2121+
swap(type.array_size_literal.back(), old_array_size_literal);
2122+
}
2123+
21072124
statement(layout_for_variable(var), to_qualifiers_glsl(var.self),
21082125
variable_decl(type, to_name(var.self), var.self), ";");
21092126

2127+
if (control_point_input_array)
2128+
{
2129+
swap(type.array.back(), old_array_size);
2130+
swap(type.array_size_literal.back(), old_array_size_literal);
2131+
}
2132+
21102133
// If a StorageClassOutput variable has an initializer, we need to initialize it in main().
21112134
if (var.storage == StorageClassOutput && var.initializer)
21122135
{
@@ -2478,7 +2501,6 @@ void CompilerGLSL::emit_declared_builtin_block(StorageClass storage, ExecutionMo
24782501
if (emitted_builtins.get(BuiltInCullDistance))
24792502
statement("float gl_CullDistance[", cull_distance_size, "];");
24802503

2481-
bool tessellation = model == ExecutionModelTessellationEvaluation || model == ExecutionModelTessellationControl;
24822504
if (builtin_array)
24832505
{
24842506
// Make sure the array has a supported name in the code.
@@ -2490,7 +2512,7 @@ void CompilerGLSL::emit_declared_builtin_block(StorageClass storage, ExecutionMo
24902512
if (model == ExecutionModelTessellationControl && storage == StorageClassOutput)
24912513
end_scope_decl(join(to_name(block_var->self), "[", get_entry_point().output_vertices, "]"));
24922514
else
2493-
end_scope_decl(join(to_name(block_var->self), tessellation ? "[gl_MaxPatchVertices]" : "[]"));
2515+
end_scope_decl(join(to_name(block_var->self), "[]"));
24942516
}
24952517
else
24962518
end_scope_decl();
@@ -10794,14 +10816,6 @@ string CompilerGLSL::to_array_size(const SPIRType &type, uint32_t index)
1079410816
{
1079510817
assert(type.array.size() == type.array_size_literal.size());
1079610818

10797-
// Tessellation control and evaluation shaders must have either gl_MaxPatchVertices or unsized arrays for input arrays.
10798-
// Opt for unsized as it's the more "correct" variant to use.
10799-
if (type.storage == StorageClassInput &&
10800-
(get_entry_point().model == ExecutionModelTessellationControl ||
10801-
get_entry_point().model == ExecutionModelTessellationEvaluation) &&
10802-
index == uint32_t(type.array.size() - 1))
10803-
return "";
10804-
1080510819
auto &size = type.array[index];
1080610820
if (!type.array_size_literal[index])
1080710821
return to_expression(size);
@@ -12795,13 +12809,14 @@ void CompilerGLSL::unroll_array_from_complex_load(uint32_t target_id, uint32_t s
1279512809
auto builtin = BuiltIn(get_decoration(var->self, DecorationBuiltIn));
1279612810
bool is_builtin = is_builtin_variable(*var) && (builtin == BuiltInPointSize || builtin == BuiltInPosition);
1279712811
bool is_tess = is_tessellation_shader();
12812+
bool is_patch = has_decoration(var->self, DecorationPatch);
1279812813

1279912814
// Tessellation input arrays are special in that they are unsized, so we cannot directly copy from it.
1280012815
// We must unroll the array load.
1280112816
// For builtins, we couldn't catch this case normally,
1280212817
// because this is resolved in the OpAccessChain in most cases.
1280312818
// If we load the entire array, we have no choice but to unroll here.
12804-
if (is_builtin || is_tess)
12819+
if (!is_patch && (is_builtin || is_tess))
1280512820
{
1280612821
auto new_expr = join("_", target_id, "_unrolled");
1280712822
statement(variable_decl(type, new_expr, target_id), ";");

0 commit comments

Comments
 (0)