[Mesa-dev] [PATCH 7/7] tgsi: use separate structure for indirect address

Christian König deathsimple at vodafone.de
Mon Mar 11 08:34:33 PDT 2013


Am 11.03.2013 15:52, schrieb Jose Fonseca:
> Christian,
>
> I didn't comment on the previous threads, but the approach mentioned in http://lists.freedesktop.org/archives/mesa-dev/2012-November/030476.html seems sensible to me.
>
> I think after the first round we should have this in a branch to allow drivers to catch up with the interface change. Or is it possible for drivers to opt-in via a cap?

Not the drivers are in question of changing, the state trackers are. If 
the drivers just ignore those additional informations nothing should 
change for them.

For the state trackers my current approach also doesn't need them to 
change, currently the semantics is as following:

If Declaration==0 then we fall back to the "old" behavior, e.g. the 
whole register file is indirectly addressed.
Else the state tracker (currently only glsl_to_tgsi) provided the 
necessary information in the Declaration field to only indirect address 
a certain part of the register file.

> Also, I think that a nice summary of how this is supposed to work in src/gallium/docs is a must.

Of course, yes. So far I haven't written ANY documentation at all. I 
just coded the patch and wanted to discuss all the details first before 
proceeding with anything that wouldn't be accepted.

> A few more remarks inline.
>
> ----- Original Message -----
>> From: Christian König <christian.koenig at amd.com>
>>
>> To further improve the optimization of source and destination
>> indirect addressing we need the ability to store a reference
>> to the declaration of the addressed operands.
> Just to be perfectly clear, declaration number does not refer to the n-th TEMP declaration, but declaration of TEMP[n], right?

No, currently it indeed refers to the n-th TEMP declaration. But I'm 
still fighting with myself weather or not that's a good idea.

> That is, this
>
>    DCL TEMP[1][0..70]
>    DCL TEMP[2][0..7]
>    MOV OUT[1], TEMP[1][ADDR[0].x]
>
> and this
>
>    DCL TEMP[2][0..7]
>    DCL TEMP[1][0..70]
>    MOV OUT[1], TEMP[1][ADDR[0].x]
>
> are equivalent, right?
>
> If so, I wonder if there is a name more descriptive than "Declaration" here. Maybe "Range", or "IndexableRange"?

Correct, yes. As said above, currently "Declaration" refers to the n-th 
declaration but I can easily add an "Indirect" flag to tgsi_declaration 
(there are still 6 bits of padding in it) and have an "IndirectRangeID" 
(or ArrayID, ArrayName, whatever, make your choice) token following the 
declaration.



