From 175078ebc4021012ff48cf1df2f259ec0942ee6e Mon Sep 17 00:00:00 2001 From: Nathan Morrical Date: Tue, 9 Sep 2025 13:13:51 -0700 Subject: [PATCH 1/2] some initial revisions being made to 017-shader-record, to reflect discussions regarding updated type wrapper syntax --- proposals/017-shader-record.md | 148 +++++++++++++++++++++++---------- 1 file changed, 103 insertions(+), 45 deletions(-) diff --git a/proposals/017-shader-record.md b/proposals/017-shader-record.md index abd16a8..af2e5ae 100644 --- a/proposals/017-shader-record.md +++ b/proposals/017-shader-record.md @@ -1,29 +1,40 @@ -SP #017: Disambiguate `uniform` via `[[push_constant]]` and `[[shader_record]]` -======================================================================= +SP #017: Disambiguate `uniform` via `Payload`, `HitAttribute`, and `ShaderRecord` +============================================================================================ This document proposes a first step toward resolving ambiguities and bugs that arise from the current usage of `uniform` (and to a lesser extent, `varying`) in Slang, particularly in ray tracing pipelines. - +This document proposes two concrete shifts to remove ambiguity around `uniform` and ray-tracing +entry point parameters: -It suggests promoting Vulkan's `[[push_constant]] uniform T` and +- It proposes to make `uniform` universally mean "push constants" at entry points across all backends + and pipeline stages with Slang version 2026. Where push constants are not first-class, Slang maps + them to the closest equivalent (e.g., D3D root constants or a small constant buffer; OptiX launch parameters). +- It suggests introducing new types such as `PushConstant`, `ShaderRecord`, and `HitAttribute`, + which can be used to unify compile-time mappings across APIs like Direct3D and Vulkan. These new types act + as clearer, more consistent markers of data binding points, compared to the over-loaded semantics + of `uniform` parameters today. + +Together, these changes provide clear, explicit markers of data binding points without overloading +`uniform`, `in`, `out`, and `inout` semantics on ray tracing entry points. + + + + -Additionally, this document proposes annotations to more clearly distinguish between + Status ------ @@ -140,13 +151,37 @@ in complexity. Global attributed uniform buffers prevent more localized and reduced usage of per-dispatch constant values. -The following attempts to disambiguate the two overloaded uses of `uniform` that -Slang users face today. +The following attempts to disambiguate the overloaded uses of `uniform`, `in`, `out`, and +`inout` that Slang users face today. Proposed Approach ----------------- - +1. Define `uniform` as push constants everywhere + - At entry points, `uniform` parameters always map to push-constant-like storage. + Where the target lacks native push constants, Slang lowers to the closest equivalent + (e.g., a small `ConstantBuffer` with root constants on D3D, or OptiX launch parameters). + - This removes stage- and backend-dependent ambiguity. Developers keep using `uniform` for + per-dispatch/draw constants with identical semantics across ray tracing, compute, and graphics. + +2. Introduce `ShaderRecord` for per-shader-record data + - `ShaderRecord` is a first-class generic type valid only on ray-tracing entry points. + - Entry point parameters typed as `ShaderRecord` designate data that lives in the + per-shader record (Vulkan/OptiX SBT; D3D local root signature). Slang reflects this intent so + applications can bind appropriately on each backend. + - Parameters of type `ShaderRecord` are input-only. Using `out`/`inout` is illegal. + +3. Introduce `HitAttribute` for hit attributes + - `HitAttribute` is a first-class generic type valid only on ray-tracing entry points that + maps to hit-attribute registers provided by built-in or user geometry intersectors. + - Parameters of type `HitAttribute` are input-only. Using `out`/`inout` is illegal. + +4. Introduce `Payload` for ray and callable payloads + - `Payload` is a first-class generic type valid only on callable and ray-tracing entry points + that maps to user-controlled payload registers. + - `in`, `out`, and `inout` are all okay and legal on `Payload` parameters. The default is `inout`. + + + 2. **Introduce `ShaderRecord`** 2. **Extend the use of `[[shader_record]] T`** Likewise, we would extend the use of `[[shader_record]]` to become systematically equivalent to: ``` @@ -249,20 +284,29 @@ Proposed Approach `inout` being the default. This would resolve the ambiguity regarding `in` and implicit `uniform` incorrectly mapping to hit attributes - and shader records. + and shader records. --> Detailed Explanation -------------------- -1. **Language-Level Model** + + +1. **Entry-Point Parameter Rules** + * Parameters declared `uniform` at entry points always map to push-constant-like storage + (push constants, root constants, or a small constant buffer) regardless of stage/backend. + * Parameters typed as `ShaderRecord` map to per-shader-record data (Vulkan/OptiX SBT; + D3D local root signature). + * Parameters typed as `Payload` map to payload registers. `in`, `out`, and `inout` apply, + with `inout` as the default. + * Parameters typed as `HitAttribute` map to hit-attribute registers and are input-only. + + -3. **IR and Reflection Impact** - * For Vulkan, the compiler can remap annotations to the necessary `[[vk::push_constant]]` or - `[[vk::shader_record]]` attributes under the hood. +2. **IR and Reflection Impact** * For D3D, the compiler would still produce a `ConstantBuffer` or resource binding in reflection metadata, but with an additional `slang::TypeReflection::Kind::PushConstant` or `slang::TypeReflection::Kind::ShaderRecord` hint. @@ -287,8 +329,21 @@ Detailed Explanation signatures. - + 4. **Migration Strategy** + * Existing Slang code using `[[vk::push_constant]] ConstantBuffer` remains valid but is + encouraged to migrate to `uniform` entry point parameters for clarity and portability. + * Existing code using `[[vk::shader_record]] ConstantBuffer` remains valid; `ShaderRecord` + entry point parameters are the recommended form. + * If either `[[vk::shader_record]]` or `[[vk::push_constant]]` or `[[shader_record]]` or `[[push_constant]]` + appear on entrypoint parameters, these will become "syntax sugar" which is transformed by slang into + the appropriate wrapper type. `[[hit_attribute]]` might be considered for addition to allow for consistency. + * Legacy usage of bare (non-`uniform`) parameters in ray tracing entry points should result in a warning, telling + the user to explicitly mark the parameter with one of: `uniform`, `ShaderRecord`, `Payload`, or `HitAttribute`. + * Default behavior of `uniform` will occur with Slang version 2026. Otherwise, a compiler flag will be added to + enable switching default uniform behavior for RT entrypoints. + + 5. **Example** Rather than this: @@ -311,27 +366,24 @@ void myAnyHitShader( ) {...} ``` -We would now support the following: +We support the following, with explicit types and unambiguous `uniform`: ``` [shader("anyhit")] void myAnyHitShader( - [[hit_attribute]] T1 a, - [[payload]] inout T2 b, - [[push_constant]] T3 c, - [[shader_record]] T4 d + HitAttribute a, + Payload b, + uniform T3 c, + ShaderRecord d ) {...} ``` -* On Vulkan, constant "uniform" data is now compiled to two distinct binding regions: - * `T3` in the push constant region - * `T4` in the shader binding table record -* On D3D, the same code would reflect as two `ConstantBuffer` regions, with -reflection metadata marking them as "intended for push constant" vs. "intended -for shader record." -* `[[payload]]` and `[[hit_attribute]]` distinguish which registers map to `T1` and `T2` -* Any remaining unannotated parameters would default to `[[push_constant]]`, which would match -current behavior with other entry point types. +* On Vulkan, `uniform T3` maps to the push-constant region; `ShaderRecord` maps to the SBT. +* On D3D, reflection shows `T3` as push-constant-like and `T4` as shader-record-like data so apps + can bind via root signatures accordingly. +* `Payload` and `HitAttribute` explicitly select payload and hit-attribute registers. +* Any remaining unannotated parameters should be made explicit; `uniform` is preferred for + per-dispatch constants. It would also now be possible to specify different push constant structures in a mixed ray tracing entrypoint setup. @@ -364,8 +416,14 @@ Alternatives Considered Still, extending `[[push_constant]]` might be a more natural approach, seeing as we already have this annotation. -By extending `[[push_constant]]` and `[[shader_record]]` annotations, we offer a clearer -language-level model that reduces the ambiguity around uniform and bridges the gap -across GPU backends and pipeline stages. This proposal is a stepping stone toward a -more comprehensive "rates" system in Slang, while providing immediate, practical -improvements to developers. +4. `[[shader_record]]`, `[[payload]]`, `[[push_constant]]`, and ``[[hit_attribute]]` + * Early versions of this language proposal suggested to leverage Slang's attribute annotations + to disambiguate `uniform`, `in`, `out`, etc on RT entrypoints. After some internal discussion, + we decided that a `WrapperType` would be a better fit, as this would open the door for + pipeline-scale use of Slang's interfaces. For example, intersection entrypoints conforming to + an LSS interface might be required to accept a standardized payload structure type. + +By redefining `uniform` as push constants and introducing `Payload`, `HitAttribute`, and +`ShaderRecord`, we offer a clearer language model that removes ambiguity and +bridges the gap across GPU backends and pipeline stages. This is a stepping stone toward a more +comprehensive "rates" system in Slang, while providing immediate, practical improvements. From 864ad0e25628d2f797e548515592404e938d74c8 Mon Sep 17 00:00:00 2001 From: Nathan Morrical Date: Tue, 9 Sep 2025 13:20:59 -0700 Subject: [PATCH 2/2] pushconstant->payload --- proposals/017-shader-record.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/017-shader-record.md b/proposals/017-shader-record.md index af2e5ae..187b702 100644 --- a/proposals/017-shader-record.md +++ b/proposals/017-shader-record.md @@ -11,7 +11,7 @@ entry point parameters: - It proposes to make `uniform` universally mean "push constants" at entry points across all backends and pipeline stages with Slang version 2026. Where push constants are not first-class, Slang maps them to the closest equivalent (e.g., D3D root constants or a small constant buffer; OptiX launch parameters). -- It suggests introducing new types such as `PushConstant`, `ShaderRecord`, and `HitAttribute`, +- It suggests introducing new types such as `Payload`, `ShaderRecord`, and `HitAttribute`, which can be used to unify compile-time mappings across APIs like Direct3D and Vulkan. These new types act as clearer, more consistent markers of data binding points, compared to the over-loaded semantics of `uniform` parameters today.