diff --git a/GPU/Common/TextureCacheCommon.cpp b/GPU/Common/TextureCacheCommon.cpp index 668db2a130..1fedfa67d3 100644 --- a/GPU/Common/TextureCacheCommon.cpp +++ b/GPU/Common/TextureCacheCommon.cpp @@ -146,19 +146,18 @@ static int TexLog2(float delta) { return useful - 127 * 256; } -void TextureCacheCommon::GetSamplingParams(int &minFilt, int &magFilt, bool &sClamp, bool &tClamp, float &lodBias, int maxLevel, u32 addr, GETexLevelMode &mode) { - minFilt = gstate.texfilter & 0x7; - magFilt = gstate.isMagnifyFilteringEnabled(); - sClamp = gstate.isTexCoordClampedS(); - tClamp = gstate.isTexCoordClampedT(); +void TextureCacheCommon::UpdateSamplingParams(int maxLevel, u32 texAddr, SamplerCacheKey &key) { + int minFilt = gstate.texfilter & 0x7; + int magFilt = gstate.isMagnifyFilteringEnabled(); + bool sClamp = gstate.isTexCoordClampedS(); + bool tClamp = gstate.isTexCoordClampedT(); GETexLevelMode mipMode = gstate.getTexLevelMode(); - mode = mipMode; bool autoMip = mipMode == GE_TEXLEVEL_MODE_AUTO; // TODO: Slope mipmap bias is still not well understood. - lodBias = (float)gstate.getTexLevelOffset16() * (1.0f / 16.0f); + float lodBias = (float)gstate.getTexLevelOffset16() * (1.0f / 16.0f); if (mipMode == GE_TEXLEVEL_MODE_SLOPE) { lodBias += 1.0f + TexLog2(gstate.getTextureLodSlope()) * (1.0f / 256.0f); } @@ -175,8 +174,8 @@ void TextureCacheCommon::GetSamplingParams(int &minFilt, int &magFilt, bool &sCl lodBias = 0.0f; } - if (!(magFilt & 1) && addr != 0 && g_Config.iTexFiltering != TEX_FILTER_FORCE_NEAREST) { - if (videos_.find(addr & 0x3FFFFFFF) != videos_.end()) { + if (!(magFilt & 1) && texAddr != 0 && g_Config.iTexFiltering != TEX_FILTER_FORCE_NEAREST) { + if (videos_.find(texAddr & 0x3FFFFFFF) != videos_.end()) { // Enforce bilinear filtering on magnification. magFilt |= 1; } @@ -211,18 +210,7 @@ void TextureCacheCommon::GetSamplingParams(int &minFilt, int &magFilt, bool &sCl minFilt &= ~1; break; } -} -void TextureCacheCommon::UpdateSamplingParams(int maxLevel, u32 texAddr, SamplerCacheKey &key) { - // TODO: Make GetSamplingParams write SamplerCacheKey directly - int minFilt; - int magFilt; - bool sClamp; - bool tClamp; - float lodBias; - GETexLevelMode mode; - - GetSamplingParams(minFilt, magFilt, sClamp, tClamp, lodBias, maxLevel, texAddr, mode); key.minFilt = minFilt & 1; key.mipEnable = (minFilt >> 2) & 1; key.mipFilt = (minFilt >> 1) & 1; @@ -235,8 +223,9 @@ void TextureCacheCommon::UpdateSamplingParams(int maxLevel, u32 texAddr, Sampler key.maxLevel = 0; key.minLevel = 0; key.lodBias = 0; + key.mipFilt = 0; } else { - switch (mode) { + switch (mipMode) { case GE_TEXLEVEL_MODE_AUTO: key.maxLevel = maxLevel * 256; key.minLevel = 0; diff --git a/GPU/D3D11/TextureCacheD3D11.cpp b/GPU/D3D11/TextureCacheD3D11.cpp index 8e4b72b338..717a4b8119 100644 --- a/GPU/D3D11/TextureCacheD3D11.cpp +++ b/GPU/D3D11/TextureCacheD3D11.cpp @@ -159,6 +159,7 @@ void TextureCacheD3D11::InvalidateLastTexture(TexCacheEntry *entry) { void TextureCacheD3D11::SetFramebufferSamplingParams(u16 bufferWidth, u16 bufferHeight, SamplerCacheKey &key) { UpdateSamplingParams(0, 0, key); + key.mipEnable = false; key.minFilt &= 1; key.mipFilt = 0; key.magFilt &= 1; diff --git a/GPU/Directx9/TextureCacheDX9.cpp b/GPU/Directx9/TextureCacheDX9.cpp index 89b294b763..16272c3b84 100644 --- a/GPU/Directx9/TextureCacheDX9.cpp +++ b/GPU/Directx9/TextureCacheDX9.cpp @@ -119,37 +119,15 @@ D3DFORMAT getClutDestFormat(GEPaletteFormat format) { return D3DFMT_A8R8G8B8; } -static const u8 MinFilt[8] = { - D3DTEXF_POINT, - D3DTEXF_LINEAR, - D3DTEXF_POINT, - D3DTEXF_LINEAR, - D3DTEXF_POINT, // GL_NEAREST_MIPMAP_NEAREST, - D3DTEXF_LINEAR, // GL_LINEAR_MIPMAP_NEAREST, - D3DTEXF_POINT, // GL_NEAREST_MIPMAP_LINEAR, - D3DTEXF_LINEAR, // GL_LINEAR_MIPMAP_LINEAR, -}; - -static const u8 MipFilt[8] = { - D3DTEXF_NONE, - D3DTEXF_NONE, - D3DTEXF_NONE, - D3DTEXF_NONE, - D3DTEXF_POINT, // GL_NEAREST_MIPMAP_NEAREST, - D3DTEXF_POINT, // GL_LINEAR_MIPMAP_NEAREST, - D3DTEXF_LINEAR, // GL_NEAREST_MIPMAP_LINEAR, - D3DTEXF_LINEAR, // GL_LINEAR_MIPMAP_LINEAR, -}; - -static const u8 MagFilt[2] = { - D3DTEXF_POINT, - D3DTEXF_LINEAR -}; - void TextureCacheDX9::SetFramebufferSamplingParams(u16 bufferWidth, u16 bufferHeight) { SamplerCacheKey key; UpdateSamplingParams(0, 0, key); + key.mipEnable = false; + key.minFilt &= 1; + key.mipFilt = 0; + key.magFilt &= 1; + // Often the framebuffer will not match the texture size. We'll wrap/clamp in the shader in that case. int w = gstate.getTextureWidth(0); int h = gstate.getTextureHeight(0); @@ -165,8 +143,17 @@ void TextureCacheDX9::ApplySamplingParams(const SamplerCacheKey &key) { dxstate.texMinFilter.set(key.minFilt ? D3DTEXF_LINEAR : D3DTEXF_POINT); dxstate.texMipFilter.set(key.mipFilt ? D3DTEXF_LINEAR : D3DTEXF_POINT); dxstate.texMagFilter.set(key.magFilt ? D3DTEXF_LINEAR : D3DTEXF_POINT); - dxstate.texMipLodBias.set((float)key.lodBias / 256.0f); - dxstate.texMaxMipLevel.set(key.maxLevel / 256); + + // DX9 mip levels are .. odd. The "max level" sets the LARGEST mip to use. + // We can enforce only the top mip level by setting a massive negative lod bias. + + if (!key.mipEnable) { + dxstate.texMaxMipLevel.set(0); + dxstate.texMipLodBias.set(-100.0f); + } else { + dxstate.texMipLodBias.set((float)key.lodBias / 256.0f); + dxstate.texMaxMipLevel.set(key.minLevel / 256); + } dxstate.texAddressU.set(key.sClamp ? D3DTADDRESS_CLAMP : D3DTADDRESS_WRAP); dxstate.texAddressV.set(key.tClamp ? D3DTADDRESS_CLAMP : D3DTADDRESS_WRAP); diff --git a/GPU/Vulkan/TextureCacheVulkan.cpp b/GPU/Vulkan/TextureCacheVulkan.cpp index 0b3fa58544..6ecd34e419 100644 --- a/GPU/Vulkan/TextureCacheVulkan.cpp +++ b/GPU/Vulkan/TextureCacheVulkan.cpp @@ -442,6 +442,7 @@ static const VkFilter MagFiltVK[2] = { void TextureCacheVulkan::SetFramebufferSamplingParams(u16 bufferWidth, u16 bufferHeight, SamplerCacheKey &key) { UpdateSamplingParams(0, 0, key); + key.mipEnable = false; key.minFilt &= 1; key.mipFilt = 0; key.magFilt &= 1;