mirror of https://github.com/PCSX2/pcsx2.git
GS: Move PrimitiveWithoutGaps function to GSState
This commit is contained in:
parent
f3a75f55e7
commit
c729a6f91c
|
@ -2981,6 +2981,106 @@ GSState::PRIM_OVERLAP GSState::PrimitiveOverlap()
|
|||
return overlap;
|
||||
}
|
||||
|
||||
bool GSState::PrimitiveCoversWithoutGaps()
|
||||
{
|
||||
if (m_primitive_covers_without_gaps.has_value())
|
||||
return m_primitive_covers_without_gaps.value();
|
||||
|
||||
// Draw shouldn't be offset.
|
||||
if (((m_r.eq32(GSVector4i::zero())).mask() & 0xff) != 0xff)
|
||||
{
|
||||
m_primitive_covers_without_gaps = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (m_vt.m_primclass == GS_POINT_CLASS)
|
||||
{
|
||||
m_primitive_covers_without_gaps = (m_vertex.next < 2);
|
||||
return m_primitive_covers_without_gaps.value();
|
||||
}
|
||||
else if (m_vt.m_primclass == GS_TRIANGLE_CLASS)
|
||||
{
|
||||
m_primitive_covers_without_gaps = (m_index.tail == 6 && TrianglesAreQuads());
|
||||
return m_primitive_covers_without_gaps.value();
|
||||
}
|
||||
else if (m_vt.m_primclass != GS_SPRITE_CLASS)
|
||||
{
|
||||
m_primitive_covers_without_gaps = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Simple case: one sprite.
|
||||
if (m_index.tail == 2)
|
||||
{
|
||||
m_primitive_covers_without_gaps = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Check that the height matches. Xenosaga 3 draws a letterbox around
|
||||
// the FMV with a sprite at the top and bottom of the framebuffer.
|
||||
const GSVertex* v = &m_vertex.buff[0];
|
||||
const int first_dpY = v[1].XYZ.Y - v[0].XYZ.Y;
|
||||
const int first_dpX = v[1].XYZ.X - v[0].XYZ.X;
|
||||
|
||||
// Horizontal Match.
|
||||
if ((first_dpX >> 4) == m_r_no_scissor.z)
|
||||
{
|
||||
// Borrowed from MergeSprite() modified to calculate heights.
|
||||
for (u32 i = 2; i < m_vertex.next; i += 2)
|
||||
{
|
||||
const int last_pY = v[i - 1].XYZ.Y;
|
||||
const int dpY = v[i + 1].XYZ.Y - v[i].XYZ.Y;
|
||||
if (std::abs(dpY - first_dpY) >= 16 || std::abs(static_cast<int>(v[i].XYZ.Y) - last_pY) >= 16)
|
||||
{
|
||||
m_primitive_covers_without_gaps = false;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
m_primitive_covers_without_gaps = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Vertical Match.
|
||||
if ((first_dpY >> 4) == m_r_no_scissor.w)
|
||||
{
|
||||
// Borrowed from MergeSprite().
|
||||
const int offset_X = m_context->XYOFFSET.OFX;
|
||||
for (u32 i = 2; i < m_vertex.next; i += 2)
|
||||
{
|
||||
const int last_pX = v[i - 1].XYZ.X;
|
||||
const int this_start_X = v[i].XYZ.X;
|
||||
const int last_start_X = v[i - 2].XYZ.X;
|
||||
|
||||
const int dpX = v[i + 1].XYZ.X - v[i].XYZ.X;
|
||||
|
||||
if (this_start_X < last_start_X)
|
||||
{
|
||||
const int prev_X = last_start_X - offset_X;
|
||||
if (std::abs(dpX - prev_X) >= 16 || std::abs(this_start_X - offset_X) >= 16)
|
||||
{
|
||||
m_primitive_covers_without_gaps = false;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (std::abs(dpX - first_dpX) >= 16 || std::abs(this_start_X - last_pX) >= 16)
|
||||
{
|
||||
m_primitive_covers_without_gaps = false;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m_primitive_covers_without_gaps = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
m_primitive_covers_without_gaps = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
__forceinline bool GSState::IsAutoFlushDraw(u32 prim)
|
||||
{
|
||||
if (!PRIM->TME || (GSConfig.UserHacks_AutoFlush == GSHWAutoFlushLevel::SpritesOnly && prim != GS_SPRITE))
|
||||
|
|
|
@ -221,6 +221,9 @@ public:
|
|||
u32 m_dirty_gs_regs = 0;
|
||||
int m_backed_up_ctx = 0;
|
||||
std::vector<GSUploadQueue> m_draw_transfers;
|
||||
std::optional<bool> m_primitive_covers_without_gaps;
|
||||
GSVector4i m_r = {};
|
||||
GSVector4i m_r_no_scissor = {};
|
||||
|
||||
static int s_n;
|
||||
static int s_last_transfer_draw_n;
|
||||
|
@ -408,6 +411,7 @@ public:
|
|||
|
||||
bool TrianglesAreQuads() const;
|
||||
PRIM_OVERLAP PrimitiveOverlap();
|
||||
bool PrimitiveCoversWithoutGaps();
|
||||
GIFRegTEX0 GetTex0Layer(u32 lod);
|
||||
};
|
||||
|
||||
|
|
|
@ -6732,106 +6732,6 @@ bool GSRendererHW::IsDiscardingDstAlpha() const
|
|||
((m_cached_ctx.FRAME.FBMSK & GSLocalMemory::m_psm[m_cached_ctx.FRAME.PSM].fmsk) & 0xFF000000u) == 0); // alpha isn't masked
|
||||
}
|
||||
|
||||
bool GSRendererHW::PrimitiveCoversWithoutGaps()
|
||||
{
|
||||
if (m_primitive_covers_without_gaps.has_value())
|
||||
return m_primitive_covers_without_gaps.value();
|
||||
|
||||
// Draw shouldn't be offset.
|
||||
if (((m_r.eq32(GSVector4i::zero())).mask() & 0xff) != 0xff)
|
||||
{
|
||||
m_primitive_covers_without_gaps = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (m_vt.m_primclass == GS_POINT_CLASS)
|
||||
{
|
||||
m_primitive_covers_without_gaps = (m_vertex.next < 2);
|
||||
return m_primitive_covers_without_gaps.value();
|
||||
}
|
||||
else if (m_vt.m_primclass == GS_TRIANGLE_CLASS)
|
||||
{
|
||||
m_primitive_covers_without_gaps = (m_index.tail == 6 && TrianglesAreQuads());
|
||||
return m_primitive_covers_without_gaps.value();
|
||||
}
|
||||
else if (m_vt.m_primclass != GS_SPRITE_CLASS)
|
||||
{
|
||||
m_primitive_covers_without_gaps = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Simple case: one sprite.
|
||||
if (m_index.tail == 2)
|
||||
{
|
||||
m_primitive_covers_without_gaps = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Check that the height matches. Xenosaga 3 draws a letterbox around
|
||||
// the FMV with a sprite at the top and bottom of the framebuffer.
|
||||
const GSVertex* v = &m_vertex.buff[0];
|
||||
const int first_dpY = v[1].XYZ.Y - v[0].XYZ.Y;
|
||||
const int first_dpX = v[1].XYZ.X - v[0].XYZ.X;
|
||||
|
||||
// Horizontal Match.
|
||||
if ((first_dpX >> 4) == m_r_no_scissor.z)
|
||||
{
|
||||
// Borrowed from MergeSprite() modified to calculate heights.
|
||||
for (u32 i = 2; i < m_vertex.next; i += 2)
|
||||
{
|
||||
const int last_pY = v[i - 1].XYZ.Y;
|
||||
const int dpY = v[i + 1].XYZ.Y - v[i].XYZ.Y;
|
||||
if (std::abs(dpY - first_dpY) >= 16 || std::abs(static_cast<int>(v[i].XYZ.Y) - last_pY) >= 16)
|
||||
{
|
||||
m_primitive_covers_without_gaps = false;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
m_primitive_covers_without_gaps = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Vertical Match.
|
||||
if ((first_dpY >> 4) == m_r_no_scissor.w)
|
||||
{
|
||||
// Borrowed from MergeSprite().
|
||||
const int offset_X = m_context->XYOFFSET.OFX;
|
||||
for (u32 i = 2; i < m_vertex.next; i += 2)
|
||||
{
|
||||
const int last_pX = v[i - 1].XYZ.X;
|
||||
const int this_start_X = v[i].XYZ.X;
|
||||
const int last_start_X = v[i - 2].XYZ.X;
|
||||
|
||||
const int dpX = v[i + 1].XYZ.X - v[i].XYZ.X;
|
||||
|
||||
if (this_start_X < last_start_X)
|
||||
{
|
||||
const int prev_X = last_start_X - offset_X;
|
||||
if (std::abs(dpX - prev_X) >= 16 || std::abs(this_start_X - offset_X) >= 16)
|
||||
{
|
||||
m_primitive_covers_without_gaps = false;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (std::abs(dpX - first_dpX) >= 16 || std::abs(this_start_X - last_pX) >= 16)
|
||||
{
|
||||
m_primitive_covers_without_gaps = false;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m_primitive_covers_without_gaps = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
m_primitive_covers_without_gaps = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Like PrimitiveCoversWithoutGaps but with texture coordinates.
|
||||
bool GSRendererHW::TextureCoversWithoutGapsNotEqual()
|
||||
{
|
||||
|
|
|
@ -56,7 +56,6 @@ private:
|
|||
bool IsDiscardingDstColor();
|
||||
bool IsDiscardingDstRGB();
|
||||
bool IsDiscardingDstAlpha() const;
|
||||
bool PrimitiveCoversWithoutGaps();
|
||||
bool TextureCoversWithoutGapsNotEqual();
|
||||
|
||||
enum class CLUTDrawTestResult
|
||||
|
@ -123,9 +122,6 @@ private:
|
|||
bool IsUsingCsInBlend();
|
||||
bool IsUsingAsInBlend();
|
||||
|
||||
GSVector4i m_r = {};
|
||||
GSVector4i m_r_no_scissor = {};
|
||||
|
||||
// We modify some of the context registers to optimize away unnecessary operations.
|
||||
// Instead of messing with the real context, we copy them and use those instead.
|
||||
struct HWCachedCtx
|
||||
|
@ -173,7 +169,6 @@ private:
|
|||
u32 m_split_clear_pages = 0; // if zero, inactive
|
||||
u32 m_split_clear_color = 0;
|
||||
|
||||
std::optional<bool> m_primitive_covers_without_gaps;
|
||||
bool m_userhacks_tcoffset = false;
|
||||
float m_userhacks_tcoffset_x = 0.0f;
|
||||
float m_userhacks_tcoffset_y = 0.0f;
|
||||
|
|
Loading…
Reference in New Issue