[Mesa-dev] [PATCH 12/18] radeonsi: don't use emit_data->args in atomic_emit
Marek Olšák
maraeo at gmail.com
Sat Aug 4 07:54:51 UTC 2018
From: Marek Olšák <marek.olsak at amd.com>
---
.../drivers/radeonsi/si_shader_internal.h | 2 +
.../drivers/radeonsi/si_shader_tgsi_mem.c | 79 ++++++++++---------
.../drivers/radeonsi/si_shader_tgsi_setup.c | 2 +
3 files changed, 47 insertions(+), 36 deletions(-)
diff --git a/src/gallium/drivers/radeonsi/si_shader_internal.h b/src/gallium/drivers/radeonsi/si_shader_internal.h
index 36351391d95..ac7784f7d46 100644
--- a/src/gallium/drivers/radeonsi/si_shader_internal.h
+++ b/src/gallium/drivers/radeonsi/si_shader_internal.h
@@ -193,20 +193,22 @@ struct si_shader_context {
LLVMTypeRef i64;
LLVMTypeRef i128;
LLVMTypeRef f32;
LLVMTypeRef v2i32;
LLVMTypeRef v4i32;
LLVMTypeRef v4f32;
LLVMTypeRef v8i32;
LLVMValueRef i32_0;
LLVMValueRef i32_1;
+ LLVMValueRef i1false;
+ LLVMValueRef i1true;
};
static inline struct si_shader_context *
si_shader_context(struct lp_build_tgsi_context *bld_base)
{
return (struct si_shader_context*)bld_base;
}
static inline struct si_shader_context *
si_shader_context_from_abi(struct ac_shader_abi *abi)
diff --git a/src/gallium/drivers/radeonsi/si_shader_tgsi_mem.c b/src/gallium/drivers/radeonsi/si_shader_tgsi_mem.c
index 4781526b071..1e21cabe770 100644
--- a/src/gallium/drivers/radeonsi/si_shader_tgsi_mem.c
+++ b/src/gallium/drivers/radeonsi/si_shader_tgsi_mem.c
@@ -338,20 +338,34 @@ static void buffer_append_args(
emit_data->args[emit_data->arg_count++] = offset; /* voffset */
if (!atomic) {
emit_data->args[emit_data->arg_count++] =
force_glc ||
inst->Memory.Qualifier & (TGSI_MEMORY_COHERENT | TGSI_MEMORY_VOLATILE) ?
i1true : i1false; /* glc */
}
emit_data->args[emit_data->arg_count++] = i1false; /* slc */
}
+static unsigned get_cache_policy(struct si_shader_context *ctx,
+ const struct tgsi_full_instruction *inst,
+ bool atomic, bool force_glc)
+{
+ unsigned cache_policy = 0;
+
+ if (!atomic &&
+ (force_glc ||
+ inst->Memory.Qualifier & (TGSI_MEMORY_COHERENT | TGSI_MEMORY_VOLATILE)))
+ cache_policy |= ac_glc;
+
+ return cache_policy;
+}
+
static void load_emit_buffer(struct si_shader_context *ctx,
struct lp_build_emit_data *emit_data,
bool can_speculate, bool allow_smem)
{
const struct tgsi_full_instruction *inst = emit_data->inst;
uint writemask = inst->Dst[0].Register.WriteMask;
uint count = util_last_bit(writemask);
LLVMValueRef *args = emit_data->args;
/* Don't use SMEM for shader buffer loads, because LLVM doesn't
@@ -852,101 +866,94 @@ static void atomic_emit_memory(struct si_shader_context *ctx,
LLVMBuildBitCast(builder, result, ctx->f32, "");
}
static void atomic_emit(
const struct lp_build_tgsi_action *action,
struct lp_build_tgsi_context *bld_base,
struct lp_build_emit_data *emit_data)
{
struct si_shader_context *ctx = si_shader_context(bld_base);
const struct tgsi_full_instruction * inst = emit_data->inst;
+ struct ac_image_args args = {};
+ unsigned num_data = 0;
+ LLVMValueRef vindex = ctx->i32_0;
+ LLVMValueRef voffset = ctx->i32_0;
if (inst->Src[0].Register.File == TGSI_FILE_MEMORY) {
atomic_emit_memory(ctx, emit_data);
return;
}
if (inst->Instruction.Opcode == TGSI_OPCODE_ATOMCAS) {
/* llvm.amdgcn.image/buffer.atomic.cmpswap reflect the hardware order
* of arguments, which is reversed relative to TGSI (and GLSL)
*/
- emit_data->args[emit_data->arg_count++] =
+ args.data[num_data++] =
ac_to_integer(&ctx->ac, lp_build_emit_fetch(bld_base, inst, 3, 0));
}
- emit_data->args[emit_data->arg_count++] =
+ args.data[num_data++] =
ac_to_integer(&ctx->ac, lp_build_emit_fetch(bld_base, inst, 2, 0));
+ args.cache_policy = get_cache_policy(ctx, inst, true, false);
if (inst->Src[0].Register.File == TGSI_FILE_BUFFER) {
- LLVMValueRef rsrc, offset;
-
- rsrc = shader_buffer_fetch_rsrc(ctx, &inst->Src[0], false);
- offset = ac_to_integer(&ctx->ac, lp_build_emit_fetch(bld_base, inst, 1, 0));
-
- buffer_append_args(ctx, emit_data, rsrc, ctx->i32_0,
- offset, true, false);
+ args.resource = shader_buffer_fetch_rsrc(ctx, &inst->Src[0], false);
+ voffset = ac_to_integer(&ctx->ac, lp_build_emit_fetch(bld_base, inst, 1, 0));
} else if (inst->Src[0].Register.File == TGSI_FILE_IMAGE ||
tgsi_is_bindless_image_file(inst->Src[0].Register.File)) {
- unsigned target = inst->Memory.Texture;
- LLVMValueRef rsrc;
-
- image_fetch_rsrc(bld_base, &inst->Src[0], true, target, &rsrc);
- image_fetch_coords(bld_base, inst, 1, rsrc,
- &emit_data->args[emit_data->arg_count + 1]);
-
- if (target == TGSI_TEXTURE_BUFFER) {
- buffer_append_args(ctx, emit_data, rsrc,
- emit_data->args[emit_data->arg_count + 1],
- ctx->i32_0, true, false);
- } else {
- emit_data->args[emit_data->arg_count] = rsrc;
- }
+ image_fetch_rsrc(bld_base, &inst->Src[0], true,
+ inst->Memory.Texture, &args.resource);
+ image_fetch_coords(bld_base, inst, 1, args.resource, args.coords);
+ vindex = args.coords[0]; /* for buffers only */
}
if (inst->Src[0].Register.File == TGSI_FILE_BUFFER ||
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];
snprintf(intrinsic_name, sizeof(intrinsic_name),
"llvm.amdgcn.buffer.atomic.%s", action->intr_name);
- LLVMValueRef tmp = ac_build_intrinsic(
- &ctx->ac, intrinsic_name, ctx->i32,
- emit_data->args, emit_data->arg_count, 0);
- emit_data->output[emit_data->chan] = ac_to_float(&ctx->ac, tmp);
+ 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));
} else {
- unsigned num_data = inst->Instruction.Opcode == TGSI_OPCODE_ATOMCAS ? 2 : 1;
- struct ac_image_args args = {};
-
if (inst->Instruction.Opcode == TGSI_OPCODE_ATOMCAS) {
args.opcode = ac_image_atomic_cmpswap;
} else {
args.opcode = ac_image_atomic;
switch (inst->Instruction.Opcode) {
case TGSI_OPCODE_ATOMXCHG: args.atomic = ac_atomic_swap; break;
case TGSI_OPCODE_ATOMUADD: args.atomic = ac_atomic_add; break;
case TGSI_OPCODE_ATOMAND: args.atomic = ac_atomic_and; break;
case TGSI_OPCODE_ATOMOR: args.atomic = ac_atomic_or; break;
case TGSI_OPCODE_ATOMXOR: args.atomic = ac_atomic_xor; break;
case TGSI_OPCODE_ATOMUMIN: args.atomic = ac_atomic_umin; break;
case TGSI_OPCODE_ATOMUMAX: args.atomic = ac_atomic_umax; break;
case TGSI_OPCODE_ATOMIMIN: args.atomic = ac_atomic_smin; break;
case TGSI_OPCODE_ATOMIMAX: args.atomic = ac_atomic_smax; break;
default: unreachable("unhandled image atomic");
}
}
- for (unsigned i = 0; i < num_data; ++i)
- args.data[i] = emit_data->args[i];
-
- args.resource = emit_data->args[num_data];
- memcpy(args.coords, &emit_data->args[num_data + 1], sizeof(args.coords));
args.dim = ac_image_dim_from_tgsi_target(ctx->screen, inst->Memory.Texture);
-
emit_data->output[emit_data->chan] =
ac_to_float(&ctx->ac, ac_build_image_opcode(&ctx->ac, &args));
}
}
static LLVMValueRef fix_resinfo(struct si_shader_context *ctx,
unsigned target, LLVMValueRef out)
{
LLVMBuilderRef builder = ctx->ac.builder;
diff --git a/src/gallium/drivers/radeonsi/si_shader_tgsi_setup.c b/src/gallium/drivers/radeonsi/si_shader_tgsi_setup.c
index b9ed0fc3ab0..975696d07ad 100644
--- a/src/gallium/drivers/radeonsi/si_shader_tgsi_setup.c
+++ b/src/gallium/drivers/radeonsi/si_shader_tgsi_setup.c
@@ -1014,20 +1014,22 @@ void si_llvm_context_init(struct si_shader_context *ctx,
ctx->i64 = LLVMInt64TypeInContext(ctx->ac.context);
ctx->i128 = LLVMIntTypeInContext(ctx->ac.context, 128);
ctx->f32 = LLVMFloatTypeInContext(ctx->ac.context);
ctx->v2i32 = LLVMVectorType(ctx->i32, 2);
ctx->v4i32 = LLVMVectorType(ctx->i32, 4);
ctx->v4f32 = LLVMVectorType(ctx->f32, 4);
ctx->v8i32 = LLVMVectorType(ctx->i32, 8);
ctx->i32_0 = LLVMConstInt(ctx->i32, 0, 0);
ctx->i32_1 = LLVMConstInt(ctx->i32, 1, 0);
+ ctx->i1false = LLVMConstInt(ctx->i1, 0, 0);
+ ctx->i1true = LLVMConstInt(ctx->i1, 1, 0);
}
/* Set the context to a certain TGSI shader. Can be called repeatedly
* to change the shader. */
void si_llvm_context_set_tgsi(struct si_shader_context *ctx,
struct si_shader *shader)
{
const struct tgsi_shader_info *info = NULL;
const struct tgsi_token *tokens = NULL;
--
2.17.1
More information about the mesa-dev
mailing list