From 7e2dbedb22d6f89c1f91af57ee2d39403ec5aebc Mon Sep 17 00:00:00 2001 From: Tex Riddell Date: Tue, 4 Nov 2025 14:49:47 -0800 Subject: [PATCH] Fix linking of SV_PrimitiveID for Geometry Shader entry This fixes a linking bug where the `SemanticKind` of a `SV_PrimitiveID` input in a Geometry Shader gets erroneously replaced with `SemanticKind::Invalid`. When copying the input signature from the library module to the final module during linking, new signature elements are constructed and initialized using `DxilSignatureElement::Initialize` (there is not direct copy constructor). Initialize doesn't have an argument for the original SemanticKind, normally constructing it based on the name and the `SigPoint`. However, the `SigPoint` for this element should be `GSIn` rather than `GSVIn`, which is the default for all items in this signature. This causes it to set the `SemanticKind` to `Invalid`. There is code to correct for this in `DxilSignatureElement::SetKind` used when initializing an element from metadata, but that wasn't called in this signature copying code path. This change updates `DxilSignatureElement::Initialize` to call `SetKind` using the semantic looked up only by name. `SetKind` will correct the `SigPoint` if necessary and set the semantic by looking it up by `SemanticKind` and `SigPoint`. This change also moves system value name canonicalization to `SetKind`. --- lib/DXIL/DxilSignatureElement.cpp | 8 ++++---- tools/clang/test/DXC/link-gs-primitiveid.hlsl | 20 +++++++++++++++++++ 2 files changed, 24 insertions(+), 4 deletions(-) create mode 100644 tools/clang/test/DXC/link-gs-primitiveid.hlsl diff --git a/lib/DXIL/DxilSignatureElement.cpp b/lib/DXIL/DxilSignatureElement.cpp index bf8ee0abe0..c527c76932 100644 --- a/lib/DXIL/DxilSignatureElement.cpp +++ b/lib/DXIL/DxilSignatureElement.cpp @@ -50,10 +50,7 @@ void DxilSignatureElement::Initialize(llvm::StringRef Name, if (!IndexVector.empty()) m_SemanticStartIndex = IndexVector[0]; // Find semantic in the table. - m_pSemantic = Semantic::GetByName(m_SemanticName, m_sigPointKind); - // Replace semantic name with canonical name if it's a system value. - if (!m_pSemantic->IsInvalid() && !m_pSemantic->IsArbitrary()) - m_SemanticName = m_pSemantic->GetName(); + SetKind(Semantic::GetByName(m_SemanticName)->GetKind()); SetCompType(ElementType); m_InterpMode = InterpMode; m_SemanticIndex = IndexVector; @@ -136,6 +133,9 @@ void DxilSignatureElement::SetKind(Semantic::Kind kind) { // recover the original SigPointKind if necessary (for Shadow element). m_sigPointKind = SigPoint::RecoverKind(kind, m_sigPointKind); m_pSemantic = Semantic::Get(kind, m_sigPointKind); + // Replace semantic name with canonical name if it's a system value. + if (!m_pSemantic->IsInvalid() && !m_pSemantic->IsArbitrary()) + m_SemanticName = m_pSemantic->GetName(); } Semantic::Kind DxilSignatureElement::GetKind() const { diff --git a/tools/clang/test/DXC/link-gs-primitiveid.hlsl b/tools/clang/test/DXC/link-gs-primitiveid.hlsl new file mode 100644 index 0000000000..8335e57069 --- /dev/null +++ b/tools/clang/test/DXC/link-gs-primitiveid.hlsl @@ -0,0 +1,20 @@ +// RUN: %dxc -T lib_6_3 %s -Fo %t.dxl +// RUN: %dxl %t.dxl -T gs_6_3 -E GS | FileCheck %s + +// Make sure link succeeds and produces correct system value for SV_PrimitiveID +// i8 10 = DXIL::SemanticKind::PrimitiveID +// CHECK: !{i32 1, !"SV_PrimitiveID", i8 5, i8 10, !{{[0-9]+}}, i8 0, i32 1, i8 1, i32 -1, i8 -1, null} + +struct GSINOUT { + uint id : ID; +}; + +[maxvertexcount(3)] +[shader("geometry")] +void GS(point GSINOUT input[1], + uint j : SV_PrimitiveID, + inout PointStream outStream) { + GSINOUT output = input[0]; + output.id += j; + outStream.Append(output); +}