diff --git a/src/dxvk/dxvk_context.cpp b/src/dxvk/dxvk_context.cpp index 005c22733..210526438 100644 --- a/src/dxvk/dxvk_context.cpp +++ b/src/dxvk/dxvk_context.cpp @@ -1950,22 +1950,27 @@ namespace dxvk { this->prepareImage(dstImage, vk::makeSubresourceRange(region.dstSubresource)); this->prepareImage(srcImage, vk::makeSubresourceRange(region.srcSubresource)); - bool useFb = srcImage->info().format != format + auto formatInfo = lookupFormatInfo(format); + + bool useRp = srcImage->info().format != format || dstImage->info().format != format; - if (m_device->perfHints().preferFbResolve) { - useFb |= (dstImage->info().usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) - && (srcImage->info().usage & VK_IMAGE_USAGE_SAMPLED_BIT); - } + useRp |= (srcImage->info().usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) + && (dstImage->info().usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT); - if (!useFb) { - this->resolveImageHw( - dstImage, srcImage, region); + if (useRp) { + // Work out resolve mode based on format properties. For color images, + // we must use AVERAGE unless the resolve uses an integer format. + VkResolveModeFlagBits mode = VK_RESOLVE_MODE_AVERAGE_BIT; + + if (formatInfo->flags.any(DxvkFormatFlag::SampledSInt, DxvkFormatFlag::SampledUInt) + || (formatInfo->aspectMask & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT))) + mode = VK_RESOLVE_MODE_SAMPLE_ZERO_BIT; + + this->resolveImageRp(dstImage, srcImage, region, + format, mode, mode); } else { - this->resolveImageFb( - dstImage, srcImage, region, format, - VK_RESOLVE_MODE_NONE, - VK_RESOLVE_MODE_NONE); + this->resolveImageHw(dstImage, srcImage, region); } } diff --git a/src/dxvk/dxvk_device.cpp b/src/dxvk/dxvk_device.cpp index 5a4999942..e0f04e74d 100644 --- a/src/dxvk/dxvk_device.cpp +++ b/src/dxvk/dxvk_device.cpp @@ -427,9 +427,6 @@ namespace dxvk { && (m_adapter->matchesDriver(VK_DRIVER_ID_MESA_RADV_KHR) || m_adapter->matchesDriver(VK_DRIVER_ID_AMD_OPEN_SOURCE_KHR) || m_adapter->matchesDriver(VK_DRIVER_ID_AMD_PROPRIETARY_KHR)); - 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. diff --git a/src/dxvk/dxvk_device.h b/src/dxvk/dxvk_device.h index 9142a739d..0a1e622e5 100644 --- a/src/dxvk/dxvk_device.h +++ b/src/dxvk/dxvk_device.h @@ -36,7 +36,6 @@ namespace dxvk { */ struct DxvkDevicePerfHints { VkBool32 preferFbDepthStencilCopy : 1; - VkBool32 preferFbResolve : 1; VkBool32 renderPassClearFormatBug : 1; VkBool32 preferRenderPassOps : 1; VkBool32 preferPrimaryCmdBufs : 1;