Merge remote branch 'origin/master' into radeon-rewrite
[mesa.git] / src / gallium / auxiliary / tgsi / tgsi_exec.c
index 4a217454dda899120644f12deb6e90017b969980..ab641efb6032b07082167a7c2545463d210b9385 100644 (file)
@@ -133,7 +133,7 @@ tgsi_exec_machine_bind_shader(
    struct tgsi_exec_machine *mach,
    const struct tgsi_token *tokens,
    uint numSamplers,
-   struct tgsi_sampler *samplers)
+   struct tgsi_sampler **samplers)
 {
    uint k;
    struct tgsi_parse_context parse;
@@ -202,7 +202,7 @@ tgsi_exec_machine_bind_shader(
 
       case TGSI_TOKEN_TYPE_IMMEDIATE:
          {
-            uint size = parse.FullToken.FullImmediate.Immediate.Size - 1;
+            uint size = parse.FullToken.FullImmediate.Immediate.NrTokens - 1;
             assert( size % 4 == 0 );
             assert( mach->ImmLimit + size / 4 <= TGSI_EXEC_NUM_IMMEDIATES );
 
@@ -320,6 +320,7 @@ micro_add(
    dst->f[3] = src0->f[3] + src1->f[3];
 }
 
+#if 0
 static void
 micro_iadd(
    union tgsi_exec_channel *dst,
@@ -331,6 +332,7 @@ micro_iadd(
    dst->i[2] = src0->i[2] + src1->i[2];
    dst->i[3] = src0->i[3] + src1->i[3];
 }
+#endif
 
 static void
 micro_and(
@@ -408,6 +410,7 @@ micro_div(
    }
 }
 
+#if 0
 static void
 micro_udiv(
    union tgsi_exec_channel *dst,
@@ -419,6 +422,7 @@ micro_udiv(
    dst->u[2] = src0->u[2] / src1->u[2];
    dst->u[3] = src0->u[3] / src1->u[3];
 }
+#endif
 
 static void
 micro_eq(
@@ -434,6 +438,7 @@ micro_eq(
    dst->f[3] = src0->f[3] == src1->f[3] ? src2->f[3] : src3->f[3];
 }
 
+#if 0
 static void
 micro_ieq(
    union tgsi_exec_channel *dst,
@@ -447,6 +452,7 @@ micro_ieq(
    dst->i[2] = src0->i[2] == src1->i[2] ? src2->i[2] : src3->i[2];
    dst->i[3] = src0->i[3] == src1->i[3] ? src2->i[3] : src3->i[3];
 }
+#endif
 
 static void
 micro_exp2(
@@ -466,17 +472,7 @@ micro_exp2(
 #endif
 }
 
-static void
-micro_f2it(
-   union tgsi_exec_channel *dst,
-   const union tgsi_exec_channel *src )
-{
-   dst->i[0] = (int) src->f[0];
-   dst->i[1] = (int) src->f[1];
-   dst->i[2] = (int) src->f[2];
-   dst->i[3] = (int) src->f[3];
-}
-
+#if 0
 static void
 micro_f2ut(
    union tgsi_exec_channel *dst,
@@ -487,6 +483,7 @@ micro_f2ut(
    dst->u[2] = (uint) src->f[2];
    dst->u[3] = (uint) src->f[3];
 }
+#endif
 
 static void
 micro_flr(
@@ -581,6 +578,7 @@ micro_lt(
    dst->f[3] = src0->f[3] < src1->f[3] ? src2->f[3] : src3->f[3];
 }
 
+#if 0
 static void
 micro_ilt(
    union tgsi_exec_channel *dst,
@@ -594,7 +592,9 @@ micro_ilt(
    dst->i[2] = src0->i[2] < src1->i[2] ? src2->i[2] : src3->i[2];
    dst->i[3] = src0->i[3] < src1->i[3] ? src2->i[3] : src3->i[3];
 }
+#endif
 
+#if 0
 static void
 micro_ult(
    union tgsi_exec_channel *dst,
@@ -608,6 +608,7 @@ micro_ult(
    dst->u[2] = src0->u[2] < src1->u[2] ? src2->u[2] : src3->u[2];
    dst->u[3] = src0->u[3] < src1->u[3] ? src2->u[3] : src3->u[3];
 }
+#endif
 
 static void
 micro_max(
@@ -621,6 +622,7 @@ micro_max(
    dst->f[3] = src0->f[3] > src1->f[3] ? src0->f[3] : src1->f[3];
 }
 
+#if 0
 static void
 micro_imax(
    union tgsi_exec_channel *dst,
@@ -632,7 +634,9 @@ micro_imax(
    dst->i[2] = src0->i[2] > src1->i[2] ? src0->i[2] : src1->i[2];
    dst->i[3] = src0->i[3] > src1->i[3] ? src0->i[3] : src1->i[3];
 }
+#endif
 
+#if 0
 static void
 micro_umax(
    union tgsi_exec_channel *dst,
@@ -644,6 +648,7 @@ micro_umax(
    dst->u[2] = src0->u[2] > src1->u[2] ? src0->u[2] : src1->u[2];
    dst->u[3] = src0->u[3] > src1->u[3] ? src0->u[3] : src1->u[3];
 }
+#endif
 
 static void
 micro_min(
@@ -657,6 +662,7 @@ micro_min(
    dst->f[3] = src0->f[3] < src1->f[3] ? src0->f[3] : src1->f[3];
 }
 
+#if 0
 static void
 micro_imin(
    union tgsi_exec_channel *dst,
@@ -668,7 +674,9 @@ micro_imin(
    dst->i[2] = src0->i[2] < src1->i[2] ? src0->i[2] : src1->i[2];
    dst->i[3] = src0->i[3] < src1->i[3] ? src0->i[3] : src1->i[3];
 }
+#endif
 
+#if 0
 static void
 micro_umin(
    union tgsi_exec_channel *dst,
@@ -680,7 +688,9 @@ micro_umin(
    dst->u[2] = src0->u[2] < src1->u[2] ? src0->u[2] : src1->u[2];
    dst->u[3] = src0->u[3] < src1->u[3] ? src0->u[3] : src1->u[3];
 }
+#endif
 
+#if 0
 static void
 micro_umod(
    union tgsi_exec_channel *dst,
@@ -692,6 +702,7 @@ micro_umod(
    dst->u[2] = src0->u[2] % src1->u[2];
    dst->u[3] = src0->u[3] % src1->u[3];
 }
+#endif
 
 static void
 micro_mul(
@@ -705,6 +716,7 @@ micro_mul(
    dst->f[3] = src0->f[3] * src1->f[3];
 }
 
+#if 0
 static void
 micro_imul(
    union tgsi_exec_channel *dst,
@@ -716,7 +728,9 @@ micro_imul(
    dst->i[2] = src0->i[2] * src1->i[2];
    dst->i[3] = src0->i[3] * src1->i[3];
 }
+#endif
 
+#if 0
 static void
 micro_imul64(
    union tgsi_exec_channel *dst0,
@@ -733,7 +747,9 @@ micro_imul64(
    dst0->i[2] = 0;
    dst0->i[3] = 0;
 }
+#endif
 
+#if 0
 static void
 micro_umul64(
    union tgsi_exec_channel *dst0,
@@ -750,7 +766,10 @@ micro_umul64(
    dst0->u[2] = 0;
    dst0->u[3] = 0;
 }
+#endif
+
 
+#if 0
 static void
 micro_movc(
    union tgsi_exec_channel *dst,
@@ -763,6 +782,7 @@ micro_movc(
    dst->u[2] = src0->u[2] ? src1->u[2] : src2->u[2];
    dst->u[3] = src0->u[3] ? src1->u[3] : src2->u[3];
 }
+#endif
 
 static void
 micro_neg(
@@ -775,6 +795,7 @@ micro_neg(
    dst->f[3] = -src->f[3];
 }
 
+#if 0
 static void
 micro_ineg(
    union tgsi_exec_channel *dst,
@@ -785,6 +806,7 @@ micro_ineg(
    dst->i[2] = -src->i[2];
    dst->i[3] = -src->i[3];
 }
+#endif
 
 static void
 micro_not(
@@ -839,6 +861,17 @@ micro_rnd(
    dst->f[3] = floorf( src->f[3] + 0.5f );
 }
 
+static void
+micro_sgn(
+   union tgsi_exec_channel *dst,
+   const union tgsi_exec_channel *src )
+{
+   dst->f[0] = src->f[0] < 0.0f ? -1.0f : src->f[0] > 0.0f ? 1.0f : 0.0f;
+   dst->f[1] = src->f[1] < 0.0f ? -1.0f : src->f[1] > 0.0f ? 1.0f : 0.0f;
+   dst->f[2] = src->f[2] < 0.0f ? -1.0f : src->f[2] > 0.0f ? 1.0f : 0.0f;
+   dst->f[3] = src->f[3] < 0.0f ? -1.0f : src->f[3] > 0.0f ? 1.0f : 0.0f;
+}
+
 static void
 micro_shl(
    union tgsi_exec_channel *dst,
@@ -874,6 +907,7 @@ micro_trunc(
    dst->f[3] = (float) (int) src0->f[3];
 }
 
+#if 0
 static void
 micro_ushr(
    union tgsi_exec_channel *dst,
@@ -885,6 +919,7 @@ micro_ushr(
    dst->u[2] = src0->u[2] >> src1->u[2];
    dst->u[3] = src0->u[3] >> src1->u[3];
 }
+#endif
 
 static void
 micro_sin(
@@ -919,6 +954,7 @@ micro_sub(
    dst->f[3] = src0->f[3] - src1->f[3];
 }
 
+#if 0
 static void
 micro_u2f(
    union tgsi_exec_channel *dst,
@@ -929,6 +965,7 @@ micro_u2f(
    dst->f[2] = (float) src->u[2];
    dst->f[3] = (float) src->u[3];
 }
+#endif
 
 static void
 micro_xor(
@@ -958,14 +995,22 @@ fetch_src_file_channel(
       switch( file ) {
       case TGSI_FILE_CONSTANT:
          assert(mach->Consts);
-         assert(index->i[0] >= 0);
-         assert(index->i[1] >= 0);
-         assert(index->i[2] >= 0);
-         assert(index->i[3] >= 0);
-         chan->f[0] = mach->Consts[index->i[0]][swizzle];
-         chan->f[1] = mach->Consts[index->i[1]][swizzle];
-         chan->f[2] = mach->Consts[index->i[2]][swizzle];
-         chan->f[3] = mach->Consts[index->i[3]][swizzle];
+         if (index->i[0] < 0)
+            chan->f[0] = 0.0f;
+         else
+            chan->f[0] = mach->Consts[index->i[0]][swizzle];
+         if (index->i[1] < 0)
+            chan->f[1] = 0.0f;
+         else
+            chan->f[1] = mach->Consts[index->i[1]][swizzle];
+         if (index->i[2] < 0)
+            chan->f[2] = 0.0f;
+         else
+            chan->f[2] = mach->Consts[index->i[2]][swizzle];
+         if (index->i[3] < 0)
+            chan->f[3] = 0.0f;
+         else
+            chan->f[3] = mach->Consts[index->i[3]][swizzle];
          break;
 
       case TGSI_FILE_INPUT:
@@ -1081,10 +1126,10 @@ fetch_source(
          &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];
+      index.i[0] += (int) indir_index.f[0];
+      index.i[1] += (int) indir_index.f[1];
+      index.i[2] += (int) indir_index.f[2];
+      index.i[3] += (int) indir_index.f[3];
 
       /* for disabled execution channels, zero-out the index to
        * avoid using a potential garbage value.
@@ -1160,10 +1205,10 @@ fetch_source(
             &index2,
             &indir_index );
 
-         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];
+         index.i[0] += (int) indir_index.f[0];
+         index.i[1] += (int) indir_index.f[1];
+         index.i[2] += (int) indir_index.f[2];
+         index.i[3] += (int) indir_index.f[3];
 
          /* for disabled execution channels, zero-out the index to
           * avoid using a potential garbage value.
@@ -1527,7 +1572,7 @@ exec_kilp(struct tgsi_exec_machine *mach,
 
 
 /*
- * Fetch a texel using STR texture coordinates.
+ * Fetch a four texture samples using STR texture coordinates.
  */
 static void
 fetch_texel( struct tgsi_sampler *sampler,
@@ -1561,7 +1606,7 @@ exec_tex(struct tgsi_exec_machine *mach,
          boolean projected)
 {
    const uint unit = inst->FullSrcRegisters[1].SrcRegister.Index;
-   union tgsi_exec_channel r[8];
+   union tgsi_exec_channel r[4];
    uint chan_index;
    float lodBias;
 
@@ -1584,7 +1629,7 @@ exec_tex(struct tgsi_exec_machine *mach,
       else
          lodBias = 0.0;
 
-      fetch_texel(&mach->Samplers[unit],
+      fetch_texel(mach->Samplers[unit],
                   &r[0], NULL, NULL, lodBias,  /* S, T, P, BIAS */
                   &r[0], &r[1], &r[2], &r[3]); /* R, G, B, A */
       break;
@@ -1610,7 +1655,7 @@ exec_tex(struct tgsi_exec_machine *mach,
       else
          lodBias = 0.0;
 
-      fetch_texel(&mach->Samplers[unit],
+      fetch_texel(mach->Samplers[unit],
                   &r[0], &r[1], &r[2], lodBias,  /* inputs */
                   &r[0], &r[1], &r[2], &r[3]);  /* outputs */
       break;
@@ -1636,7 +1681,7 @@ exec_tex(struct tgsi_exec_machine *mach,
       else
          lodBias = 0.0;
 
-      fetch_texel(&mach->Samplers[unit],
+      fetch_texel(mach->Samplers[unit],
                   &r[0], &r[1], &r[2], lodBias,
                   &r[0], &r[1], &r[2], &r[3]);
       break;
@@ -1789,7 +1834,7 @@ exec_instruction(
    case TGSI_OPCODE_ARL:
       FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) {
          FETCH( &r[0], 0, chan_index );
-         micro_f2it( &r[0], &r[0] );
+         micro_flr( &r[0], &r[0] );
          STORE( &r[0], 0, chan_index );
       }
       break;
@@ -2127,6 +2172,7 @@ exec_instruction(
       break;
 
    case TGSI_OPCODE_ROUND:
+   case TGSI_OPCODE_ARR:
       FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) {
          FETCH( &r[0], 0, chan_index );
          micro_rnd( &r[0], &r[0] );
@@ -2427,10 +2473,6 @@ exec_instruction(
       assert (0);
       break;
 
-   case TGSI_OPCODE_ARR:
-      assert (0);
-      break;
-
    case TGSI_OPCODE_BRA:
       assert (0);
       break;
@@ -2486,7 +2528,12 @@ exec_instruction(
       break;
 
    case TGSI_OPCODE_SSG:
-      assert (0);
+   /* TGSI_OPCODE_SGN */
+      FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) {
+         FETCH( &r[0], 0, chan_index );
+         micro_sgn( &r[0], &r[0] );
+         STORE( &r[0], 0, chan_index );
+      }
       break;
 
    case TGSI_OPCODE_CMP: