From 1b34eb14f8a7f1cf62348e49f58c2be329a19273 Mon Sep 17 00:00:00 2001 From: TellowKrinkle Date: Thu, 1 Sep 2022 01:50:25 -0500 Subject: [PATCH] GS: Pass through primitive ID in geometry shaders in DX12 and VK Fixes primid destination alpha on sprites --- bin/resources/shaders/dx11/tfx.fx | 50 ++++++++++++++++++----- bin/resources/shaders/vulkan/tfx.glsl | 3 ++ pcsx2/GS/Renderers/Common/GSDevice.h | 1 + pcsx2/GS/Renderers/DX11/GSTextureFX11.cpp | 1 + pcsx2/GS/Renderers/DX12/GSDevice12.cpp | 1 + pcsx2/GS/Renderers/HW/GSRendererHW.cpp | 10 +++-- pcsx2/GS/Renderers/Vulkan/GSDeviceVK.cpp | 1 + 7 files changed, 52 insertions(+), 15 deletions(-) diff --git a/bin/resources/shaders/dx11/tfx.fx b/bin/resources/shaders/dx11/tfx.fx index f54de2cd1f..8f68184cec 100644 --- a/bin/resources/shaders/dx11/tfx.fx +++ b/bin/resources/shaders/dx11/tfx.fx @@ -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 stream) +void gs_main(point VS_OUTPUT input[1], inout TriangleStream 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 stream) #elif GS_PRIM == 1 [maxvertexcount(6)] -void gs_main(line VS_OUTPUT input[2], inout TriangleStream stream) +void gs_main(line VS_OUTPUT input[2], inout TriangleStream 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 stream) #elif GS_PRIM == 3 [maxvertexcount(4)] -void gs_main(line VS_OUTPUT input[2], inout TriangleStream stream) +void gs_main(line VS_OUTPUT input[2], inout TriangleStream 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 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; diff --git a/bin/resources/shaders/vulkan/tfx.glsl b/bin/resources/shaders/vulkan/tfx.glsl index 463e8f41dc..a8b7b5277e 100644 --- a/bin/resources/shaders/vulkan/tfx.glsl +++ b/bin/resources/shaders/vulkan/tfx.glsl @@ -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; diff --git a/pcsx2/GS/Renderers/Common/GSDevice.h b/pcsx2/GS/Renderers/Common/GSDevice.h index a9e6d0f9af..d04c15c23f 100644 --- a/pcsx2/GS/Renderers/Common/GSDevice.h +++ b/pcsx2/GS/Renderers/Common/GSDevice.h @@ -263,6 +263,7 @@ struct alignas(16) GSHWDrawConfig GSTopology topology : 2; bool expand : 1; bool iip : 1; + bool forward_primid : 1; }; u8 key; }; diff --git a/pcsx2/GS/Renderers/DX11/GSTextureFX11.cpp b/pcsx2/GS/Renderers/DX11/GSTextureFX11.cpp index 31d8ea1fd5..9d188cb85a 100644 --- a/pcsx2/GS/Renderers/DX11/GSTextureFX11.cpp +++ b/pcsx2/GS/Renderers/DX11/GSTextureFX11.cpp @@ -137,6 +137,7 @@ void GSDevice11::SetupGS(GSSelector sel) sm.AddMacro("GS_IIP", sel.iip); sm.AddMacro("GS_PRIM", static_cast(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"); diff --git a/pcsx2/GS/Renderers/DX12/GSDevice12.cpp b/pcsx2/GS/Renderers/DX12/GSDevice12.cpp index 5f19ea28d4..146c98becf 100644 --- a/pcsx2/GS/Renderers/DX12/GSDevice12.cpp +++ b/pcsx2/GS/Renderers/DX12/GSDevice12.cpp @@ -1506,6 +1506,7 @@ const ID3DBlob* GSDevice12::GetTFXGeometryShader(GSHWDrawConfig::GSSelector sel) sm.AddMacro("GS_IIP", sel.iip); sm.AddMacro("GS_PRIM", static_cast(sel.topology)); sm.AddMacro("GS_EXPAND", sel.expand); + sm.AddMacro("GS_FORWARD_PRIMID", sel.forward_primid); ComPtr gs(m_shader_cache.GetGeometryShader(m_tfx_source, sm.GetPtr(), "gs_main")); it = m_tfx_geometry_shaders.emplace(sel.key, std::move(gs)).first; diff --git a/pcsx2/GS/Renderers/HW/GSRendererHW.cpp b/pcsx2/GS/Renderers/HW/GSRendererHW.cpp index 17711f2dc7..aa4166305d 100644 --- a/pcsx2/GS/Renderers/HW/GSRendererHW.cpp +++ b/pcsx2/GS/Renderers/HW/GSRendererHW.cpp @@ -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; diff --git a/pcsx2/GS/Renderers/Vulkan/GSDeviceVK.cpp b/pcsx2/GS/Renderers/Vulkan/GSDeviceVK.cpp index d326c38b12..9229274636 100644 --- a/pcsx2/GS/Renderers/Vulkan/GSDeviceVK.cpp +++ b/pcsx2/GS/Renderers/Vulkan/GSDeviceVK.cpp @@ -1933,6 +1933,7 @@ VkShaderModule GSDeviceVK::GetTFXGeometryShader(GSHWDrawConfig::GSSelector sel) AddMacro(ss, "GS_IIP", sel.iip); AddMacro(ss, "GS_PRIM", static_cast(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());