Skip to content

Commit f2a9214

Browse files
committed
GS: Do scissor test in autoflush handler.
The autoflush handler is called before the scissor test in the vertex kick. To save some work and prevent unnecessary autoflushes, do the scissor test in the autoflush handler also.
1 parent edb808c commit f2a9214

File tree

1 file changed

+18
-0
lines changed

1 file changed

+18
-0
lines changed

pcsx2/GS/GSState.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4041,10 +4041,13 @@ __forceinline void GSState::HandleAutoFlush()
40414041
const float K = static_cast<float>(m_context->TEX1.K) / 16;
40424042
const float powL = static_cast<float>(1 << m_context->TEX1.L);
40434043

4044+
GSVector4i xy_coord;
40444045
GSVector4i tex_coord;
40454046
float vert_lod = K;
40464047

40474048
// Prepare the currently processed vertex.
4049+
xy_coord.x = (static_cast<int>(m_v.XYZ.X) - static_cast<int>(m_context->XYOFFSET.OFX)) >> 4;
4050+
xy_coord.y = (static_cast<int>(m_v.XYZ.Y) - static_cast<int>(m_context->XYOFFSET.OFY)) >> 4;
40484051
if (PRIM->FST)
40494052
{
40504053
tex_coord.x = (m_v.U >> 4) >> tex_layer;
@@ -4062,6 +4065,7 @@ __forceinline void GSState::HandleAutoFlush()
40624065
vert_lod = -std::log2(std::abs(m_v.RGBAQ.Q)) * powL + K;
40634066
}
40644067

4068+
GSVector4i xy_rect = xy_coord.xyxy();
40654069
GSVector4i tex_rect = tex_coord.xyxy();
40664070
GSVector2i lod_range = GSVector2i(static_cast<int>(std::floor(vert_lod)), static_cast<int>(std::ceil(vert_lod)));
40674071

@@ -4072,6 +4076,8 @@ __forceinline void GSState::HandleAutoFlush()
40724076
{
40734077
const GSVertex* v = &m_vertex.buff[buff[i]];
40744078

4079+
xy_coord.x = (static_cast<int>(v->XYZ.X) - static_cast<int>(m_context->XYOFFSET.OFX)) >> 4;
4080+
xy_coord.y = (static_cast<int>(v->XYZ.Y) - static_cast<int>(m_context->XYOFFSET.OFY)) >> 4;
40754081
if (PRIM->FST)
40764082
{
40774083
tex_coord.x = (v->U >> 4) >> tex_layer;
@@ -4089,6 +4095,10 @@ __forceinline void GSState::HandleAutoFlush()
40894095
vert_lod = -std::log2(std::abs(v->RGBAQ.Q)) * powL + K;
40904096
}
40914097

4098+
xy_rect.x = std::min(xy_rect.x, xy_coord.x);
4099+
xy_rect.z = std::max(xy_rect.z, xy_coord.x);
4100+
xy_rect.y = std::min(xy_rect.y, xy_coord.y);
4101+
xy_rect.w = std::max(xy_rect.w, xy_coord.y);
40924102
tex_rect.x = std::min(tex_rect.x, tex_coord.x);
40934103
tex_rect.z = std::max(tex_rect.z, tex_coord.x);
40944104
tex_rect.y = std::min(tex_rect.y, tex_coord.y);
@@ -4102,11 +4112,19 @@ __forceinline void GSState::HandleAutoFlush()
41024112
return;
41034113

41044114
// If the draw was 1 line thick, make it larger as rects are exclusive of ends.
4115+
if (xy_rect.x == xy_rect.z)
4116+
xy_rect += GSVector4i::cxpr(0, 0, 1, 0);
4117+
if (xy_rect.y == xy_rect.w)
4118+
xy_rect += GSVector4i::cxpr(0, 0, 0, 1);
41054119
if (tex_rect.x == tex_rect.z)
41064120
tex_rect += GSVector4i::cxpr(0, 0, 1, 0);
41074121
if (tex_rect.y == tex_rect.w)
41084122
tex_rect += GSVector4i::cxpr(0, 0, 0, 1);
41094123

4124+
// If the current prim fails the scissor test then we don't need to flush.
4125+
if (xy_rect.rintersect(m_context->scissor.in).rempty())
4126+
return;
4127+
41104128
// Get the last texture position from the last draw.
41114129
const GSVertex* v = &m_vertex.buff[m_index.buff[m_index.tail - 1]];
41124130

0 commit comments

Comments
 (0)