HLSL default function parameters

This PR adds support for default function parameters in the following cases:

1. Simple constants, such as void fn(int x, float myparam = 3)
2. Expressions that can be const folded, such a ... myparam = sin(some_const)
3. Initializer lists that can be const folded, such as ... float2 myparam = {1,2}

New tests are added: hlsl.params.default.frag and hlsl.params.default.err.frag
(for testing error situations, such as ambiguity or non-const-foldable).

In order to avoid sampler method ambiguity, the hlsl better() lambda now
considers sampler matches.  Previously, all sampler types looked identical
since only the basic type of EbtSampler was considered.
This commit is contained in:
steve-lunarg 2016-12-23 18:56:57 -07:00
parent 807a0d9e2f
commit 26d3145334
15 changed files with 1263 additions and 24 deletions

View File

@ -1,6 +1,10 @@
hlsl.intrinsics.negative.frag
ERROR: 0:10: 'determinant' : no matching overloaded function found
ERROR: 0:12: 'f32tof16' : unimplemented intrinsic: handle natively
ERROR: 0:23: 'length' : 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:39: 'GetRenderTargetSamplePosition' : no matching overloaded function found
@ -59,7 +63,7 @@ ERROR: 0:133: 'normalize' : no matching overloaded function found
ERROR: 0:133: 'reflect' : no matching overloaded function found
ERROR: 0:133: 'refract' : no matching overloaded function found
ERROR: 0:133: 'reversebits' : no matching overloaded function found
ERROR: 60 compilation errors. No code generated.
ERROR: 64 compilation errors. No code generated.
Shader version: 450

View File

