GS/HW: Add a field for LOD clamp to sampler

This way SampleLevel for manual LOD doesn't get clamped.
This commit is contained in:
Connor McLaughlin 2022-01-11 20:01:31 +10:00 committed by lightningterror
parent e1e83c11cc
commit 5bdb34521d
6 changed files with 17 additions and 20 deletions

View File

@ -274,8 +274,7 @@ struct alignas(16) GSHWDrawConfig
u8 biln : 1;
u8 triln : 3;
u8 aniso : 1;
u8 _free : 1;
u8 lodclamp : 1;
};
u8 key;
};
@ -317,14 +316,6 @@ struct alignas(16) GSHWDrawConfig
return (triln == static_cast<u8>(GS_MIN_FILTER::Nearest_Mipmap_Linear) ||
triln == static_cast<u8>(GS_MIN_FILTER::Linear_Mipmap_Linear));
}
/// Returns the maximum LOD for this sampler (0 if mipmapping is disabled).
__fi float GetMaxLOD() const
{
// See https://www.khronos.org/registry/vulkan/specs/1.2-extensions/man/html/VkSamplerCreateInfo.html#_description
// for the reasoning behind 0.25f here.
return triln >= static_cast<u8>(GS_MIN_FILTER::Nearest_Mipmap_Nearest) ? 1000.0f : 0.25f;
}
};
struct DepthStencilSelector
{

View File

@ -253,7 +253,7 @@ void GSDevice11::SetupPS(PSSelector sel, const GSHWDrawConfig::PSConstantBuffer*
sd.AddressV = ssel.tav ? D3D11_TEXTURE_ADDRESS_WRAP : D3D11_TEXTURE_ADDRESS_CLAMP;
sd.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP;
sd.MinLOD = 0.0f;
sd.MaxLOD = ssel.GetMaxLOD();
sd.MaxLOD = ssel.lodclamp ? 0.0f : FLT_MAX;
sd.MaxAnisotropy = std::clamp(anisotropy, 1, 16);
sd.ComparisonFunc = D3D11_COMPARISON_NEVER;

View File

@ -996,6 +996,10 @@ void GSRendererNew::EmulateTextureSampler(const GSTextureCache::Source* tex)
}
}
// clamp to base level if we're not providing or generating mipmaps
// manual trilinear causes the chain to be uploaded, auto causes it to be generated
m_conf.sampler.lodclamp = !(trilinear_manual || trilinear_auto);
m_conf.tex = tex->m_texture;
m_conf.pal = tex->m_palette;
}

View File

@ -879,8 +879,8 @@ GLuint GSDeviceOGL::CreateSampler(PSSamplerSelector sel)
break;
}
//glSamplerParameterf(sampler, GL_TEXTURE_MIN_LOD, 0);
//glSamplerParameterf(sampler, GL_TEXTURE_MAX_LOD, 6);
glSamplerParameterf(sampler, GL_TEXTURE_MIN_LOD, -1000.0f);
glSamplerParameterf(sampler, GL_TEXTURE_MAX_LOD, sel.lodclamp ? 0.0f : 1000.0f);
if (sel.tau)
glSamplerParameteri(sampler, GL_TEXTURE_WRAP_S, GL_REPEAT);

View File

@ -288,7 +288,7 @@ private:
GLuint timer() { return timer_query[last_query]; }
} m_profiler;
GLuint m_ps_ss[1 << 7];
GLuint m_ps_ss[1 << 8];
GSDepthStencilOGL* m_om_dss[1 << 5];
std::unordered_map<ProgramSelector, GL::Program, ProgramSelectorHash> m_programs;
GL::ShaderCache m_shader_cache;

View File

@ -951,6 +951,8 @@ VkSampler GSDeviceVK::GetSampler(GSHWDrawConfig::SamplerSelector ss)
const bool aniso = (ss.aniso && GSConfig.MaxAnisotropy > 1);
// See https://www.khronos.org/registry/vulkan/specs/1.2-extensions/man/html/VkSamplerCreateInfo.html#_description
// for the reasoning behind 0.25f here.
const VkSamplerCreateInfo ci = {
VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO, nullptr, 0,
ss.IsMinFilterLinear() ? VK_FILTER_LINEAR : VK_FILTER_NEAREST, // min
@ -967,7 +969,7 @@ VkSampler GSDeviceVK::GetSampler(GSHWDrawConfig::SamplerSelector ss)
VK_FALSE, // compare enable
VK_COMPARE_OP_ALWAYS, // compare op
0.0f, // min lod
ss.GetMaxLOD(), // max lod
ss.lodclamp ? 0.25f : VK_LOD_CLAMP_NONE, // max lod
VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK, // border
VK_FALSE // unnormalized coordinates
};