[Mesa-stable] [PATCH 1/2] glsl: Fix lowering of direct assignment in lower_clip_distance.
Paul Berry
stereotype441 at gmail.com
Fri Nov 22 13:30:09 PST 2013
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 at freedesktop.org>
Cc: "9.2" <mesa-stable at lists.freedesktop.org>
Cc: "10.0" <mesa-stable at lists.freedesktop.org>
---
src/glsl/lower_clip_distance.cpp | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/src/glsl/lower_clip_distance.cpp b/src/glsl/lower_clip_distance.cpp
index 682c8fd..04fa6d4 100644
--- a/src/glsl/lower_clip_distance.cpp
+++ b/src/glsl/lower_clip_distance.cpp
@@ -381,6 +381,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);
+
if (this->is_clip_distance_vec8(ir->lhs) ||
this->is_clip_distance_vec8(ir->rhs)) {
/* LHS or RHS of the assignment is the entire 1D gl_ClipDistance array
--
1.8.4.2
More information about the mesa-stable
mailing list