From 16c02e4dc3c9a10df15d4ddca2afd29cf3be8d73 Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Thu, 11 Mar 2021 23:39:59 +0200 Subject: [PATCH] Avoid generating invalid interfaces in geometry shader Geometry inputs need an extra array dimension compared to vertex shader outputs, but multi-dimensional arrays currently can't be properly represented. --- source/glsl/generate.cpp | 13 +++- .../ignore_array_in_geometry_passthrough.glsl | 71 +++++++++++++++++++ 2 files changed, 82 insertions(+), 2 deletions(-) create mode 100644 tests/glsl/ignore_array_in_geometry_passthrough.glsl diff --git a/source/glsl/generate.cpp b/source/glsl/generate.cpp index 158bb4cc..01d34c63 100644 --- a/source/glsl/generate.cpp +++ b/source/glsl/generate.cpp @@ -1040,6 +1040,9 @@ VariableDeclaration *InterfaceGenerator::generate_interface(VariableDeclaration if(stage->content.variables.count(name)) return 0; + if(stage->type==Stage::GEOMETRY && !copy_block && var.interface=="out" && var.array) + return 0; + VariableDeclaration* iface_var = new VariableDeclaration; iface_var->sampling = var.sampling; iface_var->interface = iface; @@ -1137,8 +1140,14 @@ void InterfaceGenerator::visit(VariableReference &var) i = prev_vars.find(in_prefix+var.name); if(i!=prev_vars.end() && i->second->interface=="out") { - generate_interface(*i->second, "in", i->second->name); - var.name = i->second->name; + if(stage->type==Stage::GEOMETRY && i->second->array) + stage->diagnostics.push_back(Diagnostic(Diagnostic::WARN, var.source, var.line, + format("Can't access '%s' through automatic interface because it's an array", var.name))); + else + { + generate_interface(*i->second, "in", i->second->name); + var.name = i->second->name; + } return; } diff --git a/tests/glsl/ignore_array_in_geometry_passthrough.glsl b/tests/glsl/ignore_array_in_geometry_passthrough.glsl new file mode 100644 index 00000000..2b3eea26 --- /dev/null +++ b/tests/glsl/ignore_array_in_geometry_passthrough.glsl @@ -0,0 +1,71 @@ +uniform mat4 vp_matrix; +uniform sampler2D tex; + +#pragma MSP stage(vertex) +layout(location=0) in vec4 position; +layout(location=1) in vec2 texcoord; +layout(location=2) in vec4 instance_transform[3]; +void main() +{ + passthrough; + mat4 model_matrix = transpose(mat4(instance_transform[0], instance_transform[1], instance_transform[2], vec4(0.0, 0.0, 0.0, 1.0))); + gl_Position = vp_matrix*model_matrix*position; +} + +#pragma MSP stage(geometry) +layout(triangles) in; +layout(triangles, max_vertices=3) out; +void main() +{ + for(int i=0; i<3; ++i) + { + passthrough[i]; + EmitVertex(); + } +} + +#pragma MSP stage(fragment) +layout(location=0) out vec4 frag_color; +void main() +{ + frag_color = texture(tex, texcoord); +} + +/* Expected output: vertex +uniform mat4 vp_matrix; +layout(location=0) in vec4 position; +layout(location=1) in vec2 texcoord; +layout(location=2) in vec4 instance_transform[3]; +out vec2 _vs_out_texcoord; +void main() +{ + _vs_out_texcoord = texcoord; + gl_Position = vp_matrix*transpose(mat4(instance_transform[0], instance_transform[1], instance_transform[2], vec4(0.0, 0.0, 0.0, 1.0)))*position; +} +*/ + +/* Expected output: geometry +layout(triangles) in; +layout(triangles, max_vertices=3) out; +in vec2 _vs_out_texcoord[]; +out vec2 _gs_out_texcoord; +void main() +{ + for(int i = 0; i<3; ++i) + { + gl_Position = gl_in[i].gl_Position; + _gs_out_texcoord = _vs_out_texcoord[i]; + EmitVertex(); + } +} +*/ + +/* Expected output: fragment +uniform sampler2D tex; +layout(location=0) out vec4 frag_color; +in vec2 _gs_out_texcoord; +void main() +{ + frag_color = texture(tex, _gs_out_texcoord); +} +*/ -- 2.45.2