diff --git a/Source/Core/VideoBackends/D3D/D3DMain.cpp b/Source/Core/VideoBackends/D3D/D3DMain.cpp index a74fb1bb2f..4d78c49831 100644 --- a/Source/Core/VideoBackends/D3D/D3DMain.cpp +++ b/Source/Core/VideoBackends/D3D/D3DMain.cpp @@ -109,6 +109,7 @@ void VideoBackend::FillBackendInfo() g_Config.backend_info.bSupportsPipelineCacheData = false; g_Config.backend_info.bSupportsCoarseDerivatives = true; g_Config.backend_info.bSupportsTextureQueryLevels = true; + g_Config.backend_info.bSupportsLodBiasInSampler = 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 c3fd307a06..9ee16c1781 100644 --- a/Source/Core/VideoBackends/D3D12/VideoBackend.cpp +++ b/Source/Core/VideoBackends/D3D12/VideoBackend.cpp @@ -85,6 +85,7 @@ void VideoBackend::FillBackendInfo() g_Config.backend_info.bSupportsPipelineCacheData = true; g_Config.backend_info.bSupportsCoarseDerivatives = true; g_Config.backend_info.bSupportsTextureQueryLevels = true; + g_Config.backend_info.bSupportsLodBiasInSampler = 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 d6bd70c50a..635650cb11 100644 --- a/Source/Core/VideoBackends/Null/NullBackend.cpp +++ b/Source/Core/VideoBackends/Null/NullBackend.cpp @@ -58,6 +58,7 @@ void VideoBackend::InitBackendInfo() g_Config.backend_info.bSupportsPipelineCacheData = false; g_Config.backend_info.bSupportsCoarseDerivatives = false; g_Config.backend_info.bSupportsTextureQueryLevels = false; + g_Config.backend_info.bSupportsLodBiasInSampler = 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 b83c3af638..4f4dc21d25 100644 --- a/Source/Core/VideoBackends/OGL/OGLMain.cpp +++ b/Source/Core/VideoBackends/OGL/OGLMain.cpp @@ -93,6 +93,7 @@ void VideoBackend::InitBackendInfo() g_Config.backend_info.bSupportsPartialDepthCopies = true; g_Config.backend_info.bSupportsShaderBinaries = false; g_Config.backend_info.bSupportsPipelineCacheData = false; + g_Config.backend_info.bSupportsLodBiasInSampler = true; // TODO: There is a bug here, if texel buffers or SSBOs/atomics are not supported the graphics // options will show the option when it is not supported. The only way around this would be diff --git a/Source/Core/VideoBackends/OGL/OGLRender.cpp b/Source/Core/VideoBackends/OGL/OGLRender.cpp index 2fc307cb9c..3b70579d90 100644 --- a/Source/Core/VideoBackends/OGL/OGLRender.cpp +++ b/Source/Core/VideoBackends/OGL/OGLRender.cpp @@ -513,6 +513,9 @@ Renderer::Renderer(std::unique_ptr main_gl_context, float backbuffer_ // ARB_get_texture_sub_image (unlikely, except maybe on NVIDIA), we can use that instead. g_Config.backend_info.bSupportsDepthReadback = g_ogl_config.bSupportsTextureSubImage; + // GL_TEXTURE_LOD_BIAS is not supported on GLES. + g_Config.backend_info.bSupportsLodBiasInSampler = false; + if (GLExtensions::Supports("GL_EXT_shader_framebuffer_fetch")) { g_ogl_config.SupportedFramebufferFetch = EsFbFetchType::FbFetchExt; diff --git a/Source/Core/VideoBackends/OGL/SamplerCache.cpp b/Source/Core/VideoBackends/OGL/SamplerCache.cpp index ed14c11a47..c111caa546 100644 --- a/Source/Core/VideoBackends/OGL/SamplerCache.cpp +++ b/Source/Core/VideoBackends/OGL/SamplerCache.cpp @@ -97,8 +97,10 @@ void SamplerCache::SetParameters(GLuint sampler_id, const SamplerState& params) glSamplerParameterf(sampler_id, GL_TEXTURE_MIN_LOD, params.tm1.min_lod / 16.f); glSamplerParameterf(sampler_id, GL_TEXTURE_MAX_LOD, params.tm1.max_lod / 16.f); - if (!static_cast(g_renderer.get())->IsGLES()) + if (g_ActiveConfig.backend_info.bSupportsLodBiasInSampler) + { glSamplerParameterf(sampler_id, GL_TEXTURE_LOD_BIAS, params.tm0.lod_bias / 256.f); + } if (params.tm0.anisotropic_filtering && g_ogl_config.bSupportsAniso) { diff --git a/Source/Core/VideoBackends/Software/SWmain.cpp b/Source/Core/VideoBackends/Software/SWmain.cpp index 6a12c467d8..654813d5eb 100644 --- a/Source/Core/VideoBackends/Software/SWmain.cpp +++ b/Source/Core/VideoBackends/Software/SWmain.cpp @@ -87,6 +87,7 @@ void VideoSoftware::InitBackendInfo() g_Config.backend_info.bSupportsBBox = true; g_Config.backend_info.bSupportsCoarseDerivatives = false; g_Config.backend_info.bSupportsTextureQueryLevels = false; + g_Config.backend_info.bSupportsLodBiasInSampler = 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 23cb06e846..ead13df547 100644 --- a/Source/Core/VideoBackends/Vulkan/VulkanContext.cpp +++ b/Source/Core/VideoBackends/Vulkan/VulkanContext.cpp @@ -289,6 +289,7 @@ void VulkanContext::PopulateBackendInfo(VideoConfig* config) config->backend_info.bSupportsFramebufferFetch = false; // Dependent on OS and features. config->backend_info.bSupportsCoarseDerivatives = true; // Assumed support. config->backend_info.bSupportsTextureQueryLevels = true; // Assumed support. + config->backend_info.bSupportsLodBiasInSampler = false; // Dependent on OS. } void VulkanContext::PopulateBackendInfoAdapters(VideoConfig* config, const GPUList& gpu_list) @@ -316,6 +317,13 @@ void VulkanContext::PopulateBackendInfoFeatures(VideoConfig* config, VkPhysicalD config->backend_info.bSupportsSSAA = (features.sampleRateShading == VK_TRUE); config->backend_info.bSupportsLogicOp = (features.logicOp == VK_TRUE); +#ifdef __APPLE__ + // Metal doesn't support this. + config->backend_info.bSupportsLodBiasInSampler = false; +#else + config->backend_info.bSupportsLodBiasInSampler = true; +#endif + // Disable geometry shader when shaderTessellationAndGeometryPointSize is not supported. // Seems this is needed for gl_Layer. if (!features.shaderTessellationAndGeometryPointSize) diff --git a/Source/Core/VideoCommon/PixelShaderGen.cpp b/Source/Core/VideoCommon/PixelShaderGen.cpp index c8f3bf5b15..ce607242c0 100644 --- a/Source/Core/VideoCommon/PixelShaderGen.cpp +++ b/Source/Core/VideoCommon/PixelShaderGen.cpp @@ -648,7 +648,19 @@ uint WrapCoord(int coord, uint wrap, int size) {{ " float3 coords = float3(float(uv.x) / size_s, float(uv.y) / size_t, layer);\n"); if (api_type == APIType::OpenGL || api_type == APIType::Vulkan) { - out.Write(" return iround(255.0 * texture(tex, coords));\n}}\n"); + if (!host_config.backend_sampler_lod_bias) + { + out.Write(" uint texmode0 = samp_texmode0(texmap);\n" + " float lod_bias = {} / 256.0f;\n" + " return iround(255.0 * texture(tex, coords, lod_bias));\n", + BitfieldExtract<&SamplerState::TM0::lod_bias>("texmode0")); + } + else + { + out.Write(" return iround(255.0 * texture(tex, coords));\n"); + } + + out.Write("}}\n"); } else if (api_type == APIType::D3D) { diff --git a/Source/Core/VideoCommon/ShaderGenCommon.cpp b/Source/Core/VideoCommon/ShaderGenCommon.cpp index 34921f9116..0a965e6f62 100644 --- a/Source/Core/VideoCommon/ShaderGenCommon.cpp +++ b/Source/Core/VideoCommon/ShaderGenCommon.cpp @@ -42,6 +42,7 @@ ShaderHostConfig ShaderHostConfig::GetCurrent() bits.manual_texture_sampling = !g_ActiveConfig.bFastTextureSampling; bits.manual_texture_sampling_custom_texture_sizes = g_ActiveConfig.ManualTextureSamplingWithHiResTextures(); + bits.backend_sampler_lod_bias = g_ActiveConfig.backend_info.bSupportsLodBiasInSampler; return bits; } diff --git a/Source/Core/VideoCommon/ShaderGenCommon.h b/Source/Core/VideoCommon/ShaderGenCommon.h index 88a303356b..b787035a36 100644 --- a/Source/Core/VideoCommon/ShaderGenCommon.h +++ b/Source/Core/VideoCommon/ShaderGenCommon.h @@ -172,6 +172,7 @@ union ShaderHostConfig BitField<23, 1, bool, u32> enable_validation_layer; BitField<24, 1, bool, u32> manual_texture_sampling; BitField<25, 1, bool, u32> manual_texture_sampling_custom_texture_sizes; + BitField<26, 1, bool, u32> backend_sampler_lod_bias; static ShaderHostConfig GetCurrent(); }; diff --git a/Source/Core/VideoCommon/VideoConfig.h b/Source/Core/VideoCommon/VideoConfig.h index 395b0f6a94..80d42db233 100644 --- a/Source/Core/VideoCommon/VideoConfig.h +++ b/Source/Core/VideoCommon/VideoConfig.h @@ -233,6 +233,7 @@ struct VideoConfig final bool bSupportsPipelineCacheData = false; bool bSupportsCoarseDerivatives = false; bool bSupportsTextureQueryLevels = false; + bool bSupportsLodBiasInSampler = false; } backend_info; // Utility