GS/Vulkan: Work around NVIDIA driver clear issue

NVIDIA drivers appear to return random garbage when sampling the
RT via a feedback loop, if the load op for the render pass is CLEAR.
Using vkCmdClearAttachments() doesn't work, so we have to clear the
image instead.

I'm not sure if this is a spec violation, or what we're doing just
happens to be undefined. Given attachment clear doesn't work, I'm
inclined to go with the former.
This commit is contained in:
Stenzek 2023-07-04 17:39:14 +10:00 committed by Connor McLaughlin
parent 9e19ef0d03
commit 08649b7aa8
2 changed files with 11 additions and 0 deletions

View File

@ -1521,6 +1521,14 @@ void GSDeviceVK::OMSetRenderTargets(GSTexture* rt, GSTexture* ds, const GSVector
{
if (vkRt)
{
// NVIDIA drivers appear to return random garbage when sampling the RT via a feedback loop, if the load op for
// the render pass is CLEAR. Using vkCmdClearAttachments() doesn't work, so we have to clear the image instead.
if (feedback_loop & FeedbackLoopFlag_ReadAndWriteRT && vkRt->GetState() == GSTexture::State::Cleared &&
g_vulkan_context->IsDeviceNVIDIA())
{
vkRt->CommitClear();
}
vkRt->TransitionToLayout((feedback_loop & FeedbackLoopFlag_ReadAndWriteRT) ?
GSTextureVK::Layout::FeedbackLoop :
GSTextureVK::Layout::ColorAttachment);

View File

@ -128,6 +128,9 @@ public:
return m_device_properties.limits.maxImageDimension2D;
}
/// Returns true if running on an NVIDIA GPU.
__fi bool IsDeviceNVIDIA() const { return (m_device_properties.vendorID == 0x10DE); }
// Creates a simple render pass.
__ri VkRenderPass GetRenderPass(VkFormat color_format, VkFormat depth_format,
VkAttachmentLoadOp color_load_op = VK_ATTACHMENT_LOAD_OP_LOAD,