<feed xmlns='http://www.w3.org/2005/Atom'>
<title>slang.git/tests/rewriter, 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-03-23T17:54:01+00:00</updated>
<entry>
<title>Make `-no-mangle` option work, add `-no-hlsl-binding`. (#3817)</title>
<updated>2024-03-23T17:54:01+00:00</updated>
<author>
<name>Yong He</name>
<email>yonghe@outlook.com</email>
</author>
<published>2024-03-23T17:54:01+00:00</published>
<link rel='alternate' type='text/html' href='https://git.yummers.dev/slang.git/commit/?id=a23adc221b1ea26db3f3313226b629eb9e308b0f'/>
<id>urn:sha1:a23adc221b1ea26db3f3313226b629eb9e308b0f</id>
<content type='text'>
</content>
</entry>
<entry>
<title>Change how buffers are emitted (#741)</title>
<updated>2018-12-07T21:31:06+00:00</updated>
<author>
<name>Tim Foley</name>
<email>tfoleyNV@users.noreply.github.com</email>
</author>
<published>2018-12-07T21:31:06+00:00</published>
<link rel='alternate' type='text/html' href='https://git.yummers.dev/slang.git/commit/?id=135eaff6b892fc91a398714ddcf7ef377cd4cccb'/>
<id>urn:sha1:135eaff6b892fc91a398714ddcf7ef377cd4cccb</id>
<content type='text'>
* Change how buffers are emitted

This is a change with a lot of pieces, which can't always be separated out cleanly. I'm going to walk through them in what I hope is a logical order.

The main goal of this change was to allow arrays of structured buffers to translate to Vulkan. Consider two declarations of structured buffers in HLSL/Slang:

```hlsl
StructuredBuffer&lt;X&gt; single;
StructuredBuffer&lt;Y&gt; multiple[10];
```

The current translation logic was handling `single` by translating it into an *unnamed* GLSL `buffer` block like:

```glsl
layout(std430)
buffer _S1
{
	X single[];
};
```

That syntax allows an expression like `single[i]` in Slang to be translated simply as `single[i]` in GLSL.

But that naive translating doesn't work for `multiple`, since we need to declare a array of blocks in GLSL, which requires giving the whole thing a name:

```glsl
layout(std430)
buffer _S2
{
	Y _data[];
} multiple[10];
```

Now a reference to `multiple[i][j]` in Slang needs to become `multiple[i]._data[j]` in GLSL.

To avoid having way too many special cases around single structured buffers vs. arrays, it makes sense to allows emit things in the latter form, so that we instead lower `single` as:

```glsl
layout(std430)
buffer _S1
{
	X _data[];
} single;
```

So that now a reference to `single[i]` becomes `single._data[i]` in GLSL.
Most of that can be handled in the standard library translation of the structured buffer indexing operations.

The only wrinkle there is that there were some *old* special-case instructions in the IR intended to handle buffer load/store operations (these were added back when I was trying to keep the "VM" path working). These aren't really needed to have structured-buffer operations work; they can be handled as ordinary functions as far as the stdlib is concerned. I removed the old instructions.

Along the way, it became clear that a few other cases follow the same pattern. Byte-addressed buffers are an obvious case. We were lowering HLSL/Slang:

```hlsl
ByteAddressBuffer b;
...
uint x = b.Load(0);
```

to GLSL like:

```glsl
layout(std430)
buffer _S1
{
	uint b[];
};
...
uint x = b[0];
```

That logic would fail for arrays the same way that the structured buffer case was failing. The fix is the same: use named `buffer` blocks and then introduce an explicit `_data` field:

```glsl
layout(std430)
buffer _S1
{
	uint _data[];
} b;
...
uint x = b._data[0];
```

Just like with structured buffers, all of the VK translation for operations on byte-addressed buffers can be implemented directly in teh stdlib, so once the emit logic was changed it was just a matter of adding `._data` to a bunch of VK tranlsations.

It turns out that arrays of constant buffers have more or less the same problem, and furthermore we have some problems with any code that directly uses the modern HLSL `ConstantBuffer&lt;T&gt;` type.

Note: the emit logic around constant buffers sometimes refers to "parameter groups" because that is being used in the compiler as a catch-all term for constant buffers, texture buffers, and parameter blocks.

The existing code was going out of its way to reproduce the way that constant buffer declarations are implicitly referenced in HLSL:

```hlsl
cbuffer C { float f; }
...
float tmp = f; // No reference to `C` here
```

This can be seen in the emit logic with the `isDerefBaseImplicit` function, which is used to take the internal IR representation for a reference to `f` (which is closer to the expression `(*C).f` or `C-&gt;f`) and leave off any reference to `C` so that we emit just `f`.

That kind of logic just flat out doesn't work in some important cases. Arrays of constant buffers are a clear one:

```hlsl
ConstantBuffer&lt;X&gt; cbArray[3];
...
X x = cbArray[0];
```

There is no way to translate that to an ordinary `cbuffer` declaration at all. The same problem can be created without arrays, though:

```hlsl
ConstantBuffer&lt;X&gt; singleCB;
...
X x = singleCB;
```

The current strategy for translating constant buffers was translating `singleCB` into a `cbuffer` declaration that reproduced the fields of `X` as its members, which just wouldn't work:

```hlsl
cbuffer singleCB
{
	float f; // field of `X`
}
...
X x = singleCB; // ERROR: there is nothing named `singleCB` in this HLSL
```

The new strategy is more consistent. We still generate a `cbuffer` declaration for a single constant buffer, but we always give it a single field of the chosen element type:

```hlsl
cbuffer singleCB
{
	X singleCB;
}
...
X x = singleCB; // this works fine!
```

And in the array case we generate code that uses the explicit `ConstantBuffer&lt;T&gt;` type:

```hlsl
ConstantBuffer&lt;X&gt; cbArray[3];
...
X x = cbArray[0];
```

The GLSL output is more complicated because unlike with HLSL there is no implicit conversion from a uniform block to its element type (there is no notion of an element type). The array case thus needs a `_data` field similar to what we do for structured buffers:

```glsl
layout(std140)
uniform _S3
{
	X _data;
} cbArray[3];
...
X x = cbArray[0]._data;
```

And then the non-array case needs to have a similar `_data` field for consistency:

```glsl
layout(std140)
uniform _S1
{
	X _data;
} singleCB;
...
X x = singleCB._data;
```

This is handled by inserting the necessary reference to `_data` whenever we dereference a constant buffer, either as part of a load instruction (loading from the whole CB as a pointer), or an `IRFieldAddress` instruction which forms a pointer into the CB (e.g., `&amp;(singleCB-&gt;f)` becomes `singleCB._data.f`).

The current emit logic handles `ParameterBlock&lt;X&gt;` differently from `ConstantBuffer&lt;X&gt;`, but really only to allow parameter blocks to be explicitly named in the output, while constant buffers were left implicit by default. Thus the only difference was a legacy one (from back when trying to exactly reproduce the HLSL text we got as input was considered an important goal), and the new approach to emitting constant buffers would get rid of it.

I removed the separate logic for emitting `ParameterBlock&lt;X&gt;` and just let the handling for constant buffers deal with it.

Note that any resource types inside of a `ParameterBlock&lt;X&gt;` would have been moved out as part of legalization, so that a parameter block is 100% equivalent to a constant buffer when it comes time to emit code.

Unsurprisingly, changing the way we generate HLSL and GLSL output for all these buffer types meant that any tests that were directly comparing the output of `slangc` against `fxc`, `dxc`, or `glslang` broke.

The basic approach to fixing the breakage in GLSL tests was to update the GLSL baseline to reflect the new output startegy. In some cases I used macros to name the various `_S&lt;digits&gt;` temporaries so that future renaming will hopefully be easier (it would be great if we auto-generated temporary names with a bit more context). There was one GLSL test (`tests/bugs/vk-structured-buffer-binding`) that was using raw GLSL expected output, and this was changed to use a GLSL baseline to generate SPIR-V for comparison.

For HLSL tests we were sometimes running the same input file through `slangc` and `fxc`/`dxc`, and in these cases I macro-ized the various `cbuffer` declarations to generate different declarations depending on the compiler.

I completely dropped the tests coming from the D3D SDK because they aren't providing much coverage, and updating them would change them so far from the original code that the purported benefit (using a body of existing shaders) would be lost.

I also dropped the explicit matrix layout qualifiers in the `matrix-layout` test because the new output strategy breaks those for GLSL (you can't put matrix layout qualifiers on `struct` fields, and now the body of every constant buffer is inside a `struct`). This isn't as big of a loss as it seems, because our handling of those qualifiers wasn't really right to begin with. Slang users should only be setting the matrix layout mode globally (and we should probably switch to error out on the explicit qualifiers for now).

The other thing that got dropped is tests involving `packoffset` modifiers.
Slang already warns that it doesn't support these, and the way they were used in the test cases is actually misleading. For the binding/layout-related tests, the goal was to show that Slang reproduces the same layout as fxc, in which case explicitly enforcing a layout via `packoffset` seems like cheating (are we sure we enforced the layout fxc would have produced?). The real reason was that Slang used to emit explicit `packoffset` on *every* field of a `cbuffer` it would output, because of an `fxc` bug where you couldn't use `register` on textures/samplers declared inside a `cbuffer` unless *every* field in the `cbuffer` used a `register` or `packoffset` modifier. Slang hasn't required that behavior in a while because it now splits textures and samplers, and the one test case where we needed `packoffset` to work around the `fxc` bug in the baseline HLSL has been macro-ified even more to work around the bug.

The amount of churn in the test cases is unfortunate, but it continues to point at the weakness of any testing strategy that checks for exact equivalent between Slang's output and that of other compilers. We need to keep working to replace these tests with better alternatives.

In `check.cpp` there is logic to perform implicit dereferencing, so that if you write `obj.f` where `obj` is a `ConstantBuffer&lt;X&gt;` (or some other "pointer-like" type) and `f` is a field in `X`, then this effectively translates as `(*obj).f`. That is, we dereference the value of type `ConstantBuffer&lt;X&gt;` to get a value of type `X`, and then refer to the field of the `X` value.

There was a problem where the logic to insert that kind of implicit dereference operation was using a reference (`auto&amp; type = ...`) for the type of the expression being dereferenced, and then clobbering it. This would mean that an expression of type `ConstantBuffer&lt;X&gt;` would have its type overwritten to be just `X` and then codegen would break later on.

I'm not sure how we haven't run into that before.

The `array-of-buffers` test case was added to confirm that we now support arrays of constant, structured, and byte-address buffers for both DXIL and SPIR-V output.

Okay, so that was a lot of stuff, but hopefully it is clear how this all works to make the output of the compiler more consistent and explicit, while also supporting the required new functionality.

* fixup: review feedback
</content>
</entry>
<entry>
<title>Rework command-line options handling for entry points and targets (#697)</title>
<updated>2018-10-29T21:44:39+00:00</updated>
<author>
<name>Tim Foley</name>
<email>tfoleyNV@users.noreply.github.com</email>
</author>
<published>2018-10-29T21:44:39+00:00</published>
<link rel='alternate' type='text/html' href='https://git.yummers.dev/slang.git/commit/?id=725985528f77ba939a5cddc71e5006fee7638465'/>
<id>urn:sha1:725985528f77ba939a5cddc71e5006fee7638465</id>
<content type='text'>
* Rework command-line options handling for entry points and targets

Overview:

* The biggest functionality change is that the implicit ordering constraints when multiple `-entry` options are reversed: any `-stage` option affects the `-entry` to its *left* instead of to its *right* as it used to. This is technically a breaking change, but I expect most users aren't using this feature.

* The options parsing tries to handle profile versions and stages as distinct data (rather than using the combined `Profile` type all over), and treats a `-profile` option that specifies both a profile version and a stage (e.g., `-profile ps_5_0`) as if it were sugar for both a `-profile` and a `-stage` (e.g., `-profile sm_5_0 -stage fragment`).

* We now technically handle multiple `-target` options in one invocation of `-slangc`, but do not advertise that fact in the documentation because it might be confusing for users. Similar to the relationship between `-stage` and `-entry`, any `-profile` option affects the most recent `-target` option unless there is only one `-target`.

* The logic for associating `-o` options with corresponding entry points and targets has been beefed up. The rule is that a `-o` option for a compiled kernel binds to the entry point to its left, unless there is only one entry point (just like for `-stage`). The associated target for a `-o` option is found via a search, however, because otherwise it would be impossible to specify `-o` options for both SPIR-V and DXIL in one pass.

* The handling of output paths for entry points in the internal compiler structures was changed, because previously it could only handle one output path per entry point (even when there are multiple targets). The new logic builds up a per-target mapping from an entry point to its desired output path (if any).

Details:

* Support for formatting profile versions, stages, and compile targets (formats) was added to diagnostic printing, so that we can make better error messages. This is fairly ad hoc, and it would be nice to have all of the string&lt;-&gt;enum stuff be more data-driven throughout the codebase.

* Test cases were added for (almost) all of the error conditions in the current options validation. The main one that is missing is around specifying an `-entry` option before any source file when compiling multiple files. This is because the test runner is putting the source file name first on the command line automatically, so we can't reproduce that case.

* Several reflection-related tests now reflect entry points where they didn't before, because the logic for detecting when to infer a default `main` entry point have been made more loose

* On the dxc path, beefed up the handling of mapping from Slang `Profile`s to the coresponding string to use when invoking dxc.

* A bunch of tests cases were in violation of the newly imposed rules, so those needed to be cleaned up.

* There were also a bunch of test cases that had accidentally gotten "disabled" at some point because there were comparing output from `slangc` both with and without a `-pass-through` option, but that meant that any errors in command-line parsing produced the *same* error output in both the Slang and pass-through cases. This change updates `slang-test` to always expect a successful run for these tests, and then manually updates or disables the various test cases that are affected.

* When merging the updated test for matrix layout mode, I found that the new command-line logic was failing to propagate a matrix layout mode passed to `render-test` into the compiler. This was because the `-matrix-layout*` options were implemented as per-target, but the target was being set by API while the option came in via command line (passed through the API). It seems like we want matrix layout mode to be a global option anyway (rather than per-target), so I made that change here.

* Add missing expected output files

* A 64-bit fix

* Remove commented-out code noted in review
</content>
</entry>
<entry>
<title>Remove non-IR codegen paths (#398)</title>
<updated>2018-02-03T15:30:54+00:00</updated>
<author>
<name>Tim Foley</name>
<email>tfoleyNV@users.noreply.github.com</email>
</author>
<published>2018-02-03T15:30:54+00:00</published>
<link rel='alternate' type='text/html' href='https://git.yummers.dev/slang.git/commit/?id=662f43fff6721c6cd013a8f1b2639c2e29fe6be3'/>
<id>urn:sha1:662f43fff6721c6cd013a8f1b2639c2e29fe6be3</id>
<content type='text'>
The basic change is simple: remove support for all code generation paths other than the IR.
There is a lot of vestigial code left, but the main logic in `ast-legalize.*` is gone.

Doing this breaks a *lot* of tests, for various reasons:

- We can no longer guarantee exactly matching DXBC or SPIR-V output after things pass through out IR

- Many builtins don't have matching versions defined for GLSL output via IR (even when they had versions defined via the earlier approach that worked with the AST)

- A lot of code creates intermediate values of opaque types in the IR, which turn into opaque-type temporaries that aren't allowed (this breaks many GLSL tests, but also some HLSL)

I implemented some small fixes for issues that I could get working in the time I had, but most of the above are larger than made sense to fix in this commit.

For now I'm disabling the tests that cause problems, but we will need to make a concerted effort to get things working on this new substrate if we are going to make good on our goals.</content>
</entry>
<entry>
<title>Parameter blocks (#245)</title>
<updated>2017-11-06T18:37:27+00:00</updated>
<author>
<name>Tim Foley</name>
<email>tfoleyNV@users.noreply.github.com</email>
</author>
<published>2017-11-06T18:37:27+00:00</published>
<link rel='alternate' type='text/html' href='https://git.yummers.dev/slang.git/commit/?id=9919c823938ae929b16efac9d507f6d5eb122bf4'/>
<id>urn:sha1:9919c823938ae929b16efac9d507f6d5eb122bf4</id>
<content type='text'>
* Rename existing ParameterBlock to ParameterGroup

We are planning to add a new `ParameterBlock&lt;T&gt;` type, which maps to the notion of a "parameter block" as used in the Spire research work.
Unfortunately, the compiler codebase already uses the term `ParameterBlock` as catch-all to encompass all of HLSL `cbuffer`/`tbuffer` and GLSL `uniform`/`buffer`/`in`/`out` blocks (all of which are lexical `{}`-enclosed blocks that define parameters...).

This change instead renames all of the existing concepts over to `ParameterGroup`, which isn't an ideal name, but at least doesn't directly overlap the new terminology or any existing terminology.

The new `ParameterBlockType` case will probably be a subclass of `ParameterGroupType`, since it is a logical extension of the underlying concept.

* Add Shader Model 5.1 profiles

The HLSL `register(..., space0)` syntax is only allowed on "SM5.1" and later profiles (which is supported by the newer version of `d3dcompiler_47.dll` that comes with the Win10 SDK, but not the older version of `d3dcompiler_47.dll` - good luck figuring out which you have!).

This change adds those profiles to our master list of profiles, and nothing else.

* First pass at support for `ParameterBlock&lt;T&gt;`

- Add the type declaration in stdlib

- Add a special case of `ParameterGroupType` for parameter blocks

- Handle parameter blocks in type layout (currently handling them identically to constant buffers for now, which isn't going to be right in the long term)

- Add an IR pass that basically replaces `ParameterBlock&lt;T&gt;` with `T`
  - Eventually this should replace it with either `T` or `ConstantBuffer&lt;T&gt;`, depending on whether the layout that was computed required a constant buffer to hold any "free" uniforms

- Add first stab at an IR pass to "scalarize" global variables using aggregate types with resources inside.
  - This currently only applies to global variables, so it won't handle things passed through functions, or used as local variables
  - It also only supports cases where the references to the original variable are always references to its fields, and not the whole value itself

- Add a single test case that technically passes with this level of support, but probably isn't very representative of what we need from the feature

* Fold parameter-block desugaring into a more complete "type legalization" pass

The basic problem that was arising is that once you desugar `ParameterBlock&lt;T&gt;` into `T`, you then need todeal with splitting `T` into its constituent fields if it contains any resource types.
Handling those transformations by following the usual use-def chains wasn't really helping, because you might need systematic rewriting that can really only be handled bottom-up.

This change adds a new pass that is intended to perform multiple kinds of type "legalization" at once:

- It will turn `ParameterBlock&lt;T&gt;` into `T`
  - It may at some point also convert `ConstantBuffer&lt;T&gt;` into `T` as well
- It will turn an value of an aggregate type that contains resources into N different values (one per field)
  - As a result of this, it will also deal with AOS-to-SOA conversion of these types

Legalization is applied to *every* function/instruction/value, so that it can make large-scale changes that would be tough to manage with a work list.

This pass needs to be run *after* generics have been fully specialized, so that we know we are always dealing with fully concrete types, so that their legalization for a given target is completely known.

This is still work in progress; there's more to be done to get this working with all our test cases, and finish the remaining `ParameterBlock&lt;T&gt;` work.

* Improve binding/layout information when using parameter blocks

- When doing type layout for a parameter block, don't include the resources consumed by the element type in the resource usage for the parameter block
  - Note that this is pretty much identical to how a `ConstantBuffer&lt;T&gt;` does not report any `LayoutResourceKind::Uniform` usage, except that `ParameterBlock&lt;T&gt;` is *also* going to hide underlying texture/sampler reigster usage
  - The one exception here is that any nested items that use up entire `space`s or `set`s those need to be exposed in the resource usage of the parent (I don't have a test for this)

- When type legalization needs to scalarize things, it must propagate layout information down to the new leaf variables. In general, the register/index for a new leaf parameter should be the sum of the offsets for all of the parent variables along the "chain" from the original variable down to the leaf (we aren't dealing with arrays here just yet).

- When type legalization decides to eliminate a pointer(-like) type (e.g., desugar `ParameterBlock&lt;T&gt;` over to `T`), actually deal with that in terms of the `LegalVal`s created, so that we can know to turn a `load` into a no-op when applied to a value that got indirection removed.

- Hack up the "complex" parameter-block test so that it actually passes (the big hack here is that the HLSL baseline is using names that are generated by the IR, and are unlikely to be stable as we add/remove transformations).
  - Note: I can't make these be compute tests right now, because regsiter spaces/sets are a feature of D3D12/Vulkan, and our test runner isn't using those APIs.
</content>
</entry>
<entry>
<title>Add a flag to control type splitting</title>
<updated>2017-08-17T15:59:30+00:00</updated>
<author>
<name>Tim Foley</name>
<email>tfoley@nvidia.com</email>
</author>
<published>2017-08-17T15:59:30+00:00</published>
<link rel='alternate' type='text/html' href='https://git.yummers.dev/slang.git/commit/?id=d13bd05164c6a3d0b7ba95bb415f6bfac4cfcb70'/>
<id>urn:sha1:d13bd05164c6a3d0b7ba95bb415f6bfac4cfcb70</id>
<content type='text'>
The `-split-mixed-types` flag can be provided to command-line `slangc`, and the `SLANG_COMPILE_FLAG_SPLIT_MIXED_TYPE` flag can be passed to `spSetCompileFlags`.
Either of these turns on a mode where Slang will split types that included both resource and non-resource fields.
The declaration of such a type will just drop the resource fields, while a variable declare using such a type turns into multiple declararations: one for the non-resource fields, and then one for each resource field (recursively).

This behavior was already implemented for GLSL support, and this change just adds a flag so that the user can turn it on unconditionally.

Caveats:

- This does not apply in "full rewriter" mode, which is what happens if the user doesn't use any `import`s. I could try to fix that, but it seems like in that mode people are asking to bypass as much of the compiler as possible.

- When it *does* apply, it applies to user code as well as library/Slang code. So this will potentially rewrite the user's own HLSL in ways they wouldn't expect. I don't see a great way around it, though.
</content>
</entry>
<entry>
<title>Handle possibility of bad types in varying input/output signature.</title>
<updated>2017-08-15T15:52:13+00:00</updated>
<author>
<name>Tim Foley</name>
<email>tfoley@nvidia.com</email>
</author>
<published>2017-08-15T15:52:13+00:00</published>
<link rel='alternate' type='text/html' href='https://git.yummers.dev/slang.git/commit/?id=3a2f191d9edd7c61d49cae1e979fa7633b2aaf8b'/>
<id>urn:sha1:3a2f191d9edd7c61d49cae1e979fa7633b2aaf8b</id>
<content type='text'>
Fixes #160

If the front-end runs into a type it doesn't understand in the parameter list of an entry point, it will create an `ErrorType` for that parameter, but then the parameter binding/layout rules will fail to create a `TypeLayout` for the prameter (and return `NULL`).
There were some places where the code was expecting that operation to succeed unconditionally, and so would crash when there was a bad type.

The specific case in the bug report was when the return type of a shader entry point was bad:

    // `vec4` is not an HLSL type
    vec4 main(...) { ... }

Note that the specific case in the buf report only manifests in "rewriter" mode (when the Slang compiler isn't allowed to issue error messages from the front-end), but the same basic thing would happen if the varying parameter/output had used a type that is invalid for varying input/output:

    Texture2D main(...) { ... }

I'm not 100% happy with just adding more `NULL` checks for this, because there is no easy way to tell if they are exhaustive.
A better solution in the longer term might be to construct a kind of `ErrorTypeLayout` to represent cases where we wanted a type layout, but none could be constructed.
</content>
</entry>
<entry>
<title>Fixup for the glslang bug workaround</title>
<updated>2017-07-24T02:52:14+00:00</updated>
<author>
<name>Tim Foley</name>
<email>tfoley@nvidia.com</email>
</author>
<published>2017-07-24T02:52:14+00:00</published>
<link rel='alternate' type='text/html' href='https://git.yummers.dev/slang.git/commit/?id=e7241a921407ae79e0767956127f7ed501c5eeb1'/>
<id>urn:sha1:e7241a921407ae79e0767956127f7ed501c5eeb1</id>
<content type='text'>
There was a bug where the intialization expression for a variable was being lowered after the declaration was added to the output code, so that any sub-expressions that get hoisted out actually get computed *after* the original variable. This obviously led to downstream compilation failure.

I've updated the test case to stress this scenario.
</content>
</entry>
<entry>
<title>Work around glslang issue 988</title>
<updated>2017-07-24T01:37:52+00:00</updated>
<author>
<name>Tim Foley</name>
<email>tfoley@nvidia.com</email>
</author>
<published>2017-07-24T01:22:30+00:00</published>
<link rel='alternate' type='text/html' href='https://git.yummers.dev/slang.git/commit/?id=d4cfe5781284551d7c5ccf2cf1d28a86211bb1df'/>
<id>urn:sha1:d4cfe5781284551d7c5ccf2cf1d28a86211bb1df</id>
<content type='text'>
The basic bug there is that if you have a member of `struct` type in a `uniform` block and then pass a reference to that member directly to a call:

```
struct Foo { vec4 bar; };
uniform U { Foo foo; };

void main() { doSomething(foo); }
```

then glslang generates invalid SPIR-V which seems to cause an issue for some drivers.

This change works around the problem by detecting cases where an argument to a function call is a reference to `uniform` block member (of `struct` type) and then rewrites the code to move that value to a temporary before the call.
</content>
</entry>
<entry>
<title>Support scalarization of varying input/output for GLSL</title>
<updated>2017-07-18T19:58:48+00:00</updated>
<author>
<name>Tim Foley</name>
<email>tfoley@nvidia.com</email>
</author>
<published>2017-07-18T14:49:33+00:00</published>
<link rel='alternate' type='text/html' href='https://git.yummers.dev/slang.git/commit/?id=1c022e2c3654de868c45658683f9e04cf4d68cc0'/>
<id>urn:sha1:1c022e2c3654de868c45658683f9e04cf4d68cc0</id>
<content type='text'>
GLSL technically supports varying (`in`, `out`) parameters of `struct` type, but there are some annoying constraints (not allowed for VS input), and it doesn't work with how an HLSL user would usually put "system-value" inputs/outputs into a `struct` together with ordinary inputs/outputs.

To work around this, this change adds support for using an imported Slang `struct` type for an `in` or `out` parameter, in which case it will (1) be scalarized and (2) will have system-value semantics mapped appropriately, just as for an entry-point parameter when cross-compiling an HLSL-style `main()`.

Changes:

- Add a notion of a `VaryingTupleExpr` and `VaryingTupleVarDecl`, similar to those for the resources-in-structs case

- Trigger use of these when we have a global-scope varying in/out using an imported `struct` type

- Also use these in the cross-compilation case for ordinary varying input/output (since this approach seems like it should be more general, and can hopefully handle stuff like GS input/output some day)

- When generating parameter binding information, special case global-scope input/output, and treat it the same as entry-point-parameter input/output

- Revamp how used resource ranges are computed so that we can eventually make this specific to an entry point

- Actually implement first signs of life for `maybeMoveTemp` so that assignments to the tuple-ified outputs will work better

- Add first test case that actually seems to work

- Add diagnostics for conflicting explicit bindings on a parameter

- Add diagnostic for different parameters with overlapping bindings

- Make global-scope varying input/output use a tracking data structure specific to the translation unit for computing locations (so that they are independent of other TUs)
</content>
</entry>
</feed>
