VK: Copy depth buffer if we can't blit. Some GPUs can't blit to depth.

Fixes some recent issues with Intel GPUs on Vulkan.
This commit is contained in:
Henrik Rydgård 2020-10-11 10:52:55 +02:00
parent b3cf097e77
commit dc0f7ca8ee
5 changed files with 14 additions and 4 deletions

View File

@ -537,9 +537,13 @@ void VulkanContext::ChooseDevice(int physical_device) {
break;
}
}
if (deviceInfo_.preferredDepthStencilFormat == VK_FORMAT_UNDEFINED) {
// WTF? This is bad.
ERROR_LOG(G3D, "Could not find a usable depth stencil format.");
_assert_msg_(deviceInfo_.preferredDepthStencilFormat != VK_FORMAT_UNDEFINED, "Could not find a usable depth stencil format.");
VkFormatProperties preferredProps;
vkGetPhysicalDeviceFormatProperties(physical_devices_[physical_device_], deviceInfo_.preferredDepthStencilFormat, &preferredProps);
if ((preferredProps.optimalTilingFeatures & VK_FORMAT_FEATURE_BLIT_SRC_BIT) &&
(preferredProps.optimalTilingFeatures & VK_FORMAT_FEATURE_BLIT_DST_BIT)) {
deviceInfo_.canBlitToPreferredDepthStencilFormat = true;
}
// This is as good a place as any to do this.

View File

@ -52,6 +52,7 @@ enum WindowSystem {
struct VulkanPhysicalDeviceInfo {
VkFormat preferredDepthStencilFormat;
bool canBlitToPreferredDepthStencilFormat;
};
// This is a bit repetitive...

View File

@ -471,7 +471,7 @@ void FramebufferManagerCommon::BlitFramebufferDepth(VirtualFramebuffer *src, Vir
int h = std::min(src->renderHeight, dst->renderHeight);
// Note: We prefer Blit ahead of Copy here, since at least on GL, Copy will always also copy stencil which we don't want. See #9740.
if (gstate_c.Supports(GPU_SUPPORTS_FRAMEBUFFER_BLIT)) {
if (gstate_c.Supports(GPU_SUPPORTS_FRAMEBUFFER_BLIT_TO_DEPTH)) {
draw_->BlitFramebuffer(src->fbo, 0, 0, w, h, dst->fbo, 0, 0, w, h, Draw::FB_DEPTH_BIT, Draw::FB_BLIT_NEAREST, "BlitFramebufferDepth");
RebindFramebuffer("BlitFramebufferDepth");
} else if (gstate_c.Supports(GPU_SUPPORTS_COPY_IMAGE)) {

View File

@ -490,6 +490,7 @@ enum {
GPU_ROUND_DEPTH_TO_16BIT = FLAG_BIT(23), // Can be disabled either per game or if we use a real 16-bit depth buffer
GPU_SUPPORTS_TEXTURE_LOD_CONTROL = FLAG_BIT(24),
GPU_SUPPORTS_FRAMEBUFFER_BLIT = FLAG_BIT(26),
GPU_SUPPORTS_FRAMEBUFFER_BLIT_TO_DEPTH = FLAG_BIT(27),
GPU_SUPPORTS_OES_TEXTURE_NPOT = FLAG_BIT(28),
GPU_NEEDS_Z_EQUAL_W_HACK = FLAG_BIT(29),
GPU_PREFER_CPU_DOWNLOAD = FLAG_BIT(30),

View File

@ -233,6 +233,10 @@ void GPU_Vulkan::CheckGPUFeatures() {
features |= GPU_SUPPORTS_TEXTURE_FLOAT;
features |= GPU_PREFER_CPU_DOWNLOAD;
if (vulkan_->GetDeviceInfo().canBlitToPreferredDepthStencilFormat) {
features |= GPU_SUPPORTS_FRAMEBUFFER_BLIT_TO_DEPTH;
}
if (vulkan_->GetDeviceFeatures().enabled.wideLines) {
features |= GPU_SUPPORTS_WIDE_LINES;
}