Fix crash clearing the texture cache on shutdown.

git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@2374 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
hrydgard 2009-02-22 20:21:56 +00:00
parent 16584c83d1
commit 769160dfbd
5 changed files with 35 additions and 44 deletions

View File

@ -472,11 +472,11 @@ void ConfigDialog::AdvancedSettingsChanged(wxCommandEvent& event)
case ID_TEXFMTOVERLAY: case ID_TEXFMTOVERLAY:
g_Config.bTexFmtOverlayEnable = m_TexFmtOverlay->IsChecked(); g_Config.bTexFmtOverlayEnable = m_TexFmtOverlay->IsChecked();
m_TexFmtCenter->Enable(m_TexFmtOverlay->IsChecked()); m_TexFmtCenter->Enable(m_TexFmtOverlay->IsChecked());
TextureMngr::Invalidate(); TextureMngr::Invalidate(false);
break; break;
case ID_TEXFMTCENTER: case ID_TEXFMTCENTER:
g_Config.bTexFmtOverlayCenter = m_TexFmtCenter->IsChecked(); g_Config.bTexFmtOverlayCenter = m_TexFmtCenter->IsChecked();
TextureMngr::Invalidate(); TextureMngr::Invalidate(false);
break; break;
case ID_USEXFB: case ID_USEXFB:
g_Config.bUseXFB = m_UseXFB->IsChecked(); g_Config.bUseXFB = m_UseXFB->IsChecked();

View File

@ -880,9 +880,9 @@ void Renderer::Swap(const TRectangle& rc)
// The picture width // The picture width
PictureWidth = WinWidth / Ratio; PictureWidth = WinWidth / Ratio;
// Move the left of the picture to the middle of the screen // Move the left of the picture to the middle of the screen
FloatXOffset = FloatXOffset + WinWidth / 2.0; FloatXOffset = FloatXOffset + WinWidth / 2.0f;
// Then remove half the picture height to move it to the horizontal center // Then remove half the picture height to move it to the horizontal center
FloatXOffset = FloatXOffset - PictureWidth / 2.0; FloatXOffset = FloatXOffset - PictureWidth / 2.0f;
// -------------------- // --------------------
} }
// The window is to high, we have to limit the height // The window is to high, we have to limit the height
@ -1113,7 +1113,7 @@ void Renderer::SwapBuffers()
// Clean out old stuff from caches // Clean out old stuff from caches
PixelShaderCache::Cleanup(); PixelShaderCache::Cleanup();
TextureMngr::Cleanup(); TextureMngr::ProgressiveCleanup();
frameCount++; frameCount++;

View File

