i965: Make try_rewrite_rhs_to_dst compare VGRF size to regs written.
authorKenneth Graunke <kenneth@whitecape.org>
Sun, 9 Dec 2012 23:44:03 +0000 (15:44 -0800)
committerKenneth Graunke <kenneth@whitecape.org>
Wed, 12 Dec 2012 22:44:37 +0000 (14:44 -0800)
commitc2eb9d3a0a0dfe42255e0b68c5064213053ac293
tree958c0d5060c203a3ebf0fda9f389c2cf7d8e2a1b
parent122345876479cf5cf553e38162ab105658614ab7
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 <eric@anholt.net>
src/mesa/drivers/dri/i965/brw_fs_visitor.cpp