diff --git a/Source/Core/VideoBackends/D3D/D3DMain.cpp b/Source/Core/VideoBackends/D3D/D3DMain.cpp index b217218986..f101f60321 100644 --- a/Source/Core/VideoBackends/D3D/D3DMain.cpp +++ b/Source/Core/VideoBackends/D3D/D3DMain.cpp @@ -107,6 +107,7 @@ void VideoBackend::FillBackendInfo() g_Config.backend_info.bSupportsShaderBinaries = true; g_Config.backend_info.bSupportsPipelineCacheData = false; g_Config.backend_info.bSupportsCoarseDerivatives = true; + g_Config.backend_info.bSupportsTextureQueryLevels = true; g_Config.backend_info.bSupportsLogicOp = D3D::SupportsLogicOp(g_Config.iAdapter); g_Config.backend_info.Adapters = D3DCommon::GetAdapterNames(); diff --git a/Source/Core/VideoBackends/D3D12/VideoBackend.cpp b/Source/Core/VideoBackends/D3D12/VideoBackend.cpp index 3a33832dc1..a82dd428a5 100644 --- a/Source/Core/VideoBackends/D3D12/VideoBackend.cpp +++ b/Source/Core/VideoBackends/D3D12/VideoBackend.cpp @@ -83,6 +83,7 @@ void VideoBackend::FillBackendInfo() g_Config.backend_info.bSupportsShaderBinaries = true; g_Config.backend_info.bSupportsPipelineCacheData = true; g_Config.backend_info.bSupportsCoarseDerivatives = true; + g_Config.backend_info.bSupportsTextureQueryLevels = true; // We can only check texture support once we have a device. if (g_dx_context) diff --git a/Source/Core/VideoBackends/Null/NullBackend.cpp b/Source/Core/VideoBackends/Null/NullBackend.cpp index 17e31c4418..78ce7f1afe 100644 --- a/Source/Core/VideoBackends/Null/NullBackend.cpp +++ b/Source/Core/VideoBackends/Null/NullBackend.cpp @@ -56,6 +56,7 @@ void VideoBackend::InitBackendInfo() g_Config.backend_info.bSupportsShaderBinaries = false; g_Config.backend_info.bSupportsPipelineCacheData = false; g_Config.backend_info.bSupportsCoarseDerivatives = false; + g_Config.backend_info.bSupportsTextureQueryLevels = false; // aamodes: We only support 1 sample, so no MSAA g_Config.backend_info.Adapters.clear(); diff --git a/Source/Core/VideoBackends/OGL/OGLMain.cpp b/Source/Core/VideoBackends/OGL/OGLMain.cpp index 375b1d12c7..537058a565 100644 --- a/Source/Core/VideoBackends/OGL/OGLMain.cpp +++ b/Source/Core/VideoBackends/OGL/OGLMain.cpp @@ -108,6 +108,7 @@ void VideoBackend::InitBackendInfo() g_Config.backend_info.bSupportsST3CTextures = false; g_Config.backend_info.bSupportsBPTCTextures = false; g_Config.backend_info.bSupportsCoarseDerivatives = false; + g_Config.backend_info.bSupportsTextureQueryLevels = false; g_Config.backend_info.Adapters.clear(); diff --git a/Source/Core/VideoBackends/OGL/OGLRender.cpp b/Source/Core/VideoBackends/OGL/OGLRender.cpp index 76064920f2..2fc307cb9c 100644 --- a/Source/Core/VideoBackends/OGL/OGLRender.cpp +++ b/Source/Core/VideoBackends/OGL/OGLRender.cpp @@ -485,6 +485,8 @@ Renderer::Renderer(std::unique_ptr main_gl_context, float backbuffer_ GLExtensions::Supports("GL_ARB_texture_compression_bptc"); g_Config.backend_info.bSupportsCoarseDerivatives = GLExtensions::Supports("GL_ARB_derivative_control") || GLExtensions::Version() >= 450; + g_Config.backend_info.bSupportsTextureQueryLevels = + GLExtensions::Supports("GL_ARB_texture_query_levels") || GLExtensions::Version() >= 430; if (m_main_gl_context->IsGLES()) { diff --git a/Source/Core/VideoBackends/OGL/ProgramShaderCache.cpp b/Source/Core/VideoBackends/OGL/ProgramShaderCache.cpp index 8aba81b7ed..492d4b956c 100644 --- a/Source/Core/VideoBackends/OGL/ProgramShaderCache.cpp +++ b/Source/Core/VideoBackends/OGL/ProgramShaderCache.cpp @@ -748,6 +748,7 @@ void ProgramShaderCache::CreateHeader() "%s\n" // shader framebuffer fetch "%s\n" // shader thread shuffle "%s\n" // derivative control + "%s\n" // query levels // Precision defines for GLSL ES "%s\n" @@ -830,6 +831,9 @@ void ProgramShaderCache::CreateHeader() g_ActiveConfig.backend_info.bSupportsCoarseDerivatives ? "#extension GL_ARB_derivative_control : enable" : "", + g_ActiveConfig.backend_info.bSupportsTextureQueryLevels ? + "#extension GL_ARB_texture_query_levels : enable" : + "", is_glsles ? "precision highp float;" : "", is_glsles ? "precision highp int;" : "", is_glsles ? "precision highp sampler2DArray;" : "", (is_glsles && g_ActiveConfig.backend_info.bSupportsPaletteConversion) ? diff --git a/Source/Core/VideoBackends/Software/SWmain.cpp b/Source/Core/VideoBackends/Software/SWmain.cpp index ca1f4304dd..fa6f89ba2d 100644 --- a/Source/Core/VideoBackends/Software/SWmain.cpp +++ b/Source/Core/VideoBackends/Software/SWmain.cpp @@ -85,6 +85,7 @@ void VideoSoftware::InitBackendInfo() g_Config.backend_info.bSupportsPipelineCacheData = false; g_Config.backend_info.bSupportsBBox = true; g_Config.backend_info.bSupportsCoarseDerivatives = false; + g_Config.backend_info.bSupportsTextureQueryLevels = false; // aamodes g_Config.backend_info.AAModes = {1}; diff --git a/Source/Core/VideoBackends/Vulkan/VulkanContext.cpp b/Source/Core/VideoBackends/Vulkan/VulkanContext.cpp index 16aa7872e7..a571c6c38d 100644 --- a/Source/Core/VideoBackends/Vulkan/VulkanContext.cpp +++ b/Source/Core/VideoBackends/Vulkan/VulkanContext.cpp @@ -287,6 +287,7 @@ void VulkanContext::PopulateBackendInfo(VideoConfig* config) config->backend_info.bSupportsLargePoints = false; // Dependent on features. config->backend_info.bSupportsFramebufferFetch = false; // No support. config->backend_info.bSupportsCoarseDerivatives = true; // Assumed support. + config->backend_info.bSupportsTextureQueryLevels = true; // Assumed support. } void VulkanContext::PopulateBackendInfoAdapters(VideoConfig* config, const GPUList& gpu_list) diff --git a/Source/Core/VideoCommon/PixelShaderGen.cpp b/Source/Core/VideoCommon/PixelShaderGen.cpp index 7ad7f54366..6261f57812 100644 --- a/Source/Core/VideoCommon/PixelShaderGen.cpp +++ b/Source/Core/VideoCommon/PixelShaderGen.cpp @@ -692,11 +692,21 @@ uint WrapCoord(int coord, uint wrap, int size) {{ int3 size = textureSize(tex, 0); int size_s = size.x; int size_t = size.y; - int number_of_levels = textureQueryLevels(tex); )"); + if (g_ActiveConfig.backend_info.bSupportsTextureQueryLevels) + { + out.Write(" int number_of_levels = textureQueryLevels(tex);\n"); + } + else + { + out.Write(" int number_of_levels = 256; // textureQueryLevels is not supported\n"); + ERROR_LOG_FMT(VIDEO, "textureQueryLevels is not supported! Odd graphical results may " + "occur if custom textures are in use!"); + } } else if (api_type == APIType::D3D) { + ASSERT(g_ActiveConfig.backend_info.bSupportsTextureQueryLevels); out.Write(R"( int size_s, size_t, layers, number_of_levels; tex.GetDimensions(0, size_s, size_t, layers, number_of_levels); diff --git a/Source/Core/VideoCommon/VideoConfig.h b/Source/Core/VideoCommon/VideoConfig.h index c4e2a7ed85..395b0f6a94 100644 --- a/Source/Core/VideoCommon/VideoConfig.h +++ b/Source/Core/VideoCommon/VideoConfig.h @@ -232,6 +232,7 @@ struct VideoConfig final bool bSupportsShaderBinaries = false; bool bSupportsPipelineCacheData = false; bool bSupportsCoarseDerivatives = false; + bool bSupportsTextureQueryLevels = false; } backend_info; // Utility