mirror of https://github.com/PCSX2/pcsx2.git
GS/VertexTrace: Fix min/max when last provoking vertex unsupported
This was causing incorrect min/max alpha values due to the index swap, which caused the sides of text boxes in KH to disappear (because the alpha test optimized to always failing). Closes #5639.
This commit is contained in:
parent
3bab470db6
commit
6b54db9b75
|
@ -29,6 +29,11 @@ static __fi bool IsAutoFlushEnabled()
|
||||||
return (GSConfig.Renderer == GSRendererType::SW) ? GSConfig.AutoFlushSW : GSConfig.UserHacks_AutoFlush;
|
return (GSConfig.Renderer == GSRendererType::SW) ? GSConfig.AutoFlushSW : GSConfig.UserHacks_AutoFlush;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static __fi bool IsFirstProvokingVertex()
|
||||||
|
{
|
||||||
|
return (GSConfig.Renderer != GSRendererType::SW && !g_gs_device->Features().provoking_vertex_last);
|
||||||
|
}
|
||||||
|
|
||||||
GSState::GSState()
|
GSState::GSState()
|
||||||
: m_version(STATE_VERSION)
|
: m_version(STATE_VERSION)
|
||||||
, m_gsc(NULL)
|
, m_gsc(NULL)
|
||||||
|
@ -37,7 +42,7 @@ GSState::GSState()
|
||||||
, m_q(1.0f)
|
, m_q(1.0f)
|
||||||
, m_scanmask_used(false)
|
, m_scanmask_used(false)
|
||||||
, tex_flushed(true)
|
, tex_flushed(true)
|
||||||
, m_vt(this)
|
, m_vt(this, IsFirstProvokingVertex())
|
||||||
, m_regs(NULL)
|
, m_regs(NULL)
|
||||||
, m_crc(0)
|
, m_crc(0)
|
||||||
, m_options(0)
|
, m_options(0)
|
||||||
|
@ -252,11 +257,10 @@ void GSState::ResetHandlers()
|
||||||
m_fpGIFPackedRegHandlers[GIF_REG_NOP] = &GSState::GIFPackedRegHandlerNOP;
|
m_fpGIFPackedRegHandlers[GIF_REG_NOP] = &GSState::GIFPackedRegHandlerNOP;
|
||||||
|
|
||||||
// swap first/last indices when the provoking vertex is the first (D3D/Vulkan)
|
// swap first/last indices when the provoking vertex is the first (D3D/Vulkan)
|
||||||
const bool index_swap = GSConfig.UseHardwareRenderer() && !g_gs_device->Features().provoking_vertex_last;
|
|
||||||
if (IsAutoFlushEnabled())
|
if (IsAutoFlushEnabled())
|
||||||
index_swap ? SetPrimHandlers<true, true>() : SetPrimHandlers<true, false>();
|
IsFirstProvokingVertex() ? SetPrimHandlers<true, true>() : SetPrimHandlers<true, false>();
|
||||||
else
|
else
|
||||||
index_swap ? SetPrimHandlers<false, true>() : SetPrimHandlers<false, false>();
|
IsFirstProvokingVertex() ? SetPrimHandlers<false, true>() : SetPrimHandlers<false, false>();
|
||||||
|
|
||||||
std::fill(std::begin(m_fpGIFRegHandlers), std::end(m_fpGIFRegHandlers), &GSState::GIFRegHandlerNull);
|
std::fill(std::begin(m_fpGIFRegHandlers), std::end(m_fpGIFRegHandlers), &GSState::GIFRegHandlerNull);
|
||||||
|
|
||||||
|
@ -3238,8 +3242,9 @@ bool GSState::TryAlphaTest(u32& fm, u32& zm)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
const int amin = GetAlphaMinMax().min;
|
const GSVertexTrace::VertexAlpha& aminmax = GetAlphaMinMax();
|
||||||
const int amax = GetAlphaMinMax().max;
|
const int amin = aminmax.min;
|
||||||
|
const int amax = aminmax.max;
|
||||||
|
|
||||||
const int aref = m_context->TEST.AREF;
|
const int aref = m_context->TEST.AREF;
|
||||||
|
|
||||||
|
|
|
@ -21,13 +21,15 @@
|
||||||
|
|
||||||
CONSTINIT const GSVector4 GSVertexTrace::s_minmax = GSVector4::cxpr(FLT_MAX, -FLT_MAX, 0.f, 0.f);
|
CONSTINIT const GSVector4 GSVertexTrace::s_minmax = GSVector4::cxpr(FLT_MAX, -FLT_MAX, 0.f, 0.f);
|
||||||
|
|
||||||
GSVertexTrace::GSVertexTrace(const GSState* state)
|
GSVertexTrace::GSVertexTrace(const GSState* state, bool provoking_vertex_first)
|
||||||
: m_accurate_stq(false), m_state(state), m_primclass(GS_INVALID_CLASS)
|
: m_accurate_stq(false), m_state(state), m_primclass(GS_INVALID_CLASS)
|
||||||
{
|
{
|
||||||
memset(&m_alpha, 0, sizeof(m_alpha));
|
memset(&m_alpha, 0, sizeof(m_alpha));
|
||||||
|
|
||||||
#define InitUpdate3(P, IIP, TME, FST, COLOR) \
|
#define InitUpdate3(P, IIP, TME, FST, COLOR) \
|
||||||
m_fmm[COLOR][FST][TME][IIP][P] = &GSVertexTrace::FindMinMax<P, IIP, TME, FST, COLOR>;
|
m_fmm[COLOR][FST][TME][IIP][P] = \
|
||||||
|
provoking_vertex_first ? &GSVertexTrace::FindMinMax<P, IIP, TME, FST, COLOR, true> : \
|
||||||
|
&GSVertexTrace::FindMinMax<P, IIP, TME, FST, COLOR, false>;
|
||||||
|
|
||||||
#define InitUpdate2(P, IIP, TME) \
|
#define InitUpdate2(P, IIP, TME) \
|
||||||
InitUpdate3(P, IIP, TME, 0, 0) \
|
InitUpdate3(P, IIP, TME, 0, 0) \
|
||||||
|
@ -151,7 +153,7 @@ void GSVertexTrace::Update(const void* vertex, const u32* index, int v_count, in
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template <GS_PRIM_CLASS primclass, u32 iip, u32 tme, u32 fst, u32 color>
|
template <GS_PRIM_CLASS primclass, u32 iip, u32 tme, u32 fst, u32 color, bool flat_swapped>
|
||||||
void GSVertexTrace::FindMinMax(const void* vertex, const u32* index, int count)
|
void GSVertexTrace::FindMinMax(const void* vertex, const u32* index, int count)
|
||||||
{
|
{
|
||||||
const GSDrawingContext* context = m_state->m_context;
|
const GSDrawingContext* context = m_state->m_context;
|
||||||
|
@ -283,16 +285,16 @@ void GSVertexTrace::FindMinMax(const void* vertex, const u32* index, int count)
|
||||||
int i = 0;
|
int i = 0;
|
||||||
for (; i < (count - 3); i += 6)
|
for (; i < (count - 3); i += 6)
|
||||||
{
|
{
|
||||||
processVertices(v[index[i + 0]], v[index[i + 3]], false);
|
processVertices(v[index[i + 0]], v[index[i + 3]], flat_swapped);
|
||||||
processVertices(v[index[i + 1]], v[index[i + 4]], false);
|
processVertices(v[index[i + 1]], v[index[i + 4]], false);
|
||||||
processVertices(v[index[i + 2]], v[index[i + 5]], true);
|
processVertices(v[index[i + 2]], v[index[i + 5]], !flat_swapped);
|
||||||
}
|
}
|
||||||
if (count & 1)
|
if (count & 1)
|
||||||
{
|
{
|
||||||
processVertices(v[index[i + 0]], v[index[i + 1]], false);
|
processVertices(v[index[i + 0]], v[index[i + 1]], flat_swapped);
|
||||||
// Compiler optimizations go!
|
// Compiler optimizations go!
|
||||||
// (And if they don't, it's only one vertex out of many)
|
// (And if they don't, it's only one vertex out of many)
|
||||||
processVertices(v[index[i + 2]], v[index[i + 2]], true);
|
processVertices(v[index[i + 2]], v[index[i + 2]], !flat_swapped);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
|
@ -48,7 +48,7 @@ protected:
|
||||||
|
|
||||||
FindMinMaxPtr m_fmm[2][2][2][2][4];
|
FindMinMaxPtr m_fmm[2][2][2][2][4];
|
||||||
|
|
||||||
template <GS_PRIM_CLASS primclass, u32 iip, u32 tme, u32 fst, u32 color>
|
template <GS_PRIM_CLASS primclass, u32 iip, u32 tme, u32 fst, u32 color, bool provoking_vertex_first>
|
||||||
void FindMinMax(const void* vertex, const u32* index, int count);
|
void FindMinMax(const void* vertex, const u32* index, int count);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -73,7 +73,7 @@ public:
|
||||||
GSVector2 m_lod; // x = min, y = max
|
GSVector2 m_lod; // x = min, y = max
|
||||||
|
|
||||||
public:
|
public:
|
||||||
GSVertexTrace(const GSState* state);
|
GSVertexTrace(const GSState* state, bool provoking_vertex_first);
|
||||||
virtual ~GSVertexTrace() {}
|
virtual ~GSVertexTrace() {}
|
||||||
|
|
||||||
void Update(const void* vertex, const u32* index, int v_count, int i_count, GS_PRIM_CLASS primclass);
|
void Update(const void* vertex, const u32* index, int v_count, int i_count, GS_PRIM_CLASS primclass);
|
||||||
|
|
Loading…
Reference in New Issue