]> git.tdb.fi Git - libs/gl.git/commitdiff
Only remove load IDs of variables actually assigned in a loop
authorMikko Rasa <tdb@tdb.fi>
Sun, 10 Oct 2021 08:54:24 +0000 (11:54 +0300)
committerMikko Rasa <tdb@tdb.fi>
Sun, 10 Oct 2021 10:57:03 +0000 (13:57 +0300)
Some variables like function arguments are not pointers and can't be
loaded again.

source/glsl/reflect.cpp
source/glsl/reflect.h
source/glsl/spirv.cpp
tests/glsl/use_parameter_in_loop.glsl [new file with mode: 0644]

index 258244e88b4e2457b441a75bfe9ecbed24fcc2b8..cc2e3a0c8bc2c6570e30bb50decd35cd413b97f1 100644 (file)
@@ -380,6 +380,19 @@ void DependencyCollector::visit(FunctionDeclaration &func)
        }
 }
 
+
+set<VariableDeclaration *> AssignmentCollector::apply(Node &node)
+{
+       node.visit(*this);
+       return assigned_variables;
+}
+
+void AssignmentCollector::visit(Assignment &assign)
+{
+       if(VariableDeclaration *var = dynamic_cast<VariableDeclaration *>(assign.target.declaration))
+               assigned_variables.insert(var);
+}
+
 } // namespace SL
 } // namespace GL
 } // namespace Msp
index d48fbec156506f31fda79fd86aa676b8257a128d..5b4170a9c766e460d34da7157fe84f1d68dbbeec 100644 (file)
@@ -104,6 +104,18 @@ private:
        virtual void visit(FunctionDeclaration &);
 };
 
+class AssignmentCollector: private TraversingVisitor
+{
+private:
+       std::set<VariableDeclaration *> assigned_variables;
+
+public:
+       std::set<VariableDeclaration *> apply(Node &);
+
+private:
+       virtual void visit(Assignment &);
+};
+
 } // namespace SL
 } // namespace GL
 } // namespace Msp
index edbdf6359eeb8d751690f9e5d45923f9bac32fd9..16168a8cb8725671197bf39567d276992e6c5695 100644 (file)
@@ -1858,7 +1858,8 @@ void SpirVGenerator::visit(Iteration &iter)
        if(iter.init_statement)
                iter.init_statement->visit(*this);
 
-       variable_load_ids.clear();
+       for(VariableDeclaration *v: AssignmentCollector().apply(iter))
+               variable_load_ids.erase(v);
 
        Id header_id = next_id++;
        Id continue_id = next_id++;
diff --git a/tests/glsl/use_parameter_in_loop.glsl b/tests/glsl/use_parameter_in_loop.glsl
new file mode 100644 (file)
index 0000000..a0bbc5c
--- /dev/null
@@ -0,0 +1,67 @@
+uniform Lighting
+{
+       vec3 light_dir[3];
+};
+uniform mat4 model_matrix;
+uniform mat4 view_matrix;
+uniform mat4 proj_matrix;
+
+#pragma MSP stage(vertex)
+layout(location=0) in vec4 vertex;
+void main()
+{
+       out vec4 world_vertex = model_matrix*vertex;
+       vec3 eye_pos = inverse(view_matrix)[3].xyz;
+       out vec3 world_look_dir = normalize(world_vertex.xyz-eye_pos);
+       gl_Position = proj_matrix*view_matrix*world_vertex;
+}
+
+#pragma MSP stage(fragment)
+layout(location=0) out vec4 frag_color;
+float calculate_lighting(vec3 look_dir)
+{
+       float intensity = 0.0;
+       for(int i=0; i<3; ++i)
+               intensity += max(dot(look_dir, light_dir[i]), 0.0);
+       return intensity;
+}
+void main()
+{
+       float light_intensity = calculate_lighting(world_look_dir);
+       frag_color = vec4(vec3(light_intensity), 1.0);
+}
+
+/* Expected output: vertex
+layout(location=0) uniform mat4 model_matrix;
+layout(location=4) uniform mat4 view_matrix;
+layout(location=8) uniform mat4 proj_matrix;
+layout(location=0) in vec4 vertex;
+layout(location=0) out vec4 world_vertex;
+layout(location=1) out vec3 world_look_dir;
+void main()
+{
+       world_vertex = model_matrix*vertex;
+       world_look_dir = normalize(world_vertex.xyz-inverse(view_matrix)[3].xyz);
+       gl_Position = proj_matrix*view_matrix*world_vertex;
+}
+*/
+
+/* Expected output: fragment
+layout(binding=5) uniform Lighting
+{
+       vec3 light_dir[3];
+};
+layout(location=0) out vec4 frag_color;
+float calculate_lighting(vec3 look_dir)
+{
+       float intensity = 0.0;
+       for(int i = 0; i<3; ++i)
+               intensity += max(dot(look_dir, light_dir[i]), 0.0);
+       return intensity;
+}
+layout(location=1) in vec3 world_look_dir;
+void main()
+{
+       frag_color = vec4(vec3(calculate_lighting(world_look_dir)), 1.0);
+}
+*/