Repository navigation
[SPIR-V] Fix SPV_NV_mesh_shader PrimitiveCountNV bugs #9036
Description
Description
When DXC emits SPV_NV_mesh_shader, SetMeshOutputCounts has three problems:
- Every invocation stores its own primitive count to PrimitiveCountNV. The D3D mesh shader spec and GL_EXT_mesh_shader both take the counts from the first invocation. With non-uniform arguments, DXC's SPIR-V NV lowering is a race condition.
- The vertex-count argument is never evaluated, so its side effects are lost. In the repro, counter.IncrementCounter() disappears.
- PrimitiveCountNV starts undefined. D3D's count starts at 0, but a shader that skips SetMeshOutputCounts, for example an early return, leaves the count undefined.
These problems are solved by defaulting PrimitiveCountNV to 0, and writing it only from the first invocation.
Steps to Reproduce
Repro 1 (non-uniform count, lost side effect):
struct VertOut { float4 pos : SV_Position; };
RWStructuredBuffer<uint> counter;
[outputtopology("triangle")]
[numthreads(32, 1, 1)]
void main(uint gid : SV_GroupIndex,
out vertices VertOut verts[3], out indices uint3 tris[32]) {
SetMeshOutputCounts(counter.IncrementCounter(), gid + 1);
if (gid < 3)
verts[gid].pos = float4(0, 0, 0, 1);
tris[gid] = uint3(0, 1, 2);
}
dxc -T ms_6_5 -E main -spirv -fcgl t1.hlsl
Repro 2 (skipped call):
struct VertOut { float4 pos : SV_Position; };
[outputtopology("triangle")]
[numthreads(1, 1, 1)]
void main(uint gid : SV_GroupID,
out vertices VertOut verts[3], out indices uint3 tris[1]) {
if (gid == 0)
return;
SetMeshOutputCounts(3, 1);
verts[0].pos = float4(0, 0, 0, 1);
tris[0] = uint3(0, 1, 2);
}
dxc -T ms_6_5 -E main -spirv t2.hlsl
Actual Behavior
Repro 1: every invocation stores its own gid + 1 , and no counter increment is emitted:
%52 = OpLoad %uint %gid
%53 = OpIAdd %uint %52 %uint_1
OpStore %5 %53 ; %5 = BuiltIn PrimitiveCountNV
Expected: evaluate both arguments in every invocation, and store the count only when LocalInvocationIndex == 0 .
Repro 2: the only store to PrimitiveCountNV ( OpStore %5 %uint_1 ) is on the non-returning path. When gid == 0 , the primitive count is undefined. Expected: the count defaults to 0, as in DXIL.
Environment
- DXC version 1.10.2609.0
- Host Operating System Windows
Metadata
Metadata
Assignees
Labels
Type
Projects
- StatusShow more project fieldsNo status
Activity