diff options
author | Brian Paul <brianp@vmware.com> | 2010-11-03 17:29:28 -0600 |
---|---|---|
committer | Brian Paul <brianp@vmware.com> | 2010-11-03 17:34:07 -0600 |
commit | 2fefbc79ac8bb55197ff817feeca2626585d7a8c (patch) | |
tree | cbee9b063a64bfedeccdecbc8bc99ce87f24d047 /src/gallium | |
parent | c180e95d267c302c40e1cb92e5b134b4e370ef2e (diff) |
gallivm: implement scatter stores into temp register file
Something is not quite right, however. The piglit tests mentioned in
fd.o bug 31226 still don't pass.
Diffstat (limited to 'src/gallium')
-rw-r--r-- | src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c | 51 |
1 files changed, 47 insertions, 4 deletions
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c b/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c index 3c318cc8c8..cb0ece83ea 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c +++ b/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c @@ -468,8 +468,34 @@ build_gather(struct lp_build_tgsi_soa_context *bld, /** + * Scatter/store vector. + */ +static void +build_scatter(struct lp_build_tgsi_soa_context *bld, + LLVMValueRef base_ptr, + LLVMValueRef indexes, + LLVMValueRef values) +{ + LLVMBuilderRef builder = bld->base.builder; + unsigned i; + + /* + * Loop over elements of index_vec, store scalar value. + */ + for (i = 0; i < bld->base.type.length; i++) { + LLVMValueRef ii = LLVMConstInt(LLVMInt32Type(), i, 0); + LLVMValueRef index = LLVMBuildExtractElement(builder, indexes, ii, ""); + LLVMValueRef scalar_ptr = LLVMBuildGEP(builder, base_ptr, &index, 1, "scatter_ptr"); + LLVMValueRef val = LLVMBuildExtractElement(builder, values, ii, "scatter_val"); + + LLVMBuildStore(builder, val, scalar_ptr); + } +} + + +/** * Read the current value of the ADDR register, convert the floats to - * ints, multiply by four and return the vector of offsets. + * ints, add the base index and return the vector of offsets. * The offsets will be used to index into the constant buffer or * temporary register file. */ @@ -748,6 +774,7 @@ emit_store( LLVMValueRef value) { const struct tgsi_full_dst_register *reg = &inst->Dst[index]; + struct lp_build_context *uint_bld = &bld->uint_bld; LLVMValueRef indirect_index = NULL; switch( inst->Instruction.Saturate ) { @@ -785,9 +812,25 @@ emit_store( case TGSI_FILE_TEMPORARY: if (reg->Register.Indirect) { - /* XXX not done yet */ - debug_printf("WARNING: LLVM scatter store of temp regs" - " not implemented\n"); + LLVMValueRef chan_vec = + lp_build_const_int_vec(uint_bld->type, chan_index); + LLVMValueRef length_vec = + lp_build_const_int_vec(uint_bld->type, bld->base.type.length); + LLVMValueRef index_vec; /* indexes into the temp registers */ + LLVMValueRef temps_array; + LLVMTypeRef float_ptr_type; + + /* index_vec = (indirect_index * 4 + chan_index) * length */ + index_vec = lp_build_shl_imm(uint_bld, indirect_index, 2); + index_vec = lp_build_add(uint_bld, index_vec, chan_vec); + index_vec = lp_build_mul(uint_bld, index_vec, length_vec); + + float_ptr_type = LLVMPointerType(LLVMFloatType(), 0); + temps_array = LLVMBuildBitCast(bld->base.builder, bld->temps_array, + float_ptr_type, ""); + + /* Scatter store values into temp registers */ + build_scatter(bld, temps_array, index_vec, value); } else { LLVMValueRef temp_ptr = get_temp_ptr(bld, reg->Register.Index, |