diff options
| author | Tim Foley <tfoleyNV@users.noreply.github.com> | 2017-12-22 12:09:26 -0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2017-12-22 12:09:26 -0800 |
| commit | d1c38523d4bfbb6672baca9973013538b549bfae (patch) | |
| tree | 6dbfb2e1096014ee99eb3c6c77abb595a0d28e1c /source/slang/hlsl.meta.slang.h | |
| parent | fab52a1bd6aa056ba91a2697133e62a169866242 (diff) | |
Support for transitive subtype witnesses (#331)
* Change stdlib `saturate` to explicitly specialize `clamp`
This exposes issue #329, and so gives us an easy way to see if transitive subtype witnesses have been implemented correctly.
* Fixup: invoke correct `clamp` overloads
When switching the `clamp` calls in the stdlib definition of `saturate` I made two big mistakes:
1. I was passing in `<T>` in all cases, instead of, e.g., `<vector<T,N>>` in the vector case
2. Of course, the overloads don't actually take `<vector<T,N>>` for the vector case, because `vector<T,N>` is not a `__BuiltinArithmeticType` (`T` is), so instead it should be `clamp<T,N>(...)`.
The issue behind (2) is that we don't support "conditional conformances," which would be a way to say that when `T : __BuiltinArithmeticType` then `vector<T,N> : __BuiltinArithmeticType`. That would be a great long-term wish-list feature, but not something I can see us adding in a hurry.
Anyway the fix here is the simple one: change the vector/matrix call sites to invoke the correct overload in each case.
* Add a notion of transitive subtype witnesses
There are two pieces here:
1. Add the `TransitiveSubtypeWitness` class. This is a witness that `A : C` that works by storing nested subtype witnesses that show that `A : B` and `B : C` for some intermediate type `B`. All the basic `Val` operations are easy enough to define on this.
- The one gotcha case is whether we can ever simplify away a `TransitiveSubtypeWitness` as part of substitution. That is, if we end up substituting so that both `A` and `B` end up as the same type, then we really just need the `B : C` sub-part. Stuff like that is left as future work.
2. Make the logic in `check.cpp` that constructs subtype witnesses based on found inheritance and constraint declarations able to build up transitive chains. Most of the required infrastructure was already there (the search process maintains a trail of "breadcrumbs" that represent all the steps getting from `A : B` to `B : C` to `C : D` ...).
This change does *not* deal with the required changes in the IR to take advantage of transitive witnesses.
Diffstat (limited to 'source/slang/hlsl.meta.slang.h')
| -rw-r--r-- | source/slang/hlsl.meta.slang.h | 6 |
1 files changed, 3 insertions, 3 deletions
diff --git a/source/slang/hlsl.meta.slang.h b/source/slang/hlsl.meta.slang.h index acaef8fbd..921c361bd 100644 --- a/source/slang/hlsl.meta.slang.h +++ b/source/slang/hlsl.meta.slang.h @@ -826,14 +826,14 @@ sb << "__generic<T : __BuiltinFloatingPointType>\n"; sb << "__specialized_for_target(glsl)\n"; sb << "T saturate(T x)\n"; sb << "{\n"; -sb << " return clamp(x, T(0), T(1));\n"; +sb << " return clamp<T>(x, T(0), T(1));\n"; sb << "}\n"; sb << "\n"; sb << "__generic<T : __BuiltinFloatingPointType, let N : int>\n"; sb << "__specialized_for_target(glsl)\n"; sb << "vector<T,N> saturate(vector<T,N> x)\n"; sb << "{\n"; -sb << " return clamp(x,\n"; +sb << " return clamp<T,N>(x,\n"; sb << " vector<T,N>(T(0)),\n"; sb << " vector<T,N>(T(1)));\n"; sb << "}\n"; @@ -848,7 +848,7 @@ sb << "__generic<T : __BuiltinFloatingPointType, let N : int, let M : int>\n"; sb << "__specialized_for_target(glsl)\n"; sb << "matrix<T,N,M> saturate(matrix<T,N,M> x)\n"; sb << "{\n"; -sb << " return clamp(x,\n"; +sb << " return clamp<T,N,M>(x,\n"; sb << " __scalarToMatrix<T,N,M>(T(0)),\n"; sb << " __scalarToMatrix<T,N,M>(T(1)));\n"; sb << "}\n"; |
