From 9fe833dfd940bc08633257cb32028c9335820b09 Mon Sep 17 00:00:00 2001 From: Chia-I Wu Date: Wed, 5 May 2021 10:42:50 -0700 Subject: [PATCH] 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 Reviewed-by: Yiwei Zhang (v1) Part-of: --- src/virtio/vulkan/vn_image.h | 7 + src/virtio/vulkan/vn_render_pass.c | 206 +++++++++++++++++------------ src/virtio/vulkan/vn_render_pass.h | 13 ++ 3 files changed, 141 insertions(+), 85 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" +#include "vn_image.h" -static bool -vn_render_pass_has_present_src(const VkRenderPassCreateInfo *create_info) +#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); +} + +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 struct vn_render_pass * +vn_render_pass_create(struct vn_device *dev, + uint32_t acquire_count, + uint32_t release_count, + const VkAllocationCallbacks *alloc) +{ + 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; + + 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 */ -static const VkAttachmentDescription * -vn_get_intercepted_attachments(const VkAttachmentDescription *attachments, - uint32_t 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) - 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_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,