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

Author: Benjamin Cheng <[email protected]>
Date:   Fri May  6 15:54:18 2022 -0400

radv: implement disjoint memory for multiplane images

For descriptor binding, we need to allow up to three buffers to be
referenced by any image.

Reviewed-by: Bas Nieuwenhuizen <[email protected]>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/16510>

---

 src/amd/vulkan/radv_cmd_buffer.c     | 14 +++++++++++++-
 src/amd/vulkan/radv_descriptor_set.c | 37 ++++++++++++++++++++++++++----------
 src/amd/vulkan/radv_device.c         | 30 ++++++++++++++++++++++++++---
 src/amd/vulkan/radv_image.c          |  6 ++++--
 src/amd/vulkan/radv_private.h        |  1 +
 5 files changed, 72 insertions(+), 16 deletions(-)

diff --git a/src/amd/vulkan/radv_cmd_buffer.c b/src/amd/vulkan/radv_cmd_buffer.c
index a46c0b3b587..f0622e10b40 100644
--- a/src/amd/vulkan/radv_cmd_buffer.c
+++ b/src/amd/vulkan/radv_cmd_buffer.c
@@ -2761,7 +2761,19 @@ radv_emit_framebuffer_state(struct radv_cmd_buffer 
*cmd_buffer)
       radv_cs_add_buffer(cmd_buffer->device->ws, cmd_buffer->cs, 
iview->image->bindings[0].bo);
 
       assert(iview->vk.aspects & (VK_IMAGE_ASPECT_COLOR_BIT | 
VK_IMAGE_ASPECT_PLANE_0_BIT |
-                                  VK_IMAGE_ASPECT_PLANE_1_BIT | 
VK_IMAGE_ASPECT_PLANE_2_BIT));
+                                   VK_IMAGE_ASPECT_PLANE_1_BIT | 
VK_IMAGE_ASPECT_PLANE_2_BIT));
+
+      if (iview->image->disjoint && iview->vk.aspects == 
VK_IMAGE_ASPECT_COLOR_BIT) {
+         for (uint32_t plane_id = 0; plane_id < iview->image->plane_count; 
plane_id++) {
+            radv_cs_add_buffer(cmd_buffer->device->ws, cmd_buffer->cs,
+                  iview->image->bindings[plane_id].bo);
+         }
+      } else {
+         uint32_t plane_id = iview->image->disjoint ? iview->plane_id : 0;
+         radv_cs_add_buffer(cmd_buffer->device->ws, cmd_buffer->cs,
+               iview->image->bindings[plane_id].bo);
+      }
+
       radv_emit_fb_color_state(cmd_buffer, i, 
&cmd_buffer->state.attachments[idx].cb, iview, layout,
                                in_render_loop);
 
diff --git a/src/amd/vulkan/radv_descriptor_set.c 
b/src/amd/vulkan/radv_descriptor_set.c
index 393939172aa..d71de46003d 100644
--- a/src/amd/vulkan/radv_descriptor_set.c
+++ b/src/amd/vulkan/radv_descriptor_set.c
@@ -41,6 +41,12 @@ radv_descriptor_type_buffer_count(VkDescriptorType type)
       case VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK:
       case VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR:
          return 0;
+      case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
+      case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
+      case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
+      case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
+      case VK_DESCRIPTOR_TYPE_MUTABLE_VALVE:
+         return 3;
       default:
          return 1;
    }
@@ -1166,10 +1172,17 @@ write_image_descriptor(struct radv_device *device, 
struct radv_cmd_buffer *cmd_b
 
    memcpy(dst, descriptor, size);
 
-   if (cmd_buffer)
-      radv_cs_add_buffer(device->ws, cmd_buffer->cs, 
iview->image->bindings[0].bo);
-   else
-      *buffer_list = iview->image->bindings[0].bo;
+   const uint32_t max_bindings = sizeof(iview->image->bindings) /
+                                 sizeof(iview->image->bindings[0]);
+   for (uint32_t b = 0; b < max_bindings; b++) {
+      if (cmd_buffer) {
+         if (iview->image->bindings[b].bo)
+            radv_cs_add_buffer(device->ws, cmd_buffer->cs, 
iview->image->bindings[b].bo);
+      } else {
+         *buffer_list = iview->image->bindings[b].bo;
+         buffer_list++;
+      }
+   }
 }
 
 static ALWAYS_INLINE void
@@ -1364,13 +1377,17 @@ radv_update_descriptor_sets_impl(struct radv_device 
*device, struct radv_cmd_buf
          src_ptr += src_binding_layout->size / 4;
          dst_ptr += dst_binding_layout->size / 4;
 
-         if (src_binding_layout->type != VK_DESCRIPTOR_TYPE_SAMPLER &&
-             dst_binding_layout->type != VK_DESCRIPTOR_TYPE_SAMPLER &&
-             src_binding_layout->type != 
VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR &&
-             dst_binding_layout->type != 
VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR) {
-            /* Sampler/acceleration structure descriptors don't have a buffer 
list. */
-            dst_buffer_list[j] = src_buffer_list[j];
+         unsigned src_buffer_count = 
radv_descriptor_type_buffer_count(src_binding_layout->type);
+         unsigned dst_buffer_count = 
radv_descriptor_type_buffer_count(dst_binding_layout->type);
+         for (unsigned k = 0; k < dst_buffer_count; k++) {
+            if (k < src_buffer_count)
+               dst_buffer_list[k] = src_buffer_list[k];
+            else
+               dst_buffer_list[k] = NULL;
          }
+
+         dst_buffer_list += dst_buffer_count;
+         src_buffer_list += src_buffer_count;
       }
    }
 }
