<feed xmlns='http://www.w3.org/2005/Atom'>
<title>slang.git/source/slang/slang-ir-glsl-legalize.cpp, 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-16T03:59:47+00:00</updated>
<entry>
<title>Immutable access qualifier for pointers and use `__ldg` on cuda. (#8710)</title>
<updated>2025-10-16T03:59:47+00:00</updated>
<author>
<name>Yong He</name>
<email>yonghe@outlook.com</email>
</author>
<published>2025-10-16T03:59:47+00:00</published>
<link rel='alternate' type='text/html' href='https://git.yummers.dev/slang.git/commit/?id=01510f2c922af8629c7a730ef92a31fa83bd9f49'/>
<id>urn:sha1:01510f2c922af8629c7a730ef92a31fa83bd9f49</id>
<content type='text'>
This PR implements `Access.Immutable` to allow pointers to immutable
data.

The new type `ImmutablePtr&lt;T&gt;` is defined as an alias of `Ptr&lt;T,
Address.Immutable&gt;`.
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 &lt;186143334+slangbot@users.noreply.github.com&gt;</content>
</entry>
<entry>
<title>Clean up Slang IR representation of undefined values (#8708)</title>
<updated>2025-10-15T01:00:47+00:00</updated>
<author>
<name>Theresa Foley</name>
<email>10618364+tangent-vector@users.noreply.github.com</email>
</author>
<published>2025-10-15T01:00:47+00:00</published>
<link rel='alternate' type='text/html' href='https://git.yummers.dev/slang.git/commit/?id=907410f6a52cf4e7538870ebf5aeb88858f97973'/>
<id>urn:sha1:907410f6a52cf4e7538870ebf5aeb88858f97973</id>
<content type='text'>
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&lt;IRUndefined&gt;` 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 &lt;186143334+slangbot@users.noreply.github.com&gt;</content>
</entry>
<entry>
<title>Add direct usage support for gl_DrawID (#8594)</title>
<updated>2025-10-03T19:52:50+00:00</updated>
<author>
<name>Copilot</name>
<email>198982749+Copilot@users.noreply.github.com</email>
</author>
<published>2025-10-03T19:52:50+00:00</published>
<link rel='alternate' type='text/html' href='https://git.yummers.dev/slang.git/commit/?id=2491ac5f42d78d082d4afa6416906fad9b32ea80'/>
<id>urn:sha1:2491ac5f42d78d082d4afa6416906fad9b32ea80</id>
<content type='text'>
- [x] Add `gl_DrawID` property declaration in
`source/slang/glsl.meta.slang` similar to `gl_BaseVertex` and
`gl_BaseInstance`
- [x] Ensure it maps to `SV_DrawIndex` semantic
- [x] Add extension requirements in `slang-ir-glsl-legalize.cpp` (GLSL
460 and GL_ARB_shader_draw_parameters)
- [x] Create test case to verify SPIRV output contains `DrawIndex`
decoration
- [x] Run formatting script before committing
- [x] Verify existing tests still pass
- [x] Remove accidentally committed temp files (1.glsl, 3.spv-asm)
- [x] Update .gitignore to prevent similar files from being committed

&lt;!-- START COPILOT CODING AGENT SUFFIX --&gt;



&lt;details&gt;

&lt;summary&gt;Original prompt&lt;/summary&gt;

&gt; 
&gt; ----
&gt; 
&gt; *This section details on the original issue you should resolve*
&gt; 
&gt; &lt;issue_title&gt;Missing direct usage support for gl_DrawID&lt;/issue_title&gt;
&gt; &lt;issue_description&gt;# Problem Description
&gt; Because DirectX does not have support for DrawIndex like vulkan does,
i add the support in d3d12 by emulating it and storing it in a root
constant. In vulkan though, i should be able to use it directly, but
because now i store it as a global variable, i cannot use the
SV_DrawIndex semantic either.
&gt; 
&gt; # Preferred Solution
&gt; I'd like to be able to use gl_DrawID like you how can use
gl_BaseVertex and gl_BaseInstance.
&gt; &lt;/issue_description&gt;
&gt; 
&gt; &lt;agent_instructions&gt;You can just edit glsl.meta.slang and add a
declaration for gl_DrawID in a similar way to gl_BaseVertex, and map it
to SV_DrawIndex.
&gt; 
&gt; Create a `//TEST:SIMPLE(filecheck=SPIRV): -target spirv` test case,
and use filecheck to verify the output contains the correct SPIRV
`DrawIndex` decoration.&lt;/agent_instructions&gt;
&gt; 
&gt; ## Comments on the Issue (you are @copilot in this section)
&gt; 
&gt; &lt;comments&gt;
&gt; &lt;/comments&gt;
&gt; 


&lt;/details&gt;
Fixes shader-slang/slang#8548

&lt;!-- START COPILOT CODING AGENT TIPS --&gt;
---

✨ Let Copilot coding agent [set things up for
you](https://github.com/shader-slang/slang/issues/new?title=✨+Set+up+Copilot+instructions&amp;body=Configure%20instructions%20for%20this%20repository%20as%20documented%20in%20%5BBest%20practices%20for%20Copilot%20coding%20agent%20in%20your%20repository%5D%28https://gh.io/copilot-coding-agent-tips%29%2E%0A%0A%3COnboard%20this%20repo%3E&amp;assignees=copilot)
— coding agent works faster and does higher quality work when set up for
your repo.

---------

Co-authored-by: copilot-swe-agent[bot] &lt;198982749+Copilot@users.noreply.github.com&gt;
Co-authored-by: csyonghe &lt;2652293+csyonghe@users.noreply.github.com&gt;</content>
</entry>
<entry>
<title>Rename some symbols related to pointers types (#8592)</title>
<updated>2025-10-03T04:48:11+00:00</updated>
<author>
<name>Theresa Foley</name>
<email>10618364+tangent-vector@users.noreply.github.com</email>
</author>
<published>2025-10-03T04:48:11+00:00</published>
<link rel='alternate' type='text/html' href='https://git.yummers.dev/slang.git/commit/?id=cc8f6a241edb47c43c5698ee33abed4fe57d4566'/>
<id>urn:sha1:cc8f6a241edb47c43c5698ee33abed4fe57d4566</id>
<content type='text'>
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&lt;T&gt;` 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 &lt;186143334+slangbot@users.noreply.github.com&gt;</content>
</entry>
<entry>
<title>Enhance buffer load specialization pass to specialize past field extracts. (#8547)</title>
<updated>2025-10-01T02:08:23+00:00</updated>
<author>
<name>Yong He</name>
<email>yonghe@outlook.com</email>
</author>
<published>2025-10-01T02:08:23+00:00</published>
<link rel='alternate' type='text/html' href='https://git.yummers.dev/slang.git/commit/?id=e4611e2e30a3e5969d402f5ed7e72706a0e3b024'/>
<id>urn:sha1:e4611e2e30a3e5969d402f5ed7e72706a0e3b024</id>
<content type='text'>
This allows us to specialize functions whose argument is a sub element
of a constant buffer, instead of being only applicable to entire buffer
element. Closes #8421.

This change also implements a proper heuristic to determine when to
specialize the calls and defer the buffer loads.

This PR addresses a pathological case exposed in
`slangpy\slangpy\benchmarks\test_benchmark_tensor.py`, which used to
take 27ms to finish, and now takes 1.25ms.


For example, given:
```
struct Bottom
{
    float bigArray[1024];

    [mutating]
    void setVal(int index, float value) { bigArray[index] = value; }
}

struct Root
{
    Bottom top[2];
    [mutating]
    void setTopVal(int x, int y, float value)
    {
        top[x].setVal(y, value);
    }
}

RWStructuredBuffer&lt;Root&gt; sb;

[shader("compute")]
[numthreads(1, 1, 1)]
void compute_main(uint3 tid: SV_DispatchThreadID)
{
    sb[0].setTopVal(1, 2, 100.0f);
}
```

We are now able to specialize the call to `setTopVal` into:
```
void compute_main(uint3 tid: SV_DispatchThreadID)
{
    setTopVal_specialized(0, 1, 2, 100.0f);
}

void setTopVal_specialized(int sbIdx, int x, int y, float value)
{
      Bottom_setVal_specialized(sbIdx, x, y, value);
}

void Bottom_setVal_specialized(int sbIdx, int x, int y, float value)
{
     sb[sbIdx].top[x].bigArray[y] = value;
}
```

And get rid of all unnecessary loads. Achieving this requires a
combination of function call specialization and buffer-load-defer pass.
The buffer-load-defer pass has been completely rewritten to be more
correct and avoid introducing redundant loads.

This PR also adds tests to make sure pointers, bindless handles, and
loads from structured buffer or constant buffers works as expected.</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>Squash warnings on gcc 14 (#8377)</title>
<updated>2025-09-10T13:26:45+00:00</updated>
<author>
<name>Ellie Hermaszewska</name>
<email>ellieh@nvidia.com</email>
</author>
<published>2025-09-10T13:26:45+00:00</published>
<link rel='alternate' type='text/html' href='https://git.yummers.dev/slang.git/commit/?id=b03cbb02c6486274d46865f3995953f2105cefc9'/>
<id>urn:sha1:b03cbb02c6486274d46865f3995953f2105cefc9</id>
<content type='text'>
</content>
</entry>
<entry>
<title>[CBP] Pointer frontend changes + groupshared pointer support (#7848)</title>
<updated>2025-08-29T22:52:34+00:00</updated>
<author>
<name>ArielG-NV</name>
<email>159081215+ArielG-NV@users.noreply.github.com</email>
</author>
<published>2025-08-29T22:52:34+00:00</published>
<link rel='alternate' type='text/html' href='https://git.yummers.dev/slang.git/commit/?id=7758625d3fea67e55e98e7e4103d56c9918365be'/>
<id>urn:sha1:7758625d3fea67e55e98e7e4103d56c9918365be</id>
<content type='text'>
Resolves #7628
Resolves: #8197

Primary Goals:
1. Add `Access` to pointer
2. AddressSpace::GroupShared support for pointers (SPIR-V)
3. Add `__getAddress()` to replace `&amp;`
* `&amp;` is not updated to `require(cpu)` since slangpy uses `&amp;`. This
means we must: (1) merge PR; (2) replace `&amp;` with `__getAddress()`; (3)
add `require(cpu)` to `&amp;`

Changes:
* Added to `Ptr` the `Access` generic argument &amp; 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 &lt;186143334+slangbot@users.noreply.github.com&gt;</content>
</entry>
<entry>
<title>Implement SV_VulkanSamplePosition (#8236)</title>
<updated>2025-08-21T00:30:44+00:00</updated>
<author>
<name>davli-nv</name>
<email>davli@nvidia.com</email>
</author>
<published>2025-08-21T00:30:44+00:00</published>
<link rel='alternate' type='text/html' href='https://git.yummers.dev/slang.git/commit/?id=05f0f5603561daed2c134e13bc64649362759968'/>
<id>urn:sha1:05f0f5603561daed2c134e13bc64649362759968</id>
<content type='text'>
-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 &lt;159081215+ArielG-NV@users.noreply.github.com&gt;</content>
</entry>
<entry>
<title>Fix noperspective modifier for SV_Barycentrics in SPIRV and GLSL (#8067)</title>
<updated>2025-08-06T19:29:28+00:00</updated>
<author>
<name>davli-nv</name>
<email>davli@nvidia.com</email>
</author>
<published>2025-08-06T19:29:28+00:00</published>
<link rel='alternate' type='text/html' href='https://git.yummers.dev/slang.git/commit/?id=5074c4948d73b451c74bd21ac139d69eaeb390f3'/>
<id>urn:sha1:5074c4948d73b451c74bd21ac139d69eaeb390f3</id>
<content type='text'>
* 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 &lt;davli-nv@users.noreply.github.com&gt;

* 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] &lt;41898282+github-actions[bot]@users.noreply.github.com&gt;
Co-authored-by: davli-nv &lt;davli-nv@users.noreply.github.com&gt;</content>
</entry>
</feed>
