<feed xmlns='http://www.w3.org/2005/Atom'>
<title>slang.git/tests/language-feature/types/opaque, 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>2024-11-07T00:42:14+00:00</updated>
<entry>
<title>Fix IntVal unification logic to insert type casts + buffer element lowering regression. (#5508)</title>
<updated>2024-11-07T00:42:14+00:00</updated>
<author>
<name>Yong He</name>
<email>yonghe@outlook.com</email>
</author>
<published>2024-11-07T00:42:14+00:00</published>
<link rel='alternate' type='text/html' href='https://git.yummers.dev/slang.git/commit/?id=989847f6a9408b68e90ac242f4a19d3266054c3e'/>
<id>urn:sha1:989847f6a9408b68e90ac242f4a19d3266054c3e</id>
<content type='text'>
* Fix IntVal unification logic to insert type casts.

* Fix regression.</content>
</entry>
<entry>
<title>Enable WebGPU tests in CI (#5239)</title>
<updated>2024-10-15T16:11:53+00:00</updated>
<author>
<name>Anders Leino</name>
<email>aleino@nvidia.com</email>
</author>
<published>2024-10-15T16:11:53+00:00</published>
<link rel='alternate' type='text/html' href='https://git.yummers.dev/slang.git/commit/?id=9e3b0367cfd63f21a0519b61b6fd13e94dac1c51'/>
<id>urn:sha1:9e3b0367cfd63f21a0519b61b6fd13e94dac1c51</id>
<content type='text'>
</content>
</entry>
<entry>
<title>Support parameter block in metal shader objects. (#4671)</title>
<updated>2024-07-19T18:49:42+00:00</updated>
<author>
<name>Yong He</name>
<email>yonghe@outlook.com</email>
</author>
<published>2024-07-19T18:49:42+00:00</published>
<link rel='alternate' type='text/html' href='https://git.yummers.dev/slang.git/commit/?id=f114433debfba67cbe1db239b6e92278d41ed438'/>
<id>urn:sha1:f114433debfba67cbe1db239b6e92278d41ed438</id>
<content type='text'>
* Support parameter block in metal shader objects.

* Ingore parameter block tests on devices without tier2 argument buffer.

* Fix warning.

* Fix texture subscript test.

---------

Co-authored-by: Yong He &lt;yhe@nvidia.com&gt;</content>
</entry>
<entry>
<title>Cache address-space-legalization of `kIROp_Store` (#4480)</title>
<updated>2024-06-27T16:26:02+00:00</updated>
<author>
<name>ArielG-NV</name>
<email>159081215+ArielG-NV@users.noreply.github.com</email>
</author>
<published>2024-06-27T16:26:02+00:00</published>
<link rel='alternate' type='text/html' href='https://git.yummers.dev/slang.git/commit/?id=5dd8f29443508bd8663a92c62d33e69cc47b61af'/>
<id>urn:sha1:5dd8f29443508bd8663a92c62d33e69cc47b61af</id>
<content type='text'>
* Cache address-space-legalization  of `kIROp_Store`

without caching we will infinetly loop re-processing the same `kIROp_Store`

* uncomment tests which should now work with metal

* disable gfx backend failing tests</content>
</entry>
<entry>
<title>enable more metal tests (#4326)</title>
<updated>2024-06-10T20:28:36+00:00</updated>
<author>
<name>skallweitNV</name>
<email>64953474+skallweitNV@users.noreply.github.com</email>
</author>
<published>2024-06-10T20:28:36+00:00</published>
<link rel='alternate' type='text/html' href='https://git.yummers.dev/slang.git/commit/?id=712ce653d4c3d7284dd71389f31540d0da7f144e'/>
<id>urn:sha1:712ce653d4c3d7284dd71389f31540d0da7f144e</id>
<content type='text'>
</content>
</entry>
<entry>
<title>Metal compute tests (#4292)</title>
<updated>2024-06-07T07:28:16+00:00</updated>
<author>
<name>skallweitNV</name>
<email>64953474+skallweitNV@users.noreply.github.com</email>
</author>
<published>2024-06-07T07:28:16+00:00</published>
<link rel='alternate' type='text/html' href='https://git.yummers.dev/slang.git/commit/?id=004fe27a52b7952111ad7e749397aeff499de7ed'/>
<id>urn:sha1:004fe27a52b7952111ad7e749397aeff499de7ed</id>
<content type='text'>
</content>
</entry>
<entry>
<title>Warning on lossy implicit casts. (#2367)</title>
<updated>2022-08-18T06:08:34+00:00</updated>
<author>
<name>Yong He</name>
<email>yonghe@outlook.com</email>
</author>
<published>2022-08-18T06:08:34+00:00</published>
<link rel='alternate' type='text/html' href='https://git.yummers.dev/slang.git/commit/?id=adaea0e993fd8db351b5dad92802e47ed6d0ec77'/>
<id>urn:sha1:adaea0e993fd8db351b5dad92802e47ed6d0ec77</id>
<content type='text'>
* Warning on bool to float conversion.

* Fix test cases.

* Improve.

* LanguageServer: don't show constant value for non constant variables.

* Fix tests.

* Fix warnings in tests.

Co-authored-by: Yong He &lt;yhe@nvidia.com&gt;</content>
</entry>
<entry>
<title>Add support for returning structures that contain opaque types (#1835)</title>
<updated>2021-05-04T23:59:54+00:00</updated>
<author>
<name>Tim Foley</name>
<email>tfoleyNV@users.noreply.github.com</email>
</author>
<published>2021-05-04T23:59:54+00:00</published>
<link rel='alternate' type='text/html' href='https://git.yummers.dev/slang.git/commit/?id=85632e8db19916a2f348fe356a91119d2fde2929'/>
<id>urn:sha1:85632e8db19916a2f348fe356a91119d2fde2929</id>
<content type='text'>
Introduction
============

Several of our target platforms share a concept of "opaque" types, including resources (`Texture2D`) and samplers (`SamplerState`), which are restricted in how they can be used. GLSL and SPIR-V place very severe restrictions, in that opaque types cannot be used for the type of:

* (mutable) local variables
* (mutable) global variables
* structure fields
* Function result/return
* `out` or `inout` parameters

The HLSL language allows all of these cases, but with the practical caveat that the compiler front-end must be able to statically analyze how opaque types have been used and "optimize away" all of the above cases. For example, it is legal to have a local variable of an opaque type, but at any point where the variable gets used it must be statically known which top-level shader parameter the variable refers to.

Existing Work
=============

In the Slang compiler we need to implement our own passes to detect these "illegal" uses of opaque types and legalize them. The work is basically broken into two distinct steps:

* The existing `legalizeResourceTypes()` pass detects illegal types (e.g., a `struct` that has a field of type `Texture2D`) and replaces them with legal types, sometimes by splitting apart declarations (e.g., a parameter using such a `struct` type gets split into multiple parameters). At a high level, we can think of this as "exposing" opaque types so that they are not hidden inside of nested structures.

* Next, the `specializeResourceOutputs()` pass detects calls to functions that output opaque types (whether by the function return value of `out` / `inout` parameters). The pass analyzes the body of such functions, and tries to isolate the logic that determines their resource-type outputs and hoise that logic into call sites (so that the opaque-type outputs can then be eliminated).

This Change
===========

One important missing case was that the type legalization step was incapable of legalizing types that appear in the result/return type of functions. The existing logic would simply diagnose an internal/unimplemented error if it ecountered a non-simple type in the return position.

At a high-level, supporting this case seems simple enough. Given a function signature like:

```
struct Things { int a; Texture2D b; }

Things myFunc(int x) { ... }
```

we want to split the result type into an "ordinary" result type and then `out` parameters for any opaque-type fields:

```
struct Things_Legal { int a; }

Things_Legal myFunc(int x, out Texture2D result_b) { ... };
```

Similarly, at a call site to a function like this:

```
Things t = myFunc(99);
```

we split the function result into ordinary and opaque-type parts, and pass the latter as `out` parameters:

```
Texture2D t_b;
Things_Legal t = myFunc(99, /*out*/ t_b);
```

The main place where things get tricky is when dealing with `return` sites within the body of a function that needs legalization:

```
Things myFunc(int x) {
    ...
    Things things = ...;
    ...
    return things;
}
```

In theory the answer is simple: a `return` translates into writes to the `out` parameters for any opaque-type data, followed by a return of the ordinary-type part:

```
Things_Legal myFunc(int x, out Texture2D result_b) {
    ...
    Things_Legal things = ...;
    Texture2D things_b = ...;
    ...
    result_b = things_b;
    return things;
}
```

The sticking point here is that this step requires tracking data between the legalization of the parameter list for `myFunc` and legalization of the `return`s in its body, so that we can identify the `result_b` parameter to be able to write to it. The existing type legalization pass was not built with the idea that such communication is commonly needed; it assumes that each instruction can be legalized in isolation, so long as dependencies are respected.

This change adds logic such that the `legalizeFunc()` step sets up a data structure that it used to represent information about how a function (and its parameter list) got legalized, so that the logic for a `return` can make use of that legalized information. Right now the information we track consists of just the list of parameters that were introduced to represent a return/result type.

Testing
=======

In order to confirm what features do/don't work, I added a set of tests that cover a cross-product of opaque type use cases:

* The opaque type can be used in the function result type, an `out` parameter, or an `inout` parameter
* The opaque type can be used "directly" or nested inside a `struct`.

These tests are helpful to make sure we handle the most important cases, but it is worth noting that the coverage is still lacking in that we do not sufficiently test all the options for what the function body might do. An opaque-type function result could be derived from many different sources:

* It could be a global shader parameter
* It could be an `in` or `inout` parameter of the function itself
* It could be wrapped up in one or more structure types
* It could be wrapped up in one or more array types (such that the output of specialization needs to pass around array indices)
* It could involve use of the type as a local variable (including passing it into other functions with result/`out`/`inout` outputs of opaque types)

This change makes it so that we can handle the simplest cases involving result/return types with a wrapper `struct`, and adds test cases that confirm we handle several other cases for `out` and `inout` parameters. Gaining confidence that we cover all the cases that arise in practical shaders will require more work over following changes.</content>
</entry>
</feed>