>
>> Since most of the fields in tgsi_src_register doesn't apply for
>> an indirect addressing operand replace it with a separate
>> tgsi_ind_register structure and so make room for extra information.
>>
>> Signed-off-by: Christian König <christian.koenig at amd.com>
>> ---
>>   src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c    |    4 +-
>>   src/gallium/auxiliary/tgsi/tgsi_build.c            |  109
>>   +++++++++++---------
>>   src/gallium/auxiliary/tgsi/tgsi_dump.c             |   28 ++++-
>>   src/gallium/auxiliary/tgsi/tgsi_exec.c             |    8 +-
>>   src/gallium/auxiliary/tgsi/tgsi_parse.c            |   35 +------
>>   src/gallium/auxiliary/tgsi/tgsi_parse.h            |    8 +-
>>   src/gallium/auxiliary/tgsi/tgsi_text.c             |   98 +++++++++---------
>>   src/gallium/auxiliary/tgsi/tgsi_ureg.c             |   38 +++----
>>   src/gallium/auxiliary/tgsi/tgsi_ureg.h             |    7 ++
>>   src/gallium/auxiliary/tgsi/tgsi_util.c             |   18 ++++
>>   src/gallium/auxiliary/tgsi/tgsi_util.h             |    3 +
>>   src/gallium/drivers/i915/i915_fpc.h                |    8 +-
>>   src/gallium/drivers/nv30/nvfx_vertprog.c           |    2 +-
>>   .../drivers/nv50/codegen/nv50_ir_from_tgsi.cpp     |    6 ++
>>   src/gallium/drivers/r600/r600_llvm.c               |    2 +-
>>   src/gallium/include/pipe/p_shader_tokens.h         |   18 ++--
>>   16 files changed, 221 insertions(+), 171 deletions(-)
>>
>> diff --git a/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c
>> b/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c
>> index 69957fe..f8e011e 100644
>> --- a/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c
>> +++ b/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c
>> @@ -517,12 +517,12 @@ emit_mask_scatter(struct lp_build_tgsi_soa_context
>> *bld,
>>   static LLVMValueRef
>>   get_indirect_index(struct lp_build_tgsi_soa_context *bld,
>>                      unsigned reg_file, unsigned reg_index,
>> -                   const struct tgsi_src_register *indirect_reg)
>> +                   const struct tgsi_ind_register *indirect_reg)
>>   {
>>      LLVMBuilderRef builder = bld->bld_base.base.gallivm->builder;
>>      struct lp_build_context *uint_bld = &bld->bld_base.uint_bld;
>>      /* always use X component of address register */
>> -   unsigned swizzle = indirect_reg->SwizzleX;
>> +   unsigned swizzle = indirect_reg->Swizzle;
>>      LLVMValueRef base;
>>      LLVMValueRef rel;
>>      LLVMValueRef max_index;
>> diff --git a/src/gallium/auxiliary/tgsi/tgsi_build.c
>> b/src/gallium/auxiliary/tgsi/tgsi_build.c
>> index 33cbbd8..e71a6ea 100644
>> --- a/src/gallium/auxiliary/tgsi/tgsi_build.c
>> +++ b/src/gallium/auxiliary/tgsi/tgsi_build.c
>> @@ -816,6 +816,43 @@ tgsi_build_src_register(
>>      return src_register;
>>   }
>>   
>> +static struct tgsi_ind_register
>> +tgsi_default_ind_register( void )
>> +{
>> +   struct tgsi_ind_register ind_register;
>> +
>> +   ind_register.File = TGSI_FILE_NULL;
>> +   ind_register.Swizzle = TGSI_SWIZZLE_X;
>> +   ind_register.Declaration = 0;
>> +
>> +   return ind_register;
>> +}
>> +
>> +static struct tgsi_ind_register
>> +tgsi_build_ind_register(
>> +   unsigned file,
>> +   unsigned swizzle,
>> +   unsigned declaration,
>> +   int index,
>> +   struct tgsi_instruction *instruction,
>> +   struct tgsi_header *header )
>> +{
>> +   struct tgsi_ind_register   ind_register;
>> +
>> +   assert( file < TGSI_FILE_COUNT );
>> +   assert( swizzle <= TGSI_SWIZZLE_W );
>> +   assert( index >= -0x8000 && index <= 0x7FFF );
>> +
>> +   ind_register.File = file;
>> +   ind_register.Swizzle = swizzle;
>> +   ind_register.Index = index;
>> +   ind_register.Declaration = declaration;
>> +
>> +   instruction_grow( instruction, header );
>> +
>> +   return ind_register;
>> +}
>> +
>>   static struct tgsi_dimension
>>   tgsi_default_dimension( void )
>>   {
>> @@ -835,9 +872,9 @@ tgsi_default_full_src_register( void )
>>      struct tgsi_full_src_register full_src_register;
>>   
>>      full_src_register.Register = tgsi_default_src_register();
>> -   full_src_register.Indirect = tgsi_default_src_register();
>> +   full_src_register.Indirect = tgsi_default_ind_register();
>>      full_src_register.Dimension = tgsi_default_dimension();
>> -   full_src_register.DimIndirect = tgsi_default_src_register();
>> +   full_src_register.DimIndirect = tgsi_default_ind_register();
>>   
>>      return full_src_register;
>>   }
>> @@ -910,9 +947,9 @@ tgsi_default_full_dst_register( void )
>>      struct tgsi_full_dst_register full_dst_register;
>>   
>>      full_dst_register.Register = tgsi_default_dst_register();
>> -   full_dst_register.Indirect = tgsi_default_src_register();
>> +   full_dst_register.Indirect = tgsi_default_ind_register();
>>      full_dst_register.Dimension = tgsi_default_dimension();
>> -   full_dst_register.DimIndirect = tgsi_default_src_register();
>> +   full_dst_register.DimIndirect = tgsi_default_ind_register();
>>   
>>      return full_dst_register;
>>   }
>> @@ -1057,24 +1094,18 @@ tgsi_build_full_instruction(
>>            header );
>>   
>>         if( reg->Register.Indirect ) {
>> -         struct tgsi_src_register *ind;
>> +         struct tgsi_ind_register *ind;
>>   
>>            if( maxsize <= size )
>>               return 0;
>> -         ind = (struct tgsi_src_register *) &tokens[size];
>> +         ind = (struct tgsi_ind_register *) &tokens[size];
>>            size++;
>>   
>> -         *ind = tgsi_build_src_register(
>> +         *ind = tgsi_build_ind_register(
>>               reg->Indirect.File,
>> -            reg->Indirect.SwizzleX,
>> -            reg->Indirect.SwizzleY,
>> -            reg->Indirect.SwizzleZ,
>> -            reg->Indirect.SwizzleW,
>> -            reg->Indirect.Negate,
>> -            reg->Indirect.Absolute,
>> -            reg->Indirect.Indirect,
>> -            reg->Indirect.Dimension,
>> +            reg->Indirect.Swizzle,
>>               reg->Indirect.Index,
>> +            reg->Indirect.Declaration,
>>               instruction,
>>               header );
>>         }
>> @@ -1096,24 +1127,18 @@ tgsi_build_full_instruction(
>>               header );
>>   
>>            if( reg->Dimension.Indirect ) {
>> -            struct tgsi_src_register *ind;
>> +            struct tgsi_ind_register *ind;
>>   
>>               if( maxsize <= size )
>>                  return 0;
>> -            ind = (struct tgsi_src_register *) &tokens[size];
>> +            ind = (struct tgsi_ind_register *) &tokens[size];
>>               size++;
>>   
>> -            *ind = tgsi_build_src_register(
>> +            *ind = tgsi_build_ind_register(
>>                  reg->DimIndirect.File,
>> -               reg->DimIndirect.SwizzleX,
>> -               reg->DimIndirect.SwizzleY,
>> -               reg->DimIndirect.SwizzleZ,
>> -               reg->DimIndirect.SwizzleW,
>> -               reg->DimIndirect.Negate,
>> -               reg->DimIndirect.Absolute,
>> -               reg->DimIndirect.Indirect,
>> -               reg->DimIndirect.Dimension,
>> +               reg->DimIndirect.Swizzle,
>>                  reg->DimIndirect.Index,
>> +               reg->DimIndirect.Declaration,
>>                  instruction,
>>                  header );
>>            }
>> @@ -1144,24 +1169,18 @@ tgsi_build_full_instruction(
>>            header );
>>   
>>         if( reg->Register.Indirect ) {
>> -         struct  tgsi_src_register *ind;
>> +         struct  tgsi_ind_register *ind;
>>   
>>            if( maxsize <= size )
>>               return 0;
>> -         ind = (struct tgsi_src_register *) &tokens[size];
>> +         ind = (struct tgsi_ind_register *) &tokens[size];
>>            size++;
>>   
>> -         *ind = tgsi_build_src_register(
>> +         *ind = tgsi_build_ind_register(
>>               reg->Indirect.File,
>> -            reg->Indirect.SwizzleX,
>> -            reg->Indirect.SwizzleY,
>> -            reg->Indirect.SwizzleZ,
>> -            reg->Indirect.SwizzleW,
>> -            reg->Indirect.Negate,
>> -            reg->Indirect.Absolute,
>> -            reg->Indirect.Indirect,
>> -            reg->Indirect.Dimension,
>> +            reg->Indirect.Swizzle,
>>               reg->Indirect.Index,
>> +            reg->Indirect.Declaration,
>>               instruction,
>>               header );
>>         }
>> @@ -1183,24 +1202,18 @@ tgsi_build_full_instruction(
>>               header );
>>   
>>            if( reg->Dimension.Indirect ) {
>> -            struct tgsi_src_register *ind;
>> +            struct tgsi_ind_register *ind;
>>   
>>               if( maxsize <= size )
>>                  return 0;
>> -            ind = (struct tgsi_src_register *) &tokens[size];
>> +            ind = (struct tgsi_ind_register *) &tokens[size];
>>               size++;
>>   
>> -            *ind = tgsi_build_src_register(
>> +            *ind = tgsi_build_ind_register(
>>                  reg->DimIndirect.File,
>> -               reg->DimIndirect.SwizzleX,
>> -               reg->DimIndirect.SwizzleY,
>> -               reg->DimIndirect.SwizzleZ,
>> -               reg->DimIndirect.SwizzleW,
>> -               reg->DimIndirect.Negate,
>> -               reg->DimIndirect.Absolute,
>> -               reg->DimIndirect.Indirect,
>> -               reg->DimIndirect.Dimension,
>> +               reg->DimIndirect.Swizzle,
>>                  reg->DimIndirect.Index,
>> +               reg->DimIndirect.Declaration,
>>                  instruction,
>>                  header );
>>            }
>> diff --git a/src/gallium/auxiliary/tgsi/tgsi_dump.c
>> b/src/gallium/auxiliary/tgsi/tgsi_dump.c
>> index 177be0f..466fb13 100644
>> --- a/src/gallium/auxiliary/tgsi/tgsi_dump.c
>> +++ b/src/gallium/auxiliary/tgsi/tgsi_dump.c
>> @@ -102,12 +102,17 @@ _dump_register_src(
>>      ENM(src->Register.File, tgsi_file_names);
>>      if (src->Register.Dimension) {
>>         if (src->Dimension.Indirect) {
>> +         if (src->DimIndirect.Declaration) {
>> +            CHR( '[' );
>> +            SID( src->DimIndirect.Declaration );
>> +            CHR( ']' );
>> +         }
>>            CHR( '[' );
>>            ENM( src->DimIndirect.File, tgsi_file_names );
>>            CHR( '[' );
>>            SID( src->DimIndirect.Index );
>>            TXT( "]." );
>> -         ENM( src->DimIndirect.SwizzleX, tgsi_swizzle_names );
>> +         ENM( src->DimIndirect.Swizzle, tgsi_swizzle_names );
>>            if (src->Dimension.Index != 0) {
>>               if (src->Dimension.Index > 0)
>>                  CHR( '+' );
>> @@ -121,12 +126,17 @@ _dump_register_src(
>>         }
>>      }
>>      if (src->Register.Indirect) {
>> +      if (src->Indirect.Declaration) {
>> +         CHR( '[' );
>> +         SID( src->Indirect.Declaration );
>> +         CHR( ']' );
>> +      }
>>         CHR( '[' );
>>         ENM( src->Indirect.File, tgsi_file_names );
>>         CHR( '[' );
>>         SID( src->Indirect.Index );
>>         TXT( "]." );
>> -      ENM( src->Indirect.SwizzleX, tgsi_swizzle_names );
>> +      ENM( src->Indirect.Swizzle, tgsi_swizzle_names );
>>         if (src->Register.Index != 0) {
>>            if (src->Register.Index > 0)
>>               CHR( '+' );
>> @@ -149,12 +159,17 @@ _dump_register_dst(
>>      ENM(dst->Register.File, tgsi_file_names);
>>      if (dst->Register.Dimension) {
>>         if (dst->Dimension.Indirect) {
>> +         if (dst->DimIndirect.Declaration) {
>> +            CHR( '[' );
>> +            SID( dst->DimIndirect.Declaration );
>> +            CHR( ']' );
>> +         }
>>            CHR( '[' );
>>            ENM( dst->DimIndirect.File, tgsi_file_names );
>>            CHR( '[' );
>>            SID( dst->DimIndirect.Index );
>>            TXT( "]." );
>> -         ENM( dst->DimIndirect.SwizzleX, tgsi_swizzle_names );
>> +         ENM( dst->DimIndirect.Swizzle, tgsi_swizzle_names );
>>            if (dst->Dimension.Index != 0) {
>>               if (dst->Dimension.Index > 0)
>>                  CHR( '+' );
>> @@ -168,12 +183,17 @@ _dump_register_dst(
>>         }
>>      }
>>      if (dst->Register.Indirect) {
>> +      if (dst->Indirect.Declaration) {
>> +         CHR( '[' );
>> +         SID( dst->Indirect.Declaration );
>> +         CHR( ']' );
>> +      }
>>         CHR( '[' );
>>         ENM( dst->Indirect.File, tgsi_file_names );
>>         CHR( '[' );
>>         SID( dst->Indirect.Index );
>>         TXT( "]." );
>> -      ENM( dst->Indirect.SwizzleX, tgsi_swizzle_names );
>> +      ENM( dst->Indirect.Swizzle, tgsi_swizzle_names );
>>         if (dst->Register.Index != 0) {
>>            if (dst->Register.Index > 0)
>>               CHR( '+' );
>> diff --git a/src/gallium/auxiliary/tgsi/tgsi_exec.c
>> b/src/gallium/auxiliary/tgsi/tgsi_exec.c
>> index 838c4a8..3f5f182 100644
>> --- a/src/gallium/auxiliary/tgsi/tgsi_exec.c
>> +++ b/src/gallium/auxiliary/tgsi/tgsi_exec.c
>> @@ -1192,7 +1192,7 @@ fetch_source(const struct tgsi_exec_machine *mach,
>>         index2.i[2] =
>>         index2.i[3] = reg->Indirect.Index;
>>         /* get current value of address register[swizzle] */
>> -      swizzle = tgsi_util_get_src_register_swizzle( &reg->Indirect,
>> TGSI_CHAN_X );
>> +      swizzle = reg->Indirect.Swizzle;
>>         fetch_src_file_channel(mach,
>>                                chan_index,
>>                                reg->Indirect.File,
>> @@ -1252,7 +1252,7 @@ fetch_source(const struct tgsi_exec_machine *mach,
>>            index2.i[2] =
>>            index2.i[3] = reg->DimIndirect.Index;
>>   
>> -         swizzle = tgsi_util_get_src_register_swizzle( &reg->DimIndirect,
>> TGSI_CHAN_X );
>> +         swizzle = reg->DimIndirect.Swizzle;
>>            fetch_src_file_channel(mach,
>>                                   chan_index,
>>                                   reg->DimIndirect.File,
>> @@ -1356,7 +1356,7 @@ store_dest(struct tgsi_exec_machine *mach,
>>         index.i[3] = reg->Indirect.Index;
>>   
>>         /* get current value of address register[swizzle] */
>> -      swizzle = tgsi_util_get_src_register_swizzle( &reg->Indirect,
>> TGSI_CHAN_X );
>> +      swizzle = reg->Indirect.Swizzle;
>>   
>>         /* fetch values from the address/indirection register */
>>         fetch_src_file_channel(mach,
>> @@ -1408,7 +1408,7 @@ store_dest(struct tgsi_exec_machine *mach,
>>            index2.i[2] =
>>            index2.i[3] = reg->DimIndirect.Index;
>>   
>> -         swizzle = tgsi_util_get_src_register_swizzle( &reg->DimIndirect,
>> TGSI_CHAN_X );
>> +         swizzle = reg->DimIndirect.Swizzle;
>>            fetch_src_file_channel(mach,
>>                                   chan_index,
>>                                   reg->DimIndirect.File,
>> diff --git a/src/gallium/auxiliary/tgsi/tgsi_parse.c
>> b/src/gallium/auxiliary/tgsi/tgsi_parse.c
>> index 720d68d..4990871 100644
>> --- a/src/gallium/auxiliary/tgsi/tgsi_parse.c
>> +++ b/src/gallium/auxiliary/tgsi/tgsi_parse.c
>> @@ -196,15 +196,9 @@ tgsi_parse_token(
>>   
>>            next_token( ctx, &inst->Dst[i].Register );
>>   
>> -         if( inst->Dst[i].Register.Indirect ) {
>> +         if( inst->Dst[i].Register.Indirect )
>>               next_token( ctx, &inst->Dst[i].Indirect );
>>   
>> -            /*
>> -             * No support for indirect or multi-dimensional addressing.
>> -             */
>> -            assert( !inst->Dst[i].Indirect..Dimension );
>> -            assert( !inst->Dst[i].Indirect..Indirect );
>> -         }
>>            if( inst->Dst[i].Register.Dimension ) {
>>               next_token( ctx, &inst->Dst[i].Dimension );
>>   
>> @@ -213,15 +207,8 @@ tgsi_parse_token(
>>                */
>>               assert( !inst->Dst[i].Dimension.Dimension );
>>   
>> -            if( inst->Dst[i].Dimension.Indirect ) {
>> +            if( inst->Dst[i].Dimension.Indirect )
>>                  next_token( ctx, &inst->Dst[i].DimIndirect );
>> -
>> -               /*
>> -                * No support for indirect or multi-dimensional addressing.
>> -                */
>> -               assert( !inst->Dst[i].Indirect.Indirect );
>> -               assert( !inst->Dst[i].Indirect.Dimension );
>> -            }
>>            }
>>         }
>>   
>> @@ -231,16 +218,9 @@ tgsi_parse_token(
>>   
>>            next_token( ctx, &inst->Src[i].Register );
>>   
>> -         if( inst->Src[i].Register.Indirect ) {
>> +         if( inst->Src[i].Register.Indirect )
>>               next_token( ctx, &inst->Src[i].Indirect );
>>   
>> -            /*
>> -             * No support for indirect or multi-dimensional addressing.
>> -             */
>> -            assert( !inst->Src[i].Indirect..Indirect );
>> -            assert( !inst->Src[i].Indirect..Dimension );
>> -         }
>> -
>>            if( inst->Src[i].Register.Dimension ) {
>>               next_token( ctx, &inst->Src[i].Dimension );
>>   
>> @@ -249,15 +229,8 @@ tgsi_parse_token(
>>                */
>>               assert( !inst->Src[i].Dimension.Dimension );
>>   
>> -            if( inst->Src[i].Dimension.Indirect ) {
>> +            if( inst->Src[i].Dimension.Indirect )
>>                  next_token( ctx, &inst->Src[i].DimIndirect );
>> -
>> -               /*
>> -               * No support for indirect or multi-dimensional addressing.
>> -               */
>> -               assert( !inst->Src[i].Indirect.Indirect );
>> -               assert( !inst->Src[i].Indirect.Dimension );
>> -            }
>>            }
>>         }
>>   
>> diff --git a/src/gallium/auxiliary/tgsi/tgsi_parse.h
>> b/src/gallium/auxiliary/tgsi/tgsi_parse.h
>> index 78210ed..31aea1c 100644
>> --- a/src/gallium/auxiliary/tgsi/tgsi_parse.h
>> +++ b/src/gallium/auxiliary/tgsi/tgsi_parse.h
>> @@ -44,17 +44,17 @@ struct tgsi_full_header
>>   struct tgsi_full_dst_register
>>   {
>>      struct tgsi_dst_register               Register;
>> -   struct tgsi_src_register               Indirect;
>> +   struct tgsi_ind_register               Indirect;
>>      struct tgsi_dimension                  Dimension;
>> -   struct tgsi_src_register               DimIndirect;
>> +   struct tgsi_ind_register               DimIndirect;
>>   };
>>   
>>   struct tgsi_full_src_register
>>   {
>>      struct tgsi_src_register         Register;
>> -   struct tgsi_src_register         Indirect;
>> +   struct tgsi_ind_register         Indirect;
>>      struct tgsi_dimension            Dimension;
>> -   struct tgsi_src_register         DimIndirect;
>> +   struct tgsi_ind_register         DimIndirect;
>>   };
>>   
>>   struct tgsi_full_declaration
>> diff --git a/src/gallium/auxiliary/tgsi/tgsi_text.c
>> b/src/gallium/auxiliary/tgsi/tgsi_text.c
>> index 7d580e6..8ff73a5 100644
>> --- a/src/gallium/auxiliary/tgsi/tgsi_text.c
>> +++ b/src/gallium/auxiliary/tgsi/tgsi_text.c
>> @@ -441,6 +441,7 @@ struct parsed_bracket {
>>      uint ind_file;
>>      int ind_index;
>>      uint ind_comp;
>> +   uint ind_decl;
>>   };
>>   
>>   
>> @@ -449,59 +450,64 @@ parse_register_bracket(
>>      struct translate_ctx *ctx,
>>      struct parsed_bracket *brackets)
>>   {
>> -   const char *cur;
>>      uint uindex;
>>   
>>      memset(brackets, 0, sizeof(struct parsed_bracket));
>>   
>>      eat_opt_white( &ctx->cur );
>>   
>> -   cur = ctx->cur;
>> -   if (parse_file( &cur, &brackets->ind_file )) {
>> -      if (!parse_register_1d( ctx, &brackets->ind_file,
>> -                              &brackets->ind_index ))
>> -         return FALSE;
>> +   if (parse_uint( &ctx->cur, &uindex )) {
>>         eat_opt_white( &ctx->cur );
>> +      if (*ctx->cur != ']') {
>> +         report_error( ctx, "Expected `]'" );
>> +         return FALSE;
>> +      }
>> +      ctx->cur++;
>> +      if (*ctx->cur != '[') {
>> +         brackets->index = (int) uindex;
>> +         brackets->ind_file = TGSI_FILE_NULL;
>> +         brackets->ind_index = 0;
>> +         return TRUE;
>> +      }
>> +      brackets->ind_decl = uindex;
>> +   }
>> +
>> +   if (!parse_register_1d( ctx, &brackets->ind_file,
>> +                           &brackets->ind_index ))
>> +      return FALSE;
>>   
>> -      if (*ctx->cur == '.') {
>> -         ctx->cur++;
>> -         eat_opt_white(&ctx->cur);
>> +   eat_opt_white( &ctx->cur );
>>   
>> -         switch (uprcase(*ctx->cur)) {
>> -         case 'X':
>> -            brackets->ind_comp = TGSI_SWIZZLE_X;
>> -            break;
>> -         case 'Y':
>> -            brackets->ind_comp = TGSI_SWIZZLE_Y;
>> -            break;
>> -         case 'Z':
>> -            brackets->ind_comp = TGSI_SWIZZLE_Z;
>> -            break;
>> -         case 'W':
>> -            brackets->ind_comp = TGSI_SWIZZLE_W;
>> -            break;
>> -         default:
>> -            report_error(ctx, "Expected indirect register swizzle component
>> `x', `y', `z' or `w'");
>> -            return FALSE;
>> -         }
>> -         ctx->cur++;
>> -         eat_opt_white(&ctx->cur);
>> -      }
>> +   if (*ctx->cur == '.') {
>> +      ctx->cur++;
>> +      eat_opt_white(&ctx->cur);
>>   
>> -      if (*ctx->cur == '+' || *ctx->cur == '-')
>> -         parse_int( &ctx->cur, &brackets->index );
>> -      else
>> -         brackets->index = 0;
>> -   }
>> -   else {
>> -      if (!parse_uint( &ctx->cur, &uindex )) {
>> -         report_error( ctx, "Expected literal unsigned integer" );
>> +      switch (uprcase(*ctx->cur)) {
>> +      case 'X':
>> +         brackets->ind_comp = TGSI_SWIZZLE_X;
>> +         break;
>> +      case 'Y':
>> +         brackets->ind_comp = TGSI_SWIZZLE_Y;
>> +         break;
>> +      case 'Z':
>> +         brackets->ind_comp = TGSI_SWIZZLE_Z;
>> +         break;
>> +      case 'W':
>> +         brackets->ind_comp = TGSI_SWIZZLE_W;
>> +         break;
>> +      default:
>> +         report_error(ctx, "Expected indirect register swizzle component
>> `x', `y', `z' or `w'");
>>            return FALSE;
>>         }
>> -      brackets->index = (int) uindex;
>> -      brackets->ind_file = TGSI_FILE_NULL;
>> -      brackets->ind_index = 0;
>> +      ctx->cur++;
>> +      eat_opt_white(&ctx->cur);
>>      }
>> +
>> +   if (*ctx->cur == '+' || *ctx->cur == '-')
>> +      parse_int( &ctx->cur, &brackets->index );
>> +   else
>> +      brackets->index = 0;
>> +
>>      eat_opt_white( &ctx->cur );
>>      if (*ctx->cur != ']') {
>>         report_error( ctx, "Expected `]'" );
>> @@ -711,10 +717,8 @@ parse_dst_operand(
>>         dst->Register.Indirect = 1;
>>         dst->Indirect.File = bracket[0].ind_file;
>>         dst->Indirect.Index = bracket[0].ind_index;
>> -      dst->Indirect.SwizzleX = bracket[0].ind_comp;
>> -      dst->Indirect.SwizzleY = bracket[0].ind_comp;
>> -      dst->Indirect.SwizzleZ = bracket[0].ind_comp;
>> -      dst->Indirect.SwizzleW = bracket[0].ind_comp;
>> +      dst->Indirect.Swizzle = bracket[0].ind_comp;
>> +      dst->Indirect.Declaration = bracket[0].ind_decl;
>>      }
>>      return TRUE;
>>   }
>> @@ -797,10 +801,8 @@ parse_src_operand(
>>         src->Register.Indirect = 1;
>>         src->Indirect.File = bracket[0].ind_file;
>>         src->Indirect.Index = bracket[0].ind_index;
>> -      src->Indirect.SwizzleX = bracket[0].ind_comp;
>> -      src->Indirect.SwizzleY = bracket[0].ind_comp;
>> -      src->Indirect.SwizzleZ = bracket[0].ind_comp;
>> -      src->Indirect.SwizzleW = bracket[0].ind_comp;
>> +      src->Indirect.Swizzle = bracket[0].ind_comp;
>> +      src->Indirect.Declaration = bracket[0].ind_decl;
>>      }
>>   
>>      /* Parse optional swizzle.
>> diff --git a/src/gallium/auxiliary/tgsi/tgsi_ureg.c
>> b/src/gallium/auxiliary/tgsi/tgsi_ureg.c
>> index d5fa084..8f693e0 100644
>> --- a/src/gallium/auxiliary/tgsi/tgsi_ureg.c
>> +++ b/src/gallium/auxiliary/tgsi/tgsi_ureg.c
>> @@ -58,6 +58,7 @@ union tgsi_any_token {
>>      struct tgsi_instruction_texture insn_texture;
>>      struct tgsi_texture_offset insn_texture_offset;
>>      struct tgsi_src_register src;
>> +   struct tgsi_ind_register ind;
>>      struct tgsi_dimension dim;
>>      struct tgsi_dst_register dst;
>>      unsigned value;
>> @@ -155,6 +156,7 @@ struct ureg_program
>>      struct util_bitmask *local_temps;
>>      struct util_bitmask *decl_temps;
>>      unsigned nr_temps;
>> +   unsigned nr_decls;
>>   
>>      struct const_decl const_decls;
>>      struct const_decl const_decls2D[PIPE_MAX_CONSTANT_BUFFERS];
>> @@ -262,6 +264,7 @@ ureg_dst_register( unsigned file,
>>      dst.PredSwizzleZ = TGSI_SWIZZLE_Z;
>>      dst.PredSwizzleW = TGSI_SWIZZLE_W;
>>      dst.Index     = index;
>> +   dst.Declaration = 0;
>>   
>>      return dst;
>>   }
>> @@ -557,6 +560,9 @@ static struct ureg_dst alloc_temporary( struct
>> ureg_program *ureg,
>>         /* Start a new declaration when the local flag changes */
>>         if (!i || util_bitmask_get(ureg->local_temps, i - 1) != local)
>>            util_bitmask_set(ureg->decl_temps, i);
>> +
>> +      if (util_bitmask_get(ureg->decl_temps, i))
>> +         ureg->nr_decls++;
>>      }
>>   
>>      util_bitmask_clear(ureg->free_temps, i);
>> @@ -584,11 +590,13 @@ struct ureg_dst ureg_DECL_array_temporary( struct
>> ureg_program *ureg,
>>      if (local)
>>         util_bitmask_set(ureg->local_temps, i);
>>   
>> +   ureg->nr_decls++;
>>      util_bitmask_set(ureg->decl_temps, i);
>>   
>>      ureg->nr_temps += size;
>>      util_bitmask_set(ureg->decl_temps, ureg->nr_temps);
>>   
>> +   dst.Declaration = ureg->nr_decls;
>>      return dst;
>>   }
>>   
>> @@ -870,12 +878,10 @@ ureg_emit_src( struct ureg_program *ureg,
>>      if (src.Indirect) {
>>         out[0].src.Indirect = 1;
>>         out[n].value = 0;
>> -      out[n].src.File = src.IndirectFile;
>> -      out[n].src.SwizzleX = src.IndirectSwizzle;
>> -      out[n].src.SwizzleY = src.IndirectSwizzle;
>> -      out[n].src.SwizzleZ = src.IndirectSwizzle;
>> -      out[n].src.SwizzleW = src.IndirectSwizzle;
>> -      out[n].src.Index = src.IndirectIndex;
>> +      out[n].ind.File = src.IndirectFile;
>> +      out[n].ind.Swizzle = src.IndirectSwizzle;
>> +      out[n].ind.Index = src.IndirectIndex;
>> +      out[n].ind.Declaration = src.Declaration;
>>         n++;
>>      }
>>   
>> @@ -888,12 +894,10 @@ ureg_emit_src( struct ureg_program *ureg,
>>            out[n].dim.Index = src.DimensionIndex;
>>            n++;
>>            out[n].value = 0;
>> -         out[n].src.File = src.DimIndFile;
>> -         out[n].src.SwizzleX = src.DimIndSwizzle;
>> -         out[n].src.SwizzleY = src.DimIndSwizzle;
>> -         out[n].src.SwizzleZ = src.DimIndSwizzle;
>> -         out[n].src.SwizzleW = src.DimIndSwizzle;
>> -         out[n].src.Index = src.DimIndIndex;
>> +         out[n].ind.File = src.DimIndFile;
>> +         out[n].ind.Swizzle = src.DimIndSwizzle;
>> +         out[n].ind.Index = src.DimIndIndex;
>> +         out[n].ind.Declaration = src.Declaration;
>>         } else {
>>            out[n].dim.Indirect = 0;
>>            out[n].dim.Index = src.DimensionIndex;
>> @@ -932,12 +936,10 @@ ureg_emit_dst( struct ureg_program *ureg,
>>      
>>      if (dst.Indirect) {
>>         out[n].value = 0;
>> -      out[n].src.File = TGSI_FILE_ADDRESS;
>> -      out[n].src.SwizzleX = dst.IndirectSwizzle;
>> -      out[n].src.SwizzleY = dst.IndirectSwizzle;
>> -      out[n].src.SwizzleZ = dst.IndirectSwizzle;
>> -      out[n].src.SwizzleW = dst.IndirectSwizzle;
>> -      out[n].src.Index = dst.IndirectIndex;
>> +      out[n].ind.File = TGSI_FILE_ADDRESS;
>> +      out[n].ind.Swizzle = dst.IndirectSwizzle;
>> +      out[n].ind.Index = dst.IndirectIndex;
>> +      out[n].ind.Declaration = dst.Declaration;
>>         n++;
>>      }
>>   
>> diff --git a/src/gallium/auxiliary/tgsi/tgsi_ureg.h
>> b/src/gallium/auxiliary/tgsi/tgsi_ureg.h
>> index cd140de..6bb1f7f 100644
>> --- a/src/gallium/auxiliary/tgsi/tgsi_ureg.h
>> +++ b/src/gallium/auxiliary/tgsi/tgsi_ureg.h
>> @@ -62,6 +62,7 @@ struct ureg_src
>>      int      IndirectIndex    : 16; /* SINT */
>>      int      DimensionIndex   : 16; /* SINT */
>>      int      DimIndIndex      : 16; /* SINT */
>> +   unsigned Declaration      : 10; /* UINT */
>>   };
>>   
>>   /* Very similar to a tgsi_dst_register, removing unsupported fields
>> @@ -84,6 +85,7 @@ struct ureg_dst
>>      int      Index           : 16; /* SINT */
>>      int      IndirectIndex   : 16; /* SINT */
>>      int      IndirectSwizzle : 2;  /* TGSI_SWIZZLE_ */
>> +   unsigned Declaration     : 10; /* UINT */
>>   };
>>   
>>   struct pipe_context;
>> @@ -1129,6 +1131,7 @@ ureg_dst( struct ureg_src src )
>>      dst.PredSwizzleZ = TGSI_SWIZZLE_Z;
>>      dst.PredSwizzleW = TGSI_SWIZZLE_W;
>>      dst.Index     = src.Index;
>> +   dst.Declaration = src.Declaration;
>>   
>>      return dst;
>>   }
>> @@ -1157,6 +1160,7 @@ ureg_src_register(unsigned file,
>>      src.DimIndFile = TGSI_FILE_NULL;
>>      src.DimIndIndex = 0;
>>      src.DimIndSwizzle = 0;
>> +   src.Declaration = 0;
>>   
>>      return src;
>>   }
>> @@ -1184,6 +1188,7 @@ ureg_src( struct ureg_dst dst )
>>      src.DimIndFile = TGSI_FILE_NULL;
>>      src.DimIndIndex = 0;
>>      src.DimIndSwizzle = 0;
>> +   src.Declaration = dst.Declaration;
>>   
>>      return src;
>>   }
>> @@ -1208,6 +1213,7 @@ ureg_dst_undef( void )
>>      dst.PredSwizzleZ = TGSI_SWIZZLE_Z;
>>      dst.PredSwizzleW = TGSI_SWIZZLE_W;
>>      dst.Index     = 0;
>> +   dst.Declaration = 0;
>>   
>>      return dst;
>>   }
>> @@ -1235,6 +1241,7 @@ ureg_src_undef( void )
>>      src.DimIndFile = TGSI_FILE_NULL;
>>      src.DimIndIndex = 0;
>>      src.DimIndSwizzle = 0;
>> +   src.Declaration = 0;
>>   
>>      return src;
>>   }
>> diff --git a/src/gallium/auxiliary/tgsi/tgsi_util.c
>> b/src/gallium/auxiliary/tgsi/tgsi_util.c
>> index 8a5a8ea..dfd32d7 100644
>> --- a/src/gallium/auxiliary/tgsi/tgsi_util.c
>> +++ b/src/gallium/auxiliary/tgsi/tgsi_util.c
>> @@ -320,3 +320,21 @@ tgsi_util_get_inst_usage_mask(const struct
>> tgsi_full_instruction *inst,
>>   
>>      return usage_mask;
>>   }
>> +
>> +/**
>> + * Convert a tgsi_ind_register into a tgsi_src_register
>> + */
>> +struct tgsi_src_register
>> +tgsi_util_get_src_from_ind(const struct tgsi_ind_register *reg)
>> +{
>> +   struct tgsi_src_register src = {};
>> +
>> +   src.File = reg->File;
>> +   src.Index = reg->Index;
>> +   src.SwizzleX = reg->Swizzle;
>> +   src.SwizzleY = reg->Swizzle;
>> +   src.SwizzleZ = reg->Swizzle;
>> +   src.SwizzleW = reg->Swizzle;
>> +
>> +   return src;
>> +}
>> diff --git a/src/gallium/auxiliary/tgsi/tgsi_util.h
>> b/src/gallium/auxiliary/tgsi/tgsi_util.h
>> index 04702ba..d9f8859 100644
>> --- a/src/gallium/auxiliary/tgsi/tgsi_util.h
>> +++ b/src/gallium/auxiliary/tgsi/tgsi_util.h
>> @@ -76,6 +76,9 @@ unsigned
>>   tgsi_util_get_inst_usage_mask(const struct tgsi_full_instruction *inst,
>>                                 unsigned src_idx);
>>   
>> +struct tgsi_src_register
>> +tgsi_util_get_src_from_ind(const struct tgsi_ind_register *reg);
>> +
>>   #if defined __cplusplus
>>   }
>>   #endif
>> diff --git a/src/gallium/drivers/i915/i915_fpc.h
>> b/src/gallium/drivers/i915/i915_fpc.h
>> index 9e4a7ea..e915822 100644
>> --- a/src/gallium/drivers/i915/i915_fpc.h
>> +++ b/src/gallium/drivers/i915/i915_fpc.h
>> @@ -276,9 +276,9 @@ struct i915_full_dst_register
>>   {
>>      struct i915_dst_register               Register;
>>   /*
>> -   struct tgsi_src_register               Indirect;
>> +   struct tgsi_ind_register               Indirect;
>>      struct tgsi_dimension                  Dimension;
>> -   struct tgsi_src_register               DimIndirect;
>> +   struct tgsi_ind_register               DimIndirect;
>>   */
>>   };
>>   
>> @@ -286,9 +286,9 @@ struct i915_full_src_register
>>   {
>>      struct i915_src_register         Register;
>>   /*
>> -   struct tgsi_src_register         Indirect;
>> +   struct tgsi_ind_register         Indirect;
>>      struct tgsi_dimension            Dimension;
>> -   struct tgsi_src_register         DimIndirect;
>> +   struct tgsi_ind_register         DimIndirect;
>>   */
>>   };
>>   
>> diff --git a/src/gallium/drivers/nv30/nvfx_vertprog.c
>> b/src/gallium/drivers/nv30/nvfx_vertprog.c
>> index 827d518..74dba38 100644
>> --- a/src/gallium/drivers/nv30/nvfx_vertprog.c
>> +++ b/src/gallium/drivers/nv30/nvfx_vertprog.c
>> @@ -405,7 +405,7 @@ tgsi_src(struct nvfx_vpc *vpc, const struct
>> tgsi_full_src_register *fsrc) {
>>             fsrc->Register.File == TGSI_FILE_INPUT)) {
>>            src.indirect = 1;
>>            src.indirect_reg = fsrc->Indirect.Index;
>> -         src.indirect_swz = fsrc->Indirect.SwizzleX;
>> +         src.indirect_swz = fsrc->Indirect.Swizzle;
>>         } else {
>>            src.reg.index = 0;
>>            src.reg.type = -1;
>> diff --git a/src/gallium/drivers/nv50/codegen/nv50_ir_from_tgsi.cpp
>> b/src/gallium/drivers/nv50/codegen/nv50_ir_from_tgsi.cpp
>> index f5525b2..7e7b688 100644
>> --- a/src/gallium/drivers/nv50/codegen/nv50_ir_from_tgsi.cpp
>> +++ b/src/gallium/drivers/nv50/codegen/nv50_ir_from_tgsi.cpp
>> @@ -23,6 +23,7 @@
>>   extern "C" {
>>   #include "tgsi/tgsi_dump.h"
>>   #include "tgsi/tgsi_scan.h"
>> +#include "tgsi/tgsi_util.h"
>>   }
>>   
>>   #include "nv50_ir.h"
>> @@ -53,6 +54,11 @@ public:
>>   
>>         SrcRegister(const struct tgsi_src_register& src) : reg(src), fsr(NULL)
>>         { }
>>   
>> +      SrcRegister(const struct tgsi_ind_register& ind)
>> +         : reg(tgsi_util_get_src_from_ind(&ind)),
>> +           fsr(NULL)
>> +      { }
>> +
>>         struct tgsi_src_register offsetToSrc(struct tgsi_texture_offset off)
>>         {
>>            struct tgsi_src_register reg;
>> diff --git a/src/gallium/drivers/r600/r600_llvm.c
>> b/src/gallium/drivers/r600/r600_llvm.c
>> index c7aa45f..d256f22 100644
>> --- a/src/gallium/drivers/r600/r600_llvm.c
>> +++ b/src/gallium/drivers/r600/r600_llvm.c
>> @@ -35,7 +35,7 @@ static LLVMValueRef llvm_fetch_const(
>>           };
>>           if (reg->Register.Indirect) {
>>                   struct lp_build_tgsi_soa_context *bld = lp_soa_context(bld_base);
>> -                LLVMValueRef index = LLVMBuildLoad(bld_base->base..gallivm->builder,
>> bld->addr[reg->Indirect.Index][reg->Indirect.SwizzleX], "");
>> +                LLVMValueRef index = LLVMBuildLoad(bld_base->base..gallivm->builder,
>> bld->addr[reg->Indirect.Index][reg->Indirect.Swizzle], "");
>>                   offset[1] = LLVMBuildAdd(bld_base->base.gallivm->builder, offset[1],
>>                   index, "");
>>           }
>>           unsigned ConstantAddressSpace = CONSTANT_BUFFER_0_ADDR_SPACE ;
>> diff --git a/src/gallium/include/pipe/p_shader_tokens.h
>> b/src/gallium/include/pipe/p_shader_tokens.h
>> index 81e4a6b..6aa9ba5 100644
>> --- a/src/gallium/include/pipe/p_shader_tokens.h
>> +++ b/src/gallium/include/pipe/p_shader_tokens.h
>> @@ -583,14 +583,20 @@ struct tgsi_src_register
>>   };
>>   
>>   /**
>> - * If tgsi_src_register::Modifier is TRUE, tgsi_src_register_modifier
>> follows.
>> - *
>> - * Then, if tgsi_src_register::Indirect is TRUE, another tgsi_src_register
>> - * follows.
>> - *
>> - * Then, if tgsi_src_register::Dimension is TRUE, tgsi_dimension follows..
>> + * If tgsi_src_register::Indirect is TRUE, tgsi_ind_register follows.
>>    */
>>   
>> +struct tgsi_ind_register
>> +{
>> +   unsigned File        : 4;  /* TGSI_FILE_ */
>> +   int      Index       : 16; /* SINT */
>> +   unsigned Swizzle     : 2;  /* TGSI_SWIZZLE_ */
>> +   unsigned Declaration : 10; /* INT */
> I think you mean /* UINT */

Right, going to fix it.

>
>> +};
>> +
>> +/**
>> + * If tgsi_src_register::Dimension is TRUE, tgsi_dimension follows.
>> + */
>>   
>>   struct tgsi_dimension
>>   {
>> --
>> 1.7.9.5
>>
>> _______________________________________________
>> mesa-dev mailing list
>> mesa-dev at lists.freedesktop.org
>> http://lists.freedesktop.org/mailman/listinfo/mesa-dev
>>

Christian.


More information about the mesa-dev mailing list