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

Reply via email to