Merge pull request #1346 from PCSX2/gsdx-cleanup

Gsdx cleanup
This commit is contained in:
Gregory Hainaut 2016-05-06 12:23:54 +02:00
commit c94fecdadb
18 changed files with 390 additions and 423 deletions

View File

@ -121,8 +121,6 @@ void GSDevice::Present(const GSVector4i& r, int shader)
} }
Flip(); Flip();
GL_POP();
} }
void GSDevice::Present(GSTexture* sTex, GSTexture* dTex, const GSVector4& dRect, int shader) void GSDevice::Present(GSTexture* sTex, GSTexture* dTex, const GSVector4& dRect, int shader)
@ -202,6 +200,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) GSTexture* GSDevice::CreateRenderTarget(int w, int h, bool msaa, int format)
{ {
return FetchSurface(GSTexture::RenderTarget, w, h, msaa, format); return FetchSurface(GSTexture::RenderTarget, w, h, msaa, format);

View File

@ -194,6 +194,7 @@ public:
bool IsRBSwapped() {return m_rbswapped;} bool IsRBSwapped() {return m_rbswapped;}
void AgePool(); void AgePool();
void PurgePool();
virtual void PrintMemoryUsage(); virtual void PrintMemoryUsage();
}; };

View File

@ -523,6 +523,9 @@ GSTexture* GSDevice11::CreateSurface(int type, int w, int h, bool msaa, int form
if(SUCCEEDED(hr)) if(SUCCEEDED(hr))
{ {
t = new GSTexture11(texture); t = new GSTexture11(texture);
if (t == NULL) {
throw GSDXErrorOOM();
}
switch(type) switch(type)
{ {

View File

@ -718,11 +718,17 @@ GSTexture* GSDevice9::CreateSurface(int type, int w, int h, bool msaa, int forma
if(surface) if(surface)
{ {
t = new GSTexture9(surface); t = new GSTexture9(surface);
if (t == NULL) {
throw GSDXErrorOOM();
}
} }
if(texture) if(texture)
{ {
t = new GSTexture9(texture); t = new GSTexture9(texture);
if (t == NULL) {
throw GSDXErrorOOM();
}
} }
if(t) if(t)

View File

@ -133,8 +133,6 @@ GSDeviceOGL::~GSDeviceOGL()
// Must be done after the destruction of all shader/program objects // Must be done after the destruction of all shader/program objects
delete m_shader; delete m_shader;
m_shader = NULL; m_shader = NULL;
GL_POP();
} }
GSTexture* GSDeviceOGL::CreateSurface(int type, int w, int h, bool msaa, int fmt) GSTexture* GSDeviceOGL::CreateSurface(int type, int w, int h, bool msaa, int fmt)
@ -144,6 +142,9 @@ GSTexture* GSDeviceOGL::CreateSurface(int type, int w, int h, bool msaa, int fmt
// A wrapper to call GSTextureOGL, with the different kind of parameter // A wrapper to call GSTextureOGL, with the different kind of parameter
GSTextureOGL* t = NULL; GSTextureOGL* t = NULL;
t = new GSTextureOGL(type, w, h, fmt, m_fbo_read); t = new GSTextureOGL(type, w, h, fmt, m_fbo_read);
if (t == NULL) {
throw GSDXErrorOOM();
}
// NOTE: I'm not sure RenderTarget always need to be cleared. It could be costly for big upscale. // NOTE: I'm not sure RenderTarget always need to be cleared. It could be costly for big upscale.
switch(type) switch(type)
@ -157,7 +158,6 @@ GSTexture* GSDeviceOGL::CreateSurface(int type, int w, int h, bool msaa, int fmt
break; break;
} }
GL_POP();
return t; return t;
} }
@ -197,6 +197,7 @@ bool GSDeviceOGL::Create(GSWnd* wnd)
// **************************************************************** // ****************************************************************
// Various object // Various object
// **************************************************************** // ****************************************************************
{
GL_PUSH("GSDeviceOGL::Various"); GL_PUSH("GSDeviceOGL::Various");
m_shader = new GSShaderOGL(!!theApp.GetConfig("debug_glsl_shader", 0)); m_shader = new GSShaderOGL(!!theApp.GetConfig("debug_glsl_shader", 0));
@ -213,12 +214,12 @@ bool GSDeviceOGL::Create(GSWnd* wnd)
glBindFramebuffer(GL_READ_FRAMEBUFFER, m_fbo_read); glBindFramebuffer(GL_READ_FRAMEBUFFER, m_fbo_read);
glReadBuffer(GL_COLOR_ATTACHMENT0); glReadBuffer(GL_COLOR_ATTACHMENT0);
glBindFramebuffer(GL_READ_FRAMEBUFFER, 0); glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
}
GL_POP();
// **************************************************************** // ****************************************************************
// Vertex buffer state // Vertex buffer state
// **************************************************************** // ****************************************************************
{
GL_PUSH("GSDeviceOGL::Vertex Buffer"); GL_PUSH("GSDeviceOGL::Vertex Buffer");
ASSERT(sizeof(GSVertexPT1) == sizeof(GSVertex)); ASSERT(sizeof(GSVertexPT1) == sizeof(GSVertex));
@ -234,22 +235,25 @@ bool GSDeviceOGL::Create(GSWnd* wnd)
{4 , GL_UNSIGNED_BYTE , GL_TRUE , sizeof(GSVertex) , (const GLvoid*)(28) } , // Only 1 byte is useful but hardware unit only support 4B {4 , GL_UNSIGNED_BYTE , GL_TRUE , sizeof(GSVertex) , (const GLvoid*)(28) } , // Only 1 byte is useful but hardware unit only support 4B
}; };
m_va = new GSVertexBufferStateOGL(il_convert, countof(il_convert)); m_va = new GSVertexBufferStateOGL(il_convert, countof(il_convert));
}
GL_POP();
// **************************************************************** // ****************************************************************
// Pre Generate the different sampler object // Pre Generate the different sampler object
// **************************************************************** // ****************************************************************
{
GL_PUSH("GSDeviceOGL::Sampler"); GL_PUSH("GSDeviceOGL::Sampler");
for (uint32 key = 0; key < countof(m_ps_ss); key++) { for (uint32 key = 0; key < countof(m_ps_ss); key++) {
m_ps_ss[key] = CreateSampler(PSSamplerSelector(key)); m_ps_ss[key] = CreateSampler(PSSamplerSelector(key));
} }
}
GL_POP();
// **************************************************************** // ****************************************************************
// convert // convert
// **************************************************************** // ****************************************************************
GLuint vs = 0;
GLuint ps = 0;
{
GL_PUSH("GSDeviceOGL::Convert"); GL_PUSH("GSDeviceOGL::Convert");
m_convert.cb = new GSUniformBufferOGL(g_convert_index, sizeof(ConvertConstantBuffer)); m_convert.cb = new GSUniformBufferOGL(g_convert_index, sizeof(ConvertConstantBuffer));
@ -258,8 +262,7 @@ bool GSDeviceOGL::Create(GSWnd* wnd)
cb.ScalingFactor = GSVector4i(theApp.GetConfig("upscale_multiplier", 1)); cb.ScalingFactor = GSVector4i(theApp.GetConfig("upscale_multiplier", 1));
m_convert.cb->upload(&cb); m_convert.cb->upload(&cb);
GLuint vs = m_shader->Compile("convert.glsl", "vs_main", GL_VERTEX_SHADER, convert_glsl); vs = m_shader->Compile("convert.glsl", "vs_main", GL_VERTEX_SHADER, convert_glsl);
GLuint ps = 0;
m_convert.vs = vs; m_convert.vs = vs;
for(size_t i = 0; i < countof(m_convert.ps); i++) { for(size_t i = 0; i < countof(m_convert.ps); i++) {
@ -278,12 +281,12 @@ bool GSDeviceOGL::Create(GSWnd* wnd)
m_convert.dss_write = new GSDepthStencilOGL(); m_convert.dss_write = new GSDepthStencilOGL();
m_convert.dss_write->EnableDepth(); m_convert.dss_write->EnableDepth();
m_convert.dss_write->SetDepth(GL_ALWAYS, true); m_convert.dss_write->SetDepth(GL_ALWAYS, true);
}
GL_POP();
// **************************************************************** // ****************************************************************
// merge // merge
// **************************************************************** // ****************************************************************
{
GL_PUSH("GSDeviceOGL::Merge"); GL_PUSH("GSDeviceOGL::Merge");
m_merge_obj.cb = new GSUniformBufferOGL(g_merge_cb_index, sizeof(MergeConstantBuffer)); m_merge_obj.cb = new GSUniformBufferOGL(g_merge_cb_index, sizeof(MergeConstantBuffer));
@ -292,12 +295,12 @@ bool GSDeviceOGL::Create(GSWnd* wnd)
ps = m_shader->Compile("merge.glsl", format("ps_main%d", i), GL_FRAGMENT_SHADER, merge_glsl); ps = m_shader->Compile("merge.glsl", format("ps_main%d", i), GL_FRAGMENT_SHADER, merge_glsl);
m_merge_obj.ps[i] = m_shader->LinkPipeline(vs, 0, ps); m_merge_obj.ps[i] = m_shader->LinkPipeline(vs, 0, ps);
} }
}
GL_POP();
// **************************************************************** // ****************************************************************
// interlace // interlace
// **************************************************************** // ****************************************************************
{
GL_PUSH("GSDeviceOGL::Interlace"); GL_PUSH("GSDeviceOGL::Interlace");
m_interlace.cb = new GSUniformBufferOGL(g_interlace_cb_index, sizeof(InterlaceConstantBuffer)); m_interlace.cb = new GSUniformBufferOGL(g_interlace_cb_index, sizeof(InterlaceConstantBuffer));
@ -306,12 +309,12 @@ bool GSDeviceOGL::Create(GSWnd* wnd)
ps = m_shader->Compile("interlace.glsl", format("ps_main%d", i), GL_FRAGMENT_SHADER, interlace_glsl); ps = m_shader->Compile("interlace.glsl", format("ps_main%d", i), GL_FRAGMENT_SHADER, interlace_glsl);
m_interlace.ps[i] = m_shader->LinkPipeline(vs, 0, ps); m_interlace.ps[i] = m_shader->LinkPipeline(vs, 0, ps);
} }
}
GL_POP();
// **************************************************************** // ****************************************************************
// Shade boost // Shade boost
// **************************************************************** // ****************************************************************
{
GL_PUSH("GSDeviceOGL::Shadeboost"); GL_PUSH("GSDeviceOGL::Shadeboost");
int ShadeBoost_Contrast = theApp.GetConfig("ShadeBoost_Contrast", 50); int ShadeBoost_Contrast = theApp.GetConfig("ShadeBoost_Contrast", 50);
@ -323,12 +326,12 @@ bool GSDeviceOGL::Create(GSWnd* wnd)
ps = m_shader->Compile("shadeboost.glsl", "ps_main", GL_FRAGMENT_SHADER, shadeboost_glsl, shade_macro); ps = m_shader->Compile("shadeboost.glsl", "ps_main", GL_FRAGMENT_SHADER, shadeboost_glsl, shade_macro);
m_shadeboost.ps = m_shader->LinkPipeline(vs, 0, ps); m_shadeboost.ps = m_shader->LinkPipeline(vs, 0, ps);
}
GL_POP();
// **************************************************************** // ****************************************************************
// rasterization configuration // rasterization configuration
// **************************************************************** // ****************************************************************
{
GL_PUSH("GSDeviceOGL::Rasterization"); GL_PUSH("GSDeviceOGL::Rasterization");
#ifdef ONLY_LINES #ifdef ONLY_LINES
@ -341,19 +344,18 @@ bool GSDeviceOGL::Create(GSWnd* wnd)
glEnable(GL_SCISSOR_TEST); glEnable(GL_SCISSOR_TEST);
glDisable(GL_MULTISAMPLE); glDisable(GL_MULTISAMPLE);
glDisable(GL_DITHER); // Honestly I don't know! glDisable(GL_DITHER); // Honestly I don't know!
}
GL_POP();
// **************************************************************** // ****************************************************************
// DATE // DATE
// **************************************************************** // ****************************************************************
{
GL_PUSH("GSDeviceOGL::Date"); GL_PUSH("GSDeviceOGL::Date");
m_date.dss = new GSDepthStencilOGL(); m_date.dss = new GSDepthStencilOGL();
m_date.dss->EnableStencil(); m_date.dss->EnableStencil();
m_date.dss->SetStencil(GL_ALWAYS, GL_REPLACE); m_date.dss->SetStencil(GL_ALWAYS, GL_REPLACE);
}
GL_POP();
// **************************************************************** // ****************************************************************
// Use DX coordinate convention // Use DX coordinate convention
@ -370,15 +372,12 @@ bool GSDeviceOGL::Create(GSWnd* wnd)
// **************************************************************** // ****************************************************************
// HW renderer shader // HW renderer shader
// **************************************************************** // ****************************************************************
GL_PUSH("GSDeviceOGL::CreateTextureFX");
CreateTextureFX(); CreateTextureFX();
GL_POP();
// **************************************************************** // ****************************************************************
// Pbo Pool allocation // Pbo Pool allocation
// **************************************************************** // ****************************************************************
{
GL_PUSH("GSDeviceOGL::PBO"); GL_PUSH("GSDeviceOGL::PBO");
// Mesa seems to use it to compute the row length. In our case, we are // Mesa seems to use it to compute the row length. In our case, we are
@ -387,11 +386,7 @@ bool GSDeviceOGL::Create(GSWnd* wnd)
glPixelStorei(GL_UNPACK_ALIGNMENT, 1); glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
PboPool::Init(); PboPool::Init();
}
GL_POP();
// Done !
GL_POP();
// **************************************************************** // ****************************************************************
// Finish window setup and backbuffer // Finish window setup and backbuffer
@ -414,6 +409,8 @@ bool GSDeviceOGL::Create(GSWnd* wnd)
void GSDeviceOGL::CreateTextureFX() void GSDeviceOGL::CreateTextureFX()
{ {
GL_PUSH("GSDeviceOGL::CreateTextureFX");
m_vs_cb = new GSUniformBufferOGL(g_vs_cb_index, sizeof(VSConstantBuffer)); m_vs_cb = new GSUniformBufferOGL(g_vs_cb_index, sizeof(VSConstantBuffer));
m_ps_cb = new GSUniformBufferOGL(g_ps_cb_index, sizeof(PSConstantBuffer)); m_ps_cb = new GSUniformBufferOGL(g_ps_cb_index, sizeof(PSConstantBuffer));
@ -423,6 +420,7 @@ void GSDeviceOGL::CreateTextureFX()
// Pre compile all Geometry & Vertex Shader // Pre compile all Geometry & Vertex Shader
// It might cost a seconds at startup but it would reduce benchmark pollution // It might cost a seconds at startup but it would reduce benchmark pollution
{
GL_PUSH("Compile GS"); GL_PUSH("Compile GS");
for (uint32 key = 0; key < countof(m_gs); key++) { for (uint32 key = 0; key < countof(m_gs); key++) {
@ -432,17 +430,16 @@ void GSDeviceOGL::CreateTextureFX()
else else
m_gs[key] = CompileGS(GSSelector(key)); m_gs[key] = CompileGS(GSSelector(key));
} }
}
GL_POP(); {
GL_PUSH("Compile VS"); GL_PUSH("Compile VS");
for (uint32 key = 0; key < countof(m_vs); key++) { for (uint32 key = 0; key < countof(m_vs); key++) {
VSSelector sel(key); VSSelector sel(key);
m_vs[key] = CompileVS(sel); m_vs[key] = CompileVS(sel);
} }
}
GL_POP();
// Enable all bits for stencil operations. Technically 1 bit is // Enable all bits for stencil operations. Technically 1 bit is
// enough but buffer is polluted with noise. Clear will be limited // enough but buffer is polluted with noise. Clear will be limited
@ -556,8 +553,6 @@ void GSDeviceOGL::ClearRenderTarget(GSTexture* t, const GSVector4& c)
glEnable(GL_SCISSOR_TEST); glEnable(GL_SCISSOR_TEST);
T->WasCleaned(); T->WasCleaned();
GL_POP();
} }
void GSDeviceOGL::ClearRenderTarget(GSTexture* t, uint32 c) void GSDeviceOGL::ClearRenderTarget(GSTexture* t, uint32 c)
@ -598,8 +593,6 @@ void GSDeviceOGL::ClearRenderTarget_i(GSTexture* t, int32 c)
if (GLState::blend) { if (GLState::blend) {
glEnable(GL_BLEND); glEnable(GL_BLEND);
} }
GL_POP();
} }
void GSDeviceOGL::ClearDepth(GSTexture* t, float c) void GSDeviceOGL::ClearDepth(GSTexture* t, float c)
@ -623,8 +616,6 @@ void GSDeviceOGL::ClearDepth(GSTexture* t, float c)
glDepthMask(false); glDepthMask(false);
} }
glEnable(GL_SCISSOR_TEST); glEnable(GL_SCISSOR_TEST);
GL_POP();
} }
void GSDeviceOGL::ClearStencil(GSTexture* t, uint8 c) void GSDeviceOGL::ClearStencil(GSTexture* t, uint8 c)
@ -642,8 +633,6 @@ void GSDeviceOGL::ClearStencil(GSTexture* t, uint8 c)
GLint color = c; GLint color = c;
glClearBufferiv(GL_STENCIL, 0, &color); glClearBufferiv(GL_STENCIL, 0, &color);
GL_POP();
} }
GLuint GSDeviceOGL::CreateSampler(PSSamplerSelector sel) GLuint GSDeviceOGL::CreateSampler(PSSamplerSelector sel)
@ -683,7 +672,6 @@ GLuint GSDeviceOGL::CreateSampler(bool bilinear, bool tau, bool tav, bool aniso)
if (GLLoader::found_GL_EXT_texture_filter_anisotropic && anisotropy && aniso) if (GLLoader::found_GL_EXT_texture_filter_anisotropic && anisotropy && aniso)
glSamplerParameterf(sampler, GL_TEXTURE_MAX_ANISOTROPY_EXT, (float)anisotropy); glSamplerParameterf(sampler, GL_TEXTURE_MAX_ANISOTROPY_EXT, (float)anisotropy);
GL_POP();
return sampler; return sampler;
} }
@ -1036,8 +1024,6 @@ void GSDeviceOGL::CopyRectConv(GSTexture* sTex, GSTexture* dTex, const GSVector4
glCopyTextureSubImage2D(did, GL_TEX_LEVEL_0, r.x, r.y, r.x, r.y, r.width(), r.height()); glCopyTextureSubImage2D(did, GL_TEX_LEVEL_0, r.x, r.y, r.x, r.y, r.width(), r.height());
glBindFramebuffer(GL_READ_FRAMEBUFFER, 0); glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
GL_POP();
} }
// Copy a sub part of a texture into another // Copy a sub part of a texture into another
@ -1057,8 +1043,6 @@ void GSDeviceOGL::CopyRect(GSTexture* sTex, GSTexture* dTex, const GSVector4i& r
did, GL_TEXTURE_2D, did, GL_TEXTURE_2D,
0, 0, 0, 0, 0, 0, 0, 0,
r.width(), r.height(), 1); r.width(), r.height(), 1);
GL_POP();
} }
void GSDeviceOGL::StretchRect(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect, int shader, bool linear) void GSDeviceOGL::StretchRect(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect, int shader, bool linear)
@ -1172,8 +1156,6 @@ void GSDeviceOGL::StretchRect(GSTexture* sTex, const GSVector4& sRect, GSTexture
// ************************************ // ************************************
EndScene(); EndScene();
GL_POP();
} }
void GSDeviceOGL::DoMerge(GSTexture* sTex[2], GSVector4* sRect, GSTexture* dTex, GSVector4* dRect, bool slbg, bool mmod, const GSVector4& c) void GSDeviceOGL::DoMerge(GSTexture* sTex[2], GSVector4* sRect, GSTexture* dTex, GSVector4* dRect, bool slbg, bool mmod, const GSVector4& c)
@ -1196,8 +1178,6 @@ void GSDeviceOGL::DoMerge(GSTexture* sTex[2], GSVector4* sRect, GSTexture* dTex,
StretchRect(sTex[0], sRect[0], dTex, dRect[0], m_merge_obj.ps[mmod ? 1 : 0], m_MERGE_BLEND); StretchRect(sTex[0], sRect[0], dTex, dRect[0], m_merge_obj.ps[mmod ? 1 : 0], m_MERGE_BLEND);
} }
GL_POP();
} }
void GSDeviceOGL::DoInterlace(GSTexture* sTex, GSTexture* dTex, int shader, bool linear, float yoffset) void GSDeviceOGL::DoInterlace(GSTexture* sTex, GSTexture* dTex, int shader, bool linear, float yoffset)
@ -1220,8 +1200,6 @@ void GSDeviceOGL::DoInterlace(GSTexture* sTex, GSTexture* dTex, int shader, bool
m_interlace.cb->upload(&cb); m_interlace.cb->upload(&cb);
StretchRect(sTex, sRect, dTex, dRect, m_interlace.ps[shader], linear); StretchRect(sTex, sRect, dTex, dRect, m_interlace.ps[shader], linear);
GL_POP();
} }
void GSDeviceOGL::DoFXAA(GSTexture* sTex, GSTexture* dTex) void GSDeviceOGL::DoFXAA(GSTexture* sTex, GSTexture* dTex)
@ -1248,8 +1226,6 @@ void GSDeviceOGL::DoFXAA(GSTexture* sTex, GSTexture* dTex)
GSVector4 dRect(0, 0, s.x, s.y); GSVector4 dRect(0, 0, s.x, s.y);
StretchRect(sTex, sRect, dTex, dRect, m_fxaa.ps, true); StretchRect(sTex, sRect, dTex, dRect, m_fxaa.ps, true);
GL_POP();
} }
void GSDeviceOGL::DoExternalFX(GSTexture* sTex, GSTexture* dTex) void GSDeviceOGL::DoExternalFX(GSTexture* sTex, GSTexture* dTex)
@ -1302,8 +1278,6 @@ void GSDeviceOGL::DoExternalFX(GSTexture* sTex, GSTexture* dTex)
m_shaderfx.cb->upload(&cb); m_shaderfx.cb->upload(&cb);
StretchRect(sTex, sRect, dTex, dRect, m_shaderfx.ps, true); StretchRect(sTex, sRect, dTex, dRect, m_shaderfx.ps, true);
GL_POP();
} }
void GSDeviceOGL::DoShadeBoost(GSTexture* sTex, GSTexture* dTex) void GSDeviceOGL::DoShadeBoost(GSTexture* sTex, GSTexture* dTex)
@ -1318,8 +1292,6 @@ void GSDeviceOGL::DoShadeBoost(GSTexture* sTex, GSTexture* dTex)
GSVector4 dRect(0, 0, s.x, s.y); GSVector4 dRect(0, 0, s.x, s.y);
StretchRect(sTex, sRect, dTex, dRect, m_shadeboost.ps, true); StretchRect(sTex, sRect, dTex, dRect, m_shadeboost.ps, true);
GL_POP();
} }
void GSDeviceOGL::SetupDATE(GSTexture* rt, GSTexture* ds, const GSVertexPT1* vertices, bool datm) void GSDeviceOGL::SetupDATE(GSTexture* rt, GSTexture* ds, const GSVertexPT1* vertices, bool datm)
@ -1360,8 +1332,6 @@ void GSDeviceOGL::SetupDATE(GSTexture* rt, GSTexture* ds, const GSVertexPT1* ver
} }
EndScene(); EndScene();
GL_POP();
} }
void GSDeviceOGL::EndScene() void GSDeviceOGL::EndScene()
@ -1576,7 +1546,6 @@ void GSDeviceOGL::SetupCB(const VSConstantBuffer* vs_cb, const PSConstantBuffer*
if(m_ps_cb_cache.Update(ps_cb)) { if(m_ps_cb_cache.Update(ps_cb)) {
m_ps_cb->upload(ps_cb); m_ps_cb->upload(ps_cb);
} }
GL_POP();
} }
void GSDeviceOGL::SetupPipeline(const VSSelector& vsel, const GSSelector& gsel, const PSSelector& psel) void GSDeviceOGL::SetupPipeline(const VSSelector& vsel, const GSSelector& gsel, const PSSelector& psel)

