summaryrefslogtreecommitdiff
path: root/tests
AgeCommit message (Collapse)Author
2025-09-29Fix segfault when shader entry points return resource types (#8434)Copilot
The Slang compiler was segfaulting when trying to compile shaders that return resource types (like `Texture2D`, `RWTexture2D`, `SamplerState`, etc.) from entry point functions. This occurred because there was missing validation that should reject such invalid return types before they reach IR generation. For example, this code would cause a segfault: ```slang StructuredBuffer<Texture2D<int>> skyLight; [shader("compute")] Texture2D<int> computeMain(uint3 threadID : SV_DispatchThreadID) { return skyLight[threadID.x]; } ``` ## Root Cause The issue was in the entry point validation logic in `validateEntryPoint()`. While there was a TODO comment indicating that return type validation should be performed, it was never implemented. The compiler would accept the invalid shader code and attempt to process it during IR lowering, where resource types as return values are not properly handled, leading to a segmentation fault. ## Solution 1. **Added robust validation**: Modified `validateEntryPoint()` in `slang-check-shader.cpp` to use the existing `SemanticsVisitor::getTypeTags()` functionality to check for invalid return types by detecting `TypeTag::Opaque` and `TypeTag::Unsized` bits. This leverages the existing type analysis infrastructure that comprehensively handles: - Direct resource types (Texture2D, RWTexture2D, SamplerState, etc.) - Structs containing resource-typed fields (through type tag propagation) - Nested structures and complex type hierarchies - Arrays and other composite types 2. **Added diagnostic message**: Uses existing diagnostic `entryPointCannotReturnResourceType` (error 38010) that provides a clear error message explaining why resource types cannot be returned from shader entry points 3. **Updated existing tests**: Modified existing tests to match the updated validation behavior ## Result Instead of a segfault, users now get a clear, actionable error message: ``` error 38010: entry point 'computeMain' cannot return type 'Texture2D<int>' that contains resource types ``` The fix properly handles all resource types including `Texture2D`, `RWTexture2D`, `SamplerState`, and others, while preserving the ability to compile valid shaders that return simple data types. Fixes #6438. <!-- START COPILOT CODING AGENT TIPS --> --- 💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more [Copilot coding agent tips](https://gh.io/copilot-coding-agent-tips) in the docs. --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: expipiplus1 <857308+expipiplus1@users.noreply.github.com> Co-authored-by: Ellie Hermaszewska <ellieh@nvidia.com> Co-authored-by: csyonghe <2652293+csyonghe@users.noreply.github.com>
2025-09-26Add SPV_NV_bindless_texture support (#8534)Lujin Wang
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>
2025-09-26Diagnostic on use of unsupported entry point modifiers (#8487)James Helferty (NVIDIA)
Generate a diagnostic warning whenever unsupported modifiers (keywords, attributes) are found on entry point parameters. These have been silently ignored up until now, with the parser accepting them but Slang not actually doing anything with them. Fixes #7151 --------- Co-authored-by: slangbot <186143334+slangbot@users.noreply.github.com>
2025-09-26Remove `cooperative-vector` tests from expected CI failures (#8381)aidanfnv
Fixes #7715 Updating the Vulkan SDK on the Windows CI machines to 1.4.321.1 has fixed some illegitimate VVL errors in the `cooperative-vector` tests, and #8541 has fixed some legitimate VVL errors in some of those tests, so now they can be removed from the list of expected test failures. The only expected `cooperative-vector` failures that remain are for `-emit-spriv-via-glsl`, as we do not support `GLSL_NV_cooperative_vector` yet, see #7727.
2025-09-25Fix VVL errors on coopvec tests (#8541)Jay Kwak
It appears that the inputType of the coopvec-mat-mul cannot be signed int32. It could be floating types or signed int32. Changing the tests to use uint32 instead of int32. The spec guarantees the following combinations and the rest should be queried at the runtime if it is supported by the HW. https://registry.khronos.org/vulkan/specs/latest/man/html/VkCooperativeVectorPropertiesNV.html#_description inputType | inputInterpretation | matrixInterpretation | biasInterpretation | resultType -- | -- | -- | -- | -- FLOAT16 | FLOAT16 | FLOAT16 | FLOAT16 | FLOAT16 UINT32 | SINT8_PACKED | SINT8 | SINT32 | SINT32 SINT8 | SINT8 | SINT8 | SINT32 | SINT32 FLOAT32 | SINT8 | SINT8 | SINT32 | SINT32 FLOAT16 | FLOAT_E4M3 | FLOAT_E4M3 | FLOAT16 | FLOAT16 FLOAT16 | FLOAT_E5M2 | FLOAT_E5M2 | FLOAT16 | FLOAT16
2025-09-25Adding 4 WGPU tests to expected-failure-github (#8540)Jay Kwak
Four WGPU tests print VVL errors. And it is preventing us from upgrading VulkanSDK on CI machines. This commit put them in the expected-failure-github.txt so that we can continue upgrading VulkanSDK. They will be re-enabled when the following issues are resolved: - https://github.com/shader-slang/slang/issues/8145 - https://github.com/shader-slang/slang/issues/8379
2025-09-25Prepare VulkanSDK release Oct 2025 (#8525)Jay Kwak
Related to - https://github.com/shader-slang/slang/issues/8519
2025-09-24Remove unnecessary Load and Store pair (#8433)Jay Kwak
This commit removes unnecessary Load and Store pairs in IR. When the IR is like ``` let %1 = var let %2 = load(%ptr) store(%1 %2) ``` This PR will replace all uses of %1 with %ptr. And the load and store instructions will be removed. But I found that there can be cases where %2 might be still used later in other IRs. For these cases, the removal of load instruction relies on DCE. --------- Co-authored-by: slangbot <ellieh+slangbot@nvidia.com>
2025-09-23Legalize type as well in legalizeOperand (#8483)Gangzheng Tong
This fixes a type mismatch issue. See the generated cuda code ```cuda struct Query_0 { EmptyExample_0 query_0; uint hasNonEmptyAbsorbingBoundary_0; }; struct Query_1 { uint hasNonEmptyAbsorbingBoundary_0; }; struct GlobalParams_0 { Query_0* gQuery_0; RWStructuredBuffer<float3 > gInput_0; RWStructuredBuffer<float> gOutput_0; }; ... Query_1 _S4 = *globalParams_0->gQuery_0; // ==> type mismatch at call site! ``` **Root Cause:** During the empty type legalization pass in Slang's IR processing, struct types were being optimized. e.g., `Query_0` → `Query_1` with empty type removed), but this created an inconsistency: **Function parameters were updated:** When Query_compute_0 function was legalized, its parameter type was correctly updated from `Query_0` to the optimized `Query_1` **Global parameter types were NOT updated:** The `ParameterBlock<Struct>` type in globalParams still referenced the old `Query_0` type The PR adds special handling for type operands in the `legalizeInst` function. This triggers the legalization of the `StructType` from the original `legalizeOperand` call site. The leaglized result will be saved in the type-to-legal-type map and be re-used when the same type requires legalization again (e.g. in the `IRFunc` as parameter) Fixes: https://github.com/shader-slang/slang/issues/7905
2025-09-23Lookup refactor (#8467)kaizhangNV
Close #8201. This PR unify the lowering logic for LookupDeclRef of an interface requirement. We will always lower this AST node to a LookupWitness IR. The key of this IR is the special witnessTableType `ThisTypeWitness`, this witness Table is simply a wrapper for an interface type. Our current specialization pass doesn't handle this kind of LookupWitness IR at all, so we will also add the specialization of this_type IR as well.
2025-09-23fix a crash when using type equality constaint (#8515)kaizhangNV
Close #8193. When constructing `TransitiveTypeWitness` node, we should check if there is operand that represents two equal times. Currently, we only check whether the operand is `TypeEqualityWitness`, which is not good enough, because a `DeclaredSubtypeWitness` could also be representing two same types, in that case, we should also const fold this kind of witness. Fails to do so, we could finally ends up with a generating a lookup witness IR on a generic parameter that is not supposed to be looked up.
2025-09-23Fix varying output structs in GLSL source (#8501)Julius Ikkala
Closes #8500. `slang-ir-translate-global-varying-var.cpp` turns the global varying outputs into a struct that's returned from the entry point. Currently, there's a problem when one of the outputs is a struct. It always creates a generic `IRTypeLayout`, even when a correct type layout already exists. Somehow, this appears to work when the global varying outputs aren't structs. The crash occurs in `slang-ir-glsl-legalize.cpp:createGLSLGlobalVaryingsImpl()`. It correctly handles the generated outer struct, but when that contains an inner struct, it's been given a non-struct type layout and crashes. This PR uses the correct layout if found, instead of generating a broken placeholder. This matches the behaviour that has already been implemented for inputs. Additionally, I removed a call to `addResourceUsage` from both the input and output side. I can't see any way in which it would've affected anything, the layout builder is never used after that call and it doesn't retroactively modify the layout that was already created.
2025-09-23Split overloaded uses of RefType in front-end (#8427)Theresa Foley
Overview ======== This change is the start of an attempt to address how the Slang compiler codebase has ended up conflating two similar, but semantically distinct, concepts: * The long-standing notion of `ref` parameters (only allowed for use in the builtin modules), which are encoded using a wrapper `Type` in the AST as part of the representation of the parameters of a `FuncType`. * A recently-introduced notion of explicit reference types that mirror the built-in `Ptr` type, with a relationship comparable to that between pointer and reference types in C++. The change splits the `Ref<T>` type in the core module into two distinct types, with one for each of the two use cases. Similarly, the `RefType` class in the compiler's AST is split into two distinct classes, to represent the two cases. Background ========== The `Ref<T>` type in the core module (hidden and not intended for users to ever see or use) was originally introduced to encode the `ref` parameter-passing mode, comparable to the hidden `Out<T>` and `InOut<T>` types used to encode `out` and `inout` parameter-passing modes. The `Ref<T>` type in the core module was encoded as a instance of the `RefType` class in the Slang AST (similar to how `Out<T>` mapped to an `OutType`). These AST classes were *only* intended to be used by the compiler front-end as part of its encoding of function types. The `FuncType` class needed a way to distinguish an `inout int` parameter from a plain (implicitly `in`) `int` parameter, so these wrapper like `RefType` and `OutType` were introduced to encode both the parameter type (`T`) and the parameter-passing mode in a form that could be passed around as a `Type`. Notably, the `Ref<T>` type (and `Out<T>`, etc.) were *not* intended to be type names that ever get uttered in Slang code (not even in the builtin modules), and the vast majority of the compiler code was not supposed to ever encounter them. They were an implementation detail of `FuncType`, and nothing else. (In hindsight it may have been a mistake to use a nominal type declared in the core module to implement these wrappers; it might have been a good idea to use an entirely separate class of `Type` for this case...) Recent changes to the builtin modules introduced functions that wanted to *return* a reference (so that the parameter-passing-mode modifiers like `ref` could not trivially be used), and as part of those changes the appealingly-named `Ref<T>` type in the core module was re-used for this new case. Builtin operations were declared with an explicit `Ref<T>` return type, and parts of the compiler front-end that had previously been blissfully unaware of the AST's `RefType` (and `InOutType`, etc.) had to start accounting for the possibility that an explicit `Ref<T>` would show up. Related changes also introduced a comparable conflation of the (unfortunately-named) `constref` parameter-passing modifier and builtin operations that wanted to return an explicit reference that is read-only. Both use cases were mapped to the core-module `ConstRef<T>` type, which appeared in the AST as an instance of the `ConstRefType` class. The overlapping use of `ConstRef<T>`` is actually significantly more troublesome than the `Ref<T>` case because, despite what its name implies, `constref` was not really supposed to be the read-only analogue of `ref`, but rather it is closer to the "immutable value borrow" analogue to `inout`'s "mutable value borrow." The semantics of a "value borrow" vs. a "memory reference" in Slang have not been very carefully codified, and the conflation around `ConstRef<T>` has contributed to things becoming increasingly muddy in the compiler back-end. Main Changes ============ Core Module ----------- The `Ref<T>` type has been replaced with two distinct types, with one for each use case: * `RefParam<T>` is intended for use when encoding a `ref` parameter in a function type * `ExplicitRef<T>` is intended for use when an operation in a builtin module wants to return a reference The other types used to represent parameter-passing modes (e.g., `InOut<T>`) were renamed to better indicate that their role in defining parameter types (e.g., `InOutParam<T>`). The `ExplicitRef<T>` type was given additional generic parameters for the allowed access and the address space, akin to what `Ptr<T>` now supports. The pointer dereference operator (prefix `*`) in the core module should now properly propagate the access and address space of the pointer over to the reference that gets returned. The two distinct use cases of `ConstRef<T>` were not split in the way as `Ref<T>`, instead the case for the `constref` parameter-passing mode uses `ConstParamRef<T>`, while cases that previously used `ConstRef<T>` to represent a read-only explicit reference instead now use `ExplicitRef<T, Access.Read>`. Prior to this change there were two subscripts declared on pointers: one in the `Ptr` type itself, and another in an `extension` for pointers with `Access.ReadWrite`. The comments on the code seemed to indicate that the catch-all subscript used to only have a `get` accessor, while the `ref` was only available on read-write pointers, but it seems that subsequent changes converted the default subscript to support `ref`. This change eliminates the subscript added via `extension`, since it is redundant. AST and Front-End ================= Similar to the changes in the core module, the AST `RefType` class was split into: * `RefParamType` for the case of encoding `ref` parameters * `ExplicitRefType` for the case where the user meant an explicit reference type All the other classes that represent wrappers for encoding parameter-passing modes (e.g., `OutType`) were similarly renamed (e.g., `OutParamType`). The `ConstRefType` class was simply renamed to `ConstRefParamType`, because any use cases of `ConstRefType` that intended an explicit reference type will now use `ExplicitRefType` with `Acccess.Read`. For convenience, this change includes type aliases to map the old names for these types over to the new ones (e.g., `using OutType = OutParamType`) so that the change doesn't need to affect quite so many lines of code. The `RefType` and `ConstRefType` names are intentionally left undefined, since it woudl be unsafe to assume that existing use sites should default to either of the two possible interpretations. All use cases of `RefType` and `ConstRefType` (and their former shared base class `RefTypeBase`) were audited and updated to refer to either `RefParamType`/`ConstRefParamType` or `ExplicitRefType`, as appropriate (based on whether the context of the code indicated it was working with parameter-passing mode wrapper types, or explicit reference types). In many (many) cases comments were added to the code that was updated (and some unrelated code that needed to be audited along the way) to note cases where there appears to be something fishy going on in the compiler and/or there are obvious opportunities for next-step improvement. The `QualType` constructor used to infer l-value-ness when passed a `RefType` or `ConstRefType`; that code was introduced to support explicit reference types. The code was updated to consult the access argument of an `ExplicitRefType` to try and determine the right l-value-ness to use. There is some ambiguity about what should be done in the case where the value of the generic argument representing the access cannot be statically determined; a better solution may be needed. Many other cases in the front-end that were working with `RefType` and `ConstRefType` for explicit references also need to figure out l-value-ness, and these were changed to rely on the logic already added to `QualType` so that it wouldn't have to be duplicated. It isn't clear if this structure is the best way to tackle the problem, but it seems to at least be an upgrade over the more strictly ad-hoc logic that was in place before. Future Work =========== IR-Level Work ------------- The most obvious next step to take is that the split that was made in the compiler front-end needs to be properly plumbed through all of the back-end. There appears to be a lot of code in the back end of the compiler that has made the same conflation of `ref` parameters and explicit reference types that the front-end did. In practice, any uses of `ExplicitRef<T>` in the front-end should desugar into plain pointer-based code in the IR. Clean Up Parameter-Passing Modes -------------------------------- The code that handles different parameter-passing modes (`ParameterDirection`s) and their wrapper types is somewhat scattered and messy (as found while auditing use cases of `RefType`). A cleanup pass is warranted to ensure that most code only needs to think about `ParameterDirection`s. There should ideally be only a single operation in the front-end that handles determining the `ParameterDirection` of a parameter based on its modifiers. Similarly, there should be one operation to wrap a value type based on a parameter direction, and one operation to derive a `ParameterDirection` from the wrapper type. Ideally, the accessors for `FuncType` should not provide unrestricted access to the potentially-wrapped parameter types, and should instead return some kind of `ParamInfo` struct that encodes both a `ParameterDirection` and the unwrapped `Type` of the parameter. Clean Up `QualType` ------------------- A significant piece of future work that appears required is to drastically clean up and improve the way that `QualType`s are represente and handled in the front-end. There are currently various distinct `bool` flags in `QualType` (some with very unclear meaning) and differnet parts of the codebase consult/modify only subsets of them; a clear enumeration of the "value categories" (to use the C++ terminology) that Slang supports could be quite helpful. Naively, a `QualType` should at least encode the basic information that a `Ptr` type encodes: * A value type * Allowed access (read-only, read-write, etc.) * Address space The main additional thing that a `QualType` needs is a way to distinguish cases where an expression evaluates to: * A reference to a memory location, where all the information from a `Ptr` is relevant * A simple value, such that the access and address space are irrelevant * A reference to an abstract storage location (a `property`, `subscript`, or an implicit conversion that needs to support being an l-value), in which case address space is irrelevant and the "allowed access" basically amounts to a listing of the accessors the storage location supports Eliminate Explicit Reference Types ---------------------------------- Finally, twe should eventually eliminate the `ExplicitRef<T>` type from the core module (and all of the supporting code from the front-end), since the feature is not a good fit for the Slang language. We should find some other way to decorate operations in the builtin module that need to returns a reference rather than a value (note how `ref` accessors already avoided exposing explicit reference types, by design). --------- Co-authored-by: slangbot <186143334+slangbot@users.noreply.github.com>
2025-09-18Fix DebugCompilationUnit to reference main shader file instead of header ↵Lujin Wang
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>
2025-09-18Fix CUDA global variable initialization with constructor calls (#8340)Harsh Aggarwal (NVIDIA)
Fix CUDA global variable initialization with constructor calls Resolves CUDA compilation failure where global variables with struct constructor initialization generated illegal `__device__` variable runtime initialization. **Problem:** ```cuda // Generated invalid CUDA code: __device__ static const Stuff_0 gStuff_0 = Stuff_x24init_0(args...); // Error: "dynamic initialization is not supported for a __device__ variable" Root Cause Discovered: Through extensive debugging, found that moveGlobalVarInitializationToEntryPoints pass only handled kIROp_GlobalVar instructions, but global constants with constructor calls appeared as kIROp_Call instructions at module scope. Solution: 1. IR Pipeline Fix: Extended moveGlobalVarInitializationToEntryPoints to detect and transform module-level constructor calls into proper global variables with entry-point initialization 2. Field Access Fix: Enhanced kIROp_FieldExtract logic to emit correct -> syntax for pointer types and address-of operations 3. Constructor Emission: Added CUDA-specific handling for constructor calls Architecture: - Transforms let %gStuff = call %Constructor(...) into kernel context initialization - Moves runtime initialization from global scope to entry-point execution - Follows CUDA best practices for global state management Files: - source/slang/slang-ir-explicit-global-init.cpp: Extended IR transformation pass - source/slang/slang-emit-c-like.cpp: Enhanced field access and foldable value logic - source/slang/slang-emit-cuda.cpp: Added CUDA-specific field extraction handling Result: // Now generates proper CUDA code: struct KernelContext_0 { Stuff_0 gStuff_1; }; // Runtime initialization in entry point: kernelContext_1.gStuff_1 = constructor_call(); Fixes: tests/compute/type-legalize-global-with-init.slang
2025-09-17Diagnostic for metal ref mesh output assignment (#8365)James Helferty (NVIDIA)
When slang detects assignment to a mesh output reference on metal, generate a diagnostic message. (Metal mesh shader outputs must be assigned via 'set' instead of 'ref'.) Fixes #7498
2025-09-16Diagnose error when the function args can't satisfy constexpr parameter ↵Gangzheng Tong
requirements (#7269) ## Summary This PR enhances constexpr validation by adding proper error checking when function arguments cannot satisfy constexpr parameter requirements, addressing issue #6370. ## Problem Previously, when a function declared constexpr parameters, the compiler would attempt to propagate constexpr-ness to the call site arguments, but there was insufficient validation and error reporting when this propagation failed. This could lead silent failures where constexpr requirements weren't properly enforced ## Solution This PR adds checks that: 1. **Validates constexpr arguments**: When a function parameter is marked as `constexpr`, the compiler now explicitly checks that the corresponding argument can be marked as `constexpr` 2. **Issues clear compilation errors**: added `Diagnostics::argIsNotConstexpr`) 3. **Handles both call scenarios**: The validation works for both: - Direct function calls with IR-level function definitions - Calls to function from external modules Fixes #6370 --------- Co-authored-by: slangbot <ellieh+slangbot@nvidia.com> Co-authored-by: slangbot <186143334+slangbot@users.noreply.github.com>
2025-09-10Fix pointers and C-like layout in varying parameters (#8425)Julius Ikkala
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.
2025-09-10CUDA: Fix compiler crash with unsized array field - nonuniformres-as-… (#8380)Harsh Aggarwal (NVIDIA)
…function-parameter.slang #8315 Root Cause: CUDA compilation crashed with `assert failure: !seenFinalUnsizedArrayField` because unsized arrays like `RWStructuredBuffer<uint> globalBuffer[]` were not the final field in generated parameter structs, violating the layout constraint in slang-ir-layout.cpp. Fix: Extended `collectGlobalUniformParameters` to automatically reorder struct fields for CUDA targets - regular fields first, unsized arrays last. Other targets preserve original order. Impact: - Enables CUDA support for nonuniform resource indexing as function parameters - Zero impact on existing GLSL/HLSL/SPIRV targets - Automatic handling - no manual parameter reordering required Files: slang-emit.cpp, slang-ir-collect-global-uniforms.cpp/.h, test file --------- Co-authored-by: slangbot <ellieh+slangbot@nvidia.com> Co-authored-by: slangbot <186143334+slangbot@users.noreply.github.com> Co-authored-by: Ellie Hermaszewska <ellieh@nvidia.com>
2025-09-10Check if debugVar for is debuggable types in the legalization pass (#8326)Gangzheng Tong
## Problem When generic functions with debug variables were specialized with concrete types containing non-debuggable fields (e.g., `StructuredBuffer`), the IR cloning process would create invalid `DebugVar` instructions without checking if the substituted types remained debuggable. ## Solution This fix adds a defensive check in the legalization pass that removes the debugVar created for the non-debuggable types. --------- Co-authored-by: slangbot <ellieh+slangbot@nvidia.com> Co-authored-by: slangbot <186143334+slangbot@users.noreply.github.com>
2025-09-10Fix language server auto-complete regression in debug build. (#8416)Yong He
Fixes this regression: ```slang struct MyType { // Regression Condition 1: there must be more than one member in the lookup scope. float v; int getSum() { return 0; } } void m(MyType t) { // Regression condition 2: the completion must be in an init expression. // Regression condition 3: none of the candidate members can coerce to the expected type. // Regression behavior: no completion candidates are shown, because // SemanticsVisitor::resolveOverloadedLookup throws an error when there are 0 applicable candidates // after type coercion filtering. Texture2D x = t.; // completion request after . here } ``` The root cause is that we shouldn't be applying candidate filtering on the candidate list when in completion checking mode. Closes #8417.
2025-09-09Fix #8314 - Enable tests/compute/texture-subscript.slang for CUDA (#8408)Harsh Aggarwal (NVIDIA)
The test can be enabled
2025-09-05Relax restriction on using link-time types for shader parameters. (#8387)Yong He
This change relaxes a previous restriction on link-time types and constants, so that we now allow them to be used to define shader parameters. Doing so will result in a parameter layout that is incomplete prior to linking. The PR added a test to call the reflection API on a fully linked program and ensure that we can report correct binding info.
2025-09-05Disable a few WGSL testing using Wave functions in branches (#8386)Jay Kwak
WGSL requires Wave functions to be used only in uniform control flow. The latest compiler, Tint, started to error out when Wave functions are used in a dynamic control flow. This commit disables some of tests using Wave functions in dynamic branches. If possible, they are altered to call Wave functions in uniform control flows.
2025-09-05Add warnings for overflows of integer types (#8281)jarcherNV
The code int x4 = 0xFFFFFFFFFFFFFFFF previously did not produce a warning due to the value being too large for the type. This patch now checks for this and similar issues during parsing.
2025-09-05Try both LoadLibrary functions on Windows (#8368)jarcherNV
If a given library cannot be found using LoadLibraryExA then try again using LoadLibraryA. Return an error only if both of these failed.
2025-09-04Enable CUDA support for additional HLSL intrinsic tests (#8293)Harsh Aggarwal (NVIDIA)
Enable CUDA support for additional HLSL intrinsic tests by implementing missing functionality and fixing compiler bugs affecting CUDA targets. - Fix critical bug in InterlockedCompareStore64 where division used /4 instead of /8 for 64-bit types, causing incorrect memory addressing for all signed int 64_t atomics - Add signed int64_t atomic wrappers (atomicExch, atomicCAS) to CUDA prelu de that properly cast to/from unsigned types as required by CUDA's atomic API - Enable tests: atomic-intrinsics-64bit.slang - Implement CUDA support for QuadAny and QuadAll operations using warp shu ffle primitives (__shfl_sync with quad-level lane masking) - Add CUDA to quad_control capability definition in slang-capabilities.capdef - Add _slang_quadAny/_slang_quadAll helper functions to CUDA prelude - Enable tests: quad-control-comp-functionality.slang, subgroup-quad.slang --------- Co-authored-by: szihs <675653+szihs@users.noreply.github.com>
2025-09-04Handle slang-test command comments better (#8363)Jay Kwak
Before this PR only the following was a valid line without any white-space character nor additional `/` character, ``` //TEST: ``` This PR is to allow slang-test to handle the following variants of the test command comments, ``` ///TEST: // TEST: // TEST: ////// TEST: ``` This PR revealed a regression on two tests: - tests/cpp-compiler/c-compile-shared-library.c (cpu) - tests/cpp-compiler/cpp-compile-shared-library.cpp (cpu) They are disabled as a part of this PR. And there is a new github issue to track it later, - https://github.com/shader-slang/slang/issues/8362
2025-09-03Diagnose on structured buffers containing resources (#8222)Ellie Hermaszewska
closes https://github.com/shader-slang/slang/issues/3313
2025-09-03Fix#8085: Batch-9: Enable cuda tests (#8269)Harsh Aggarwal (NVIDIA)
2025-09-03Add Optix Intrinsics Coverage (#8159) (#8310)Harsh Aggarwal (NVIDIA)
Add 29 intrinsics to the list by new test
2025-09-03Fix#8086: Batch-10: Enable cuda tests (#8270)Harsh Aggarwal (NVIDIA)
2025-09-02render-test: Change D3D12 default to sm_6_5 (#8320)James Helferty (NVIDIA)
Changes default for render-test to sm_6_5. Since sm_6_5 is the new default, remove the -use-dxil option, add -use-dxcb option Remove -use-dxil option from all test cases. Add -use-dxcb to two tests that needed it. Fixes #7611
2025-09-02Emit DebugInfo for the legalized entry point parameters (#7703)Jay Kwak
This commit is to emit the debug-info for the entry point parameters. Two things are implemented/fixed in this PR: - We were not emitting the `DebugVar` and `DebugValue` at the IR lowering level when the type of the entry point parameter is `ConstRef`. This commit handles the `ConstRef` case in a same way that the other types are handled so that `DebugVar` and `DebugValues` are properly emitted at the IR lowering level. - Two types for Geometry shaders were incorrectly treated as not valid types for the DebugInfo. They are `InputPatch` and `OutputPatch`. This commit handles them as valid types for DebugInfo.
2025-08-29[CBP] Pointer frontend changes + groupshared pointer support (#7848)ArielG-NV
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>
2025-08-28Remove the embedded source to avoid self-matching in slang-test (#8305)Jay Kwak
When `SIMPLE` type test is used with `-g[1-3]` option, the filecheck pattern will most likely to match to the string itself on the embedded source code rather than match to the emitted spirv-asm code. This commit avoids the problem by removing the embedded source code. This commit also provides an option to keep the embedded source code, `-preserve-embedded-source`. The source code removal is happening in two steps: 1. iterate all output lines and find SPIRV-ASM in the following pattern: `%N = OpExtInst %void %M DebugSource %fileId %sourceId`. And then, store the "%sourceId" value to identify which SPIRV instructions are for the embedded source code. 2. iterate all output lines again to find the `%sourceId = OpString "...."` and replace the whole string with the following string, ``` %1 = OpString "// slang-test removed the embedded source // Use `-preserve-embedded-source` to keep it explicitly " ``` This change revealed problems in the existing tests: - tests/bugs/spirv-debug-info.slang : The expected text was missing and it had to be added. The file also had Carrage-Return character on all lines and the pre-commit git hook removed them. - tests/spirv/debug-info.slang : the expected keyword DebugValue had to change to DebugDeclare, because that's what we get with ToT. - tests/spirv/debug-value-dynamic-index.slang : This test is currently failing, and it will pass once DebugLocalVariable instruction missing for parameter of the entry point function #7693 is resolved. --------- Co-authored-by: slangbot <ellieh+slangbot@nvidia.com>
2025-08-28Add SPIRV OpCapability for 8/16bit use in storage (#8194)James Helferty (NVIDIA)
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>
2025-08-26Fail slang-test when VVL printed errors (#8280)Jay Kwak
fixes https://github.com/shader-slang/slang/issues/8271 This PR does the following, - Fail slang-test when there are VVL error messages. - VVL error for `gfx-unit-test-tool/` were not captured properly by the debug callback. - Set an environment variable, `VK_INSTANCE_LAYERS=VK_LAYER_KHRONOS_validation`, for CI and VisualStudio project setup. - Ignores VVL error about NullHandle is used for the acceleration structure; a fix is at ToT of VVL and not available from release build yet. - Fix VVL error complaining about the varying inputs are not provided for the tests, `gfx-unit-test-tool/linkTimeTypeLayout.internal` and `gfx-unit-test-tool/linkTimeTypeLayoutNested.internal`. --------- Co-authored-by: slangbot <ellieh+slangbot@nvidia.com> Co-authored-by: slangbot <186143334+slangbot@users.noreply.github.com>
2025-08-26Fix Metal 8-bit vector type names: emit char/uchar instead of int8_t/uint8_t ↵Copilot
(#8223) The Metal backend was generating incorrect type names for 8-bit vector types, causing compilation failures when targeting Metal. According to the Metal specification, 8-bit vector types should be named `charN` and `ucharN` (e.g., `char2`, `uchar3`) rather than `int8_tN` and `uint8_tN`. ## Problem When compiling Slang code with 8-bit vector types for Metal, the compiler would emit: ```metal uint8_t2 _S8 = uint8_t2(uint8_t(0U), uint8_t(16U)); int8_t3 _S9 = int8_t3(int8_t(0), int8_t(16), int8_t(48)); ``` But the Metal compiler expects: ```metal uchar2 _S8 = uchar2(uint8_t(0U), uint8_t(16U)); char3 _S9 = char3(int8_t(0), int8_t(16), int8_t(48)); ``` This caused errors like: ``` error: unknown type name 'uint8_t2'; did you mean 'uint8_t'? ``` ## Solution Modified `MetalSourceEmitter::emitSimpleTypeImpl()` to emit the correct Metal-specific type names for 8-bit types: - `kIROp_Int8Type` now emits `char` instead of `int8_t` - `kIROp_UInt8Type` now emits `uchar` instead of `uint8_t` This change only affects the Metal backend and ensures that vector types like `int8_t2`, `uint8_t3`, etc. are correctly emitted as `char2`, `uchar3`, etc. ## Testing - Added a new test case `tests/metal/8bit-vector-types.slang` to verify the fix - Re-enabled the previously disabled Metal test in `tests/hlsl-intrinsic/countbits8.slang` - Updated `tests/metal/byte-address-buffer.slang` to expect the correct type names - Verified that existing Metal tests continue to pass Fixes #8211. <!-- START COPILOT CODING AGENT TIPS --> --- 💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more [Copilot coding agent tips](https://gh.io/copilot-coding-agent-tips) in the docs. --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: bmillsNV <163073245+bmillsNV@users.noreply.github.com>
2025-08-25Fix#8084: Batch-8: Enable cuda tests (#8268)Harsh Aggarwal (NVIDIA)
2025-08-25Fix#8083: Batch-7: Enable cuda tests (#8267)Harsh Aggarwal (NVIDIA)
2025-08-25Fix#8082: Batch-6: Enable cuda tests (#8266)Harsh Aggarwal (NVIDIA)
2025-08-25Fix#8081: Batch-5: Enable cuda tests (#8263)Harsh Aggarwal (NVIDIA)
2025-08-25Fix#8080: Batch-4: Enable cuda tests (#8261)Harsh Aggarwal (NVIDIA)
2025-08-22Fix mesh shader OutputIndices subscript error by adding missing ref accessor ↵Lujin Wang
(#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>
2025-08-21Fix reflection JSON writing userAttribs section twice for some cases. (#8210)MindSpunk
`emitReflectionVarLayoutJSON` will output the `userAttribs` section twice as it gets output by `emitReflectionModifierInfoJSON` first before being output again by a direct call to `emitUserAttributes`. It seems the answer here is to just remove the extra explicit call to `emitUserAttributes` and rely on the call in `emitReflectionModifierInfoJSON`?
2025-08-21Introduce CDataLayout & -fvk-use-c-layout (#8136)Julius Ikkala
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>
2025-08-21Implement SV_VulkanSamplePosition (#8236)davli-nv
-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>
2025-08-20Fix nextafter() (#8195)Julius Ikkala
Fixes #8185. The previous implementation is incorrect and basically only works in the `x = 0` case. `delta` was the smallest possible positive value representable as a float, but that's below the rounding error of addition with almost all reasonably sized floats. This fixed implementation is based on bit twiddling instead. I've checked the float case against the C++ `nextafterf` with both a -inf -> inf and inf -> -inf sweep, in addition to the test included in this PR.
2025-08-20Add Metal support for WaveGetActiveMask and WaveActiveCountBits (#8218)Tianyu Li
## Summary - Add Metal platform support for `WaveGetActiveMask()` and `WaveActiveCountBits()` wave intrinsics - Update capability requirements to include Metal platform for subgroup ballot operations - Implement Metal-specific intrinsic assembly using `simd_ballot()` and `simd_vote` APIs ## Changes - **source/slang/hlsl.meta.slang**: - Add Metal target case for `WaveGetActiveMask()` using `simd_ballot(true)` - Update capability requirements from `cuda_glsl_hlsl_spirv` to `cuda_glsl_hlsl_metal_spirv` for wave ballot functions - **source/slang/slang-capabilities.capdef**: - Add `metal` to `subgroup_ballot_activemask` capability alias