summaryrefslogtreecommitdiffstats
path: root/source/slang/slang-emit-spirv.cpp
Commit message (Collapse)AuthorAge
* Immutable access qualifier for pointers and use `__ldg` on cuda. (#8710)Yong He2025-10-16
| | | | | | | | | | | | | | | | | | | | | | | | This PR implements `Access.Immutable` to allow pointers to immutable data. The new type `ImmutablePtr<T>` is defined as an alias of `Ptr<T, Address.Immutable>`. By forming a immutable pointer, the programmer is conveying to the compiler that the data at the pointer address will never change during the execution of the current program. Therefore loads from immutable pointers can be deduplicated by the compiler, and will translate to `__ldg` when generating code for CUDA. The SPIRV backend is not changed in this PR, since the current SPIRV spec makes it very difficult to specify loads from immutable address without generating tons of wrappers and boilerplate type declarations. We would like to see the spec evolved a bit to around its support of `NonWritable` physical storage pointers or immutable loads before we attempt to express such immutability in SPIRV. For now we simply emit ordinary pointers and loads when generating spirv. --------- Co-authored-by: slangbot <186143334+slangbot@users.noreply.github.com>
* Clean up Slang IR representation of undefined values (#8708)Theresa Foley2025-10-15
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Prior to this change, the Slang IR used a single opcode (`kIROp_Undefined`) to encode all cases of undefined values. The particular motivation for this change was a need to distinguish those undefined values that represent a load from an uninitialized memory location versus other sorts of undefined values. If transforming a variable into SSA form results in `undefined` values in cases where the a `load` was executed without a prior `store`, that represents an error on the programmer's part, and should be diagnosed. However, other cases of undefined values can arise during program transformation and optimization, and should not typically result in diagnostics being emitted. While it was not the original motivation for this change, it is also worth noting that the LLVM project has transitioned from initially using only a single `undef` instruction to having a more nuanced model, and the same factors that motivated their shift also apply to the Slang IR. Counter-intuitively, the semantics of undefined values actually need to be carefully defined. Concretely, this change splits the pre-existing `undefined` opcode into two sub-cases: - `kIROp_LoadFromUninitializedMemory`, to represent the case of loading from a memory location (such as a local variable) that has not been initialized. - `kIROp_Poison`, corresponding to the LLVM `poison` value. Our poison instruction is intended to have semantics comparable to LLVM's equivalent. Conceptually, any operation that is invoked with a poison value as input will (with a few exceptions) produce a poison value as output. One can think of the behavior of `poison` as similar to how not-a-number values propagate in floating-point computations: by default they "infect" the result of any computation they are involved in. This semantic choice helps to ensure that many optimizations end up being correct in the presence of undefined values, even if they did not specifically account for them. The `kIROp_LoadFromUninitializedMemory` case is comparable to the combination of `freeze` and `undef` in LLVM. An LLVM `undef` value has semantics that allow *each* use of that value to be replaced with a *different* arbitrary value; these semantics cause many optimizations to only be correct in the absence of undefined values. An LLVM `freeze` instruction can take an undefined value as input, and produces a single value that is still arbitrary, but must be consistent across all uses. The latter semantics are what we want, since a given `load` from an uninitialized memory location will yield an arbitrary-but-fixed value. Note that we intentionally do not have a direct analogue to LLVM's `undef` instruction, because of the way that `undef` causes so many complications when trying to write optimizations. We also do not add a `kIROp_Freeze` instruction in this change, but that is simply because we currently have no need for it. Existing code that was creating `IRUndefined` values has been updated to create either `IRPoison` or `IRLoadFromUninitializedMemory` values, as appropriate to the use case. Code that was checking for the `kIROp_Undefined` opcode has been updated to either check for both of the new opcodes (in the case of `switch` statements), or to use `as<IRUndefined>` to perform a dynamic cast to the common base type of the two new instructions. Note that this change does not alter the way that instructions representing undefined values are typically emitted as ordinary instructions in the block that produces an undefined value. While emitting `IRLoadFromUninitializedMemory` as an ordinary instruction is exactly what we want, the `IRPoison` case would actually be better represented in Slang IR as a "hoistable" instruction, so that there would only be a singular `poison` value of each type. Changing `IRPoison` to be hoistable would be a good follow-up change, but might run into more challenges depending on what assumptions (if any) the codebase is making about where undefined values get emitted. --------- Co-authored-by: slangbot <186143334+slangbot@users.noreply.github.com>
* Addition of `Load`/`Store` coherent operations (#8395)16-Bit-Dog2025-10-10
| | | | | | | | | | | | | | | | | | | | | | | | Fixes: https://github.com/shader-slang/slang/issues/7634 Duplicate of PR https://github.com/shader-slang/slang/pull/8052 Primary Changes: * Added `storeCoherent` and `loadCoherent` for coherent load/store via pointers. This is backed by `IRMemoryScopeAttr` which is an `IRAttr` attached to `IRLoad` and `IRStore` * Logic in `source\slang\slang-emit-spirv.cpp` for load/store emitting has been reworked to be less messy and more maintainable * Add to `hlsl.meta.slang` coop vector and coop matrix coherent load/store operations Secondary Changes: * Added a missing load/store test for coop matrix: `tests\cooperative-matrix\load-store-pointer.slang` --------- Co-authored-by: ArielG-NV <aglasroth@nvidia.com> Co-authored-by: ArielG-NV <159081215+ArielG-NV@users.noreply.github.com> Co-authored-by: slangbot <186143334+slangbot@users.noreply.github.com> Co-authored-by: Nathan V. Morrical <natemorrical@gmail.com>
* Update debug var when in-param proxy var is being updated. (#8671)Yong He2025-10-10
| | | | | | | | | | | | | | | | | | | | | | | Closes #8664. The problem is that when there is an `in` parameter, Slang will create a local variable to proxy the parameter, copy the value of the parameter into the proxy variable, and replace all uses of the parameter in the function body to use the proxy variable instead. This way all writes to the parameter become writes to the proxy variable. However, when there is debug info enabled, we are also going to create a "debugVariable" corresponding to the parameter, but this debugVariable isn't updated when the proxy variable is updated. The fix is to map the proxy var instead of the original param to the debug var during the `insertDebugValueStore` pass, so that any changes to the proxy var will result in additional stores being inserted to the debug var. Allowing function body to modify an `in` parameter is a bad legacy behavior we inherited from HLSL that we should really be moving away from. I would like us to completely treat an `in` parameter as immutable by default in the next language version (Slang 2026), and make it an error if the user tries to do so. This will allow us to generate much cleaner code and in many cases would help with performance.
* Fix DerivativeGroupQuadsKHR workgroup size validation for texture sampling ↵Lujin Wang2025-10-08
| | | | | | | | | | | | | | | | | | | | | | | (#8647) Fixes #8545 where Slang generates SPIR-V with DerivativeGroupQuadsKHR execution mode but doesn't validate workgroup sizes when texture sampling triggers automatic derivative computation. **Root Cause**: Validation code was looking for IRNumThreadsDecoration on the wrong IR node **Fix**: One-line change in slang-emit-spirv.cpp to search decoration on entryPoint instead of entryPointDecor **Tests**: Added regression tests for both quad and linear derivative group validation Generated with [Claude Code](https://claude.ai/code) --------- Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: Lujin Wang <lujinwangnv@users.noreply.github.com> Co-authored-by: slangbot <ellieh+slangbot@nvidia.com> Co-authored-by: slangbot <186143334+slangbot@users.noreply.github.com>
* Respect isShadow() flag when setting depth type in SPIR-V backend (#8604)Nils Hasenbanck2025-10-04
| | | | | | | This is important for SPIR-V targets that need to know if a texture is designated as a depth texture or not (for example WebGPU). I didn't change the default behavior for when isShadow() is not set, since I didn't want to make the change too invasive.
* Rename some symbols related to pointers types (#8592)Theresa Foley2025-10-03
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Note that while this change touched a large numer of files, there are no changes to functionality being made here. The only things being done are renaming various symbols and, in a few cases, updating or adding comments for consistency with the new names. The core of the naming changes are: * Most things named to refer to `OutType` (e.g., `IROutType`, `IRBuilder::getOutType()`, etc.) have been consistently renamed to refer to `OutParamType`, to emphasize that the relevant AST/IR node types are only intended for use to represent `out` parameters. * The same change as described above for `OutType` is also made for `RefType`, which becomes `RefParamType` in most cases. One mess that this exposes is the way that the `ExplicitRef<T>` type in the core module currently lowers to `IRRefParamType`. This change sticks to the rule of not making functional changes, so that mess is left as-is for now. * Names referring to `InOutType` have been changed to instead refer to `BorrowInOutType`. The intention with this naming change is to emphasize that the Slang rules for `inout` are semantically those of a borrow (or at least our interpretation of what a borrow means). * Names referring to `ConstRefType` have been changed to instead refer to `BorrowInType`. This change starts work on clarifying that the existing `__constref` modifier was never intended to be a read-only analogue of `__ref`, and instead is the input-only analogue of `inout`. * The `ParameterDirection` enum type has been changed to `ParamPassingMode`, to reflect the fact that the concept of "direction" fails to capture what is actually being encoded, particularly once we have modes beyond simple `in`/`out`/`inout`. While this change does not alter behavior in any case (the user-exposed Slang language is unchanged), it is intended to set up subsequence changes that will work to make the handling of these types in the compiler more nuanced and correct. Breaking this part of the change out separately is primarily motivated by a desire to minimize the effort for reviewers. --------- Co-authored-by: slangbot <186143334+slangbot@users.noreply.github.com>
* Rewriting the lower-buffer-element-type pass to avoid unnecessary ↵Yong He2025-09-30
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | packing/unpacking. (#8526) Part of the effort to improve the performance of generated SPIRV code. The existing lower-buffer-element-type pass works by loading the entire buffer element content from memory, and translate it to logical type stored in a local variable at the earliest reference of a buffer handle. This means that is can generate inefficient code that reads more than necessary. Consider this example: ``` struct BigStruct { bool values[1024]; } ConstantBuffer<BigStruct> cb; void test(BigStruct v) { if (v.values[0]) { printf("ok"); } } [numthreads(1,1,1)] void computeMain() { test(cb); } ``` In IR, the `computeMain` function before lower-buffer-element-type pass is something like following: ``` func test: %v = param : BigStruct %barr = fieldExtract(%v, "values") %element = elementExtract(%barr, 0) ... // uses %element func computeMain: %v = load(cb) call %test %v ``` The existing lower-buffer-element-type pass will rewrite the bool array in `BigStruct` into `int` array so it is legal in SPIRV. However, it does so by inserting the translation on the first `load` of the constant buffer: ``` struct BigStruct_std430 { int values[1024]; } var cb : ConstantBuffer<BigStruct_std430>; func computeMain: %tmpVar : var<BigStruct> call %unpackStorage(%tmpVar, cb) %v : BigStruct = load %tmpVar call %test %v ``` This means that the entire array will be loaded and translated to int, before calling `test`, which only uses one element. It turns out that the downstream compiler isn't always able to optimize out this inefficient translation/copy. This PR completely rewrites the way buffer-element-type lowering is handled to avoid producing this inefficient code. It works in two parts: first we turn on the `transformParamsToConstRef` pass for SPIRV target as well, so we will translate the `test` function to take the `v` parameter as `constref`. The second part is a redesigned buffer-element-type pass that defers the storage-type to logical-type translation until a value is actually used by a `load` instruction. In this example, after `transformParamsToConstRef`, the IR is: ``` func test: %v = param : ConstRef<BigStruct> %barr = fieldAddr(%v, "values") %elementPtr = elementAddr(%barr, 0) %element = load(%elementPtr) ... // uses %element func computeMain: call %test %cb ``` The new `buffer-element-type-lowering` pass will take this IR, and insert translation at latest possible time across the entire call graph, and translate the IR into: ``` func test: %v = param : ConstRef<BigStruct_std430> %barr = fieldAddr(%v, "values") %elementPtr : ptr<int> = elementAddr(%barr, 0) %element_int = load(%elementPtr) %element = cast(%element_int) : %bool ... // uses %element func computeMain: call %test %cb ``` In this new IR, there is no longer a load and conversion of the entire array. See new comment in `slang-ir-lower-buffer-element-type.cpp` for more details of how the pass works. This PR also address many other issues surfaced by turning on `transformParamsToConstRef` pass on SPIRV backend. --------- Co-authored-by: slangbot <186143334+slangbot@users.noreply.github.com>
* Add SPV_NV_bindless_texture support (#8534)Lujin Wang2025-09-26
| | | | | | | | | | | | | Treat DescriptorHandle as uint64_t instead of uint2. Implement target-specific SPIR-V emission with the bindless texture support. For OpImageTexelPointer, Image must have a type of OpTypePointer with Type OpTypeImage. Fix the issue by using [constref] in __subscript. Add a test coverage for various texture/sampler handle types. --------- Co-authored-by: slangbot <186143334+slangbot@users.noreply.github.com>
* Fix DebugCompilationUnit to reference main shader file instead of header ↵Lujin Wang2025-09-18
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | files (#7957) This PR implements the requested fix for issue #7923 where DebugCompilationUnit incorrectly referenced header files instead of the main shader file. ## Summary - Modified IRDebugSource to include isIncludedFile flag as third operand - Updated emitDebugSource function to accept and pass the included file flag - Updated call sites to use source->isIncludedFile() from SourceFile class - Modified SPIR-V emission to only create DebugCompilationUnit for non-included files ## Test Results The fix has been verified with the provided reproducer code. The SPIR-V output now correctly shows DebugCompilationUnit referencing the main shader file instead of header files. Generated with [Claude Code](https://claude.ai/code) --------- Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: Lujin Wang <lujinwangnv@users.noreply.github.com> Co-authored-by: Claude Code <claude@anthropic.com> Co-authored-by: slangbot <ellieh+slangbot@nvidia.com> Co-authored-by: slangbot <186143334+slangbot@users.noreply.github.com>
* Fix pointers and C-like layout in varying parameters (#8425)Julius Ikkala2025-09-10
| | | | | | | | | | | | | Closes #8409, but ended up being more about fixing another bug. While the issue itself seems to only be a simple typo fix (see second commit in this PR), I found out during writing a test that pointers never got correct locations regardless of layout. Their locations were always assigned to zero due to lacking a resource usage entry in `TypeLayout`. They were also missing the `Flat` decoration, so I went ahead and added that too. I can split this up into two separate PRs if that's preferred; both aspects just share a test right now and fix a similar-looking issue in the resulting SPIR-V.
* Don't emit ArrayStride 0 for RWStructuredBuffer pointers (#8397)Julius Ikkala2025-09-08
| | | | | | | | | | | | | | | | | Fixes #8396 by not emitting the `ArrayStride` when it would've been zero. The problem is caused by #7848, more details in the issue description. I checked that with equivalent GLSL code, glslangValidator does not emit any `ArrayStride`. I assume that the addition of `storageClass == SpvStorageClassStorageBuffer` to line 1848 is not a mistake. If it is, that addition could also be simply reverted to fix this issue, I tested that option as well. With these changes, Slang tests work locally on my PC again. Related to this; it'd be nice to have GPUs from multiple vendors in the CI to avoid this kind of thing happening again. Or even just llvmpipe; that doesn't even require a GPU and would add at least one more driver to test with.
* [CBP] Pointer frontend changes + groupshared pointer support (#7848)ArielG-NV2025-08-29
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Resolves #7628 Resolves: #8197 Primary Goals: 1. Add `Access` to pointer 2. AddressSpace::GroupShared support for pointers (SPIR-V) 3. Add `__getAddress()` to replace `&` * `&` is not updated to `require(cpu)` since slangpy uses `&`. This means we must: (1) merge PR; (2) replace `&` with `__getAddress()`; (3) add `require(cpu)` to `&` Changes: * Added to `Ptr` the `Access` generic argument & logic (for `Access::Read`). * Moved the generic argument `AddressSpace` from `Ptr` to the end of the type. * Added pointer casting support between any `Ptr` as long as the `AddressSpace` is the same * Disallow globallycoherent T* and coherent T* * Disallow const T*, T const*, and const T* * Fixed .natvis display of `ConstantValue` `ValOperandNode` * Support generic resolution of type-casted integers * Added `VariablePointer` emitting for spirv + other minor logic needed for groupshared pointers Breaking Changes: * Anyone using the `AddressSpace` of `Ptr` will now have to account for the `Access` argument * we disallow various syntax paired with `Ptr` and `T*` --------- Co-authored-by: slangbot <186143334+slangbot@users.noreply.github.com>
* Add SPIRV OpCapability for 8/16bit use in storage (#8194)James Helferty (NVIDIA)2025-08-28
| | | | | | | | | | | | | | | | | | | | | Emits the appropriate OpCapability for 8- and 16-bit type usage: - UniformAndStorageBuffer8BitAccess: for 16-bit types in SpvStorageClassUniform and SpvStorageClassStorageBuffer - UniformAndStorageBuffer16BitAccess: for 16-bit types in SpvStorageClassUniform and SpvStorageClassStorageBuffer - StoragePushConstant8: for 8-bit types in SpvStorageClassPushConstant - StoragePushConstant16: for 16-bit types in SpvStorageClassPushConstant - StorageInputOutput16: for 16-bit types in SpvStorageClassInput and SpvStorageClassOutput Generated with Claude Code, with revisions. Fixes #7879. --------- Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: James Helferty (NVIDIA) <jhelferty-nv@users.noreply.github.com> Co-authored-by: slangbot <186143334+slangbot@users.noreply.github.com>
* Fix mesh shader OutputIndices subscript error by adding missing ref accessor ↵Lujin Wang2025-08-22
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | (#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>
* Introduce CDataLayout & -fvk-use-c-layout (#8136)Julius Ikkala2025-08-21
| | | | | | | | | | | | | | | | Closes #8112. ~~The issue asks for a "C layout", but in this PR I use the term "CPU layout" because this naming was pre-existing in the codebase as `kCPULayoutRulesImpl_`. The primary purpose of this layout is to match CPU-side struct definitions with the shader side. I'm open to better naming suggestions, though.~~ Edit: switched back to using `CDataLayout` & `-fvk-use-c-layout`, as the CPU target depends on the object layout rules of existing CPU layout rules, but they're incompatible with actual shaders. So a new `kCLayoutRulesImpl_` was needed anyway. --------- Co-authored-by: Ellie Hermaszewska <ellieh@nvidia.com>
* Implement SV_VulkanSamplePosition (#8236)davli-nv2025-08-21
| | | | | | | | | | | | | | | | -Adds semantic SV_VulkanSamplePosition that emits corresponding gl_SamplePosition and SpvBuiltinSamplePosition -Adds gl_SamplePosition property to glsl.meta.slang -Adds SPIRV and GLSL tests for the semantic and property -Plan is to later implement SV_SamplePosition that follows HLSL range of -0.5 to +0.5, and emits GetRenderTargetSamplePosition(SV_SampleIndex) which needs more complicated IR manipulation for HLSL and Metal Fixes #7906 --------- Co-authored-by: ArielG-NV <159081215+ArielG-NV@users.noreply.github.com>
* [SPIR-V] Emit control flags for `branch/flatten` decorations (#8134)amidescent2025-08-09
| | | | Co-authored-by: Jay Kwak <82421531+jkwak-work@users.noreply.github.com> Co-authored-by: slangbot <186143334+slangbot@users.noreply.github.com>
* Fix atomic fp16 vector SPIRV emit (#8104)jarcherNV2025-08-07
| | | | Update the SPIRV emit of atomic fp16 vector extension from its previous incorrect name to SPV_NV_shader_atomic_fp16_vector.
* Fix noperspective modifier for SV_Barycentrics in SPIRV and GLSL (#8067)davli-nv2025-08-06
| | | | | | | | | | | | | | | | | | | | | | | | | | * Fix noperspective modifier for SV_Barycentrics in SPIRV and GLSL - Added test case with both regular and noperspective SV_Barycentrics inputs 🤖 Generated with [Claude Code](https://claude.ai/code) Co-authored-by: davli-nv <davli-nv@users.noreply.github.com> * fixup format * address review https://github.com/shader-slang/slang/pull/8067#pullrequestreview-3090037501 * address review https://github.com/shader-slang/slang/pull/8067#discussion_r2255818595 * add test case from review --------- Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: davli-nv <davli-nv@users.noreply.github.com>
* Implement SPV_EXT_fragment_invocation_density (SPV_NV_shading_rate) (#8037)davli-nv2025-08-05
| | | | | | | | | | | | | | | | | | | | | * Implement SPV_EXT_fragment_invocation_density -Adds semantics SV_FragSize and SV_FragInvocationCount and implements them for SPIRV and GLSL using the appropriate target builtins from extensions. -Adds test case checking for expected target builtins from these semantics. -For future work, could implement SV_FragSize using pixel shader input SV_ShadingRate for HLSL, and SV_FragInvocationCount needs research. Fixes #7974 Generated with Claude Code * address review feedback https://github.com/shader-slang/slang/pull/8037#pullrequestreview-3084645845 * fixup format * review feedback https://github.com/shader-slang/slang/pull/8037#pullrequestreview-3086442819
* Lowering unsupported matrix types for GLSL/WGSL/Metal targets (#7936)venkataram-nv2025-07-30
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | * Add emit cases for WGSL and GLSL * Fix compilation warnings Modify short cutting test to reflect change in emit logic Lower matrix for metal as well Add emit matrix logic for metal Fix compiler warning Brace initializer for lowered matrices Fix compiler warnings * Tests for metal * Fix mult, any, and determinant * Fix matrix-matrix multiplication * Fix mat mul to be element-wise * Fix compiler warning * Move makeMatrix to legalization * Move unary and binary arithmetic operator lowering to legalization * Remove emit logic and move final comparison operators to legalization * Handle vector/matrix negation for WGSL * Restore older SPIR-V emit logic * Address PR comments * Revert to zero minus for negation * format code --------- Co-authored-by: slangbot <186143334+slangbot@users.noreply.github.com>
* Fix nv_viewport_mask semantic to emit SpvBuiltInViewportMaskNV (#7904)davli-nv2025-07-25
| | | | | Fixes #7903 SPV_NV_viewport_array2 says ViewportMaskNV corresponds to gl_ViewportMask
* Fix SPIRV OpMemberName member indices (#7912)davli-nv2025-07-25
| | | | | | | | | | | | | | | | OpMemberName instructions were all using member index 0 instead of incrementing indices (0, 1, 2, ...) as required by the SPIR-V spec. The bug was that the member index increment (id++) was only happening for physical struct types, but OpMemberName emission occurs for all struct types when they have name decorations. This fix ensures member indices are properly incremented for both physical and non-physical struct types. Fixes #7909 Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: davli-nv <davli-nv@users.noreply.github.com>
* Include Inst UID in some assert failure messages. (#7882)Yong He2025-07-24
|
* Lower int/uint/bool matrices to arrays for SPIRV (#7687)venkataram-nv2025-07-18
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | * Add tests for expected behaviour * Allow matrix types in logical or/and * Legalize int/bool matrix types and construction with makeMatrix * Legalize uint matrices and operations * Limit testing to only SPIRV * Better tests for int and bool * Add test for uint * Remove GLSL tests * Remove old test for diagnosing int matrices * Emit SPIRV directly in tests * format code * Address PR comments * Improve testing * Address PR comments * format code * Add tests for matrix intrinsic operations * Move matrix lowering to dedicated legalization pass * Fix compiler warning * Remove signal again * Reorder matrix and vector legalization * Fix formatting * Add shift and comparison tests --------- Co-authored-by: slangbot <186143334+slangbot@users.noreply.github.com>
* Fix duplicate DiffPair struct generation for row_major matrices in autodiff ↵Copilot2025-07-16
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | (#7728) * Initial plan * Fix duplicate DiffPair struct generation for row_major matrices in autodiff Co-authored-by: csyonghe <2652293+csyonghe@users.noreply.github.com> * Fix matrix layout conversion to use BuiltinCastExpr Address root cause in slang-check-conversion.cpp by creating proper cast expressions for matrix layout conversions instead of reusing expressions. This ensures autodiff sees proper type conversions and generates consistent DiffPair structs. Reverted the band-aid fix in autodiff system and implemented the proper front-end fix as suggested in code review. Co-authored-by: csyonghe <2652293+csyonghe@users.noreply.github.com> * Fix test to prevent dead code elimination and make it executable on CPU Co-authored-by: csyonghe <2652293+csyonghe@users.noreply.github.com> * Fix spirv emit of matrix layout cast insts. * Update test. * cleanup test. * Improve test with meaningful values that verify correct gradient computation Co-authored-by: csyonghe <2652293+csyonghe@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: csyonghe <2652293+csyonghe@users.noreply.github.com> Co-authored-by: Yong He <yonghe@outlook.com>
* Fixup address spaces after inlining. (#7731)Yong He2025-07-11
| | | | | * Fixup address spaces after inlining. * add -O0
* Add DebugGlobalVariable instructions to SPIR-V output (#7686)Jay Kwak2025-07-11
| | | | | | | | | | | | | | | | | | | | | | | | * Add DebugGlobalVariable instructions to SPIR-V output Implements generation of DebugGlobalVariable instructions for global variables like Texture2D and SamplerState in SPIR-V debug information output. Adds debug type support for texture and sampler types using DebugTypeComposite. * Handle two more types for DebugGlobalVariable kIROp_RaytracingAccelerationStructureType and kIROp_SamplerComparisonStateType had to be handled in `emitDebugTypeImpl()` * Fix format * Refactor debug type emission to reduce duplication Use IRSamplerStateTypeBase type check and fallback pattern instead of separate cases for each opcode type. * Fix compiler warning * Simplify `emitDebugTypeImpl()` more
* Generate OpExecutionMode PointMode for tessellation shaders (#7662)pdeayton-nv2025-07-09
| | | | | | | * Generate "OpExecutionMode PointMode" for tessellation shaders instead of the incorrect geometry and mesh shader specific "OpExecutionMode OutputPoints". * Add a test case verifying the OpExecutionMode is correct. Fixes #7660
* Fix for emitting ArrayStride decoration for arrays of opaque types (#7568)Jerran Schmidt2025-07-02
| | | | | | | | | * WIP opaque type decoration fix * Clearer intent * Formatting * Added test for fix
* Defer immutable buffer loads when emitting spirv. (#7579)Yong He2025-07-02
| | | | | | | | | | | | | * Defer immutable buffer loads when emitting spirv. * Fix. * Fix. * Fix. * Fix tests. * Fix test.
* extend fiddle to allow custom lua splices in more places (#7559)Ellie Hermaszewska2025-07-01
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | * Add fkYAML submodule * Generate slang-ir-inst-defs.h from slang-ir-inst-defs.yaml * generate ir-inst-defs.h * neaten things * neaten inst def parser * add rapidyaml submodule * remove fkyaml * remove fkyaml submodule * remove use of ir-inst-defs.h * format and warnings * fix wasm build * tidy * remove rapidyaml * Extend fiddle to allow custom splices in more places * Use lua to describe ir insts * fix * neaten * neaten * neaten * spelling * neaten * comment comment out assert * merge
* Add arguments for controlling floating point denormal mode (#7461)aidanfnv2025-07-01
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | * Implement -fp-denorm-mode slangc arg * Split fp-denorm-mode into 3 args for fp16/32/64 * Remove redundant option categories * Use emitInst for multiple of the same OpExecutionMode * Fix formatting * Remove -denorm any * Re-add option categories * emitinst for ftz * Use enums for type text * Remove extra categories again * Add tests for denorm mode * Move denorm mode to post linking * format code (#8) Co-authored-by: slangbot <186143334+slangbot@users.noreply.github.com> * regenerate command line reference (#9) Co-authored-by: slangbot <186143334+slangbot@users.noreply.github.com> * Clean up tests * Fix option text * format code (#10) Co-authored-by: slangbot <186143334+slangbot@users.noreply.github.com> * Add tests for "any" mode * Return "any" enum if option not set * Simplify emission logic * Add support for generic entrypoints * Move denorm modes to end of CompilerOptionName enum * format code (#11) Co-authored-by: slangbot <186143334+slangbot@users.noreply.github.com> * Move new enum members to before CountOf * Add not checks to tests, fix generic test, add functionality tests * Rename denorm to fpDenormal * Clean up functional test * Rename denorm test dir * Fix formatting, regenerate cmdline ref * Fold simple tests into functional tests, add more dxil checks * Remove no-op DX tests, make tests more consistent * Disable VK functionality tests that will fail on the CI configs * Fix formatting * Add comments to disabled tests explaining why --------- Co-authored-by: slangbot <ellieh+slangbot@nvidia.com> Co-authored-by: slangbot <186143334+slangbot@users.noreply.github.com>
* Emit sample index when constructing a `OpImageTexelPointer` (#7563)ArielG-NV2025-06-30
| | | | | | | | | | | * fix #7554 * format code * test ms and non ms texture --------- Co-authored-by: slangbot <186143334+slangbot@users.noreply.github.com>
* Support the GLSL/SPIR-V Built-in variable `DeviceIndex` (#7552)ArielG-NV2025-06-29
| | | | | | | | | | | * Support DeviceIndex * format code * regenerate command line reference --------- Co-authored-by: slangbot <186143334+slangbot@users.noreply.github.com>
* Fix for OpUConvert producing invalid opcode when to/from signs differ (#7398)Jerran Schmidt2025-06-26
| | | | | | | | | | | | | | | | | * Fix for OpUConvert outputting scalar type for mixed sign vector type conversions * Fix compiler warning * Added regression test for UConvert vector fix * Formatting * getUnsignedType helper * Formatting * Fix for addtional int types * Helper function to convert signed type to unsigned type
* Fix the invalid SPIRV decoration issue (#7527)kaizhangNV2025-06-26
| | | | | | | | | | | | | | * Fix the invalid SPIRV decoration issue Close #7508. SPIRV doesn't allow decoration on type with Private or Function storage class. In our lowering logic, if the array type is used by buffer type it will always have stride operand after lowering, so if the array is not used by buffer type, it must be used only by thread_local or group_shared variable, and it will not have stride operand. For this case, we don't need to emit stride decoration for SPIRV.
* Correct the scope for DebugLocalVariable (#7516)Lujin Wang2025-06-26
| | | | | | | | | | | | | | | | * Correct the scope for DebugLocalVariable All of the DebugLocalVariable instructions have their scope set to DebugCompilationUnit. The scope should instead be set to a DebugFunction, or a DebugLexicalBlock which is recursively inside a DebugFunction. Register the debug info for the function instructions, which helps findDebugScope() to find the right DebugFunction scope for DebugLocalVariable. * Add a test for DebugLocalVariable To check the scope, which should be a DebugFunction.
* Always emit DepthReplacing execution mode when writing to FragDepth (#7450)dubiousconst2822025-06-19
|
* Fix for missing signedness cast in SwizzleIR (#7448)Jerran Schmidt2025-06-16
| | | | | | | | | * Cast if there is a signedness mismatch on the swizzle * Move isSignedType to slang-util and add test --------- Co-authored-by: Yong He <yonghe@outlook.com>
* Add command line option for separate debug info (#7178)jarcherNV2025-06-06
| | | | | | | | | | | | | * Add command line option for separate debug info Add command line arg -separate-debug-info which, if provided, produces both a .spv and a .dbg.spv file. The .dbg.spv file contains full debug info and the .spv file has all debug info stripped out. Also add a DebugBuildIdentifier instruction to store a unique hash in both the output files, so they can be more easily matched together. A matching API is provided to allow using the Slang API to retrieve a base and debug SPIRV as well as the debug build identifier string.
* Fix SPIRV `OpSpecConstantOp` emit (#7158)Darren Wihandi2025-05-29
| | | | | | | | | | | | | * Fix SPIRV specialization constant with floating-point operations * Improve test * WIP * Restrict `OpSpecConstantOp` allowed operations based on SPIRV specifications * Fix typo on floating type check * Emit error on float to int spec cosnt int val casts
* Implement MapElement for CoopMat (#7159)Jay Kwak2025-05-29
| | | | | | | | | With this PR, MapElement works for the following signatures: - CoopMat<...>::MapElement(functype(...)); - CoopMat<...>::MapElement(capturing-lambda); - CoopMat<...>::MapElement(not-capturing-lambda); - Tuple<CoopMat<...>,...>::MapElement(functype(...)); - Tuple<CoopMat<...>,...>::MapElement(capturing-lambda); - Tuple<CoopMat<...>,...>::MapElement(not-capturing-lambda);
* Add CoopVec load/store pointer overloads (#6822)Darren Wihandi2025-05-23
| | | | | | | | | | | * Add pointer/T* variants for coop vec load/store * fix stride decoration and improved test * fix compile warnings * Improve test * Use `coopVecLoad` function in test
* Map `SV_VertexID` to `gl_VertexIndex-gl_BaseVertex`, add `SV_Vulkan*ID` ↵Darren Wihandi2025-05-19
| | | | | | | | | | | | | | | | | semantics (#7150) * Map SV_VertexID to `gl_VertexIndex - gl_BaseVertex`, provide SV_Vulkan* SV semantics * Fix docs * Regenerate toc * Fix affected pointer-2 test * Add tests --------- Co-authored-by: Yong He <yonghe@outlook.com>
* Support Vulkan memory model (#7057)Jay Kwak2025-05-16
| | | | | | | | | | | | | | | The user can explicitly use Vulkan memory model, or it will be automatically used when cooperative-matrix is used. When vulkan memory model is used, two keywords, "Coherent" and "Volatile", are not allowed. There are many differences regarding atomic and texture but this PR has changes limited to support `globallycoherent` keyword. When variables with `globallycoherent` is used with `OpLoad`, it will use additional options, `MakePointerAvailable|NonPrivatePointer`, that will provide the same effect. For `OpStore`, it will use `MakePointerVisible|NonPrivatePointer`.
* Address structured buffer `GetDimensions` issues for WGSL, GLSL and SPIRV ↵Darren Wihandi2025-05-16
| | | | | | | | | | | | | | | | | | | | | | | (#7010) * Fix structured buffer get dimensions * Further fixes and added tests * Remove unnecessary include * Fix test issues * attempt to fix wgpu crash * test remove half usage in test * attempt to fix WGPU test issue * Another attempt to fix WGSL test - make test similar to the existing GetDimensions test --------- Co-authored-by: Yong He <yonghe@outlook.com>
* Support tensor addressing (#7060)Jay Kwak2025-05-15
| | | | | | | | | | | This commit implements two new types and related Load/Store functions in CoopMat. tensor_addrressing.TensorLayout tensor_addressing.TensorView CoopMat.Load(..., TensorLayout) CoopMat.Load(..., TensorLayout, TensorView) CoopMat.Store(..., TensorLayout) CoopMat.Store(..., TensorLayout, TensorView) CoopMat.Load(..., TensorLayout, TensorView)
* support specialization constant sized array (#6871)kaizhangNV2025-05-14
| | | | | | | | | | | | | | | | | | | | | Close #6859 Goal of this PR We want to support an array whose size can be specialization constant for shared/global variable e.g. layout (constant_id = 0) const uint BLOCK_SIZE = 64; shared float buf_a[(BLOCK_SIZE + 5) * 4]; Overview of the solution: During IndexExpr check, we will loose the restriction to allow SpecConst passing, but the size parameter will not be a constant value because it cannot be folded into a constant, so we will make it follow the same logic as generic parameter value, and the size will be represented by FuncCallIntVal/PolynomialIntVal/DeclRefIntVal. During IR lowering, we will detect whether there is spec constant in the IntVal, and wrap the IRInst with a SpecConstRateType, and propagate the type though the lowering logic, such that the IntVal representing the array size will have SpecConstRateType. During spirv emit stage, if we detect that a IRInst has SpecConstRateType, we will emit it as SpecConstantOp. We have to implement new logic to emit OpSpecConstantOp, the existing emit logic doesn't support emitting OpSpecConstantOp, especially this op can embed arithmetic operation at global scope, where we can only emit arithmetic instruct at local. But there are only few instructs we need to support. Overview of the solution: This PR doesn't support generic, and we will create a separate PR to extend that, tracked in #6840.