View File

@ -29,18 +29,6 @@ int s_crc_hack_level = 3;
#define Aggresive (s_crc_hack_level > 3) #define Aggresive (s_crc_hack_level > 3)
#define Dx_only (s_crc_hack_level > 2) #define Dx_only (s_crc_hack_level > 2)
struct GSFrameInfo
{
uint32 FBP;
uint32 FPSM;
uint32 FBMSK;
uint32 TBP0;
uint32 TPSM;
uint32 TZTST;
bool TME;
};
typedef bool (*GetSkipCount)(const GSFrameInfo& fi, int& skip);
CRC::Region g_crc_region = CRC::NoRegion; CRC::Region g_crc_region = CRC::NoRegion;
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -2442,7 +2430,159 @@ bool IsInvokedDynamicCrcHack( GSFrameInfo &fi, int& skip, int region, bool &resu
#endif #endif
bool GSState::IsBadFrame(int& skip, int UserHacks_SkipDraw) void GSState::SetupCrcHack()
{
GetSkipCount lut[CRC::TitleCount];
s_crc_hack_level = theApp.GetConfig("crc_hack_level", 3);
memset(lut, 0, sizeof(lut));
if (s_crc_hack_level > 1) {
lut[CRC::AceCombat4] = GSC_AceCombat4;
lut[CRC::AlpineRacer3] = GSC_AlpineRacer3;
lut[CRC::BlackHawkDown] = GSC_BlackHawkDown;
lut[CRC::BleachBladeBattlers] = GSC_BleachBladeBattlers;
lut[CRC::BurnoutDominator] = GSC_Burnout;
lut[CRC::BurnoutRevenge] = GSC_Burnout;
lut[CRC::BurnoutTakedown] = GSC_Burnout;
lut[CRC::CaptainTsubasa] = GSC_CaptainTsubasa;
lut[CRC::CrashBandicootWoC] = GSC_CrashBandicootWoC;
lut[CRC::DBZBT2] = GSC_DBZBT2;
lut[CRC::DBZBT3] = GSC_DBZBT3;
lut[CRC::DevilMayCry3] = GSC_DevilMayCry3;
lut[CRC::EternalPoison] = GSC_EternalPoison;
lut[CRC::EvangelionJo] = GSC_EvangelionJo;
lut[CRC::FFVIIDoC] = GSC_FFVIIDoC;
lut[CRC::FightingBeautyWulong] = GSC_FightingBeautyWulong;
lut[CRC::FinalFightStreetwise] = GSC_FinalFightStreetwise;
lut[CRC::FrontMission5] = GSC_FrontMission5;
lut[CRC::Genji] = GSC_Genji;
lut[CRC::GetaWayBlackMonday] = GSC_GetaWay;
lut[CRC::GetaWay] = GSC_GetaWay;
lut[CRC::GiTS] = GSC_GiTS;
lut[CRC::GodHand] = GSC_GodHand;
lut[CRC::GTASanAndreas] = GSC_GTASanAndreas;
lut[CRC::HauntingGround] = GSC_HauntingGround;
lut[CRC::HeavyMetalThunder] = GSC_HeavyMetalThunder;
lut[CRC::HummerBadlands] = GSC_HummerBadlands;
lut[CRC::IkkiTousen] = GSC_IkkiTousen;
lut[CRC::KnightsOfTheTemple2] = GSC_KnightsOfTheTemple2;
lut[CRC::Kunoichi] = GSC_Kunoichi;
lut[CRC::LordOfTheRingsThirdAge] = GSC_LordOfTheRingsThirdAge;
lut[CRC::Manhunt2] = GSC_Manhunt2;
lut[CRC::MidnightClub3] = GSC_MidnightClub3;
lut[CRC::NanoBreaker] = GSC_NanoBreaker;
lut[CRC::NarutimateAccel] = GSC_NarutimateAccel;
lut[CRC::Naruto] = GSC_Naruto;
lut[CRC::Oneechanbara2Special] = GSC_Oneechanbara2Special;
lut[CRC::Onimusha3] = GSC_Onimusha3;
lut[CRC::RedDeadRevolver] = GSC_RedDeadRevolver;
lut[CRC::ResidentEvil4] = GSC_ResidentEvil4;
lut[CRC::SacredBlaze] = GSC_SacredBlaze;
lut[CRC::SakuraTaisen] = GSC_SakuraTaisen;
lut[CRC::SakuraWarsSoLongMyLove] = GSC_SakuraWarsSoLongMyLove;
lut[CRC::SengokuBasara] = GSC_SengokuBasara;
lut[CRC::ShadowofRome] = GSC_ShadowofRome;
lut[CRC::ShinOnimusha] = GSC_ShinOnimusha;
lut[CRC::Simple2000Vol114] = GSC_Simple2000Vol114;
lut[CRC::SoulCalibur2] = GSC_SoulCalibur2;
lut[CRC::SoulCalibur3] = GSC_SoulCalibur3;
lut[CRC::Spartan] = GSC_Spartan;
lut[CRC::StarWarsForceUnleashed] = GSC_StarWarsForceUnleashed;
lut[CRC::SteambotChronicles] = GSC_SteambotChronicles;
lut[CRC::TalesOfAbyss] = GSC_TalesOfAbyss;
lut[CRC::TalesOfLegendia] = GSC_TalesOfLegendia;
lut[CRC::TalesofSymphonia] = GSC_TalesofSymphonia;
lut[CRC::Tekken5] = GSC_Tekken5;
lut[CRC::TimeSplitters2] = GSC_TimeSplitters2;
lut[CRC::TombRaiderAnniversary] = GSC_TombRaider;
lut[CRC::TombRaiderLegend] = GSC_TombRaiderLegend;
lut[CRC::TombRaiderUnderworld] = GSC_TombRaiderUnderWorld;
lut[CRC::UltramanFightingEvolution] = GSC_UltramanFightingEvolution;
lut[CRC::UrbanReign] = GSC_UrbanReign;
lut[CRC::WildArms4] = GSC_WildArms4;
lut[CRC::WildArms5] = GSC_WildArms5;
lut[CRC::Yakuza2] = GSC_Yakuza2;
lut[CRC::Yakuza] = GSC_Yakuza;
lut[CRC::ZettaiZetsumeiToshi2] = GSC_ZettaiZetsumeiToshi2;
// Only Aggresive
lut[CRC::FFX2] = GSC_FFX2;
lut[CRC::FFX] = GSC_FFX;
lut[CRC::FFXII] = GSC_FFXII;
lut[CRC::SMTDDS1] = GSC_SMTNocturneDDS<0x203BA820>;
lut[CRC::SMTDDS2] = GSC_SMTNocturneDDS<0x20435BF0>;
lut[CRC::SMTNocturne] = GSC_SMTNocturneDDS<0x2054E870>;
lut[CRC::SoTC] = GSC_SoTC;
lut[CRC::SSX3] = GSC_SSX3;
}
// Hack that were fixed on openGL
if (Dx_only) {
// Depth
lut[CRC::Bully] = GSC_Bully;
lut[CRC::BullyCC] = GSC_BullyCC;
lut[CRC::GodOfWar2] = GSC_GodOfWar2;
lut[CRC::ICO] = GSC_ICO;
lut[CRC::LordOfTheRingsTwoTowers] = GSC_LordOfTheRingsTwoTowers;
lut[CRC::Okami] = GSC_Okami;
lut[CRC::SimpsonsGame] = GSC_SimpsonsGame;
lut[CRC::SuikodenTactics] = GSC_SuikodenTactics;
lut[CRC::XE3] = GSC_XE3;
// Not tested but must be fixed with texture shuffle
lut[CRC::BigMuthaTruckers] = GSC_BigMuthaTruckers;
lut[CRC::DemonStone] = GSC_DemonStone;
lut[CRC::CrashNburn] = GSC_CrashNburn; // seem to be a basic depth effect
lut[CRC::LegoBatman] = GSC_LegoBatman;
lut[CRC::OnePieceGrandAdventure] = GSC_OnePieceGrandAdventure;
lut[CRC::OnePieceGrandBattle] = GSC_OnePieceGrandBattle;
lut[CRC::SFEX3] = GSC_SFEX3;
lut[CRC::SpyroEternalNight] = GSC_SpyroEternalNight;
lut[CRC::SpyroNewBeginning] = GSC_SpyroNewBeginning;
lut[CRC::SonicUnleashed] = GSC_SonicUnleashed;
lut[CRC::TenchuFS] = GSC_Tenchu;
lut[CRC::TenchuWoH] = GSC_Tenchu;
// Those games might requires accurate fbmask
lut[CRC::Sly2] = GSC_Sly2;
lut[CRC::Sly3] = GSC_Sly3;
// Those games require accurate_colclip (perf)
lut[CRC::CastlevaniaCoD] = GSC_Castlevania;
lut[CRC::CastlevaniaLoI] = GSC_Castlevania;
lut[CRC::GodOfWar] = GSC_GodOfWar;
// Those games emulate a stencil buffer with the alpha channel of the RT (Slow)
lut[CRC::RadiataStories] = GSC_RadiataStories;
lut[CRC::StarOcean3] = GSC_StarOcean3;
lut[CRC::ValkyrieProfile2] = GSC_ValkyrieProfile2;
// Deprecated hack could be removed (Cutie)
lut[CRC::Grandia3] = GSC_Grandia3;
// At least a part of the CRC is fixed with texture shuffle.
// The status of post-processing effect is unknown
lut[CRC::Black] = GSC_Black;
// Channel Effect
lut[CRC::DeathByDegreesTekkenNinaWilliams] = GSC_DeathByDegreesTekkenNinaWilliams;
lut[CRC::GT3] = GSC_GT3;
lut[CRC::GT4] = GSC_GT4;
lut[CRC::GTConcept] = GSC_GTConcept;
lut[CRC::JamesBondEverythingOrNothing] = GSC_JamesBondEverythingOrNothing;
lut[CRC::MetalGearSolid3] = GSC_MetalGearSolid3; // + accurate blending
lut[CRC::SkyGunner] = GSC_SkyGunner;
lut[CRC::StarWarsBattlefront2] = GSC_StarWarsBattlefront2;
lut[CRC::StarWarsBattlefront] = GSC_StarWarsBattlefront;
lut[CRC::TouristTrophy] = GSC_TouristTrophy;
}
m_gsc = lut[m_game.title];
g_crc_region = m_game.region;
}
bool GSState::IsBadFrame()
{ {
GSFrameInfo fi; GSFrameInfo fi;
@ -2454,193 +2594,30 @@ bool GSState::IsBadFrame(int& skip, int UserHacks_SkipDraw)
fi.TPSM = m_context->TEX0.PSM; fi.TPSM = m_context->TEX0.PSM;
fi.TZTST = m_context->TEST.ZTST; fi.TZTST = m_context->TEST.ZTST;
static GetSkipCount map[CRC::TitleCount];
if (!m_crcinited)
{
m_crcinited = true;
s_crc_hack_level = theApp.GetConfig("crc_hack_level", 3);
memset(map, 0, sizeof(map));
if (s_crc_hack_level > 1) {
map[CRC::AceCombat4] = GSC_AceCombat4;
map[CRC::AlpineRacer3] = GSC_AlpineRacer3;
map[CRC::BlackHawkDown] = GSC_BlackHawkDown;
map[CRC::BleachBladeBattlers] = GSC_BleachBladeBattlers;
map[CRC::BurnoutDominator] = GSC_Burnout;
map[CRC::BurnoutRevenge] = GSC_Burnout;
map[CRC::BurnoutTakedown] = GSC_Burnout;
map[CRC::CaptainTsubasa] = GSC_CaptainTsubasa;
map[CRC::CrashBandicootWoC] = GSC_CrashBandicootWoC;
map[CRC::DBZBT2] = GSC_DBZBT2;
map[CRC::DBZBT3] = GSC_DBZBT3;
map[CRC::DevilMayCry3] = GSC_DevilMayCry3;
map[CRC::EternalPoison] = GSC_EternalPoison;
map[CRC::EvangelionJo] = GSC_EvangelionJo;
map[CRC::FFVIIDoC] = GSC_FFVIIDoC;
map[CRC::FightingBeautyWulong] = GSC_FightingBeautyWulong;
map[CRC::FinalFightStreetwise] = GSC_FinalFightStreetwise;
map[CRC::FrontMission5] = GSC_FrontMission5;
map[CRC::Genji] = GSC_Genji;
map[CRC::GetaWayBlackMonday] = GSC_GetaWay;
map[CRC::GetaWay] = GSC_GetaWay;
map[CRC::GiTS] = GSC_GiTS;
map[CRC::GodHand] = GSC_GodHand;
map[CRC::GTASanAndreas] = GSC_GTASanAndreas;
map[CRC::HauntingGround] = GSC_HauntingGround;
map[CRC::HeavyMetalThunder] = GSC_HeavyMetalThunder;
map[CRC::HummerBadlands] = GSC_HummerBadlands;
map[CRC::IkkiTousen] = GSC_IkkiTousen;
map[CRC::KnightsOfTheTemple2] = GSC_KnightsOfTheTemple2;
map[CRC::Kunoichi] = GSC_Kunoichi;
map[CRC::LordOfTheRingsThirdAge] = GSC_LordOfTheRingsThirdAge;
map[CRC::Manhunt2] = GSC_Manhunt2;
map[CRC::MidnightClub3] = GSC_MidnightClub3;
map[CRC::NanoBreaker] = GSC_NanoBreaker;
map[CRC::NarutimateAccel] = GSC_NarutimateAccel;
map[CRC::Naruto] = GSC_Naruto;
map[CRC::Oneechanbara2Special] = GSC_Oneechanbara2Special;
map[CRC::Onimusha3] = GSC_Onimusha3;
map[CRC::RedDeadRevolver] = GSC_RedDeadRevolver;
map[CRC::ResidentEvil4] = GSC_ResidentEvil4;
map[CRC::SacredBlaze] = GSC_SacredBlaze;
map[CRC::SakuraTaisen] = GSC_SakuraTaisen;
map[CRC::SakuraWarsSoLongMyLove] = GSC_SakuraWarsSoLongMyLove;
map[CRC::SengokuBasara] = GSC_SengokuBasara;
map[CRC::ShadowofRome] = GSC_ShadowofRome;
map[CRC::ShinOnimusha] = GSC_ShinOnimusha;
map[CRC::Simple2000Vol114] = GSC_Simple2000Vol114;
map[CRC::SoulCalibur2] = GSC_SoulCalibur2;
map[CRC::SoulCalibur3] = GSC_SoulCalibur3;
map[CRC::Spartan] = GSC_Spartan;
map[CRC::StarWarsForceUnleashed] = GSC_StarWarsForceUnleashed;
map[CRC::SteambotChronicles] = GSC_SteambotChronicles;
map[CRC::TalesOfAbyss] = GSC_TalesOfAbyss;
map[CRC::TalesOfLegendia] = GSC_TalesOfLegendia;
map[CRC::TalesofSymphonia] = GSC_TalesofSymphonia;
map[CRC::Tekken5] = GSC_Tekken5;
map[CRC::TimeSplitters2] = GSC_TimeSplitters2;
map[CRC::TombRaiderAnniversary] = GSC_TombRaider;
map[CRC::TombRaiderLegend] = GSC_TombRaiderLegend;
map[CRC::TombRaiderUnderworld] = GSC_TombRaiderUnderWorld;
map[CRC::UltramanFightingEvolution] = GSC_UltramanFightingEvolution;
map[CRC::UrbanReign] = GSC_UrbanReign;
map[CRC::WildArms4] = GSC_WildArms4;
map[CRC::WildArms5] = GSC_WildArms5;
map[CRC::Yakuza2] = GSC_Yakuza2;
map[CRC::Yakuza] = GSC_Yakuza;
map[CRC::ZettaiZetsumeiToshi2] = GSC_ZettaiZetsumeiToshi2;
// Only Aggresive
map[CRC::FFX2] = GSC_FFX2;
map[CRC::FFX] = GSC_FFX;
map[CRC::FFXII] = GSC_FFXII;
map[CRC::SMTDDS1] = GSC_SMTNocturneDDS<0x203BA820>;
map[CRC::SMTDDS2] = GSC_SMTNocturneDDS<0x20435BF0>;
map[CRC::SMTNocturne] = GSC_SMTNocturneDDS<0x2054E870>;
map[CRC::SoTC] = GSC_SoTC;
map[CRC::SSX3] = GSC_SSX3;
}
// Hack that were fixed on openGL
if (Dx_only) {
// Depth
map[CRC::Bully] = GSC_Bully;
map[CRC::BullyCC] = GSC_BullyCC;
map[CRC::GodOfWar2] = GSC_GodOfWar2;
map[CRC::ICO] = GSC_ICO;
map[CRC::LordOfTheRingsTwoTowers] = GSC_LordOfTheRingsTwoTowers;
map[CRC::Okami] = GSC_Okami;
map[CRC::SimpsonsGame] = GSC_SimpsonsGame;
map[CRC::SuikodenTactics] = GSC_SuikodenTactics;
map[CRC::XE3] = GSC_XE3;
// Not tested but must be fixed with texture shuffle
map[CRC::BigMuthaTruckers] = GSC_BigMuthaTruckers;
map[CRC::DemonStone] = GSC_DemonStone;
map[CRC::CrashNburn] = GSC_CrashNburn; // seem to be a basic depth effect
map[CRC::LegoBatman] = GSC_LegoBatman;
map[CRC::OnePieceGrandAdventure] = GSC_OnePieceGrandAdventure;
map[CRC::OnePieceGrandBattle] = GSC_OnePieceGrandBattle;
map[CRC::SFEX3] = GSC_SFEX3;
map[CRC::SpyroEternalNight] = GSC_SpyroEternalNight;
map[CRC::SpyroNewBeginning] = GSC_SpyroNewBeginning;
map[CRC::SonicUnleashed] = GSC_SonicUnleashed;
map[CRC::TenchuFS] = GSC_Tenchu;
map[CRC::TenchuWoH] = GSC_Tenchu;
// Those games might requires accurate fbmask
map[CRC::Sly2] = GSC_Sly2;
map[CRC::Sly3] = GSC_Sly3;
// Those games require accurate_colclip (perf)
map[CRC::CastlevaniaCoD] = GSC_Castlevania;
map[CRC::CastlevaniaLoI] = GSC_Castlevania;
map[CRC::GodOfWar] = GSC_GodOfWar;
// Those games emulate a stencil buffer with the alpha channel of the RT (Slow)
map[CRC::RadiataStories] = GSC_RadiataStories;
map[CRC::StarOcean3] = GSC_StarOcean3;
map[CRC::ValkyrieProfile2] = GSC_ValkyrieProfile2;
// Deprecated hack could be removed (Cutie)
map[CRC::Grandia3] = GSC_Grandia3;
// At least a part of the CRC is fixed with texture shuffle.
// The status of post-processing effect is unknown
map[CRC::Black] = GSC_Black;
// Channel Effect
map[CRC::DeathByDegreesTekkenNinaWilliams] = GSC_DeathByDegreesTekkenNinaWilliams;
map[CRC::GT3] = GSC_GT3;
map[CRC::GT4] = GSC_GT4;
map[CRC::GTConcept] = GSC_GTConcept;
map[CRC::JamesBondEverythingOrNothing] = GSC_JamesBondEverythingOrNothing;
map[CRC::MetalGearSolid3] = GSC_MetalGearSolid3; // + accurate blending
map[CRC::SkyGunner] = GSC_SkyGunner;
map[CRC::StarWarsBattlefront2] = GSC_StarWarsBattlefront2;
map[CRC::StarWarsBattlefront] = GSC_StarWarsBattlefront;
map[CRC::TouristTrophy] = GSC_TouristTrophy;
}
}
// TODO: just set gsc in SetGameCRC once
GetSkipCount gsc = map[m_game.title];
g_crc_region = m_game.region;
#ifdef ENABLE_DYNAMIC_CRC_HACK #ifdef ENABLE_DYNAMIC_CRC_HACK
bool res=false; if(IsInvokedDynamicCrcHack(fi, skip, g_crc_region, res, m_crc)){ if( !res ) return false; } else bool res=false; if(IsInvokedDynamicCrcHack(fi, m_skip, g_crc_region, res, m_crc)){ if( !res ) return false; } else
#endif #endif
if(gsc && !gsc(fi, skip)) if(m_gsc && !m_gsc(fi, m_skip))
{ {
return false; return false;
} }
if(skip == 0 && (UserHacks_SkipDraw > 0) ) if(m_skip == 0 && (m_userhacks_skipdraw > 0) )
{ {
if(fi.TME) if(fi.TME)
{ {
// depth textures (bully, mgs3s1 intro, Front Mission 5) // depth textures (bully, mgs3s1 intro, Front Mission 5)
if( (fi.TPSM == PSM_PSMZ32 || fi.TPSM == PSM_PSMZ24 || fi.TPSM == PSM_PSMZ16 || fi.TPSM == PSM_PSMZ16S) ||
// General, often problematic post processing // General, often problematic post processing
(GSUtil::HasSharedBits(fi.FBP, fi.FPSM, fi.TBP0, fi.TPSM)) ) if (GSLocalMemory::m_psm[fi.TPSM].depth || GSUtil::HasSharedBits(fi.FBP, fi.FPSM, fi.TBP0, fi.TPSM))
{ {
skip = UserHacks_SkipDraw; m_skip = m_userhacks_skipdraw;
} }
} }
} }
#ifdef ENABLE_OGL_DEBUG
else if (fi.TME) {
if(fi.TPSM == PSM_PSMZ32 || fi.TPSM == PSM_PSMZ24 || fi.TPSM == PSM_PSMZ16 || fi.TPSM == PSM_PSMZ16S)
GL_INS("!!! Depth Texture 0x%x!!!", fi.TPSM);
}
#endif
if(skip > 0) if(m_skip > 0)
{ {
skip--; m_skip--;
return true; return true;
} }

View File

@ -293,8 +293,6 @@ bool GSRenderer::Merge(int field)
} }
} }
GL_POP();
return true; return true;
} }
@ -645,3 +643,8 @@ void GSRenderer::KeyEvent(GSKeyEventData* e)
} }
#endif #endif
} }
void GSRenderer::PurgePool()
{
m_dev->PurgePool();
}