@ -129,19 +129,16 @@ void TextureMngr::TCacheEntry::SetTextureParameters(TexMode0 &newmode)
} }
} }
void TextureMngr::TCacheEntry::Destroy() void TextureMngr::TCacheEntry::Destroy(bool shutdown)
{ {
if (!texture) if (!texture)
return; return;
glDeleteTextures(1, &texture); glDeleteTextures(1, &texture);
if (!isRenderTarget) { if (!isRenderTarget && !shutdown && !g_Config.bSafeTextureCache) {
if (!g_Config.bSafeTextureCache) {
u32 *ptr = (u32*)g_VideoInitialize.pGetMemoryPointer(addr + hashoffset * 4); u32 *ptr = (u32*)g_VideoInitialize.pGetMemoryPointer(addr + hashoffset * 4);
if (*ptr == hash) if (ptr && *ptr == hash)
*ptr = oldpixel; *ptr = oldpixel;
} }
}
texture = 0; texture = 0;
} }
@ -152,20 +149,20 @@ void TextureMngr::Init()
TexDecoder_SetTexFmtOverlayOptions(g_Config.bTexFmtOverlayEnable, g_Config.bTexFmtOverlayCenter); TexDecoder_SetTexFmtOverlayOptions(g_Config.bTexFmtOverlayEnable, g_Config.bTexFmtOverlayCenter);
} }
void TextureMngr::Invalidate() void TextureMngr::Invalidate(bool shutdown)
{ {
TexCache::iterator iter = textures.begin(); for (TexCache::iterator iter = textures.begin(); iter != textures.end(); ++iter)
for (; iter!=textures.end(); iter++) iter->second.Destroy(shutdown);
iter->second.Destroy();
textures.clear(); textures.clear();
TexDecoder_SetTexFmtOverlayOptions(g_Config.bTexFmtOverlayEnable, g_Config.bTexFmtOverlayCenter);
} }
void TextureMngr::Shutdown() void TextureMngr::Shutdown()
{ {
Invalidate(); Invalidate(true);
std::map<u32, DEPTHTARGET>::iterator itdepth = mapDepthTargets.begin(); std::map<u32, DEPTHTARGET>::iterator itdepth = mapDepthTargets.begin();
for (itdepth = mapDepthTargets.begin(); itdepth != mapDepthTargets.end(); ++itdepth) { for (itdepth = mapDepthTargets.begin(); itdepth != mapDepthTargets.end(); ++itdepth)
{
glDeleteRenderbuffersEXT(1, &itdepth->second.targ); glDeleteRenderbuffersEXT(1, &itdepth->second.targ);
} }
mapDepthTargets.clear(); mapDepthTargets.clear();
@ -179,13 +176,15 @@ void TextureMngr::Shutdown()
temp = NULL; temp = NULL;
} }
void TextureMngr::Cleanup() void TextureMngr::ProgressiveCleanup()
{ {
TexCache::iterator iter = textures.begin(); TexCache::iterator iter = textures.begin();
while (iter != textures.end()) { while (iter != textures.end())
if (frameCount > TEXTURE_KILL_THRESHOLD + iter->second.frameCount) { {
if (frameCount > TEXTURE_KILL_THRESHOLD + iter->second.frameCount)
{
if (!iter->second.isRenderTarget) { if (!iter->second.isRenderTarget) {
iter->second.Destroy(); iter->second.Destroy(false);
#ifdef _WIN32 #ifdef _WIN32
iter = textures.erase(iter); iter = textures.erase(iter);
#else #else
@ -193,7 +192,7 @@ void TextureMngr::Cleanup()
#endif #endif
} }
else { else {
iter->second.Destroy(); iter->second.Destroy(false);
#ifdef _WIN32 #ifdef _WIN32
iter = textures.erase(iter); iter = textures.erase(iter);
#else #else
@ -206,7 +205,8 @@ void TextureMngr::Cleanup()
} }
std::map<u32, DEPTHTARGET>::iterator itdepth = mapDepthTargets.begin(); std::map<u32, DEPTHTARGET>::iterator itdepth = mapDepthTargets.begin();
while (itdepth != mapDepthTargets.end()) { while (itdepth != mapDepthTargets.end())
{
if (frameCount > 20 + itdepth->second.framecount) { if (frameCount > 20 + itdepth->second.framecount) {
#ifdef _WIN32 #ifdef _WIN32
itdepth = mapDepthTargets.erase(itdepth); itdepth = mapDepthTargets.erase(itdepth);
@ -218,8 +218,6 @@ void TextureMngr::Cleanup()
} }
} }
//int dbgTexIdx=0;
TextureMngr::TCacheEntry* TextureMngr::Load(int texstage, u32 address, int width, int height, int format, int tlutaddr, int tlutfmt) TextureMngr::TCacheEntry* TextureMngr::Load(int texstage, u32 address, int width, int height, int format, int tlutaddr, int tlutfmt)
{ {
/* notes (about "UNsafe texture cache"): /* notes (about "UNsafe texture cache"):
@ -306,7 +304,7 @@ TextureMngr::TCacheEntry* TextureMngr::Load(int texstage, u32 address, int width
} }
else else
{ {
entry.Destroy(); entry.Destroy(false);
textures.erase(iter); textures.erase(iter);
} }
} }
@ -422,7 +420,6 @@ TextureMngr::TCacheEntry* TextureMngr::Load(int texstage, u32 address, int width
dbgTexIdx++; dbgTexIdx++;
} }
*/ */
//SaveTexture("tex.tga", target, entry.texture, entry.w, entry.h);
return &entry; return &entry;
} }
@ -541,7 +538,7 @@ void TextureMngr::CopyRenderTargetToTexture(u32 address, bool bFromZBuffer, bool
} }
else if (bIsIntensityFmt) { else if (bIsIntensityFmt) {
fConstAdd[0] = fConstAdd[1] = fConstAdd[2] = 16.0f/255.0f; fConstAdd[0] = fConstAdd[1] = fConstAdd[2] = 16.0f/255.0f;
switch(copyfmt) { switch (copyfmt) {
case 0: // I4 case 0: // I4
case 1: // I8 case 1: // I8
case 2: // IA4 case 2: // IA4
@ -730,7 +727,6 @@ void TextureMngr::DisableStage(int stage)
void TextureMngr::ClearRenderTargets() void TextureMngr::ClearRenderTargets()
{ {
TexCache::iterator iter = textures.begin(); for (TexCache::iterator iter = textures.begin(); iter!=textures.end(); iter++)
for (; iter!=textures.end(); iter++)
iter->second.isRenderTarget = false; iter->second.isRenderTarget = false;
} }

View File

@ -49,7 +49,7 @@ public:
bool bHaveMipMaps; bool bHaveMipMaps;
void SetTextureParameters(TexMode0& newmode); void SetTextureParameters(TexMode0& newmode);
void Destroy(); void Destroy(bool shutdown);
void ConvertFromRenderTarget(u32 taddr, int twidth, int theight, int tformat, int tlutaddr, int tlutfmt); void ConvertFromRenderTarget(u32 taddr, int twidth, int theight, int tformat, int tlutaddr, int tlutfmt);
}; };
@ -61,7 +61,7 @@ public:
}; };
private: private:
typedef std::map<u32,TCacheEntry> TexCache; typedef std::map<u32, TCacheEntry> TexCache;
static u8 *temp; static u8 *temp;
static TexCache textures; static TexCache textures;
@ -70,9 +70,9 @@ private:
public: public:
static void Init(); static void Init();
static void Cleanup(); static void ProgressiveCleanup();
static void Shutdown(); static void Shutdown();
static void Invalidate(); static void Invalidate(bool shutdown);
static TCacheEntry* Load(int texstage, u32 address, int width, int height, int format, int tlutaddr, int tlutfmt); static TCacheEntry* Load(int texstage, u32 address, int width, int height, int format, int tlutaddr, int tlutfmt);
static void CopyRenderTargetToTexture(u32 address, bool bFromZBuffer, bool bIsIntensityFmt, u32 copyfmt, bool bScaleByHalf, TRectangle *source); static void CopyRenderTargetToTexture(u32 address, bool bFromZBuffer, bool bIsIntensityFmt, u32 copyfmt, bool bScaleByHalf, TRectangle *source);

View File

@ -255,7 +255,7 @@ void DoState(unsigned char **ptr, int mode) {
OpenGL_MakeCurrent(); OpenGL_MakeCurrent();
#endif #endif
// Clear all caches that touch RAM // Clear all caches that touch RAM
TextureMngr::Invalidate(); TextureMngr::Invalidate(false);
// DisplayListManager::Invalidate(); // DisplayListManager::Invalidate();
VertexLoaderManager::MarkAllDirty(); VertexLoaderManager::MarkAllDirty();
@ -306,12 +306,7 @@ void Shutdown(void)
PixelShaderManager::Shutdown(); PixelShaderManager::Shutdown();
PixelShaderCache::Shutdown(); PixelShaderCache::Shutdown();
VertexManager::Shutdown(); VertexManager::Shutdown();
// This cause some kind of crash, at least in the Release build and with this setup option
// If there wasn't so little explanations and comments in this code I would be more interested
// in trying to fix this function, now I'll just leave it like this, because it works
#ifndef SETUP_FREE_VIDEO_PLUGIN_ON_BOOT
TextureMngr::Shutdown(); TextureMngr::Shutdown();
#endif
OpcodeDecoder_Shutdown(); OpcodeDecoder_Shutdown();
Renderer::Shutdown(); Renderer::Shutdown();
OpenGL_Shutdown(); OpenGL_Shutdown();