From c859aaae84642ded91fe046ef91404431c84f48b Mon Sep 17 00:00:00 2001 From: NeoBrainX Date: Fri, 10 Aug 2012 12:36:19 +0200 Subject: [PATCH 1/7] [optimization] TextureCacheBase: Slightly loosen the requirements for reusing mipmapped textures --- Source/Core/VideoCommon/Src/TextureCacheBase.cpp | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/Source/Core/VideoCommon/Src/TextureCacheBase.cpp b/Source/Core/VideoCommon/Src/TextureCacheBase.cpp index a5c390df3d..65407f2a0e 100644 --- a/Source/Core/VideoCommon/Src/TextureCacheBase.cpp +++ b/Source/Core/VideoCommon/Src/TextureCacheBase.cpp @@ -363,8 +363,10 @@ TextureCache::TCacheEntryBase* TextureCache::Load(unsigned int stage, } // 2. b) For normal textures, all texture parameters need to match + // NOTE: maxlevel is specified via render states, so it doesn't need to match exactly + // TODO: D3D9 doesn't support min_lod, so we should check for this here if (address == entry->addr && tex_hash == entry->hash && full_format == entry->format && - entry->num_mipmaps == maxlevel && entry->native_width == nativeW && entry->native_height == nativeH) + entry->num_mipmaps > maxlevel && entry->native_width == nativeW && entry->native_height == nativeH) { goto return_entry; } @@ -374,7 +376,7 @@ TextureCache::TCacheEntryBase* TextureCache::Load(unsigned int stage, // // TODO: Don't we need to force texture decoding to RGBA8 for dynamic EFB copies? // TODO: Actually, it should be enough if the internal texture format matches... - if ((entry->type == TCET_NORMAL && width == entry->native_width && height == entry->native_height && full_format == entry->format && entry->num_mipmaps == maxlevel) + if ((entry->type == TCET_NORMAL && width == entry->native_width && height == entry->native_height && full_format == entry->format && entry->num_mipmaps > maxlevel) || (entry->type == TCET_EC_DYNAMIC && entry->native_width == width && entry->native_height == height)) { // reuse the texture @@ -421,9 +423,8 @@ TextureCache::TCacheEntryBase* TextureCache::Load(unsigned int stage, // Sometimes, we can get around recreating a texture if only the number of mip levels changes // e.g. if our texture cache entry got too many mipmap levels we can limit the number of used levels by setting the appropriate render states // Thus, we don't update this member for every Load, but just whenever the texture gets recreated - // - // TODO: Won't we end up recreating textures all the time because maxlevel doesn't necessarily equal texLevels? - entry->num_mipmaps = maxlevel; // TODO: Does this actually work? We can't really adjust mipmap settings per-stage... + // TODO: D3D9 doesn't support min_lod. We should add a workaround for that here! + entry->num_mipmaps = maxlevel + 1; // TODO: Does this actually work? We can't really adjust mipmap settings per-stage... entry->type = TCET_NORMAL; GFX_DEBUGGER_PAUSE_AT(NEXT_NEW_TEXTURE, true); From ee3d6d66d77dd40cc69e0cf219833d0c0a3a5be3 Mon Sep 17 00:00:00 2001 From: NeoBrainX Date: Fri, 10 Aug 2012 13:09:16 +0200 Subject: [PATCH 2/7] [cleanup] [bugfix] TextureCacheBase: Cleanup and simplify mipmapping logic. Possibly fixes a bug or two. --- .../Core/VideoCommon/Src/TextureCacheBase.cpp | 22 +++++++++---------- .../Core/VideoCommon/Src/TextureCacheBase.h | 2 +- 2 files changed, 11 insertions(+), 13 deletions(-) diff --git a/Source/Core/VideoCommon/Src/TextureCacheBase.cpp b/Source/Core/VideoCommon/Src/TextureCacheBase.cpp index 65407f2a0e..21e4a9d989 100644 --- a/Source/Core/VideoCommon/Src/TextureCacheBase.cpp +++ b/Source/Core/VideoCommon/Src/TextureCacheBase.cpp @@ -211,6 +211,9 @@ void TextureCache::ClearRenderTargets() bool TextureCache::CheckForCustomTextureLODs(u64 tex_hash, int texformat, unsigned int levels) { + if (levels == 1) + return false; + // Just checking if the necessary files exist, if they can't be loaded or have incorrect dimensions LODs will be black char texBasePathTemp[MAX_PATH]; char texPathTemp[MAX_PATH]; @@ -293,7 +296,7 @@ void TextureCache::DumpTexture(TCacheEntryBase* entry, unsigned int level) TextureCache::TCacheEntryBase* TextureCache::Load(unsigned int stage, u32 address, unsigned int width, unsigned int height, int texformat, - unsigned int tlutaddr, int tlutfmt, bool UseNativeMips, unsigned int maxlevel, bool from_tmem) + unsigned int tlutaddr, int tlutfmt, bool use_mipmaps, unsigned int maxlevel, bool from_tmem) { if (0 == address) return NULL; @@ -363,8 +366,6 @@ TextureCache::TCacheEntryBase* TextureCache::Load(unsigned int stage, } // 2. b) For normal textures, all texture parameters need to match - // NOTE: maxlevel is specified via render states, so it doesn't need to match exactly - // TODO: D3D9 doesn't support min_lod, so we should check for this here if (address == entry->addr && tex_hash == entry->hash && full_format == entry->format && entry->num_mipmaps > maxlevel && entry->native_width == nativeW && entry->native_height == nativeH) { @@ -406,15 +407,12 @@ TextureCache::TCacheEntryBase* TextureCache::Load(unsigned int stage, pcfmt = TexDecoder_Decode(temp, src_data, expandedWidth, expandedHeight, texformat, tlutaddr, tlutfmt, g_ActiveConfig.backend_info.bUseRGBATextures); - // TODO: Cleanup. Plus, we still autogenerate mipmaps in certain cases (we shouldn't do that) - bool isPow2; unsigned int texLevels; - isPow2 = !((width & (width - 1)) || (height & (height - 1))); - texLevels = (isPow2 && maxlevel) ? GetPow2(std::max(width, height)) : !isPow2; - texLevels = maxlevel ? std::min(texLevels, maxlevel + 1) : texLevels; + bool use_native_mips; + texLevels = use_mipmaps ? (maxlevel + 1) : 1; using_custom_lods = using_custom_texture && CheckForCustomTextureLODs(tex_hash, texformat, texLevels); - UseNativeMips = UseNativeMips && !using_custom_lods && (width == nativeW && height == nativeH); // Only load native mips if their dimensions fit to our virtual texture dimensions - texLevels = (UseNativeMips || using_custom_lods) ? texLevels : !isPow2; + use_native_mips = use_mipmaps && !using_custom_lods && (width == nativeW && height == nativeH); // Only load native mips if their dimensions fit to our virtual texture dimensions + texLevels = (use_native_mips || using_custom_lods) ? texLevels : 1; // create the entry/texture if (NULL == entry) { @@ -424,7 +422,7 @@ TextureCache::TCacheEntryBase* TextureCache::Load(unsigned int stage, // e.g. if our texture cache entry got too many mipmap levels we can limit the number of used levels by setting the appropriate render states // Thus, we don't update this member for every Load, but just whenever the texture gets recreated // TODO: D3D9 doesn't support min_lod. We should add a workaround for that here! - entry->num_mipmaps = maxlevel + 1; // TODO: Does this actually work? We can't really adjust mipmap settings per-stage... + entry->num_mipmaps = maxlevel + 1; entry->type = TCET_NORMAL; GFX_DEBUGGER_PAUSE_AT(NEXT_NEW_TEXTURE, true); @@ -443,7 +441,7 @@ TextureCache::TCacheEntryBase* TextureCache::Load(unsigned int stage, DumpTexture(entry, 0); // load mips - TODO: Loading mipmaps from tmem is untested! - if (texLevels > 1 && pcfmt != PC_TEX_FMT_NONE && UseNativeMips) + if (texLevels > 1 && pcfmt != PC_TEX_FMT_NONE && use_native_mips) { const unsigned int bsdepth = TexDecoder_GetTexelSizeInNibbles(texformat); diff --git a/Source/Core/VideoCommon/Src/TextureCacheBase.h b/Source/Core/VideoCommon/Src/TextureCacheBase.h index 4ef3b8a985..7197a639a7 100644 --- a/Source/Core/VideoCommon/Src/TextureCacheBase.h +++ b/Source/Core/VideoCommon/Src/TextureCacheBase.h @@ -116,7 +116,7 @@ public: virtual TCacheEntryBase* CreateRenderTargetTexture(unsigned int scaled_tex_w, unsigned int scaled_tex_h) = 0; static TCacheEntryBase* Load(unsigned int stage, u32 address, unsigned int width, unsigned int height, - int format, unsigned int tlutaddr, int tlutfmt, bool UseNativeMips, unsigned int maxlevel, bool from_tmem); + int format, unsigned int tlutaddr, int tlutfmt, bool use_mipmaps, unsigned int maxlevel, bool from_tmem); static void CopyRenderTargetToTexture(u32 dstAddr, unsigned int dstFormat, unsigned int srcFormat, const EFBRectangle& srcRect, bool isIntensity, bool scaleByHalf); From 069d949a572ea2543e86819487c0ba34e5564af8 Mon Sep 17 00:00:00 2001 From: NeoBrainX Date: Fri, 10 Aug 2012 13:13:51 +0200 Subject: [PATCH 3/7] [cleanup] TextureCache: Kill the autogen_mipmap parameter --- Source/Core/VideoCommon/Src/TextureCacheBase.cpp | 6 +++--- Source/Core/VideoCommon/Src/TextureCacheBase.h | 2 +- .../Plugins/Plugin_VideoDX11/Src/TextureCache.cpp | 5 +---- Source/Plugins/Plugin_VideoDX11/Src/TextureCache.h | 2 +- Source/Plugins/Plugin_VideoDX9/Src/TextureCache.cpp | 3 +-- Source/Plugins/Plugin_VideoDX9/Src/TextureCache.h | 2 +- Source/Plugins/Plugin_VideoOGL/Src/TextureCache.cpp | 13 ++----------- Source/Plugins/Plugin_VideoOGL/Src/TextureCache.h | 2 +- 8 files changed, 11 insertions(+), 24 deletions(-) diff --git a/Source/Core/VideoCommon/Src/TextureCacheBase.cpp b/Source/Core/VideoCommon/Src/TextureCacheBase.cpp index 21e4a9d989..dc80d98639 100644 --- a/Source/Core/VideoCommon/Src/TextureCacheBase.cpp +++ b/Source/Core/VideoCommon/Src/TextureCacheBase.cpp @@ -435,7 +435,7 @@ TextureCache::TCacheEntryBase* TextureCache::Load(unsigned int stage, else entry->type = TCET_NORMAL; // load texture - entry->Load(width, height, expandedWidth, 0, (texLevels == 0)); + entry->Load(width, height, expandedWidth, 0); if (g_ActiveConfig.bDumpTextures && !using_custom_texture) DumpTexture(entry, 0); @@ -470,7 +470,7 @@ TextureCache::TCacheEntryBase* TextureCache::Load(unsigned int stage, expandedHeight = (currentHeight + bsh) & (~bsh); TexDecoder_Decode(temp, *ptr, expandedWidth, expandedHeight, texformat, tlutaddr, tlutfmt, g_ActiveConfig.backend_info.bUseRGBATextures); - entry->Load(currentWidth, currentHeight, expandedWidth, level, false); + entry->Load(currentWidth, currentHeight, expandedWidth, level); if (g_ActiveConfig.bDumpTextures) DumpTexture(entry, level); @@ -493,7 +493,7 @@ TextureCache::TCacheEntryBase* TextureCache::Load(unsigned int stage, unsigned int currentHeight = (mipHeight > 0) ? mipHeight : 1; LoadCustomTexture(tex_hash, texformat, level, currentWidth, currentHeight); - entry->Load(currentWidth, currentHeight, currentWidth, level, false); + entry->Load(currentWidth, currentHeight, currentWidth, level); mipWidth >>= 1; mipHeight >>= 1; diff --git a/Source/Core/VideoCommon/Src/TextureCacheBase.h b/Source/Core/VideoCommon/Src/TextureCacheBase.h index 7197a639a7..5d44341c7c 100644 --- a/Source/Core/VideoCommon/Src/TextureCacheBase.h +++ b/Source/Core/VideoCommon/Src/TextureCacheBase.h @@ -89,7 +89,7 @@ public: virtual bool Save(const char filename[], unsigned int level) = 0; virtual void Load(unsigned int width, unsigned int height, - unsigned int expanded_width, unsigned int level, bool autogen_mips) = 0; + unsigned int expanded_width, unsigned int level) = 0; virtual void FromRenderTarget(u32 dstAddr, unsigned int dstFormat, unsigned int srcFormat, const EFBRectangle& srcRect, bool isIntensity, bool scaleByHalf, unsigned int cbufid, diff --git a/Source/Plugins/Plugin_VideoDX11/Src/TextureCache.cpp b/Source/Plugins/Plugin_VideoDX11/Src/TextureCache.cpp index 5f82a18fc0..844cf24b47 100644 --- a/Source/Plugins/Plugin_VideoDX11/Src/TextureCache.cpp +++ b/Source/Plugins/Plugin_VideoDX11/Src/TextureCache.cpp @@ -59,12 +59,9 @@ bool TextureCache::TCacheEntry::Save(const char filename[], unsigned int level) } void TextureCache::TCacheEntry::Load(unsigned int width, unsigned int height, - unsigned int expanded_width, unsigned int level, bool autogen_mips) + unsigned int expanded_width, unsigned int level) { D3D::ReplaceRGBATexture2D(texture->GetTex(), TextureCache::temp, width, height, expanded_width, level, usage); - - if (autogen_mips) - PD3DX11FilterTexture(D3D::context, texture->GetTex(), 0, D3DX11_DEFAULT); } TextureCache::TCacheEntryBase* TextureCache::CreateTexture(unsigned int width, diff --git a/Source/Plugins/Plugin_VideoDX11/Src/TextureCache.h b/Source/Plugins/Plugin_VideoDX11/Src/TextureCache.h index 59d343017c..7876cb79ee 100644 --- a/Source/Plugins/Plugin_VideoDX11/Src/TextureCache.h +++ b/Source/Plugins/Plugin_VideoDX11/Src/TextureCache.h @@ -41,7 +41,7 @@ private: ~TCacheEntry(); void Load(unsigned int width, unsigned int height, - unsigned int expanded_width, unsigned int levels, bool autogen_mips = false); + unsigned int expanded_width, unsigned int levels); void FromRenderTarget(u32 dstAddr, unsigned int dstFormat, unsigned int srcFormat, const EFBRectangle& srcRect, diff --git a/Source/Plugins/Plugin_VideoDX9/Src/TextureCache.cpp b/Source/Plugins/Plugin_VideoDX9/Src/TextureCache.cpp index 2be29048d3..660fad7379 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/TextureCache.cpp +++ b/Source/Plugins/Plugin_VideoDX9/Src/TextureCache.cpp @@ -72,10 +72,9 @@ bool TextureCache::TCacheEntry::Save(const char filename[], unsigned int level) } void TextureCache::TCacheEntry::Load(unsigned int width, unsigned int height, - unsigned int expanded_width, unsigned int level, bool autogen_mips) + unsigned int expanded_width, unsigned int level) { D3D::ReplaceTexture2D(texture, temp, width, height, expanded_width, d3d_fmt, swap_r_b, level); - // D3D9 will automatically generate mip maps if necessary } void TextureCache::TCacheEntry::FromRenderTarget(u32 dstAddr, unsigned int dstFormat, diff --git a/Source/Plugins/Plugin_VideoDX9/Src/TextureCache.h b/Source/Plugins/Plugin_VideoDX9/Src/TextureCache.h index 4a7cddd575..fc338e623f 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/TextureCache.h +++ b/Source/Plugins/Plugin_VideoDX9/Src/TextureCache.h @@ -44,7 +44,7 @@ private: ~TCacheEntry(); void Load(unsigned int width, unsigned int height, - unsigned int expanded_width, unsigned int levels, bool autogen_mips = false); + unsigned int expanded_width, unsigned int levels); void FromRenderTarget(u32 dstAddr, unsigned int dstFormat, unsigned int srcFormat, const EFBRectangle& srcRect, diff --git a/Source/Plugins/Plugin_VideoOGL/Src/TextureCache.cpp b/Source/Plugins/Plugin_VideoOGL/Src/TextureCache.cpp index 7a62131f90..ab850d9af2 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/TextureCache.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/TextureCache.cpp @@ -201,7 +201,7 @@ TextureCache::TCacheEntryBase* TextureCache::CreateTexture(unsigned int width, } void TextureCache::TCacheEntry::Load(unsigned int width, unsigned int height, - unsigned int expanded_width, unsigned int level, bool autogen_mips) + unsigned int expanded_width, unsigned int level) { //glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, texture); @@ -212,16 +212,7 @@ void TextureCache::TCacheEntry::Load(unsigned int width, unsigned int height, if (expanded_width != width) glPixelStorei(GL_UNPACK_ROW_LENGTH, expanded_width); - if (bHaveMipMaps && autogen_mips) - { - glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE); - glTexImage2D(GL_TEXTURE_2D, level, gl_iformat, width, height, 0, gl_format, gl_type, temp); - glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_FALSE); - } - else - { - glTexImage2D(GL_TEXTURE_2D, level, gl_iformat, width, height, 0, gl_format, gl_type, temp); - } + glTexImage2D(GL_TEXTURE_2D, level, gl_iformat, width, height, 0, gl_format, gl_type, temp); if (expanded_width != width) glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); diff --git a/Source/Plugins/Plugin_VideoOGL/Src/TextureCache.h b/Source/Plugins/Plugin_VideoOGL/Src/TextureCache.h index 30f44b797d..a26aa4049e 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/TextureCache.h +++ b/Source/Plugins/Plugin_VideoOGL/Src/TextureCache.h @@ -54,7 +54,7 @@ private: ~TCacheEntry(); void Load(unsigned int width, unsigned int height, - unsigned int expanded_width, unsigned int level, bool autogen_mips = false); + unsigned int expanded_width, unsigned int level); void FromRenderTarget(u32 dstAddr, unsigned int dstFormat, unsigned int srcFormat, const EFBRectangle& srcRect, From 0706050b746e841227f0dcfd1572b62ddf184728 Mon Sep 17 00:00:00 2001 From: NeoBrainX Date: Fri, 10 Aug 2012 13:24:40 +0200 Subject: [PATCH 4/7] [cleanup] Vastly clean up backend-specific sampler state logic. --- .../Plugins/Plugin_VideoDX11/Src/Render.cpp | 6 +--- Source/Plugins/Plugin_VideoDX9/Src/Render.cpp | 8 ++--- .../Plugin_VideoOGL/Src/TextureCache.cpp | 29 ++++++------------- 3 files changed, 13 insertions(+), 30 deletions(-) diff --git a/Source/Plugins/Plugin_VideoDX11/Src/Render.cpp b/Source/Plugins/Plugin_VideoDX11/Src/Render.cpp index 81efa3623f..cb9a0d32a0 100644 --- a/Source/Plugins/Plugin_VideoDX11/Src/Render.cpp +++ b/Source/Plugins/Plugin_VideoDX11/Src/Render.cpp @@ -1382,14 +1382,10 @@ void Renderer::SetSamplerState(int stage, int texindex) const TexMode0 &tm0 = tex.texMode0[stage]; const TexMode1 &tm1 = tex.texMode1[stage]; - unsigned int mip; - mip = (tm0.min_filter == 8) ? TEXF_NONE:d3dMipFilters[tm0.min_filter & 3]; - if ((tm0.min_filter & 3) && (tm0.min_filter != 8) && ((tm1.max_lod >> 4) == 0)) mip = TEXF_NONE; + unsigned int mip = d3dMipFilters[tm0.min_filter & 3]; if (texindex) stage += 4; - // TODO: Clarify whether these values are correct - // NOTE: since there's no "no filter" in DX11 we're using point filters in these cases if (g_ActiveConfig.bForceFiltering) { gx_state.sampdc[stage].Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR; diff --git a/Source/Plugins/Plugin_VideoDX9/Src/Render.cpp b/Source/Plugins/Plugin_VideoDX9/Src/Render.cpp index 653e387192..1bca963bd6 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/Render.cpp +++ b/Source/Plugins/Plugin_VideoDX9/Src/Render.cpp @@ -1318,9 +1318,7 @@ void Renderer::SetSamplerState(int stage, int texindex) { min = (tm0.min_filter & 4) ? D3DTEXF_LINEAR : D3DTEXF_POINT; mag = tm0.mag_filter ? D3DTEXF_LINEAR : D3DTEXF_POINT; - mip = (tm0.min_filter == 8) ? D3DTEXF_NONE : d3dMipFilters[tm0.min_filter & 3]; - if((tm0.min_filter & 3) && (tm0.min_filter != 8) && ((tm1.max_lod >> 4) == 0)) - mip = D3DTEXF_NONE; + mip = d3dMipFilters[tm0.min_filter & 3]; } if (texindex) stage += 4; @@ -1335,8 +1333,8 @@ void Renderer::SetSamplerState(int stage, int texindex) D3D::SetSamplerState(stage, D3DSAMP_ADDRESSU, d3dClamps[tm0.wrap_s]); D3D::SetSamplerState(stage, D3DSAMP_ADDRESSV, d3dClamps[tm0.wrap_t]); - //float SuperSampleCoeficient = (s_LastAA < 3)? s_LastAA + 1 : s_LastAA - 1;// uncoment this changes to conserve detail when incresing ssaa level - float lodbias = (tm0.lod_bias / 32.0f);// + (s_LastAA)?(log(SuperSampleCoeficient) / log(2.0f)):0; + + float lodbias = (tm0.lod_bias / 32.0f); D3D::SetSamplerState(stage, D3DSAMP_MIPMAPLODBIAS, *(DWORD*)&lodbias); D3D::SetSamplerState(stage, D3DSAMP_MAXMIPLEVEL, tm1.min_lod >> 4); } diff --git a/Source/Plugins/Plugin_VideoOGL/Src/TextureCache.cpp b/Source/Plugins/Plugin_VideoOGL/Src/TextureCache.cpp index ab850d9af2..14c771b799 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/TextureCache.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/TextureCache.cpp @@ -348,35 +348,24 @@ void TextureCache::TCacheEntry::FromRenderTarget(u32 dstAddr, unsigned int dstFo void TextureCache::TCacheEntry::SetTextureParameters(const TexMode0 &newmode, const TexMode1 &newmode1) { - // TODO: not used anywhere - TexMode0 mode = newmode; - //mode1 = newmode1; - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, - (newmode.mag_filter || g_Config.bForceFiltering) ? GL_LINEAR : GL_NEAREST); + (newmode.mag_filter || g_Config.bForceFiltering) ? GL_LINEAR : GL_NEAREST); - if (bHaveMipMaps) - { - // TODO: not used anywhere - if (g_ActiveConfig.bForceFiltering && newmode.min_filter < 4) - mode.min_filter += 4; // take equivalent forced linear + int filt = newmode.min_filter; + if (g_ActiveConfig.bForceFiltering && newmode.min_filter < 4) + filt += 4; // take equivalent forced linear - int filt = newmode.min_filter; - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, c_MinLinearFilter[filt & 7]); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, newmode1.min_lod >> 4); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, newmode1.max_lod >> 4); - glTexEnvf(GL_TEXTURE_FILTER_CONTROL, GL_TEXTURE_LOD_BIAS, (newmode.lod_bias / 32.0f)); - } - else - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, - (g_ActiveConfig.bForceFiltering || newmode.min_filter >= 4) ? GL_LINEAR : GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, c_MinLinearFilter[filt & 7]); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, newmode1.min_lod / 16.f); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, newmode1.max_lod / 16.f); + glTexEnvf(GL_TEXTURE_FILTER_CONTROL, GL_TEXTURE_LOD_BIAS, newmode.lod_bias / 32.0f); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, c_WrapSettings[newmode.wrap_s]); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, c_WrapSettings[newmode.wrap_t]); if (g_Config.iMaxAnisotropy >= 1) glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, - (float)(1 << g_ActiveConfig.iMaxAnisotropy)); + (float)(1 << g_ActiveConfig.iMaxAnisotropy)); } TextureCache::~TextureCache() From 6c8a22de24e1e374c4357ca653ac584c8a6adfac Mon Sep 17 00:00:00 2001 From: NeoBrainX Date: Fri, 10 Aug 2012 13:25:21 +0200 Subject: [PATCH 5/7] [bugfix] DX9::TextureCache: Use max_lod instead of min_lod where necessary. --- Source/Plugins/Plugin_VideoDX9/Src/Render.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/Plugins/Plugin_VideoDX9/Src/Render.cpp b/Source/Plugins/Plugin_VideoDX9/Src/Render.cpp index 1bca963bd6..9299bf0b8f 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/Render.cpp +++ b/Source/Plugins/Plugin_VideoDX9/Src/Render.cpp @@ -1336,7 +1336,7 @@ void Renderer::SetSamplerState(int stage, int texindex) float lodbias = (tm0.lod_bias / 32.0f); D3D::SetSamplerState(stage, D3DSAMP_MIPMAPLODBIAS, *(DWORD*)&lodbias); - D3D::SetSamplerState(stage, D3DSAMP_MAXMIPLEVEL, tm1.min_lod >> 4); + D3D::SetSamplerState(stage, D3DSAMP_MAXMIPLEVEL, tm1.max_lod >> 4); } void Renderer::SetInterlacingMode() From 9d5fc3d7f06b10d27438ea73bd29b09d2fd21ec2 Mon Sep 17 00:00:00 2001 From: NeoBrainX Date: Fri, 10 Aug 2012 13:27:35 +0200 Subject: [PATCH 6/7] [bugfix] Properly decode lod_bias. --- Source/Plugins/Plugin_VideoDX11/Src/Render.cpp | 2 +- Source/Plugins/Plugin_VideoDX9/Src/Render.cpp | 2 +- Source/Plugins/Plugin_VideoOGL/Src/TextureCache.cpp | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Source/Plugins/Plugin_VideoDX11/Src/Render.cpp b/Source/Plugins/Plugin_VideoDX11/Src/Render.cpp index cb9a0d32a0..345cce580a 100644 --- a/Source/Plugins/Plugin_VideoDX11/Src/Render.cpp +++ b/Source/Plugins/Plugin_VideoDX11/Src/Render.cpp @@ -1427,7 +1427,7 @@ void Renderer::SetSamplerState(int stage, int texindex) // When mipfilter is set to "none", just disable mipmapping altogether gx_state.sampdc[stage].MaxLOD = (mip == TEXF_NONE) ? 0.0f : (float)tm1.max_lod/16.f; gx_state.sampdc[stage].MinLOD = (float)tm1.min_lod/16.f; - gx_state.sampdc[stage].MipLODBias = (float)tm0.lod_bias/32.0f; + gx_state.sampdc[stage].MipLODBias = (s32)tm0.lod_bias/32.0f; } void Renderer::SetInterlacingMode() diff --git a/Source/Plugins/Plugin_VideoDX9/Src/Render.cpp b/Source/Plugins/Plugin_VideoDX9/Src/Render.cpp index 9299bf0b8f..019efe1682 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/Render.cpp +++ b/Source/Plugins/Plugin_VideoDX9/Src/Render.cpp @@ -1334,7 +1334,7 @@ void Renderer::SetSamplerState(int stage, int texindex) D3D::SetSamplerState(stage, D3DSAMP_ADDRESSU, d3dClamps[tm0.wrap_s]); D3D::SetSamplerState(stage, D3DSAMP_ADDRESSV, d3dClamps[tm0.wrap_t]); - float lodbias = (tm0.lod_bias / 32.0f); + float lodbias = (s32)tm0.lod_bias / 32.0f; D3D::SetSamplerState(stage, D3DSAMP_MIPMAPLODBIAS, *(DWORD*)&lodbias); D3D::SetSamplerState(stage, D3DSAMP_MAXMIPLEVEL, tm1.max_lod >> 4); } diff --git a/Source/Plugins/Plugin_VideoOGL/Src/TextureCache.cpp b/Source/Plugins/Plugin_VideoOGL/Src/TextureCache.cpp index 14c771b799..035c42248d 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/TextureCache.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/TextureCache.cpp @@ -358,7 +358,7 @@ void TextureCache::TCacheEntry::SetTextureParameters(const TexMode0 &newmode, co glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, c_MinLinearFilter[filt & 7]); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, newmode1.min_lod / 16.f); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, newmode1.max_lod / 16.f); - glTexEnvf(GL_TEXTURE_FILTER_CONTROL, GL_TEXTURE_LOD_BIAS, newmode.lod_bias / 32.0f); + glTexEnvf(GL_TEXTURE_FILTER_CONTROL, GL_TEXTURE_LOD_BIAS, (s32)newmode.lod_bias / 32.0f); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, c_WrapSettings[newmode.wrap_s]); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, c_WrapSettings[newmode.wrap_t]); From 52963584f0339be68c7f5fcc8d79da37cf0cba5b Mon Sep 17 00:00:00 2001 From: NeoBrainX Date: Fri, 10 Aug 2012 13:29:19 +0200 Subject: [PATCH 7/7] [bugfix] Make sure to specify the correct max lod level. --- Source/Plugins/Plugin_VideoDX11/Src/VertexManager.cpp | 4 ++-- Source/Plugins/Plugin_VideoDX9/Src/VertexManager.cpp | 4 ++-- Source/Plugins/Plugin_VideoOGL/Src/VertexManager.cpp | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Source/Plugins/Plugin_VideoDX11/Src/VertexManager.cpp b/Source/Plugins/Plugin_VideoDX11/Src/VertexManager.cpp index e2a8f4a547..2ab21e29ad 100644 --- a/Source/Plugins/Plugin_VideoDX11/Src/VertexManager.cpp +++ b/Source/Plugins/Plugin_VideoDX11/Src/VertexManager.cpp @@ -246,8 +246,8 @@ void VertexManager::vFlush() tex.texImage0[i&3].width + 1, tex.texImage0[i&3].height + 1, tex.texImage0[i&3].format, tex.texTlut[i&3].tmem_offset<<9, tex.texTlut[i&3].tlut_format, - (tex.texMode0[i&3].min_filter & 3) && (tex.texMode0[i&3].min_filter != 8), - tex.texMode1[i&3].max_lod >> 4, + (tex.texMode0[i&3].min_filter & 3), + ceil(tex.texMode1[i&3].max_lod / 16.f), tex.texImage1[i&3].image_type); if (tentry) diff --git a/Source/Plugins/Plugin_VideoDX9/Src/VertexManager.cpp b/Source/Plugins/Plugin_VideoDX9/Src/VertexManager.cpp index e8e425cc96..47b40a93f9 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/VertexManager.cpp +++ b/Source/Plugins/Plugin_VideoDX9/Src/VertexManager.cpp @@ -345,8 +345,8 @@ void VertexManager::vFlush() tex.texImage0[i&3].width + 1, tex.texImage0[i&3].height + 1, tex.texImage0[i&3].format, tex.texTlut[i&3].tmem_offset<<9, tex.texTlut[i&3].tlut_format, - (tex.texMode0[i&3].min_filter & 3) && (tex.texMode0[i&3].min_filter != 8), - tex.texMode1[i&3].max_lod >> 4, + (tex.texMode0[i&3].min_filter & 3), + ceil(tex.texMode1[i&3].max_lod / 16.f), tex.texImage1[i&3].image_type); if (tentry) diff --git a/Source/Plugins/Plugin_VideoOGL/Src/VertexManager.cpp b/Source/Plugins/Plugin_VideoOGL/Src/VertexManager.cpp index 501c4969e5..05621ce838 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/VertexManager.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/VertexManager.cpp @@ -164,8 +164,8 @@ void VertexManager::vFlush() tex.texImage0[i&3].width + 1, tex.texImage0[i&3].height + 1, tex.texImage0[i&3].format, tex.texTlut[i&3].tmem_offset<<9, tex.texTlut[i&3].tlut_format, - (tex.texMode0[i&3].min_filter & 3) && (tex.texMode0[i&3].min_filter != 8), - tex.texMode1[i&3].max_lod >> 4, + (tex.texMode0[i&3].min_filter & 3), + ceil(tex.texMode1[i&3].max_lod / 16.f), tex.texImage1[i&3].image_type); if (tentry)