From 29da1bb9efc6146c66a089e98aaa44bccb8e1153 Mon Sep 17 00:00:00 2001 From: Stenzek Date: Mon, 8 May 2023 21:02:43 +1000 Subject: [PATCH] GS: Make context scissor.in an integer vector Doesn't make sense for it to be floats, and saves a bunch of conversions. --- pcsx2/GS/GSDrawingContext.h | 4 ++-- pcsx2/GS/GSState.cpp | 9 ++++----- pcsx2/GS/Renderers/HW/GSRendererHW.cpp | 20 +++++++++---------- .../GS/Renderers/HW/GSRendererHWMultiISA.cpp | 2 +- pcsx2/GS/Renderers/SW/GSRendererSW.cpp | 4 ++-- 5 files changed, 19 insertions(+), 20 deletions(-) diff --git a/pcsx2/GS/GSDrawingContext.h b/pcsx2/GS/GSDrawingContext.h index 5d88010af1..17b6b08e00 100644 --- a/pcsx2/GS/GSDrawingContext.h +++ b/pcsx2/GS/GSDrawingContext.h @@ -38,7 +38,7 @@ public: struct { - GSVector4 in; + GSVector4i in; GSVector4i ex; GSVector4i ofxy; } scissor; @@ -82,7 +82,7 @@ public: scissor.ex.U16[2] = (u16)((SCISSOR.SCAX1 << 4) + XYOFFSET.OFX - 0x8000); scissor.ex.U16[3] = (u16)((SCISSOR.SCAY1 << 4) + XYOFFSET.OFY - 0x8000); - scissor.in = GSVector4( + scissor.in = GSVector4i( (int)SCISSOR.SCAX0, (int)SCISSOR.SCAY0, (int)SCISSOR.SCAX1 + 1, diff --git a/pcsx2/GS/GSState.cpp b/pcsx2/GS/GSState.cpp index add8e80ec0..3d5b21cd3e 100644 --- a/pcsx2/GS/GSState.cpp +++ b/pcsx2/GS/GSState.cpp @@ -2956,7 +2956,7 @@ __forceinline void GSState::HandleAutoFlush() tex_rect += GSVector4i(0, 0, 0, 1); const GSVector2i offset = GSVector2i(m_context->XYOFFSET.OFX, m_context->XYOFFSET.OFY); - const GSVector4i scissor = GSVector4i(m_context->scissor.in); + const GSVector4i scissor = m_context->scissor.in; GSVector4i old_tex_rect = GSVector4i::zero(); int current_draw_end = m_index.tail; @@ -3009,7 +3009,7 @@ __forceinline void GSState::HandleAutoFlush() m_vt.Update(m_vertex.buff, m_index.buff, m_vertex.tail - m_vertex.head, m_index.tail, GSUtil::GetPrimClass(PRIM->PRIM)); - GSVector4i area_out = GSVector4i(m_vt.m_min.p.xyxy(m_vt.m_max.p)).rintersect(GSVector4i(m_context->scissor.in)); + GSVector4i area_out = GSVector4i(m_vt.m_min.p.xyxy(m_vt.m_max.p)).rintersect(m_context->scissor.in); area_out = area_out & page_mask; area_out += GSVector4i(0, 0, 1, 1); // Intersect goes on space inside the rect area_out.z += GSLocalMemory::m_psm[m_context->TEX0.PSM].pgs.x; @@ -3333,8 +3333,7 @@ __forceinline void GSState::VertexKick(u32 skip) } } - const GSVector4i scissor = GSVector4i(m_context->scissor.in); - temp_draw_rect = min.upl64(max).rintersect(scissor); + temp_draw_rect = min.upl64(max).rintersect(m_context->scissor.in); } CLUTAutoFlush(prim); @@ -3498,7 +3497,7 @@ GSState::TextureMinMaxResult GSState::GetTextureMinMax(GIFRegTEX0 TEX0, GIFRegCL // When coordinates are fractional, GS appears to draw to the right/bottom (effectively // taking the ceiling), not to the top/left (taking the floor). const GSVector4i int_rc(m_vt.m_min.p.ceil().xyxy(m_vt.m_max.p.floor())); - const GSVector4i scissored_rc(int_rc.rintersect(GSVector4i(m_context->scissor.in))); + const GSVector4i scissored_rc(int_rc.rintersect(m_context->scissor.in)); if (!int_rc.eq(scissored_rc)) { // draw will get scissored, adjust UVs to suit diff --git a/pcsx2/GS/Renderers/HW/GSRendererHW.cpp b/pcsx2/GS/Renderers/HW/GSRendererHW.cpp index f8e614b0bf..8b1a751c9d 100644 --- a/pcsx2/GS/Renderers/HW/GSRendererHW.cpp +++ b/pcsx2/GS/Renderers/HW/GSRendererHW.cpp @@ -690,11 +690,11 @@ GSVector2i GSRendererHW::GetTargetSize(const GSTextureCache::Source* tex) { // Don't blindly expand out to the scissor size if we're not drawing to it. // e.g. Burnout 3, God of War II, etc. - int height = std::min(static_cast(m_context->scissor.in.w), m_r.w); + int height = std::min(m_context->scissor.in.w, m_r.w); // If the draw is less than a page high, FBW=0 is the same as FBW=1. const GSLocalMemory::psm_t& frame_psm = GSLocalMemory::m_psm[m_cached_ctx.FRAME.PSM]; - int width = std::min(std::max(m_cached_ctx.FRAME.FBW, 1) * 64, static_cast(m_context->scissor.in.z)); + int width = std::min(std::max(m_cached_ctx.FRAME.FBW, 1) * 64, m_context->scissor.in.z); if (m_cached_ctx.FRAME.FBW == 0 && m_r.w > frame_psm.pgs.y) { GL_INS("FBW=0 when drawing more than 1 page in height (PSM %s, PGS %dx%d).", psm_str(m_cached_ctx.FRAME.PSM), @@ -821,7 +821,7 @@ bool GSRendererHW::IsSplitTextureShuffle() } // Matrix Path of Neo draws 512x512 instead of 512x448, then scissors to 512x448. - aligned_rc = aligned_rc.rintersect(GSVector4i(m_context->scissor.in)); + aligned_rc = aligned_rc.rintersect(m_context->scissor.in); // We should have the same number of pages in both the position and UV. const u32 pages_high = static_cast(aligned_rc.height()) / frame_psm.pgs.y; @@ -865,7 +865,7 @@ bool GSRendererHW::IsSplitTextureShuffle() GSVector4i GSRendererHW::GetSplitTextureShuffleDrawRect() const { const GSLocalMemory::psm_t& frame_psm = GSLocalMemory::m_psm[m_cached_ctx.FRAME.PSM]; - GSVector4i r = GSVector4i(m_vt.m_min.p.upld(m_vt.m_max.p + GSVector4::cxpr(0.5f))).rintersect(GSVector4i(m_context->scissor.in)); + GSVector4i r = GSVector4i(m_vt.m_min.p.upld(m_vt.m_max.p + GSVector4::cxpr(0.5f))).rintersect(m_context->scissor.in); // Some games (e.g. Crash Twinsanity) adjust both FBP and TBP0, so the rectangle will be half the size // of the actual shuffle. Others leave the FBP alone, but only adjust TBP0, and offset the draw rectangle @@ -1574,7 +1574,7 @@ void GSRendererHW::Draw() // The rectangle of the draw rounded up. const GSVector4 rect = m_vt.m_min.p.upld(m_vt.m_max.p + GSVector4::cxpr(0.5f)); - m_r = GSVector4i(rect).rintersect(GSVector4i(context->scissor.in)); + m_r = GSVector4i(rect).rintersect(context->scissor.in); if (!m_channel_shuffle && m_cached_ctx.FRAME.Block() == m_cached_ctx.TEX0.TBP0 && IsPossibleChannelShuffle()) @@ -1602,7 +1602,7 @@ void GSRendererHW::Draw() m_r = new_r; // Adjust the scissor too, if it's in two parts, this will be wrong. - m_context->scissor.in = GSVector4(new_r); + m_context->scissor.in = new_r; // Fudge FRAME and TEX0 to point to the start of the shuffle. m_cached_ctx.TEX0.TBP0 = m_split_texture_shuffle_start_TBP; @@ -4161,7 +4161,7 @@ void GSRendererHW::ResetStates() __ri void GSRendererHW::DrawPrims(GSTextureCache::Target* rt, GSTextureCache::Target* ds, GSTextureCache::Source* tex, const TextureMinMaxResult& tmm) { #ifdef ENABLE_OGL_DEBUG - const GSVector4i area_out = GSVector4i(m_vt.m_min.p.upld(m_vt.m_max.p)).rintersect(GSVector4i(m_context->scissor.in)); + const GSVector4i area_out = GSVector4i(m_vt.m_min.p.upld(m_vt.m_max.p)).rintersect(m_context->scissor.in); const GSVector4i area_in = GSVector4i(m_vt.m_min.t.upld(m_vt.m_max.t)); GL_PUSH("GL Draw from (area %d,%d => %d,%d) in (area %d,%d => %d,%d)", @@ -4511,8 +4511,8 @@ __ri void GSRendererHW::DrawPrims(GSTextureCache::Target* rt, GSTextureCache::Ta } // rs - const GSVector4 hacked_scissor(m_channel_shuffle ? GSVector4(0, 0, 1024, 1024) : m_context->scissor.in); - const GSVector4i scissor(GSVector4i(GSVector4(rtscale) * hacked_scissor).rintersect(GSVector4i(rtsize).zwxy())); + const GSVector4i hacked_scissor = m_channel_shuffle ? GSVector4i::cxpr(0, 0, 1024, 1024) : m_context->scissor.in; + const GSVector4i scissor(GSVector4i(GSVector4(rtscale) * GSVector4(hacked_scissor)).rintersect(GSVector4i::loadh(rtsize))); m_conf.drawarea = m_channel_shuffle ? scissor : scissor.rintersect(ComputeBoundingBox(rtsize, rtscale)); m_conf.scissor = (DATE && !DATE_BARRIER) ? m_conf.drawarea : scissor; @@ -5060,7 +5060,7 @@ bool GSRendererHW::OI_GsMemClear() if ((PrimitiveCoversWithoutGaps() || ZisFrame) && m_vt.m_eq.rgba == 0xFFFF) { const GSOffset& off = m_context->offset.fb; - GSVector4i r = GSVector4i(m_vt.m_min.p.upld(m_vt.m_max.p)).rintersect(GSVector4i(m_context->scissor.in)); + GSVector4i r = GSVector4i(m_vt.m_min.p.upld(m_vt.m_max.p)).rintersect(m_context->scissor.in); if (r.width() == 32 && ZisFrame) r.z += 32; diff --git a/pcsx2/GS/Renderers/HW/GSRendererHWMultiISA.cpp b/pcsx2/GS/Renderers/HW/GSRendererHWMultiISA.cpp index 7918366fd9..ba497b7da2 100644 --- a/pcsx2/GS/Renderers/HW/GSRendererHWMultiISA.cpp +++ b/pcsx2/GS/Renderers/HW/GSRendererHWMultiISA.cpp @@ -67,7 +67,7 @@ bool GSRendererHWFunctions::SwPrimRender(GSRendererHW& hw, bool invalidate_tc) const u32 q_div = !hw.IsMipMapActive() && ((vt.m_eq.q && vt.m_min.t.z != 1.0f) || (!vt.m_eq.q && vt.m_primclass == GS_SPRITE_CLASS)); GSVertexSW::s_cvb[vt.m_primclass][PRIM->TME][PRIM->FST][q_div](context, data.vertex, hw.m_vertex.buff, hw.m_vertex.next); - GSVector4i scissor = GSVector4i(context->scissor.in); + GSVector4i scissor = context->scissor.in; GSVector4i bbox = GSVector4i(vt.m_min.p.floor().xyxy(vt.m_max.p.ceil())); // Points and lines may have zero area bbox (single line: 0, 0 - 256, 0) diff --git a/pcsx2/GS/Renderers/SW/GSRendererSW.cpp b/pcsx2/GS/Renderers/SW/GSRendererSW.cpp index 983032cdf1..9f4739b57a 100644 --- a/pcsx2/GS/Renderers/SW/GSRendererSW.cpp +++ b/pcsx2/GS/Renderers/SW/GSRendererSW.cpp @@ -356,8 +356,8 @@ void GSRendererSW::Draw() std::memcpy(sd->index, m_index.buff, sizeof(u16) * m_index.tail); - GSVector4i scissor = GSVector4i(context->scissor.in); - GSVector4i bbox = GSVector4i(m_vt.m_min.p.floor().xyxy(m_vt.m_max.p.ceil())); + GSVector4i scissor = context->scissor.in; + GSVector4i bbox = GSVector4i(m_vt.m_min.p.floor().upld(m_vt.m_max.p.ceil())); // points and lines may have zero area bbox (single line: 0, 0 - 256, 0)