HLSL: vector shape conversions for all ops: Fix #839. Fix #653. Fix #631.

This commit is contained in:
John Kessenich 2017-04-18 21:07:05 -06:00
parent 2aa12b1c05
commit d5d9ffbdfd
5 changed files with 330 additions and 67 deletions

View File

@ -95,27 +95,66 @@ gl_FragCoord origin is upper left
0:22 Construct vec4 ( temp 4-component vector of float) 0:22 Construct vec4 ( temp 4-component vector of float)
0:22 'f' ( in float) 0:22 'f' ( in float)
0:22 'v' ( temp 4-component vector of float) 0:22 'v' ( temp 4-component vector of float)
0:26 Compare Equal ( temp bool) 0:26 Equal ( temp 4-component vector of bool)
0:26 'f1' ( temp 1-component vector of float) 0:26 Construct vec4 ( temp 4-component vector of float)
0:26 Construct float ( temp 1-component vector of float) 0:26 'f1' ( temp 1-component vector of float)
0:26 'v' ( temp 4-component vector of float) 0:26 'v' ( temp 4-component vector of float)
0:27 Compare Less Than ( temp bool) 0:27 Compare Less Than ( temp 4-component vector of bool)
0:27 Construct float ( temp 1-component vector of float) 0:27 'v' ( temp 4-component vector of float)
0:27 'v' ( temp 4-component vector of float) 0:27 Construct vec4 ( temp 4-component vector of float)
0:27 'f1' ( temp 1-component vector of float) 0:27 'f1' ( temp 1-component vector of float)
0:28 Construct float ( temp float) 0:28 Construct float ( temp float)
0:28 'f1' ( temp 1-component vector of float) 0:28 'f1' ( temp 1-component vector of float)
0:29 Construct vec3 ( temp 3-component vector of float) 0:29 Construct vec3 ( temp 3-component vector of float)
0:29 Construct float ( temp float) 0:29 Construct float ( temp float)
0:29 'f1' ( temp 1-component vector of float) 0:29 'f1' ( temp 1-component vector of float)
0:33 Branch: Return with expression 0:36 right-shift ( temp 3-component vector of uint)
0:33 component-wise multiply ( temp 4-component vector of float) 0:36 Construct uvec3 ( temp 3-component vector of uint)
0:33 'input' ( in 4-component vector of float) 0:36 'ui' ( temp uint)
0:33 Constant: 0:36 'ui3' ( temp 3-component vector of uint)
0:33 3.000000 0:37 right-shift ( temp 3-component vector of uint)
0:33 3.000000 0:37 'ui3' ( temp 3-component vector of uint)
0:33 3.000000 0:37 'ui' ( temp uint)
0:33 3.000000 0:39 multiply second child into first child ( temp 4-component vector of float)
0:39 'v' ( temp 4-component vector of float)
0:39 'f1' ( temp 1-component vector of float)
0:40 multiply second child into first child ( temp 1-component vector of float)
0:40 'f1' ( temp 1-component vector of float)
0:40 Construct float ( temp 1-component vector of float)
0:40 'v' ( temp 4-component vector of float)
0:42 Sequence
0:42 move second child to first child ( temp 3-component vector of float)
0:42 'mixed' ( temp 3-component vector of float)
0:42 component-wise multiply ( temp 3-component vector of float)
0:42 'u' ( temp 3-component vector of float)
0:42 Construct vec3 ( temp 3-component vector of float)
0:42 'v' ( temp 4-component vector of float)
0:43 move second child to first child ( temp float)
0:43 'f' ( in float)
0:43 Construct float ( in float)
0:43 'u' ( temp 3-component vector of float)
0:44 move second child to first child ( temp 1-component vector of float)
0:44 'f1' ( temp 1-component vector of float)
0:44 Construct float ( temp 1-component vector of float)
0:44 'u' ( temp 3-component vector of float)
0:45 Sequence
0:45 move second child to first child ( temp float)
0:45 'sf' ( temp float)
0:45 Construct float ( temp float)
0:45 'v' ( temp 4-component vector of float)
0:46 Sequence
0:46 move second child to first child ( temp 1-component vector of float)
0:46 'sf1' ( temp 1-component vector of float)
0:46 Construct float ( temp 1-component vector of float)
0:46 'v' ( temp 4-component vector of float)
0:48 Branch: Return with expression
0:48 component-wise multiply ( temp 4-component vector of float)
0:48 'input' ( in 4-component vector of float)
0:48 Constant:
0:48 3.000000
0:48 3.000000
0:48 3.000000
0:48 3.000000
0:? Linker Objects 0:? Linker Objects
@ -219,32 +258,71 @@ gl_FragCoord origin is upper left
0:22 Construct vec4 ( temp 4-component vector of float) 0:22 Construct vec4 ( temp 4-component vector of float)
0:22 'f' ( in float) 0:22 'f' ( in float)
0:22 'v' ( temp 4-component vector of float) 0:22 'v' ( temp 4-component vector of float)
0:26 Compare Equal ( temp bool) 0:26 Equal ( temp 4-component vector of bool)
0:26 'f1' ( temp 1-component vector of float) 0:26 Construct vec4 ( temp 4-component vector of float)
0:26 Construct float ( temp 1-component vector of float) 0:26 'f1' ( temp 1-component vector of float)
0:26 'v' ( temp 4-component vector of float) 0:26 'v' ( temp 4-component vector of float)
0:27 Compare Less Than ( temp bool) 0:27 Compare Less Than ( temp 4-component vector of bool)
0:27 Construct float ( temp 1-component vector of float) 0:27 'v' ( temp 4-component vector of float)
0:27 'v' ( temp 4-component vector of float) 0:27 Construct vec4 ( temp 4-component vector of float)
0:27 'f1' ( temp 1-component vector of float) 0:27 'f1' ( temp 1-component vector of float)
0:28 Construct float ( temp float) 0:28 Construct float ( temp float)
0:28 'f1' ( temp 1-component vector of float) 0:28 'f1' ( temp 1-component vector of float)
0:29 Construct vec3 ( temp 3-component vector of float) 0:29 Construct vec3 ( temp 3-component vector of float)
0:29 Construct float ( temp float) 0:29 Construct float ( temp float)
0:29 'f1' ( temp 1-component vector of float) 0:29 'f1' ( temp 1-component vector of float)
0:33 Branch: Return with expression 0:36 right-shift ( temp 3-component vector of uint)
0:33 component-wise multiply ( temp 4-component vector of float) 0:36 Construct uvec3 ( temp 3-component vector of uint)
0:33 'input' ( in 4-component vector of float) 0:36 'ui' ( temp uint)
0:33 Constant: 0:36 'ui3' ( temp 3-component vector of uint)
0:33 3.000000 0:37 right-shift ( temp 3-component vector of uint)
0:33 3.000000 0:37 'ui3' ( temp 3-component vector of uint)
0:33 3.000000 0:37 'ui' ( temp uint)
0:33 3.000000 0:39 multiply second child into first child ( temp 4-component vector of float)
0:39 'v' ( temp 4-component vector of float)
0:39 'f1' ( temp 1-component vector of float)
0:40 multiply second child into first child ( temp 1-component vector of float)
0:40 'f1' ( temp 1-component vector of float)
0:40 Construct float ( temp 1-component vector of float)
0:40 'v' ( temp 4-component vector of float)
0:42 Sequence
0:42 move second child to first child ( temp 3-component vector of float)
0:42 'mixed' ( temp 3-component vector of float)
0:42 component-wise multiply ( temp 3-component vector of float)
0:42 'u' ( temp 3-component vector of float)
0:42 Construct vec3 ( temp 3-component vector of float)
0:42 'v' ( temp 4-component vector of float)
0:43 move second child to first child ( temp float)
0:43 'f' ( in float)
0:43 Construct float ( in float)
0:43 'u' ( temp 3-component vector of float)
0:44 move second child to first child ( temp 1-component vector of float)
0:44 'f1' ( temp 1-component vector of float)
0:44 Construct float ( temp 1-component vector of float)
0:44 'u' ( temp 3-component vector of float)
0:45 Sequence
0:45 move second child to first child ( temp float)
0:45 'sf' ( temp float)
0:45 Construct float ( temp float)
0:45 'v' ( temp 4-component vector of float)
0:46 Sequence
0:46 move second child to first child ( temp 1-component vector of float)
0:46 'sf1' ( temp 1-component vector of float)
0:46 Construct float ( temp 1-component vector of float)
0:46 'v' ( temp 4-component vector of float)
0:48 Branch: Return with expression
0:48 component-wise multiply ( temp 4-component vector of float)
0:48 'input' ( in 4-component vector of float)
0:48 Constant:
0:48 3.000000
0:48 3.000000
0:48 3.000000
0:48 3.000000
0:? Linker Objects 0:? Linker Objects
// Module Version 10000 // Module Version 10000
// Generated by (magic number): 80001 // Generated by (magic number): 80001
// Id's are bound by 88 // Id's are bound by 127
Capability Shader Capability Shader
1: ExtInstImport "GLSL.std.450" 1: ExtInstImport "GLSL.std.450"
@ -263,6 +341,11 @@ gl_FragCoord origin is upper left
Name 34 "MyVal" Name 34 "MyVal"
Name 37 "foo" Name 37 "foo"
Name 70 "f1" Name 70 "f1"
Name 83 "ui"
Name 88 "ui3"
Name 103 "mixed"
Name 115 "sf"
Name 118 "sf1"
2: TypeVoid 2: TypeVoid
3: TypeFunction 2 3: TypeFunction 2
6: TypeFloat 32 6: TypeFloat 32
@ -294,8 +377,11 @@ gl_FragCoord origin is upper left
56: TypeInt 32 0 56: TypeInt 32 0
57: 56(int) Constant 0 57: 56(int) Constant 0
62: TypeVector 41(bool) 4 62: TypeVector 41(bool) 4
83: 6(float) Constant 1077936128 82: TypePointer Function 56(int)
84: 7(fvec4) ConstantComposite 83 83 83 83 85: TypeVector 56(int) 3
87: TypePointer Function 85(ivec3)
122: 6(float) Constant 1077936128
123: 7(fvec4) ConstantComposite 122 122 122 122
4(main): 2 Function None 3 4(main): 2 Function None 3
5: Label 5: Label
Return Return
@ -311,6 +397,11 @@ gl_FragCoord origin is upper left
34(MyVal): 23(ptr) Variable Function 34(MyVal): 23(ptr) Variable Function
37(foo): 23(ptr) Variable Function 37(foo): 23(ptr) Variable Function
70(f1): 9(ptr) Variable Function 70(f1): 9(ptr) Variable Function
83(ui): 82(ptr) Variable Function
88(ui3): 87(ptr) Variable Function
103(mixed): 23(ptr) Variable Function
115(sf): 9(ptr) Variable Function
118(sf1): 9(ptr) Variable Function
Store 15(v) 17 Store 15(v) 17
Store 15(v) 19 Store 15(v) 19
20: 6(float) Load 12(f) 20: 6(float) Load 12(f)
@ -346,17 +437,55 @@ gl_FragCoord origin is upper left
68: 62(bvec4) FOrdNotEqual 66 67 68: 62(bvec4) FOrdNotEqual 66 67
69: 41(bool) Any 68 69: 41(bool) Any 68
71: 6(float) Load 70(f1) 71: 6(float) Load 70(f1)
72: 7(fvec4) Load 15(v) 72: 7(fvec4) CompositeConstruct 71 71 71 71
73: 6(float) CompositeExtract 72 0 73: 7(fvec4) Load 15(v)
74: 41(bool) FOrdEqual 71 73 74: 62(bvec4) FOrdEqual 72 73
75: 7(fvec4) Load 15(v) 75: 7(fvec4) Load 15(v)
76: 6(float) CompositeExtract 75 0 76: 6(float) Load 70(f1)
77: 6(float) Load 70(f1) 77: 7(fvec4) CompositeConstruct 76 76 76 76
78: 41(bool) FOrdLessThan 76 77 78: 62(bvec4) FOrdLessThan 75 77
79: 6(float) Load 70(f1) 79: 6(float) Load 70(f1)
80: 6(float) Load 70(f1) 80: 6(float) Load 70(f1)
81: 22(fvec3) CompositeConstruct 80 80 80 81: 22(fvec3) CompositeConstruct 80 80 80
82: 7(fvec4) Load 11(input) 84: 56(int) Load 83(ui)
85: 7(fvec4) FMul 82 84 86: 85(ivec3) CompositeConstruct 84 84 84
ReturnValue 85 89: 85(ivec3) Load 88(ui3)
90: 85(ivec3) ShiftRightLogical 86 89
91: 85(ivec3) Load 88(ui3)
92: 56(int) Load 83(ui)
93: 85(ivec3) CompositeConstruct 92 92 92
94: 85(ivec3) ShiftRightLogical 91 93
95: 6(float) Load 70(f1)
96: 7(fvec4) Load 15(v)
97: 7(fvec4) CompositeConstruct 95 95 95 95
98: 7(fvec4) FMul 96 97
Store 15(v) 98
99: 7(fvec4) Load 15(v)
100: 6(float) CompositeExtract 99 0
101: 6(float) Load 70(f1)
102: 6(float) FMul 101 100
Store 70(f1) 102
104: 22(fvec3) Load 24(u)
105: 7(fvec4) Load 15(v)
106: 6(float) CompositeExtract 105 0
107: 6(float) CompositeExtract 105 1
108: 6(float) CompositeExtract 105 2
109: 22(fvec3) CompositeConstruct 106 107 108
110: 22(fvec3) FMul 104 109
Store 103(mixed) 110
111: 22(fvec3) Load 24(u)
112: 6(float) CompositeExtract 111 0
Store 12(f) 112
113: 22(fvec3) Load 24(u)
114: 6(float) CompositeExtract 113 0
Store 70(f1) 114
116: 7(fvec4) Load 15(v)
117: 6(float) CompositeExtract 116 0
Store 115(sf) 117
119: 7(fvec4) Load 15(v)
120: 6(float) CompositeExtract 119 0
Store 118(sf1) 120
121: 7(fvec4) Load 11(input)
124: 7(fvec4) FMul 121 123
ReturnValue 124
FunctionEnd FunctionEnd

