i965/fs: Fix user-defined FS outputs with less than four components.
authorKenneth Graunke <kenneth@whitecape.org>
Fri, 1 Jun 2012 20:16:58 +0000 (13:16 -0700)
committerKenneth Graunke <kenneth@whitecape.org>
Tue, 5 Jun 2012 21:41:34 +0000 (14:41 -0700)
commit2f18698220d8b27991fab550c4721590d17278e0
treed454d74884c0322050146a15d33dc18553dfbc37
parentcb18472eca9910e7a4222ebc1b6b1b66869f5b53
i965/fs: Fix user-defined FS outputs with less than four components.

OpenGL allows you to declare user-defined fragment shader outputs with
less than four components:

    out ivec2 color;

This makes sense if you're rendering to an RG format render target.

Previously, we assumed that all color outputs had four components (like
the built-in gl_FragColor/gl_FragData variables).  This caused us to
call emit_color_write for invalid indices, incrementing the output
virtual GRF's reg_offset beyond the size of the register.

This caused cascading failures: split_virtual_grfs would allocate new
size-1 registers based on the virtual GRF size, but then proceed to
rewrite the out-of-bounds accesses assuming that it had allocated enough
new (contiguously numbered) registers.  This resulted in instructions
that accessed size-1 GRFs which register numbers beyond
virtual_grf_next (i.e. registers that were never allocated).

Finally, this manifested as live variable analysis and instruction
scheduling accessing their temporary array with an out of bounds index
(as they're all sized based on virtual_grf_next), and the program would
segfault.

It looks like the hardware's Render Target Write message requires you to
send four components, even for RT formats such as RG or RGB.  This patch
continues to use all four MRFs, but doesn't bother to fill any data for
the last few, which should be unused.

+2 oglconforms.

NOTE: This is a candidate for stable release branches.

Signed-off-by: Kenneth Graunke <kenneth@whitecape.org>
Reviewed-by: Eric Anholt <eric@anholt.net>
src/mesa/drivers/dri/i965/brw_fs.h
src/mesa/drivers/dri/i965/brw_fs_visitor.cpp