diff --git a/SPIRV/GlslangToSpv.cpp b/SPIRV/GlslangToSpv.cpp index 3dffceb9..72292e61 100755 --- a/SPIRV/GlslangToSpv.cpp +++ b/SPIRV/GlslangToSpv.cpp @@ -99,16 +99,16 @@ protected: void makeGlobalInitializers(const glslang::TIntermSequence&); void visitFunctions(const glslang::TIntermSequence&); void handleFunctionEntry(const glslang::TIntermAggregate* node); - void translateArguments(const glslang::TIntermSequence& glslangArguments, std::vector& arguments); + void translateArguments(const glslang::TIntermAggregate& node, std::vector& arguments); void translateArguments(glslang::TIntermUnary& node, std::vector& arguments); spv::Id createImageTextureFunctionCall(glslang::TIntermOperator* node); spv::Id handleUserFunctionCall(const glslang::TIntermAggregate*); spv::Id createBinaryOperation(glslang::TOperator op, spv::Decoration precision, spv::Id typeId, spv::Id left, spv::Id right, glslang::TBasicType typeProxy, bool reduceComparison = true); - spv::Id createUnaryOperation(glslang::TOperator op, spv::Decoration precision, spv::Id typeId, spv::Id operand, bool isFloat); + spv::Id createUnaryOperation(glslang::TOperator op, spv::Decoration precision, spv::Id typeId, spv::Id operand,glslang::TBasicType typeProxy); spv::Id createConversion(glslang::TOperator op, spv::Decoration precision, spv::Id destTypeId, spv::Id operand); spv::Id makeSmearedConstant(spv::Id constant, int vectorSize); - spv::Id createAtomicOperation(glslang::TOperator op, spv::Decoration precision, spv::Id typeId, std::vector& operands); + spv::Id createAtomicOperation(glslang::TOperator op, spv::Decoration precision, spv::Id typeId, std::vector& operands, glslang::TBasicType typeProxy); spv::Id createMiscOperation(glslang::TOperator op, spv::Decoration precision, spv::Id typeId, std::vector& operands, glslang::TBasicType typeProxy); spv::Id createNoArgOperation(glslang::TOperator op); spv::Id getSymbolId(const glslang::TIntermSymbol* node); @@ -181,6 +181,8 @@ spv::StorageClass TranslateStorageClass(const glslang::TType& type) else if (type.getQualifier().isUniformOrBuffer()) { if (type.getBasicType() == glslang::EbtBlock) return spv::StorageClassUniform; + else if (type.getBasicType() == glslang::EbtAtomicUint) + return spv::StorageClassAtomicCounter; else return spv::StorageClassUniformConstant; // TODO: how are we distuingishing between default and non-default non-writable uniforms? Do default uniforms even exist? @@ -347,6 +349,56 @@ spv::BuiltIn TranslateBuiltInDecoration(glslang::TBuiltInVariable builtIn) } } +// Translate glslang image layout format to SPIR-V image format. +spv::ImageFormat TranslateImageFormat(const glslang::TType& type) +{ + assert(type.getBasicType() == glslang::EbtSampler); + + switch (type.getQualifier().layoutFormat) { + case glslang::ElfNone: return spv::ImageFormatUnknown; + case glslang::ElfRgba32f: return spv::ImageFormatRgba32f; + case glslang::ElfRgba16f: return spv::ImageFormatRgba16f; + case glslang::ElfR32f: return spv::ImageFormatR32f; + case glslang::ElfRgba8: return spv::ImageFormatRgba8; + case glslang::ElfRgba8Snorm: return spv::ImageFormatRgba8Snorm; + case glslang::ElfRg32f: return spv::ImageFormatRg32f; + case glslang::ElfRg16f: return spv::ImageFormatRg16f; + case glslang::ElfR11fG11fB10f: return spv::ImageFormatR11fG11fB10f; + case glslang::ElfR16f: return spv::ImageFormatR16f; + case glslang::ElfRgba16: return spv::ImageFormatRgba16; + case glslang::ElfRgb10A2: return spv::ImageFormatRgb10A2; + case glslang::ElfRg16: return spv::ImageFormatRg16; + case glslang::ElfRg8: return spv::ImageFormatRg8; + case glslang::ElfR16: return spv::ImageFormatR16; + case glslang::ElfR8: return spv::ImageFormatR8; + case glslang::ElfRgba16Snorm: return spv::ImageFormatRgba16Snorm; + case glslang::ElfRg16Snorm: return spv::ImageFormatRg16Snorm; + case glslang::ElfRg8Snorm: return spv::ImageFormatRg8Snorm; + case glslang::ElfR16Snorm: return spv::ImageFormatR16Snorm; + case glslang::ElfR8Snorm: return spv::ImageFormatR8Snorm; + case glslang::ElfRgba32i: return spv::ImageFormatRgba32i; + case glslang::ElfRgba16i: return spv::ImageFormatRgba16i; + case glslang::ElfRgba8i: return spv::ImageFormatRgba8i; + case glslang::ElfR32i: return spv::ImageFormatR32i; + case glslang::ElfRg32i: return spv::ImageFormatRg32i; + case glslang::ElfRg16i: return spv::ImageFormatRg16i; + case glslang::ElfRg8i: return spv::ImageFormatRg8i; + case glslang::ElfR16i: return spv::ImageFormatR16i; + case glslang::ElfR8i: return spv::ImageFormatR8i; + case glslang::ElfRgba32ui: return spv::ImageFormatRgba32ui; + case glslang::ElfRgba16ui: return spv::ImageFormatRgba16ui; + case glslang::ElfRgba8ui: return spv::ImageFormatRgba8ui; + case glslang::ElfR32ui: return spv::ImageFormatR32ui; + case glslang::ElfRg32ui: return spv::ImageFormatRg32ui; + case glslang::ElfRg16ui: return spv::ImageFormatRg16ui; + case glslang::ElfRgb10a2ui: return spv::ImageFormatRgb10a2ui; + case glslang::ElfRg8ui: return spv::ImageFormatRg8ui; + case glslang::ElfR16ui: return spv::ImageFormatR16ui; + case glslang::ElfR8ui: return spv::ImageFormatR8ui; + default: return (spv::ImageFormat)spv::BadValue; + } +} + // // Implement the TGlslangToSpvTraverser class. // @@ -702,7 +754,15 @@ bool TGlslangToSpvTraverser::visitUnary(glslang::TVisit /* visit */, glslang::TI builder.clearAccessChain(); node->getOperand()->traverse(this); - spv::Id operand = builder.accessChainLoad(convertGlslangToSpvType(node->getOperand()->getType())); + + spv::Id operand = spv::NoResult; + + if (node->getOp() == glslang::EOpAtomicCounterIncrement || + node->getOp() == glslang::EOpAtomicCounterDecrement || + node->getOp() == glslang::EOpAtomicCounter) + operand = builder.accessChainGetLValue(); // Special case l-value operands + else + operand = builder.accessChainLoad(convertGlslangToSpvType(node->getOperand()->getType())); spv::Decoration precision = TranslatePrecisionDecoration(node->getType()); @@ -712,8 +772,7 @@ bool TGlslangToSpvTraverser::visitUnary(glslang::TVisit /* visit */, glslang::TI // if not, then possibly an operation if (! result) - result = createUnaryOperation(node->getOp(), precision, convertGlslangToSpvType(node->getType()), operand, - node->getBasicType() == glslang::EbtFloat || node->getBasicType() == glslang::EbtDouble); + result = createUnaryOperation(node->getOp(), precision, convertGlslangToSpvType(node->getType()), operand, node->getBasicType()); if (result) { builder.clearAccessChain(); @@ -786,6 +845,11 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt return false; } + else if (node->getOp() == glslang::EOpImageStore) + { + // "imageStore" is a special case, which has no result + return false; + } glslang::TOperator binOp = glslang::EOpNull; bool reduceComparison = true; @@ -923,7 +987,7 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt case glslang::EOpConstructStruct: { std::vector arguments; - translateArguments(node->getSequence(), arguments); + translateArguments(*node, arguments); spv::Id resultTypeId = convertGlslangToSpvType(node->getType()); spv::Id constructed; if (node->getOp() == glslang::EOpConstructStruct || node->getType().isArray()) { @@ -1075,6 +1139,17 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt if (arg == 1) lvalue = true; break; + case glslang::EOpAtomicAdd: + case glslang::EOpAtomicMin: + case glslang::EOpAtomicMax: + case glslang::EOpAtomicAnd: + case glslang::EOpAtomicOr: + case glslang::EOpAtomicXor: + case glslang::EOpAtomicExchange: + case glslang::EOpAtomicCompSwap: + if (arg == 0) + lvalue = true; + break; //case glslang::EOpUAddCarry: //case glslang::EOpUSubBorrow: //case glslang::EOpUMulExtended: @@ -1089,7 +1164,7 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt if (atomic) { // Handle all atomics - result = createAtomicOperation(node->getOp(), precision, convertGlslangToSpvType(node->getType()), operands); + result = createAtomicOperation(node->getOp(), precision, convertGlslangToSpvType(node->getType()), operands, node->getBasicType()); } else { // Pass through to generic operations. switch (glslangOperands.size()) { @@ -1097,7 +1172,7 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt result = createNoArgOperation(node->getOp()); break; case 1: - result = createUnaryOperation(node->getOp(), precision, convertGlslangToSpvType(node->getType()), operands.front(), node->getType().getBasicType() == glslang::EbtFloat || node->getType().getBasicType() == glslang::EbtDouble); + result = createUnaryOperation(node->getOp(), precision, convertGlslangToSpvType(node->getType()), operands.front(), node->getType().getBasicType()); break; default: result = createMiscOperation(node->getOp(), precision, convertGlslangToSpvType(node->getType()), operands, node->getBasicType()); @@ -1367,7 +1442,7 @@ spv::Id TGlslangToSpvTraverser::convertGlslangToSpvType(const glslang::TType& ty { const glslang::TSampler& sampler = type.getSampler(); spvType = builder.makeImageType(getSampledType(sampler), TranslateDimensionality(sampler), sampler.shadow, sampler.arrayed, sampler.ms, - sampler.image ? 2 : 1, spv::ImageFormatUnknown); // TODO: translate format, needed for GLSL image ops + sampler.image ? 2 : 1, TranslateImageFormat(type)); // OpenGL "textures" need to be combined with a sampler if (! sampler.image) spvType = builder.makeSampledImageType(spvType); @@ -1657,12 +1732,35 @@ void TGlslangToSpvTraverser::handleFunctionEntry(const glslang::TIntermAggregate builder.setBuildPoint(functionBlock); } -void TGlslangToSpvTraverser::translateArguments(const glslang::TIntermSequence& glslangArguments, std::vector& arguments) +void TGlslangToSpvTraverser::translateArguments(const glslang::TIntermAggregate& node, std::vector& arguments) { + const glslang::TIntermSequence& glslangArguments = node.getSequence(); for (int i = 0; i < (int)glslangArguments.size(); ++i) { builder.clearAccessChain(); glslangArguments[i]->traverse(this); - arguments.push_back(builder.accessChainLoad(convertGlslangToSpvType(glslangArguments[i]->getAsTyped()->getType()))); + + // Special case l-value operands + bool lvalue = false; + switch (node.getOp()) { + case glslang::EOpImageAtomicAdd: + case glslang::EOpImageAtomicMin: + case glslang::EOpImageAtomicMax: + case glslang::EOpImageAtomicAnd: + case glslang::EOpImageAtomicOr: + case glslang::EOpImageAtomicXor: + case glslang::EOpImageAtomicExchange: + case glslang::EOpImageAtomicCompSwap: + if (i == 0) + lvalue = true; + break; + default: + break; + } + + if (lvalue) + arguments.push_back(builder.accessChainGetLValue()); + else + arguments.push_back(builder.accessChainLoad(convertGlslangToSpvType(glslangArguments[i]->getAsTyped()->getType()))); } } @@ -1675,23 +1773,16 @@ void TGlslangToSpvTraverser::translateArguments(glslang::TIntermUnary& node, std spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermOperator* node) { - if (node->isImage()) { - spv::MissingFunctionality("GLSL image function"); - return spv::NoResult; - } else if (! node->isTexture()) { + if (! node->isImage() && ! node->isTexture()) { return spv::NoResult; } // Process a GLSL texturing op (will be SPV image) - - glslang::TCrackedTextureOp cracked; - node->crackTexture(cracked); - const glslang::TSampler sampler = node->getAsAggregate() ? node->getAsAggregate()->getSequence()[0]->getAsTyped()->getType().getSampler() : node->getAsUnaryNode()->getOperand()->getAsTyped()->getType().getSampler(); std::vector arguments; if (node->getAsAggregate()) - translateArguments(node->getAsAggregate()->getSequence(), arguments); + translateArguments(*node->getAsAggregate(), arguments); else translateArguments(*node->getAsUnaryNode(), arguments); spv::Decoration precision = TranslatePrecisionDecoration(node->getType()); @@ -1699,6 +1790,9 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO spv::Builder::TextureParameters params = { }; params.sampler = arguments[0]; + glslang::TCrackedTextureOp cracked; + node->crackTexture(sampler, cracked); + // Check for queries if (cracked.query) { switch (node->getOp()) { @@ -1723,8 +1817,58 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO } } - // This is no longer a query.... + // Check for image functions other than queries + if (node->isImage()) { + // Process image load/store + if (node->getOp() == glslang::EOpImageLoad || + node->getOp() == glslang::EOpImageStore) { + std::vector operands; + auto opIt = arguments.begin(); + operands.push_back(*(opIt++)); + operands.push_back(*(opIt++)); + if (sampler.ms) { + // For MS, image operand mask has to be added to indicate the presence of "sample" operand. + spv::Id sample = *(opIt++); + for (; opIt != arguments.end(); ++opIt) + operands.push_back(*opIt); + operands.push_back(spv::ImageOperandsSampleMask); + operands.push_back(sample); + } else { + for (; opIt != arguments.end(); ++opIt) + operands.push_back(*opIt); + } + + if (node->getOp() == glslang::EOpImageLoad) + return builder.createOp(spv::OpImageRead, convertGlslangToSpvType(node->getType()), operands); + else { + builder.createNoResultOp(spv::OpImageWrite, operands); + return spv::NoResult; + } + } else { + // Process image atomic operations + + // GLSL "IMAGE_PARAMS" will involve in constructing an image texel pointer and this pointer, + // as the first source operand, is required by SPIR-V atomic operations. + std::vector imageParams; + auto opIt = arguments.begin(); + imageParams.push_back(*(opIt++)); + imageParams.push_back(*(opIt++)); + imageParams.push_back(sampler.ms ? *(opIt++) : 0); // For non-MS, the value should be 0 + + spv::Id resultTypeId = builder.makePointer(spv::StorageClassImage, convertGlslangToSpvType(node->getType())); + spv::Id pointer = builder.createOp(spv::OpImageTexelPointer, resultTypeId, imageParams); + + std::vector operands; + operands.push_back(pointer); + for (; opIt != arguments.end(); ++opIt) + operands.push_back(*opIt); + + return createAtomicOperation(node->getOp(), precision, convertGlslangToSpvType(node->getType()), operands, node->getBasicType()); + } + } + + // Check for texture functions other than queries if (cracked.gather) spv::MissingFunctionality("texture gather"); @@ -1761,6 +1905,9 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO if (cracked.lod) { params.lod = arguments[2]; ++extraArgs; + } else if (sampler.ms) { + params.sample = arguments[2]; // For MS, "sample" should be specified + ++extraArgs; } if (cracked.grad) { params.gradX = arguments[2 + extraArgs]; @@ -2115,10 +2262,11 @@ spv::Id TGlslangToSpvTraverser::createBinaryOperation(glslang::TOperator op, spv return 0; } -spv::Id TGlslangToSpvTraverser::createUnaryOperation(glslang::TOperator op, spv::Decoration precision, spv::Id typeId, spv::Id operand, bool isFloat) +spv::Id TGlslangToSpvTraverser::createUnaryOperation(glslang::TOperator op, spv::Decoration precision, spv::Id typeId, spv::Id operand, glslang::TBasicType typeProxy) { spv::Op unaryOp = spv::OpNop; int libCall = -1; + bool isFloat = typeProxy == glslang::EbtFloat || typeProxy == glslang::EbtDouble; switch (op) { case glslang::EOpNegative: @@ -2334,7 +2482,7 @@ spv::Id TGlslangToSpvTraverser::createUnaryOperation(glslang::TOperator op, spv: // Handle all of the atomics in one place, in createAtomicOperation() std::vector operands; operands.push_back(operand); - return createAtomicOperation(op, precision, typeId, operands); + return createAtomicOperation(op, precision, typeId, operands, typeProxy); } case glslang::EOpImageLoad: @@ -2480,33 +2628,41 @@ spv::Id TGlslangToSpvTraverser::makeSmearedConstant(spv::Id constant, int vector } // For glslang ops that map to SPV atomic opCodes -spv::Id TGlslangToSpvTraverser::createAtomicOperation(glslang::TOperator op, spv::Decoration precision, spv::Id typeId, std::vector& operands) +spv::Id TGlslangToSpvTraverser::createAtomicOperation(glslang::TOperator op, spv::Decoration precision, spv::Id typeId, std::vector& operands, glslang::TBasicType typeProxy) { spv::Op opCode = spv::OpNop; switch (op) { case glslang::EOpAtomicAdd: + case glslang::EOpImageAtomicAdd: opCode = spv::OpAtomicIAdd; break; case glslang::EOpAtomicMin: - opCode = spv::OpAtomicSMin; + case glslang::EOpImageAtomicMin: + opCode = typeProxy == glslang::EbtUint ? spv::OpAtomicUMin : spv::OpAtomicSMin; break; case glslang::EOpAtomicMax: - opCode = spv::OpAtomicSMax; + case glslang::EOpImageAtomicMax: + opCode = typeProxy == glslang::EbtUint ? spv::OpAtomicUMax : spv::OpAtomicSMax; break; case glslang::EOpAtomicAnd: + case glslang::EOpImageAtomicAnd: opCode = spv::OpAtomicAnd; break; case glslang::EOpAtomicOr: + case glslang::EOpImageAtomicOr: opCode = spv::OpAtomicOr; break; case glslang::EOpAtomicXor: + case glslang::EOpImageAtomicXor: opCode = spv::OpAtomicXor; break; case glslang::EOpAtomicExchange: + case glslang::EOpImageAtomicExchange: opCode = spv::OpAtomicExchange; break; case glslang::EOpAtomicCompSwap: + case glslang::EOpImageAtomicCompSwap: opCode = spv::OpAtomicCompareExchange; break; case glslang::EOpAtomicCounterIncrement: @@ -2534,7 +2690,9 @@ spv::Id TGlslangToSpvTraverser::createAtomicOperation(glslang::TOperator op, spv spvAtomicOperands.push_back(builder.makeUintConstant(spv::ScopeDevice)); // TBD: what is the correct scope? spvAtomicOperands.push_back(builder.makeUintConstant(spv::MemorySemanticsMaskNone)); // TBD: what are the correct memory semantics? if (opCode == spv::OpAtomicCompareExchange) { - spvAtomicOperands.push_back(builder.makeUintConstant(spv::MemorySemanticsMaskNone)); // TBD: what are the correct memory semantics? + // There are 2 memory semantics for compare-exchange. And the operand order of "comparator" and "new value" in GLSL + // differs from that in SPIR-V. Hence, special processing is required. + spvAtomicOperands.push_back(builder.makeUintConstant(spv::MemorySemanticsMaskNone)); spvAtomicOperands.push_back(*(opIt + 1)); spvAtomicOperands.push_back(*opIt); opIt += 2; diff --git a/SPIRV/SpvBuilder.cpp b/SPIRV/SpvBuilder.cpp index 45328b54..df76328e 100755 --- a/SPIRV/SpvBuilder.cpp +++ b/SPIRV/SpvBuilder.cpp @@ -812,6 +812,7 @@ Id Builder::createVariable(StorageClass storageClass, Id type, const char* name) case StorageClassWorkgroupLocal: case StorageClassPrivateGlobal: case StorageClassWorkgroupGlobal: + case StorageClassAtomicCounter: constantsTypesGlobals.push_back(inst); module.mapInstruction(inst); break; @@ -965,6 +966,15 @@ void Builder::createNoResultOp(Op opCode, Id operand) buildPoint->addInstruction(op); } +// An opcode that has one operand, no result id, and no type +void Builder::createNoResultOp(Op opCode, const std::vector& operands) +{ + Instruction* op = new Instruction(opCode); + for (auto operand : operands) + op->addIdOperand(operand); + buildPoint->addInstruction(op); +} + void Builder::createControlBarrier(Scope execution, Scope memory, MemorySemanticsMask semantics) { Instruction* op = new Instruction(OpControlBarrier); diff --git a/SPIRV/SpvBuilder.h b/SPIRV/SpvBuilder.h index e4835703..336aa243 100755 --- a/SPIRV/SpvBuilder.h +++ b/SPIRV/SpvBuilder.h @@ -159,8 +159,9 @@ public: } Id getImageType(Id resultId) const { - assert(isSampledImageType(getTypeId(resultId))); - return module.getInstruction(getTypeId(resultId))->getIdOperand(0); + Id typeId = getTypeId(resultId); + assert(isImageType(typeId) || isSampledImageType(typeId)); + return isSampledImageType(typeId) ? module.getInstruction(typeId)->getIdOperand(0) : typeId; } bool isArrayedImageType(Id typeId) const { @@ -235,6 +236,7 @@ public: void createNoResultOp(Op); void createNoResultOp(Op, Id operand); + void createNoResultOp(Op, const std::vector& operands); void createControlBarrier(Scope execution, Scope memory, MemorySemanticsMask); void createMemoryBarrier(unsigned executionScope, unsigned memorySemantics); Id createUnaryOp(Op, Id typeId, Id operand); diff --git a/SPIRV/doc.cpp b/SPIRV/doc.cpp index ff0d7805..ccc163d4 100755 --- a/SPIRV/doc.cpp +++ b/SPIRV/doc.cpp @@ -1635,10 +1635,12 @@ void Parameterize() InstructionDesc[OpImageRead].operands.push(OperandId, "'Image'"); InstructionDesc[OpImageRead].operands.push(OperandId, "'Coordinate'"); + InstructionDesc[OpImageRead].operands.push(OperandOptionalImage, ""); InstructionDesc[OpImageWrite].operands.push(OperandId, "'Image'"); InstructionDesc[OpImageWrite].operands.push(OperandId, "'Coordinate'"); InstructionDesc[OpImageWrite].operands.push(OperandId, "'Texel'"); + InstructionDesc[OpImageWrite].operands.push(OperandOptionalImage, ""); InstructionDesc[OpImageSampleImplicitLod].operands.push(OperandId, "'Sampled Image'"); InstructionDesc[OpImageSampleImplicitLod].operands.push(OperandId, "'Coordinate'"); diff --git a/Test/baseResults/spv.atomic.comp.out b/Test/baseResults/spv.atomic.comp.out index 55052aef..f3ae798f 100755 --- a/Test/baseResults/spv.atomic.comp.out +++ b/Test/baseResults/spv.atomic.comp.out @@ -8,7 +8,7 @@ Linked compute stage: TBD functionality: Is atomic_uint an opaque handle in the uniform storage class, or an addresses in the atomic storage class? // Module Version 99 // Generated by (magic number): 51a00bb -// Id's are bound by 74 +// Id's are bound by 64 Source ESSL 310 Capability Shader @@ -19,108 +19,98 @@ TBD functionality: Is atomic_uint an opaque handle in the uniform storage class, Name 10 "func(au1;" Name 9 "c" Name 12 "atoms(" - Name 21 "counter" - Name 22 "param" - Name 25 "val" - Name 29 "countArr" - Name 38 "origi" - Name 40 "atomi" - Name 44 "origu" - Name 46 "atomu" - Name 48 "value" - Name 71 "arrX" - Name 72 "arrY" - Name 73 "arrZ" - Decorate 21(counter) Binding 0 - Decorate 29(countArr) Binding 0 - Decorate 71(arrX) NoStaticUse - Decorate 72(arrY) NoStaticUse - Decorate 73(arrZ) NoStaticUse + Name 20 "counter" + Name 21 "param" + Name 24 "val" + Name 28 "countArr" + Name 35 "origi" + Name 37 "atomi" + Name 40 "origu" + Name 42 "atomu" + Name 44 "value" + Name 61 "arrX" + Name 62 "arrY" + Name 63 "arrZ" + Decorate 20(counter) Binding 0 + Decorate 28(countArr) Binding 0 + Decorate 61(arrX) NoStaticUse + Decorate 62(arrY) NoStaticUse + Decorate 63(arrZ) NoStaticUse 2: TypeVoid 3: TypeFunction 2 6: TypeInt 32 0 7: TypePointer Function 6(int) 8: TypeFunction 6(int) 7(ptr) - 15: 6(int) Constant 1 - 16: 6(int) Constant 0 - 19: 6(int) Constant 256 - 20: TypePointer UniformConstant 6(int) - 21(counter): 20(ptr) Variable UniformConstant - 26: 6(int) Constant 4 - 27: TypeArray 6(int) 26 - 28: TypePointer UniformConstant 27 - 29(countArr): 28(ptr) Variable UniformConstant - 30: TypeInt 32 1 - 31: 30(int) Constant 2 - 37: TypePointer Function 30(int) - 39: TypePointer WorkgroupLocal 30(int) - 40(atomi): 39(ptr) Variable WorkgroupLocal - 42: 30(int) Constant 3 - 45: TypePointer WorkgroupLocal 6(int) - 46(atomu): 45(ptr) Variable WorkgroupLocal - 48(value): 20(ptr) Variable UniformConstant - 52: 6(int) Constant 7 - 60: 30(int) Constant 7 - 66: 6(int) Constant 10 - 69: TypeArray 30(int) 15 - 70: TypePointer PrivateGlobal 69 - 71(arrX): 70(ptr) Variable PrivateGlobal - 72(arrY): 70(ptr) Variable PrivateGlobal - 73(arrZ): 70(ptr) Variable PrivateGlobal + 14: 6(int) Constant 1 + 15: 6(int) Constant 0 + 18: 6(int) Constant 256 + 19: TypePointer AtomicCounter 6(int) + 20(counter): 19(ptr) Variable AtomicCounter + 25: 6(int) Constant 4 + 26: TypeArray 6(int) 25 + 27: TypePointer AtomicCounter 26 + 28(countArr): 27(ptr) Variable AtomicCounter + 29: TypeInt 32 1 + 30: 29(int) Constant 2 + 34: TypePointer Function 29(int) + 36: TypePointer WorkgroupLocal 29(int) + 37(atomi): 36(ptr) Variable WorkgroupLocal + 38: 29(int) Constant 3 + 41: TypePointer WorkgroupLocal 6(int) + 42(atomu): 41(ptr) Variable WorkgroupLocal + 43: TypePointer UniformConstant 6(int) + 44(value): 43(ptr) Variable UniformConstant + 47: 6(int) Constant 7 + 52: 29(int) Constant 7 + 56: 6(int) Constant 10 + 59: TypeArray 29(int) 14 + 60: TypePointer PrivateGlobal 59 + 61(arrX): 60(ptr) Variable PrivateGlobal + 62(arrY): 60(ptr) Variable PrivateGlobal + 63(arrZ): 60(ptr) Variable PrivateGlobal 4(main): 2 Function None 3 5: Label - 22(param): 7(ptr) Variable Function - 25(val): 7(ptr) Variable Function - MemoryBarrier 15 19 - 23: 6(int) Load 21(counter) - Store 22(param) 23 - 24: 6(int) FunctionCall 10(func(au1;) 22(param) - 32: 20(ptr) AccessChain 29(countArr) 31 - 33: 6(int) Load 32 - 34: 6(int) AtomicLoad 33 15 16 - Store 25(val) 34 - 35: 6(int) Load 21(counter) - 36: 6(int) AtomicIDecrement 35 15 16 + 21(param): 7(ptr) Variable Function + 24(val): 7(ptr) Variable Function + MemoryBarrier 14 18 + 22: 6(int) Load 20(counter) + Store 21(param) 22 + 23: 6(int) FunctionCall 10(func(au1;) 21(param) + 31: 19(ptr) AccessChain 28(countArr) 30 + 32: 6(int) AtomicLoad 31 14 15 + Store 24(val) 32 + 33: 6(int) AtomicIDecrement 20(counter) 14 15 Return FunctionEnd 10(func(au1;): 6(int) Function None 8 9(c): 7(ptr) FunctionParameter 11: Label - 14: 6(int) Load 9(c) - 17: 6(int) AtomicIIncrement 14 15 16 - ReturnValue 17 + 16: 6(int) AtomicIIncrement 9(c) 14 15 + ReturnValue 16 FunctionEnd 12(atoms(): 2 Function None 3 13: Label - 38(origi): 37(ptr) Variable Function - 44(origu): 7(ptr) Variable Function - 41: 30(int) Load 40(atomi) - 43: 30(int) AtomicIAdd 41 15 16 42 - Store 38(origi) 43 - 47: 6(int) Load 46(atomu) - 49: 6(int) Load 48(value) - 50: 6(int) AtomicAnd 47 15 16 49 - Store 44(origu) 50 - 51: 6(int) Load 46(atomu) - 53: 6(int) AtomicOr 51 15 16 52 - Store 44(origu) 53 - 54: 6(int) Load 46(atomu) - 55: 6(int) AtomicXor 54 15 16 52 - Store 44(origu) 55 - 56: 6(int) Load 46(atomu) - 57: 6(int) Load 48(value) - 58: 6(int) AtomicSMin 56 15 16 57 - Store 44(origu) 58 - 59: 30(int) Load 40(atomi) - 61: 30(int) AtomicSMax 59 15 16 60 - Store 38(origi) 61 - 62: 30(int) Load 40(atomi) - 63: 30(int) Load 38(origi) - 64: 30(int) AtomicExchange 62 15 16 63 - Store 38(origi) 64 - 65: 6(int) Load 46(atomu) - 67: 6(int) Load 48(value) - 68: 6(int) AtomicCompareExchange 65 15 16 16 67 66 - Store 44(origu) 68 + 35(origi): 34(ptr) Variable Function + 40(origu): 7(ptr) Variable Function + 39: 29(int) AtomicIAdd 37(atomi) 14 15 38 + Store 35(origi) 39 + 45: 6(int) Load 44(value) + 46: 6(int) AtomicAnd 42(atomu) 14 15 45 + Store 40(origu) 46 + 48: 6(int) AtomicOr 42(atomu) 14 15 47 + Store 40(origu) 48 + 49: 6(int) AtomicXor 42(atomu) 14 15 47 + Store 40(origu) 49 + 50: 6(int) Load 44(value) + 51: 6(int) AtomicUMin 42(atomu) 14 15 50 + Store 40(origu) 51 + 53: 29(int) AtomicSMax 37(atomi) 14 15 52 + Store 35(origi) 53 + 54: 29(int) Load 35(origi) + 55: 29(int) AtomicExchange 37(atomi) 14 15 54 + Store 35(origi) 55 + 57: 6(int) Load 44(value) + 58: 6(int) AtomicCompareExchange 42(atomu) 14 15 15 57 56 + Store 40(origu) 58 Return FunctionEnd diff --git a/Test/baseResults/spv.do-simple.vert.out b/Test/baseResults/spv.do-simple.vert.out index be111143..b33dae83 100755 --- a/Test/baseResults/spv.do-simple.vert.out +++ b/Test/baseResults/spv.do-simple.vert.out @@ -25,11 +25,11 @@ Linked vertex stage: 6: TypeInt 32 1 7: TypePointer Function 6(int) 9: 6(int) Constant 0 - 14: TypeBool - 15: 14(bool) ConstantTrue + 13: TypeBool + 15: 13(bool) ConstantTrue 19: 6(int) Constant 10 23: 6(int) Constant 1 - 25: 14(bool) ConstantFalse + 25: 13(bool) ConstantFalse 26: TypePointer Input 6(int) 27(gl_VertexID): 26(ptr) Variable Input 28(gl_InstanceID): 26(ptr) Variable Input @@ -39,15 +39,15 @@ Linked vertex stage: Store 8(i) 9 Branch 10 10: Label - 13: 14(bool) Phi 15 5 25 12 + 14: 13(bool) Phi 15 5 25 12 LoopMerge 11 None Branch 16 16: Label SelectionMerge 12 None - BranchConditional 13 12 17 + BranchConditional 14 12 17 17: Label 18: 6(int) Load 8(i) - 20: 14(bool) SLessThan 18 19 + 20: 13(bool) SLessThan 18 19 SelectionMerge 21 None BranchConditional 20 21 11 21: Label diff --git a/Test/baseResults/spv.do-while-continue-break.vert.out b/Test/baseResults/spv.do-while-continue-break.vert.out index 5687acdf..edca3d4d 100755 --- a/Test/baseResults/spv.do-while-continue-break.vert.out +++ b/Test/baseResults/spv.do-while-continue-break.vert.out @@ -32,12 +32,12 @@ Linked vertex stage: 6: TypeInt 32 1 7: TypePointer Function 6(int) 9: 6(int) Constant 0 - 14: TypeBool - 15: 14(bool) ConstantTrue + 13: TypeBool + 15: 13(bool) ConstantTrue 19: 6(int) Constant 1 21: 6(int) Constant 19 26: 6(int) Constant 2 - 31: 14(bool) ConstantFalse + 31: 13(bool) ConstantFalse 35: 6(int) Constant 5 40: 6(int) Constant 3 43: 6(int) Constant 42 @@ -59,17 +59,17 @@ Linked vertex stage: Store 8(i) 9 Branch 10 10: Label - 13: 14(bool) Phi 15 5 31 28 31 38 + 14: 13(bool) Phi 15 5 31 28 31 38 LoopMerge 11 None Branch 16 16: Label SelectionMerge 12 None - BranchConditional 13 12 17 + BranchConditional 14 12 17 17: Label 18: 6(int) Load 8(i) 20: 6(int) IAdd 18 19 Store 8(i) 20 - 22: 14(bool) SLessThan 20 21 + 22: 13(bool) SLessThan 20 21 SelectionMerge 23 None BranchConditional 22 23 11 23: Label @@ -77,7 +77,7 @@ Linked vertex stage: 12: Label Store 24(A) 9 25: 6(int) Load 8(i) - 27: 14(bool) IEqual 25 26 + 27: 13(bool) IEqual 25 26 SelectionMerge 29 None BranchConditional 27 28 29 28: Label @@ -88,7 +88,7 @@ Linked vertex stage: Branch 29 29: Label 34: 6(int) Load 8(i) - 36: 14(bool) IEqual 34 35 + 36: 13(bool) IEqual 34 35 SelectionMerge 38 None BranchConditional 36 37 38 37: Label diff --git a/Test/baseResults/spv.doWhileLoop.frag.out b/Test/baseResults/spv.doWhileLoop.frag.out index 1a204b02..b8951777 100755 --- a/Test/baseResults/spv.doWhileLoop.frag.out +++ b/Test/baseResults/spv.doWhileLoop.frag.out @@ -28,13 +28,13 @@ Linked fragment stage: 8: TypePointer Function 7(fvec4) 10: TypePointer Input 7(fvec4) 11(BaseColor): 10(ptr) Variable Input - 17: TypeBool - 18: 17(bool) ConstantTrue + 16: TypeBool + 18: 16(bool) ConstantTrue 23: TypePointer UniformConstant 6(float) 24(d): 23(ptr) Variable UniformConstant 28: TypePointer UniformConstant 7(fvec4) 29(bigColor): 28(ptr) Variable UniformConstant - 33: 17(bool) ConstantFalse + 33: 16(bool) ConstantFalse 34: TypePointer Output 7(fvec4) 35(gl_FragColor): 34(ptr) Variable Output 4(main): 2 Function None 3 @@ -44,17 +44,17 @@ Linked fragment stage: Store 9(color) 12 Branch 13 13: Label - 16: 17(bool) Phi 18 5 33 15 + 17: 16(bool) Phi 18 5 33 15 LoopMerge 14 None Branch 19 19: Label SelectionMerge 15 None - BranchConditional 16 15 20 + BranchConditional 17 15 20 20: Label 21: 7(fvec4) Load 9(color) 22: 6(float) CompositeExtract 21 0 25: 6(float) Load 24(d) - 26: 17(bool) FOrdLessThan 22 25 + 26: 16(bool) FOrdLessThan 22 25 SelectionMerge 27 None BranchConditional 26 27 14 27: Label diff --git a/Test/baseResults/spv.image.frag.out b/Test/baseResults/spv.image.frag.out new file mode 100644 index 00000000..f686ee3c --- /dev/null +++ b/Test/baseResults/spv.image.frag.out @@ -0,0 +1,497 @@ +spv.image.frag +Warning, version 450 is not yet complete; most version-specific features are present, but some are missing. + + +Linked fragment stage: + + +// Module Version 99 +// Generated by (magic number): 51a00bb +// Id's are bound by 383 + + Source GLSL 450 + Capability Shader + 1: ExtInstImport "GLSL.std.450" + MemoryModel Logical GLSL450 + EntryPoint Fragment 4 "main" + ExecutionMode 4 OriginLowerLeft + Name 4 "main" + Name 9 "iv" + Name 15 "i1D" + Name 25 "i2D" + Name 36 "i3D" + Name 43 "iCube" + Name 53 "iCubeArray" + Name 60 "i2DRect" + Name 70 "i1DArray" + Name 80 "i2DArray" + Name 87 "iBuffer" + Name 97 "i2DMS" + Name 107 "i2DMSArray" + Name 128 "v" + Name 133 "ic1D" + Name 143 "ic2D" + Name 153 "ic3D" + Name 172 "ic4D" + Name 234 "ui" + Name 238 "ii1D" + Name 252 "ui2D" + Name 255 "value" + Name 370 "fragData" + Decorate 15(i1D) Binding 0 + Decorate 25(i2D) Binding 1 + Decorate 36(i3D) Binding 2 + Decorate 43(iCube) Binding 3 + Decorate 53(iCubeArray) Binding 4 + Decorate 60(i2DRect) Binding 5 + Decorate 70(i1DArray) Binding 6 + Decorate 80(i2DArray) Binding 7 + Decorate 87(iBuffer) Binding 8 + Decorate 97(i2DMS) Binding 9 + Decorate 107(i2DMSArray) Binding 10 + Decorate 238(ii1D) Binding 11 + Decorate 252(ui2D) Binding 12 + 2: TypeVoid + 3: TypeFunction 2 + 6: TypeInt 32 1 + 7: TypeVector 6(int) 3 + 8: TypePointer Function 7(ivec3) + 10: 6(int) Constant 0 + 11: 7(ivec3) ConstantComposite 10 10 10 + 12: TypeFloat 32 + 13: TypeImage 12(float) 1D nonsampled format:Rgba32f + 14: TypePointer UniformConstant 13 + 15(i1D): 14(ptr) Variable UniformConstant + 23: TypeImage 12(float) 2D nonsampled format:Rgba32f + 24: TypePointer UniformConstant 23 + 25(i2D): 24(ptr) Variable UniformConstant + 27: TypeVector 6(int) 2 + 34: TypeImage 12(float) 3D nonsampled format:Rgba32f + 35: TypePointer UniformConstant 34 + 36(i3D): 35(ptr) Variable UniformConstant + 41: TypeImage 12(float) Cube nonsampled format:Rgba32f + 42: TypePointer UniformConstant 41 + 43(iCube): 42(ptr) Variable UniformConstant + 51: TypeImage 12(float) Cube array nonsampled format:Rgba32f + 52: TypePointer UniformConstant 51 + 53(iCubeArray): 52(ptr) Variable UniformConstant + 58: TypeImage 12(float) Rect nonsampled format:Rgba32f + 59: TypePointer UniformConstant 58 + 60(i2DRect): 59(ptr) Variable UniformConstant + 68: TypeImage 12(float) 1D array nonsampled format:Rgba32f + 69: TypePointer UniformConstant 68 + 70(i1DArray): 69(ptr) Variable UniformConstant + 78: TypeImage 12(float) 2D array nonsampled format:Rgba32f + 79: TypePointer UniformConstant 78 + 80(i2DArray): 79(ptr) Variable UniformConstant + 85: TypeImage 12(float) Buffer nonsampled format:Rgba32f + 86: TypePointer UniformConstant 85 + 87(iBuffer): 86(ptr) Variable UniformConstant + 95: TypeImage 12(float) 2D multi-sampled nonsampled format:Rgba32f + 96: TypePointer UniformConstant 95 + 97(i2DMS): 96(ptr) Variable UniformConstant + 105: TypeImage 12(float) 2D array multi-sampled nonsampled format:Rgba32f + 106: TypePointer UniformConstant 105 + 107(i2DMSArray): 106(ptr) Variable UniformConstant + 126: TypeVector 12(float) 4 + 127: TypePointer Function 126(fvec4) + 129: 12(float) Constant 0 + 130: 126(fvec4) ConstantComposite 129 129 129 129 + 132: TypePointer UniformConstant 6(int) + 133(ic1D): 132(ptr) Variable UniformConstant + 142: TypePointer UniformConstant 27(ivec2) + 143(ic2D): 142(ptr) Variable UniformConstant + 152: TypePointer UniformConstant 7(ivec3) + 153(ic3D): 152(ptr) Variable UniformConstant + 170: TypeVector 6(int) 4 + 171: TypePointer UniformConstant 170(ivec4) + 172(ic4D): 171(ptr) Variable UniformConstant + 214: 6(int) Constant 1 + 220: 6(int) Constant 2 + 224: 6(int) Constant 3 + 230: 6(int) Constant 4 + 232: TypeInt 32 0 + 233: TypePointer Function 232(int) + 235: 232(int) Constant 0 + 236: TypeImage 6(int) 1D nonsampled format:R32i + 237: TypePointer UniformConstant 236 + 238(ii1D): 237(ptr) Variable UniformConstant + 240: 6(int) Constant 10 + 241: TypePointer Image 6(int) + 243: 232(int) Constant 1 + 250: TypeImage 232(int) 2D nonsampled format:R32ui + 251: TypePointer UniformConstant 250 + 252(ui2D): 251(ptr) Variable UniformConstant + 254: TypePointer UniformConstant 232(int) + 255(value): 254(ptr) Variable UniformConstant + 257: TypePointer Image 232(int) + 263: 6(int) Constant 11 + 278: 6(int) Constant 12 + 293: 6(int) Constant 13 + 308: 6(int) Constant 14 + 323: 6(int) Constant 15 + 338: 6(int) Constant 16 + 353: 6(int) Constant 18 + 354: 6(int) Constant 17 + 363: 232(int) Constant 19 + 369: TypePointer Output 126(fvec4) + 370(fragData): 369(ptr) Variable Output + 376: TypeBool + 4(main): 2 Function None 3 + 5: Label + 9(iv): 8(ptr) Variable Function + 128(v): 127(ptr) Variable Function + 234(ui): 233(ptr) Variable Function + 371: 127(ptr) Variable Function + Store 9(iv) 11 + 16: 13 Load 15(i1D) + 17: 6(int) ImageQuerySize 16 + 18: 7(ivec3) Load 9(iv) + 19: 6(int) CompositeExtract 18 0 + 20: 6(int) IAdd 19 17 + 21: 7(ivec3) Load 9(iv) + 22: 7(ivec3) CompositeInsert 20 21 0 + Store 9(iv) 22 + 26: 23 Load 25(i2D) + 28: 27(ivec2) ImageQuerySize 26 + 29: 7(ivec3) Load 9(iv) + 30: 27(ivec2) VectorShuffle 29 29 0 1 + 31: 27(ivec2) IAdd 30 28 + 32: 7(ivec3) Load 9(iv) + 33: 7(ivec3) VectorShuffle 32 31 3 4 2 + Store 9(iv) 33 + 37: 34 Load 36(i3D) + 38: 7(ivec3) ImageQuerySize 37 + 39: 7(ivec3) Load 9(iv) + 40: 7(ivec3) IAdd 39 38 + Store 9(iv) 40 + 44: 41 Load 43(iCube) + 45: 27(ivec2) ImageQuerySize 44 + 46: 7(ivec3) Load 9(iv) + 47: 27(ivec2) VectorShuffle 46 46 0 1 + 48: 27(ivec2) IAdd 47 45 + 49: 7(ivec3) Load 9(iv) + 50: 7(ivec3) VectorShuffle 49 48 3 4 2 + Store 9(iv) 50 + 54: 51 Load 53(iCubeArray) + 55: 7(ivec3) ImageQuerySize 54 + 56: 7(ivec3) Load 9(iv) + 57: 7(ivec3) IAdd 56 55 + Store 9(iv) 57 + 61: 58 Load 60(i2DRect) + 62: 27(ivec2) ImageQuerySize 61 + 63: 7(ivec3) Load 9(iv) + 64: 27(ivec2) VectorShuffle 63 63 0 1 + 65: 27(ivec2) IAdd 64 62 + 66: 7(ivec3) Load 9(iv) + 67: 7(ivec3) VectorShuffle 66 65 3 4 2 + Store 9(iv) 67 + 71: 68 Load 70(i1DArray) + 72: 27(ivec2) ImageQuerySize 71 + 73: 7(ivec3) Load 9(iv) + 74: 27(ivec2) VectorShuffle 73 73 0 1 + 75: 27(ivec2) IAdd 74 72 + 76: 7(ivec3) Load 9(iv) + 77: 7(ivec3) VectorShuffle 76 75 3 4 2 + Store 9(iv) 77 + 81: 78 Load 80(i2DArray) + 82: 7(ivec3) ImageQuerySize 81 + 83: 7(ivec3) Load 9(iv) + 84: 7(ivec3) IAdd 83 82 + Store 9(iv) 84 + 88: 85 Load 87(iBuffer) + 89: 6(int) ImageQuerySize 88 + 90: 7(ivec3) Load 9(iv) + 91: 6(int) CompositeExtract 90 0 + 92: 6(int) IAdd 91 89 + 93: 7(ivec3) Load 9(iv) + 94: 7(ivec3) CompositeInsert 92 93 0 + Store 9(iv) 94 + 98: 95 Load 97(i2DMS) + 99: 27(ivec2) ImageQuerySize 98 + 100: 7(ivec3) Load 9(iv) + 101: 27(ivec2) VectorShuffle 100 100 0 1 + 102: 27(ivec2) IAdd 101 99 + 103: 7(ivec3) Load 9(iv) + 104: 7(ivec3) VectorShuffle 103 102 3 4 2 + Store 9(iv) 104 + 108: 105 Load 107(i2DMSArray) + 109: 7(ivec3) ImageQuerySize 108 + 110: 7(ivec3) Load 9(iv) + 111: 7(ivec3) IAdd 110 109 + Store 9(iv) 111 + 112: 95 Load 97(i2DMS) + 113: 6(int) ImageQuerySamples 112 + 114: 7(ivec3) Load 9(iv) + 115: 6(int) CompositeExtract 114 0 + 116: 6(int) IAdd 115 113 + 117: 7(ivec3) Load 9(iv) + 118: 7(ivec3) CompositeInsert 116 117 0 + Store 9(iv) 118 + 119: 105 Load 107(i2DMSArray) + 120: 6(int) ImageQuerySamples 119 + 121: 7(ivec3) Load 9(iv) + 122: 6(int) CompositeExtract 121 0 + 123: 6(int) IAdd 122 120 + 124: 7(ivec3) Load 9(iv) + 125: 7(ivec3) CompositeInsert 123 124 0 + Store 9(iv) 125 + Store 128(v) 130 + 131: 13 Load 15(i1D) + 134: 6(int) Load 133(ic1D) + 135: 126(fvec4) ImageRead 131 134 + 136: 126(fvec4) Load 128(v) + 137: 126(fvec4) FAdd 136 135 + Store 128(v) 137 + 138: 13 Load 15(i1D) + 139: 6(int) Load 133(ic1D) + 140: 126(fvec4) Load 128(v) + ImageWrite 138 139 140 + 141: 23 Load 25(i2D) + 144: 27(ivec2) Load 143(ic2D) + 145: 126(fvec4) ImageRead 141 144 + 146: 126(fvec4) Load 128(v) + 147: 126(fvec4) FAdd 146 145 + Store 128(v) 147 + 148: 23 Load 25(i2D) + 149: 27(ivec2) Load 143(ic2D) + 150: 126(fvec4) Load 128(v) + ImageWrite 148 149 150 + 151: 34 Load 36(i3D) + 154: 7(ivec3) Load 153(ic3D) + 155: 126(fvec4) ImageRead 151 154 + 156: 126(fvec4) Load 128(v) + 157: 126(fvec4) FAdd 156 155 + Store 128(v) 157 + 158: 34 Load 36(i3D) + 159: 7(ivec3) Load 153(ic3D) + 160: 126(fvec4) Load 128(v) + ImageWrite 158 159 160 + 161: 41 Load 43(iCube) + 162: 7(ivec3) Load 153(ic3D) + 163: 126(fvec4) ImageRead 161 162 + 164: 126(fvec4) Load 128(v) + 165: 126(fvec4) FAdd 164 163 + Store 128(v) 165 + 166: 41 Load 43(iCube) + 167: 7(ivec3) Load 153(ic3D) + 168: 126(fvec4) Load 128(v) + ImageWrite 166 167 168 + 169: 51 Load 53(iCubeArray) + 173: 170(ivec4) Load 172(ic4D) + 174: 126(fvec4) ImageRead 169 173 + 175: 126(fvec4) Load 128(v) + 176: 126(fvec4) FAdd 175 174 + Store 128(v) 176 + 177: 51 Load 53(iCubeArray) + 178: 170(ivec4) Load 172(ic4D) + 179: 126(fvec4) Load 128(v) + ImageWrite 177 178 179 + 180: 58 Load 60(i2DRect) + 181: 27(ivec2) Load 143(ic2D) + 182: 126(fvec4) ImageRead 180 181 + 183: 126(fvec4) Load 128(v) + 184: 126(fvec4) FAdd 183 182 + Store 128(v) 184 + 185: 58 Load 60(i2DRect) + 186: 27(ivec2) Load 143(ic2D) + 187: 126(fvec4) Load 128(v) + ImageWrite 185 186 187 + 188: 68 Load 70(i1DArray) + 189: 27(ivec2) Load 143(ic2D) + 190: 126(fvec4) ImageRead 188 189 + 191: 126(fvec4) Load 128(v) + 192: 126(fvec4) FAdd 191 190 + Store 128(v) 192 + 193: 68 Load 70(i1DArray) + 194: 27(ivec2) Load 143(ic2D) + 195: 126(fvec4) Load 128(v) + ImageWrite 193 194 195 + 196: 78 Load 80(i2DArray) + 197: 7(ivec3) Load 153(ic3D) + 198: 126(fvec4) ImageRead 196 197 + 199: 126(fvec4) Load 128(v) + 200: 126(fvec4) FAdd 199 198 + Store 128(v) 200 + 201: 78 Load 80(i2DArray) + 202: 7(ivec3) Load 153(ic3D) + 203: 126(fvec4) Load 128(v) + ImageWrite 201 202 203 + 204: 85 Load 87(iBuffer) + 205: 6(int) Load 133(ic1D) + 206: 126(fvec4) ImageRead 204 205 + 207: 126(fvec4) Load 128(v) + 208: 126(fvec4) FAdd 207 206 + Store 128(v) 208 + 209: 85 Load 87(iBuffer) + 210: 6(int) Load 133(ic1D) + 211: 126(fvec4) Load 128(v) + ImageWrite 209 210 211 + 212: 95 Load 97(i2DMS) + 213: 27(ivec2) Load 143(ic2D) + 215: 126(fvec4) ImageRead 212 213 214 + 216: 126(fvec4) Load 128(v) + 217: 126(fvec4) FAdd 216 215 + Store 128(v) 217 + 218: 95 Load 97(i2DMS) + 219: 27(ivec2) Load 143(ic2D) + 221: 126(fvec4) Load 128(v) + ImageWrite 218 219 221 220 + 222: 105 Load 107(i2DMSArray) + 223: 7(ivec3) Load 153(ic3D) + 225: 126(fvec4) ImageRead 222 223 224 + 226: 126(fvec4) Load 128(v) + 227: 126(fvec4) FAdd 226 225 + Store 128(v) 227 + 228: 105 Load 107(i2DMSArray) + 229: 7(ivec3) Load 153(ic3D) + 231: 126(fvec4) Load 128(v) + ImageWrite 228 229 231 230 + Store 234(ui) 235 + 239: 6(int) Load 133(ic1D) + 242: 241(ptr) ImageTexelPointer 238(ii1D) 239 0 + 244: 6(int) AtomicIAdd 242 243 235 240 + 245: 7(ivec3) Load 9(iv) + 246: 6(int) CompositeExtract 245 0 + 247: 6(int) IAdd 246 244 + 248: 7(ivec3) Load 9(iv) + 249: 7(ivec3) CompositeInsert 247 248 0 + Store 9(iv) 249 + 253: 27(ivec2) Load 143(ic2D) + 256: 232(int) Load 255(value) + 258: 257(ptr) ImageTexelPointer 252(ui2D) 253 0 + 259: 232(int) AtomicIAdd 258 243 235 256 + 260: 232(int) Load 234(ui) + 261: 232(int) IAdd 260 259 + Store 234(ui) 261 + 262: 6(int) Load 133(ic1D) + 264: 241(ptr) ImageTexelPointer 238(ii1D) 262 0 + 265: 6(int) AtomicSMin 264 243 235 263 + 266: 7(ivec3) Load 9(iv) + 267: 6(int) CompositeExtract 266 0 + 268: 6(int) IAdd 267 265 + 269: 7(ivec3) Load 9(iv) + 270: 7(ivec3) CompositeInsert 268 269 0 + Store 9(iv) 270 + 271: 27(ivec2) Load 143(ic2D) + 272: 232(int) Load 255(value) + 273: 257(ptr) ImageTexelPointer 252(ui2D) 271 0 + 274: 232(int) AtomicUMin 273 243 235 272 + 275: 232(int) Load 234(ui) + 276: 232(int) IAdd 275 274 + Store 234(ui) 276 + 277: 6(int) Load 133(ic1D) + 279: 241(ptr) ImageTexelPointer 238(ii1D) 277 0 + 280: 6(int) AtomicSMax 279 243 235 278 + 281: 7(ivec3) Load 9(iv) + 282: 6(int) CompositeExtract 281 0 + 283: 6(int) IAdd 282 280 + 284: 7(ivec3) Load 9(iv) + 285: 7(ivec3) CompositeInsert 283 284 0 + Store 9(iv) 285 + 286: 27(ivec2) Load 143(ic2D) + 287: 232(int) Load 255(value) + 288: 257(ptr) ImageTexelPointer 252(ui2D) 286 0 + 289: 232(int) AtomicUMax 288 243 235 287 + 290: 232(int) Load 234(ui) + 291: 232(int) IAdd 290 289 + Store 234(ui) 291 + 292: 6(int) Load 133(ic1D) + 294: 241(ptr) ImageTexelPointer 238(ii1D) 292 0 + 295: 6(int) AtomicAnd 294 243 235 293 + 296: 7(ivec3) Load 9(iv) + 297: 6(int) CompositeExtract 296 0 + 298: 6(int) IAdd 297 295 + 299: 7(ivec3) Load 9(iv) + 300: 7(ivec3) CompositeInsert 298 299 0 + Store 9(iv) 300 + 301: 27(ivec2) Load 143(ic2D) + 302: 232(int) Load 255(value) + 303: 257(ptr) ImageTexelPointer 252(ui2D) 301 0 + 304: 232(int) AtomicAnd 303 243 235 302 + 305: 232(int) Load 234(ui) + 306: 232(int) IAdd 305 304 + Store 234(ui) 306 + 307: 6(int) Load 133(ic1D) + 309: 241(ptr) ImageTexelPointer 238(ii1D) 307 0 + 310: 6(int) AtomicOr 309 243 235 308 + 311: 7(ivec3) Load 9(iv) + 312: 6(int) CompositeExtract 311 0 + 313: 6(int) IAdd 312 310 + 314: 7(ivec3) Load 9(iv) + 315: 7(ivec3) CompositeInsert 313 314 0 + Store 9(iv) 315 + 316: 27(ivec2) Load 143(ic2D) + 317: 232(int) Load 255(value) + 318: 257(ptr) ImageTexelPointer 252(ui2D) 316 0 + 319: 232(int) AtomicOr 318 243 235 317 + 320: 232(int) Load 234(ui) + 321: 232(int) IAdd 320 319 + Store 234(ui) 321 + 322: 6(int) Load 133(ic1D) + 324: 241(ptr) ImageTexelPointer 238(ii1D) 322 0 + 325: 6(int) AtomicXor 324 243 235 323 + 326: 7(ivec3) Load 9(iv) + 327: 6(int) CompositeExtract 326 0 + 328: 6(int) IAdd 327 325 + 329: 7(ivec3) Load 9(iv) + 330: 7(ivec3) CompositeInsert 328 329 0 + Store 9(iv) 330 + 331: 27(ivec2) Load 143(ic2D) + 332: 232(int) Load 255(value) + 333: 257(ptr) ImageTexelPointer 252(ui2D) 331 0 + 334: 232(int) AtomicXor 333 243 235 332 + 335: 232(int) Load 234(ui) + 336: 232(int) IAdd 335 334 + Store 234(ui) 336 + 337: 6(int) Load 133(ic1D) + 339: 241(ptr) ImageTexelPointer 238(ii1D) 337 0 + 340: 6(int) AtomicExchange 339 243 235 338 + 341: 7(ivec3) Load 9(iv) + 342: 6(int) CompositeExtract 341 0 + 343: 6(int) IAdd 342 340 + 344: 7(ivec3) Load 9(iv) + 345: 7(ivec3) CompositeInsert 343 344 0 + Store 9(iv) 345 + 346: 27(ivec2) Load 143(ic2D) + 347: 232(int) Load 255(value) + 348: 257(ptr) ImageTexelPointer 252(ui2D) 346 0 + 349: 232(int) AtomicExchange 348 243 235 347 + 350: 232(int) Load 234(ui) + 351: 232(int) IAdd 350 349 + Store 234(ui) 351 + 352: 6(int) Load 133(ic1D) + 355: 241(ptr) ImageTexelPointer 238(ii1D) 352 0 + 356: 6(int) AtomicCompareExchange 355 243 235 235 354 353 + 357: 7(ivec3) Load 9(iv) + 358: 6(int) CompositeExtract 357 0 + 359: 6(int) IAdd 358 356 + 360: 7(ivec3) Load 9(iv) + 361: 7(ivec3) CompositeInsert 359 360 0 + Store 9(iv) 361 + 362: 27(ivec2) Load 143(ic2D) + 364: 232(int) Load 255(value) + 365: 257(ptr) ImageTexelPointer 252(ui2D) 362 0 + 366: 232(int) AtomicCompareExchange 365 243 235 235 364 363 + 367: 232(int) Load 234(ui) + 368: 232(int) IAdd 367 366 + Store 234(ui) 368 + 372: 232(int) Load 234(ui) + 373: 7(ivec3) Load 9(iv) + 374: 6(int) CompositeExtract 373 1 + 375: 232(int) Bitcast 374 + 377: 376(bool) INotEqual 372 375 + SelectionMerge 379 None + BranchConditional 377 378 381 + 378: Label + 380: 126(fvec4) Load 128(v) + Store 371 380 + Branch 379 + 381: Label + Store 371 130 + Branch 379 + 379: Label + 382: 126(fvec4) Load 371 + Store 370(fragData) 382 + Return + FunctionEnd diff --git a/Test/baseResults/spv.loopsArtificial.frag.out b/Test/baseResults/spv.loopsArtificial.frag.out index 3871d858..74cea2d2 100755 --- a/Test/baseResults/spv.loopsArtificial.frag.out +++ b/Test/baseResults/spv.loopsArtificial.frag.out @@ -117,15 +117,15 @@ Linked fragment stage: 8: TypePointer Function 7(fvec4) 10: TypePointer Input 7(fvec4) 11(BaseColor): 10(ptr) Variable Input - 17: TypeBool - 18: 17(bool) ConstantTrue + 16: TypeBool + 18: 16(bool) ConstantTrue 23: TypePointer UniformConstant 6(float) 24(d4): 23(ptr) Variable UniformConstant 28: TypePointer UniformConstant 7(fvec4) 29(bigColor4): 28(ptr) Variable UniformConstant 39: 6(float) Constant 1073741824 53: 6(float) Constant 1065353216 - 57: 17(bool) ConstantFalse + 57: 16(bool) ConstantFalse 83(d13): 23(ptr) Variable UniformConstant 147: TypePointer Output 7(fvec4) 148(gl_FragColor): 147(ptr) Variable Output @@ -181,17 +181,17 @@ Linked fragment stage: Store 9(color) 12 Branch 13 13: Label - 16: 17(bool) Phi 18 5 57 49 57 64 + 17: 16(bool) Phi 18 5 57 49 57 64 LoopMerge 14 None Branch 19 19: Label SelectionMerge 15 None - BranchConditional 16 15 20 + BranchConditional 17 15 20 20: Label 21: 7(fvec4) Load 9(color) 22: 6(float) CompositeExtract 21 2 25: 6(float) Load 24(d4) - 26: 17(bool) FOrdLessThan 22 25 + 26: 16(bool) FOrdLessThan 22 25 SelectionMerge 27 None BranchConditional 26 27 14 27: Label @@ -204,7 +204,7 @@ Linked fragment stage: 33: 7(fvec4) Load 9(color) 34: 6(float) CompositeExtract 33 0 35: 6(float) Load 24(d4) - 36: 17(bool) FOrdLessThan 34 35 + 36: 16(bool) FOrdLessThan 34 35 SelectionMerge 38 None BranchConditional 36 37 38 37: Label @@ -217,7 +217,7 @@ Linked fragment stage: 45: 7(fvec4) Load 9(color) 46: 6(float) CompositeExtract 45 2 47: 6(float) Load 24(d4) - 48: 17(bool) FOrdLessThan 46 47 + 48: 16(bool) FOrdLessThan 46 47 SelectionMerge 50 None BranchConditional 48 49 50 49: Label @@ -234,7 +234,7 @@ Linked fragment stage: 59: 7(fvec4) Load 9(color) 60: 6(float) CompositeExtract 59 1 61: 6(float) Load 24(d4) - 62: 17(bool) FOrdLessThan 60 61 + 62: 16(bool) FOrdLessThan 60 61 SelectionMerge 64 None BranchConditional 62 63 71 63: Label @@ -263,14 +263,14 @@ Linked fragment stage: 81: 7(fvec4) Load 9(color) 82: 6(float) CompositeExtract 81 3 84: 6(float) Load 83(d13) - 85: 17(bool) FOrdLessThan 82 84 + 85: 16(bool) FOrdLessThan 82 84 LoopMerge 79 None BranchConditional 85 80 79 80: Label 86: 7(fvec4) Load 9(color) 87: 6(float) CompositeExtract 86 2 88: 6(float) Load 83(d13) - 89: 17(bool) FOrdLessThan 87 88 + 89: 16(bool) FOrdLessThan 87 88 SelectionMerge 91 None BranchConditional 89 90 95 90: Label @@ -293,7 +293,7 @@ Linked fragment stage: 102: 7(fvec4) Load 9(color) 103: 6(float) CompositeExtract 102 0 104: 6(float) Load 24(d4) - 105: 17(bool) FOrdLessThan 103 104 + 105: 16(bool) FOrdLessThan 103 104 SelectionMerge 107 None BranchConditional 105 106 107 106: Label @@ -306,7 +306,7 @@ Linked fragment stage: 113: 7(fvec4) Load 9(color) 114: 6(float) CompositeExtract 113 2 115: 6(float) Load 24(d4) - 116: 17(bool) FOrdLessThan 114 115 + 116: 16(bool) FOrdLessThan 114 115 SelectionMerge 118 None BranchConditional 116 117 118 117: Label @@ -323,7 +323,7 @@ Linked fragment stage: 125: 7(fvec4) Load 9(color) 126: 6(float) CompositeExtract 125 1 127: 6(float) Load 24(d4) - 128: 17(bool) FOrdLessThan 126 127 + 128: 16(bool) FOrdLessThan 126 127 SelectionMerge 130 None BranchConditional 128 129 137 129: Label diff --git a/Test/baseResults/spv.newTexture.frag.out b/Test/baseResults/spv.newTexture.frag.out index ef635657..d9ca9217 100644 --- a/Test/baseResults/spv.newTexture.frag.out +++ b/Test/baseResults/spv.newTexture.frag.out @@ -196,13 +196,13 @@ Linked fragment stage: 64: 21 Load 23(s3D) 68: 65(ivec3) Load 67(ic3D) 71: 50(int) Load 70(ic1D) - 72: 7(fvec4) ImageFetch 64 68 + 72: 7(fvec4) ImageFetch 64 68 71 73: 7(fvec4) Load 9(v) 74: 7(fvec4) FAdd 73 72 Store 9(v) 74 75: 11 Load 13(s2D) 78: 51(ivec2) Load 77(ic2D) - 80: 7(fvec4) ImageFetch 75 78 79 + 80: 7(fvec4) ImageFetch 75 78 79 53 81: 7(fvec4) Load 9(v) 82: 7(fvec4) FAdd 81 80 Store 9(v) 82 @@ -321,7 +321,7 @@ Linked fragment stage: 205: 202 Load 204(is2DArray) 206: 65(ivec3) Load 67(ic3D) 207: 50(int) Load 70(ic1D) - 208: 139(ivec4) ImageFetch 205 206 + 208: 139(ivec4) ImageFetch 205 206 207 Store 141(iv) 208 209: 139(ivec4) Load 141(iv) 210: 7(fvec4) ConvertSToF 209 diff --git a/Test/baseResults/spv.texture.frag.out b/Test/baseResults/spv.texture.frag.out index 010ea35f..bba3fb13 100644 --- a/Test/baseResults/spv.texture.frag.out +++ b/Test/baseResults/spv.texture.frag.out @@ -310,7 +310,7 @@ Linked fragment stage: 214: 70 Load 72(texSampler2D) 215: 205(ivec2) Load 207(iCoords2D) 216: 204(int) Load 212(iLod) - 217: 22(fvec4) ImageFetch 214 215 + 217: 22(fvec4) ImageFetch 214 215 216 218: 22(fvec4) Load 26(color) 219: 22(fvec4) FAdd 218 217 Store 26(color) 219 diff --git a/Test/spv.image.frag b/Test/spv.image.frag new file mode 100644 index 00000000..21269ea6 --- /dev/null +++ b/Test/spv.image.frag @@ -0,0 +1,89 @@ +#version 450 + +layout(rgba32f, binding = 0) uniform image1D i1D; +layout(rgba32f, binding = 1) uniform image2D i2D; +layout(rgba32f, binding = 2) uniform image3D i3D; +layout(rgba32f, binding = 3) uniform imageCube iCube; +layout(rgba32f, binding = 4) uniform imageCubeArray iCubeArray; +layout(rgba32f, binding = 5) uniform image2DRect i2DRect; +layout(rgba32f, binding = 6) uniform image1DArray i1DArray; +layout(rgba32f, binding = 7) uniform image2DArray i2DArray; +layout(rgba32f, binding = 8) uniform imageBuffer iBuffer; +layout(rgba32f, binding = 9) uniform image2DMS i2DMS; +layout(rgba32f, binding = 10) uniform image2DMSArray i2DMSArray; + +layout(r32i, binding = 11) uniform iimage1D ii1D; +layout(r32ui, binding = 12) uniform uimage2D ui2D; + +uniform int ic1D; +uniform ivec2 ic2D; +uniform ivec3 ic3D; +uniform ivec4 ic4D; + +uniform uint value; + +out vec4 fragData; + +void main() +{ + ivec3 iv = ivec3(0); + iv.x += imageSize(i1D); + iv.xy += imageSize(i2D); + iv.xyz += imageSize(i3D); + iv.xy += imageSize(iCube); + iv.xyz += imageSize(iCubeArray); + iv.xy += imageSize(i2DRect); + iv.xy += imageSize(i1DArray); + iv.xyz += imageSize(i2DArray); + iv.x += imageSize(iBuffer); + iv.xy += imageSize(i2DMS); + iv.xyz += imageSize(i2DMSArray); + + iv.x += imageSamples(i2DMS); + iv.x += imageSamples(i2DMSArray); + + vec4 v = vec4(0.0); + v += imageLoad(i1D, ic1D); + imageStore(i1D, ic1D, v); + v += imageLoad(i2D, ic2D); + imageStore(i2D, ic2D, v); + v += imageLoad(i3D, ic3D); + imageStore(i3D, ic3D, v); + v += imageLoad(iCube, ic3D); + imageStore(iCube, ic3D, v); + v += imageLoad(iCubeArray, ic4D); + imageStore(iCubeArray, ic4D, v); + v += imageLoad(i2DRect, ic2D); + imageStore(i2DRect, ic2D, v); + v += imageLoad(i1DArray, ic2D); + imageStore(i1DArray, ic2D, v); + v += imageLoad(i2DArray, ic3D); + imageStore(i2DArray, ic3D, v); + v += imageLoad(iBuffer, ic1D); + imageStore(iBuffer, ic1D, v); + v += imageLoad(i2DMS, ic2D, 1); + imageStore(i2DMS, ic2D, 2, v); + v += imageLoad(i2DMSArray, ic3D, 3); + imageStore(i2DMSArray, ic3D, 4, v); + + uint ui = 0; + iv.x += imageAtomicAdd(ii1D, ic1D, 10); + ui += imageAtomicAdd(ui2D, ic2D, value); + iv.x += imageAtomicMin(ii1D, ic1D, 11); + ui += imageAtomicMin(ui2D, ic2D, value); + iv.x += imageAtomicMax(ii1D, ic1D, 12); + ui += imageAtomicMax(ui2D, ic2D, value); + iv.x += imageAtomicAnd(ii1D, ic1D, 13); + ui += imageAtomicAnd(ui2D, ic2D, value); + iv.x += imageAtomicOr(ii1D, ic1D, 14); + ui += imageAtomicOr(ui2D, ic2D, value); + iv.x += imageAtomicXor(ii1D, ic1D, 15); + ui += imageAtomicXor(ui2D, ic2D, value); + iv.x += imageAtomicExchange(ii1D, ic1D, 16); + ui += imageAtomicExchange(ui2D, ic2D, value); + iv.x += imageAtomicCompSwap(ii1D, ic1D, 18, 17); + ui += imageAtomicCompSwap(ui2D, ic2D, 19u, value); + + fragData = ui != iv.y ? v : vec4(0.0); +} + diff --git a/Test/test-spirv-list b/Test/test-spirv-list index bddd8aa8..d3b65213 100644 --- a/Test/test-spirv-list +++ b/Test/test-spirv-list @@ -70,6 +70,7 @@ spv.test.frag spv.test.vert spv.texture.frag spv.texture.vert +spv.image.frag spv.types.frag spv.uint.frag spv.uniformArray.frag diff --git a/glslang/Include/intermediate.h b/glslang/Include/intermediate.h index 9d9d28a1..59955fcf 100644 --- a/glslang/Include/intermediate.h +++ b/glslang/Include/intermediate.h @@ -639,7 +639,7 @@ public: bool isImage() const { return op > EOpImageGuardBegin && op < EOpImageGuardEnd; } // Crack the op into the individual dimensions of texturing operation. - void crackTexture(TCrackedTextureOp& cracked) const + void crackTexture(TSampler sampler, TCrackedTextureOp& cracked) const { cracked.query = false; cracked.proj = false; @@ -651,6 +651,8 @@ public: cracked.grad = false; switch (op) { + case EOpImageQuerySize: + case EOpImageQuerySamples: case EOpTextureQuerySize: case EOpTextureQueryLod: case EOpTextureQueryLevels: @@ -670,10 +672,14 @@ public: break; case EOpTextureFetch: cracked.fetch = true; + if (sampler.dim == Esd1D || (sampler.dim == Esd2D && ! sampler.ms) || sampler.dim == Esd3D) + cracked.lod = true; break; case EOpTextureFetchOffset: cracked.fetch = true; cracked.offset = true; + if (sampler.dim == Esd1D || (sampler.dim == Esd2D && ! sampler.ms) || sampler.dim == Esd3D) + cracked.lod = true; break; case EOpTextureProjOffset: cracked.offset = true; diff --git a/glslang/MachineIndependent/Constant.cpp b/glslang/MachineIndependent/Constant.cpp index e64ee3df..6a797f0a 100644 --- a/glslang/MachineIndependent/Constant.cpp +++ b/glslang/MachineIndependent/Constant.cpp @@ -768,7 +768,7 @@ TIntermTyped* TIntermediate::fold(TIntermAggregate* aggrNode) } break; case EOpReflect: - // I – 2 * dot(N, I) * N: Arguments are (I, N). + // I - 2 * dot(N, I) * N: Arguments are (I, N). dot = childConstUnions[0].dot(childConstUnions[1]); dot *= 2.0; for (int comp = 0; comp < numComps; ++comp) diff --git a/glslang/MachineIndependent/ParseHelper.cpp b/glslang/MachineIndependent/ParseHelper.cpp index 4ab1c9f0..f91d93d8 100644 --- a/glslang/MachineIndependent/ParseHelper.cpp +++ b/glslang/MachineIndependent/ParseHelper.cpp @@ -4090,7 +4090,7 @@ void TParseContext::layoutTypeCheck(const TSourceLoc& loc, const TType& type) // "If the binding point for any uniform or shader storage block instance is less than zero, or greater than or // equal to the implementation-dependent maximum number of uniform buffer bindings, a compile-time // error will occur. When the binding identifier is used with a uniform or shader storage block instanced as - // an array of size N, all elements of the array from binding through binding + N – 1 must be within this + // an array of size N, all elements of the array from binding through binding + N - 1 must be within this // range." // if (type.getBasicType() != EbtSampler && type.getBasicType() != EbtBlock && type.getBasicType() != EbtAtomicUint)