<feed xmlns='http://www.w3.org/2005/Atom'>
<title>slang.git/tests/spirv, branch master</title>
<subtitle>Making it easier to work with shaders</subtitle>
<id>https://git.yummers.dev/slang.git/atom?h=master</id>
<link rel='self' href='https://git.yummers.dev/slang.git/atom?h=master'/>
<link rel='alternate' type='text/html' href='https://git.yummers.dev/slang.git/'/>
<updated>2025-10-17T01:22:39+00:00</updated>
<entry>
<title>Fix infinite loop in SPIRVLegalizationContext::processWorkList (#8712)</title>
<updated>2025-10-17T01:22:39+00:00</updated>
<author>
<name>davli-nv</name>
<email>davli@nvidia.com</email>
</author>
<published>2025-10-17T01:22:39+00:00</published>
<link rel='alternate' type='text/html' href='https://git.yummers.dev/slang.git/commit/?id=ff064b9a0f1316007f46710432f854777a520fdf'/>
<id>urn:sha1:ff064b9a0f1316007f46710432f854777a520fdf</id>
<content type='text'>
When slangc is invoked with -g, a source shader that has static infinite
loop can generate IR that have branch to a block that contains a branch
to the first block that contains the first branch, resulting in infinite
loop.

Change SPIRVLegalizationContext::processWorkList to only add branch
target to work list via its parent, this avoids the infinite loop above.

Also change addToWorkList to stop addUsersToWorkList, users should be
added explicitly by logic for specific insts.

Add regression test as tests/spirv/infinite-loop.slang

Fixes #8669</content>
</entry>
<entry>
<title>8503 wgsl depth texture (#8645)</title>
<updated>2025-10-10T16:39:13+00:00</updated>
<author>
<name>Sami Kiminki (NVIDIA)</name>
<email>235843927+skiminki-nv@users.noreply.github.com</email>
</author>
<published>2025-10-10T16:39:13+00:00</published>
<link rel='alternate' type='text/html' href='https://git.yummers.dev/slang.git/commit/?id=5c672cef1f6ac6b5cd6cd71bd47489b7b7331adb'/>
<id>urn:sha1:5c672cef1f6ac6b5cd6cd71bd47489b7b7331adb</id>
<content type='text'>
Add built-in type aliases for DepthTexture* and unify Sampler*Shadow
    
Add the following type aliases:
- DepthTexture1D, DepthTexture1DArray
- DepthTexture2D, DepthTexture2DArray
- DepthTexture2DMS, DepthTexture2DMSArray
- DepthTexture3D
- DepthTextureCube, DepthTextureCubeArray
    
These match with the type aliases for non-depth textures.
    
Also, unify the Sampler*Shadow type aliases with DepthTexture*
ones. This adds the following:
    
- Sampler2DMSShadow
- Sampler2DMSArrayShadow
    
and removes the Sampler3DArrayShadow type alias. As a side-effect, the
descriptions of Sampler*ArrayShadow type aliases are fixed
("texture-sampler for shadow" ==&gt; "texture-sampler array for shadow").

Update the slang tests to use the newly introduced type aliases instead
of
the custom type aliases that use _Texture&lt;&gt; directly.

Add DepthTexture testing in
hlsl-intrinsic/texture/texture-intrinsics. Do this by extracting the
test logic of computeMain() in a separate function and parametrize it
for non-depth/depth texture types. This adds basic coverage for the
following types:

- DepthTexture1D
- DepthTexture2D
- DepthTexture3D
- DepthTextureCube
- DepthTexture1DArray
- DepthTexture2DArray
- DepthTextureCubeArray

Issue #6166
Issue #8503</content>
</entry>
<entry>
<title>Update debug var when in-param proxy var is being updated. (#8671)</title>
<updated>2025-10-10T06:27:57+00:00</updated>
<author>
<name>Yong He</name>
<email>yonghe@outlook.com</email>
</author>
<published>2025-10-10T06:27:57+00:00</published>
<link rel='alternate' type='text/html' href='https://git.yummers.dev/slang.git/commit/?id=cd50974490b82dd7e0f9ac0dd5ce9c17e390ff1f'/>
<id>urn:sha1:cd50974490b82dd7e0f9ac0dd5ce9c17e390ff1f</id>
<content type='text'>
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.</content>
</entry>
<entry>
<title>Respect isShadow() flag when setting depth type in SPIR-V backend (#8604)</title>
<updated>2025-10-04T12:50:56+00:00</updated>
<author>
<name>Nils Hasenbanck</name>
<email>hasenbanck@users.noreply.github.com</email>
</author>
<published>2025-10-04T12:50:56+00:00</published>
<link rel='alternate' type='text/html' href='https://git.yummers.dev/slang.git/commit/?id=3375cde1add65894b8f2e2780cc91ab4ccf6d8fb'/>
<id>urn:sha1:3375cde1add65894b8f2e2780cc91ab4ccf6d8fb</id>
<content type='text'>
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.</content>
</entry>
<entry>
<title>Rewriting the lower-buffer-element-type pass to avoid unnecessary packing/unpacking. (#8526)</title>
<updated>2025-09-30T00:45:08+00:00</updated>
<author>
<name>Yong He</name>
<email>yonghe@outlook.com</email>
</author>
<published>2025-09-30T00:45:08+00:00</published>
<link rel='alternate' type='text/html' href='https://git.yummers.dev/slang.git/commit/?id=a6deb5ed82cb8fc6b4f4c5c5fee264e09f97ff89'/>
<id>urn:sha1:a6deb5ed82cb8fc6b4f4c5c5fee264e09f97ff89</id>
<content type='text'>
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&lt;BigStruct&gt; 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&lt;BigStruct_std430&gt;;
func computeMain:
   %tmpVar : var&lt;BigStruct&gt;
    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&lt;BigStruct&gt;
   %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&lt;BigStruct_std430&gt;
   %barr = fieldAddr(%v, "values")
   %elementPtr : ptr&lt;int&gt; = 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 &lt;186143334+slangbot@users.noreply.github.com&gt;</content>
</entry>
<entry>
<title>Prepare VulkanSDK release Oct 2025 (#8525)</title>
<updated>2025-09-25T04:49:26+00:00</updated>
<author>
<name>Jay Kwak</name>
<email>82421531+jkwak-work@users.noreply.github.com</email>
</author>
<published>2025-09-25T04:49:26+00:00</published>
<link rel='alternate' type='text/html' href='https://git.yummers.dev/slang.git/commit/?id=db44c1b732891102199f0ec9d219a33d2ab2d6a1'/>
<id>urn:sha1:db44c1b732891102199f0ec9d219a33d2ab2d6a1</id>
<content type='text'>
Related to
- https://github.com/shader-slang/slang/issues/8519</content>
</entry>
<entry>
<title>Split overloaded uses of RefType in front-end (#8427)</title>
<updated>2025-09-23T01:20:13+00:00</updated>
<author>
<name>Theresa Foley</name>
<email>10618364+tangent-vector@users.noreply.github.com</email>
</author>
<published>2025-09-23T01:20:13+00:00</published>
<link rel='alternate' type='text/html' href='https://git.yummers.dev/slang.git/commit/?id=c35b763f811298a6e9c61a4a8eaf805ea98bd608'/>
<id>urn:sha1:c35b763f811298a6e9c61a4a8eaf805ea98bd608</id>
<content type='text'>
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&lt;T&gt;` 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&lt;T&gt;` 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&lt;T&gt;` and `InOut&lt;T&gt;`
types used to encode `out` and `inout` parameter-passing modes. The
`Ref&lt;T&gt;` type in the core module was encoded as a instance of the
`RefType` class in the Slang AST (similar to how `Out&lt;T&gt;` 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&lt;T&gt;` type (and `Out&lt;T&gt;`, 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&lt;T&gt;` type in the core module was re-used for
this new case. Builtin operations were declared with an explicit
`Ref&lt;T&gt;` 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&lt;T&gt;` 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&lt;T&gt;`
type, which appeared in the AST as an instance of the `ConstRefType`
class.

The overlapping use of `ConstRef&lt;T&gt;`` is actually significantly more
troublesome than the `Ref&lt;T&gt;` 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&lt;T&gt;` has contributed to
things becoming increasingly muddy in the compiler back-end.

Main Changes
============

Core Module
-----------

The `Ref&lt;T&gt;` type has been replaced with two distinct types, with one
for each use case:

* `RefParam&lt;T&gt;` is intended for use when encoding a `ref` parameter in a
function type

* `ExplicitRef&lt;T&gt;` 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&lt;T&gt;`) were renamed to better indicate that their role in defining
parameter types (e.g., `InOutParam&lt;T&gt;`).

The `ExplicitRef&lt;T&gt;` type was given additional generic parameters for
the allowed access and the address space, akin to what `Ptr&lt;T&gt;` 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&lt;T&gt;` were not split in the way as
`Ref&lt;T&gt;`, instead the case for the `constref` parameter-passing mode
uses `ConstParamRef&lt;T&gt;`, while cases that previously used `ConstRef&lt;T&gt;`
to represent a read-only explicit reference instead now use
`ExplicitRef&lt;T, Access.Read&gt;`.

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&lt;T&gt;` 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&lt;T&gt;` 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 &lt;186143334+slangbot@users.noreply.github.com&gt;</content>
</entry>
<entry>
<title>Fix DebugCompilationUnit to reference main shader file instead of header files (#7957)</title>
<updated>2025-09-18T17:37:14+00:00</updated>
<author>
<name>Lujin Wang</name>
<email>143145775+lujinwangnv@users.noreply.github.com</email>
</author>
<published>2025-09-18T17:37:14+00:00</published>
<link rel='alternate' type='text/html' href='https://git.yummers.dev/slang.git/commit/?id=ed9f42361e2f07a79fde39ded9e57473d5fac39f'/>
<id>urn:sha1:ed9f42361e2f07a79fde39ded9e57473d5fac39f</id>
<content type='text'>
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-&gt;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] &lt;41898282+github-actions[bot]@users.noreply.github.com&gt;
Co-authored-by: Lujin Wang &lt;lujinwangnv@users.noreply.github.com&gt;
Co-authored-by: Claude Code &lt;claude@anthropic.com&gt;
Co-authored-by: slangbot &lt;ellieh+slangbot@nvidia.com&gt;
Co-authored-by: slangbot &lt;186143334+slangbot@users.noreply.github.com&gt;</content>
</entry>
<entry>
<title>Fix pointers and C-like layout in varying parameters (#8425)</title>
<updated>2025-09-10T18:41:07+00:00</updated>
<author>
<name>Julius Ikkala</name>
<email>julius.ikkala@gmail.com</email>
</author>
<published>2025-09-10T18:41:07+00:00</published>
<link rel='alternate' type='text/html' href='https://git.yummers.dev/slang.git/commit/?id=ec42c4a20facbcae441cd172bfd607614e761907'/>
<id>urn:sha1:ec42c4a20facbcae441cd172bfd607614e761907</id>
<content type='text'>
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.</content>
</entry>
<entry>
<title>Check if debugVar for is debuggable types in the legalization pass (#8326)</title>
<updated>2025-09-10T07:14:05+00:00</updated>
<author>
<name>Gangzheng Tong</name>
<email>tonggangzheng@gmail.com</email>
</author>
<published>2025-09-10T07:14:05+00:00</published>
<link rel='alternate' type='text/html' href='https://git.yummers.dev/slang.git/commit/?id=2020a102e9e0ea2f39a0f2b2a75085c3607ce734'/>
<id>urn:sha1:2020a102e9e0ea2f39a0f2b2a75085c3607ce734</id>
<content type='text'>
## 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 &lt;ellieh+slangbot@nvidia.com&gt;
Co-authored-by: slangbot &lt;186143334+slangbot@users.noreply.github.com&gt;</content>
</entry>
</feed>
