Mesa (mesa_7_5_branch): tgis: implement indirect addressing for destination registers

Brian Paul brianp at kemper.freedesktop.org
Fri Jul 10 19:10:06 UTC 2009


Module: Mesa
Branch: mesa_7_5_branch
Commit: baa7ff47d548cdcc1ea68657ee1b0500f78041be
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=baa7ff47d548cdcc1ea68657ee1b0500f78041be

Author: Brian Paul <brianp at vmware.com>
Date:   Fri Jul 10 13:07:16 2009 -0600

tgis: implement indirect addressing for destination registers

Includes the TGSI interpreter, but not the SSE/PPC/etc code generators.

---

 src/gallium/auxiliary/tgsi/tgsi_build.c |   26 ++++++++++++++++
 src/gallium/auxiliary/tgsi/tgsi_build.h |    1 +
 src/gallium/auxiliary/tgsi/tgsi_dump.c  |   21 ++++++++++---
 src/gallium/auxiliary/tgsi/tgsi_exec.c  |   51 ++++++++++++++++++++++++++++---
 src/gallium/auxiliary/tgsi/tgsi_parse.c |   12 +++++++-
 src/gallium/auxiliary/tgsi/tgsi_parse.h |    1 +
 6 files changed, 101 insertions(+), 11 deletions(-)

diff --git a/src/gallium/auxiliary/tgsi/tgsi_build.c b/src/gallium/auxiliary/tgsi/tgsi_build.c
index a1891a1..18c448a 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_build.c
+++ b/src/gallium/auxiliary/tgsi/tgsi_build.c
@@ -584,6 +584,7 @@ tgsi_build_full_instruction(
       *dst_register = tgsi_build_dst_register(
          reg->DstRegister.File,
          reg->DstRegister.WriteMask,
+         reg->DstRegister.Indirect,
          reg->DstRegister.Index,
          instruction,
          header );
@@ -631,6 +632,28 @@ tgsi_build_full_instruction(
             header );
          prev_token = (struct tgsi_token  *) dst_register_ext_modulate;
       }
