From 25fe723fa69306f74555c70f30444d16a6dbbc8f Mon Sep 17 00:00:00 2001 From: GPUCode Date: Wed, 11 Jan 2023 17:34:01 +0200 Subject: [PATCH] renderer_vulkan: Support self copy FE games copy parts of the framebuffer to itself. Don't switch layout in that case --- .../renderer_vulkan/vk_swapchain.cpp | 13 +++++++------ .../renderer_vulkan/vk_texture_runtime.cpp | 18 ++++++++++++------ 2 files changed, 19 insertions(+), 12 deletions(-) diff --git a/src/video_core/renderer_vulkan/vk_swapchain.cpp b/src/video_core/renderer_vulkan/vk_swapchain.cpp index 75e5e3a03..2756adf51 100644 --- a/src/video_core/renderer_vulkan/vk_swapchain.cpp +++ b/src/video_core/renderer_vulkan/vk_swapchain.cpp @@ -43,8 +43,10 @@ Swapchain::~Swapchain() { } void Swapchain::Create(vk::SurfaceKHR new_surface) { - is_outdated = false; - is_suboptimal = false; + vk::Device device = instance.GetDevice(); + device.waitIdle(); + Destroy(); + if (new_surface) { instance.GetInstance().destroySurfaceKHR(surface); surface = new_surface; @@ -79,10 +81,6 @@ void Swapchain::Create(vk::SurfaceKHR new_surface) { .oldSwapchain = nullptr, }; - vk::Device device = instance.GetDevice(); - device.waitIdle(); - Destroy(); - try { swapchain = device.createSwapchainKHR(swapchain_info); } catch (vk::SystemError& err) { @@ -93,6 +91,9 @@ void Swapchain::Create(vk::SurfaceKHR new_surface) { SetupImages(); resource_ticks.clear(); resource_ticks.resize(image_count); + + is_outdated = false; + is_suboptimal = false; } MICROPROFILE_DEFINE(Vulkan_Acquire, "Vulkan", "Swapchain Acquire", MP_RGB(185, 66, 245)); diff --git a/src/video_core/renderer_vulkan/vk_texture_runtime.cpp b/src/video_core/renderer_vulkan/vk_texture_runtime.cpp index e0501c7c2..46351f358 100644 --- a/src/video_core/renderer_vulkan/vk_texture_runtime.cpp +++ b/src/video_core/renderer_vulkan/vk_texture_runtime.cpp @@ -625,12 +625,18 @@ bool TextureRuntime::CopyTextures(Surface& source, Surface& dest, .extent = {copy.extent.width, copy.extent.height, 1}, }; + const bool self_copy = params.src_image == params.dst_image; + const vk::ImageLayout new_src_layout = + self_copy ? vk::ImageLayout::eGeneral : vk::ImageLayout::eTransferSrcOptimal; + const vk::ImageLayout new_dst_layout = + self_copy ? vk::ImageLayout::eGeneral : vk::ImageLayout::eTransferDstOptimal; + const std::array pre_barriers = { vk::ImageMemoryBarrier{ .srcAccessMask = params.src_access, .dstAccessMask = vk::AccessFlagBits::eTransferRead, .oldLayout = vk::ImageLayout::eGeneral, - .newLayout = vk::ImageLayout::eTransferSrcOptimal, + .newLayout = new_src_layout, .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, .image = params.src_image, @@ -646,7 +652,7 @@ bool TextureRuntime::CopyTextures(Surface& source, Surface& dest, .srcAccessMask = params.dst_access, .dstAccessMask = vk::AccessFlagBits::eTransferWrite, .oldLayout = vk::ImageLayout::eGeneral, - .newLayout = vk::ImageLayout::eTransferDstOptimal, + .newLayout = new_dst_layout, .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, .image = params.dst_image, @@ -663,7 +669,7 @@ bool TextureRuntime::CopyTextures(Surface& source, Surface& dest, vk::ImageMemoryBarrier{ .srcAccessMask = vk::AccessFlagBits::eNone, .dstAccessMask = vk::AccessFlagBits::eNone, - .oldLayout = vk::ImageLayout::eTransferSrcOptimal, + .oldLayout = new_src_layout, .newLayout = vk::ImageLayout::eGeneral, .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, @@ -679,7 +685,7 @@ bool TextureRuntime::CopyTextures(Surface& source, Surface& dest, vk::ImageMemoryBarrier{ .srcAccessMask = vk::AccessFlagBits::eTransferWrite, .dstAccessMask = params.dst_access, - .oldLayout = vk::ImageLayout::eTransferDstOptimal, + .oldLayout = new_dst_layout, .newLayout = vk::ImageLayout::eGeneral, .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, @@ -697,8 +703,8 @@ bool TextureRuntime::CopyTextures(Surface& source, Surface& dest, cmdbuf.pipelineBarrier(params.pipeline_flags, vk::PipelineStageFlagBits::eTransfer, vk::DependencyFlagBits::eByRegion, {}, {}, pre_barriers); - cmdbuf.copyImage(params.src_image, vk::ImageLayout::eTransferSrcOptimal, params.dst_image, - vk::ImageLayout::eTransferDstOptimal, image_copy); + cmdbuf.copyImage(params.src_image, new_src_layout, params.dst_image, new_dst_layout, + image_copy); cmdbuf.pipelineBarrier(vk::PipelineStageFlagBits::eTransfer, params.pipeline_flags, vk::DependencyFlagBits::eByRegion, {}, {}, post_barriers);