diff --git a/SPIRV/GlslangToSpv.cpp b/SPIRV/GlslangToSpv.cpp index 2899a741..fe51ae1d 100755 --- a/SPIRV/GlslangToSpv.cpp +++ b/SPIRV/GlslangToSpv.cpp @@ -2914,6 +2914,12 @@ 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); + }; + 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 +2940,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 +2960,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/SPIRV/SpvBuilder.cpp b/SPIRV/SpvBuilder.cpp index 11e9fe60..d472eb53 100644 --- a/SPIRV/SpvBuilder.cpp +++ b/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/SPIRV/SpvBuilder.h b/SPIRV/SpvBuilder.h index 2b17ba60..3a949190 100755 --- a/SPIRV/SpvBuilder.h +++ b/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.