From 574ab04caa0d643cccdcb8f133579a308d17a62d Mon Sep 17 00:00:00 2001 From: Rex Xu Date: Thu, 14 Apr 2016 16:53:07 +0800 Subject: [PATCH] Implement the extension GL_ARB_shader_ballot Add new built-in variables and functions to the parser (SPIR-V tokens are missing). --- SPIRV/GlslangToSpv.cpp | 23 +- Test/baseResults/spv.shaderBallot.comp.out | 345 +++++++++++++++++++++ Test/spv.shaderBallot.comp | 59 ++++ Test/test-spirv-list | 1 + glslang/Include/BaseTypes.h | 14 + glslang/Include/intermediate.h | 4 + glslang/MachineIndependent/Initialize.cpp | 88 +++++- glslang/MachineIndependent/Versions.cpp | 2 + glslang/MachineIndependent/Versions.h | 1 + glslang/MachineIndependent/intermOut.cpp | 5 + gtests/Spv.FromFile.cpp | 1 + 11 files changed, 537 insertions(+), 6 deletions(-) create mode 100644 Test/baseResults/spv.shaderBallot.comp.out create mode 100644 Test/spv.shaderBallot.comp diff --git a/SPIRV/GlslangToSpv.cpp b/SPIRV/GlslangToSpv.cpp index 0c62d52e8..62383cc13 100755 --- a/SPIRV/GlslangToSpv.cpp +++ b/SPIRV/GlslangToSpv.cpp @@ -433,7 +433,7 @@ spv::BuiltIn TGlslangToSpvTraverser::TranslateBuiltInDecoration(glslang::TBuiltI case glslang::EbvBaseInstance: case glslang::EbvDrawId: // TODO: Add SPIR-V builtin ID. - spv::MissingFunctionality("Draw parameters"); + spv::MissingFunctionality("shader draw parameters"); return (spv::BuiltIn)spv::BadValue; case glslang::EbvPrimitiveId: return spv::BuiltInPrimitiveId; case glslang::EbvInvocationId: return spv::BuiltInInvocationId; @@ -453,6 +453,16 @@ spv::BuiltIn TGlslangToSpvTraverser::TranslateBuiltInDecoration(glslang::TBuiltI case glslang::EbvLocalInvocationId: return spv::BuiltInLocalInvocationId; case glslang::EbvLocalInvocationIndex: return spv::BuiltInLocalInvocationIndex; case glslang::EbvGlobalInvocationId: return spv::BuiltInGlobalInvocationId; + case glslang::EbvSubGroupSize: + case glslang::EbvSubGroupInvocation: + case glslang::EbvSubGroupEqMask: + case glslang::EbvSubGroupGeMask: + case glslang::EbvSubGroupGtMask: + case glslang::EbvSubGroupLeMask: + case glslang::EbvSubGroupLtMask: + // TODO: Add SPIR-V builtin ID. + spv::MissingFunctionality("shader ballot"); + return (spv::BuiltIn)spv::BadValue; default: return (spv::BuiltIn)spv::BadValue; } } @@ -3234,6 +3244,12 @@ spv::Id TGlslangToSpvTraverser::createUnaryOperation(glslang::TOperator op, spv: libCall = spv::GLSLstd450FindSMsb; break; + case glslang::EOpBallot: + case glslang::EOpReadFirstInvocation: + spv::MissingFunctionality("shader ballot"); + libCall = spv::GLSLstd450Bad; + break; + default: return 0; } @@ -3687,6 +3703,11 @@ spv::Id TGlslangToSpvTraverser::createMiscOperation(glslang::TOperator op, spv:: libCall = spv::GLSLstd450Ldexp; break; + case glslang::EOpReadInvocation: + spv::MissingFunctionality("shader ballot"); + libCall = spv::GLSLstd450Bad; + break; + default: return 0; } diff --git a/Test/baseResults/spv.shaderBallot.comp.out b/Test/baseResults/spv.shaderBallot.comp.out new file mode 100644 index 000000000..51ddc63db --- /dev/null +++ b/Test/baseResults/spv.shaderBallot.comp.out @@ -0,0 +1,345 @@ +spv.shaderBallot.comp +Warning, version 450 is not yet complete; most version-specific features are present, but some are missing. + + +Linked compute stage: + + +Missing functionality: shader ballot +Missing functionality: shader ballot +Missing functionality: shader ballot +Missing functionality: shader ballot +Missing functionality: shader ballot +Missing functionality: shader ballot +Missing functionality: shader ballot +Missing functionality: shader ballot +Missing functionality: shader ballot +Missing functionality: shader ballot +Missing functionality: shader ballot +Missing functionality: shader ballot +Missing functionality: shader ballot +Missing functionality: shader ballot +Missing functionality: shader ballot +Missing functionality: shader ballot +Missing functionality: shader ballot +Missing functionality: shader ballot +Missing functionality: shader ballot +Missing functionality: shader ballot +Missing functionality: shader ballot +Missing functionality: shader ballot +Missing functionality: shader ballot +Missing functionality: shader ballot +Missing functionality: shader ballot +Missing functionality: shader ballot +Missing functionality: shader ballot +Missing functionality: shader ballot +Missing functionality: shader ballot +Missing functionality: shader ballot +Missing functionality: shader ballot +Missing functionality: shader ballot +// Module Version 10000 +// Generated by (magic number): 80001 +// Id's are bound by 241 + + Capability Shader + Capability Int64 + 1: ExtInstImport "GLSL.std.450" + MemoryModel Logical GLSL450 + EntryPoint GLCompute 4 "main" 10 22 24 27 30 33 + ExecutionMode 4 LocalSize 8 8 1 + Source GLSL 450 + SourceExtension "GL_ARB_gpu_shader_int64" + SourceExtension "GL_ARB_shader_ballot" + Name 4 "main" + Name 8 "invocation" + Name 10 "gl_SubGroupInvocationARB" + Name 13 "gl_SubGroupSizeARB" + Name 20 "relMask" + Name 22 "gl_SubGroupEqMaskARB" + Name 24 "gl_SubGroupGeMaskARB" + Name 27 "gl_SubGroupGtMaskARB" + Name 30 "gl_SubGroupLeMaskARB" + Name 33 "gl_SubGroupLtMaskARB" + Name 48 "Buffers" + MemberName 48(Buffers) 0 "f4" + MemberName 48(Buffers) 1 "i4" + MemberName 48(Buffers) 2 "u4" + Name 51 "data" + MemberDecorate 48(Buffers) 0 Offset 0 + MemberDecorate 48(Buffers) 1 Offset 16 + MemberDecorate 48(Buffers) 2 Offset 32 + Decorate 48(Buffers) BufferBlock + Decorate 51(data) DescriptorSet 0 + Decorate 51(data) Binding 0 + Decorate 240 BuiltIn WorkgroupSize + 2: TypeVoid + 3: TypeFunction 2 + 6: TypeInt 32 0 + 7: TypePointer Function 6(int) + 9: TypePointer Input 6(int) +10(gl_SubGroupInvocationARB): 9(ptr) Variable Input + 12: TypePointer UniformConstant 6(int) +13(gl_SubGroupSizeARB): 12(ptr) Variable UniformConstant + 16: 6(int) Constant 4 + 18: TypeInt 64 0 + 19: TypePointer Function 18(int) + 21: TypePointer Input 18(int) +22(gl_SubGroupEqMaskARB): 21(ptr) Variable Input +24(gl_SubGroupGeMaskARB): 21(ptr) Variable Input +27(gl_SubGroupGtMaskARB): 21(ptr) Variable Input +30(gl_SubGroupLeMaskARB): 21(ptr) Variable Input +33(gl_SubGroupLtMaskARB): 21(ptr) Variable Input + 37: TypeBool + 38: 37(bool) ConstantTrue + 43: TypeFloat 32 + 44: TypeVector 43(float) 4 + 45: TypeInt 32 1 + 46: TypeVector 45(int) 4 + 47: TypeVector 6(int) 4 + 48(Buffers): TypeStruct 44(fvec4) 46(ivec4) 47(ivec4) + 49: TypeArray 48(Buffers) 16 + 50: TypePointer Uniform 49 + 51(data): 50(ptr) Variable Uniform + 53: 45(int) Constant 0 + 54: 6(int) Constant 0 + 55: TypePointer Uniform 43(float) + 62: 45(int) Constant 1 + 63: TypeVector 43(float) 2 + 64: TypePointer Uniform 44(fvec4) + 74: 45(int) Constant 2 + 75: TypeVector 43(float) 3 + 85: 45(int) Constant 3 + 92: TypePointer Uniform 45(int) + 99: TypeVector 45(int) 2 + 100: TypePointer Uniform 46(ivec4) + 110: TypeVector 45(int) 3 + 126: TypePointer Uniform 6(int) + 133: TypeVector 6(int) 2 + 134: TypePointer Uniform 47(ivec4) + 144: TypeVector 6(int) 3 + 238: 6(int) Constant 8 + 239: 6(int) Constant 1 + 240: 144(ivec3) ConstantComposite 238 238 239 + 4(main): 2 Function None 3 + 5: Label + 8(invocation): 7(ptr) Variable Function + 20(relMask): 19(ptr) Variable Function + 11: 6(int) Load 10(gl_SubGroupInvocationARB) + 14: 6(int) Load 13(gl_SubGroupSizeARB) + 15: 6(int) IAdd 11 14 + 17: 6(int) UMod 15 16 + Store 8(invocation) 17 + 23: 18(int) Load 22(gl_SubGroupEqMaskARB) + 25: 18(int) Load 24(gl_SubGroupGeMaskARB) + 26: 18(int) IAdd 23 25 + 28: 18(int) Load 27(gl_SubGroupGtMaskARB) + 29: 18(int) IAdd 26 28 + 31: 18(int) Load 30(gl_SubGroupLeMaskARB) + 32: 18(int) IAdd 29 31 + 34: 18(int) Load 33(gl_SubGroupLtMaskARB) + 35: 18(int) IAdd 32 34 + Store 20(relMask) 35 + 36: 18(int) Load 20(relMask) + 39: 18(int) ExtInst 1(GLSL.std.450) 0(Unknown) 38 + 40: 37(bool) IEqual 36 39 + SelectionMerge 42 None + BranchConditional 40 41 159 + 41: Label + 52: 6(int) Load 8(invocation) + 56: 55(ptr) AccessChain 51(data) 53 53 54 + 57: 43(float) Load 56 + 58: 6(int) Load 8(invocation) + 59: 43(float) ExtInst 1(GLSL.std.450) 0(Unknown) 57 58 + 60: 55(ptr) AccessChain 51(data) 52 53 54 + Store 60 59 + 61: 6(int) Load 8(invocation) + 65: 64(ptr) AccessChain 51(data) 62 53 + 66: 44(fvec4) Load 65 + 67: 63(fvec2) VectorShuffle 66 66 0 1 + 68: 6(int) Load 8(invocation) + 69: 63(fvec2) ExtInst 1(GLSL.std.450) 0(Unknown) 67 68 + 70: 64(ptr) AccessChain 51(data) 61 53 + 71: 44(fvec4) Load 70 + 72: 44(fvec4) VectorShuffle 71 69 4 5 2 3 + Store 70 72 + 73: 6(int) Load 8(invocation) + 76: 64(ptr) AccessChain 51(data) 74 53 + 77: 44(fvec4) Load 76 + 78: 75(fvec3) VectorShuffle 77 77 0 1 2 + 79: 6(int) Load 8(invocation) + 80: 75(fvec3) ExtInst 1(GLSL.std.450) 0(Unknown) 78 79 + 81: 64(ptr) AccessChain 51(data) 73 53 + 82: 44(fvec4) Load 81 + 83: 44(fvec4) VectorShuffle 82 80 4 5 6 3 + Store 81 83 + 84: 6(int) Load 8(invocation) + 86: 64(ptr) AccessChain 51(data) 85 53 + 87: 44(fvec4) Load 86 + 88: 6(int) Load 8(invocation) + 89: 44(fvec4) ExtInst 1(GLSL.std.450) 0(Unknown) 87 88 + 90: 64(ptr) AccessChain 51(data) 84 53 + Store 90 89 + 91: 6(int) Load 8(invocation) + 93: 92(ptr) AccessChain 51(data) 53 62 54 + 94: 45(int) Load 93 + 95: 6(int) Load 8(invocation) + 96: 45(int) ExtInst 1(GLSL.std.450) 0(Unknown) 94 95 + 97: 92(ptr) AccessChain 51(data) 91 62 54 + Store 97 96 + 98: 6(int) Load 8(invocation) + 101: 100(ptr) AccessChain 51(data) 62 62 + 102: 46(ivec4) Load 101 + 103: 99(ivec2) VectorShuffle 102 102 0 1 + 104: 6(int) Load 8(invocation) + 105: 99(ivec2) ExtInst 1(GLSL.std.450) 0(Unknown) 103 104 + 106: 100(ptr) AccessChain 51(data) 98 62 + 107: 46(ivec4) Load 106 + 108: 46(ivec4) VectorShuffle 107 105 4 5 2 3 + Store 106 108 + 109: 6(int) Load 8(invocation) + 111: 100(ptr) AccessChain 51(data) 74 62 + 112: 46(ivec4) Load 111 + 113: 110(ivec3) VectorShuffle 112 112 0 1 2 + 114: 6(int) Load 8(invocation) + 115: 110(ivec3) ExtInst 1(GLSL.std.450) 0(Unknown) 113 114 + 116: 100(ptr) AccessChain 51(data) 109 62 + 117: 46(ivec4) Load 116 + 118: 46(ivec4) VectorShuffle 117 115 4 5 6 3 + Store 116 118 + 119: 6(int) Load 8(invocation) + 120: 100(ptr) AccessChain 51(data) 85 62 + 121: 46(ivec4) Load 120 + 122: 6(int) Load 8(invocation) + 123: 46(ivec4) ExtInst 1(GLSL.std.450) 0(Unknown) 121 122 + 124: 100(ptr) AccessChain 51(data) 119 62 + Store 124 123 + 125: 6(int) Load 8(invocation) + 127: 126(ptr) AccessChain 51(data) 53 74 54 + 128: 6(int) Load 127 + 129: 6(int) Load 8(invocation) + 130: 6(int) ExtInst 1(GLSL.std.450) 0(Unknown) 128 129 + 131: 126(ptr) AccessChain 51(data) 125 74 54 + Store 131 130 + 132: 6(int) Load 8(invocation) + 135: 134(ptr) AccessChain 51(data) 62 74 + 136: 47(ivec4) Load 135 + 137: 133(ivec2) VectorShuffle 136 136 0 1 + 138: 6(int) Load 8(invocation) + 139: 133(ivec2) ExtInst 1(GLSL.std.450) 0(Unknown) 137 138 + 140: 134(ptr) AccessChain 51(data) 132 74 + 141: 47(ivec4) Load 140 + 142: 47(ivec4) VectorShuffle 141 139 4 5 2 3 + Store 140 142 + 143: 6(int) Load 8(invocation) + 145: 134(ptr) AccessChain 51(data) 74 74 + 146: 47(ivec4) Load 145 + 147: 144(ivec3) VectorShuffle 146 146 0 1 2 + 148: 6(int) Load 8(invocation) + 149: 144(ivec3) ExtInst 1(GLSL.std.450) 0(Unknown) 147 148 + 150: 134(ptr) AccessChain 51(data) 143 74 + 151: 47(ivec4) Load 150 + 152: 47(ivec4) VectorShuffle 151 149 4 5 6 3 + Store 150 152 + 153: 6(int) Load 8(invocation) + 154: 134(ptr) AccessChain 51(data) 85 74 + 155: 47(ivec4) Load 154 + 156: 6(int) Load 8(invocation) + 157: 47(ivec4) ExtInst 1(GLSL.std.450) 0(Unknown) 155 156 + 158: 134(ptr) AccessChain 51(data) 153 74 + Store 158 157 + Branch 42 + 159: Label + 160: 6(int) Load 8(invocation) + 161: 55(ptr) AccessChain 51(data) 53 53 54 + 162: 43(float) Load 161 + 163: 43(float) ExtInst 1(GLSL.std.450) 0(Unknown) 162 + 164: 55(ptr) AccessChain 51(data) 160 53 54 + Store 164 163 + 165: 6(int) Load 8(invocation) + 166: 64(ptr) AccessChain 51(data) 62 53 + 167: 44(fvec4) Load 166 + 168: 63(fvec2) VectorShuffle 167 167 0 1 + 169: 63(fvec2) ExtInst 1(GLSL.std.450) 0(Unknown) 168 + 170: 64(ptr) AccessChain 51(data) 165 53 + 171: 44(fvec4) Load 170 + 172: 44(fvec4) VectorShuffle 171 169 4 5 2 3 + Store 170 172 + 173: 6(int) Load 8(invocation) + 174: 64(ptr) AccessChain 51(data) 74 53 + 175: 44(fvec4) Load 174 + 176: 75(fvec3) VectorShuffle 175 175 0 1 2 + 177: 75(fvec3) ExtInst 1(GLSL.std.450) 0(Unknown) 176 + 178: 64(ptr) AccessChain 51(data) 173 53 + 179: 44(fvec4) Load 178 + 180: 44(fvec4) VectorShuffle 179 177 4 5 6 3 + Store 178 180 + 181: 6(int) Load 8(invocation) + 182: 64(ptr) AccessChain 51(data) 85 53 + 183: 44(fvec4) Load 182 + 184: 44(fvec4) ExtInst 1(GLSL.std.450) 0(Unknown) 183 + 185: 64(ptr) AccessChain 51(data) 181 53 + Store 185 184 + 186: 6(int) Load 8(invocation) + 187: 92(ptr) AccessChain 51(data) 53 62 54 + 188: 45(int) Load 187 + 189: 45(int) ExtInst 1(GLSL.std.450) 0(Unknown) 188 + 190: 92(ptr) AccessChain 51(data) 186 62 54 + Store 190 189 + 191: 6(int) Load 8(invocation) + 192: 100(ptr) AccessChain 51(data) 62 62 + 193: 46(ivec4) Load 192 + 194: 99(ivec2) VectorShuffle 193 193 0 1 + 195: 99(ivec2) ExtInst 1(GLSL.std.450) 0(Unknown) 194 + 196: 100(ptr) AccessChain 51(data) 191 62 + 197: 46(ivec4) Load 196 + 198: 46(ivec4) VectorShuffle 197 195 4 5 2 3 + Store 196 198 + 199: 6(int) Load 8(invocation) + 200: 100(ptr) AccessChain 51(data) 74 62 + 201: 46(ivec4) Load 200 + 202: 110(ivec3) VectorShuffle 201 201 0 1 2 + 203: 110(ivec3) ExtInst 1(GLSL.std.450) 0(Unknown) 202 + 204: 100(ptr) AccessChain 51(data) 199 62 + 205: 46(ivec4) Load 204 + 206: 46(ivec4) VectorShuffle 205 203 4 5 6 3 + Store 204 206 + 207: 6(int) Load 8(invocation) + 208: 100(ptr) AccessChain 51(data) 85 62 + 209: 46(ivec4) Load 208 + 210: 46(ivec4) ExtInst 1(GLSL.std.450) 0(Unknown) 209 + 211: 100(ptr) AccessChain 51(data) 207 62 + Store 211 210 + 212: 6(int) Load 8(invocation) + 213: 126(ptr) AccessChain 51(data) 53 74 54 + 214: 6(int) Load 213 + 215: 6(int) ExtInst 1(GLSL.std.450) 0(Unknown) 214 + 216: 126(ptr) AccessChain 51(data) 212 74 54 + Store 216 215 + 217: 6(int) Load 8(invocation) + 218: 134(ptr) AccessChain 51(data) 62 74 + 219: 47(ivec4) Load 218 + 220: 133(ivec2) VectorShuffle 219 219 0 1 + 221: 133(ivec2) ExtInst 1(GLSL.std.450) 0(Unknown) 220 + 222: 134(ptr) AccessChain 51(data) 217 74 + 223: 47(ivec4) Load 222 + 224: 47(ivec4) VectorShuffle 223 221 4 5 2 3 + Store 222 224 + 225: 6(int) Load 8(invocation) + 226: 134(ptr) AccessChain 51(data) 74 74 + 227: 47(ivec4) Load 226 + 228: 144(ivec3) VectorShuffle 227 227 0 1 2 + 229: 144(ivec3) ExtInst 1(GLSL.std.450) 0(Unknown) 228 + 230: 134(ptr) AccessChain 51(data) 225 74 + 231: 47(ivec4) Load 230 + 232: 47(ivec4) VectorShuffle 231 229 4 5 6 3 + Store 230 232 + 233: 6(int) Load 8(invocation) + 234: 134(ptr) AccessChain 51(data) 85 74 + 235: 47(ivec4) Load 234 + 236: 47(ivec4) ExtInst 1(GLSL.std.450) 0(Unknown) 235 + 237: 134(ptr) AccessChain 51(data) 233 74 + Store 237 236 + Branch 42 + 42: Label + Return + FunctionEnd diff --git a/Test/spv.shaderBallot.comp b/Test/spv.shaderBallot.comp new file mode 100644 index 000000000..20059b1c3 --- /dev/null +++ b/Test/spv.shaderBallot.comp @@ -0,0 +1,59 @@ +#version 450 + +#extension GL_ARB_gpu_shader_int64: enable +#extension GL_ARB_shader_ballot: enable + +layout (local_size_x = 8, local_size_y = 8, local_size_z = 1) in; + +layout(binding = 0) buffer Buffers +{ + vec4 f4; + ivec4 i4; + uvec4 u4; +} data[4]; + +void main() +{ + uint invocation = (gl_SubGroupInvocationARB + gl_SubGroupSizeARB) % 4; + + uint64_t relMask = gl_SubGroupEqMaskARB + + gl_SubGroupGeMaskARB + + gl_SubGroupGtMaskARB + + gl_SubGroupLeMaskARB + + gl_SubGroupLtMaskARB; + + if (relMask == ballotARB(true)) + { + data[invocation].f4.x = readInvocationARB(data[0].f4.x, invocation); + data[invocation].f4.xy = readInvocationARB(data[1].f4.xy, invocation); + data[invocation].f4.xyz = readInvocationARB(data[2].f4.xyz, invocation); + data[invocation].f4 = readInvocationARB(data[3].f4, invocation); + + data[invocation].i4.x = readInvocationARB(data[0].i4.x, invocation); + data[invocation].i4.xy = readInvocationARB(data[1].i4.xy, invocation); + data[invocation].i4.xyz = readInvocationARB(data[2].i4.xyz, invocation); + data[invocation].i4 = readInvocationARB(data[3].i4, invocation); + + data[invocation].u4.x = readInvocationARB(data[0].u4.x, invocation); + data[invocation].u4.xy = readInvocationARB(data[1].u4.xy, invocation); + data[invocation].u4.xyz = readInvocationARB(data[2].u4.xyz, invocation); + data[invocation].u4 = readInvocationARB(data[3].u4, invocation); + } + else + { + data[invocation].f4.x = readFirstInvocationARB(data[0].f4.x); + data[invocation].f4.xy = readFirstInvocationARB(data[1].f4.xy); + data[invocation].f4.xyz = readFirstInvocationARB(data[2].f4.xyz); + data[invocation].f4 = readFirstInvocationARB(data[3].f4); + + data[invocation].i4.x = readFirstInvocationARB(data[0].i4.x); + data[invocation].i4.xy = readFirstInvocationARB(data[1].i4.xy); + data[invocation].i4.xyz = readFirstInvocationARB(data[2].i4.xyz); + data[invocation].i4 = readFirstInvocationARB(data[3].i4); + + data[invocation].u4.x = readFirstInvocationARB(data[0].u4.x); + data[invocation].u4.xy = readFirstInvocationARB(data[1].u4.xy); + data[invocation].u4.xyz = readFirstInvocationARB(data[2].u4.xyz); + data[invocation].u4 = readFirstInvocationARB(data[3].u4); + } +} \ No newline at end of file diff --git a/Test/test-spirv-list b/Test/test-spirv-list index dfc6db7b4..5167b13c5 100644 --- a/Test/test-spirv-list +++ b/Test/test-spirv-list @@ -72,6 +72,7 @@ spv.intOps.vert spv.precision.frag spv.prepost.frag spv.qualifiers.vert +spv.shaderBallot.comp spv.shiftOps.frag spv.simpleFunctionCall.frag spv.simpleMat.vert diff --git a/glslang/Include/BaseTypes.h b/glslang/Include/BaseTypes.h index ff4b560cd..2c2757724 100644 --- a/glslang/Include/BaseTypes.h +++ b/glslang/Include/BaseTypes.h @@ -130,6 +130,13 @@ enum TBuiltInVariable { EbvLocalInvocationId, EbvGlobalInvocationId, EbvLocalInvocationIndex, + EbvSubGroupSize, + EbvSubGroupInvocation, + EbvSubGroupEqMask, + EbvSubGroupGeMask, + EbvSubGroupGtMask, + EbvSubGroupLeMask, + EbvSubGroupLtMask, EbvVertexId, EbvInstanceId, EbvVertexIndex, @@ -223,6 +230,13 @@ __inline const char* GetBuiltInVariableString(TBuiltInVariable v) case EbvLocalInvocationId: return "LocalInvocationID"; case EbvGlobalInvocationId: return "GlobalInvocationID"; case EbvLocalInvocationIndex: return "LocalInvocationIndex"; + case EbvSubGroupSize: return "SubGroupSize"; + case EbvSubGroupInvocation: return "SubGroupInvocation"; + case EbvSubGroupEqMask: return "SubGroupEqMask"; + case EbvSubGroupGeMask: return "SubGroupGeMask"; + case EbvSubGroupGtMask: return "SubGroupGtMask"; + case EbvSubGroupLeMask: return "SubGroupLeMask"; + case EbvSubGroupLtMask: return "SubGroupLtMask"; case EbvVertexId: return "VertexId"; case EbvInstanceId: return "InstanceId"; case EbvVertexIndex: return "VertexIndex"; diff --git a/glslang/Include/intermediate.h b/glslang/Include/intermediate.h index 1dd55a7b0..ef2547a7a 100644 --- a/glslang/Include/intermediate.h +++ b/glslang/Include/intermediate.h @@ -283,6 +283,10 @@ enum TOperator { EOpMemoryBarrierShared, // compute only EOpGroupMemoryBarrier, // compute only + EOpBallot, + EOpReadInvocation, + EOpReadFirstInvocation, + EOpAtomicAdd, EOpAtomicMin, EOpAtomicMax, diff --git a/glslang/MachineIndependent/Initialize.cpp b/glslang/MachineIndependent/Initialize.cpp index 0b27ddd96..ac9dfc794 100644 --- a/glslang/MachineIndependent/Initialize.cpp +++ b/glslang/MachineIndependent/Initialize.cpp @@ -1325,6 +1325,44 @@ void TBuiltIns::initialize(int version, EProfile profile, int spv, int vulkan) "\n"); } + // GL_ARB_shader_ballot + if (profile != EEsProfile && version >= 450) { + commonBuiltins.append( + "uint64_t ballotARB(bool);" + + "float readInvocationARB(float, uint);" + "vec2 readInvocationARB(vec2, uint);" + "vec3 readInvocationARB(vec3, uint);" + "vec4 readInvocationARB(vec4, uint);" + + "int readInvocationARB(int, uint);" + "ivec2 readInvocationARB(ivec2, uint);" + "ivec3 readInvocationARB(ivec3, uint);" + "ivec4 readInvocationARB(ivec4, uint);" + + "uint readInvocationARB(uint, uint);" + "uvec2 readInvocationARB(uvec2, uint);" + "uvec3 readInvocationARB(uvec3, uint);" + "uvec4 readInvocationARB(uvec4, uint);" + + "float readFirstInvocationARB(float);" + "vec2 readFirstInvocationARB(vec2);" + "vec3 readFirstInvocationARB(vec3);" + "vec4 readFirstInvocationARB(vec4);" + + "int readFirstInvocationARB(int);" + "ivec2 readFirstInvocationARB(ivec2);" + "ivec3 readFirstInvocationARB(ivec3);" + "ivec4 readFirstInvocationARB(ivec4);" + + "uint readFirstInvocationARB(uint);" + "uvec2 readFirstInvocationARB(uvec2);" + "uvec3 readFirstInvocationARB(uvec3);" + "uvec4 readFirstInvocationARB(uvec4);" + + "\n"); + } + //============================================================================ // // Prototypes for built-in functions seen by vertex shaders only. @@ -2232,6 +2270,21 @@ void TBuiltIns::initialize(int version, EProfile profile, int spv, int vulkan) if (version >= 130) add2ndGenerationSamplingImaging(version, profile, spv, vulkan); + // GL_ARB_shader_ballot + if (profile != EEsProfile && version >= 450) { + commonBuiltins.append( + "uniform uint gl_SubGroupSizeARB;" + + "in uint gl_SubGroupInvocationARB;" + "in uint64_t gl_SubGroupEqMaskARB;" + "in uint64_t gl_SubGroupGeMaskARB;" + "in uint64_t gl_SubGroupGtMaskARB;" + "in uint64_t gl_SubGroupLeMaskARB;" + "in uint64_t gl_SubGroupLtMaskARB;" + + "\n"); + } + //printf("%s\n", commonBuiltins.c_str()); //printf("%s\n", stageBuiltins[EShLangFragment].c_str()); } @@ -3394,7 +3447,7 @@ void IdentifyBuiltIns(int version, EProfile profile, int spv, int vulkan, EShLan switch(language) { case EShLangVertex: - if (profile != EEsProfile && version >= 440) { + if (profile != EEsProfile) { symbolTable.setVariableExtensions("gl_BaseVertexARB", 1, &E_GL_ARB_shader_draw_parameters); symbolTable.setVariableExtensions("gl_BaseInstanceARB", 1, &E_GL_ARB_shader_draw_parameters); symbolTable.setVariableExtensions("gl_DrawIDARB", 1, &E_GL_ARB_shader_draw_parameters); @@ -3404,6 +3457,28 @@ void IdentifyBuiltIns(int version, EProfile profile, int spv, int vulkan, EShLan BuiltInVariable("gl_DrawIDARB", EbvDrawId, symbolTable); } + if (profile != EEsProfile) { + symbolTable.setVariableExtensions("gl_SubGroupSizeARB", 1, &E_GL_ARB_shader_ballot); + symbolTable.setVariableExtensions("gl_SubGroupInvocationARB", 1, &E_GL_ARB_shader_ballot); + symbolTable.setVariableExtensions("gl_SubGroupEqMaskARB", 1, &E_GL_ARB_shader_ballot); + symbolTable.setVariableExtensions("gl_SubGroupGeMaskARB", 1, &E_GL_ARB_shader_ballot); + symbolTable.setVariableExtensions("gl_SubGroupGtMaskARB", 1, &E_GL_ARB_shader_ballot); + symbolTable.setVariableExtensions("gl_SubGroupLeMaskARB", 1, &E_GL_ARB_shader_ballot); + symbolTable.setVariableExtensions("gl_SubGroupLtMaskARB", 1, &E_GL_ARB_shader_ballot); + + symbolTable.setFunctionExtensions("ballotARB", 1, &E_GL_ARB_shader_ballot); + symbolTable.setFunctionExtensions("readInvocationARB", 1, &E_GL_ARB_shader_ballot); + symbolTable.setFunctionExtensions("readFirstInvocationARB", 1, &E_GL_ARB_shader_ballot); + + BuiltInVariable("gl_SubGroupSizeARB", EbvSubGroupSize, symbolTable); + BuiltInVariable("gl_SubGroupInvocationARB", EbvSubGroupInvocation, symbolTable); + BuiltInVariable("gl_SubGroupEqMaskARB", EbvSubGroupEqMask, symbolTable); + BuiltInVariable("gl_SubGroupGeMaskARB", EbvSubGroupGeMask, symbolTable); + BuiltInVariable("gl_SubGroupGtMaskARB", EbvSubGroupGtMask, symbolTable); + BuiltInVariable("gl_SubGroupLeMaskARB", EbvSubGroupLeMask, symbolTable); + BuiltInVariable("gl_SubGroupLtMaskARB", EbvSubGroupLtMask, symbolTable); + } + // Compatibility variables, vertex only if (spv == 0) { BuiltInVariable("gl_Color", EbvColor, symbolTable); @@ -3963,8 +4038,7 @@ void IdentifyBuiltIns(int version, EProfile profile, int spv, int vulkan, EShLan symbolTable.relateToOperator("shadow2DProjLod", EOpTextureProjLod); } - if (profile != EEsProfile) - { + if (profile != EEsProfile) { symbolTable.relateToOperator("sparseTextureARB", EOpSparseTexture); symbolTable.relateToOperator("sparseTextureLodARB", EOpSparseTextureLod); symbolTable.relateToOperator("sparseTextureOffsetARB", EOpSparseTextureOffset); @@ -3987,6 +4061,10 @@ void IdentifyBuiltIns(int version, EProfile profile, int spv, int vulkan, EShLan symbolTable.relateToOperator("textureOffsetClampARB", EOpTextureOffsetClamp); symbolTable.relateToOperator("textureGradClampARB", EOpTextureGradClamp); symbolTable.relateToOperator("textureGradOffsetClampARB", EOpTextureGradOffsetClamp); + + symbolTable.relateToOperator("ballotARB", EOpBallot); + symbolTable.relateToOperator("readInvocationARB", EOpReadInvocation); + symbolTable.relateToOperator("readFirstInvocationARB", EOpReadFirstInvocation); } } @@ -4023,8 +4101,8 @@ void IdentifyBuiltIns(int version, EProfile profile, int spv, int vulkan, EShLan break; case EShLangCompute: - symbolTable.relateToOperator("memoryBarrierShared", EOpMemoryBarrierShared); - symbolTable.relateToOperator("groupMemoryBarrier", EOpGroupMemoryBarrier); + symbolTable.relateToOperator("memoryBarrierShared", EOpMemoryBarrierShared); + symbolTable.relateToOperator("groupMemoryBarrier", EOpGroupMemoryBarrier); break; default: diff --git a/glslang/MachineIndependent/Versions.cpp b/glslang/MachineIndependent/Versions.cpp index 911535af0..42eca96d7 100644 --- a/glslang/MachineIndependent/Versions.cpp +++ b/glslang/MachineIndependent/Versions.cpp @@ -176,6 +176,7 @@ void TParseVersions::initializeExtensionBehavior() extensionBehavior[E_GL_ARB_viewport_array] = EBhDisable; extensionBehavior[E_GL_ARB_gpu_shader_int64] = EBhDisable; extensionBehavior[E_GL_ARB_gl_spirv] = EBhDisable; + extensionBehavior[E_GL_ARB_shader_ballot] = EBhDisable; extensionBehavior[E_GL_ARB_sparse_texture2] = EBhDisable; extensionBehavior[E_GL_ARB_sparse_texture_clamp] = EBhDisable; // extensionBehavior[E_GL_ARB_cull_distance] = EBhDisable; // present for 4.5, but need extension control over block members @@ -277,6 +278,7 @@ void TParseVersions::getPreamble(std::string& preamble) "#define GL_ARB_viewport_array 1\n" "#define GL_ARB_gpu_shader_int64 1\n" "#define GL_ARB_gl_spirv 1\n" + "#define GL_ARB_shader_ballot 1\n" "#define GL_ARB_sparse_texture2 1\n" "#define GL_ARB_sparse_texture_clamp 1\n" // "#define GL_ARB_cull_distance 1\n" // present for 4.5, but need extension control over block members diff --git a/glslang/MachineIndependent/Versions.h b/glslang/MachineIndependent/Versions.h index 779ba9f2e..93db6c3eb 100644 --- a/glslang/MachineIndependent/Versions.h +++ b/glslang/MachineIndependent/Versions.h @@ -113,6 +113,7 @@ const char* const E_GL_ARB_shader_texture_image_samples = "GL_ARB_shader_texture const char* const E_GL_ARB_viewport_array = "GL_ARB_viewport_array"; const char* const E_GL_ARB_gpu_shader_int64 = "GL_ARB_gpu_shader_int64"; const char* const E_GL_ARB_gl_spirv = "GL_ARB_gl_spirv"; +const char* const E_GL_ARB_shader_ballot = "GL_ARB_shader_ballot"; const char* const E_GL_ARB_sparse_texture2 = "GL_ARB_sparse_texture2"; const char* const E_GL_ARB_sparse_texture_clamp = "GL_ARB_sparse_texture_clamp"; //const char* const E_GL_ARB_cull_distance = "GL_ARB_cull_distance"; // present for 4.5, but need extension control over block members diff --git a/glslang/MachineIndependent/intermOut.cpp b/glslang/MachineIndependent/intermOut.cpp index 82e716004..4a7ee653d 100644 --- a/glslang/MachineIndependent/intermOut.cpp +++ b/glslang/MachineIndependent/intermOut.cpp @@ -351,6 +351,9 @@ bool TOutputTraverser::visitUnary(TVisit /* visit */, TIntermUnary* node) case EOpNoise: out.debug << "noise"; break; + case EOpBallot: out.debug << "ballot"; break; + case EOpReadFirstInvocation: out.debug << "readFirstInvocation"; break; + default: out.debug.message(EPrefixError, "Bad unary op"); } @@ -466,6 +469,8 @@ bool TOutputTraverser::visitAggregate(TVisit /* visit */, TIntermAggregate* node case EOpMemoryBarrierShared: out.debug << "MemoryBarrierShared"; break; case EOpGroupMemoryBarrier: out.debug << "GroupMemoryBarrier"; break; + case EOpReadInvocation: out.debug << "readInvocation"; break; + case EOpAtomicAdd: out.debug << "AtomicAdd"; break; case EOpAtomicMin: out.debug << "AtomicMin"; break; case EOpAtomicMax: out.debug << "AtomicMax"; break; diff --git a/gtests/Spv.FromFile.cpp b/gtests/Spv.FromFile.cpp index e5040b221..e35954462 100644 --- a/gtests/Spv.FromFile.cpp +++ b/gtests/Spv.FromFile.cpp @@ -138,6 +138,7 @@ INSTANTIATE_TEST_CASE_P( "spv.precision.frag", "spv.prepost.frag", "spv.qualifiers.vert", + "spv.shaderBallot.comp", "spv.shiftOps.frag", "spv.simpleFunctionCall.frag", "spv.simpleMat.vert",