From 08396c56e56708344d63fded5900020f47337b8e Mon Sep 17 00:00:00 2001 From: OatmealDome Date: Fri, 6 Aug 2021 23:26:51 -0400 Subject: [PATCH 1/4] VideoConfig: Add bool for sampler LOD bias support --- Source/Core/VideoBackends/D3D/D3DMain.cpp | 1 + Source/Core/VideoBackends/D3D12/VideoBackend.cpp | 1 + Source/Core/VideoBackends/Null/NullBackend.cpp | 1 + Source/Core/VideoBackends/OGL/OGLMain.cpp | 1 + Source/Core/VideoBackends/OGL/OGLRender.cpp | 3 +++ Source/Core/VideoBackends/Software/SWmain.cpp | 1 + Source/Core/VideoBackends/Vulkan/VulkanContext.cpp | 8 ++++++++ Source/Core/VideoCommon/VideoConfig.h | 1 + 8 files changed, 17 insertions(+) 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/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/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 From 91cdeb5aa6e46ea0cc60e157d4d30863e54f7ec0 Mon Sep 17 00:00:00 2001 From: OatmealDome Date: Sat, 7 Aug 2021 00:15:49 -0400 Subject: [PATCH 2/4] SamplerCache: Check for bSupportsLodBiasInSampler instead of IsGLES --- Source/Core/VideoBackends/OGL/SamplerCache.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) 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) { From 4e12d6e871680fe70bb45e7909f00a89539f7a3f Mon Sep 17 00:00:00 2001 From: OatmealDome Date: Fri, 6 Aug 2021 23:28:26 -0400 Subject: [PATCH 3/4] ShaderGenCommon: Add bit for LOD bias --- Source/Core/VideoCommon/ShaderGenCommon.cpp | 1 + Source/Core/VideoCommon/ShaderGenCommon.h | 1 + 2 files changed, 2 insertions(+) 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(); }; From 056613ecc5c79941d4bc9747bdc6f79fe332183a Mon Sep 17 00:00:00 2001 From: OatmealDome Date: Sat, 25 Dec 2021 15:36:09 -0500 Subject: [PATCH 4/4] PixelShaderGen: Add LOD bias to texture() call on systems that don't support it in the sampler --- Source/Core/VideoCommon/PixelShaderGen.cpp | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) 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) {