summaryrefslogtreecommitdiffstats
path: root/src/glsl
diff options
context:
space:
mode:
authorDave Airlie <[email protected]>2016-01-17 14:23:35 +1000
committerDave Airlie <[email protected]>2016-01-18 15:02:34 +1000
commit119bef954379ebb35faf182b0b665becacddab76 (patch)
tree7b6fa82e138b639f6b748bb8e611c4a5a17f5b69 /src/glsl
parent9258d9f23daca39767a41abc47836991a5f189b4 (diff)
glsl: fix subroutine lowering reusing actual parmaters
One of the oglconform tests was crashing here, and it was due to not cloning the actual parameters before creating the new call. This makes a call clone function that does the right things to make sure we clone all the needed info, and points the callee at it. (It differs from ->clone due to this). this may fix https://bugs.freedesktop.org/show_bug.cgi?id=93722, I had this patch in my cts fixes tree, but hadn't had time to make sure I liked it. Cc: "11.0 11.1" <[email protected]> Signed-off-by: Dave Airlie <[email protected]> Reviewed-by: Timothy Arceri <[email protected]>
Diffstat (limited to 'src/glsl')
-rw-r--r--src/glsl/lower_subroutine.cpp24
1 files changed, 19 insertions, 5 deletions
diff --git a/src/glsl/lower_subroutine.cpp b/src/glsl/lower_subroutine.cpp
index a0df5e1df81..ac8ade13d99 100644
--- a/src/glsl/lower_subroutine.cpp
+++ b/src/glsl/lower_subroutine.cpp
@@ -44,6 +44,7 @@ public:
}
ir_visitor_status visit_leave(ir_call *);
+ ir_call *call_clone(ir_call *call, ir_function_signature *callee);
bool progress;
struct _mesa_glsl_parse_state *state;
};
@@ -58,6 +59,23 @@ lower_subroutine(exec_list *instructions, struct _mesa_glsl_parse_state *state)
return v.progress;
}
+ir_call *
+lower_subroutine_visitor::call_clone(ir_call *call, ir_function_signature *callee)
+{
+ void *mem_ctx = ralloc_parent(call);
+ ir_dereference_variable *new_return_ref = NULL;
+ if (call->return_deref != NULL)
+ new_return_ref = call->return_deref->clone(mem_ctx, NULL);
+
+ exec_list new_parameters;
+
+ foreach_in_list(ir_instruction, ir, &call->actual_parameters) {
+ new_parameters.push_tail(ir->clone(mem_ctx, NULL));
+ }
+
+ return new(mem_ctx) ir_call(callee, new_return_ref, &new_parameters);
+}
+
ir_visitor_status
lower_subroutine_visitor::visit_leave(ir_call *ir)
{
@@ -66,7 +84,6 @@ lower_subroutine_visitor::visit_leave(ir_call *ir)
void *mem_ctx = ralloc_parent(ir);
ir_if *last_branch = NULL;
- ir_dereference_variable *return_deref = ir->return_deref;
for (int s = this->state->num_subroutines - 1; s >= 0; s--) {
ir_rvalue *var;
@@ -92,14 +109,11 @@ lower_subroutine_visitor::visit_leave(ir_call *ir)
fn->exact_matching_signature(this->state,
&ir->actual_parameters);
- ir_call *new_call = new(mem_ctx) ir_call(sub_sig, return_deref, &ir->actual_parameters);
+ ir_call *new_call = call_clone(ir, sub_sig);
if (!last_branch)
last_branch = if_tree(equal(subr_to_int(var), lc), new_call);
else
last_branch = if_tree(equal(subr_to_int(var), lc), new_call, last_branch);
-
- if (return_deref && s > 0)
- return_deref = return_deref->clone(mem_ctx, NULL);
}
if (last_branch)
ir->insert_before(last_branch);