GS/Vulkan: Fix incorrect layout during copy to self

Of course this happened in Dark Cloud 2.
This commit is contained in:
Stenzek 2023-05-08 20:57:19 +10:00 committed by refractionpcsx2
parent 75b782f261
commit 5fe64396b4
3 changed files with 19 additions and 5 deletions

View File

@ -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);
}

View File

@ -38,6 +38,7 @@ static constexpr std::array<VkImageLayout, static_cast<u32>(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;

View File

@ -35,6 +35,7 @@ public:
ClearDst,
TransferSrc,
TransferDst,
TransferSelf,
PresentSrc,
FeedbackLoop,
ReadWriteImage,