GS/Vulkan: Use fence counter for upload cmdbuffer selection

Readbacks don't increment the frame number, but submit the cmdbuffer.

Fixes incorrectly rendered status bar in Devil May Cry.
This commit is contained in:
Connor McLaughlin 2022-02-02 20:29:33 +10:00 committed by refractionpcsx2
parent ead6f9f4cd
commit 0c0bd8be98
3 changed files with 16 additions and 9 deletions

View File

@ -509,8 +509,9 @@ void GSDeviceVK::DoCopyRect(GSTexture* sTex, GSTexture* dTex, const GSVector4i&
EndRenderPass();
sTexVK->TransitionToLayout(VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);
dTexVK->TransitionToLayout(VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
sTexVK->TransitionToLayout(VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);
sTexVK->SetUsedThisCommandBuffer();
vkCmdCopyImage(g_vulkan_context->GetCurrentCommandBuffer(), sTexVK->GetImage(),
VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, dTexVK->GetImage(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &ic);
@ -798,10 +799,6 @@ void GSDeviceVK::DoInterlace(GSTexture* sTex, GSTexture* dTex, int shader, bool
static_cast<GSTextureVK*>(dTex)->TransitionToLayout(VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
const VkFramebuffer fb = static_cast<GSTextureVK*>(dTex)->GetFramebuffer(false);
if (fb == VK_NULL_HANDLE)
return;
const GSVector4i rc(0, 0, size.x, size.y);
EndRenderPass();
OMSetRenderTargets(dTex, nullptr, rc, false);
@ -2099,7 +2096,7 @@ void GSDeviceVK::PSSetShaderResource(int i, GSTexture* sr, bool check_state)
vkTex->CommitClear();
vkTex->TransitionToLayout(VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
}
vkTex->last_frame_used = m_frame;
vkTex->SetUsedThisCommandBuffer();
view = vkTex->GetView();
}
else
@ -2131,9 +2128,9 @@ void GSDeviceVK::SetUtilityTexture(GSTexture* tex, VkSampler sampler)
if (tex)
{
GSTextureVK* vkTex = static_cast<GSTextureVK*>(tex);
vkTex->last_frame_used = m_frame;
vkTex->CommitClear();
vkTex->TransitionToLayout(VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
vkTex->SetUsedThisCommandBuffer();
view = vkTex->GetView();
}
else

View File

@ -151,8 +151,7 @@ void* GSTextureVK::GetNativeHandle() const { return const_cast<Vulkan::Texture*>
VkCommandBuffer GSTextureVK::GetCommandBufferForUpdate()
{
const u32 frame = GSDeviceVK::GetInstance()->GetFrameNumber();
if (m_type != Type::Texture || frame == last_frame_used)
if (m_type != Type::Texture || m_use_fence_counter == g_vulkan_context->GetCurrentFenceCounter())
{
// Console.WriteLn("Texture update within frame, can't use do beforehand");
GSDeviceVK::GetInstance()->EndRenderPass();

View File

@ -17,6 +17,7 @@
#include "GS.h"
#include "GS/Renderers/Common/GSTexture.h"
#include "common/Vulkan/Context.h"
#include "common/Vulkan/Texture.h"
class GSTextureVK final : public GSTexture
@ -70,11 +71,21 @@ public:
m_clear_value.depth = depth;
}
// Call when the texture is bound to the pipeline, or read from in a copy.
__fi void SetUsedThisCommandBuffer()
{
m_use_fence_counter = g_vulkan_context->GetCurrentFenceCounter();
}
private:
VkCommandBuffer GetCommandBufferForUpdate();
Vulkan::Texture m_texture;
// Contains the fence counter when the texture was last used.
// When this matches the current fence counter, the texture was used this command buffer.
u64 m_use_fence_counter = 0;
ClearValue m_clear_value = {};
GSVector4i m_map_area = GSVector4i::zero();