Commit 2d46e73b by John Kessenich Committed by GitHub

Merge pull request #931 from LoopDawg/scalar-mat-assign

HLSL: fix several issues in mat construction from scalars
parents f7cd88a2 e2713125
hlsl.intrinsics.negative.frag
ERROR: 0:10: 'determinant' : no matching overloaded function found
ERROR: 0:10: 'determinant' : ambiguous best function under implicit type conversion
ERROR: 0:25: 'normalize' : ambiguous best function under implicit type conversion
ERROR: 0:26: 'reflect' : ambiguous best function under implicit type conversion
ERROR: 0:27: 'refract' : ambiguous best function under implicit type conversion
ERROR: 0:28: 'refract' : no matching overloaded function found
ERROR: 0:30: 'transpose' : no matching overloaded function found
ERROR: 0:30: 'transpose' : ambiguous best function under implicit type conversion
ERROR: 0:39: 'GetRenderTargetSamplePosition' : no matching overloaded function found
ERROR: 0:46: 'asdouble' : double2 conversion not implemented
ERROR: 0:47: 'CheckAccessFullyMapped' : no matching overloaded function found
......@@ -104,8 +104,9 @@ ERROR: node is still EOpNull!
0:9 0 (const int)
0:9 Constant:
0:9 3 (const int)
0:10 Constant:
0:10 0.000000
0:10 determinant ( temp float)
ERROR: node is still EOpNull!
0:10 'inF0' ( in float)
0:12 direct index ( temp float)
0:12 unpackHalf2x16 ( temp 2-component vector of float)
0:12 Convert float to uint ( temp uint)
......@@ -150,8 +151,9 @@ ERROR: node is still EOpNull!
0:29 bitFieldReverse ( temp uint)
0:29 Convert float to uint ( temp uint)
0:29 'inF0' ( in float)
0:30 Constant:
0:30 0.000000
0:30 transpose ( temp 1X1 matrix of float)
ERROR: node is still EOpNull!
0:30 'inF0' ( in float)
0:32 Branch: Return with expression
0:32 Constant:
0:32 0.000000
......@@ -565,8 +567,9 @@ ERROR: node is still EOpNull!
0:9 0 (const int)
0:9 Constant:
0:9 3 (const int)
0:10 Constant:
0:10 0.000000
0:10 determinant ( temp float)
ERROR: node is still EOpNull!
0:10 'inF0' ( in float)
0:12 direct index ( temp float)
0:12 unpackHalf2x16 ( temp 2-component vector of float)
0:12 Convert float to uint ( temp uint)
......@@ -611,8 +614,9 @@ ERROR: node is still EOpNull!
0:29 bitFieldReverse ( temp uint)
0:29 Convert float to uint ( temp uint)
0:29 'inF0' ( in float)
0:30 Constant:
0:30 0.000000
0:30 transpose ( temp 1X1 matrix of float)
ERROR: node is still EOpNull!
0:30 'inF0' ( in float)
0:32 Branch: Return with expression
0:32 Constant:
0:32 0.000000
......
......@@ -49,11 +49,11 @@ gl_FragCoord origin is upper left
0:16 'h23' ( temp 2X3 matrix of float)
0:16 Constant:
0:16 4.900000
0:16 0.000000
0:16 0.000000
0:16 0.000000
0:16 4.900000
0:16 0.000000
0:16 4.900000
0:16 4.900000
0:16 4.900000
0:16 4.900000
0:27 Branch: Return with expression
0:27 Construct vec4 ( temp 4-component vector of float)
0:27 add ( temp float)
......@@ -133,11 +133,11 @@ gl_FragCoord origin is upper left
0:16 'h23' ( temp 2X3 matrix of float)
0:16 Constant:
0:16 4.900000
0:16 0.000000
0:16 0.000000
0:16 0.000000
0:16 4.900000
0:16 0.000000
0:16 4.900000
0:16 4.900000
0:16 4.900000
0:16 4.900000
0:27 Branch: Return with expression
0:27 Construct vec4 ( temp 4-component vector of float)
0:27 add ( temp float)
......@@ -165,12 +165,12 @@ gl_FragCoord origin is upper left
// Module Version 10000
// Generated by (magic number): 80001
// Id's are bound by 61
// Id's are bound by 60
Capability Shader
1: ExtInstImport "GLSL.std.450"
MemoryModel Logical GLSL450
EntryPoint Fragment 4 "main" 59
EntryPoint Fragment 4 "main" 58
ExecutionMode 4 OriginUpperLeft
Source HLSL 500
Name 4 "main"
......@@ -182,8 +182,8 @@ gl_FragCoord origin is upper left
Name 27 "h4"
Name 32 "h22"
Name 38 "h23"
Name 59 "@entryPointOutput"
Decorate 59(@entryPointOutput) Location 0
Name 58 "@entryPointOutput"
Decorate 58(@entryPointOutput) Location 0
2: TypeVoid
3: TypeFunction 2
6: TypeFloat 32
......@@ -211,20 +211,19 @@ gl_FragCoord origin is upper left
36: TypeMatrix 21(fvec3) 2
37: TypePointer Function 36
39: 6(float) Constant 1084017869
40: 21(fvec3) ConstantComposite 39 13 13
41: 21(fvec3) ConstantComposite 13 39 13
42: 36 ConstantComposite 40 41
43: TypeInt 32 1
44: 43(int) Constant 0
45: TypeInt 32 0
46: 45(int) Constant 0
49: 45(int) Constant 1
58: TypePointer Output 7(fvec4)
59(@entryPointOutput): 58(ptr) Variable Output
40: 21(fvec3) ConstantComposite 39 39 39
41: 36 ConstantComposite 40 40
42: TypeInt 32 1
43: 42(int) Constant 0
44: TypeInt 32 0
45: 44(int) Constant 0
48: 44(int) Constant 1
57: TypePointer Output 7(fvec4)
58(@entryPointOutput): 57(ptr) Variable Output
4(main): 2 Function None 3
5: Label
60: 7(fvec4) FunctionCall 9(@main()
Store 59(@entryPointOutput) 60
59: 7(fvec4) FunctionCall 9(@main()
Store 58(@entryPointOutput) 59
Return
FunctionEnd
9(@main(): 7(fvec4) Function None 8
......@@ -242,14 +241,14 @@ gl_FragCoord origin is upper left
Store 23(h3) 25
Store 27(h4) 29
Store 32(h22) 35
Store 38(h23) 42
47: 11(ptr) AccessChain 38(h23) 44 46
48: 6(float) Load 47
50: 11(ptr) AccessChain 27(h4) 49
51: 6(float) Load 50
52: 6(float) FAdd 48 51
53: 6(float) Load 12(h0)
54: 6(float) FAdd 52 53
55: 7(fvec4) CompositeConstruct 54 54 54 54
ReturnValue 55
Store 38(h23) 41
46: 11(ptr) AccessChain 38(h23) 43 45
47: 6(float) Load 46
49: 11(ptr) AccessChain 27(h4) 48
50: 6(float) Load 49
51: 6(float) FAdd 47 50
52: 6(float) Load 12(h0)
53: 6(float) FAdd 51 52
54: 7(fvec4) CompositeConstruct 53 53 53 53
ReturnValue 54
FunctionEnd
void Fn1(float4x4 p) { }
float4 main() : SV_TARGET
{
const float4x4 mat1c = 0.20;
const float4x4 mat2c = {2, 2.1, 2.2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
const float4x4 mat3c = (float4x4)float1(0.1);
float4x4 mat1 = 0.25;
float4x4 mat2 = {3, 3.1, 3.2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
float4x4 mat3 = (float4x4)0.375;
// float4x4 mat5 = (float4x4)Fn2(); // TODO: enable when compex rvalue handling is in place
float4x4 mat4;
mat4 = 0.75;
mat4 = float4x4(4, 4.1, 4.2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
mat4 = (float4x4)0.5;
mat4 *= 0.75;
mat4 += 0.75;
mat4 -= 0.5;
mat4 /= 2.0;
Fn1(5.0); // test calling fn accepting matrix with scalar type
return mat1c[0] + mat3c[0] + mat1[1] + mat4[2];
}
......@@ -1043,6 +1043,32 @@ TIntermTyped* TIntermediate::addShapeConversion(const TType& type, TIntermTyped*
// The new node that handles the conversion
TOperator constructorOp = mapTypeToConstructorOp(type);
// HLSL has custom semantics for scalar->mat shape conversions.
if (source == EShSourceHlsl) {
if (node->getType().isScalarOrVec1() && type.isMatrix()) {
// HLSL semantics: the scalar (or vec1) is replicated to every component of the matrix. Left to its
// own devices, the constructor from a scalar would populate the diagonal. This forces replication
// to every matrix element.
// Note that if the node is complex (e.g, a function call), we don't want to duplicate it here
// repeatedly, so we copy it to a temp, then use the temp.
const int matSize = type.getMatrixRows() * type.getMatrixCols();
TIntermAggregate* rhsAggregate = new TIntermAggregate();
const bool isSimple = (node->getAsSymbolNode() != nullptr) || (node->getAsConstantUnion() != nullptr);
if (!isSimple) {
assert(0); // TODO: use node replicator service when available.
}
for (int x=0; x<matSize; ++x)
rhsAggregate->getSequence().push_back(node);
return setAggregateOperator(rhsAggregate, constructorOp, type, node->getLoc());
}
}
// scalar -> vector or vec1 -> vector or
// vector -> scalar or
// bigger vector -> smaller vector
......
......@@ -285,6 +285,7 @@ INSTANTIATE_TEST_CASE_P(
{"hlsl.max.frag", "PixelShaderFunction"},
{"hlsl.precedence.frag", "PixelShaderFunction"},
{"hlsl.precedence2.frag", "PixelShaderFunction"},
{"hlsl.scalar2matrix.frag", "main"},
{"hlsl.semantic.geom", "main"},
{"hlsl.semantic.vert", "main"},
{"hlsl.scope.frag", "PixelShaderFunction"},
......
......@@ -6616,6 +6616,7 @@ const TFunction* HlslParseContext::findFunction(const TSourceLoc& loc, TFunction
// shapes have to be convertible
if ((from.isScalarOrVec1() && to.isScalarOrVec1()) ||
(from.isScalarOrVec1() && to.isVector()) ||
(from.isScalarOrVec1() && to.isMatrix()) ||
(from.isVector() && to.isVector() && from.getVectorSize() >= to.getVectorSize()))
return true;
......@@ -7393,8 +7394,15 @@ TIntermTyped* HlslParseContext::addConstructor(const TSourceLoc& loc, TIntermTyp
newNode = constructAggregate(node, elementType, 1, node->getLoc());
else if (op == EOpConstructStruct)
newNode = constructAggregate(node, *(*memberTypes).type, 1, node->getLoc());
else
else {
// shape conversion for matrix constructor from scalar. HLSL semantics are: scalar
// is replicated into every element of the matrix (not just the diagnonal), so
// that is handled specially here.
if (type.isMatrix() && node->getType().isScalarOrVec1())
node = intermediate.addShapeConversion(type, node);
newNode = constructBuiltIn(type, op, node, node->getLoc(), false);
}
if (newNode && (type.isArray() || op == EOpConstructStruct))
newNode = intermediate.setAggregateOperator(newNode, EOpConstructStruct, type, loc);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment