[Mesa-dev] [PATCH 2/2] tgsi: clean up exec_tex()

Roland Scheidegger sroland at vmware.com
Tue May 7 05:51:59 PDT 2013


Am 07.05.2013 12:21, schrieb Chia-I Wu:
> 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>
> ---
>  src/gallium/auxiliary/tgsi/tgsi_exec.c |  220 ++++++++------------------------
>  1 file 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]);
> 

Provided there are no piglit regressions, series looks good to me.
As for array layer projection, I wouldn't worry too much about it.
GL_MESA_texture_array can do projected textures with fixed function (and
hence projection) but I couldn't figure out if the layer should be
projected or not. llvmpipe already does project it so it might just be
correct.

Roland


More information about the mesa-dev mailing list