[SPIR-V] `%gl_TessCoord` Is Decorated With `Patch`
Introduction
When compiling Domain/TessellationEvaluation shaders using the DirectX Compiler (DXC), the %gl_TessCoord
variable generated from the SV_DomainLocation
semantic is decorated with the Patch
decoration. This behavior is in accordance with the SPIR-V specification, but it is considered invalid. As a result, Vulkan graphics pipeline creation fails for some pipelines with complex tessellation shaders on current NVIDIA drivers after updating from Vulkan SDK 1.3.296.0 to 1.4.304.1.
The Issue
The issue arises from the change in the generated SPIR-V code in the new Vulkan SDK version. The %gl_TessCoord
variable is decorated with the Patch
decoration, which is not a valid SPIR-V decoration. This causes the Vulkan graphics pipeline creation to fail.
The Problematic Code
The problematic code is located in the DeclResultIdMapper.cpp
file, specifically in the if
statement at line 3519. The code checks if the stage variable data's signature kind is PatchConstOrPrim
and if the kind is MSPOut
. If both conditions are met, it decorates the variable with PerPrimitiveNV
for per-primitive out variables. Otherwise, it decorates the variable with Patch
.
// TODO: the following may not be correct?
if (stageVarData.sigPoint->GetSignatureKind() ==
hlsl::DXIL::SignatureKind::PatchConstOrPrim) {
if (stageVarData.sigPoint->GetKind() == hlsl::SigPoint::Kind::MSPOut) {
// Decorate with PerPrimitiveNV for per-primitive out variables.
spvBuilder.decoratePerPrimitiveNV(varInstr,
varInstr->getSourceLocation());
} else {
spvBuilder.decoratePatch(varInstr, varInstr->getSourceLocation());
}
}
Steps to Reproduce
To reproduce the issue, you can compile the attached HLSL file using the following DXC command line:
-nologo -spirv -E tes_main -Fc test.s -Fo test.spv -HV 202x -Wconversion -Wdouble-promotion -T ds_6_2 -Wx -fspv-target-env="vulkan1.1" test.hlsl
Alternatively, you can use the Godbolt online compiler: https://godbolt.org/z/TqTnK7GYj
Actual Behavior
The actual behavior is that the %gl_TessCoord
variable is decorated with the Patch
decoration, which is not a valid SPIR-V decoration.
OpDecorate %gl_TessCoord Patch
Environment
- DXC version:
dxcompiler.dll: 1.8 - 1.8.0.4775 (d39324e06)
and commit0a1143572d107c8b6980df092b84a79190ec1fbd
compiled from source - Host Operating System: Windows 10
Conclusion
Q&A
Q: What is the issue with the %gl_TessCoord
variable in SPIR-V?
A: The issue is that the %gl_TessCoord
variable is decorated with the Patch
decoration, which is not a valid SPIR-V decoration. This causes the Vulkan graphics pipeline creation to fail for some pipelines with complex tessellation shaders on current NVIDIA drivers.
Q: What is the cause of this issue?
A: The cause of this issue is the change in the generated SPIR-V code in the new Vulkan SDK version. The %gl_TessCoord
variable is decorated with the Patch
decoration, which is not a valid SPIR-V decoration.
Q: What is the problematic code that causes this issue?
A: The problematic code is located in the DeclResultIdMapper.cpp
file, specifically in the if
statement at line 3519. The code checks if the stage variable data's signature kind is PatchConstOrPrim
and if the kind is MSPOut
. If both conditions are met, it decorates the variable with PerPrimitiveNV
for per-primitive out variables. Otherwise, it decorates the variable with Patch
.
// TODO: the following may not be correct?
if (stageVarData.sigPoint->GetSignatureKind() ==
hlsl::DXIL::SignatureKind::PatchConstOrPrim) {
if (stageVarData.sigPoint->GetKind() == hlsl::SigPoint::Kind::MSPOut) {
// Decorate with PerPrimitiveNV for per-primitive out variables.
spvBuilder.decoratePerPrimitiveNV(varInstr,
varInstr->getSourceLocation());
} else {
spvBuilder.decoratePatch(varInstr, varInstr->getSourceLocation());
}
}
Q: How can I reproduce this issue? A: You can reproduce this issue by compiling the attached HLSL file using the following DXC command line:
-nologo -spirv -E tes_main -Fc test.s -Fo test.spv -HV 202x -Wconversion -Wdouble-promotion -T ds_6_2 -Wx -fspv-target-env="vulkan1.1" test.hlsl
Alternatively, you can use the Godbolt online compiler: https://godbolt.org/z/TqTnK7GYj
Q: What is the actual behavior of the %gl_TessCoord
variable?
A: The actual behavior is that the %gl_TessCoord
variable is decorated with the Patch
decoration, which is not a valid SPIR-V decoration.
OpDecorate %gl_TessCoord Patch
Q: What is the environment in which this issue occurs? A: The issue occurs in the following environment:
- DXC version:
dxcompiler.dll: 1.8 - 1.8.0.4775 (d39324e06)
and commit0a1143572d107c8b6980df092b84a79190ec1fbd
compiled from source - Host Operating System: Windows 10
Q: Is this issue still present in the latest commit?
A: Yes, the issue is still present in the latest commit 0a1143572d107c8b6980df092b84a79190ec1fbd
of the main
branch from February 28, 2025.
Q: What is the solution to this issue?
A: The solution to this issue is to fix the problematic code in the DeclResultIdMapper.cpp
file to correctly decorate the %gl_TessCoord
variable with the correct SPIR-V decoration.