aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarek Olšák <[email protected]>2018-11-19 20:36:35 -0500
committerMarek Olšák <[email protected]>2018-11-28 20:20:27 -0500
commit648dc52367c666817f04cc2c2c4f8f853d4e9ca9 (patch)
treed4e8a511346212010cb42a826f07a5c641d46759
parent442dae2693a67fc56f5fbdb4b577ee554604eb3b (diff)
radeonsi: use structured buffer intrinsics for image views
to stop using the workaround in si_make_buffer_descriptor.
-rw-r--r--src/gallium/drivers/radeonsi/si_shader_tgsi_mem.c45
-rw-r--r--src/gallium/drivers/radeonsi/si_state.c7
2 files changed, 42 insertions, 10 deletions
diff --git a/src/gallium/drivers/radeonsi/si_shader_tgsi_mem.c b/src/gallium/drivers/radeonsi/si_shader_tgsi_mem.c
index 8c44831bccb..2ba3f251ff8 100644
--- a/src/gallium/drivers/radeonsi/si_shader_tgsi_mem.c
+++ b/src/gallium/drivers/radeonsi/si_shader_tgsi_mem.c
@@ -698,17 +698,25 @@ static void store_emit(
}
if (target == TGSI_TEXTURE_BUFFER) {
- LLVMValueRef buf_args[] = {
+ LLVMValueRef buf_args[6] = {
value,
args.resource,
vindex,
ctx->i32_0, /* voffset */
- LLVMConstInt(ctx->i1, !!(args.cache_policy & ac_glc), 0),
- LLVMConstInt(ctx->i1, !!(args.cache_policy & ac_slc), 0),
};
+ if (HAVE_LLVM >= 0x0800) {
+ buf_args[4] = ctx->i32_0; /* soffset */
+ buf_args[5] = LLVMConstInt(ctx->i1, args.cache_policy, 0);
+ } else {
+ buf_args[4] = LLVMConstInt(ctx->i1, !!(args.cache_policy & ac_glc), 0);
+ buf_args[5] = LLVMConstInt(ctx->i1, !!(args.cache_policy & ac_slc), 0);
+ }
+
emit_data->output[emit_data->chan] = ac_build_intrinsic(
- &ctx->ac, "llvm.amdgcn.buffer.store.format.v4f32",
+ &ctx->ac,
+ HAVE_LLVM >= 0x0800 ? "llvm.amdgcn.struct.buffer.store.format.v4f32" :
+ "llvm.amdgcn.buffer.store.format.v4f32",
ctx->voidt, buf_args, 6,
ac_get_store_intr_attribs(writeonly_memory));
} else {
@@ -830,7 +838,8 @@ static void atomic_emit(
vindex = args.coords[0]; /* for buffers only */
}
- if (inst->Src[0].Register.File == TGSI_FILE_BUFFER ||
+ if (HAVE_LLVM >= 0x0800 &&
+ inst->Src[0].Register.File != TGSI_FILE_BUFFER &&
inst->Memory.Texture == TGSI_TEXTURE_BUFFER) {
LLVMValueRef buf_args[7];
unsigned num_args = 0;
@@ -842,6 +851,32 @@ static void atomic_emit(
buf_args[num_args++] = args.resource;
buf_args[num_args++] = vindex;
buf_args[num_args++] = voffset;
+ buf_args[num_args++] = ctx->i32_0; /* soffset */
+ buf_args[num_args++] = LLVMConstInt(ctx->i32, args.cache_policy & ac_slc, 0);
+
+ char intrinsic_name[64];
+ snprintf(intrinsic_name, sizeof(intrinsic_name),
+ "llvm.amdgcn.struct.buffer.atomic.%s", action->intr_name);
+ emit_data->output[emit_data->chan] =
+ ac_to_float(&ctx->ac,
+ ac_build_intrinsic(&ctx->ac, intrinsic_name,
+ ctx->i32, buf_args, num_args, 0));
+ return;
+ }
+
+ if (inst->Src[0].Register.File == TGSI_FILE_BUFFER ||
+ (HAVE_LLVM < 0x0800 &&
+ inst->Memory.Texture == TGSI_TEXTURE_BUFFER)) {
+ LLVMValueRef buf_args[7];
+ unsigned num_args = 0;
+
+ buf_args[num_args++] = args.data[0];
+ if (inst->Instruction.Opcode == TGSI_OPCODE_ATOMCAS)
+ buf_args[num_args++] = args.data[1];
+
+ buf_args[num_args++] = args.resource;
+ buf_args[num_args++] = vindex;
+ buf_args[num_args++] = voffset;
buf_args[num_args++] = args.cache_policy & ac_slc ? ctx->i1true : ctx->i1false;
char intrinsic_name[40];
diff --git a/src/gallium/drivers/radeonsi/si_state.c b/src/gallium/drivers/radeonsi/si_state.c
index e3b45fa6ea7..41aa4ef3336 100644
--- a/src/gallium/drivers/radeonsi/si_state.c
+++ b/src/gallium/drivers/radeonsi/si_state.c
@@ -3613,14 +3613,11 @@ si_make_buffer_descriptor(struct si_screen *screen, struct r600_resource *buf,
* - For VMEM and inst.IDXEN == 0 or STRIDE == 0, it's in byte units.
* - For VMEM and inst.IDXEN == 1 and STRIDE != 0, it's in units of STRIDE.
*/
- if (screen->info.chip_class >= GFX9)
- /* When vindex == 0, LLVM sets IDXEN = 0, thus changing units
+ if (screen->info.chip_class >= GFX9 && HAVE_LLVM < 0x0800)
+ /* When vindex == 0, LLVM < 8.0 sets IDXEN = 0, thus changing units
* from STRIDE to bytes. This works around it by setting
* NUM_RECORDS to at least the size of one element, so that
* the first element is readable when IDXEN == 0.
- *
- * TODO: Fix this in LLVM, but do we need a new intrinsic where
- * IDXEN is enforced?
*/
num_records = num_records ? MAX2(num_records, stride) : 0;
else if (screen->info.chip_class == VI)