View File

@ -79,6 +79,8 @@ public:
virtual bool BeginCapture(); virtual bool BeginCapture();
virtual void EndCapture(); virtual void EndCapture();
void PurgePool();
public: public:
std::mutex m_pGSsetTitle_Crit; std::mutex m_pGSsetTitle_Crit;

View File

@ -25,7 +25,6 @@
GSRendererHW::GSRendererHW(GSTextureCache* tc) GSRendererHW::GSRendererHW(GSTextureCache* tc)
: m_width(1280) : m_width(1280)
, m_height(1024) , m_height(1024)
, m_skip(0)
, m_reset(false) , m_reset(false)
, m_upscale_multiplier(1) , m_upscale_multiplier(1)
, m_tc(tc) , m_tc(tc)
@ -33,7 +32,6 @@ GSRendererHW::GSRendererHW(GSTextureCache* tc)
, m_double_downscale(false) , m_double_downscale(false)
{ {
m_upscale_multiplier = theApp.GetConfig("upscale_multiplier", 1); m_upscale_multiplier = theApp.GetConfig("upscale_multiplier", 1);
m_userhacks_skipdraw = !!theApp.GetConfig("UserHacks", 0) ? theApp.GetConfig("UserHacks_SkipDraw", 0) : 0;
m_userhacks_align_sprite_X = !!theApp.GetConfig("UserHacks_align_sprite_X", 0) && !!theApp.GetConfig("UserHacks", 0); m_userhacks_align_sprite_X = !!theApp.GetConfig("UserHacks_align_sprite_X", 0) && !!theApp.GetConfig("UserHacks", 0);
m_userhacks_round_sprite_offset = !!theApp.GetConfig("UserHacks", 0) ? theApp.GetConfig("UserHacks_round_sprite_offset", 0) : 0; m_userhacks_round_sprite_offset = !!theApp.GetConfig("UserHacks", 0) ? theApp.GetConfig("UserHacks_round_sprite_offset", 0) : 0;
m_userhacks_disable_gs_mem_clear = theApp.GetConfig("UserHacks_DisableGsMemClear", 0) && theApp.GetConfig("UserHacks", 0); m_userhacks_disable_gs_mem_clear = theApp.GetConfig("UserHacks_DisableGsMemClear", 0) && theApp.GetConfig("UserHacks", 0);
@ -353,7 +351,7 @@ void GSRendererHW::RoundSpriteOffset()
void GSRendererHW::Draw() void GSRendererHW::Draw()
{ {
if(m_dev->IsLost() || GSRenderer::IsBadFrame(m_skip, m_userhacks_skipdraw)) { if(m_dev->IsLost() || IsBadFrame()) {
GL_INS("Warning skipping a draw call (%d)", s_n); GL_INS("Warning skipping a draw call (%d)", s_n);
s_n += 3; // Keep it sync with SW renderer s_n += 3; // Keep it sync with SW renderer
return; return;
@ -385,7 +383,6 @@ void GSRendererHW::Draw()
m_channel_shuffle = draw_sprite_tex && (m_context->TEX0.PSM == PSM_PSMT8) && single_page; m_channel_shuffle = draw_sprite_tex && (m_context->TEX0.PSM == PSM_PSMT8) && single_page;
if (m_channel_shuffle) { if (m_channel_shuffle) {
GL_CACHE("Channel shuffle effect detected SKIP"); GL_CACHE("Channel shuffle effect detected SKIP");
GL_POP();
s_n += 3; // Keep it sync with SW renderer s_n += 3; // Keep it sync with SW renderer
return; return;
} }
@ -415,21 +412,22 @@ void GSRendererHW::Draw()
TEX0.TBW = context->FRAME.FBW; TEX0.TBW = context->FRAME.FBW;
TEX0.PSM = context->FRAME.PSM; TEX0.PSM = context->FRAME.PSM;
GSTextureCache::Target* rt = no_rt ? NULL : m_tc->LookupTarget(TEX0, m_width, m_height, GSTextureCache::RenderTarget, true); GSTextureCache::Target* rt = NULL;
GSTexture* rt_tex = rt ? rt->m_texture : NULL; GSTexture* rt_tex = NULL;
if (!no_rt) {
rt = m_tc->LookupTarget(TEX0, m_width, m_height, GSTextureCache::RenderTarget, true);
rt_tex = rt->m_texture;
}
TEX0.TBP0 = context->ZBUF.Block(); TEX0.TBP0 = context->ZBUF.Block();
TEX0.TBW = context->FRAME.FBW; TEX0.TBW = context->FRAME.FBW;
TEX0.PSM = context->ZBUF.PSM; TEX0.PSM = context->ZBUF.PSM;
GSTextureCache::Target* ds = no_ds ? NULL : m_tc->LookupTarget(TEX0, m_width, m_height, GSTextureCache::DepthStencil, context->DepthWrite()); GSTextureCache::Target* ds = NULL;
GSTexture* ds_tex = ds ? ds->m_texture : NULL; GSTexture* ds_tex = NULL;
if (!no_ds) {
if(!(rt || no_rt) || !(ds || no_ds)) ds = m_tc->LookupTarget(TEX0, m_width, m_height, GSTextureCache::DepthStencil, context->DepthWrite());
{ ds_tex = ds->m_texture;
GL_POP();
ASSERT(0);
return;
} }
GSTextureCache::Source* tex = NULL; GSTextureCache::Source* tex = NULL;
@ -456,11 +454,6 @@ void GSRendererHW::Draw()
tex = tex_psm.depth ? m_tc->LookupDepthSource(context->TEX0, env.TEXA, r) : m_tc->LookupSource(context->TEX0, env.TEXA, r); tex = tex_psm.depth ? m_tc->LookupDepthSource(context->TEX0, env.TEXA, r) : m_tc->LookupSource(context->TEX0, env.TEXA, r);
if(!tex) {
GL_POP();
return;
}
// FIXME: Could be removed on openGL // FIXME: Could be removed on openGL
if(tex_psm.pal > 0) if(tex_psm.pal > 0)
{ {
@ -556,14 +549,12 @@ void GSRendererHW::Draw()
{ {
s_n += 1; // keep counter sync s_n += 1; // keep counter sync
GL_INS("Warning skipping a draw call (%d)", s_n); GL_INS("Warning skipping a draw call (%d)", s_n);
GL_POP();
return; return;
} }
if (!OI_BlitFMV(rt, tex, r)) { if (!OI_BlitFMV(rt, tex, r)) {
s_n += 1; // keep counter sync s_n += 1; // keep counter sync
GL_INS("Warning skipping a draw call (%d)", s_n); GL_INS("Warning skipping a draw call (%d)", s_n);
GL_POP();
return; return;
} }
@ -718,8 +709,6 @@ void GSRendererHW::Draw()
m_tc->Read(rt, r); m_tc->Read(rt, r);
#endif #endif
GL_POP();
} }
// hacks // hacks
@ -951,8 +940,6 @@ bool GSRendererHW::OI_BlitFMV(GSTextureCache::Target* _rt, GSTextureCache::Sourc
m_tc->InvalidateVideoMemSubTarget(_rt); m_tc->InvalidateVideoMemSubTarget(_rt);
GL_POP();
return false; // skip current draw return false; // skip current draw
} }

View File

@ -32,10 +32,8 @@ class GSRendererHW : public GSRenderer
private: private:
int m_width; int m_width;
int m_height; int m_height;
int m_skip;
bool m_reset; bool m_reset;
int m_upscale_multiplier; int m_upscale_multiplier;
int m_userhacks_skipdraw;
bool m_userhacks_align_sprite_X; bool m_userhacks_align_sprite_X;
bool m_userhacks_disable_gs_mem_clear; bool m_userhacks_disable_gs_mem_clear;

View File

@ -124,6 +124,8 @@ void GSRendererOGL::EmulateGS()
void GSRendererOGL::SetupIA() void GSRendererOGL::SetupIA()
{ {
GL_PUSH("IA");
GSDeviceOGL* dev = (GSDeviceOGL*)m_dev; GSDeviceOGL* dev = (GSDeviceOGL*)m_dev;
if (!GLLoader::found_geometry_shader) if (!GLLoader::found_geometry_shader)
@ -615,8 +617,6 @@ void GSRendererOGL::SendDraw(bool require_barrier)
glTextureBarrier(); glTextureBarrier();
dev->DrawIndexedPrimitive(p, count); dev->DrawIndexedPrimitive(p, count);
} }
GL_POP();
} else { } else {
// FIXME: Investigate: a dynamic check to pack as many primitives as possibles // FIXME: Investigate: a dynamic check to pack as many primitives as possibles
// I'm nearly sure GSdx already have this kind of code (maybe we can adapt GSDirtyRect) // I'm nearly sure GSdx already have this kind of code (maybe we can adapt GSDirtyRect)
@ -630,8 +630,6 @@ void GSRendererOGL::SendDraw(bool require_barrier)
glTextureBarrier(); glTextureBarrier();
dev->DrawIndexedPrimitive(p, nb_vertex); dev->DrawIndexedPrimitive(p, nb_vertex);
} }
GL_POP();
} }
} }
@ -1098,9 +1096,7 @@ void GSRendererOGL::DrawPrims(GSTexture* rt, GSTexture* ds, GSTextureCache::Sour
const GSVector4& hacked_scissor = m_channel_shuffle ? GSVector4(0, 0, 1024, 1024) : m_context->scissor.in; const GSVector4& hacked_scissor = m_channel_shuffle ? GSVector4(0, 0, 1024, 1024) : m_context->scissor.in;
GSVector4i scissor = GSVector4i(GSVector4(rtscale).xyxy() * hacked_scissor).rintersect(GSVector4i(rtsize).zwxy()); GSVector4i scissor = GSVector4i(GSVector4(rtscale).xyxy() * hacked_scissor).rintersect(GSVector4i(rtsize).zwxy());
GL_PUSH("IA");
SetupIA(); SetupIA();
GL_POP();
dev->OMSetColorMaskState(om_csel); dev->OMSetColorMaskState(om_csel);
dev->SetupOM(om_dssel); dev->SetupOM(om_dssel);
@ -1134,8 +1130,6 @@ void GSRendererOGL::DrawPrims(GSTexture* rt, GSTexture* ds, GSTextureCache::Sour
// Be sure that first pass is finished ! // Be sure that first pass is finished !
dev->Barrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT); dev->Barrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);
GL_POP();
} }
if (ps_sel.hdr) { if (ps_sel.hdr) {
@ -1211,6 +1205,4 @@ void GSRendererOGL::DrawPrims(GSTexture* rt, GSTexture* ds, GSTextureCache::Sour
dev->Recycle(hdr_rt); dev->Recycle(hdr_rt);
} }
GL_POP();
} }

View File

@ -33,6 +33,8 @@ GSState::GSState()
, m_irq(NULL) , m_irq(NULL)
, m_path3hack(0) , m_path3hack(0)
, m_init_read_fifo_supported(false) , m_init_read_fifo_supported(false)
, m_gsc(NULL)
, m_skip(0)
, m_q(1.0f) , m_q(1.0f)
, m_texflush(true) , m_texflush(true)
, m_vt(this) , m_vt(this)
@ -40,11 +42,11 @@ GSState::GSState()
, m_crc(0) , m_crc(0)
, m_options(0) , m_options(0)
, m_frameskip(0) , m_frameskip(0)
, m_crcinited(false)
{ {
m_nativeres = theApp.GetConfig("upscale_multiplier",1) == 1; m_nativeres = theApp.GetConfig("upscale_multiplier",1) == 1;
m_mipmap = !!theApp.GetConfig("mipmap", 1); m_mipmap = !!theApp.GetConfig("mipmap", 1);
m_NTSC_Saturation = !!theApp.GetConfig("NTSC_Saturation", true); m_NTSC_Saturation = !!theApp.GetConfig("NTSC_Saturation", true);
m_userhacks_skipdraw = !!theApp.GetConfig("UserHacks", 0) ? theApp.GetConfig("UserHacks_SkipDraw", 0) : 0;
s_n = 0; s_n = 0;
s_dump = !!theApp.GetConfig("dump", 0); s_dump = !!theApp.GetConfig("dump", 0);
@ -1473,7 +1475,15 @@ void GSState::FlushPrim()
m_vt.Update(m_vertex.buff, m_index.buff, m_index.tail, GSUtil::GetPrimClass(PRIM->PRIM)); m_vt.Update(m_vertex.buff, m_index.buff, m_index.tail, GSUtil::GetPrimClass(PRIM->PRIM));
try {
Draw(); 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::Draw, 1);
m_perfmon.Put(GSPerfMon::Prim, m_index.tail / GSUtil::GetVertexCount(PRIM->PRIM)); m_perfmon.Put(GSPerfMon::Prim, m_index.tail / GSUtil::GetVertexCount(PRIM->PRIM));
@ -2350,6 +2360,7 @@ void GSState::SetGameCRC(uint32 crc, int options)
m_crc = crc; m_crc = crc;
m_options = options; m_options = options;
m_game = CRC::Lookup(m_crc_hack_level ? crc : 0); m_game = CRC::Lookup(m_crc_hack_level ? crc : 0);
SetupCrcHack();
} }
// //

