[Mesa-dev] [PATCH 2/2] gallivm/soa: implement indirect addressing in immediates

Roland Scheidegger sroland at vmware.com
Wed May 8 08:17:02 PDT 2013


Am 08.05.2013 05:16, schrieb Zack Rusin:
> The support is analogous to the way we handle indirect addressing
> in temporaries, except that we don't have to worry about storing
> (after declarations) and thus we'll able to keep using the old
> code when indirect addressing isn't used. In other words we're
> still using constants directly, unless the instrunction has
"instrunction"

> immediate register with indirect addressing.
> 
> Signed-off-by: Zack Rusin <zackr at vmware.com>
> ---
>  src/gallium/auxiliary/gallivm/lp_bld_tgsi.h     |    6 ++
>  src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c |   78 ++++++++++++++++++++++-
>  2 files changed, 82 insertions(+), 2 deletions(-)
> 
> diff --git a/src/gallium/auxiliary/gallivm/lp_bld_tgsi.h b/src/gallium/auxiliary/gallivm/lp_bld_tgsi.h
> index 9d9c742..fd566b1 100644
> --- a/src/gallium/auxiliary/gallivm/lp_bld_tgsi.h
> +++ b/src/gallium/auxiliary/gallivm/lp_bld_tgsi.h
> @@ -453,6 +453,12 @@ struct lp_build_tgsi_soa_context
>      */
>     LLVMValueRef inputs_array;
>  
> +   /* We allocate/use this array of temps if (1 << TGSI_FILE_IMMEDIATE) is
> +    * set in the indirect_files field.
> +    */
> +   LLVMValueRef imms_array;
> +
> +
>     struct lp_bld_tgsi_system_values system_values;
>  
>     /** bitmask indicating which register files are accessed indirectly */
> diff --git a/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c b/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c
> index 733f0ed..066f64a 100644
> --- a/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c
> +++ b/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c
> @@ -972,8 +972,58 @@ emit_fetch_immediate(
>     unsigned swizzle)
>  {
>     struct lp_build_tgsi_soa_context * bld = lp_soa_context(bld_base);
> -   LLVMValueRef res = bld->immediates[reg->Register.Index][swizzle];
> -   assert(res);
> +   struct gallivm_state *gallivm = bld->bld_base.base.gallivm;
> +   LLVMBuilderRef builder = gallivm->builder;
> +   struct lp_build_context *uint_bld = &bld_base->uint_bld;
> +   struct lp_build_context *float_bld = &bld_base->base;
> +   LLVMValueRef res = NULL;
> +   LLVMValueRef indirect_index = NULL;
> +
> +   if (reg->Register.Indirect) {
> +      indirect_index = get_indirect_index(bld,
> +                                          reg->Register.File,
> +                                          reg->Register.Index,
> +                                          &reg->Indirect);
> +   }
> +
> +   if (reg->Register.Indirect) {
> +      LLVMValueRef swizzle_vec =
> +         lp_build_const_int_vec(bld->bld_base.base.gallivm,
> +                                uint_bld->type, swizzle);
> +      LLVMValueRef length_vec =
> +         lp_build_const_int_vec(bld->bld_base.base.gallivm, uint_bld->type,
> +                                bld->bld_base.base.type.length);
> +      LLVMValueRef index_vec;  /* index into the const buffer */
> +      LLVMValueRef imms_array;
> +      LLVMValueRef pixel_offsets;
> +      LLVMValueRef offsets[LP_MAX_VECTOR_LENGTH];
> +      LLVMTypeRef float4_ptr_type;
> +      int i;
> +
> +      /* build pixel offset vector: {0, 1, 2, 3, ...} */
> +      for (i = 0; i < float_bld->type.length; i++) {
> +         offsets[i] = lp_build_const_int32(gallivm, i);
> +      }
> +      pixel_offsets = LLVMConstVector(offsets, float_bld->type.length);
> +
> +      /* index_vec = (indirect_index * 4 + swizzle) * length */
> +      index_vec = lp_build_shl_imm(uint_bld, indirect_index, 2);
> +      index_vec = lp_build_add(uint_bld, index_vec, swizzle_vec);
> +      index_vec = lp_build_mul(uint_bld, index_vec, length_vec);
> +      index_vec = lp_build_add(uint_bld, index_vec, pixel_offsets);
> +
> +      /* cast imms_array pointer to float* */
> +      float4_ptr_type = LLVMPointerType(
> +         LLVMFloatTypeInContext(bld->bld_base.base.gallivm->context), 0);
> +      imms_array = LLVMBuildBitCast(builder, bld->imms_array,
> +                                    float4_ptr_type, "");
> +
> +      /* Gather values from the temporary register array */
> +      res = build_gather(&bld_base->base, imms_array, index_vec);
> +   }
> +   else {
> +      res = bld->immediates[reg->Register.Index][swizzle];
> +   }
>  
>     if (stype == TGSI_TYPE_UNSIGNED) {
>        res = LLVMConstBitCast(res, bld_base->uint_bld.vec_type);
> @@ -2222,6 +2272,21 @@ void lp_emit_immediate_soa(
>     for( i = size; i < 4; ++i )
>        bld->immediates[bld->num_immediates][i] = bld_base->base.undef;
>  
> +   if (bld->indirect_files & (1 << TGSI_FILE_IMMEDIATE)) {
> +      unsigned index = bld->num_immediates;
> +      struct gallivm_state *gallivm = bld->bld_base.base.gallivm;
> +      LLVMBuilderRef builder = gallivm->builder;
> +      for (i = 0; i < 4; ++i ) {
> +         LLVMValueRef lindex = lp_build_const_int32(
> +            bld->bld_base.base.gallivm, index * 4 + i);
> +         LLVMValueRef imm_ptr = LLVMBuildGEP(builder,
> +                                             bld->imms_array, &lindex, 1, "");
> +         LLVMBuildStore(builder, 
> +                        bld->immediates[index][i],
> +                        imm_ptr);
> +      }
> +   }
> +
>     bld->num_immediates++;
>  }
>  
> @@ -2934,6 +2999,15 @@ static void emit_prologue(struct lp_build_tgsi_context * bld_base)
>                                                  "output_array");
>     }
>  
> +   if (bld->indirect_files & (1 << TGSI_FILE_IMMEDIATE)) {
> +      LLVMValueRef array_size =
> +         lp_build_const_int32(gallivm,
> +                         bld_base->info->file_max[TGSI_FILE_IMMEDIATE] * 4 + 4);
> +      bld->imms_array = lp_build_array_alloca(gallivm,
> +                                              bld_base->base.vec_type, array_size,
> +                                              "imms_array");
> +   }
> +
>     /* If we have indirect addressing in inputs we need to copy them into
>      * our alloca array to be able to iterate over them */
>     if (bld->indirect_files & (1 << TGSI_FILE_INPUT) && !bld->gs_iface) {
> 

Looks good to me. Though indirectly addressed immediates still sound
like a strange concept to me :-).

Roland


More information about the mesa-dev mailing list