https://github.com/shader-slang/slang
Revision d4924f5fc67f56b60d11381bf77d21bc01eb8763 authored by Tim Foley on 22 May 2019, 22:01:13 UTC, committed by GitHub on 22 May 2019, 22:01:13 UTC
* Basic layout and reflection for specialized types

Suppose I have an interface, and a simple implementation of it:

```hlsl
interface IModifier
{
    float modify(float value);
}

struct Doubler : IModifier
{
    float modify(float value) { return 2 * value; }
}
```

SAnd now suppose I want to define an implementation that recursively uses the same interface:

```hlsl
struct MultiModifier : IModifier
{
    IModifier first;
    IModifier second;

    float modify(float value)
    {
        value = first.modify(value);
        value = second.modify(value);
        return value;
    }
}
```

And now consider that I might have a generic entry point that uses the interface:

```hlsl
void myShader<M : IModifier>( uniform M modifier, ... )
{ ... }
```

I can easily specialize `myShader` for `M = Doubler`, but in order to specialze it for `M = MultiModifier` I need a way to specify what the types of `MultiModifier.first` and `.second` should be.

That is what the `spReflection_specializeType` function is used to do: take a type like `MultiModifier` and specialize it for, say, `first : Doubler` and `second : Doubler`. That function creates an `ExistentialSpecializedType` that records the base type (`MultiModifier`) and the specialization arguments (the concrete types plus the witness tables that prove they implement the required interfaces).

The change that introduced that logic neglected to include an implementation of type layout for `ExistentialSpecializedType`, and also didn't add any support for the new kind of type through the reflection API. That is what this change seeks to rectify.

When it comes to layout, a specialized type neeeds to apply layout to its base type (e.g., `MultiModifier`) with the appropriate existential type "slot" arguments bound, which luckily is stuff that type layout already supporst (to handle specialization of interface-type shader parameters).

Unlike the case for interface-type shader parameters where the "primary" and "pending" data for a type get propagated up the chain and allocated to different places, a specialized type should be allocated contiguously (e.g., `myShader<M>` is going to assume that the type `M` occupies a contiguous range in memory). The type layout for a specialized type thus computes a layout that is more-or-less a structure type consisting of the "primary" data followed by the "pending" data. This gets wrapped up in a new `ExistentialSpecializedTypeLayout` class.

The reflection API then needs to expose an `ExistentialSpecializedTypeLayout` as a new kind of type, and then also provide access to the relevant pieces. For the "base" type, I went ahead and re-used the `getElementType` entry point, just for simplicity (we can debate whether that or a new entry point is more appropriate/convenient). For the actual layout, all that was needed was a way to query the offset for where the "pending" data gets placed, and that is already conveniently encoded as a `VarLayout` field in the `ExistentialSpecializedTypeLayout`.

With this change, specialized types are closer to being truly usable, although there is still missing logic in IR lowering because we need to make sure that explicitly specialized types are represented differently from types that are specialized based on global shader parameters.

* fixup: review feedback
1 parent 06e1ab6
History
Tip revision: d4924f5fc67f56b60d11381bf77d21bc01eb8763 authored by Tim Foley on 22 May 2019, 22:01:13 UTC
Basic layout and reflection for specialized types (#970)
Tip revision: d4924f5
File Mode Size
docs
examples
external
source
tests
tools
.editorconfig -rw-r--r-- 937 bytes
.gitattributes -rw-r--r-- 95 bytes
.gitignore -rw-r--r-- 407 bytes
.gitmodules -rw-r--r-- 406 bytes
.travis.yml -rw-r--r-- 1.7 KB
CODE_OF_CONDUCT.md -rw-r--r-- 3.1 KB
LICENSE -rw-r--r-- 1.1 KB
README.md -rw-r--r-- 6.7 KB
appveyor.yml -rw-r--r-- 3.7 KB
premake5.lua -rw-r--r-- 26.6 KB
slang-com-helper.h -rw-r--r-- 4.8 KB
slang-com-ptr.h -rw-r--r-- 4.8 KB
slang.h -rw-r--r-- 93.2 KB
slang.sln -rw-r--r-- 9.8 KB
test.bat -rw-r--r-- 1.4 KB
travis_build.sh -rw-r--r-- 304 bytes
travis_test.sh -rw-r--r-- 435 bytes

README.md

back to top