summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKenneth Graunke <[email protected]>2012-12-09 15:44:03 -0800
committerKenneth Graunke <[email protected]>2012-12-12 14:44:37 -0800
commitc2eb9d3a0a0dfe42255e0b68c5064213053ac293 (patch)
tree958c0d5060c203a3ebf0fda9f389c2cf7d8e2a1b
parent122345876479cf5cf553e38162ab105658614ab7 (diff)
i965: Make try_rewrite_rhs_to_dst compare VGRF size to regs written.
try_rewrite_rhs_to_dst is a quick optimization to avoid generating new temporaries (and MOVs from those temporaries to the dest) for every expression tree we visit. By generating better code in simple cases, we reduce the burden on later optimization passes like register coalescing. Previously, we compared inst->regs_written() to lhs->vector_elements to make sure the instruction generating our value wrote the same number of components as our destination register. However, this fails in some cases. One example is texturing (which produces a vec4) into gl_FragData[i]. Technically, gl_FragData[i] is also a vec4. However, the destination VGRF actually has size 4n (where n is the size of the array). split_virtual_grfs() can't split VGRFs that are used by SEND messages which require contiguous destination registers (like texturing), and register allocation needs all VGRFs to have sizes between 1 and 4. Amnesia: The Dark Descent hits this case: a texturing instruction (4 components) gets rewritten to the gl_FragData output register (which was 4*3 = 12 components), causing the register allocator to hit the "we rely on split_virtual_grfs" assertion. This makes it possible to play Amnesia. Reviewed-by: Eric Anholt <[email protected]>
-rw-r--r--src/mesa/drivers/dri/i965/brw_fs_visitor.cpp2
1 files changed, 1 insertions, 1 deletions
diff --git a/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp b/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp
index 56d43309f9d..ccf905ebc62 100644
--- a/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp
+++ b/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp
@@ -703,7 +703,7 @@ fs_visitor::try_rewrite_rhs_to_dst(ir_assignment *ir,
/* If last_rhs_inst wrote a different number of components than our LHS,
* we can't safely rewrite it.
*/
- if (ir->lhs->type->vector_elements != modify->regs_written())
+ if (virtual_grf_sizes[dst.reg] != modify->regs_written())
return false;
/* Success! Rewrite the instruction. */