assignment_target(false),
r_side_effects(false),
in_struct(false),
- composite_reference(false)
+ composite_reference(false),
+ in_loop(0)
{ }
bool UnusedVariableRemover::apply(Stage &s)
var_info.referenced = true;
if(!assignment_target)
{
+ bool loop_external = false;
for(vector<AssignmentInfo *>::const_iterator i=var_info.assignments.begin(); i!=var_info.assignments.end(); ++i)
{
bool covered = true;
else
covered = ((*i)->target.chain[j]==target.chain[j]);
}
+
if(covered)
+ {
(*i)->used_by.push_back(&node);
+ if((*i)->in_loop<in_loop)
+ loop_external = true;
+ }
}
+
+ if(loop_external)
+ loop_ext_refs.push_back(&node);
}
}
AssignmentInfo &assign_info = assignments.back();
assign_info.node = &node;
assign_info.target = target;
+ assign_info.in_loop = in_loop;
/* An assignment to the target hides any assignments to the same target or
its subfields. */
void UnusedVariableRemover::visit(Iteration &iter)
{
BlockVariableMap saved_vars = variables;
- TraversingVisitor::visit(iter);
+ vector<Node *> saved_refs;
+ swap(loop_ext_refs, saved_refs);
+ {
+ SetForScope<unsigned> set_loop(in_loop, in_loop+1);
+ TraversingVisitor::visit(iter);
+ }
+ swap(loop_ext_refs, saved_refs);
+
+ /* Visit the external references of the loop again to record assignments
+ done in the loop as used. */
+ for(vector<Node *>::const_iterator i=saved_refs.begin(); i!=saved_refs.end(); ++i)
+ (*i)->visit(*this);
/* Merge assignments from the iteration, without clearing previous state.
Further analysis is needed to determine which parts of the iteration body
Node *node;
Assignment::Target target;
std::vector<Node *> used_by;
+ unsigned in_loop;
AssignmentInfo(): node(0) { }
};
bool r_side_effects;
bool in_struct;
bool composite_reference;
+ unsigned in_loop;
+ std::vector<Node *> loop_ext_refs;
Assignment::Target r_reference;
std::set<Node *> unused_nodes;
--- /dev/null
+uniform Params
+{
+ float start_height;
+ float max_height;
+ float min_height;
+ float step_size;
+};
+
+#pragma MSP stage(vertex)
+layout(location=0) in vec4 position;
+void main()
+{
+ gl_Position = position;
+ out vec3 dir = vec3(position.xy, 1.0);
+}
+
+#pragma MSP stage(fragment)
+layout(location=0) out vec4 frag_color;
+void main()
+{
+ vec3 ndir = normalize(dir);
+ vec3 pos = vec3(0.0, 0.0, start_height);
+ float luminance = 0.0;
+ float extinction = 0.0;
+ while(true)
+ {
+ if(pos.z<min_height || pos.z>max_height)
+ break;
+
+ float density = exp(pos.z/-1000.0);
+ luminance += density*exp(-extinction);
+
+ extinction += density*step_size;
+ pos += ndir*step_size;
+ }
+
+ frag_color = vec4(vec3(luminance), 1.0);
+}
+
+/* Expected output: vertex
+layout(location=0) in vec4 position;
+layout(location=0) out vec3 dir;
+void main()
+{
+ gl_Position = position;
+ dir = vec3(position.xy, 1.0);
+}
+*/
+
+/* Expected output: fragment
+layout(binding=80) uniform Params
+{
+ float start_height;
+ float max_height;
+ float min_height;
+ float step_size;
+};
+layout(location=0) out vec4 frag_color;
+layout(location=0) in vec3 dir;
+void main()
+{
+ vec3 ndir = normalize(dir);
+ vec3 pos = vec3(0.0, 0.0, start_height);
+ float luminance = 0.0;
+ float extinction = 0.0;
+ while(true)
+ {
+ if(pos.z<min_height || pos.z>max_height)
+ break;
+ float density = exp(pos.z/-1000.0);
+ luminance += density*exp(-extinction);
+ extinction += density*step_size;
+ pos += ndir*step_size;
+ }
+ frag_color = vec4(vec3(luminance), 1.0);
+}
+*/