mirror of https://github.com/PCSX2/pcsx2.git
gsdx: GS kinds of support draw without framebuffer
Gow uses 24 bits buffer, so only color is updated but blending is configured as Cd so it is a NOP In this case, we don't lookup the target in the texture cache. It reduces the complexity to handle depth which can be located at same address as RT Note: please test DX renderer
This commit is contained in:
parent
e3adf823b3
commit
35081f922a
|
@ -523,6 +523,7 @@ REG_END2
|
||||||
// opaque => output will be Cs/As
|
// opaque => output will be Cs/As
|
||||||
__forceinline bool IsOpaque() const {return ((A == B || (C == 2 && FIX == 0)) && D == 0) || (A == 0 && B == D && C == 2 && FIX == 0x80);}
|
__forceinline bool IsOpaque() const {return ((A == B || (C == 2 && FIX == 0)) && D == 0) || (A == 0 && B == D && C == 2 && FIX == 0x80);}
|
||||||
__forceinline bool IsOpaque(int amin, int amax) const {return ((A == B || amax == 0) && D == 0) || (A == 0 && B == D && amin == 0x80 && amax == 0x80);}
|
__forceinline bool IsOpaque(int amin, int amax) const {return ((A == B || amax == 0) && D == 0) || (A == 0 && B == D && amin == 0x80 && amax == 0x80);}
|
||||||
|
__forceinline bool IsCd() { return (A == B) && (D == 1);}
|
||||||
REG_END2
|
REG_END2
|
||||||
|
|
||||||
REG64_(GIFReg, BITBLTBUF)
|
REG64_(GIFReg, BITBLTBUF)
|
||||||
|
|
|
@ -996,7 +996,6 @@ void GSDeviceOGL::SetupDATE(GSTexture* rt, GSTexture* ds, const GSVertexPT1* ver
|
||||||
{
|
{
|
||||||
GL_PUSH("DATE First Pass");
|
GL_PUSH("DATE First Pass");
|
||||||
|
|
||||||
GSTexture* t = NULL;
|
|
||||||
// sfex3 (after the capcom logo), vf4 (first menu fading in), ffxii shadows, rumble roses shadows, persona4 shadows
|
// sfex3 (after the capcom logo), vf4 (first menu fading in), ffxii shadows, rumble roses shadows, persona4 shadows
|
||||||
|
|
||||||
BeginScene();
|
BeginScene();
|
||||||
|
@ -1016,7 +1015,7 @@ void GSDeviceOGL::SetupDATE(GSTexture* rt, GSTexture* ds, const GSVertexPT1* ver
|
||||||
OMSetDepthStencilState(m_date.dss, 1);
|
OMSetDepthStencilState(m_date.dss, 1);
|
||||||
OMSetBlendState(m_date.bs, 0);
|
OMSetBlendState(m_date.bs, 0);
|
||||||
// normally ok without any RT if GL_ARB_framebuffer_no_attachments is supported (minus driver bug)
|
// normally ok without any RT if GL_ARB_framebuffer_no_attachments is supported (minus driver bug)
|
||||||
OMSetRenderTargets(t, ds, &GLState::scissor);
|
OMSetRenderTargets(NULL, ds, &GLState::scissor);
|
||||||
OMSetColorMaskState(); // TODO: likely useless
|
OMSetColorMaskState(); // TODO: likely useless
|
||||||
|
|
||||||
// ia
|
// ia
|
||||||
|
@ -1035,9 +1034,7 @@ void GSDeviceOGL::SetupDATE(GSTexture* rt, GSTexture* ds, const GSVertexPT1* ver
|
||||||
PSSetSamplerState(m_convert.pt);
|
PSSetSamplerState(m_convert.pt);
|
||||||
}
|
}
|
||||||
|
|
||||||
OMSetWriteBuffer(GL_NONE);
|
|
||||||
DrawPrimitive();
|
DrawPrimitive();
|
||||||
OMSetWriteBuffer();
|
|
||||||
|
|
||||||
EndScene();
|
EndScene();
|
||||||
|
|
||||||
|
@ -1179,9 +1176,10 @@ void GSDeviceOGL::OMSetRenderTargets(GSTexture* rt, GSTexture* ds, const GSVecto
|
||||||
if (rt == NULL || !RT->IsBackbuffer()) {
|
if (rt == NULL || !RT->IsBackbuffer()) {
|
||||||
OMSetFBO(m_fbo);
|
OMSetFBO(m_fbo);
|
||||||
if (rt) {
|
if (rt) {
|
||||||
|
OMSetWriteBuffer();
|
||||||
OMAttachRt(RT);
|
OMAttachRt(RT);
|
||||||
} else {
|
} else {
|
||||||
// Note: NULL rt is only used in DATE so far.
|
OMSetWriteBuffer(GL_NONE);
|
||||||
OMAttachRt();
|
OMAttachRt();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -47,8 +47,8 @@ void GSRendererDX::DrawPrims(GSTexture* rt, GSTexture* ds, GSTextureCache::Sourc
|
||||||
GSDrawingEnvironment& env = m_env;
|
GSDrawingEnvironment& env = m_env;
|
||||||
GSDrawingContext* context = m_context;
|
GSDrawingContext* context = m_context;
|
||||||
|
|
||||||
const GSVector2i& rtsize = rt->GetSize();
|
const GSVector2i& rtsize = ds->GetSize();
|
||||||
const GSVector2& rtscale = rt->GetScale();
|
const GSVector2& rtscale = ds->GetScale();
|
||||||
|
|
||||||
bool DATE = m_context->TEST.DATE && context->FRAME.PSM != PSM_PSMCT24;
|
bool DATE = m_context->TEST.DATE && context->FRAME.PSM != PSM_PSMCT24;
|
||||||
|
|
||||||
|
@ -199,7 +199,7 @@ void GSRendererDX::DrawPrims(GSTexture* rt, GSTexture* ds, GSTextureCache::Sourc
|
||||||
//The resulting shifted output aligns better with common blending / corona / blurring effects,
|
//The resulting shifted output aligns better with common blending / corona / blurring effects,
|
||||||
//but introduces a few bad pixels on the edges.
|
//but introduces a few bad pixels on the edges.
|
||||||
|
|
||||||
if(rt->LikelyOffset)
|
if(rt && rt->LikelyOffset)
|
||||||
{
|
{
|
||||||
// DX9 has pixelcenter set to 0.0, so give it some value here
|
// DX9 has pixelcenter set to 0.0, so give it some value here
|
||||||
|
|
||||||
|
|
|
@ -231,6 +231,9 @@ void GSRendererDX9::SetupIA()
|
||||||
|
|
||||||
void GSRendererDX9::UpdateFBA(GSTexture* rt)
|
void GSRendererDX9::UpdateFBA(GSTexture* rt)
|
||||||
{
|
{
|
||||||
|
if (!rt)
|
||||||
|
return;
|
||||||
|
|
||||||
GSDevice9* dev = (GSDevice9*)m_dev;
|
GSDevice9* dev = (GSDevice9*)m_dev;
|
||||||
|
|
||||||
dev->BeginScene();
|
dev->BeginScene();
|
||||||
|
|
|
@ -334,12 +334,17 @@ void GSRendererHW::Draw()
|
||||||
GSDrawingEnvironment& env = m_env;
|
GSDrawingEnvironment& env = m_env;
|
||||||
GSDrawingContext* context = m_context;
|
GSDrawingContext* context = m_context;
|
||||||
|
|
||||||
|
// It is allowed to use the depth and rt at the same location. However at least 1 must
|
||||||
|
// be disabled. GoW uses a Cd blending on a 24 bits buffer (no alpha)
|
||||||
|
const bool no_rt = context->ALPHA.IsCd() && PRIM->ABE && (context->FRAME.PSM == 1);
|
||||||
|
|
||||||
GIFRegTEX0 TEX0;
|
GIFRegTEX0 TEX0;
|
||||||
|
|
||||||
TEX0.TBP0 = context->FRAME.Block();
|
TEX0.TBP0 = context->FRAME.Block();
|
||||||
TEX0.TBW = context->FRAME.FBW;
|
TEX0.TBW = context->FRAME.FBW;
|
||||||
TEX0.PSM = context->FRAME.PSM;
|
TEX0.PSM = context->FRAME.PSM;
|
||||||
GSTextureCache::Target* rt = m_tc->LookupTarget(TEX0, m_width, m_height, GSTextureCache::RenderTarget, true);
|
|
||||||
|
GSTextureCache::Target* rt = no_rt ? NULL : m_tc->LookupTarget(TEX0, m_width, m_height, GSTextureCache::RenderTarget, true);
|
||||||
|
|
||||||
TEX0.TBP0 = context->ZBUF.Block();
|
TEX0.TBP0 = context->ZBUF.Block();
|
||||||
TEX0.TBW = context->FRAME.FBW;
|
TEX0.TBW = context->FRAME.FBW;
|
||||||
|
@ -347,7 +352,7 @@ void GSRendererHW::Draw()
|
||||||
|
|
||||||
GSTextureCache::Target* ds = m_tc->LookupTarget(TEX0, m_width, m_height, GSTextureCache::DepthStencil, context->DepthWrite());
|
GSTextureCache::Target* ds = m_tc->LookupTarget(TEX0, m_width, m_height, GSTextureCache::DepthStencil, context->DepthWrite());
|
||||||
|
|
||||||
if(!rt || !ds)
|
if((!rt && !no_rt) || !ds)
|
||||||
{
|
{
|
||||||
GL_POP();
|
GL_POP();
|
||||||
ASSERT(0);
|
ASSERT(0);
|
||||||
|
@ -429,6 +434,7 @@ void GSRendererHW::Draw()
|
||||||
{
|
{
|
||||||
s = format("%05d_f%lld_rt0_%05x_%d.bmp", s_n, frame, context->FRAME.Block(), context->FRAME.PSM);
|
s = format("%05d_f%lld_rt0_%05x_%d.bmp", s_n, frame, context->FRAME.Block(), context->FRAME.PSM);
|
||||||
|
|
||||||
|
if (rt)
|
||||||
rt->m_texture->Save(root_hw+s);
|
rt->m_texture->Save(root_hw+s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -447,7 +453,7 @@ void GSRendererHW::Draw()
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
if(m_hacks.m_oi && !(this->*m_hacks.m_oi)(rt->m_texture, ds->m_texture, tex))
|
if(m_hacks.m_oi && !(this->*m_hacks.m_oi)(NULL, ds->m_texture, tex))
|
||||||
{
|
{
|
||||||
s_n += 1; // keep counter sync
|
s_n += 1; // keep counter sync
|
||||||
GL_POP();
|
GL_POP();
|
||||||
|
@ -514,7 +520,7 @@ void GSRendererHW::Draw()
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
||||||
DrawPrims(rt->m_texture, ds->m_texture, tex);
|
DrawPrims(rt ? rt->m_texture : NULL, ds->m_texture, tex);
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
||||||
|
@ -526,7 +532,7 @@ void GSRendererHW::Draw()
|
||||||
|
|
||||||
GSVector4i r = GSVector4i(m_vt.m_min.p.xyxy(m_vt.m_max.p)).rintersect(GSVector4i(context->scissor.in));
|
GSVector4i r = GSVector4i(m_vt.m_min.p.xyxy(m_vt.m_max.p)).rintersect(GSVector4i(context->scissor.in));
|
||||||
|
|
||||||
if(fm != 0xffffffff)
|
if(fm != 0xffffffff && rt)
|
||||||
{
|
{
|
||||||
rt->m_valid = rt->m_valid.runion(r);
|
rt->m_valid = rt->m_valid.runion(r);
|
||||||
|
|
||||||
|
@ -557,6 +563,7 @@ void GSRendererHW::Draw()
|
||||||
{
|
{
|
||||||
s = format("%05d_f%lld_rt1_%05x_%d.bmp", s_n, frame, context->FRAME.Block(), context->FRAME.PSM);
|
s = format("%05d_f%lld_rt1_%05x_%d.bmp", s_n, frame, context->FRAME.Block(), context->FRAME.PSM);
|
||||||
|
|
||||||
|
if (rt)
|
||||||
rt->m_texture->Save(root_hw+s);
|
rt->m_texture->Save(root_hw+s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -580,6 +587,7 @@ void GSRendererHW::Draw()
|
||||||
|
|
||||||
#ifdef DISABLE_HW_TEXTURE_CACHE
|
#ifdef DISABLE_HW_TEXTURE_CACHE
|
||||||
|
|
||||||
|
if (rt)
|
||||||
m_tc->Read(rt, r);
|
m_tc->Read(rt, r);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -217,13 +217,13 @@ void GSRendererOGL::DrawPrims(GSTexture* rt, GSTexture* ds, GSTextureCache::Sour
|
||||||
{
|
{
|
||||||
GL_PUSH("GL Draw from %d in %d (Depth %d)",
|
GL_PUSH("GL Draw from %d in %d (Depth %d)",
|
||||||
tex && tex->m_texture ? tex->m_texture->GetID() : 0,
|
tex && tex->m_texture ? tex->m_texture->GetID() : 0,
|
||||||
rt->GetID(), ds->GetID());
|
rt ? rt->GetID() : -1, ds->GetID());
|
||||||
|
|
||||||
GSDrawingEnvironment& env = m_env;
|
GSDrawingEnvironment& env = m_env;
|
||||||
GSDrawingContext* context = m_context;
|
GSDrawingContext* context = m_context;
|
||||||
|
|
||||||
const GSVector2i& rtsize = rt->GetSize();
|
const GSVector2i& rtsize = ds->GetSize();
|
||||||
const GSVector2& rtscale = rt->GetScale();
|
const GSVector2& rtscale = ds->GetScale();
|
||||||
|
|
||||||
bool DATE = m_context->TEST.DATE && context->FRAME.PSM != PSM_PSMCT24;
|
bool DATE = m_context->TEST.DATE && context->FRAME.PSM != PSM_PSMCT24;
|
||||||
bool DATE_GL42 = false;
|
bool DATE_GL42 = false;
|
||||||
|
@ -425,7 +425,7 @@ void GSRendererOGL::DrawPrims(GSTexture* rt, GSTexture* ds, GSTextureCache::Sour
|
||||||
//The resulting shifted output aligns better with common blending / corona / blurring effects,
|
//The resulting shifted output aligns better with common blending / corona / blurring effects,
|
||||||
//but introduces a few bad pixels on the edges.
|
//but introduces a few bad pixels on the edges.
|
||||||
|
|
||||||
if (rt->LikelyOffset)
|
if (rt && rt->LikelyOffset)
|
||||||
{
|
{
|
||||||
ox2 *= rt->OffsetHack_modx;
|
ox2 *= rt->OffsetHack_modx;
|
||||||
oy2 *= rt->OffsetHack_mody;
|
oy2 *= rt->OffsetHack_mody;
|
||||||
|
@ -621,7 +621,7 @@ void GSRendererOGL::DrawPrims(GSTexture* rt, GSTexture* ds, GSTextureCache::Sour
|
||||||
bool all_sw = !( (ALPHA.A == ALPHA.B) || (ALPHA.C == 2 && afix <= 1.002f) ) && (m_accurate_blend > 1);
|
bool all_sw = !( (ALPHA.A == ALPHA.B) || (ALPHA.C == 2 && afix <= 1.002f) ) && (m_accurate_blend > 1);
|
||||||
bool sw_blending = (m_accurate_blend && (bogus_blend & A_MAX)) || acc_colclip_wrap || all_sw;
|
bool sw_blending = (m_accurate_blend && (bogus_blend & A_MAX)) || acc_colclip_wrap || all_sw;
|
||||||
|
|
||||||
if (sw_blending && om_bsel.abe) {
|
if (sw_blending && om_bsel.abe && rt) {
|
||||||
GL_INS("!!! SW blending effect used (0x%x from sel %d) !!!", bogus_blend, blend_sel);
|
GL_INS("!!! SW blending effect used (0x%x from sel %d) !!!", bogus_blend, blend_sel);
|
||||||
|
|
||||||
// select a shader that support blending
|
// select a shader that support blending
|
||||||
|
|
Loading…
Reference in New Issue