diff options
author | Dave Airlie <[email protected]> | 2016-12-23 05:41:18 +0000 |
---|---|---|
committer | Dave Airlie <[email protected]> | 2016-12-26 10:31:20 +1000 |
commit | 4813c9ade70b4181ccf5d0ab462cf34da96373a6 (patch) | |
tree | 95e7f0b9565da3b6e20c233c56530730efccb9b4 | |
parent | d9fef848a651b47520cbeb72c38b93d4fbf842a8 (diff) |
radv: handle multi-component shared load/stores.
This was seen in doom shaders, so handle it properly.
Reviewed-by: Bas Nieuwenhuizen <[email protected]>
Signed-off-by: Dave AIrlie <[email protected]>
-rw-r--r-- | src/amd/common/ac_nir_to_llvm.c | 41 |
1 files changed, 29 insertions, 12 deletions
diff --git a/src/amd/common/ac_nir_to_llvm.c b/src/amd/common/ac_nir_to_llvm.c index 90ee917d13b..f214fcd006a 100644 --- a/src/amd/common/ac_nir_to_llvm.c +++ b/src/amd/common/ac_nir_to_llvm.c @@ -2244,13 +2244,15 @@ static LLVMValueRef visit_load_var(struct nir_to_llvm_context *ctx, &const_index, &indir_index); LLVMValueRef ptr = get_shared_memory_ptr(ctx, idx, ctx->i32); LLVMValueRef derived_ptr; - LLVMValueRef index = ctx->i32zero; - if (indir_index) - index = LLVMBuildAdd(ctx->builder, index, indir_index, ""); - derived_ptr = LLVMBuildGEP(ctx->builder, ptr, &index, 1, ""); - return to_integer(ctx, LLVMBuildLoad(ctx->builder, derived_ptr, "")); - break; + for (unsigned chan = 0; chan < ve; chan++) { + LLVMValueRef index = LLVMConstInt(ctx->i32, chan, false); + if (indir_index) + index = LLVMBuildAdd(ctx->builder, index, indir_index, ""); + derived_ptr = LLVMBuildGEP(ctx->builder, ptr, &index, 1, ""); + values[chan] = LLVMBuildLoad(ctx->builder, derived_ptr, ""); + } + return to_integer(ctx, build_gather_values(ctx, values, ve)); } default: break; @@ -2345,14 +2347,29 @@ visit_store_var(struct nir_to_llvm_context *ctx, &const_index, &indir_index); ptr = get_shared_memory_ptr(ctx, idx, ctx->i32); - LLVMValueRef index = ctx->i32zero; LLVMValueRef derived_ptr; - if (indir_index) - index = LLVMBuildAdd(ctx->builder, index, indir_index, ""); - derived_ptr = LLVMBuildGEP(ctx->builder, ptr, &index, 1, ""); - LLVMBuildStore(ctx->builder, - to_integer(ctx, src), derived_ptr); + for (unsigned chan = 0; chan < 4; chan++) { + if (!(writemask & (1 << chan))) + continue; + + LLVMValueRef index = LLVMConstInt(ctx->i32, chan, false); + + if (get_llvm_num_components(src) == 1) + value = src; + else + value = LLVMBuildExtractElement(ctx->builder, src, + LLVMConstInt(ctx->i32, + chan, false), + ""); + + if (indir_index) + index = LLVMBuildAdd(ctx->builder, index, indir_index, ""); + + derived_ptr = LLVMBuildGEP(ctx->builder, ptr, &index, 1, ""); + LLVMBuildStore(ctx->builder, + to_integer(ctx, value), derived_ptr); + } break; } default: |