View File

@ -35,6 +35,19 @@
#include "GSAlignedClass.h" #include "GSAlignedClass.h"
#include "GSDump.h" #include "GSDump.h"
struct GSFrameInfo
{
uint32 FBP;
uint32 FPSM;
uint32 FBMSK;
uint32 TBP0;
uint32 TPSM;
uint32 TZTST;
bool TME;
};
typedef bool (*GetSkipCount)(const GSFrameInfo& fi, int& skip);
class GSState : public GSAlignedClass<32> class GSState : public GSAlignedClass<32>
{ {
// RESTRICT prevents multiple loads of the same part of the register when accessing its bitfields (the compiler is happy to know that memory writes in-between will not go there) // RESTRICT prevents multiple loads of the same part of the register when accessing its bitfields (the compiler is happy to know that memory writes in-between will not go there)
@ -140,11 +153,15 @@ class GSState : public GSAlignedClass<32>
} m_tr; } m_tr;
protected: protected:
bool IsBadFrame(int& skip, int UserHacks_SkipDraw); bool IsBadFrame();
void SetupCrcHack();
int UserHacks_WildHack; int UserHacks_WildHack;
bool isPackedUV_HackFlag; bool isPackedUV_HackFlag;
int m_crc_hack_level; int m_crc_hack_level;
GetSkipCount m_gsc;
int m_skip;
int m_userhacks_skipdraw;
GSVertex m_v; GSVertex m_v;
float m_q; float m_q;
@ -199,7 +216,6 @@ public:
GSDump m_dump; GSDump m_dump;
int m_options; int m_options;
int m_frameskip; int m_frameskip;
bool m_crcinited;
bool m_framelimit; bool m_framelimit;
bool m_NTSC_Saturation; bool m_NTSC_Saturation;
bool m_nativeres; bool m_nativeres;
@ -233,6 +249,7 @@ public:
virtual void FlushPrim(); virtual void FlushPrim();
virtual void FlushWrite(); virtual void FlushWrite();
virtual void Draw() = 0; virtual void Draw() = 0;
virtual void PurgePool() = 0;
virtual void InvalidateVideoMem(const GIFRegBITBLTBUF& BITBLTBUF, const GSVector4i& r) {} virtual void InvalidateVideoMem(const GIFRegBITBLTBUF& BITBLTBUF, const GSVector4i& r) {}
virtual void InvalidateLocalMem(const GIFRegBITBLTBUF& BITBLTBUF, const GSVector4i& r, bool clut = false) {} virtual void InvalidateLocalMem(const GIFRegBITBLTBUF& BITBLTBUF, const GSVector4i& r, bool clut = false) {}

