[Mesa-dev] [PATCH 6/6] radeonsi: fix is_oneway_access_only for bindless images
Marek Olšák
maraeo at gmail.com
Tue Nov 20 04:09:42 UTC 2018
From: Marek Olšák <marek.olsak at amd.com>
---
.../drivers/radeonsi/si_shader_tgsi_mem.c | 29 +++++++++++++++----
1 file changed, 23 insertions(+), 6 deletions(-)
diff --git a/src/gallium/drivers/radeonsi/si_shader_tgsi_mem.c b/src/gallium/drivers/radeonsi/si_shader_tgsi_mem.c
index 979e47d3cc4..6decedc4cce 100644
--- a/src/gallium/drivers/radeonsi/si_shader_tgsi_mem.c
+++ b/src/gallium/drivers/radeonsi/si_shader_tgsi_mem.c
@@ -389,25 +389,29 @@ static void load_emit_memory(
}
/**
* Return true if the memory accessed by a LOAD or STORE instruction is
* read-only or write-only, respectively.
*
* \param shader_buffers_reverse_access_mask
* For LOAD, set this to (store | atomic) slot usage in the shader.
* For STORE, set this to (load | atomic) slot usage in the shader.
* \param images_reverse_access_mask Same as above, but for images.
+ * \param bindless_buffer_reverse_access_mask Same as above, but for bindless image buffers.
+ * \param bindless_image_reverse_access_mask Same as above, but for bindless images.
*/
static bool is_oneway_access_only(const struct tgsi_full_instruction *inst,
const struct tgsi_shader_info *info,
unsigned shader_buffers_reverse_access_mask,
- unsigned images_reverse_access_mask)
+ unsigned images_reverse_access_mask,
+ bool bindless_buffer_reverse_access_mask,
+ bool bindless_image_reverse_access_mask)
{
enum tgsi_file_type resource_file;
unsigned resource_index;
bool resource_indirect;
if (inst->Instruction.Opcode == TGSI_OPCODE_STORE) {
resource_file = inst->Dst[0].Register.File;
resource_index = inst->Dst[0].Register.Index;
resource_indirect = inst->Dst[0].Register.Indirect;
} else {
@@ -421,25 +425,28 @@ static bool is_oneway_access_only(const struct tgsi_full_instruction *inst,
/* bindless image */
resource_file == TGSI_FILE_INPUT ||
resource_file == TGSI_FILE_OUTPUT ||
resource_file == TGSI_FILE_CONSTANT ||
resource_file == TGSI_FILE_TEMPORARY ||
resource_file == TGSI_FILE_IMMEDIATE);
assert(resource_file != TGSI_FILE_BUFFER ||
inst->Memory.Texture == TGSI_TEXTURE_BUFFER);
+ bool bindless = resource_file != TGSI_FILE_BUFFER &&
+ resource_file != TGSI_FILE_IMAGE;
+
/* RESTRICT means NOALIAS.
* If there are no writes, we can assume the accessed memory is read-only.
* If there are no reads, we can assume the accessed memory is write-only.
*/
- if (inst->Memory.Qualifier & TGSI_MEMORY_RESTRICT) {
+ if (inst->Memory.Qualifier & TGSI_MEMORY_RESTRICT && !bindless) {
unsigned reverse_access_mask;
if (resource_file == TGSI_FILE_BUFFER) {
reverse_access_mask = shader_buffers_reverse_access_mask;
} else if (inst->Memory.Texture == TGSI_TEXTURE_BUFFER) {
reverse_access_mask = info->images_buffers &
images_reverse_access_mask;
} else {
reverse_access_mask = ~info->images_buffers &
images_reverse_access_mask;
@@ -459,24 +466,26 @@ static bool is_oneway_access_only(const struct tgsi_full_instruction *inst,
* buffers), it implies that buffer memory is read-only.
* If there are no buffer reads (for both shader buffers & image
* buffers), it implies that buffer memory is write-only.
*
* Same for the case when there are no writes/reads for non-buffer
* images.
*/
if (resource_file == TGSI_FILE_BUFFER ||
inst->Memory.Texture == TGSI_TEXTURE_BUFFER) {
if (!shader_buffers_reverse_access_mask &&
- !(info->images_buffers & images_reverse_access_mask))
+ !(info->images_buffers & images_reverse_access_mask) &&
+ !bindless_buffer_reverse_access_mask)
return true;
} else {
- if (!(~info->images_buffers & images_reverse_access_mask))
+ if (!(~info->images_buffers & images_reverse_access_mask) &&
+ !bindless_image_reverse_access_mask)
return true;
}
return false;
}
static void load_emit(
const struct lp_build_tgsi_action *action,
struct lp_build_tgsi_context *bld_base,
struct lp_build_emit_data *emit_data)
{
@@ -515,21 +524,25 @@ static void load_emit(
}
if (inst->Memory.Qualifier & TGSI_MEMORY_VOLATILE)
ac_build_waitcnt(&ctx->ac, VM_CNT);
can_speculate = !(inst->Memory.Qualifier & TGSI_MEMORY_VOLATILE) &&
is_oneway_access_only(inst, info,
info->shader_buffers_store |
info->shader_buffers_atomic,
info->images_store |
- info->images_atomic);
+ info->images_atomic,
+ info->uses_bindless_buffer_store |
+ info->uses_bindless_buffer_atomic,
+ info->uses_bindless_image_store |
+ info->uses_bindless_image_atomic);
args.cache_policy = get_cache_policy(ctx, inst, false, false, false);
if (inst->Src[0].Register.File == TGSI_FILE_BUFFER) {
/* Don't use SMEM for shader buffer loads, because LLVM doesn't
* select SMEM for SI.load.const with a non-constant offset, and
* constant offsets practically don't exist with shader buffers.
*
* Also, SI.load.const doesn't use inst_offset when it's lowered
* to VMEM, so we just end up with more VALU instructions in the end
* and no benefit.
@@ -676,21 +689,25 @@ static void store_emit(
if (inst->Dst[0].Register.File == TGSI_FILE_MEMORY) {
store_emit_memory(ctx, emit_data);
return;
}
bool writeonly_memory = is_oneway_access_only(inst, info,
info->shader_buffers_load |
info->shader_buffers_atomic,
info->images_load |
- info->images_atomic);
+ info->images_atomic,
+ info->uses_bindless_buffer_load |
+ info->uses_bindless_buffer_atomic,
+ info->uses_bindless_image_load |
+ info->uses_bindless_image_atomic);
LLVMValueRef chans[4], value;
LLVMValueRef vindex = ctx->i32_0;
LLVMValueRef voffset = ctx->i32_0;
struct ac_image_args args = {};
for (unsigned chan = 0; chan < 4; ++chan)
chans[chan] = lp_build_emit_fetch(bld_base, inst, 1, chan);
value = ac_build_gather_values(&ctx->ac, chans, 4);
--
2.17.1
More information about the mesa-dev
mailing list