From c968ba624b8f189ab541095993b1d6b2ec5795ba Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Sun, 3 Nov 2024 13:15:24 +0100 Subject: [PATCH] [dxvk] Only force late clears on older Nvidia drivers Disables the workaround introduced in 00872e9e4fdd87d92f2dd662791b8de6a7edf10c on drivers that were not affected by the bug. --- src/dxvk/dxvk_context.cpp | 16 +++++++--------- src/dxvk/dxvk_device.cpp | 4 ++++ src/dxvk/dxvk_device.h | 1 + 3 files changed, 12 insertions(+), 9 deletions(-) diff --git a/src/dxvk/dxvk_context.cpp b/src/dxvk/dxvk_context.cpp index 6e00dde40..4523be383 100644 --- a/src/dxvk/dxvk_context.cpp +++ b/src/dxvk/dxvk_context.cpp @@ -1783,7 +1783,8 @@ namespace dxvk { } if (attachmentIndex < 0) { - bool hasViewFormatMismatch = imageView->info().format != imageView->image()->info().format; + bool useLateClear = m_device->perfHints().renderPassClearFormatBug + && imageView->info().format != imageView->image()->info().format; flushPendingAccesses(*imageView, DxvkAccess::Write); @@ -1818,9 +1819,7 @@ namespace dxvk { attachmentInfo.loadOp = colorOp.loadOp; - // We can't use LOAD_OP_CLEAR if the view format does not match the - // underlying image format, so just discard here and use clear later. - if (hasViewFormatMismatch && attachmentInfo.loadOp == VK_ATTACHMENT_LOAD_OP_CLEAR) + if (useLateClear && attachmentInfo.loadOp == VK_ATTACHMENT_LOAD_OP_CLEAR) attachmentInfo.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; renderingInfo.colorAttachmentCount = 1; @@ -1853,9 +1852,9 @@ namespace dxvk { m_cmd->cmdBeginRendering(&renderingInfo); - if (hasViewFormatMismatch) { + if (useLateClear && clearAspects) { VkClearAttachment clearInfo = { }; - clearInfo.aspectMask = imageView->info().aspects; + clearInfo.aspectMask = clearAspects; clearInfo.clearValue = clearValue; VkClearRect clearRect = { }; @@ -4661,9 +4660,8 @@ namespace dxvk { if (ops.colorOps[i].loadOp == VK_ATTACHMENT_LOAD_OP_CLEAR) { colorInfos[i].clearValue.color = ops.colorOps[i].clearValue; - // We can't use LOAD_OP_CLEAR if the view format does not match the - // underlying image format, so just discard here and use clear later. - if (colorTarget.view->info().format != colorTarget.view->image()->info().format) { + if (m_device->perfHints().renderPassClearFormatBug + && colorTarget.view->info().format != colorTarget.view->image()->info().format) { colorInfos[i].loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; auto& clear = lateClears[lateClearCount++]; diff --git a/src/dxvk/dxvk_device.cpp b/src/dxvk/dxvk_device.cpp index 830f98d87..bca694268 100644 --- a/src/dxvk/dxvk_device.cpp +++ b/src/dxvk/dxvk_device.cpp @@ -346,6 +346,10 @@ namespace dxvk { hints.preferFbResolve = m_features.amdShaderFragmentMask && (m_adapter->matchesDriver(VK_DRIVER_ID_AMD_OPEN_SOURCE_KHR) || m_adapter->matchesDriver(VK_DRIVER_ID_AMD_PROPRIETARY_KHR)); + // Older Nvidia drivers sometimes use the wrong format + // to interpret the clear color in render pass clears. + hints.renderPassClearFormatBug = m_adapter->matchesDriver( + VK_DRIVER_ID_NVIDIA_PROPRIETARY, Version(), Version(560, 28, 3)); return hints; } diff --git a/src/dxvk/dxvk_device.h b/src/dxvk/dxvk_device.h index 1d07cfb6b..4b6da7922 100644 --- a/src/dxvk/dxvk_device.h +++ b/src/dxvk/dxvk_device.h @@ -36,6 +36,7 @@ namespace dxvk { struct DxvkDevicePerfHints { VkBool32 preferFbDepthStencilCopy : 1; VkBool32 preferFbResolve : 1; + VkBool32 renderPassClearFormatBug : 1; }; /**