Mesa (master): venus: handle VK_IMAGE_LAYOUT_PRESENT_SRC_KHR transfer

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Thu Apr 29 17:43:49 UTC 2021


Module: Mesa
Branch: master
Commit: 174fca5498e8fcaf471a9692c1fcaa3945417429
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=174fca5498e8fcaf471a9692c1fcaa3945417429

Author: Yiwei Zhang <zzyiwei at chromium.org>
Date:   Tue Apr 20 23:01:23 2021 +0000

venus: handle VK_IMAGE_LAYOUT_PRESENT_SRC_KHR transfer

Whenver VK_IMAGE_LAYOUT_PRESENT_SRC_KHR is used, replace it with
VK_IMAGE_LAYOUT_GENERAL as required for proper layout and ownership
transfer for external memory backed swapchain images.

This will be Android only until common WSI is fixed.

Signed-off-by: Yiwei Zhang <zzyiwei at chromium.org>
Reviewed-by: Chia-I Wu <olvaffe at gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/10335>

---

 src/virtio/vulkan/vn_command_buffer.c |  59 ++++++++++++++++++--
 src/virtio/vulkan/vn_command_buffer.h |   5 ++
 src/virtio/vulkan/vn_render_pass.c    | 100 ++++++++++++++++++++++++++++++++--
 3 files changed, 156 insertions(+), 8 deletions(-)

