From 76cc18518fc8b0b4fa11fda153e7d9b3899ed112 Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Sat, 13 Nov 2021 14:15:04 +0200 Subject: [PATCH] Fix a name conflict in certain inlining scenarios --- source/glsl/optimize.cpp | 8 ++- tests/glsl/generated_name_reuse.glsl | 89 ++++++++++++++++++++++++++++ 2 files changed, 95 insertions(+), 2 deletions(-) create mode 100644 tests/glsl/generated_name_reuse.glsl diff --git a/source/glsl/optimize.cpp b/source/glsl/optimize.cpp index 96a75d60..64ceddcc 100644 --- a/source/glsl/optimize.cpp +++ b/source/glsl/optimize.cpp @@ -114,9 +114,13 @@ string InlineContentInjector::apply(Stage &stage, FunctionDeclaration &target_fu source_func = call.declaration->definition; /* Populate referenced_names from the target function so we can rename - variables from the inlined function that would conflict. */ + variables from the inlined function that would conflict. Only consider + names which declared in blocks linearly related to the target block. */ pass = REFERENCED; - target_func.visit(*this); + tgt_blk.visit(*this); + for(const Block *b=&tgt_blk; b; b=b->parent) + for(const auto &kvp: b->variables) + referenced_names.insert(kvp.first); /* Inline and rename passes must be interleaved so used variable names are known when inlining the return statement. */ diff --git a/tests/glsl/generated_name_reuse.glsl b/tests/glsl/generated_name_reuse.glsl new file mode 100644 index 00000000..f4fc22d2 --- /dev/null +++ b/tests/glsl/generated_name_reuse.glsl @@ -0,0 +1,89 @@ +uniform LightParameters +{ + vec3 ambient; + vec4 light_position; +}; +uniform mat4 model; +uniform mat4 view_proj; +layout(constant_id=auto) const bool use_light = true; +layout(constant_id=auto) const bool use_ambient = true; + +#pragma MSP stage(vertex) +layout(location=0) in vec4 vertex; +layout(location=1) in vec3 normal; +void main() +{ + out vec4 world_vertex = model*vertex; + out vec3 world_normal = mat3(model)*normal; + gl_Position = view_proj*world_vertex; +} + +#pragma MSP stage(fragment) +layout(location=0) out vec4 frag_color; +vec4 get_light_position() +{ + return light_position; +} +float get_light_intensity(vec3 dir) +{ + return max(dot(dir, normalize(world_normal)), 0.0); +} +vec3 get_ambient() +{ + return ambient; +} +void main() +{ + vec3 color = vec3(0.0); + if(use_light) + { + vec4 light_pos = get_light_position(); + vec3 dir = normalize(light_pos.xyz-world_vertex.xyz*light_pos.w); + color += get_light_intensity(dir); + } + if(use_ambient) + color += get_ambient(); + frag_color = vec4(color, 1.0); +} + +// Compile mode: module + +/* Expected output: vertex +layout(location=0) uniform mat4 model; +layout(location=4) uniform mat4 view_proj; +layout(location=0) in vec4 vertex; +layout(location=1) in vec3 normal; +layout(location=0) out vec4 world_vertex; +layout(location=1) out vec3 world_normal; +void main() +{ + world_vertex = model*vertex; + world_normal = mat3(model[0].xyz, model[1].xyz, model[2].xyz)*normal; + gl_Position = view_proj*world_vertex; +} +*/ + +/* Expected output: fragment +layout(binding=57) uniform LightParameters +{ + vec3 ambient; + vec4 light_position; +}; +layout(constant_id=669465692) const bool use_light = true; +layout(constant_id=1735871552) const bool use_ambient = true; +layout(location=0) out vec4 frag_color; +layout(location=1) in vec3 world_normal; +layout(location=0) in vec4 world_vertex; +void main() +{ + vec3 color = vec3(0.0); + if(use_light) + { + vec4 _return = light_position; + color += max(dot(normalize(_return.xyz-world_vertex.xyz*_return.w), normalize(world_normal)), 0.0); + } + if(use_ambient) + color += ambient; + frag_color = vec4(color, 1.0); +} +*/ -- 2.43.0