Module: Mesa
Branch: main
Commit: 88e42e18d96b8048a11d18858b2a1c6ed7334890
URL:    
http://cgit.freedesktop.org/mesa/mesa/commit/?id=88e42e18d96b8048a11d18858b2a1c6ed7334890

Author: Simon Perretta <[email protected]>
Date:   Wed Feb 15 18:19:59 2023 +0000

pvr: Fix descriptor set address calculation

Signed-off-by: Simon Perretta <[email protected]>
Acked-by: Frank Binns <[email protected]>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/21474>

---

 src/imagination/rogue/rogue_compile.c       | 101 ++++++++++++++++++++--------
 src/imagination/vulkan/pvr_common.h         |  34 ++++++++++
 src/imagination/vulkan/pvr_descriptor_set.c |  34 ----------
 3 files changed, 107 insertions(+), 62 deletions(-)

diff --git a/src/imagination/rogue/rogue_compile.c 
b/src/imagination/rogue/rogue_compile.c
index b4b2f11499d..f6bdf5c4f39 100644
--- a/src/imagination/rogue/rogue_compile.c
+++ b/src/imagination/rogue/rogue_compile.c
@@ -311,6 +311,11 @@ mesa_stage_to_pvr(gl_shader_stage mesa_stage)
 
    unreachable("Unsupported gl_shader_stage.");
 }