View File

@ -30,5 +30,20 @@ float4 PixelShaderFunction(float4 input, float f) : COLOR0
const float4 f4 = 3.0; const float4 f4 = 3.0;
uint ui;
uint3 ui3;
ui >> ui3;
ui3 >> ui;
v *= f1;
f1 *= v;
float3 mixed = u * v;
f = u;
f1 = u;
float sf = v;
float1 sf1 = v;
return input * f4; return input * f4;
} }

View File

@ -130,8 +130,9 @@ TIntermTyped* TIntermediate::addBinaryMath(TOperator op, TIntermTyped* left, TIn
} }
// Convert the children's type shape to be compatible. // Convert the children's type shape to be compatible.
right = addShapeConversion(op, left->getType(), right); addBiShapeConversion(op, left, right);
left = addShapeConversion(op, right->getType(), left); if (left == nullptr || right == nullptr)
return nullptr;
// //
// Need a new node holding things together. Make // Need a new node holding things together. Make
@ -238,7 +239,7 @@ TIntermTyped* TIntermediate::addAssign(TOperator op, TIntermTyped* left, TInterm
return nullptr; return nullptr;
// convert shape // convert shape
right = addShapeConversion(op, left->getType(), right); right = addUniShapeConversion(op, left->getType(), right);
// build the node // build the node
TIntermBinary* node = addBinaryNode(op, left, right, loc); TIntermBinary* node = addBinaryNode(op, left, right, loc);
@ -788,7 +789,10 @@ TIntermTyped* TIntermediate::addConversion(TOperator op, const TType& type, TInt
} }
// Convert the node's shape of type for the given type, as allowed by the // Convert the node's shape of type for the given type, as allowed by the
// operation involved: 'op'. // operation involved: 'op'. This is for situations where there is only one
// direction to consider doing the shape conversion.
//
// This implements policy, it call addShapeConversion() for the mechanism.
// //
// Generally, the AST represents allowed GLSL shapes, so this isn't needed // Generally, the AST represents allowed GLSL shapes, so this isn't needed
// for GLSL. Bad shapes are caught in conversion or promotion. // for GLSL. Bad shapes are caught in conversion or promotion.
@ -796,7 +800,7 @@ TIntermTyped* TIntermediate::addConversion(TOperator op, const TType& type, TInt
// Return 'node' if no conversion was done. Promotion handles final shape // Return 'node' if no conversion was done. Promotion handles final shape
// checking. // checking.
// //
TIntermTyped* TIntermediate::addShapeConversion(TOperator op, const TType& type, TIntermTyped* node) TIntermTyped* TIntermediate::addUniShapeConversion(TOperator op, const TType& type, TIntermTyped* node)
{ {
// some source languages don't do this // some source languages don't do this
switch (source) { switch (source) {
@ -809,23 +813,137 @@ TIntermTyped* TIntermediate::addShapeConversion(TOperator op, const TType& type,
// some operations don't do this // some operations don't do this
switch (op) { switch (op) {
case EOpFunctionCall:
case EOpReturn:
break;
case EOpMulAssign:
// want to support vector *= scalar native ops in AST and lower, not smear, similarly for
// matrix *= scalar, etc.
case EOpAddAssign:
case EOpSubAssign:
case EOpDivAssign:
case EOpAndAssign:
case EOpInclusiveOrAssign:
case EOpExclusiveOrAssign:
case EOpRightShiftAssign:
case EOpLeftShiftAssign:
if (node->getVectorSize() == 1)
return node;
break;
case EOpAssign: case EOpAssign:
break;
default:
return node;
}
return addShapeConversion(type, node);
}
// Convert the nodes' shapes to be compatible for the operation 'op'.
//
// This implements policy, it call addShapeConversion() for the mechanism.
//
// Generally, the AST represents allowed GLSL shapes, so this isn't needed
// for GLSL. Bad shapes are caught in conversion or promotion.
//
void TIntermediate::addBiShapeConversion(TOperator op, TIntermTyped*& lhsNode, TIntermTyped*& rhsNode)
{
// some source languages don't do this
switch (source) {
case EShSourceHlsl:
break;
case EShSourceGlsl:
default:
return;
}
// some operations don't do this
// 'break' will mean attempt bidirectional conversion
switch (op) {
case EOpMulAssign:
case EOpAssign:
case EOpAddAssign:
case EOpSubAssign:
case EOpDivAssign:
case EOpAndAssign:
case EOpInclusiveOrAssign:
case EOpExclusiveOrAssign:
case EOpRightShiftAssign:
case EOpLeftShiftAssign:
// switch to unidirectional conversion (the lhs can't change)
rhsNode = addUniShapeConversion(op, lhsNode->getType(), rhsNode);
return;
case EOpAdd:
case EOpSub:
case EOpMul:
case EOpDiv:
// want to support vector * scalar native ops in AST and lower, not smear, similarly for
// matrix * vector, etc.
if (lhsNode->getVectorSize() == 1 || rhsNode->getVectorSize() == 1)
return;
break;
case EOpRightShift:
case EOpLeftShift:
// can natively support the right operand being a scalar and the left a vector,
// but not the reverse
if (rhsNode->getVectorSize() == 1)
return;
break;
case EOpLessThan: case EOpLessThan:
case EOpGreaterThan: case EOpGreaterThan:
case EOpLessThanEqual: case EOpLessThanEqual:
case EOpGreaterThanEqual: case EOpGreaterThanEqual:
case EOpEqual: case EOpEqual:
case EOpNotEqual: case EOpNotEqual:
case EOpFunctionCall:
case EOpReturn:
case EOpLogicalAnd: case EOpLogicalAnd:
case EOpLogicalOr: case EOpLogicalOr:
case EOpLogicalXor: case EOpLogicalXor:
case EOpAnd:
case EOpInclusiveOr:
case EOpExclusiveOr:
break; break;
default: default:
return node; return;
} }
// Do bidirectional conversions
if (lhsNode->getType().isScalarOrVec1() || rhsNode->getType().isScalarOrVec1()) {
if (lhsNode->getType().isScalarOrVec1())
lhsNode = addShapeConversion(rhsNode->getType(), lhsNode);
else
rhsNode = addShapeConversion(lhsNode->getType(), rhsNode);
}
lhsNode = addShapeConversion(rhsNode->getType(), lhsNode);
rhsNode = addShapeConversion(lhsNode->getType(), rhsNode);
}
// Convert the node's shape of type for the given type. It's not necessarily
// an error if they are different and not converted, as some operations accept
// mixed types. Promotion will do final shape checking.
//
// If there is a chance of two nodes, with conversions possible in each direction,
// the policy for what to ask for must be in the caller; this will do what is asked.
//
// Return 'node' if no conversion was done. Promotion handles final shape
// checking.
//
TIntermTyped* TIntermediate::addShapeConversion(const TType& type, TIntermTyped* node)
{
// no conversion needed
if (node->getType() == type)
return node;
// structures and arrays don't change shape, either to or from // structures and arrays don't change shape, either to or from
if (node->getType().isStruct() || node->getType().isArray() || if (node->getType().isStruct() || node->getType().isArray() ||
type.isStruct() || type.isArray()) type.isStruct() || type.isArray())
@ -834,12 +952,12 @@ TIntermTyped* TIntermediate::addShapeConversion(TOperator op, const TType& type,
// The new node that handles the conversion // The new node that handles the conversion
TOperator constructorOp = mapTypeToConstructorOp(type); TOperator constructorOp = mapTypeToConstructorOp(type);
// scalar -> smeared -> vector, or // scalar -> vector or vec1 -> vector or
// vec1 -> scalar, or // vector -> scalar or
// bigger vector -> smaller vector or scalar // bigger vector -> smaller vector
if ((type.isVector() && node->getType().isScalar()) || if ((node->getType().isScalarOrVec1() && type.isVector()) ||
(node->getType().isVector() && node->getVectorSize() == 1 && type.isScalar()) || (node->getType().isVector() && type.isScalar()) ||
(node->getVectorSize() > type.getVectorSize() && type.isVector())) (node->isVector() && type.isVector() && node->getVectorSize() > type.getVectorSize()))
return setAggregateOperator(makeAggregate(node), constructorOp, type, node->getLoc()); return setAggregateOperator(makeAggregate(node), constructorOp, type, node->getLoc());
return node; return node;
@ -1314,9 +1432,9 @@ TIntermTyped* TIntermediate::addSelection(TIntermTyped* cond, TIntermTyped* true
cond->getType().getVectorSize()); cond->getType().getVectorSize());
// smear true/false operations if needed // smear true/false operations if needed
if (trueBlock->getType().isScalarOrVec1()) if (trueBlock->getType().isScalarOrVec1())
trueBlock = addShapeConversion(EOpAssign, targetVectorType, trueBlock); trueBlock = addShapeConversion(targetVectorType, trueBlock);
if (falseBlock->getType().isScalarOrVec1()) if (falseBlock->getType().isScalarOrVec1())
falseBlock = addShapeConversion(EOpAssign, targetVectorType, falseBlock); falseBlock = addShapeConversion(targetVectorType, falseBlock);
// make the mix operation // make the mix operation
TIntermAggregate* mix = makeAggregate(loc); TIntermAggregate* mix = makeAggregate(loc);
@ -2139,8 +2257,6 @@ bool TIntermediate::promoteBinary(TIntermBinary& node)
case EOpLogicalXor: case EOpLogicalXor:
return left->getType() == right->getType(); return left->getType() == right->getType();
// no shifts: they can mix types (scalar int can shift a vector uint, etc.)
case EOpMod: case EOpMod:
case EOpModAssign: case EOpModAssign:
@ -2154,6 +2270,7 @@ bool TIntermediate::promoteBinary(TIntermBinary& node)
case EOpAdd: case EOpAdd:
case EOpSub: case EOpSub:
case EOpDiv: case EOpDiv:
case EOpAddAssign: case EOpAddAssign:
case EOpSubAssign: case EOpSubAssign:
case EOpDivAssign: case EOpDivAssign:
@ -2178,7 +2295,7 @@ bool TIntermediate::promoteBinary(TIntermBinary& node)
return true; return true;
// Finish handling the case, for all ops, where there are two vectors of different sizes // Finish handling the case, for all ops, where there are two vectors of different sizes
if (left->isVector() && right->isVector() && left->getVectorSize() != right->getVectorSize()) if (left->isVector() && right->isVector() && left->getVectorSize() != right->getVectorSize() && right->getVectorSize() > 1)
return false; return false;
// //

View File

@ -243,7 +243,9 @@ public:
TIntermSymbol* addSymbol(const TType&, const TSourceLoc&); TIntermSymbol* addSymbol(const TType&, const TSourceLoc&);
TIntermSymbol* addSymbol(const TIntermSymbol&); TIntermSymbol* addSymbol(const TIntermSymbol&);
TIntermTyped* addConversion(TOperator, const TType&, TIntermTyped*) const; TIntermTyped* addConversion(TOperator, const TType&, TIntermTyped*) const;
TIntermTyped* addShapeConversion(TOperator, const TType&, TIntermTyped*); TIntermTyped* addUniShapeConversion(TOperator, const TType&, TIntermTyped*);
void addBiShapeConversion(TOperator, TIntermTyped*& lhsNode, TIntermTyped*& rhsNode);
TIntermTyped* addShapeConversion(const TType&, TIntermTyped*);
TIntermTyped* addBinaryMath(TOperator, TIntermTyped* left, TIntermTyped* right, TSourceLoc); TIntermTyped* addBinaryMath(TOperator, TIntermTyped* left, TIntermTyped* right, TSourceLoc);
TIntermTyped* addAssign(TOperator op, TIntermTyped* left, TIntermTyped* right, TSourceLoc); TIntermTyped* addAssign(TOperator op, TIntermTyped* left, TIntermTyped* right, TSourceLoc);
TIntermTyped* addIndex(TOperator op, TIntermTyped* base, TIntermTyped* index, TSourceLoc); TIntermTyped* addIndex(TOperator op, TIntermTyped* base, TIntermTyped* index, TSourceLoc);

View File

@ -2087,7 +2087,7 @@ TIntermNode* HlslParseContext::handleReturnValue(const TSourceLoc& loc, TIntermT
} else if (*currentFunctionType != value->getType()) { } else if (*currentFunctionType != value->getType()) {
value = intermediate.addConversion(EOpReturn, *currentFunctionType, value); value = intermediate.addConversion(EOpReturn, *currentFunctionType, value);
if (value && *currentFunctionType != value->getType()) if (value && *currentFunctionType != value->getType())
value = intermediate.addShapeConversion(EOpReturn, *currentFunctionType, value); value = intermediate.addUniShapeConversion(EOpReturn, *currentFunctionType, value);
if (value == nullptr) { if (value == nullptr) {
error(loc, "type does not match, or is not convertible to, the function's return type", "return", ""); error(loc, "type does not match, or is not convertible to, the function's return type", "return", "");
return value; return value;
@ -4105,7 +4105,7 @@ void HlslParseContext::addInputArgumentConversions(const TFunction& function, TI
// convert to the correct type. // convert to the correct type.
TIntermTyped* convArg = intermediate.addConversion(EOpFunctionCall, *function[i].type, arg); TIntermTyped* convArg = intermediate.addConversion(EOpFunctionCall, *function[i].type, arg);
if (convArg != nullptr) if (convArg != nullptr)
convArg = intermediate.addShapeConversion(EOpFunctionCall, *function[i].type, convArg); convArg = intermediate.addUniShapeConversion(EOpFunctionCall, *function[i].type, convArg);
if (convArg != nullptr) if (convArg != nullptr)
setArg(i, convArg); setArg(i, convArg);
else else
@ -6439,7 +6439,7 @@ TIntermNode* HlslParseContext::executeInitializer(const TSourceLoc& loc, TInterm
initializer = intermediate.addConversion(EOpAssign, variable->getType(), initializer); initializer = intermediate.addConversion(EOpAssign, variable->getType(), initializer);
if (initializer != nullptr && variable->getType() != initializer->getType()) if (initializer != nullptr && variable->getType() != initializer->getType())
initializer = intermediate.addShapeConversion(EOpAssign, variable->getType(), initializer); initializer = intermediate.addUniShapeConversion(EOpAssign, variable->getType(), initializer);
if (initializer == nullptr || !initializer->getAsConstantUnion() || if (initializer == nullptr || !initializer->getAsConstantUnion() ||
variable->getType() != initializer->getType()) { variable->getType() != initializer->getType()) {
error(loc, "non-matching or non-convertible constant type for const initializer", error(loc, "non-matching or non-convertible constant type for const initializer",