]> git.tdb.fi Git - libs/gl.git/commitdiff
Fix a name conflict in certain inlining scenarios
authorMikko Rasa <tdb@tdb.fi>
Sat, 13 Nov 2021 12:15:04 +0000 (14:15 +0200)
committerMikko Rasa <tdb@tdb.fi>
Sat, 13 Nov 2021 12:15:04 +0000 (14:15 +0200)
source/glsl/optimize.cpp
tests/glsl/generated_name_reuse.glsl [new file with mode: 0644]

index 96a75d603d6db5bdaaae35de41bbe16fb938cecf..64ceddcc16ba92968c2f0d517f0230bb8e739598 100644 (file)
@@ -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 (file)
index 0000000..f4fc22d
--- /dev/null
@@ -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);
+}
+*/