On 01/09/2012 01:36 PM, Eric Anholt wrote:
We were doing the kill of the updated channels, then adding our copy
to the list of available stuff to copy. But if the copy was updating
its own source channels, we didn't notice, breaking this code:
R0.xyzw = arg0 + arg1;
R0.xyzw = R0.wwwx;
gl_FragColor.xyzw = clamp(R0.xyzw, 0.0, 1.0);
Fixes piglit glsl-copy-propagation-self-2.
---
src/glsl/opt_copy_propagation_elements.cpp | 15 ++++++++++++++-
1 files changed, 14 insertions(+), 1 deletions(-)
diff --git a/src/glsl/opt_copy_propagation_elements.cpp
b/src/glsl/opt_copy_propagation_elements.cpp
index be446bc..ebfd4fd 100644
--- a/src/glsl/opt_copy_propagation_elements.cpp
+++ b/src/glsl/opt_copy_propagation_elements.cpp
@@ -461,7 +461,20 @@
ir_copy_propagation_elements_visitor::add_copy(ir_assignment *ir)
swizzle[i] = orig_swizzle[j++];
}
- entry = new(this->mem_ctx) acp_entry(lhs->var, rhs->var, ir->write_mask,
+ int write_mask = ir->write_mask;
+ if (lhs->var == rhs->var) {
+ /* If this is a copy from the variable to itself, then we need
+ * to be sure not to include the updated channels from this
+ * instruction in the set of new source channels to be
+ * copy-propagated from.
+ */
+ for (int i = 0; i< 4; i++) {
+ if (ir->write_mask& (1<< orig_swizzle[i]))
+ write_mask&= ~(1<< i);
+ }
+ }
+
+ entry = new(this->mem_ctx) acp_entry(lhs->var, rhs->var, write_mask,
swizzle);
this->acp->push_tail(entry);
}
Whoops. Yeah, that's definitely necessary.
Reviewed-by: Kenneth Graunke <kenn...@whitecape.org>
_______________________________________________
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/mesa-dev