tgsi: handle some src/dst aliasing in tgsi_sse2.c

Src/Dst aliasing (aka SOA dependencies) requires some care to ensure
intermediate results do not overwrite yet-to-be read source registers.

This change ensures that MOV/SWZ handle this correctly, which is poor but
no worse than the current tgsi_exec.c path.  Remove the fallback as there
is nothing to be gained correctness-wise between the two implementations now.

Fixing this properly looks like a bit of work in this code, but might be
easily achieved by sending destination writes to temporary storage.
This commit is contained in:
Keith Whitwell 2009-09-13 11:59:24 -07:00
parent 86226d5ea1
commit 66a7eedaa2
3 changed files with 35 additions and 8 deletions

6
progs/fp/mov-alias.txt Normal file
View File

@ -0,0 +1,6 @@
!!ARBfp1.0
TEMP R0;
MOV R0, fragment.color;
MOV R0, R0.zyxw;
MOV result.color, R0;
END

6
progs/fp/mul-alias.txt Normal file
View File

@ -0,0 +1,6 @@
!!ARBfp1.0
TEMP R0;
MOV R0, fragment.color;
MUL R0, R0.zyxw, fragment.color;
MOV result.color, R0;
END

View File

@ -39,8 +39,9 @@
#include "tgsi/tgsi_info.h"
#include "tgsi/tgsi_parse.h"
#include "tgsi/tgsi_util.h"
#include "tgsi_exec.h"
#include "tgsi_sse2.h"
#include "tgsi/tgsi_dump.h"
#include "tgsi/tgsi_exec.h"
#include "tgsi/tgsi_sse2.h"
#include "rtasm/rtasm_x86sse.h"
@ -1760,10 +1761,6 @@ emit_instruction(
if (indirect_temp_reference(inst))
return FALSE;
/* need to use extra temps to fix SOA dependencies : */
if (tgsi_check_soa_dependencies(inst))
return FALSE;
switch (inst->Instruction.Opcode) {
case TGSI_OPCODE_ARL:
FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) {
@ -1777,8 +1774,10 @@ emit_instruction(
case TGSI_OPCODE_MOV:
case TGSI_OPCODE_SWZ:
FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) {
FETCH( func, *inst, 0, 0, chan_index );
STORE( func, *inst, 0, 0, chan_index );
FETCH( func, *inst, 4 + chan_index, 0, chan_index );
}
FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) {
STORE( func, *inst, 4 + chan_index, 0, chan_index );
}
break;
@ -2938,6 +2937,22 @@ tgsi_emit_sse2(
parse.FullHeader.Processor.Processor == TGSI_PROCESSOR_VERTEX ?
"vertex shader" : "fragment shader");
}
if (tgsi_check_soa_dependencies(&parse.FullToken.FullInstruction)) {
uint opcode = parse.FullToken.FullInstruction.Instruction.Opcode;
/* XXX: we only handle src/dst aliasing in a few opcodes
* currently. Need to use an additional temporay to hold
* the result in the cases where the code is too opaque to
* fix.
*/
if (opcode != TGSI_OPCODE_MOV &&
opcode != TGSI_OPCODE_SWZ) {
debug_printf("Warning: src/dst aliasing in instruction"
" is not handled:\n");
tgsi_dump_instruction(&parse.FullToken.FullInstruction, 1);
}
}
break;
case TGSI_TOKEN_TYPE_IMMEDIATE: