summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Berry <stereotype441@gmail.com>2013-11-22 12:37:22 -0800
committerCarl Worth <cworth@cworth.org>2013-11-26 16:39:13 -0800
commit6a022c8b03caea0d356b6e5cc186f1efc42ecca1 (patch)
tree6053cd1c8aa902604756d84206c8dee5b00fe3d4
parentdfaf5de46052ea5f8408d3c7fcac5f8393d6fc8e (diff)
glsl: Fix lowering of direct assignment in lower_clip_distance.
In commit 065da16 (glsl: Convert lower_clip_distance_visitor to be an ir_rvalue_visitor), we failed to notice that since lower_clip_distance_visitor overrides visit_leave(ir_assignment *), ir_rvalue_visitor::visit_leave(ir_assignment *) wasn't getting called. As a result, clip distance dereferences appearing directly on the right hand side of an assignment (not in a subexpression) weren't getting properly lowered. This caused an ir_dereference_variable node to be left in the IR that referred to the old gl_ClipDistance variable. However, since the lowering pass replaces gl_ClipDistance with gl_ClipDistanceMESA, this turned into a dangling pointer when the IR got reparented. Prior to the introduction of geometry shaders, this bug was unlikely to arise, because (a) reading from gl_ClipDistance[i] in the fragment shader was rare, and (b) when it happened, it was likely that it would either appear in a subexpression, or be hoisted into a subexpression by tree grafting. However, in a geometry shader, we're likely to see a statement like this, which would trigger the bug: gl_ClipDistance[i] = gl_in[j].gl_ClipDistance[i]; This patch causes lower_clip_distance_visitor::visit_leave(ir_assignment *) to call the base class visitor, so that the right hand side of the assignment is properly lowered. Fixes piglit test: - spec/glsl-1.50/execution/geometry/clip-distance-itemized-copy Cc: Ian Romanick <idr@freedesktop.org> Cc: "9.2" <mesa-stable@lists.freedesktop.org> Cc: "10.0" <mesa-stable@lists.freedesktop.org> Reviewed-by: Eric Anholt <eric@anholt.net> Reviewed-by: Ian Romanick <ian.d.romanick@intel.com> (cherry picked from commit 9dfcb05fa649ee7a573eab3d16851ebd4cb96010)
-rw-r--r--src/glsl/lower_clip_distance.cpp5
1 files changed, 5 insertions, 0 deletions
diff --git a/src/glsl/lower_clip_distance.cpp b/src/glsl/lower_clip_distance.cpp
index d6cf944388..50cd315528 100644
--- a/src/glsl/lower_clip_distance.cpp
+++ b/src/glsl/lower_clip_distance.cpp
@@ -251,6 +251,11 @@ lower_clip_distance_visitor::fix_lhs(ir_assignment *ir)
ir_visitor_status
lower_clip_distance_visitor::visit_leave(ir_assignment *ir)
{
+ /* First invoke the base class visitor. This causes handle_rvalue() to be
+ * called on ir->rhs and ir->condition.
+ */
+ ir_rvalue_visitor::visit_leave(ir);
+
ir_dereference_variable *lhs_var = ir->lhs->as_dereference_variable();
ir_dereference_variable *rhs_var = ir->rhs->as_dereference_variable();
if ((lhs_var && lhs_var->var == this->old_clip_distance_var)