diff --git a/Source/Core/VideoBackends/D3D/main.cpp b/Source/Core/VideoBackends/D3D/main.cpp index 816c896478..0372cfb609 100644 --- a/Source/Core/VideoBackends/D3D/main.cpp +++ b/Source/Core/VideoBackends/D3D/main.cpp @@ -92,6 +92,7 @@ void VideoBackend::FillBackendInfo() g_Config.backend_info.bSupportsGPUTextureDecoding = true; g_Config.backend_info.bSupportsCopyToVram = true; g_Config.backend_info.bSupportsLargePoints = false; + g_Config.backend_info.bSupportsDepthReadback = true; g_Config.backend_info.bSupportsPartialDepthCopies = false; g_Config.backend_info.bSupportsBitfield = false; g_Config.backend_info.bSupportsDynamicSamplerIndexing = false; diff --git a/Source/Core/VideoBackends/D3D12/VideoBackend.cpp b/Source/Core/VideoBackends/D3D12/VideoBackend.cpp index 8bfc68a5e3..d92599e5ea 100644 --- a/Source/Core/VideoBackends/D3D12/VideoBackend.cpp +++ b/Source/Core/VideoBackends/D3D12/VideoBackend.cpp @@ -77,6 +77,7 @@ void VideoBackend::FillBackendInfo() g_Config.backend_info.bSupportsFramebufferFetch = false; g_Config.backend_info.bSupportsBackgroundCompiling = true; g_Config.backend_info.bSupportsLargePoints = false; + g_Config.backend_info.bSupportsDepthReadback = true; g_Config.backend_info.bSupportsPartialDepthCopies = false; g_Config.backend_info.Adapters = D3DCommon::GetAdapterNames(); g_Config.backend_info.AAModes = DXContext::GetAAModes(g_Config.iAdapter); diff --git a/Source/Core/VideoBackends/Null/NullBackend.cpp b/Source/Core/VideoBackends/Null/NullBackend.cpp index 5b0661fe2e..d64265dc77 100644 --- a/Source/Core/VideoBackends/Null/NullBackend.cpp +++ b/Source/Core/VideoBackends/Null/NullBackend.cpp @@ -52,6 +52,7 @@ void VideoBackend::InitBackendInfo() g_Config.backend_info.bSupportsBackgroundCompiling = false; g_Config.backend_info.bSupportsLogicOp = false; g_Config.backend_info.bSupportsLargePoints = false; + g_Config.backend_info.bSupportsDepthReadback = false; g_Config.backend_info.bSupportsPartialDepthCopies = false; g_Config.backend_info.bSupportsShaderBinaries = false; g_Config.backend_info.bSupportsPipelineCacheData = false; diff --git a/Source/Core/VideoBackends/OGL/Render.cpp b/Source/Core/VideoBackends/OGL/Render.cpp index 27a8c05287..ee813fbbda 100644 --- a/Source/Core/VideoBackends/OGL/Render.cpp +++ b/Source/Core/VideoBackends/OGL/Render.cpp @@ -521,6 +521,10 @@ Renderer::Renderer(std::unique_ptr main_gl_context, float backbuffer_ // GLES does not support logic op. g_Config.backend_info.bSupportsLogicOp = false; + // glReadPixels() can't be used with non-color formats. But, if we support + // ARB_get_texture_sub_image (unlikely, except maybe on NVIDIA), we can use that instead. + g_Config.backend_info.bSupportsDepthReadback = g_ogl_config.bSupportsTextureSubImage; + if (GLExtensions::Supports("GL_EXT_shader_framebuffer_fetch")) { g_ogl_config.SupportedFramebufferFetch = EsFbFetchType::FbFetchExt; diff --git a/Source/Core/VideoBackends/OGL/main.cpp b/Source/Core/VideoBackends/OGL/main.cpp index c2cf0af192..d9d27c2b84 100644 --- a/Source/Core/VideoBackends/OGL/main.cpp +++ b/Source/Core/VideoBackends/OGL/main.cpp @@ -89,6 +89,7 @@ void VideoBackend::InitBackendInfo() g_Config.backend_info.bSupportsMultithreading = false; g_Config.backend_info.bSupportsCopyToVram = true; g_Config.backend_info.bSupportsLargePoints = true; + g_Config.backend_info.bSupportsDepthReadback = true; g_Config.backend_info.bSupportsPartialDepthCopies = true; g_Config.backend_info.bSupportsShaderBinaries = false; g_Config.backend_info.bSupportsPipelineCacheData = false; diff --git a/Source/Core/VideoBackends/Software/SWmain.cpp b/Source/Core/VideoBackends/Software/SWmain.cpp index 4309e39021..2e75416171 100644 --- a/Source/Core/VideoBackends/Software/SWmain.cpp +++ b/Source/Core/VideoBackends/Software/SWmain.cpp @@ -77,6 +77,7 @@ void VideoSoftware::InitBackendInfo() g_Config.backend_info.bSupportsBPTCTextures = false; g_Config.backend_info.bSupportsCopyToVram = false; g_Config.backend_info.bSupportsLargePoints = false; + g_Config.backend_info.bSupportsDepthReadback = false; g_Config.backend_info.bSupportsPartialDepthCopies = false; g_Config.backend_info.bSupportsFramebufferFetch = false; g_Config.backend_info.bSupportsBackgroundCompiling = false; diff --git a/Source/Core/VideoCommon/FramebufferManager.cpp b/Source/Core/VideoCommon/FramebufferManager.cpp index de3ca7457d..0aeb691362 100644 --- a/Source/Core/VideoCommon/FramebufferManager.cpp +++ b/Source/Core/VideoCommon/FramebufferManager.cpp @@ -513,7 +513,8 @@ bool FramebufferManager::CreateReadbackFramebuffer() // Since we can't partially copy from a depth buffer directly to the staging texture in D3D, we // use an intermediate buffer to avoid copying the whole texture. - if ((IsUsingTiledEFBCache() && !g_ActiveConfig.backend_info.bSupportsPartialDepthCopies) || + if (!g_ActiveConfig.backend_info.bSupportsDepthReadback || + (IsUsingTiledEFBCache() && !g_ActiveConfig.backend_info.bSupportsPartialDepthCopies) || !AbstractTexture::IsCompatibleDepthAndColorFormats(m_efb_depth_texture->GetFormat(), GetEFBDepthCopyFormat()) || g_renderer->GetEFBScale() != 1) @@ -577,7 +578,8 @@ void FramebufferManager::PopulateEFBCache(bool depth, u32 tile_index) // buffer directly to a staging texture (must be the whole resource). const bool force_intermediate_copy = depth && - ((!g_ActiveConfig.backend_info.bSupportsPartialDepthCopies && IsUsingTiledEFBCache()) || + (!g_ActiveConfig.backend_info.bSupportsDepthReadback || + (!g_ActiveConfig.backend_info.bSupportsPartialDepthCopies && IsUsingTiledEFBCache()) || !AbstractTexture::IsCompatibleDepthAndColorFormats(m_efb_depth_texture->GetFormat(), GetEFBDepthCopyFormat())); diff --git a/Source/Core/VideoCommon/VideoConfig.h b/Source/Core/VideoCommon/VideoConfig.h index 41dc891e8a..ee0951180a 100644 --- a/Source/Core/VideoCommon/VideoConfig.h +++ b/Source/Core/VideoCommon/VideoConfig.h @@ -229,6 +229,7 @@ struct VideoConfig final bool bSupportsBackgroundCompiling; bool bSupportsLargePoints; bool bSupportsPartialDepthCopies; + bool bSupportsDepthReadback; bool bSupportsShaderBinaries; bool bSupportsPipelineCacheData; } backend_info;