Series looks good to me. Jose
----- Original Message ----- > 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 > immediate register with indirect addressing. > > Signed-off-by: Zack Rusin <za...@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, > + ®->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) { > -- > 1.7.10.4 > _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev