summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLujin Wang <143145775+lujinwangnv@users.noreply.github.com>2025-08-22 13:48:20 -0700
committerGitHub <noreply@github.com>2025-08-22 20:48:20 +0000
commitcd9e1f67184c1361558e18993e5cb392dc1131f0 (patch)
tree109e42e28618a4db785b474891ba58b2ffb7ee05
parent3ca2e47514e3fce133a6ac7d1aca88a3b679c551 (diff)
Fix mesh shader OutputIndices subscript error by adding missing ref accessor (#7929)
Fixes the Slang compiler internal error "subscript had no getter" when reading from mesh shader output index arrays (e.g., `triangles[0].x`). ## Problem The `OutputIndices` struct was missing a `ref` accessor in its `__subscript` implementation, causing the compiler to fail when trying to materialize subscript expressions as r-values. ## Solution Added the missing `ref` accessor to `OutputIndices.__subscript` using the `kIROp_MeshOutputRef` intrinsic operation, matching the pattern used in `OutputVertices` and `OutputPrimitives`. ## Files Changed - `source/slang/core.meta.slang` - Added missing `ref` accessor - `tests/bugs/gh-7925.slang` - Test case to reproduce and verify the fix Fixes #7925 Generated with [Claude Code](https://claude.ai/code) --------- Co-authored-by: Claude <noreply@anthropic.com> Co-authored-by: Lujin Wang <lujinwangnv@users.noreply.github.com> Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: slangbot <ellieh+slangbot@nvidia.com> Co-authored-by: slangbot <186143334+slangbot@users.noreply.github.com>
-rw-r--r--source/slang/core.meta.slang5
-rw-r--r--source/slang/slang-emit-spirv.cpp16
-rw-r--r--tests/bugs/gh-7925.slang54
3 files changed, 75 insertions, 0 deletions
diff --git a/source/slang/core.meta.slang b/source/slang/core.meta.slang
index 2c6bf04d1..3306403f5 100644
--- a/source/slang/core.meta.slang
+++ b/source/slang/core.meta.slang
@@ -2349,6 +2349,11 @@ struct OutputIndices
case spirv: __setIndices(this, index, newValue);
}
}
+
+ // If a 'OutputIndices[index]' is referred to by a '__ref', call 'kIROp_MeshOutputRef(index)'
+ [require(glsl_hlsl_metal_spirv, meshshading)]
+ __intrinsic_op($(kIROp_MeshOutputRef))
+ ref;
}
};
diff --git a/source/slang/slang-emit-spirv.cpp b/source/slang/slang-emit-spirv.cpp
index d6f4ac176..0facaac3f 100644
--- a/source/slang/slang-emit-spirv.cpp
+++ b/source/slang/slang-emit-spirv.cpp
@@ -4032,6 +4032,9 @@ struct SPIRVEmitContext : public SourceEmitterBase, public SPIRVEmitSharedContex
case kIROp_GetOffsetPtr:
result = emitGetOffsetPtr(parent, inst);
break;
+ case kIROp_MeshOutputRef:
+ result = emitMeshOutputRef(parent, inst);
+ break;
case kIROp_GetElement:
result = emitGetElement(parent, as<IRGetElement>(inst));
break;
@@ -7002,6 +7005,19 @@ struct SPIRVEmitContext : public SourceEmitterBase, public SPIRVEmitSharedContex
makeArray(inst->getIndex()));
}
+ SpvInst* emitMeshOutputRef(SpvInstParent* parent, IRInst* inst)
+ {
+ // MeshOutputRef takes two operands: the mesh output array and the index
+ // It should return a reference (address) to the element at that index
+ auto base = inst->getOperand(0);
+ auto index = inst->getOperand(1);
+
+ const SpvWord baseId = getID(ensureInst(base));
+
+ // Use OpAccessChain to get the address of the element
+ return emitOpAccessChain(parent, inst, inst->getFullType(), baseId, makeArray(index));
+ }
+
SpvInst* emitGetElement(SpvInstParent* parent, IRGetElement* inst)
{
requireVariableBufferCapabilityIfNeeded(inst->getDataType());
diff --git a/tests/bugs/gh-7925.slang b/tests/bugs/gh-7925.slang
new file mode 100644
index 000000000..470a039c3
--- /dev/null
+++ b/tests/bugs/gh-7925.slang
@@ -0,0 +1,54 @@
+//TEST:SIMPLE(filecheck=CHECK): -target spirv -profile sm_6_6 -stage mesh -entry main
+
+struct MeshOutput
+{
+ float4 position : SV_Position;
+ float3 color : COLOR0;
+}
+
+// Uniform variable for time-based animation
+uniform uint iTime;
+
+[shader("mesh")]
+[outputtopology("triangle")]
+[numthreads(1, 1, 1)]
+void main(
+ in uint tig : SV_GroupIndex,
+ OutputVertices<MeshOutput, 3> vertices,
+ OutputIndices<uint3, 1> triangles
+)
+{
+ // Set the number of vertices and primitives
+ SetMeshOutputCounts(3, 1);
+
+ // Define the triangle indices
+ triangles[0] = uint3(0, 1, 2);
+
+ // Use uiColor as in the original shader
+ // This line should now work after the fix - it was causing the "subscript had no getter" error
+ uint uiColor = triangles[0].x + iTime;
+
+ // Create triangle vertices with time-based animation
+ float timeOffset = float(iTime) * 0.01; // Convert to float and scale
+ float colorOffset = float(uiColor) * 0.005; // Use uiColor for color variation
+
+ // Vertex 0 - Red vertex (top) with uiColor influence
+ vertices[0].position = float4(0.0, 0.5 + sin(timeOffset) * 0.1, 0.0, 1.0);
+ vertices[0].color = float3(1.0, (sin(colorOffset) + 1.0) * 0.5, 0.0); // Red with green modulation from uiColor
+
+ // Vertex 1 - Green vertex (bottom left)
+ vertices[1].position = float4(-0.5, -0.5, 0.0, 1.0);
+ vertices[1].color = float3(0.0, 1.0, 0.0); // Green
+
+ // Vertex 2 - Blue vertex (bottom right)
+ vertices[2].position = float4(0.5, -0.5, 0.0, 1.0);
+ vertices[2].color = float3(0.0, 0.0, 1.0); // Blue
+}
+
+// CHECK: OpCapability MeshShadingEXT
+// CHECK: OpExtension "SPV_EXT_mesh_shader"
+// CHECK: OpEntryPoint MeshEXT %main "main"
+// CHECK: OpExecutionMode %main OutputPrimitivesEXT 1
+// CHECK: OpExecutionMode %main OutputVertices 3
+// CHECK: OpExecutionMode %main LocalSize 1 1 1
+// CHECK: OpExecutionMode %main OutputTrianglesEXT