summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEric Anholt <[email protected]>2012-10-15 17:51:59 -0700
committerEric Anholt <[email protected]>2012-10-17 12:24:00 -0700
commit338fd85e624883996bf9072ca710f2d04e3c59dd (patch)
tree2aa60fadc5d7f11940c1a9b03d6393ea7dc8269e
parentaf911b2819e5175008c67e6939d88ec28cda69d1 (diff)
i965/vs: Trim the swizzle of the scratch write temporary.
This fixes confusion by the upcoming live variable analysis which saw e.g. use of temp.w when only temp.xyz were initialized in the basic block, and concluded that temp.w must have come from outside of the block (even though it was never initialized anywhere). Reviewed-by: Kenneth Graunke <[email protected]>
-rw-r--r--src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp17
1 files changed, 16 insertions, 1 deletions
diff --git a/src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp b/src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp
index 310f3470dd7..9fc7ec7996c 100644
--- a/src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp
+++ b/src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp
@@ -2469,9 +2469,24 @@ vec4_visitor::emit_scratch_write(vec4_instruction *inst, int base_offset)
int reg_offset = base_offset + inst->dst.reg_offset;
src_reg index = get_scratch_offset(inst, inst->dst.reladdr, reg_offset);
- /* Create a temporary register to store *inst's result in. */
+ /* Create a temporary register to store *inst's result in.
+ *
+ * We have to be careful in MOVing from our temporary result register in
+ * the scratch write. If we swizzle from channels of the temporary that
+ * weren't initialized, it will confuse live interval analysis, which will
+ * make spilling fail to make progress.
+ */
src_reg temp = src_reg(this, glsl_type::vec4_type);
temp.type = inst->dst.type;
+ int first_writemask_chan = ffs(inst->dst.writemask) - 1;
+ int swizzles[4];
+ for (int i = 0; i < 4; i++)
+ if (inst->dst.writemask & (1 << i))
+ swizzles[i] = i;
+ else
+ swizzles[i] = first_writemask_chan;
+ temp.swizzle = BRW_SWIZZLE4(swizzles[0], swizzles[1],
+ swizzles[2], swizzles[3]);
dst_reg dst = dst_reg(brw_writemask(brw_vec8_grf(0, 0),
inst->dst.writemask));