From d9cb832f9cce8440336758169c6e7d90ff2a54db Mon Sep 17 00:00:00 2001 From: steve-lunarg Date: Fri, 11 Nov 2016 15:37:10 -0700 Subject: [PATCH] HLSL: allow promotion from 1-vector types to scalars, e.g, float<-float1 Previously, an error was thrown when assigning a float1 to a scalar float, or similar for other basic types. This allows that. Also, this allows calling functions accepting scalars with float1 params, so for example sin(float1) will work. This is a minor change in HlslParseContext::findFunction(). --- Test/baseResults/hlsl.promote.vec1.frag.out | 118 ++++++++++++++++++++++++++++ Test/hlsl.promote.vec1.frag | 16 ++++ glslang/Include/Types.h | 1 + glslang/MachineIndependent/Intermediate.cpp | 2 + gtests/Hlsl.FromFile.cpp | 1 + hlsl/hlslParseHelper.cpp | 4 +- 6 files changed, 140 insertions(+), 2 deletions(-) create mode 100644 Test/baseResults/hlsl.promote.vec1.frag.out create mode 100644 Test/hlsl.promote.vec1.frag diff --git a/Test/baseResults/hlsl.promote.vec1.frag.out b/Test/baseResults/hlsl.promote.vec1.frag.out new file mode 100644 index 0000000..3b68450 --- /dev/null +++ b/Test/baseResults/hlsl.promote.vec1.frag.out @@ -0,0 +1,118 @@ +hlsl.promote.vec1.frag +Shader version: 450 +gl_FragCoord origin is upper left +0:? Sequence +0:3 Function Definition: main( (temp 4-component vector of float) +0:3 Function Parameters: +0:? Sequence +0:7 move second child to first child (temp float) +0:7 'f1a' (temp float) +0:7 Construct float (temp float) +0:7 'f1b' (temp 1-component vector of float) +0:8 move second child to first child (temp 1-component vector of float) +0:8 'f1b' (temp 1-component vector of float) +0:8 Construct float (temp 1-component vector of float) +0:8 'f1a' (temp float) +0:11 step (global 3-component vector of float) +0:11 Constant: +0:11 0.000000 +0:11 0.000000 +0:11 0.000000 +0:11 'f3' (temp 3-component vector of float) +0:13 sine (global float) +0:13 Construct float (in float) +0:13 'f1b' (temp 1-component vector of float) +0:15 Sequence +0:15 move second child to first child (temp 4-component vector of float) +0:? '@entryPointOutput' (layout(location=0 ) out 4-component vector of float) +0:? Constant: +0:? 0.000000 +0:? 0.000000 +0:? 0.000000 +0:? 0.000000 +0:15 Branch: Return +0:? Linker Objects +0:? '@entryPointOutput' (layout(location=0 ) out 4-component vector of float) + + +Linked fragment stage: + + +Shader version: 450 +gl_FragCoord origin is upper left +0:? Sequence +0:3 Function Definition: main( (temp 4-component vector of float) +0:3 Function Parameters: +0:? Sequence +0:7 move second child to first child (temp float) +0:7 'f1a' (temp float) +0:7 Construct float (temp float) +0:7 'f1b' (temp 1-component vector of float) +0:8 move second child to first child (temp 1-component vector of float) +0:8 'f1b' (temp 1-component vector of float) +0:8 Construct float (temp 1-component vector of float) +0:8 'f1a' (temp float) +0:11 step (global 3-component vector of float) +0:11 Constant: +0:11 0.000000 +0:11 0.000000 +0:11 0.000000 +0:11 'f3' (temp 3-component vector of float) +0:13 sine (global float) +0:13 Construct float (in float) +0:13 'f1b' (temp 1-component vector of float) +0:15 Sequence +0:15 move second child to first child (temp 4-component vector of float) +0:? '@entryPointOutput' (layout(location=0 ) out 4-component vector of float) +0:? Constant: +0:? 0.000000 +0:? 0.000000 +0:? 0.000000 +0:? 0.000000 +0:15 Branch: Return +0:? Linker Objects +0:? '@entryPointOutput' (layout(location=0 ) out 4-component vector of float) + +// Module Version 10000 +// Generated by (magic number): 80001 +// Id's are bound by 26 + + Capability Shader + 1: ExtInstImport "GLSL.std.450" + MemoryModel Logical GLSL450 + EntryPoint Fragment 4 "main" 23 + ExecutionMode 4 OriginUpperLeft + Name 4 "main" + Name 8 "f1a" + Name 9 "f1b" + Name 16 "f3" + Name 23 "@entryPointOutput" + Decorate 23(@entryPointOutput) Location 0 + 2: TypeVoid + 3: TypeFunction 2 + 6: TypeFloat 32 + 7: TypePointer Function 6(float) + 12: TypeVector 6(float) 3 + 13: 6(float) Constant 0 + 14: 12(fvec3) ConstantComposite 13 13 13 + 15: TypePointer Function 12(fvec3) + 21: TypeVector 6(float) 4 + 22: TypePointer Output 21(fvec4) +23(@entryPointOutput): 22(ptr) Variable Output + 24: 21(fvec4) ConstantComposite 13 13 13 13 + 4(main): 2 Function None 3 + 5: Label + 8(f1a): 7(ptr) Variable Function + 9(f1b): 7(ptr) Variable Function + 16(f3): 15(ptr) Variable Function + 10: 6(float) Load 9(f1b) + Store 8(f1a) 10 + 11: 6(float) Load 8(f1a) + Store 9(f1b) 11 + 17: 12(fvec3) Load 16(f3) + 18: 12(fvec3) ExtInst 1(GLSL.std.450) 48(Step) 14 17 + 19: 6(float) Load 9(f1b) + 20: 6(float) ExtInst 1(GLSL.std.450) 13(Sin) 19 + Store 23(@entryPointOutput) 24 + Return + FunctionEnd diff --git a/Test/hlsl.promote.vec1.frag b/Test/hlsl.promote.vec1.frag new file mode 100644 index 0000000..a674ccb --- /dev/null +++ b/Test/hlsl.promote.vec1.frag @@ -0,0 +1,16 @@ + +float4 main() : SV_Target +{ + float f1a; + float1 f1b; + + f1a = f1b; // convert float1 to float + f1b = f1a; // convert float to float1 + + float3 f3; + step(0.0, f3); + + sin(f1b); // test 1-vectors in intrinsics + + return float4(0,0,0,0); +} diff --git a/glslang/Include/Types.h b/glslang/Include/Types.h index 6c8cb82..8745c7a 100644 --- a/glslang/Include/Types.h +++ b/glslang/Include/Types.h @@ -1271,6 +1271,7 @@ public: virtual TArraySizes& getArraySizes() { assert(arraySizes != nullptr); return *arraySizes; } virtual bool isScalar() const { return ! isVector() && ! isMatrix() && ! isStruct() && ! isArray(); } + virtual bool isScalarOrVec1() const { return isScalar() || vector1; } virtual bool isVector() const { return vectorSize > 1 || vector1; } virtual bool isMatrix() const { return matrixCols ? true : false; } virtual bool isArray() const { return arraySizes != nullptr; } diff --git a/glslang/MachineIndependent/Intermediate.cpp b/glslang/MachineIndependent/Intermediate.cpp index ee102fa..9c2590f 100644 --- a/glslang/MachineIndependent/Intermediate.cpp +++ b/glslang/MachineIndependent/Intermediate.cpp @@ -814,8 +814,10 @@ TIntermTyped* TIntermediate::addShapeConversion(TOperator op, const TType& type, TOperator constructorOp = mapTypeToConstructorOp(type); // scalar -> smeared -> vector, or + // vec1 -> scalar, or // bigger vector -> smaller vector or scalar if ((type.isVector() && node->getType().isScalar()) || + (node->getType().isVector() && node->getVectorSize() == 1 && type.isScalar()) || (node->getVectorSize() > type.getVectorSize() && type.isVector())) return setAggregateOperator(makeAggregate(node), constructorOp, type, node->getLoc()); diff --git a/gtests/Hlsl.FromFile.cpp b/gtests/Hlsl.FromFile.cpp index 17e2133..edd7e4d 100644 --- a/gtests/Hlsl.FromFile.cpp +++ b/gtests/Hlsl.FromFile.cpp @@ -157,6 +157,7 @@ INSTANTIATE_TEST_CASE_P( {"hlsl.pp.line.frag", "main"}, {"hlsl.precise.frag", "main"}, {"hlsl.promote.binary.frag", "main"}, + {"hlsl.promote.vec1.frag", "main"}, {"hlsl.promotions.frag", "main"}, {"hlsl.rw.atomics.frag", "main"}, {"hlsl.rw.bracket.frag", "main"}, diff --git a/hlsl/hlslParseHelper.cpp b/hlsl/hlslParseHelper.cpp index abe027e..31fb0d4 100755 --- a/hlsl/hlslParseHelper.cpp +++ b/hlsl/hlslParseHelper.cpp @@ -4308,8 +4308,8 @@ const TFunction* HlslParseContext::findFunction(const TSourceLoc& loc, const TFu return false; // shapes have to be convertible - if ((from.isScalar() && to.isScalar()) || - (from.isScalar() && to.isVector()) || + if ((from.isScalarOrVec1() && to.isScalarOrVec1()) || + (from.isScalarOrVec1() && to.isVector()) || (from.isVector() && to.isVector() && from.getVectorSize() >= to.getVectorSize())) return true; -- 2.7.4