mirror of
https://github.com/PCSX2/pcsx2.git
synced 2026-07-11 01:34:17 +02:00
GS/HW: Make all vertices the same color in certain flat shading cases.
Fixes issues with AA1 with flat shading.
This commit is contained in:
@@ -2014,11 +2014,6 @@ VS_OUTPUT vs_main_expand(uint vid : SV_VertexID)
|
||||
vtx.inv_cov = is_near_corner ? 0.0f : 1.0f; // Full coverage at near corner, otherwise none.
|
||||
|
||||
vtx.interior = 0;
|
||||
|
||||
#if !VS_IIP
|
||||
// Get the provoking vertex color (first vertex in DX)
|
||||
vtx.c = i0 == 0 ? vtx.c : (i1 == 0 ? other.c : opposite.c);
|
||||
#endif
|
||||
}
|
||||
|
||||
return vtx;
|
||||
|
||||
@@ -455,11 +455,6 @@ void main()
|
||||
VSout.inv_cov = is_near_corner ? 0.0f : 1.0f; // Full coverage at near corner, otherwise none.
|
||||
|
||||
VSout.interior = 0;
|
||||
|
||||
#if !VS_IIP
|
||||
// Get the provoking vertex color (last vertex in GL)
|
||||
vtx.c = i0 == 2 ? vtx.c : (i1 == 2 ? other.c : opposite.c);
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -450,11 +450,6 @@ void main()
|
||||
vsOut.inv_cov = is_near_corner ? 0.0f : 1.0f; // Full coverage at near corner, otherwise none.
|
||||
|
||||
vsOut.interior = 0;
|
||||
|
||||
#if !VS_IIP
|
||||
// Get the provoking vertex color (last vertex in VK)
|
||||
vtx.c = i0 == 2 ? vtx.c : (i1 == 2 ? other.c : opposite.c);
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -5331,31 +5331,36 @@ bool GSRendererHW::VerifyIndices()
|
||||
return true;
|
||||
}
|
||||
|
||||
// Fix the colors in vertices in case the API only supports "provoking first vertex"
|
||||
// (i.e., when using flat shading the color comes from the first vertex, unlike PS2
|
||||
// which is "provoking last vertex").
|
||||
void GSRendererHW::HandleProvokingVertexFirst()
|
||||
void GSRendererHW::HandleFlatShadedVertices()
|
||||
{
|
||||
// Early exit conditions:
|
||||
if (g_gs_device->Features().provoking_vertex_last || // device supports provoking last vertex
|
||||
m_conf.vs.iip || // we are doing Gouraud shading
|
||||
m_vt.m_primclass == GS_POINT_CLASS || // drawing points (one vertex per primitive; color is unambiguous)
|
||||
m_vt.m_primclass == GS_SPRITE_CLASS) // drawing sprites (handled by the sprites -> triangles expand shader)
|
||||
// These cases might need fixing.
|
||||
const bool maybe_fix_vertices = !m_conf.vs.iip &&
|
||||
(!g_gs_device->Features().provoking_vertex_last || IsCoverageAlphaSupported());
|
||||
|
||||
// These cases definitely don't need fixing.
|
||||
const bool dont_fix_vertices = m_vt.m_primclass == GS_POINT_CLASS || m_vt.m_primclass == GS_SPRITE_CLASS;
|
||||
|
||||
if (!maybe_fix_vertices || dont_fix_vertices)
|
||||
return;
|
||||
|
||||
const int n = GSUtil::GetClassVertexCount(m_vt.m_primclass);
|
||||
|
||||
// If all first/last vertices have the same color there is nothing to do.
|
||||
bool first_eq_last = true;
|
||||
// If all vertices of each prim have the same color there is nothing to do.
|
||||
bool prims_flat = true;
|
||||
for (u32 i = 0; i < m_index->tail; i += n)
|
||||
{
|
||||
if (m_vertex->buff[m_index->buff[i]].RGBAQ.U32[0] != m_vertex->buff[m_index->buff[i + n - 1]].RGBAQ.U32[0])
|
||||
for (u32 j = 0; j < n - 1; j++)
|
||||
{
|
||||
first_eq_last = false;
|
||||
break;
|
||||
if (m_vertex->buff[m_index->buff[i + j]].RGBAQ.U32[0] != m_vertex->buff[m_index->buff[i + n - 1]].RGBAQ.U32[0])
|
||||
{
|
||||
prims_flat = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!prims_flat)
|
||||
break;
|
||||
}
|
||||
if (first_eq_last)
|
||||
if (prims_flat)
|
||||
return;
|
||||
|
||||
// De-index the vertices using the copy buffer
|
||||
@@ -5369,11 +5374,11 @@ void GSRendererHW::HandleProvokingVertexFirst()
|
||||
std::swap(m_vertex->buff, m_vertex->buff_copy);
|
||||
m_vertex->head = m_vertex->next = m_vertex->tail = m_index->tail;
|
||||
|
||||
// Put correct color in the first vertex
|
||||
// Make all vertices the same color to simplify handling in expand shaders.
|
||||
for (u32 i = 0; i < m_index->tail; i += n)
|
||||
{
|
||||
m_vertex->buff[i].RGBAQ.U32[0] = m_vertex->buff[i + n - 1].RGBAQ.U32[0];
|
||||
m_vertex->buff[i + n - 1].RGBAQ.U32[0] = 0xff; // Make last vertex red for debugging if used improperly
|
||||
for (u32 j = 0; j < n - 1; j++)
|
||||
m_vertex->buff[i + j].RGBAQ.U32[0] = m_vertex->buff[i + n - 1].RGBAQ.U32[0];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9450,7 +9455,7 @@ __ri void GSRendererHW::DrawPrims(GSTextureCache::Target* rt, GSTextureCache::Ta
|
||||
DetermineROVUsage(rt, ds);
|
||||
ConvertTextureTypeROV(rt, ds);
|
||||
|
||||
// Barriers must be determined before indices are modified via HandleProvokingVertexFirst/SetupIA.
|
||||
// Barriers must be determined before indices are modified via HandleFlatShadedVertices/SetupIA.
|
||||
// This also computes the drawlist if needed.
|
||||
DetermineBarriers(rt, tex);
|
||||
|
||||
@@ -9475,7 +9480,7 @@ __ri void GSRendererHW::DrawPrims(GSTextureCache::Target* rt, GSTextureCache::Ta
|
||||
|
||||
m_conf.scissor = (date_options.enabled && !date_options.barrier) ? m_conf.drawarea : scissor;
|
||||
|
||||
HandleProvokingVertexFirst();
|
||||
HandleFlatShadedVertices();
|
||||
|
||||
SetupIA(rtscale, vs_scale_x, vs_scale_y, m_channel_shuffle_width != 0, no_rt);
|
||||
|
||||
|
||||
@@ -215,7 +215,7 @@ private:
|
||||
void DrawPrims(GSTextureCache::Target* rt, GSTextureCache::Target* ds, GSTextureCache::Source* tex, const TextureMinMaxResult& tmm);
|
||||
|
||||
void ResetStates();
|
||||
void HandleProvokingVertexFirst();
|
||||
void HandleFlatShadedVertices();
|
||||
void SetupIA(float target_scale, float sx, float sy, bool req_vert_backup, const bool no_rt);
|
||||
void EmulateTextureShuffleAndFbmask(GSTextureCache::Target* rt, GSTextureCache::Source* tex);
|
||||
u32 EmulateChannelShuffle(GSTextureCache::Target* src, bool test_only, GSTextureCache::Target* rt = nullptr);
|
||||
|
||||
@@ -555,12 +555,6 @@ vertex MainVSOut vs_main_expand(
|
||||
out.inv_cov = is_near_corner ? 0.0f : 1.0f; // Full coverage at near corner, otherwise none.
|
||||
|
||||
out.interior = 0;
|
||||
|
||||
if (NOT_IIP)
|
||||
{
|
||||
// Get the provoking vertex color (first vertex in Metal)
|
||||
out.fc = i0 == 0 ? out.fc : (i1 == 0 ? other.fc : opposite.fc);
|
||||
}
|
||||
}
|
||||
|
||||
return out;
|
||||
|
||||
@@ -3,4 +3,4 @@
|
||||
|
||||
/// Version number for GS and other shaders. Increment whenever any of the contents of the
|
||||
/// shaders change, to invalidate the cache.
|
||||
static constexpr u32 SHADER_CACHE_VERSION = 106; // Last changed in PR 14643
|
||||
static constexpr u32 SHADER_CACHE_VERSION = 107; // Last changed in PR 14634
|
||||
|
||||
Reference in New Issue
Block a user