diff --git a/src/amd/vulkan/radv_device.c b/src/amd/vulkan/radv_device.c
index 54ee6dc775c..3bbeef44749 100644
--- a/src/amd/vulkan/radv_device.c
+++ b/src/amd/vulkan/radv_device.c
@@ -5870,8 +5870,30 @@ radv_BindImageMemory2(VkDevice _device, uint32_t 
bindInfoCount,
          }
       }
 
-      image->bindings[0].bo = mem->bo;
-      image->bindings[0].offset = pBindInfos[i].memoryOffset;
+      if (image->disjoint) {
+         const VkBindImagePlaneMemoryInfo *plane_info =
+            vk_find_struct_const(pBindInfos[i].pNext, 
BIND_IMAGE_PLANE_MEMORY_INFO);
+
+         switch (plane_info->planeAspect) {
+            case VK_IMAGE_ASPECT_PLANE_0_BIT:
+               image->bindings[0].bo = mem->bo;
+               image->bindings[0].offset = pBindInfos[i].memoryOffset;
+               break;
+            case VK_IMAGE_ASPECT_PLANE_1_BIT:
+               image->bindings[1].bo = mem->bo;
+               image->bindings[1].offset = pBindInfos[i].memoryOffset;
+               break;
+            case VK_IMAGE_ASPECT_PLANE_2_BIT:
+               image->bindings[2].bo = mem->bo;
+               image->bindings[2].offset = pBindInfos[i].memoryOffset;
+               break;
+            default:
+               break;
+         }
+      } else {
+         image->bindings[0].bo = mem->bo;
+         image->bindings[0].offset = pBindInfos[i].memoryOffset;
+      }
    }
    return VK_SUCCESS;
 }
@@ -6209,7 +6231,9 @@ radv_initialise_color_surface(struct radv_device *device, 
struct radv_color_buff
    else
       cb->cb_color_attrib = S_028C74_FORCE_DST_ALPHA_1_GFX6(desc->swizzle[3] 
== PIPE_SWIZZLE_1);
 
-   va = radv_buffer_get_va(iview->image->bindings[0].bo) + 
iview->image->bindings[0].offset;
+   uint32_t plane_id = iview->image->disjoint ? iview->plane_id : 0;
+   va = radv_buffer_get_va(iview->image->bindings[plane_id].bo) +
+      iview->image->bindings[plane_id].offset;
 
    cb->cb_color_base = va >> 8;
 
diff --git a/src/amd/vulkan/radv_image.c b/src/amd/vulkan/radv_image.c
index 51ce6c53571..487d1cf059c 100644
--- a/src/amd/vulkan/radv_image.c
+++ b/src/amd/vulkan/radv_image.c
@@ -766,7 +766,7 @@ si_set_mutable_tex_desc_fields(struct radv_device *device, 
struct radv_image *im
                                bool enable_write_compression, uint32_t *state)
 {
    struct radv_image_plane *plane = &image->planes[plane_id];
-   struct radv_image_binding *binding = &image->bindings[0];
+   struct radv_image_binding *binding = image->disjoint ? 
&image->bindings[plane_id] : &image->bindings[0];
    uint64_t gpu_address = binding->bo ? radv_buffer_get_va(binding->bo) + 
binding->offset : 0;
    uint64_t va = gpu_address;
    enum amd_gfx_level gfx_level = device->physical_device->rad_info.gfx_level;
@@ -1684,7 +1684,8 @@ radv_image_create_layout(struct radv_device *device, 
struct radv_image_create_in
          offset = mod_info->pPlaneLayouts[plane].offset;
          stride = mod_info->pPlaneLayouts[plane].rowPitch / 
image->planes[plane].surface.bpe;
       } else {
-         offset = align64(image->size, 1 << 
image->planes[plane].surface.alignment_log2);
+         offset = image->disjoint ? 0 :
+            align64(image->size, 1 << 
image->planes[plane].surface.alignment_log2);
          stride = 0; /* 0 means no override */
       }
 
@@ -1850,6 +1851,7 @@ radv_image_create(VkDevice _device, const struct 
radv_image_create_info *create_
    image->info.num_channels = vk_format_get_nr_components(format);
 
    image->plane_count = vk_format_get_plane_count(format);
+   image->disjoint = image->plane_count > 1 && pCreateInfo->flags & 
VK_IMAGE_CREATE_DISJOINT_BIT;
 
    image->exclusive = pCreateInfo->sharingMode == VK_SHARING_MODE_EXCLUSIVE;
    if (pCreateInfo->sharingMode == VK_SHARING_MODE_CONCURRENT) {
diff --git a/src/amd/vulkan/radv_private.h b/src/amd/vulkan/radv_private.h
index 77122242d44..f2b1fbf7a04 100644
--- a/src/amd/vulkan/radv_private.h
+++ b/src/amd/vulkan/radv_private.h
@@ -2412,6 +2412,7 @@ struct radv_image {
    VkDeviceMemory owned_memory;
 
    unsigned plane_count;
+   bool disjoint;
    struct radv_image_plane planes[0];
 };
 

Reply via email to