mirror of https://github.com/PCSX2/pcsx2.git
commit
c94fecdadb
|
@ -121,8 +121,6 @@ void GSDevice::Present(const GSVector4i& r, int shader)
|
|||
}
|
||||
|
||||
Flip();
|
||||
|
||||
GL_POP();
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
return FetchSurface(GSTexture::RenderTarget, w, h, msaa, format);
|
||||
|
|
|
@ -194,6 +194,7 @@ public:
|
|||
bool IsRBSwapped() {return m_rbswapped;}
|
||||
|
||||
void AgePool();
|
||||
void PurgePool();
|
||||
|
||||
virtual void PrintMemoryUsage();
|
||||
};
|
||||
|
|
|
@ -523,6 +523,9 @@ GSTexture* GSDevice11::CreateSurface(int type, int w, int h, bool msaa, int form
|
|||
if(SUCCEEDED(hr))
|
||||
{
|
||||
t = new GSTexture11(texture);
|
||||
if (t == NULL) {
|
||||
throw GSDXErrorOOM();
|
||||
}
|
||||
|
||||
switch(type)
|
||||
{
|
||||
|
|
|
@ -718,11 +718,17 @@ GSTexture* GSDevice9::CreateSurface(int type, int w, int h, bool msaa, int forma
|
|||
if(surface)
|
||||
{
|
||||
t = new GSTexture9(surface);
|
||||
if (t == NULL) {
|
||||
throw GSDXErrorOOM();
|
||||
}
|
||||
}
|
||||
|
||||
if(texture)
|
||||
{
|
||||
t = new GSTexture9(texture);
|
||||
if (t == NULL) {
|
||||
throw GSDXErrorOOM();
|
||||
}
|
||||
}
|
||||
|
||||
if(t)
|
||||
|
|
|
@ -133,8 +133,6 @@ GSDeviceOGL::~GSDeviceOGL()
|
|||
// Must be done after the destruction of all shader/program objects
|
||||
delete m_shader;
|
||||
m_shader = NULL;
|
||||
|
||||
GL_POP();
|
||||
}
|
||||
|
||||
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
|
||||
GSTextureOGL* t = NULL;
|
||||
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.
|
||||
switch(type)
|
||||
|
@ -157,7 +158,6 @@ GSTexture* GSDeviceOGL::CreateSurface(int type, int w, int h, bool msaa, int fmt
|
|||
break;
|
||||
}
|
||||
|
||||
GL_POP();
|
||||
return t;
|
||||
}
|
||||
|
||||
|
@ -197,6 +197,7 @@ bool GSDeviceOGL::Create(GSWnd* wnd)
|
|||
// ****************************************************************
|
||||
// Various object
|
||||
// ****************************************************************
|
||||
{
|
||||
GL_PUSH("GSDeviceOGL::Various");
|
||||
|
||||
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);
|
||||
glReadBuffer(GL_COLOR_ATTACHMENT0);
|
||||
glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
|
||||
|
||||
GL_POP();
|
||||
}
|
||||
|
||||
// ****************************************************************
|
||||
// Vertex buffer state
|
||||
// ****************************************************************
|
||||
{
|
||||
GL_PUSH("GSDeviceOGL::Vertex Buffer");
|
||||
|
||||
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
|
||||
};
|
||||
m_va = new GSVertexBufferStateOGL(il_convert, countof(il_convert));
|
||||
}
|
||||
|
||||
GL_POP();
|
||||
// ****************************************************************
|
||||
// Pre Generate the different sampler object
|
||||
// ****************************************************************
|
||||
{
|
||||
GL_PUSH("GSDeviceOGL::Sampler");
|
||||
|
||||
for (uint32 key = 0; key < countof(m_ps_ss); key++) {
|
||||
m_ps_ss[key] = CreateSampler(PSSamplerSelector(key));
|
||||
}
|
||||
|
||||
GL_POP();
|
||||
}
|
||||
|
||||
// ****************************************************************
|
||||
// convert
|
||||
// ****************************************************************
|
||||
GLuint vs = 0;
|
||||
GLuint ps = 0;
|
||||
{
|
||||
GL_PUSH("GSDeviceOGL::Convert");
|
||||
|
||||
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));
|
||||
m_convert.cb->upload(&cb);
|
||||
|
||||
GLuint vs = m_shader->Compile("convert.glsl", "vs_main", GL_VERTEX_SHADER, convert_glsl);
|
||||
GLuint ps = 0;
|
||||
vs = m_shader->Compile("convert.glsl", "vs_main", GL_VERTEX_SHADER, convert_glsl);
|
||||
|
||||
m_convert.vs = vs;
|
||||
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->EnableDepth();
|
||||
m_convert.dss_write->SetDepth(GL_ALWAYS, true);
|
||||
|
||||
GL_POP();
|
||||
}
|
||||
|
||||
// ****************************************************************
|
||||
// merge
|
||||
// ****************************************************************
|
||||
{
|
||||
GL_PUSH("GSDeviceOGL::Merge");
|
||||
|
||||
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);
|
||||
m_merge_obj.ps[i] = m_shader->LinkPipeline(vs, 0, ps);
|
||||
}
|
||||
|
||||
GL_POP();
|
||||
}
|
||||
|
||||
// ****************************************************************
|
||||
// interlace
|
||||
// ****************************************************************
|
||||
{
|
||||
GL_PUSH("GSDeviceOGL::Interlace");
|
||||
|
||||
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);
|
||||
m_interlace.ps[i] = m_shader->LinkPipeline(vs, 0, ps);
|
||||
}
|
||||
|
||||
GL_POP();
|
||||
}
|
||||
|
||||
// ****************************************************************
|
||||
// Shade boost
|
||||
// ****************************************************************
|
||||
{
|
||||
GL_PUSH("GSDeviceOGL::Shadeboost");
|
||||
|
||||
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);
|
||||
m_shadeboost.ps = m_shader->LinkPipeline(vs, 0, ps);
|
||||
|
||||
GL_POP();
|
||||
}
|
||||
|
||||
// ****************************************************************
|
||||
// rasterization configuration
|
||||
// ****************************************************************
|
||||
{
|
||||
GL_PUSH("GSDeviceOGL::Rasterization");
|
||||
|
||||
#ifdef ONLY_LINES
|
||||
|
@ -341,19 +344,18 @@ bool GSDeviceOGL::Create(GSWnd* wnd)
|
|||
glEnable(GL_SCISSOR_TEST);
|
||||
glDisable(GL_MULTISAMPLE);
|
||||
glDisable(GL_DITHER); // Honestly I don't know!
|
||||
|
||||
GL_POP();
|
||||
}
|
||||
|
||||
// ****************************************************************
|
||||
// DATE
|
||||
// ****************************************************************
|
||||
{
|
||||
GL_PUSH("GSDeviceOGL::Date");
|
||||
|
||||
m_date.dss = new GSDepthStencilOGL();
|
||||
m_date.dss->EnableStencil();
|
||||
m_date.dss->SetStencil(GL_ALWAYS, GL_REPLACE);
|
||||
|
||||
GL_POP();
|
||||
}
|
||||
|
||||
// ****************************************************************
|
||||
// Use DX coordinate convention
|
||||
|
@ -370,15 +372,12 @@ bool GSDeviceOGL::Create(GSWnd* wnd)
|
|||
// ****************************************************************
|
||||
// HW renderer shader
|
||||
// ****************************************************************
|
||||
GL_PUSH("GSDeviceOGL::CreateTextureFX");
|
||||
|
||||
CreateTextureFX();
|
||||
|
||||
GL_POP();
|
||||
|
||||
// ****************************************************************
|
||||
// Pbo Pool allocation
|
||||
// ****************************************************************
|
||||
{
|
||||
GL_PUSH("GSDeviceOGL::PBO");
|
||||
|
||||
// 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);
|
||||
|
||||
PboPool::Init();
|
||||
|
||||
GL_POP();
|
||||
|
||||
// Done !
|
||||
GL_POP();
|
||||
}
|
||||
|
||||
// ****************************************************************
|
||||
// Finish window setup and backbuffer
|
||||
|
@ -414,6 +409,8 @@ bool GSDeviceOGL::Create(GSWnd* wnd)
|
|||
|
||||
void GSDeviceOGL::CreateTextureFX()
|
||||
{
|
||||
GL_PUSH("GSDeviceOGL::CreateTextureFX");
|
||||
|
||||
m_vs_cb = new GSUniformBufferOGL(g_vs_cb_index, sizeof(VSConstantBuffer));
|
||||
m_ps_cb = new GSUniformBufferOGL(g_ps_cb_index, sizeof(PSConstantBuffer));
|
||||
|
||||
|
@ -423,6 +420,7 @@ void GSDeviceOGL::CreateTextureFX()
|
|||
|
||||
// Pre compile all Geometry & Vertex Shader
|
||||
// It might cost a seconds at startup but it would reduce benchmark pollution
|
||||
{
|
||||
GL_PUSH("Compile GS");
|
||||
|
||||
for (uint32 key = 0; key < countof(m_gs); key++) {
|
||||
|
@ -432,17 +430,16 @@ void GSDeviceOGL::CreateTextureFX()
|
|||
else
|
||||
m_gs[key] = CompileGS(GSSelector(key));
|
||||
}
|
||||
}
|
||||
|
||||
GL_POP();
|
||||
|
||||
{
|
||||
GL_PUSH("Compile VS");
|
||||
|
||||
for (uint32 key = 0; key < countof(m_vs); key++) {
|
||||
VSSelector sel(key);
|
||||
m_vs[key] = CompileVS(sel);
|
||||
}
|
||||
|
||||
GL_POP();
|
||||
}
|
||||
|
||||
// Enable all bits for stencil operations. Technically 1 bit is
|
||||
// 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);
|
||||
|
||||
T->WasCleaned();
|
||||
|
||||
GL_POP();
|
||||
}
|
||||
|
||||
void GSDeviceOGL::ClearRenderTarget(GSTexture* t, uint32 c)
|
||||
|
@ -598,8 +593,6 @@ void GSDeviceOGL::ClearRenderTarget_i(GSTexture* t, int32 c)
|
|||
if (GLState::blend) {
|
||||
glEnable(GL_BLEND);
|
||||
}
|
||||
|
||||
GL_POP();
|
||||
}
|
||||
|
||||
void GSDeviceOGL::ClearDepth(GSTexture* t, float c)
|
||||
|
@ -623,8 +616,6 @@ void GSDeviceOGL::ClearDepth(GSTexture* t, float c)
|
|||
glDepthMask(false);
|
||||
}
|
||||
glEnable(GL_SCISSOR_TEST);
|
||||
|
||||
GL_POP();
|
||||
}
|
||||
|
||||
void GSDeviceOGL::ClearStencil(GSTexture* t, uint8 c)
|
||||
|
@ -642,8 +633,6 @@ void GSDeviceOGL::ClearStencil(GSTexture* t, uint8 c)
|
|||
GLint color = c;
|
||||
|
||||
glClearBufferiv(GL_STENCIL, 0, &color);
|
||||
|
||||
GL_POP();
|
||||
}
|
||||
|
||||
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)
|
||||
glSamplerParameterf(sampler, GL_TEXTURE_MAX_ANISOTROPY_EXT, (float)anisotropy);
|
||||
|
||||
GL_POP();
|
||||
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());
|
||||
|
||||
glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
|
||||
|
||||
GL_POP();
|
||||
}
|
||||
|
||||
// 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,
|
||||
0, 0, 0, 0,
|
||||
r.width(), r.height(), 1);
|
||||
|
||||
GL_POP();
|
||||
}
|
||||
|
||||
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();
|
||||
|
||||
GL_POP();
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
GL_POP();
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
StretchRect(sTex, sRect, dTex, dRect, m_interlace.ps[shader], linear);
|
||||
|
||||
GL_POP();
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
StretchRect(sTex, sRect, dTex, dRect, m_fxaa.ps, true);
|
||||
|
||||
GL_POP();
|
||||
}
|
||||
|
||||
void GSDeviceOGL::DoExternalFX(GSTexture* sTex, GSTexture* dTex)
|
||||
|
@ -1302,8 +1278,6 @@ void GSDeviceOGL::DoExternalFX(GSTexture* sTex, GSTexture* dTex)
|
|||
m_shaderfx.cb->upload(&cb);
|
||||
|
||||
StretchRect(sTex, sRect, dTex, dRect, m_shaderfx.ps, true);
|
||||
|
||||
GL_POP();
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
StretchRect(sTex, sRect, dTex, dRect, m_shadeboost.ps, true);
|
||||
|
||||
GL_POP();
|
||||
}
|
||||
|
||||
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();
|
||||
|
||||
GL_POP();
|
||||
}
|
||||
|
||||
void GSDeviceOGL::EndScene()
|
||||
|
@ -1576,7 +1546,6 @@ void GSDeviceOGL::SetupCB(const VSConstantBuffer* vs_cb, const PSConstantBuffer*
|
|||
if(m_ps_cb_cache.Update(ps_cb)) {
|
||||
m_ps_cb->upload(ps_cb);
|
||||
}
|
||||
GL_POP();
|
||||
}
|
||||
|
||||
void GSDeviceOGL::SetupPipeline(const VSSelector& vsel, const GSSelector& gsel, const PSSelector& psel)
|
||||
|
|
|
@ -29,18 +29,6 @@ int s_crc_hack_level = 3;
|
|||
#define Aggresive (s_crc_hack_level > 3)
|
||||
#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;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -2442,7 +2430,159 @@ bool IsInvokedDynamicCrcHack( GSFrameInfo &fi, int& skip, int region, bool &resu
|
|||
|
||||
#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;
|
||||
|
||||
|
@ -2454,193 +2594,30 @@ bool GSState::IsBadFrame(int& skip, int UserHacks_SkipDraw)
|
|||
fi.TPSM = m_context->TEX0.PSM;
|
||||
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
|
||||
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
|
||||
if(gsc && !gsc(fi, skip))
|
||||
if(m_gsc && !m_gsc(fi, m_skip))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if(skip == 0 && (UserHacks_SkipDraw > 0) )
|
||||
if(m_skip == 0 && (m_userhacks_skipdraw > 0) )
|
||||
{
|
||||
if(fi.TME)
|
||||
{
|
||||
// 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
|
||||
(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;
|
||||
}
|
||||
|
|
|
@ -293,8 +293,6 @@ bool GSRenderer::Merge(int field)
|
|||
}
|
||||
}
|
||||
|
||||
GL_POP();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -645,3 +643,8 @@ void GSRenderer::KeyEvent(GSKeyEventData* e)
|
|||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void GSRenderer::PurgePool()
|
||||
{
|
||||
m_dev->PurgePool();
|
||||
}
|
||||
|
|
|
@ -79,6 +79,8 @@ public:
|
|||
virtual bool BeginCapture();
|
||||
virtual void EndCapture();
|
||||
|
||||
void PurgePool();
|
||||
|
||||
public:
|
||||
std::mutex m_pGSsetTitle_Crit;
|
||||
|
||||
|
|
|
@ -25,7 +25,6 @@
|
|||
GSRendererHW::GSRendererHW(GSTextureCache* tc)
|
||||
: m_width(1280)
|
||||
, m_height(1024)
|
||||
, m_skip(0)
|
||||
, m_reset(false)
|
||||
, m_upscale_multiplier(1)
|
||||
, m_tc(tc)
|
||||
|
@ -33,7 +32,6 @@ GSRendererHW::GSRendererHW(GSTextureCache* tc)
|
|||
, m_double_downscale(false)
|
||||
{
|
||||
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_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);
|
||||
|
@ -353,7 +351,7 @@ void GSRendererHW::RoundSpriteOffset()
|
|||
|
||||
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);
|
||||
s_n += 3; // Keep it sync with SW renderer
|
||||
return;
|
||||
|
@ -385,7 +383,6 @@ void GSRendererHW::Draw()
|
|||
m_channel_shuffle = draw_sprite_tex && (m_context->TEX0.PSM == PSM_PSMT8) && single_page;
|
||||
if (m_channel_shuffle) {
|
||||
GL_CACHE("Channel shuffle effect detected SKIP");
|
||||
GL_POP();
|
||||
s_n += 3; // Keep it sync with SW renderer
|
||||
return;
|
||||
}
|
||||
|
@ -415,21 +412,22 @@ void GSRendererHW::Draw()
|
|||
TEX0.TBW = context->FRAME.FBW;
|
||||
TEX0.PSM = context->FRAME.PSM;
|
||||
|
||||
GSTextureCache::Target* rt = no_rt ? NULL : m_tc->LookupTarget(TEX0, m_width, m_height, GSTextureCache::RenderTarget, true);
|
||||
GSTexture* rt_tex = rt ? rt->m_texture : NULL;
|
||||
GSTextureCache::Target* rt = 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.TBW = context->FRAME.FBW;
|
||||
TEX0.PSM = context->ZBUF.PSM;
|
||||
|
||||
GSTextureCache::Target* ds = no_ds ? NULL : m_tc->LookupTarget(TEX0, m_width, m_height, GSTextureCache::DepthStencil, context->DepthWrite());
|
||||
GSTexture* ds_tex = ds ? ds->m_texture : NULL;
|
||||
|
||||
if(!(rt || no_rt) || !(ds || no_ds))
|
||||
{
|
||||
GL_POP();
|
||||
ASSERT(0);
|
||||
return;
|
||||
GSTextureCache::Target* ds = NULL;
|
||||
GSTexture* ds_tex = NULL;
|
||||
if (!no_ds) {
|
||||
ds = m_tc->LookupTarget(TEX0, m_width, m_height, GSTextureCache::DepthStencil, context->DepthWrite());
|
||||
ds_tex = ds->m_texture;
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
if(!tex) {
|
||||
GL_POP();
|
||||
return;
|
||||
}
|
||||
|
||||
// FIXME: Could be removed on openGL
|
||||
if(tex_psm.pal > 0)
|
||||
{
|
||||
|
@ -556,14 +549,12 @@ void GSRendererHW::Draw()
|
|||
{
|
||||
s_n += 1; // keep counter sync
|
||||
GL_INS("Warning skipping a draw call (%d)", s_n);
|
||||
GL_POP();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!OI_BlitFMV(rt, tex, r)) {
|
||||
s_n += 1; // keep counter sync
|
||||
GL_INS("Warning skipping a draw call (%d)", s_n);
|
||||
GL_POP();
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -718,8 +709,6 @@ void GSRendererHW::Draw()
|
|||
m_tc->Read(rt, r);
|
||||
|
||||
#endif
|
||||
|
||||
GL_POP();
|
||||
}
|
||||
|
||||
// hacks
|
||||
|
@ -951,8 +940,6 @@ bool GSRendererHW::OI_BlitFMV(GSTextureCache::Target* _rt, GSTextureCache::Sourc
|
|||
|
||||
m_tc->InvalidateVideoMemSubTarget(_rt);
|
||||
|
||||
GL_POP();
|
||||
|
||||
return false; // skip current draw
|
||||
}
|
||||
|
||||
|
|
|
@ -32,10 +32,8 @@ class GSRendererHW : public GSRenderer
|
|||
private:
|
||||
int m_width;
|
||||
int m_height;
|
||||
int m_skip;
|
||||
bool m_reset;
|
||||
int m_upscale_multiplier;
|
||||
int m_userhacks_skipdraw;
|
||||
|
||||
bool m_userhacks_align_sprite_X;
|
||||
bool m_userhacks_disable_gs_mem_clear;
|
||||
|
|
|
@ -124,6 +124,8 @@ void GSRendererOGL::EmulateGS()
|
|||
|
||||
void GSRendererOGL::SetupIA()
|
||||
{
|
||||
GL_PUSH("IA");
|
||||
|
||||
GSDeviceOGL* dev = (GSDeviceOGL*)m_dev;
|
||||
|
||||
if (!GLLoader::found_geometry_shader)
|
||||
|
@ -615,8 +617,6 @@ void GSRendererOGL::SendDraw(bool require_barrier)
|
|||
glTextureBarrier();
|
||||
dev->DrawIndexedPrimitive(p, count);
|
||||
}
|
||||
|
||||
GL_POP();
|
||||
} else {
|
||||
// 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)
|
||||
|
@ -630,8 +630,6 @@ void GSRendererOGL::SendDraw(bool require_barrier)
|
|||
glTextureBarrier();
|
||||
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;
|
||||
GSVector4i scissor = GSVector4i(GSVector4(rtscale).xyxy() * hacked_scissor).rintersect(GSVector4i(rtsize).zwxy());
|
||||
|
||||
GL_PUSH("IA");
|
||||
SetupIA();
|
||||
GL_POP();
|
||||
|
||||
dev->OMSetColorMaskState(om_csel);
|
||||
dev->SetupOM(om_dssel);
|
||||
|
@ -1134,8 +1130,6 @@ void GSRendererOGL::DrawPrims(GSTexture* rt, GSTexture* ds, GSTextureCache::Sour
|
|||
|
||||
// Be sure that first pass is finished !
|
||||
dev->Barrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);
|
||||
|
||||
GL_POP();
|
||||
}
|
||||
|
||||
if (ps_sel.hdr) {
|
||||
|
@ -1211,6 +1205,4 @@ void GSRendererOGL::DrawPrims(GSTexture* rt, GSTexture* ds, GSTextureCache::Sour
|
|||
|
||||
dev->Recycle(hdr_rt);
|
||||
}
|
||||
|
||||
GL_POP();
|
||||
}
|
||||
|
|
|
@ -33,6 +33,8 @@ GSState::GSState()
|
|||
, m_irq(NULL)
|
||||
, m_path3hack(0)
|
||||
, m_init_read_fifo_supported(false)
|
||||
, m_gsc(NULL)
|
||||
, m_skip(0)
|
||||
, m_q(1.0f)
|
||||
, m_texflush(true)
|
||||
, m_vt(this)
|
||||
|
@ -40,11 +42,11 @@ GSState::GSState()
|
|||
, m_crc(0)
|
||||
, m_options(0)
|
||||
, m_frameskip(0)
|
||||
, m_crcinited(false)
|
||||
{
|
||||
m_nativeres = theApp.GetConfig("upscale_multiplier",1) == 1;
|
||||
m_mipmap = !!theApp.GetConfig("mipmap", 1);
|
||||
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_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));
|
||||
|
||||
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));
|
||||
|
@ -2350,6 +2360,7 @@ void GSState::SetGameCRC(uint32 crc, int options)
|
|||
m_crc = crc;
|
||||
m_options = options;
|
||||
m_game = CRC::Lookup(m_crc_hack_level ? crc : 0);
|
||||
SetupCrcHack();
|
||||
}
|
||||
|
||||
//
|
||||
|
|
|
@ -35,6 +35,19 @@
|
|||
#include "GSAlignedClass.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>
|
||||
{
|
||||
// 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;
|
||||
|
||||
protected:
|
||||
bool IsBadFrame(int& skip, int UserHacks_SkipDraw);
|
||||
bool IsBadFrame();
|
||||
void SetupCrcHack();
|
||||
|
||||
int UserHacks_WildHack;
|
||||
bool isPackedUV_HackFlag;
|
||||
int m_crc_hack_level;
|
||||
GetSkipCount m_gsc;
|
||||
int m_skip;
|
||||
int m_userhacks_skipdraw;
|
||||
|
||||
GSVertex m_v;
|
||||
float m_q;
|
||||
|
@ -199,7 +216,6 @@ public:
|
|||
GSDump m_dump;
|
||||
int m_options;
|
||||
int m_frameskip;
|
||||
bool m_crcinited;
|
||||
bool m_framelimit;
|
||||
bool m_NTSC_Saturation;
|
||||
bool m_nativeres;
|
||||
|
@ -233,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) {}
|
||||
|
||||
|
|
|
@ -87,7 +87,7 @@ void GSTextureCache::RemoveAll()
|
|||
|
||||
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];
|
||||
|
||||
|
@ -332,11 +332,6 @@ GSTextureCache::Source* GSTextureCache::LookupSource(const GIFRegTEX0& TEX0, con
|
|||
#endif
|
||||
src = CreateSource(TEX0, TEXA, dst, half_right);
|
||||
|
||||
if(src == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
} else {
|
||||
GL_CACHE("TC: src hit: %d (0x%x, F:0x%x)",
|
||||
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);
|
||||
|
||||
if(dst == NULL)
|
||||
return NULL;
|
||||
|
||||
// In theory new textures contain invalidated data. Still in theory a new target
|
||||
// must contains the content of the GS memory.
|
||||
// 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);
|
||||
|
||||
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
|
||||
|
||||
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];
|
||||
Source* src = new Source(m_renderer, TEX0, TEXA, m_temp);
|
||||
if (src == NULL) throw GSDXErrorOOM();
|
||||
|
||||
int tw = 1 << TEX0.TW;
|
||||
int th = 1 << TEX0.TH;
|
||||
|
@ -1370,9 +1358,8 @@ GSTextureCache::Source* GSTextureCache::CreateSource(const GIFRegTEX0& TEX0, con
|
|||
|
||||
if(src->m_texture == NULL)
|
||||
{
|
||||
ASSERT(0);
|
||||
delete src;
|
||||
return NULL;
|
||||
throw GSDXErrorOOM();
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
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
|
||||
|
||||
|
@ -1406,9 +1394,8 @@ GSTextureCache::Target* GSTextureCache::CreateTarget(const GIFRegTEX0& TEX0, int
|
|||
|
||||
if(t->m_texture == NULL)
|
||||
{
|
||||
ASSERT(0);
|
||||
delete t;
|
||||
return NULL;
|
||||
throw GSDXErrorOOM();
|
||||
}
|
||||
|
||||
m_dst[type].push_front(t);
|
||||
|
@ -1536,7 +1523,7 @@ void GSTextureCache::Source::Update(const GSVector4i& rect)
|
|||
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 th = std::max<int>(1 << m_TEX0.TH, bs.y);
|
||||
|
|
|
@ -125,8 +125,6 @@ void GSTextureCacheOGL::Read(Target* t, const GSVector4i& r)
|
|||
// FIXME invalidate data
|
||||
m_renderer->m_dev->Recycle(offscreen);
|
||||
}
|
||||
|
||||
GL_POP();
|
||||
}
|
||||
|
||||
void GSTextureCacheOGL::Read(Source* t, const GSVector4i& r)
|
||||
|
|
|
@ -343,8 +343,6 @@ bool GSTextureOGL::Update(const GSVector4i& r, const void* data, int pitch)
|
|||
PboPool::EndTransfer();
|
||||
#endif
|
||||
|
||||
GL_POP();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -379,7 +377,7 @@ bool GSTextureOGL::Map(GSMap& m, const GSVector4i* _r)
|
|||
|
||||
return true;
|
||||
} 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;
|
||||
|
||||
|
|
|
@ -79,5 +79,6 @@ public:
|
|||
|
||||
struct GSDXError {};
|
||||
struct GSDXRecoverableError : GSDXError {};
|
||||
struct GSDXErrorOOM : GSDXError {};
|
||||
|
||||
extern GSdxApp theApp;
|
||||
|
|
|
@ -435,11 +435,19 @@ extern void vmfree(void* ptr, size_t size);
|
|||
#endif
|
||||
|
||||
#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_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__)
|
||||
#else
|
||||
#define GL_PUSH_(...) (0);
|
||||
#define GL_PUSH(...) (0);
|
||||
#define GL_POP() (0);
|
||||
#define GL_INS(...) (0);
|
||||
|
|
Loading…
Reference in New Issue