Skip to content

Allow SV_PrimitiveID in ray tracing hit stages#11423

Open
jkwak-work wants to merge 38 commits into
shader-slang:masterfrom
jkwak-work:issue-11197
Open

Allow SV_PrimitiveID in ray tracing hit stages#11423
jkwak-work wants to merge 38 commits into
shader-slang:masterfrom
jkwak-work:issue-11197

Conversation

@jkwak-work
Copy link
Copy Markdown
Collaborator

@jkwak-work jkwak-work commented Jun 2, 2026

Fixes #11197

Summary of the problem from the end user perspective

SV_PrimitiveID could not be used consistently as an input in ray tracing intersection, any-hit, and closest-hit shaders. Shaders that need the primitive index in those stages had to use backend-specific forms instead of the semantic spelling.

Minimal repro shader; if applicable

[shader("closesthit")]
void main(uint primitiveId : SV_PrimitiveID)
{
    uint id = primitiveId;
}

Root cause

The semantic metadata and parameter binding rules did not allow SV_PrimitiveID in ray tracing hit stages. Backend legalization also needed target-specific handling so the value is not treated like payload or hit-attribute data.

Solution in this PR

The PR allows SV_PrimitiveID in intersection, any-hit, and closest-hit stages. SPIR-V lowers it as BuiltIn PrimitiveId input, SPIR-V-via-GLSL routes through gl_PrimitiveID, HLSL/DXIL emission replaces uses with the native PrimitiveIndex() intrinsic, and CUDA/OptiX emission replaces uses with optixGetPrimitiveIndex().

Notes to the reviewers; where to focus on

The main review points are the semantic/stage allowlist changes, the parameter-binding behavior for ray tracing system-value inputs, and the SPIR-V, GLSL, HLSL, and CUDA legalization paths. Direct SPIR-V ray tracing entry points still reach the GLSL legalization pass, so the shouldEmitSPIRVDirectly() guard in that pass is intentional.

Reviewer Directives (maintained by agent)

Related PRs in the past

@jkwak-work jkwak-work added pr: non-breaking PRs without breaking changes CoPilot labels Jun 2, 2026
@jkwak-work jkwak-work self-assigned this Jun 2, 2026
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Jun 2, 2026

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 63ad34f4-955e-482e-bf52-70cd56782bbb

📥 Commits

Reviewing files that changed from the base of the PR and between 92b53ac and 5190000.

📒 Files selected for processing (1)
  • source/slang/slang-ir-glsl-legalize.cpp

📝 Walkthrough

Walkthrough

Adds SV_PrimitiveID support for ray-tracing hit stages by expanding the semantic stage list, validating and binding runtime system-value inputs, implementing IR legalization and backend plumbing (HLSL/GLSL/CUDA), mapping SPIR-V address spaces, updating emit wiring, and adding codegen and diagnostic tests.

Changes

SV_PrimitiveID ray tracing hit-stage support

Layer / File(s) Summary
Semantic declaration and stage requirements
source/slang/core.meta.slang
sv_primitiveid accessor now lists intersection, anyhit, and closesthit as allowed stages.
Parameter validation and binding
source/slang/slang-parameter-binding.cpp
Adds allowlist detection for runtime-provided SV_PrimitiveID on hit stages, target gating (D3D/Khronos/CUDA), suppresses some stage-rejection diagnostics, and avoids treating allowed inputs as hit-attributes.
Varying-parameter legalization core
source/slang/slang-ir-legalize-varying-params.{h,cpp}
Introduces hit-stage classifier, tryLegalizeRayTracingPrimitiveIDParam helper, virtualized entry-point/param hooks, module entry-point filtering, and plumbing for per-target legalization.
HLSL PrimitiveID legalization & emit wiring
source/slang/slang-ir-legalize-varying-params.cpp, source/slang/slang-ir-hlsl-legalize.{h,cpp}, source/slang/slang-emit.cpp
Detects sv_primitiveid parameters, creates/caches primitive-index intrinsic, rewrites uses to a compatible replacement with proper loads/temporaries, optionally removes the original parameter, exposes legalizeRayTracingPrimitiveIDParamsForHLSL, replaces prior parameter-struct pass with legalizeParametersForHLSL, and updates D3D emit pipeline to call it.
SPIR-V address-space inference
source/slang/slang-ir-spirv-legalize.cpp
Maps sv_primitiveid to AddressSpace::BuiltinInput for ray-tracing hit entry points when inferred space is still Generic.
GLSL legalization threading
source/slang/slang-ir-glsl-legalize.cpp
Threads a shared primitiveIndexFunc through per-parameter legalization and invokes primitive-ID legalization for hit stages when not emitting SPIR-V directly.
Codegen regression coverage
tests/hlsl-intrinsic/ray-tracing/sv-primitiveid-raytracing.slang, tests/hlsl-intrinsic/ray-tracing/rt-pipeline-intrinsics-*.slang, tests/cuda/sv-primitiveid-raytracing.slang
Adds intersection/anyhit/closesthit tests and FileCheck expectations for SPIR-V PrimitiveId, DXIL primitiveIndex/reportHit patterns (int/uint/unused variants), and CUDA optixGetPrimitiveIndex lowering.
Diagnostic regression coverage
tests/diagnostics/execution-model/sv-primitiveid-rt-invalid.slang
Adds diagnostics covering disallowed stages/directions, unsupported targets, and invalid carrier types for SV_PrimitiveID usage.

Suggested reviewers

  • bmillsNV
  • csyonghe
  • mkeshavaNV
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 11.76% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title 'Allow SV_PrimitiveID in ray tracing hit stages' accurately and clearly describes the main change—enabling SV_PrimitiveID as an input parameter in ray-tracing hit stages, which is the primary objective of this PR.
Description check ✅ Passed The PR description is comprehensive and directly related to the changeset. It clearly explains the problem (SV_PrimitiveID not allowed in ray tracing stages), the root cause, and the solution with target-specific legalization paths for SPIR-V, HLSL, and CUDA.
Linked Issues check ✅ Passed The PR fully addresses issue #11197 by enabling SV_PrimitiveID in intersection, any-hit, and closest-hit shaders with proper semantic allowlist changes, parameter-binding rules, and backend-specific legalization paths across SPIR-V, GLSL, HLSL/DXIL, and CUDA targets.
Out of Scope Changes check ✅ Passed All code changes are directly scoped to enabling SV_PrimitiveID support in ray tracing hit stages. Changes include semantic declarations, parameter binding, and target-specific legalization—all necessary and related to the stated objective. No unrelated modifications detected.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@jkwak-work
Copy link
Copy Markdown
Collaborator Author

@coderabbitai review

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Jun 2, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4


ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: ba7eab78-0f00-444e-ad98-ede136284665

📥 Commits

Reviewing files that changed from the base of the PR and between fd4f6c7 and b85c65b.

📒 Files selected for processing (11)
  • source/slang/core.meta.slang
  • source/slang/slang-emit.cpp
  • source/slang/slang-ir-glsl-legalize.cpp
  • source/slang/slang-ir-hlsl-legalize.cpp
  • source/slang/slang-ir-hlsl-legalize.h
  • source/slang/slang-ir-spirv-legalize.cpp
  • source/slang/slang-parameter-binding.cpp
  • tests/hlsl-intrinsic/ray-tracing/rt-pipeline-intrinsics-ahit.slang
  • tests/hlsl-intrinsic/ray-tracing/rt-pipeline-intrinsics-chit.slang
  • tests/hlsl-intrinsic/ray-tracing/rt-pipeline-intrinsics-int.slang
  • tests/hlsl-intrinsic/ray-tracing/sv-primitiveid-raytracing.slang

Comment thread source/slang/slang-ir-glsl-legalize.cpp Outdated
Comment thread tests/hlsl-intrinsic/ray-tracing/rt-pipeline-intrinsics-ahit.slang Outdated
Comment thread tests/hlsl-intrinsic/ray-tracing/rt-pipeline-intrinsics-chit.slang Outdated
Comment thread tests/hlsl-intrinsic/ray-tracing/rt-pipeline-intrinsics-int.slang Outdated
@jkwak-work jkwak-work marked this pull request as ready for review June 2, 2026 13:33
@jkwak-work jkwak-work requested a review from a team as a code owner June 2, 2026 13:33
@jkwak-work jkwak-work requested review from bmillsNV and removed request for a team June 2, 2026 13:33
github-actions[bot]

This comment was marked as outdated.

@jkwak-work
Copy link
Copy Markdown
Collaborator Author

@coderabbitai review

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Jun 2, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

github-actions[bot]

This comment was marked as outdated.

@jkwak-work
Copy link
Copy Markdown
Collaborator Author

@coderabbitai review

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Jun 2, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1


ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: dc284f9c-3c3f-4e6c-9851-02e3cd7b8f34

📥 Commits

Reviewing files that changed from the base of the PR and between 240a14a and 9d2552d.

📒 Files selected for processing (3)
  • tests/diagnostics/execution-model/sv-primitiveid-rt-invalid.slang
  • tests/hlsl-intrinsic/ray-tracing/rt-pipeline-intrinsics-int.slang
  • tests/hlsl-intrinsic/ray-tracing/sv-primitiveid-raytracing.slang

Comment thread tests/diagnostics/execution-model/sv-primitiveid-rt-invalid.slang Outdated
@jkwak-work
Copy link
Copy Markdown
Collaborator Author

@coderabbitai review

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

♻️ Duplicate comments (1)
source/slang/slang-ir-glsl-legalize.cpp (1)

3990-4009: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Legalize hit-stage SV_PrimitiveID before ray-tracing consolidation consumes its uses.

Line 4935 still runs consolidateRayTracingParameters() before the loop on Line 4945. In hit stages, that step can already replaceUsesWith() the original SV_PrimitiveID parameter: the outParams.getCount() <= 1 branch routes every varying param through handleSingleParam(), and the else branch still does it for non-out params like SV_PrimitiveID. By the time Line 4001 calls tryLegalizeRayTracingPrimitiveIDParam(), the param often has no remaining uses, so the helper never materializes and this new primitiveIndexFunc threading stays nullptr.

Example: main_isect(int pid : SV_PrimitiveID) and main_chit(..., int pid : SV_PrimitiveID) from tests/hlsl-intrinsic/ray-tracing/sv-primitiveid-raytracing.slang can reach the later legalization pass with pid already rewritten to a generic global param. That skips the intended canonicalization to (gl_PrimitiveID) on the GLSL/SPIR-V-via-GLSL path.

Suggested fix:

