X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;ds=sidebyside;f=src%2Fgallium%2Fauxiliary%2Fgallivm%2Flp_bld_tgsi_soa.c;h=ca8db9ce01d1320b7c100e02acd7963aebad3115;hb=72ae834fa16a32cc58ae7a93e74f6e11822fcac0;hp=4e640f5903c948068b73f044df4424aff6077c51;hpb=695814a15b4d64e1fa829d51f18c4089837929c3;p=mesa.git diff --git a/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c b/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c index 4e640f5903c..ca8db9ce01d 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c +++ b/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c @@ -133,10 +133,14 @@ struct lp_build_tgsi_soa_context LLVMValueRef addr[LP_MAX_TGSI_ADDRS][NUM_CHANNELS]; LLVMValueRef preds[LP_MAX_TGSI_PREDS][NUM_CHANNELS]; - /* we allocate an array of temps if we have indirect - * addressing and then the temps above is unused */ + /* We allocate/use this array of temps if (1 << TGSI_FILE_TEMPORARY) is + * set in the indirect_files field. + * The temps[] array above is unused then. + */ LLVMValueRef temps_array; - boolean has_indirect_addressing; + + /** bitmask indicating which register files are accessed indirectly */ + unsigned indirect_files; struct lp_build_mask_context *mask; struct lp_exec_mask exec_mask; @@ -408,25 +412,18 @@ static void lp_exec_mask_endsub(struct lp_exec_mask *mask, int *pc) /** * Return pointer to a temporary register channel (src or dest). + * Note that indirect addressing cannot be handled here. * \param index which temporary register * \param chan which channel of the temp register. - * \param is_indirect if true, add 'addr' to the index - * \param addr indirect addressing offset (should already have been - * multiplied by four). */ static LLVMValueRef get_temp_ptr(struct lp_build_tgsi_soa_context *bld, unsigned index, - unsigned chan, - boolean is_indirect, - LLVMValueRef addr) + unsigned chan) { assert(chan < 4); - if (bld->has_indirect_addressing) { - LLVMValueRef lindex = - LLVMConstInt(LLVMInt32Type(), index * 4 + chan, 0); - if (is_indirect) - lindex = lp_build_add(&bld->base, lindex, addr); + if (bld->indirect_files & (1 << TGSI_FILE_TEMPORARY)) { + LLVMValueRef lindex = lp_build_const_int32(index * 4 + chan); return LLVMBuildGEP(bld->base.builder, bld->temps_array, &lindex, 1, ""); } else { @@ -466,6 +463,38 @@ build_gather(struct lp_build_tgsi_soa_context *bld, } +/** + * Read the current value of the ADDR register, convert the floats to + * ints, multiply by four and return the vector of offsets. + * The offsets will be used to index into the constant buffer or + * temporary register file. + */ +static LLVMValueRef +get_indirect_offsets(struct lp_build_tgsi_soa_context *bld, + const struct tgsi_src_register *indirect_reg) +{ + /* always use X component of address register */ + const int x = indirect_reg->SwizzleX; + LLVMTypeRef int_vec_type = lp_build_int_vec_type(bld->base.type); + uint swizzle = tgsi_util_get_src_register_swizzle(indirect_reg, x); + LLVMValueRef vec4 = lp_build_const_int_vec(bld->int_bld.type, 4); + LLVMValueRef addr_vec; + + addr_vec = LLVMBuildLoad(bld->base.builder, + bld->addr[indirect_reg->Index][swizzle], + "load addr reg"); + + /* for indexing we want integers */ + addr_vec = LLVMBuildFPToSI(bld->base.builder, addr_vec, + int_vec_type, ""); + + /* addr_vec = addr_vec * 4 */ + addr_vec = lp_build_mul(&bld->int_bld, addr_vec, vec4); + + return addr_vec; +} + + /** * Register fetch. */ @@ -488,53 +517,38 @@ emit_fetch( } if (reg->Register.Indirect) { - LLVMTypeRef int_vec_type = lp_build_int_vec_type(bld->base.type); - unsigned swizzle = tgsi_util_get_src_register_swizzle( ®->Indirect, chan_index ); - - LLVMValueRef vec4 = lp_build_const_int_vec(bld->int_bld.type, 4); - - assert(bld->has_indirect_addressing); - - addr_vec = LLVMBuildLoad(bld->base.builder, - bld->addr[reg->Indirect.Index][swizzle], - "load addr"); - - /* for indexing we want integers */ - addr_vec = LLVMBuildFPToSI(bld->base.builder, addr_vec, - int_vec_type, ""); - - /* addr_vec = addr_vec * 4 */ - addr_vec = lp_build_mul(&bld->base, addr_vec, vec4); + assert(bld->indirect_files); + addr_vec = get_indirect_offsets(bld, ®->Indirect); } switch (reg->Register.File) { case TGSI_FILE_CONSTANT: - { - if (reg->Register.Indirect) { - LLVMValueRef index_vec; /* index into the const buffer */ + if (reg->Register.Indirect) { + LLVMValueRef index_vec; /* index into the const buffer */ - /* index_vec = broadcast(reg->Register.Index * 4 + swizzle) */ - index_vec = lp_build_const_int_vec(bld->int_bld.type, - reg->Register.Index * 4 + swizzle); + assert(bld->indirect_files & (1 << TGSI_FILE_CONSTANT)); - /* index_vec = index_vec + addr_vec */ - index_vec = lp_build_add(&bld->base, index_vec, addr_vec); + /* index_vec = broadcast(reg->Register.Index * 4 + swizzle) */ + index_vec = lp_build_const_int_vec(bld->int_bld.type, + reg->Register.Index * 4 + swizzle); - /* Gather values from the constant buffer */ - res = build_gather(bld, bld->consts_ptr, index_vec); - } - else { - LLVMValueRef index; /* index into the const buffer */ - LLVMValueRef scalar, scalar_ptr; + /* index_vec = index_vec + addr_vec */ + index_vec = lp_build_add(&bld->int_bld, index_vec, addr_vec); - index = lp_build_const_int32(reg->Register.Index*4 + swizzle); + /* Gather values from the constant buffer */ + res = build_gather(bld, bld->consts_ptr, index_vec); + } + else { + LLVMValueRef index; /* index into the const buffer */ + LLVMValueRef scalar, scalar_ptr; - scalar_ptr = LLVMBuildGEP(bld->base.builder, bld->consts_ptr, - &index, 1, ""); - scalar = LLVMBuildLoad(bld->base.builder, scalar_ptr, ""); + index = lp_build_const_int32(reg->Register.Index*4 + swizzle); - res = lp_build_broadcast_scalar(&bld->base, scalar); - } + scalar_ptr = LLVMBuildGEP(bld->base.builder, bld->consts_ptr, + &index, 1, ""); + scalar = LLVMBuildLoad(bld->base.builder, scalar_ptr, ""); + + res = lp_build_broadcast_scalar(&bld->base, scalar); } break; @@ -549,22 +563,38 @@ emit_fetch( break; case TGSI_FILE_TEMPORARY: - { - LLVMValueRef addr = NULL; - LLVMValueRef temp_ptr; + if (reg->Register.Indirect) { + LLVMValueRef vec_len = + lp_build_const_int_vec(bld->int_bld.type, bld->base.type.length); + LLVMValueRef index_vec; /* index into the const buffer */ + LLVMValueRef temps_array; + LLVMTypeRef float4_ptr_type; - if (reg->Register.Indirect) { - LLVMValueRef zero = lp_build_const_int32(0); - addr = LLVMBuildExtractElement(bld->base.builder, - addr_vec, zero, ""); - } + assert(bld->indirect_files & (1 << TGSI_FILE_TEMPORARY)); + + /* index_vec = broadcast(reg->Register.Index * 4 + swizzle) */ + index_vec = lp_build_const_int_vec(bld->int_bld.type, + reg->Register.Index * 4 + swizzle); + + /* index_vec += addr_vec */ + index_vec = lp_build_add(&bld->int_bld, index_vec, addr_vec); + + /* index_vec *= vector_length */ + index_vec = lp_build_mul(&bld->int_bld, index_vec, vec_len); + + /* cast temps_array pointer to float* */ + float4_ptr_type = LLVMPointerType(LLVMFloatType(), 0); + temps_array = LLVMBuildBitCast(bld->int_bld.builder, bld->temps_array, + float4_ptr_type, ""); - temp_ptr = get_temp_ptr(bld, reg->Register.Index, - swizzle, - reg->Register.Indirect, - addr); + /* Gather values from the temporary register array */ + res = build_gather(bld, temps_array, index_vec); + } + else { + LLVMValueRef temp_ptr; + temp_ptr = get_temp_ptr(bld, reg->Register.Index, swizzle); res = LLVMBuildLoad(bld->base.builder, temp_ptr, ""); - if(!res) + if (!res) return bld->base.undef; } break; @@ -582,11 +612,9 @@ emit_fetch( case TGSI_UTIL_SIGN_SET: /* TODO: Use bitwese OR for floating point */ res = lp_build_abs( &bld->base, res ); - res = LLVMBuildNeg( bld->base.builder, res, "" ); - break; - + /* fall through */ case TGSI_UTIL_SIGN_TOGGLE: - res = LLVMBuildNeg( bld->base.builder, res, "" ); + res = lp_build_negate( &bld->base, res ); break; case TGSI_UTIL_SIGN_KEEP: @@ -728,8 +756,12 @@ emit_store( } if (reg->Register.Indirect) { + /* XXX use get_indirect_offsets() here eventually */ LLVMTypeRef int_vec_type = lp_build_int_vec_type(bld->base.type); unsigned swizzle = tgsi_util_get_src_register_swizzle( ®->Indirect, chan_index ); + + assert(bld->indirect_files); + addr = LLVMBuildLoad(bld->base.builder, bld->addr[reg->Indirect.Index][swizzle], ""); @@ -739,7 +771,9 @@ emit_store( addr = LLVMBuildExtractElement(bld->base.builder, addr, LLVMConstInt(LLVMInt32Type(), 0, 0), ""); - addr = lp_build_mul(&bld->base, addr, LLVMConstInt(LLVMInt32Type(), 4, 0)); + addr = LLVMBuildMul(bld->base.builder, + addr, LLVMConstInt(LLVMInt32Type(), 4, 0), + ""); } switch( reg->Register.File ) { @@ -748,14 +782,18 @@ emit_store( bld->outputs[reg->Register.Index][chan_index]); break; - case TGSI_FILE_TEMPORARY: { - LLVMValueRef temp_ptr = get_temp_ptr(bld, reg->Register.Index, - chan_index, - reg->Register.Indirect, - addr); - lp_exec_mask_store(&bld->exec_mask, pred, value, temp_ptr); + case TGSI_FILE_TEMPORARY: + if (reg->Register.Indirect) { + /* XXX not done yet */ + debug_printf("WARNING: LLVM scatter store of temp regs" + " not implemented\n"); + } + else { + LLVMValueRef temp_ptr = get_temp_ptr(bld, reg->Register.Index, + chan_index); + lp_exec_mask_store(&bld->exec_mask, pred, value, temp_ptr); + } break; - } case TGSI_FILE_ADDRESS: lp_exec_mask_store(&bld->exec_mask, pred, value, @@ -764,7 +802,7 @@ emit_store( case TGSI_FILE_PREDICATE: lp_exec_mask_store(&bld->exec_mask, pred, value, - bld->preds[index][chan_index]); + bld->preds[reg->Register.Index][chan_index]); break; default: @@ -973,7 +1011,7 @@ emit_declaration( switch (decl->Declaration.File) { case TGSI_FILE_TEMPORARY: assert(idx < LP_MAX_TGSI_TEMPS); - if (bld->has_indirect_addressing) { + if (bld->indirect_files & (1 << TGSI_FILE_TEMPORARY)) { LLVMValueRef array_size = LLVMConstInt(LLVMInt32Type(), last*4 + 4, 0); bld->temps_array = lp_build_array_alloca(bld->base.builder, @@ -1997,8 +2035,7 @@ lp_build_tgsi_soa(LLVMBuilderRef builder, bld.outputs = outputs; bld.consts_ptr = consts_ptr; bld.sampler = sampler; - bld.has_indirect_addressing = info->opcode_count[TGSI_OPCODE_ARR] > 0 || - info->opcode_count[TGSI_OPCODE_ARL] > 0; + bld.indirect_files = info->indirect_files; bld.instructions = (struct tgsi_full_instruction *) MALLOC( LP_MAX_INSTRUCTIONS * sizeof(struct tgsi_full_instruction) ); bld.max_instructions = LP_MAX_INSTRUCTIONS;