From 0e1893f2924f125e613cc88a179ad81d16bb8c82 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Branimir=20Karad=C5=BEi=C4=87?= Date: Fri, 21 Jul 2017 19:49:23 -0700 Subject: [PATCH] Updated glslang. --- 3rdparty/glslang/SPIRV/GlslangToSpv.cpp | 18 ++- 3rdparty/glslang/SPIRV/SpvBuilder.cpp | 12 +- 3rdparty/glslang/SPIRV/SpvBuilder.h | 2 +- 3rdparty/glslang/StandAlone/StandAlone.cpp | 41 +++--- .../glslang/Test/baseResults/glspv.frag.out | 7 +- .../hlsl.explicitDescriptorSet-2.frag.out | 66 +++++++++ .../hlsl.explicitDescriptorSet.frag.out | 66 +++++++++ .../baseResults/hlsl.structbuffer.fn.frag.out | 1 + .../hlsl.structbuffer.fn2.comp.out | 1 + .../Test/baseResults/spv.paramMemory.frag.out | 137 ++++++++++++++++++ 3rdparty/glslang/Test/glspv.frag | 7 +- .../Test/hlsl.explicitDescriptorSet.frag | 15 ++ 3rdparty/glslang/Test/runtests | 6 + 3rdparty/glslang/Test/spv.paramMemory.frag | 30 ++++ 3rdparty/glslang/Test/spv.targetOpenGL.vert | 5 +- .../MachineIndependent/ParseHelper.cpp | 18 ++- .../glslang/MachineIndependent/ParseHelper.h | 2 +- .../glslang/MachineIndependent/ShaderLang.cpp | 1 + .../glslang/MachineIndependent/iomapper.cpp | 5 + .../glslang/MachineIndependent/reflection.h | 21 ++- 3rdparty/glslang/glslang/Public/ShaderLang.h | 1 + 3rdparty/glslang/gtests/Spv.FromFile.cpp | 1 + 3rdparty/glslang/hlsl/hlslParseHelper.cpp | 18 ++- 23 files changed, 421 insertions(+), 60 deletions(-) create mode 100644 3rdparty/glslang/Test/baseResults/hlsl.explicitDescriptorSet-2.frag.out create mode 100644 3rdparty/glslang/Test/baseResults/hlsl.explicitDescriptorSet.frag.out create mode 100755 3rdparty/glslang/Test/baseResults/spv.paramMemory.frag.out create mode 100644 3rdparty/glslang/Test/hlsl.explicitDescriptorSet.frag create mode 100644 3rdparty/glslang/Test/spv.paramMemory.frag diff --git a/3rdparty/glslang/SPIRV/GlslangToSpv.cpp b/3rdparty/glslang/SPIRV/GlslangToSpv.cpp index 2899a741d..b65d6ed61 100755 --- a/3rdparty/glslang/SPIRV/GlslangToSpv.cpp +++ b/3rdparty/glslang/SPIRV/GlslangToSpv.cpp @@ -2914,6 +2914,13 @@ bool TGlslangToSpvTraverser::isShaderEntryPoint(const glslang::TIntermAggregate* // Make all the functions, skeletally, without actually visiting their bodies. void TGlslangToSpvTraverser::makeFunctions(const glslang::TIntermSequence& glslFunctions) { + const auto getParamDecorations = [](std::vector& decorations, const glslang::TType& type) { + spv::Decoration paramPrecision = TranslatePrecisionDecoration(type); + if (paramPrecision != spv::NoPrecision) + decorations.push_back(paramPrecision); + TranslateMemoryDecoration(type.getQualifier(), decorations); + }; + for (int f = 0; f < (int)glslFunctions.size(); ++f) { glslang::TIntermAggregate* glslFunction = glslFunctions[f]->getAsAggregate(); if (! glslFunction || glslFunction->getOp() != glslang::EOpFunction || isShaderEntryPoint(glslFunction)) @@ -2934,11 +2941,13 @@ void TGlslangToSpvTraverser::makeFunctions(const glslang::TIntermSequence& glslF // GLSL has copy-in/copy-out semantics. They can be handled though with a pointer to a copy. std::vector paramTypes; - std::vector paramPrecisions; + std::vector> paramDecorations; // list of decorations per parameter glslang::TIntermSequence& parameters = glslFunction->getSequence()[0]->getAsAggregate()->getSequence(); - bool implicitThis = (int)parameters.size() > 0 && parameters[0]->getAsSymbolNode()->getName() == glslangIntermediate->implicitThisName; + bool implicitThis = (int)parameters.size() > 0 && parameters[0]->getAsSymbolNode()->getName() == + glslangIntermediate->implicitThisName; + paramDecorations.resize(parameters.size()); for (int p = 0; p < (int)parameters.size(); ++p) { const glslang::TType& paramType = parameters[p]->getAsTyped()->getType(); spv::Id typeId = convertGlslangToSpvType(paramType); @@ -2952,14 +2961,15 @@ void TGlslangToSpvTraverser::makeFunctions(const glslang::TIntermSequence& glslF typeId = builder.makePointer(spv::StorageClassFunction, typeId); else rValueParameters.insert(parameters[p]->getAsSymbolNode()->getId()); - paramPrecisions.push_back(TranslatePrecisionDecoration(paramType)); + getParamDecorations(paramDecorations[p], paramType); paramTypes.push_back(typeId); } spv::Block* functionBlock; spv::Function *function = builder.makeFunctionEntry(TranslatePrecisionDecoration(glslFunction->getType()), convertGlslangToSpvType(glslFunction->getType()), - glslFunction->getName().c_str(), paramTypes, paramPrecisions, &functionBlock); + glslFunction->getName().c_str(), paramTypes, + paramDecorations, &functionBlock); if (implicitThis) function->setImplicitThis(); diff --git a/3rdparty/glslang/SPIRV/SpvBuilder.cpp b/3rdparty/glslang/SPIRV/SpvBuilder.cpp index 11e9fe600..d472eb533 100644 --- a/3rdparty/glslang/SPIRV/SpvBuilder.cpp +++ b/3rdparty/glslang/SPIRV/SpvBuilder.cpp @@ -983,16 +983,16 @@ Function* Builder::makeEntryPoint(const char* entryPoint) Block* entry; std::vector params; - std::vector precisions; + std::vector> decorations; - entryPointFunction = makeFunctionEntry(NoPrecision, makeVoidType(), entryPoint, params, precisions, &entry); + entryPointFunction = makeFunctionEntry(NoPrecision, makeVoidType(), entryPoint, params, decorations, &entry); return entryPointFunction; } // Comments in header Function* Builder::makeFunctionEntry(Decoration precision, Id returnType, const char* name, - const std::vector& paramTypes, const std::vector& precisions, Block **entry) + const std::vector& paramTypes, const std::vector>& decorations, Block **entry) { // Make the function and initial instructions in it Id typeId = makeFunctionType(returnType, paramTypes); @@ -1001,8 +1001,10 @@ Function* Builder::makeFunctionEntry(Decoration precision, Id returnType, const // Set up the precisions setPrecision(function->getId(), precision); - for (unsigned p = 0; p < (unsigned)precisions.size(); ++p) - setPrecision(firstParamId + p, precisions[p]); + for (unsigned p = 0; p < (unsigned)decorations.size(); ++p) { + for (int d = 0; d < (int)decorations[p].size(); ++d) + addDecoration(firstParamId + p, decorations[p][d]); + } // CFG if (entry) { diff --git a/3rdparty/glslang/SPIRV/SpvBuilder.h b/3rdparty/glslang/SPIRV/SpvBuilder.h index 2b17ba608..3a949190a 100755 --- a/3rdparty/glslang/SPIRV/SpvBuilder.h +++ b/3rdparty/glslang/SPIRV/SpvBuilder.h @@ -247,7 +247,7 @@ public: // Return the function, pass back the entry. // The returned pointer is only valid for the lifetime of this builder. Function* makeFunctionEntry(Decoration precision, Id returnType, const char* name, const std::vector& paramTypes, - const std::vector& precisions, Block **entry = 0); + const std::vector>& precisions, Block **entry = 0); // Create a return. An 'implicit' return is one not appearing in the source // code. In the case of an implicit return, no post-return block is inserted. diff --git a/3rdparty/glslang/StandAlone/StandAlone.cpp b/3rdparty/glslang/StandAlone/StandAlone.cpp index 1089432a3..3301df453 100644 --- a/3rdparty/glslang/StandAlone/StandAlone.cpp +++ b/3rdparty/glslang/StandAlone/StandAlone.cpp @@ -289,31 +289,29 @@ void ProcessResourceSetBindingBase(int& argc, char**& argv, std::array 1 && argv[1] != nullptr && argv[1][0] != '-') { + base[lang].push_back(argv[1]); + + argc--; + argv++; } + + // Must have one arg, or a multiple of three (for [regname set binding] triples) + if (base[lang].size() != 1 && (base[lang].size() % 3) != 0) + usage(); + } else { - // Parse form: --argname base + // Parse form: --argname set for (int lang=0; lang g_tTex1df4 : register(t0); + +SamplerState g_sSamp2_amb; +uniform float floatval_amb; + +Buffer floatbuff; + +float4 main() : SV_Target0 +{ + g_sSamp2_amb; + + return 0; +} diff --git a/3rdparty/glslang/Test/runtests b/3rdparty/glslang/Test/runtests index 2a8542f49..c5a93378f 100755 --- a/3rdparty/glslang/Test/runtests +++ b/3rdparty/glslang/Test/runtests @@ -97,6 +97,12 @@ echo Configuring HLSL descriptor set and binding number manually $EXE -V -D -e main -H hlsl.multiDescriptorSet.frag --rsb frag t0 0 0 t1 1 0 s0 0 1 s1 1 1 b0 2 0 b1 2 1 b2 2 2 > $TARGETDIR/hlsl.multiDescriptorSet.frag.out diff -b $BASEDIR/hlsl.multiDescriptorSet.frag.out $TARGETDIR/hlsl.multiDescriptorSet.frag.out || HASERROR=1 +$EXE -V -D -e main -H hlsl.explicitDescriptorSet.frag --hlsl-iomap --amb --ssb 10 --stb 20 --rsb 4 > $TARGETDIR/hlsl.explicitDescriptorSet.frag.out +diff -b $BASEDIR/hlsl.explicitDescriptorSet.frag.out $TARGETDIR/hlsl.explicitDescriptorSet.frag.out || HASERROR=1 + +$EXE -V -D -e main -H hlsl.explicitDescriptorSet.frag --hlsl-iomap --amb --ssb 10 --stb 20 --rsb frag 3 > $TARGETDIR/hlsl.explicitDescriptorSet-2.frag.out +diff -b $BASEDIR/hlsl.explicitDescriptorSet-2.frag.out $TARGETDIR/hlsl.explicitDescriptorSet-2.frag.out || HASERROR=1 + # # Testing location error # diff --git a/3rdparty/glslang/Test/spv.paramMemory.frag b/3rdparty/glslang/Test/spv.paramMemory.frag new file mode 100644 index 000000000..79d2fe579 --- /dev/null +++ b/3rdparty/glslang/Test/spv.paramMemory.frag @@ -0,0 +1,30 @@ +#version 310 es + +readonly coherent uniform layout(set = 0, binding = 0, rgba32f) highp image2D image1; +readonly uniform layout(set = 0, binding = 2, rgba16f) highp image2D image2; +writeonly coherent uniform layout(set = 0, binding = 1, rgba32f) highp image2D image3; +writeonly uniform layout(set = 0, binding = 3, rgba16f) highp image2D image4; + +flat in layout(location = 0) highp ivec2 in_coords; +out layout(location = 0) highp vec4 out_color; + +highp vec4 image_load(readonly coherent highp image2D image, highp ivec2 coords) +{ + return imageLoad(image, in_coords); +} + +void image_store(writeonly coherent highp image2D image, highp ivec2 coords, highp vec4 data) +{ + imageStore(image, in_coords, data); +} + +void main() +{ + highp vec4 read1 = image_load(image1, in_coords); + highp vec4 read2 = image_load(image2, in_coords); + + image_store(image3, in_coords, read1*0.5); + image_store(image4, in_coords, read2*2.0); + + out_color = vec4(0.0); +} diff --git a/3rdparty/glslang/Test/spv.targetOpenGL.vert b/3rdparty/glslang/Test/spv.targetOpenGL.vert index 0920334fa..6d68a3391 100755 --- a/3rdparty/glslang/Test/spv.targetOpenGL.vert +++ b/3rdparty/glslang/Test/spv.targetOpenGL.vert @@ -1,8 +1,9 @@ #version 450 layout(constant_id = 3) const int a = 2; - -uniform float f; +layout(location = 2) uniform float f; +layout(location = 4) uniform sampler2D s1; +uniform sampler2D s2; void main() { diff --git a/3rdparty/glslang/glslang/MachineIndependent/ParseHelper.cpp b/3rdparty/glslang/glslang/MachineIndependent/ParseHelper.cpp index 1d56c1fa8..25d360e69 100644 --- a/3rdparty/glslang/glslang/MachineIndependent/ParseHelper.cpp +++ b/3rdparty/glslang/glslang/MachineIndependent/ParseHelper.cpp @@ -2472,16 +2472,22 @@ void TParseContext::atomicUintCheck(const TSourceLoc& loc, const TType& type, co error(loc, "atomic_uints can only be used in uniform variables or function parameters:", type.getBasicTypeString().c_str(), identifier.c_str()); } -void TParseContext::transparentCheck(const TSourceLoc& loc, const TType& type, const TString& /*identifier*/) +void TParseContext::transparentOpaqueCheck(const TSourceLoc& loc, const TType& type, const TString& identifier) { if (parsingBuiltins) return; - // Vulkan doesn't allow transparent uniforms outside of blocks - if (spvVersion.vulkan == 0 || type.getQualifier().storage != EvqUniform) + if (type.getQualifier().storage != EvqUniform) return; - if (type.containsNonOpaque()) - vulkanRemoved(loc, "non-opaque uniforms outside a block"); + + if (type.containsNonOpaque()) { + // Vulkan doesn't allow transparent uniforms outside of blocks + if (spvVersion.vulkan > 0) + vulkanRemoved(loc, "non-opaque uniforms outside a block"); + // OpenGL wants locations on these + if (spvVersion.openGl > 0 && !type.getQualifier().hasLocation()) + error(loc, "non-opaque uniform variables need a layout(location=L)", identifier.c_str(), ""); + } } // @@ -5107,7 +5113,7 @@ TIntermNode* TParseContext::declareVariable(const TSourceLoc& loc, TString& iden samplerCheck(loc, type, identifier, initializer); atomicUintCheck(loc, type, identifier); - transparentCheck(loc, type, identifier); + transparentOpaqueCheck(loc, type, identifier); if (identifier != "gl_FragCoord" && (publicType.shaderQualifiers.originUpperLeft || publicType.shaderQualifiers.pixelCenterInteger)) error(loc, "can only apply origin_upper_left and pixel_center_origin to gl_FragCoord", "layout qualifier", ""); diff --git a/3rdparty/glslang/glslang/MachineIndependent/ParseHelper.h b/3rdparty/glslang/glslang/MachineIndependent/ParseHelper.h index 9e81a378a..73f2470ca 100644 --- a/3rdparty/glslang/glslang/MachineIndependent/ParseHelper.h +++ b/3rdparty/glslang/glslang/MachineIndependent/ParseHelper.h @@ -327,7 +327,7 @@ public: void boolCheck(const TSourceLoc&, const TPublicType&); void samplerCheck(const TSourceLoc&, const TType&, const TString& identifier, TIntermTyped* initializer); void atomicUintCheck(const TSourceLoc&, const TType&, const TString& identifier); - void transparentCheck(const TSourceLoc&, const TType&, const TString& identifier); + void transparentOpaqueCheck(const TSourceLoc&, const TType&, const TString& identifier); void globalQualifierFixCheck(const TSourceLoc&, TQualifier&); void globalQualifierTypeCheck(const TSourceLoc&, const TQualifier&, const TPublicType&); bool structQualifierErrorCheck(const TSourceLoc&, const TPublicType& pType); diff --git a/3rdparty/glslang/glslang/MachineIndependent/ShaderLang.cpp b/3rdparty/glslang/glslang/MachineIndependent/ShaderLang.cpp index 26f81bd9a..93f1568fc 100644 --- a/3rdparty/glslang/glslang/MachineIndependent/ShaderLang.cpp +++ b/3rdparty/glslang/glslang/MachineIndependent/ShaderLang.cpp @@ -1836,6 +1836,7 @@ const char* TProgram::getUniformName(int index) const { return reflection const char* TProgram::getUniformBlockName(int index) const { return reflection->getUniformBlock(index).name.c_str(); } int TProgram::getUniformBlockSize(int index) const { return reflection->getUniformBlock(index).size; } int TProgram::getUniformIndex(const char* name) const { return reflection->getIndex(name); } +int TProgram::getUniformBinding(int index) const { return reflection->getUniform(index).getBinding(); } int TProgram::getUniformBlockIndex(int index) const { return reflection->getUniform(index).index; } int TProgram::getUniformBlockCounterIndex(int index) const { return reflection->getUniformBlock(index).counterIndex; } int TProgram::getUniformType(int index) const { return reflection->getUniform(index).glDefineType; } diff --git a/3rdparty/glslang/glslang/MachineIndependent/iomapper.cpp b/3rdparty/glslang/glslang/MachineIndependent/iomapper.cpp index ea5f16113..958562708 100644 --- a/3rdparty/glslang/glslang/MachineIndependent/iomapper.cpp +++ b/3rdparty/glslang/glslang/MachineIndependent/iomapper.cpp @@ -404,6 +404,11 @@ struct TDefaultIoResolverBase : public glslang::TIoMapResolver { if (type.getQualifier().hasSet()) return type.getQualifier().layoutSet; + + // If a command line or API option requested a single descriptor set, use that (if not overrided by spaceN) + if (baseResourceSetBinding.size() == 1) + return atoi(baseResourceSetBinding[0].c_str()); + return 0; } diff --git a/3rdparty/glslang/glslang/MachineIndependent/reflection.h b/3rdparty/glslang/glslang/MachineIndependent/reflection.h index 7a1cc8ed8..fedfbe8d4 100644 --- a/3rdparty/glslang/glslang/MachineIndependent/reflection.h +++ b/3rdparty/glslang/glslang/MachineIndependent/reflection.h @@ -59,7 +59,15 @@ public: name(pName), offset(pOffset), glDefineType(pGLDefineType), size(pSize), index(pIndex), counterIndex(-1), type(pType.clone()) { } - void dump() const { + const TType* const getType() const { return type; } + int getBinding() const + { + if (type == nullptr || !type->getQualifier().hasBinding()) + return -1; + return type->getQualifier().layoutBinding; + } + void dump() const + { printf("%s: offset %d, type %x, size %d, index %d, binding %d", name.c_str(), offset, glDefineType, size, index, getBinding() ); @@ -68,8 +76,7 @@ public: printf("\n"); } - - const TType* const getType() const { return type; } + static TObjectReflection badReflection() { return TObjectReflection(); } TString name; int offset; @@ -78,15 +85,7 @@ public: int index; int counterIndex; - static TObjectReflection badReflection() { return TObjectReflection(); } - protected: - int getBinding() const { - if (type == nullptr || type->getQualifier().layoutBinding == TQualifier::layoutBindingEnd) - return -1; - return type->getQualifier().layoutBinding; - } - TObjectReflection() : offset(-1), glDefineType(-1), size(-1), index(-1), type(nullptr) { } const TType* type; diff --git a/3rdparty/glslang/glslang/Public/ShaderLang.h b/3rdparty/glslang/glslang/Public/ShaderLang.h index 2a0247875..12672eeea 100644 --- a/3rdparty/glslang/glslang/Public/ShaderLang.h +++ b/3rdparty/glslang/glslang/Public/ShaderLang.h @@ -619,6 +619,7 @@ public: const char* getUniformBlockName(int blockIndex) const; // can be used for glGetActiveUniformBlockName() int getUniformBlockSize(int blockIndex) const; // can be used for glGetActiveUniformBlockiv(UNIFORM_BLOCK_DATA_SIZE) int getUniformIndex(const char* name) const; // can be used for glGetUniformIndices() + int getUniformBinding(int index) const; // returns the binding number int getUniformBlockIndex(int index) const; // can be used for glGetActiveUniformsiv(GL_UNIFORM_BLOCK_INDEX) int getUniformBlockCounterIndex(int index) const; // returns block index of associated counter. int getUniformType(int index) const; // can be used for glGetActiveUniformsiv(GL_UNIFORM_TYPE) diff --git a/3rdparty/glslang/gtests/Spv.FromFile.cpp b/3rdparty/glslang/gtests/Spv.FromFile.cpp index 268aa0b78..dfad30c72 100644 --- a/3rdparty/glslang/gtests/Spv.FromFile.cpp +++ b/3rdparty/glslang/gtests/Spv.FromFile.cpp @@ -275,6 +275,7 @@ INSTANTIATE_TEST_CASE_P( "spv.noWorkgroup.comp", "spv.offsets.frag", "spv.Operations.frag", + "spv.paramMemory.frag", "spv.precision.frag", "spv.prepost.frag", "spv.qualifiers.vert", diff --git a/3rdparty/glslang/hlsl/hlslParseHelper.cpp b/3rdparty/glslang/hlsl/hlslParseHelper.cpp index 6e12f8201..dc44c3697 100755 --- a/3rdparty/glslang/hlsl/hlslParseHelper.cpp +++ b/3rdparty/glslang/hlsl/hlslParseHelper.cpp @@ -5411,7 +5411,7 @@ void HlslParseContext::handleRegister(const TSourceLoc& loc, TQualifier& qualifi } // TODO: learn what all these really mean and how they interact with regNumber and subComponent - std::vector resourceInfo = intermediate.getResourceSetBinding(); + const std::vector& resourceInfo = intermediate.getResourceSetBinding(); switch (std::tolower(desc[0])) { case 'b': case 't': @@ -5419,11 +5419,17 @@ void HlslParseContext::handleRegister(const TSourceLoc& loc, TQualifier& qualifi case 's': case 'u': qualifier.layoutBinding = regNumber + subComponent; - for (auto it = resourceInfo.cbegin(); it != resourceInfo.cend(); it = it + 3) { - if (strcmp(desc.c_str(), it[0].c_str()) == 0) { - qualifier.layoutSet = atoi(it[1].c_str()); - qualifier.layoutBinding = atoi(it[2].c_str()) + subComponent; - break; + + // This handles per-register layout sets numbers. For the global mode which sets + // every symbol to the same value, see setLinkageLayoutSets(). + if ((resourceInfo.size() % 3) == 0) { + // Apply per-symbol resource set and binding. + for (auto it = resourceInfo.cbegin(); it != resourceInfo.cend(); it = it + 3) { + if (strcmp(desc.c_str(), it[0].c_str()) == 0) { + qualifier.layoutSet = atoi(it[1].c_str()); + qualifier.layoutBinding = atoi(it[2].c_str()) + subComponent; + break; + } } } break;