One safe direction
+    if (isRayTracingHitStage(stage))
+    {
+        if (auto firstBlock = func->getFirstBlock())
+        {
+            for (auto pp = firstBlock->getFirstParam(); pp; pp = pp->getNextParam())
+            {
+                builder.setInsertBefore(firstBlock->getFirstOrdinaryInst());
+                tryLegalizeRayTracingPrimitiveIDParam(
+                    module,
+                    builder,
+                    pp,
+                    primitiveIndexFunc,
+                    /* removeParam */ false);
+            }
+        }
+    }
+
     // Special handling for ray tracing shaders
     switch (stage)
     {
     case Stage::AnyHit:
     case Stage::Callable:

The alternative is to make consolidateRayTracingParameters() explicitly skip SV_PrimitiveID, but the key is that the helper has to see live uses before consolidation rewrites the parameter.

Also applies to: 4960-4966, 5092-5098


ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 293e4fd6-e362-4e4f-950a-105348607095

📥 Commits

Reviewing files that changed from the base of the PR and between bd32d06 and 2c5092b.

📒 Files selected for processing (3)
  • source/slang/slang-ir-glsl-legalize.cpp
  • source/slang/slang-ir-spirv-legalize.cpp
  • source/slang/slang-parameter-binding.cpp

@jkwak-work
Copy link
Copy Markdown
Collaborator Author

[Agent] Addressed CodeRabbit's note about GLSL hit-stage SV_PrimitiveID legalization after ray-tracing consolidation in ccc10a4.

The GLSL path now attempts tryLegalizeRayTracingPrimitiveIDParam() for hit-stage entry params before consolidateRayTracingParameters() consumes their uses. The pre-consolidation pass is scoped to !shouldEmitSPIRVDirectly(), so direct SPIR-V keeps the BuiltIn PrimitiveId path and does not materialize the target-intrinsic helper.

Validation:

  • cmake.exe --build --preset debug --target slangc slang-test
  • build/Debug/bin/slang-test.exe tests/hlsl-intrinsic/ray-tracing/sv-primitiveid-raytracing tests/cuda/sv-primitiveid-raytracing tests/diagnostics/execution-model/sv-primitiveid-rt-invalid tests/hlsl-intrinsic/ray-tracing/rt-pipeline-intrinsics-ahit tests/hlsl-intrinsic/ray-tracing/rt-pipeline-intrinsics-chit tests/hlsl-intrinsic/ray-tracing/rt-pipeline-intrinsics-int passed 40/40
  • explicit -emit-spirv-via-glsl compile checks for intersection/any-hit/closest-hit emitted BuiltIn PrimitiveId and no primitive-index helper function

@jkwak-work
Copy link
Copy Markdown
Collaborator Author

@coderabbitai review

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Jun 6, 2026

✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

github-actions[bot]

This comment was marked as outdated.

@jkwak-work
Copy link
Copy Markdown
Collaborator Author

@coderabbitai review

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Jun 6, 2026

✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

github-actions[bot]

This comment was marked as outdated.

Comment thread source/slang/slang-ir-glsl-legalize.cpp Outdated
@@ -4909,6 +4912,26 @@ void legalizeEntryPointForGLSL(
invokePathConstantFuncInHullShader(&context, codeGenContext, scalarizedGlobalOutput);
}

if (isRayTracingHitStage(stage) &&
!codeGenContext->getTargetProgram()->shouldEmitSPIRVDirectly())
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because this file is about GLSL legalization, the following condition is assumed to be true all the time,

!codeGenContext->getTargetProgram()->shouldEmitSPIRVDirectly())

It is assumed that this check happened at an earlier stage before come this the GLSL legalization or at the early stage.
If needed, it should be SLANG_ASSERT but it shouldn't be needed.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[Agent] I tested removing the guard and did not keep that change. Direct SPIR-V ray-tracing tests do enter this legalizer with shouldEmitSPIRVDirectly() true; removing the guard materialized the GLSL PrimitiveIndex helper in direct SPIR-V without the required import linkage and caused six focused SPIR-V checks to fail with Function declaration must have a LinkageAttributes decoration. The guard remains so direct SPIR-V stays on its BuiltIn PrimitiveId path. Validation after restoring the guard and committing e12ab61: cmake.exe --build --preset debug --target slangc slang-test; focused slang-test.exe set passed 43/43; git.exe diff --check.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In that case, we should run the check only once at an early stage and store somewhere rather than call the function all the time.
The current implementation gives us the impression that the implementation expect the value to change more frequently than it does.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[Agent] Addressed in 4f4b6c9. legalizeEntryPointForGLSL() now computes shouldEmitSPIRVDirectly once immediately after reading the entry-point stage and reuses that stored value for the ray-tracing hit-stage SV_PrimitiveID legalization gate. This keeps the direct-SPIR-V decision fixed at the early entry-point legalization point instead of calling through TargetProgram at the use site.

Validation: build/Debug/bin/slang-test.exe tests/hlsl-intrinsic/ray-tracing/sv-primitiveid-raytracing tests/cuda/sv-primitiveid-raytracing tests/diagnostics/execution-model/sv-primitiveid-rt-invalid tests/hlsl-intrinsic/ray-tracing/rt-pipeline-intrinsics-ahit tests/hlsl-intrinsic/ray-tracing/rt-pipeline-intrinsics-chit tests/hlsl-intrinsic/ray-tracing/rt-pipeline-intrinsics-int passed 47/47; git.exe diff --check reported only the expected LF-to-CRLF warning.

Comment thread source/slang/slang-ir-glsl-legalize.cpp Outdated
@jkwak-work
Copy link
Copy Markdown
Collaborator Author

@coderabbitai review

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Jun 6, 2026

✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

github-actions[bot]

This comment was marked as outdated.

@jkwak-work
Copy link
Copy Markdown
Collaborator Author

@coderabbitai review

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Jun 6, 2026

✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

github-actions[bot]

This comment was marked as outdated.

Copy link
Copy Markdown
Collaborator Author

@jkwak-work jkwak-work left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please reduce/remove unnecessary changes and minimize the code changes as much as you can

Comment thread source/slang/slang-ir-glsl-legalize.cpp Outdated
github-actions[bot]

This comment was marked as outdated.

Comment thread source/slang/slang-ir-glsl-legalize.cpp Outdated
Session* session,
IRModule* module,
IRFunc* func,
CodeGenContext* codeGenContext,
ShaderExtensionTracker* glslExtensionTracker)
ShaderExtensionTracker* glslExtensionTracker,
IRFunc* primitiveIndexFunc)
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remind me why this function has to take primitiveIndexFunc?
Can we keep the original function signature?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[Agent] Addressed in 5190000. legalizeEntryPointForGLSL() now keeps its original signature; the primitiveIndexFunc cache is local to the hit-stage parameter legalization block. The previous argument was only carrying the helper across GLSL entry points, but this use only needs a per-entry-point cache while walking that entry point's params before ray-tracing consolidation.

Validation: cmake.exe --build --preset debug --target slangc slang-test; focused build/Debug/bin/slang-test.exe tests/hlsl-intrinsic/ray-tracing/sv-primitiveid-raytracing tests/cuda/sv-primitiveid-raytracing tests/diagnostics/execution-model/sv-primitiveid-rt-invalid tests/hlsl-intrinsic/ray-tracing/rt-pipeline-intrinsics-ahit tests/hlsl-intrinsic/ray-tracing/rt-pipeline-intrinsics-chit tests/hlsl-intrinsic/ray-tracing/rt-pipeline-intrinsics-int passed 47/47; git.exe diff --check reported only the expected LF-to-CRLF warning.

@jkwak-work
Copy link
Copy Markdown
Collaborator Author

@coderabbitai review

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Jun 7, 2026

✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link
Copy Markdown
Contributor

@github-actions github-actions Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Verdict: ✅ Clean — no significant issues found

PR enables SV_PrimitiveID as an input semantic in ray-tracing intersection/anyhit/closesthit stages and routes it to per-target intrinsics (PrimitiveIndex() for HLSL/DXIL, (gl_PrimitiveID) for GLSL via SPIR-V, optixGetPrimitiveIndex() for CUDA/OptiX, BuiltIn PrimitiveId for direct SPIR-V). Targets without ray tracing (Metal, WGSL) emit an Unimplemented diagnostic; raygen/miss/callable stages and out/inout directions are rejected by parameter binding and semantic-check rules respectively. IR-pass review confirmed iterator safety on the GLSL param loop (next captured before removeAndDeallocate), traverseUses snapshot-iteration safety in replacePrimitiveIDParamUses, correct result == AddressSpace::Generic precondition in the new SPIR-V legalize branch, and that the two-pass restructure of EntryPointVaryingParamLegalizeContext::processModule preserves behavior for existing CUDA/CPU subtypes (shouldProcessEntryPoint defaults to true). Test coverage exercises all four backend paths plus negative cases for stage, direction, target, and type.

