From 1371dcfa4ac1ea0ed60e07e3254850f9f7d2fbcb Mon Sep 17 00:00:00 2001 From: Stenzek Date: Sun, 5 Feb 2023 13:03:10 +1000 Subject: [PATCH] Vulkan/Texture: Fix incorrect upload image layout --- src/common/vulkan/swap_chain.cpp | 3 ++- src/common/vulkan/texture.cpp | 13 +++++++++---- src/common/vulkan/texture.h | 3 ++- src/frontend-common/imgui_impl_vulkan.cpp | 1 + 4 files changed, 14 insertions(+), 6 deletions(-) diff --git a/src/common/vulkan/swap_chain.cpp b/src/common/vulkan/swap_chain.cpp index 06b2eb1f51..d9a54e0dda 100644 --- a/src/common/vulkan/swap_chain.cpp +++ b/src/common/vulkan/swap_chain.cpp @@ -715,7 +715,8 @@ bool SwapChain::SetupSwapChainImages() // Create texture object, which creates a view of the backbuffer if (!image.texture.Adopt(image.image, VK_IMAGE_VIEW_TYPE_2D, m_window_info.surface_width, - m_window_info.surface_height, 1, 1, m_surface_format.format, VK_SAMPLE_COUNT_1_BIT)) + m_window_info.surface_height, 1, 1, m_surface_format.format, VK_SAMPLE_COUNT_1_BIT, + VK_IMAGE_LAYOUT_UNDEFINED)) { return false; } diff --git a/src/common/vulkan/texture.cpp b/src/common/vulkan/texture.cpp index 59166ee92b..82f57fb328 100644 --- a/src/common/vulkan/texture.cpp +++ b/src/common/vulkan/texture.cpp @@ -163,6 +163,7 @@ bool Vulkan::Texture::Create(u32 width, u32 height, u32 levels, u32 layers, VkFo m_samples = static_cast(samples); m_format = LookupBaseFormat(format); m_view_type = view_type; + m_layout = VK_IMAGE_LAYOUT_UNDEFINED; m_image = image; m_allocation = allocation; m_view = view; @@ -170,7 +171,7 @@ bool Vulkan::Texture::Create(u32 width, u32 height, u32 levels, u32 layers, VkFo } bool Vulkan::Texture::Adopt(VkImage existing_image, VkImageViewType view_type, u32 width, u32 height, u32 levels, - u32 layers, VkFormat format, VkSampleCountFlagBits samples, + u32 layers, VkFormat format, VkSampleCountFlagBits samples, VkImageLayout layout, const VkComponentMapping* swizzle /* = nullptr */) { // Only need to create the image view, this is mainly for swap chains. @@ -205,6 +206,7 @@ bool Vulkan::Texture::Adopt(VkImage existing_image, VkImageViewType view_type, u m_format = LookupBaseFormat(format); m_samples = static_cast(samples); m_view_type = view_type; + m_layout = layout; m_image = existing_image; m_view = view; return true; @@ -395,8 +397,11 @@ VkFramebuffer Vulkan::Texture::CreateFramebuffer(VkRenderPass render_pass) void Vulkan::Texture::UpdateFromBuffer(VkCommandBuffer cmdbuf, u32 level, u32 layer, u32 x, u32 y, u32 width, u32 height, VkBuffer buffer, u32 buffer_offset, u32 row_length) { + // If we're previously undefined, don't leave any images in this layout. const VkImageLayout old_layout = m_layout; - if (old_layout != VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL) + if (old_layout == VK_IMAGE_LAYOUT_UNDEFINED) + TransitionToLayout(cmdbuf, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL); + else if (old_layout != VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL) TransitionSubresourcesToLayout(cmdbuf, level, 1, layer, 1, old_layout, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL); const VkBufferImageCopy bic = {static_cast(buffer_offset), @@ -406,9 +411,9 @@ void Vulkan::Texture::UpdateFromBuffer(VkCommandBuffer cmdbuf, u32 level, u32 la {static_cast(x), static_cast(y), 0}, {width, height, 1u}}; - vkCmdCopyBufferToImage(cmdbuf, buffer, m_image, m_layout, 1, &bic); + vkCmdCopyBufferToImage(cmdbuf, buffer, m_image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &bic); - if (old_layout != VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL) + if (old_layout != VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL && old_layout != VK_IMAGE_LAYOUT_UNDEFINED) TransitionSubresourcesToLayout(cmdbuf, level, 1, layer, 1, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, old_layout); } diff --git a/src/common/vulkan/texture.h b/src/common/vulkan/texture.h index c8daedd4bf..644e1d87d6 100644 --- a/src/common/vulkan/texture.h +++ b/src/common/vulkan/texture.h @@ -46,7 +46,8 @@ class Texture final : public GPUTexture const VkComponentMapping* swizzle = nullptr); bool Adopt(VkImage existing_image, VkImageViewType view_type, u32 width, u32 height, u32 levels, u32 layers, - VkFormat format, VkSampleCountFlagBits samples, const VkComponentMapping* swizzle = nullptr); + VkFormat format, VkSampleCountFlagBits samples, VkImageLayout layout, + const VkComponentMapping* swizzle = nullptr); void Destroy(bool defer = true); diff --git a/src/frontend-common/imgui_impl_vulkan.cpp b/src/frontend-common/imgui_impl_vulkan.cpp index d157767e6e..381e4a96c1 100644 --- a/src/frontend-common/imgui_impl_vulkan.cpp +++ b/src/frontend-common/imgui_impl_vulkan.cpp @@ -413,6 +413,7 @@ bool ImGui_ImplVulkan_CreateFontsTexture() // Store our identifier bd->FontTexture.Update(0, 0, width, height, 0, 0, pixels, sizeof(u32) * width); + bd->FontTexture.TransitionToLayout(g_vulkan_context->GetCurrentCommandBuffer(), VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); io.Fonts->SetTexID((ImTextureID)&bd->FontTexture); return true; }