diff options
author | Brian <brian.paul@tungstengraphics.com> | 2008-11-05 20:04:49 -0700 |
---|---|---|
committer | Brian <brian.paul@tungstengraphics.com> | 2008-11-05 20:04:49 -0700 |
commit | 5b2b064a5c1328449e3eb8179afc2ba366f18ae6 (patch) | |
tree | 9d299298a6714df6306b1da2ee9a7d1763aa3674 /src/gallium/auxiliary/tgsi/tgsi_exec.c | |
parent | 639a2b0ec853eda49e3e7150b2ed7f8f40d101af (diff) |
gallium: check execution mask in indirect register loads
Zero-out the index for disabled execution channels to avoid using potential
garbage values (thus avoiding bad array indexing).
Diffstat (limited to 'src/gallium/auxiliary/tgsi/tgsi_exec.c')
-rw-r--r-- | src/gallium/auxiliary/tgsi/tgsi_exec.c | 23 |
1 files changed, 23 insertions, 0 deletions
diff --git a/src/gallium/auxiliary/tgsi/tgsi_exec.c b/src/gallium/auxiliary/tgsi/tgsi_exec.c index ea5a44fb8a..53e92b96ae 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_exec.c +++ b/src/gallium/auxiliary/tgsi/tgsi_exec.c @@ -1045,12 +1045,16 @@ fetch_source( if (reg->SrcRegister.Indirect) { union tgsi_exec_channel index2; union tgsi_exec_channel indir_index; + const uint execmask = mach->ExecMask; + uint i; + /* which address register (always zero now) */ index2.i[0] = index2.i[1] = index2.i[2] = index2.i[3] = reg->SrcRegisterInd.Index; + /* get current value of address register[swizzle] */ swizzle = tgsi_util_get_src_register_swizzle( ®->SrcRegisterInd, CHAN_X ); fetch_src_file_channel( mach, @@ -1059,10 +1063,19 @@ fetch_source( &index2, &indir_index ); + /* add value of address register to the offset */ index.i[0] += indir_index.i[0]; index.i[1] += indir_index.i[1]; index.i[2] += indir_index.i[2]; index.i[3] += indir_index.i[3]; + + /* for disabled execution channels, zero-out the index to + * avoid using a potential garbage value. + */ + for (i = 0; i < QUAD_SIZE; i++) { + if ((execmask & (1 << i)) == 0) + index.i[i] = 0; + } } if( reg->SrcRegister.Dimension ) { @@ -1091,6 +1104,8 @@ fetch_source( if (reg->SrcRegisterDim.Indirect) { union tgsi_exec_channel index2; union tgsi_exec_channel indir_index; + const uint execmask = mach->ExecMask; + uint i; index2.i[0] = index2.i[1] = @@ -1109,6 +1124,14 @@ fetch_source( index.i[1] += indir_index.i[1]; index.i[2] += indir_index.i[2]; index.i[3] += indir_index.i[3]; + + /* for disabled execution channels, zero-out the index to + * avoid using a potential garbage value. + */ + for (i = 0; i < QUAD_SIZE; i++) { + if ((execmask & (1 << i)) == 0) + index.i[i] = 0; + } } } |