mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-07-22 13:49:53 -06:00
TextureCacheBase: Support dumping individual mipmaps.
This commit is contained in:
@ -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));
|
||||
}
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
||||
}
|
||||
|
||||
|
@ -163,13 +163,14 @@ void VertexManager::vFlush()
|
||||
// 0s are probably for no manual wrapping needed.
|
||||
PixelShaderManager::SetTexDims(i, tentry->native_width, tentry->native_height, 0, 0);
|
||||
|
||||
// TODO: Dump this code, it's redundant.
|
||||
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);
|
||||
tentry->Save(strfile, 0);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
Reference in New Issue
Block a user