@ -0,0 +1,639 @@
hlsl.params.default.frag
Shader version: 450
gl_FragCoord origin is upper left
0:? Sequence
0:9 Function Definition: fn1(vi4;b1;b1; (temp 4-component vector of int)
0:9 Function Parameters:
0:9 'p0' (in 4-component vector of int)
0:9 'b1' (in bool)
0:9 'b2' (in bool)
0:? Sequence
0:10 Branch: Return with expression
0:10 'p0' (in 4-component vector of int)
0:17 Function Definition: fn1(vi4;vi4;i1[2];i1; (temp 4-component vector of int)
0:17 Function Parameters:
0:17 'p0' (in 4-component vector of int)
0:17 'p1' (in 4-component vector of int)
0:17 'p2' (in 2-element array of int)
0:17 'p3' (in int)
0:? Sequence
0:18 Branch: Return with expression
0:18 add (temp 4-component vector of int)
0:18 add (temp 4-component vector of int)
0:18 add (temp 4-component vector of int)
0:18 'p0' (in 4-component vector of int)
0:18 'p1' (in 4-component vector of int)
0:18 direct index (temp int)
0:18 'p2' (in 2-element array of int)
0:18 Constant:
0:18 0 (const int)
0:18 'p3' (in int)
0:23 Function Definition: fn2(vi4;i1; (temp 4-component vector of int)
0:23 Function Parameters:
0:23 'p0' (in 4-component vector of int)
0:23 'x' (in int)
0:? Sequence
0:24 Branch: Return with expression
0:? Constant:
0:? 10 (const int)
0:? 11 (const int)
0:? 12 (const int)
0:? 13 (const int)
0:28 Function Definition: fn2(vi4;f1; (temp 4-component vector of int)
0:28 Function Parameters:
0:28 'p0' (in 4-component vector of int)
0:28 'x' (in float)
0:? Sequence
0:29 Branch: Return with expression
0:29 add (temp 4-component vector of int)
0:29 'p0' (in 4-component vector of int)
0:? Constant:
0:? 20 (const int)
0:? 21 (const int)
0:? 22 (const int)
0:? 23 (const int)
0:32 Function Definition: fn3(i1; (temp void)
0:32 Function Parameters:
0:32 'p0' (in int)
0:36 Function Definition: main( (temp 4-component vector of int)
0:36 Function Parameters:
0:? Sequence
0:37 Sequence
0:37 move second child to first child (temp 2-element array of int)
0:37 'myarray' (temp 2-element array of int)
0:37 Constant:
0:37 30 (const int)
0:37 31 (const int)
0:39 Function Call: fn3(i1; (temp void)
0:32 Constant:
0:32 3 (const int)
0:40 Function Call: fn3(i1; (temp void)
0:40 Constant:
0:40 5 (const int)
0:50 Sequence
0:50 move second child to first child (temp 4-component vector of int)
0:? '@entryPointOutput' (layout(location=0 ) out 4-component vector of int)
0:49 add (temp 4-component vector of int)
0:47 add (temp 4-component vector of int)
0:46 add (temp 4-component vector of int)
0:45 add (temp 4-component vector of int)
0:44 add (temp 4-component vector of int)
0:43 add (temp 4-component vector of int)
0:42 add (temp 4-component vector of int)
0:42 Function Call: fn1(vi4;vi4;i1[2];i1; (temp 4-component vector of int)
0:42 Constant:
0:42 100 (const int)
0:42 100 (const int)
0:42 100 (const int)
0:42 100 (const int)
0:? Constant:
0:? -1 (const int)
0:? -2 (const int)
0:? -3 (const int)
0:? -4 (const int)
0:15 Constant:
0:15 1 (const int)
0:15 2 (const int)
0:16 Constant:
0:16 42 (const int)
0:43 Function Call: fn1(vi4;vi4;i1[2];i1; (temp 4-component vector of int)
0:43 Constant:
0:43 101 (const int)
0:43 101 (const int)
0:43 101 (const int)
0:43 101 (const int)
0:43 ui4: direct index for structure (layout(offset=0 ) uniform 4-component vector of int)
0:43 'anon@0' (layout(row_major std140 ) uniform block{layout(offset=0 ) uniform 4-component vector of int ui4})
0:43 Constant:
0:43 0 (const uint)
0:15 Constant:
0:15 1 (const int)
0:15 2 (const int)
0:16 Constant:
0:16 42 (const int)
0:44 Function Call: fn1(vi4;vi4;i1[2];i1; (temp 4-component vector of int)
0:44 Constant:
0:44 102 (const int)
0:44 102 (const int)
0:44 102 (const int)
0:44 102 (const int)
0:44 ui4: direct index for structure (layout(offset=0 ) uniform 4-component vector of int)
0:44 'anon@0' (layout(row_major std140 ) uniform block{layout(offset=0 ) uniform 4-component vector of int ui4})
0:44 Constant:
0:44 0 (const uint)
0:44 'myarray' (temp 2-element array of int)
0:16 Constant:
0:16 42 (const int)
0:45 Function Call: fn1(vi4;vi4;i1[2];i1; (temp 4-component vector of int)
0:45 Constant:
0:45 103 (const int)
0:45 103 (const int)
0:45 103 (const int)
0:45 103 (const int)
0:45 ui4: direct index for structure (layout(offset=0 ) uniform 4-component vector of int)
0:45 'anon@0' (layout(row_major std140 ) uniform block{layout(offset=0 ) uniform 4-component vector of int ui4})
0:45 Constant:
0:45 0 (const uint)
0:45 'myarray' (temp 2-element array of int)
0:45 Constant:
0:45 99 (const int)
0:46 Function Call: fn1(vi4;b1;b1; (temp 4-component vector of int)
0:46 Constant:
0:46 104 (const int)
0:46 104 (const int)
0:46 104 (const int)
0:46 104 (const int)
0:46 Constant:
0:46 false (const bool)
0:9 Constant:
0:9 false (const bool)
0:47 Function Call: fn1(vi4;b1;b1; (temp 4-component vector of int)
0:47 Constant:
0:47 105 (const int)
0:47 105 (const int)
0:47 105 (const int)
0:47 105 (const int)
0:47 Constant:
0:47 false (const bool)
0:47 Constant:
0:47 true (const bool)
0:49 Function Call: fn2(vi4;f1; (temp 4-component vector of int)
0:49 Constant:
0:49 110 (const int)
0:49 110 (const int)
0:49 110 (const int)
0:49 110 (const int)
0:49 Constant:
0:49 11.110000
0:50 Function Call: fn2(vi4;i1; (temp 4-component vector of int)
0:50 Constant:
0:50 111 (const int)
0:50 111 (const int)
0:50 111 (const int)
0:50 111 (const int)
0:50 Constant:
0:50 12 (const int)
0:50 Branch: Return
0:? Linker Objects
0:? '@entryPointOutput' (layout(location=0 ) out 4-component vector of int)
0:? 'cia' (const int)
0:? -4 (const int)
0:? 'cib' (const int)
0:? -42 (const int)
0:? 'anon@0' (layout(row_major std140 ) uniform block{layout(offset=0 ) uniform 4-component vector of int ui4})
Linked fragment stage:
Shader version: 450
gl_FragCoord origin is upper left
0:? Sequence
0:9 Function Definition: fn1(vi4;b1;b1; (temp 4-component vector of int)
0:9 Function Parameters:
0:9 'p0' (in 4-component vector of int)
0:9 'b1' (in bool)
0:9 'b2' (in bool)
0:? Sequence
0:10 Branch: Return with expression
0:10 'p0' (in 4-component vector of int)
0:17 Function Definition: fn1(vi4;vi4;i1[2];i1; (temp 4-component vector of int)
0:17 Function Parameters:
0:17 'p0' (in 4-component vector of int)
0:17 'p1' (in 4-component vector of int)
0:17 'p2' (in 2-element array of int)
0:17 'p3' (in int)
0:? Sequence
0:18 Branch: Return with expression
0:18 add (temp 4-component vector of int)
0:18 add (temp 4-component vector of int)
0:18 add (temp 4-component vector of int)
0:18 'p0' (in 4-component vector of int)
0:18 'p1' (in 4-component vector of int)
0:18 direct index (temp int)
0:18 'p2' (in 2-element array of int)
0:18 Constant:
0:18 0 (const int)
0:18 'p3' (in int)
0:23 Function Definition: fn2(vi4;i1; (temp 4-component vector of int)
0:23 Function Parameters:
0:23 'p0' (in 4-component vector of int)
0:23 'x' (in int)
0:? Sequence
0:24 Branch: Return with expression
0:? Constant:
0:? 10 (const int)
0:? 11 (const int)
0:? 12 (const int)
0:? 13 (const int)
0:28 Function Definition: fn2(vi4;f1; (temp 4-component vector of int)
0:28 Function Parameters:
0:28 'p0' (in 4-component vector of int)
0:28 'x' (in float)
0:? Sequence
0:29 Branch: Return with expression
0:29 add (temp 4-component vector of int)
0:29 'p0' (in 4-component vector of int)
0:? Constant:
0:? 20 (const int)
0:? 21 (const int)
0:? 22 (const int)
0:? 23 (const int)
0:32 Function Definition: fn3(i1; (temp void)
0:32 Function Parameters:
0:32 'p0' (in int)
0:36 Function Definition: main( (temp 4-component vector of int)
0:36 Function Parameters:
0:? Sequence
0:37 Sequence
0:37 move second child to first child (temp 2-element array of int)
0:37 'myarray' (temp 2-element array of int)
0:37 Constant:
0:37 30 (const int)
0:37 31 (const int)
0:39 Function Call: fn3(i1; (temp void)
0:32 Constant:
0:32 3 (const int)
0:40 Function Call: fn3(i1; (temp void)
0:40 Constant:
0:40 5 (const int)
0:50 Sequence
0:50 move second child to first child (temp 4-component vector of int)
0:? '@entryPointOutput' (layout(location=0 ) out 4-component vector of int)
0:49 add (temp 4-component vector of int)
0:47 add (temp 4-component vector of int)
0:46 add (temp 4-component vector of int)
0:45 add (temp 4-component vector of int)
0:44 add (temp 4-component vector of int)
0:43 add (temp 4-component vector of int)
0:42 add (temp 4-component vector of int)
0:42 Function Call: fn1(vi4;vi4;i1[2];i1; (temp 4-component vector of int)
0:42 Constant:
0:42 100 (const int)
0:42 100 (const int)
0:42 100 (const int)
0:42 100 (const int)
0:? Constant:
0:? -1 (const int)
0:? -2 (const int)
0:? -3 (const int)
0:? -4 (const int)
0:15 Constant:
0:15 1 (const int)
0:15 2 (const int)
0:16 Constant:
0:16 42 (const int)
0:43 Function Call: fn1(vi4;vi4;i1[2];i1; (temp 4-component vector of int)
0:43 Constant:
0:43 101 (const int)
0:43 101 (const int)
0:43 101 (const int)
0:43 101 (const int)
0:43 ui4: direct index for structure (layout(offset=0 ) uniform 4-component vector of int)
0:43 'anon@0' (layout(row_major std140 ) uniform block{layout(offset=0 ) uniform 4-component vector of int ui4})
0:43 Constant:
0:43 0 (const uint)
0:15 Constant:
0:15 1 (const int)
0:15 2 (const int)
0:16 Constant:
0:16 42 (const int)
0:44 Function Call: fn1(vi4;vi4;i1[2];i1; (temp 4-component vector of int)
0:44 Constant:
0:44 102 (const int)
0:44 102 (const int)
0:44 102 (const int)
0:44 102 (const int)
0:44 ui4: direct index for structure (layout(offset=0 ) uniform 4-component vector of int)
0:44 'anon@0' (layout(row_major std140 ) uniform block{layout(offset=0 ) uniform 4-component vector of int ui4})
0:44 Constant:
0:44 0 (const uint)
0:44 'myarray' (temp 2-element array of int)
0:16 Constant:
0:16 42 (const int)
0:45 Function Call: fn1(vi4;vi4;i1[2];i1; (temp 4-component vector of int)
0:45 Constant:
0:45 103 (const int)
0:45 103 (const int)
0:45 103 (const int)
0:45 103 (const int)
0:45 ui4: direct index for structure (layout(offset=0 ) uniform 4-component vector of int)
0:45 'anon@0' (layout(row_major std140 ) uniform block{layout(offset=0 ) uniform 4-component vector of int ui4})
0:45 Constant:
0:45 0 (const uint)
0:45 'myarray' (temp 2-element array of int)
0:45 Constant:
0:45 99 (const int)
0:46 Function Call: fn1(vi4;b1;b1; (temp 4-component vector of int)
0:46 Constant:
0:46 104 (const int)
0:46 104 (const int)
0:46 104 (const int)
0:46 104 (const int)
0:46 Constant:
0:46 false (const bool)
0:9 Constant:
0:9 false (const bool)
0:47 Function Call: fn1(vi4;b1;b1; (temp 4-component vector of int)
0:47 Constant:
0:47 105 (const int)
0:47 105 (const int)
0:47 105 (const int)
0:47 105 (const int)
0:47 Constant:
0:47 false (const bool)
0:47 Constant:
0:47 true (const bool)
0:49 Function Call: fn2(vi4;f1; (temp 4-component vector of int)
0:49 Constant:
0:49 110 (const int)
0:49 110 (const int)
0:49 110 (const int)
0:49 110 (const int)
0:49 Constant:
0:49 11.110000
0:50 Function Call: fn2(vi4;i1; (temp 4-component vector of int)
0:50 Constant:
0:50 111 (const int)
0:50 111 (const int)
0:50 111 (const int)
0:50 111 (const int)
0:50 Constant:
0:50 12 (const int)
0:50 Branch: Return
0:? Linker Objects
0:? '@entryPointOutput' (layout(location=0 ) out 4-component vector of int)
0:? 'cia' (const int)
0:? -4 (const int)
0:? 'cib' (const int)
0:? -42 (const int)
0:? 'anon@0' (layout(row_major std140 ) uniform block{layout(offset=0 ) uniform 4-component vector of int ui4})
// Module Version 10000
// Generated by (magic number): 80001
// Id's are bound by 173
Capability Shader
1: ExtInstImport "GLSL.std.450"
MemoryModel Logical GLSL450
EntryPoint Fragment 4 "main" 88
ExecutionMode 4 OriginUpperLeft
Name 4 "main"
Name 15 "fn1(vi4;b1;b1;"
Name 12 "p0"
Name 13 "b1"
Name 14 "b2"
Name 27 "fn1(vi4;vi4;i1[2];i1;"
Name 23 "p0"
Name 24 "p1"
Name 25 "p2"
Name 26 "p3"
Name 32 "fn2(vi4;i1;"
Name 30 "p0"
Name 31 "x"
Name 39 "fn2(vi4;f1;"
Name 37 "p0"
Name 38 "x"
Name 43 "fn3(i1;"
Name 42 "p0"
Name 77 "myarray"
Name 82 "param"
Name 85 "param"
Name 88 "@entryPointOutput"
Name 100 "param"
Name 101 "param"
Name 102 "param"
Name 103 "param"
Name 107 "$Global"
MemberName 107($Global) 0 "ui4"
Name 109 ""
Name 110 "param"
Name 111 "param"
Name 115 "param"
Name 116 "param"
Name 121 "param"
Name 122 "param"
Name 125 "param"
Name 127 "param"
Name 133 "param"
Name 134 "param"
Name 137 "param"
Name 139 "param"
Name 145 "param"
Name 146 "param"
Name 147 "param"
Name 153 "param"
Name 154 "param"
Name 155 "param"
Name 161 "param"
Name 162 "param"
Name 167 "param"
Name 168 "param"
Decorate 88(@entryPointOutput) Location 0
MemberDecorate 107($Global) 0 Offset 0
Decorate 107($Global) Block
Decorate 109 DescriptorSet 0
2: TypeVoid
3: TypeFunction 2
6: TypeInt 32 1
7: TypeVector 6(int) 4
8: TypePointer Function 7(ivec4)
9: TypeBool
10: TypePointer Function 9(bool)
11: TypeFunction 7(ivec4) 8(ptr) 10(ptr) 10(ptr)
17: TypeInt 32 0
18: 17(int) Constant 2
19: TypeArray 6(int) 18
20: TypePointer Function 19
21: TypePointer Function 6(int)
22: TypeFunction 7(ivec4) 8(ptr) 8(ptr) 20(ptr) 21(ptr)
29: TypeFunction 7(ivec4) 8(ptr) 21(ptr)
34: TypeFloat 32
35: TypePointer Function 34(float)
36: TypeFunction 7(ivec4) 8(ptr) 35(ptr)
41: TypeFunction 2 21(ptr)
51: 6(int) Constant 0
61: 6(int) Constant 10
62: 6(int) Constant 11
63: 6(int) Constant 12
64: 6(int) Constant 13
65: 7(ivec4) ConstantComposite 61 62 63 64
69: 6(int) Constant 20
70: 6(int) Constant 21
71: 6(int) Constant 22
72: 6(int) Constant 23
73: 7(ivec4) ConstantComposite 69 70 71 72
78: 6(int) Constant 30
79: 6(int) Constant 31
80: 19 ConstantComposite 78 79
81: 6(int) Constant 3
84: 6(int) Constant 5
87: TypePointer Output 7(ivec4)
88(@entryPointOutput): 87(ptr) Variable Output
89: 6(int) Constant 100
90: 7(ivec4) ConstantComposite 89 89 89 89
91: 6(int) Constant 4294967295
92: 6(int) Constant 4294967294
93: 6(int) Constant 4294967293
94: 6(int) Constant 4294967292
95: 7(ivec4) ConstantComposite 91 92 93 94
96: 6(int) Constant 1
97: 6(int) Constant 2
98: 19 ConstantComposite 96 97
99: 6(int) Constant 42
105: 6(int) Constant 101
106: 7(ivec4) ConstantComposite 105 105 105 105
107($Global): TypeStruct 7(ivec4)
108: TypePointer Uniform 107($Global)
109: 108(ptr) Variable Uniform
112: TypePointer Uniform 7(ivec4)
119: 6(int) Constant 102
120: 7(ivec4) ConstantComposite 119 119 119 119
130: 6(int) Constant 103
131: 7(ivec4) ConstantComposite 130 130 130 130
132: 6(int) Constant 99
142: 6(int) Constant 104
143: 7(ivec4) ConstantComposite 142 142 142 142
144: 9(bool) ConstantFalse
150: 6(int) Constant 105
151: 7(ivec4) ConstantComposite 150 150 150 150
152: 9(bool) ConstantTrue
158: 6(int) Constant 110
159: 7(ivec4) ConstantComposite 158 158 158 158
160: 34(float) Constant 1093780111
165: 6(int) Constant 111
166: 7(ivec4) ConstantComposite 165 165 165 165
172: 6(int) Constant 4294967254
4(main): 2 Function None 3
5: Label
77(myarray): 20(ptr) Variable Function
82(param): 21(ptr) Variable Function
85(param): 21(ptr) Variable Function
100(param): 8(ptr) Variable Function
101(param): 8(ptr) Variable Function
102(param): 20(ptr) Variable Function
103(param): 21(ptr) Variable Function
110(param): 8(ptr) Variable Function
111(param): 8(ptr) Variable Function
115(param): 20(ptr) Variable Function
116(param): 21(ptr) Variable Function
121(param): 8(ptr) Variable Function
122(param): 8(ptr) Variable Function
125(param): 20(ptr) Variable Function
127(param): 21(ptr) Variable Function
133(param): 8(ptr) Variable Function
134(param): 8(ptr) Variable Function
137(param): 20(ptr) Variable Function
139(param): 21(ptr) Variable Function
145(param): 8(ptr) Variable Function
146(param): 10(ptr) Variable Function
147(param): 10(ptr) Variable Function
153(param): 8(ptr) Variable Function
154(param): 10(ptr) Variable Function
155(param): 10(ptr) Variable Function
161(param): 8(ptr) Variable Function
162(param): 35(ptr) Variable Function
167(param): 8(ptr) Variable Function
168(param): 21(ptr) Variable Function
Store 77(myarray) 80
Store 82(param) 81
83: 2 FunctionCall 43(fn3(i1;) 82(param)
Store 85(param) 84
86: 2 FunctionCall 43(fn3(i1;) 85(param)
Store 100(param) 90
Store 101(param) 95
Store 102(param) 98
Store 103(param) 99
104: 7(ivec4) FunctionCall 27(fn1(vi4;vi4;i1[2];i1;) 100(param) 101(param) 102(param) 103(param)
Store 110(param) 106
113: 112(ptr) AccessChain 109 51
114: 7(ivec4) Load 113
Store 111(param) 114
Store 115(param) 98
Store 116(param) 99
117: 7(ivec4) FunctionCall 27(fn1(vi4;vi4;i1[2];i1;) 110(param) 111(param) 115(param) 116(param)
118: 7(ivec4) IAdd 104 117
Store 121(param) 120
123: 112(ptr) AccessChain 109 51
124: 7(ivec4) Load 123
Store 122(param) 124
126: 19 Load 77(myarray)
Store 125(param) 126
Store 127(param) 99
128: 7(ivec4) FunctionCall 27(fn1(vi4;vi4;i1[2];i1;) 121(param) 122(param) 125(param) 127(param)
129: 7(ivec4) IAdd 118 128
Store 133(param) 131
135: 112(ptr) AccessChain 109 51
136: 7(ivec4) Load 135
Store 134(param) 136
138: 19 Load 77(myarray)
Store 137(param) 138
Store 139(param) 132
140: 7(ivec4) FunctionCall 27(fn1(vi4;vi4;i1[2];i1;) 133(param) 134(param) 137(param) 139(param)
141: 7(ivec4) IAdd 129 140
Store 145(param) 143
Store 146(param) 144
Store 147(param) 144
148: 7(ivec4) FunctionCall 15(fn1(vi4;b1;b1;) 145(param) 146(param) 147(param)
149: 7(ivec4) IAdd 141 148
Store 153(param) 151
Store 154(param) 144
Store 155(param) 152
156: 7(ivec4) FunctionCall 15(fn1(vi4;b1;b1;) 153(param) 154(param) 155(param)
157: 7(ivec4) IAdd 149 156
Store 161(param) 159
Store 162(param) 160
163: 7(ivec4) FunctionCall 39(fn2(vi4;f1;) 161(param) 162(param)
164: 7(ivec4) IAdd 157 163
Store 167(param) 166
Store 168(param) 63
169: 7(ivec4) FunctionCall 32(fn2(vi4;i1;) 167(param) 168(param)
170: 7(ivec4) IAdd 164 169
Store 88(@entryPointOutput) 170
Return
FunctionEnd
15(fn1(vi4;b1;b1;): 7(ivec4) Function None 11
12(p0): 8(ptr) FunctionParameter
13(b1): 10(ptr) FunctionParameter
14(b2): 10(ptr) FunctionParameter
16: Label
45: 7(ivec4) Load 12(p0)
ReturnValue 45
FunctionEnd
27(fn1(vi4;vi4;i1[2];i1;): 7(ivec4) Function None 22
23(p0): 8(ptr) FunctionParameter
24(p1): 8(ptr) FunctionParameter
25(p2): 20(ptr) FunctionParameter
26(p3): 21(ptr) FunctionParameter
28: Label
48: 7(ivec4) Load 23(p0)
49: 7(ivec4) Load 24(p1)
50: 7(ivec4) IAdd 48 49
52: 21(ptr) AccessChain 25(p2) 51
53: 6(int) Load 52
54: 7(ivec4) CompositeConstruct 53 53 53 53
55: 7(ivec4) IAdd 50 54
56: 6(int) Load 26(p3)
57: 7(ivec4) CompositeConstruct 56 56 56 56
58: 7(ivec4) IAdd 55 57
ReturnValue 58
FunctionEnd
32(fn2(vi4;i1;): 7(ivec4) Function None 29
30(p0): 8(ptr) FunctionParameter
31(x): 21(ptr) FunctionParameter
33: Label
ReturnValue 65
FunctionEnd
39(fn2(vi4;f1;): 7(ivec4) Function None 36
37(p0): 8(ptr) FunctionParameter
38(x): 35(ptr) FunctionParameter
40: Label
68: 7(ivec4) Load 37(p0)
74: 7(ivec4) IAdd 68 73
ReturnValue 74
FunctionEnd
43(fn3(i1;): 2 Function None 41
42(p0): 21(ptr) FunctionParameter
44: Label
Return
FunctionEnd

View File

@ -0,0 +1,379 @@
hlsl.params.default.negative.frag
ERROR: 0:27: '' : invalid default parameter value
ERROR: 0:32: 'p1' : invalid parameter after default value parameters
ERROR: 0:40: 'fn1' : ambiguous best function under implicit type conversion
ERROR: 0:47: 'fn2' : ambiguous best function under implicit type conversion
ERROR: 4 compilation errors. No code generated.
Shader version: 450
gl_FragCoord origin is upper left
ERROR: node is still EOpNull!
0:7 Function Definition: fn1(vi4; (temp 4-component vector of int)
0:7 Function Parameters:
0:7 'p0' (in 4-component vector of int)
0:? Sequence
0:7 Branch: Return with expression
0:? Constant:
0:? 1 (const int)
0:? 2 (const int)
0:? 3 (const int)
0:? 4 (const int)
0:9 Function Definition: fn1(vi4;b1;b1; (temp 4-component vector of int)
0:9 Function Parameters:
0:9 'p0' (in 4-component vector of int)
0:9 'b1' (in bool)
0:9 'b2' (in bool)
0:? Sequence
0:10 Branch: Return with expression
0:10 'p0' (in 4-component vector of int)
0:17 Function Definition: fn1(vi4;vi4;i1[2];i1; (temp 4-component vector of int)
0:17 Function Parameters:
0:17 'p0' (in 4-component vector of int)
0:17 'p1' (in 4-component vector of int)
0:17 'p2' (in 2-element array of int)
0:17 'p3' (in int)
0:? Sequence
0:18 Branch: Return with expression
0:18 add (temp 4-component vector of int)
0:18 add (temp 4-component vector of int)
0:18 add (temp 4-component vector of int)
0:18 'p0' (in 4-component vector of int)
0:18 'p1' (in 4-component vector of int)
0:18 direct index (temp int)
0:18 'p2' (in 2-element array of int)
0:18 Constant:
0:18 0 (const int)
0:18 'p3' (in int)
0:23 Function Definition: fn2(vi4;i1; (temp 4-component vector of int)
0:23 Function Parameters:
0:23 'p0' (in 4-component vector of int)
0:23 'x' (in int)
0:? Sequence
0:24 Branch: Return with expression
0:? Constant:
0:? 10 (const int)
0:? 11 (const int)
0:? 12 (const int)
0:? 13 (const int)
0:28 Function Definition: fn2(vi4; (temp 4-component vector of int)
0:28 Function Parameters:
0:28 'p0' (in 4-component vector of int)
0:? Sequence
0:29 Branch: Return with expression
0:29 add (temp 4-component vector of int)
0:29 'p0' (in 4-component vector of int)
0:? Constant:
0:? 20 (const int)
0:? 21 (const int)
0:? 22 (const int)
0:? 23 (const int)
0:33 Function Definition: fn3(i1; (temp void)
0:33 Function Parameters:
0:33 'p0' (in int)
0:37 Function Definition: main( (temp 4-component vector of int)
0:37 Function Parameters:
0:? Sequence
0:38 Sequence
0:38 move second child to first child (temp 2-element array of int)
0:38 'myarray' (temp 2-element array of int)
0:38 Constant:
0:38 30 (const int)
0:38 31 (const int)
0:49 Sequence
0:49 move second child to first child (temp 4-component vector of int)
0:? '@entryPointOutput' (layout(location=0 ) out 4-component vector of int)
0:48 add (temp 4-component vector of int)
0:47 add (temp 4-component vector of int)
0:45 add (temp 4-component vector of int)
0:44 add (temp 4-component vector of int)
0:43 add (temp 4-component vector of int)
0:42 add (temp 4-component vector of int)
0:41 add (temp 4-component vector of int)
0:40 add (temp 4-component vector of int)
0:40 Function Call: fn1(vi4; (temp 4-component vector of int)
0:40 Constant:
0:40 100 (const int)
0:40 100 (const int)
0:40 100 (const int)
0:40 100 (const int)
0:41 Function Call: fn1(vi4;vi4;i1[2];i1; (temp 4-component vector of int)
0:41 Constant:
0:41 101 (const int)
0:41 101 (const int)
0:41 101 (const int)
0:41 101 (const int)
0:41 ui4: direct index for structure (layout(offset=0 ) uniform 4-component vector of int)
0:41 'anon@0' (layout(row_major std140 ) uniform block{layout(offset=0 ) uniform 4-component vector of int ui4, layout(offset=16 ) uniform float ufvar})
0:41 Constant:
0:41 0 (const uint)
0:15 Constant:
0:15 1 (const int)
0:15 2 (const int)
0:16 Constant:
0:16 42 (const int)
0:42 Function Call: fn1(vi4;vi4;i1[2];i1; (temp 4-component vector of int)
0:42 Constant:
0:42 102 (const int)
0:42 102 (const int)
0:42 102 (const int)
0:42 102 (const int)
0:42 ui4: direct index for structure (layout(offset=0 ) uniform 4-component vector of int)
0:42 'anon@0' (layout(row_major std140 ) uniform block{layout(offset=0 ) uniform 4-component vector of int ui4, layout(offset=16 ) uniform float ufvar})
0:42 Constant:
0:42 0 (const uint)
0:42 'myarray' (temp 2-element array of int)
0:16 Constant:
0:16 42 (const int)
0:43 Function Call: fn1(vi4;vi4;i1[2];i1; (temp 4-component vector of int)
0:43 Constant:
0:43 103 (const int)
0:43 103 (const int)
0:43 103 (const int)
0:43 103 (const int)
0:43 ui4: direct index for structure (layout(offset=0 ) uniform 4-component vector of int)
0:43 'anon@0' (layout(row_major std140 ) uniform block{layout(offset=0 ) uniform 4-component vector of int ui4, layout(offset=16 ) uniform float ufvar})
0:43 Constant:
0:43 0 (const uint)
0:43 'myarray' (temp 2-element array of int)
0:43 Constant:
0:43 99 (const int)
0:44 Function Call: fn1(vi4;b1;b1; (temp 4-component vector of int)
0:44 Constant:
0:44 104 (const int)
0:44 104 (const int)
0:44 104 (const int)
0:44 104 (const int)
0:44 Constant:
0:44 false (const bool)
0:9 Constant:
0:9 false (const bool)
0:45 Function Call: fn1(vi4;b1;b1; (temp 4-component vector of int)
0:45 Constant:
0:45 105 (const int)
0:45 105 (const int)
0:45 105 (const int)
0:45 105 (const int)
0:45 Constant:
0:45 false (const bool)
0:45 Constant:
0:45 true (const bool)
0:47 Function Call: fn2(vi4; (temp 4-component vector of int)
0:47 Constant:
0:47 112 (const int)
0:47 112 (const int)
0:47 112 (const int)
0:47 112 (const int)
0:48 Function Call: fn2(vi4;i1; (temp 4-component vector of int)
0:48 Constant:
0:48 110 (const int)
0:48 110 (const int)
0:48 110 (const int)
0:48 110 (const int)
0:48 Constant:
0:48 11 (const int)
0:49 Function Call: fn2(vi4;i1; (temp 4-component vector of int)
0:49 Constant:
0:49 111 (const int)
0:49 111 (const int)
0:49 111 (const int)
0:49 111 (const int)
0:49 Constant:
0:49 12 (const int)
0:49 Branch: Return
0:? Linker Objects
0:? '@entryPointOutput' (layout(location=0 ) out 4-component vector of int)
0:? 'cia' (const int)
0:? -4 (const int)
0:? 'cib' (const int)
0:? -42 (const int)
0:? 'anon@0' (layout(row_major std140 ) uniform block{layout(offset=0 ) uniform 4-component vector of int ui4, layout(offset=16 ) uniform float ufvar})
Linked fragment stage:
Shader version: 450
gl_FragCoord origin is upper left
ERROR: node is still EOpNull!
0:7 Function Definition: fn1(vi4; (temp 4-component vector of int)
0:7 Function Parameters:
0:7 'p0' (in 4-component vector of int)
0:? Sequence
0:7 Branch: Return with expression
0:? Constant:
0:? 1 (const int)
0:? 2 (const int)
0:? 3 (const int)
0:? 4 (const int)
0:9 Function Definition: fn1(vi4;b1;b1; (temp 4-component vector of int)
0:9 Function Parameters:
0:9 'p0' (in 4-component vector of int)
0:9 'b1' (in bool)
0:9 'b2' (in bool)
0:? Sequence
0:10 Branch: Return with expression
0:10 'p0' (in 4-component vector of int)
0:17 Function Definition: fn1(vi4;vi4;i1[2];i1; (temp 4-component vector of int)
0:17 Function Parameters:
0:17 'p0' (in 4-component vector of int)
0:17 'p1' (in 4-component vector of int)
0:17 'p2' (in 2-element array of int)
0:17 'p3' (in int)
0:? Sequence
0:18 Branch: Return with expression
0:18 add (temp 4-component vector of int)
0:18 add (temp 4-component vector of int)
0:18 add (temp 4-component vector of int)
0:18 'p0' (in 4-component vector of int)
0:18 'p1' (in 4-component vector of int)
0:18 direct index (temp int)
0:18 'p2' (in 2-element array of int)
0:18 Constant:
0:18 0 (const int)
0:18 'p3' (in int)
0:23 Function Definition: fn2(vi4;i1; (temp 4-component vector of int)
0:23 Function Parameters:
0:23 'p0' (in 4-component vector of int)
0:23 'x' (in int)
0:? Sequence
0:24 Branch: Return with expression
0:? Constant:
0:? 10 (const int)
0:? 11 (const int)
0:? 12 (const int)
0:? 13 (const int)
0:28 Function Definition: fn2(vi4; (temp 4-component vector of int)
0:28 Function Parameters:
0:28 'p0' (in 4-component vector of int)
0:? Sequence
0:29 Branch: Return with expression
0:29 add (temp 4-component vector of int)
0:29 'p0' (in 4-component vector of int)
0:? Constant:
0:? 20 (const int)
0:? 21 (const int)
0:? 22 (const int)
0:? 23 (const int)
0:33 Function Definition: fn3(i1; (temp void)
0:33 Function Parameters:
0:33 'p0' (in int)
0:37 Function Definition: main( (temp 4-component vector of int)
0:37 Function Parameters:
0:? Sequence
0:38 Sequence
0:38 move second child to first child (temp 2-element array of int)
0:38 'myarray' (temp 2-element array of int)
0:38 Constant:
0:38 30 (const int)
0:38 31 (const int)
0:49 Sequence
0:49 move second child to first child (temp 4-component vector of int)
0:? '@entryPointOutput' (layout(location=0 ) out 4-component vector of int)
0:48 add (temp 4-component vector of int)
0:47 add (temp 4-component vector of int)
0:45 add (temp 4-component vector of int)
0:44 add (temp 4-component vector of int)
0:43 add (temp 4-component vector of int)
0:42 add (temp 4-component vector of int)
0:41 add (temp 4-component vector of int)
0:40 add (temp 4-component vector of int)
0:40 Function Call: fn1(vi4; (temp 4-component vector of int)
0:40 Constant:
0:40 100 (const int)
0:40 100 (const int)
0:40 100 (const int)
0:40 100 (const int)
0:41 Function Call: fn1(vi4;vi4;i1[2];i1; (temp 4-component vector of int)
0:41 Constant:
0:41 101 (const int)
0:41 101 (const int)
0:41 101 (const int)
0:41 101 (const int)
0:41 ui4: direct index for structure (layout(offset=0 ) uniform 4-component vector of int)
0:41 'anon@0' (layout(row_major std140 ) uniform block{layout(offset=0 ) uniform 4-component vector of int ui4, layout(offset=16 ) uniform float ufvar})
0:41 Constant:
0:41 0 (const uint)
0:15 Constant:
0:15 1 (const int)
0:15 2 (const int)
0:16 Constant:
0:16 42 (const int)
0:42 Function Call: fn1(vi4;vi4;i1[2];i1; (temp 4-component vector of int)
0:42 Constant:
0:42 102 (const int)
0:42 102 (const int)
0:42 102 (const int)
0:42 102 (const int)
0:42 ui4: direct index for structure (layout(offset=0 ) uniform 4-component vector of int)
0:42 'anon@0' (layout(row_major std140 ) uniform block{layout(offset=0 ) uniform 4-component vector of int ui4, layout(offset=16 ) uniform float ufvar})
0:42 Constant:
0:42 0 (const uint)
0:42 'myarray' (temp 2-element array of int)
0:16 Constant:
0:16 42 (const int)
0:43 Function Call: fn1(vi4;vi4;i1[2];i1; (temp 4-component vector of int)
0:43 Constant:
0:43 103 (const int)
0:43 103 (const int)
0:43 103 (const int)
0:43 103 (const int)
0:43 ui4: direct index for structure (layout(offset=0 ) uniform 4-component vector of int)
0:43 'anon@0' (layout(row_major std140 ) uniform block{layout(offset=0 ) uniform 4-component vector of int ui4, layout(offset=16 ) uniform float ufvar})
0:43 Constant:
0:43 0 (const uint)
0:43 'myarray' (temp 2-element array of int)
0:43 Constant:
0:43 99 (const int)
0:44 Function Call: fn1(vi4;b1;b1; (temp 4-component vector of int)
0:44 Constant:
0:44 104 (const int)
0:44 104 (const int)
0:44 104 (const int)
0:44 104 (const int)
0:44 Constant:
0:44 false (const bool)
0:9 Constant:
0:9 false (const bool)
0:45 Function Call: fn1(vi4;b1;b1; (temp 4-component vector of int)
0:45 Constant:
0:45 105 (const int)
0:45 105 (const int)
0:45 105 (const int)
0:45 105 (const int)
0:45 Constant:
0:45 false (const bool)
0:45 Constant:
0:45 true (const bool)
0:47 Function Call: fn2(vi4; (temp 4-component vector of int)
0:47 Constant:
0:47 112 (const int)
0:47 112 (const int)
0:47 112 (const int)
0:47 112 (const int)
0:48 Function Call: fn2(vi4;i1; (temp 4-component vector of int)
0:48 Constant:
0:48 110 (const int)
0:48 110 (const int)
0:48 110 (const int)
0:48 110 (const int)
0:48 Constant:
0:48 11 (const int)
0:49 Function Call: fn2(vi4;i1; (temp 4-component vector of int)
0:49 Constant:
0:49 111 (const int)
0:49 111 (const int)
0:49 111 (const int)
0:49 111 (const int)
0:49 Constant:
0:49 12 (const int)
0:49 Branch: Return
0:? Linker Objects
0:? '@entryPointOutput' (layout(location=0 ) out 4-component vector of int)
0:? 'cia' (const int)
0:? -4 (const int)
0:? 'cib' (const int)
0:? -42 (const int)
0:? 'anon@0' (layout(row_major std140 ) uniform block{layout(offset=0 ) uniform 4-component vector of int ui4, layout(offset=16 ) uniform float ufvar})
SPIR-V is not generated for failed compile or link

View File

@ -0,0 +1,51 @@
uniform int4 ui4;
static const int cia = -4;
static const int cib = -42;
// ERROR: Ambiguous with fn1 below.
// int4 fn1(int4 p0) { return int4(1,2,3,4); }
int4 fn1(int4 p0, bool b1, bool b2 = false) {
return p0;
}
int4 fn1(int4 p0,
int4 p1 : FOO = int4(-1,-2,-3, cia),
int p2[2] : BAR = { int(1), 2 },
int p3 = abs(cib) )
{
return p0 + p1 + p2[0] + p3;
}
// These should not be ambiguous if given either an int or a float explicit second parameter.
int4 fn2(int4 p0, int x = 3)
{
return int4(10,11,12,13);
}
int4 fn2(int4 p0, float x = sin(3.3)) // OK to have a const expression as a default value
{
return p0 + int4(20,21,22,23);
}
void fn3(int p0 = 3) { }
int4 main() : SV_Target0
{
int myarray[2] = {30,31};
fn3();
fn3(5);
return fn1(100) +
fn1(101, ui4) +
fn1(102, ui4, myarray) +
fn1(103, ui4, myarray, 99) +
fn1(104, false) +
fn1(105, false, true) +
fn2(110, 11.11) + // calls int4, float form
fn2(111, 12); // calls int4, int form
}

View File

@ -0,0 +1,50 @@
uniform int4 ui4;
uniform float ufvar;
static const int cia = -4;
static const int cib = -42;
int4 fn1(int4 p0) { return int4(1,2,3,4); }
int4 fn1(int4 p0, bool b1, bool b2 = false) {
return p0;
}
int4 fn1(int4 p0,
int4 p1 : FOO = int4(-1,-2,-3, cia),
int p2[2] : BAR = { int(1), 2 },
int p3 = abs(cib) )
{
return p0 + p1 + p2[0] + p3;
}
// These should not be ambiguous if given either an int or a float explicit second parameter.
int4 fn2(int4 p0, int x = 3)
{
return int4(10,11,12,13);
}
int4 fn2(int4 p0, float x = ufvar) // ERROR: non-const expression
{
return p0 + int4(20,21,22,23);
}
void fn3(int p0 = 5, int p1) // ERROR no-default param after default param
{
}
int4 main() : SV_Target0
{
int myarray[2] = {30,31};
return fn1(100) + // ERROR: ambiguous
fn1(101, ui4) +
fn1(102, ui4, myarray) +
fn1(103, ui4, myarray, 99) +
fn1(104, false) +
fn1(105, false, true) +
fn2(112) + // ERROR: ambiguous
fn2(110, 11.11) + // calls int4, float form
fn2(111, 12); // calls int4, int form
}

View File

@ -629,6 +629,9 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TType& returnType)
//
TIntermTyped* TIntermediate::fold(TIntermAggregate* aggrNode)
{
if (aggrNode == nullptr)
return aggrNode;
if (! areAllChildConst(aggrNode))
return aggrNode;

View File

@ -348,13 +348,18 @@ const TFunction* TParseContextBase::selectFunction(
for (auto it = candidateList.begin(); it != candidateList.end(); ++it) {
const TFunction& candidate = *(*it);
// to even be a potential match, number of arguments has to match
if (call.getParamCount() != candidate.getParamCount())
// to even be a potential match, number of arguments must be >= the number of
// fixed (non-default) parameters, and <= the total (including parameter with defaults).
if (call.getParamCount() < candidate.getFixedParamCount() ||
call.getParamCount() > candidate.getParamCount())
continue;
// see if arguments are convertible
bool viable = true;
for (int param = 0; param < candidate.getParamCount(); ++param) {
// The call can have fewer parameters than the candidate, if some have defaults.
const int paramCount = std::min(call.getParamCount(), candidate.getParamCount());
for (int param = 0; param < paramCount; ++param) {
if (candidate[param].type->getQualifier().isParamInput()) {
if (! convertible(*call[param].type, *candidate[param].type, candidate.getBuiltInOp(), param)) {
viable = false;
@ -382,7 +387,7 @@ const TFunction* TParseContextBase::selectFunction(
return viableCandidates.front();
// 4. find best...
auto betterParam = [&call, &better](const TFunction& can1, const TFunction& can2) -> bool {
const auto betterParam = [&call, &better](const TFunction& can1, const TFunction& can2) -> bool {
// is call -> can2 better than call -> can1 for any parameter
bool hasBetterParam = false;
for (int param = 0; param < call.getParamCount(); ++param) {
@ -394,6 +399,16 @@ const TFunction* TParseContextBase::selectFunction(
return hasBetterParam;
};
const auto equivalentParams = [&call, &better](const TFunction& can1, const TFunction& can2) -> bool {
// is call -> can2 equivalent to call -> can1 for all the call parameters?
for (int param = 0; param < call.getParamCount(); ++param) {
if (better(*call[param].type, *can1[param].type, *can2[param].type) ||
better(*call[param].type, *can2[param].type, *can1[param].type))
return false;
}
return true;
};
const TFunction* incumbent = viableCandidates.front();
for (auto it = viableCandidates.begin() + 1; it != viableCandidates.end(); ++it) {
const TFunction& candidate = *(*it);
@ -406,7 +421,10 @@ const TFunction* TParseContextBase::selectFunction(
if (incumbent == *it)
continue;
const TFunction& candidate = *(*it);
if (betterParam(*incumbent, candidate))
// In the case of default parameters, it may have an identical initial set, which is
// also ambiguous
if (betterParam(*incumbent, candidate) || equivalentParams(*incumbent, candidate))
tie = true;
}

View File

@ -295,6 +295,7 @@ TFunction::TFunction(const TFunction& copyOf) : TSymbol(copyOf)
op = copyOf.op;
defined = copyOf.defined;
prototyped = copyOf.prototyped;
defaultParamCount = copyOf.defaultParamCount;
}
TFunction* TFunction::clone() const

View File

@ -191,6 +191,7 @@ protected:
struct TParameter {
TString *name;
TType* type;
TIntermTyped* defaultValue;
void copyParam(const TParameter& param)
{
if (param.name)
@ -198,6 +199,7 @@ struct TParameter {
else
name = 0;
type = param.type->clone();
defaultValue = param.defaultValue;
}
};
@ -209,12 +211,12 @@ public:
explicit TFunction(TOperator o) :
TSymbol(0),
op(o),
defined(false), prototyped(false) { }
defined(false), prototyped(false), defaultParamCount(0) { }
TFunction(const TString *name, const TType& retType, TOperator tOp = EOpNull) :
TSymbol(name),
mangledName(*name + '('),
op(tOp),
defined(false), prototyped(false) { returnType.shallowCopy(retType); }
defined(false), prototyped(false), defaultParamCount(0) { returnType.shallowCopy(retType); }
virtual TFunction* clone() const;
virtual ~TFunction();
@ -226,6 +228,9 @@ public:
assert(writable);
parameters.push_back(p);
p.type->appendMangledName(mangledName);
if (p.defaultValue != nullptr)
defaultParamCount++;
}
virtual const TString& getMangledName() const { return mangledName; }
@ -238,7 +243,13 @@ public:
virtual void setPrototyped() { assert(writable); prototyped = true; }
virtual bool isPrototyped() const { return prototyped; }
// Return total number of parameters
virtual int getParamCount() const { return static_cast<int>(parameters.size()); }
// Return number of parameters with default values.
virtual int getDefaultParamCount() const { return defaultParamCount; }
// Return number of fixed parameters (without default values)
virtual int getFixedParamCount() const { return getParamCount() - getDefaultParamCount(); }
virtual TParameter& operator[](int i) { assert(writable); return parameters[i]; }
virtual const TParameter& operator[](int i) const { return parameters[i]; }
@ -255,6 +266,7 @@ protected:
TOperator op;
bool defined;
bool prototyped;
int defaultParamCount;
};
//

View File

@ -160,6 +160,8 @@ INSTANTIATE_TEST_CASE_P(
{"hlsl.numericsuffixes.frag", "main"},
{"hlsl.numthreads.comp", "main_aux1"},
{"hlsl.overload.frag", "PixelShaderFunction"},
{"hlsl.params.default.frag", "main"},
{"hlsl.params.default.negative.frag", "main"},
{"hlsl.partialInit.frag", "PixelShaderFunction"},
{"hlsl.pp.line.frag", "main"},
{"hlsl.precise.frag", "main"},

View File

@ -1776,9 +1776,55 @@ bool HlslGrammar::acceptFunctionParameters(TFunction& function)
return true;
}
// default_parameter_declaration
// : EQUAL conditional_expression
// : EQUAL initializer
bool HlslGrammar::acceptDefaultParameterDeclaration(const TType& type, TIntermTyped*& node)
{
node = nullptr;
// Valid not to have a default_parameter_declaration
if (!acceptTokenClass(EHTokAssign))
return true;
if (!acceptConditionalExpression(node)) {
if (!acceptInitializer(node))
return false;
// For initializer lists, we have to const-fold into a constructor for the type, so build
// that.
TFunction* constructor = parseContext.handleConstructorCall(token.loc, type);
if (constructor == nullptr) // cannot construct
return false;
TIntermTyped* arguments = nullptr;
for (int i=0; i<int(node->getAsAggregate()->getSequence().size()); i++)
parseContext.handleFunctionArgument(constructor, arguments, node->getAsAggregate()->getSequence()[i]->getAsTyped());
node = parseContext.handleFunctionCall(token.loc, constructor, node);
}
// If this is simply a constant, we can use it directly.
if (node->getAsConstantUnion())
return true;
// Otherwise, it has to be const-foldable.
TIntermTyped* origNode = node;
node = intermediate.fold(node->getAsAggregate());
if (node != nullptr && origNode != node)
return true;
parseContext.error(token.loc, "invalid default parameter value", "", "");
return false;
}
// parameter_declaration
// : fully_specified_type post_decls
// | fully_specified_type identifier array_specifier post_decls
// : fully_specified_type post_decls [ = default_parameter_declaration ]
// | fully_specified_type identifier array_specifier post_decls [ = default_parameter_declaration ]
//
bool HlslGrammar::acceptParameterDeclaration(TFunction& function)
{
@ -1806,9 +1852,19 @@ bool HlslGrammar::acceptParameterDeclaration(TFunction& function)
// post_decls
acceptPostDecls(type->getQualifier());
TIntermTyped* defaultValue;
if (!acceptDefaultParameterDeclaration(*type, defaultValue))
return false;
parseContext.paramFix(*type);
TParameter param = { idToken.string, type };
// If any prior parameters have default values, all the parameters after that must as well.
if (defaultValue == nullptr && function.getDefaultParamCount() > 0) {
parseContext.error(idToken.loc, "invalid parameter after default value parameters", idToken.string->c_str(), "");
return false;
}
TParameter param = { idToken.string, type, defaultValue };
function.addParameter(param);
return true;

View File

@ -111,6 +111,7 @@ namespace glslang {
bool acceptDefaultLabel(TIntermNode*&);
void acceptArraySpecifier(TArraySizes*&);
void acceptPostDecls(TQualifier&);
bool acceptDefaultParameterDeclaration(const TType&, TIntermTyped*&);
HlslParseContext& parseContext; // state of parsing and helper functions for building the intermediate
TIntermediate& intermediate; // the final product, the intermediate representation, includes the AST

View File

@ -1375,7 +1375,7 @@ TIntermNode* HlslParseContext::handleReturnValue(const TSourceLoc& loc, TIntermT
void HlslParseContext::handleFunctionArgument(TFunction* function, TIntermTyped*& arguments, TIntermTyped* newArg)
{
TParameter param = { 0, new TType };
TParameter param = { 0, new TType, nullptr };
param.type->shallowCopy(newArg->getType());
function->addParameter(param);
if (arguments)
@ -2643,7 +2643,7 @@ void HlslParseContext::decomposeIntrinsic(const TSourceLoc& loc, TIntermTyped*&
// - user function
// - subroutine call (not implemented yet)
//
TIntermTyped* HlslParseContext::handleFunctionCall(const TSourceLoc& loc, TFunction* function, TIntermNode* arguments)
TIntermTyped* HlslParseContext::handleFunctionCall(const TSourceLoc& loc, TFunction* function, TIntermTyped* arguments)
{
TIntermTyped* result = nullptr;
@ -2783,10 +2783,10 @@ TIntermTyped* HlslParseContext::handleLengthMethod(const TSourceLoc& loc, TFunct
//
// Add any needed implicit conversions for function-call arguments to input parameters.
//
void HlslParseContext::addInputArgumentConversions(const TFunction& function, TIntermNode*& arguments)
void HlslParseContext::addInputArgumentConversions(const TFunction& function, TIntermTyped*& arguments)
{
TIntermAggregate* aggregate = arguments->getAsAggregate();
const auto setArg = [&](int argNum, TIntermNode* arg) {
const auto setArg = [&](int argNum, TIntermTyped* arg) {
if (function.getParamCount() == 1)
arguments = arg;
else {
@ -4483,8 +4483,8 @@ void HlslParseContext::mergeObjectLayoutQualifiers(TQualifier& dst, const TQuali
//
// Return the function symbol if found, otherwise nullptr.
//
const TFunction* HlslParseContext::findFunction(const TSourceLoc& loc, const TFunction& call, bool& builtIn,
TIntermNode* args)
const TFunction* HlslParseContext::findFunction(const TSourceLoc& loc, TFunction& call, bool& builtIn,
TIntermTyped*& args)
{
// const TFunction* function = nullptr;
@ -4583,6 +4583,22 @@ const TFunction* HlslParseContext::findFunction(const TSourceLoc& loc, const TFu
return false;
}
// Handle sampler betterness: An exact sampler match beats a non-exact match.
// (If we just looked at basic type, all EbtSamplers would look the same).
// If any type is not a sampler, just use the linearize function below.
if (from.getBasicType() == EbtSampler && to1.getBasicType() == EbtSampler && to2.getBasicType() == EbtSampler) {
// We can ignore the vector size in the comparison.
TSampler to1Sampler = to1.getSampler();
TSampler to2Sampler = to2.getSampler();
to1Sampler.vectorSize = to2Sampler.vectorSize = from.getSampler().vectorSize;
if (from.getSampler() == to2Sampler)
return from.getSampler() != to1Sampler;
if (from.getSampler() == to1Sampler)
return false;
}
// Might or might not be changing shape, which means basic type might
// or might not match, so within that, the question is how big a
// basic-type conversion is being done.
@ -4672,18 +4688,18 @@ const TFunction* HlslParseContext::findFunction(const TSourceLoc& loc, const TFu
// Handle aggregates: put all args into the new function call
for (int arg=0; arg<int(args->getAsAggregate()->getSequence().size()); ++arg) {
// TODO: But for constness, we could avoid the new & shallowCopy, and use the pointer directly.
TParameter param = { 0, new TType };
TParameter param = { 0, new TType, nullptr };
param.type->shallowCopy(args->getAsAggregate()->getSequence()[arg]->getAsTyped()->getType());
convertedCall.addParameter(param);
}
} else if (args->getAsUnaryNode()) {
// Handle unaries: put all args into the new function call
TParameter param = { 0, new TType };
TParameter param = { 0, new TType, nullptr };
param.type->shallowCopy(args->getAsUnaryNode()->getOperand()->getAsTyped()->getType());
convertedCall.addParameter(param);
} else if (args->getAsTyped()) {
// Handle bare e.g, floats, not in an aggregate.
TParameter param = { 0, new TType };
TParameter param = { 0, new TType, nullptr };
param.type->shallowCopy(args->getAsTyped()->getType());
convertedCall.addParameter(param);
} else {
@ -4701,6 +4717,13 @@ const TFunction* HlslParseContext::findFunction(const TSourceLoc& loc, const TFu
if (tie)
error(loc, "ambiguous best function under implicit type conversion", call.getName().c_str(), "");
// Append default parameter values if needed
if (!tie && bestMatch != nullptr) {
for (int defParam = call.getParamCount(); defParam < bestMatch->getParamCount(); ++defParam) {
handleFunctionArgument(&call, args, (*bestMatch)[defParam].defaultValue);
}
}
return bestMatch;
}

View File

@ -79,12 +79,12 @@ public:
TIntermNode* handleReturnValue(const TSourceLoc&, TIntermTyped*);
void handleFunctionArgument(TFunction*, TIntermTyped*& arguments, TIntermTyped* newArg);
TIntermTyped* handleAssign(const TSourceLoc&, TOperator, TIntermTyped* left, TIntermTyped* right) const;
TIntermTyped* handleFunctionCall(const TSourceLoc&, TFunction*, TIntermNode*);
TIntermTyped* handleFunctionCall(const TSourceLoc&, TFunction*, TIntermTyped*);
void decomposeIntrinsic(const TSourceLoc&, TIntermTyped*& node, TIntermNode* arguments);
void decomposeSampleMethods(const TSourceLoc&, TIntermTyped*& node, TIntermNode* arguments);
void decomposeGeometryMethods(const TSourceLoc&, TIntermTyped*& node, TIntermNode* arguments);
TIntermTyped* handleLengthMethod(const TSourceLoc&, TFunction*, TIntermNode*);
void addInputArgumentConversions(const TFunction&, TIntermNode*&);
void addInputArgumentConversions(const TFunction&, TIntermTyped*&);
TIntermTyped* addOutputArgumentConversions(const TFunction&, TIntermOperator&);
void builtInOpCheck(const TSourceLoc&, const TFunction&, TIntermOperator&);
TFunction* handleConstructorCall(const TSourceLoc&, const TType&);
@ -126,7 +126,7 @@ public:
void mergeObjectLayoutQualifiers(TQualifier& dest, const TQualifier& src, bool inheritOnly);
void checkNoShaderLayouts(const TSourceLoc&, const TShaderQualifiers&);
const TFunction* findFunction(const TSourceLoc& loc, const TFunction& call, bool& builtIn, TIntermNode* args);
const TFunction* findFunction(const TSourceLoc& loc, TFunction& call, bool& builtIn, TIntermTyped*& args);
void declareTypedef(const TSourceLoc&, TString& identifier, const TType&, TArraySizes* typeArray = 0);
TIntermNode* declareVariable(const TSourceLoc&, TString& identifier, TType&, TIntermTyped* initializer = 0);
void lengthenList(const TSourceLoc&, TIntermSequence& list, int size);

View File

@ -586,7 +586,7 @@ void TBuiltInParseablesHlsl::initialize(int /*version*/, EProfile /*profile*/, c
{ "DeviceMemoryBarrier", nullptr, nullptr, "-", "-", EShLangPSCS },
{ "DeviceMemoryBarrierWithGroupSync", nullptr, nullptr, "-", "-", EShLangCS },
{ "distance", "S", "F", "V,", "F,", EShLangAll },
{ "dot", "S", nullptr, "V,", "FI,", EShLangAll },
{ "dot", "S", nullptr, "SV,", "FI,", EShLangAll },
{ "dst", nullptr, nullptr, "V4,", "F,", EShLangAll },
// { "errorf", "-", "-", "", "", EShLangAll }, TODO: varargs
{ "EvaluateAttributeAtCentroid", nullptr, nullptr, "SVM", "F", EShLangPS },