[Mesa-dev] [PATCH] gallivm: hook up dx10 sampling opcodes

Roland Scheidegger sroland at vmware.com
Fri Feb 1 14:02:59 PST 2013


Am 01.02.2013 21:00, schrieb Brian Paul:
> On 02/01/2013 12:39 PM, sroland at vmware.com wrote:
>> From: Roland Scheidegger<sroland at vmware.com>
>>
>> They are similar to old-style tex opcodes but with separate sampler and
>> texture units (and other arguments in different places).
>> Also adjust the debug tgsi dump code.
>> ---
>>   src/gallium/auxiliary/gallivm/lp_bld_tgsi.h      |    6 +-
>>   src/gallium/auxiliary/gallivm/lp_bld_tgsi_info.c |  115 ++++++++-
>>   src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c  |  291
>> ++++++++++++++++++++++
>>   3 files changed, 406 insertions(+), 6 deletions(-)
>>
>> diff --git a/src/gallium/auxiliary/gallivm/lp_bld_tgsi.h
>> b/src/gallium/auxiliary/gallivm/lp_bld_tgsi.h
>> index 4898849..5d6b737 100644
>> --- a/src/gallium/auxiliary/gallivm/lp_bld_tgsi.h
>> +++ b/src/gallium/auxiliary/gallivm/lp_bld_tgsi.h
>> @@ -68,7 +68,8 @@ enum lp_build_tex_modifier {
>>      LP_BLD_TEX_MODIFIER_PROJECTED,
>>      LP_BLD_TEX_MODIFIER_LOD_BIAS,
>>      LP_BLD_TEX_MODIFIER_EXPLICIT_LOD,
>> -   LP_BLD_TEX_MODIFIER_EXPLICIT_DERIV
>> +   LP_BLD_TEX_MODIFIER_EXPLICIT_DERIV,
>> +   LP_BLD_TEX_MODIFIER_LZ
> 
> Could you put a comment on the last one to say what LZ means?
Sure. Better yet, I'll rename it to LOD_ZERO.

> 
> 
>>   };
>>
>>
>> @@ -104,7 +105,8 @@ struct lp_tgsi_texture_info
>>   {
>>      struct lp_tgsi_channel_info coord[4];
>>      unsigned target:8; /* TGSI_TEXTURE_* */
>> -   unsigned unit:8;  /* Sampler unit */
>> +   unsigned sampler_unit:8;  /* Sampler unit */
>> +   unsigned texture_unit:8;  /* Texture unit */
>>      unsigned modifier:8; /* LP_BLD_TEX_MODIFIER_* */
> 
> Maybe we could just use ubyte instead of bitfields?
There's more bitfiled usage around there so this looks more consistent.
That said, using 8 bits for all of these seems arbitrary,
target would only require 5 bits, sampler_unit 4, texture_unit 7 (for
dx10 limits) and modifier only 3... At least for target/modifier I'm not
sure why they are using 8 bits.

> 
> 
>>   };
>>
>> diff --git a/src/gallium/auxiliary/gallivm/lp_bld_tgsi_info.c
>> b/src/gallium/auxiliary/gallivm/lp_bld_tgsi_info.c
>> index 1c54ef9..2a445d6 100644
>> --- a/src/gallium/auxiliary/gallivm/lp_bld_tgsi_info.c
>> +++ b/src/gallium/auxiliary/gallivm/lp_bld_tgsi_info.c
>> @@ -140,14 +140,104 @@ analyse_tex(struct analysis_context *ctx,
>>         if (modifier == LP_BLD_TEX_MODIFIER_EXPLICIT_DERIV) {
>>            /* We don't track explicit derivatives, although we could */
>>            indirect = TRUE;
>> -         tex_info->unit = inst->Src[3].Register.Index;
>> +         tex_info->sampler_unit = inst->Src[3].Register.Index;
>> +         tex_info->texture_unit = inst->Src[3].Register.Index;
>>         }  else {
>>            if (modifier == LP_BLD_TEX_MODIFIER_PROJECTED ||
>>                modifier == LP_BLD_TEX_MODIFIER_LOD_BIAS ||
>>                modifier == LP_BLD_TEX_MODIFIER_EXPLICIT_LOD) {
>>               readmask |= TGSI_WRITEMASK_W;
>>            }
>> -         tex_info->unit = inst->Src[1].Register.Index;
>> +         tex_info->sampler_unit = inst->Src[1].Register.Index;
>> +         tex_info->texture_unit = inst->Src[1].Register.Index;
>> +      }
>> +
>> +      for (chan = 0; chan<  4; ++chan) {
>> +         struct lp_tgsi_channel_info *chan_info =&tex_info->coord[chan];
>> +         if (readmask&  (1<<  chan)) {
>> +            analyse_src(ctx, chan_info,&inst->Src[0].Register, chan);
>> +            if (chan_info->file != TGSI_FILE_INPUT) {
>> +               indirect = TRUE;
>> +            }
>> +         } else {
>> +            memset(chan_info, 0, sizeof *chan_info);
>> +         }
>> +      }
>> +
>> +      if (indirect) {
>> +         info->indirect_textures = TRUE;
>> +      }
>> +
>> +      ++info->num_texs;
>> +   } else {
>> +      info->indirect_textures = TRUE;
>> +   }
>> +}
>> +
>> +
>> +static void
>> +analyse_sample(struct analysis_context *ctx,
>> +               const struct tgsi_full_instruction *inst,
>> +               enum lp_build_tex_modifier modifier)
> 
> It would be good to have a comment on this function (and analyse_tex())
> to say something about what they do.
Ok.

> 
> 
>> +{
>> +   struct lp_tgsi_info *info = ctx->info;
>> +   unsigned chan;
>> +
>> +   if (info->num_texs<  Elements(info->tex)) {
>> +      struct lp_tgsi_texture_info *tex_info =&info->tex[info->num_texs];
>> +      boolean indirect = FALSE;
>> +      boolean shadow = FALSE;
>> +      unsigned readmask = 0;
>> +
>> +      tex_info->target = inst->Texture.Texture;
>> +      switch (inst->Texture.Texture) {
>> +      case TGSI_TEXTURE_SHADOW1D:
>> +         shadow = TRUE;
>> +         /* Fallthrough */
>> +      case TGSI_TEXTURE_1D:
>> +         readmask = TGSI_WRITEMASK_X;
>> +         break;
>> +      case TGSI_TEXTURE_SHADOW1D_ARRAY:
>> +      case TGSI_TEXTURE_SHADOW2D:
>> +      case TGSI_TEXTURE_SHADOWRECT:
>> +         shadow = TRUE;
>> +         /* Fallthrough */
>> +      case TGSI_TEXTURE_1D_ARRAY:
>> +      case TGSI_TEXTURE_2D:
>> +      case TGSI_TEXTURE_RECT:
>> +         readmask = TGSI_WRITEMASK_XY;
>> +         break;
>> +      case TGSI_TEXTURE_SHADOW2D_ARRAY:
>> +      case TGSI_TEXTURE_SHADOWCUBE:
>> +         shadow = TRUE;
>> +         /* Fallthrough */
>> +      case TGSI_TEXTURE_2D_ARRAY:
>> +      case TGSI_TEXTURE_3D:
>> +      case TGSI_TEXTURE_CUBE:
>> +         readmask = TGSI_WRITEMASK_XYZ;
>> +         break;
>> +      case TGSI_TEXTURE_SHADOWCUBE_ARRAY:
>> +         shadow = TRUE;
>> +         /* Fallthrough */
>> +      case TGSI_TEXTURE_CUBE_ARRAY:
>> +         readmask = TGSI_WRITEMASK_XYZW;
>> +         break;
>> +      default:
>> +         assert(0);
>> +         return;
>> +      }
>> +
>> +      tex_info->texture_unit = inst->Src[1].Register.Index;
>> +      tex_info->sampler_unit = inst->Src[2].Register.Index;
>> +
>> +      if (modifier == LP_BLD_TEX_MODIFIER_EXPLICIT_DERIV ||
>> +          modifier == LP_BLD_TEX_MODIFIER_LOD_BIAS || shadow) {
>> +         /* We don't track insts with additional regs, although we
>> could */
>> +         indirect = TRUE;
>> +      }  else {
>> +         if (modifier == LP_BLD_TEX_MODIFIER_EXPLICIT_LOD) {
>> +            readmask |= TGSI_WRITEMASK_W;
>> +         }
>>         }
>>
>>         for (chan = 0; chan<  4; ++chan) {
>> @@ -229,6 +319,22 @@ analyse_instruction(struct analysis_context *ctx,
>>         case TGSI_OPCODE_TXP:
>>            analyse_tex(ctx, inst, LP_BLD_TEX_MODIFIER_PROJECTED);
>>            break;
>> +      case TGSI_OPCODE_SAMPLE:
>> +      case TGSI_OPCODE_SAMPLE_C:
>> +         analyse_sample(ctx, inst, LP_BLD_TEX_MODIFIER_NONE);
>> +         break;
>> +      case TGSI_OPCODE_SAMPLE_C_LZ:
>> +         analyse_sample(ctx, inst, LP_BLD_TEX_MODIFIER_LZ);
>> +         break;
>> +      case TGSI_OPCODE_SAMPLE_D:
>> +         analyse_sample(ctx, inst, LP_BLD_TEX_MODIFIER_EXPLICIT_DERIV);
>> +         break;
>> +      case TGSI_OPCODE_SAMPLE_B:
>> +         analyse_sample(ctx, inst, LP_BLD_TEX_MODIFIER_LOD_BIAS);
>> +         break;
>> +      case TGSI_OPCODE_SAMPLE_L:
>> +         analyse_sample(ctx, inst, LP_BLD_TEX_MODIFIER_EXPLICIT_LOD);
>> +         break;
>>         default:
>>            break;
>>         }
>> @@ -355,8 +461,9 @@ dump_info(const struct tgsi_token *tokens,
>>               debug_printf(" _");
>>            }
>>         }
>> -      debug_printf(", SAMP[%u], %s\n",
>> -                   tex_info->unit,
>> +      debug_printf(", RES[%u], SAMP[%u], %s\n",
>> +                   tex_info->texture_unit,
>> +                   tex_info->sampler_unit,
>>                      tgsi_texture_names[tex_info->target]);
>>      }
>>
>> diff --git a/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c
>> b/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c
>> index 0621fb4..c6801ac 100644
>> --- a/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c
>> +++ b/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c
>> @@ -1340,6 +1340,197 @@ emit_tex( struct lp_build_tgsi_soa_context *bld,
>>   }
>>
>>   static void
>> +emit_sample(struct lp_build_tgsi_soa_context *bld,
>> +            const struct tgsi_full_instruction *inst,
>> +            enum lp_build_tex_modifier modifier,
>> +            LLVMValueRef *texel)
>> +{
>> +   LLVMBuilderRef builder = bld->bld_base.base.gallivm->builder;
>> +   struct gallivm_state *gallivm = bld->bld_base.base.gallivm;
>> +   unsigned texture_unit, sampler_unit;
>> +   LLVMValueRef lod_bias, explicit_lod;
>> +   LLVMValueRef coords[4];
>> +   LLVMValueRef offsets[3] = { NULL };
>> +   struct lp_derivatives derivs;
>> +   unsigned num_coords, dims;
>> +   unsigned i;
>> +   boolean compare = FALSE;
>> +
>> +   if (!bld->sampler) {
>> +      _debug_printf("warning: found texture instruction but no
>> sampler generator supplied\n");
>> +      for (i = 0; i<  4; i++) {
>> +         texel[i] = bld->bld_base.base.undef;
>> +      }
>> +      return;
>> +   }
>> +
>> +   derivs.ddx_ddy[0] = bld->bld_base.base.undef;
>> +   derivs.ddx_ddy[1] = bld->bld_base.base.undef;
>> +
>> +   switch (inst->Texture.Texture) {
>> +   case TGSI_TEXTURE_SHADOW1D:
>> +      compare = TRUE;
>> +      /* Fallthrough */
>> +   case TGSI_TEXTURE_1D:
>> +      num_coords = 1;
>> +      dims = 1;
>> +      break;
>> +   case TGSI_TEXTURE_SHADOW1D_ARRAY:
>> +      compare = TRUE;
>> +      /* Fallthrough */
>> +   case TGSI_TEXTURE_1D_ARRAY:
>> +      num_coords = 2;
>> +      dims = 1;
>> +      break;
>> +   case TGSI_TEXTURE_SHADOW2D:
>> +   case TGSI_TEXTURE_SHADOWRECT:
>> +      compare = TRUE;
>> +      /* Fallthrough */
>> +   case TGSI_TEXTURE_2D:
>> +   case TGSI_TEXTURE_RECT:
>> +      num_coords = 2;
>> +      dims = 2;
>> +      break;
>> +   case TGSI_TEXTURE_SHADOW2D_ARRAY:
>> +   case TGSI_TEXTURE_SHADOWCUBE:
>> +      compare = TRUE;
>> +      /* Fallthrough */
>> +   case TGSI_TEXTURE_2D_ARRAY:
>> +   case TGSI_TEXTURE_CUBE:
>> +      num_coords = 3;
>> +      dims = 2;
>> +      break;
>> +   case TGSI_TEXTURE_3D:
>> +      num_coords = 3;
>> +      dims = 3;
>> +      break;
>> +   case TGSI_TEXTURE_SHADOWCUBE_ARRAY:
>> +      compare = TRUE;
>> +      /* Fallthrough */
>> +   case TGSI_TEXTURE_CUBE_ARRAY:
>> +      num_coords = 4;
>> +      dims = 3;
>> +      break;
>> +   default:
>> +      assert(0);
>> +      return;
>> +   }
>> +
>> +   /* unlike tex opcodes the sampler/texture unit always come from
>> same reg */
>> +   texture_unit = inst->Src[1].Register.Index;
>> +   sampler_unit = inst->Src[2].Register.Index;
> 
> The comment and code don't seem to agree there.
> 
> [...]
Yes this needs reformulating. (The idea was that tex_unit is always
taken from reg 1, sampler_unit from reg 2 - unlike the old texture
opcodes where sampler doesn't have a fixed location but is last src reg
used instead.)

> 
> 
> Otherwise looks good AFAICT.
> 
> Reviewed-by: Brian Paul <brianp at vmware.com>


More information about the mesa-dev mailing list