From: Marek Olšák <marek.ol...@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 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev