Mesa (main): radv: add support for independent descriptor set layouts

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Fri Apr 15 06:37:50 UTC 2022


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

Author: Samuel Pitoiset <samuel.pitoiset at gmail.com>
Date:   Mon Apr 11 12:05:48 2022 +0200

radv: add support for independent descriptor set layouts

With VK_EXT_graphics_pipeline_library, pipeline layouts created with
VK_PIPELINE_LAYOUT_CREATE_INDEPENDENT_SETS_BIT_EXT might contain NULL
descriptor sets.

Signed-off-by: Samuel Pitoiset <samuel.pitoiset at gmail.com>
Reviewed-by: Mike Blumenkrantz <michael.blumenkrantz at gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/15926>

---

 src/amd/vulkan/radv_cmd_buffer.c     | 11 +++++++++++
 src/amd/vulkan/radv_descriptor_set.c | 31 ++++++++++++++++++++++++++++---
 src/amd/vulkan/radv_descriptor_set.h |  5 ++++-
 3 files changed, 43 insertions(+), 4 deletions(-)

diff --git a/src/amd/vulkan/radv_cmd_buffer.c b/src/amd/vulkan/radv_cmd_buffer.c
index 8ab0b5aaacc..502e1792eff 100644
--- a/src/amd/vulkan/radv_cmd_buffer.c
+++ b/src/amd/vulkan/radv_cmd_buffer.c
@@ -4819,6 +4819,17 @@ radv_CmdBindDescriptorSets(VkCommandBuffer commandBuffer, VkPipelineBindPoint pi
       unsigned set_idx = i + firstSet;
       RADV_FROM_HANDLE(radv_descriptor_set, set, pDescriptorSets[i]);
 
+      if (!set) {
+         /* From the Vulkan spec 1.3.211:
+          *
+          * "VUID-vkCmdBindDescriptorSets-layout-06564
+          *  If layout was not created with VK_PIPELINE_LAYOUT_CREATE_INDEPENDENT_SETS_BIT_EXT, each
+          *  element of pDescriptorSets must be a valid VkDescriptorSet"
+          */
+         assert(layout->independent_sets);
+         continue;
+      }
+
       /* If the set is already bound we only need to update the
        * (potentially changed) dynamic offsets. */
       if (descriptors_state->sets[set_idx] != set ||
diff --git a/src/amd/vulkan/radv_descriptor_set.c b/src/amd/vulkan/radv_descriptor_set.c
index 815340c16ee..545dfea5d9d 100644
--- a/src/amd/vulkan/radv_descriptor_set.c
+++ b/src/amd/vulkan/radv_descriptor_set.c
@@ -479,11 +479,14 @@ radv_GetDescriptorSetLayoutSupport(VkDevice device,
  * just multiple descriptor set layouts pasted together.
  */
 void
-radv_pipeline_layout_init(struct radv_device *device, struct radv_pipeline_layout *layout)
+radv_pipeline_layout_init(struct radv_device *device, struct radv_pipeline_layout *layout,
+                          bool independent_sets)
 {
    memset(layout, 0, sizeof(*layout));
 
    vk_object_base_init(&device->vk, &layout->base, VK_OBJECT_TYPE_PIPELINE_LAYOUT);
+
+   layout->independent_sets = independent_sets;
 }
 
 void
@@ -492,6 +495,9 @@ radv_pipeline_layout_add_set(struct radv_pipeline_layout *layout, uint32_t set_i
 {
    unsigned dynamic_offset_count = 0;
 
+   if (layout->set[set_idx].layout)
+      return;
+
    layout->num_sets = MAX2(set_idx + 1, layout->num_sets);
 
    layout->set[set_idx].layout = set_layout;
@@ -516,6 +522,9 @@ radv_pipeline_layout_hash(struct radv_pipeline_layout *layout)
    for (uint32_t i = 0; i < layout->num_sets; i++) {
       struct radv_descriptor_set_layout *set_layout = layout->set[i].layout;
 
+      if (!set_layout)
+         continue;
+
       /* Hash the entire set layout except for the vk_object_base and the reference counter. The
        * rest of the set layout is carefully constructed to not have pointers so a full hash instead
        * of a per-field hash should be ok.
@@ -531,8 +540,12 @@ radv_pipeline_layout_hash(struct radv_pipeline_layout *layout)
 void
 radv_pipeline_layout_finish(struct radv_device *device, struct radv_pipeline_layout *layout)
 {
-   for (uint32_t i = 0; i < layout->num_sets; i++)
+   for (uint32_t i = 0; i < layout->num_sets; i++) {
+      if (!layout->set[i].layout)
+         continue;
+
       radv_descriptor_set_layout_unref(device, layout->set[i].layout);
+   }
 
    vk_object_base_finish(&layout->base);
 }
@@ -552,13 +565,25 @@ radv_CreatePipelineLayout(VkDevice _device, const VkPipelineLayoutCreateInfo *pC
    if (layout == NULL)
       return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
 
-   radv_pipeline_layout_init(device, layout);
+   radv_pipeline_layout_init(device, layout,
+                             pCreateInfo->flags & VK_PIPELINE_LAYOUT_CREATE_INDEPENDENT_SETS_BIT_EXT);
 
    layout->num_sets = pCreateInfo->setLayoutCount;
 
    for (uint32_t set = 0; set < pCreateInfo->setLayoutCount; set++) {
       RADV_FROM_HANDLE(radv_descriptor_set_layout, set_layout, pCreateInfo->pSetLayouts[set]);
 
+      /* From the Vulkan spec 1.3.211:
+       *
+       * "VUID-VkPipelineLayoutCreateInfo-flags-06562
+       *  If flags: does not include VK_PIPELINE_LAYOUT_CREATE_INDEPENDENT_SETS_BIT_EXT, elements of
+       *  pSetLayouts must be valid VkDescriptorSetLayout objects"
+       */
+      if (set_layout == NULL) {
+         assert(layout->independent_sets);
+         continue;
+      }
+
       radv_pipeline_layout_add_set(layout, set, set_layout);
    }
 
diff --git a/src/amd/vulkan/radv_descriptor_set.h b/src/amd/vulkan/radv_descriptor_set.h
index 9902569da43..aaee6eacbf2 100644
--- a/src/amd/vulkan/radv_descriptor_set.h
+++ b/src/amd/vulkan/radv_descriptor_set.h
@@ -103,6 +103,8 @@ struct radv_pipeline_layout {
    uint32_t dynamic_offset_count;
    uint16_t dynamic_shader_stages;
 
+   bool independent_sets;
+
    unsigned char sha1[20];
 };
 
@@ -137,7 +139,8 @@ radv_immutable_ycbcr_samplers(const struct radv_descriptor_set_layout *set, unsi
 
 struct radv_device;
 
-void radv_pipeline_layout_init(struct radv_device *device, struct radv_pipeline_layout *layout);
+void radv_pipeline_layout_init(struct radv_device *device, struct radv_pipeline_layout *layout,
+                               bool independent_sets);
 void radv_pipeline_layout_add_set(struct radv_pipeline_layout *layout, uint32_t set_idx,
                                   struct radv_descriptor_set_layout *set_layout);
 void radv_pipeline_layout_hash(struct radv_pipeline_layout *layout);



More information about the mesa-commit mailing list