gallium/i915: fix i915_emit_texld() to handle swizzled texcoords
authorBrian <brian@i915.localnet.net>
Tue, 26 Feb 2008 00:59:51 +0000 (17:59 -0700)
committerBrian <brian@i915.localnet.net>
Tue, 26 Feb 2008 01:56:36 +0000 (18:56 -0700)
Allocate a temporary register, insert MOV instruction, etc.

src/gallium/drivers/i915simple/i915_fpc_emit.c
src/gallium/drivers/i915simple/i915_fpc_translate.c

index a59ee2340379c8f48472fcda3c849cff5ac5a87a..ad6dab6c117d97a707ab6cb8f015c7ecabc493b9 100644 (file)
@@ -71,10 +71,21 @@ i915_get_temp(struct i915_fp_compile *p)
    }
 
    p->temp_flag |= 1 << (bit - 1);
-   return UREG(REG_TYPE_R, (bit - 1));
+   return bit - 1;
 }
 
 
+static void
+i915_release_temp(struct i915_fp_compile *p, int reg)
+{
+   p->temp_flag &= ~(1 << reg);
+}
+
+
+/**
+ * Get unpreserved temporary, a temp whose value is not preserved between
+ * PS program phases.
+ */
 uint
 i915_get_utemp(struct i915_fp_compile * p)
 {
@@ -183,41 +194,63 @@ i915_emit_arith(struct i915_fp_compile * p,
    return dest;
 }
 
+
+/**
+ * Emit a texture load or texkill instruction.
+ * \param dest  the dest i915 register
+ * \param destmask  the dest register writemask
+ * \param sampler  the i915 sampler register
+ * \param coord  the i915 source texcoord operand
+ * \param opcode  the instruction opcode
+ */
 uint i915_emit_texld( struct i915_fp_compile *p,
                        uint dest,
                        uint destmask,
                        uint sampler,
                        uint coord,
-                       uint op )
+                       uint opcode )
 {
-   uint k = UREG(GET_UREG_TYPE(coord), GET_UREG_NR(coord));
+   const uint k = UREG(GET_UREG_TYPE(coord), GET_UREG_NR(coord));
+   int temp = -1;
+
    if (coord != k) {
-      /* No real way to work around this in the general case - need to
-       * allocate and declare a new temporary register (a utemp won't
-       * do).  Will fallback for now.
+      /* texcoord is swizzled or negated.  Need to allocate a new temporary
+       * register (a utemp / unpreserved temp) won't do.
        */
-      i915_program_error(p, "Can't (yet) swizzle TEX arguments");
-      assert(0);
-      return 0;
+      uint tempReg;
+
+      temp = i915_get_temp(p);           /* get temp reg index */
+      printf("***** ALLOC TEMP %d\n", temp);
+      tempReg = UREG(REG_TYPE_R, temp);  /* make i915 register */
+
+      i915_emit_arith( p, A0_MOV,
+                       tempReg, A0_DEST_CHANNEL_ALL, /* dest reg, writemask */
+                       0,                            /* saturate */
+                       coord, 0, 0 );                /* src0, src1, src2 */
+
+      /* new src texcoord is tempReg */
+      coord = tempReg;
    }
 
    /* Don't worry about saturate as we only support  
     */
    if (destmask != A0_DEST_CHANNEL_ALL) {
+      /* if not writing to XYZW... */
       uint tmp = i915_get_utemp(p);
-      i915_emit_texld( p, tmp, A0_DEST_CHANNEL_ALL, sampler, coord, op );
+      i915_emit_texld( p, tmp, A0_DEST_CHANNEL_ALL, sampler, coord, opcode );
       i915_emit_arith( p, A0_MOV, dest, destmask, 0, tmp, 0, 0 );
-      return dest;
+      /* XXX release utemp here? */
    }
    else {
       assert(GET_UREG_TYPE(dest) != REG_TYPE_CONST);
       assert(dest = UREG(GET_UREG_TYPE(dest), GET_UREG_NR(dest)));
 
+      /* is the sampler coord a texcoord input reg? */
       if (GET_UREG_TYPE(coord) != REG_TYPE_T) {
         p->nr_tex_indirect++;
       }
 
-      *(p->csr++) = (op | 
+      *(p->csr++) = (opcode | 
                     T0_DEST( dest ) |
                     T0_SAMPLER( sampler ));
 
@@ -225,8 +258,12 @@ uint i915_emit_texld( struct i915_fp_compile *p,
       *(p->csr++) = T2_MBZ;
 
       p->nr_tex_insn++;
-      return dest;
    }
+
+   if (temp >= 0)
+      i915_release_temp(p, temp);
+
+   return dest;
 }
 
 
index 50c9e6540954dcec1da0818791df4a949c27fd24..76a2184e9aba87bc3a9f69cbbd2cb8c89700790d 100644 (file)
@@ -575,8 +575,12 @@ i915_translate_instruction(struct i915_fp_compile *p,
       src0 = src_vector(p, &inst->FullSrcRegisters[0]);
       tmp = i915_get_utemp(p);
 
-      i915_emit_texld(p, tmp, A0_DEST_CHANNEL_ALL,   /* use a dummy dest reg */
-                      0, src0, T0_TEXKILL);
+      i915_emit_texld(p,
+                      tmp,                   /* dest reg: a dummy reg */
+                      A0_DEST_CHANNEL_ALL,   /* dest writemask */
+                      0,                     /* sampler */
+                      src0,                  /* coord*/
+                      T0_TEXKILL);           /* opcode */
       break;
 
    case TGSI_OPCODE_LG2:
@@ -970,6 +974,16 @@ i915_translate_instructions(struct i915_fp_compile *p,
                ifs->num_constants = MAX2(ifs->num_constants, i + 1);
             }
          }
+         else if (parse.FullToken.FullDeclaration.Declaration.File
+                  == TGSI_FILE_TEMPORARY) {
+            uint i;
+            for (i = parse.FullToken.FullDeclaration.u.DeclarationRange.First;
+                 i <= parse.FullToken.FullDeclaration.u.DeclarationRange.Last;
+                 i++) {
+               assert(i < I915_MAX_TEMPORARY);
+               p->temp_flag |= (1 << i); /* mark temp as used */
+            }
+         }
          break;
 
       case TGSI_TOKEN_TYPE_IMMEDIATE:
@@ -1048,7 +1062,7 @@ i915_init_compile(struct i915_context *i915,
    p->decl = p->declarations;
    p->decl_s = 0;
    p->decl_t = 0;
-   p->temp_flag = 0xffff000;
+   p->temp_flag = ~0x0 << I915_MAX_TEMPORARY;
    p->utemp_flag = ~0x7;
 
    p->wpos_tex = -1;