From 06055add5c225d18290a59d1681e9a7546a6df9a Mon Sep 17 00:00:00 2001 From: Gregory Hainaut Date: Sun, 9 Oct 2016 14:46:55 +0200 Subject: [PATCH] gsdx merge: get a new buffer for the feedback write --- plugins/GSdx/GSRenderer.cpp | 5 ++++- plugins/GSdx/GSRenderer.h | 1 + plugins/GSdx/GSRendererHW.cpp | 20 ++++++++++++++++++++ plugins/GSdx/GSRendererHW.h | 1 + 4 files changed, 26 insertions(+), 1 deletion(-) diff --git a/plugins/GSdx/GSRenderer.cpp b/plugins/GSdx/GSRenderer.cpp index 6a147b9964..49ace2318b 100644 --- a/plugins/GSdx/GSRenderer.cpp +++ b/plugins/GSdx/GSRenderer.cpp @@ -201,7 +201,9 @@ bool GSRenderer::Merge(int field) s_n++; - if(samesrc && fr[0].bottom == fr[1].bottom) + bool feedback_merge = m_regs->EXTWRITE.WRITE == 1; + + if(samesrc && fr[0].bottom == fr[1].bottom && !feedback_merge) { tex[0] = GetOutput(0, y_offset[0]); tex[1] = tex[0]; // saves one texture fetch @@ -211,6 +213,7 @@ bool GSRenderer::Merge(int field) { if(en[0]) tex[0] = GetOutput(0, y_offset[0]); if(en[1]) tex[1] = GetOutput(1, y_offset[1]); + if(feedback_merge) tex[2] = GetFeedbackOutput(); } GSVector4 src[2]; diff --git a/plugins/GSdx/GSRenderer.h b/plugins/GSdx/GSRenderer.h index 06abd0a3dc..08f2b725e9 100644 --- a/plugins/GSdx/GSRenderer.h +++ b/plugins/GSdx/GSRenderer.h @@ -52,6 +52,7 @@ protected: GSVector2i m_real_size; virtual GSTexture* GetOutput(int i, int& y_offset) = 0; + virtual GSTexture* GetFeedbackOutput() { return nullptr; } public: GSWnd* m_wnd; diff --git a/plugins/GSdx/GSRendererHW.cpp b/plugins/GSdx/GSRendererHW.cpp index 1cbffeca37..bb46da8fe9 100644 --- a/plugins/GSdx/GSRendererHW.cpp +++ b/plugins/GSdx/GSRendererHW.cpp @@ -252,6 +252,26 @@ GSTexture* GSRendererHW::GetOutput(int i, int& y_offset) return t; } +GSTexture* GSRendererHW::GetFeedbackOutput() +{ + GIFRegTEX0 TEX0; + + TEX0.TBP0 = m_regs->EXTBUF.EXBP; + TEX0.TBW = m_regs->EXTBUF.EXBW; + TEX0.PSM = m_regs->DISP[m_regs->EXTBUF.FBIN & 1].DISPFB.PSM; + + GSTextureCache::Target* rt = m_tc->LookupTarget(TEX0, m_width, m_height, /*GetFrameRect(i).bottom*/0); + + GSTexture* t = rt->m_texture; + +#ifdef ENABLE_OGL_DEBUG + if(s_dump && s_savef && s_n >= s_saven) + t->Save(m_dump_root + format("%05d_f%lld_fr%d_%05x_%s.bmp", s_n, m_perfmon.GetFrame(), 3, (int)TEX0.TBP0, psm_str(TEX0.PSM))); +#endif + + return t; +} + void GSRendererHW::InvalidateVideoMem(const GIFRegBITBLTBUF& BITBLTBUF, const GSVector4i& r) { // printf("[%d] InvalidateVideoMem %d,%d - %d,%d %05x (%d)\n", (int)m_perfmon.GetFrame(), r.left, r.top, r.right, r.bottom, (int)BITBLTBUF.DBP, (int)BITBLTBUF.DPSM); diff --git a/plugins/GSdx/GSRendererHW.h b/plugins/GSdx/GSRendererHW.h index 310a38bc2c..229d0c6da6 100644 --- a/plugins/GSdx/GSRendererHW.h +++ b/plugins/GSdx/GSRendererHW.h @@ -170,6 +170,7 @@ public: void VSync(int field); void ResetDevice(); GSTexture* GetOutput(int i, int& y_offset); + GSTexture* GetFeedbackOutput(); void InvalidateVideoMem(const GIFRegBITBLTBUF& BITBLTBUF, const GSVector4i& r); void InvalidateLocalMem(const GIFRegBITBLTBUF& BITBLTBUF, const GSVector4i& r, bool clut = false); void Draw();