<feed xmlns='http://www.w3.org/2005/Atom'>
<title>slang.git/source/slang/slang-ir-lower-buffer-element-type.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-10T01:30:24+00:00</updated>
<entry>
<title>Defer `IRCastStorageToLogicalDeref` in lowerBufferElementType pass. (#8668)</title>
<updated>2025-10-10T01:30:24+00:00</updated>
<author>
<name>Yong He</name>
<email>yonghe@outlook.com</email>
</author>
<published>2025-10-10T01:30:24+00:00</published>
<link rel='alternate' type='text/html' href='https://git.yummers.dev/slang.git/commit/?id=e420f2f980813559b186a6a6bcd5540f74310d02'/>
<id>urn:sha1:e420f2f980813559b186a6a6bcd5540f74310d02</id>
<content type='text'>
Fix a regression on metal test.

In `lowerBufferElementTypeToStorageType` pass, not only we want to defer
an argument that is `CastStorageToLogical` to the callee, but also apply
the same defer logic to `CastStorageToLogicalDeref` as well.

Because `CastStorageToLogicalDeref` will appear as argumnet if
`lowerBufferElementTypeToStorageType` is run before we apply the
`in-&gt;borrow` transformation pass, which is the case for metal parameter
block legalization.</content>
</entry>
<entry>
<title>Fix legalization crash when processing metal parameter blocks. (#8591)</title>
<updated>2025-10-03T19:52:26+00:00</updated>
<author>
<name>Yong He</name>
<email>yonghe@outlook.com</email>
</author>
<published>2025-10-03T19:52:26+00:00</published>
<link rel='alternate' type='text/html' href='https://git.yummers.dev/slang.git/commit/?id=6a2cf239a89340ed2985d04609499e8c4a2d8f89'/>
<id>urn:sha1:6a2cf239a89340ed2985d04609499e8c4a2d8f89</id>
<content type='text'>
Closes #7606.

When Slang compile for a bindful target, we will run the resource type
legalization pass to hoist resource typed struct fields outside of the
struct type and define them as global parameters and passing them around
via dedicated function parameters.
When we compile for a bindless target, we don't run this pass.
However, Metal is a hybrid bindful and bindless target. We need to run
type legalization for the constant buffer, but skip type legalization
for parameter block.

The previous attempt to support this behavior is to hack the type
legalization pass to return `LegalVal::simple` when it sees a
`ParameterBlock&lt;T&gt;`. However, whenever the code is accessing
`parameterBlock.someNestedField`, the type of the nested field may get a
`LegalType::tuple`, and now we will run into inconsistent scenarios
where we have a `LegalVal::simple` on the operand val, and but the
legalization logic is expecting that val to be a `LegalType::tuple`.
This breaks a lot of assumptions and invariants in the type legalization
pass, resulting unstable/fragile behavior.

To systematically solve this problem, this change generalizes the
existing legalize buffer element type pass to translate
`ParameterBlock&lt;Texture2D&gt;` (and similar cases) to
`ParameterBlock&lt;Texture2D.Handle&gt;`. So that such parameter block will
always be legalized to `LegalType:::simple` during type legalization,
and we will never run into any inconsistent cases. This allowed us to
get rid of the hacky logic in the type legalization pass to try to
workaround the inconsistencies.</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>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>Fix `shouldEmitSPIRVDirectly` (#8019)</title>
<updated>2025-08-26T17:48:49+00:00</updated>
<author>
<name>ArielG-NV</name>
<email>159081215+ArielG-NV@users.noreply.github.com</email>
</author>
<published>2025-08-26T17:48:49+00:00</published>
<link rel='alternate' type='text/html' href='https://git.yummers.dev/slang.git/commit/?id=b36659eca38be716bee43c01c6584bda5f91166a'/>
<id>urn:sha1:b36659eca38be716bee43c01c6584bda5f91166a</id>
<content type='text'>
Fixes: #8018

Changes:
* Do not emit true for `shouldEmitSPIRVDirectly` with a GLSL target</content>
</entry>
<entry>
<title>Introduce CDataLayout &amp; -fvk-use-c-layout (#8136)</title>
<updated>2025-08-21T05:47:18+00:00</updated>
<author>
<name>Julius Ikkala</name>
<email>julius.ikkala@gmail.com</email>
</author>
<published>2025-08-21T05:47:18+00:00</published>
<link rel='alternate' type='text/html' href='https://git.yummers.dev/slang.git/commit/?id=35f8e092f2aa3ed5e3cf03387e712f798ff4850e'/>
<id>urn:sha1:35f8e092f2aa3ed5e3cf03387e712f798ff4850e</id>
<content type='text'>
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` &amp; `-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 &lt;ellieh@nvidia.com&gt;</content>
</entry>
<entry>
<title>Address structured buffer `GetDimensions` issues for WGSL, GLSL and SPIRV (#7010)</title>
<updated>2025-05-16T19:01:24+00:00</updated>
<author>
<name>Darren Wihandi</name>
<email>65404740+fairywreath@users.noreply.github.com</email>
</author>
<published>2025-05-16T19:01:24+00:00</published>
<link rel='alternate' type='text/html' href='https://git.yummers.dev/slang.git/commit/?id=da951e06e7eb8ad1b9c91d6176be8165ea4f2b45'/>
<id>urn:sha1:da951e06e7eb8ad1b9c91d6176be8165ea4f2b45</id>
<content type='text'>
* Fix structured buffer get dimensions

* Further fixes and added tests

* Remove unnecessary include

* Fix test issues

* attempt to fix wgpu crash

* test remove half usage in test

* attempt to fix WGPU test issue

* Another attempt to fix WGSL test - make test similar to the existing GetDimensions test

---------

Co-authored-by: Yong He &lt;yonghe@outlook.com&gt;</content>
</entry>
<entry>
<title>support specialization constant sized array (#6871)</title>
<updated>2025-05-14T17:11:53+00:00</updated>
<author>
<name>kaizhangNV</name>
<email>149626564+kaizhangNV@users.noreply.github.com</email>
</author>
<published>2025-05-14T17:11:53+00:00</published>
<link rel='alternate' type='text/html' href='https://git.yummers.dev/slang.git/commit/?id=375ecfe2903b09f07abeba2eafb88d9a564c1458'/>
<id>urn:sha1:375ecfe2903b09f07abeba2eafb88d9a564c1458</id>
<content type='text'>
Close #6859

Goal of this PR
We want to support an array whose size can be specialization constant for shared/global variable e.g.

layout (constant_id = 0) const uint BLOCK_SIZE = 64;
shared float buf_a[(BLOCK_SIZE + 5) * 4];
Overview of the solution:

During IndexExpr check, we will loose the restriction to allow SpecConst passing, but the size parameter will not be a constant value because it cannot be folded into a constant, so we will make it follow the same logic as generic parameter value, and the size will be represented by FuncCallIntVal/PolynomialIntVal/DeclRefIntVal.

During IR lowering, we will detect whether there is spec constant in the IntVal, and wrap the IRInst with a SpecConstRateType, and propagate the type though the lowering logic, such that the IntVal representing the array size will have SpecConstRateType.

During spirv emit stage, if we detect that a IRInst has SpecConstRateType, we will emit it as SpecConstantOp.

We have to implement new logic to emit OpSpecConstantOp, the existing emit logic doesn't support emitting OpSpecConstantOp, especially this op can embed arithmetic operation at global scope, where we can only emit arithmetic instruct at local. But there are only few instructs we need to support.

Overview of the solution:
This PR doesn't support generic, and we will create a separate PR to extend that, tracked in #6840.</content>
</entry>
<entry>
<title>Update SPIRV-Tools and fix new validation errors. (#6511)</title>
<updated>2025-03-06T22:26:34+00:00</updated>
<author>
<name>Yong He</name>
<email>yonghe@outlook.com</email>
</author>
<published>2025-03-06T22:26:34+00:00</published>
<link rel='alternate' type='text/html' href='https://git.yummers.dev/slang.git/commit/?id=4485cf3eaf142cfd5f8470e86739acc67d4e12ea'/>
<id>urn:sha1:4485cf3eaf142cfd5f8470e86739acc67d4e12ea</id>
<content type='text'>
* Update SPIRV-Tools and fix new validation errors.

* Implement pointers for glsl target.

* Reworked packStorage/unpackStorage code gen to operate on pointers rather than values.</content>
</entry>
<entry>
<title>Lower varying parameters as pointers instead of SSA values. (#5919)</title>
<updated>2025-01-08T06:26:31+00:00</updated>
<author>
<name>Yong He</name>
<email>yonghe@outlook.com</email>
</author>
<published>2025-01-08T06:26:31+00:00</published>
<link rel='alternate' type='text/html' href='https://git.yummers.dev/slang.git/commit/?id=c43f6fa55aca23365c86c6ec1737d42be74d9d3e'/>
<id>urn:sha1:c43f6fa55aca23365c86c6ec1737d42be74d9d3e</id>
<content type='text'>
* Add executable test on matrix-typed vertex input.
* Fix emit logic of matrix layout qualifier.
* Pass fragment shader varying input by constref to allow EvaluateAttributeAtCentroid etc. to be implemented correctly.</content>
</entry>
</feed>
