From cb50d2873f30d6480a833d4ff397818ca644b640 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=91=D1=80=D0=B0=D0=BD=D0=B8=D0=BC=D0=B8=D1=80=20=D0=9A?= =?UTF-8?q?=D0=B0=D1=80=D0=B0=D1=9F=D0=B8=D1=9B?= Date: Fri, 30 Aug 2024 20:20:38 -0700 Subject: [PATCH] Updated glslang. --- .../SPIRV/CInterface/spirv_c_interface.cpp | 2 + 3rdparty/glslang/SPIRV/GlslangToSpv.cpp | 44 ++++-- 3rdparty/glslang/SPIRV/GlslangToSpv.h | 1 + 3rdparty/glslang/SPIRV/SPVRemapper.cpp | 1 - 3rdparty/glslang/SPIRV/SPVRemapper.h | 3 +- 3rdparty/glslang/SPIRV/SpvBuilder.cpp | 126 +++++++++++----- 3rdparty/glslang/SPIRV/SpvBuilder.h | 31 ++-- 3rdparty/glslang/SPIRV/SpvPostProcess.cpp | 14 +- 3rdparty/glslang/SPIRV/SpvTools.cpp | 12 ++ 3rdparty/glslang/SPIRV/SpvTools.h | 5 +- 3rdparty/glslang/SPIRV/doc.cpp | 0 3rdparty/glslang/SPIRV/spirv.hpp | 36 ++--- 3rdparty/glslang/StandAlone/StandAlone.cpp | 26 +++- 3rdparty/glslang/StandAlone/Worklist.h | 1 - 3rdparty/glslang/build_info.h | 2 +- .../CInterface/glslang_c_interface.cpp | 58 ++++++++ .../glslang/glslang/HLSL/hlslParseHelper.cpp | 4 +- 3rdparty/glslang/glslang/HLSL/pch.h | 2 - 3rdparty/glslang/glslang/Include/BaseTypes.h | 0 3rdparty/glslang/glslang/Include/Common.h | 5 + 3rdparty/glslang/glslang/Include/InfoSink.h | 14 +- .../glslang/Include/glslang_c_interface.h | 38 +++-- .../glslang/Include/glslang_c_shader_types.h | 1 + 3rdparty/glslang/glslang/Include/visibility.h | 51 +++++++ .../glslang/MachineIndependent/Constant.cpp | 12 +- .../glslang/MachineIndependent/Initialize.cpp | 0 .../MachineIndependent/ParseContextBase.cpp | 2 +- .../MachineIndependent/ParseHelper.cpp | 42 ++++-- .../glslang/MachineIndependent/ParseHelper.h | 1 + .../glslang/MachineIndependent/PoolAlloc.cpp | 11 +- .../glslang/MachineIndependent/ShaderLang.cpp | 17 +++ .../glslang/MachineIndependent/Versions.cpp | 12 +- .../glslang/MachineIndependent/Versions.h | 0 .../glslang/MachineIndependent/iomapper.cpp | 135 ++++++++++++++++- .../glslang/MachineIndependent/iomapper.h | 137 +----------------- .../MachineIndependent/linkValidate.cpp | 110 ++++++++++---- .../MachineIndependent/localintermediate.h | 9 +- .../MachineIndependent/preprocessor/Pp.cpp | 2 +- 3rdparty/glslang/glslang/Public/ShaderLang.h | 21 +-- 3rdparty/glslang/glslang/stub.cpp | 37 +++++ 40 files changed, 698 insertions(+), 327 deletions(-) mode change 100755 => 100644 3rdparty/glslang/SPIRV/GlslangToSpv.cpp mode change 100755 => 100644 3rdparty/glslang/SPIRV/doc.cpp mode change 100755 => 100644 3rdparty/glslang/glslang/Include/BaseTypes.h create mode 100644 3rdparty/glslang/glslang/Include/visibility.h mode change 100755 => 100644 3rdparty/glslang/glslang/MachineIndependent/Initialize.cpp mode change 100755 => 100644 3rdparty/glslang/glslang/MachineIndependent/Versions.h create mode 100644 3rdparty/glslang/glslang/stub.cpp diff --git a/3rdparty/glslang/SPIRV/CInterface/spirv_c_interface.cpp b/3rdparty/glslang/SPIRV/CInterface/spirv_c_interface.cpp index 2ba819b81..631d19d79 100644 --- a/3rdparty/glslang/SPIRV/CInterface/spirv_c_interface.cpp +++ b/3rdparty/glslang/SPIRV/CInterface/spirv_c_interface.cpp @@ -32,6 +32,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "glslang/Include/glslang_c_interface.h" +#include +#include "glslang/Public/ShaderLang.h" #include "SPIRV/GlslangToSpv.h" #include "SPIRV/Logger.h" #include "SPIRV/SpvTools.h" diff --git a/3rdparty/glslang/SPIRV/GlslangToSpv.cpp b/3rdparty/glslang/SPIRV/GlslangToSpv.cpp old mode 100755 new mode 100644 index 0fd79b1a4..2ca475c2c --- a/3rdparty/glslang/SPIRV/GlslangToSpv.cpp +++ b/3rdparty/glslang/SPIRV/GlslangToSpv.cpp @@ -4372,7 +4372,14 @@ spv::Id TGlslangToSpvTraverser::createSpvVariable(const glslang::TIntermSymbol* initializer = builder.makeNullConstant(spvType); } - return builder.createVariable(spv::NoPrecision, storageClass, spvType, name, initializer, false); + spv::Id var = builder.createVariable(spv::NoPrecision, storageClass, spvType, name, initializer, false); + std::vector topLevelDecorations; + glslang::TQualifier typeQualifier = node->getType().getQualifier(); + TranslateMemoryDecoration(typeQualifier, topLevelDecorations, glslangIntermediate->usingVulkanMemoryModel()); + for (auto deco : topLevelDecorations) { + builder.addDecoration(var, deco); + } + return var; } // Return type Id of the sampled type. @@ -5404,13 +5411,16 @@ void TGlslangToSpvTraverser::updateMemberOffset(const glslang::TType& structType memberAlignment = componentAlignment; // Don't add unnecessary padding after this member - if (memberType.isMatrix()) { - if (matrixLayout == glslang::ElmRowMajor) - memberSize -= componentSize * (4 - memberType.getMatrixCols()); - else - memberSize -= componentSize * (4 - memberType.getMatrixRows()); - } else if (memberType.isArray()) - memberSize -= componentSize * (4 - memberType.getVectorSize()); + // (undo std140 bumping size to a mutliple of vec4) + if (explicitLayout == glslang::ElpStd140) { + if (memberType.isMatrix()) { + if (matrixLayout == glslang::ElmRowMajor) + memberSize -= componentSize * (4 - memberType.getMatrixCols()); + else + memberSize -= componentSize * (4 - memberType.getMatrixRows()); + } else if (memberType.isArray()) + memberSize -= componentSize * (4 - memberType.getVectorSize()); + } } // Bump up to member alignment @@ -5518,12 +5528,16 @@ void TGlslangToSpvTraverser::makeFunctions(const glslang::TIntermSequence& glslF glslang::TIntermAggregate* glslFunction = glslFunctions[f]->getAsAggregate(); if (! glslFunction || glslFunction->getOp() != glslang::EOpFunction) continue; + + builder.setDebugSourceLocation(glslFunction->getLoc().line, glslFunction->getLoc().getFilename()); + if (isShaderEntryPoint(glslFunction)) { + // For HLSL, the entry function is actually a compiler generated function to resolve the difference of + // entry function signature between HLSL and SPIR-V. So we don't emit debug information for that. if (glslangIntermediate->getSource() != glslang::EShSourceHlsl) { - builder.setupDebugFunctionEntry(shaderEntry, glslangIntermediate->getEntryPointMangledName().c_str(), - glslFunction->getLoc().line, - std::vector(), // main function has no param - std::vector()); + builder.setupFunctionDebugInfo(shaderEntry, glslangIntermediate->getEntryPointMangledName().c_str(), + std::vector(), // main function has no param + std::vector()); } continue; } @@ -5576,8 +5590,7 @@ void TGlslangToSpvTraverser::makeFunctions(const glslang::TIntermSequence& glslF TranslatePrecisionDecoration(glslFunction->getType()), convertGlslangToSpvType(glslFunction->getType()), glslFunction->getName().c_str(), convertGlslangLinkageToSpv(glslFunction->getLinkType()), paramTypes, paramDecorations, &functionBlock); - builder.setupDebugFunctionEntry(function, glslFunction->getName().c_str(), glslFunction->getLoc().line, - paramTypes, paramNames); + builder.setupFunctionDebugInfo(function, glslFunction->getName().c_str(), paramTypes, paramNames); if (implicitThis) function->setImplicitThis(); @@ -6441,6 +6454,9 @@ spv::Id TGlslangToSpvTraverser::handleUserFunctionCall(const glslang::TIntermAgg } } + // Reset source location to the function call location after argument evaluation + builder.setDebugSourceLocation(node->getLoc().line, node->getLoc().getFilename()); + // 2. Allocate space for anything needing a copy, and if it's "in" or "inout" // copy the original into that space. // diff --git a/3rdparty/glslang/SPIRV/GlslangToSpv.h b/3rdparty/glslang/SPIRV/GlslangToSpv.h index 1b9ef3c51..95ea891bf 100644 --- a/3rdparty/glslang/SPIRV/GlslangToSpv.h +++ b/3rdparty/glslang/SPIRV/GlslangToSpv.h @@ -53,6 +53,7 @@ struct SpvOptions { bool emitNonSemanticShaderDebugInfo {false}; bool emitNonSemanticShaderDebugSource{ false }; bool compileOnly{false}; + bool optimizerAllowExpandedIDBound{false}; }; void GetSpirvVersion(std::string&); diff --git a/3rdparty/glslang/SPIRV/SPVRemapper.cpp b/3rdparty/glslang/SPIRV/SPVRemapper.cpp index f8f50a951..2ef3bf756 100644 --- a/3rdparty/glslang/SPIRV/SPVRemapper.cpp +++ b/3rdparty/glslang/SPIRV/SPVRemapper.cpp @@ -38,7 +38,6 @@ #include #include -#include "../glslang/Include/Common.h" namespace spv { diff --git a/3rdparty/glslang/SPIRV/SPVRemapper.h b/3rdparty/glslang/SPIRV/SPVRemapper.h index 33efe331e..bd9f91395 100644 --- a/3rdparty/glslang/SPIRV/SPVRemapper.h +++ b/3rdparty/glslang/SPIRV/SPVRemapper.h @@ -79,7 +79,8 @@ public: #include "spirv.hpp" namespace spv { -const Id NoResult = 0; + +static inline constexpr Id NoResult = 0; // class to hold SPIR-V binary data for remapping, DCE, and debug stripping class spirvbin_t : public spirvbin_base_t diff --git a/3rdparty/glslang/SPIRV/SpvBuilder.cpp b/3rdparty/glslang/SPIRV/SpvBuilder.cpp index 51c6bc21d..caff5c114 100644 --- a/3rdparty/glslang/SPIRV/SpvBuilder.cpp +++ b/3rdparty/glslang/SPIRV/SpvBuilder.cpp @@ -1312,7 +1312,7 @@ Op Builder::getMostBasicTypeClass(Id typeId) const } } -int Builder::getNumTypeConstituents(Id typeId) const +unsigned int Builder::getNumTypeConstituents(Id typeId) const { Instruction* instr = module.getInstruction(typeId); @@ -1979,7 +1979,7 @@ void Builder::addDecoration(Id id, Decoration decoration, int num) if (num >= 0) dec->addImmediateOperand(num); - decorations.push_back(std::unique_ptr(dec)); + decorations.insert(std::unique_ptr(dec)); } void Builder::addDecoration(Id id, Decoration decoration, const char* s) @@ -1993,7 +1993,7 @@ void Builder::addDecoration(Id id, Decoration decoration, const char* s) dec->addImmediateOperand(decoration); dec->addStringOperand(s); - decorations.push_back(std::unique_ptr(dec)); + decorations.insert(std::unique_ptr(dec)); } void Builder::addDecoration(Id id, Decoration decoration, const std::vector& literals) @@ -2008,7 +2008,7 @@ void Builder::addDecoration(Id id, Decoration decoration, const std::vectoraddImmediateOperand(literal); - decorations.push_back(std::unique_ptr(dec)); + decorations.insert(std::unique_ptr(dec)); } void Builder::addDecoration(Id id, Decoration decoration, const std::vector& strings) @@ -2023,7 +2023,7 @@ void Builder::addDecoration(Id id, Decoration decoration, const std::vectoraddStringOperand(string); - decorations.push_back(std::unique_ptr(dec)); + decorations.insert(std::unique_ptr(dec)); } void Builder::addLinkageDecoration(Id id, const char* name, spv::LinkageType linkType) { @@ -2034,7 +2034,7 @@ void Builder::addLinkageDecoration(Id id, const char* name, spv::LinkageType lin dec->addStringOperand(name); dec->addImmediateOperand(linkType); - decorations.push_back(std::unique_ptr(dec)); + decorations.insert(std::unique_ptr(dec)); } void Builder::addDecorationId(Id id, Decoration decoration, Id idDecoration) @@ -2048,7 +2048,7 @@ void Builder::addDecorationId(Id id, Decoration decoration, Id idDecoration) dec->addImmediateOperand(decoration); dec->addIdOperand(idDecoration); - decorations.push_back(std::unique_ptr(dec)); + decorations.insert(std::unique_ptr(dec)); } void Builder::addDecorationId(Id id, Decoration decoration, const std::vector& operandIds) @@ -2064,7 +2064,7 @@ void Builder::addDecorationId(Id id, Decoration decoration, const std::vectoraddIdOperand(operandId); - decorations.push_back(std::unique_ptr(dec)); + decorations.insert(std::unique_ptr(dec)); } void Builder::addMemberDecoration(Id id, unsigned int member, Decoration decoration, int num) @@ -2080,7 +2080,7 @@ void Builder::addMemberDecoration(Id id, unsigned int member, Decoration decorat if (num >= 0) dec->addImmediateOperand(num); - decorations.push_back(std::unique_ptr(dec)); + decorations.insert(std::unique_ptr(dec)); } void Builder::addMemberDecoration(Id id, unsigned int member, Decoration decoration, const char *s) @@ -2095,7 +2095,7 @@ void Builder::addMemberDecoration(Id id, unsigned int member, Decoration decorat dec->addImmediateOperand(decoration); dec->addStringOperand(s); - decorations.push_back(std::unique_ptr(dec)); + decorations.insert(std::unique_ptr(dec)); } void Builder::addMemberDecoration(Id id, unsigned int member, Decoration decoration, const std::vector& literals) @@ -2111,7 +2111,7 @@ void Builder::addMemberDecoration(Id id, unsigned int member, Decoration decorat for (auto literal : literals) dec->addImmediateOperand(literal); - decorations.push_back(std::unique_ptr(dec)); + decorations.insert(std::unique_ptr(dec)); } void Builder::addMemberDecoration(Id id, unsigned int member, Decoration decoration, const std::vector& strings) @@ -2127,10 +2127,16 @@ void Builder::addMemberDecoration(Id id, unsigned int member, Decoration decorat for (auto string : strings) dec->addStringOperand(string); - decorations.push_back(std::unique_ptr(dec)); + decorations.insert(std::unique_ptr(dec)); } void Builder::addInstruction(std::unique_ptr inst) { + // Phis must appear first in their block, don't insert line tracking instructions + // in front of them, just add the OpPhi and return. + if (inst->getOpCode() == OpPhi) { + buildPoint->addInstruction(std::move(inst)); + return; + } // Optionally insert OpDebugScope if (emitNonSemanticShaderDebugInfo && dirtyScopeTracker) { if (buildPoint->updateDebugScope(currentDebugScopeId.top())) { @@ -2236,14 +2242,13 @@ Function* Builder::makeFunctionEntry(Decoration precision, Id returnType, const return function; } -void Builder::setupDebugFunctionEntry(Function* function, const char* name, int line, const std::vector& paramTypes, - const std::vector& paramNames) +void Builder::setupFunctionDebugInfo(Function* function, const char* name, const std::vector& paramTypes, + const std::vector& paramNames) { if (!emitNonSemanticShaderDebugInfo) return; - currentLine = line; Id nameId = getStringId(unmangleFunctionName(name)); Id funcTypeId = function->getFuncTypeId(); assert(debugId[funcTypeId] != 0); @@ -2924,7 +2929,7 @@ Id Builder::createLvalueSwizzle(Id typeId, Id target, Id source, const std::vect swizzle->reserveOperands(2); swizzle->addIdOperand(target); - assert(getNumComponents(source) == (int)channels.size()); + assert(getNumComponents(source) == channels.size()); assert(isVector(source)); swizzle->addIdOperand(source); @@ -3371,7 +3376,7 @@ Id Builder::createCompositeCompare(Decoration precision, Id value1, Id value2, b Id Builder::createCompositeConstruct(Id typeId, const std::vector& constituents) { assert(isAggregateType(typeId) || (getNumTypeConstituents(typeId) > 1 && - getNumTypeConstituents(typeId) == (int)constituents.size())); + getNumTypeConstituents(typeId) == constituents.size())); if (generatingOpCodeForSpecConst) { // Sometime, even in spec-constant-op mode, the constant composite to be @@ -3424,6 +3429,12 @@ Id Builder::createConstructor(Decoration precision, const std::vector& sourc if (sources.size() == 1 && isScalar(sources[0]) && numTargetComponents > 1) return smearScalar(precision, sources[0], resultTypeId); + // Special case: 2 vectors of equal size + if (sources.size() == 1 && isVector(sources[0]) && numTargetComponents == getNumComponents(sources[0])) { + assert(resultTypeId == getTypeId(sources[0])); + return sources[0]; + } + // accumulate the arguments for OpCompositeConstruct std::vector constituents; Id scalarTypeId = getScalarTypeId(resultTypeId); @@ -3458,8 +3469,8 @@ Id Builder::createConstructor(Decoration precision, const std::vector& sourc if (sourcesToUse + targetComponent > numTargetComponents) sourcesToUse = numTargetComponents - targetComponent; - int col = 0; - int row = 0; + unsigned int col = 0; + unsigned int row = 0; for (unsigned int s = 0; s < sourcesToUse; ++s) { if (row >= getNumRows(sourceArg)) { row = 0; @@ -3504,8 +3515,8 @@ Id Builder::createConstructor(Decoration precision, const std::vector& sourc Id Builder::createMatrixConstructor(Decoration precision, const std::vector& sources, Id resultTypeId) { Id componentTypeId = getScalarTypeId(resultTypeId); - int numCols = getTypeNumColumns(resultTypeId); - int numRows = getTypeNumRows(resultTypeId); + unsigned int numCols = getTypeNumColumns(resultTypeId); + unsigned int numRows = getTypeNumRows(resultTypeId); Instruction* instr = module.getInstruction(componentTypeId); const unsigned bitCount = instr->getImmediateOperand(0); @@ -3520,11 +3531,11 @@ Id Builder::createMatrixConstructor(Decoration precision, const std::vector& Id sourceColumnTypeId = getContainedTypeId(getTypeId(matrix)); std::vector channels; - for (int row = 0; row < numRows; ++row) + for (unsigned int row = 0; row < numRows; ++row) channels.push_back(row); std::vector matrixColumns; - for (int col = 0; col < numCols; ++col) { + for (unsigned int col = 0; col < numCols; ++col) { std::vector indexes; indexes.push_back(col); Id colv = createCompositeExtract(matrix, sourceColumnTypeId, indexes); @@ -3542,7 +3553,7 @@ Id Builder::createMatrixConstructor(Decoration precision, const std::vector& // Detect a matrix being constructed from a repeated vector of the correct size. // Create the composite directly from it. - if ((int)sources.size() == numCols && isVector(sources[0]) && getNumComponents(sources[0]) == numRows && + if (sources.size() == numCols && isVector(sources[0]) && getNumComponents(sources[0]) == numRows && std::equal(sources.begin() + 1, sources.end(), sources.begin())) { return setPrecision(createCompositeConstruct(resultTypeId, sources), precision); } @@ -3574,12 +3585,12 @@ Id Builder::createMatrixConstructor(Decoration precision, const std::vector& } else if (isMatrix(sources[0])) { // constructing from another matrix; copy over the parts that exist in both the argument and constructee Id matrix = sources[0]; - int minCols = std::min(numCols, getNumColumns(matrix)); - int minRows = std::min(numRows, getNumRows(matrix)); - for (int col = 0; col < minCols; ++col) { + unsigned int minCols = std::min(numCols, getNumColumns(matrix)); + unsigned int minRows = std::min(numRows, getNumRows(matrix)); + for (unsigned int col = 0; col < minCols; ++col) { std::vector indexes; indexes.push_back(col); - for (int row = 0; row < minRows; ++row) { + for (unsigned int row = 0; row < minRows; ++row) { indexes.push_back(row); ids[col][row] = createCompositeExtract(matrix, componentTypeId, indexes); indexes.pop_back(); @@ -3588,12 +3599,12 @@ Id Builder::createMatrixConstructor(Decoration precision, const std::vector& } } else { // fill in the matrix in column-major order with whatever argument components are available - int row = 0; - int col = 0; + unsigned int row = 0; + unsigned int col = 0; - for (int arg = 0; arg < (int)sources.size() && col < numCols; ++arg) { + for (unsigned int arg = 0; arg < sources.size() && col < numCols; ++arg) { Id argComp = sources[arg]; - for (int comp = 0; comp < getNumComponents(sources[arg]); ++comp) { + for (unsigned int comp = 0; comp < getNumComponents(sources[arg]); ++comp) { if (getNumComponents(sources[arg]) > 1) { argComp = createCompositeExtract(sources[arg], componentTypeId, comp); setPrecision(argComp, precision); @@ -3617,9 +3628,9 @@ Id Builder::createMatrixConstructor(Decoration precision, const std::vector& // make the column vectors Id columnTypeId = getContainedTypeId(resultTypeId); std::vector matrixColumns; - for (int col = 0; col < numCols; ++col) { + for (unsigned int col = 0; col < numCols; ++col) { std::vector vectorComponents; - for (int row = 0; row < numRows; ++row) + for (unsigned int row = 0; row < numRows; ++row) vectorComponents.push_back(ids[col][row]); Id column = createCompositeConstruct(columnTypeId, vectorComponents); setPrecision(column, precision); @@ -3846,7 +3857,7 @@ void Builder::accessChainStore(Id rvalue, Decoration nonUniform, spv::MemoryAcce // If a swizzle exists and is not full and is not dynamic, then the swizzle will be broken into individual stores. if (accessChain.swizzle.size() > 0 && - getNumTypeComponents(getResultingAccessChainType()) != (int)accessChain.swizzle.size() && + getNumTypeComponents(getResultingAccessChainType()) != accessChain.swizzle.size() && accessChain.component == NoResult) { for (unsigned int i = 0; i < accessChain.swizzle.size(); ++i) { accessChain.indexChain.push_back(makeUintConstant(accessChain.swizzle[i])); @@ -4166,7 +4177,7 @@ void Builder::simplifyAccessChainSwizzle() { // If the swizzle has fewer components than the vector, it is subsetting, and must stay // to preserve that fact. - if (getNumTypeComponents(accessChain.preSwizzleBaseType) > (int)accessChain.swizzle.size()) + if (getNumTypeComponents(accessChain.preSwizzleBaseType) > accessChain.swizzle.size()) return; // if components are out of order, it is a swizzle @@ -4324,11 +4335,10 @@ void Builder::dumpSourceInstructions(std::vector& out) const dumpSourceInstructions(iItr->first, *iItr->second, out); } -void Builder::dumpInstructions(std::vector& out, - const std::vector >& instructions) const +template void Builder::dumpInstructions(std::vector& out, const Range& instructions) const { - for (int i = 0; i < (int)instructions.size(); ++i) { - instructions[i]->dump(out); + for (const auto& inst : instructions) { + inst->dump(out); } } @@ -4341,4 +4351,40 @@ void Builder::dumpModuleProcesses(std::vector& out) const } } +bool Builder::DecorationInstructionLessThan::operator()(const std::unique_ptr& lhs, + const std::unique_ptr& rhs) const +{ + // Order by the id to which the decoration applies first. This is more intuitive. + assert(lhs->isIdOperand(0) && rhs->isIdOperand(0)); + if (lhs->getIdOperand(0) != rhs->getIdOperand(0)) { + return lhs->getIdOperand(0) < rhs->getIdOperand(0); + } + + if (lhs->getOpCode() != rhs->getOpCode()) + return lhs->getOpCode() < rhs->getOpCode(); + + // Now compare the operands. + int minSize = std::min(lhs->getNumOperands(), rhs->getNumOperands()); + for (int i = 1; i < minSize; ++i) { + if (lhs->isIdOperand(i) != rhs->isIdOperand(i)) { + return lhs->isIdOperand(i) < rhs->isIdOperand(i); + } + + if (lhs->isIdOperand(i)) { + if (lhs->getIdOperand(i) != rhs->getIdOperand(i)) { + return lhs->getIdOperand(i) < rhs->getIdOperand(i); + } + } else { + if (lhs->getImmediateOperand(i) != rhs->getImmediateOperand(i)) { + return lhs->getImmediateOperand(i) < rhs->getImmediateOperand(i); + } + } + } + + if (lhs->getNumOperands() != rhs->getNumOperands()) + return lhs->getNumOperands() < rhs->getNumOperands(); + + // In this case they are equal. + return false; +} } // end spv namespace diff --git a/3rdparty/glslang/SPIRV/SpvBuilder.h b/3rdparty/glslang/SPIRV/SpvBuilder.h index 35327d6e7..d688436a6 100644 --- a/3rdparty/glslang/SPIRV/SpvBuilder.h +++ b/3rdparty/glslang/SPIRV/SpvBuilder.h @@ -56,6 +56,7 @@ namespace spv { } #include +#include #include #include #include @@ -247,9 +248,12 @@ public: Id makeDebugFunction(Function* function, Id nameId, Id funcTypeId); Id makeDebugLexicalBlock(uint32_t line); std::string unmangleFunctionName(std::string const& name) const; - void setupDebugFunctionEntry(Function* function, const char* name, int line, - const std::vector& paramTypes, - const std::vector& paramNames); + + // Initialize non-semantic debug information for a function, including those of: + // - The function definition + // - The function parameters + void setupFunctionDebugInfo(Function* function, const char* name, const std::vector& paramTypes, + const std::vector& paramNames); // accelerationStructureNV type Id makeAccelerationStructureType(); @@ -264,9 +268,9 @@ public: Op getOpCode(Id id) const { return module.getInstruction(id)->getOpCode(); } Op getTypeClass(Id typeId) const { return getOpCode(typeId); } Op getMostBasicTypeClass(Id typeId) const; - int getNumComponents(Id resultId) const { return getNumTypeComponents(getTypeId(resultId)); } - int getNumTypeConstituents(Id typeId) const; - int getNumTypeComponents(Id typeId) const { return getNumTypeConstituents(typeId); } + unsigned int getNumComponents(Id resultId) const { return getNumTypeComponents(getTypeId(resultId)); } + unsigned int getNumTypeConstituents(Id typeId) const; + unsigned int getNumTypeComponents(Id typeId) const { return getNumTypeConstituents(typeId); } Id getScalarTypeId(Id typeId) const; Id getContainedTypeId(Id typeId) const; Id getContainedTypeId(Id typeId, int) const; @@ -334,18 +338,18 @@ public: return module.getInstruction(scalarTypeId)->getImmediateOperand(0); } - int getTypeNumColumns(Id typeId) const + unsigned int getTypeNumColumns(Id typeId) const { assert(isMatrixType(typeId)); return getNumTypeConstituents(typeId); } - int getNumColumns(Id resultId) const { return getTypeNumColumns(getTypeId(resultId)); } - int getTypeNumRows(Id typeId) const + unsigned int getNumColumns(Id resultId) const { return getTypeNumColumns(getTypeId(resultId)); } + unsigned int getTypeNumRows(Id typeId) const { assert(isMatrixType(typeId)); return getNumTypeComponents(getContainedTypeId(typeId)); } - int getNumRows(Id resultId) const { return getTypeNumRows(getTypeId(resultId)); } + unsigned int getNumRows(Id resultId) const { return getTypeNumRows(getTypeId(resultId)); } Dim getTypeDimensionality(Id typeId) const { @@ -890,10 +894,13 @@ public: void createSelectionMerge(Block* mergeBlock, unsigned int control); void dumpSourceInstructions(std::vector&) const; void dumpSourceInstructions(const spv::Id fileId, const std::string& text, std::vector&) const; - void dumpInstructions(std::vector&, const std::vector >&) const; + template void dumpInstructions(std::vector& out, const Range& instructions) const; void dumpModuleProcesses(std::vector&) const; spv::MemoryAccessMask sanitizeMemoryAccessForStorageClass(spv::MemoryAccessMask memoryAccess, StorageClass sc) const; + struct DecorationInstructionLessThan { + bool operator()(const std::unique_ptr& lhs, const std::unique_ptr& rhs) const; + }; unsigned int spvVersion; // the version of SPIR-V to emit in the header SourceLanguage sourceLang; @@ -950,7 +957,7 @@ public: std::vector > entryPoints; std::vector > executionModes; std::vector > names; - std::vector > decorations; + std::set, DecorationInstructionLessThan> decorations; std::vector > constantsTypesGlobals; std::vector > externals; std::vector > functions; diff --git a/3rdparty/glslang/SPIRV/SpvPostProcess.cpp b/3rdparty/glslang/SPIRV/SpvPostProcess.cpp index 5b3fbb565..e35ab71fe 100644 --- a/3rdparty/glslang/SPIRV/SpvPostProcess.cpp +++ b/3rdparty/glslang/SPIRV/SpvPostProcess.cpp @@ -387,12 +387,14 @@ void Builder::postProcessCFG() } // Remove unneeded decorations, for unreachable instructions - decorations.erase(std::remove_if(decorations.begin(), decorations.end(), - [&unreachableDefinitions](std::unique_ptr& I) -> bool { - Id decoration_id = I.get()->getIdOperand(0); - return unreachableDefinitions.count(decoration_id) != 0; - }), - decorations.end()); + for (auto decorationIter = decorations.begin(); decorationIter != decorations.end();) { + Id decorationId = (*decorationIter)->getIdOperand(0); + if (unreachableDefinitions.count(decorationId) != 0) { + decorationIter = decorations.erase(decorationIter); + } else { + ++decorationIter; + } + } } // comment in header diff --git a/3rdparty/glslang/SPIRV/SpvTools.cpp b/3rdparty/glslang/SPIRV/SpvTools.cpp index ff04f4f96..6360ab498 100644 --- a/3rdparty/glslang/SPIRV/SpvTools.cpp +++ b/3rdparty/glslang/SPIRV/SpvTools.cpp @@ -44,6 +44,7 @@ #include "SpvTools.h" #include "spirv-tools/optimizer.hpp" +#include "glslang/MachineIndependent/localintermediate.h" namespace glslang { @@ -218,9 +219,20 @@ void SpirvToolsTransform(const glslang::TIntermediate& intermediate, std::vector optimizer.RegisterPass(spvtools::CreateCFGCleanupPass()); spvtools::OptimizerOptions spvOptOptions; + if (options->optimizerAllowExpandedIDBound) + spvOptOptions.set_max_id_bound(0x3FFFFFFF); optimizer.SetTargetEnv(MapToSpirvToolsEnv(intermediate.getSpv(), logger)); spvOptOptions.set_run_validator(false); // The validator may run as a separate step later on optimizer.Run(spirv.data(), spirv.size(), &spirv, spvOptOptions); + + if (options->optimizerAllowExpandedIDBound) { + if (spirv.size() > 3 && spirv[3] > kDefaultMaxIdBound) { + spvtools::Optimizer optimizer2(target_env); + optimizer2.SetMessageConsumer(OptimizerMesssageConsumer); + optimizer2.RegisterPass(spvtools::CreateCompactIdsPass()); + optimizer2.Run(spirv.data(), spirv.size(), &spirv, spvOptOptions); + } + } } bool SpirvToolsAnalyzeDeadOutputStores(spv_target_env target_env, std::vector& spirv, diff --git a/3rdparty/glslang/SPIRV/SpvTools.h b/3rdparty/glslang/SPIRV/SpvTools.h index eabde4666..a72d652c5 100644 --- a/3rdparty/glslang/SPIRV/SpvTools.h +++ b/3rdparty/glslang/SPIRV/SpvTools.h @@ -44,10 +44,11 @@ #if ENABLE_OPT #include #include +#include #include "spirv-tools/libspirv.h" #endif -#include "glslang/MachineIndependent/localintermediate.h" +#include "glslang/MachineIndependent/Versions.h" #include "GlslangToSpv.h" #include "Logger.h" @@ -55,6 +56,8 @@ namespace glslang { #if ENABLE_OPT +class TIntermediate; + // Translate glslang's view of target versioning to what SPIRV-Tools uses. spv_target_env MapToSpirvToolsEnv(const SpvVersion& spvVersion, spv::SpvBuildLogger* logger); diff --git a/3rdparty/glslang/SPIRV/doc.cpp b/3rdparty/glslang/SPIRV/doc.cpp old mode 100755 new mode 100644 diff --git a/3rdparty/glslang/SPIRV/spirv.hpp b/3rdparty/glslang/SPIRV/spirv.hpp index afa89a585..b09d99bee 100644 --- a/3rdparty/glslang/SPIRV/spirv.hpp +++ b/3rdparty/glslang/SPIRV/spirv.hpp @@ -385,7 +385,7 @@ enum ImageOperandsShift { ImageOperandsMax = 0x7fffffff, }; -enum ImageOperandsMask { +enum ImageOperandsMask : unsigned { ImageOperandsMaskNone = 0, ImageOperandsBiasMask = 0x00000001, ImageOperandsLodMask = 0x00000002, @@ -420,7 +420,7 @@ enum FPFastMathModeShift { FPFastMathModeMax = 0x7fffffff, }; -enum FPFastMathModeMask { +enum FPFastMathModeMask : unsigned { FPFastMathModeMaskNone = 0, FPFastMathModeNotNaNMask = 0x00000001, FPFastMathModeNotInfMask = 0x00000002, @@ -745,7 +745,7 @@ enum SelectionControlShift { SelectionControlMax = 0x7fffffff, }; -enum SelectionControlMask { +enum SelectionControlMask : unsigned { SelectionControlMaskNone = 0, SelectionControlFlattenMask = 0x00000001, SelectionControlDontFlattenMask = 0x00000002, @@ -774,7 +774,7 @@ enum LoopControlShift { LoopControlMax = 0x7fffffff, }; -enum LoopControlMask { +enum LoopControlMask : unsigned { LoopControlMaskNone = 0, LoopControlUnrollMask = 0x00000001, LoopControlDontUnrollMask = 0x00000002, @@ -806,7 +806,7 @@ enum FunctionControlShift { FunctionControlMax = 0x7fffffff, }; -enum FunctionControlMask { +enum FunctionControlMask : unsigned { FunctionControlMaskNone = 0, FunctionControlInlineMask = 0x00000001, FunctionControlDontInlineMask = 0x00000002, @@ -836,7 +836,7 @@ enum MemorySemanticsShift { MemorySemanticsMax = 0x7fffffff, }; -enum MemorySemanticsMask { +enum MemorySemanticsMask : unsigned { MemorySemanticsMaskNone = 0, MemorySemanticsAcquireMask = 0x00000002, MemorySemanticsReleaseMask = 0x00000004, @@ -872,7 +872,7 @@ enum MemoryAccessShift { MemoryAccessMax = 0x7fffffff, }; -enum MemoryAccessMask { +enum MemoryAccessMask : unsigned { MemoryAccessMaskNone = 0, MemoryAccessVolatileMask = 0x00000001, MemoryAccessAlignedMask = 0x00000002, @@ -922,7 +922,7 @@ enum KernelProfilingInfoShift { KernelProfilingInfoMax = 0x7fffffff, }; -enum KernelProfilingInfoMask { +enum KernelProfilingInfoMask : unsigned { KernelProfilingInfoMaskNone = 0, KernelProfilingInfoCmdExecTimeMask = 0x00000001, }; @@ -1163,7 +1163,7 @@ enum Capability { CapabilityDotProduct = 6019, CapabilityDotProductKHR = 6019, CapabilityRayCullMaskKHR = 6020, - CapabilityCooperativeMatrixKHR = 6022, + CapabilityCooperativeMatrixKHR = 6022, CapabilityReplicatedCompositesEXT = 6024, CapabilityBitInstructions = 6025, CapabilityGroupNonUniformRotateKHR = 6026, @@ -1194,7 +1194,7 @@ enum RayFlagsShift { RayFlagsMax = 0x7fffffff, }; -enum RayFlagsMask { +enum RayFlagsMask : unsigned { RayFlagsMaskNone = 0, RayFlagsOpaqueKHRMask = 0x00000001, RayFlagsNoOpaqueKHRMask = 0x00000002, @@ -1236,7 +1236,7 @@ enum FragmentShadingRateShift { FragmentShadingRateMax = 0x7fffffff, }; -enum FragmentShadingRateMask { +enum FragmentShadingRateMask : unsigned { FragmentShadingRateMaskNone = 0, FragmentShadingRateVertical2PixelsMask = 0x00000001, FragmentShadingRateVertical4PixelsMask = 0x00000002, @@ -1291,7 +1291,7 @@ enum CooperativeMatrixOperandsShift { CooperativeMatrixOperandsMax = 0x7fffffff, }; -enum CooperativeMatrixOperandsMask { +enum CooperativeMatrixOperandsMask : unsigned { CooperativeMatrixOperandsMaskNone = 0, CooperativeMatrixOperandsMatrixASignedComponentsKHRMask = 0x00000001, CooperativeMatrixOperandsMatrixBSignedComponentsKHRMask = 0x00000002, @@ -1693,9 +1693,9 @@ enum Op { OpCooperativeMatrixLoadKHR = 4457, OpCooperativeMatrixStoreKHR = 4458, OpCooperativeMatrixMulAddKHR = 4459, - OpCooperativeMatrixLengthKHR = 4460, - OpConstantCompositeReplicateEXT = 4461, - OpSpecConstantCompositeReplicateEXT = 4462, + OpCooperativeMatrixLengthKHR = 4460, + OpConstantCompositeReplicateEXT = 4461, + OpSpecConstantCompositeReplicateEXT = 4462, OpCompositeConstructReplicateEXT = 4463, OpTypeRayQueryKHR = 4472, OpRayQueryInitializeKHR = 4473, @@ -2426,9 +2426,9 @@ inline void HasResultAndType(Op opcode, bool *hasResult, bool *hasResultType) { case OpCooperativeMatrixLoadKHR: *hasResult = true; *hasResultType = true; break; case OpCooperativeMatrixStoreKHR: *hasResult = false; *hasResultType = false; break; case OpCooperativeMatrixMulAddKHR: *hasResult = true; *hasResultType = true; break; - case OpCooperativeMatrixLengthKHR: *hasResult = true; *hasResultType = true; break; - case OpConstantCompositeReplicateEXT: *hasResult = true; *hasResultType = true; break; - case OpSpecConstantCompositeReplicateEXT: *hasResult = true; *hasResultType = true; break; + case OpCooperativeMatrixLengthKHR: *hasResult = true; *hasResultType = true; break; + case OpConstantCompositeReplicateEXT: *hasResult = true; *hasResultType = true; break; + case OpSpecConstantCompositeReplicateEXT: *hasResult = true; *hasResultType = true; break; case OpCompositeConstructReplicateEXT: *hasResult = true; *hasResultType = true; break; case OpTypeRayQueryKHR: *hasResult = true; *hasResultType = false; break; case OpRayQueryInitializeKHR: *hasResult = false; *hasResultType = false; break; diff --git a/3rdparty/glslang/StandAlone/StandAlone.cpp b/3rdparty/glslang/StandAlone/StandAlone.cpp index ac967f2b5..9c3beac92 100644 --- a/3rdparty/glslang/StandAlone/StandAlone.cpp +++ b/3rdparty/glslang/StandAlone/StandAlone.cpp @@ -44,12 +44,10 @@ #include "glslang/Public/ResourceLimits.h" #include "Worklist.h" #include "DirStackFileIncluder.h" -#include "./../glslang/Include/ShHandle.h" #include "./../glslang/Public/ShaderLang.h" #include "../glslang/MachineIndependent/localintermediate.h" #include "../SPIRV/GlslangToSpv.h" #include "../SPIRV/GLSL.std.450.h" -#include "../SPIRV/doc.h" #include "../SPIRV/disassemble.h" #include @@ -110,6 +108,7 @@ enum TOptions : uint64_t { EOptionInvertY = (1ull << 30), EOptionDumpBareVersion = (1ull << 31), EOptionCompileOnly = (1ull << 32), + EOptionDisplayErrorColumn = (1ull << 33), }; bool targetHlslFunctionality1 = false; bool SpvToolsDisassembler = false; @@ -898,6 +897,8 @@ void ProcessArguments(std::vector>& workItem Options |= EOptionDumpVersions; } else if (lowerword == "no-link") { Options |= EOptionCompileOnly; + } else if (lowerword == "error-column") { + Options |= EOptionDisplayErrorColumn; } else if (lowerword == "help") { usage(); break; @@ -1164,6 +1165,8 @@ void SetMessageOptions(EShMessages& messages) messages = (EShMessages)(messages | EShMsgEnhanced); if (AbsolutePath) messages = (EShMessages)(messages | EShMsgAbsolutePath); + if (Options & EOptionDisplayErrorColumn) + messages = (EShMessages)(messages | EShMsgDisplayErrorColumn); } // @@ -1504,6 +1507,7 @@ void CompileAndLinkShaderUnits(std::vector compUnits) std::vector outputFiles; +#ifdef ENABLE_SPIRV // Dump SPIR-V if (Options & EOptionSpv) { CompileOrLinkFailed.fetch_or(CompileFailed); @@ -1566,6 +1570,7 @@ void CompileAndLinkShaderUnits(std::vector compUnits) } } } +#endif CompileOrLinkFailed.fetch_or(CompileFailed); CompileOrLinkFailed.fetch_or(LinkFailed); @@ -1664,21 +1669,31 @@ int singleMain() } if (Options & EOptionDumpBareVersion) { - printf("%d:%d.%d.%d%s\n", glslang::GetSpirvGeneratorVersion(), GLSLANG_VERSION_MAJOR, GLSLANG_VERSION_MINOR, + int spirvGeneratorVersion = 0; +#ifdef ENABLE_SPIRV + spirvGeneratorVersion = glslang::GetSpirvGeneratorVersion(); +#endif + printf("%d:%d.%d.%d%s\n", spirvGeneratorVersion, GLSLANG_VERSION_MAJOR, GLSLANG_VERSION_MINOR, GLSLANG_VERSION_PATCH, GLSLANG_VERSION_FLAVOR); if (workList.empty()) return ESuccess; } else if (Options & EOptionDumpVersions) { - printf("Glslang Version: %d:%d.%d.%d%s\n", glslang::GetSpirvGeneratorVersion(), GLSLANG_VERSION_MAJOR, + int spirvGeneratorVersion = 0; +#ifdef ENABLE_SPIRV + spirvGeneratorVersion = glslang::GetSpirvGeneratorVersion(); +#endif + printf("Glslang Version: %d:%d.%d.%d%s\n", spirvGeneratorVersion, GLSLANG_VERSION_MAJOR, GLSLANG_VERSION_MINOR, GLSLANG_VERSION_PATCH, GLSLANG_VERSION_FLAVOR); printf("ESSL Version: %s\n", glslang::GetEsslVersionString()); printf("GLSL Version: %s\n", glslang::GetGlslVersionString()); std::string spirvVersion; +#if ENABLE_SPIRV glslang::GetSpirvVersion(spirvVersion); +#endif printf("SPIR-V Version %s\n", spirvVersion.c_str()); printf("GLSL.std.450 Version %d, Revision %d\n", GLSLstd450Version, GLSLstd450Revision); printf("Khronos Tool ID %d\n", glslang::GetKhronosToolId()); - printf("SPIR-V Generator Version %d\n", glslang::GetSpirvGeneratorVersion()); + printf("SPIR-V Generator Version %d\n", spirvGeneratorVersion); printf("GL_KHR_vulkan_glsl version %d\n", 100); printf("ARB_GL_gl_spirv version %d\n", 100); if (workList.empty()) @@ -2024,6 +2039,7 @@ void usage() " shaders compatible with DirectX\n" " --invert-y | --iy invert position.Y output in vertex shader\n" " --enhanced-msgs print more readable error messages (GLSL only)\n" + " --error-column display the column of the error along the line\n" " --keep-uncalled | --ku don't eliminate uncalled functions\n" " --nan-clamp favor non-NaN operand in min, max, and clamp\n" " --no-storage-format | --nsf use Unknown image format\n" diff --git a/3rdparty/glslang/StandAlone/Worklist.h b/3rdparty/glslang/StandAlone/Worklist.h index 91b6f516b..dc726270a 100644 --- a/3rdparty/glslang/StandAlone/Worklist.h +++ b/3rdparty/glslang/StandAlone/Worklist.h @@ -35,7 +35,6 @@ #ifndef WORKLIST_H_INCLUDED #define WORKLIST_H_INCLUDED -#include "../glslang/OSDependent/osinclude.h" #include #include #include diff --git a/3rdparty/glslang/build_info.h b/3rdparty/glslang/build_info.h index c9d5a917c..35940d133 100644 --- a/3rdparty/glslang/build_info.h +++ b/3rdparty/glslang/build_info.h @@ -35,7 +35,7 @@ #define GLSLANG_BUILD_INFO #define GLSLANG_VERSION_MAJOR 14 -#define GLSLANG_VERSION_MINOR 2 +#define GLSLANG_VERSION_MINOR 3 #define GLSLANG_VERSION_PATCH 0 #define GLSLANG_VERSION_FLAVOR "" diff --git a/3rdparty/glslang/glslang/CInterface/glslang_c_interface.cpp b/3rdparty/glslang/glslang/CInterface/glslang_c_interface.cpp index cea965d40..a7d08744c 100644 --- a/3rdparty/glslang/glslang/CInterface/glslang_c_interface.cpp +++ b/3rdparty/glslang/glslang/CInterface/glslang_c_interface.cpp @@ -34,9 +34,13 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "StandAlone/DirStackFileIncluder.h" #include "glslang/Public/ResourceLimits.h" +#include "glslang/Public/ShaderLang.h" #include "glslang/Include/ShHandle.h" +#include "glslang/Include/BaseTypes.h" #include "glslang/Include/ResourceLimits.h" +#include "glslang/Include/Types.h" +#include "glslang/MachineIndependent/iomapper.h" #include "glslang/MachineIndependent/Versions.h" #include "glslang/MachineIndependent/localintermediate.h" @@ -54,6 +58,7 @@ static_assert(int(GLSLANG_REFLECTION_COUNT) == EShReflectionCount, ""); static_assert(int(GLSLANG_PROFILE_COUNT) == EProfileCount, ""); static_assert(sizeof(glslang_limits_t) == sizeof(TLimits), ""); static_assert(sizeof(glslang_resource_t) == sizeof(TBuiltInResource), ""); +static_assert(sizeof(glslang_version_t) == sizeof(glslang::Version), ""); typedef struct glslang_shader_s { glslang::TShader* shader; @@ -141,6 +146,11 @@ private: void* context; }; +GLSLANG_EXPORT void glslang_get_version(glslang_version_t* version) +{ + *reinterpret_cast(version) = glslang::GetVersion(); +} + GLSLANG_EXPORT int glslang_initialize_process() { return static_cast(glslang::InitializeProcess()); } GLSLANG_EXPORT void glslang_finalize_process() { glslang::FinalizeProcess(); } @@ -205,7 +215,9 @@ static int c_shader_messages(glslang_messages_t messages) CONVERT_MSG(GLSLANG_MSG_HLSL_LEGALIZATION_BIT, EShMsgHlslLegalization); CONVERT_MSG(GLSLANG_MSG_HLSL_DX9_COMPATIBLE_BIT, EShMsgHlslDX9Compatible); CONVERT_MSG(GLSLANG_MSG_BUILTIN_SYMBOL_TABLE_BIT, EShMsgBuiltinSymbolTable); + CONVERT_MSG(GLSLANG_MSG_ENHANCED, EShMsgEnhanced); CONVERT_MSG(GLSLANG_MSG_ABSOLUTE_PATH, EShMsgAbsolutePath); + CONVERT_MSG(GLSLANG_MSG_DISPLAY_ERROR_COLUMN, EShMsgDisplayErrorColumn); return res; #undef CONVERT_MSG } @@ -368,11 +380,25 @@ GLSLANG_EXPORT void glslang_shader_set_glsl_version(glslang_shader_t* shader, in shader->shader->setOverrideVersion(version); } +GLSLANG_EXPORT void glslang_shader_set_default_uniform_block_set_and_binding(glslang_shader_t* shader, unsigned int set, unsigned int binding) { + shader->shader->setGlobalUniformSet(set); + shader->shader->setGlobalUniformBinding(binding); +} + +GLSLANG_EXPORT void glslang_shader_set_default_uniform_block_name(glslang_shader_t* shader, const char *name) { + shader->shader->setGlobalUniformBlockName(name); +} + GLSLANG_EXPORT const char* glslang_shader_get_preprocessed_code(glslang_shader_t* shader) { return shader->preprocessedGLSL.c_str(); } +GLSLANG_EXPORT void glslang_shader_set_preprocessed_code(glslang_shader_t* shader, const char* code) +{ + shader->preprocessedGLSL.assign(code); +} + GLSLANG_EXPORT int glslang_shader_preprocess(glslang_shader_t* shader, const glslang_input_t* input) { DirStackFileIncluder dirStackFileIncluder; @@ -459,6 +485,11 @@ GLSLANG_EXPORT int glslang_program_map_io(glslang_program_t* program) return (int)program->program->mapIO(); } +GLSLANG_EXPORT int glslang_program_map_io_with_resolver_and_mapper(glslang_program_t* program, glslang_resolver_t* resolver, glslang_mapper_t* mapper) +{ + return (int)program->program->mapIO(reinterpret_cast(resolver), reinterpret_cast(mapper)); +} + GLSLANG_EXPORT const char* glslang_program_get_info_log(glslang_program_t* program) { return program->program->getInfoLog(); @@ -468,3 +499,30 @@ GLSLANG_EXPORT const char* glslang_program_get_info_debug_log(glslang_program_t* { return program->program->getInfoDebugLog(); } + +GLSLANG_EXPORT glslang_mapper_t* glslang_glsl_mapper_create() +{ + return reinterpret_cast(new glslang::TGlslIoMapper()); +} + +GLSLANG_EXPORT void glslang_glsl_mapper_delete(glslang_mapper_t* mapper) +{ + if (!mapper) + return; + + delete reinterpret_cast(mapper); +} + +GLSLANG_EXPORT glslang_resolver_t* glslang_glsl_resolver_create(glslang_program_t* program, glslang_stage_t stage) +{ + glslang::TIntermediate* intermediate = program->program->getIntermediate(c_shader_stage(stage)); + return reinterpret_cast(new glslang::TDefaultGlslIoResolver(reinterpret_cast(*intermediate))); +} + +GLSLANG_EXPORT void glslang_glsl_resolver_delete(glslang_resolver_t* resolver) +{ + if (!resolver) + return; + + delete reinterpret_cast(resolver); +} diff --git a/3rdparty/glslang/glslang/HLSL/hlslParseHelper.cpp b/3rdparty/glslang/glslang/HLSL/hlslParseHelper.cpp index 0fd724d0d..35eb222ce 100644 --- a/3rdparty/glslang/glslang/HLSL/hlslParseHelper.cpp +++ b/3rdparty/glslang/glslang/HLSL/hlslParseHelper.cpp @@ -43,8 +43,6 @@ #include "../MachineIndependent/Scan.h" #include "../MachineIndependent/preprocessor/PpContext.h" -#include "../OSDependent/osinclude.h" - #include #include #include @@ -6059,7 +6057,7 @@ void HlslParseContext::builtInOpCheck(const TSourceLoc& loc, const TFunction& fn unaryArg = callNode.getAsUnaryNode()->getOperand(); arg0 = unaryArg; } - const TIntermSequence& aggArgs = *argp; // only valid when unaryArg is nullptr + const TIntermSequence& aggArgs = argp ? *argp : TIntermSequence(); // only valid when unaryArg is nullptr switch (callNode.getOp()) { case EOpTextureGather: diff --git a/3rdparty/glslang/glslang/HLSL/pch.h b/3rdparty/glslang/glslang/HLSL/pch.h index 465e7c14f..f51efacc6 100644 --- a/3rdparty/glslang/glslang/HLSL/pch.h +++ b/3rdparty/glslang/glslang/HLSL/pch.h @@ -42,8 +42,6 @@ #include "../MachineIndependent/Scan.h" #include "../MachineIndependent/preprocessor/PpContext.h" -#include "../OSDependent/osinclude.h" - #include #include #include diff --git a/3rdparty/glslang/glslang/Include/BaseTypes.h b/3rdparty/glslang/glslang/Include/BaseTypes.h old mode 100755 new mode 100644 diff --git a/3rdparty/glslang/glslang/Include/Common.h b/3rdparty/glslang/glslang/Include/Common.h index a6e67d7ef..bf37d9643 100644 --- a/3rdparty/glslang/glslang/Include/Common.h +++ b/3rdparty/glslang/glslang/Include/Common.h @@ -96,6 +96,11 @@ std::string to_string(const T& val) { #pragma warning(disable : 4201) // nameless union #endif +// Allow compilation to WASI which does not support threads yet. +#ifdef __wasi__ +#define DISABLE_THREAD_SUPPORT +#endif + #include "PoolAlloc.h" // diff --git a/3rdparty/glslang/glslang/Include/InfoSink.h b/3rdparty/glslang/glslang/Include/InfoSink.h index 23f495dcb..262933941 100644 --- a/3rdparty/glslang/glslang/Include/InfoSink.h +++ b/3rdparty/glslang/glslang/Include/InfoSink.h @@ -95,10 +95,14 @@ public: default: append("UNKNOWN ERROR: "); break; } } - void location(const TSourceLoc& loc, bool absolute = false) { + void location(const TSourceLoc& loc, bool absolute = false, bool displayColumn = false) { const int maxSize = 24; char locText[maxSize]; - snprintf(locText, maxSize, ":%d", loc.line); + if (displayColumn) { + snprintf(locText, maxSize, ":%d:%d", loc.line, loc.column); + } else { + snprintf(locText, maxSize, ":%d", loc.line); + } if(loc.getFilename() == nullptr && shaderFileName != nullptr && absolute) { append(std::filesystem::absolute(shaderFileName).string()); @@ -119,9 +123,11 @@ public: append(s); append("\n"); } - void message(TPrefixType message, const char* s, const TSourceLoc& loc) { + void message(TPrefixType message, const char* s, const TSourceLoc& loc, bool absolute = false, + bool displayColumn = false) + { prefix(message); - location(loc); + location(loc, absolute, displayColumn); append(s); append("\n"); } diff --git a/3rdparty/glslang/glslang/Include/glslang_c_interface.h b/3rdparty/glslang/glslang/Include/glslang_c_interface.h index 7fa1a05d5..cbf10b455 100644 --- a/3rdparty/glslang/glslang/Include/glslang_c_interface.h +++ b/3rdparty/glslang/glslang/Include/glslang_c_interface.h @@ -37,9 +37,20 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include #include "glslang_c_shader_types.h" +#include "visibility.h" typedef struct glslang_shader_s glslang_shader_t; typedef struct glslang_program_s glslang_program_t; +typedef struct glslang_mapper_s glslang_mapper_t; +typedef struct glslang_resolver_s glslang_resolver_t; + +/* Version counterpart */ +typedef struct glslang_version_s { + int major; + int minor; + int patch; + const char* flavor; +} glslang_version_t; /* TLimits counterpart */ typedef struct glslang_limits_s { @@ -227,27 +238,14 @@ typedef struct glslang_spv_options_s { bool emit_nonsemantic_shader_debug_info; bool emit_nonsemantic_shader_debug_source; bool compile_only; + bool optimize_allow_expanded_id_bound; } glslang_spv_options_t; #ifdef __cplusplus extern "C" { #endif -#ifdef GLSLANG_IS_SHARED_LIBRARY - #ifdef _WIN32 - #ifdef GLSLANG_EXPORTING - #define GLSLANG_EXPORT __declspec(dllexport) - #else - #define GLSLANG_EXPORT __declspec(dllimport) - #endif - #elif __GNUC__ >= 4 - #define GLSLANG_EXPORT __attribute__((visibility("default"))) - #endif -#endif // GLSLANG_IS_SHARED_LIBRARY - -#ifndef GLSLANG_EXPORT -#define GLSLANG_EXPORT -#endif +GLSLANG_EXPORT void glslang_get_version(glslang_version_t* version); GLSLANG_EXPORT int glslang_initialize_process(void); GLSLANG_EXPORT void glslang_finalize_process(void); @@ -259,9 +257,12 @@ GLSLANG_EXPORT void glslang_shader_shift_binding(glslang_shader_t* shader, glsla GLSLANG_EXPORT void glslang_shader_shift_binding_for_set(glslang_shader_t* shader, glslang_resource_type_t res, unsigned int base, unsigned int set); GLSLANG_EXPORT void glslang_shader_set_options(glslang_shader_t* shader, int options); // glslang_shader_options_t GLSLANG_EXPORT void glslang_shader_set_glsl_version(glslang_shader_t* shader, int version); +GLSLANG_EXPORT void glslang_shader_set_default_uniform_block_set_and_binding(glslang_shader_t* shader, unsigned int set, unsigned int binding); +GLSLANG_EXPORT void glslang_shader_set_default_uniform_block_name(glslang_shader_t* shader, const char *name); GLSLANG_EXPORT int glslang_shader_preprocess(glslang_shader_t* shader, const glslang_input_t* input); GLSLANG_EXPORT int glslang_shader_parse(glslang_shader_t* shader, const glslang_input_t* input); GLSLANG_EXPORT const char* glslang_shader_get_preprocessed_code(glslang_shader_t* shader); +GLSLANG_EXPORT void glslang_shader_set_preprocessed_code(glslang_shader_t* shader, const char* code); GLSLANG_EXPORT const char* glslang_shader_get_info_log(glslang_shader_t* shader); GLSLANG_EXPORT const char* glslang_shader_get_info_debug_log(glslang_shader_t* shader); @@ -272,6 +273,7 @@ GLSLANG_EXPORT int glslang_program_link(glslang_program_t* program, int messages GLSLANG_EXPORT void glslang_program_add_source_text(glslang_program_t* program, glslang_stage_t stage, const char* text, size_t len); GLSLANG_EXPORT void glslang_program_set_source_file(glslang_program_t* program, glslang_stage_t stage, const char* file); GLSLANG_EXPORT int glslang_program_map_io(glslang_program_t* program); +GLSLANG_EXPORT int glslang_program_map_io_with_resolver_and_mapper(glslang_program_t* program, glslang_resolver_t* resolver, glslang_mapper_t* mapper); GLSLANG_EXPORT void glslang_program_SPIRV_generate(glslang_program_t* program, glslang_stage_t stage); GLSLANG_EXPORT void glslang_program_SPIRV_generate_with_options(glslang_program_t* program, glslang_stage_t stage, glslang_spv_options_t* spv_options); GLSLANG_EXPORT size_t glslang_program_SPIRV_get_size(glslang_program_t* program); @@ -281,6 +283,12 @@ GLSLANG_EXPORT const char* glslang_program_SPIRV_get_messages(glslang_program_t* GLSLANG_EXPORT const char* glslang_program_get_info_log(glslang_program_t* program); GLSLANG_EXPORT const char* glslang_program_get_info_debug_log(glslang_program_t* program); +GLSLANG_EXPORT glslang_mapper_t* glslang_glsl_mapper_create(); +GLSLANG_EXPORT void glslang_glsl_mapper_delete(glslang_mapper_t* mapper); + +GLSLANG_EXPORT glslang_resolver_t* glslang_glsl_resolver_create(glslang_program_t* program, glslang_stage_t stage); +GLSLANG_EXPORT void glslang_glsl_resolver_delete(glslang_resolver_t* resolver); + #ifdef __cplusplus } #endif diff --git a/3rdparty/glslang/glslang/Include/glslang_c_shader_types.h b/3rdparty/glslang/glslang/Include/glslang_c_shader_types.h index 51f5642ab..7bb0ccda2 100644 --- a/3rdparty/glslang/glslang/Include/glslang_c_shader_types.h +++ b/3rdparty/glslang/glslang/Include/glslang_c_shader_types.h @@ -175,6 +175,7 @@ typedef enum { GLSLANG_MSG_BUILTIN_SYMBOL_TABLE_BIT = (1 << 14), GLSLANG_MSG_ENHANCED = (1 << 15), GLSLANG_MSG_ABSOLUTE_PATH = (1 << 16), + GLSLANG_MSG_DISPLAY_ERROR_COLUMN = (1 << 17), LAST_ELEMENT_MARKER(GLSLANG_MSG_COUNT), } glslang_messages_t; diff --git a/3rdparty/glslang/glslang/Include/visibility.h b/3rdparty/glslang/glslang/Include/visibility.h new file mode 100644 index 000000000..d6b6bb343 --- /dev/null +++ b/3rdparty/glslang/glslang/Include/visibility.h @@ -0,0 +1,51 @@ +// +// Copyright (C) 2023 LunarG, Inc. +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// +// Neither the name of 3Dlabs Inc. Ltd. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +#ifdef GLSLANG_IS_SHARED_LIBRARY + #ifdef _WIN32 + #ifdef GLSLANG_EXPORTING + #define GLSLANG_EXPORT __declspec(dllexport) + #else + #define GLSLANG_EXPORT __declspec(dllimport) + #endif + #elif __GNUC__ >= 4 + #define GLSLANG_EXPORT __attribute__((visibility("default"))) + #endif +#endif // GLSLANG_IS_SHARED_LIBRARY + +#ifndef GLSLANG_EXPORT +#define GLSLANG_EXPORT +#endif + + diff --git a/3rdparty/glslang/glslang/MachineIndependent/Constant.cpp b/3rdparty/glslang/glslang/MachineIndependent/Constant.cpp index ac7fc8cd1..7a9fb2ed6 100644 --- a/3rdparty/glslang/glslang/MachineIndependent/Constant.cpp +++ b/3rdparty/glslang/glslang/MachineIndependent/Constant.cpp @@ -507,7 +507,11 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TType& returnType) case EbtUint8: newConstArray[i].setU8Const(static_cast(-static_cast(unionArray[i].getU8Const()))); break; case EbtInt16: newConstArray[i].setI16Const(-unionArray[i].getI16Const()); break; case EbtUint16:newConstArray[i].setU16Const(static_cast(-static_cast(unionArray[i].getU16Const()))); break; - case EbtInt64: newConstArray[i].setI64Const(-unionArray[i].getI64Const()); break; + case EbtInt64: { + int64_t i64val = unionArray[i].getI64Const(); + newConstArray[i].setI64Const(i64val == INT64_MIN ? INT64_MIN : -i64val); + break; + } case EbtUint64: newConstArray[i].setU64Const(static_cast(-static_cast(unionArray[i].getU64Const()))); break; default: return nullptr; @@ -1009,6 +1013,12 @@ TIntermTyped* TIntermediate::fold(TIntermAggregate* aggrNode) objectSize = std::max(children[0]->getAsTyped()->getType().getVectorSize(), children[2]->getAsTyped()->getType().getVectorSize()); break; + case EOpMul: + { + TIntermConstantUnion* left = children[0]->getAsConstantUnion(); + TIntermConstantUnion* right = children[1]->getAsConstantUnion(); + return left->fold(EOpMul, right); + } default: return aggrNode; } diff --git a/3rdparty/glslang/glslang/MachineIndependent/Initialize.cpp b/3rdparty/glslang/glslang/MachineIndependent/Initialize.cpp old mode 100755 new mode 100644 diff --git a/3rdparty/glslang/glslang/MachineIndependent/ParseContextBase.cpp b/3rdparty/glslang/glslang/MachineIndependent/ParseContextBase.cpp index 591dfc718..f7895d979 100644 --- a/3rdparty/glslang/glslang/MachineIndependent/ParseContextBase.cpp +++ b/3rdparty/glslang/glslang/MachineIndependent/ParseContextBase.cpp @@ -59,7 +59,7 @@ void TParseContextBase::outputMessage(const TSourceLoc& loc, const char* szReaso safe_vsprintf(szExtraInfo, maxSize, szExtraInfoFormat, args); infoSink.info.prefix(prefix); - infoSink.info.location(loc, messages & EShMsgAbsolutePath); + infoSink.info.location(loc, messages & EShMsgAbsolutePath, messages & EShMsgDisplayErrorColumn); infoSink.info << "'" << szToken << "' : " << szReason << " " << szExtraInfo << "\n"; if (prefix == EPrefixError) { diff --git a/3rdparty/glslang/glslang/MachineIndependent/ParseHelper.cpp b/3rdparty/glslang/glslang/MachineIndependent/ParseHelper.cpp index 98a7d2688..f314b2783 100644 --- a/3rdparty/glslang/glslang/MachineIndependent/ParseHelper.cpp +++ b/3rdparty/glslang/glslang/MachineIndependent/ParseHelper.cpp @@ -4,6 +4,7 @@ // Copyright (C) 2015-2018 Google, Inc. // Copyright (C) 2017, 2019 ARM Limited. // Modifications Copyright (C) 2020 Advanced Micro Devices, Inc. All rights reserved. +// Modifications Copyright (C) 2024 Ravi Prakash Singh. // // All rights reserved. // @@ -41,7 +42,6 @@ #include "Initialize.h" #include "Scan.h" -#include "../OSDependent/osinclude.h" #include #include "preprocessor/PpContext.h" @@ -3935,6 +3935,18 @@ void TParseContext::accStructCheck(const TSourceLoc& loc, const TType& type, con } +void TParseContext::hitObjectNVCheck(const TSourceLoc & loc, const TType & type, const TString & identifier) +{ + if (type.getBasicType() == EbtStruct && containsFieldWithBasicType(type, EbtHitObjectNV)) { + error(loc, "struct is not allowed to contain hitObjectNV:", type.getTypeName().c_str(), identifier.c_str()); + } else if (type.getBasicType() == EbtHitObjectNV) { + TStorageQualifier qualifier = type.getQualifier().storage; + if (qualifier != EvqGlobal && qualifier != EvqTemporary) { + error(loc, "hitObjectNV can only be declared in global or function scope with no storage qualifier:", "hitObjectNV", identifier.c_str()); + } + } +} + void TParseContext::transparentOpaqueCheck(const TSourceLoc& loc, const TType& type, const TString& identifier) { if (parsingBuiltins) @@ -7386,7 +7398,7 @@ TIntermTyped* TParseContext::vkRelaxedRemapFunctionCall(const TSourceLoc& loc, T } } else if (function->getName() == "atomicCounter") { // change atomicCounter into a direct read of the variable - if (arguments->getAsTyped()) { + if (arguments && arguments->getAsTyped()) { result = arguments->getAsTyped(); } } @@ -7874,6 +7886,7 @@ TIntermNode* TParseContext::declareVariable(const TSourceLoc& loc, TString& iden transparentOpaqueCheck(loc, type, identifier); atomicUintCheck(loc, type, identifier); accStructCheck(loc, type, identifier); + hitObjectNVCheck(loc, type, identifier); checkAndResizeMeshViewDim(loc, type, /*isBlockMember*/ false); if (type.getQualifier().storage == EvqConst && type.containsReference()) { error(loc, "variables with reference type can't have qualifier 'const'", "qualifier", ""); @@ -8538,9 +8551,10 @@ TIntermTyped* TParseContext::constructBuiltIn(const TType& type, TOperator op, T case EOpConstructF16Mat4x4: case EOpConstructFloat16: basicOp = EOpConstructFloat16; - // 8/16-bit storage extensions don't support constructing composites of 8/16-bit types, + // 8/16-bit storage extensions don't support direct constructing composites of 8/16-bit types, // so construct a 32-bit type and convert - if (!intermediate.getArithemeticFloat16Enabled()) { + // and do not generate any conversion if it is an identity conversion, i.e. float16_t( var) + if (!intermediate.getArithemeticFloat16Enabled() && (node->getBasicType() != EbtFloat16)) { TType tempType(EbtFloat, EvqTemporary, type.getVectorSize()); newNode = node; if (tempType != newNode->getType()) { @@ -8561,9 +8575,10 @@ TIntermTyped* TParseContext::constructBuiltIn(const TType& type, TOperator op, T case EOpConstructI8Vec4: case EOpConstructInt8: basicOp = EOpConstructInt8; - // 8/16-bit storage extensions don't support constructing composites of 8/16-bit types, + // 8/16-bit storage extensions don't support direct constructing composites of 8/16-bit types, // so construct a 32-bit type and convert - if (!intermediate.getArithemeticInt8Enabled()) { + // and do not generate any conversion if it is an identity conversion, i.e. int8_t( var) + if (!intermediate.getArithemeticInt8Enabled() && (node->getBasicType() != EbtInt8)) { TType tempType(EbtInt, EvqTemporary, type.getVectorSize()); newNode = node; if (tempType != newNode->getType()) { @@ -8584,9 +8599,10 @@ TIntermTyped* TParseContext::constructBuiltIn(const TType& type, TOperator op, T case EOpConstructU8Vec4: case EOpConstructUint8: basicOp = EOpConstructUint8; - // 8/16-bit storage extensions don't support constructing composites of 8/16-bit types, + // 8/16-bit storage extensions don't support direct constructing composites of 8/16-bit types, // so construct a 32-bit type and convert - if (!intermediate.getArithemeticInt8Enabled()) { + // and do not generate any conversion if it is an identity conversion, i.e. uint8_t( var) + if (!intermediate.getArithemeticInt8Enabled() && (node->getBasicType() != EbtUint8)) { TType tempType(EbtUint, EvqTemporary, type.getVectorSize()); newNode = node; if (tempType != newNode->getType()) { @@ -8607,9 +8623,10 @@ TIntermTyped* TParseContext::constructBuiltIn(const TType& type, TOperator op, T case EOpConstructI16Vec4: case EOpConstructInt16: basicOp = EOpConstructInt16; - // 8/16-bit storage extensions don't support constructing composites of 8/16-bit types, + // 8/16-bit storage extensions don't support direct constructing composites of 8/16-bit types, // so construct a 32-bit type and convert - if (!intermediate.getArithemeticInt16Enabled()) { + // and do not generate any conversion if it is an identity conversion, i.e. int16_t( var) + if (!intermediate.getArithemeticInt16Enabled() && (node->getBasicType() != EbtInt16)) { TType tempType(EbtInt, EvqTemporary, type.getVectorSize()); newNode = node; if (tempType != newNode->getType()) { @@ -8630,9 +8647,10 @@ TIntermTyped* TParseContext::constructBuiltIn(const TType& type, TOperator op, T case EOpConstructU16Vec4: case EOpConstructUint16: basicOp = EOpConstructUint16; - // 8/16-bit storage extensions don't support constructing composites of 8/16-bit types, + // 8/16-bit storage extensions don't support direct constructing composites of 8/16-bit types, // so construct a 32-bit type and convert - if (!intermediate.getArithemeticInt16Enabled()) { + // and do not generate any conversion if it is an identity conversion, i.e. uint16_t( var) + if (!intermediate.getArithemeticInt16Enabled() && (node->getBasicType() != EbtUint16)) { TType tempType(EbtUint, EvqTemporary, type.getVectorSize()); newNode = node; if (tempType != newNode->getType()) { diff --git a/3rdparty/glslang/glslang/MachineIndependent/ParseHelper.h b/3rdparty/glslang/glslang/MachineIndependent/ParseHelper.h index 16902aefe..67ba7dbd1 100644 --- a/3rdparty/glslang/glslang/MachineIndependent/ParseHelper.h +++ b/3rdparty/glslang/glslang/MachineIndependent/ParseHelper.h @@ -397,6 +397,7 @@ public: void samplerCheck(const TSourceLoc&, const TType&, const TString& identifier, TIntermTyped* initializer); void atomicUintCheck(const TSourceLoc&, const TType&, const TString& identifier); void accStructCheck(const TSourceLoc & loc, const TType & type, const TString & identifier); + void hitObjectNVCheck(const TSourceLoc & loc, const TType & type, const TString & identifier); void transparentOpaqueCheck(const TSourceLoc&, const TType&, const TString& identifier); void memberQualifierCheck(glslang::TPublicType&); void globalQualifierFixCheck(const TSourceLoc&, TQualifier&, bool isMemberCheck = false, const TPublicType* publicType = nullptr); diff --git a/3rdparty/glslang/glslang/MachineIndependent/PoolAlloc.cpp b/3rdparty/glslang/glslang/MachineIndependent/PoolAlloc.cpp index 5d7173c9d..93a3b0d12 100644 --- a/3rdparty/glslang/glslang/MachineIndependent/PoolAlloc.cpp +++ b/3rdparty/glslang/glslang/MachineIndependent/PoolAlloc.cpp @@ -35,14 +35,21 @@ #include "../Include/Common.h" #include "../Include/PoolAlloc.h" +// Mostly here for target that do not support threads such as WASI. +#ifdef DISABLE_THREAD_SUPPORT +#define THREAD_LOCAL +#else +#define THREAD_LOCAL thread_local +#endif + namespace glslang { namespace { -thread_local TPoolAllocator* threadPoolAllocator = nullptr; +THREAD_LOCAL TPoolAllocator* threadPoolAllocator = nullptr; TPoolAllocator* GetDefaultThreadPoolAllocator() { - thread_local TPoolAllocator defaultAllocator; + THREAD_LOCAL TPoolAllocator defaultAllocator; return &defaultAllocator; } } // anonymous namespace diff --git a/3rdparty/glslang/glslang/MachineIndependent/ShaderLang.cpp b/3rdparty/glslang/glslang/MachineIndependent/ShaderLang.cpp index 034a03065..66e216636 100644 --- a/3rdparty/glslang/glslang/MachineIndependent/ShaderLang.cpp +++ b/3rdparty/glslang/glslang/MachineIndependent/ShaderLang.cpp @@ -82,7 +82,10 @@ namespace { // anonymous namespace for file-local functions and symbols int NumberOfClients = 0; // global initialization lock +#ifndef DISABLE_THREAD_SUPPORT std::mutex init_lock; +#endif + using namespace glslang; @@ -420,7 +423,9 @@ void SetupBuiltinSymbolTable(int version, EProfile profile, const SpvVersion& sp TInfoSink infoSink; // Make sure only one thread tries to do this at a time +#ifndef DISABLE_THREAD_SUPPORT const std::lock_guard lock(init_lock); +#endif // See if it's already been done for this version/profile combination int versionIndex = MapVersionToIndex(version); @@ -1311,7 +1316,9 @@ bool CompileDeferred( // int ShInitialize() { +#ifndef DISABLE_THREAD_SUPPORT const std::lock_guard lock(init_lock); +#endif ++NumberOfClients; if (PerProcessGPA == nullptr) @@ -1371,7 +1378,9 @@ void ShDestruct(ShHandle handle) // int ShFinalize() { +#ifndef DISABLE_THREAD_SUPPORT const std::lock_guard lock(init_lock); +#endif --NumberOfClients; assert(NumberOfClients >= 0); if (NumberOfClients > 0) @@ -1849,6 +1858,9 @@ void TShader::setGlobalUniformBinding(unsigned int binding) { intermediate->setG void TShader::setAtomicCounterBlockName(const char* name) { intermediate->setAtomicCounterBlockName(name); } void TShader::setAtomicCounterBlockSet(unsigned int set) { intermediate->setAtomicCounterBlockSet(set); } +void TShader::addSourceText(const char* text, size_t len) { intermediate->addSourceText(text, len); } +void TShader::setSourceFile(const char* file) { intermediate->setSourceFile(file); } + #ifdef ENABLE_HLSL // See comment above TDefaultHlslIoMapper in iomapper.cpp: void TShader::setHlslIoMapping(bool hlslIoMap) { intermediate->setHlslIoMapping(hlslIoMap); } @@ -2112,6 +2124,8 @@ bool TProgram::buildReflection(int opts) if (! linked || reflection != nullptr) return false; + SetThreadPoolAllocator(pool); + int firstStage = EShLangVertex, lastStage = EShLangFragment; if (opts & EShReflectionIntermediateIO) { @@ -2167,6 +2181,9 @@ bool TProgram::mapIO(TIoMapResolver* pResolver, TIoMapper* pIoMapper) { if (! linked) return false; + + SetThreadPoolAllocator(pool); + TIoMapper* ioMapper = nullptr; TIoMapper defaultIOMapper; if (pIoMapper == nullptr) diff --git a/3rdparty/glslang/glslang/MachineIndependent/Versions.cpp b/3rdparty/glslang/glslang/MachineIndependent/Versions.cpp index e016ef6b9..0262c54dc 100644 --- a/3rdparty/glslang/glslang/MachineIndependent/Versions.cpp +++ b/3rdparty/glslang/glslang/MachineIndependent/Versions.cpp @@ -775,7 +775,7 @@ void TParseVersions::profileRequires(const TSourceLoc& loc, int profileMask, int for (int i = 0; i < numExtensions; ++i) { switch (getExtensionBehavior(extensions[i])) { case EBhWarn: - infoSink.info.message(EPrefixWarning, ("extension " + TString(extensions[i]) + " is being used for " + featureDesc).c_str(), loc); + infoSink.info.message(EPrefixWarning, ("extension " + TString(extensions[i]) + " is being used for " + featureDesc).c_str(), loc, messages & EShMsgAbsolutePath, messages & EShMsgDisplayErrorColumn); [[fallthrough]]; case EBhRequire: case EBhEnable: @@ -813,7 +813,8 @@ void TParseVersions::checkDeprecated(const TSourceLoc& loc, int profileMask, int error(loc, "deprecated, may be removed in future release", featureDesc, ""); else if (! suppressWarnings()) infoSink.info.message(EPrefixWarning, (TString(featureDesc) + " deprecated in version " + - String(depVersion) + "; may be removed in future release").c_str(), loc); + String(depVersion) + "; may be removed in future release").c_str(), + loc, messages & EShMsgAbsolutePath, messages & EShMsgDisplayErrorColumn); } } } @@ -850,11 +851,14 @@ bool TParseVersions::checkExtensionsRequested(const TSourceLoc& loc, int numExte for (int i = 0; i < numExtensions; ++i) { TExtensionBehavior behavior = getExtensionBehavior(extensions[i]); if (behavior == EBhDisable && relaxedErrors()) { - infoSink.info.message(EPrefixWarning, "The following extension must be enabled to use this feature:", loc); + infoSink.info.message(EPrefixWarning, "The following extension must be enabled to use this feature:", loc, + messages & EShMsgAbsolutePath, messages & EShMsgDisplayErrorColumn); behavior = EBhWarn; } if (behavior == EBhWarn) { - infoSink.info.message(EPrefixWarning, ("extension " + TString(extensions[i]) + " is being used for " + featureDesc).c_str(), loc); + infoSink.info.message(EPrefixWarning, + ("extension " + TString(extensions[i]) + " is being used for " + featureDesc).c_str(), + loc, messages & EShMsgAbsolutePath, messages & EShMsgDisplayErrorColumn); warned = true; } } diff --git a/3rdparty/glslang/glslang/MachineIndependent/Versions.h b/3rdparty/glslang/glslang/MachineIndependent/Versions.h old mode 100755 new mode 100644 diff --git a/3rdparty/glslang/glslang/MachineIndependent/iomapper.cpp b/3rdparty/glslang/glslang/MachineIndependent/iomapper.cpp index 5e94a9e8d..3e7749d3a 100644 --- a/3rdparty/glslang/glslang/MachineIndependent/iomapper.cpp +++ b/3rdparty/glslang/glslang/MachineIndependent/iomapper.cpp @@ -39,6 +39,7 @@ #include "gl_types.h" #include "iomapper.h" +#include "LiveTraverser.h" #include "SymbolTable.h" // @@ -60,6 +61,108 @@ namespace glslang { +struct TVarEntryInfo { + long long id; + TIntermSymbol* symbol; + bool live; + bool upgradedToPushConstant; + int newBinding; + int newSet; + int newLocation; + int newComponent; + int newIndex; + EShLanguage stage; + + void clearNewAssignments() { + upgradedToPushConstant = false; + newBinding = -1; + newSet = -1; + newLocation = -1; + newComponent = -1; + newIndex = -1; + } + + struct TOrderById { + inline bool operator()(const TVarEntryInfo& l, const TVarEntryInfo& r) { return l.id < r.id; } + }; + + struct TOrderByPriority { + // ordering: + // 1) has both binding and set + // 2) has binding but no set + // 3) has no binding but set + // 4) has no binding and no set + inline bool operator()(const TVarEntryInfo& l, const TVarEntryInfo& r) { + const TQualifier& lq = l.symbol->getQualifier(); + const TQualifier& rq = r.symbol->getQualifier(); + + // simple rules: + // has binding gives 2 points + // has set gives 1 point + // who has the most points is more important. + int lPoints = (lq.hasBinding() ? 2 : 0) + (lq.hasSet() ? 1 : 0); + int rPoints = (rq.hasBinding() ? 2 : 0) + (rq.hasSet() ? 1 : 0); + + if (lPoints == rPoints) + return l.id < r.id; + return lPoints > rPoints; + } + }; + + struct TOrderByPriorityAndLive { + // ordering: + // 1) do live variables first + // 2) has both binding and set + // 3) has binding but no set + // 4) has no binding but set + // 5) has no binding and no set + inline bool operator()(const TVarEntryInfo& l, const TVarEntryInfo& r) { + + const TQualifier& lq = l.symbol->getQualifier(); + const TQualifier& rq = r.symbol->getQualifier(); + + // simple rules: + // has binding gives 2 points + // has set gives 1 point + // who has the most points is more important. + int lPoints = (lq.hasBinding() ? 2 : 0) + (lq.hasSet() ? 1 : 0); + int rPoints = (rq.hasBinding() ? 2 : 0) + (rq.hasSet() ? 1 : 0); + + if (l.live != r.live) + return l.live > r.live; + + if (lPoints != rPoints) + return lPoints > rPoints; + + return l.id < r.id; + } + }; +}; + +// override function "operator=", if a vector being sort, +// when use vc++, the sort function will call : +// pair& operator=(const pair<_Other1, _Other2>& _Right) +// { +// first = _Right.first; +// second = _Right.second; +// return (*this); +// } +// that will make a const type handing on left. +// override this function can avoid a compiler error. +// In the future, if the vc++ compiler can handle such a situation, +// this part of the code will be removed. +struct TVarLivePair : std::pair { + TVarLivePair(const std::pair& _Right) : pair(_Right.first, _Right.second) {} + TVarLivePair& operator=(const TVarLivePair& _Right) { + const_cast(first) = _Right.first; + second = _Right.second; + return (*this); + } + TVarLivePair(const TVarLivePair& src) : pair(src) { } +}; +typedef std::vector TVarLiveVector; + + class TVarGatherTraverser : public TLiveTraverser { public: TVarGatherTraverser(const TIntermediate& i, bool traverseDeadCode, TVarLiveMap& inList, TVarLiveMap& outList, TVarLiveMap& uniformList) @@ -176,7 +279,7 @@ struct TNotifyInOutAdaptor { EShLanguage stage; TIoMapResolver& resolver; - inline TNotifyInOutAdaptor(EShLanguage s, TIoMapResolver& r) + inline TNotifyInOutAdaptor(EShLanguage s, TIoMapResolver& r) : stage(s) , resolver(r) { @@ -1497,6 +1600,36 @@ bool TIoMapper::addStage(EShLanguage stage, TIntermediate& intermediate, TInfoSi return !hadError; } +TGlslIoMapper::TGlslIoMapper() { + memset(inVarMaps, 0, sizeof(TVarLiveMap*) * EShLangCount); + memset(outVarMaps, 0, sizeof(TVarLiveMap*) * EShLangCount); + memset(uniformVarMap, 0, sizeof(TVarLiveMap*) * EShLangCount); + memset(intermediates, 0, sizeof(TIntermediate*) * EShLangCount); + profile = ENoProfile; + version = 0; + autoPushConstantMaxSize = 128; + autoPushConstantBlockPacking = ElpStd430; +} + +TGlslIoMapper::~TGlslIoMapper() { + for (size_t stage = 0; stage < EShLangCount; stage++) { + if (inVarMaps[stage] != nullptr) { + delete inVarMaps[stage]; + inVarMaps[stage] = nullptr; + } + if (outVarMaps[stage] != nullptr) { + delete outVarMaps[stage]; + outVarMaps[stage] = nullptr; + } + if (uniformVarMap[stage] != nullptr) { + delete uniformVarMap[stage]; + uniformVarMap[stage] = nullptr; + } + if (intermediates[stage] != nullptr) + intermediates[stage] = nullptr; + } +} + // Map I/O variables to provided offsets, and make bindings for // unbound but live variables. // diff --git a/3rdparty/glslang/glslang/MachineIndependent/iomapper.h b/3rdparty/glslang/glslang/MachineIndependent/iomapper.h index 35babbce1..ef73c2731 100644 --- a/3rdparty/glslang/glslang/MachineIndependent/iomapper.h +++ b/3rdparty/glslang/glslang/MachineIndependent/iomapper.h @@ -37,7 +37,6 @@ #define _IOMAPPER_INCLUDED #include -#include "LiveTraverser.h" #include #include // @@ -49,84 +48,7 @@ class TInfoSink; namespace glslang { class TIntermediate; -struct TVarEntryInfo { - long long id; - TIntermSymbol* symbol; - bool live; - bool upgradedToPushConstant; - int newBinding; - int newSet; - int newLocation; - int newComponent; - int newIndex; - EShLanguage stage; - - void clearNewAssignments() { - upgradedToPushConstant = false; - newBinding = -1; - newSet = -1; - newLocation = -1; - newComponent = -1; - newIndex = -1; - } - - struct TOrderById { - inline bool operator()(const TVarEntryInfo& l, const TVarEntryInfo& r) { return l.id < r.id; } - }; - - struct TOrderByPriority { - // ordering: - // 1) has both binding and set - // 2) has binding but no set - // 3) has no binding but set - // 4) has no binding and no set - inline bool operator()(const TVarEntryInfo& l, const TVarEntryInfo& r) { - const TQualifier& lq = l.symbol->getQualifier(); - const TQualifier& rq = r.symbol->getQualifier(); - - // simple rules: - // has binding gives 2 points - // has set gives 1 point - // who has the most points is more important. - int lPoints = (lq.hasBinding() ? 2 : 0) + (lq.hasSet() ? 1 : 0); - int rPoints = (rq.hasBinding() ? 2 : 0) + (rq.hasSet() ? 1 : 0); - - if (lPoints == rPoints) - return l.id < r.id; - return lPoints > rPoints; - } - }; - - struct TOrderByPriorityAndLive { - // ordering: - // 1) do live variables first - // 2) has both binding and set - // 3) has binding but no set - // 4) has no binding but set - // 5) has no binding and no set - inline bool operator()(const TVarEntryInfo& l, const TVarEntryInfo& r) { - - const TQualifier& lq = l.symbol->getQualifier(); - const TQualifier& rq = r.symbol->getQualifier(); - - // simple rules: - // has binding gives 2 points - // has set gives 1 point - // who has the most points is more important. - int lPoints = (lq.hasBinding() ? 2 : 0) + (lq.hasSet() ? 1 : 0); - int rPoints = (rq.hasBinding() ? 2 : 0) + (rq.hasSet() ? 1 : 0); - - if (l.live != r.live) - return l.live > r.live; - - if (lPoints != rPoints) - return lPoints > rPoints; - - return l.id < r.id; - } - }; -}; - +struct TVarEntryInfo; // Base class for shared TIoMapResolver services, used by several derivations. struct TDefaultIoResolverBase : public glslang::TIoMapResolver { public: @@ -267,29 +189,6 @@ protected: typedef std::map TVarLiveMap; -// override function "operator=", if a vector being sort, -// when use vc++, the sort function will call : -// pair& operator=(const pair<_Other1, _Other2>& _Right) -// { -// first = _Right.first; -// second = _Right.second; -// return (*this); -// } -// that will make a const type handing on left. -// override this function can avoid a compiler error. -// In the future, if the vc++ compiler can handle such a situation, -// this part of the code will be removed. -struct TVarLivePair : std::pair { - TVarLivePair(const std::pair& _Right) : pair(_Right.first, _Right.second) {} - TVarLivePair& operator=(const TVarLivePair& _Right) { - const_cast(first) = _Right.first; - second = _Right.second; - return (*this); - } - TVarLivePair(const TVarLivePair& src) : pair(src) { } -}; -typedef std::vector TVarLiveVector; - // I/O mapper class TIoMapper { public: @@ -303,34 +202,8 @@ public: // I/O mapper for GLSL class TGlslIoMapper : public TIoMapper { public: - TGlslIoMapper() { - memset(inVarMaps, 0, sizeof(TVarLiveMap*) * (EShLangCount + 1)); - memset(outVarMaps, 0, sizeof(TVarLiveMap*) * (EShLangCount + 1)); - memset(uniformVarMap, 0, sizeof(TVarLiveMap*) * (EShLangCount + 1)); - memset(intermediates, 0, sizeof(TIntermediate*) * (EShLangCount + 1)); - profile = ENoProfile; - version = 0; - autoPushConstantMaxSize = 128; - autoPushConstantBlockPacking = ElpStd430; - } - virtual ~TGlslIoMapper() { - for (size_t stage = 0; stage < EShLangCount; stage++) { - if (inVarMaps[stage] != nullptr) { - delete inVarMaps[stage]; - inVarMaps[stage] = nullptr; - } - if (outVarMaps[stage] != nullptr) { - delete outVarMaps[stage]; - outVarMaps[stage] = nullptr; - } - if (uniformVarMap[stage] != nullptr) { - delete uniformVarMap[stage]; - uniformVarMap[stage] = nullptr; - } - if (intermediates[stage] != nullptr) - intermediates[stage] = nullptr; - } - } + TGlslIoMapper(); + virtual ~TGlslIoMapper(); // If set, the uniform block with the given name will be changed to be backed by // push_constant if it's size is <= maxSize void setAutoPushConstantBlock(const char* name, unsigned int maxSize, TLayoutPacking packing) { @@ -341,8 +214,6 @@ public: // grow the reflection stage by stage bool addStage(EShLanguage, TIntermediate&, TInfoSink&, TIoMapResolver*) override; bool doMap(TIoMapResolver*, TInfoSink&) override; - TVarLiveMap *inVarMaps[EShLangCount], *outVarMaps[EShLangCount], - *uniformVarMap[EShLangCount]; TIntermediate* intermediates[EShLangCount]; bool hadError = false; EProfile profile; @@ -352,6 +223,8 @@ private: TString autoPushConstantBlockName; unsigned int autoPushConstantMaxSize; TLayoutPacking autoPushConstantBlockPacking; + TVarLiveMap *inVarMaps[EShLangCount], *outVarMaps[EShLangCount], + *uniformVarMap[EShLangCount]; }; } // end namespace glslang diff --git a/3rdparty/glslang/glslang/MachineIndependent/linkValidate.cpp b/3rdparty/glslang/glslang/MachineIndependent/linkValidate.cpp index 62e24426e..182a67754 100644 --- a/3rdparty/glslang/glslang/MachineIndependent/linkValidate.cpp +++ b/3rdparty/glslang/glslang/MachineIndependent/linkValidate.cpp @@ -113,6 +113,28 @@ void TIntermediate::mergeUniformObjects(TInfoSink& infoSink, TIntermediate& unit mergeLinkerObjects(infoSink, linkerObjects, unitLinkerObjects, unit.getStage()); } +static inline bool isSameInterface(TIntermSymbol* symbol, EShLanguage stage, TIntermSymbol* unitSymbol, EShLanguage unitStage) { + return // 1) same stage and same shader interface + (stage == unitStage && symbol->getType().getShaderInterface() == unitSymbol->getType().getShaderInterface()) || + // 2) accross stages and both are uniform or buffer + (symbol->getQualifier().storage == EvqUniform && unitSymbol->getQualifier().storage == EvqUniform) || + (symbol->getQualifier().storage == EvqBuffer && unitSymbol->getQualifier().storage == EvqBuffer) || + // 3) in/out matched across stage boundary + (stage < unitStage && symbol->getQualifier().storage == EvqVaryingOut && unitSymbol->getQualifier().storage == EvqVaryingIn) || + (unitStage < stage && symbol->getQualifier().storage == EvqVaryingIn && unitSymbol->getQualifier().storage == EvqVaryingOut); +} + +static bool isSameSymbol(TIntermSymbol* symbol1, EShLanguage stage1, TIntermSymbol* symbol2, EShLanguage stage2) { + // If they are both blocks in the same shader interface, + // match by the block-name, not the identifier name. + if (symbol1->getType().getBasicType() == EbtBlock && symbol2->getType().getBasicType() == EbtBlock) { + if (isSameInterface(symbol1, stage1, symbol2, stage2)) { + return symbol1->getType().getTypeName() == symbol2->getType().getTypeName(); + } + } else if (symbol1->getName() == symbol2->getName()) + return true; + return false; +} // // do error checking on the shader boundary in / out vars // @@ -137,7 +159,32 @@ void TIntermediate::checkStageIO(TInfoSink& infoSink, TIntermediate& unit) { // do matching and error checking mergeLinkerObjects(infoSink, linkerObjects, unitLinkerObjects, unit.getStage()); - // TODO: final check; make sure that any statically used `in` have matching `out` written to + // Check that all of our inputs have matching outputs from the previous stage. + // Only do this for Vulkan, since GL_ARB_separate_shader_objects allows for + // the in/out to not match + if (spvVersion.vulkan > 0) { + for (auto& nextStageInterm : unitLinkerObjects) { + auto* nextStageSymbol = nextStageInterm->getAsSymbolNode(); + bool found = false; + for (auto& curStageInterm : linkerObjects) { + if (isSameSymbol(curStageInterm->getAsSymbolNode(), getStage(), nextStageSymbol, unit.getStage())) { + found = true; + break; + } + } + if (!found) { + TString errmsg; + errmsg.append("Input '"); + if (nextStageSymbol->getType().getBasicType() == EbtBlock) + errmsg.append(nextStageSymbol->getType().getTypeName()); + else + errmsg.append(nextStageSymbol->getName()); + errmsg.append("' in ").append(StageName(unit.getStage())); + errmsg.append(" shader has no corresponding output in ").append(StageName(getStage())).append(" shader."); + error(infoSink, errmsg.c_str(), unit.getStage()); + } + } + } } void TIntermediate::mergeCallGraphs(TInfoSink& infoSink, TIntermediate& unit) @@ -511,17 +558,6 @@ void TIntermediate::mergeBodies(TInfoSink& infoSink, TIntermSequence& globals, c globals.insert(globals.end() - 1, unitGlobals.begin(), unitGlobals.end() - 1); } -static inline bool isSameInterface(TIntermSymbol* symbol, EShLanguage stage, TIntermSymbol* unitSymbol, EShLanguage unitStage) { - return // 1) same stage and same shader interface - (stage == unitStage && symbol->getType().getShaderInterface() == unitSymbol->getType().getShaderInterface()) || - // 2) accross stages and both are uniform or buffer - (symbol->getQualifier().storage == EvqUniform && unitSymbol->getQualifier().storage == EvqUniform) || - (symbol->getQualifier().storage == EvqBuffer && unitSymbol->getQualifier().storage == EvqBuffer) || - // 3) in/out matched across stage boundary - (stage < unitStage && symbol->getQualifier().storage == EvqVaryingOut && unitSymbol->getQualifier().storage == EvqVaryingIn) || - (unitStage < stage && symbol->getQualifier().storage == EvqVaryingIn && unitSymbol->getQualifier().storage == EvqVaryingOut); -} - // // Global Unfiform block stores any default uniforms (i.e. uniforms without a block) // If two linked stages declare the same member, they are meant to be the same uniform @@ -707,24 +743,18 @@ void TIntermediate::mergeLinkerObjects(TInfoSink& infoSink, TIntermSequence& lin // Error check and merge the linker objects (duplicates should not be created) std::size_t initialNumLinkerObjects = linkerObjects.size(); for (unsigned int unitLinkObj = 0; unitLinkObj < unitLinkerObjects.size(); ++unitLinkObj) { + TIntermSymbol* unitSymbol = unitLinkerObjects[unitLinkObj]->getAsSymbolNode(); bool merge = true; + + // Don't merge inputs backwards into previous stages + if (getStage() != unitStage && unitSymbol->getQualifier().storage == EvqVaryingIn) + merge = false; + for (std::size_t linkObj = 0; linkObj < initialNumLinkerObjects; ++linkObj) { TIntermSymbol* symbol = linkerObjects[linkObj]->getAsSymbolNode(); - TIntermSymbol* unitSymbol = unitLinkerObjects[unitLinkObj]->getAsSymbolNode(); assert(symbol && unitSymbol); - bool isSameSymbol = false; - // If they are both blocks in the same shader interface, - // match by the block-name, not the identifier name. - if (symbol->getType().getBasicType() == EbtBlock && unitSymbol->getType().getBasicType() == EbtBlock) { - if (isSameInterface(symbol, getStage(), unitSymbol, unitStage)) { - isSameSymbol = symbol->getType().getTypeName() == unitSymbol->getType().getTypeName(); - } - } - else if (symbol->getName() == unitSymbol->getName()) - isSameSymbol = true; - - if (isSameSymbol) { + if (isSameSymbol(symbol, getStage(), unitSymbol, unitStage)) { // filter out copy merge = false; @@ -1689,7 +1719,7 @@ int TIntermediate::addUsedLocation(const TQualifier& qualifier, const TType& typ // First range: TRange locationRange(qualifier.layoutLocation, qualifier.layoutLocation); TRange componentRange(0, 3); - TIoRange range(locationRange, componentRange, type.getBasicType(), 0, qualifier.centroid, qualifier.smooth, qualifier.flat); + TIoRange range(locationRange, componentRange, type.getBasicType(), 0, qualifier.centroid, qualifier.smooth, qualifier.flat, qualifier.sample, qualifier.patch); // check for collisions collision = checkLocationRange(set, range, type, typeCollision); @@ -1699,7 +1729,7 @@ int TIntermediate::addUsedLocation(const TQualifier& qualifier, const TType& typ // Second range: TRange locationRange2(qualifier.layoutLocation + 1, qualifier.layoutLocation + 1); TRange componentRange2(0, 1); - TIoRange range2(locationRange2, componentRange2, type.getBasicType(), 0, qualifier.centroid, qualifier.smooth, qualifier.flat); + TIoRange range2(locationRange2, componentRange2, type.getBasicType(), 0, qualifier.centroid, qualifier.smooth, qualifier.flat, qualifier.sample, qualifier.patch); // check for collisions collision = checkLocationRange(set, range2, type, typeCollision); @@ -1725,7 +1755,7 @@ int TIntermediate::addUsedLocation(const TQualifier& qualifier, const TType& typ TBasicType basicTy = type.getBasicType(); if (basicTy == EbtSampler && type.getSampler().isAttachmentEXT()) basicTy = type.getSampler().type; - TIoRange range(locationRange, componentRange, basicTy, qualifier.hasIndex() ? qualifier.getIndex() : 0, qualifier.centroid, qualifier.smooth, qualifier.flat); + TIoRange range(locationRange, componentRange, basicTy, qualifier.hasIndex() ? qualifier.getIndex() : 0, qualifier.centroid, qualifier.smooth, qualifier.flat, qualifier.sample, qualifier.patch); // check for collisions, except for vertex inputs on desktop targeting OpenGL if (! (!isEsProfile() && language == EShLangVertex && qualifier.isPipeInput()) || spvVersion.vulkan > 0) @@ -1737,6 +1767,24 @@ int TIntermediate::addUsedLocation(const TQualifier& qualifier, const TType& typ return collision; } +// Check that two types can be stored in different components in the same location. +// They must be the same type, except signed/unsigned integers are considered compatible. +static bool checkCompatibleTypes(TBasicType t1, TBasicType t2) { + if (t1 != t2) { + if ((t1 == EbtInt8 && t2 == EbtUint8) || + (t2 == EbtInt8 && t1 == EbtUint8) || + (t1 == EbtInt16 && t2 == EbtUint16) || + (t2 == EbtInt16 && t1 == EbtUint16)|| + (t1 == EbtInt && t2 == EbtUint) || + (t2 == EbtInt && t1 == EbtUint)|| + (t1 == EbtInt64 && t2 == EbtUint64) || + (t2 == EbtInt64 && t1 == EbtUint64)) { + return true; + } + } + return t1 == t2; +} + // Compare a new (the passed in) 'range' against the existing set, and see // if there are any collisions. // @@ -1749,10 +1797,12 @@ int TIntermediate::checkLocationRange(int set, const TIoRange& range, const TTyp // there is a collision; pick one return std::max(range.location.start, usedIo[set][r].location.start); } else if (range.location.overlap(usedIo[set][r].location) && - (type.getBasicType() != usedIo[set][r].basicType || + (!checkCompatibleTypes(type.getBasicType(), usedIo[set][r].basicType) || type.getQualifier().centroid != usedIo[set][r].centroid || type.getQualifier().smooth != usedIo[set][r].smooth || - type.getQualifier().flat != usedIo[set][r].flat)) { + type.getQualifier().flat != usedIo[set][r].flat || + type.getQualifier().sample != usedIo[set][r].sample || + type.getQualifier().patch != usedIo[set][r].patch)) { // aliased-type mismatch typeCollision = true; return std::max(range.location.start, usedIo[set][r].location.start); diff --git a/3rdparty/glslang/glslang/MachineIndependent/localintermediate.h b/3rdparty/glslang/glslang/MachineIndependent/localintermediate.h index 2a24cdaf7..390a405fb 100644 --- a/3rdparty/glslang/glslang/MachineIndependent/localintermediate.h +++ b/3rdparty/glslang/glslang/MachineIndependent/localintermediate.h @@ -99,7 +99,8 @@ private: // A "call" is a pair: . // There can be duplicates. General assumption is the list is small. struct TCall { - TCall(const TString& pCaller, const TString& pCallee) : caller(pCaller), callee(pCallee) { } + TCall(const TString& pCaller, const TString& pCallee) + : caller(pCaller), callee(pCallee), visited(false), currentPath(false), errorGiven(false) { } TString caller; TString callee; bool visited; @@ -123,8 +124,8 @@ struct TRange { // within the same location range, component range, and index value. Locations don't alias unless // all other dimensions of their range overlap. struct TIoRange { - TIoRange(TRange location, TRange component, TBasicType basicType, int index, bool centroid, bool smooth, bool flat) - : location(location), component(component), basicType(basicType), index(index), centroid(centroid), smooth(smooth), flat(flat) + TIoRange(TRange location, TRange component, TBasicType basicType, int index, bool centroid, bool smooth, bool flat, bool sample, bool patch) + : location(location), component(component), basicType(basicType), index(index), centroid(centroid), smooth(smooth), flat(flat), sample(sample), patch(patch) { } bool overlap(const TIoRange& rhs) const @@ -138,6 +139,8 @@ struct TIoRange { bool centroid; bool smooth; bool flat; + bool sample; + bool patch; }; // An offset range is a 2-D rectangle; the set of (binding, offset) pairs all lying diff --git a/3rdparty/glslang/glslang/MachineIndependent/preprocessor/Pp.cpp b/3rdparty/glslang/glslang/MachineIndependent/preprocessor/Pp.cpp index 5f18c4e92..56f1f0b38 100644 --- a/3rdparty/glslang/glslang/MachineIndependent/preprocessor/Pp.cpp +++ b/3rdparty/glslang/glslang/MachineIndependent/preprocessor/Pp.cpp @@ -374,7 +374,7 @@ namespace { int op_div(int a, int b) { return a == INT_MIN && b == -1 ? 0 : a / b; } int op_mod(int a, int b) { return a == INT_MIN && b == -1 ? 0 : a % b; } int op_pos(int a) { return a; } - int op_neg(int a) { return -a; } + int op_neg(int a) { return a == INT_MIN ? INT_MIN : -a; } int op_cmpl(int a) { return ~a; } int op_not(int a) { return !a; } diff --git a/3rdparty/glslang/glslang/Public/ShaderLang.h b/3rdparty/glslang/glslang/Public/ShaderLang.h index b71b147a5..d78803071 100644 --- a/3rdparty/glslang/glslang/Public/ShaderLang.h +++ b/3rdparty/glslang/glslang/Public/ShaderLang.h @@ -38,6 +38,7 @@ #define _COMPILER_INTERFACE_INCLUDED_ #include "../Include/ResourceLimits.h" +#include "../Include/visibility.h" #include "../MachineIndependent/Versions.h" #include @@ -49,22 +50,6 @@ #define C_DECL #endif -#ifdef GLSLANG_IS_SHARED_LIBRARY - #ifdef _WIN32 - #ifdef GLSLANG_EXPORTING - #define GLSLANG_EXPORT __declspec(dllexport) - #else - #define GLSLANG_EXPORT __declspec(dllimport) - #endif - #elif __GNUC__ >= 4 - #define GLSLANG_EXPORT __attribute__((visibility("default"))) - #endif -#endif // GLSLANG_IS_SHARED_LIBRARY - -#ifndef GLSLANG_EXPORT -#define GLSLANG_EXPORT -#endif - // // This is the platform independent interface between an OGL driver // and the shading language compiler/linker. @@ -270,6 +255,7 @@ enum EShMessages : unsigned { EShMsgBuiltinSymbolTable = (1 << 14), // print the builtin symbol table EShMsgEnhanced = (1 << 15), // enhanced message readability EShMsgAbsolutePath = (1 << 16), // Output Absolute path for messages + EShMsgDisplayErrorColumn = (1 << 17), // Display error message column aswell as line LAST_ELEMENT_MARKER(EShMsgCount), }; @@ -509,6 +495,9 @@ public: GLSLANG_EXPORT void setAtomicCounterBlockSet(unsigned int set); GLSLANG_EXPORT void setAtomicCounterBlockBinding(unsigned int binding); + GLSLANG_EXPORT void addSourceText(const char* text, size_t len); + GLSLANG_EXPORT void setSourceFile(const char* file); + // For setting up the environment (cleared to nothingness in the constructor). // These must be called so that parsing is done for the right source language and // target environment, either indirectly through TranslateEnvironment() based on diff --git a/3rdparty/glslang/glslang/stub.cpp b/3rdparty/glslang/glslang/stub.cpp new file mode 100644 index 000000000..b9aec6d15 --- /dev/null +++ b/3rdparty/glslang/glslang/stub.cpp @@ -0,0 +1,37 @@ +// +// Copyright (C) 2024 The Khronos Group Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// +// Neither the name of 3Dlabs Inc. Ltd. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// + +// This empty source file exists to support building stubbed versions of +// deprecated libraries which have been integrated into the main glslang +// library. It should be deleted once the stub libraries are fully removed.