mirror of https://github.com/PCSX2/pcsx2.git
GS: Pass through primitive ID in geometry shaders in DX12 and VK
Fixes primid destination alpha on sprites
This commit is contained in:
parent
412480b326
commit
1b34eb14f8
|
@ -13,6 +13,7 @@
|
||||||
#ifndef GS_IIP
|
#ifndef GS_IIP
|
||||||
#define GS_IIP 0
|
#define GS_IIP 0
|
||||||
#define GS_PRIM 3
|
#define GS_PRIM 3
|
||||||
|
#define GS_FORWARD_PRIMID 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef PS_FST
|
#ifndef PS_FST
|
||||||
|
@ -102,7 +103,7 @@ struct PS_INPUT
|
||||||
#else
|
#else
|
||||||
nointerpolation float4 c : COLOR0;
|
nointerpolation float4 c : COLOR0;
|
||||||
#endif
|
#endif
|
||||||
#if PS_DATE >= 1 && PS_DATE <= 3
|
#if (PS_DATE >= 1 && PS_DATE <= 3) || GS_FORWARD_PRIMID
|
||||||
uint primid : SV_PrimitiveID;
|
uint primid : SV_PrimitiveID;
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
@ -1026,13 +1027,40 @@ VS_OUTPUT vs_main(VS_INPUT input)
|
||||||
// Geometry Shader
|
// 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
|
#if GS_PRIM == 0
|
||||||
|
|
||||||
[maxvertexcount(6)]
|
[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
|
// Transform a point to a NxN sprite
|
||||||
VS_OUTPUT Point = input[0];
|
PS_INPUT Point = VS2PS(input[0]);
|
||||||
|
|
||||||
// Get new position
|
// Get new position
|
||||||
float4 lt_p = input[0].p;
|
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
|
#elif GS_PRIM == 1
|
||||||
|
|
||||||
[maxvertexcount(6)]
|
[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
|
// Transform a line to a thick line-sprite
|
||||||
VS_OUTPUT left = input[0];
|
PS_INPUT left = VS2PS(input[0]);
|
||||||
VS_OUTPUT right = input[1];
|
PS_INPUT right = VS2PS(input[1]);
|
||||||
float2 lt_p = input[0].p.xy;
|
float2 lt_p = input[0].p.xy;
|
||||||
float2 rt_p = input[1].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
|
#elif GS_PRIM == 3
|
||||||
|
|
||||||
[maxvertexcount(4)]
|
[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];
|
PS_INPUT lt = VS2PS(input[0]);
|
||||||
VS_OUTPUT rb = input[1];
|
PS_INPUT rb = VS2PS(input[1]);
|
||||||
|
|
||||||
// flat depth
|
// flat depth
|
||||||
lt.p.z = rb.p.z;
|
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;
|
lt.c = rb.c;
|
||||||
|
|
||||||
// Swap texture and position coordinate
|
// Swap texture and position coordinate
|
||||||
VS_OUTPUT lb = rb;
|
PS_INPUT lb = rb;
|
||||||
lb.p.x = lt.p.x;
|
lb.p.x = lt.p.x;
|
||||||
lb.t.x = lt.t.x;
|
lb.t.x = lt.t.x;
|
||||||
lb.ti.x = lt.ti.x;
|
lb.ti.x = lt.ti.x;
|
||||||
lb.ti.z = lt.ti.z;
|
lb.ti.z = lt.ti.z;
|
||||||
|
|
||||||
VS_OUTPUT rt = rb;
|
PS_INPUT rt = rb;
|
||||||
rt.p.y = lt.p.y;
|
rt.p.y = lt.p.y;
|
||||||
rt.t.y = lt.t.y;
|
rt.t.y = lt.t.y;
|
||||||
rt.ti.y = lt.ti.y;
|
rt.ti.y = lt.ti.y;
|
||||||
|
|
|
@ -113,6 +113,9 @@ layout(location = 0) out GSOutput
|
||||||
|
|
||||||
void WriteVertex(vec4 pos, vec4 t, vec4 ti, vec4 c)
|
void WriteVertex(vec4 pos, vec4 t, vec4 ti, vec4 c)
|
||||||
{
|
{
|
||||||
|
#if GS_FORWARD_PRIMID
|
||||||
|
gl_PrimitiveID = gl_PrimitiveIDIn;
|
||||||
|
#endif
|
||||||
gl_Position = pos;
|
gl_Position = pos;
|
||||||
gsOut.t = t;
|
gsOut.t = t;
|
||||||
gsOut.ti = ti;
|
gsOut.ti = ti;
|
||||||
|
|
|
@ -263,6 +263,7 @@ struct alignas(16) GSHWDrawConfig
|
||||||
GSTopology topology : 2;
|
GSTopology topology : 2;
|
||||||
bool expand : 1;
|
bool expand : 1;
|
||||||
bool iip : 1;
|
bool iip : 1;
|
||||||
|
bool forward_primid : 1;
|
||||||
};
|
};
|
||||||
u8 key;
|
u8 key;
|
||||||
};
|
};
|
||||||
|
|
|
@ -137,6 +137,7 @@ void GSDevice11::SetupGS(GSSelector sel)
|
||||||
sm.AddMacro("GS_IIP", sel.iip);
|
sm.AddMacro("GS_IIP", sel.iip);
|
||||||
sm.AddMacro("GS_PRIM", static_cast<int>(sel.topology));
|
sm.AddMacro("GS_PRIM", static_cast<int>(sel.topology));
|
||||||
sm.AddMacro("GS_EXPAND", sel.expand);
|
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");
|
gs = m_shader_cache.GetGeometryShader(m_dev.get(), m_tfx_source, sm.GetPtr(), "gs_main");
|
||||||
|
|
||||||
|
|
|
@ -1506,6 +1506,7 @@ const ID3DBlob* GSDevice12::GetTFXGeometryShader(GSHWDrawConfig::GSSelector sel)
|
||||||
sm.AddMacro("GS_IIP", sel.iip);
|
sm.AddMacro("GS_IIP", sel.iip);
|
||||||
sm.AddMacro("GS_PRIM", static_cast<int>(sel.topology));
|
sm.AddMacro("GS_PRIM", static_cast<int>(sel.topology));
|
||||||
sm.AddMacro("GS_EXPAND", sel.expand);
|
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"));
|
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;
|
it = m_tfx_geometry_shaders.emplace(sel.key, std::move(gs)).first;
|
||||||
|
|
|
@ -3589,11 +3589,13 @@ void GSRendererHW::DrawPrims(GSTexture* rt, GSTexture* ds, GSTextureCache::Sourc
|
||||||
m_conf.depth.date = 1;
|
m_conf.depth.date = 1;
|
||||||
m_conf.depth.date_one = 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)
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1933,6 +1933,7 @@ VkShaderModule GSDeviceVK::GetTFXGeometryShader(GSHWDrawConfig::GSSelector sel)
|
||||||
AddMacro(ss, "GS_IIP", sel.iip);
|
AddMacro(ss, "GS_IIP", sel.iip);
|
||||||
AddMacro(ss, "GS_PRIM", static_cast<int>(sel.topology));
|
AddMacro(ss, "GS_PRIM", static_cast<int>(sel.topology));
|
||||||
AddMacro(ss, "GS_EXPAND", sel.expand);
|
AddMacro(ss, "GS_EXPAND", sel.expand);
|
||||||
|
AddMacro(ss, "GS_FORWARD_PRIMID", sel.forward_primid);
|
||||||
ss << m_tfx_source;
|
ss << m_tfx_source;
|
||||||
|
|
||||||
VkShaderModule mod = g_vulkan_shader_cache->GetGeometryShader(ss.str());
|
VkShaderModule mod = g_vulkan_shader_cache->GetGeometryShader(ss.str());
|
||||||
|
|
Loading…
Reference in New Issue