+
+      if( reg->DstRegister.Indirect ) {
+         struct tgsi_src_register *ind;
+
+         if( maxsize <= size )
+            return 0;
+         ind = (struct tgsi_src_register *) &tokens[size];
+         size++;
+
+         *ind = tgsi_build_src_register(
+            reg->DstRegisterInd.File,
+            reg->DstRegisterInd.SwizzleX,
+            reg->DstRegisterInd.SwizzleY,
+            reg->DstRegisterInd.SwizzleZ,
+            reg->DstRegisterInd.SwizzleW,
+            reg->DstRegisterInd.Negate,
+            reg->DstRegisterInd.Indirect,
+            reg->DstRegisterInd.Dimension,
+            reg->DstRegisterInd.Index,
+            instruction,
+            header );
+      }
    }
 
    for( i = 0;  i < full_inst->Instruction.NumSrcRegs; i++ ) {
@@ -1194,6 +1217,7 @@ struct tgsi_dst_register
 tgsi_build_dst_register(
    unsigned file,
    unsigned mask,
+   unsigned indirect,
    int index,
    struct tgsi_instruction *instruction,
    struct tgsi_header *header )
@@ -1208,6 +1232,7 @@ tgsi_build_dst_register(
    dst_register.File = file;
    dst_register.WriteMask = mask;
    dst_register.Index = index;
+   dst_register.Indirect = indirect;
 
    instruction_grow( instruction, header );
 
@@ -1220,6 +1245,7 @@ tgsi_default_full_dst_register( void )
    struct tgsi_full_dst_register full_dst_register;
 
    full_dst_register.DstRegister = tgsi_default_dst_register();
+   full_dst_register.DstRegisterInd = tgsi_default_src_register();
    full_dst_register.DstRegisterExtConcode =
       tgsi_default_dst_register_ext_concode();
    full_dst_register.DstRegisterExtModulate =
diff --git a/src/gallium/auxiliary/tgsi/tgsi_build.h b/src/gallium/auxiliary/tgsi/tgsi_build.h
index 0fd6fab..9a3a077 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_build.h
+++ b/src/gallium/auxiliary/tgsi/tgsi_build.h
@@ -289,6 +289,7 @@ struct tgsi_dst_register
 tgsi_build_dst_register(
    unsigned file,
    unsigned mask,
+   unsigned indirect,
    int index,
    struct tgsi_instruction *instruction,
    struct tgsi_header *header );
diff --git a/src/gallium/auxiliary/tgsi/tgsi_dump.c b/src/gallium/auxiliary/tgsi/tgsi_dump.c
index 76a09af..9b84471 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_dump.c
+++ b/src/gallium/auxiliary/tgsi/tgsi_dump.c
@@ -355,11 +355,22 @@ iter_instruction(
          CHR( ',' );
       CHR( ' ' );
 
-      _dump_register(
-         ctx,
-         dst->DstRegister.File,
-         dst->DstRegister.Index,
-         dst->DstRegister.Index );
+      if (dst->DstRegister.Indirect) {
+         _dump_register_ind(
+            ctx,
+            dst->DstRegister.File,
+            dst->DstRegister.Index,
+            dst->DstRegisterInd.File,
+            dst->DstRegisterInd.Index,
+            dst->DstRegisterInd.SwizzleX );
+      }
+      else {
+         _dump_register(
+            ctx,
+            dst->DstRegister.File,
+            dst->DstRegister.Index,
+            dst->DstRegister.Index );
+      }
       ENM( dst->DstRegisterExtModulate.Modulate, modulate_names );
       _dump_writemask( ctx, dst->DstRegister.WriteMask );
 
diff --git a/src/gallium/auxiliary/tgsi/tgsi_exec.c b/src/gallium/auxiliary/tgsi/tgsi_exec.c
index aba7a3f..5cb322a 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_exec.c
+++ b/src/gallium/auxiliary/tgsi/tgsi_exec.c
@@ -1395,28 +1395,69 @@ store_dest(
    union tgsi_exec_channel null;
    union tgsi_exec_channel *dst;
    uint execmask = mach->ExecMask;
+   int offset = 0;  /* indirection offset */
+   int index;
 
 #ifdef DEBUG
    check_inf_or_nan(chan);
 #endif
 
+   /* There is an extra source register that indirectly subscripts
+    * a register file. The direct index now becomes an offset
+    * that is being added to the indirect register.
+    *
+    *    file[ind[2].x+1],
+    *    where:
+    *       ind = DstRegisterInd.File
+    *       [2] = DstRegisterInd.Index
+    *       .x = DstRegisterInd.SwizzleX
+    */
+   if (reg->DstRegister.Indirect) {
+      union tgsi_exec_channel index;
+      union tgsi_exec_channel indir_index;
+      uint swizzle;
+
+      /* which address register (always zero for now) */
+      index.i[0] =
+      index.i[1] =
+      index.i[2] =
+      index.i[3] = reg->DstRegisterInd.Index;
+
+      /* get current value of address register[swizzle] */
+      swizzle = tgsi_util_get_src_register_swizzle( &reg->DstRegisterInd, CHAN_X );
+
+      /* fetch values from the address/indirection register */
+      fetch_src_file_channel(
+         mach,
+         reg->DstRegisterInd.File,
+         swizzle,
+         &index,
+         &indir_index );
+
+      /* save indirection offset */
+      offset = (int) indir_index.f[0];
+   }
+
    switch (reg->DstRegister.File) {
    case TGSI_FILE_NULL:
       dst = &null;
       break;
 
    case TGSI_FILE_OUTPUT:
-      dst = &mach->Outputs[mach->Temps[TEMP_OUTPUT_I].xyzw[TEMP_OUTPUT_C].u[0]
-                           + reg->DstRegister.Index].xyzw[chan_index];
+      index = mach->Temps[TEMP_OUTPUT_I].xyzw[TEMP_OUTPUT_C].u[0]
+         + reg->DstRegister.Index;
+      dst = &mach->Outputs[offset + index].xyzw[chan_index];
       break;
 
    case TGSI_FILE_TEMPORARY:
-      assert( reg->DstRegister.Index < TGSI_EXEC_NUM_TEMPS );
-      dst = &mach->Temps[reg->DstRegister.Index].xyzw[chan_index];
+      index = reg->DstRegister.Index;
+      assert( index < TGSI_EXEC_NUM_TEMPS );
+      dst = &mach->Temps[offset + index].xyzw[chan_index];
       break;
 
    case TGSI_FILE_ADDRESS:
-      dst = &mach->Addrs[reg->DstRegister.Index].xyzw[chan_index];
+      index = reg->DstRegister.Index;
+      dst = &mach->Addrs[index].xyzw[chan_index];
       break;
 
    default:
diff --git a/src/gallium/auxiliary/tgsi/tgsi_parse.c b/src/gallium/auxiliary/tgsi/tgsi_parse.c
index 0081f74..7f2cfb7 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_parse.c
+++ b/src/gallium/auxiliary/tgsi/tgsi_parse.c
@@ -219,7 +219,6 @@ tgsi_parse_token(
          /*
           * No support for indirect or multi-dimensional addressing.
           */
-         assert( !inst->FullDstRegisters[i].DstRegister.Indirect );
          assert( !inst->FullDstRegisters[i].DstRegister.Dimension );
 
          extended = inst->FullDstRegisters[i].DstRegister.Extended;
@@ -246,6 +245,17 @@ tgsi_parse_token(
 
             extended = token.Extended;
          }
+
+         if( inst->FullDstRegisters[i].DstRegister.Indirect ) {
+            next_token( ctx, &inst->FullDstRegisters[i].DstRegisterInd );
+
+            /*
+             * No support for indirect or multi-dimensional addressing.
+             */
+            assert( !inst->FullDstRegisters[i].DstRegisterInd.Indirect );
+            assert( !inst->FullDstRegisters[i].DstRegisterInd.Dimension );
+            assert( !inst->FullDstRegisters[i].DstRegisterInd.Extended );
+         }
       }
 
       assert( inst->Instruction.NumSrcRegs <= TGSI_FULL_MAX_SRC_REGISTERS );
diff --git a/src/gallium/auxiliary/tgsi/tgsi_parse.h b/src/gallium/auxiliary/tgsi/tgsi_parse.h
index 0543507..a289e26 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_parse.h
+++ b/src/gallium/auxiliary/tgsi/tgsi_parse.h
@@ -48,6 +48,7 @@ struct tgsi_full_header
 struct tgsi_full_dst_register
 {
    struct tgsi_dst_register               DstRegister;
+   struct tgsi_src_register               DstRegisterInd;
    struct tgsi_dst_register_ext_concode   DstRegisterExtConcode;
    struct tgsi_dst_register_ext_modulate  DstRegisterExtModulate;
 };




More information about the mesa-commit mailing list