GS: Pass through primitive ID in geometry shaders in DX12 and VK

Fixes primid destination alpha on sprites
This commit is contained in:
TellowKrinkle 2022-09-01 01:50:25 -05:00 committed by lightningterror
parent 412480b326
commit 1b34eb14f8
7 changed files with 52 additions and 15 deletions

View File

@ -13,6 +13,7 @@
#ifndef GS_IIP
#define GS_IIP 0
#define GS_PRIM 3
#define GS_FORWARD_PRIMID 0
#endif
#ifndef PS_FST
@ -102,7 +103,7 @@ struct PS_INPUT
#else
nointerpolation float4 c : COLOR0;
#endif
#if PS_DATE >= 1 && PS_DATE <= 3
#if (PS_DATE >= 1 && PS_DATE <= 3) || GS_FORWARD_PRIMID
uint primid : SV_PrimitiveID;
#endif
};
@ -1026,13 +1027,40 @@ VS_OUTPUT vs_main(VS_INPUT input)
// Geometry Shader
//////////////////////////////////////////////////////////////////////
#if GS_FORWARD_PRIMID
#define PRIMID_IN , uint primid : SV_PrimitiveID
#define VS2PS(x) vs2ps_impl(x, primid)
PS_INPUT vs2ps_impl(VS_OUTPUT vs, uint primid)
{
PS_INPUT o;
o.p = vs.p;
o.t = vs.t;
o.ti = vs.ti;
o.c = vs.c;
o.primid = primid;
return o;
}
#else
#define PRIMID_IN
#define VS2PS(x) vs2ps_impl(x)
PS_INPUT vs2ps_impl(VS_OUTPUT vs)
{
PS_INPUT o;
o.p = vs.p;
o.t = vs.t;
o.ti = vs.ti;
o.c = vs.c;
return o;
}
#endif
#if GS_PRIM == 0
[maxvertexcount(6)]
void gs_main(point VS_OUTPUT input[1], inout TriangleStream<VS_OUTPUT> stream)
void gs_main(point VS_OUTPUT input[1], inout TriangleStream<PS_INPUT> stream PRIMID_IN)
{
// Transform a point to a NxN sprite
VS_OUTPUT Point = input[0];
PS_INPUT Point = VS2PS(input[0]);
// Get new position
float4 lt_p = input[0].p;
@ -1066,11 +1094,11 @@ void gs_main(point VS_OUTPUT input[1], inout TriangleStream<VS_OUTPUT> stream)
#elif GS_PRIM == 1
[maxvertexcount(6)]
void gs_main(line VS_OUTPUT input[2], inout TriangleStream<VS_OUTPUT> stream)
void gs_main(line VS_OUTPUT input[2], inout TriangleStream<PS_INPUT> stream PRIMID_IN)
{
// Transform a line to a thick line-sprite
VS_OUTPUT left = input[0];
VS_OUTPUT right = input[1];
PS_INPUT left = VS2PS(input[0]);
PS_INPUT right = VS2PS(input[1]);
float2 lt_p = input[0].p.xy;
float2 rt_p = input[1].p.xy;
@ -1114,10 +1142,10 @@ void gs_main(line VS_OUTPUT input[2], inout TriangleStream<VS_OUTPUT> stream)
#elif GS_PRIM == 3
[maxvertexcount(4)]
void gs_main(line VS_OUTPUT input[2], inout TriangleStream<VS_OUTPUT> stream)
void gs_main(line VS_OUTPUT input[2], inout TriangleStream<PS_INPUT> stream PRIMID_IN)
{
VS_OUTPUT lt = input[0];
VS_OUTPUT rb = input[1];
PS_INPUT lt = VS2PS(input[0]);
PS_INPUT rb = VS2PS(input[1]);
// flat depth
lt.p.z = rb.p.z;
@ -1128,13 +1156,13 @@ void gs_main(line VS_OUTPUT input[2], inout TriangleStream<VS_OUTPUT> stream)
lt.c = rb.c;
// Swap texture and position coordinate
VS_OUTPUT lb = rb;
PS_INPUT lb = rb;
lb.p.x = lt.p.x;
lb.t.x = lt.t.x;
lb.ti.x = lt.ti.x;
lb.ti.z = lt.ti.z;
VS_OUTPUT rt = rb;
PS_INPUT rt = rb;
rt.p.y = lt.p.y;
rt.t.y = lt.t.y;
rt.ti.y = lt.ti.y;

View File

@ -113,6 +113,9 @@ layout(location = 0) out GSOutput
void WriteVertex(vec4 pos, vec4 t, vec4 ti, vec4 c)
{
#if GS_FORWARD_PRIMID
gl_PrimitiveID = gl_PrimitiveIDIn;
#endif
gl_Position = pos;
gsOut.t = t;
gsOut.ti = ti;

View File

@ -263,6 +263,7 @@ struct alignas(16) GSHWDrawConfig
GSTopology topology : 2;
bool expand : 1;
bool iip : 1;
bool forward_primid : 1;
};
u8 key;
};

View File

@ -137,6 +137,7 @@ void GSDevice11::SetupGS(GSSelector sel)
sm.AddMacro("GS_IIP", sel.iip);
sm.AddMacro("GS_PRIM", static_cast<int>(sel.topology));
sm.AddMacro("GS_EXPAND", sel.expand);
sm.AddMacro("GS_FORWARD_PRIMID", sel.forward_primid);
gs = m_shader_cache.GetGeometryShader(m_dev.get(), m_tfx_source, sm.GetPtr(), "gs_main");

View File

@ -1506,6 +1506,7 @@ const ID3DBlob* GSDevice12::GetTFXGeometryShader(GSHWDrawConfig::GSSelector sel)
sm.AddMacro("GS_IIP", sel.iip);
sm.AddMacro("GS_PRIM", static_cast<int>(sel.topology));
sm.AddMacro("GS_EXPAND", sel.expand);
sm.AddMacro("GS_FORWARD_PRIMID", sel.forward_primid);
ComPtr<ID3DBlob> gs(m_shader_cache.GetGeometryShader(m_tfx_source, sm.GetPtr(), "gs_main"));
it = m_tfx_geometry_shaders.emplace(sel.key, std::move(gs)).first;

View File

@ -3589,12 +3589,14 @@ void GSRendererHW::DrawPrims(GSTexture* rt, GSTexture* ds, GSTextureCache::Sourc
m_conf.depth.date = 1;
m_conf.depth.date_one = 1;
}
else if (DATE_PRIMID)
{
m_conf.ps.date = 1 + m_context->TEST.DATM;
m_conf.gs.forward_primid = 1;
}
else if (DATE)
{
if (DATE_PRIMID)
m_conf.ps.date = 1 + m_context->TEST.DATM;
else
m_conf.depth.date = 1;
m_conf.depth.date = 1;
}
m_conf.ps.fba = m_context->FBA.FBA;

View File

@ -1933,6 +1933,7 @@ VkShaderModule GSDeviceVK::GetTFXGeometryShader(GSHWDrawConfig::GSSelector sel)
AddMacro(ss, "GS_IIP", sel.iip);
AddMacro(ss, "GS_PRIM", static_cast<int>(sel.topology));
AddMacro(ss, "GS_EXPAND", sel.expand);
AddMacro(ss, "GS_FORWARD_PRIMID", sel.forward_primid);
ss << m_tfx_source;
VkShaderModule mod = g_vulkan_shader_cache->GetGeometryShader(ss.str());