diff --git a/src/virtio/vulkan/vn_command_buffer.c b/src/virtio/vulkan/vn_command_buffer.c
index 63962f64107..642f157ed71 100644
--- a/src/virtio/vulkan/vn_command_buffer.c
+++ b/src/virtio/vulkan/vn_command_buffer.c
@@ -134,6 +134,7 @@ vn_AllocateCommandBuffers(VkDevice device,
       vn_object_base_init(&cmd->base, VK_OBJECT_TYPE_COMMAND_BUFFER,
                           &dev->base);
       cmd->device = dev;
+      cmd->allocator = pool->allocator;
 
       list_addtail(&cmd->head, &pool->command_buffers);
 
@@ -170,6 +171,9 @@ vn_FreeCommandBuffers(VkDevice device,
       if (!cmd)
          continue;
 
+      if (cmd->image_barriers)
+         vk_free(alloc, cmd->image_barriers);
+
       vn_cs_encoder_fini(&cmd->cs);
       list_del(&cmd->head);
 
@@ -939,6 +943,51 @@ vn_CmdResetEvent(VkCommandBuffer commandBuffer,
    vn_encode_vkCmdResetEvent(&cmd->cs, 0, commandBuffer, event, stageMask);
 }
 
+static const VkImageMemoryBarrier *
+vn_get_intercepted_barriers(struct vn_command_buffer *cmd,
+                            const VkImageMemoryBarrier *img_barriers,
+                            uint32_t count)
+{
+   /* XXX drop the #ifdef after fixing common wsi */
+#ifdef ANDROID
+   bool has_present_src = false;
+   for (uint32_t i = 0; i < count; i++) {
+      if (img_barriers[i].oldLayout == VK_IMAGE_LAYOUT_PRESENT_SRC_KHR ||
+          img_barriers[i].newLayout == VK_IMAGE_LAYOUT_PRESENT_SRC_KHR) {
+         has_present_src = false;
+         break;
+      }
+   }
+   if (!has_present_src)
+      return img_barriers;
+
+   size_t size = sizeof(VkImageMemoryBarrier) * count;
+   /* avoid shrinking in case of non efficient reallocation implementation */
+   VkImageMemoryBarrier *barriers = cmd->image_barriers;
+   if (count > cmd->image_barrier_count) {
+      barriers =
+         vk_realloc(&cmd->allocator, cmd->image_barriers, size,
+                    VN_DEFAULT_ALIGN, VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
+      if (!barriers)
+         return img_barriers;
+
+      /* update upon successful reallocation */
+      cmd->image_barrier_count = count;
+      cmd->image_barriers = barriers;
+   }
+   memcpy(barriers, img_barriers, size);
+   for (uint32_t i = 0; i < count; i++) {
+      if (barriers[i].oldLayout == VK_IMAGE_LAYOUT_PRESENT_SRC_KHR)
+         barriers[i].oldLayout = VK_IMAGE_LAYOUT_GENERAL;
+      if (barriers[i].newLayout == VK_IMAGE_LAYOUT_PRESENT_SRC_KHR)
+         barriers[i].newLayout = VK_IMAGE_LAYOUT_GENERAL;
+   }
+   return barriers;
+#else
+   return img_barriers;
+#endif
+}
+
 void
 vn_CmdWaitEvents(VkCommandBuffer commandBuffer,
                  uint32_t eventCount,
@@ -963,13 +1012,14 @@ vn_CmdWaitEvents(VkCommandBuffer commandBuffer,
    if (!vn_cs_encoder_reserve(&cmd->cs, cmd_size))
       return;
 
-   /* XXX VK_IMAGE_LAYOUT_PRESENT_SRC_KHR */
+   const VkImageMemoryBarrier *img_barriers = vn_get_intercepted_barriers(
+      cmd, pImageMemoryBarriers, imageMemoryBarrierCount);
 
    vn_encode_vkCmdWaitEvents(&cmd->cs, 0, commandBuffer, eventCount, pEvents,
                              srcStageMask, dstStageMask, memoryBarrierCount,
                              pMemoryBarriers, bufferMemoryBarrierCount,
                              pBufferMemoryBarriers, imageMemoryBarrierCount,
-                             pImageMemoryBarriers);
+                             img_barriers);
 }
 
 void
@@ -995,12 +1045,13 @@ vn_CmdPipelineBarrier(VkCommandBuffer commandBuffer,
    if (!vn_cs_encoder_reserve(&cmd->cs, cmd_size))
       return;
 
-   /* XXX VK_IMAGE_LAYOUT_PRESENT_SRC_KHR */
+   const VkImageMemoryBarrier *img_barriers = vn_get_intercepted_barriers(
+      cmd, pImageMemoryBarriers, imageMemoryBarrierCount);
 
    vn_encode_vkCmdPipelineBarrier(
       &cmd->cs, 0, commandBuffer, srcStageMask, dstStageMask, dependencyFlags,
       memoryBarrierCount, pMemoryBarriers, bufferMemoryBarrierCount,
-      pBufferMemoryBarriers, imageMemoryBarrierCount, pImageMemoryBarriers);
+      pBufferMemoryBarriers, imageMemoryBarrierCount, img_barriers);
 }
 
 void
diff --git a/src/virtio/vulkan/vn_command_buffer.h b/src/virtio/vulkan/vn_command_buffer.h
index 77ec43b27d4..ab74effe507 100644
--- a/src/virtio/vulkan/vn_command_buffer.h
+++ b/src/virtio/vulkan/vn_command_buffer.h
@@ -38,6 +38,11 @@ struct vn_command_buffer {
 
    struct vn_device *device;
 
+   /* for scrubbing VK_IMAGE_LAYOUT_PRESENT_SRC_KHR */
+   VkAllocationCallbacks allocator;
+   uint32_t image_barrier_count;
+   VkImageMemoryBarrier *image_barriers;
+
    struct list_head head;
 
    enum vn_command_buffer_state state;
diff --git a/src/virtio/vulkan/vn_render_pass.c b/src/virtio/vulkan/vn_render_pass.c
index 7411f5556a6..fa87a662fe0 100644
--- a/src/virtio/vulkan/vn_render_pass.c
+++ b/src/virtio/vulkan/vn_render_pass.c
@@ -17,6 +17,43 @@
 
 /* render pass commands */
 
+static const VkAttachmentDescription *
+vn_get_intercepted_attachments(const VkAttachmentDescription *attachments,
+                               uint32_t count,
+                               const VkAllocationCallbacks *alloc)
+{
+   /* XXX drop the #ifdef after fixing common wsi */
+#ifdef ANDROID
+   bool has_present_src = false;
+   for (uint32_t i = 0; i < count; i++) {
+      if (attachments[i].initialLayout == VK_IMAGE_LAYOUT_PRESENT_SRC_KHR ||
+          attachments[i].finalLayout == VK_IMAGE_LAYOUT_PRESENT_SRC_KHR) {
+         has_present_src = true;
+         break;
+      }
+   }
+   if (!has_present_src)
+      return attachments;
+
+   size_t size = sizeof(VkAttachmentDescription) * count;
+   VkAttachmentDescription *out_attachments = vk_alloc(
+      alloc, size, VN_DEFAULT_ALIGN, VK_SYSTEM_ALLOCATION_SCOPE_COMMAND);
+   if (!out_attachments)
+      return NULL;
+
+   memcpy(out_attachments, attachments, size);
+   for (uint32_t i = 0; i < count; i++) {
+      if (out_attachments[i].initialLayout == VK_IMAGE_LAYOUT_PRESENT_SRC_KHR)
+         out_attachments[i].initialLayout = VK_IMAGE_LAYOUT_GENERAL;
+      if (out_attachments[i].finalLayout == VK_IMAGE_LAYOUT_PRESENT_SRC_KHR)
+         out_attachments[i].finalLayout = VK_IMAGE_LAYOUT_GENERAL;
+   }
+   return out_attachments;
+#else
+   return attachments;
+#endif
+}
+
 VkResult
 vn_CreateRenderPass(VkDevice device,
                     const VkRenderPassCreateInfo *pCreateInfo,
@@ -35,17 +72,63 @@ vn_CreateRenderPass(VkDevice device,
 
    vn_object_base_init(&pass->base, VK_OBJECT_TYPE_RENDER_PASS, &dev->base);
 
-   /* XXX VK_IMAGE_LAYOUT_PRESENT_SRC_KHR */
+   VkRenderPassCreateInfo local_pass_info = *pCreateInfo;
+   local_pass_info.pAttachments = vn_get_intercepted_attachments(
+      pCreateInfo->pAttachments, pCreateInfo->attachmentCount, alloc);
+   if (!local_pass_info.pAttachments) {
+      vk_free(alloc, pass);
+      return vn_error(dev->instance, VK_ERROR_OUT_OF_HOST_MEMORY);
+   }
 
    VkRenderPass pass_handle = vn_render_pass_to_handle(pass);
-   vn_async_vkCreateRenderPass(dev->instance, device, pCreateInfo, NULL,
+   vn_async_vkCreateRenderPass(dev->instance, device, &local_pass_info, NULL,
                                &pass_handle);
 
+   if (local_pass_info.pAttachments != pCreateInfo->pAttachments)
+      vk_free(alloc, (void *)local_pass_info.pAttachments);
+
    *pRenderPass = pass_handle;
 
    return VK_SUCCESS;
 }
 
+static const VkAttachmentDescription2 *
+vn_get_intercepted_attachments2(const VkAttachmentDescription2 *attachments,
+                                uint32_t count,
+                                const VkAllocationCallbacks *alloc)
+{
+   /* XXX drop the #ifdef after fixing common wsi */
+#ifdef ANDROID
+   bool has_present_src = false;
+   for (uint32_t i = 0; i < count; i++) {
+      if (attachments[i].initialLayout == VK_IMAGE_LAYOUT_PRESENT_SRC_KHR ||
+          attachments[i].finalLayout == VK_IMAGE_LAYOUT_PRESENT_SRC_KHR) {
+         has_present_src = true;
+         break;
+      }
+   }
+   if (!has_present_src)
+      return attachments;
+
+   size_t size = sizeof(VkAttachmentDescription2) * count;
+   VkAttachmentDescription2 *out_attachments = vk_alloc(
+      alloc, size, VN_DEFAULT_ALIGN, VK_SYSTEM_ALLOCATION_SCOPE_COMMAND);
+   if (!out_attachments)
+      return NULL;
+
+   memcpy(out_attachments, attachments, size);
+   for (uint32_t i = 0; i < count; i++) {
+      if (out_attachments[i].initialLayout == VK_IMAGE_LAYOUT_PRESENT_SRC_KHR)
+         out_attachments[i].initialLayout = VK_IMAGE_LAYOUT_GENERAL;
+      if (out_attachments[i].finalLayout == VK_IMAGE_LAYOUT_PRESENT_SRC_KHR)
+         out_attachments[i].finalLayout = VK_IMAGE_LAYOUT_GENERAL;
+   }
+   return out_attachments;
+#else
+   return attachments;
+#endif
+}
+
 VkResult
 vn_CreateRenderPass2(VkDevice device,
                      const VkRenderPassCreateInfo2 *pCreateInfo,
@@ -64,12 +147,21 @@ vn_CreateRenderPass2(VkDevice device,
 
    vn_object_base_init(&pass->base, VK_OBJECT_TYPE_RENDER_PASS, &dev->base);
 
-   /* XXX VK_IMAGE_LAYOUT_PRESENT_SRC_KHR */
+   VkRenderPassCreateInfo2 local_pass_info = *pCreateInfo;
+   local_pass_info.pAttachments = vn_get_intercepted_attachments2(
+      pCreateInfo->pAttachments, pCreateInfo->attachmentCount, alloc);
+   if (!local_pass_info.pAttachments) {
+      vk_free(alloc, pass);
+      return vn_error(dev->instance, VK_ERROR_OUT_OF_HOST_MEMORY);
+   }
 
    VkRenderPass pass_handle = vn_render_pass_to_handle(pass);
-   vn_async_vkCreateRenderPass2(dev->instance, device, pCreateInfo, NULL,
+   vn_async_vkCreateRenderPass2(dev->instance, device, &local_pass_info, NULL,
                                 &pass_handle);
 
+   if (local_pass_info.pAttachments != pCreateInfo->pAttachments)
+      vk_free(alloc, (void *)local_pass_info.pAttachments);
+
    *pRenderPass = pass_handle;
 
    return VK_SUCCESS;



More information about the mesa-commit mailing list