From 5fe64396b4c19a0a9df4e5e3013dd143f944b786 Mon Sep 17 00:00:00 2001 From: Stenzek Date: Mon, 8 May 2023 20:57:19 +1000 Subject: [PATCH] GS/Vulkan: Fix incorrect layout during copy to self Of course this happened in Dark Cloud 2. --- pcsx2/GS/Renderers/Vulkan/GSDeviceVK.cpp | 11 ++++++----- pcsx2/GS/Renderers/Vulkan/GSTextureVK.cpp | 12 ++++++++++++ pcsx2/GS/Renderers/Vulkan/GSTextureVK.h | 1 + 3 files changed, 19 insertions(+), 5 deletions(-) diff --git a/pcsx2/GS/Renderers/Vulkan/GSDeviceVK.cpp b/pcsx2/GS/Renderers/Vulkan/GSDeviceVK.cpp index c0da80a6b4..626ec4a769 100644 --- a/pcsx2/GS/Renderers/Vulkan/GSDeviceVK.cpp +++ b/pcsx2/GS/Renderers/Vulkan/GSDeviceVK.cpp @@ -955,11 +955,12 @@ void GSDeviceVK::CopyRect(GSTexture* sTex, GSTexture* dTex, const GSVector4i& r, EndRenderPass(); - dTexVK->TransitionToLayout(GSTextureVK::Layout::TransferDst); - dTexVK->SetUsedThisCommandBuffer(); - - sTexVK->TransitionToLayout(GSTextureVK::Layout::TransferSrc); sTexVK->SetUsedThisCommandBuffer(); + dTexVK->SetUsedThisCommandBuffer(); + sTexVK->TransitionToLayout( + (dTexVK == sTexVK) ? GSTextureVK::Layout::TransferSelf : GSTextureVK::Layout::TransferSrc); + dTexVK->TransitionToLayout( + (dTexVK == sTexVK) ? GSTextureVK::Layout::TransferSelf : GSTextureVK::Layout::TransferDst); #ifdef PCSX2_DEVBUILD // ensure we don't leave this bound later on, debug layer gets cranky @@ -968,7 +969,7 @@ void GSDeviceVK::CopyRect(GSTexture* sTex, GSTexture* dTex, const GSVector4i& r, #endif vkCmdCopyImage(g_vulkan_context->GetCurrentCommandBuffer(), sTexVK->GetImage(), - VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, dTexVK->GetImage(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &ic); + sTexVK->GetVkLayout(), dTexVK->GetImage(), dTexVK->GetVkLayout(), 1, &ic); dTexVK->SetState(GSTexture::State::Dirty); } diff --git a/pcsx2/GS/Renderers/Vulkan/GSTextureVK.cpp b/pcsx2/GS/Renderers/Vulkan/GSTextureVK.cpp index 0b07d35a2d..cfe9e6a59e 100644 --- a/pcsx2/GS/Renderers/Vulkan/GSTextureVK.cpp +++ b/pcsx2/GS/Renderers/Vulkan/GSTextureVK.cpp @@ -38,6 +38,7 @@ static constexpr std::array(GSTextureVK::Layout: VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // ClearDst VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, // TransferSrc VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // TransferDst + VK_IMAGE_LAYOUT_GENERAL, // TransferSelf VK_IMAGE_LAYOUT_PRESENT_SRC_KHR, // PresentSrc VK_IMAGE_LAYOUT_GENERAL, // FeedbackLoop VK_IMAGE_LAYOUT_GENERAL, // ReadWriteImage @@ -647,6 +648,12 @@ void GSTextureVK::TransitionSubresourcesToLayout( srcStageMask = VK_PIPELINE_STAGE_TRANSFER_BIT; break; + case Layout::TransferSelf: + // Image was being used as a copy source and destination, ensure all reads and writes have finished. + barrier.srcAccessMask = VK_ACCESS_TRANSFER_READ_BIT | VK_ACCESS_TRANSFER_WRITE_BIT; + srcStageMask = VK_PIPELINE_STAGE_TRANSFER_BIT; + break; + case Layout::FeedbackLoop: barrier.srcAccessMask = (aspect == VK_IMAGE_ASPECT_COLOR_BIT) ? (VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | @@ -713,6 +720,11 @@ void GSTextureVK::TransitionSubresourcesToLayout( dstStageMask = VK_PIPELINE_STAGE_TRANSFER_BIT; break; + case Layout::TransferSelf: + barrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT | VK_ACCESS_TRANSFER_WRITE_BIT; + dstStageMask = VK_PIPELINE_STAGE_TRANSFER_BIT; + break; + case Layout::PresentSrc: srcStageMask = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT; dstStageMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT; diff --git a/pcsx2/GS/Renderers/Vulkan/GSTextureVK.h b/pcsx2/GS/Renderers/Vulkan/GSTextureVK.h index 9b36c8ee72..7bdbb3dd66 100644 --- a/pcsx2/GS/Renderers/Vulkan/GSTextureVK.h +++ b/pcsx2/GS/Renderers/Vulkan/GSTextureVK.h @@ -35,6 +35,7 @@ public: ClearDst, TransferSrc, TransferDst, + TransferSelf, PresentSrc, FeedbackLoop, ReadWriteImage,