mirror of https://github.com/PCSX2/pcsx2.git
gsdx: add an auto flush hack to implement a Read Write GS effect.
It impacts all renderers. It ought to fix issue in GTA radiosity, Shadows in Jak series. (note shadows will suck in upscaling) Implementation is really brutal. Expect a massive slow down, but at least we can test the effect easily. Normally perf impact will remain reasonable if the game doesn't use a Read-Write effect Performances number are welcomes (my guess is really awful in HW mode, slow in SW mode). You can enable it with "UserHacks_AutoFlush = 1"
This commit is contained in:
parent
bcb951077d
commit
029d74f855
|
@ -47,6 +47,7 @@ GSState::GSState()
|
||||||
m_mipmap = theApp.GetConfigB("mipmap");
|
m_mipmap = theApp.GetConfigB("mipmap");
|
||||||
m_NTSC_Saturation = theApp.GetConfigB("NTSC_Saturation");
|
m_NTSC_Saturation = theApp.GetConfigB("NTSC_Saturation");
|
||||||
m_userhacks_skipdraw = theApp.GetConfigB("UserHacks") ? theApp.GetConfigI("UserHacks_SkipDraw") : 0;
|
m_userhacks_skipdraw = theApp.GetConfigB("UserHacks") ? theApp.GetConfigI("UserHacks_SkipDraw") : 0;
|
||||||
|
m_userhacks_auto_flush = theApp.GetConfigB("UserHacks") ? theApp.GetConfigB("UserHacks_AutoFlush") : 0;
|
||||||
|
|
||||||
s_n = 0;
|
s_n = 0;
|
||||||
s_dump = theApp.GetConfigB("dump");
|
s_dump = theApp.GetConfigB("dump");
|
||||||
|
@ -271,26 +272,37 @@ void GSState::ResetHandlers()
|
||||||
m_fpGIFPackedRegHandlers[GIF_REG_A_D] = &GSState::GIFPackedRegHandlerA_D;
|
m_fpGIFPackedRegHandlers[GIF_REG_A_D] = &GSState::GIFPackedRegHandlerA_D;
|
||||||
m_fpGIFPackedRegHandlers[GIF_REG_NOP] = &GSState::GIFPackedRegHandlerNOP;
|
m_fpGIFPackedRegHandlers[GIF_REG_NOP] = &GSState::GIFPackedRegHandlerNOP;
|
||||||
|
|
||||||
#define SetHandlerXYZ(P) \
|
#define SetHandlerXYZ(P, auto_flush) \
|
||||||
m_fpGIFPackedRegHandlerXYZ[P][0] = &GSState::GIFPackedRegHandlerXYZF2<P, 0>; \
|
m_fpGIFPackedRegHandlerXYZ[P][0] = &GSState::GIFPackedRegHandlerXYZF2<P, 0, auto_flush>; \
|
||||||
m_fpGIFPackedRegHandlerXYZ[P][1] = &GSState::GIFPackedRegHandlerXYZF2<P, 1>; \
|
m_fpGIFPackedRegHandlerXYZ[P][1] = &GSState::GIFPackedRegHandlerXYZF2<P, 1, auto_flush>; \
|
||||||
m_fpGIFPackedRegHandlerXYZ[P][2] = &GSState::GIFPackedRegHandlerXYZ2<P, 0>; \
|
m_fpGIFPackedRegHandlerXYZ[P][2] = &GSState::GIFPackedRegHandlerXYZ2<P, 0, auto_flush>; \
|
||||||
m_fpGIFPackedRegHandlerXYZ[P][3] = &GSState::GIFPackedRegHandlerXYZ2<P, 1>; \
|
m_fpGIFPackedRegHandlerXYZ[P][3] = &GSState::GIFPackedRegHandlerXYZ2<P, 1, auto_flush>; \
|
||||||
m_fpGIFRegHandlerXYZ[P][0] = &GSState::GIFRegHandlerXYZF2<P, 0>; \
|
m_fpGIFRegHandlerXYZ[P][0] = &GSState::GIFRegHandlerXYZF2<P, 0, auto_flush>; \
|
||||||
m_fpGIFRegHandlerXYZ[P][1] = &GSState::GIFRegHandlerXYZF2<P, 1>; \
|
m_fpGIFRegHandlerXYZ[P][1] = &GSState::GIFRegHandlerXYZF2<P, 1, auto_flush>; \
|
||||||
m_fpGIFRegHandlerXYZ[P][2] = &GSState::GIFRegHandlerXYZ2<P, 0>; \
|
m_fpGIFRegHandlerXYZ[P][2] = &GSState::GIFRegHandlerXYZ2<P, 0, auto_flush>; \
|
||||||
m_fpGIFRegHandlerXYZ[P][3] = &GSState::GIFRegHandlerXYZ2<P, 1>; \
|
m_fpGIFRegHandlerXYZ[P][3] = &GSState::GIFRegHandlerXYZ2<P, 1, auto_flush>; \
|
||||||
m_fpGIFPackedRegHandlerSTQRGBAXYZF2[P] = &GSState::GIFPackedRegHandlerSTQRGBAXYZF2<P>; \
|
m_fpGIFPackedRegHandlerSTQRGBAXYZF2[P] = &GSState::GIFPackedRegHandlerSTQRGBAXYZF2<P, auto_flush>; \
|
||||||
m_fpGIFPackedRegHandlerSTQRGBAXYZ2[P] = &GSState::GIFPackedRegHandlerSTQRGBAXYZ2<P>; \
|
m_fpGIFPackedRegHandlerSTQRGBAXYZ2[P] = &GSState::GIFPackedRegHandlerSTQRGBAXYZ2<P, auto_flush>; \
|
||||||
|
|
||||||
SetHandlerXYZ(GS_POINTLIST);
|
if (m_userhacks_auto_flush) {
|
||||||
SetHandlerXYZ(GS_LINELIST);
|
SetHandlerXYZ(GS_POINTLIST, true);
|
||||||
SetHandlerXYZ(GS_LINESTRIP);
|
SetHandlerXYZ(GS_LINELIST, true);
|
||||||
SetHandlerXYZ(GS_TRIANGLELIST);
|
SetHandlerXYZ(GS_LINESTRIP, true);
|
||||||
SetHandlerXYZ(GS_TRIANGLESTRIP);
|
SetHandlerXYZ(GS_TRIANGLELIST, true);
|
||||||
SetHandlerXYZ(GS_TRIANGLEFAN);
|
SetHandlerXYZ(GS_TRIANGLESTRIP, true);
|
||||||
SetHandlerXYZ(GS_SPRITE);
|
SetHandlerXYZ(GS_TRIANGLEFAN, true);
|
||||||
SetHandlerXYZ(GS_INVALID);
|
SetHandlerXYZ(GS_SPRITE, true);
|
||||||
|
SetHandlerXYZ(GS_INVALID, true);
|
||||||
|
} else {
|
||||||
|
SetHandlerXYZ(GS_POINTLIST, false);
|
||||||
|
SetHandlerXYZ(GS_LINELIST, false);
|
||||||
|
SetHandlerXYZ(GS_LINESTRIP, false);
|
||||||
|
SetHandlerXYZ(GS_TRIANGLELIST, false);
|
||||||
|
SetHandlerXYZ(GS_TRIANGLESTRIP, false);
|
||||||
|
SetHandlerXYZ(GS_TRIANGLEFAN, false);
|
||||||
|
SetHandlerXYZ(GS_SPRITE, false);
|
||||||
|
SetHandlerXYZ(GS_INVALID, false);
|
||||||
|
}
|
||||||
|
|
||||||
for(size_t i = 0; i < countof(m_fpGIFRegHandlers); i++)
|
for(size_t i = 0; i < countof(m_fpGIFRegHandlers); i++)
|
||||||
{
|
{
|
||||||
|
@ -558,7 +570,7 @@ void GSState::GIFPackedRegHandlerUV_Hack(const GIFPackedReg* RESTRICT r)
|
||||||
isPackedUV_HackFlag = true;
|
isPackedUV_HackFlag = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<uint32 prim, uint32 adc>
|
template<uint32 prim, uint32 adc, bool auto_flush>
|
||||||
void GSState::GIFPackedRegHandlerXYZF2(const GIFPackedReg* RESTRICT r)
|
void GSState::GIFPackedRegHandlerXYZF2(const GIFPackedReg* RESTRICT r)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
|
@ -574,10 +586,10 @@ void GSState::GIFPackedRegHandlerXYZF2(const GIFPackedReg* RESTRICT r)
|
||||||
|
|
||||||
m_v.m[1] = xy.upl32(zf);
|
m_v.m[1] = xy.upl32(zf);
|
||||||
|
|
||||||
VertexKick<prim>(adc ? 1 : r->XYZF2.Skip());
|
VertexKick<prim, auto_flush>(adc ? 1 : r->XYZF2.Skip());
|
||||||
}
|
}
|
||||||
|
|
||||||
template<uint32 prim, uint32 adc>
|
template<uint32 prim, uint32 adc, bool auto_flush>
|
||||||
void GSState::GIFPackedRegHandlerXYZ2(const GIFPackedReg* RESTRICT r)
|
void GSState::GIFPackedRegHandlerXYZ2(const GIFPackedReg* RESTRICT r)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
|
@ -591,7 +603,7 @@ void GSState::GIFPackedRegHandlerXYZ2(const GIFPackedReg* RESTRICT r)
|
||||||
|
|
||||||
m_v.m[1] = xyz.upl64(GSVector4i::loadl(&m_v.UV));
|
m_v.m[1] = xyz.upl64(GSVector4i::loadl(&m_v.UV));
|
||||||
|
|
||||||
VertexKick<prim>(adc ? 1 : r->XYZ2.Skip());
|
VertexKick<prim, auto_flush>(adc ? 1 : r->XYZ2.Skip());
|
||||||
}
|
}
|
||||||
|
|
||||||
void GSState::GIFPackedRegHandlerFOG(const GIFPackedReg* RESTRICT r)
|
void GSState::GIFPackedRegHandlerFOG(const GIFPackedReg* RESTRICT r)
|
||||||
|
@ -608,7 +620,7 @@ void GSState::GIFPackedRegHandlerNOP(const GIFPackedReg* RESTRICT r)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
template<uint32 prim>
|
template<uint32 prim, bool auto_flush>
|
||||||
void GSState::GIFPackedRegHandlerSTQRGBAXYZF2(const GIFPackedReg* RESTRICT r, uint32 size)
|
void GSState::GIFPackedRegHandlerSTQRGBAXYZF2(const GIFPackedReg* RESTRICT r, uint32 size)
|
||||||
{
|
{
|
||||||
ASSERT(size > 0 && size % 3 == 0);
|
ASSERT(size > 0 && size % 3 == 0);
|
||||||
|
@ -637,7 +649,7 @@ void GSState::GIFPackedRegHandlerSTQRGBAXYZF2(const GIFPackedReg* RESTRICT r, ui
|
||||||
|
|
||||||
m_v.m[1] = xy.upl32(zf); // TODO: only store the last one
|
m_v.m[1] = xy.upl32(zf); // TODO: only store the last one
|
||||||
|
|
||||||
VertexKick<prim>(r[2].XYZF2.Skip());
|
VertexKick<prim, auto_flush>(r[2].XYZF2.Skip());
|
||||||
|
|
||||||
r += 3;
|
r += 3;
|
||||||
}
|
}
|
||||||
|
@ -645,7 +657,7 @@ void GSState::GIFPackedRegHandlerSTQRGBAXYZF2(const GIFPackedReg* RESTRICT r, ui
|
||||||
m_q = r[-3].STQ.Q; // remember the last one, STQ outputs this to the temp Q each time
|
m_q = r[-3].STQ.Q; // remember the last one, STQ outputs this to the temp Q each time
|
||||||
}
|
}
|
||||||
|
|
||||||
template<uint32 prim>
|
template<uint32 prim, bool auto_flush>
|
||||||
void GSState::GIFPackedRegHandlerSTQRGBAXYZ2(const GIFPackedReg* RESTRICT r, uint32 size)
|
void GSState::GIFPackedRegHandlerSTQRGBAXYZ2(const GIFPackedReg* RESTRICT r, uint32 size)
|
||||||
{
|
{
|
||||||
ASSERT(size > 0 && size % 3 == 0);
|
ASSERT(size > 0 && size % 3 == 0);
|
||||||
|
@ -673,7 +685,7 @@ void GSState::GIFPackedRegHandlerSTQRGBAXYZ2(const GIFPackedReg* RESTRICT r, uin
|
||||||
|
|
||||||
m_v.m[1] = xyz.upl64(GSVector4i::loadl(&m_v.UV)); // TODO: only store the last one
|
m_v.m[1] = xyz.upl64(GSVector4i::loadl(&m_v.UV)); // TODO: only store the last one
|
||||||
|
|
||||||
VertexKick<prim>(r[2].XYZ2.Skip());
|
VertexKick<prim, auto_flush>(r[2].XYZ2.Skip());
|
||||||
|
|
||||||
r += 3;
|
r += 3;
|
||||||
}
|
}
|
||||||
|
@ -772,7 +784,7 @@ void GSState::GIFRegHandlerUV_Hack(const GIFReg* RESTRICT r)
|
||||||
isPackedUV_HackFlag = false;
|
isPackedUV_HackFlag = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<uint32 prim, uint32 adc>
|
template<uint32 prim, uint32 adc, bool auto_flush>
|
||||||
void GSState::GIFRegHandlerXYZF2(const GIFReg* RESTRICT r)
|
void GSState::GIFRegHandlerXYZF2(const GIFReg* RESTRICT r)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
|
@ -794,17 +806,17 @@ void GSState::GIFRegHandlerXYZF2(const GIFReg* RESTRICT r)
|
||||||
|
|
||||||
m_v.m[1] = xyz.upl64(uvf);
|
m_v.m[1] = xyz.upl64(uvf);
|
||||||
|
|
||||||
VertexKick<prim>(adc);
|
VertexKick<prim, auto_flush>(adc);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<uint32 prim, uint32 adc>
|
template<uint32 prim, uint32 adc, bool auto_flush>
|
||||||
void GSState::GIFRegHandlerXYZ2(const GIFReg* RESTRICT r)
|
void GSState::GIFRegHandlerXYZ2(const GIFReg* RESTRICT r)
|
||||||
{
|
{
|
||||||
// m_v.XYZ = (GSVector4i)r->XYZ;
|
// m_v.XYZ = (GSVector4i)r->XYZ;
|
||||||
|
|
||||||
m_v.m[1] = GSVector4i::load(&r->XYZ, &m_v.UV);
|
m_v.m[1] = GSVector4i::load(&r->XYZ, &m_v.UV);
|
||||||
|
|
||||||
VertexKick<prim>(adc);
|
VertexKick<prim, auto_flush>(adc);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<int i> void GSState::ApplyTEX0(GIFRegTEX0& TEX0)
|
template<int i> void GSState::ApplyTEX0(GIFRegTEX0& TEX0)
|
||||||
|
@ -2455,7 +2467,7 @@ void GSState::GrowVertexBuffer()
|
||||||
m_index.buff = index;
|
m_index.buff = index;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<uint32 prim>
|
template<uint32 prim, bool auto_flush>
|
||||||
__forceinline void GSState::VertexKick(uint32 skip)
|
__forceinline void GSState::VertexKick(uint32 skip)
|
||||||
{
|
{
|
||||||
ASSERT(m_vertex.tail < m_vertex.maxcount + 3);
|
ASSERT(m_vertex.tail < m_vertex.maxcount + 3);
|
||||||
|
@ -2688,6 +2700,9 @@ __forceinline void GSState::VertexKick(uint32 skip)
|
||||||
default:
|
default:
|
||||||
__assume(0);
|
__assume(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (auto_flush && PRIM->TME && (m_context->FRAME.Block() == m_context->TEX0.TBP0))
|
||||||
|
FlushPrim();
|
||||||
}
|
}
|
||||||
|
|
||||||
void GSState::GetTextureMinMax(GSVector4i& r, const GIFRegTEX0& TEX0, const GIFRegCLAMP& CLAMP, bool linear)
|
void GSState::GetTextureMinMax(GSVector4i& r, const GIFRegTEX0& TEX0, const GIFRegCLAMP& CLAMP, bool linear)
|
||||||
|
|
|
@ -62,8 +62,8 @@ class GSState : public GSAlignedClass<32>
|
||||||
void GIFPackedRegHandlerSTQ(const GIFPackedReg* RESTRICT r);
|
void GIFPackedRegHandlerSTQ(const GIFPackedReg* RESTRICT r);
|
||||||
void GIFPackedRegHandlerUV(const GIFPackedReg* RESTRICT r);
|
void GIFPackedRegHandlerUV(const GIFPackedReg* RESTRICT r);
|
||||||
void GIFPackedRegHandlerUV_Hack(const GIFPackedReg* RESTRICT r);
|
void GIFPackedRegHandlerUV_Hack(const GIFPackedReg* RESTRICT r);
|
||||||
template<uint32 prim, uint32 adc> void GIFPackedRegHandlerXYZF2(const GIFPackedReg* RESTRICT r);
|
template<uint32 prim, uint32 adc, bool auto_flush> void GIFPackedRegHandlerXYZF2(const GIFPackedReg* RESTRICT r);
|
||||||
template<uint32 prim, uint32 adc> void GIFPackedRegHandlerXYZ2(const GIFPackedReg* RESTRICT r);
|
template<uint32 prim, uint32 adc, bool auto_flush> void GIFPackedRegHandlerXYZ2(const GIFPackedReg* RESTRICT r);
|
||||||
void GIFPackedRegHandlerFOG(const GIFPackedReg* RESTRICT r);
|
void GIFPackedRegHandlerFOG(const GIFPackedReg* RESTRICT r);
|
||||||
void GIFPackedRegHandlerA_D(const GIFPackedReg* RESTRICT r);
|
void GIFPackedRegHandlerA_D(const GIFPackedReg* RESTRICT r);
|
||||||
void GIFPackedRegHandlerNOP(const GIFPackedReg* RESTRICT r);
|
void GIFPackedRegHandlerNOP(const GIFPackedReg* RESTRICT r);
|
||||||
|
@ -79,8 +79,8 @@ class GSState : public GSAlignedClass<32>
|
||||||
GIFPackedRegHandlerC m_fpGIFPackedRegHandlerSTQRGBAXYZF2[8];
|
GIFPackedRegHandlerC m_fpGIFPackedRegHandlerSTQRGBAXYZF2[8];
|
||||||
GIFPackedRegHandlerC m_fpGIFPackedRegHandlerSTQRGBAXYZ2[8];
|
GIFPackedRegHandlerC m_fpGIFPackedRegHandlerSTQRGBAXYZ2[8];
|
||||||
|
|
||||||
template<uint32 prim> void GIFPackedRegHandlerSTQRGBAXYZF2(const GIFPackedReg* RESTRICT r, uint32 size);
|
template<uint32 prim, bool auto_flush> void GIFPackedRegHandlerSTQRGBAXYZF2(const GIFPackedReg* RESTRICT r, uint32 size);
|
||||||
template<uint32 prim> void GIFPackedRegHandlerSTQRGBAXYZ2(const GIFPackedReg* RESTRICT r, uint32 size);
|
template<uint32 prim, bool auto_flush> void GIFPackedRegHandlerSTQRGBAXYZ2(const GIFPackedReg* RESTRICT r, uint32 size);
|
||||||
void GIFPackedRegHandlerNOP(const GIFPackedReg* RESTRICT r, uint32 size);
|
void GIFPackedRegHandlerNOP(const GIFPackedReg* RESTRICT r, uint32 size);
|
||||||
|
|
||||||
template<int i> void ApplyTEX0(GIFRegTEX0& TEX0);
|
template<int i> void ApplyTEX0(GIFRegTEX0& TEX0);
|
||||||
|
@ -92,8 +92,8 @@ class GSState : public GSAlignedClass<32>
|
||||||
void GIFRegHandlerST(const GIFReg* RESTRICT r);
|
void GIFRegHandlerST(const GIFReg* RESTRICT r);
|
||||||
void GIFRegHandlerUV(const GIFReg* RESTRICT r);
|
void GIFRegHandlerUV(const GIFReg* RESTRICT r);
|
||||||
void GIFRegHandlerUV_Hack(const GIFReg* RESTRICT r);
|
void GIFRegHandlerUV_Hack(const GIFReg* RESTRICT r);
|
||||||
template<uint32 prim, uint32 adc> void GIFRegHandlerXYZF2(const GIFReg* RESTRICT r);
|
template<uint32 prim, uint32 adc, bool auto_flush> void GIFRegHandlerXYZF2(const GIFReg* RESTRICT r);
|
||||||
template<uint32 prim, uint32 adc> void GIFRegHandlerXYZ2(const GIFReg* RESTRICT r);
|
template<uint32 prim, uint32 adc, bool auto_flush> void GIFRegHandlerXYZ2(const GIFReg* RESTRICT r);
|
||||||
template<int i> void GIFRegHandlerTEX0(const GIFReg* RESTRICT r);
|
template<int i> void GIFRegHandlerTEX0(const GIFReg* RESTRICT r);
|
||||||
template<int i> void GIFRegHandlerCLAMP(const GIFReg* RESTRICT r);
|
template<int i> void GIFRegHandlerCLAMP(const GIFReg* RESTRICT r);
|
||||||
void GIFRegHandlerFOG(const GIFReg* RESTRICT r);
|
void GIFRegHandlerFOG(const GIFReg* RESTRICT r);
|
||||||
|
@ -163,6 +163,7 @@ protected:
|
||||||
GetSkipCount m_gsc;
|
GetSkipCount m_gsc;
|
||||||
int m_skip;
|
int m_skip;
|
||||||
int m_userhacks_skipdraw;
|
int m_userhacks_skipdraw;
|
||||||
|
bool m_userhacks_auto_flush;
|
||||||
|
|
||||||
GSVertex m_v;
|
GSVertex m_v;
|
||||||
float m_q;
|
float m_q;
|
||||||
|
@ -191,7 +192,7 @@ protected:
|
||||||
|
|
||||||
void GrowVertexBuffer();
|
void GrowVertexBuffer();
|
||||||
|
|
||||||
template<uint32 prim>
|
template<uint32 prim, bool auto_flush>
|
||||||
void VertexKick(uint32 skip);
|
void VertexKick(uint32 skip);
|
||||||
|
|
||||||
// following functions need m_vt to be initialized
|
// following functions need m_vt to be initialized
|
||||||
|
|
|
@ -336,6 +336,7 @@ void GSdxApp::Init()
|
||||||
m_default_configuration["UserHacks_align_sprite_X"] = "0";
|
m_default_configuration["UserHacks_align_sprite_X"] = "0";
|
||||||
m_default_configuration["UserHacks_AlphaHack"] = "0";
|
m_default_configuration["UserHacks_AlphaHack"] = "0";
|
||||||
m_default_configuration["UserHacks_AlphaStencil"] = "0";
|
m_default_configuration["UserHacks_AlphaStencil"] = "0";
|
||||||
|
m_default_configuration["UserHacks_AutoFlush"] = "0";
|
||||||
m_default_configuration["UserHacks_ColorDepthClearOverlap"] = "0";
|
m_default_configuration["UserHacks_ColorDepthClearOverlap"] = "0";
|
||||||
m_default_configuration["UserHacks_DisableDepthSupport"] = "0";
|
m_default_configuration["UserHacks_DisableDepthSupport"] = "0";
|
||||||
m_default_configuration["UserHacks_DisableGsMemClear"] = "0";
|
m_default_configuration["UserHacks_DisableGsMemClear"] = "0";
|
||||||
|
|
Loading…
Reference in New Issue