From 72e83140f01b247a4fb0ca7a3eb9afc377d994b4 Mon Sep 17 00:00:00 2001 From: NeoBrainX Date: Sun, 13 May 2012 15:38:56 +0200 Subject: [PATCH] TextureCacheBase: Remove the texture size limit for custom textures. Only the GPU restrictions for maximum texture size remain. --- Source/Core/VideoCommon/Src/HiresTextures.cpp | 27 ++++++++++--------- .../Core/VideoCommon/Src/TextureCacheBase.cpp | 23 +++++++++++----- .../Core/VideoCommon/Src/TextureCacheBase.h | 3 ++- 3 files changed, 33 insertions(+), 20 deletions(-) diff --git a/Source/Core/VideoCommon/Src/HiresTextures.cpp b/Source/Core/VideoCommon/Src/HiresTextures.cpp index 68b2111d4b..5a3fb051c3 100644 --- a/Source/Core/VideoCommon/Src/HiresTextures.cpp +++ b/Source/Core/VideoCommon/Src/HiresTextures.cpp @@ -99,7 +99,6 @@ 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) { std::string key(fileName); - if (textureMap.find(key) == textureMap.end()) return PC_TEX_FMT_NONE; @@ -108,23 +107,17 @@ PC_TexFormat GetHiresTex(const char *fileName, unsigned int *pWidth, unsigned in int channels; u8 *temp = SOIL_load_image(textureMap[key].c_str(), &width, &height, &channels, SOIL_LOAD_RGBA); - if (temp == NULL) { ERROR_LOG(VIDEO, "Custom texture %s failed to load", textureMap[key].c_str()); - SOIL_free_image_data(temp); return PC_TEX_FMT_NONE; } - if (width > 2048 || height > 2048) - { - ERROR_LOG(VIDEO, "Custom texture %s is too large (%ix%i); textures can only be 2048 pixels tall and wide", textureMap[key].c_str(), width, height); - SOIL_free_image_data(temp); - return PC_TEX_FMT_NONE; - } + *pWidth = width; + *pHeight = height; int offset = 0; - PC_TexFormat returnTex; + PC_TexFormat returnTex = PC_TEX_FMT_NONE; switch (texformat) { @@ -132,24 +125,32 @@ PC_TexFormat GetHiresTex(const char *fileName, unsigned int *pWidth, unsigned in case GX_TF_I8: case GX_TF_IA4: case GX_TF_IA8: + *required_size = width * height * 8; + if (data_size < *required_size) + goto cleanup; + for (int i = 0; i < width * height * 4; i += 4) { // Rather than use a luminosity function, just use the most intense color for luminance + // TODO(neobrain): Isn't this kind of.. stupid? data[offset++] = *std::max_element(temp+i, temp+i+3); data[offset++] = temp[i+3]; } returnTex = PC_TEX_FMT_IA8; break; default: + *required_size = width * height * 4; + if (data_size < *required_size) + goto cleanup; + memcpy(data, temp, width * height * 4); returnTex = PC_TEX_FMT_RGBA32; break; } - *pWidth = width; - *pHeight = height; - SOIL_free_image_data(temp); INFO_LOG(VIDEO, "loading custom texture from %s", textureMap[key].c_str()); +cleanup: + SOIL_free_image_data(temp); return returnTex; } 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; diff --git a/Source/Core/VideoCommon/Src/TextureCacheBase.h b/Source/Core/VideoCommon/Src/TextureCacheBase.h index 9d29577c9c..f67ad518c5 100644 --- a/Source/Core/VideoCommon/Src/TextureCacheBase.h +++ b/Source/Core/VideoCommon/Src/TextureCacheBase.h @@ -124,10 +124,11 @@ protected: TextureCache(); static GC_ALIGNED16(u8 *temp); + static unsigned int temp_size; private: 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 PC_TexFormat LoadCustomTexture(u64 tex_hash, int texformat, unsigned int level, unsigned int& width, unsigned int& height); static void DumpTexture(TCacheEntryBase* entry, unsigned int level);