From 3ecc5e879c2ca82a021ca7ebbfd4299d192ba178 Mon Sep 17 00:00:00 2001 From: NeoBrainX Date: Sat, 12 May 2012 13:25:13 +0200 Subject: TextureCacheBase: Move custom texture loading to a helper function --- Source/Core/VideoCommon/Src/TextureCacheBase.cpp | 32 ++++++++++++++++-------- 1 file changed, 21 insertions(+), 11 deletions(-) (limited to 'Source/Core/VideoCommon/Src/TextureCacheBase.cpp') diff --git a/Source/Core/VideoCommon/Src/TextureCacheBase.cpp b/Source/Core/VideoCommon/Src/TextureCacheBase.cpp index 00ff9610be..34d4020c86 100644 --- a/Source/Core/VideoCommon/Src/TextureCacheBase.cpp +++ b/Source/Core/VideoCommon/Src/TextureCacheBase.cpp @@ -178,6 +178,23 @@ void TextureCache::ClearRenderTargets() iter->second->type = TCET_NORMAL; } +PC_TexFormat TextureCache::LoadCustomTexture(u64 tex_hash, int texformat, unsigned int& width, unsigned int& height, u8* dest) +{ + char texPathTemp[MAX_PATH]; + unsigned int newWidth = 0; + unsigned int newHeight = 0; + + sprintf(texPathTemp, "%s_%08x_%i", SConfig::GetInstance().m_LocalCoreStartupParameter.m_strUniqueID.c_str(), (u32) (tex_hash & 0x00000000FFFFFFFFLL), texformat); + PC_TexFormat ret = HiresTextures::GetHiresTex(texPathTemp, &newWidth, &newHeight, texformat, dest); + + if (ret != PC_TEX_FMT_NONE) + { + width = newWidth; + height = newHeight; + } + return ret; +} + 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) @@ -272,21 +289,14 @@ TextureCache::TCacheEntryBase* TextureCache::Load(unsigned int stage, } } + if (g_ActiveConfig.bHiresTextures) { - // Load Custom textures - char texPathTemp[MAX_PATH]; - - unsigned int newWidth = width; - unsigned int newHeight = height; - - sprintf(texPathTemp, "%s_%08x_%i", SConfig::GetInstance().m_LocalCoreStartupParameter.m_strUniqueID.c_str(), (u32) (tex_hash & 0x00000000FFFFFFFFLL), texformat); - pcfmt = HiresTextures::GetHiresTex(texPathTemp, &newWidth, &newHeight, texformat, temp); - + pcfmt = LoadCustomTexture(tex_hash, texformat, width, height, temp); if (pcfmt != PC_TEX_FMT_NONE) { - expandedWidth = width = newWidth; - expandedHeight = height = newHeight; + expandedWidth = width; + expandedHeight = height; } } -- cgit v1.2.3 From a8ad59ee3e4345b9cc2fcf9bfe28e385a7e443c6 Mon Sep 17 00:00:00 2001 From: NeoBrainX Date: Sat, 12 May 2012 13:31:09 +0200 Subject: TextureCacheBase: Move texture dumping to a helper function. --- Source/Core/VideoCommon/Src/TextureCacheBase.cpp | 36 +++++++++++++----------- 1 file changed, 19 insertions(+), 17 deletions(-) (limited to 'Source/Core/VideoCommon/Src/TextureCacheBase.cpp') diff --git a/Source/Core/VideoCommon/Src/TextureCacheBase.cpp b/Source/Core/VideoCommon/Src/TextureCacheBase.cpp index 34d4020c86..d01a68954c 100644 --- a/Source/Core/VideoCommon/Src/TextureCacheBase.cpp +++ b/Source/Core/VideoCommon/Src/TextureCacheBase.cpp @@ -195,6 +195,24 @@ PC_TexFormat TextureCache::LoadCustomTexture(u64 tex_hash, int texformat, unsign return ret; } +void TextureCache::DumpTexture(TCacheEntryBase* entry) +{ + char szTemp[MAX_PATH]; + std::string szDir = File::GetUserPath(D_DUMPTEXTURES_IDX) + + SConfig::GetInstance().m_LocalCoreStartupParameter.m_strUniqueID; + + // make sure that the directory exists + if (false == File::Exists(szDir) || false == File::IsDirectory(szDir)) + File::CreateDir(szDir.c_str()); + + sprintf(szTemp, "%s/%s_%08x_%i.png", szDir.c_str(), + SConfig::GetInstance().m_LocalCoreStartupParameter.m_strUniqueID.c_str(), + (u32) (entry->hash & 0x00000000FFFFFFFFLL), entry->format & 0xFFFF); // TODO: TLUT format should actually be here as well? :/ + + if (false == File::Exists(szTemp)) + entry->Save(szTemp); +} + 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) @@ -379,24 +397,8 @@ TextureCache::TCacheEntryBase* TextureCache::Load(unsigned int stage, } // TODO: won't this cause loaded hires textures to be dumped as well? - // dump texture to file if (g_ActiveConfig.bDumpTextures) - { - char szTemp[MAX_PATH]; - std::string szDir = File::GetUserPath(D_DUMPTEXTURES_IDX) + - SConfig::GetInstance().m_LocalCoreStartupParameter.m_strUniqueID; - - // make sure that the directory exists - if (false == File::Exists(szDir) || false == File::IsDirectory(szDir)) - File::CreateDir(szDir.c_str()); - - sprintf(szTemp, "%s/%s_%08x_%i.png", szDir.c_str(), - SConfig::GetInstance().m_LocalCoreStartupParameter.m_strUniqueID.c_str(), - (u32) (tex_hash & 0x00000000FFFFFFFFLL), texformat); - - if (false == File::Exists(szTemp)) - entry->Save(szTemp); - } + DumpTexture(entry); INCSTAT(stats.numTexturesCreated); SETSTAT(stats.numTexturesAlive, textures.size()); -- cgit v1.2.3 From a5e68ab10e2655853e7063ce3c7ce1aa31df9db8 Mon Sep 17 00:00:00 2001 From: NeoBrainX Date: Sat, 12 May 2012 13:50:03 +0200 Subject: TextureCacheBase: Support dumping individual mipmaps. --- Source/Core/VideoCommon/Src/TextureCacheBase.cpp | 33 +++++++++++++++++------- 1 file changed, 24 insertions(+), 9 deletions(-) (limited to 'Source/Core/VideoCommon/Src/TextureCacheBase.cpp') diff --git a/Source/Core/VideoCommon/Src/TextureCacheBase.cpp b/Source/Core/VideoCommon/Src/TextureCacheBase.cpp index d01a68954c..ce306d55c6 100644 --- a/Source/Core/VideoCommon/Src/TextureCacheBase.cpp +++ b/Source/Core/VideoCommon/Src/TextureCacheBase.cpp @@ -195,7 +195,7 @@ PC_TexFormat TextureCache::LoadCustomTexture(u64 tex_hash, int texformat, unsign return ret; } -void TextureCache::DumpTexture(TCacheEntryBase* entry) +void TextureCache::DumpTexture(TCacheEntryBase* entry, unsigned int level) { char szTemp[MAX_PATH]; std::string szDir = File::GetUserPath(D_DUMPTEXTURES_IDX) + @@ -205,12 +205,23 @@ void TextureCache::DumpTexture(TCacheEntryBase* entry) if (false == File::Exists(szDir) || false == File::IsDirectory(szDir)) File::CreateDir(szDir.c_str()); - sprintf(szTemp, "%s/%s_%08x_%i.png", szDir.c_str(), - SConfig::GetInstance().m_LocalCoreStartupParameter.m_strUniqueID.c_str(), - (u32) (entry->hash & 0x00000000FFFFFFFFLL), entry->format & 0xFFFF); // TODO: TLUT format should actually be here as well? :/ + // For compatibility with old texture packs, don't print the LOD index for level 0. + // TODO: TLUT format should actually be stored in filename? :/ + if (level == 0) + { + sprintf(szTemp, "%s/%s_%08x_%i.png", szDir.c_str(), + SConfig::GetInstance().m_LocalCoreStartupParameter.m_strUniqueID.c_str(), + (u32) (entry->hash & 0x00000000FFFFFFFFLL), entry->format & 0xFFFF); + } + else + { + sprintf(szTemp, "%s/%s_%08x_%i_mip%d.png", szDir.c_str(), + SConfig::GetInstance().m_LocalCoreStartupParameter.m_strUniqueID.c_str(), + (u32) (entry->hash & 0x00000000FFFFFFFFLL), entry->format & 0xFFFF, level); + } if (false == File::Exists(szTemp)) - entry->Save(szTemp); + entry->Save(szTemp, level); } TextureCache::TCacheEntryBase* TextureCache::Load(unsigned int stage, @@ -357,6 +368,10 @@ TextureCache::TCacheEntryBase* TextureCache::Load(unsigned int stage, // load texture entry->Load(width, height, expandedWidth, 0, (texLevels == 0)); + // TODO: won't this cause loaded hires textures to be dumped as well? + if (g_ActiveConfig.bDumpTextures) + DumpTexture(entry, 0); + // load mips - TODO: Loading mipmaps from tmem is untested! if (texLevels > 1 && pcfmt != PC_TEX_FMT_NONE) { @@ -389,6 +404,10 @@ TextureCache::TCacheEntryBase* TextureCache::Load(unsigned int stage, TexDecoder_Decode(temp, *ptr, expandedWidth, expandedHeight, texformat, tlutaddr, tlutfmt, g_ActiveConfig.backend_info.bUseRGBATextures); entry->Load(currentWidth, currentHeight, expandedWidth, level, false); + // TODO: won't this cause loaded hires textures to be dumped as well? + if (g_ActiveConfig.bDumpTextures) + DumpTexture(entry, level); + *ptr += ((std::max(mipWidth, bsw) * std::max(mipHeight, bsh) * bsdepth) >> 1); mipWidth >>= 1; mipHeight >>= 1; @@ -396,10 +415,6 @@ TextureCache::TCacheEntryBase* TextureCache::Load(unsigned int stage, } } - // TODO: won't this cause loaded hires textures to be dumped as well? - if (g_ActiveConfig.bDumpTextures) - DumpTexture(entry); - INCSTAT(stats.numTexturesCreated); SETSTAT(stats.numTexturesAlive, textures.size()); -- cgit v1.2.3 From 41d37ab0a0e1236d4e5665c3a7206478ffca2a7f Mon Sep 17 00:00:00 2001 From: NeoBrainX Date: Sat, 12 May 2012 14:31:38 +0200 Subject: TextureCacheBase: Support loading custom mipmaps. --- Source/Core/VideoCommon/Src/TextureCacheBase.cpp | 74 +++++++++++++++++++----- 1 file changed, 60 insertions(+), 14 deletions(-) (limited to 'Source/Core/VideoCommon/Src/TextureCacheBase.cpp') diff --git a/Source/Core/VideoCommon/Src/TextureCacheBase.cpp b/Source/Core/VideoCommon/Src/TextureCacheBase.cpp index ce306d55c6..6ebeba2ffb 100644 --- a/Source/Core/VideoCommon/Src/TextureCacheBase.cpp +++ b/Source/Core/VideoCommon/Src/TextureCacheBase.cpp @@ -178,13 +178,39 @@ void TextureCache::ClearRenderTargets() iter->second->type = TCET_NORMAL; } -PC_TexFormat TextureCache::LoadCustomTexture(u64 tex_hash, int texformat, unsigned int& width, unsigned int& height, u8* dest) +bool TextureCache::CheckForCustomTextureLODs(u64 tex_hash, int texformat, unsigned int levels) +{ + // 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]; + + sprintf(texBasePathTemp, "%s_%08x_%i", SConfig::GetInstance().m_LocalCoreStartupParameter.m_strUniqueID.c_str(), (u32) (tex_hash & 0x00000000FFFFFFFFLL), texformat); + + for (unsigned int level = 1; level < levels; ++level) + { + sprintf(texPathTemp, "%s_mip%i", texBasePathTemp, level); + if (!HiresTextures::HiresTexExists(texPathTemp)) + { + if (level > 1) + WARN_LOG(VIDEO, "Couldn't find custom texture LOD with index %i (filename: %s), disabling custom LODs for this texture", level, texPathTemp); + + return false; + } + } + return true; +} + +PC_TexFormat TextureCache::LoadCustomTexture(u64 tex_hash, int texformat, unsigned int level, unsigned int& width, unsigned int& height, u8* dest) { char texPathTemp[MAX_PATH]; unsigned int newWidth = 0; unsigned int newHeight = 0; - sprintf(texPathTemp, "%s_%08x_%i", SConfig::GetInstance().m_LocalCoreStartupParameter.m_strUniqueID.c_str(), (u32) (tex_hash & 0x00000000FFFFFFFFLL), texformat); + if (level == 0) + sprintf(texPathTemp, "%s_%08x_%i", SConfig::GetInstance().m_LocalCoreStartupParameter.m_strUniqueID.c_str(), (u32) (tex_hash & 0x00000000FFFFFFFFLL), texformat); + else + sprintf(texPathTemp, "%s_%08x_%i_mip%i", SConfig::GetInstance().m_LocalCoreStartupParameter.m_strUniqueID.c_str(), (u32) (tex_hash & 0x00000000FFFFFFFFLL), texformat, level); + PC_TexFormat ret = HiresTextures::GetHiresTex(texPathTemp, &newWidth, &newHeight, texformat, dest); if (ret != PC_TEX_FMT_NONE) @@ -215,7 +241,7 @@ void TextureCache::DumpTexture(TCacheEntryBase* entry, unsigned int level) } else { - sprintf(szTemp, "%s/%s_%08x_%i_mip%d.png", szDir.c_str(), + sprintf(szTemp, "%s/%s_%08x_%i_mip%i.png", szDir.c_str(), SConfig::GetInstance().m_LocalCoreStartupParameter.m_strUniqueID.c_str(), (u32) (entry->hash & 0x00000000FFFFFFFFLL), entry->format & 0xFFFF, level); } @@ -240,6 +266,9 @@ TextureCache::TCacheEntryBase* TextureCache::Load(unsigned int stage, const unsigned int nativeW = width; const unsigned int nativeH = height; + bool using_custom_texture = false; + bool using_custom_lods = false; + u32 texID = address; u64 tex_hash = TEXHASH_INVALID; // Hash assigned to texcache entry (also used to generate filenames used for texture dumping and custom texture lookup) u64 tlut_hash = TEXHASH_INVALID; @@ -321,11 +350,12 @@ TextureCache::TCacheEntryBase* TextureCache::Load(unsigned int stage, if (g_ActiveConfig.bHiresTextures) { - pcfmt = LoadCustomTexture(tex_hash, texformat, width, height, temp); + pcfmt = LoadCustomTexture(tex_hash, texformat, 0, width, height, temp); if (pcfmt != PC_TEX_FMT_NONE) { expandedWidth = width; expandedHeight = height; + using_custom_texture = true; } } @@ -336,13 +366,12 @@ TextureCache::TCacheEntryBase* TextureCache::Load(unsigned int stage, bool isPow2; unsigned int texLevels; - UseNativeMips = UseNativeMips && (width == nativeW && height == nativeH); // Only load native mips if their dimensions fit to our virtual texture dimensions isPow2 = !((width & (width - 1)) || (height & (height - 1))); - texLevels = (isPow2 && UseNativeMips && maxlevel) ? - GetPow2(std::max(width, height)) : !isPow2; - - if ((texLevels > (maxlevel + 1)) && maxlevel) - texLevels = maxlevel + 1; + texLevels = (isPow2 && maxlevel) ? GetPow2(std::max(width, height)) : !isPow2; + texLevels = maxlevel ? std::min(texLevels, maxlevel + 1) : 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 + texLevels = (UseNativeMips || using_custom_lods) ? texLevels : !isPow2; // create the entry/texture if (NULL == entry) { @@ -368,12 +397,11 @@ TextureCache::TCacheEntryBase* TextureCache::Load(unsigned int stage, // load texture entry->Load(width, height, expandedWidth, 0, (texLevels == 0)); - // TODO: won't this cause loaded hires textures to be dumped as well? - if (g_ActiveConfig.bDumpTextures) + if (g_ActiveConfig.bDumpTextures && !using_custom_texture) DumpTexture(entry, 0); // load mips - TODO: Loading mipmaps from tmem is untested! - if (texLevels > 1 && pcfmt != PC_TEX_FMT_NONE) + if (texLevels > 1 && pcfmt != PC_TEX_FMT_NONE && UseNativeMips) { const unsigned int bsdepth = TexDecoder_GetTexelSizeInNibbles(texformat); @@ -404,7 +432,6 @@ TextureCache::TCacheEntryBase* TextureCache::Load(unsigned int stage, TexDecoder_Decode(temp, *ptr, expandedWidth, expandedHeight, texformat, tlutaddr, tlutfmt, g_ActiveConfig.backend_info.bUseRGBATextures); entry->Load(currentWidth, currentHeight, expandedWidth, level, false); - // TODO: won't this cause loaded hires textures to be dumped as well? if (g_ActiveConfig.bDumpTextures) DumpTexture(entry, level); @@ -414,6 +441,25 @@ TextureCache::TCacheEntryBase* TextureCache::Load(unsigned int stage, ++level; } } + else if (texLevels > 1 && pcfmt != PC_TEX_FMT_NONE && using_custom_lods) + { + unsigned int level = 1; + unsigned int mipWidth = (width + 1) >> 1; + unsigned int mipHeight = (height + 1) >> 1; + + while ((mipHeight || mipWidth) && (level < texLevels)) + { + unsigned int currentWidth = (mipWidth > 0) ? mipWidth : 1; + unsigned int currentHeight = (mipHeight > 0) ? mipHeight : 1; + + LoadCustomTexture(tex_hash, texformat, level, currentWidth, currentHeight, temp); + entry->Load(currentWidth, currentHeight, currentWidth, level, false); + + mipWidth >>= 1; + mipHeight >>= 1; + ++level; + } + } INCSTAT(stats.numTexturesCreated); SETSTAT(stats.numTexturesAlive, textures.size()); -- cgit v1.2.3 From 72e83140f01b247a4fb0ca7a3eb9afc377d994b4 Mon Sep 17 00:00:00 2001 From: NeoBrainX Date: Sun, 13 May 2012 15:38:56 +0200 Subject: TextureCacheBase: Remove the texture size limit for custom textures. Only the GPU restrictions for maximum texture size remain. --- Source/Core/VideoCommon/Src/TextureCacheBase.cpp | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) (limited to 'Source/Core/VideoCommon/Src/TextureCacheBase.cpp') diff --git a/Source/Core/VideoCommon/Src/TextureCacheBase.cpp b/Source/Core/VideoCommon/Src/TextureCacheBase.cpp index 6ebeba2ffb..e2fca05395 100644 --- a/Source/Core/VideoCommon/Src/TextureCacheBase.cpp +++ b/Source/Core/VideoCommon/Src/TextureCacheBase.cpp @@ -33,13 +33,13 @@ extern int frameCount; enum { - TEMP_SIZE = (2048 * 2048 * 4), TEXTURE_KILL_THRESHOLD = 200, }; TextureCache *g_texture_cache; GC_ALIGNED16(u8 *TextureCache::temp) = NULL; +unsigned int TextureCache::temp_size; TextureCache::TexCache TextureCache::textures; bool TextureCache::DeferredInvalidate; @@ -50,8 +50,9 @@ TextureCache::TCacheEntryBase::~TCacheEntryBase() TextureCache::TextureCache() { + temp_size = 2048 * 2048 * 4; if (!temp) - temp = (u8*)AllocateAlignedMemory(TEMP_SIZE,16); + temp = (u8*)AllocateAlignedMemory(temp_size, 16); TexDecoder_SetTexFmtOverlayOptions(g_ActiveConfig.bTexFmtOverlayEnable, g_ActiveConfig.bTexFmtOverlayCenter); if(g_ActiveConfig.bHiresTextures && !g_ActiveConfig.bDumpTextures) HiresTextures::Init(SConfig::GetInstance().m_LocalCoreStartupParameter.m_strUniqueID.c_str()); @@ -200,7 +201,7 @@ bool TextureCache::CheckForCustomTextureLODs(u64 tex_hash, int texformat, unsign return true; } -PC_TexFormat TextureCache::LoadCustomTexture(u64 tex_hash, int texformat, unsigned int level, unsigned int& width, unsigned int& height, u8* dest) +PC_TexFormat TextureCache::LoadCustomTexture(u64 tex_hash, int texformat, unsigned int level, unsigned int& width, unsigned int& height) { char texPathTemp[MAX_PATH]; unsigned int newWidth = 0; @@ -211,7 +212,17 @@ PC_TexFormat TextureCache::LoadCustomTexture(u64 tex_hash, int texformat, unsign else sprintf(texPathTemp, "%s_%08x_%i_mip%i", SConfig::GetInstance().m_LocalCoreStartupParameter.m_strUniqueID.c_str(), (u32) (tex_hash & 0x00000000FFFFFFFFLL), texformat, level); - PC_TexFormat ret = HiresTextures::GetHiresTex(texPathTemp, &newWidth, &newHeight, texformat, dest); + unsigned int required_size = 0; + PC_TexFormat ret = HiresTextures::GetHiresTex(texPathTemp, &newWidth, &newHeight, &required_size, texformat, temp_size, temp); + if (ret == PC_TEX_FMT_NONE && temp_size < required_size) + { + // Allocate more memory and try again + // TODO: Should probably check if newWidth and newHeight are texture dimensions which are actually supported by the current video backend + temp_size = required_size; + FreeAlignedMemory(temp); + temp = (u8*)AllocateAlignedMemory(temp_size, 16); + ret = HiresTextures::GetHiresTex(texPathTemp, &newWidth, &newHeight, &required_size, texformat, temp_size, temp); + } if (ret != PC_TEX_FMT_NONE) { @@ -350,7 +361,7 @@ TextureCache::TCacheEntryBase* TextureCache::Load(unsigned int stage, if (g_ActiveConfig.bHiresTextures) { - pcfmt = LoadCustomTexture(tex_hash, texformat, 0, width, height, temp); + pcfmt = LoadCustomTexture(tex_hash, texformat, 0, width, height); if (pcfmt != PC_TEX_FMT_NONE) { expandedWidth = width; @@ -452,7 +463,7 @@ TextureCache::TCacheEntryBase* TextureCache::Load(unsigned int stage, unsigned int currentWidth = (mipWidth > 0) ? mipWidth : 1; unsigned int currentHeight = (mipHeight > 0) ? mipHeight : 1; - LoadCustomTexture(tex_hash, texformat, level, currentWidth, currentHeight, temp); + LoadCustomTexture(tex_hash, texformat, level, currentWidth, currentHeight); entry->Load(currentWidth, currentHeight, currentWidth, level, false); mipWidth >>= 1; -- cgit v1.2.3