Compare commits

...

2 Commits

Author SHA1 Message Date
lightningterror
8819018a18 GS/HW: Check for flat shading when doing aniso. 2026-01-02 21:42:05 +01:00
lightningterror
4cf5b98cdd GS/HW: Use MipLevel 2 for anisotropic filtering which fixes aniso on newer amd cards. 2026-01-02 16:25:00 +01:00
7 changed files with 19 additions and 11 deletions

View File

@@ -1799,6 +1799,7 @@ void GSDevice11::SetupPS(const PSSelector& sel, const GSHWDrawConfig::PSConstant
if (anisotropy > 1 && ssel.aniso)
{
sd.Filter = D3D11_FILTER_ANISOTROPIC;
sd.MaxLOD = (ssel.lodclamp || !ssel.UseMipmapFiltering()) ? 0.01f : FLT_MAX;
}
else
{
@@ -1817,13 +1818,13 @@ void GSDevice11::SetupPS(const PSSelector& sel, const GSHWDrawConfig::PSConstant
(static_cast<u8>(ssel.IsMagFilterLinear()) << 1) |
static_cast<u8>(ssel.IsMinFilterLinear());
sd.Filter = filters[index];
sd.MaxLOD = (ssel.lodclamp || !ssel.UseMipmapFiltering()) ? 0.25f : FLT_MAX;
}
sd.AddressU = ssel.tau ? D3D11_TEXTURE_ADDRESS_WRAP : D3D11_TEXTURE_ADDRESS_CLAMP;
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.lodclamp || !ssel.UseMipmapFiltering()) ? 0.25f : FLT_MAX;
sd.MaxAnisotropy = std::clamp(anisotropy, 1, 16);
sd.ComparisonFunc = D3D11_COMPARISON_NEVER;

View File

@@ -2246,6 +2246,7 @@ bool GSDevice12::GetSampler(D3D12DescriptorHandle* cpu_handle, GSHWDrawConfig::S
if (anisotropy > 1 && ss.aniso)
{
sd.Filter = D3D12_FILTER_ANISOTROPIC;
sd.MaxLOD = (ss.lodclamp || !ss.UseMipmapFiltering()) ? 0.01f : FLT_MAX;
}
else
{
@@ -2263,13 +2264,13 @@ bool GSDevice12::GetSampler(D3D12DescriptorHandle* cpu_handle, GSHWDrawConfig::S
const u8 index = (static_cast<u8>(ss.IsMipFilterLinear()) << 2) |
(static_cast<u8>(ss.IsMagFilterLinear()) << 1) | static_cast<u8>(ss.IsMinFilterLinear());
sd.Filter = filters[index];
sd.MaxLOD = (ss.lodclamp || !ss.UseMipmapFiltering()) ? 0.25f : FLT_MAX;
}
sd.AddressU = ss.tau ? D3D12_TEXTURE_ADDRESS_MODE_WRAP : D3D12_TEXTURE_ADDRESS_MODE_CLAMP;
sd.AddressV = ss.tav ? D3D12_TEXTURE_ADDRESS_MODE_WRAP : D3D12_TEXTURE_ADDRESS_MODE_CLAMP;
sd.AddressW = D3D12_TEXTURE_ADDRESS_MODE_CLAMP;
sd.MinLOD = 0.0f;
sd.MaxLOD = (ss.lodclamp || !ss.UseMipmapFiltering()) ? 0.25f : FLT_MAX;
sd.MaxAnisotropy = std::clamp<u8>(GSConfig.MaxAnisotropy, 1, 16);
sd.ComparisonFunc = D3D12_COMPARISON_FUNC_NEVER;

View File

@@ -6783,11 +6783,11 @@ __ri void GSRendererHW::EmulateTextureSampler(const GSTextureCache::Target* rt,
m_conf.sampler.biln = bilinear;
// Aniso filtering doesn't work with textureLod so use texture (automatic_lod) instead.
// Enable aniso only for triangles. Sprites are flat so aniso is likely useless (it would save perf for others primitives).
const bool anisotropic = m_vt.m_primclass == GS_TRIANGLE_CLASS && !trilinear_manual;
// Also make sure there isn't flat shading.
const bool anisotropic = m_vt.m_primclass == GS_TRIANGLE_CLASS && !trilinear_manual && !m_vt.m_eq.z;
m_conf.sampler.aniso = anisotropic;
m_conf.sampler.triln = trilinear;
if (anisotropic && !trilinear_manual)
m_conf.ps.automatic_lod = 1;
m_conf.ps.automatic_lod = anisotropic;
}
// clamp to base level if we're not providing or generating mipmaps

View File

@@ -5826,6 +5826,9 @@ GSTextureCache::Source* GSTextureCache::CreateSource(const GIFRegTEX0& TEX0, con
src->m_lod = *lod;
}
if (GSConfig.MaxAnisotropy > 1)
tlevels = std::max(2, tlevels);
bool hack = false;
bool channel_shuffle = dst && (TEX0.PSM == PSMT8) && (GSRendererHW::GetInstance()->TestChannelShuffle(dst));
@@ -6780,7 +6783,8 @@ GSTextureCache::HashCacheEntry* GSTextureCache::LookupHashCache(const GIFRegTEX0
const int tw = region.HasX() ? region.GetWidth() : (1 << TEX0.TW);
const int th = region.HasY() ? region.GetHeight() : (1 << TEX0.TH);
const int tlevels = lod ? (GSConfig.HWMipmap ? std::min(lod->y - lod->x + 1, GSDevice::GetMipmapLevelsForSize(tw, th)) : -1) : 1;
GSTexture* tex = g_gs_device->CreateTexture(tw, th, tlevels, paltex ? GSTexture::Format::UNorm8 : GSTexture::Format::Color);
const int aniso_tlevels = (GSConfig.MaxAnisotropy > 1) ? std::max(2, tlevels) : tlevels;
GSTexture* tex = g_gs_device->CreateTexture(tw, th, aniso_tlevels, paltex ? GSTexture::Format::UNorm8 : GSTexture::Format::Color);
if (!tex)
{
// out of video memory if we hit here

View File

@@ -839,7 +839,8 @@ static MRCOwned<id<MTLSamplerState>> CreateSampler(id<MTLDevice> dev, GSHWDrawCo
[sdesc setMaxAnisotropy:GSConfig.MaxAnisotropy && sel.aniso ? GSConfig.MaxAnisotropy : 1];
bool clampLOD = sel.lodclamp || !sel.UseMipmapFiltering();
const char* clampdesc = clampLOD ? " LODClamp" : "";
[sdesc setLodMaxClamp:clampLOD ? 0.25f : FLT_MAX];
float clampValue = GSConfig.MaxAnisotropy > 1 && sel.aniso ? 0.01f : 0.25f;
[sdesc setLodMaxClamp:clampLOD ? clampValue : FLT_MAX];
[sdesc setLabel:[NSString stringWithFormat:@"%s%s %s%s%s", taudesc, tavdesc, magname, minname, clampdesc]];
MRCOwned<id<MTLSamplerState>> ret = MRCTransfer([dev newSamplerStateWithDescriptor:sdesc]);

View File

@@ -1186,8 +1186,9 @@ GLuint GSDeviceOGL::CreateSampler(PSSamplerSelector sel)
glSamplerParameteri(sampler, GL_TEXTURE_MIN_FILTER, sel.IsMinFilterLinear() ? GL_LINEAR_MIPMAP_NEAREST : GL_NEAREST_MIPMAP_NEAREST);
}
const bool aniso = GSConfig.MaxAnisotropy > 1 && sel.aniso;
glSamplerParameterf(sampler, GL_TEXTURE_MIN_LOD, -1000.0f);
glSamplerParameterf(sampler, GL_TEXTURE_MAX_LOD, sel.lodclamp ? 0.25f : 1000.0f);
glSamplerParameterf(sampler, GL_TEXTURE_MAX_LOD, sel.lodclamp ? (aniso ? 0.01f : 0.25f) : 1000.0f);
if (sel.tau)
glSamplerParameteri(sampler, GL_TEXTURE_WRAP_S, GL_REPEAT);
@@ -1200,9 +1201,9 @@ GLuint GSDeviceOGL::CreateSampler(PSSamplerSelector sel)
glSamplerParameteri(sampler, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
const int anisotropy = GSConfig.MaxAnisotropy;
if (anisotropy > 1 && sel.aniso)
if (aniso)
{
const int anisotropy = GSConfig.MaxAnisotropy;
if (GLAD_GL_ARB_texture_filter_anisotropic)
glSamplerParameterf(sampler, GL_TEXTURE_MAX_ANISOTROPY, static_cast<float>(anisotropy));
else if (GLAD_GL_EXT_texture_filter_anisotropic)

View File

@@ -3581,7 +3581,7 @@ VkSampler GSDeviceVK::GetSampler(GSHWDrawConfig::SamplerSelector ss)
VK_FALSE, // compare enable
VK_COMPARE_OP_ALWAYS, // compare op
0.0f, // min lod
(ss.lodclamp || !ss.UseMipmapFiltering()) ? 0.25f : VK_LOD_CLAMP_NONE, // max lod
(ss.lodclamp || !ss.UseMipmapFiltering()) ? (aniso ? 0.01f : 0.25f) : VK_LOD_CLAMP_NONE, // max lod
VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK, // border
VK_FALSE // unnormalized coordinates
};