Mesa (master): tgsi: clean up exec_tex()

Chia-I Wu olv at kemper.freedesktop.org
Wed May 8 03:03:01 UTC 2013


Module: Mesa
Branch: master
Commit: 61d57ec2768fde57cb3926d6757044593d6e9a08
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=61d57ec2768fde57cb3926d6757044593d6e9a08

Author: Chia-I Wu <olvaffe at gmail.com>
Date:   Tue May  7 14:50:02 2013 +0800

tgsi: clean up exec_tex()

Make use of tgsi_util_get_texture_coord_dim() to replace the big switch table.

There is a subtle difference with this change.  When TXP is used with an array
texture, the layer is now also projected.  This behavior matches the TGSI doc.
Since GLSL does not allow TXP on an array texture, I am not sure which
behavior is correct or preferred.

Signed-off-by: Chia-I Wu <olvaffe at gmail.com>
Acked-by: Roland Scheidegger <sroland at vmware.com>

---

 src/gallium/auxiliary/tgsi/tgsi_exec.c |  220 ++++++++------------------------
 1 files changed, 52 insertions(+), 168 deletions(-)

diff --git a/src/gallium/auxiliary/tgsi/tgsi_exec.c b/src/gallium/auxiliary/tgsi/tgsi_exec.c
index 75b0663..cb66a40 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_exec.c
+++ b/src/gallium/auxiliary/tgsi/tgsi_exec.c
@@ -1780,201 +1780,85 @@ exec_tex(struct tgsi_exec_machine *mach,
          uint modifier, uint sampler)
 {
    const uint unit = inst->Src[sampler].Register.Index;
-   union tgsi_exec_channel r[4], cubearraycomp, cubelod;
-   const union tgsi_exec_channel *lod = &ZeroVec;
+   const union tgsi_exec_channel *args[5], *proj = NULL;
+   union tgsi_exec_channel r[5];
    enum tgsi_sampler_control control =  tgsi_sampler_lod_none;
    uint chan;
    int8_t offsets[3];
+   int dim, shadow_ref, i;
 
    /* always fetch all 3 offsets, overkill but keeps code simple */
    fetch_texel_offsets(mach, inst, offsets);
 
    assert(modifier != TEX_MODIFIER_LEVEL_ZERO);
 
-   if (modifier != TEX_MODIFIER_NONE && (sampler == 1)) {
-      FETCH(&r[3], 0, TGSI_CHAN_W);
-      if (modifier != TEX_MODIFIER_PROJECTED) {
-         lod = &r[3];
-      }
-   }
-
-   if (modifier == TEX_MODIFIER_EXPLICIT_LOD) {
-      control = tgsi_sampler_lod_explicit;
-   } else if (modifier == TEX_MODIFIER_LOD_BIAS){
-      control = tgsi_sampler_lod_bias;
-   }
-
-   switch (inst->Texture.Texture) {
-   case TGSI_TEXTURE_1D:
-      FETCH(&r[0], 0, TGSI_CHAN_X);
-
-      if (modifier == TEX_MODIFIER_PROJECTED) {
-         micro_div(&r[0], &r[0], &r[3]);
-      }
-
-      fetch_texel(mach->Sampler, unit, unit,
-                  &r[0], &ZeroVec, &ZeroVec, &ZeroVec, lod, /* S, T, P, C, LOD */
-                  NULL, offsets, control,
-                  &r[0], &r[1], &r[2], &r[3]);     /* R, G, B, A */
-      break;
-
-   case TGSI_TEXTURE_SHADOW1D:
-      FETCH(&r[0], 0, TGSI_CHAN_X);
-      FETCH(&r[2], 0, TGSI_CHAN_Z);
-
-      if (modifier == TEX_MODIFIER_PROJECTED) {
-         micro_div(&r[0], &r[0], &r[3]);
-         micro_div(&r[2], &r[2], &r[3]);
-      }
-
-      fetch_texel(mach->Sampler, unit, unit,
-                  &r[0], &ZeroVec, &r[2], &ZeroVec, lod, /* S, T, P, C, LOD */
-                  NULL, offsets, control,
-                  &r[0], &r[1], &r[2], &r[3]);     /* R, G, B, A */
-      break;
-
-   case TGSI_TEXTURE_2D:
-   case TGSI_TEXTURE_RECT:
-      FETCH(&r[0], 0, TGSI_CHAN_X);
-      FETCH(&r[1], 0, TGSI_CHAN_Y);
-
-      if (modifier == TEX_MODIFIER_PROJECTED) {
-         micro_div(&r[0], &r[0], &r[3]);
-         micro_div(&r[1], &r[1], &r[3]);
-      }
+   dim = tgsi_util_get_texture_coord_dim(inst->Texture.Texture, &shadow_ref);
 
-      fetch_texel(mach->Sampler, unit, unit,
-                  &r[0], &r[1], &ZeroVec, &ZeroVec, lod,    /* S, T, P, C, LOD */
-                  NULL, offsets, control,
-                  &r[0], &r[1], &r[2], &r[3]);  /* outputs */
-      break;
+   assert(dim <= 4);
+   if (shadow_ref >= 0)
+      assert(shadow_ref >= dim && shadow_ref < Elements(args));
 
-   case TGSI_TEXTURE_SHADOW2D:
-   case TGSI_TEXTURE_SHADOWRECT:
-      FETCH(&r[0], 0, TGSI_CHAN_X);
-      FETCH(&r[1], 0, TGSI_CHAN_Y);
-      FETCH(&r[2], 0, TGSI_CHAN_Z);
+   /* fetch modifier to the last argument */
+   if (modifier != TEX_MODIFIER_NONE) {
+      const int last = Elements(args) - 1;
 
-      if (modifier == TEX_MODIFIER_PROJECTED) {
-         micro_div(&r[0], &r[0], &r[3]);
-         micro_div(&r[1], &r[1], &r[3]);
-         micro_div(&r[2], &r[2], &r[3]);
+      /* fetch modifier from src0.w or src1.x */
+      if (sampler == 1) {
+         assert(dim <= TGSI_CHAN_W && shadow_ref != TGSI_CHAN_W);
+         FETCH(&r[last], 0, TGSI_CHAN_W);
       }
-
-      fetch_texel(mach->Sampler, unit, unit,
-                  &r[0], &r[1], &r[2], &ZeroVec, lod,    /* S, T, P, C, LOD */
-                  NULL, offsets, control,
-                  &r[0], &r[1], &r[2], &r[3]);  /* outputs */
-      break;
-
-   case TGSI_TEXTURE_1D_ARRAY:
-      FETCH(&r[0], 0, TGSI_CHAN_X);
-      FETCH(&r[1], 0, TGSI_CHAN_Y);
-
-      if (modifier == TEX_MODIFIER_PROJECTED) {
-         micro_div(&r[0], &r[0], &r[3]);
+      else {
+         assert(shadow_ref != 4);
+         FETCH(&r[last], 1, TGSI_CHAN_X);
       }
 
-      fetch_texel(mach->Sampler, unit, unit,
-                  &r[0], &r[1], &ZeroVec, &ZeroVec, lod,   /* S, T, P, C, LOD */
-                  NULL, offsets, control,
-                  &r[0], &r[1], &r[2], &r[3]);  /* outputs */
-      break;
-   case TGSI_TEXTURE_SHADOW1D_ARRAY:
-      FETCH(&r[0], 0, TGSI_CHAN_X);
-      FETCH(&r[1], 0, TGSI_CHAN_Y);
-      FETCH(&r[2], 0, TGSI_CHAN_Z);
-
-      if (modifier == TEX_MODIFIER_PROJECTED) {
-         micro_div(&r[0], &r[0], &r[3]);
-         micro_div(&r[2], &r[2], &r[3]);
+      if (modifier != TEX_MODIFIER_PROJECTED) {
+         args[last] = &r[last];
       }
-
-      fetch_texel(mach->Sampler, unit, unit,
-                  &r[0], &r[1], &r[2], &ZeroVec, lod,   /* S, T, P, C, LOD */
-                  NULL, offsets, control,
-                  &r[0], &r[1], &r[2], &r[3]);  /* outputs */
-      break;
-
-   case TGSI_TEXTURE_2D_ARRAY:
-      FETCH(&r[0], 0, TGSI_CHAN_X);
-      FETCH(&r[1], 0, TGSI_CHAN_Y);
-      FETCH(&r[2], 0, TGSI_CHAN_Z);
-
-      if (modifier == TEX_MODIFIER_PROJECTED) {
-         micro_div(&r[0], &r[0], &r[3]);
-         micro_div(&r[1], &r[1], &r[3]);
+      else {
+         proj = &r[last];
+         args[last] = &ZeroVec;
       }
 
-      fetch_texel(mach->Sampler, unit, unit,
-                  &r[0], &r[1], &r[2], &ZeroVec, lod,   /* S, T, P, C, LOD */
-                  NULL, offsets, control,
-                  &r[0], &r[1], &r[2], &r[3]);  /* outputs */
-      break;
-   case TGSI_TEXTURE_SHADOW2D_ARRAY:
-   case TGSI_TEXTURE_SHADOWCUBE:
-      FETCH(&r[0], 0, TGSI_CHAN_X);
-      FETCH(&r[1], 0, TGSI_CHAN_Y);
-      FETCH(&r[2], 0, TGSI_CHAN_Z);
-      FETCH(&r[3], 0, TGSI_CHAN_W);
-
-      fetch_texel(mach->Sampler, unit, unit,
-                  &r[0], &r[1], &r[2], &r[3], &ZeroVec,    /* S, T, P, C, LOD */
-                  NULL, offsets, control,
-                  &r[0], &r[1], &r[2], &r[3]);  /* outputs */
-      break;
-   case TGSI_TEXTURE_CUBE_ARRAY:
-      FETCH(&r[0], 0, TGSI_CHAN_X);
-      FETCH(&r[1], 0, TGSI_CHAN_Y);
-      FETCH(&r[2], 0, TGSI_CHAN_Z);
-      FETCH(&r[3], 0, TGSI_CHAN_W);
+      /* point unused arguments to zero vector */
+      for (i = dim; i < last; i++)
+         args[i] = &ZeroVec;
 
-      if (modifier == TEX_MODIFIER_EXPLICIT_LOD ||
-          modifier == TEX_MODIFIER_LOD_BIAS)
-         FETCH(&cubelod, 1, TGSI_CHAN_X);
-      else
-         cubelod = ZeroVec;
+      if (modifier == TEX_MODIFIER_EXPLICIT_LOD)
+         control = tgsi_sampler_lod_explicit;
+      else if (modifier == TEX_MODIFIER_LOD_BIAS)
+         control = tgsi_sampler_lod_bias;
+   }
+   else {
+      for (i = dim; i < Elements(args); i++)
+         args[i] = &ZeroVec;
+   }
 
-      fetch_texel(mach->Sampler, unit, unit,
-                  &r[0], &r[1], &r[2], &r[3], &cubelod,    /* S, T, P, C, LOD */
-                  NULL, offsets, control,
-                  &r[0], &r[1], &r[2], &r[3]);  /* outputs */
-      break;
-   case TGSI_TEXTURE_3D:
-   case TGSI_TEXTURE_CUBE:
-      FETCH(&r[0], 0, TGSI_CHAN_X);
-      FETCH(&r[1], 0, TGSI_CHAN_Y);
-      FETCH(&r[2], 0, TGSI_CHAN_Z);
+   /* fetch coordinates */
+   for (i = 0; i < dim; i++) {
+      FETCH(&r[i], 0, TGSI_CHAN_X + i);
 
-      if (modifier == TEX_MODIFIER_PROJECTED) {
-         micro_div(&r[0], &r[0], &r[3]);
-         micro_div(&r[1], &r[1], &r[3]);
-         micro_div(&r[2], &r[2], &r[3]);
-      }
+      if (proj)
+         micro_div(&r[i], &r[i], proj);
 
-      fetch_texel(mach->Sampler, unit, unit,
-                  &r[0], &r[1], &r[2], &ZeroVec, lod,
-                  NULL, offsets, control,
-                  &r[0], &r[1], &r[2], &r[3]);
-      break;
+      args[i] = &r[i];
+   }
 
-   case TGSI_TEXTURE_SHADOWCUBE_ARRAY:
-      FETCH(&r[0], 0, TGSI_CHAN_X);
-      FETCH(&r[1], 0, TGSI_CHAN_Y);
-      FETCH(&r[2], 0, TGSI_CHAN_Z);
-      FETCH(&r[3], 0, TGSI_CHAN_W);
+   /* fetch reference value */
+   if (shadow_ref >= 0) {
+      FETCH(&r[shadow_ref], shadow_ref / 4, TGSI_CHAN_X + (shadow_ref % 4));
 
-      FETCH(&cubearraycomp, 1, TGSI_CHAN_X);
+      if (proj)
+         micro_div(&r[shadow_ref], &r[shadow_ref], proj);
 
-      fetch_texel(mach->Sampler, unit, unit,
-                  &r[0], &r[1], &r[2], &r[3], &cubearraycomp, /* S, T, P, C, LOD */
-                  NULL, offsets, control,
-                  &r[0], &r[1], &r[2], &r[3]);  /* outputs */
-      break;
-   default:
-      assert(0);
+      args[shadow_ref] = &r[shadow_ref];
    }
 
+   fetch_texel(mach->Sampler, unit, unit,
+         args[0], args[1], args[2], args[3], args[4],
+         NULL, offsets, control,
+         &r[0], &r[1], &r[2], &r[3]);     /* R, G, B, A */
+
 #if 0
    debug_printf("fetch r: %g %g %g %g\n",
          r[0].f[0], r[0].f[1], r[0].f[2], r[0].f[3]);




More information about the mesa-commit mailing list