diff options
author | Rhys Perry <pendingchaos02@gmail.com> | 2021-11-12 10:45:46 +0000 |
---|---|---|
committer | Marge Bot <emma+marge@anholt.net> | 2022-04-13 23:08:07 +0000 |
commit | 67fc0e3655550600dcf16e98c78fe368f04b11e9 (patch) | |
tree | 57361f1ccb391f9fb2939774a3e0067aa8a59ee7 | |
parent | c883abda763de4034f62c473cfdb81b0afd41bde (diff) |
ac/llvm: implement load_shared2_amd/store_shared2_amd
Signed-off-by: Rhys Perry <pendingchaos02@gmail.com>
Reviewed-by: Timur Kristóf <timur.kristof@gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/13778>
-rw-r--r-- | src/amd/llvm/ac_nir_to_llvm.c | 38 |
1 files changed, 38 insertions, 0 deletions
diff --git a/src/amd/llvm/ac_nir_to_llvm.c b/src/amd/llvm/ac_nir_to_llvm.c index dbfe071363c..e5d468cc93c 100644 --- a/src/amd/llvm/ac_nir_to_llvm.c +++ b/src/amd/llvm/ac_nir_to_llvm.c @@ -3152,6 +3152,38 @@ static void visit_store_shared(struct ac_nir_context *ctx, const nir_intrinsic_i } } +static LLVMValueRef visit_load_shared2_amd(struct ac_nir_context *ctx, + const nir_intrinsic_instr *instr) +{ + LLVMValueRef ptr = get_memory_ptr(ctx, instr->src[0], instr->dest.ssa.bit_size, 0); + + LLVMValueRef values[2]; + uint8_t offsets[] = {nir_intrinsic_offset0(instr), nir_intrinsic_offset1(instr)}; + unsigned stride = nir_intrinsic_st64(instr) ? 64 : 1; + for (unsigned i = 0; i < 2; i++) { + LLVMValueRef index = LLVMConstInt(ctx->ac.i32, offsets[i] * stride, 0); + LLVMValueRef derived_ptr = LLVMBuildGEP(ctx->ac.builder, ptr, &index, 1, ""); + values[i] = LLVMBuildLoad(ctx->ac.builder, derived_ptr, ""); + } + + LLVMValueRef ret = ac_build_gather_values(&ctx->ac, values, 2); + return LLVMBuildBitCast(ctx->ac.builder, ret, get_def_type(ctx, &instr->dest.ssa), ""); +} + +static void visit_store_shared2_amd(struct ac_nir_context *ctx, const nir_intrinsic_instr *instr) +{ + LLVMValueRef ptr = get_memory_ptr(ctx, instr->src[1], instr->src[0].ssa->bit_size, 0); + LLVMValueRef src = get_src(ctx, instr->src[0]); + + uint8_t offsets[] = {nir_intrinsic_offset0(instr), nir_intrinsic_offset1(instr)}; + unsigned stride = nir_intrinsic_st64(instr) ? 64 : 1; + for (unsigned i = 0; i < 2; i++) { + LLVMValueRef index = LLVMConstInt(ctx->ac.i32, offsets[i] * stride, 0); + LLVMValueRef derived_ptr = LLVMBuildGEP(ctx->ac.builder, ptr, &index, 1, ""); + LLVMBuildStore(ctx->ac.builder, ac_llvm_extract_elem(&ctx->ac, src, i), derived_ptr); + } +} + static LLVMValueRef visit_var_atomic(struct ac_nir_context *ctx, const nir_intrinsic_instr *instr, LLVMValueRef ptr, int src_idx) { @@ -3820,6 +3852,12 @@ static void visit_intrinsic(struct ac_nir_context *ctx, nir_intrinsic_instr *ins case nir_intrinsic_store_shared: visit_store_shared(ctx, instr); break; + case nir_intrinsic_load_shared2_amd: + result = visit_load_shared2_amd(ctx, instr); + break; + case nir_intrinsic_store_shared2_amd: + visit_store_shared2_amd(ctx, instr); + break; case nir_intrinsic_bindless_image_samples: case nir_intrinsic_image_deref_samples: result = visit_image_samples(ctx, instr); |