diff --git a/Test/baseResults/hlsl.intrinsics.negative.frag.out b/Test/baseResults/hlsl.intrinsics.negative.frag.out index e27505432..0325c1c49 100644 --- a/Test/baseResults/hlsl.intrinsics.negative.frag.out +++ b/Test/baseResults/hlsl.intrinsics.negative.frag.out @@ -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 diff --git a/Test/baseResults/hlsl.params.default.frag.out b/Test/baseResults/hlsl.params.default.frag.out new file mode 100644 index 000000000..3c62c5db5 --- /dev/null +++ b/Test/baseResults/hlsl.params.default.frag.out @@ -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 diff --git a/Test/baseResults/hlsl.params.default.negative.frag.out b/Test/baseResults/hlsl.params.default.negative.frag.out new file mode 100644 index 000000000..fa723f3e1 --- /dev/null +++ b/Test/baseResults/hlsl.params.default.negative.frag.out @@ -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 diff --git a/Test/hlsl.params.default.frag b/Test/hlsl.params.default.frag new file mode 100644 index 000000000..42ad84f84 --- /dev/null +++ b/Test/hlsl.params.default.frag @@ -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 +} diff --git a/Test/hlsl.params.default.negative.frag b/Test/hlsl.params.default.negative.frag new file mode 100644 index 000000000..c9ff330b5 --- /dev/null +++ b/Test/hlsl.params.default.negative.frag @@ -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 +} diff --git a/glslang/MachineIndependent/Constant.cpp b/glslang/MachineIndependent/Constant.cpp index 61b6f67e7..537eb5d6a 100644 --- a/glslang/MachineIndependent/Constant.cpp +++ b/glslang/MachineIndependent/Constant.cpp @@ -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; diff --git a/glslang/MachineIndependent/ParseContextBase.cpp b/glslang/MachineIndependent/ParseContextBase.cpp index d86e19d24..872c27630 100644 --- a/glslang/MachineIndependent/ParseContextBase.cpp +++ b/glslang/MachineIndependent/ParseContextBase.cpp @@ -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; } diff --git a/glslang/MachineIndependent/SymbolTable.cpp b/glslang/MachineIndependent/SymbolTable.cpp index fb09fdf99..d34f4d2ca 100644 --- a/glslang/MachineIndependent/SymbolTable.cpp +++ b/glslang/MachineIndependent/SymbolTable.cpp @@ -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 diff --git a/glslang/MachineIndependent/SymbolTable.h b/glslang/MachineIndependent/SymbolTable.h index aeec34fc0..1cb08d6de 100644 --- a/glslang/MachineIndependent/SymbolTable.h +++ b/glslang/MachineIndependent/SymbolTable.h @@ -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(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; }; // diff --git a/gtests/Hlsl.FromFile.cpp b/gtests/Hlsl.FromFile.cpp index f0332aac6..2acd241a2 100644 --- a/gtests/Hlsl.FromFile.cpp +++ b/gtests/Hlsl.FromFile.cpp @@ -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"}, diff --git a/hlsl/hlslGrammar.cpp b/hlsl/hlslGrammar.cpp index b874aa8c9..d0f3b006a 100755 --- a/hlsl/hlslGrammar.cpp +++ b/hlsl/hlslGrammar.cpp @@ -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; igetAsAggregate()->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; diff --git a/hlsl/hlslGrammar.h b/hlsl/hlslGrammar.h index 8804b217e..8612c90de 100755 --- a/hlsl/hlslGrammar.h +++ b/hlsl/hlslGrammar.h @@ -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 diff --git a/hlsl/hlslParseHelper.cpp b/hlsl/hlslParseHelper.cpp index 62dac4bfa..46ae8970b 100755 --- a/hlsl/hlslParseHelper.cpp +++ b/hlsl/hlslParseHelper.cpp @@ -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; arggetAsAggregate()->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; } diff --git a/hlsl/hlslParseHelper.h b/hlsl/hlslParseHelper.h index d017a2a7c..6280ab424 100755 --- a/hlsl/hlslParseHelper.h +++ b/hlsl/hlslParseHelper.h @@ -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); diff --git a/hlsl/hlslParseables.cpp b/hlsl/hlslParseables.cpp index 8ecaec9dd..ee89af5b0 100755 --- a/hlsl/hlslParseables.cpp +++ b/hlsl/hlslParseables.cpp @@ -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 },