mirror of https://github.com/PCSX2/pcsx2.git
gsdx hw: group the double half clear with gs mem clear hack
It avoid redundant check of the GS context You can disable the extra clear with UserHacks_DisableGsMemClear = 1
This commit is contained in:
parent
6c6ed5f443
commit
1e343084e2
|
@ -692,7 +692,18 @@ void GSRendererHW::Draw()
|
|||
}
|
||||
|
||||
if (!m_userhacks_disable_gs_mem_clear) {
|
||||
OI_GsMemClear();
|
||||
// Constant Direct Write without texture/test/blending (aka a GS mem clear)
|
||||
if ((m_vt.m_primclass == GS_SPRITE_CLASS) && !PRIM->TME && !PRIM->ABE // Direct write
|
||||
&& (m_context->FRAME.FBMSK == 0) // no color mask
|
||||
&& !m_context->TEST.ATE // no alpha test
|
||||
&& (!m_context->TEST.ZTE || m_context->TEST.ZTST == ZTST_ALWAYS) // no depth test
|
||||
&& (m_vt.m_eq.rgba == 0xFFFF) // constant color write
|
||||
&& r.x == 0 && r.y == 0) { // Likely full buffer write
|
||||
|
||||
OI_GsMemClear();
|
||||
|
||||
OI_DoubleHalfClear(rt_tex, ds_tex);
|
||||
}
|
||||
}
|
||||
|
||||
// skip alpha test if possible
|
||||
|
@ -875,11 +886,6 @@ GSRendererHW::Hacks::Hacks()
|
|||
m_oi_list.push_back(HackEntry<OI_Ptr>(CRC::SuperManReturns, CRC::RegionCount, &GSRendererHW::OI_SuperManReturns));
|
||||
m_oi_list.push_back(HackEntry<OI_Ptr>(CRC::ArTonelico2, CRC::RegionCount, &GSRendererHW::OI_ArTonelico2));
|
||||
m_oi_list.push_back(HackEntry<OI_Ptr>(CRC::ItadakiStreet, CRC::RegionCount, &GSRendererHW::OI_ItadakiStreet));
|
||||
// Enable it by default in the future (hack ought to be safe enough)
|
||||
m_oi_list.push_back(HackEntry<OI_Ptr>(CRC::SimpsonsGame, CRC::RegionCount, &GSRendererHW::OI_DoubleHalfClear));
|
||||
m_oi_list.push_back(HackEntry<OI_Ptr>(CRC::TyTasmanianTiger, CRC::RegionCount, &GSRendererHW::OI_DoubleHalfClear));
|
||||
m_oi_list.push_back(HackEntry<OI_Ptr>(CRC::TyTasmanianTiger2, CRC::RegionCount, &GSRendererHW::OI_DoubleHalfClear));
|
||||
m_oi_list.push_back(HackEntry<OI_Ptr>(CRC::FFVIIDoC, CRC::RegionCount, &GSRendererHW::OI_DoubleHalfClear));
|
||||
|
||||
if (!can_handle_depth)
|
||||
m_oi_list.push_back(HackEntry<OI_Ptr>(CRC::SMTNocturne, CRC::RegionCount, &GSRendererHW::OI_SMTNocturne));
|
||||
|
@ -905,34 +911,28 @@ void GSRendererHW::Hacks::SetGameCRC(const CRC::Game& game)
|
|||
|
||||
m_oi = &GSRendererHW::OI_PointListPalette;
|
||||
}
|
||||
|
||||
bool hack = theApp.GetConfigB("UserHacks_ColorDepthClearOverlap") && theApp.GetConfigB("UserHacks");
|
||||
if (hack && !m_oi) {
|
||||
// FIXME: Enable this code in the future. I think it could replace
|
||||
// most of the "old" OI hack. So far code was tested on GoW2 & SimpsonsGame with
|
||||
// success
|
||||
m_oi = &GSRendererHW::OI_DoubleHalfClear;
|
||||
}
|
||||
}
|
||||
|
||||
// Handle case where the frame buffer and the Z buffer overlap
|
||||
bool GSRendererHW::OI_DoubleHalfClear(GSTexture* rt, GSTexture* ds, GSTextureCache::Source* t)
|
||||
// Trick to do a fast clear on the GS
|
||||
// Set frame buffer pointer on the start of the buffer. Set depth buffer pointer on the half buffer
|
||||
// FB + depth write will fill the full buffer.
|
||||
void GSRendererHW::OI_DoubleHalfClear(GSTexture* rt, GSTexture* ds)
|
||||
{
|
||||
// Trick to do a fast clear on the GS
|
||||
// Set frame buffer pointer on the start of the buffer. Set depth buffer pointer on the half buffer
|
||||
// FB + depth write will fill the full buffer.
|
||||
if ((m_vt.m_primclass == GS_SPRITE_CLASS) && !PRIM->TME && !m_context->ZBUF.ZMSK && rt && ds) {
|
||||
// Note gs mem clear must be tested before calling this function
|
||||
|
||||
// Limit further to unmask Z write
|
||||
if (!m_context->ZBUF.ZMSK && rt && ds) {
|
||||
const GSVertex* v = &m_vertex.buff[0];
|
||||
const GSLocalMemory::psm_t& frame_psm = GSLocalMemory::m_psm[m_context->FRAME.PSM];
|
||||
const GSLocalMemory::psm_t& depth_psm = GSLocalMemory::m_psm[m_context->ZBUF.PSM];
|
||||
|
||||
// Z and color must be constant and the same
|
||||
if (m_vt.m_eq.rgba != 0xFFFF || !m_vt.m_eq.z || v[1].XYZ.Z != v[1].RGBAQ.u32[0])
|
||||
return true;
|
||||
return;
|
||||
|
||||
// Format doesn't have the same size. It smells fishy
|
||||
if (frame_psm.trbpp != depth_psm.trbpp)
|
||||
return true;
|
||||
return;
|
||||
|
||||
// Size of the current draw
|
||||
uint32 w_pages = roundf(m_vt.m_max.p.x / frame_psm.pgs.x);
|
||||
|
@ -963,24 +963,17 @@ bool GSRendererHW::OI_DoubleHalfClear(GSTexture* rt, GSTexture* ds, GSTextureCac
|
|||
} else {
|
||||
m_dev->ClearRenderTarget(rt, color);
|
||||
}
|
||||
|
||||
// warning: draw call mustn't be skipped to keep correct invalidation. Don't return false
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Note: hack is safe, but it could impact the perf a little (normally games do only a couple of clear by frame)
|
||||
void GSRendererHW::OI_GsMemClear()
|
||||
{
|
||||
// Rectangle draw without texture
|
||||
if ((m_vt.m_primclass == GS_SPRITE_CLASS) && (m_vertex.next == 2) && !PRIM->TME && !PRIM->ABE // Direct write
|
||||
&& (m_context->FRAME.FBMSK == 0)
|
||||
&& !m_context->TEST.ATE // no alpha test
|
||||
&& (!m_context->TEST.ZTE || m_context->TEST.ZTST == ZTST_ALWAYS) // no depth test
|
||||
&& (m_vt.m_eq.rgba == 0xFFFF && m_vt.m_min.c.eq(GSVector4i(0))) // Constant 0 write
|
||||
) {
|
||||
// Note gs mem clear must be tested before calling this function
|
||||
|
||||
// Limit it further to a full screen 0 write
|
||||
if ((m_vertex.next == 2) && m_vt.m_min.c.eq(GSVector4i(0))) {
|
||||
GSOffset* off = m_context->offset.fb;
|
||||
GSVector4i r = GSVector4i(m_vt.m_min.p.xyxy(m_vt.m_max.p)).rintersect(GSVector4i(m_context->scissor.in));
|
||||
// Limit the hack to a single fullscreen clear. Some games might use severals column to clear a screen
|
||||
|
|
|
@ -50,8 +50,8 @@ private:
|
|||
// Require special argument
|
||||
bool OI_BlitFMV(GSTextureCache::Target* _rt, GSTextureCache::Source* t, const GSVector4i& r_draw);
|
||||
void OI_GsMemClear(); // always on
|
||||
void OI_DoubleHalfClear(GSTexture* rt, GSTexture* ds); // always on
|
||||
|
||||
bool OI_DoubleHalfClear(GSTexture* rt, GSTexture* ds, GSTextureCache::Source* t);
|
||||
bool OI_DoubleHalfClear_Vertical(GSTexture* rt, GSTexture* ds, GSTextureCache::Source* t);
|
||||
bool OI_FFXII(GSTexture* rt, GSTexture* ds, GSTextureCache::Source* t);
|
||||
bool OI_FFX(GSTexture* rt, GSTexture* ds, GSTextureCache::Source* t);
|
||||
|
|
|
@ -337,7 +337,6 @@ void GSdxApp::Init()
|
|||
m_default_configuration["UserHacks_AlphaHack"] = "0";
|
||||
m_default_configuration["UserHacks_AlphaStencil"] = "0";
|
||||
m_default_configuration["UserHacks_AutoFlush"] = "0";
|
||||
m_default_configuration["UserHacks_ColorDepthClearOverlap"] = "0";
|
||||
m_default_configuration["UserHacks_DisableDepthSupport"] = "0";
|
||||
m_default_configuration["UserHacks_DisableGsMemClear"] = "0";
|
||||
m_default_configuration["UserHacks_DisablePartialInvalidation"] = "0";
|
||||
|
|
Loading…
Reference in New Issue