GS/HW: Detect shuffles using quads

This commit is contained in:
refractionpcsx2 2024-04-25 20:20:03 +01:00
parent d63966b071
commit f5276f13ae
3 changed files with 16 additions and 8 deletions

View File

@ -2820,7 +2820,7 @@ void GSState::GrowVertexBuffer()
m_index.buff = index; m_index.buff = index;
} }
bool GSState::TrianglesAreQuads() const bool GSState::TrianglesAreQuads(bool shuffle_check) const
{ {
// If this is a quad, there should only be two distinct values for both X and Y, which // If this is a quad, there should only be two distinct values for both X and Y, which
// also happen to be the minimum/maximum bounds of the primitive. // also happen to be the minimum/maximum bounds of the primitive.
@ -2833,10 +2833,17 @@ bool GSState::TrianglesAreQuads() const
if (idx > 0) if (idx > 0)
{ {
const u16* const prev_tri= m_index.buff + (idx - 3); const u16* const prev_tri= m_index.buff + (idx - 3);
const GSVertex& vert = v[i[0]]; GIFRegXYZ vert = v[i[0]].XYZ;
const GSVertex& last_vert = v[i[2]]; GIFRegXYZ last_vert = v[i[2]].XYZ;
if (vert.XYZ != m_vertex.buff[prev_tri[0]].XYZ && vert.XYZ != m_vertex.buff[prev_tri[1]].XYZ && vert.XYZ != m_vertex.buff[prev_tri[2]].XYZ &&
last_vert.XYZ != m_vertex.buff[prev_tri[0]].XYZ && last_vert.XYZ != m_vertex.buff[prev_tri[1]].XYZ && last_vert.XYZ != m_vertex.buff[prev_tri[2]].XYZ) if (shuffle_check)
{
vert.X -= 8 << 4;
last_vert.X -= 8 << 4;
}
if (vert != m_vertex.buff[prev_tri[0]].XYZ && vert != m_vertex.buff[prev_tri[1]].XYZ && vert != m_vertex.buff[prev_tri[2]].XYZ &&
last_vert != m_vertex.buff[prev_tri[0]].XYZ && last_vert != m_vertex.buff[prev_tri[1]].XYZ && last_vert != m_vertex.buff[prev_tri[2]].XYZ)
return false; return false;
} }
// Degenerate triangles should've been culled already, so we can check indices. // Degenerate triangles should've been culled already, so we can check indices.

View File

@ -409,7 +409,7 @@ public:
void DumpVertices(const std::string& filename); void DumpVertices(const std::string& filename);
bool TrianglesAreQuads() const; bool TrianglesAreQuads(bool shuffle_check = false) const;
PRIM_OVERLAP PrimitiveOverlap(); PRIM_OVERLAP PrimitiveOverlap();
bool PrimitiveCoversWithoutGaps(); bool PrimitiveCoversWithoutGaps();
GIFRegTEX0 GetTex0Layer(u32 lod); GIFRegTEX0 GetTex0Layer(u32 lod);

View File

@ -2709,8 +2709,9 @@ void GSRendererHW::Draw()
// Both input and output are 16 bits and texture was initially 32 bits! Same for the target, Sonic Unleash makes a new target which really is 16bit. // Both input and output are 16 bits and texture was initially 32 bits! Same for the target, Sonic Unleash makes a new target which really is 16bit.
m_texture_shuffle = ((m_same_group_texture_shuffle || (tex_psm.bpp == 16)) && (GSLocalMemory::m_psm[m_cached_ctx.FRAME.PSM].bpp == 16) && m_texture_shuffle = ((m_same_group_texture_shuffle || (tex_psm.bpp == 16)) && (GSLocalMemory::m_psm[m_cached_ctx.FRAME.PSM].bpp == 16) &&
(shuffle_coords || rt->m_32_bits_fmt)) (shuffle_coords || rt->m_32_bits_fmt)) &&
&& draw_sprite_tex && (src->m_32_bits_fmt || m_copy_16bit_to_target_shuffle); (src->m_32_bits_fmt || m_copy_16bit_to_target_shuffle) &&
(draw_sprite_tex || (m_vt.m_primclass == GS_TRIANGLE_CLASS && (m_index.tail % 6) == 0 && TrianglesAreQuads(true)));
}; };
// Okami mustn't call this code // Okami mustn't call this code