View File

@ -87,7 +87,7 @@ void GSTextureCache::RemoveAll()
GSTextureCache::Source* GSTextureCache::LookupDepthSource(const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA, const GSVector4i& r, bool palette) GSTextureCache::Source* GSTextureCache::LookupDepthSource(const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA, const GSVector4i& r, bool palette)
{ {
if (!CanConvertDepth()) return NULL; if (!CanConvertDepth()) throw GSDXRecoverableError();
const GSLocalMemory::psm_t& psm_s = GSLocalMemory::m_psm[TEX0.PSM]; const GSLocalMemory::psm_t& psm_s = GSLocalMemory::m_psm[TEX0.PSM];
@ -332,11 +332,6 @@ GSTextureCache::Source* GSTextureCache::LookupSource(const GIFRegTEX0& TEX0, con
#endif #endif
src = CreateSource(TEX0, TEXA, dst, half_right); src = CreateSource(TEX0, TEXA, dst, half_right);
if(src == NULL)
{
return NULL;
}
} else { } else {
GL_CACHE("TC: src hit: %d (0x%x, F:0x%x)", GL_CACHE("TC: src hit: %d (0x%x, F:0x%x)",
src->m_texture ? src->m_texture->GetID() : 0, src->m_texture ? src->m_texture->GetID() : 0,
@ -432,9 +427,6 @@ GSTextureCache::Target* GSTextureCache::LookupTarget(const GIFRegTEX0& TEX0, int
dst = CreateTarget(TEX0, w, h, type); dst = CreateTarget(TEX0, w, h, type);
if(dst == NULL)
return NULL;
// In theory new textures contain invalidated data. Still in theory a new target // In theory new textures contain invalidated data. Still in theory a new target
// must contains the content of the GS memory. // must contains the content of the GS memory.
// In practice, TC will wrongly invalidate some RT. For example due to write on the alpha // In practice, TC will wrongly invalidate some RT. For example due to write on the alpha
@ -594,11 +586,6 @@ GSTextureCache::Target* GSTextureCache::LookupTarget(const GIFRegTEX0& TEX0, int
dst = CreateTarget(TEX0, w, h, RenderTarget); dst = CreateTarget(TEX0, w, h, RenderTarget);
if(dst == NULL)
{
return NULL;
}
m_renderer->m_dev->ClearRenderTarget(dst->m_texture, 0); // new frame buffers after reset should be cleared, don't display memory garbage m_renderer->m_dev->ClearRenderTarget(dst->m_texture, 0); // new frame buffers after reset should be cleared, don't display memory garbage
if (m_preload_frame) { if (m_preload_frame) {
@ -1076,6 +1063,7 @@ GSTextureCache::Source* GSTextureCache::CreateSource(const GIFRegTEX0& TEX0, con
{ {
const GSLocalMemory::psm_t& psm = GSLocalMemory::m_psm[TEX0.PSM]; const GSLocalMemory::psm_t& psm = GSLocalMemory::m_psm[TEX0.PSM];
Source* src = new Source(m_renderer, TEX0, TEXA, m_temp); Source* src = new Source(m_renderer, TEX0, TEXA, m_temp);
if (src == NULL) throw GSDXErrorOOM();
int tw = 1 << TEX0.TW; int tw = 1 << TEX0.TW;
int th = 1 << TEX0.TH; int th = 1 << TEX0.TH;
@ -1370,9 +1358,8 @@ GSTextureCache::Source* GSTextureCache::CreateSource(const GIFRegTEX0& TEX0, con
if(src->m_texture == NULL) if(src->m_texture == NULL)
{ {
ASSERT(0);
delete src; delete src;
return NULL; throw GSDXErrorOOM();
} }
if(psm.pal > 0) if(psm.pal > 0)
@ -1388,6 +1375,7 @@ GSTextureCache::Source* GSTextureCache::CreateSource(const GIFRegTEX0& TEX0, con
GSTextureCache::Target* GSTextureCache::CreateTarget(const GIFRegTEX0& TEX0, int w, int h, int type) GSTextureCache::Target* GSTextureCache::CreateTarget(const GIFRegTEX0& TEX0, int w, int h, int type)
{ {
Target* t = new Target(m_renderer, TEX0, m_temp, CanConvertDepth()); Target* t = new Target(m_renderer, TEX0, m_temp, CanConvertDepth());
if (t == NULL) throw GSDXErrorOOM();
// FIXME: initial data should be unswizzled from local mem in Update() if dirty // FIXME: initial data should be unswizzled from local mem in Update() if dirty
@ -1406,9 +1394,8 @@ GSTextureCache::Target* GSTextureCache::CreateTarget(const GIFRegTEX0& TEX0, int
if(t->m_texture == NULL) if(t->m_texture == NULL)
{ {
ASSERT(0);
delete t; delete t;
return NULL; throw GSDXErrorOOM();
} }
m_dst[type].push_front(t); m_dst[type].push_front(t);
@ -1536,7 +1523,7 @@ void GSTextureCache::Source::Update(const GSVector4i& rect)
return; return;
} }
GSVector2i bs = GSLocalMemory::m_psm[m_TEX0.PSM].bs; const GSVector2i& bs = GSLocalMemory::m_psm[m_TEX0.PSM].bs;
int tw = std::max<int>(1 << m_TEX0.TW, bs.x); int tw = std::max<int>(1 << m_TEX0.TW, bs.x);
int th = std::max<int>(1 << m_TEX0.TH, bs.y); int th = std::max<int>(1 << m_TEX0.TH, bs.y);

View File

@ -125,8 +125,6 @@ void GSTextureCacheOGL::Read(Target* t, const GSVector4i& r)
// FIXME invalidate data // FIXME invalidate data
m_renderer->m_dev->Recycle(offscreen); m_renderer->m_dev->Recycle(offscreen);
} }
GL_POP();
} }
void GSTextureCacheOGL::Read(Source* t, const GSVector4i& r) void GSTextureCacheOGL::Read(Source* t, const GSVector4i& r)

View File

@ -343,8 +343,6 @@ bool GSTextureOGL::Update(const GSVector4i& r, const void* data, int pitch)
PboPool::EndTransfer(); PboPool::EndTransfer();
#endif #endif
GL_POP();
return true; return true;
} }
@ -379,7 +377,7 @@ bool GSTextureOGL::Map(GSMap& m, const GSVector4i* _r)
return true; return true;
} else if (m_type == GSTexture::Texture || m_type == GSTexture::RenderTarget) { } else if (m_type == GSTexture::Texture || m_type == GSTexture::RenderTarget) {
GL_PUSH("Upload Texture %d", m_texture_id); // POP is in Unmap GL_PUSH_("Upload Texture %d", m_texture_id); // POP is in Unmap
m_clean = false; m_clean = false;

View File

@ -79,5 +79,6 @@ public:
struct GSDXError {}; struct GSDXError {};
struct GSDXRecoverableError : GSDXError {}; struct GSDXRecoverableError : GSDXError {};
struct GSDXErrorOOM : GSDXError {};
extern GSdxApp theApp; extern GSdxApp theApp;

View File

@ -435,11 +435,19 @@ extern void vmfree(void* ptr, size_t size);
#endif #endif
#if defined(ENABLE_OGL_DEBUG) #if defined(ENABLE_OGL_DEBUG)
#define GL_PUSH(...) do glPushDebugGroup(GL_DEBUG_SOURCE_APPLICATION, 0xBAD, -1, format(__VA_ARGS__).c_str()); while(0); struct GLAutoPop {
~GLAutoPop() {
glPopDebugGroup();
}
};
#define GL_PUSH_(...) do glPushDebugGroup(GL_DEBUG_SOURCE_APPLICATION, 0xBAD, -1, format(__VA_ARGS__).c_str()); while(0);
#define GL_PUSH(...) do glPushDebugGroup(GL_DEBUG_SOURCE_APPLICATION, 0xBAD, -1, format(__VA_ARGS__).c_str()); while(0); GLAutoPop gl_auto_pop;
#define GL_POP() do glPopDebugGroup(); while(0); #define GL_POP() do glPopDebugGroup(); while(0);
#define GL_INS(...) GL_INSERT(GL_DEBUG_TYPE_ERROR, 0xDEAD, GL_DEBUG_SEVERITY_MEDIUM, __VA_ARGS__) #define GL_INS(...) GL_INSERT(GL_DEBUG_TYPE_ERROR, 0xDEAD, GL_DEBUG_SEVERITY_MEDIUM, __VA_ARGS__)
#define GL_PERF(...) GL_INSERT(GL_DEBUG_TYPE_PERFORMANCE, 0xFEE1, GL_DEBUG_SEVERITY_NOTIFICATION, __VA_ARGS__) #define GL_PERF(...) GL_INSERT(GL_DEBUG_TYPE_PERFORMANCE, 0xFEE1, GL_DEBUG_SEVERITY_NOTIFICATION, __VA_ARGS__)
#else #else
#define GL_PUSH_(...) (0);
#define GL_PUSH(...) (0); #define GL_PUSH(...) (0);
#define GL_POP() (0); #define GL_POP() (0);
#define GL_INS(...) (0); #define GL_INS(...) (0);