HLSL: Fix #805: Support cast of scalars to structures.

Somewhat complex due to recognizing a general scalar, but not
replicating it for each member to avoid side effects.
This commit is contained in:
John Kessenich 2017-04-04 11:47:42 -06:00
parent 5ce1e4aff8
commit 82460b5e21
6 changed files with 617 additions and 40 deletions

View File

@ -0,0 +1,501 @@
hlsl.scalarCast.vert
Shader version: 450
0:? Sequence
0:5 Function Definition: r0( ( temp structure{ temp 4-component vector of float position, temp 2-component vector of float texCoord})
0:5 Function Parameters:
0:? Sequence
0:7 Branch: Return with expression
0:7 Constant:
0:7 2.000000
0:7 2.000000
0:7 2.000000
0:7 2.000000
0:7 2.000000
0:7 2.000000
0:9 Function Definition: r1( ( temp structure{ temp 4-component vector of float position, temp 2-component vector of float texCoord})
0:9 Function Parameters:
0:? Sequence
0:11 Branch: Return with expression
0:11 Constant:
0:11 3.000000
0:11 3.000000
0:11 3.000000
0:11 3.000000
0:11 3.000000
0:11 3.000000
0:13 Function Definition: r2( ( temp structure{ temp 4-component vector of float position, temp 2-component vector of float texCoord})
0:13 Function Parameters:
0:? Sequence
0:15 Branch: Return with expression
0:15 Constant:
0:15 0.909297
0:15 0.909297
0:15 0.909297
0:15 0.909297
0:15 0.909297
0:15 0.909297
0:17 Function Definition: r3( ( temp structure{ temp 4-component vector of float position, temp 2-component vector of float texCoord})
0:17 Function Parameters:
0:? Sequence
0:18 Sequence
0:18 move second child to first child ( temp float)
0:18 'f' ( temp float)
0:18 Constant:
0:18 2.000000
0:19 Branch: Return with expression
0:19 Construct structure ( temp structure{ temp 4-component vector of float position, temp 2-component vector of float texCoord})
0:19 Construct vec4 ( temp 4-component vector of float)
0:19 'f' ( temp float)
0:19 'f' ( temp float)
0:19 'f' ( temp float)
0:19 'f' ( temp float)
0:19 Construct vec2 ( temp 2-component vector of float)
0:19 'f' ( temp float)
0:19 'f' ( temp float)
0:21 Function Definition: r4( ( temp structure{ temp 4-component vector of float position, temp 2-component vector of float texCoord})
0:21 Function Parameters:
0:? Sequence
0:22 Sequence
0:22 move second child to first child ( temp float)
0:22 'f' ( temp float)
0:22 Constant:
0:22 2.000000
0:23 Branch: Return with expression
0:23 Comma ( temp structure{ temp 4-component vector of float position, temp 2-component vector of float texCoord})
0:23 move second child to first child ( temp float)
0:23 'scalarCopy' ( temp float)
0:23 add ( temp float)
0:23 'f' ( temp float)
0:23 Constant:
0:23 1.000000
0:23 Construct structure ( temp structure{ temp 4-component vector of float position, temp 2-component vector of float texCoord})
0:23 Construct vec4 ( temp 4-component vector of float)
0:23 'scalarCopy' ( temp float)
0:23 'scalarCopy' ( temp float)
0:23 'scalarCopy' ( temp float)
0:23 'scalarCopy' ( temp float)
0:23 Construct vec2 ( temp 2-component vector of float)
0:23 'scalarCopy' ( temp float)
0:23 'scalarCopy' ( temp float)
0:25 Function Definition: r5( ( temp structure{ temp 4-component vector of float position, temp 2-component vector of float texCoord})
0:25 Function Parameters:
0:? Sequence
0:26 Sequence
0:26 move second child to first child ( temp float)
0:26 'f' ( temp float)
0:26 Constant:
0:26 2.000000
0:27 Branch: Return with expression
0:27 Comma ( temp structure{ temp 4-component vector of float position, temp 2-component vector of float texCoord})
0:27 move second child to first child ( temp float)
0:27 'scalarCopy' ( temp float)
0:27 sine ( temp float)
0:27 'f' ( temp float)
0:27 Construct structure ( temp structure{ temp 4-component vector of float position, temp 2-component vector of float texCoord})
0:27 Construct vec4 ( temp 4-component vector of float)
0:27 'scalarCopy' ( temp float)
0:27 'scalarCopy' ( temp float)
0:27 'scalarCopy' ( temp float)
0:27 'scalarCopy' ( temp float)
0:27 Construct vec2 ( temp 2-component vector of float)
0:27 'scalarCopy' ( temp float)
0:27 'scalarCopy' ( temp float)
0:29 Function Definition: @main( ( temp structure{ temp 4-component vector of float position, temp 2-component vector of float texCoord})
0:29 Function Parameters:
0:? Sequence
0:30 Sequence
0:30 move second child to first child ( temp structure{ temp 4-component vector of float position, temp 2-component vector of float texCoord})
0:30 'v0' ( temp structure{ temp 4-component vector of float position, temp 2-component vector of float texCoord})
0:30 Function Call: r0( ( temp structure{ temp 4-component vector of float position, temp 2-component vector of float texCoord})
0:31 Sequence
0:31 move second child to first child ( temp structure{ temp 4-component vector of float position, temp 2-component vector of float texCoord})
0:31 'v1' ( temp structure{ temp 4-component vector of float position, temp 2-component vector of float texCoord})
0:31 Function Call: r1( ( temp structure{ temp 4-component vector of float position, temp 2-component vector of float texCoord})
0:32 Sequence
0:32 move second child to first child ( temp structure{ temp 4-component vector of float position, temp 2-component vector of float texCoord})
0:32 'v2' ( temp structure{ temp 4-component vector of float position, temp 2-component vector of float texCoord})
0:32 Function Call: r2( ( temp structure{ temp 4-component vector of float position, temp 2-component vector of float texCoord})
0:33 Sequence
0:33 move second child to first child ( temp structure{ temp 4-component vector of float position, temp 2-component vector of float texCoord})
0:33 'v3' ( temp structure{ temp 4-component vector of float position, temp 2-component vector of float texCoord})
0:33 Function Call: r3( ( temp structure{ temp 4-component vector of float position, temp 2-component vector of float texCoord})
0:34 Sequence
0:34 move second child to first child ( temp structure{ temp 4-component vector of float position, temp 2-component vector of float texCoord})
0:34 'v4' ( temp structure{ temp 4-component vector of float position, temp 2-component vector of float texCoord})
0:34 Function Call: r4( ( temp structure{ temp 4-component vector of float position, temp 2-component vector of float texCoord})
0:35 Sequence
0:35 move second child to first child ( temp structure{ temp 4-component vector of float position, temp 2-component vector of float texCoord})
0:35 'v5' ( temp structure{ temp 4-component vector of float position, temp 2-component vector of float texCoord})
0:35 Function Call: r5( ( temp structure{ temp 4-component vector of float position, temp 2-component vector of float texCoord})
0:36 Branch: Return with expression
0:36 Constant:
0:36 1.000000
0:36 1.000000
0:36 1.000000
0:36 1.000000
0:36 1.000000
0:36 1.000000
0:29 Function Definition: main( ( temp void)
0:29 Function Parameters:
0:? Sequence
0:29 Sequence
0:29 move second child to first child ( temp structure{ temp 4-component vector of float position, temp 2-component vector of float texCoord})
0:29 'flattenTemp' ( temp structure{ temp 4-component vector of float position, temp 2-component vector of float texCoord})
0:29 Function Call: @main( ( temp structure{ temp 4-component vector of float position, temp 2-component vector of float texCoord})
0:29 move second child to first child ( temp 4-component vector of float)
0:? '@entryPointOutput_position' ( out 4-component vector of float Position)
0:29 position: direct index for structure ( temp 4-component vector of float)
0:29 'flattenTemp' ( temp structure{ temp 4-component vector of float position, temp 2-component vector of float texCoord})
0:29 Constant:
0:29 0 (const int)
0:29 move second child to first child ( temp 2-component vector of float)
0:29 texCoord: direct index for structure ( temp 2-component vector of float)
0:29 '@entryPointOutput' (layout( location=0) out structure{ temp 2-component vector of float texCoord})
0:29 Constant:
0:29 0 (const int)
0:29 texCoord: direct index for structure ( temp 2-component vector of float)
0:29 'flattenTemp' ( temp structure{ temp 4-component vector of float position, temp 2-component vector of float texCoord})
0:29 Constant:
0:29 1 (const int)
0:? Linker Objects
0:? '@entryPointOutput' (layout( location=0) out structure{ temp 2-component vector of float texCoord})
Linked vertex stage:
Shader version: 450
0:? Sequence
0:5 Function Definition: r0( ( temp structure{ temp 4-component vector of float position, temp 2-component vector of float texCoord})
0:5 Function Parameters:
0:? Sequence
0:7 Branch: Return with expression
0:7 Constant:
0:7 2.000000
0:7 2.000000
0:7 2.000000
0:7 2.000000
0:7 2.000000
0:7 2.000000
0:9 Function Definition: r1( ( temp structure{ temp 4-component vector of float position, temp 2-component vector of float texCoord})
0:9 Function Parameters:
0:? Sequence
0:11 Branch: Return with expression
0:11 Constant:
0:11 3.000000
0:11 3.000000
0:11 3.000000
0:11 3.000000
0:11 3.000000
0:11 3.000000
0:13 Function Definition: r2( ( temp structure{ temp 4-component vector of float position, temp 2-component vector of float texCoord})
0:13 Function Parameters:
0:? Sequence
0:15 Branch: Return with expression
0:15 Constant:
0:15 0.909297
0:15 0.909297
0:15 0.909297
0:15 0.909297
0:15 0.909297
0:15 0.909297
0:17 Function Definition: r3( ( temp structure{ temp 4-component vector of float position, temp 2-component vector of float texCoord})
0:17 Function Parameters:
0:? Sequence
0:18 Sequence
0:18 move second child to first child ( temp float)
0:18 'f' ( temp float)
0:18 Constant:
0:18 2.000000
0:19 Branch: Return with expression
0:19 Construct structure ( temp structure{ temp 4-component vector of float position, temp 2-component vector of float texCoord})
0:19 Construct vec4 ( temp 4-component vector of float)
0:19 'f' ( temp float)
0:19 'f' ( temp float)
0:19 'f' ( temp float)
0:19 'f' ( temp float)
0:19 Construct vec2 ( temp 2-component vector of float)
0:19 'f' ( temp float)
0:19 'f' ( temp float)
0:21 Function Definition: r4( ( temp structure{ temp 4-component vector of float position, temp 2-component vector of float texCoord})
0:21 Function Parameters:
0:? Sequence
0:22 Sequence
0:22 move second child to first child ( temp float)
0:22 'f' ( temp float)
0:22 Constant:
0:22 2.000000
0:23 Branch: Return with expression
0:23 Comma ( temp structure{ temp 4-component vector of float position, temp 2-component vector of float texCoord})
0:23 move second child to first child ( temp float)
0:23 'scalarCopy' ( temp float)
0:23 add ( temp float)
0:23 'f' ( temp float)
0:23 Constant:
0:23 1.000000
0:23 Construct structure ( temp structure{ temp 4-component vector of float position, temp 2-component vector of float texCoord})
0:23 Construct vec4 ( temp 4-component vector of float)
0:23 'scalarCopy' ( temp float)
0:23 'scalarCopy' ( temp float)
0:23 'scalarCopy' ( temp float)
0:23 'scalarCopy' ( temp float)
0:23 Construct vec2 ( temp 2-component vector of float)
0:23 'scalarCopy' ( temp float)
0:23 'scalarCopy' ( temp float)
0:25 Function Definition: r5( ( temp structure{ temp 4-component vector of float position, temp 2-component vector of float texCoord})
0:25 Function Parameters:
0:? Sequence
0:26 Sequence
0:26 move second child to first child ( temp float)
0:26 'f' ( temp float)
0:26 Constant:
0:26 2.000000
0:27 Branch: Return with expression
0:27 Comma ( temp structure{ temp 4-component vector of float position, temp 2-component vector of float texCoord})
0:27 move second child to first child ( temp float)
0:27 'scalarCopy' ( temp float)
0:27 sine ( temp float)
0:27 'f' ( temp float)
0:27 Construct structure ( temp structure{ temp 4-component vector of float position, temp 2-component vector of float texCoord})
0:27 Construct vec4 ( temp 4-component vector of float)
0:27 'scalarCopy' ( temp float)
0:27 'scalarCopy' ( temp float)
0:27 'scalarCopy' ( temp float)
0:27 'scalarCopy' ( temp float)
0:27 Construct vec2 ( temp 2-component vector of float)
0:27 'scalarCopy' ( temp float)
0:27 'scalarCopy' ( temp float)
0:29 Function Definition: @main( ( temp structure{ temp 4-component vector of float position, temp 2-component vector of float texCoord})
0:29 Function Parameters:
0:? Sequence
0:30 Sequence
0:30 move second child to first child ( temp structure{ temp 4-component vector of float position, temp 2-component vector of float texCoord})
0:30 'v0' ( temp structure{ temp 4-component vector of float position, temp 2-component vector of float texCoord})
0:30 Function Call: r0( ( temp structure{ temp 4-component vector of float position, temp 2-component vector of float texCoord})
0:31 Sequence
0:31 move second child to first child ( temp structure{ temp 4-component vector of float position, temp 2-component vector of float texCoord})
0:31 'v1' ( temp structure{ temp 4-component vector of float position, temp 2-component vector of float texCoord})
0:31 Function Call: r1( ( temp structure{ temp 4-component vector of float position, temp 2-component vector of float texCoord})
0:32 Sequence
0:32 move second child to first child ( temp structure{ temp 4-component vector of float position, temp 2-component vector of float texCoord})
0:32 'v2' ( temp structure{ temp 4-component vector of float position, temp 2-component vector of float texCoord})
0:32 Function Call: r2( ( temp structure{ temp 4-component vector of float position, temp 2-component vector of float texCoord})
0:33 Sequence
0:33 move second child to first child ( temp structure{ temp 4-component vector of float position, temp 2-component vector of float texCoord})
0:33 'v3' ( temp structure{ temp 4-component vector of float position, temp 2-component vector of float texCoord})
0:33 Function Call: r3( ( temp structure{ temp 4-component vector of float position, temp 2-component vector of float texCoord})
0:34 Sequence
0:34 move second child to first child ( temp structure{ temp 4-component vector of float position, temp 2-component vector of float texCoord})
0:34 'v4' ( temp structure{ temp 4-component vector of float position, temp 2-component vector of float texCoord})
0:34 Function Call: r4( ( temp structure{ temp 4-component vector of float position, temp 2-component vector of float texCoord})
0:35 Sequence
0:35 move second child to first child ( temp structure{ temp 4-component vector of float position, temp 2-component vector of float texCoord})
0:35 'v5' ( temp structure{ temp 4-component vector of float position, temp 2-component vector of float texCoord})
0:35 Function Call: r5( ( temp structure{ temp 4-component vector of float position, temp 2-component vector of float texCoord})
0:36 Branch: Return with expression
0:36 Constant:
0:36 1.000000
0:36 1.000000
0:36 1.000000
0:36 1.000000
0:36 1.000000
0:36 1.000000
0:29 Function Definition: main( ( temp void)
0:29 Function Parameters:
0:? Sequence
0:29 Sequence
0:29 move second child to first child ( temp structure{ temp 4-component vector of float position, temp 2-component vector of float texCoord})
0:29 'flattenTemp' ( temp structure{ temp 4-component vector of float position, temp 2-component vector of float texCoord})
0:29 Function Call: @main( ( temp structure{ temp 4-component vector of float position, temp 2-component vector of float texCoord})
0:29 move second child to first child ( temp 4-component vector of float)
0:? '@entryPointOutput_position' ( out 4-component vector of float Position)
0:29 position: direct index for structure ( temp 4-component vector of float)
0:29 'flattenTemp' ( temp structure{ temp 4-component vector of float position, temp 2-component vector of float texCoord})
0:29 Constant:
0:29 0 (const int)
0:29 move second child to first child ( temp 2-component vector of float)
0:29 texCoord: direct index for structure ( temp 2-component vector of float)
0:29 '@entryPointOutput' (layout( location=0) out structure{ temp 2-component vector of float texCoord})
0:29 Constant:
0:29 0 (const int)
0:29 texCoord: direct index for structure ( temp 2-component vector of float)
0:29 'flattenTemp' ( temp structure{ temp 4-component vector of float position, temp 2-component vector of float texCoord})
0:29 Constant:
0:29 1 (const int)
0:? Linker Objects
0:? '@entryPointOutput' (layout( location=0) out structure{ temp 2-component vector of float texCoord})
// Module Version 10000
// Generated by (magic number): 80001
// Id's are bound by 123
Capability Shader
1: ExtInstImport "GLSL.std.450"
MemoryModel Logical GLSL450
EntryPoint Vertex 4 "main" 108 116
Name 4 "main"
Name 9 "VertexOut"
MemberName 9(VertexOut) 0 "position"
MemberName 9(VertexOut) 1 "texCoord"
Name 11 "r0("
Name 13 "r1("
Name 15 "r2("
Name 17 "r3("
Name 19 "r4("
Name 21 "r5("
Name 23 "@main("
Name 44 "f"
Name 56 "f"
Name 57 "scalarCopy"
Name 72 "f"
Name 73 "scalarCopy"
Name 88 "v0"
Name 90 "v1"
Name 92 "v2"
Name 94 "v3"
Name 96 "v4"
Name 98 "v5"
Name 105 "flattenTemp"
Name 108 "@entryPointOutput_position"
Name 114 "VertexOut"
MemberName 114(VertexOut) 0 "texCoord"
Name 116 "@entryPointOutput"
Decorate 108(@entryPointOutput_position) BuiltIn Position
Decorate 116(@entryPointOutput) Location 0
2: TypeVoid
3: TypeFunction 2
6: TypeFloat 32
7: TypeVector 6(float) 4
8: TypeVector 6(float) 2
9(VertexOut): TypeStruct 7(fvec4) 8(fvec2)
10: TypeFunction 9(VertexOut)
25: 6(float) Constant 1073741824
26: 7(fvec4) ConstantComposite 25 25 25 25
27: 8(fvec2) ConstantComposite 25 25
28:9(VertexOut) ConstantComposite 26 27
31: 6(float) Constant 1077936128
32: 7(fvec4) ConstantComposite 31 31 31 31
33: 8(fvec2) ConstantComposite 31 31
34:9(VertexOut) ConstantComposite 32 33
37: 6(float) Constant 1063831479
38: 7(fvec4) ConstantComposite 37 37 37 37
39: 8(fvec2) ConstantComposite 37 37
40:9(VertexOut) ConstantComposite 38 39
43: TypePointer Function 6(float)
59: 6(float) Constant 1065353216
87: TypePointer Function 9(VertexOut)
100: 7(fvec4) ConstantComposite 59 59 59 59
101: 8(fvec2) ConstantComposite 59 59
102:9(VertexOut) ConstantComposite 100 101
107: TypePointer Output 7(fvec4)
108(@entryPointOutput_position): 107(ptr) Variable Output
109: TypeInt 32 1
110: 109(int) Constant 0
111: TypePointer Function 7(fvec4)
114(VertexOut): TypeStruct 8(fvec2)
115: TypePointer Output 114(VertexOut)
116(@entryPointOutput): 115(ptr) Variable Output
117: 109(int) Constant 1
118: TypePointer Function 8(fvec2)
121: TypePointer Output 8(fvec2)
4(main): 2 Function None 3
5: Label
105(flattenTemp): 87(ptr) Variable Function
106:9(VertexOut) FunctionCall 23(@main()
Store 105(flattenTemp) 106
112: 111(ptr) AccessChain 105(flattenTemp) 110
113: 7(fvec4) Load 112
Store 108(@entryPointOutput_position) 113
119: 118(ptr) AccessChain 105(flattenTemp) 117
120: 8(fvec2) Load 119
122: 121(ptr) AccessChain 116(@entryPointOutput) 110
Store 122 120
Return
FunctionEnd
11(r0():9(VertexOut) Function None 10
12: Label
ReturnValue 28
FunctionEnd
13(r1():9(VertexOut) Function None 10
14: Label
ReturnValue 34
FunctionEnd
15(r2():9(VertexOut) Function None 10
16: Label
ReturnValue 40
FunctionEnd
17(r3():9(VertexOut) Function None 10
18: Label
44(f): 43(ptr) Variable Function
Store 44(f) 25
45: 6(float) Load 44(f)
46: 6(float) Load 44(f)
47: 6(float) Load 44(f)
48: 6(float) Load 44(f)
49: 7(fvec4) CompositeConstruct 45 46 47 48
50: 6(float) Load 44(f)
51: 6(float) Load 44(f)
52: 8(fvec2) CompositeConstruct 50 51
53:9(VertexOut) CompositeConstruct 49 52
ReturnValue 53
FunctionEnd
19(r4():9(VertexOut) Function None 10
20: Label
56(f): 43(ptr) Variable Function
57(scalarCopy): 43(ptr) Variable Function
Store 56(f) 25
58: 6(float) Load 56(f)
60: 6(float) FAdd 58 59
Store 57(scalarCopy) 60
61: 6(float) Load 57(scalarCopy)
62: 6(float) Load 57(scalarCopy)
63: 6(float) Load 57(scalarCopy)
64: 6(float) Load 57(scalarCopy)
65: 7(fvec4) CompositeConstruct 61 62 63 64
66: 6(float) Load 57(scalarCopy)
67: 6(float) Load 57(scalarCopy)
68: 8(fvec2) CompositeConstruct 66 67
69:9(VertexOut) CompositeConstruct 65 68
ReturnValue 69
FunctionEnd
21(r5():9(VertexOut) Function None 10
22: Label
72(f): 43(ptr) Variable Function
73(scalarCopy): 43(ptr) Variable Function
Store 72(f) 25
74: 6(float) Load 72(f)
75: 6(float) ExtInst 1(GLSL.std.450) 13(Sin) 74
Store 73(scalarCopy) 75
76: 6(float) Load 73(scalarCopy)
77: 6(float) Load 73(scalarCopy)
78: 6(float) Load 73(scalarCopy)
79: 6(float) Load 73(scalarCopy)
80: 7(fvec4) CompositeConstruct 76 77 78 79
81: 6(float) Load 73(scalarCopy)
82: 6(float) Load 73(scalarCopy)
83: 8(fvec2) CompositeConstruct 81 82
84:9(VertexOut) CompositeConstruct 80 83
ReturnValue 84
FunctionEnd
23(@main():9(VertexOut) Function None 10
24: Label
88(v0): 87(ptr) Variable Function
90(v1): 87(ptr) Variable Function
92(v2): 87(ptr) Variable Function
94(v3): 87(ptr) Variable Function
96(v4): 87(ptr) Variable Function
98(v5): 87(ptr) Variable Function
89:9(VertexOut) FunctionCall 11(r0()
Store 88(v0) 89
91:9(VertexOut) FunctionCall 13(r1()
Store 90(v1) 91
93:9(VertexOut) FunctionCall 15(r2()
Store 92(v2) 93
95:9(VertexOut) FunctionCall 17(r3()
Store 94(v3) 95
97:9(VertexOut) FunctionCall 19(r4()
Store 96(v4) 97
99:9(VertexOut) FunctionCall 21(r5()
Store 98(v5) 99
ReturnValue 102
FunctionEnd

37
Test/hlsl.scalarCast.vert Executable file
View File

@ -0,0 +1,37 @@
struct VertexOut {
float4 position : SV_Position;
float2 texCoord : TEXCOORD;
};
VertexOut r0() {
const float f = 2.0;
return (VertexOut)f;
}
VertexOut r1() {
const float f = 2.0;
return (VertexOut)(f + 1.0);
}
VertexOut r2() {
const float f = 2.0;
return (VertexOut)(sin(f));
}
VertexOut r3() {
float f = 2.0;
return (VertexOut)f;
}
VertexOut r4() {
float f = 2.0;
return (VertexOut)(f + 1.0);
}
VertexOut r5() {
float f = 2.0;
return (VertexOut)(sin(f));
}
VertexOut main() {
VertexOut v0 = r0();
VertexOut v1 = r1();
VertexOut v2 = r2();
VertexOut v3 = r3();
VertexOut v4 = r4();
VertexOut v5 = r5();
return (VertexOut)1;
}

View File

@ -3,4 +3,4 @@
// For the date, it uses the current date (when then script is run).
#define GLSLANG_REVISION "Overload400-PrecQual.1971"
#define GLSLANG_DATE "03-Apr-2017"
#define GLSLANG_DATE "04-Apr-2017"

View File

@ -223,6 +223,7 @@ INSTANTIATE_TEST_CASE_P(
{"hlsl.samplelevel.offsetarray.dx10.frag", "main"},
{"hlsl.sample.sub-vec4.dx10.frag", "main"},
{"hlsl.scalar-length.frag", "main"},
{"hlsl.scalarCast.vert", "main"},
{"hlsl.semicolons.frag", "main"},
{"hlsl.shapeConv.frag", "main"},
{"hlsl.shapeConvRet.frag", "main"},

View File

@ -335,13 +335,6 @@ TIntermTyped* HlslParseContext::handleLvalue(const TSourceLoc& loc, const char*
[](bool isSet) { return isSet; } );
};
// helper to create a temporary variable
const auto addTmpVar = [&](const char* name, const TType& derefType) -> TIntermSymbol* {
TVariable* tmpVar = makeInternalVariable(name, derefType);
tmpVar->getWritableType().getQualifier().makeTemporary();
return intermediate.addSymbol(*tmpVar, loc);
};
// Create swizzle matching input swizzle
const auto addSwizzle = [&](TIntermSymbol* var, TIntermBinary* swizzle) -> TIntermTyped* {
if (swizzle)
@ -419,7 +412,7 @@ TIntermTyped* HlslParseContext::handleLvalue(const TSourceLoc& loc, const char*
TIntermTyped* coordTmp = coord;
if (rhsTmp == nullptr || isModifyOp || lhsIsSwizzle) {
rhsTmp = addTmpVar("storeTemp", objDerefType);
rhsTmp = makeInternalVariableNode(loc, "storeTemp", objDerefType);
// Partial updates not yet supported
if (!writesAllComponents(rhsTmp, lhsAsBinary)) {
@ -429,7 +422,7 @@ TIntermTyped* HlslParseContext::handleLvalue(const TSourceLoc& loc, const char*
// Assign storeTemp = rhs
if (isModifyOp) {
// We have to make a temp var for the coordinate, to avoid evaluating it twice.
coordTmp = addTmpVar("coordTemp", coord->getType());
coordTmp = makeInternalVariableNode(loc, "coordTemp", coord->getType());
makeBinary(EOpAssign, coordTmp, coord); // coordtmp = load[param1]
makeLoad(rhsTmp, object, coordTmp, objDerefType); // rhsTmp = OpImageLoad(object, coordTmp)
}
@ -462,8 +455,8 @@ TIntermTyped* HlslParseContext::handleLvalue(const TSourceLoc& loc, const char*
// OpImageStore(object, coordTmp, rhsTmp)
// rhsTmp
TIntermSymbol* rhsTmp = addTmpVar("storeTemp", objDerefType);
TIntermTyped* coordTmp = addTmpVar("coordTemp", coord->getType());
TIntermSymbol* rhsTmp = makeInternalVariableNode(loc, "storeTemp", objDerefType);
TIntermTyped* coordTmp = makeInternalVariableNode(loc, "coordTemp", coord->getType());
makeBinary(EOpAssign, coordTmp, coord); // coordtmp = load[param1]
makeLoad(rhsTmp, object, coordTmp, objDerefType); // rhsTmp = OpImageLoad(object, coordTmp)
@ -483,9 +476,9 @@ TIntermTyped* HlslParseContext::handleLvalue(const TSourceLoc& loc, const char*
// rhsTmp2 op
// OpImageStore(object, coordTmp, rhsTmp2)
// rhsTmp1 (pre-op value)
TIntermSymbol* rhsTmp1 = addTmpVar("storeTempPre", objDerefType);
TIntermSymbol* rhsTmp2 = addTmpVar("storeTempPost", objDerefType);
TIntermTyped* coordTmp = addTmpVar("coordTemp", coord->getType());
TIntermSymbol* rhsTmp1 = makeInternalVariableNode(loc, "storeTempPre", objDerefType);
TIntermSymbol* rhsTmp2 = makeInternalVariableNode(loc, "storeTempPost", objDerefType);
TIntermTyped* coordTmp = makeInternalVariableNode(loc, "coordTemp", coord->getType());
makeBinary(EOpAssign, coordTmp, coord); // coordtmp = load[param1]
makeLoad(rhsTmp1, object, coordTmp, objDerefType); // rhsTmp1 = OpImageLoad(object, coordTmp)
@ -4739,7 +4732,7 @@ bool HlslParseContext::constructorError(const TSourceLoc& loc, TIntermNode* node
return true;
}
if (op == EOpConstructStruct && ! type.isArray() && isZeroConstructor(node))
if (op == EOpConstructStruct && ! type.isArray() && isScalarConstructor(node))
return false;
if (op == EOpConstructStruct && ! type.isArray() && (int)type.getStruct()->size() != function.getParamCount()) {
@ -4756,10 +4749,21 @@ bool HlslParseContext::constructorError(const TSourceLoc& loc, TIntermNode* node
return false;
}
bool HlslParseContext::isZeroConstructor(const TIntermNode* node)
// See if 'node', in the context of constructing aggregates, is a scalar argument
// to a constructor.
//
bool HlslParseContext::isScalarConstructor(const TIntermNode* node)
{
return node->getAsTyped()->isScalar() && node->getAsConstantUnion() &&
node->getAsConstantUnion()->getConstArray()[0].getIConst() == 0;
// Obviously, it must be a scalar, but an aggregate node might not be fully
// completed yet: holding a sequence of initializers under an aggregate
// would not yet be typed, so don't check it's type. This corresponds to
// the aggregate operator also not being set yet. (An aggregate operation
// that legitimately yields a scalar will have a getOp() of that operator,
// not EOpNull.)
return node->getAsTyped() != nullptr &&
node->getAsTyped()->isScalar() &&
(node->getAsAggregate() == nullptr || node->getAsAggregate()->getOp() != EOpNull);
}
// Verify all the correct semantics for constructing a combined texture/sampler.
@ -6295,6 +6299,15 @@ TVariable* HlslParseContext::makeInternalVariable(const char* name, const TType&
return variable;
}
// Make a symbol node holding a new internal temporary variable.
TIntermSymbol* HlslParseContext::makeInternalVariableNode(const TSourceLoc& loc, const char* name, const TType& type) const
{
TVariable* tmpVar = makeInternalVariable(name, type);
tmpVar->getWritableType().getQualifier().makeTemporary();
return intermediate.addSymbol(*tmpVar, loc);
}
//
// Declare a non-array variable, the main point being there is no redeclaration
// for resizing allowed.
@ -6345,7 +6358,7 @@ TIntermNode* HlslParseContext::executeInitializer(const TSourceLoc& loc, TInterm
skeletalType.shallowCopy(variable->getType());
skeletalType.getQualifier().makeTemporary();
if (initializer->getAsAggregate() && initializer->getAsAggregate()->getOp() == EOpNull)
initializer = convertInitializerList(loc, skeletalType, initializer);
initializer = convertInitializerList(loc, skeletalType, initializer, nullptr);
if (! initializer) {
// error recovery; don't leave const without constant values
if (qualifier == EvqConst)
@ -6427,7 +6440,8 @@ TIntermNode* HlslParseContext::executeInitializer(const TSourceLoc& loc, TInterm
//
// Returns nullptr if there is an error.
//
TIntermTyped* HlslParseContext::convertInitializerList(const TSourceLoc& loc, const TType& type, TIntermTyped* initializer)
TIntermTyped* HlslParseContext::convertInitializerList(const TSourceLoc& loc, const TType& type,
TIntermTyped* initializer, TIntermTyped* scalarInit)
{
// Will operate recursively. Once a subtree is found that is constructor style,
// everything below it is already good: Only the "top part" of the initializer
@ -6473,12 +6487,12 @@ TIntermTyped* HlslParseContext::convertInitializerList(const TSourceLoc& loc, co
}
// lengthen list to be long enough
lengthenList(loc, initList->getSequence(), arrayType.getOuterArraySize());
lengthenList(loc, initList->getSequence(), arrayType.getOuterArraySize(), scalarInit);
// recursively process each element
TType elementType(arrayType, 0); // dereferenced type
for (int i = 0; i < arrayType.getOuterArraySize(); ++i) {
initList->getSequence()[i] = convertInitializerList(loc, elementType, initList->getSequence()[i]->getAsTyped());
initList->getSequence()[i] = convertInitializerList(loc, elementType, initList->getSequence()[i]->getAsTyped(), scalarInit);
if (initList->getSequence()[i] == nullptr)
return nullptr;
}
@ -6486,14 +6500,14 @@ TIntermTyped* HlslParseContext::convertInitializerList(const TSourceLoc& loc, co
return addConstructor(loc, initList, arrayType);
} else if (type.isStruct()) {
// lengthen list to be long enough
lengthenList(loc, initList->getSequence(), static_cast<int>(type.getStruct()->size()));
lengthenList(loc, initList->getSequence(), static_cast<int>(type.getStruct()->size()), scalarInit);
if (type.getStruct()->size() != initList->getSequence().size()) {
error(loc, "wrong number of structure members", "initializer list", "");
return nullptr;
}
for (size_t i = 0; i < type.getStruct()->size(); ++i) {
initList->getSequence()[i] = convertInitializerList(loc, *(*type.getStruct())[i].type, initList->getSequence()[i]->getAsTyped());
initList->getSequence()[i] = convertInitializerList(loc, *(*type.getStruct())[i].type, initList->getSequence()[i]->getAsTyped(), scalarInit);
if (initList->getSequence()[i] == nullptr)
return nullptr;
}
@ -6504,7 +6518,7 @@ TIntermTyped* HlslParseContext::convertInitializerList(const TSourceLoc& loc, co
// a constructor; no further processing needed.
} else {
// lengthen list to be long enough
lengthenList(loc, initList->getSequence(), type.getMatrixCols());
lengthenList(loc, initList->getSequence(), type.getMatrixCols(), scalarInit);
if (type.getMatrixCols() != (int)initList->getSequence().size()) {
error(loc, "wrong number of matrix columns:", "initializer list", type.getCompleteString().c_str());
@ -6512,14 +6526,14 @@ TIntermTyped* HlslParseContext::convertInitializerList(const TSourceLoc& loc, co
}
TType vectorType(type, 0); // dereferenced type
for (int i = 0; i < type.getMatrixCols(); ++i) {
initList->getSequence()[i] = convertInitializerList(loc, vectorType, initList->getSequence()[i]->getAsTyped());
initList->getSequence()[i] = convertInitializerList(loc, vectorType, initList->getSequence()[i]->getAsTyped(), scalarInit);
if (initList->getSequence()[i] == nullptr)
return nullptr;
}
}
} else if (type.isVector()) {
// lengthen list to be long enough
lengthenList(loc, initList->getSequence(), type.getVectorSize());
lengthenList(loc, initList->getSequence(), type.getVectorSize(), scalarInit);
// error check; we're at bottom, so work is finished below
if (type.getVectorSize() != (int)initList->getSequence().size()) {
@ -6528,7 +6542,7 @@ TIntermTyped* HlslParseContext::convertInitializerList(const TSourceLoc& loc, co
}
} else if (type.isScalar()) {
// lengthen list to be long enough
lengthenList(loc, initList->getSequence(), 1);
lengthenList(loc, initList->getSequence(), 1, scalarInit);
if ((int)initList->getSequence().size() != 1) {
error(loc, "scalar expected one element:", "initializer list", type.getCompleteString().c_str());
@ -6553,10 +6567,21 @@ TIntermTyped* HlslParseContext::convertInitializerList(const TSourceLoc& loc, co
// Lengthen list to be long enough to cover any gap from the current list size
// to 'size'. If the list is longer, do nothing.
// The value to lengthen with is the default for short lists.
void HlslParseContext::lengthenList(const TSourceLoc& loc, TIntermSequence& list, int size)
//
// By default, lists that are too short due to lack of initializers initialize to zero.
// Alternatively, it could be a scalar initializer for a structure. Both cases are handled,
// based on whether something is passed in as 'scalarInit'.
//
// 'scalarInit' must be safe to use each time this is called (no side effects replication).
//
void HlslParseContext::lengthenList(const TSourceLoc& loc, TIntermSequence& list, int size, TIntermTyped* scalarInit)
{
for (int c = (int)list.size(); c < size; ++c)
list.push_back(intermediate.addConstantUnion(0, loc));
for (int c = (int)list.size(); c < size; ++c) {
if (scalarInit == nullptr)
list.push_back(intermediate.addConstantUnion(0, loc));
else
list.push_back(scalarInit);
}
}
//
@ -6570,11 +6595,23 @@ TIntermTyped* HlslParseContext::handleConstructor(const TSourceLoc& loc, TInterm
if (node == nullptr)
return nullptr;
// Handle the idiom "(struct type)0"
// Sequences (in an aggregate) for initialization are not yet tagged with
// an operator or type, so it is too early to ask if they are scalars.
if (type.isStruct() && isZeroConstructor(node))
return convertInitializerList(loc, type, intermediate.makeAggregate(loc));
// Handle the idiom "(struct type)<scalar value>"
if (type.isStruct() && isScalarConstructor(node)) {
// 'node' will almost always get used multiple times, so should not be used directly,
// it would create a DAG instead of a tree, which might be okay (would
// like to formalize that for constants and symbols), but if it has
// side effects, they would get executed multiple times, which is not okay.
if (node->getAsConstantUnion() == nullptr && node->getAsSymbolNode() == nullptr) {
TIntermAggregate* seq = intermediate.makeAggregate(loc);
TIntermSymbol* copy = makeInternalVariableNode(loc, "scalarCopy", node->getType());
seq = intermediate.growAggregate(seq, intermediate.addBinaryNode(EOpAssign, copy, node, loc));
seq = intermediate.growAggregate(seq, convertInitializerList(loc, type, intermediate.makeAggregate(loc), copy));
seq->setOp(EOpComma);
seq->setType(type);
return seq;
} else
return convertInitializerList(loc, type, intermediate.makeAggregate(loc), node);
}
return addConstructor(loc, node, type);
}

View File

@ -140,7 +140,7 @@ public:
void declareStruct(const TSourceLoc&, TString& structName, TType&);
TSymbol* lookupUserType(const TString&, TType&);
TIntermNode* declareVariable(const TSourceLoc&, const TString& identifier, TType&, TIntermTyped* initializer = 0);
void lengthenList(const TSourceLoc&, TIntermSequence& list, int size);
void lengthenList(const TSourceLoc&, TIntermSequence& list, int size, TIntermTyped* scalarInit);
TIntermTyped* handleConstructor(const TSourceLoc&, TIntermTyped*, const TType&);
TIntermTyped* addConstructor(const TSourceLoc&, TIntermTyped*, const TType&);
TIntermTyped* constructAggregate(TIntermNode*, const TType&, int, const TSourceLoc&);
@ -217,11 +217,12 @@ protected:
TVariable* makeInternalVariable(const TString& name, const TType& type) const {
return makeInternalVariable(name.c_str(), type);
}
TIntermSymbol* makeInternalVariableNode(const TSourceLoc&, const char* name, const TType&) const;
TVariable* declareNonArray(const TSourceLoc&, const TString& identifier, const TType&, bool track);
void declareArray(const TSourceLoc&, const TString& identifier, const TType&, TSymbol*&, bool track);
TIntermNode* executeInitializer(const TSourceLoc&, TIntermTyped* initializer, TVariable* variable);
TIntermTyped* convertInitializerList(const TSourceLoc&, const TType&, TIntermTyped* initializer);
bool isZeroConstructor(const TIntermNode*);
TIntermTyped* convertInitializerList(const TSourceLoc&, const TType&, TIntermTyped* initializer, TIntermTyped* scalarInit);
bool isScalarConstructor(const TIntermNode*);
TOperator mapAtomicOp(const TSourceLoc& loc, TOperator op, bool isImage);
// Return true if this node requires L-value conversion (e.g, to an imageStore).