Changes Overview

Semantic / parameter-binding allowlist (source/slang/core.meta.slang, source/slang/slang-parameter-binding.cpp)

  • core.meta.slang: adds [require(intersection)], [require(anyhit)], [require(closesthit)] to the get accessor of sv_primitiveid.
  • slang-parameter-binding.cpp: allowlists SV_PrimitiveID as a runtime-provided varying input in hit stages for D3D / Khronos / CUDA targets, falling through to ordinary varying-input handling instead of the hit-attributes layout. Unsupported targets (Metal, WGSL) get an Unimplemented diagnostic.

IR legalization helpers (source/slang/slang-ir-legalize-varying-params.cpp/.h)

  • New tryLegalizeRayTracingPrimitiveIDParam helper rewrites SV_PrimitiveID params into a call to a synthesized IRFunc carrying per-target targetIntrinsic decorations for HLSL/GLSL/CUDA.
  • New HLSLRayTracingPrimitiveIDParamLegalizeContext reuses the helper inside the EntryPointVaryingParamLegalizeContext framework; that framework is restructured to a two-pass collect-then-process model with a new shouldProcessEntryPoint filter hook.
  • CUDA path adds case SystemValueSemanticName::PrimitiveID that routes through the same value emitter.

Backend wiring (source/slang/slang-emit.cpp, source/slang/slang-ir-hlsl-legalize.cpp/.h, source/slang/slang-ir-glsl-legalize.cpp, source/slang/slang-ir-spirv-legalize.cpp)

  • slang-emit.cpp / slang-ir-hlsl-legalize.{cpp,h}: pass renamed legalizeNonStructParameterToStructForHLSLlegalizeParametersForHLSL; new dispatcher also calls legalizeRayTracingPrimitiveIDParamsForHLSL.
  • slang-ir-glsl-legalize.cpp: legalizeEntryPointForGLSL invokes tryLegalizeRayTracingPrimitiveIDParam over hit-stage params when !shouldEmitSPIRVDirectly() (so SPIR-V via GLSL routes through gl_PrimitiveID).
  • slang-ir-spirv-legalize.cpp: in direct SPIR-V path, sets AddressSpace::BuiltinInput for sv_primitiveid parameters in hit stages when no varying-input offset attr was assigned (result == AddressSpace::Generic).

Tests (tests/cuda/sv-primitiveid-raytracing.slang, tests/diagnostics/execution-model/sv-primitiveid-rt-invalid.slang, tests/hlsl-intrinsic/ray-tracing/{rt-pipeline-intrinsics-ahit,rt-pipeline-intrinsics-chit,rt-pipeline-intrinsics-int,sv-primitiveid-raytracing}.slang)

  • CUDA: filechecks for optixGetPrimitiveIndex() and absence of primitiveID parameter in __closesthit__ entry point, including int→uint conversion.
  • Diagnostics: negative tests for raygen/miss/callable (rejected stages), out/inout (rejected directions), Metal/WGSL (unsupported targets), and struct-typed semantic (BAD_TYPE).
  • Ray-tracing intrinsics suite: per-stage SPIR-V (OpDecorate ... BuiltIn PrimitiveId), DXIL (@dx.op.primitiveIndex.i32), GLSL (gl_PrimitiveID), CUDA (optixGetPrimitiveIndex()), unused-param case, multi-entry-point case, and a forward-call case (helper function called from a hit shader).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CoPilot pr: non-breaking PRs without breaking changes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Slang does not accept SV_PrimitiveID as input to intersection shaders

2 participants