HLSL: add intrinsic function implicit promotions
authorsteve-lunarg <steve_gh@khasekhemwy.net>
Wed, 2 Nov 2016 18:42:34 +0000 (12:42 -0600)
committersteve-lunarg <steve_gh@khasekhemwy.net>
Wed, 23 Nov 2016 17:36:34 +0000 (10:36 -0700)
commitef33ec0925fa68e24e4b26471957bb1f27cadd24
tree7db33092e21b20b0483bc8536fc8605a9d171f0e
parent1c573fbcfba6b3d631008b1babc838501ca925d3
HLSL: add intrinsic function implicit promotions

This PR handles implicit promotions for intrinsics when there is no exact match,
such as for example clamp(int, bool, float).  In this case the int and bool will
be promoted to a float, and the clamp(float, float, float) form used.

These promotions can be mixed with shape conversions, e.g, clamp(int, bool2, float2).

Output conversions are handled either via the existing addOutputArgumentConversion
function, which this PR generalizes to handle either aggregates or unaries, or by
intrinsic decomposition.  If there are methods or intrinsics to be decomposed,
then decomposition is responsible for any output conversions, which turns out to
happen automatically in all current cases.  This can be revisited once inout
conversions are in place.

Some cases of actual ambiguity were fixed in several tests, e.g, spv.register.autoassign.*

Some intrinsics with only uint versions were expanded to signed ints natively, where the
underlying AST and SPIR-V supports that.  E.g, countbits.  This avoids extraneous
conversion nodes.

A new function promoteAggregate is added, and used by findFunction.  This is essentially
a generalization of the "promote 1st or 2nd arg" algorithm in promoteBinary.

The actual selection proceeds in three steps, as described in the comments in
hlslParseContext::findFunction:

1. Attempt an exact match.  If found, use it.
2. If not, obtain the operator from step 1, and promote arguments.
3. Re-select the intrinsic overload from the results of step 2.
19 files changed:
Test/baseResults/hlsl.intrinsics.frag.out
Test/baseResults/hlsl.intrinsics.promote.down.frag.out [new file with mode: 0644]
Test/baseResults/hlsl.intrinsics.promote.frag.out [new file with mode: 0644]
Test/baseResults/hlsl.intrinsics.promote.outputs.frag.out [new file with mode: 0644]
Test/baseResults/hlsl.intrinsics.vert.out
Test/baseResults/spv.register.autoassign-2.frag.out
Test/hlsl.intrinsics.frag
Test/hlsl.intrinsics.promote.down.frag [new file with mode: 0644]
Test/hlsl.intrinsics.promote.frag [new file with mode: 0644]
Test/hlsl.intrinsics.promote.outputs.frag [new file with mode: 0644]
Test/spv.register.autoassign-2.frag
Test/spv.register.autoassign.rangetest.frag
glslang/MachineIndependent/Intermediate.cpp
glslang/MachineIndependent/linkValidate.cpp
glslang/MachineIndependent/localintermediate.h
gtests/Hlsl.FromFile.cpp
hlsl/hlslParseHelper.cpp
hlsl/hlslParseHelper.h
hlsl/hlslParseables.cpp