summaryrefslogtreecommitdiff
path: root/Source
diff options
context:
space:
mode:
authorNeoBrainX <NeoBrainX@gmail.com>2012-05-12 14:31:38 +0200
committerNeoBrainX <NeoBrainX@gmail.com>2012-05-13 17:42:22 +0200
commit41d37ab0a0e1236d4e5665c3a7206478ffca2a7f (patch)
treee3baaac2407b9a7be60fea9a833c749dcfd88e19 /Source
parenta5e68ab10e2655853e7063ce3c7ce1aa31df9db8 (diff)
TextureCacheBase: Support loading custom mipmaps.
Diffstat (limited to 'Source')
-rw-r--r--Source/Core/VideoCommon/Src/HiresTextures.cpp8
-rw-r--r--Source/Core/VideoCommon/Src/HiresTextures.h3
-rw-r--r--Source/Core/VideoCommon/Src/TextureCacheBase.cpp74
-rw-r--r--Source/Core/VideoCommon/Src/TextureCacheBase.h3
4 files changed, 71 insertions, 17 deletions
diff --git a/Source/Core/VideoCommon/Src/HiresTextures.cpp b/Source/Core/VideoCommon/Src/HiresTextures.cpp
index 50e8a194af..68b2111d4b 100644
--- a/Source/Core/VideoCommon/Src/HiresTextures.cpp
+++ b/Source/Core/VideoCommon/Src/HiresTextures.cpp
@@ -90,7 +90,13 @@ void Init(const char *gameCode)
}
}
-PC_TexFormat GetHiresTex(const char *fileName, unsigned int *pWidth, unsigned int *pHeight, int texformat, u8 *data)
+bool HiresTexExists(const char* filename)
+{
+ std::string key(filename);
+ return textureMap.find(key) != textureMap.end();
+}
+
+PC_TexFormat GetHiresTex(const char *fileName, unsigned int *pWidth, unsigned int *pHeight, unsigned int *required_size, int texformat, unsigned int data_size, u8 *data)
{
std::string key(fileName);
diff --git a/Source/Core/VideoCommon/Src/HiresTextures.h b/Source/Core/VideoCommon/Src/HiresTextures.h
index 409c2cc260..4b0db76fd9 100644
--- a/Source/Core/VideoCommon/Src/HiresTextures.h
+++ b/Source/Core/VideoCommon/Src/HiresTextures.h
@@ -25,7 +25,8 @@
namespace HiresTextures
{
void Init(const char *gameCode);
-PC_TexFormat GetHiresTex(const char *fileName, unsigned int *pWidth, unsigned int *pHeight, int texformat, u8 *data);
+bool HiresTexExists(const char *filename);
+PC_TexFormat GetHiresTex(const char *fileName, unsigned int *pWidth, unsigned int *pHeight, unsigned int *required_size, int texformat, unsigned int data_size, u8 *data);
};
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());
diff --git a/Source/Core/VideoCommon/Src/TextureCacheBase.h b/Source/Core/VideoCommon/Src/TextureCacheBase.h
index a1d1bfb54c..9d29577c9c 100644
--- a/Source/Core/VideoCommon/Src/TextureCacheBase.h
+++ b/Source/Core/VideoCommon/Src/TextureCacheBase.h
@@ -126,7 +126,8 @@ protected:
static GC_ALIGNED16(u8 *temp);
private:
- static PC_TexFormat LoadCustomTexture(u64 tex_hash, int texformat, unsigned int& width, unsigned int& height, u8* dest);
+ static bool CheckForCustomTextureLODs(u64 tex_hash, int texformat, unsigned int levels);
+ static PC_TexFormat LoadCustomTexture(u64 tex_hash, int texformat, unsigned int level, unsigned int& width, unsigned int& height, u8* dest);
static void DumpTexture(TCacheEntryBase* entry, unsigned int level);