Mesa (main): venus: remember render pass PRESENT_SRC attachments

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Thu Jun 3 06:13:17 UTC 2021


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

Author: Chia-I Wu <olvaffe at gmail.com>
Date:   Wed May  5 10:42:50 2021 -0700

venus: remember render pass PRESENT_SRC attachments

We need them for wsi queue ownership transfer.

v2: make VN_PRESENT_SRC_INTERNAL_LAYOUT public

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

---

 src/virtio/vulkan/vn_image.h       |   7 ++
 src/virtio/vulkan/vn_render_pass.c | 200 ++++++++++++++++++++++---------------
 src/virtio/vulkan/vn_render_pass.h |  13 +++
 3 files changed, 138 insertions(+), 82 deletions(-)

diff --git a/src/virtio/vulkan/vn_image.h b/src/virtio/vulkan/vn_image.h
index a8266af01ee..ac0338f9827 100644
--- a/src/virtio/vulkan/vn_image.h
+++ b/src/virtio/vulkan/vn_image.h
@@ -13,6 +13,13 @@
 
 #include "vn_common.h"
 
+/* XXX drop the #ifdef after fixing common wsi */
+#ifdef ANDROID
+#define VN_PRESENT_SRC_INTERNAL_LAYOUT VK_IMAGE_LAYOUT_GENERAL
+#else
+#define VN_PRESENT_SRC_INTERNAL_LAYOUT VK_IMAGE_LAYOUT_PRESENT_SRC_KHR
+#endif
+
 enum {
    VN_IMAGE_OWNERSHIP_ACQUIRE = 0,
    VN_IMAGE_OWNERSHIP_RELEASE = 1,
diff --git a/src/virtio/vulkan/vn_render_pass.c b/src/virtio/vulkan/vn_render_pass.c
index b7f4db0ba53..7f3310fe2e6 100644
--- a/src/virtio/vulkan/vn_render_pass.c
+++ b/src/virtio/vulkan/vn_render_pass.c
@@ -14,62 +14,105 @@
 #include "venus-protocol/vn_protocol_driver_render_pass.h"
 
 #include "vn_device.h"
-
-static bool
-vn_render_pass_has_present_src(const VkRenderPassCreateInfo *create_info)
+#include "vn_image.h"
+
+#define COUNT_PRESENT_SRC(atts, att_count, initial_count, final_count)       \
+   do {                                                                      \
+      *initial_count = 0;                                                    \
+      *final_count = 0;                                                      \
+      for (uint32_t i = 0; i < att_count; i++) {                             \
+         if (atts[i].initialLayout == VK_IMAGE_LAYOUT_PRESENT_SRC_KHR)       \
+            (*initial_count)++;                                              \
+         if (atts[i].finalLayout == VK_IMAGE_LAYOUT_PRESENT_SRC_KHR)         \
+            (*final_count)++;                                                \
+      }                                                                      \
+   } while (false)
+
+#define REPLACE_PRESENT_SRC(pass, atts, att_count, out_atts)                 \
+   do {                                                                      \
+      struct vn_present_src_attachment *_acquire_atts =                      \
+         pass->present_src_attachments;                                      \
+      struct vn_present_src_attachment *_release_atts =                      \
+         _acquire_atts + pass->acquire_count;                                \
+                                                                             \
+      memcpy(out_atts, atts, sizeof(*atts) * att_count);                     \
+      for (uint32_t i = 0; i < att_count; i++) {                             \
+         if (out_atts[i].initialLayout == VK_IMAGE_LAYOUT_PRESENT_SRC_KHR) { \
+            out_atts[i].initialLayout = VN_PRESENT_SRC_INTERNAL_LAYOUT;      \
+            _acquire_atts->acquire = true;                                   \
+            _acquire_atts->index = i;                                        \
+            _acquire_atts++;                                                 \
+         }                                                                   \
+         if (out_atts[i].finalLayout == VK_IMAGE_LAYOUT_PRESENT_SRC_KHR) {   \
+            out_atts[i].finalLayout = VN_PRESENT_SRC_INTERNAL_LAYOUT;        \
+            _release_atts->acquire = false;                                  \
+            _release_atts->index = i;                                        \
+            _release_atts++;                                                 \
+         }                                                                   \
+      }                                                                      \
+   } while (false)
+
+static void
+vn_render_pass_count_present_src(const VkRenderPassCreateInfo *create_info,
+                                 uint32_t *initial_count,
+                                 uint32_t *final_count)
 {
-   /* XXX drop the #ifdef after fixing common wsi */
-#ifdef ANDROID
-   for (uint32_t i = 0; i < create_info->attachmentCount; i++) {
-      const VkAttachmentDescription *att = &create_info->pAttachments[i];
-      if (att->initialLayout == VK_IMAGE_LAYOUT_PRESENT_SRC_KHR ||
-          att->finalLayout == VK_IMAGE_LAYOUT_PRESENT_SRC_KHR)
-         return true;
-   }
-#endif
-
-   return false;
+   COUNT_PRESENT_SRC(create_info->pAttachments, create_info->attachmentCount,
+                     initial_count, final_count);
 }
 
-static bool
-vn_render_pass_has_present_src2(const VkRenderPassCreateInfo2 *create_info)
+static void
+vn_render_pass_count_present_src2(const VkRenderPassCreateInfo2 *create_info,
+                                  uint32_t *initial_count,
+                                  uint32_t *final_count)
 {
-   /* XXX drop the #ifdef after fixing common wsi */
-#ifdef ANDROID
-   for (uint32_t i = 0; i < create_info->attachmentCount; i++) {
-      const VkAttachmentDescription2 *att = &create_info->pAttachments[i];
-      if (att->initialLayout == VK_IMAGE_LAYOUT_PRESENT_SRC_KHR ||
-          att->finalLayout == VK_IMAGE_LAYOUT_PRESENT_SRC_KHR)
-         return true;
-   }
-#endif
+   COUNT_PRESENT_SRC(create_info->pAttachments, create_info->attachmentCount,
+                     initial_count, final_count);
+}
 
-   return false;
+static void
+vn_render_pass_replace_present_src(struct vn_render_pass *pass,
+                                   const VkRenderPassCreateInfo *create_info,
+                                   VkAttachmentDescription *out_atts)
+{
+   REPLACE_PRESENT_SRC(pass, create_info->pAttachments,
+                       create_info->attachmentCount, out_atts);
 }
 
-/* render pass commands */
+static void
+vn_render_pass_replace_present_src2(struct vn_render_pass *pass,
+                                    const VkRenderPassCreateInfo2 *create_info,
+                                    VkAttachmentDescription2 *out_atts)
+{
+   REPLACE_PRESENT_SRC(pass, create_info->pAttachments,
+                       create_info->attachmentCount, out_atts);
+}
 
-static const VkAttachmentDescription *
-vn_get_intercepted_attachments(const VkAttachmentDescription *attachments,
-                               uint32_t count,
-                               const VkAllocationCallbacks *alloc)
+static struct vn_render_pass *
+vn_render_pass_create(struct vn_device *dev,
+                      uint32_t acquire_count,
+                      uint32_t release_count,
+                      const VkAllocationCallbacks *alloc)
 {
-   size_t size = sizeof(VkAttachmentDescription) * count;
-   VkAttachmentDescription *out_attachments = vk_alloc(
-      alloc, size, VN_DEFAULT_ALIGN, VK_SYSTEM_ALLOCATION_SCOPE_COMMAND);
-   if (!out_attachments)
+   const uint32_t total_count = acquire_count + release_count;
+   struct vn_render_pass *pass = vk_zalloc(
+      alloc,
+      sizeof(*pass) + sizeof(pass->present_src_attachments[0]) * total_count,
+      VN_DEFAULT_ALIGN, VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
+   if (!pass)
       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;
+   vn_object_base_init(&pass->base, VK_OBJECT_TYPE_RENDER_PASS, &dev->base);
+
+   pass->acquire_count = acquire_count;
+   pass->release_count = release_count;
+   pass->present_src_count = total_count;
+
+   return pass;
 }
 
+/* render pass commands */
+
 VkResult
 vn_CreateRenderPass(VkDevice device,
                     const VkRenderPassCreateInfo *pCreateInfo,
@@ -80,23 +123,30 @@ vn_CreateRenderPass(VkDevice device,
    const VkAllocationCallbacks *alloc =
       pAllocator ? pAllocator : &dev->base.base.alloc;
 
+   uint32_t acquire_count;
+   uint32_t release_count;
+   vn_render_pass_count_present_src(pCreateInfo, &acquire_count,
+                                    &release_count);
+
    struct vn_render_pass *pass =
-      vk_zalloc(alloc, sizeof(*pass), VN_DEFAULT_ALIGN,
-                VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
+      vn_render_pass_create(dev, acquire_count, release_count, alloc);
    if (!pass)
       return vn_error(dev->instance, VK_ERROR_OUT_OF_HOST_MEMORY);
 
-   vn_object_base_init(&pass->base, VK_OBJECT_TYPE_RENDER_PASS, &dev->base);
-
    VkRenderPassCreateInfo local_pass_info;
-   if (vn_render_pass_has_present_src(pCreateInfo)) {
-      local_pass_info = *pCreateInfo;
-      local_pass_info.pAttachments = vn_get_intercepted_attachments(
-         pCreateInfo->pAttachments, pCreateInfo->attachmentCount, alloc);
-      if (!local_pass_info.pAttachments) {
+   if (pass->present_src_count) {
+      VkAttachmentDescription *temp_atts =
+         vk_alloc(alloc, sizeof(*temp_atts) * pCreateInfo->attachmentCount,
+                  VN_DEFAULT_ALIGN, VK_SYSTEM_ALLOCATION_SCOPE_COMMAND);
+      if (!temp_atts) {
          vk_free(alloc, pass);
          return vn_error(dev->instance, VK_ERROR_OUT_OF_HOST_MEMORY);
       }
+
+      vn_render_pass_replace_present_src(pass, pCreateInfo, temp_atts);
+
+      local_pass_info = *pCreateInfo;
+      local_pass_info.pAttachments = temp_atts;
       pCreateInfo = &local_pass_info;
    }
 
@@ -112,27 +162,6 @@ vn_CreateRenderPass(VkDevice device,
    return VK_SUCCESS;
 }
 
-static const VkAttachmentDescription2 *
-vn_get_intercepted_attachments2(const VkAttachmentDescription2 *attachments,
-                                uint32_t count,
-                                const VkAllocationCallbacks *alloc)
-{
-   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;
-}
-
 VkResult
 vn_CreateRenderPass2(VkDevice device,
                      const VkRenderPassCreateInfo2 *pCreateInfo,
@@ -143,23 +172,30 @@ vn_CreateRenderPass2(VkDevice device,
    const VkAllocationCallbacks *alloc =
       pAllocator ? pAllocator : &dev->base.base.alloc;
 
+   uint32_t acquire_count;
+   uint32_t release_count;
+   vn_render_pass_count_present_src2(pCreateInfo, &acquire_count,
+                                     &release_count);
+
    struct vn_render_pass *pass =
-      vk_zalloc(alloc, sizeof(*pass), VN_DEFAULT_ALIGN,
-                VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
+      vn_render_pass_create(dev, acquire_count, release_count, alloc);
    if (!pass)
       return vn_error(dev->instance, VK_ERROR_OUT_OF_HOST_MEMORY);
 
-   vn_object_base_init(&pass->base, VK_OBJECT_TYPE_RENDER_PASS, &dev->base);
-
    VkRenderPassCreateInfo2 local_pass_info;
-   if (vn_render_pass_has_present_src2(pCreateInfo)) {
-      local_pass_info = *pCreateInfo;
-      local_pass_info.pAttachments = vn_get_intercepted_attachments2(
-         pCreateInfo->pAttachments, pCreateInfo->attachmentCount, alloc);
-      if (!local_pass_info.pAttachments) {
+   if (pass->present_src_count) {
+      VkAttachmentDescription2 *temp_atts =
+         vk_alloc(alloc, sizeof(*temp_atts) * pCreateInfo->attachmentCount,
+                  VN_DEFAULT_ALIGN, VK_SYSTEM_ALLOCATION_SCOPE_COMMAND);
+      if (!temp_atts) {
          vk_free(alloc, pass);
          return vn_error(dev->instance, VK_ERROR_OUT_OF_HOST_MEMORY);
       }
+
+      vn_render_pass_replace_present_src2(pass, pCreateInfo, temp_atts);
+
+      local_pass_info = *pCreateInfo;
+      local_pass_info.pAttachments = temp_atts;
       pCreateInfo = &local_pass_info;
    }
 
diff --git a/src/virtio/vulkan/vn_render_pass.h b/src/virtio/vulkan/vn_render_pass.h
index 34bf31c317e..fe245124a52 100644
--- a/src/virtio/vulkan/vn_render_pass.h
+++ b/src/virtio/vulkan/vn_render_pass.h
@@ -13,10 +13,23 @@
 
 #include "vn_common.h"
 
+struct vn_present_src_attachment {
+   bool acquire;
+   uint32_t index;
+};
+
 struct vn_render_pass {
    struct vn_object_base base;
 
    VkExtent2D granularity;
+
+   /* track attachments that have PRESENT_SRC as their initialLayout or
+    * finalLayout
+    */
+   uint32_t acquire_count;
+   uint32_t release_count;
+   uint32_t present_src_count;
+   struct vn_present_src_attachment present_src_attachments[];
 };
 VK_DEFINE_NONDISP_HANDLE_CASTS(vn_render_pass,
                                base.base,



More information about the mesa-commit mailing list