summaryrefslogtreecommitdiff
path: root/Source
diff options
context:
space:
mode:
authorNeoBrainX <NeoBrainX@gmail.com>2012-05-22 08:14:33 +0200
committerNeoBrainX <NeoBrainX@gmail.com>2012-05-22 08:14:49 +0200
commit4131ca8d386eb37533eb2863214bbc76de67e389 (patch)
tree35e15f462a9cb581fb6ccb91f948432470dbf997 /Source
parent1bc5f41e40e604ef6c1d1e84617c13fdf40e04d1 (diff)
parent54aeec7a8ff6b6e5d050637b6cce8df6d9a8b633 (diff)
Merge branch 'hires-tex-improvements'
Diffstat (limited to 'Source')
-rw-r--r--Source/Core/VideoCommon/Src/HiresTextures.cpp35
-rw-r--r--Source/Core/VideoCommon/Src/HiresTextures.h3
-rw-r--r--Source/Core/VideoCommon/Src/TextureCacheBase.cpp154
-rw-r--r--Source/Core/VideoCommon/Src/TextureCacheBase.h8
-rw-r--r--Source/Core/VideoCommon/Src/VertexManagerBase.cpp9
-rw-r--r--Source/Core/VideoCommon/Src/VideoConfig.h1
-rw-r--r--Source/Plugins/Plugin_VideoDX11/Src/TextureCache.cpp10
-rw-r--r--Source/Plugins/Plugin_VideoDX11/Src/TextureCache.h2
-rw-r--r--Source/Plugins/Plugin_VideoDX9/Src/TextureCache.cpp12
-rw-r--r--Source/Plugins/Plugin_VideoDX9/Src/TextureCache.h2
-rw-r--r--Source/Plugins/Plugin_VideoOGL/Src/TextureCache.cpp12
-rw-r--r--Source/Plugins/Plugin_VideoOGL/Src/TextureCache.h4
-rw-r--r--Source/Plugins/Plugin_VideoOGL/Src/VertexManager.cpp9
13 files changed, 179 insertions, 82 deletions
diff --git a/Source/Core/VideoCommon/Src/HiresTextures.cpp b/Source/Core/VideoCommon/Src/HiresTextures.cpp
index 50e8a194af..5a3fb051c3 100644
--- a/Source/Core/VideoCommon/Src/HiresTextures.cpp
+++ b/Source/Core/VideoCommon/Src/HiresTextures.cpp
@@ -90,10 +90,15 @@ 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);
+ 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);
if (textureMap.find(key) == textureMap.end())
return PC_TEX_FMT_NONE;
@@ -102,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)
{
@@ -126,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/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 00ff9610be..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());
@@ -178,6 +179,88 @@ void TextureCache::ClearRenderTargets()
iter->second->type = TCET_NORMAL;
}
+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)
+{
+ char texPathTemp[MAX_PATH];
+ unsigned int newWidth = 0;
+ unsigned int newHeight = 0;
+
+ 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);
+
+ 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)
+ {
+ width = newWidth;
+ height = newHeight;
+ }
+ return ret;
+}
+
+void TextureCache::DumpTexture(TCacheEntryBase* entry, unsigned int level)
+{
+ 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());
+
+ // 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%i.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, 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)
@@ -194,6 +277,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;
@@ -272,21 +358,15 @@ 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, 0, width, height);
if (pcfmt != PC_TEX_FMT_NONE)
{
- expandedWidth = width = newWidth;
- expandedHeight = height = newHeight;
+ expandedWidth = width;
+ expandedHeight = height;
+ using_custom_texture = true;
}
}
@@ -297,13 +377,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) {
@@ -329,8 +408,11 @@ TextureCache::TCacheEntryBase* TextureCache::Load(unsigned int stage,
// load texture
entry->Load(width, height, expandedWidth, 0, (texLevels == 0));
+ 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);
@@ -361,31 +443,33 @@ 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);
+ if (g_ActiveConfig.bDumpTextures)
+ DumpTexture(entry, level);
+
*ptr += ((std::max(mipWidth, bsw) * std::max(mipHeight, bsh) * bsdepth) >> 1);
mipWidth >>= 1;
mipHeight >>= 1;
++level;
}
}
-
- // TODO: won't this cause loaded hires textures to be dumped as well?
- // dump texture to file
- if (g_ActiveConfig.bDumpTextures)
+ else if (texLevels > 1 && pcfmt != PC_TEX_FMT_NONE && using_custom_lods)
{
- char szTemp[MAX_PATH];
- std::string szDir = File::GetUserPath(D_DUMPTEXTURES_IDX) +
- SConfig::GetInstance().m_LocalCoreStartupParameter.m_strUniqueID;
+ unsigned int level = 1;
+ unsigned int mipWidth = (width + 1) >> 1;
+ unsigned int mipHeight = (height + 1) >> 1;
- // make sure that the directory exists
- if (false == File::Exists(szDir) || false == File::IsDirectory(szDir))
- File::CreateDir(szDir.c_str());
+ while ((mipHeight || mipWidth) && (level < texLevels))
+ {
+ unsigned int currentWidth = (mipWidth > 0) ? mipWidth : 1;
+ unsigned int currentHeight = (mipHeight > 0) ? mipHeight : 1;
- sprintf(szTemp, "%s/%s_%08x_%i.png", szDir.c_str(),
- SConfig::GetInstance().m_LocalCoreStartupParameter.m_strUniqueID.c_str(),
- (u32) (tex_hash & 0x00000000FFFFFFFFLL), texformat);
+ LoadCustomTexture(tex_hash, texformat, level, currentWidth, currentHeight);
+ entry->Load(currentWidth, currentHeight, currentWidth, level, false);
- if (false == File::Exists(szTemp))
- entry->Save(szTemp);
+ mipWidth >>= 1;
+ mipHeight >>= 1;
+ ++level;
+ }
}
INCSTAT(stats.numTexturesCreated);
diff --git a/Source/Core/VideoCommon/Src/TextureCacheBase.h b/Source/Core/VideoCommon/Src/TextureCacheBase.h
index 2924c5871f..f67ad518c5 100644
--- a/Source/Core/VideoCommon/Src/TextureCacheBase.h
+++ b/Source/Core/VideoCommon/Src/TextureCacheBase.h
@@ -84,7 +84,7 @@ public:
virtual ~TCacheEntryBase();
virtual void Bind(unsigned int stage) = 0;
- virtual bool Save(const char filename[]) = 0;
+ 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;
@@ -124,8 +124,14 @@ 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);
+ static void DumpTexture(TCacheEntryBase* entry, unsigned int level);
+
+
typedef std::map<u32, TCacheEntryBase*> TexCache;
static TexCache textures;
diff --git a/Source/Core/VideoCommon/Src/VertexManagerBase.cpp b/Source/Core/VideoCommon/Src/VertexManagerBase.cpp
index 004b0f3cca..d66da30273 100644
--- a/Source/Core/VideoCommon/Src/VertexManagerBase.cpp
+++ b/Source/Core/VideoCommon/Src/VertexManagerBase.cpp
@@ -243,15 +243,6 @@ void VertexManager::Flush()
{
// 0s are probably for no manual wrapping needed.
PixelShaderManager::SetTexDims(i, tentry->nativeW, tentry->nativeH, 0, 0);
-
- // TODO:
- //if (g_ActiveConfig.iLog & CONF_SAVETEXTURES)
- //{
- // // save the textures
- // char strfile[255];
- // sprintf(strfile, "%stex%.3d_%d.tga", File::GetUserPath(D_DUMPFRAMES_IDX).c_str(), g_Config.iSaveTargetId, i);
- // SaveTexture(strfile, GL_TEXTURE_2D, tentry->texture, tentry->w, tentry->h);
- //}
}
else
ERROR_LOG(VIDEO, "error loading texture");
diff --git a/Source/Core/VideoCommon/Src/VideoConfig.h b/Source/Core/VideoCommon/Src/VideoConfig.h
index 7c846676bb..e43aa28981 100644
--- a/Source/Core/VideoCommon/Src/VideoConfig.h
+++ b/Source/Core/VideoCommon/Src/VideoConfig.h
@@ -34,7 +34,6 @@
// Log in two categories, and save three other options in the same byte
#define CONF_LOG 1
#define CONF_PRIMLOG 2
-#define CONF_SAVETEXTURES 4
#define CONF_SAVETARGETS 8
#define CONF_SAVESHADERS 16
diff --git a/Source/Plugins/Plugin_VideoDX11/Src/TextureCache.cpp b/Source/Plugins/Plugin_VideoDX11/Src/TextureCache.cpp
index e59fbd496e..0e43eb013d 100644
--- a/Source/Plugins/Plugin_VideoDX11/Src/TextureCache.cpp
+++ b/Source/Plugins/Plugin_VideoDX11/Src/TextureCache.cpp
@@ -45,8 +45,16 @@ void TextureCache::TCacheEntry::Bind(unsigned int stage)
D3D::context->PSSetShaderResources(stage, 1, &texture->GetSRV());
}
-bool TextureCache::TCacheEntry::Save(const char filename[])
+bool TextureCache::TCacheEntry::Save(const char filename[], unsigned int level)
{
+ // TODO: Somehow implement this (D3DX11 doesn't support dumping individual LODs)
+ static bool warn_once = true;
+ if (level && warn_once)
+ {
+ WARN_LOG(VIDEO, "Dumping individual LOD not supported by D3D11 backend!");
+ warn_once = false;
+ return false;
+ }
return SUCCEEDED(PD3DX11SaveTextureToFileA(D3D::context, texture->GetTex(), D3DX11_IFF_PNG, filename));
}
diff --git a/Source/Plugins/Plugin_VideoDX11/Src/TextureCache.h b/Source/Plugins/Plugin_VideoDX11/Src/TextureCache.h
index 89c0c66447..59d343017c 100644
--- a/Source/Plugins/Plugin_VideoDX11/Src/TextureCache.h
+++ b/Source/Plugins/Plugin_VideoDX11/Src/TextureCache.h
@@ -49,7 +49,7 @@ private:
const float *colmat);
void Bind(unsigned int stage);
- bool Save(const char filename[]);
+ bool Save(const char filename[], unsigned int level);
};
TCacheEntryBase* CreateTexture(unsigned int width, unsigned int height,
diff --git a/Source/Plugins/Plugin_VideoDX9/Src/TextureCache.cpp b/Source/Plugins/Plugin_VideoDX9/Src/TextureCache.cpp
index 2a3f12ddcf..0d31098c17 100644
--- a/Source/Plugins/Plugin_VideoDX9/Src/TextureCache.cpp
+++ b/Source/Plugins/Plugin_VideoDX9/Src/TextureCache.cpp
@@ -58,9 +58,17 @@ void TextureCache::TCacheEntry::Bind(unsigned int stage)
D3D::SetTexture(stage, texture);
}
-bool TextureCache::TCacheEntry::Save(const char filename[])
+bool TextureCache::TCacheEntry::Save(const char filename[], unsigned int level)
{
- return SUCCEEDED(PD3DXSaveTextureToFileA(filename, D3DXIFF_PNG, texture, 0));
+ IDirect3DSurface9* surface;
+ HRESULT hr = texture->GetSurfaceLevel(level, &surface);
+ if (FAILED(hr))
+ return false;
+
+ hr = PD3DXSaveSurfaceToFileA(filename, D3DXIFF_PNG, surface, NULL, NULL);
+ surface->Release();
+
+ return SUCCEEDED(hr);
}
void TextureCache::TCacheEntry::Load(unsigned int width, unsigned int height,
diff --git a/Source/Plugins/Plugin_VideoDX9/Src/TextureCache.h b/Source/Plugins/Plugin_VideoDX9/Src/TextureCache.h
index 6234824c2e..4a7cddd575 100644
--- a/Source/Plugins/Plugin_VideoDX9/Src/TextureCache.h
+++ b/Source/Plugins/Plugin_VideoDX9/Src/TextureCache.h
@@ -52,7 +52,7 @@ private:
const float *colmat);
void Bind(unsigned int stage);
- bool Save(const char filename[]);
+ bool Save(const char filename[], unsigned int level);
};
TCacheEntryBase* CreateTexture(unsigned int width, unsigned int height,
diff --git a/Source/Plugins/Plugin_VideoOGL/Src/TextureCache.cpp b/Source/Plugins/Plugin_VideoOGL/Src/TextureCache.cpp
index f78eb11905..bc1b1f6fc5 100644
--- a/Source/Plugins/Plugin_VideoOGL/Src/TextureCache.cpp
+++ b/Source/Plugins/Plugin_VideoOGL/Src/TextureCache.cpp
@@ -76,11 +76,13 @@ static const GLint c_WrapSettings[4] = {
GL_REPEAT,
};
-bool SaveTexture(const char* filename, u32 textarget, u32 tex, int width, int height)
+bool SaveTexture(const char* filename, u32 textarget, u32 tex, int virtual_width, int virtual_height, unsigned int level)
{
+ int width = std::max(virtual_width >> level, 1);
+ int height = std::max(virtual_height >> level, 1);
std::vector<u32> data(width * height);
glBindTexture(textarget, tex);
- glGetTexImage(textarget, 0, GL_BGRA, GL_UNSIGNED_BYTE, &data[0]);
+ glGetTexImage(textarget, level, GL_BGRA, GL_UNSIGNED_BYTE, &data[0]);
const GLenum err = GL_REPORT_ERROR();
if (GL_NO_ERROR != err)
@@ -119,13 +121,13 @@ void TextureCache::TCacheEntry::Bind(unsigned int stage)
SetTextureParameters(tm0, tm1);
}
-bool TextureCache::TCacheEntry::Save(const char filename[])
+bool TextureCache::TCacheEntry::Save(const char filename[], unsigned int level)
{
// TODO: make ogl dump PNGs
std::string tga_filename(filename);
tga_filename.replace(tga_filename.size() - 3, 3, "tga");
- return SaveTexture(tga_filename.c_str(), GL_TEXTURE_2D, texture, virtual_width, virtual_height);
+ return SaveTexture(tga_filename.c_str(), GL_TEXTURE_2D, texture, virtual_width, virtual_height, level);
}
TextureCache::TCacheEntryBase* TextureCache::CreateTexture(unsigned int width,
@@ -347,7 +349,7 @@ void TextureCache::TCacheEntry::FromRenderTarget(u32 dstAddr, unsigned int dstFo
{
static int count = 0;
SaveTexture(StringFromFormat("%sefb_frame_%i.tga", File::GetUserPath(D_DUMPTEXTURES_IDX).c_str(),
- count++).c_str(), GL_TEXTURE_2D, texture, virtual_width, virtual_height);
+ count++).c_str(), GL_TEXTURE_2D, texture, virtual_width, virtual_height, 0);
}
}
diff --git a/Source/Plugins/Plugin_VideoOGL/Src/TextureCache.h b/Source/Plugins/Plugin_VideoOGL/Src/TextureCache.h
index 866fba33b3..30f44b797d 100644
--- a/Source/Plugins/Plugin_VideoOGL/Src/TextureCache.h
+++ b/Source/Plugins/Plugin_VideoOGL/Src/TextureCache.h
@@ -62,7 +62,7 @@ private:
const float *colmat);
void Bind(unsigned int stage);
- bool Save(const char filename[]);
+ bool Save(const char filename[], unsigned int level);
private:
void SetTextureParameters(const TexMode0 &newmode, const TexMode1 &newmode1);
@@ -76,7 +76,7 @@ private:
TCacheEntryBase* CreateRenderTargetTexture(unsigned int scaled_tex_w, unsigned int scaled_tex_h);
};
-bool SaveTexture(const char* filename, u32 textarget, u32 tex, int width, int height);
+bool SaveTexture(const char* filename, u32 textarget, u32 tex, int virtual_width, int virtual_height, unsigned int level);
}
diff --git a/Source/Plugins/Plugin_VideoOGL/Src/VertexManager.cpp b/Source/Plugins/Plugin_VideoOGL/Src/VertexManager.cpp
index dff7f8299e..7be31e7b07 100644
--- a/Source/Plugins/Plugin_VideoOGL/Src/VertexManager.cpp
+++ b/Source/Plugins/Plugin_VideoOGL/Src/VertexManager.cpp
@@ -162,15 +162,6 @@ void VertexManager::vFlush()
{
// 0s are probably for no manual wrapping needed.
PixelShaderManager::SetTexDims(i, tentry->native_width, tentry->native_height, 0, 0);
-
- if (g_ActiveConfig.iLog & CONF_SAVETEXTURES)
- {
- // save the textures
- char strfile[255];
- sprintf(strfile, "%stex%.3d_%d.tga",
- File::GetUserPath(D_DUMPFRAMES_IDX).c_str(), g_Config.iSaveTargetId, i);
- tentry->Save(strfile);
- }
}
else
ERROR_LOG(VIDEO, "error loading texture");