tgsi: handle some src/dst aliasing in tgsi_sse2.c
authorKeith Whitwell <keithw@vmware.com>
Sun, 13 Sep 2009 18:59:24 +0000 (11:59 -0700)
committerKeith Whitwell <keithw@vmware.com>
Sun, 13 Sep 2009 18:59:24 +0000 (11:59 -0700)
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.

progs/fp/mov-alias.txt [new file with mode: 0644]
progs/fp/mul-alias.txt [new file with mode: 0644]
src/gallium/auxiliary/tgsi/tgsi_sse2.c

diff --git a/progs/fp/mov-alias.txt b/progs/fp/mov-alias.txt
new file mode 100644 (file)
index 0000000..5f04e9c
--- /dev/null
@@ -0,0 +1,6 @@
+!!ARBfp1.0
+TEMP R0;
+MOV R0, fragment.color;
+MOV R0, R0.zyxw;
+MOV result.color, R0;
+END
diff --git a/progs/fp/mul-alias.txt b/progs/fp/mul-alias.txt
new file mode 100644 (file)
index 0000000..cf7d359
--- /dev/null
@@ -0,0 +1,6 @@
+!!ARBfp1.0
+TEMP R0;
+MOV R0, fragment.color;
+MUL R0, R0.zyxw, fragment.color;
+MOV result.color, R0;
+END
index 53e3f746eefa00eb83a6b0dab0e9eebf20fd44a2..501fc05e729b2e268f04cd390387944e9e58bd64 100644 (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: