diff options
| author | Tim Foley <tfoleyNV@users.noreply.github.com> | 2020-09-02 09:51:25 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2020-09-02 09:51:25 -0700 |
| commit | 7f567df6937b33c653c424af3abb20d32eb80561 (patch) | |
| tree | 34952785f3e4f924ba252e5758cccb1db7b218b2 /source/slang/core.meta.slang | |
| parent | c2873f406d544057e0ec61e61fb8580ca768e493 (diff) | |
Add support for (undocumented) HLSL 16-bit bit-cast ops (#1528)
As of SM 6.2, the dxc compiler added support for a set of 16-bit bit-cast operations to mirror the `asuint`, `asfloat`, and `asint` operations that were provided for 32-bit scalar types. These operations are not publicly documented, so we didn't think to add them.
It should be noted that there was already a similar operation in HLSL, called `f32tof16`, that took as input a `float` and then packed a half-precision version of it into the low bits of a `uint`. The problem is that using that operation for `half`->`uint16_t` conversion required a round trip through a `float`, and downstream compilers seemingly can't optimize away that conversion.
This change adds the new operations along with a test that tries to make use of them to ensure the results are what is expected. There are enough cases to cover that I had to write the test in a way where each thread only writes out a subset of the required output.
There are two other changes here are that are not directly related to the main feature:
First, it seems like the `[__forceInlineEarly]` attribute on some of these overloads interacts poorly with generics, and results in an `IRVectorType` appearing at local scope in the output code. That is semantically reasonable given our IR model, but it would ideally be something that gets eliminated as a result of deduplication of types. For now I've introduced a slight hack to make types always get inlined into their use sites during emission, which should handle the case of locally-defined types. I'm not 100% happy with that solution, but it seemed better than introducing a bunch of unrelated fixes into this PR.
Second, the way that conversion operations were being declared for matrix types seems to have been incorrect: we had a single *explicit* initializer added to matrix types via an `extension` that allowed them to be initialized from other matrix types with the same size and *any* element type. In order to support implicit conversions of matrix types, I cribbed the code we were already using to introduce implicit conversion operations for vector types.
Diffstat (limited to 'source/slang/core.meta.slang')
| -rw-r--r-- | source/slang/core.meta.slang | 34 |
1 files changed, 27 insertions, 7 deletions
diff --git a/source/slang/core.meta.slang b/source/slang/core.meta.slang index 0eaf5cb1a..62039992e 100644 --- a/source/slang/core.meta.slang +++ b/source/slang/core.meta.slang @@ -520,13 +520,6 @@ for( int C = 2; C <= 4; ++C ) } sb << ");\n"; - - // initialize from another matrix of the same size - // - // TODO(tfoley): See comment about how this overlaps - // with implicit conversion, in the `vector` case above - sb << "__generic<U> __init(matrix<U," << R << ", " << C << ">);\n"; - // initialize from a matrix of larger size for(int rr = R; rr <= 4; ++rr) for( int cc = C; cc <= 4; ++cc ) @@ -537,6 +530,33 @@ for( int C = 2; C <= 4; ++C ) sb << "}\n"; } + +for (int tt = 0; tt < kBaseTypeCount; ++tt) +{ + if(kBaseTypes[tt].tag == BaseType::Void) continue; + auto toType = kBaseTypes[tt].name; +}}}} +__generic<let R : int, let C : int> extension matrix<$(toType),R,C> +{ +${{{{ + for (int ff = 0; ff < kBaseTypeCount; ++ff) + { + if(kBaseTypes[ff].tag == BaseType::Void) continue; + if( tt == ff ) continue; + + auto cost = getBaseTypeConversionCost( + kBaseTypes[tt], + kBaseTypes[ff]); + auto fromType = kBaseTypes[ff].name; +}}}} + __implicit_conversion($(cost)) + __init(matrix<$(fromType),R,C> value); +${{{{ + } +}}}} +} +${{{{ +} }}}} |
