From 81318c54456957b818e51aa37c31b9ead62ae7c9 Mon Sep 17 00:00:00 2001 From: s2s <12202580+standard-two-simplex@users.noreply.github.com> Date: Fri, 5 Mar 2021 18:28:25 +0100 Subject: [PATCH] Use screen coordinates to render primitives --- src/BufferCopy/RDRAMtoColorBuffer.cpp | 1 - .../GLSL/glsl_CombinerProgramBuilder.cpp | 47 +++--- .../glsl_CombinerProgramUniformFactory.cpp | 38 ++--- src/GraphicsDrawer.cpp | 134 ++++-------------- src/GraphicsDrawer.h | 3 +- src/TexrectDrawer.cpp | 2 +- src/gSP.cpp | 28 +--- 7 files changed, 79 insertions(+), 174 deletions(-) diff --git a/src/BufferCopy/RDRAMtoColorBuffer.cpp b/src/BufferCopy/RDRAMtoColorBuffer.cpp index d65eb747..bb4fe0ec 100644 --- a/src/BufferCopy/RDRAMtoColorBuffer.cpp +++ b/src/BufferCopy/RDRAMtoColorBuffer.cpp @@ -179,7 +179,6 @@ u32 RGBA32ToABGR32(u32 col, bool _fullAlpha) void RDRAMtoColorBuffer::_copyFromRDRAM(u32 _height, bool _fullAlpha) { Cleaner cleaner(this); - ValueKeeper otherMode(gSP.clipRatio, 1U); const u32 address = m_pCurBuffer->m_startAddress; const u32 width = m_pCurBuffer->m_width; const u32 height = _height; diff --git a/src/Graphics/OpenGLContext/GLSL/glsl_CombinerProgramBuilder.cpp b/src/Graphics/OpenGLContext/GLSL/glsl_CombinerProgramBuilder.cpp index 1ce273b7..5939f66e 100644 --- a/src/Graphics/OpenGLContext/GLSL/glsl_CombinerProgramBuilder.cpp +++ b/src/Graphics/OpenGLContext/GLSL/glsl_CombinerProgramBuilder.cpp @@ -267,7 +267,6 @@ public: ss << "# define IN in" << std::endl << "# define OUT out" << std::endl; m_part = ss.str(); } - m_part += "uniform lowp float uClipRatio; \n"; } }; @@ -296,6 +295,8 @@ public: "uniform mediump vec2 uCacheScale[2]; \n" "uniform mediump vec2 uCacheOffset[2]; \n" "uniform mediump vec2 uCacheShiftScale[2]; \n" + "uniform mediump vec2 uVTrans; \n" + "uniform mediump vec2 uVScale; \n" "uniform lowp ivec2 uCacheFrameBuffer; \n" "OUT highp vec2 vTexCoord0; \n" "OUT highp vec2 vTexCoord1; \n" @@ -330,17 +331,17 @@ public: " vTexCoord1 = calcTexCoord(texCoord, 1); \n" " vLodTexCoord = texCoord; \n" " vNumLights = aNumLights; \n" - " if (aModify != vec4(0.0)) { \n" - " if ((aModify[0]) != 0.0) { \n" - " gl_Position.xy = gl_Position.xy * uScreenCoordsScale + vec2(-1.0, 1.0); \n" - " gl_Position.xy *= gl_Position.w; \n" - " } \n" - " if ((aModify[1]) != 0.0) \n" - " gl_Position.z *= gl_Position.w; \n" - " if ((aModify[3]) != 0.0) \n" - " vNumLights = 0.0; \n" + " if ((aModify[0]) != 0.0) { \n" + " gl_Position.xy *= gl_Position.w; \n" " } \n" - " gl_Position.y = -gl_Position.y; \n" + " else { \n" + " gl_Position.xy = gl_Position.xy * uVScale.xy + uVTrans.xy * gl_Position.ww; \n" + " gl_Position.xy = floor(gl_Position.xy * vec2(4.0)) * vec2(0.25); \n" + " } \n" + " if ((aModify[1]) != 0.0) \n" + " gl_Position.z *= gl_Position.w; \n" + " if ((aModify[3]) != 0.0) \n" + " vNumLights = 0.0; \n" " if (uFogUsage > 0) { \n" " lowp float fp; \n" " if (aPosition.z < -aPosition.w && aModify[1] == 0.0) \n" @@ -374,6 +375,8 @@ public: "uniform lowp int uFogUsage; \n" "uniform mediump vec2 uFogScale; \n" "uniform mediump vec2 uScreenCoordsScale; \n" + "uniform mediump vec2 uVTrans; \n" + "uniform mediump vec2 uVScale; \n" " \n" "OUT lowp float vNumLights; \n" "OUT lowp vec4 vShadeColor; \n" @@ -390,17 +393,17 @@ public: " gl_Position = aPosition; \n" " vShadeColor = aColor; \n" " vNumLights = aNumLights; \n" - " if (aModify != vec4(0.0)) { \n" - " if ((aModify[0]) != 0.0) { \n" - " gl_Position.xy = gl_Position.xy * uScreenCoordsScale + vec2(-1.0, 1.0); \n" - " gl_Position.xy *= gl_Position.w; \n" - " } \n" - " if ((aModify[1]) != 0.0) \n" - " gl_Position.z *= gl_Position.w; \n" - " if ((aModify[3]) != 0.0) \n" - " vNumLights = 0.0; \n" + " if ((aModify[0]) != 0.0) { \n" + " gl_Position.xy *= gl_Position.w; \n" " } \n" - " gl_Position.y = -gl_Position.y; \n" + " else { \n" + " gl_Position.xy = gl_Position.xy * uVScale.xy + uVTrans.xy * gl_Position.ww; \n" + " gl_Position.xy = floor(gl_Position.xy * vec2(4.0)) * vec2(0.25); \n" + " } \n" + " if ((aModify[1]) != 0.0) \n" + " gl_Position.z *= gl_Position.w; \n" + " if ((aModify[3]) != 0.0) \n" + " vNumLights = 0.0; \n" " if (uFogUsage > 0) { \n" " lowp float fp; \n" " if (aPosition.z < -aPosition.w && aModify[1] == 0.0) \n" @@ -503,7 +506,7 @@ public: m_part = " gl_Position.z /= 8.0; \n"; } m_part += - " gl_Position.zw *= vec2(uClipRatio); \n" + " gl_Position.zw *= vec2(1024.0f); \n" "} \n" ; } diff --git a/src/Graphics/OpenGLContext/GLSL/glsl_CombinerProgramUniformFactory.cpp b/src/Graphics/OpenGLContext/GLSL/glsl_CombinerProgramUniformFactory.cpp index d3efd7ad..7237a1c1 100644 --- a/src/Graphics/OpenGLContext/GLSL/glsl_CombinerProgramUniformFactory.cpp +++ b/src/Graphics/OpenGLContext/GLSL/glsl_CombinerProgramUniformFactory.cpp @@ -603,6 +603,25 @@ private: fUniform uAlphaTestValue; }; +class UViewportInfo : public UniformGroup +{ +public: + UViewportInfo(GLuint _program) { + LocateUniform(uVTrans); + LocateUniform(uVScale); + } + + void update(bool _force) override + { + uVTrans.set(gSP.viewport.vtrans[0], gSP.viewport.vtrans[1], _force); + uVScale.set(gSP.viewport.vscale[0], -gSP.viewport.vscale[1], _force); + } + +private: + fv2Uniform uVTrans; + fv2Uniform uVScale; +}; + class UDepthScale : public UniformGroup { public: @@ -738,22 +757,6 @@ private: iUniform uClampMode; }; -class UClipRatio : public UniformGroup -{ -public: - UClipRatio(GLuint _program) { - LocateUniform(uClipRatio); - } - - void update(bool _force) override - { - uClipRatio.set(float(gSP.clipRatio), _force); - } - -private: - fUniform uClipRatio; -}; - class UPolygonOffset : public UniformGroup { public: @@ -1094,6 +1097,7 @@ void CombinerProgramUniformFactory::buildUniforms(GLuint _program, { _uniforms.emplace_back(new UNoiseTex(_program)); _uniforms.emplace_back(new UScreenSpaceTriangleInfo(_program)); + _uniforms.emplace_back(new UViewportInfo(_program)); if (!m_glInfo.isGLES2) { _uniforms.emplace_back(new UDepthTex(_program)); @@ -1165,8 +1169,6 @@ void CombinerProgramUniformFactory::buildUniforms(GLuint _program, _uniforms.emplace_back(new UPolygonOffset(_program)); } - _uniforms.emplace_back(new UClipRatio(_program)); - _uniforms.emplace_back(new UScreenCoordsScale(_program)); _uniforms.emplace_back(new UColors(_program)); diff --git a/src/GraphicsDrawer.cpp b/src/GraphicsDrawer.cpp index 86bf0605..b28d741d 100644 --- a/src/GraphicsDrawer.cpp +++ b/src/GraphicsDrawer.cpp @@ -238,86 +238,25 @@ void GraphicsDrawer::updateScissor(FrameBuffer * _pBuffer) const gDP.changed &= ~CHANGED_SCISSOR; } -inline -float _adjustViewportX(f32 _X0) +void GraphicsDrawer::_updateViewport(const FrameBuffer* _pBuffer, const f32 scale) const { - const f32 halfX = gDP.colorImage.width / 2.0f; - const f32 halfVP = gSP.viewport.width / 2.0f; - return (_X0 + halfVP - halfX) * dwnd().getAdjustScale() + halfX - halfVP; -} - -inline -void _adjustViewportToClipRatio(s32 & x, s32 & y, s32 & width, s32 & height) -{ - x -= static_cast(gSP.clipRatio - 1) * width / 2; - y -= static_cast(gSP.clipRatio - 1) * height / 2; - width *= gSP.clipRatio; - height *= gSP.clipRatio; -} - - -void GraphicsDrawer::_updateViewport() const -{ - DisplayWindow & wnd = DisplayWindow::get(); - FrameBuffer * pCurrentBuffer = frameBufferList().getCurrent(); - if (pCurrentBuffer == nullptr) { - const f32 scaleX = wnd.getScaleX(); - const f32 scaleY = wnd.getScaleY(); - float Xf = gSP.viewport.vscale[0] < 0 ? (gSP.viewport.x + gSP.viewport.vscale[0] * 2.0f) : gSP.viewport.x; - if (_needAdjustCoordinate(wnd)) - Xf = _adjustViewportX(Xf); - s32 X = static_cast(Xf * scaleX); - s32 Y = static_cast(gSP.viewport.y * scaleY); - s32 WIDTH = std::max(static_cast(gSP.viewport.width * scaleX), 0); - s32 HEIGHT = std::max(static_cast(gSP.viewport.height * scaleY), 0); - _adjustViewportToClipRatio(X, Y, WIDTH, HEIGHT); - gfxContext.setViewport(X, Y, WIDTH, HEIGHT); - } else { - const f32 scaleX = pCurrentBuffer->m_scale; - const f32 scaleY = pCurrentBuffer->m_scale; - float Xf = gSP.viewport.vscale[0] < 0 ? (gSP.viewport.x + gSP.viewport.vscale[0] * 2.0f) : gSP.viewport.x; - Xf += f32(pCurrentBuffer->m_originX); - if (_needAdjustCoordinate(wnd)) - Xf = _adjustViewportX(Xf); - s32 X = roundup(Xf, scaleX); - float Yf = gSP.viewport.vscale[1] < 0 ? (gSP.viewport.y + gSP.viewport.vscale[1] * 2.0f) : gSP.viewport.y; - Yf += f32(pCurrentBuffer->m_originY); - s32 Y = roundup(Yf, scaleY); - s32 WIDTH = std::max(roundup(gSP.viewport.width, scaleX), 0); - s32 HEIGHT = std::max(roundup(gSP.viewport.height, scaleY), 0); - _adjustViewportToClipRatio(X, Y, WIDTH, HEIGHT); - gfxContext.setViewport(X, Y, WIDTH, HEIGHT); - } - gSP.changed &= ~CHANGED_VIEWPORT; -} - -void GraphicsDrawer::_updateScreenCoordsViewport(const FrameBuffer * _pBuffer) const -{ - DisplayWindow & wnd = DisplayWindow::get(); - const FrameBuffer * pCurrentBuffer = _pBuffer != nullptr ? _pBuffer : frameBufferList().getCurrent(); - - u32 bufferWidth, bufferHeight; - f32 viewportScaleX, viewportScaleY; - s32 X = 0, Y = 0; - if (pCurrentBuffer == nullptr) { - bufferWidth = VI.width; - bufferHeight = VI.height; - viewportScaleX = wnd.getScaleX(); - viewportScaleY = wnd.getScaleY(); - } else { - bufferWidth = pCurrentBuffer->m_width; - bufferHeight = VI_GetMaxBufferHeight(static_cast(bufferWidth)); - viewportScaleX = viewportScaleY = pCurrentBuffer->m_scale; - X = roundup(f32(pCurrentBuffer->m_originX), viewportScaleX); - Y = roundup(f32(pCurrentBuffer->m_originY), viewportScaleY); - if (RSP.LLE || gSP.viewport.width == 0.0f) { - gSP.viewport.width = f32(bufferWidth); - gSP.viewport.height = f32(bufferHeight); + s32 X, Y, WIDTH, HEIGHT; + f32 scaleX, scaleY; + if (scale == 0.0f) { + const FrameBuffer* pCurrentBuffer = _pBuffer != nullptr ? _pBuffer : frameBufferList().getCurrent(); + if (pCurrentBuffer != nullptr) { + scaleX = scaleY = pCurrentBuffer->m_scale; + } else { + scaleX = dwnd().getScaleX(); + scaleY = dwnd().getScaleY(); } + } else { + scaleX = scaleY = scale; } - s32 WIDTH = roundup(f32(bufferWidth), viewportScaleX); - s32 HEIGHT = roundup(f32(bufferHeight), viewportScaleY); - _adjustViewportToClipRatio(X, Y, WIDTH, HEIGHT); + X = roundup(-1024.0f, scaleX); + Y = roundup(-1024.0f, scaleY); + WIDTH = roundup(2048.0f, scaleX); + HEIGHT = roundup(2048.0f, scaleY); gfxContext.setViewport(X, Y, WIDTH, HEIGHT); gSP.changed |= CHANGED_VIEWPORT; } @@ -796,7 +735,7 @@ void GraphicsDrawer::_prepareDrawTriangle(DrawingState _drawingState) m_bFlatColors = bFlatColors; if ((m_modifyVertices & MODIFY_XY) != 0) - _updateScreenCoordsViewport(); + _updateViewport(); m_modifyVertices = 0; } @@ -853,8 +792,6 @@ void GraphicsDrawer::drawScreenSpaceTriangle(u32 _numVtx, graphics::DrawModePara if (_numVtx == 0 || !_canDraw()) return; - ValueKeeper otherMode(gSP.clipRatio, 1U); - f32 maxY = 0; for (u32 i = 0; i < _numVtx; ++i) { SPVertex & vtx = m_dmaVertices[i]; @@ -1042,7 +979,7 @@ void GraphicsDrawer::drawLine(u32 _v0, u32 _v1, float _width) m_drawingState = DrawingState::Line; if ((triangles.vertices[_v0].modify & MODIFY_XY) != 0) - _updateScreenCoordsViewport(); + _updateViewport(); SPVertex vertexBuf[2] = { triangles.vertices[_v0], triangles.vertices[_v1] }; gfxContext.drawLine(lineWidth, vertexBuf); @@ -1050,7 +987,6 @@ void GraphicsDrawer::drawLine(u32 _v0, u32 _v1, float _width) void GraphicsDrawer::drawRect(int _ulx, int _uly, int _lrx, int _lry) { - ValueKeeper otherMode(gSP.clipRatio, 1U); m_texrectDrawer.draw(); m_statistics.fillRects++; @@ -1064,24 +1000,22 @@ void GraphicsDrawer::drawRect(int _ulx, int _uly, int _lrx, int _lry) m_drawingState = DrawingState::Rect; - _updateScreenCoordsViewport(); + _updateViewport(); gfxContext.enable(enable::CULL_FACE, false); - f32 scaleX, scaleY; - calcCoordsScales(frameBufferList().getCurrent(), scaleX, scaleY); const float Z = (gDP.otherMode.depthSource == G_ZS_PRIM) ? gDP.primDepth.z : 0.0f; const float W = 1.0f; - m_rect[0].x = static_cast(_ulx) * (2.0f * scaleX) - 1.0f; - m_rect[0].y = static_cast(_uly) * (2.0f * scaleY) - 1.0f; + m_rect[0].x = static_cast(_ulx); + m_rect[0].y = static_cast(_uly); m_rect[0].z = Z; m_rect[0].w = W; - m_rect[1].x = static_cast(_lrx) * (2.0f * scaleX) - 1.0f; + m_rect[1].x = static_cast(_lrx); m_rect[1].y = m_rect[0].y; m_rect[1].z = Z; m_rect[1].w = W; m_rect[2].x = m_rect[0].x; - m_rect[2].y = static_cast(_lry) * (2.0f * scaleY) - 1.0f; + m_rect[2].y = static_cast(_lry); m_rect[2].z = Z; m_rect[2].w = W; m_rect[3].x = m_rect[1].x; @@ -1265,7 +1199,6 @@ void GraphicsDrawer::drawTexturedRect(const TexturedRectParams & _params) gSP.changed &= ~CHANGED_GEOMETRYMODE; // Don't update cull mode m_drawingState = DrawingState::TexRect; m_statistics.texRects++; - ValueKeeper otherMode(gSP.clipRatio, 1U); if (m_texrectDrawer.canContinue()) { CombinerInfo & cmbInfo = CombinerInfo::get(); @@ -1305,14 +1238,13 @@ void GraphicsDrawer::drawTexturedRect(const TexturedRectParams & _params) && ((cache.current[0]->frameBufferTexture == CachedTexture::fbNone && !cache.current[0]->bHDTexture)) && (cache.current[1] == nullptr || (cache.current[1]->frameBufferTexture == CachedTexture::fbNone && !cache.current[1]->bHDTexture))); - f32 scaleX, scaleY; - calcCoordsScales(pCurrentBuffer, scaleX, scaleY); const float Z = (gDP.otherMode.depthSource == G_ZS_PRIM) ? gDP.primDepth.z : 0.0f; const float W = 1.0f; - const f32 ulx = _params.ulx * (2.0f * scaleX) - 1.0f; - const f32 uly = _params.uly * (2.0f * scaleY) - 1.0f; - const f32 lrx = _params.lrx * (2.0f * scaleX) - 1.0f; - const f32 lry = _params.lry * (2.0f * scaleY) - 1.0f; + const f32 ulx = _params.ulx; + const f32 uly = _params.uly; + const f32 lrx = _params.lrx; + const f32 lry = _params.lry; + m_rect[0].x = ulx; m_rect[0].y = uly; m_rect[0].z = Z; @@ -1505,7 +1437,7 @@ void GraphicsDrawer::drawTexturedRect(const TexturedRectParams & _params) return; } - _updateScreenCoordsViewport(_params.pBuffer); + _updateViewport(_params.pBuffer); Context::DrawRectParameters rectParams; rectParams.mode = drawmode::TRIANGLE_STRIP; rectParams.verticesCount = 4; @@ -1513,14 +1445,6 @@ void GraphicsDrawer::drawTexturedRect(const TexturedRectParams & _params) 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); } diff --git a/src/GraphicsDrawer.h b/src/GraphicsDrawer.h index de06d595..87f432ac 100644 --- a/src/GraphicsDrawer.h +++ b/src/GraphicsDrawer.h @@ -190,8 +190,7 @@ private: void _ordinaryBlending() const; void _dualSourceBlending() const; void _updateCullFace() const; - void _updateViewport() const; - void _updateScreenCoordsViewport(const FrameBuffer * _pBuffer = nullptr) const; + void _updateViewport(const FrameBuffer * _pBuffer = nullptr, const f32 scale = 0.0f) const; void _updateDepthUpdate() const; void _updateDepthCompare() const; void _updateTextures() const; diff --git a/src/TexrectDrawer.cpp b/src/TexrectDrawer.cpp index e8335235..313429cc 100644 --- a/src/TexrectDrawer.cpp +++ b/src/TexrectDrawer.cpp @@ -387,7 +387,7 @@ bool TexrectDrawer::draw() const float t1 = (m_uly + 1.0f) / scaleY / (float)m_pTexture->height; const float W = 1.0f; - drawer._updateScreenCoordsViewport(m_pBuffer); + drawer._updateViewport(m_pBuffer); textureCache().activateTexture(0, m_pTexture); // Disable filtering to avoid black outlines diff --git a/src/gSP.cpp b/src/gSP.cpp index e9cf9d3b..3d6a43bf 100644 --- a/src/gSP.cpp +++ b/src/gSP.cpp @@ -826,18 +826,6 @@ void gSPProcessVertex(u32 v, SPVertex * spVtx) vtx.w *= adjustScale; } } - if (gSP.viewport.vscale[0] < 0) { - for(int i = 0; i < VNUM; ++i) { - SPVertex & vtx = spVtx[v+i]; - vtx.x = -vtx.x; - } - } - if (gSP.viewport.vscale[1] < 0) { - for(int i = 0; i < VNUM; ++i) { - SPVertex & vtx = spVtx[v+i]; - vtx.y = -vtx.y; - } - } if (gSP.matrix.billboard) gSPBillboardVertex(v, spVtx); @@ -1670,32 +1658,22 @@ void gSPModifyVertex( u32 _vtx, u32 _where, u32 _val ) case G_MWO_POINT_XYSCREEN: vtx0.x = _FIXED2FLOAT((s16)_SHIFTR(_val, 16, 16), 2); vtx0.y = _FIXED2FLOAT((s16)_SHIFTR(_val, 0, 16), 2); - DebugMsg(DEBUG_NORMAL, "gSPModifyVertex: XY(%02f, %02f);\n", vtx0.x, vtx0.y); + vtx0.modify |= MODIFY_XY; + vtx0.clip &= ~(CLIP_POSX | CLIP_NEGX | CLIP_POSY | CLIP_NEGY); if ((config.generalEmulation.hacks & hack_ModifyVertexXyInShader) == 0) { - vtx0.x = (vtx0.x - gSP.viewport.vtrans[0]) / gSP.viewport.vscale[0]; - if (gSP.viewport.vscale[0] < 0) - vtx0.x = -vtx0.x; - vtx0.x *= vtx0.w; - if (dwnd().isAdjustScreen()) { const f32 adjustScale = dwnd().getAdjustScale(); vtx0.x *= adjustScale; if (gSP.matrix.projection[3][2] == -1.f) vtx0.w *= adjustScale; } - - vtx0.y = -(vtx0.y - gSP.viewport.vtrans[1]) / gSP.viewport.vscale[1]; - if (gSP.viewport.vscale[1] < 0) - vtx0.y = -vtx0.y; - vtx0.y *= vtx0.w; } else { - vtx0.modify |= MODIFY_XY; if (vtx0.w == 0.0f || gDP.otherMode.depthSource == G_ZS_PRIM) { vtx0.w = 1.0f; vtx0.clip &= ~(CLIP_W); } } - vtx0.clip &= ~(CLIP_POSX | CLIP_NEGX | CLIP_POSY | CLIP_NEGY); + DebugMsg(DEBUG_NORMAL, "gSPModifyVertex: XY(%02f, %02f);\n", vtx0.x, vtx0.y); break; case G_MWO_POINT_ZSCREEN: {