+static bool descriptor_is_dynamic(VkDescriptorType type)
+{
+   return (type == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC ||
+           type == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC);
+}
 
 static void
 trans_nir_intrinsic_load_vulkan_descriptor(rogue_builder *b,
@@ -325,12 +330,9 @@ trans_nir_intrinsic_load_vulkan_descriptor(rogue_builder 
*b,
    struct pvr_pipeline_layout *pipeline_layout =
       b->shader->ctx->pipeline_layout;
 
-   /* Defaults for offline compiler. */
-   /* TODO: Load these from an offline pipeline description
-    * if using the offline compiler.
-    */
-   unsigned desc_set_table_sh_reg = 0;
-   unsigned flat_desc_idx = binding;
+   unsigned desc_set_table_sh_reg;
+   unsigned desc_set_offset;
+   unsigned desc_offset;
 
    if (pipeline_layout) {
       /* Fetch shared registers containing descriptor set table address. */
@@ -341,26 +343,45 @@ trans_nir_intrinsic_load_vulkan_descriptor(rogue_builder 
*b,
          pipeline_layout->sh_reg_layout_per_stage[pvr_stage]
             .descriptor_set_addrs_table.offset;
 
-      /* Lookup offsets for descriptor set and descriptor. */
+      /* Calculate offset for the descriptor set. */
       assert(desc_set < pipeline_layout->set_count);
+      desc_set_offset = desc_set * sizeof(pvr_dev_addr_t); /* Table is an array
+                                                              of addresses. */
 
-      unsigned binding_count =
-         pipeline_layout->set_layout[desc_set]->binding_count;
-      assert(binding < binding_count);
+      const struct pvr_descriptor_set_layout *set_layout =
+         pipeline_layout->set_layout[desc_set];
+      const struct pvr_descriptor_set_layout_mem_layout *mem_layout =
+         &set_layout->memory_layout_in_dwords_per_stage[pvr_stage];
 
-      flat_desc_idx = ~0U;
-      for (unsigned u = 0; u < binding_count; ++u) {
-         unsigned binding_number =
-            pipeline_layout->set_layout[desc_set]->bindings[u].binding_number;
+      /* Calculate offset for the descriptor/binding. */
+      assert(binding < set_layout->binding_count);
 
-         if (binding_number == binding) {
-            flat_desc_idx = pipeline_layout->set_layout[desc_set]
-                               ->bindings[u]
-                               .descriptor_index;
-            break;
-         }
-      }
-      assert(flat_desc_idx != ~0U);
+      const struct pvr_descriptor_set_layout_binding *binding_layout =
+         pvr_get_descriptor_binding(set_layout, binding);
+      assert(binding_layout);
+
+      /* TODO: Handle secondaries. */
+      /* TODO: Handle bindings having multiple descriptors
+       * (VkDescriptorSetLayoutBinding->descriptorCount).
+       */
+
+      if (descriptor_is_dynamic(binding_layout->type))
+         desc_offset = set_layout->total_size_in_dwords;
+      else
+         desc_offset = mem_layout->primary_offset;
+
+      desc_offset +=
+         binding_layout->per_stage_offset_in_dwords[pvr_stage].primary;
+
+      desc_offset *= sizeof(uint32_t); /* DWORDs to bytes. */
+   } else {
+      /* Dummy defaults for offline compiler. */
+      /* TODO: Load these from an offline pipeline description
+       * if using the offline compiler.
+       */
+      desc_set_table_sh_reg = 0;
+      desc_set_offset = desc_set * sizeof(pvr_dev_addr_t);
+      desc_offset = binding * sizeof(pvr_dev_addr_t);
    }
 
    unsigned desc_set_table_addr_idx = b->shader->ctx->next_ssa_idx++;
@@ -384,8 +405,6 @@ trans_nir_intrinsic_load_vulkan_descriptor(rogue_builder *b,
           ->instr;
    rogue_add_instr_comment(instr, "desc_set_table_addr_hi");
 
-   /* TODO: Don't add offsets if the descriptor set/flat descriptor is 0. */
-
    /* Offset the descriptor set table address to access the descriptor set. */
    unsigned desc_set_table_addr_offset_idx = b->shader->ctx->next_ssa_idx++;
    rogue_regarray *desc_set_table_addr_offset_64 =
@@ -395,14 +414,27 @@ trans_nir_intrinsic_load_vulkan_descriptor(rogue_builder 
*b,
       rogue_ssa_vec_regarray(b->shader, 1, desc_set_table_addr_offset_idx, 1),
    };
 
+   unsigned desc_set_table_addr_offset_lo_idx = b->shader->ctx->next_ssa_idx++;
+   unsigned desc_set_table_addr_offset_hi_idx = b->shader->ctx->next_ssa_idx++;
+
+   rogue_reg *desc_set_table_addr_offset_lo =
+      rogue_ssa_reg(b->shader, desc_set_table_addr_offset_lo_idx);
+   rogue_reg *desc_set_table_addr_offset_hi =
+      rogue_ssa_reg(b->shader, desc_set_table_addr_offset_hi_idx);
+
+   rogue_MOV(b,
+             rogue_ref_reg(desc_set_table_addr_offset_lo),
+             rogue_ref_imm(desc_set_offset));
+   rogue_MOV(b, rogue_ref_reg(desc_set_table_addr_offset_hi), 
rogue_ref_imm(0));
+
    rogue_ADD64(b,
                rogue_ref_regarray(desc_set_table_addr_offset_2x32[0]),
                rogue_ref_regarray(desc_set_table_addr_offset_2x32[1]),
                rogue_ref_io(ROGUE_IO_NONE),
                rogue_ref_regarray(desc_set_table_addr_2x32[0]),
                rogue_ref_regarray(desc_set_table_addr_2x32[1]),
-               rogue_ref_imm(desc_set * 4), /* TODO: use UMADD64 instead */
-               rogue_ref_imm(0),
+               rogue_ref_reg(desc_set_table_addr_offset_lo),
+               rogue_ref_reg(desc_set_table_addr_offset_hi),
                rogue_ref_io(ROGUE_IO_NONE));
 
    unsigned desc_set_addr_idx = b->shader->ctx->next_ssa_idx++;
@@ -429,14 +461,27 @@ trans_nir_intrinsic_load_vulkan_descriptor(rogue_builder 
*b,
       rogue_ssa_vec_regarray(b->shader, 1, desc_addr_offset_idx, 1),
    };
 
+   unsigned desc_addr_offset_lo_idx = b->shader->ctx->next_ssa_idx++;
+   unsigned desc_addr_offset_hi_idx = b->shader->ctx->next_ssa_idx++;
+
+   rogue_reg *desc_addr_offset_val_lo =
+      rogue_ssa_reg(b->shader, desc_addr_offset_lo_idx);
+   rogue_reg *desc_addr_offset_val_hi =
+      rogue_ssa_reg(b->shader, desc_addr_offset_hi_idx);
+
+   rogue_MOV(b,
+             rogue_ref_reg(desc_addr_offset_val_lo),
+             rogue_ref_imm(desc_offset));
+   rogue_MOV(b, rogue_ref_reg(desc_addr_offset_val_hi), rogue_ref_imm(0));
+
    rogue_ADD64(b,
                rogue_ref_regarray(desc_addr_offset_2x32[0]),
                rogue_ref_regarray(desc_addr_offset_2x32[1]),
                rogue_ref_io(ROGUE_IO_NONE),
                rogue_ref_regarray(desc_set_addr_2x32[0]),
                rogue_ref_regarray(desc_set_addr_2x32[1]),
-               rogue_ref_imm(flat_desc_idx * 4), /* TODO: use UMADD64 instead 
*/
-               rogue_ref_imm(0),
+               rogue_ref_reg(desc_addr_offset_val_lo),
+               rogue_ref_reg(desc_addr_offset_val_hi),
                rogue_ref_io(ROGUE_IO_NONE));
 
    unsigned desc_addr_idx = intr->dest.ssa.index;
diff --git a/src/imagination/vulkan/pvr_common.h 
b/src/imagination/vulkan/pvr_common.h
index 19bb76dca60..5976123dbe7 100644
--- a/src/imagination/vulkan/pvr_common.h
+++ b/src/imagination/vulkan/pvr_common.h
@@ -407,4 +407,38 @@ struct pvr_pipeline_layout {
    } per_stage_reg_info[PVR_STAGE_ALLOCATION_COUNT];
 };
 
+static int pvr_compare_layout_binding(const void *a, const void *b)
+{
+   uint32_t binding_a;
+   uint32_t binding_b;
+
+   binding_a = ((struct pvr_descriptor_set_layout_binding *)a)->binding_number;
+   binding_b = ((struct pvr_descriptor_set_layout_binding *)b)->binding_number;
+
+   if (binding_a < binding_b)
+      return -1;
+
+   if (binding_a > binding_b)
+      return 1;
+
+   return 0;
+}
+
+/* This function does not assume that the binding will always exist for a
+ * particular binding_num. Caller should check before using the return pointer.
+ */
+static struct pvr_descriptor_set_layout_binding *
+pvr_get_descriptor_binding(const struct pvr_descriptor_set_layout *layout,
+                           const uint32_t binding_num)
+{
+   struct pvr_descriptor_set_layout_binding binding;
+   binding.binding_number = binding_num;
+
+   return bsearch(&binding,
+                  layout->bindings,
+                  layout->binding_count,
+                  sizeof(binding),
+                  pvr_compare_layout_binding);
+}
+
 #endif /* PVR_COMMON_H */
diff --git a/src/imagination/vulkan/pvr_descriptor_set.c 
b/src/imagination/vulkan/pvr_descriptor_set.c
index 9d5c0e8fac0..2c0737be86b 100644
--- a/src/imagination/vulkan/pvr_descriptor_set.c
+++ b/src/imagination/vulkan/pvr_descriptor_set.c
@@ -1339,40 +1339,6 @@ VkResult pvr_FreeDescriptorSets(VkDevice _device,
    return VK_SUCCESS;
 }
 
-static int pvr_compare_layout_binding(const void *a, const void *b)
-{
-   uint32_t binding_a;
-   uint32_t binding_b;
-
-   binding_a = ((struct pvr_descriptor_set_layout_binding *)a)->binding_number;
-   binding_b = ((struct pvr_descriptor_set_layout_binding *)b)->binding_number;
-
-   if (binding_a < binding_b)
-      return -1;
-
-   if (binding_a > binding_b)
-      return 1;
-
-   return 0;
-}
-
-/* This function does not assume that the binding will always exist for a
- * particular binding_num. Caller should check before using the return pointer.
- */
-static struct pvr_descriptor_set_layout_binding *
-pvr_get_descriptor_binding(const struct pvr_descriptor_set_layout *layout,
-                           const uint32_t binding_num)
-{
-   struct pvr_descriptor_set_layout_binding binding;
-   binding.binding_number = binding_num;
-
-   return bsearch(&binding,
-                  layout->bindings,
-                  layout->binding_count,
-                  sizeof(binding),
-                  pvr_compare_layout_binding);
-}
-
 static void pvr_descriptor_update_buffer_info(
    const struct pvr_device *device,
    const VkWriteDescriptorSet *write_set,

Reply via email to