[cleanup] [bugfix] TextureCacheBase: Cleanup and simplify mipmapping logic. Possibly fixes a bug or two.

This commit is contained in:
NeoBrainX
2012-08-10 13:09:16 +02:00
parent c859aaae84
commit ee3d6d66d7
2 changed files with 11 additions and 13 deletions

View File

@ -211,6 +211,9 @@ void TextureCache::ClearRenderTargets()
bool TextureCache::CheckForCustomTextureLODs(u64 tex_hash, int texformat, unsigned int levels) 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 // 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 texBasePathTemp[MAX_PATH];
char texPathTemp[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, TextureCache::TCacheEntryBase* TextureCache::Load(unsigned int stage,
u32 address, unsigned int width, unsigned int height, int texformat, 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) if (0 == address)
return NULL; return NULL;
@ -363,8 +366,6 @@ TextureCache::TCacheEntryBase* TextureCache::Load(unsigned int stage,
} }
// 2. b) For normal textures, all texture parameters need to match // 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 && 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)
{ {
@ -406,15 +407,12 @@ TextureCache::TCacheEntryBase* TextureCache::Load(unsigned int stage,
pcfmt = TexDecoder_Decode(temp, src_data, expandedWidth, pcfmt = TexDecoder_Decode(temp, src_data, expandedWidth,
expandedHeight, texformat, tlutaddr, tlutfmt, g_ActiveConfig.backend_info.bUseRGBATextures); 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; unsigned int texLevels;
isPow2 = !((width & (width - 1)) || (height & (height - 1))); bool use_native_mips;
texLevels = (isPow2 && maxlevel) ? GetPow2(std::max(width, height)) : !isPow2; texLevels = use_mipmaps ? (maxlevel + 1) : 1;
texLevels = maxlevel ? std::min(texLevels, maxlevel + 1) : texLevels;
using_custom_lods = using_custom_texture && CheckForCustomTextureLODs(tex_hash, texformat, texLevels); 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 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 = (UseNativeMips || using_custom_lods) ? texLevels : !isPow2; texLevels = (use_native_mips || using_custom_lods) ? texLevels : 1;
// create the entry/texture // create the entry/texture
if (NULL == entry) { 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 // 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 // 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! // 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; entry->type = TCET_NORMAL;
GFX_DEBUGGER_PAUSE_AT(NEXT_NEW_TEXTURE, true); GFX_DEBUGGER_PAUSE_AT(NEXT_NEW_TEXTURE, true);
@ -443,7 +441,7 @@ TextureCache::TCacheEntryBase* TextureCache::Load(unsigned int stage,
DumpTexture(entry, 0); DumpTexture(entry, 0);
// load mips - TODO: Loading mipmaps from tmem is untested! // 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); const unsigned int bsdepth = TexDecoder_GetTexelSizeInNibbles(texformat);

View File

@ -116,7 +116,7 @@ public:
virtual TCacheEntryBase* CreateRenderTargetTexture(unsigned int scaled_tex_w, unsigned int scaled_tex_h) = 0; 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, 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, static void CopyRenderTargetToTexture(u32 dstAddr, unsigned int dstFormat, unsigned int srcFormat,
const EFBRectangle& srcRect, bool isIntensity, bool scaleByHalf); const EFBRectangle& srcRect, bool isIntensity, bool scaleByHalf);