From d82c906378e6829ed8d1444e5be2cdac55ad1d7a Mon Sep 17 00:00:00 2001 From: John Kessenich Date: Mon, 23 May 2016 16:07:07 -0600 Subject: [PATCH] Vulkan: Finish semantics for what creates spec-const-semantics. Note: This required adding a new test mode to see the AST for vulkan tests. This also required reworking some deeper parts of type creation, regarding when storage qualification and constness is deduced bottom-up or dictated top-down. --- Test/baseResults/100.frag.out | 3 +- Test/baseResults/150.tesc.out | 18 +- Test/baseResults/420.tese.out | 18 +- Test/baseResults/430AofA.frag.out | 2 +- .../spv.specConstantComposite.vert.out | 130 +------ .../spv.specConstantOperations.vert.out | 83 +++-- Test/baseResults/vulkan.ast.vert.out | 324 ++++++++++++++++++ Test/spv.specConstantComposite.vert | 64 ++-- Test/spv.specConstantOperations.vert | 2 +- Test/vulkan.ast.vert | 42 +++ glslang/Include/Types.h | 1 + glslang/MachineIndependent/Intermediate.cpp | 54 ++- glslang/MachineIndependent/ParseHelper.cpp | 94 +++-- .../MachineIndependent/localintermediate.h | 1 - gtests/Spv.FromFile.cpp | 17 + gtests/TestFixture.cpp | 2 +- 16 files changed, 610 insertions(+), 245 deletions(-) create mode 100755 Test/baseResults/vulkan.ast.vert.out create mode 100644 Test/vulkan.ast.vert diff --git a/Test/baseResults/100.frag.out b/Test/baseResults/100.frag.out index 2c39cad43..7af716d84 100644 --- a/Test/baseResults/100.frag.out +++ b/Test/baseResults/100.frag.out @@ -2,7 +2,6 @@ ERROR: 0:3: '{ } style initializers' : not supported with this profile: es ERROR: 0:3: 'initializer' : not supported for this version or the enabled extensions ERROR: 0:3: 'array initializer' : not supported for this version or the enabled extensions -ERROR: 0:3: 'non-constant global initializer' : not supported with this profile: es ERROR: 0:4: '#version' : must occur first in shader ERROR: 0:7: 'attribute' : not supported in this stage: fragment ERROR: 0:7: 'float' : type requires declaration of default precision qualifier @@ -86,7 +85,7 @@ ERROR: 0:194: 'a' : can't use function syntax on variable ERROR: 0:214: 'non-constant global initializer' : not supported with this profile: es ERROR: 0:3000: '#error' : line of this error should be 3000 ERROR: 0:3002: '' : syntax error -ERROR: 78 compilation errors. No code generated. +ERROR: 77 compilation errors. No code generated. Shader version: 100 diff --git a/Test/baseResults/150.tesc.out b/Test/baseResults/150.tesc.out index 638ef82f1..78020e125 100644 --- a/Test/baseResults/150.tesc.out +++ b/Test/baseResults/150.tesc.out @@ -720,18 +720,18 @@ ERROR: node is still EOpNull! 420.tese Warning, version 420 is not yet complete; most version-specific features are present, but some are missing. -ERROR: 0:7: '=' : cannot convert from 'global 3-element array of float' to 'global 2-element array of float' -ERROR: 0:8: 'initializer list' : wrong vector size (or rows in a matrix column): global 2-component vector of float -ERROR: 0:9: 'initializer list' : wrong number of matrix columns: global 3X3 matrix of float -ERROR: 0:10: 'initializer list' : wrong number of matrix columns: global 2X2 matrix of float +ERROR: 0:7: '=' : cannot convert from 'const 3-element array of float' to 'global 2-element array of float' +ERROR: 0:8: 'initializer list' : wrong vector size (or rows in a matrix column): temp 2-component vector of float +ERROR: 0:9: 'initializer list' : wrong number of matrix columns: temp 3X3 matrix of float +ERROR: 0:10: 'initializer list' : wrong number of matrix columns: temp 2X2 matrix of float ERROR: 0:25: 'initializer list' : wrong number of structure members ERROR: 0:27: '=' : cannot convert from 'const bool' to 'global int' -ERROR: 0:28: 'constructor' : cannot convert parameter 2 from 'const float' to 'global 4-component vector of float' +ERROR: 0:28: 'constructor' : cannot convert parameter 2 from 'const float' to 'temp 4-component vector of float' ERROR: 0:29: 'constructor' : cannot convert parameter 2 from 'const 2X2 matrix of float' to 'const 4-component vector of float' ERROR: 0:29: 'const 2-element array of 4-component vector of float' : cannot construct with these arguments ERROR: 0:29: '=' : cannot convert from 'const float' to 'global 2-element array of 4-component vector of float' -ERROR: 0:30: 'initializer list' : wrong number of matrix columns: global 4X2 matrix of float -ERROR: 0:40: 'constructor' : cannot convert parameter 1 from 'temp float' to 'global structure{global float s, global float t}' +ERROR: 0:30: 'initializer list' : wrong number of matrix columns: temp 4X2 matrix of float +ERROR: 0:40: 'constructor' : cannot convert parameter 1 from 'temp float' to 'temp structure{global float s, global float t}' ERROR: 0:58: 'initializer list' : wrong number of structure members ERROR: 13 compilation errors. No code generated. @@ -780,7 +780,7 @@ ERROR: node is still EOpNull! 0:68 Sequence 0:68 move second child to first child (temp 3-component vector of float) 0:68 'bv3' (global 3-component vector of float) -0:68 Construct vec3 (global 3-component vector of float) +0:68 Construct vec3 (temp 3-component vector of float) 0:68 'vc1' (global float) 0:68 'vc2' (global float) 0:68 'vc3' (global float) @@ -1534,7 +1534,7 @@ ERROR: node is still EOpNull! 0:68 Sequence 0:68 move second child to first child (temp 3-component vector of float) 0:68 'bv3' (global 3-component vector of float) -0:68 Construct vec3 (global 3-component vector of float) +0:68 Construct vec3 (temp 3-component vector of float) 0:68 'vc1' (global float) 0:68 'vc2' (global float) 0:68 'vc3' (global float) diff --git a/Test/baseResults/420.tese.out b/Test/baseResults/420.tese.out index 26eac1030..fb9bc2013 100644 --- a/Test/baseResults/420.tese.out +++ b/Test/baseResults/420.tese.out @@ -1,17 +1,17 @@ 420.tese Warning, version 420 is not yet complete; most version-specific features are present, but some are missing. -ERROR: 0:7: '=' : cannot convert from 'global 3-element array of float' to 'global 2-element array of float' -ERROR: 0:8: 'initializer list' : wrong vector size (or rows in a matrix column): global 2-component vector of float -ERROR: 0:9: 'initializer list' : wrong number of matrix columns: global 3X3 matrix of float -ERROR: 0:10: 'initializer list' : wrong number of matrix columns: global 2X2 matrix of float +ERROR: 0:7: '=' : cannot convert from 'const 3-element array of float' to 'global 2-element array of float' +ERROR: 0:8: 'initializer list' : wrong vector size (or rows in a matrix column): temp 2-component vector of float +ERROR: 0:9: 'initializer list' : wrong number of matrix columns: temp 3X3 matrix of float +ERROR: 0:10: 'initializer list' : wrong number of matrix columns: temp 2X2 matrix of float ERROR: 0:25: 'initializer list' : wrong number of structure members ERROR: 0:27: '=' : cannot convert from 'const bool' to 'global int' -ERROR: 0:28: 'constructor' : cannot convert parameter 2 from 'const float' to 'global 4-component vector of float' +ERROR: 0:28: 'constructor' : cannot convert parameter 2 from 'const float' to 'temp 4-component vector of float' ERROR: 0:29: 'constructor' : cannot convert parameter 2 from 'const 2X2 matrix of float' to 'const 4-component vector of float' ERROR: 0:29: 'const 2-element array of 4-component vector of float' : cannot construct with these arguments ERROR: 0:29: '=' : cannot convert from 'const float' to 'global 2-element array of 4-component vector of float' -ERROR: 0:30: 'initializer list' : wrong number of matrix columns: global 4X2 matrix of float -ERROR: 0:40: 'constructor' : cannot convert parameter 1 from 'temp float' to 'global structure{global float s, global float t}' +ERROR: 0:30: 'initializer list' : wrong number of matrix columns: temp 4X2 matrix of float +ERROR: 0:40: 'constructor' : cannot convert parameter 1 from 'temp float' to 'temp structure{global float s, global float t}' ERROR: 0:58: 'initializer list' : wrong number of structure members ERROR: 13 compilation errors. No code generated. @@ -60,7 +60,7 @@ ERROR: node is still EOpNull! 0:68 Sequence 0:68 move second child to first child (temp 3-component vector of float) 0:68 'bv3' (global 3-component vector of float) -0:68 Construct vec3 (global 3-component vector of float) +0:68 Construct vec3 (temp 3-component vector of float) 0:68 'vc1' (global float) 0:68 'vc2' (global float) 0:68 'vc3' (global float) @@ -210,7 +210,7 @@ ERROR: node is still EOpNull! 0:68 Sequence 0:68 move second child to first child (temp 3-component vector of float) 0:68 'bv3' (global 3-component vector of float) -0:68 Construct vec3 (global 3-component vector of float) +0:68 Construct vec3 (temp 3-component vector of float) 0:68 'vc1' (global float) 0:68 'vc2' (global float) 0:68 'vc3' (global float) diff --git a/Test/baseResults/430AofA.frag.out b/Test/baseResults/430AofA.frag.out index e8b79b7ee..68285f737 100644 --- a/Test/baseResults/430AofA.frag.out +++ b/Test/baseResults/430AofA.frag.out @@ -6,7 +6,7 @@ ERROR: 0:15: 'constructior' : array constructor argument not correct type to con ERROR: 0:28: '[' : array index out of range '4' ERROR: 0:56: 'constructor' : cannot convert parameter 2 from 'const 3-element array of 4-component vector of float' to 'temp 2-element array of 4-component vector of float' ERROR: 0:60: 'constructor' : cannot convert parameter 2 from 'const 2-element array of 4-component vector of float' to 'temp 3-element array of 4-component vector of float' -ERROR: 0:64: '=' : cannot convert from 'temp 3-element array of 2-element array of 4-component vector of float' to 'temp 4-element array of 2-element array of 4-component vector of float' +ERROR: 0:64: '=' : cannot convert from 'const 3-element array of 2-element array of 4-component vector of float' to 'temp 4-element array of 2-element array of 4-component vector of float' ERROR: 0:70: 'assign' : cannot convert from 'global 4-element array of 7-element array of float' to 'global 5-element array of 7-element array of float' ERROR: 0:71: 'assign' : cannot convert from 'global 4-element array of 7-element array of float' to 'global implicitly-sized array of 7-element array of float' ERROR: 0:73: 'foo' : no matching overloaded function found diff --git a/Test/baseResults/spv.specConstantComposite.vert.out b/Test/baseResults/spv.specConstantComposite.vert.out index ac101f289..c4585e40d 100644 --- a/Test/baseResults/spv.specConstantComposite.vert.out +++ b/Test/baseResults/spv.specConstantComposite.vert.out @@ -7,13 +7,13 @@ Linked vertex stage: // Module Version 10000 // Generated by (magic number): 80001 -// Id's are bound by 119 +// Id's are bound by 43 Capability Shader Capability Float64 1: ExtInstImport "GLSL.std.450" MemoryModel Logical GLSL450 - EntryPoint Vertex 4 "main" 27 118 + EntryPoint Vertex 4 "main" 27 42 Source GLSL 450 Name 4 "main" Name 6 "refer_primary_spec_const(" @@ -23,23 +23,12 @@ Linked vertex stage: Name 16 "refer_spec_const_array_length(" Name 18 "declare_spec_const_in_func(" Name 27 "color" - Name 42 "flat_struct" - MemberName 42(flat_struct) 0 "i" - MemberName 42(flat_struct) 1 "f" - MemberName 42(flat_struct) 2 "d" - MemberName 42(flat_struct) 3 "b" - Name 44 "nesting_struct" - MemberName 44(nesting_struct) 0 "nested" - MemberName 44(nesting_struct) 1 "v" - MemberName 44(nesting_struct) 2 "i" - Name 72 "indexable" - Name 76 "indexable" - Name 83 "len" - Name 118 "global_vec4_array_with_spec_length" + Name 33 "len" + Name 42 "global_vec4_array_with_spec_length" Decorate 21 SpecId 203 Decorate 28 SpecId 200 - Decorate 32 SpecId 201 - Decorate 41 SpecId 202 + Decorate 37 SpecId 201 + Decorate 39 SpecId 202 2: TypeVoid 3: TypeFunction 2 14: TypeInt 32 1 @@ -51,58 +40,13 @@ Linked vertex stage: 26: TypePointer Output 25(fvec4) 27(color): 26(ptr) Variable Output 28: 14(int) SpecConstant 3 - 32: 24(float) SpecConstant 1078523331 - 33: 25(fvec4) SpecConstantComposite 32 32 32 32 - 36: 24(float) Constant 1133908460 - 37: 25(fvec4) SpecConstantComposite 32 32 36 36 - 40: TypeFloat 64 - 41: 40(float) SpecConstant 1413754136 1074340347 - 42(flat_struct): TypeStruct 14(int) 24(float) 40(float) 20(bool) - 43:42(flat_struct) SpecConstantComposite 28 32 41 21 -44(nesting_struct): TypeStruct 42(flat_struct) 25(fvec4) 14(int) - 45:44(nesting_struct) SpecConstantComposite 43 33 28 - 46: 14(int) Constant 2 - 51: TypeInt 32 0 - 52: 51(int) Constant 0 - 57: 24(float) Constant 1065353216 - 58: 24(float) Constant 1073741824 - 59: 24(float) Constant 1077936128 - 60: 51(int) Constant 5 - 61: TypeArray 24(float) 60 - 62: 61 SpecConstantComposite 32 32 57 58 59 - 63: 14(int) Constant 1 - 68: 14(int) Constant 30 - 69: TypeArray 14(int) 60 - 70: 69 SpecConstantComposite 28 28 63 46 68 - 71: TypePointer Function 69 - 73: TypePointer Function 14(int) - 87: 24(float) Constant 1106321080 - 88:42(flat_struct) SpecConstantComposite 68 87 41 21 - 89: 14(int) Constant 10 - 90:44(nesting_struct) SpecConstantComposite 88 37 89 - 96: 20(bool) ConstantFalse - 97:42(flat_struct) SpecConstantComposite 28 32 41 96 - 98: 24(float) Constant 1036831949 - 99: 25(fvec4) ConstantComposite 98 98 98 98 - 100:44(nesting_struct) SpecConstantComposite 97 99 28 - 101: 25(fvec4) SpecConstantComposite 32 32 32 32 - 102: 24(float) Constant 1066192077 - 103: 24(float) Constant 1074580685 - 104: 24(float) Constant 1079194419 - 105: TypeVector 24(float) 3 - 106: TypeMatrix 105(fvec3) 2 - 107: 24(float) Constant 0 - 108: 105(fvec3) SpecConstantComposite 32 32 32 - 109: 105(fvec3) ConstantComposite 102 103 104 - 110: 106 SpecConstantComposite 108 109 - 111: 105(fvec3) SpecConstantComposite 32 107 107 - 112: 105(fvec3) SpecConstantComposite 107 32 107 - 113: 106 SpecConstantComposite 111 112 - 114: 14(int) Constant 3000 - 115:44(nesting_struct) SpecConstantComposite 88 37 114 - 116: TypeArray 25(fvec4) 28 - 117: TypePointer Input 116 -118(global_vec4_array_with_spec_length): 117(ptr) Variable Input + 32: TypePointer Function 14(int) + 37: 24(float) SpecConstant 1078523331 + 38: TypeFloat 64 + 39: 38(float) SpecConstant 1413754136 1074340347 + 40: TypeArray 25(fvec4) 28 + 41: TypePointer Input 40 +42(global_vec4_array_with_spec_length): 41(ptr) Variable Input 4(main): 2 Function None 3 5: Label Return @@ -122,64 +66,24 @@ Linked vertex stage: FunctionEnd 8(refer_composite_spec_const(): 2 Function None 3 9: Label - 34: 25(fvec4) Load 27(color) - 35: 25(fvec4) FAdd 34 33 - Store 27(color) 35 - 38: 25(fvec4) Load 27(color) - 39: 25(fvec4) FSub 38 37 - Store 27(color) 39 Return FunctionEnd 10(refer_copmosite_dot_dereference(): 2 Function None 3 11: Label - 47: 14(int) CompositeExtract 45 2 - 48: 24(float) ConvertSToF 47 - 49: 25(fvec4) Load 27(color) - 50: 25(fvec4) VectorTimesScalar 49 48 - Store 27(color) 50 - 53: 24(float) CompositeExtract 33 0 - 54: 25(fvec4) Load 27(color) - 55: 25(fvec4) CompositeConstruct 53 53 53 53 - 56: 25(fvec4) FAdd 54 55 - Store 27(color) 56 Return FunctionEnd 12(refer_composite_bracket_dereference(): 2 Function None 3 13: Label - 72(indexable): 71(ptr) Variable Function - 76(indexable): 71(ptr) Variable Function - 64: 24(float) CompositeExtract 62 1 - 65: 25(fvec4) Load 27(color) - 66: 25(fvec4) CompositeConstruct 64 64 64 64 - 67: 25(fvec4) FSub 65 66 - Store 27(color) 67 - Store 72(indexable) 70 - 74: 73(ptr) AccessChain 72(indexable) 28 - 75: 14(int) Load 74 - Store 76(indexable) 70 - 77: 73(ptr) AccessChain 76(indexable) 75 - 78: 14(int) Load 77 - 79: 24(float) ConvertSToF 78 - 80: 25(fvec4) Load 27(color) - 81: 25(fvec4) CompositeConstruct 79 79 79 79 - 82: 25(fvec4) FDiv 80 81 - Store 27(color) 82 Return FunctionEnd 16(refer_spec_const_array_length(): 14(int) Function None 15 17: Label - 83(len): 73(ptr) Variable Function - Store 83(len) 28 - 84: 14(int) Load 83(len) - ReturnValue 84 + 33(len): 32(ptr) Variable Function + Store 33(len) 28 + 34: 14(int) Load 33(len) + ReturnValue 34 FunctionEnd 18(declare_spec_const_in_func(): 2 Function None 3 19: Label - 91: 14(int) CompositeExtract 90 2 - 92: 24(float) ConvertSToF 91 - 93: 25(fvec4) Load 27(color) - 94: 25(fvec4) CompositeConstruct 92 92 92 92 - 95: 25(fvec4) FDiv 93 94 - Store 27(color) 95 Return FunctionEnd diff --git a/Test/baseResults/spv.specConstantOperations.vert.out b/Test/baseResults/spv.specConstantOperations.vert.out index 39de987da..ea4c69a2d 100644 --- a/Test/baseResults/spv.specConstantOperations.vert.out +++ b/Test/baseResults/spv.specConstantOperations.vert.out @@ -7,7 +7,7 @@ Linked vertex stage: // Module Version 10000 // Generated by (magic number): 80001 -// Id's are bound by 134 +// Id's are bound by 131 Capability Shader 1: ExtInstImport "GLSL.std.450" @@ -91,48 +91,45 @@ Linked vertex stage: 89: 41(int) Constant 4294967294 90: TypeVector 41(int) 4 91: 90(ivec4) SpecConstantComposite 42 42 88 89 - 92: 39(float) Constant 1067450368 - 93: TypeVector 39(float) 4 - 94: 93(fvec4) SpecConstantComposite 40 92 40 92 - 95: TypeVector 22(bool) 4 - 96: 90(ivec4) ConstantComposite 44 44 44 44 - 97: 95(bvec4) SpecConstantOp 171 87 96 - 98: 95(bvec4) SpecConstantOp 171 91 96 - 99: 86(ivec4) ConstantComposite 12 12 12 12 - 100: 86(ivec4) ConstantComposite 32 32 32 32 - 101: 86(ivec4) SpecConstantOp 169 97 100 99 - 102: 90(ivec4) ConstantComposite 48 48 48 48 - 103: 90(ivec4) SpecConstantOp 169 97 102 96 - 104: 90(ivec4) SpecConstantOp 128 87 96 - 105: 86(ivec4) SpecConstantOp 128 91 96 - 106: 86(ivec4) SpecConstantOp 200 87 - 107: 86(ivec4) SpecConstantOp 126 87 - 108: 86(ivec4) ConstantComposite 20 20 20 20 - 109: 86(ivec4) SpecConstantOp 128 87 108 - 110: 86(ivec4) SpecConstantOp 128 87 108 - 111: 86(ivec4) ConstantComposite 56 56 56 56 - 112: 86(ivec4) SpecConstantOp 130 110 111 - 113: 86(ivec4) ConstantComposite 58 58 58 58 - 114: 86(ivec4) SpecConstantOp 130 112 113 - 115: 86(ivec4) SpecConstantOp 132 87 108 - 116: 86(ivec4) ConstantComposite 63 63 63 63 - 117: 86(ivec4) SpecConstantOp 135 115 116 - 118: 86(ivec4) SpecConstantOp 139 87 113 - 119: 86(ivec4) ConstantComposite 72 72 72 72 - 120: 86(ivec4) SpecConstantOp 195 87 119 - 121: 86(ivec4) SpecConstantOp 196 87 108 - 122: 6(int) Constant 1024 - 123: 86(ivec4) ConstantComposite 122 122 122 122 - 124: 86(ivec4) SpecConstantOp 197 87 123 - 125: 41(int) Constant 2048 - 126: 90(ivec4) ConstantComposite 125 125 125 125 - 127: 90(ivec4) SpecConstantOp 198 91 126 - 128: 6(int) SpecConstantOp 81 87 0 - 129: TypeVector 6(int) 2 - 130: 129(ivec2) SpecConstantOp 79 87 87 1(GLSL.std.450) 0 - 131: TypeVector 6(int) 3 - 132: 131(ivec3) SpecConstantOp 79 87 87 2 1(GLSL.std.450) 0 - 133: 86(ivec4) SpecConstantOp 79 87 87 1(GLSL.std.450) 2 0 3 + 92: TypeVector 22(bool) 4 + 93: 90(ivec4) ConstantComposite 44 44 44 44 + 94: 92(bvec4) SpecConstantOp 171 87 93 + 95: 92(bvec4) SpecConstantOp 171 91 93 + 96: 86(ivec4) ConstantComposite 12 12 12 12 + 97: 86(ivec4) ConstantComposite 32 32 32 32 + 98: 86(ivec4) SpecConstantOp 169 94 97 96 + 99: 90(ivec4) ConstantComposite 48 48 48 48 + 100: 90(ivec4) SpecConstantOp 169 94 99 93 + 101: 90(ivec4) SpecConstantOp 128 87 93 + 102: 86(ivec4) SpecConstantOp 128 91 93 + 103: 86(ivec4) SpecConstantOp 200 87 + 104: 86(ivec4) SpecConstantOp 126 87 + 105: 86(ivec4) ConstantComposite 20 20 20 20 + 106: 86(ivec4) SpecConstantOp 128 87 105 + 107: 86(ivec4) SpecConstantOp 128 87 105 + 108: 86(ivec4) ConstantComposite 56 56 56 56 + 109: 86(ivec4) SpecConstantOp 130 107 108 + 110: 86(ivec4) ConstantComposite 58 58 58 58 + 111: 86(ivec4) SpecConstantOp 130 109 110 + 112: 86(ivec4) SpecConstantOp 132 87 105 + 113: 86(ivec4) ConstantComposite 63 63 63 63 + 114: 86(ivec4) SpecConstantOp 135 112 113 + 115: 86(ivec4) SpecConstantOp 139 87 110 + 116: 86(ivec4) ConstantComposite 72 72 72 72 + 117: 86(ivec4) SpecConstantOp 195 87 116 + 118: 86(ivec4) SpecConstantOp 196 87 105 + 119: 6(int) Constant 1024 + 120: 86(ivec4) ConstantComposite 119 119 119 119 + 121: 86(ivec4) SpecConstantOp 197 87 120 + 122: 41(int) Constant 2048 + 123: 90(ivec4) ConstantComposite 122 122 122 122 + 124: 90(ivec4) SpecConstantOp 198 91 123 + 125: 6(int) SpecConstantOp 81 87 0 + 126: TypeVector 6(int) 2 + 127: 126(ivec2) SpecConstantOp 79 87 87 1(GLSL.std.450) 0 + 128: TypeVector 6(int) 3 + 129: 128(ivec3) SpecConstantOp 79 87 87 2 1(GLSL.std.450) 0 + 130: 86(ivec4) SpecConstantOp 79 87 87 1(GLSL.std.450) 2 0 3 4(main): 2 Function None 3 5: Label Return diff --git a/Test/baseResults/vulkan.ast.vert.out b/Test/baseResults/vulkan.ast.vert.out new file mode 100755 index 000000000..31ac4940e --- /dev/null +++ b/Test/baseResults/vulkan.ast.vert.out @@ -0,0 +1,324 @@ +vulkan.ast.vert +Warning, version 450 is not yet complete; most version-specific features are present, but some are missing. + +Shader version: 450 +0:? Sequence +0:7 Function Definition: main( (global void) +0:7 Function Parameters: +0:9 Sequence +0:9 Convert float to bool (temp bool) +0:9 'scf1' (specialization-constant const float) +0:9 1.000000 +0:10 Construct bool (specialization-constant const bool) +0:10 'scbt' (specialization-constant const bool) +0:10 true (const bool) +0:11 Convert int to bool (specialization-constant const bool) +0:11 'sci2' (specialization-constant const int) +0:11 2 (const int) +0:13 Construct float (temp float) +0:13 'scf1' (specialization-constant const float) +0:13 1.000000 +0:14 Convert bool to float (temp float) +0:14 'scbt' (specialization-constant const bool) +0:14 true (const bool) +0:15 Convert int to float (temp float) +0:15 'sci2' (specialization-constant const int) +0:15 2 (const int) +0:17 Convert float to int (temp int) +0:17 'scf1' (specialization-constant const float) +0:17 1.000000 +0:18 Convert bool to int (specialization-constant const int) +0:18 'scbt' (specialization-constant const bool) +0:18 true (const bool) +0:19 Construct int (specialization-constant const int) +0:19 'sci2' (specialization-constant const int) +0:19 2 (const int) +0:21 component-wise multiply (temp float) +0:21 'scf1' (specialization-constant const float) +0:21 1.000000 +0:21 'scf1' (specialization-constant const float) +0:21 1.000000 +0:22 logical-or (specialization-constant const bool) +0:22 'scbt' (specialization-constant const bool) +0:22 true (const bool) +0:22 'scbt' (specialization-constant const bool) +0:22 true (const bool) +0:23 component-wise multiply (specialization-constant const int) +0:23 'sci2' (specialization-constant const int) +0:23 2 (const int) +0:23 'sci2' (specialization-constant const int) +0:23 2 (const int) +0:24 add (temp float) +0:24 'scf1' (specialization-constant const float) +0:24 1.000000 +0:24 Convert int to float (temp float) +0:24 'sci2' (specialization-constant const int) +0:24 2 (const int) +0:26 Negate value (temp float) +0:26 'scf1' (specialization-constant const float) +0:26 1.000000 +0:27 Negate conditional (specialization-constant const bool) +0:27 'scbt' (specialization-constant const bool) +0:27 true (const bool) +0:28 Negate value (specialization-constant const int) +0:28 'sci2' (specialization-constant const int) +0:28 2 (const int) +0:30 Compare Greater Than (temp bool) +0:30 'scf1' (specialization-constant const float) +0:30 1.000000 +0:30 'scf1' (specialization-constant const float) +0:30 1.000000 +0:31 Compare Greater Than (specialization-constant const bool) +0:31 'sci2' (specialization-constant const int) +0:31 2 (const int) +0:31 'sci2' (specialization-constant const int) +0:31 2 (const int) +0:33 Compare Not Equal (temp bool) +0:33 'scf1' (specialization-constant const float) +0:33 1.000000 +0:33 'scf1' (specialization-constant const float) +0:33 1.000000 +0:34 Compare Not Equal (specialization-constant const bool) +0:34 'scbt' (specialization-constant const bool) +0:34 true (const bool) +0:34 'scbt' (specialization-constant const bool) +0:34 true (const bool) +0:35 Compare Not Equal (specialization-constant const bool) +0:35 'sci2' (specialization-constant const int) +0:35 2 (const int) +0:35 'sci2' (specialization-constant const int) +0:35 2 (const int) +0:37 Construct ivec2 (specialization-constant const 2-component vector of int) +0:37 'sci2' (specialization-constant const int) +0:37 2 (const int) +0:37 'sci2' (specialization-constant const int) +0:37 2 (const int) +0:38 Construct ivec2 (temp 2-element array of 2-component vector of int) +0:38 Construct ivec2 (specialization-constant const 2-component vector of int) +0:38 'sci2' (specialization-constant const int) +0:38 2 (const int) +0:38 'sci2' (specialization-constant const int) +0:38 2 (const int) +0:38 Construct ivec2 (specialization-constant const 2-component vector of int) +0:38 'sci2' (specialization-constant const int) +0:38 2 (const int) +0:38 'sci2' (specialization-constant const int) +0:38 2 (const int) +0:40 Construct vec2 (temp 2-component vector of float) +0:40 'scf1' (specialization-constant const float) +0:40 1.000000 +0:40 'scf1' (specialization-constant const float) +0:40 1.000000 +0:41 Construct vec2 (temp 2-element array of 2-component vector of float) +0:41 Construct vec2 (temp 2-component vector of float) +0:41 'scf1' (specialization-constant const float) +0:41 1.000000 +0:41 'scf1' (specialization-constant const float) +0:41 1.000000 +0:41 Construct vec2 (temp 2-component vector of float) +0:41 'scf1' (specialization-constant const float) +0:41 1.000000 +0:41 'scf1' (specialization-constant const float) +0:41 1.000000 +0:? Linker Objects +0:? 'scf1' (specialization-constant const float) +0:? 1.000000 +0:? 'scbt' (specialization-constant const bool) +0:? true (const bool) +0:? 'sci2' (specialization-constant const int) +0:? 2 (const int) + + +Linked vertex stage: + + +Shader version: 450 +0:? Sequence +0:7 Function Definition: main( (global void) +0:7 Function Parameters: +0:9 Sequence +0:9 Convert float to bool (temp bool) +0:9 'scf1' (specialization-constant const float) +0:9 1.000000 +0:10 Construct bool (specialization-constant const bool) +0:10 'scbt' (specialization-constant const bool) +0:10 true (const bool) +0:11 Convert int to bool (specialization-constant const bool) +0:11 'sci2' (specialization-constant const int) +0:11 2 (const int) +0:13 Construct float (temp float) +0:13 'scf1' (specialization-constant const float) +0:13 1.000000 +0:14 Convert bool to float (temp float) +0:14 'scbt' (specialization-constant const bool) +0:14 true (const bool) +0:15 Convert int to float (temp float) +0:15 'sci2' (specialization-constant const int) +0:15 2 (const int) +0:17 Convert float to int (temp int) +0:17 'scf1' (specialization-constant const float) +0:17 1.000000 +0:18 Convert bool to int (specialization-constant const int) +0:18 'scbt' (specialization-constant const bool) +0:18 true (const bool) +0:19 Construct int (specialization-constant const int) +0:19 'sci2' (specialization-constant const int) +0:19 2 (const int) +0:21 component-wise multiply (temp float) +0:21 'scf1' (specialization-constant const float) +0:21 1.000000 +0:21 'scf1' (specialization-constant const float) +0:21 1.000000 +0:22 logical-or (specialization-constant const bool) +0:22 'scbt' (specialization-constant const bool) +0:22 true (const bool) +0:22 'scbt' (specialization-constant const bool) +0:22 true (const bool) +0:23 component-wise multiply (specialization-constant const int) +0:23 'sci2' (specialization-constant const int) +0:23 2 (const int) +0:23 'sci2' (specialization-constant const int) +0:23 2 (const int) +0:24 add (temp float) +0:24 'scf1' (specialization-constant const float) +0:24 1.000000 +0:24 Convert int to float (temp float) +0:24 'sci2' (specialization-constant const int) +0:24 2 (const int) +0:26 Negate value (temp float) +0:26 'scf1' (specialization-constant const float) +0:26 1.000000 +0:27 Negate conditional (specialization-constant const bool) +0:27 'scbt' (specialization-constant const bool) +0:27 true (const bool) +0:28 Negate value (specialization-constant const int) +0:28 'sci2' (specialization-constant const int) +0:28 2 (const int) +0:30 Compare Greater Than (temp bool) +0:30 'scf1' (specialization-constant const float) +0:30 1.000000 +0:30 'scf1' (specialization-constant const float) +0:30 1.000000 +0:31 Compare Greater Than (specialization-constant const bool) +0:31 'sci2' (specialization-constant const int) +0:31 2 (const int) +0:31 'sci2' (specialization-constant const int) +0:31 2 (const int) +0:33 Compare Not Equal (temp bool) +0:33 'scf1' (specialization-constant const float) +0:33 1.000000 +0:33 'scf1' (specialization-constant const float) +0:33 1.000000 +0:34 Compare Not Equal (specialization-constant const bool) +0:34 'scbt' (specialization-constant const bool) +0:34 true (const bool) +0:34 'scbt' (specialization-constant const bool) +0:34 true (const bool) +0:35 Compare Not Equal (specialization-constant const bool) +0:35 'sci2' (specialization-constant const int) +0:35 2 (const int) +0:35 'sci2' (specialization-constant const int) +0:35 2 (const int) +0:37 Construct ivec2 (specialization-constant const 2-component vector of int) +0:37 'sci2' (specialization-constant const int) +0:37 2 (const int) +0:37 'sci2' (specialization-constant const int) +0:37 2 (const int) +0:38 Construct ivec2 (temp 2-element array of 2-component vector of int) +0:38 Construct ivec2 (specialization-constant const 2-component vector of int) +0:38 'sci2' (specialization-constant const int) +0:38 2 (const int) +0:38 'sci2' (specialization-constant const int) +0:38 2 (const int) +0:38 Construct ivec2 (specialization-constant const 2-component vector of int) +0:38 'sci2' (specialization-constant const int) +0:38 2 (const int) +0:38 'sci2' (specialization-constant const int) +0:38 2 (const int) +0:40 Construct vec2 (temp 2-component vector of float) +0:40 'scf1' (specialization-constant const float) +0:40 1.000000 +0:40 'scf1' (specialization-constant const float) +0:40 1.000000 +0:41 Construct vec2 (temp 2-element array of 2-component vector of float) +0:41 Construct vec2 (temp 2-component vector of float) +0:41 'scf1' (specialization-constant const float) +0:41 1.000000 +0:41 'scf1' (specialization-constant const float) +0:41 1.000000 +0:41 Construct vec2 (temp 2-component vector of float) +0:41 'scf1' (specialization-constant const float) +0:41 1.000000 +0:41 'scf1' (specialization-constant const float) +0:41 1.000000 +0:? Linker Objects +0:? 'scf1' (specialization-constant const float) +0:? 1.000000 +0:? 'scbt' (specialization-constant const bool) +0:? true (const bool) +0:? 'sci2' (specialization-constant const int) +0:? 2 (const int) + +// Module Version 10000 +// Generated by (magic number): 80001 +// Id's are bound by 50 + + Capability Shader + 1: ExtInstImport "GLSL.std.450" + MemoryModel Logical GLSL450 + EntryPoint Vertex 4 "main" + Source GLSL 450 + Name 4 "main" + Decorate 7 SpecId 200 + Decorate 11 SpecId 201 + Decorate 13 SpecId 202 + 2: TypeVoid + 3: TypeFunction 2 + 6: TypeFloat 32 + 7: 6(float) SpecConstant 1065353216 + 8: TypeBool + 9: 6(float) Constant 0 + 11: 8(bool) SpecConstantTrue + 12: TypeInt 32 1 + 13: 12(int) SpecConstant 2 + 14: TypeInt 32 0 + 15: 14(int) Constant 0 + 16: 8(bool) SpecConstantOp 171 13 15 + 17: 6(float) Constant 1065353216 + 21: 12(int) Constant 0 + 22: 12(int) Constant 1 + 23: 12(int) SpecConstantOp 169 11 22 21 + 25: 8(bool) SpecConstantOp 166 11 11 + 26: 12(int) SpecConstantOp 132 13 13 + 30: 8(bool) SpecConstantOp 168 11 + 31: 12(int) SpecConstantOp 126 13 + 33: 8(bool) SpecConstantOp 173 13 13 + 35: 8(bool) SpecConstantOp 165 11 11 + 36: 8(bool) SpecConstantOp 171 13 13 + 37: TypeVector 12(int) 2 + 38: 37(ivec2) SpecConstantComposite 13 13 + 39: 37(ivec2) SpecConstantComposite 13 13 + 40: 37(ivec2) SpecConstantComposite 13 13 + 41: 14(int) Constant 2 + 42: TypeArray 37(ivec2) 41 + 44: TypeVector 6(float) 2 + 48: TypeArray 44(fvec2) 41 + 4(main): 2 Function None 3 + 5: Label + 10: 8(bool) FOrdNotEqual 7 9 + 18: 6(float) Select 11 17 9 + 19: 6(float) ConvertSToF 13 + 20: 12(int) ConvertFToS 7 + 24: 6(float) FMul 7 7 + 27: 6(float) ConvertSToF 13 + 28: 6(float) FAdd 7 27 + 29: 6(float) FNegate 7 + 32: 8(bool) FOrdGreaterThan 7 7 + 34: 8(bool) FOrdNotEqual 7 7 + 43: 42 CompositeConstruct 39 40 + 45: 44(fvec2) CompositeConstruct 7 7 + 46: 44(fvec2) CompositeConstruct 7 7 + 47: 44(fvec2) CompositeConstruct 7 7 + 49: 48 CompositeConstruct 46 47 + Return + FunctionEnd diff --git a/Test/spv.specConstantComposite.vert b/Test/spv.specConstantComposite.vert index 011033026..d9d07a3ed 100644 --- a/Test/spv.specConstantComposite.vert +++ b/Test/spv.specConstantComposite.vert @@ -7,7 +7,7 @@ layout(constant_id = 202) const double spec_double = 3.1415926535897932384626433832795; layout(constant_id = 203) const bool spec_bool = true; -const float cast_spec_float = float(spec_float); +// const float cast_spec_float = float(spec_float); // Flat struct struct flat_struct { @@ -26,40 +26,40 @@ struct nesting_struct { // Expect OpSpecConstantComposite // Flat struct initializer -const flat_struct spec_flat_struct_all_spec = {spec_int, spec_float, - spec_double, spec_bool}; -const flat_struct spec_flat_struct_partial_spec = {30, 30.14, spec_double, - spec_bool}; +//const flat_struct spec_flat_struct_all_spec = {spec_int, spec_float, +// spec_double, spec_bool}; +//const flat_struct spec_flat_struct_partial_spec = {30, 30.14, spec_double, +// spec_bool}; // Nesting struct initializer -const nesting_struct nesting_struct_ctor = { - {spec_int, spec_float, spec_double, false}, - vec4(0.1, 0.1, 0.1, 0.1), - spec_int}; +//const nesting_struct nesting_struct_ctor = { +// {spec_int, spec_float, spec_double, false}, +// vec4(0.1, 0.1, 0.1, 0.1), +// spec_int}; // Vector constructor -const vec4 spec_vec4_all_spec = - vec4(spec_float, spec_float, spec_float, spec_float); -const vec4 spec_vec4_partial_spec = - vec4(spec_float, spec_float, 300.14, 300.14); -const vec4 spec_vec4_from_one_scalar = vec4(spec_float); +//const vec4 spec_vec4_all_spec = +// vec4(spec_float, spec_float, spec_float, spec_float); +//const vec4 spec_vec4_partial_spec = +// vec4(spec_float, spec_float, 300.14, 300.14); +//const vec4 spec_vec4_from_one_scalar = vec4(spec_float); // Matrix constructor -const mat2x3 spec_mat2x3 = mat2x3(spec_float, spec_float, spec_float, 1.1, 2.2, 3.3); -const mat2x3 spec_mat2x3_from_one_scalar = mat2x3(spec_float); +//const mat2x3 spec_mat2x3 = mat2x3(spec_float, spec_float, spec_float, 1.1, 2.2, 3.3); +//const mat2x3 spec_mat2x3_from_one_scalar = mat2x3(spec_float); // Struct nesting constructor -const nesting_struct spec_nesting_struct_all_spec = { - spec_flat_struct_all_spec, spec_vec4_all_spec, spec_int}; -const nesting_struct spec_nesting_struct_partial_spec = { - spec_flat_struct_partial_spec, spec_vec4_partial_spec, 3000}; +//const nesting_struct spec_nesting_struct_all_spec = { +// spec_flat_struct_all_spec, spec_vec4_all_spec, spec_int}; +//const nesting_struct spec_nesting_struct_partial_spec = { +// spec_flat_struct_partial_spec, spec_vec4_partial_spec, 3000}; -const float spec_float_array[5] = {spec_float, spec_float, 1.0, 2.0, 3.0}; -const int spec_int_array[5] = {spec_int, spec_int, 1, 2, 30}; +//const float spec_float_array[5] = {spec_float, spec_float, 1.0, 2.0, 3.0}; +//const int spec_int_array[5] = {spec_int, spec_int, 1, 2, 30}; // global_vec4_array_with_spec_length is not a spec constant, but its array // size is. When calling global_vec4_array_with_spec_length.length(), A -// TIntermSymbol Node shoule be returned, instead of a TIntermConstantUnion +// TIntermSymbol Node should be returned, instead of a TIntermConstantUnion // node which represents a known constant value. in vec4 global_vec4_array_with_spec_length[spec_int]; @@ -70,18 +70,18 @@ void refer_primary_spec_const() { } void refer_composite_spec_const() { - color += spec_vec4_all_spec; - color -= spec_vec4_partial_spec; + //color += spec_vec4_all_spec; + //color -= spec_vec4_partial_spec; } void refer_copmosite_dot_dereference() { - color *= spec_nesting_struct_all_spec.i; - color += spec_vec4_all_spec.x; + //color *= spec_nesting_struct_all_spec.i; + //color += spec_vec4_all_spec.x; } void refer_composite_bracket_dereference() { - color -= spec_float_array[1]; - color /= spec_int_array[spec_int_array[spec_int]]; + //color -= spec_float_array[1]; + //color /= spec_int_array[spec_int_array[spec_int]]; } int refer_spec_const_array_length() { @@ -90,9 +90,9 @@ int refer_spec_const_array_length() { } void declare_spec_const_in_func() { - const nesting_struct spec_const_declared_in_func = { - spec_flat_struct_partial_spec, spec_vec4_partial_spec, 10}; - color /= spec_const_declared_in_func.i; + //const nesting_struct spec_const_declared_in_func = { + // spec_flat_struct_partial_spec, spec_vec4_partial_spec, 10}; + //color /= spec_const_declared_in_func.i; } void main() {} diff --git a/Test/spv.specConstantOperations.vert b/Test/spv.specConstantOperations.vert index f2d57bf0f..b5e46ad4c 100644 --- a/Test/spv.specConstantOperations.vert +++ b/Test/spv.specConstantOperations.vert @@ -58,7 +58,7 @@ const bool sp_int_gt_sp_sint = sp_int > sp_sint; // const ivec4 iv = ivec4(20, 30, sp_int, sp_int); const uvec4 uv = uvec4(sp_uint, sp_uint, -1, -2); -const vec4 fv = vec4(sp_float, 1.25, sp_float, 1.25); +//const vec4 fv = vec4(sp_float, 1.25, sp_float, 1.25); // uint/int <-> bool conversion const bvec4 bv_from_iv = bvec4(iv); diff --git a/Test/vulkan.ast.vert b/Test/vulkan.ast.vert new file mode 100644 index 000000000..c5a6a42c7 --- /dev/null +++ b/Test/vulkan.ast.vert @@ -0,0 +1,42 @@ +#version 450 + +layout(constant_id = 200) const float scf1 = 1.0; +layout(constant_id = 201) const bool scbt = true; +layout(constant_id = 202) const int sci2 = 2; + +void main() +{ + bool(scf1); // not a spec-const + bool(scbt); // spec-const + bool(sci2); // spec-const + + float(scf1); // not a spec-const + float(scbt); // not a spec-const + float(sci2); // not a spec-const + + int(scf1); // not a spec-const + int(scbt); // spec-const + int(sci2); // spec-const + + scf1 * scf1; // not a spec-const + scbt || scbt; // spec-const + sci2 * sci2; // spec-const + scf1 + sci2; // implicit conversion not a spec-const + + -scf1; // not a spec-const + !scbt; // spec-const + -sci2; // spec-const + + scf1 > scf1; // not a spec-const + sci2 > sci2; // spec-const + + scf1 != scf1; // not a spec-const + scbt != scbt; // spec-const + sci2 != sci2; // spec-const + + ivec2(sci2, sci2); // spec-const + ivec2[2](ivec2(sci2, sci2), ivec2(sci2, sci2)); // not a spec-const + + vec2(scf1, scf1); // not spec-const + vec2[2](vec2(scf1, scf1), vec2(scf1, scf1)); // not a spec-const +} diff --git a/glslang/Include/Types.h b/glslang/Include/Types.h index 98de16461..c4933e079 100644 --- a/glslang/Include/Types.h +++ b/glslang/Include/Types.h @@ -1253,6 +1253,7 @@ public: virtual bool isImplicitlySizedArray() const { return isArray() && getOuterArraySize() == UnsizedArraySize && qualifier.storage != EvqBuffer; } virtual bool isRuntimeSizedArray() const { return isArray() && getOuterArraySize() == UnsizedArraySize && qualifier.storage == EvqBuffer; } virtual bool isStruct() const { return structure != nullptr; } + virtual bool isFloatingDomain() const { return basicType == EbtFloat || basicType == EbtDouble; } // "Image" is a superset of "Subpass" virtual bool isImage() const { return basicType == EbtSampler && getSampler().isImage(); } diff --git a/glslang/MachineIndependent/Intermediate.cpp b/glslang/MachineIndependent/Intermediate.cpp index f8f9237bc..416dc34a5 100644 --- a/glslang/MachineIndependent/Intermediate.cpp +++ b/glslang/MachineIndependent/Intermediate.cpp @@ -922,6 +922,7 @@ TIntermTyped* TIntermediate::addSelection(TIntermTyped* cond, TIntermTyped* true TIntermConstantUnion* TIntermediate::addConstantUnion(const TConstUnionArray& unionArray, const TType& t, const TSourceLoc& loc, bool literal) const { TIntermConstantUnion* node = new TIntermConstantUnion(unionArray, t); + node->getQualifier().storage = EvqConst; node->setLoc(loc); if (literal) node->setLiteral(); @@ -1165,20 +1166,44 @@ void TIntermediate::removeTree() // // "5.x Specialization Constant Operations" // -// ... +// Only some operations discussed in this section may be applied to a +// specialization constant and still yield a result that is as +// specialization constant. The operations allowed are listed below. +// When a specialization constant is operated on with one of these +// operators and with another constant or specialization constant, the +// result is implicitly a specialization constant. // -// It also needs to allow basic construction, swizzling, and indexing -// operations. +// - int(), uint(), and bool() constructors for type conversions +// from any of the following types to any of the following types: +// * int +// * uint +// * bool +// - vector versions of the above conversion constructors +// - allowed implicit conversions of the above +// - swizzles (e.g., foo.yx) +// - The following when applied to integer or unsigned integer types: +// * unary negative ( - ) +// * binary operations ( + , - , * , / , % ) +// * shift ( <<, >> ) +// * bitwise operations ( & , | , ^ ) +// - The following when applied to integer or unsigned integer scalar types: +// * comparison ( == , != , > , >= , < , <= ) +// - The following when applied to the Boolean scalar type: +// * not ( ! ) +// * logical operations ( && , || , ^^ ) +// * comparison ( == , != )" +// +// This function just handles binary and unary nodes. Construction +// rules are handled in construction paths that are not covered by the unary +// and binary paths, while required conversions will still show up here +// as unary converters in the from a construction operator. // bool TIntermediate::isSpecializationOperation(const TIntermOperator& node) const { - // allow construction - if (node.isConstructor()) - return true; - - // The set for floating point is quite limited - if (node.getBasicType() == EbtFloat || - node.getBasicType() == EbtDouble) { + // The operations resulting in floating point are quite limited + // (However, some floating-point operations result in bool, like ">", + // so are handled later.) + if (node.getType().isFloatingDomain()) { switch (node.getOp()) { case EOpIndexDirect: case EOpIndexIndirect: @@ -1190,7 +1215,14 @@ bool TIntermediate::isSpecializationOperation(const TIntermOperator& node) const } } - // Floating-point is out of the way. + // Check for floating-point arguments + if (const TIntermBinary* bin = node.getAsBinaryNode()) + if (bin->getLeft() ->getType().isFloatingDomain() || + bin->getRight()->getType().isFloatingDomain()) + return false; + + // So, for now, we can assume everything left is non-floating-point... + // Now check for integer/bool-based operations switch (node.getOp()) { diff --git a/glslang/MachineIndependent/ParseHelper.cpp b/glslang/MachineIndependent/ParseHelper.cpp index 93c674ee9..15d0dae31 100644 --- a/glslang/MachineIndependent/ParseHelper.cpp +++ b/glslang/MachineIndependent/ParseHelper.cpp @@ -2208,6 +2208,18 @@ bool TParseContext::builtInName(const TString& identifier) // constructor to build something of the type of the constructor. Also returns // the type of the constructor. // +// Part of establishing type is establishing specialization-constness. +// We don't yet know "top down" whether type is a specialization constant, +// but a const constructor can becomes a specialization constant if any of +// its children are, subject to KHR_vulkan_glsl rules: +// +// - int(), uint(), and bool() constructors for type conversions +// from any of the following types to any of the following types: +// * int +// * uint +// * bool +// - vector versions of the above conversion constructors +// // Returns true if there was an error in construction. // bool TParseContext::constructorError(const TSourceLoc& loc, TIntermNode* node, TFunction& function, TOperator op, TType& type) @@ -2253,6 +2265,7 @@ bool TParseContext::constructorError(const TSourceLoc& loc, TIntermNode* node, T bool overFull = false; bool matrixInMatrix = false; bool arrayArg = false; + bool floatArgument = false; for (int arg = 0; arg < function.getParamCount(); ++arg) { if (function[arg].type->isArray()) { if (! function[arg].type->isExplicitlySizedArray()) { @@ -2281,11 +2294,52 @@ bool TParseContext::constructorError(const TSourceLoc& loc, TIntermNode* node, T constType = false; if (function[arg].type->getQualifier().isSpecConstant()) specConstType = true; + if (function[arg].type->isFloatingDomain()) + floatArgument = true; } + // inherit constness from children if (constType) { - if (specConstType) + bool makeSpecConst; + // Finish pinning down spec-const semantics + if (specConstType) { + switch (op) { + case EOpConstructInt: + case EOpConstructUint: + case EOpConstructInt64: + case EOpConstructUint64: + case EOpConstructBool: + case EOpConstructBVec2: + case EOpConstructBVec3: + case EOpConstructBVec4: + case EOpConstructIVec2: + case EOpConstructIVec3: + case EOpConstructIVec4: + case EOpConstructUVec2: + case EOpConstructUVec3: + case EOpConstructUVec4: + case EOpConstructI64Vec2: + case EOpConstructI64Vec3: + case EOpConstructI64Vec4: + case EOpConstructU64Vec2: + case EOpConstructU64Vec3: + case EOpConstructU64Vec4: + // This was the list of valid ones, if they aren't converting from float + // and aren't making an array. + makeSpecConst = ! floatArgument && ! type.isArray(); + break; + default: + // anything else wasn't white-listed in the spec as a conversion + makeSpecConst = false; + break; + } + } else + makeSpecConst = false; + + if (makeSpecConst) type.getQualifier().makeSpecConstant(); + else if (specConstType) + type.getQualifier().makeTemporary(); else type.getQualifier().storage = EvqConst; } @@ -4941,7 +4995,14 @@ TIntermNode* TParseContext::executeInitializer(const TSourceLoc& loc, TIntermTyp // constructor-style subtree, allowing the rest of the code to operate // identically for both kinds of initializers. // - initializer = convertInitializerList(loc, variable->getType(), initializer); + // Type can't be deduced from the initializer list, so a skeletal type to + // follow has to be passed in. Constness and specialization-constness + // should be deduced bottom up, not dictated by the skeletal type. + // + TType skeletalType; + skeletalType.shallowCopy(variable->getType()); + skeletalType.getQualifier().makeTemporary(); + initializer = convertInitializerList(loc, skeletalType, initializer); if (! initializer) { // error recovery; don't leave const without constant values if (qualifier == EvqConst) @@ -5030,7 +5091,7 @@ TIntermNode* TParseContext::executeInitializer(const TSourceLoc& loc, TIntermTyp // normal assigning of a value to a variable... specializationCheck(loc, initializer->getType(), "initializer"); TIntermSymbol* intermSymbol = intermediate.addSymbol(*variable, loc); - TIntermNode* initNode = intermediate.addAssign(EOpAssign, intermSymbol, initializer, loc); + TIntermTyped* initNode = intermediate.addAssign(EOpAssign, intermSymbol, initializer, loc); if (! initNode) assignError(loc, "=", intermSymbol->getCompleteString(), initializer->getCompleteString()); @@ -5041,11 +5102,14 @@ TIntermNode* TParseContext::executeInitializer(const TSourceLoc& loc, TIntermTyp } // -// Reprocess any initializer-list { ... } parts of the initializer. +// Reprocess any initializer-list (the "{ ... }" syntax) parts of the +// initializer. +// // Need to hierarchically assign correct types and implicit // conversions. Will do this mimicking the same process used for // creating a constructor-style initializer, ensuring we get the -// same form. +// same form. However, it has to in parallel walk the 'type' +// passed in, as type cannot be deduced from an initializer list. // TIntermTyped* TParseContext::convertInitializerList(const TSourceLoc& loc, const TType& type, TIntermTyped* initializer) { @@ -5191,12 +5255,6 @@ TIntermTyped* TParseContext::addConstructor(const TSourceLoc& loc, TIntermNode* // for each parameter to the constructor call, check to see if the right type is passed or convert them // to the right type if possible (and allowed). // for structure constructors, just check if the right type is passed, no conversion is allowed. - - // We don't know "top down" whether type is a specialization constant, - // but a const becomes a specialization constant if any of its children are. - bool hasSpecConst = false; - bool isConstConstrutor = true; - for (TIntermSequence::iterator p = sequenceVector.begin(); p != sequenceVector.end(); p++, paramCount++) { if (type.isArray()) @@ -5206,21 +5264,13 @@ TIntermTyped* TParseContext::addConstructor(const TSourceLoc& loc, TIntermNode* else newNode = constructBuiltIn(type, op, (*p)->getAsTyped(), node->getLoc(), true); - if (newNode) { + if (newNode) *p = newNode; - if (! newNode->getType().getQualifier().isConstant()) - isConstConstrutor = false; - if (newNode->getType().getQualifier().isSpecConstant()) - hasSpecConst = true; - } else + else return nullptr; } - TIntermTyped* constructor = intermediate.setAggregateOperator(aggrNode, op, type, loc); - if (isConstConstrutor && hasSpecConst) - constructor->getWritableType().getQualifier().makeSpecConstant(); - - return constructor; + return intermediate.setAggregateOperator(aggrNode, op, type, loc); } // Function for constructor implementation. Calls addUnaryMath with appropriate EOp value diff --git a/glslang/MachineIndependent/localintermediate.h b/glslang/MachineIndependent/localintermediate.h index 17b7d21ce..d60c59ede 100644 --- a/glslang/MachineIndependent/localintermediate.h +++ b/glslang/MachineIndependent/localintermediate.h @@ -346,7 +346,6 @@ protected: static int getBaseAlignmentScalar(const TType&, int& size); bool isSpecializationOperation(const TIntermOperator&) const; - const EShLanguage language; // stage, known at construction time EShSource source; // source language, known a bit later std::string entryPoint; diff --git a/gtests/Spv.FromFile.cpp b/gtests/Spv.FromFile.cpp index 04e204e37..054e293a6 100644 --- a/gtests/Spv.FromFile.cpp +++ b/gtests/Spv.FromFile.cpp @@ -43,6 +43,7 @@ namespace { using CompileToSpirvTest = GlslangTest<::testing::TestWithParam>; using VulkanSemantics = GlslangTest<::testing::TestWithParam>; +using VulkanAstSemantics = GlslangTest<::testing::TestWithParam>; // Compiling GLSL to SPIR-V under Vulkan semantics. Expected to successfully // generate SPIR-V. @@ -62,6 +63,14 @@ TEST_P(VulkanSemantics, FromFile) Target::Spv); } +// GLSL-level Vulkan semantics test that need to see the AST for validation. +TEST_P(VulkanAstSemantics, FromFile) +{ + loadFileCompileAndCheck(GLSLANG_TEST_DIRECTORY, GetParam(), + Source::GLSL, Semantics::Vulkan, + Target::AST); +} + // clang-format off INSTANTIATE_TEST_CASE_P( Glsl, CompileToSpirvTest, @@ -187,6 +196,14 @@ INSTANTIATE_TEST_CASE_P( })), FileNameAsCustomTestSuffix ); + +INSTANTIATE_TEST_CASE_P( + Glsl, VulkanAstSemantics, + ::testing::ValuesIn(std::vector({ + "vulkan.ast.vert", + })), + FileNameAsCustomTestSuffix +); // clang-format on } // anonymous namespace diff --git a/gtests/TestFixture.cpp b/gtests/TestFixture.cpp index ca1281747..2cf70707c 100644 --- a/gtests/TestFixture.cpp +++ b/gtests/TestFixture.cpp @@ -94,7 +94,7 @@ EShMessages DeriveOptions(Source source, Semantics semantics, Target target) case Semantics::OpenGL: break; case Semantics::Vulkan: - result = static_cast(result | EShMsgVulkanRules); + result = static_cast(result | EShMsgVulkanRules | EShMsgSpvRules); break; }