From e0418c3c342c6045c49c121ec10b7289d31d5a3d Mon Sep 17 00:00:00 2001 From: Sergey Lipskiy Date: Fri, 29 Jun 2018 19:10:27 +0700 Subject: [PATCH] Apply TexrectDrawer if next draw command is also texrect and those texrect is side-by-side with the current one. It should fix performance issues with particles. Currently works only in HLE mode. --- src/GraphicsDrawer.cpp | 44 ++++++++++++------------- src/TexrectDrawer.cpp | 75 +++++++++++++++++++++++++++++++++++++++++- src/TexrectDrawer.h | 3 +- 3 files changed, 97 insertions(+), 25 deletions(-) diff --git a/src/GraphicsDrawer.cpp b/src/GraphicsDrawer.cpp index 291fac66..7e99f4bb 100644 --- a/src/GraphicsDrawer.cpp +++ b/src/GraphicsDrawer.cpp @@ -1339,31 +1339,29 @@ void GraphicsDrawer::drawTexturedRect(const TexturedRectParams & _params) m_rect[i].x *= scale; } - if (bUseTexrectDrawer) - m_texrectDrawer.add(); - else { - _updateScreenCoordsViewport(); + if (bUseTexrectDrawer && m_texrectDrawer.add()) + return; - Context::DrawRectParameters rectParams; - rectParams.mode = drawmode::TRIANGLE_STRIP; - rectParams.verticesCount = 4; - rectParams.vertices = m_rect; - rectParams.combiner = currentCombiner(); - gfxContext.drawRects(rectParams); - if (g_debugger.isCaptureMode()) { - m_rect[0].x = _params.ulx; - m_rect[0].y = _params.uly; - m_rect[1].x = _params.lrx; - m_rect[1].y = _params.uly; - m_rect[2].x = _params.ulx; - m_rect[2].y = _params.lry; - m_rect[3].x = _params.lrx; - m_rect[3].y = _params.lry; - g_debugger.addRects(rectParams); - } - - gSP.changed |= CHANGED_GEOMETRYMODE | CHANGED_VIEWPORT; + _updateScreenCoordsViewport(); + Context::DrawRectParameters rectParams; + rectParams.mode = drawmode::TRIANGLE_STRIP; + rectParams.verticesCount = 4; + rectParams.vertices = m_rect; + rectParams.combiner = currentCombiner(); + gfxContext.drawRects(rectParams); + if (g_debugger.isCaptureMode()) { + m_rect[0].x = _params.ulx; + m_rect[0].y = _params.uly; + m_rect[1].x = _params.lrx; + m_rect[1].y = _params.uly; + m_rect[2].x = _params.ulx; + m_rect[2].y = _params.lry; + m_rect[3].x = _params.lrx; + m_rect[3].y = _params.lry; + g_debugger.addRects(rectParams); } + + gSP.changed |= CHANGED_GEOMETRYMODE | CHANGED_VIEWPORT; } void GraphicsDrawer::correctTexturedRectParams(TexturedRectParams & _params) diff --git a/src/TexrectDrawer.cpp b/src/TexrectDrawer.cpp index c7569e3c..1ee0f2cb 100644 --- a/src/TexrectDrawer.cpp +++ b/src/TexrectDrawer.cpp @@ -6,6 +6,7 @@ #include #include "DisplayWindow.h" #include "Textures.h" +#include "RSP.h" #include "VI.h" #include "FrameBuffer.h" #include "TexrectDrawer.h" @@ -114,7 +115,71 @@ void TexrectDrawer::_setDrawBuffer() frameBufferList().setCurrentDrawBuffer(); } -void TexrectDrawer::add() +bool TexrectDrawer::_lookAhead(bool _checkCoordinates) const +{ + if (RSP.LLE) + return true; + switch (GBI.getMicrocodeType()) { + case Turbo3D: + case T3DUX: + case F5Rogue: + case F5Indi_Naboo: + return true; + } + + auto sideBySide = [](u32 pc) ->bool { + const u32 ulx = _SHIFTR(RSP.w1, 12, 12); + const u32 uly = _SHIFTR(RSP.w1, 0, 12); + const u32 lrx = _SHIFTR(RSP.w0, 12, 12); + const u32 lry = _SHIFTR(RSP.w0, 0, 12); + + const u32 w0 = *(u32*)&RDRAM[pc]; + const u32 w1 = *(u32*)&RDRAM[pc + 4]; + const u32 ulx_next = _SHIFTR(w1, 12, 12); + const u32 uly_next = _SHIFTR(w1, 0, 12); + const u32 lrx_next = _SHIFTR(w0, 12, 12); + const u32 lry_next = _SHIFTR(w0, 0, 12); + + if (ulx == ulx_next) { + bool sbs = lry == uly_next; + sbs |= uly == lry_next; + return sbs; + } + if (uly == uly_next) { + bool sbs = lrx == ulx_next; + sbs |= ulx == lrx_next; + return sbs; + } + return false; + }; + + u32 pc = RSP.PC[RSP.PCi] + 8; + while (true) { + switch (_SHIFTR(*(u32*)&RDRAM[pc], 24, 8)) { + case G_RDPLOADSYNC: + case G_RDPPIPESYNC: + case G_RDPTILESYNC: + case G_LOADTLUT: + case G_SETTILESIZE: + case G_LOADBLOCK: + case G_LOADTILE: + case G_SETTILE: + case G_SETTIMG: + break; + case G_TEXRECT: + case G_TEXRECTFLIP: + if (_checkCoordinates) + return sideBySide(pc); + return true; + default: + return false; + } + pc += 8; + } + return false; +} + +bool TexrectDrawer::add() { DisplayWindow & wnd = dwnd(); GraphicsDrawer & drawer = wnd.getDrawer(); @@ -148,6 +213,9 @@ void TexrectDrawer::add() } if (m_numRects == 0) { + if (!_lookAhead(true)) + return false; + m_numRects = 1; m_pBuffer = frameBufferList().getCurrent(); m_otherMode = gDP.otherMode._u64; @@ -201,6 +269,11 @@ void TexrectDrawer::add() rectParams.vertices = pRect; rectParams.combiner = currentCombiner(); gfxContext.drawRects(rectParams); + + if (m_numRects > 1 && !_lookAhead(false)) + draw(); + + return true; } bool TexrectDrawer::draw() diff --git a/src/TexrectDrawer.h b/src/TexrectDrawer.h index 3a5bbd88..7d4e6909 100644 --- a/src/TexrectDrawer.h +++ b/src/TexrectDrawer.h @@ -17,7 +17,7 @@ public: void init(); void destroy(); - void add(); + bool add(); bool draw(); bool isEmpty() const; bool canContinue() const; @@ -25,6 +25,7 @@ public: private: void _setViewport() const; void _setDrawBuffer(); + bool _lookAhead(bool _checkCoordinates) const; u32 m_numRects; u64 m_otherMode;