diff --git a/plugins/GSdx/GSDevice.cpp b/plugins/GSdx/GSDevice.cpp index c88a242a04..94c2066fab 100644 --- a/plugins/GSdx/GSDevice.cpp +++ b/plugins/GSdx/GSDevice.cpp @@ -202,6 +202,17 @@ void GSDevice::AgePool() } } +void GSDevice::PurgePool() +{ + // OOM emergency. Let's free this useless pool + while(m_pool.size() > 0) + { + delete m_pool.back(); + + m_pool.pop_back(); + } +} + GSTexture* GSDevice::CreateRenderTarget(int w, int h, bool msaa, int format) { return FetchSurface(GSTexture::RenderTarget, w, h, msaa, format); diff --git a/plugins/GSdx/GSDevice.h b/plugins/GSdx/GSDevice.h index 186d88b751..974cdbfda4 100644 --- a/plugins/GSdx/GSDevice.h +++ b/plugins/GSdx/GSDevice.h @@ -194,6 +194,7 @@ public: bool IsRBSwapped() {return m_rbswapped;} void AgePool(); + void PurgePool(); virtual void PrintMemoryUsage(); }; diff --git a/plugins/GSdx/GSRenderer.cpp b/plugins/GSdx/GSRenderer.cpp index 5e3d1d3007..11323a1edd 100644 --- a/plugins/GSdx/GSRenderer.cpp +++ b/plugins/GSdx/GSRenderer.cpp @@ -645,3 +645,8 @@ void GSRenderer::KeyEvent(GSKeyEventData* e) } #endif } + +void GSRenderer::PurgePool() +{ + m_dev->PurgePool(); +} diff --git a/plugins/GSdx/GSRenderer.h b/plugins/GSdx/GSRenderer.h index 671f014802..78309b2d40 100644 --- a/plugins/GSdx/GSRenderer.h +++ b/plugins/GSdx/GSRenderer.h @@ -79,6 +79,8 @@ public: virtual bool BeginCapture(); virtual void EndCapture(); + void PurgePool(); + public: std::mutex m_pGSsetTitle_Crit; diff --git a/plugins/GSdx/GSState.cpp b/plugins/GSdx/GSState.cpp index 64105dd982..bdc80a04d0 100644 --- a/plugins/GSdx/GSState.cpp +++ b/plugins/GSdx/GSState.cpp @@ -1475,7 +1475,15 @@ void GSState::FlushPrim() m_vt.Update(m_vertex.buff, m_index.buff, m_index.tail, GSUtil::GetPrimClass(PRIM->PRIM)); - Draw(); + try { + Draw(); + } catch (GSDXRecoverableError&) { + // could be an unsupported draw call + } catch (GSDXErrorOOM&) { + // Texture Out Of Memory + PurgePool(); + fprintf(stderr, "GSDX OUT OF MEMORY\n"); + } m_perfmon.Put(GSPerfMon::Draw, 1); m_perfmon.Put(GSPerfMon::Prim, m_index.tail / GSUtil::GetVertexCount(PRIM->PRIM)); diff --git a/plugins/GSdx/GSState.h b/plugins/GSdx/GSState.h index 05593451c3..ffe74645d6 100644 --- a/plugins/GSdx/GSState.h +++ b/plugins/GSdx/GSState.h @@ -249,6 +249,7 @@ public: virtual void FlushPrim(); virtual void FlushWrite(); virtual void Draw() = 0; + virtual void PurgePool() = 0; virtual void InvalidateVideoMem(const GIFRegBITBLTBUF& BITBLTBUF, const GSVector4i& r) {} virtual void InvalidateLocalMem(const GIFRegBITBLTBUF& BITBLTBUF, const GSVector4i& r, bool clut = false) {} diff --git a/plugins/GSdx/GSdx.h b/plugins/GSdx/GSdx.h index 5ea4201c4c..6ddaf2cb9e 100644 --- a/plugins/GSdx/GSdx.h +++ b/plugins/GSdx/GSdx.h @@ -79,5 +79,6 @@ public: struct GSDXError {}; struct GSDXRecoverableError : GSDXError {}; +struct GSDXErrorOOM : GSDXError {}; extern GSdxApp theApp;