Browse Source

Update glslang with array-of-samplers fix.

Sasha Szpakowski 1 year ago
parent
commit
fd1901b3ad
34 changed files with 1290 additions and 614 deletions
  1. 5 0
      src/libraries/glslang/SPIRV/GLSL.ext.KHR.h
  2. 3 0
      src/libraries/glslang/SPIRV/GLSL.ext.NV.h
  3. 2 0
      src/libraries/glslang/SPIRV/GLSL.ext.QCOM.h
  4. 217 60
      src/libraries/glslang/SPIRV/GlslangToSpv.cpp
  5. 115 151
      src/libraries/glslang/SPIRV/SpvBuilder.cpp
  6. 71 44
      src/libraries/glslang/SPIRV/SpvBuilder.h
  7. 1 0
      src/libraries/glslang/SPIRV/SpvPostProcess.cpp
  8. 7 2
      src/libraries/glslang/SPIRV/disassemble.cpp
  9. 68 1
      src/libraries/glslang/SPIRV/doc.cpp
  10. 23 4
      src/libraries/glslang/SPIRV/spirv.hpp
  11. 35 0
      src/libraries/glslang/SPIRV/spvIR.h
  12. 5 0
      src/libraries/glslang/glslang/Include/Common.h
  13. 21 3
      src/libraries/glslang/glslang/Include/InfoSink.h
  14. 34 5
      src/libraries/glslang/glslang/Include/Types.h
  15. 15 1
      src/libraries/glslang/glslang/Include/intermediate.h
  16. 155 4
      src/libraries/glslang/glslang/MachineIndependent/Initialize.cpp
  17. 6 2
      src/libraries/glslang/glslang/MachineIndependent/Intermediate.cpp
  18. 2 1
      src/libraries/glslang/glslang/MachineIndependent/ParseContextBase.cpp
  19. 84 13
      src/libraries/glslang/glslang/MachineIndependent/ParseHelper.cpp
  20. 6 1
      src/libraries/glslang/glslang/MachineIndependent/ShaderLang.cpp
  21. 1 0
      src/libraries/glslang/glslang/MachineIndependent/SymbolTable.cpp
  22. 20 2
      src/libraries/glslang/glslang/MachineIndependent/Versions.cpp
  23. 9 1
      src/libraries/glslang/glslang/MachineIndependent/Versions.h
  24. 6 0
      src/libraries/glslang/glslang/MachineIndependent/attribute.cpp
  25. 1 0
      src/libraries/glslang/glslang/MachineIndependent/attribute.h
  26. 246 237
      src/libraries/glslang/glslang/MachineIndependent/glslang_tab.cpp
  27. 13 2
      src/libraries/glslang/glslang/MachineIndependent/intermOut.cpp
  28. 2 2
      src/libraries/glslang/glslang/MachineIndependent/iomapper.cpp
  29. 1 1
      src/libraries/glslang/glslang/MachineIndependent/linkValidate.cpp
  30. 13 1
      src/libraries/glslang/glslang/MachineIndependent/localintermediate.h
  31. 5 0
      src/libraries/glslang/glslang/MachineIndependent/parseVersions.h
  32. 2 1
      src/libraries/glslang/glslang/MachineIndependent/preprocessor/Pp.cpp
  33. 76 57
      src/libraries/glslang/glslang/MachineIndependent/reflection.cpp
  34. 20 18
      src/libraries/glslang/glslang/Public/ShaderLang.h

+ 5 - 0
src/libraries/glslang/SPIRV/GLSL.ext.KHR.h

@@ -1,5 +1,6 @@
 /*
 ** Copyright (c) 2014-2020 The Khronos Group Inc.
+** Copyright (C) 2022-2024 Arm Limited.
 ** Modifications Copyright (C) 2020 Advanced Micro Devices, Inc. All rights reserved.
 **
 ** Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -53,8 +54,12 @@ static const char* const E_SPV_KHR_terminate_invocation         = "SPV_KHR_termi
 static const char* const E_SPV_KHR_workgroup_memory_explicit_layout = "SPV_KHR_workgroup_memory_explicit_layout";
 static const char* const E_SPV_KHR_subgroup_uniform_control_flow = "SPV_KHR_subgroup_uniform_control_flow";
 static const char* const E_SPV_KHR_fragment_shader_barycentric = "SPV_KHR_fragment_shader_barycentric";
+static const char* const E_SPV_KHR_quad_control                = "SPV_KHR_quad_control";
 static const char* const E_SPV_AMD_shader_early_and_late_fragment_tests = "SPV_AMD_shader_early_and_late_fragment_tests";
 static const char* const E_SPV_KHR_ray_tracing_position_fetch   = "SPV_KHR_ray_tracing_position_fetch";
 static const char* const E_SPV_KHR_cooperative_matrix           = "SPV_KHR_cooperative_matrix";
+static const char* const E_SPV_KHR_maximal_reconvergence        = "SPV_KHR_maximal_reconvergence";
+static const char* const E_SPV_KHR_subgroup_rotate              = "SPV_KHR_subgroup_rotate";
+static const char* const E_SPV_KHR_expect_assume                = "SPV_KHR_expect_assume";
 
 #endif  // #ifndef GLSLextKHR_H

+ 3 - 0
src/libraries/glslang/SPIRV/GLSL.ext.NV.h

@@ -87,4 +87,7 @@ const char* const E_SPV_NV_shader_invocation_reorder = "SPV_NV_shader_invocation
 //SPV_NV_displacement_micromap
 const char* const E_SPV_NV_displacement_micromap = "SPV_NV_displacement_micromap";
 
+//SPV_NV_shader_atomic_fp16_vector
+const char* const E_SPV_NV_shader_atomic_fp16_vector = "SPV_NV_shader_atomic_fp16_vector";
+
 #endif  // #ifndef GLSLextNV_H

+ 2 - 0
src/libraries/glslang/SPIRV/GLSL.ext.QCOM.h

@@ -37,5 +37,7 @@ static const int GLSLextQCOMRevision = 1;
 
 //SPV_QCOM_image_processing
 const char* const E_SPV_QCOM_image_processing = "SPV_QCOM_image_processing";
+//SPV_QCOM_image_processing2
+const char* const E_SPV_QCOM_image_processing2 = "SPV_QCOM_image_processing2";
 
 #endif  // #ifndef GLSLextQCOM_H

+ 217 - 60
src/libraries/glslang/SPIRV/GlslangToSpv.cpp

@@ -1,7 +1,7 @@
 //
 // Copyright (C) 2014-2016 LunarG, Inc.
 // Copyright (C) 2015-2020 Google, Inc.
-// Copyright (C) 2017 ARM Limited.
+// Copyright (C) 2017, 2022-2024 Arm Limited.
 // Modifications Copyright (C) 2020 Advanced Micro Devices, Inc. All rights reserved.
 //
 // All rights reserved.
@@ -204,7 +204,8 @@ protected:
     spv::Id createBinaryMatrixOperation(spv::Op, OpDecorations&, spv::Id typeId, spv::Id left, spv::Id right);
     spv::Id createUnaryOperation(glslang::TOperator op, OpDecorations&, spv::Id typeId, spv::Id operand,
                                  glslang::TBasicType typeProxy,
-                                 const spv::Builder::AccessChain::CoherentFlags &lvalueCoherentFlags);
+                                 const spv::Builder::AccessChain::CoherentFlags &lvalueCoherentFlags,
+                                 const glslang::TType &opType);
     spv::Id createUnaryMatrixOperation(spv::Op op, OpDecorations&, spv::Id typeId, spv::Id operand,
                                        glslang::TBasicType typeProxy);
     spv::Id createConversion(glslang::TOperator op, OpDecorations&, spv::Id destTypeId, spv::Id operand,
@@ -213,7 +214,8 @@ protected:
     spv::Id makeSmearedConstant(spv::Id constant, int vectorSize);
     spv::Id createAtomicOperation(glslang::TOperator op, spv::Decoration precision, spv::Id typeId,
         std::vector<spv::Id>& operands, glslang::TBasicType typeProxy,
-        const spv::Builder::AccessChain::CoherentFlags &lvalueCoherentFlags);
+        const spv::Builder::AccessChain::CoherentFlags &lvalueCoherentFlags,
+        const glslang::TType &opType);
     spv::Id createInvocationsOperation(glslang::TOperator op, spv::Id typeId, std::vector<spv::Id>& operands,
         glslang::TBasicType typeProxy);
     spv::Id CreateInvocationsVectorOperation(spv::Op op, spv::GroupOperation groupOperation,
@@ -226,6 +228,7 @@ protected:
     spv::Id getSymbolId(const glslang::TIntermSymbol* node);
     void addMeshNVDecoration(spv::Id id, int member, const glslang::TQualifier & qualifier);
     void addImageProcessingQCOMDecoration(spv::Id id, spv::Decoration decor);
+    void addImageProcessing2QCOMDecoration(spv::Id id, bool isForGather);
     spv::Id createSpvConstant(const glslang::TIntermTyped&);
     spv::Id createSpvConstantFromConstUnionArray(const glslang::TType& type, const glslang::TConstUnionArray&,
         int& nextConst, bool specConstant);
@@ -1163,6 +1166,7 @@ spv::ImageFormat TGlslangToSpvTraverser::TranslateImageFormat(const glslang::TTy
     case glslang::ElfR64i:
         builder.addExtension(spv::E_SPV_EXT_shader_image_int64);
         builder.addCapability(spv::CapabilityInt64ImageEXT);
+        break;
     default:
         break;
     }
@@ -1558,8 +1562,13 @@ TGlslangToSpvTraverser::TGlslangToSpvTraverser(unsigned int spvVersion,
             this->options.generateDebugInfo = true;
 
     if (this->options.generateDebugInfo) {
-        builder.setEmitOpLines();
-        builder.setSourceFile(glslangIntermediate->getSourceFile());
+        if (this->options.emitNonSemanticShaderDebugInfo) {
+            builder.setEmitNonSemanticShaderDebugInfo(this->options.emitNonSemanticShaderDebugSource);
+        }
+        else {
+            builder.setEmitSpirvDebugInfo();
+        }
+        builder.setDebugSourceFile(glslangIntermediate->getSourceFile());
 
         // Set the source shader's text. If for SPV version 1.0, include
         // a preamble in comments stating the OpModuleProcessed instructions.
@@ -1584,9 +1593,6 @@ TGlslangToSpvTraverser::TGlslangToSpvTraverser(unsigned int spvVersion,
             builder.addInclude(iItr->first, iItr->second);
     }
 
-    builder.setEmitNonSemanticShaderDebugInfo(this->options.emitNonSemanticShaderDebugInfo);
-    builder.setEmitNonSemanticShaderDebugSource(this->options.emitNonSemanticShaderDebugSource);
-
     stdBuiltins = builder.import("GLSL.std.450");
 
     spv::AddressingModel addressingModel = spv::AddressingModelLogical;
@@ -1635,6 +1641,24 @@ TGlslangToSpvTraverser::TGlslangToSpvTraverser(unsigned int spvVersion,
         builder.addExtension(spv::E_SPV_KHR_subgroup_uniform_control_flow);
         builder.addExecutionMode(shaderEntry, spv::ExecutionModeSubgroupUniformControlFlowKHR);
     }
+    if (glslangIntermediate->getMaximallyReconverges()) {
+        builder.addExtension(spv::E_SPV_KHR_maximal_reconvergence);
+        builder.addExecutionMode(shaderEntry, spv::ExecutionModeMaximallyReconvergesKHR);
+    }
+
+    if (glslangIntermediate->getQuadDerivMode())
+    {
+        builder.addCapability(spv::CapabilityQuadControlKHR);
+        builder.addExtension(spv::E_SPV_KHR_quad_control);
+        builder.addExecutionMode(shaderEntry, spv::ExecutionModeQuadDerivativesKHR);
+    }
+
+    if (glslangIntermediate->getReqFullQuadsMode())
+    {
+        builder.addCapability(spv::CapabilityQuadControlKHR);
+        builder.addExtension(spv::E_SPV_KHR_quad_control);
+        builder.addExecutionMode(shaderEntry, spv::ExecutionModeRequireFullQuadsKHR);
+    }
 
     unsigned int mode;
     switch (glslangIntermediate->getStage()) {
@@ -2019,7 +2043,9 @@ void TGlslangToSpvTraverser::visitSymbol(glslang::TIntermSymbol* symbol)
 {
     // We update the line information even though no code might be generated here
     // This is helpful to yield correct lines for control flow instructions
-    builder.setLine(symbol->getLoc().line, symbol->getLoc().getFilename());
+    if (!linkageOnly) {
+        builder.setDebugSourceLocation(symbol->getLoc().line, symbol->getLoc().getFilename());
+    }
 
     SpecConstantOpModeGuard spec_constant_op_mode_setter(&builder);
     if (symbol->getType().isStruct())
@@ -2128,7 +2154,7 @@ void TGlslangToSpvTraverser::visitSymbol(glslang::TIntermSymbol* symbol)
 
 bool TGlslangToSpvTraverser::visitBinary(glslang::TVisit /* visit */, glslang::TIntermBinary* node)
 {
-    builder.setLine(node->getLoc().line, node->getLoc().getFilename());
+    builder.setDebugSourceLocation(node->getLoc().line, node->getLoc().getFilename());
     if (node->getLeft()->getAsSymbolNode() != nullptr && node->getLeft()->getType().isStruct()) {
         glslangTypeToIdMap[node->getLeft()->getType().getStruct()] = node->getLeft()->getAsSymbolNode()->getId();
     }
@@ -2173,7 +2199,7 @@ bool TGlslangToSpvTraverser::visitBinary(glslang::TVisit /* visit */, glslang::T
             spv::Id rValue = accessChainLoad(node->getRight()->getType());
 
             // reset line number for assignment
-            builder.setLine(node->getLoc().line, node->getLoc().getFilename());
+            builder.setDebugSourceLocation(node->getLoc().line, node->getLoc().getFilename());
 
             if (node->getOp() != glslang::EOpAssign) {
                 // the left is also an r-value
@@ -2506,7 +2532,7 @@ spv::Id TGlslangToSpvTraverser::translateForcedType(spv::Id object)
 
 bool TGlslangToSpvTraverser::visitUnary(glslang::TVisit /* visit */, glslang::TIntermUnary* node)
 {
-    builder.setLine(node->getLoc().line, node->getLoc().getFilename());
+    builder.setDebugSourceLocation(node->getLoc().line, node->getLoc().getFilename());
 
     SpecConstantOpModeGuard spec_constant_op_mode_setter(&builder);
     if (node->getType().getQualifier().isSpecConstant())
@@ -2670,7 +2696,7 @@ bool TGlslangToSpvTraverser::visitUnary(glslang::TVisit /* visit */, glslang::TI
     // if not, then possibly an operation
     if (! result)
         result = createUnaryOperation(node->getOp(), decorations, resultType(), operand,
-            node->getOperand()->getBasicType(), lvalueCoherentFlags);
+            node->getOperand()->getBasicType(), lvalueCoherentFlags, node->getType());
 
     // it could be attached to a SPIR-V intruction
     if (!result) {
@@ -2763,6 +2789,11 @@ bool TGlslangToSpvTraverser::visitUnary(glslang::TVisit /* visit */, glslang::TI
 
         return false;
 
+    case glslang::EOpAssumeEXT:
+        builder.addCapability(spv::CapabilityExpectAssumeKHR);
+        builder.addExtension(spv::E_SPV_KHR_expect_assume);
+        builder.createNoResultOp(spv::OpAssumeTrueKHR, operand);
+        return false;
     case glslang::EOpEmitStreamVertex:
         builder.createNoResultOp(spv::OpEmitStreamVertex, operand);
         return false;
@@ -2894,11 +2925,11 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt
                 return false;
             } else {
                 if (node->getOp() == glslang::EOpScope)
-                    builder.enterScope(0);
+                    builder.enterLexicalBlock(0);
             }
         } else {
             if (sequenceDepth > 1 && node->getOp() == glslang::EOpScope)
-                builder.leaveScope();
+                builder.leaveLexicalBlock();
             --sequenceDepth;
         }
 
@@ -2925,6 +2956,9 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt
     }
     case glslang::EOpFunction:
         if (visit == glslang::EvPreVisit) {
+            if (options.generateDebugInfo) {
+                builder.setDebugSourceLocation(node->getLoc().line, node->getLoc().getFilename());
+            }
             if (isShaderEntryPoint(node)) {
                 inEntryPoint = true;
                 builder.setBuildPoint(shaderEntry->getLastBlock());
@@ -2933,10 +2967,10 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt
             } else {
                 handleFunctionEntry(node);
             }
-            if (options.generateDebugInfo) {
+            if (options.generateDebugInfo && !options.emitNonSemanticShaderDebugInfo) {
                 const auto& loc = node->getLoc();
                 const char* sourceFileName = loc.getFilename();
-                spv::Id sourceFileId = sourceFileName ? builder.getStringId(sourceFileName) : builder.getSourceFile();
+                spv::Id sourceFileId = sourceFileName ? builder.getStringId(sourceFileName) : builder.getMainFileId();
                 currentFunction->setDebugLineInfo(sourceFileId, loc.line, loc.column);
             }
         } else {
@@ -2954,7 +2988,7 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt
         return false;
     case glslang::EOpFunctionCall:
     {
-        builder.setLine(node->getLoc().line, node->getLoc().getFilename());
+        builder.setDebugSourceLocation(node->getLoc().line, node->getLoc().getFilename());
         if (node->isUserDefined())
             result = handleUserFunctionCall(node);
         if (result) {
@@ -3020,7 +3054,7 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt
     case glslang::EOpConstructF16Mat4x3:
     case glslang::EOpConstructF16Mat4x4:
         isMatrix = true;
-        // fall through
+        [[fallthrough]];
     case glslang::EOpConstructFloat:
     case glslang::EOpConstructVec2:
     case glslang::EOpConstructVec3:
@@ -3075,7 +3109,7 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt
     case glslang::EOpConstructCooperativeMatrixNV:
     case glslang::EOpConstructCooperativeMatrixKHR:
     {
-        builder.setLine(node->getLoc().line, node->getLoc().getFilename());
+        builder.setDebugSourceLocation(node->getLoc().line, node->getLoc().getFilename());
         std::vector<spv::Id> arguments;
         translateArguments(*node, arguments, lvalueCoherentFlags);
         spv::Id constructed;
@@ -3191,7 +3225,7 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt
 
     case glslang::EOpAtomicStore:
         noReturnValue = true;
-        // fallthrough
+        [[fallthrough]];
     case glslang::EOpAtomicLoad:
         atomic = true;
         break;
@@ -3221,6 +3255,12 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt
         binOp = node->getOp();
         break;
 
+    case glslang::EOpExpectEXT:
+        builder.addCapability(spv::CapabilityExpectAssumeKHR);
+        builder.addExtension(spv::E_SPV_KHR_expect_assume);
+        binOp = node->getOp();
+        break;
+
     case glslang::EOpIgnoreIntersectionNV:
     case glslang::EOpTerminateRayNV:
     case glslang::EOpTraceNV:
@@ -3288,7 +3328,7 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt
     case glslang::EOpHitObjectRecordHitWithIndexMotionNV:
     case glslang::EOpReorderThreadNV:
         noReturnValue = true;
-        //Fallthrough
+        [[fallthrough]];
     case glslang::EOpHitObjectIsEmptyNV:
     case glslang::EOpHitObjectIsMissNV:
     case glslang::EOpHitObjectIsHitNV:
@@ -3331,6 +3371,20 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt
         builder.addExtension(spv::E_SPV_QCOM_image_processing);
         break;
 
+    case glslang::EOpImageBlockMatchWindowSSDQCOM:
+    case glslang::EOpImageBlockMatchWindowSADQCOM:
+        builder.addCapability(spv::CapabilityTextureBlockMatchQCOM);
+        builder.addExtension(spv::E_SPV_QCOM_image_processing);
+        builder.addCapability(spv::CapabilityTextureBlockMatch2QCOM);
+        builder.addExtension(spv::E_SPV_QCOM_image_processing2);
+        break;
+
+    case glslang::EOpImageBlockMatchGatherSSDQCOM:
+    case glslang::EOpImageBlockMatchGatherSADQCOM:
+        builder.addCapability(spv::CapabilityTextureBlockMatch2QCOM);
+        builder.addExtension(spv::E_SPV_QCOM_image_processing2);
+        break;
+
     case glslang::EOpFetchMicroTriangleVertexPositionNV:
     case glslang::EOpFetchMicroTriangleVertexBarycentricNV:
         builder.addExtension(spv::E_SPV_NV_displacement_micromap);
@@ -3361,7 +3415,7 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt
         right->traverse(this);
         spv::Id rightId = accessChainLoad(right->getType());
 
-        builder.setLine(node->getLoc().line, node->getLoc().getFilename());
+        builder.setDebugSourceLocation(node->getLoc().line, node->getLoc().getFilename());
         OpDecorations decorations = { precision,
                                       TranslateNoContractionDecoration(node->getType().getQualifier()),
                                       TranslateNonUniformDecoration(node->getType().getQualifier()) };
@@ -3596,7 +3650,7 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt
             lvalueCoherentFlags = builder.getAccessChain().coherentFlags;
             lvalueCoherentFlags |= TranslateCoherent(glslangOperands[arg]->getAsTyped()->getType());
         } else {
-            builder.setLine(node->getLoc().line, node->getLoc().getFilename());
+            builder.setDebugSourceLocation(node->getLoc().line, node->getLoc().getFilename());
              glslang::TOperator glslangOp = node->getOp();
              if (arg == 1 &&
                 (glslangOp == glslang::EOpRayQueryGetIntersectionType ||
@@ -3648,7 +3702,7 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt
         }
     }
 
-    builder.setLine(node->getLoc().line, node->getLoc().getFilename());
+    builder.setDebugSourceLocation(node->getLoc().line, node->getLoc().getFilename());
     if (node->getOp() == glslang::EOpCooperativeMatrixLoad ||
         node->getOp() == glslang::EOpCooperativeMatrixLoadNV) {
         std::vector<spv::IdImmediate> idImmOps;
@@ -3739,7 +3793,7 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt
         glslang::TBasicType typeProxy = (node->getOp() == glslang::EOpAtomicStore)
             ? node->getSequence()[0]->getAsTyped()->getBasicType() : node->getBasicType();
         result = createAtomicOperation(node->getOp(), precision, resultType(), operands, typeProxy,
-            lvalueCoherentFlags);
+            lvalueCoherentFlags, node->getType());
     } else if (node->getOp() == glslang::EOpSpirvInst) {
         const auto& spirvInst = node->getSpirvInstruction();
         if (spirvInst.set == "") {
@@ -3786,7 +3840,7 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt
                 result = createUnaryOperation(
                     node->getOp(), decorations,
                     resultType(), operands.front(),
-                    glslangOperands[0]->getAsTyped()->getBasicType(), lvalueCoherentFlags);
+                    glslangOperands[0]->getAsTyped()->getBasicType(), lvalueCoherentFlags, node->getType());
             }
             break;
         default:
@@ -3888,7 +3942,7 @@ bool TGlslangToSpvTraverser::visitSelection(glslang::TVisit /* visit */, glslang
         node->getFalseBlock()->traverse(this);
         spv::Id falseValue = accessChainLoad(node->getFalseBlock()->getAsTyped()->getType());
 
-        builder.setLine(node->getLoc().line, node->getLoc().getFilename());
+        builder.setDebugSourceLocation(node->getLoc().line, node->getLoc().getFilename());
 
         // done if void
         if (node->getBasicType() == glslang::EbtVoid)
@@ -4096,7 +4150,7 @@ bool TGlslangToSpvTraverser::visitLoop(glslang::TVisit /* visit */, glslang::TIn
     // instructions in it, since the body/test may have arbitrary instructions,
     // including merges of its own.
     builder.setBuildPoint(&blocks.head);
-    builder.setLine(node->getLoc().line, node->getLoc().getFilename());
+    builder.setDebugSourceLocation(node->getLoc().line, node->getLoc().getFilename());
     builder.createLoopMerge(&blocks.merge, &blocks.continue_target, control, operands);
     if (node->testFirst() && node->getTest()) {
         spv::Block& test = builder.makeNewBlock();
@@ -4119,7 +4173,7 @@ bool TGlslangToSpvTraverser::visitLoop(glslang::TVisit /* visit */, glslang::TIn
             node->getTerminal()->traverse(this);
         builder.createBranch(&blocks.head);
     } else {
-        builder.setLine(node->getLoc().line, node->getLoc().getFilename());
+        builder.setDebugSourceLocation(node->getLoc().line, node->getLoc().getFilename());
         builder.createBranch(&blocks.body);
 
         breakForLoop.push(true);
@@ -4154,7 +4208,7 @@ bool TGlslangToSpvTraverser::visitBranch(glslang::TVisit /* visit */, glslang::T
     if (node->getExpression())
         node->getExpression()->traverse(this);
 
-    builder.setLine(node->getLoc().line, node->getLoc().getFilename());
+    builder.setDebugSourceLocation(node->getLoc().line, node->getLoc().getFilename());
 
     switch (node->getFlowOp()) {
     case glslang::EOpKill:
@@ -5738,7 +5792,7 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO
     if (! node->isImage() && ! node->isTexture())
         return spv::NoResult;
 
-    builder.setLine(node->getLoc().line, node->getLoc().getFilename());
+    builder.setDebugSourceLocation(node->getLoc().line, node->getLoc().getFilename());
 
     // Process a GLSL texturing op (will be SPV image)
 
@@ -6041,7 +6095,7 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO
                 operands.push_back(*opIt);
 
             return createAtomicOperation(node->getOp(), precision, resultType(), operands, typeProxy,
-                lvalueCoherentFlags);
+                lvalueCoherentFlags, node->getType());
         }
     }
 
@@ -6566,6 +6620,10 @@ spv::Id TGlslangToSpvTraverser::createBinaryOperation(glslang::TOperator op, OpD
         binOp = isUnsigned ? spv::OpUMul32x16INTEL : spv::OpIMul32x16INTEL;
         break;
 
+    case glslang::EOpExpectEXT:
+        binOp = spv::OpExpectKHR;
+        break;
+
     case glslang::EOpLessThan:
     case glslang::EOpGreaterThan:
     case glslang::EOpLessThanEqual:
@@ -6788,7 +6846,8 @@ spv::Id TGlslangToSpvTraverser::createBinaryMatrixOperation(spv::Op op, OpDecora
 }
 
 spv::Id TGlslangToSpvTraverser::createUnaryOperation(glslang::TOperator op, OpDecorations& decorations, spv::Id typeId,
-    spv::Id operand, glslang::TBasicType typeProxy, const spv::Builder::AccessChain::CoherentFlags &lvalueCoherentFlags)
+    spv::Id operand, glslang::TBasicType typeProxy, const spv::Builder::AccessChain::CoherentFlags &lvalueCoherentFlags,
+    const glslang::TType &opType)
 {
     spv::Op unaryOp = spv::OpNop;
     int extBuiltins = -1;
@@ -7076,7 +7135,7 @@ spv::Id TGlslangToSpvTraverser::createUnaryOperation(glslang::TOperator op, OpDe
         // Handle all of the atomics in one place, in createAtomicOperation()
         std::vector<spv::Id> operands;
         operands.push_back(operand);
-        return createAtomicOperation(op, decorations.precision, typeId, operands, typeProxy, lvalueCoherentFlags);
+        return createAtomicOperation(op, decorations.precision, typeId, operands, typeProxy, lvalueCoherentFlags, opType);
     }
 
     case glslang::EOpBitFieldReverse:
@@ -7169,7 +7228,9 @@ spv::Id TGlslangToSpvTraverser::createUnaryOperation(glslang::TOperator op, OpDe
     case glslang::EOpSubgroupExclusiveXor:
     case glslang::EOpSubgroupQuadSwapHorizontal:
     case glslang::EOpSubgroupQuadSwapVertical:
-    case glslang::EOpSubgroupQuadSwapDiagonal: {
+    case glslang::EOpSubgroupQuadSwapDiagonal:
+    case glslang::EOpSubgroupQuadAll:
+    case glslang::EOpSubgroupQuadAny: {
         std::vector<spv::Id> operands;
         operands.push_back(operand);
         return createSubgroupOperation(op, typeId, operands, typeProxy);
@@ -7792,7 +7853,7 @@ spv::Id TGlslangToSpvTraverser::makeSmearedConstant(spv::Id constant, int vector
 // For glslang ops that map to SPV atomic opCodes
 spv::Id TGlslangToSpvTraverser::createAtomicOperation(glslang::TOperator op, spv::Decoration /*precision*/,
     spv::Id typeId, std::vector<spv::Id>& operands, glslang::TBasicType typeProxy,
-    const spv::Builder::AccessChain::CoherentFlags &lvalueCoherentFlags)
+    const spv::Builder::AccessChain::CoherentFlags &lvalueCoherentFlags, const glslang::TType &opType)
 {
     spv::Op opCode = spv::OpNop;
 
@@ -7803,14 +7864,20 @@ spv::Id TGlslangToSpvTraverser::createAtomicOperation(glslang::TOperator op, spv
         opCode = spv::OpAtomicIAdd;
         if (typeProxy == glslang::EbtFloat16 || typeProxy == glslang::EbtFloat || typeProxy == glslang::EbtDouble) {
             opCode = spv::OpAtomicFAddEXT;
-            builder.addExtension(spv::E_SPV_EXT_shader_atomic_float_add);
-            if (typeProxy == glslang::EbtFloat16) {
-                builder.addExtension(spv::E_SPV_EXT_shader_atomic_float16_add);
-                builder.addCapability(spv::CapabilityAtomicFloat16AddEXT);
-            } else if (typeProxy == glslang::EbtFloat) {
-                builder.addCapability(spv::CapabilityAtomicFloat32AddEXT);
+            if (typeProxy == glslang::EbtFloat16 &&
+                (opType.getVectorSize() == 2 || opType.getVectorSize() == 4)) {
+                builder.addExtension(spv::E_SPV_NV_shader_atomic_fp16_vector);
+                builder.addCapability(spv::CapabilityAtomicFloat16VectorNV);
             } else {
-                builder.addCapability(spv::CapabilityAtomicFloat64AddEXT);
+                builder.addExtension(spv::E_SPV_EXT_shader_atomic_float_add);
+                if (typeProxy == glslang::EbtFloat16) {
+                    builder.addExtension(spv::E_SPV_EXT_shader_atomic_float16_add);
+                    builder.addCapability(spv::CapabilityAtomicFloat16AddEXT);
+                } else if (typeProxy == glslang::EbtFloat) {
+                    builder.addCapability(spv::CapabilityAtomicFloat32AddEXT);
+                } else {
+                    builder.addCapability(spv::CapabilityAtomicFloat64AddEXT);
+                }
             }
         }
         break;
@@ -7823,13 +7890,19 @@ spv::Id TGlslangToSpvTraverser::createAtomicOperation(glslang::TOperator op, spv
     case glslang::EOpAtomicCounterMin:
         if (typeProxy == glslang::EbtFloat16 || typeProxy == glslang::EbtFloat || typeProxy == glslang::EbtDouble) {
             opCode = spv::OpAtomicFMinEXT;
-            builder.addExtension(spv::E_SPV_EXT_shader_atomic_float_min_max);
-            if (typeProxy == glslang::EbtFloat16)
-                builder.addCapability(spv::CapabilityAtomicFloat16MinMaxEXT);
-            else if (typeProxy == glslang::EbtFloat)
-                builder.addCapability(spv::CapabilityAtomicFloat32MinMaxEXT);
-            else
-                builder.addCapability(spv::CapabilityAtomicFloat64MinMaxEXT);
+            if (typeProxy == glslang::EbtFloat16 &&
+                (opType.getVectorSize() == 2 || opType.getVectorSize() == 4)) {
+                builder.addExtension(spv::E_SPV_NV_shader_atomic_fp16_vector);
+                builder.addCapability(spv::CapabilityAtomicFloat16VectorNV);
+            } else {
+                builder.addExtension(spv::E_SPV_EXT_shader_atomic_float_min_max);
+                if (typeProxy == glslang::EbtFloat16)
+                    builder.addCapability(spv::CapabilityAtomicFloat16MinMaxEXT);
+                else if (typeProxy == glslang::EbtFloat)
+                    builder.addCapability(spv::CapabilityAtomicFloat32MinMaxEXT);
+                else
+                    builder.addCapability(spv::CapabilityAtomicFloat64MinMaxEXT);
+            }
         } else if (typeProxy == glslang::EbtUint || typeProxy == glslang::EbtUint64) {
             opCode = spv::OpAtomicUMin;
         } else {
@@ -7841,13 +7914,19 @@ spv::Id TGlslangToSpvTraverser::createAtomicOperation(glslang::TOperator op, spv
     case glslang::EOpAtomicCounterMax:
         if (typeProxy == glslang::EbtFloat16 || typeProxy == glslang::EbtFloat || typeProxy == glslang::EbtDouble) {
             opCode = spv::OpAtomicFMaxEXT;
-            builder.addExtension(spv::E_SPV_EXT_shader_atomic_float_min_max);
-            if (typeProxy == glslang::EbtFloat16)
-                builder.addCapability(spv::CapabilityAtomicFloat16MinMaxEXT);
-            else if (typeProxy == glslang::EbtFloat)
-                builder.addCapability(spv::CapabilityAtomicFloat32MinMaxEXT);
-            else
-                builder.addCapability(spv::CapabilityAtomicFloat64MinMaxEXT);
+            if (typeProxy == glslang::EbtFloat16 &&
+                (opType.getVectorSize() == 2 || opType.getVectorSize() == 4)) {
+                builder.addExtension(spv::E_SPV_NV_shader_atomic_fp16_vector);
+                builder.addCapability(spv::CapabilityAtomicFloat16VectorNV);
+            } else {
+                builder.addExtension(spv::E_SPV_EXT_shader_atomic_float_min_max);
+                if (typeProxy == glslang::EbtFloat16)
+                    builder.addCapability(spv::CapabilityAtomicFloat16MinMaxEXT);
+                else if (typeProxy == glslang::EbtFloat)
+                    builder.addCapability(spv::CapabilityAtomicFloat32MinMaxEXT);
+                else
+                    builder.addCapability(spv::CapabilityAtomicFloat64MinMaxEXT);
+            }
         } else if (typeProxy == glslang::EbtUint || typeProxy == glslang::EbtUint64) {
             opCode = spv::OpAtomicUMax;
         } else {
@@ -7872,6 +7951,12 @@ spv::Id TGlslangToSpvTraverser::createAtomicOperation(glslang::TOperator op, spv
     case glslang::EOpAtomicExchange:
     case glslang::EOpImageAtomicExchange:
     case glslang::EOpAtomicCounterExchange:
+        if ((typeProxy == glslang::EbtFloat16) && 
+            (opType.getVectorSize() == 2 || opType.getVectorSize() == 4)) {
+                builder.addExtension(spv::E_SPV_NV_shader_atomic_fp16_vector);
+                builder.addCapability(spv::CapabilityAtomicFloat16VectorNV);
+        }
+
         opCode = spv::OpAtomicExchange;
         break;
     case glslang::EOpAtomicCompSwap:
@@ -8274,6 +8359,11 @@ spv::Id TGlslangToSpvTraverser::createSubgroupOperation(glslang::TOperator op, s
     case glslang::EOpSubgroupElect:
         builder.addCapability(spv::CapabilityGroupNonUniform);
         break;
+    case glslang::EOpSubgroupQuadAll:
+    case glslang::EOpSubgroupQuadAny:
+        builder.addExtension(spv::E_SPV_KHR_quad_control);
+        builder.addCapability(spv::CapabilityQuadControlKHR);
+        [[fallthrough]];
     case glslang::EOpSubgroupAll:
     case glslang::EOpSubgroupAny:
     case glslang::EOpSubgroupAllEqual:
@@ -8293,6 +8383,11 @@ spv::Id TGlslangToSpvTraverser::createSubgroupOperation(glslang::TOperator op, s
         builder.addCapability(spv::CapabilityGroupNonUniform);
         builder.addCapability(spv::CapabilityGroupNonUniformBallot);
         break;
+    case glslang::EOpSubgroupRotate:
+    case glslang::EOpSubgroupClusteredRotate:
+        builder.addExtension(spv::E_SPV_KHR_subgroup_rotate);
+        builder.addCapability(spv::CapabilityGroupNonUniformRotateKHR);
+        break;
     case glslang::EOpSubgroupShuffle:
     case glslang::EOpSubgroupShuffleXor:
         builder.addCapability(spv::CapabilityGroupNonUniform);
@@ -8381,7 +8476,9 @@ spv::Id TGlslangToSpvTraverser::createSubgroupOperation(glslang::TOperator op, s
     // Figure out which opcode to use.
     switch (op) {
     case glslang::EOpSubgroupElect:                   opCode = spv::OpGroupNonUniformElect; break;
+    case glslang::EOpSubgroupQuadAll:                 opCode = spv::OpGroupNonUniformQuadAllKHR; break;
     case glslang::EOpSubgroupAll:                     opCode = spv::OpGroupNonUniformAll; break;
+    case glslang::EOpSubgroupQuadAny:                 opCode = spv::OpGroupNonUniformQuadAnyKHR; break;
     case glslang::EOpSubgroupAny:                     opCode = spv::OpGroupNonUniformAny; break;
     case glslang::EOpSubgroupAllEqual:                opCode = spv::OpGroupNonUniformAllEqual; break;
     case glslang::EOpSubgroupBroadcast:               opCode = spv::OpGroupNonUniformBroadcast; break;
@@ -8398,6 +8495,8 @@ spv::Id TGlslangToSpvTraverser::createSubgroupOperation(glslang::TOperator op, s
     case glslang::EOpSubgroupShuffleXor:              opCode = spv::OpGroupNonUniformShuffleXor; break;
     case glslang::EOpSubgroupShuffleUp:               opCode = spv::OpGroupNonUniformShuffleUp; break;
     case glslang::EOpSubgroupShuffleDown:             opCode = spv::OpGroupNonUniformShuffleDown; break;
+    case glslang::EOpSubgroupRotate:
+    case glslang::EOpSubgroupClusteredRotate:         opCode = spv::OpGroupNonUniformRotateKHR; break;
     case glslang::EOpSubgroupAdd:
     case glslang::EOpSubgroupInclusiveAdd:
     case glslang::EOpSubgroupExclusiveAdd:
@@ -8578,7 +8677,10 @@ spv::Id TGlslangToSpvTraverser::createSubgroupOperation(glslang::TOperator op, s
 
     // Every operation begins with the Execution Scope operand.
     spv::IdImmediate executionScope = { true, builder.makeUintConstant(spv::ScopeSubgroup) };
-    spvGroupOperands.push_back(executionScope);
+    // All other ops need the execution scope. Quad Control Ops don't need scope, it's always Quad.
+    if (opCode != spv::OpGroupNonUniformQuadAllKHR && opCode != spv::OpGroupNonUniformQuadAnyKHR) {
+        spvGroupOperands.push_back(executionScope);
+    }
 
     // Next, for all operations that use a Group Operation, push that as an operand.
     if (groupOperation != spv::GroupOperationMax) {
@@ -8821,6 +8923,8 @@ spv::Id TGlslangToSpvTraverser::createMiscOperation(glslang::TOperator op, spv::
     case glslang::EOpSubgroupShuffleXor:
     case glslang::EOpSubgroupShuffleUp:
     case glslang::EOpSubgroupShuffleDown:
+    case glslang::EOpSubgroupRotate:
+    case glslang::EOpSubgroupClusteredRotate:
     case glslang::EOpSubgroupClusteredAdd:
     case glslang::EOpSubgroupClusteredMul:
     case glslang::EOpSubgroupClusteredMin:
@@ -9179,6 +9283,30 @@ spv::Id TGlslangToSpvTraverser::createMiscOperation(glslang::TOperator op, spv::
         opCode = spv::OpFetchMicroTriangleVertexPositionNV;
         break;
 
+    case glslang::EOpImageBlockMatchWindowSSDQCOM:
+        typeId = builder.makeVectorType(builder.makeFloatType(32), 4);
+        opCode = spv::OpImageBlockMatchWindowSSDQCOM;
+        addImageProcessing2QCOMDecoration(operands[0], false);
+        addImageProcessing2QCOMDecoration(operands[2], false);
+        break;
+    case glslang::EOpImageBlockMatchWindowSADQCOM:
+        typeId = builder.makeVectorType(builder.makeFloatType(32), 4);
+        opCode = spv::OpImageBlockMatchWindowSADQCOM;
+        addImageProcessing2QCOMDecoration(operands[0], false);
+        addImageProcessing2QCOMDecoration(operands[2], false);
+        break;
+    case glslang::EOpImageBlockMatchGatherSSDQCOM:
+        typeId = builder.makeVectorType(builder.makeFloatType(32), 4);
+        opCode = spv::OpImageBlockMatchGatherSSDQCOM;
+        addImageProcessing2QCOMDecoration(operands[0], true);
+        addImageProcessing2QCOMDecoration(operands[2], true);
+        break;
+    case glslang::EOpImageBlockMatchGatherSADQCOM:
+        typeId = builder.makeVectorType(builder.makeFloatType(32), 4);
+        opCode = spv::OpImageBlockMatchGatherSADQCOM;
+        addImageProcessing2QCOMDecoration(operands[0], true);
+        addImageProcessing2QCOMDecoration(operands[2], true);
+        break;
     default:
         return 0;
     }
@@ -9699,6 +9827,36 @@ void TGlslangToSpvTraverser::addImageProcessingQCOMDecoration(spv::Id id, spv::D
   }
 }
 
+void TGlslangToSpvTraverser::addImageProcessing2QCOMDecoration(spv::Id id, bool isForGather)
+{
+  if (isForGather) {
+    return addImageProcessingQCOMDecoration(id, spv::DecorationBlockMatchTextureQCOM);
+  }
+
+  auto addDecor =
+    [this](spv::Id id, spv::Decoration decor) {
+      spv::Id tsopc = this->builder.getOpCode(id);
+      if (tsopc == spv::OpLoad) {
+        spv::Id tsid = this->builder.getIdOperand(id, 0);
+        if (this->glslangIntermediate->getSpv().spv >= glslang::EShTargetSpv_1_4) {
+          assert(iOSet.count(tsid) > 0);
+        }
+        this->builder.addDecoration(tsid, decor);
+      }
+    };
+
+  spv::Id opc = builder.getOpCode(id);
+  bool isInterfaceObject = (opc != spv::OpSampledImage);
+
+  if (!isInterfaceObject) {
+    addDecor(builder.getIdOperand(id, 0), spv::DecorationBlockMatchTextureQCOM);
+    addDecor(builder.getIdOperand(id, 1), spv::DecorationBlockMatchSamplerQCOM);
+  } else {
+    addDecor(id, spv::DecorationBlockMatchTextureQCOM);
+    addDecor(id, spv::DecorationBlockMatchSamplerQCOM);
+  }
+}
+
 // Make a full tree of instructions to build a SPIR-V specialization constant,
 // or regular constant if possible.
 //
@@ -10064,7 +10222,6 @@ spv::Id TGlslangToSpvTraverser::getExtBuiltins(const char* name)
     if (extBuiltinMap.find(name) != extBuiltinMap.end())
         return extBuiltinMap[name];
     else {
-        builder.addExtension(name);
         spv::Id extBuiltins = builder.import(name);
         extBuiltinMap[name] = extBuiltins;
         return extBuiltins;

+ 115 - 151
src/libraries/glslang/SPIRV/SpvBuilder.cpp

@@ -58,13 +58,6 @@ Builder::Builder(unsigned int spvVersion, unsigned int magicNumber, SpvBuildLogg
     spvVersion(spvVersion),
     sourceLang(SourceLanguageUnknown),
     sourceVersion(0),
-    sourceFileStringId(NoResult),
-    currentLine(0),
-    currentFile(nullptr),
-    currentFileId(NoResult),
-    lastDebugScopeId(NoResult),
-    emitOpLines(false),
-    emitNonSemanticShaderDebugInfo(false),
     addressModel(AddressingModelLogical),
     memoryModel(MemoryModelGLSL450),
     builderNumber(magicNumber),
@@ -91,78 +84,6 @@ Id Builder::import(const char* name)
     return import->getResultId();
 }
 
-// Emit instruction for non-filename-based #line directives (ie. no filename
-// seen yet): emit an OpLine if we've been asked to emit OpLines and the line
-// number has changed since the last time, and is a valid line number.
-void Builder::setLine(int lineNum)
-{
-    if (lineNum != 0 && lineNum != currentLine) {
-        currentLine = lineNum;
-        if (emitOpLines) {
-          if (emitNonSemanticShaderDebugInfo)
-              addDebugScopeAndLine(currentFileId, currentLine, 0);
-          else
-              addLine(sourceFileStringId, currentLine, 0);
-        }
-    }
-}
-
-// If no filename, do non-filename-based #line emit. Else do filename-based emit.
-// Emit OpLine if we've been asked to emit OpLines and the line number or filename
-// has changed since the last time, and line number is valid.
-void Builder::setLine(int lineNum, const char* filename)
-{
-    if (filename == nullptr) {
-        setLine(lineNum);
-        return;
-    }
-    if ((lineNum != 0 && lineNum != currentLine) || currentFile == nullptr ||
-            strncmp(filename, currentFile, strlen(currentFile) + 1) != 0) {
-        currentLine = lineNum;
-        currentFile = filename;
-        if (emitOpLines) {
-            spv::Id strId = getStringId(filename);
-            if (emitNonSemanticShaderDebugInfo)
-                addDebugScopeAndLine(strId, currentLine, 0);
-            else
-                addLine(strId, currentLine, 0);
-        }
-    }
-}
-
-void Builder::addLine(Id fileName, int lineNum, int column)
-{
-    Instruction* line = new Instruction(OpLine);
-    line->addIdOperand(fileName);
-    line->addImmediateOperand(lineNum);
-    line->addImmediateOperand(column);
-    buildPoint->addInstruction(std::unique_ptr<Instruction>(line));
-}
-
-void Builder::addDebugScopeAndLine(Id fileName, int lineNum, int column)
-{
-    assert(!currentDebugScopeId.empty());
-    if (currentDebugScopeId.top() != lastDebugScopeId) {
-        spv::Id resultId = getUniqueId();
-        Instruction* scopeInst = new Instruction(resultId, makeVoidType(), OpExtInst);
-        scopeInst->addIdOperand(nonSemanticShaderDebugInfo);
-        scopeInst->addImmediateOperand(NonSemanticShaderDebugInfo100DebugScope);
-        scopeInst->addIdOperand(currentDebugScopeId.top());
-        buildPoint->addInstruction(std::unique_ptr<Instruction>(scopeInst));
-        lastDebugScopeId = currentDebugScopeId.top();
-    }
-    spv::Id resultId = getUniqueId();
-    Instruction* lineInst = new Instruction(resultId, makeVoidType(), OpExtInst);
-    lineInst->addIdOperand(nonSemanticShaderDebugInfo);
-    lineInst->addImmediateOperand(NonSemanticShaderDebugInfo100DebugLine);
-    lineInst->addIdOperand(makeDebugSource(fileName));
-    lineInst->addIdOperand(makeUintConstant(lineNum));
-    lineInst->addIdOperand(makeUintConstant(lineNum));
-    lineInst->addIdOperand(makeUintConstant(column));
-    lineInst->addIdOperand(makeUintConstant(column));
-    buildPoint->addInstruction(std::unique_ptr<Instruction>(lineInst));
-}
-
 // For creating new groupedTypes (will return old type if the requested one was already made).
 Id Builder::makeVoidType()
 {
@@ -1011,7 +932,7 @@ Id Builder::makeMemberDebugType(Id const memberType, DebugTypeLoc const& debugTy
     type->addImmediateOperand(NonSemanticShaderDebugInfo100DebugTypeMember);
     type->addIdOperand(getStringId(debugTypeLoc.name)); // name id
     type->addIdOperand(debugId[memberType]); // type id
-    type->addIdOperand(makeDebugSource(sourceFileStringId)); // source id TODO: verify this works across include directives
+    type->addIdOperand(makeDebugSource(currentFileId)); // source id
     type->addIdOperand(makeUintConstant(debugTypeLoc.line)); // line id TODO: currentLine is always zero
     type->addIdOperand(makeUintConstant(debugTypeLoc.column)); // TODO: column id
     type->addIdOperand(makeUintConstant(0)); // TODO: offset id
@@ -1050,7 +971,7 @@ Id Builder::makeCompositeDebugType(std::vector<Id> const& memberTypes, char cons
     type->addImmediateOperand(NonSemanticShaderDebugInfo100DebugTypeComposite);
     type->addIdOperand(getStringId(name)); // name id
     type->addIdOperand(makeUintConstant(tag)); // tag id
-    type->addIdOperand(makeDebugSource(sourceFileStringId)); // source id TODO: verify this works across include directives
+    type->addIdOperand(makeDebugSource(currentFileId)); // source id
     type->addIdOperand(makeUintConstant(currentLine)); // line id TODO: currentLine always zero?
     type->addIdOperand(makeUintConstant(0)); // TODO: column id
     type->addIdOperand(makeDebugCompilationUnit()); // scope id
@@ -1113,14 +1034,19 @@ Id Builder::makeDebugSource(const Id fileName) {
     sourceInst->addIdOperand(fileName);
     if (emitNonSemanticShaderDebugSource) {
         spv::Id sourceId = 0;
-        if (fileName == sourceFileStringId) {
+        if (fileName == mainFileId) {
             sourceId = getStringId(sourceText);
         } else {
             auto incItr = includeFiles.find(fileName);
-            assert(incItr != includeFiles.end());
-            sourceId = getStringId(*incItr->second);
+            if (incItr != includeFiles.end()) {
+                sourceId = getStringId(*incItr->second);
+            }
+        }
+
+        // We omit the optional source text item if not available in glslang
+        if (sourceId != 0) {
+            sourceInst->addIdOperand(sourceId);
         }
-        sourceInst->addIdOperand(sourceId);
     }
     constantsTypesGlobals.push_back(std::unique_ptr<Instruction>(sourceInst));
     module.mapInstruction(sourceInst);
@@ -1137,7 +1063,7 @@ Id Builder::makeDebugCompilationUnit() {
     sourceInst->addImmediateOperand(NonSemanticShaderDebugInfo100DebugCompilationUnit);
     sourceInst->addIdOperand(makeUintConstant(1)); // TODO(greg-lunarg): Get rid of magic number
     sourceInst->addIdOperand(makeUintConstant(4)); // TODO(greg-lunarg): Get rid of magic number
-    sourceInst->addIdOperand(makeDebugSource(sourceFileStringId));
+    sourceInst->addIdOperand(makeDebugSource(mainFileId));
     sourceInst->addIdOperand(makeUintConstant(sourceLang));
     constantsTypesGlobals.push_back(std::unique_ptr<Instruction>(sourceInst));
     module.mapInstruction(sourceInst);
@@ -1160,7 +1086,7 @@ Id Builder::createDebugGlobalVariable(Id const type, char const*const name, Id c
     inst->addImmediateOperand(NonSemanticShaderDebugInfo100DebugGlobalVariable);
     inst->addIdOperand(getStringId(name)); // name id
     inst->addIdOperand(type); // type id
-    inst->addIdOperand(makeDebugSource(sourceFileStringId)); // source id
+    inst->addIdOperand(makeDebugSource(currentFileId)); // source id
     inst->addIdOperand(makeUintConstant(currentLine)); // line id TODO: currentLine always zero?
     inst->addIdOperand(makeUintConstant(0)); // TODO: column id
     inst->addIdOperand(makeDebugCompilationUnit()); // scope id
@@ -1184,7 +1110,7 @@ Id Builder::createDebugLocalVariable(Id type, char const*const name, size_t cons
     inst->addImmediateOperand(NonSemanticShaderDebugInfo100DebugLocalVariable);
     inst->addIdOperand(getStringId(name)); // name id
     inst->addIdOperand(type); // type id
-    inst->addIdOperand(makeDebugSource(sourceFileStringId)); // source id
+    inst->addIdOperand(makeDebugSource(currentFileId)); // source id
     inst->addIdOperand(makeUintConstant(currentLine)); // line id
     inst->addIdOperand(makeUintConstant(0)); // TODO: column id
     inst->addIdOperand(currentDebugScopeId.top()); // scope id
@@ -1224,7 +1150,7 @@ Id Builder::makeDebugDeclare(Id const debugLocalVariable, Id const pointer)
     inst->addIdOperand(debugLocalVariable); // debug local variable id
     inst->addIdOperand(pointer); // pointer to local variable id
     inst->addIdOperand(makeDebugExpression()); // expression id
-    buildPoint->addInstruction(std::unique_ptr<Instruction>(inst));
+    addInstruction(std::unique_ptr<Instruction>(inst));
 
     return inst->getResultId();
 }
@@ -1237,7 +1163,7 @@ Id Builder::makeDebugValue(Id const debugLocalVariable, Id const value)
     inst->addIdOperand(debugLocalVariable); // debug local variable id
     inst->addIdOperand(value); // value of local variable id
     inst->addIdOperand(makeDebugExpression()); // expression id
-    buildPoint->addInstruction(std::unique_ptr<Instruction>(inst));
+    addInstruction(std::unique_ptr<Instruction>(inst));
 
     return inst->getResultId();
 }
@@ -1250,6 +1176,10 @@ Id Builder::makeAccelerationStructureType()
         groupedTypes[OpTypeAccelerationStructureKHR].push_back(type);
         constantsTypesGlobals.push_back(std::unique_ptr<Instruction>(type));
         module.mapInstruction(type);
+        if (emitNonSemanticShaderDebugInfo) {
+            spv::Id debugType = makeCompositeDebugType({}, "accelerationStructure", NonSemanticShaderDebugInfo100Structure, true);
+            debugId[type->getResultId()] = debugType;
+        }
     } else {
         type = groupedTypes[OpTypeAccelerationStructureKHR].back();
     }
@@ -1265,6 +1195,10 @@ Id Builder::makeRayQueryType()
         groupedTypes[OpTypeRayQueryKHR].push_back(type);
         constantsTypesGlobals.push_back(std::unique_ptr<Instruction>(type));
         module.mapInstruction(type);
+        if (emitNonSemanticShaderDebugInfo) {
+            spv::Id debugType = makeCompositeDebugType({}, "rayQuery", NonSemanticShaderDebugInfo100Structure, true);
+            debugId[type->getResultId()] = debugType;
+        }
     } else {
         type = groupedTypes[OpTypeRayQueryKHR].back();
     }
@@ -1550,17 +1484,6 @@ bool Builder::isSpecConstantOpCode(Op opcode) const
     }
 }
 
-bool Builder::isRayTracingOpCode(Op opcode) const
-{
-    switch (opcode) {
-    case OpTypeAccelerationStructureKHR:
-    case OpTypeRayQueryKHR:
-        return true;
-    default:
-        return false;
-    }
-}
-
 Id Builder::makeNullConstant(Id typeId)
 {
     Instruction* constant;
@@ -2103,6 +2026,49 @@ void Builder::addMemberDecoration(Id id, unsigned int member, Decoration decorat
     decorations.push_back(std::unique_ptr<Instruction>(dec));
 }
 
+void Builder::addInstruction(std::unique_ptr<Instruction> inst) {
+    // Optionally insert OpDebugScope
+    if (emitNonSemanticShaderDebugInfo && dirtyScopeTracker) {
+        if (buildPoint->updateDebugScope(currentDebugScopeId.top())) {
+            auto scopeInst = std::make_unique<Instruction>(getUniqueId(), makeVoidType(), OpExtInst);
+            scopeInst->addIdOperand(nonSemanticShaderDebugInfo);
+            scopeInst->addImmediateOperand(NonSemanticShaderDebugInfo100DebugScope);
+            scopeInst->addIdOperand(currentDebugScopeId.top());
+            buildPoint->addInstruction(std::move(scopeInst));
+        }
+
+        dirtyScopeTracker = false;
+    }
+
+    // Insert OpLine/OpDebugLine if the debug source location has changed
+    if (trackDebugInfo && dirtyLineTracker) {
+        if (buildPoint->updateDebugSourceLocation(currentLine, 0, currentFileId)) {
+            if (emitSpirvDebugInfo) {
+                auto lineInst = std::make_unique<Instruction>(OpLine);
+                lineInst->addIdOperand(currentFileId);
+                lineInst->addImmediateOperand(currentLine);
+                lineInst->addImmediateOperand(0);
+                buildPoint->addInstruction(std::move(lineInst));
+            }
+            if (emitNonSemanticShaderDebugInfo) {
+                auto lineInst = std::make_unique<Instruction>(getUniqueId(), makeVoidType(), OpExtInst);
+                lineInst->addIdOperand(nonSemanticShaderDebugInfo);
+                lineInst->addImmediateOperand(NonSemanticShaderDebugInfo100DebugLine);
+                lineInst->addIdOperand(makeDebugSource(currentFileId));
+                lineInst->addIdOperand(makeUintConstant(currentLine));
+                lineInst->addIdOperand(makeUintConstant(currentLine));
+                lineInst->addIdOperand(makeUintConstant(0));
+                lineInst->addIdOperand(makeUintConstant(0));
+                buildPoint->addInstruction(std::move(lineInst));
+            }
+        }
+
+        dirtyLineTracker = false;
+    }
+
+    buildPoint->addInstruction(std::move(inst));
+}
+
 // Comments in header
 Function* Builder::makeEntryPoint(const char* entryPoint)
 {
@@ -2146,7 +2112,7 @@ Function* Builder::makeFunctionEntry(Decoration precision, Id returnType, const
 
     // reset last debug scope
     if (emitNonSemanticShaderDebugInfo) {
-        lastDebugScopeId = NoResult;
+        dirtyScopeTracker = true;
     }
 
     // CFG
@@ -2186,8 +2152,6 @@ void Builder::setupDebugFunctionEntry(Function* function, const char* name, int
     // DebugScope and DebugLine for parameter DebugDeclares
     assert(paramTypes.size() == paramNames.size());
     if ((int)paramTypes.size() > 0) {
-        addDebugScopeAndLine(currentFileId, currentLine, 0);
-
         Id firstParamId = function->getParamId(0);
 
         for (size_t p = 0; p < paramTypes.size(); ++p) {
@@ -2276,29 +2240,29 @@ void Builder::makeReturn(bool implicit, Id retVal)
     if (retVal) {
         Instruction* inst = new Instruction(NoResult, NoType, OpReturnValue);
         inst->addIdOperand(retVal);
-        buildPoint->addInstruction(std::unique_ptr<Instruction>(inst));
+        addInstruction(std::unique_ptr<Instruction>(inst));
     } else
-        buildPoint->addInstruction(std::unique_ptr<Instruction>(new Instruction(NoResult, NoType, OpReturn)));
+        addInstruction(std::unique_ptr<Instruction>(new Instruction(NoResult, NoType, OpReturn)));
 
     if (! implicit)
         createAndSetNoPredecessorBlock("post-return");
 }
 
 // Comments in header
-void Builder::enterScope(uint32_t line)
+void Builder::enterLexicalBlock(uint32_t line)
 {
     // Generate new lexical scope debug instruction
     Id lexId = makeDebugLexicalBlock(line);
     currentDebugScopeId.push(lexId);
-    lastDebugScopeId = NoResult;
+    dirtyScopeTracker = true;
 }
 
 // Comments in header
-void Builder::leaveScope()
+void Builder::leaveLexicalBlock()
 {
     // Pop current scope from stack and clear current scope
     currentDebugScopeId.pop();
-    lastDebugScopeId = NoResult;
+    dirtyScopeTracker = true;
 }
 
 // Comments in header
@@ -2322,7 +2286,7 @@ void Builder::enterFunction(Function const* function)
         defInst->addImmediateOperand(NonSemanticShaderDebugInfo100DebugFunctionDefinition);
         defInst->addIdOperand(debugId[funcId]);
         defInst->addIdOperand(funcId);
-        buildPoint->addInstruction(std::unique_ptr<Instruction>(defInst));
+        addInstruction(std::unique_ptr<Instruction>(defInst));
     }
 
     if (auto linkType = function->getLinkType(); linkType != LinkageTypeMax) {
@@ -2358,7 +2322,7 @@ void Builder::leaveFunction()
 // Comments in header
 void Builder::makeStatementTerminator(spv::Op opcode, const char *name)
 {
-    buildPoint->addInstruction(std::unique_ptr<Instruction>(new Instruction(opcode)));
+    addInstruction(std::unique_ptr<Instruction>(new Instruction(opcode)));
     createAndSetNoPredecessorBlock(name);
 }
 
@@ -2401,7 +2365,7 @@ Id Builder::createVariable(Decoration precision, StorageClass storageClass, Id t
         constantsTypesGlobals.push_back(std::unique_ptr<Instruction>(inst));
         module.mapInstruction(inst);
 
-        if (emitNonSemanticShaderDebugInfo && !isRayTracingOpCode(getOpCode(type)))
+        if (emitNonSemanticShaderDebugInfo)
         {
             auto const debugResultId = createDebugGlobalVariable(debugId[type], name, inst->getResultId());
             debugId[inst->getResultId()] = debugResultId;
@@ -2420,7 +2384,7 @@ Id Builder::createVariable(Decoration precision, StorageClass storageClass, Id t
 Id Builder::createUndefined(Id type)
 {
   Instruction* inst = new Instruction(getUniqueId(), type, OpUndef);
-  buildPoint->addInstruction(std::unique_ptr<Instruction>(inst));
+  addInstruction(std::unique_ptr<Instruction>(inst));
   return inst->getResultId();
 }
 
@@ -2464,7 +2428,7 @@ void Builder::createStore(Id rValue, Id lValue, spv::MemoryAccessMask memoryAcce
         }
     }
 
-    buildPoint->addInstruction(std::unique_ptr<Instruction>(store));
+    addInstruction(std::unique_ptr<Instruction>(store));
 }
 
 // Comments in header
@@ -2486,7 +2450,7 @@ Id Builder::createLoad(Id lValue, spv::Decoration precision, spv::MemoryAccessMa
         }
     }
 
-    buildPoint->addInstruction(std::unique_ptr<Instruction>(load));
+    addInstruction(std::unique_ptr<Instruction>(load));
     setPrecision(load->getResultId(), precision);
 
     return load->getResultId();
@@ -2504,7 +2468,7 @@ Id Builder::createAccessChain(StorageClass storageClass, Id base, const std::vec
     chain->addIdOperand(base);
     for (int i = 0; i < (int)offsets.size(); ++i)
         chain->addIdOperand(offsets[i]);
-    buildPoint->addInstruction(std::unique_ptr<Instruction>(chain));
+    addInstruction(std::unique_ptr<Instruction>(chain));
 
     return chain->getResultId();
 }
@@ -2515,7 +2479,7 @@ Id Builder::createArrayLength(Id base, unsigned int member)
     Instruction* length = new Instruction(getUniqueId(), intType, OpArrayLength);
     length->addIdOperand(base);
     length->addImmediateOperand(member);
-    buildPoint->addInstruction(std::unique_ptr<Instruction>(length));
+    addInstruction(std::unique_ptr<Instruction>(length));
 
     return length->getResultId();
 }
@@ -2532,7 +2496,7 @@ Id Builder::createCooperativeMatrixLengthKHR(Id type)
 
     Instruction* length = new Instruction(getUniqueId(), intType, OpCooperativeMatrixLengthKHR);
     length->addIdOperand(type);
-    buildPoint->addInstruction(std::unique_ptr<Instruction>(length));
+    addInstruction(std::unique_ptr<Instruction>(length));
 
     return length->getResultId();
 }
@@ -2549,7 +2513,7 @@ Id Builder::createCooperativeMatrixLengthNV(Id type)
 
     Instruction* length = new Instruction(getUniqueId(), intType, OpCooperativeMatrixLengthNV);
     length->addIdOperand(type);
-    buildPoint->addInstruction(std::unique_ptr<Instruction>(length));
+    addInstruction(std::unique_ptr<Instruction>(length));
 
     return length->getResultId();
 }
@@ -2565,7 +2529,7 @@ Id Builder::createCompositeExtract(Id composite, Id typeId, unsigned index)
     Instruction* extract = new Instruction(getUniqueId(), typeId, OpCompositeExtract);
     extract->addIdOperand(composite);
     extract->addImmediateOperand(index);
-    buildPoint->addInstruction(std::unique_ptr<Instruction>(extract));
+    addInstruction(std::unique_ptr<Instruction>(extract));
 
     return extract->getResultId();
 }
@@ -2581,7 +2545,7 @@ Id Builder::createCompositeExtract(Id composite, Id typeId, const std::vector<un
     extract->addIdOperand(composite);
     for (int i = 0; i < (int)indexes.size(); ++i)
         extract->addImmediateOperand(indexes[i]);
-    buildPoint->addInstruction(std::unique_ptr<Instruction>(extract));
+    addInstruction(std::unique_ptr<Instruction>(extract));
 
     return extract->getResultId();
 }
@@ -2592,7 +2556,7 @@ Id Builder::createCompositeInsert(Id object, Id composite, Id typeId, unsigned i
     insert->addIdOperand(object);
     insert->addIdOperand(composite);
     insert->addImmediateOperand(index);
-    buildPoint->addInstruction(std::unique_ptr<Instruction>(insert));
+    addInstruction(std::unique_ptr<Instruction>(insert));
 
     return insert->getResultId();
 }
@@ -2604,7 +2568,7 @@ Id Builder::createCompositeInsert(Id object, Id composite, Id typeId, const std:
     insert->addIdOperand(composite);
     for (int i = 0; i < (int)indexes.size(); ++i)
         insert->addImmediateOperand(indexes[i]);
-    buildPoint->addInstruction(std::unique_ptr<Instruction>(insert));
+    addInstruction(std::unique_ptr<Instruction>(insert));
 
     return insert->getResultId();
 }
@@ -2614,7 +2578,7 @@ Id Builder::createVectorExtractDynamic(Id vector, Id typeId, Id componentIndex)
     Instruction* extract = new Instruction(getUniqueId(), typeId, OpVectorExtractDynamic);
     extract->addIdOperand(vector);
     extract->addIdOperand(componentIndex);
-    buildPoint->addInstruction(std::unique_ptr<Instruction>(extract));
+    addInstruction(std::unique_ptr<Instruction>(extract));
 
     return extract->getResultId();
 }
@@ -2625,7 +2589,7 @@ Id Builder::createVectorInsertDynamic(Id vector, Id typeId, Id component, Id com
     insert->addIdOperand(vector);
     insert->addIdOperand(component);
     insert->addIdOperand(componentIndex);
-    buildPoint->addInstruction(std::unique_ptr<Instruction>(insert));
+    addInstruction(std::unique_ptr<Instruction>(insert));
 
     return insert->getResultId();
 }
@@ -2634,7 +2598,7 @@ Id Builder::createVectorInsertDynamic(Id vector, Id typeId, Id component, Id com
 void Builder::createNoResultOp(Op opCode)
 {
     Instruction* op = new Instruction(opCode);
-    buildPoint->addInstruction(std::unique_ptr<Instruction>(op));
+    addInstruction(std::unique_ptr<Instruction>(op));
 }
 
 // An opcode that has one id operand, no result id, and no type
@@ -2642,7 +2606,7 @@ void Builder::createNoResultOp(Op opCode, Id operand)
 {
     Instruction* op = new Instruction(opCode);
     op->addIdOperand(operand);
-    buildPoint->addInstruction(std::unique_ptr<Instruction>(op));
+    addInstruction(std::unique_ptr<Instruction>(op));
 }
 
 // An opcode that has one or more operands, no result id, and no type
@@ -2652,7 +2616,7 @@ void Builder::createNoResultOp(Op opCode, const std::vector<Id>& operands)
     for (auto it = operands.cbegin(); it != operands.cend(); ++it) {
         op->addIdOperand(*it);
     }
-    buildPoint->addInstruction(std::unique_ptr<Instruction>(op));
+    addInstruction(std::unique_ptr<Instruction>(op));
 }
 
 // An opcode that has multiple operands, no result id, and no type
@@ -2665,7 +2629,7 @@ void Builder::createNoResultOp(Op opCode, const std::vector<IdImmediate>& operan
         else
             op->addImmediateOperand(it->word);
     }
-    buildPoint->addInstruction(std::unique_ptr<Instruction>(op));
+    addInstruction(std::unique_ptr<Instruction>(op));
 }
 
 void Builder::createControlBarrier(Scope execution, Scope memory, MemorySemanticsMask semantics)
@@ -2674,7 +2638,7 @@ void Builder::createControlBarrier(Scope execution, Scope memory, MemorySemantic
     op->addIdOperand(makeUintConstant(execution));
     op->addIdOperand(makeUintConstant(memory));
     op->addIdOperand(makeUintConstant(semantics));
-    buildPoint->addInstruction(std::unique_ptr<Instruction>(op));
+    addInstruction(std::unique_ptr<Instruction>(op));
 }
 
 void Builder::createMemoryBarrier(unsigned executionScope, unsigned memorySemantics)
@@ -2682,7 +2646,7 @@ void Builder::createMemoryBarrier(unsigned executionScope, unsigned memorySemant
     Instruction* op = new Instruction(OpMemoryBarrier);
     op->addIdOperand(makeUintConstant(executionScope));
     op->addIdOperand(makeUintConstant(memorySemantics));
-    buildPoint->addInstruction(std::unique_ptr<Instruction>(op));
+    addInstruction(std::unique_ptr<Instruction>(op));
 }
 
 // An opcode that has one operands, a result id, and a type
@@ -2695,7 +2659,7 @@ Id Builder::createUnaryOp(Op opCode, Id typeId, Id operand)
     }
     Instruction* op = new Instruction(getUniqueId(), typeId, opCode);
     op->addIdOperand(operand);
-    buildPoint->addInstruction(std::unique_ptr<Instruction>(op));
+    addInstruction(std::unique_ptr<Instruction>(op));
 
     return op->getResultId();
 }
@@ -2712,7 +2676,7 @@ Id Builder::createBinOp(Op opCode, Id typeId, Id left, Id right)
     Instruction* op = new Instruction(getUniqueId(), typeId, opCode);
     op->addIdOperand(left);
     op->addIdOperand(right);
-    buildPoint->addInstruction(std::unique_ptr<Instruction>(op));
+    addInstruction(std::unique_ptr<Instruction>(op));
 
     return op->getResultId();
 }
@@ -2733,7 +2697,7 @@ Id Builder::createTriOp(Op opCode, Id typeId, Id op1, Id op2, Id op3)
     op->addIdOperand(op1);
     op->addIdOperand(op2);
     op->addIdOperand(op3);
-    buildPoint->addInstruction(std::unique_ptr<Instruction>(op));
+    addInstruction(std::unique_ptr<Instruction>(op));
 
     return op->getResultId();
 }
@@ -2743,7 +2707,7 @@ Id Builder::createOp(Op opCode, Id typeId, const std::vector<Id>& operands)
     Instruction* op = new Instruction(getUniqueId(), typeId, opCode);
     for (auto it = operands.cbegin(); it != operands.cend(); ++it)
         op->addIdOperand(*it);
-    buildPoint->addInstruction(std::unique_ptr<Instruction>(op));
+    addInstruction(std::unique_ptr<Instruction>(op));
 
     return op->getResultId();
 }
@@ -2757,7 +2721,7 @@ Id Builder::createOp(Op opCode, Id typeId, const std::vector<IdImmediate>& opera
         else
             op->addImmediateOperand(it->word);
     }
-    buildPoint->addInstruction(std::unique_ptr<Instruction>(op));
+    addInstruction(std::unique_ptr<Instruction>(op));
 
     return op->getResultId();
 }
@@ -2791,7 +2755,7 @@ Id Builder::createFunctionCall(spv::Function* function, const std::vector<spv::I
     op->addIdOperand(function->getId());
     for (int a = 0; a < (int)args.size(); ++a)
         op->addIdOperand(args[a]);
-    buildPoint->addInstruction(std::unique_ptr<Instruction>(op));
+    addInstruction(std::unique_ptr<Instruction>(op));
 
     return op->getResultId();
 }
@@ -2813,7 +2777,7 @@ Id Builder::createRvalueSwizzle(Decoration precision, Id typeId, Id source, cons
     swizzle->addIdOperand(source);
     for (int i = 0; i < (int)channels.size(); ++i)
         swizzle->addImmediateOperand(channels[i]);
-    buildPoint->addInstruction(std::unique_ptr<Instruction>(swizzle));
+    addInstruction(std::unique_ptr<Instruction>(swizzle));
 
     return setPrecision(swizzle->getResultId(), precision);
 }
@@ -2846,7 +2810,7 @@ Id Builder::createLvalueSwizzle(Id typeId, Id target, Id source, const std::vect
     // finish the instruction with these components selectors
     for (int i = 0; i < numTargetComponents; ++i)
         swizzle->addImmediateOperand(components[i]);
-    buildPoint->addInstruction(std::unique_ptr<Instruction>(swizzle));
+    addInstruction(std::unique_ptr<Instruction>(swizzle));
 
     return swizzle->getResultId();
 }
@@ -2891,7 +2855,7 @@ Id Builder::smearScalar(Decoration precision, Id scalar, Id vectorType)
         smear = new Instruction(getUniqueId(), vectorType, OpCompositeConstruct);
         for (int c = 0; c < numComponents; ++c)
             smear->addIdOperand(scalar);
-        buildPoint->addInstruction(std::unique_ptr<Instruction>(smear));
+        addInstruction(std::unique_ptr<Instruction>(smear));
     }
 
     return setPrecision(smear->getResultId(), precision);
@@ -2906,7 +2870,7 @@ Id Builder::createBuiltinCall(Id resultType, Id builtins, int entryPoint, const
     for (int arg = 0; arg < (int)args.size(); ++arg)
         inst->addIdOperand(args[arg]);
 
-    buildPoint->addInstruction(std::unique_ptr<Instruction>(inst));
+    addInstruction(std::unique_ptr<Instruction>(inst));
 
     return inst->getResultId();
 }
@@ -3102,7 +3066,7 @@ Id Builder::createTextureCall(Decoration precision, Id resultType, bool sparse,
     for (size_t op = optArgNum + 1; op < texArgs.size(); ++op)
         textureInst->addIdOperand(texArgs[op]);
     setPrecision(textureInst->getResultId(), precision);
-    buildPoint->addInstruction(std::unique_ptr<Instruction>(textureInst));
+    addInstruction(std::unique_ptr<Instruction>(textureInst));
 
     Id resultId = textureInst->getResultId();
 
@@ -3182,7 +3146,7 @@ Id Builder::createTextureQueryCall(Op opCode, const TextureParameters& parameter
         query->addIdOperand(parameters.coords);
     if (parameters.lod)
         query->addIdOperand(parameters.lod);
-    buildPoint->addInstruction(std::unique_ptr<Instruction>(query));
+    addInstruction(std::unique_ptr<Instruction>(query));
     addCapability(CapabilityImageQuery);
 
     return query->getResultId();
@@ -3281,7 +3245,7 @@ Id Builder::createCompositeConstruct(Id typeId, const std::vector<Id>& constitue
     Instruction* op = new Instruction(getUniqueId(), typeId, OpCompositeConstruct);
     for (int c = 0; c < (int)constituents.size(); ++c)
         op->addIdOperand(constituents[c]);
-    buildPoint->addInstruction(std::unique_ptr<Instruction>(op));
+    addInstruction(std::unique_ptr<Instruction>(op));
 
     return op->getResultId();
 }
@@ -3577,7 +3541,7 @@ void Builder::makeSwitch(Id selector, unsigned int control, int numSegments, con
         switchInst->addIdOperand(segmentBlocks[valueIndexToSegment[i]]->getId());
         segmentBlocks[valueIndexToSegment[i]]->addPredecessor(buildPoint);
     }
-    buildPoint->addInstruction(std::unique_ptr<Instruction>(switchInst));
+    addInstruction(std::unique_ptr<Instruction>(switchInst));
 
     // push the merge block
     switchMerges.push(mergeBlock);
@@ -4096,7 +4060,7 @@ void Builder::createBranch(Block* block)
 {
     Instruction* branch = new Instruction(OpBranch);
     branch->addIdOperand(block->getId());
-    buildPoint->addInstruction(std::unique_ptr<Instruction>(branch));
+    addInstruction(std::unique_ptr<Instruction>(branch));
     block->addPredecessor(buildPoint);
 }
 
@@ -4105,7 +4069,7 @@ void Builder::createSelectionMerge(Block* mergeBlock, unsigned int control)
     Instruction* merge = new Instruction(OpSelectionMerge);
     merge->addIdOperand(mergeBlock->getId());
     merge->addImmediateOperand(control);
-    buildPoint->addInstruction(std::unique_ptr<Instruction>(merge));
+    addInstruction(std::unique_ptr<Instruction>(merge));
 }
 
 void Builder::createLoopMerge(Block* mergeBlock, Block* continueBlock, unsigned int control,
@@ -4117,7 +4081,7 @@ void Builder::createLoopMerge(Block* mergeBlock, Block* continueBlock, unsigned
     merge->addImmediateOperand(control);
     for (int op = 0; op < (int)operands.size(); ++op)
         merge->addImmediateOperand(operands[op]);
-    buildPoint->addInstruction(std::unique_ptr<Instruction>(merge));
+    addInstruction(std::unique_ptr<Instruction>(merge));
 }
 
 void Builder::createConditionalBranch(Id condition, Block* thenBlock, Block* elseBlock)
@@ -4126,7 +4090,7 @@ void Builder::createConditionalBranch(Id condition, Block* thenBlock, Block* els
     branch->addIdOperand(condition);
     branch->addIdOperand(thenBlock->getId());
     branch->addIdOperand(elseBlock->getId());
-    buildPoint->addInstruction(std::unique_ptr<Instruction>(branch));
+    addInstruction(std::unique_ptr<Instruction>(branch));
     thenBlock->addPredecessor(buildPoint);
     elseBlock->addPredecessor(buildPoint);
 }
@@ -4178,7 +4142,7 @@ void Builder::dumpSourceInstructions(const spv::Id fileId, const std::string& te
 void Builder::dumpSourceInstructions(std::vector<unsigned int>& out) const
 {
     if (emitNonSemanticShaderDebugInfo) return;
-    dumpSourceInstructions(sourceFileStringId, sourceText, out);
+    dumpSourceInstructions(mainFileId, sourceText, out);
     for (auto iItr = includeFiles.begin(); iItr != includeFiles.end(); ++iItr)
         dumpSourceInstructions(iItr->first, *iItr->second, out);
 }

+ 71 - 44
src/libraries/glslang/SPIRV/SpvBuilder.h

@@ -103,31 +103,53 @@ public:
         stringIds[file_c_str] = strId;
         return strId;
     }
-    spv::Id getSourceFile() const
+
+    spv::Id getMainFileId() const { return mainFileId; }
+
+    // Initialize the main source file name
+    void setDebugSourceFile(const std::string& file)
     {
-        return sourceFileStringId;
+        if (trackDebugInfo) {
+            dirtyLineTracker = true;
+            mainFileId = getStringId(file);
+            currentFileId = mainFileId;
+        }
     }
-    void setSourceFile(const std::string& file)
+
+    // Set the debug source location tracker in the builder.
+    // The upcoming instructions in basic blocks will be associated to this location.
+    void setDebugSourceLocation(int line, const char* filename)
     {
-        sourceFileStringId = getStringId(file);
-        currentFileId = sourceFileStringId;
+        if (trackDebugInfo) {
+            dirtyLineTracker = true;
+            if (line != 0) {
+                // TODO: This is special handling of some AST nodes having (untracked) line 0. 
+                //       But they should have a valid line number.
+                currentLine = line;
+                if (filename) {
+                    currentFileId = getStringId(filename);
+                }
+            }
+        }
     }
+
     void setSourceText(const std::string& text) { sourceText = text; }
     void addSourceExtension(const char* ext) { sourceExtensions.push_back(ext); }
     void addModuleProcessed(const std::string& p) { moduleProcesses.push_back(p.c_str()); }
-    void setEmitOpLines() { emitOpLines = true; }
-    void setEmitNonSemanticShaderDebugInfo(bool const emit)
+    void setEmitSpirvDebugInfo()
     {
-        emitNonSemanticShaderDebugInfo = emit;
-
-        if(emit)
-        {
-            importNonSemanticShaderDebugInfoInstructions();
-        }
+        trackDebugInfo = true;
+        emitSpirvDebugInfo = true;
     }
-    void setEmitNonSemanticShaderDebugSource(bool const src)
+    void setEmitNonSemanticShaderDebugInfo(bool emitSourceText)
     {
-        emitNonSemanticShaderDebugSource = src;
+        trackDebugInfo = true;
+        emitNonSemanticShaderDebugInfo = true;
+        importNonSemanticShaderDebugInfoInstructions();
+
+        if (emitSourceText) {
+            emitNonSemanticShaderDebugSource = emitSourceText;
+        }
     }
     void addExtension(const char* ext) { extensions.insert(ext); }
     void removeExtension(const char* ext)
@@ -169,20 +191,6 @@ public:
         return id;
     }
 
-    // Generate OpLine for non-filename-based #line directives (ie no filename
-    // seen yet): Log the current line, and if different than the last one,
-    // issue a new OpLine using the new line and current source file name.
-    void setLine(int line);
-
-    // If filename null, generate OpLine for non-filename-based line directives,
-    // else do filename-based: Log the current line and file, and if different
-    // than the last one, issue a new OpLine using the new line and file
-    // name.
-    void setLine(int line, const char* filename);
-    // Low-level OpLine. See setLine() for a layered helper.
-    void addLine(Id fileName, int line, int column);
-    void addDebugScopeAndLine(Id fileName, int line, int column);
-
     // For creating new types (will return old type if the requested one was already made).
     Id makeVoidType();
     Id makeBoolType();
@@ -318,8 +326,6 @@ public:
     // See if a resultId is valid for use as an initializer.
     bool isValidInitializer(Id resultId) const { return isConstant(resultId) || isGlobalVariable(resultId); }
 
-    bool isRayTracingOpCode(Op opcode) const;
-
     int getScalarTypeWidth(Id typeId) const
     {
         Id scalarTypeId = getScalarTypeId(typeId);
@@ -409,11 +415,16 @@ public:
     // Also reset current last DebugScope and current source line to unknown
     void setBuildPoint(Block* bp) {
         buildPoint = bp;
-        lastDebugScopeId = NoResult;
-        currentLine = 0;
+        // TODO: Technically, change of build point should set line tracker dirty. But we'll have bad line info for
+        //       branch instructions. Commenting this for now because at least this matches the old behavior.
+        dirtyScopeTracker = true;
     }
     Block* getBuildPoint() const { return buildPoint; }
 
+    // Append an instruction to the end of the current build point.
+    // Optionally, additional debug info instructions may also be prepended.
+    void addInstruction(std::unique_ptr<Instruction> inst);
+
     // Make the entry-point function. The returned pointer is only valid
     // for the lifetime of this builder.
     Function* makeEntryPoint(const char*);
@@ -430,10 +441,10 @@ public:
     void makeReturn(bool implicit, Id retVal = 0);
 
     // Initialize state and generate instructions for new lexical scope
-    void enterScope(uint32_t line);
+    void enterLexicalBlock(uint32_t line);
 
     // Set state and generate instructions to exit current lexical scope
-    void leaveScope();
+    void leaveLexicalBlock();
 
     // Prepare builder for generation of instructions for a function.
     void enterFunction(Function const* function);
@@ -882,21 +893,37 @@ public:
     unsigned int spvVersion;     // the version of SPIR-V to emit in the header
     SourceLanguage sourceLang;
     int sourceVersion;
-    spv::Id sourceFileStringId;
     spv::Id nonSemanticShaderCompilationUnitId {0};
     spv::Id nonSemanticShaderDebugInfo {0};
     spv::Id debugInfoNone {0};
     spv::Id debugExpression {0}; // Debug expression with zero operations.
     std::string sourceText;
-    int currentLine;
-    const char* currentFile;
-    spv::Id currentFileId;
+
+    // True if an new OpLine/OpDebugLine may need to be inserted. Either:
+    // 1. The current debug location changed
+    // 2. The current build point changed
+    bool dirtyLineTracker;
+    int currentLine = 0;
+    // OpString id of the current file name. Always 0 if debug info is off.
+    spv::Id currentFileId = 0;
+    // OpString id of the main file name. Always 0 if debug info is off.
+    spv::Id mainFileId = 0;
+
+    // True if an new OpDebugScope may need to be inserted. Either:
+    // 1. A new lexical block is pushed
+    // 2. The current build point changed
+    bool dirtyScopeTracker;
     std::stack<spv::Id> currentDebugScopeId;
-    spv::Id lastDebugScopeId;
-    bool emitOpLines;
-    bool emitNonSemanticShaderDebugInfo;
-    bool restoreNonSemanticShaderDebugInfo;
-    bool emitNonSemanticShaderDebugSource;
+
+    // This flag toggles tracking of debug info while building the SPIR-V.
+    bool trackDebugInfo = false;
+    // This flag toggles emission of SPIR-V debug instructions, like OpLine and OpSource.
+    bool emitSpirvDebugInfo = false;
+    // This flag toggles emission of Non-Semantic Debug extension debug instructions.
+    bool emitNonSemanticShaderDebugInfo = false;
+    bool restoreNonSemanticShaderDebugInfo = false;
+    bool emitNonSemanticShaderDebugSource = false;
+
     std::set<std::string> extensions;
     std::vector<const char*> sourceExtensions;
     std::vector<const char*> moduleProcesses;

+ 1 - 0
src/libraries/glslang/SPIRV/SpvPostProcess.cpp

@@ -181,6 +181,7 @@ void Builder::postProcessType(const Instruction& inst, Id typeId)
             else if (width == 8)
                 addCapability(CapabilityInt8);
         }
+        break;
     default:
         if (basicTypeOp == OpTypeInt) {
             if (width == 16)

+ 7 - 2
src/libraries/glslang/SPIRV/disassemble.cpp

@@ -80,6 +80,7 @@ enum ExtInstSet {
     GLSLextNVInst,
     OpenCLExtInst,
     NonSemanticDebugPrintfExtInst,
+    NonSemanticDebugBreakExtInst,
     NonSemanticShaderDebugInfo100
 };
 
@@ -360,7 +361,7 @@ void SpirvStream::disassembleInstruction(Id resultId, Id /*typeId*/, Op opCode,
                 switch (stream[word]) {
                 case 8:  idDescriptor[resultId] = "int8_t"; break;
                 case 16: idDescriptor[resultId] = "int16_t"; break;
-                default: assert(0); // fallthrough
+                default: assert(0); [[fallthrough]];
                 case 32: idDescriptor[resultId] = "int"; break;
                 case 64: idDescriptor[resultId] = "int64_t"; break;
                 }
@@ -368,7 +369,7 @@ void SpirvStream::disassembleInstruction(Id resultId, Id /*typeId*/, Op opCode,
             case OpTypeFloat:
                 switch (stream[word]) {
                 case 16: idDescriptor[resultId] = "float16_t"; break;
-                default: assert(0); // fallthrough
+                default: assert(0); [[fallthrough]];
                 case 32: idDescriptor[resultId] = "float"; break;
                 case 64: idDescriptor[resultId] = "float64_t"; break;
                 }
@@ -506,6 +507,8 @@ void SpirvStream::disassembleInstruction(Id resultId, Id /*typeId*/, Op opCode,
                     extInstSet = OpenCLExtInst;
                 } else if (strcmp("NonSemantic.DebugPrintf", name) == 0) {
                     extInstSet = NonSemanticDebugPrintfExtInst;
+                } else if (strcmp("NonSemantic.DebugBreak", name) == 0) {
+                    extInstSet = NonSemanticDebugBreakExtInst;
                 } else if (strcmp("NonSemantic.Shader.DebugInfo.100", name) == 0) {
                     extInstSet = NonSemanticShaderDebugInfo100;
                 } else if (strcmp(spv::E_SPV_AMD_shader_ballot, name) == 0 ||
@@ -533,6 +536,8 @@ void SpirvStream::disassembleInstruction(Id resultId, Id /*typeId*/, Op opCode,
                     out << "(" << GLSLextNVGetDebugNames(name, entrypoint) << ")";
                 } else if (extInstSet == NonSemanticDebugPrintfExtInst) {
                     out << "(DebugPrintf)";
+                } else if (extInstSet == NonSemanticDebugBreakExtInst) {
+                    out << "(DebugBreak)";
                 } else if (extInstSet == NonSemanticShaderDebugInfo100) {
                     out << "(" << NonSemanticShaderDebugInfo100GetDebugNames(entrypoint) << ")";
                 }

+ 68 - 1
src/libraries/glslang/SPIRV/doc.cpp

@@ -1,5 +1,6 @@
 //
 // Copyright (C) 2014-2015 LunarG, Inc.
+// Copyright (C) 2022-2024 Arm Limited.
 // Modifications Copyright (C) 2020 Advanced Micro Devices, Inc. All rights reserved.
 //
 // All rights reserved.
@@ -198,6 +199,7 @@ const char* ExecutionModeString(int mode)
     case ExecutionModeStencilRefGreaterBackAMD:      return "StencilRefGreaterBackAMD";
     case ExecutionModeStencilRefReplacingEXT:        return "StencilRefReplacingEXT";
     case ExecutionModeSubgroupUniformControlFlowKHR: return "SubgroupUniformControlFlow";
+    case ExecutionModeMaximallyReconvergesKHR:       return "MaximallyReconverges";
 
     case ExecutionModeOutputLinesNV:                 return "OutputLinesNV";
     case ExecutionModeOutputPrimitivesNV:            return "OutputPrimitivesNV";
@@ -217,6 +219,9 @@ const char* ExecutionModeString(int mode)
     case ExecutionModeNoGlobalOffsetINTEL:      return "NoGlobalOffsetINTEL";
     case ExecutionModeNumSIMDWorkitemsINTEL:    return "NumSIMDWorkitemsINTEL";
 
+    case ExecutionModeRequireFullQuadsKHR:      return "RequireFullQuadsKHR";
+    case ExecutionModeQuadDerivativesKHR:       return "QuadDerivativesKHR";
+
     case ExecutionModeNonCoherentColorAttachmentReadEXT:        return "NonCoherentColorAttachmentReadEXT";
     case ExecutionModeNonCoherentDepthAttachmentReadEXT:        return "NonCoherentDepthAttachmentReadEXT";
     case ExecutionModeNonCoherentStencilAttachmentReadEXT:      return "NonCoherentStencilAttachmentReadEXT";
@@ -314,6 +319,7 @@ const char* DecorationString(int decoration)
 
     case DecorationWeightTextureQCOM:           return "DecorationWeightTextureQCOM";
     case DecorationBlockMatchTextureQCOM:       return "DecorationBlockMatchTextureQCOM";
+    case DecorationBlockMatchSamplerQCOM:       return "DecorationBlockMatchSamplerQCOM";
     case DecorationExplicitInterpAMD:           return "ExplicitInterpAMD";
     case DecorationOverrideCoverageNV:          return "OverrideCoverageNV";
     case DecorationPassthroughNV:               return "PassthroughNV";
@@ -938,6 +944,7 @@ const char* CapabilityString(int info)
     case CapabilitySubgroupBallotKHR: return "SubgroupBallotKHR";
     case CapabilityDrawParameters:    return "DrawParameters";
     case CapabilitySubgroupVoteKHR:   return "SubgroupVoteKHR";
+    case CapabilityGroupNonUniformRotateKHR: return "CapabilityGroupNonUniformRotateKHR";
 
     case CapabilityStorageUniformBufferBlock16: return "StorageUniformBufferBlock16";
     case CapabilityStorageUniform16:            return "StorageUniform16";
@@ -1031,11 +1038,15 @@ const char* CapabilityString(int info)
     case CapabilityFragmentShadingRateKHR:                  return "FragmentShadingRateKHR";
 
     case CapabilityDemoteToHelperInvocationEXT:             return "DemoteToHelperInvocationEXT";
+    case CapabilityAtomicFloat16VectorNV:                   return "AtomicFloat16VectorNV";
     case CapabilityShaderClockKHR:                          return "ShaderClockKHR";
+    case CapabilityQuadControlKHR:                          return "QuadControlKHR";
     case CapabilityInt64ImageEXT:                           return "Int64ImageEXT";
 
     case CapabilityIntegerFunctions2INTEL:              return "CapabilityIntegerFunctions2INTEL";
 
+    case CapabilityExpectAssumeKHR:                         return "ExpectAssumeKHR";
+
     case CapabilityAtomicFloat16AddEXT:                     return "AtomicFloat16AddEXT";
     case CapabilityAtomicFloat32AddEXT:                     return "AtomicFloat32AddEXT";
     case CapabilityAtomicFloat64AddEXT:                     return "AtomicFloat64AddEXT";
@@ -1432,10 +1443,16 @@ const char* OpcodeString(int op)
     case 4430: return "OpSubgroupAllEqualKHR";
     case 4432: return "OpSubgroupReadInvocationKHR";
 
+    case OpGroupNonUniformQuadAllKHR: return "OpGroupNonUniformQuadAllKHR";
+    case OpGroupNonUniformQuadAnyKHR: return "OpGroupNonUniformQuadAnyKHR";
+
     case OpAtomicFAddEXT: return "OpAtomicFAddEXT";
     case OpAtomicFMinEXT: return "OpAtomicFMinEXT";
     case OpAtomicFMaxEXT: return "OpAtomicFMaxEXT";
 
+    case OpAssumeTrueKHR: return "OpAssumeTrueKHR";
+    case OpExpectKHR: return "OpExpectKHR";
+
     case 5000: return "OpGroupIAddNonUniformAMD";
     case 5001: return "OpGroupFAddNonUniformAMD";
     case 5002: return "OpGroupFMinNonUniformAMD";
@@ -1472,6 +1489,8 @@ const char* OpcodeString(int op)
     case OpEmitMeshTasksEXT:                 return "OpEmitMeshTasksEXT";
     case OpSetMeshOutputsEXT:                return "OpSetMeshOutputsEXT";
 
+    case OpGroupNonUniformRotateKHR:         return "OpGroupNonUniformRotateKHR";
+
     case OpTypeRayQueryKHR:                                                   return "OpTypeRayQueryKHR";
     case OpRayQueryInitializeKHR:                                             return "OpRayQueryInitializeKHR";
     case OpRayQueryTerminateKHR:                                              return "OpRayQueryTerminateKHR";
@@ -1559,6 +1578,10 @@ const char* OpcodeString(int op)
     case OpImageBoxFilterQCOM:              return "OpImageBoxFilterQCOM";
     case OpImageBlockMatchSADQCOM:          return "OpImageBlockMatchSADQCOM";
     case OpImageBlockMatchSSDQCOM:          return "OpImageBlockMatchSSDQCOM";
+    case OpImageBlockMatchWindowSSDQCOM:    return "OpImageBlockMatchWindowSSDQCOM";
+    case OpImageBlockMatchWindowSADQCOM:    return "OpImageBlockMatchWindowSADQCOM";
+    case OpImageBlockMatchGatherSSDQCOM:    return "OpImageBlockMatchGatherSSDQCOM";
+    case OpImageBlockMatchGatherSADQCOM:    return "OpImageBlockMatchGatherSADQCOM";
 
     default:
         return "Bad";
@@ -1678,7 +1701,7 @@ void Parameterize()
         InstructionDesc[OpCooperativeMatrixStoreKHR].setResultAndType(false, false);
         InstructionDesc[OpBeginInvocationInterlockEXT].setResultAndType(false, false);
         InstructionDesc[OpEndInvocationInterlockEXT].setResultAndType(false, false);
-
+        InstructionDesc[OpAssumeTrueKHR].setResultAndType(false, false);
         // Specific additional context-dependent operands
 
         ExecutionModeOperands[ExecutionModeInvocations].push(OperandLiteralNumber, "'Number of <<Invocation,invocations>>'");
@@ -2457,6 +2480,11 @@ void Parameterize()
         InstructionDesc[OpAtomicFAddEXT].operands.push(OperandMemorySemantics, "'Semantics'");
         InstructionDesc[OpAtomicFAddEXT].operands.push(OperandId, "'Value'");
 
+        InstructionDesc[OpAssumeTrueKHR].operands.push(OperandId, "'Condition'");
+
+        InstructionDesc[OpExpectKHR].operands.push(OperandId, "'Value'");
+        InstructionDesc[OpExpectKHR].operands.push(OperandId, "'ExpectedValue'");
+
         InstructionDesc[OpAtomicISub].operands.push(OperandId, "'Pointer'");
         InstructionDesc[OpAtomicISub].operands.push(OperandScope, "'Scope'");
         InstructionDesc[OpAtomicISub].operands.push(OperandMemorySemantics, "'Semantics'");
@@ -2885,6 +2913,11 @@ void Parameterize()
         InstructionDesc[OpSubgroupAllEqualKHR].operands.push(OperandScope, "'Execution'");
         InstructionDesc[OpSubgroupAllEqualKHR].operands.push(OperandId, "'Predicate'");
 
+        InstructionDesc[OpGroupNonUniformRotateKHR].operands.push(OperandScope, "'Execution'");
+        InstructionDesc[OpGroupNonUniformRotateKHR].operands.push(OperandId, "'X'");
+        InstructionDesc[OpGroupNonUniformRotateKHR].operands.push(OperandId, "'Delta'");
+        InstructionDesc[OpGroupNonUniformRotateKHR].operands.push(OperandId, "'ClusterSize'", true);
+
         InstructionDesc[OpSubgroupReadInvocationKHR].operands.push(OperandId, "'Value'");
         InstructionDesc[OpSubgroupReadInvocationKHR].operands.push(OperandId, "'Index'");
 
@@ -2931,6 +2964,8 @@ void Parameterize()
 
         InstructionDesc[OpGroupNonUniformPartitionNV].operands.push(OperandId, "X");
 
+        InstructionDesc[OpGroupNonUniformQuadAllKHR].operands.push(OperandId, "'Predicate'");
+        InstructionDesc[OpGroupNonUniformQuadAnyKHR].operands.push(OperandId, "'Predicate'");
         InstructionDesc[OpTypeAccelerationStructureKHR].setResultAndType(true, false);
 
         InstructionDesc[OpTraceNV].operands.push(OperandId, "'Acceleration Structure'");
@@ -3403,6 +3438,38 @@ void Parameterize()
         InstructionDesc[OpImageBlockMatchSSDQCOM].operands.push(OperandId, "'block size'");
         InstructionDesc[OpImageBlockMatchSSDQCOM].operands.push(OperandImageOperands, "", true);
         InstructionDesc[OpImageBlockMatchSSDQCOM].setResultAndType(true, true);
+
+        InstructionDesc[OpImageBlockMatchWindowSSDQCOM].operands.push(OperandId, "'target texture'");
+        InstructionDesc[OpImageBlockMatchWindowSSDQCOM].operands.push(OperandId, "'target coordinates'");
+        InstructionDesc[OpImageBlockMatchWindowSSDQCOM].operands.push(OperandId, "'reference texture'");
+        InstructionDesc[OpImageBlockMatchWindowSSDQCOM].operands.push(OperandId, "'reference coordinates'");
+        InstructionDesc[OpImageBlockMatchWindowSSDQCOM].operands.push(OperandId, "'block size'");
+        InstructionDesc[OpImageBlockMatchWindowSSDQCOM].operands.push(OperandImageOperands, "", true);
+        InstructionDesc[OpImageBlockMatchWindowSSDQCOM].setResultAndType(true, true);
+
+        InstructionDesc[OpImageBlockMatchWindowSADQCOM].operands.push(OperandId, "'target texture'");
+        InstructionDesc[OpImageBlockMatchWindowSADQCOM].operands.push(OperandId, "'target coordinates'");
+        InstructionDesc[OpImageBlockMatchWindowSADQCOM].operands.push(OperandId, "'reference texture'");
+        InstructionDesc[OpImageBlockMatchWindowSADQCOM].operands.push(OperandId, "'reference coordinates'");
+        InstructionDesc[OpImageBlockMatchWindowSADQCOM].operands.push(OperandId, "'block size'");
+        InstructionDesc[OpImageBlockMatchWindowSADQCOM].operands.push(OperandImageOperands, "", true);
+        InstructionDesc[OpImageBlockMatchWindowSADQCOM].setResultAndType(true, true);
+
+        InstructionDesc[OpImageBlockMatchGatherSSDQCOM].operands.push(OperandId, "'target texture'");
+        InstructionDesc[OpImageBlockMatchGatherSSDQCOM].operands.push(OperandId, "'target coordinates'");
+        InstructionDesc[OpImageBlockMatchGatherSSDQCOM].operands.push(OperandId, "'reference texture'");
+        InstructionDesc[OpImageBlockMatchGatherSSDQCOM].operands.push(OperandId, "'reference coordinates'");
+        InstructionDesc[OpImageBlockMatchGatherSSDQCOM].operands.push(OperandId, "'block size'");
+        InstructionDesc[OpImageBlockMatchGatherSSDQCOM].operands.push(OperandImageOperands, "", true);
+        InstructionDesc[OpImageBlockMatchGatherSSDQCOM].setResultAndType(true, true);
+
+        InstructionDesc[OpImageBlockMatchGatherSADQCOM].operands.push(OperandId, "'target texture'");
+        InstructionDesc[OpImageBlockMatchGatherSADQCOM].operands.push(OperandId, "'target coordinates'");
+        InstructionDesc[OpImageBlockMatchGatherSADQCOM].operands.push(OperandId, "'reference texture'");
+        InstructionDesc[OpImageBlockMatchGatherSADQCOM].operands.push(OperandId, "'reference coordinates'");
+        InstructionDesc[OpImageBlockMatchGatherSADQCOM].operands.push(OperandId, "'block size'");
+        InstructionDesc[OpImageBlockMatchGatherSADQCOM].operands.push(OperandImageOperands, "", true);
+        InstructionDesc[OpImageBlockMatchGatherSADQCOM].setResultAndType(true, true);
     });
 }
 

+ 23 - 4
src/libraries/glslang/SPIRV/spirv.hpp

@@ -1,4 +1,4 @@
-// Copyright (c) 2014-2020 The Khronos Group Inc.
+// Copyright (c) 2014-2024 The Khronos Group Inc.
 //
 // Permission is hereby granted, free of charge, to any person obtaining a copy
 // of this software and/or associated documentation files (the "Materials"),
@@ -174,6 +174,8 @@ enum ExecutionMode {
     ExecutionModeStencilRefUnchangedBackAMD = 5082,
     ExecutionModeStencilRefGreaterBackAMD = 5083,
     ExecutionModeStencilRefLessBackAMD = 5084,
+    ExecutionModeQuadDerivativesKHR = 5088,
+    ExecutionModeRequireFullQuadsKHR = 5089,
     ExecutionModeOutputLinesEXT = 5269,
     ExecutionModeOutputLinesNV = 5269,
     ExecutionModeOutputPrimitivesEXT = 5270,
@@ -198,6 +200,7 @@ enum ExecutionMode {
     ExecutionModeNoGlobalOffsetINTEL = 5895,
     ExecutionModeNumSIMDWorkitemsINTEL = 5896,
     ExecutionModeSchedulerTargetFmaxMhzINTEL = 5903,
+    ExecutionModeMaximallyReconvergesKHR = 6023,
     ExecutionModeStreamingInterfaceINTEL = 6154,
     ExecutionModeNamedBarrierCountINTEL = 6417,
     ExecutionModeMax = 0x7fffffff,
@@ -515,6 +518,7 @@ enum Decoration {
     DecorationNoUnsignedWrap = 4470,
     DecorationWeightTextureQCOM = 4487,
     DecorationBlockMatchTextureQCOM = 4488,
+    DecorationBlockMatchSamplerQCOM = 4499,
     DecorationExplicitInterpAMD = 4999,
     DecorationOverrideCoverageNV = 5248,
     DecorationPassthroughNV = 5250,
@@ -722,8 +726,6 @@ enum BuiltIn {
     BuiltInHitTriangleVertexPositionsKHR = 5335,
     BuiltInHitMicroTriangleVertexPositionsNV = 5337,
     BuiltInHitMicroTriangleVertexBarycentricsNV = 5344,
-    BuiltInHitKindFrontFacingMicroTriangleNV = 5405,
-    BuiltInHitKindBackFacingMicroTriangleNV = 5406,
     BuiltInIncomingRayFlagsKHR = 5351,
     BuiltInIncomingRayFlagsNV = 5351,
     BuiltInRayGeometryIndexKHR = 5352,
@@ -731,6 +733,8 @@ enum BuiltIn {
     BuiltInSMCountNV = 5375,
     BuiltInWarpIDNV = 5376,
     BuiltInSMIDNV = 5377,
+    BuiltInHitKindFrontFacingMicroTriangleNV = 5405,
+    BuiltInHitKindBackFacingMicroTriangleNV = 5406,
     BuiltInCullMaskKHR = 6021,
     BuiltInMax = 0x7fffffff,
 };
@@ -1032,6 +1036,7 @@ enum Capability {
     CapabilityTextureSampleWeightedQCOM = 4484,
     CapabilityTextureBoxFilterQCOM = 4485,
     CapabilityTextureBlockMatchQCOM = 4486,
+    CapabilityTextureBlockMatch2QCOM = 4498,
     CapabilityFloat16ImageAMD = 5008,
     CapabilityImageGatherBiasLodAMD = 5009,
     CapabilityFragmentMaskAMD = 5010,
@@ -1039,6 +1044,7 @@ enum Capability {
     CapabilityImageReadWriteLodAMD = 5015,
     CapabilityInt64ImageEXT = 5016,
     CapabilityShaderClockKHR = 5055,
+    CapabilityQuadControlKHR = 5087,
     CapabilitySampleMaskOverrideCoverageNV = 5249,
     CapabilityGeometryShaderPassthroughNV = 5251,
     CapabilityShaderViewportIndexLayerEXT = 5254,
@@ -1099,11 +1105,12 @@ enum Capability {
     CapabilityDemoteToHelperInvocation = 5379,
     CapabilityDemoteToHelperInvocationEXT = 5379,
     CapabilityDisplacementMicromapNV = 5380,
-    CapabilityRayTracingDisplacementMicromapNV = 5409,
     CapabilityRayTracingOpacityMicromapEXT = 5381,
     CapabilityShaderInvocationReorderNV = 5383,
     CapabilityBindlessTextureNV = 5390,
     CapabilityRayQueryPositionFetchKHR = 5391,
+    CapabilityAtomicFloat16VectorNV = 5404,
+    CapabilityRayTracingDisplacementMicromapNV = 5409,
     CapabilitySubgroupShuffleINTEL = 5568,
     CapabilitySubgroupBufferBlockIOINTEL = 5569,
     CapabilitySubgroupImageBlockIOINTEL = 5570,
@@ -1693,6 +1700,10 @@ enum Op {
     OpImageBoxFilterQCOM = 4481,
     OpImageBlockMatchSSDQCOM = 4482,
     OpImageBlockMatchSADQCOM = 4483,
+    OpImageBlockMatchWindowSSDQCOM = 4500,
+    OpImageBlockMatchWindowSADQCOM = 4501,
+    OpImageBlockMatchGatherSSDQCOM = 4502,
+    OpImageBlockMatchGatherSADQCOM = 4503,
     OpGroupIAddNonUniformAMD = 5000,
     OpGroupFAddNonUniformAMD = 5001,
     OpGroupFMinNonUniformAMD = 5002,
@@ -1704,6 +1715,8 @@ enum Op {
     OpFragmentMaskFetchAMD = 5011,
     OpFragmentFetchAMD = 5012,
     OpReadClockKHR = 5056,
+    OpGroupNonUniformQuadAllKHR = 5110,
+    OpGroupNonUniformQuadAnyKHR = 5111,
     OpHitObjectRecordHitMotionNV = 5249,
     OpHitObjectRecordHitWithIndexMotionNV = 5250,
     OpHitObjectRecordMissMotionNV = 5251,
@@ -2416,6 +2429,10 @@ inline void HasResultAndType(Op opcode, bool *hasResult, bool *hasResultType) {
     case OpImageBoxFilterQCOM: *hasResult = true; *hasResultType = true; break;
     case OpImageBlockMatchSSDQCOM: *hasResult = true; *hasResultType = true; break;
     case OpImageBlockMatchSADQCOM: *hasResult = true; *hasResultType = true; break;
+    case OpImageBlockMatchWindowSSDQCOM: *hasResult = true; *hasResultType = true; break;
+    case OpImageBlockMatchWindowSADQCOM: *hasResult = true; *hasResultType = true; break;
+    case OpImageBlockMatchGatherSSDQCOM: *hasResult = true; *hasResultType = true; break;
+    case OpImageBlockMatchGatherSADQCOM: *hasResult = true; *hasResultType = true; break;
     case OpGroupIAddNonUniformAMD: *hasResult = true; *hasResultType = true; break;
     case OpGroupFAddNonUniformAMD: *hasResult = true; *hasResultType = true; break;
     case OpGroupFMinNonUniformAMD: *hasResult = true; *hasResultType = true; break;
@@ -2427,6 +2444,8 @@ inline void HasResultAndType(Op opcode, bool *hasResult, bool *hasResultType) {
     case OpFragmentMaskFetchAMD: *hasResult = true; *hasResultType = true; break;
     case OpFragmentFetchAMD: *hasResult = true; *hasResultType = true; break;
     case OpReadClockKHR: *hasResult = true; *hasResultType = true; break;
+    case OpGroupNonUniformQuadAllKHR: *hasResult = true; *hasResultType = true; break;
+    case OpGroupNonUniformQuadAnyKHR: *hasResult = true; *hasResultType = true; break;
     case OpHitObjectRecordHitMotionNV: *hasResult = false; *hasResultType = false; break;
     case OpHitObjectRecordHitWithIndexMotionNV: *hasResult = false; *hasResultType = false; break;
     case OpHitObjectRecordMissMotionNV: *hasResult = false; *hasResultType = false; break;

+ 35 - 0
src/libraries/glslang/SPIRV/spvIR.h

@@ -56,6 +56,7 @@
 #include <memory>
 #include <vector>
 #include <set>
+#include <optional>
 
 namespace spv {
 
@@ -190,6 +191,12 @@ protected:
 // SPIR-V IR block.
 //
 
+struct DebugSourceLocation {
+    int line;
+    int column;
+    spv::Id fileId;
+};
+
 class Block {
 public:
     Block(Id id, Function& parent);
@@ -200,6 +207,28 @@ public:
     Id getId() { return instructions.front()->getResultId(); }
 
     Function& getParent() const { return parent; }
+    // Returns true if the source location is actually updated.
+    // Note we still need the builder to insert the line marker instruction. This is just a tracker.
+    bool updateDebugSourceLocation(int line, int column, spv::Id fileId) {
+        if (currentSourceLoc && currentSourceLoc->line == line && currentSourceLoc->column == column &&
+            currentSourceLoc->fileId == fileId) {
+            return false;
+        }
+
+        currentSourceLoc = DebugSourceLocation{line, column, fileId};
+        return true;
+    }
+    // Returns true if the scope is actually updated.
+    // Note we still need the builder to insert the debug scope instruction. This is just a tracker.
+    bool updateDebugScope(spv::Id scopeId) {
+        assert(scopeId);
+        if (currentDebugScope && *currentDebugScope == scopeId) {
+            return false;
+        }
+
+        currentDebugScope = scopeId;
+        return true;
+    }
     void addInstruction(std::unique_ptr<Instruction> inst);
     void addPredecessor(Block* pred) { predecessors.push_back(pred); pred->successors.push_back(this);}
     void addLocalVariable(std::unique_ptr<Instruction> inst) { localVariables.push_back(std::move(inst)); }
@@ -292,6 +321,12 @@ protected:
     std::vector<std::unique_ptr<Instruction> > localVariables;
     Function& parent;
 
+    // Track source location of the last source location marker instruction.
+    std::optional<DebugSourceLocation> currentSourceLoc;
+
+    // Track scope of the last debug scope instruction.
+    std::optional<spv::Id> currentDebugScope;
+
     // track whether this block is known to be uncreachable (not necessarily
     // true for all unreachable blocks, but should be set at least
     // for the extraneous ones introduced by the builder).

+ 5 - 0
src/libraries/glslang/glslang/Include/Common.h

@@ -159,6 +159,11 @@ template<class T> inline T* NewPoolObject(T, int instances)
     return new(GetThreadPoolAllocator().allocate(instances * sizeof(T))) T[instances];
 }
 
+inline bool StartsWith(TString const &str, const char *prefix)
+{
+    return str.compare(0, strlen(prefix), prefix) == 0;
+}
+
 //
 // Pool allocator versions of vectors, lists, and maps
 //

+ 21 - 3
src/libraries/glslang/glslang/Include/InfoSink.h

@@ -36,6 +36,7 @@
 #define _INFOSINK_INCLUDED_
 
 #include "../Include/Common.h"
+#include <filesystem>
 #include <cmath>
 
 namespace glslang {
@@ -67,7 +68,7 @@ enum TOutputStream {
 //
 class TInfoSinkBase {
 public:
-    TInfoSinkBase() : outputStream(4) {}
+    TInfoSinkBase() : outputStream(4), shaderFileName(nullptr) {}
     void erase() { sink.erase(); }
     TInfoSinkBase& operator<<(const TPersistString& t) { append(t); return *this; }
     TInfoSinkBase& operator<<(char c)                  { append(1, c); return *this; }
@@ -94,11 +95,22 @@ public:
         default:                   append("UNKNOWN ERROR: ");   break;
         }
     }
-    void location(const TSourceLoc& loc) {
+    void location(const TSourceLoc& loc, bool absolute = false) {
         const int maxSize = 24;
         char locText[maxSize];
         snprintf(locText, maxSize, ":%d", loc.line);
-        append(loc.getStringNameOrNum(false).c_str());
+
+        if(loc.getFilename() == nullptr && shaderFileName != nullptr && absolute) {
+            append(std::filesystem::absolute(shaderFileName).string());
+        } else {
+            std::string location = loc.getStringNameOrNum(false);
+            if (absolute) {
+                append(std::filesystem::absolute(location).string());
+            } else {
+                append(location);
+            }
+        }
+
         append(locText);
         append(": ");
     }
@@ -119,6 +131,11 @@ public:
         outputStream = output;
     }
 
+    void setShaderFileName(const char* file = nullptr)
+    {
+        shaderFileName = file;
+    }
+
 protected:
     void append(const char* s);
 
@@ -131,6 +148,7 @@ protected:
     void appendToStream(const char* s);
     TPersistString sink;
     int outputStream;
+    const char* shaderFileName;
 };
 
 } // end namespace glslang

+ 34 - 5
src/libraries/glslang/glslang/Include/Types.h

@@ -573,7 +573,8 @@ public:
     }
 
     const char*         semanticName;
-    TStorageQualifier   storage   : 6;
+    TStorageQualifier   storage   : 7;
+    static_assert(EvqLast < 64, "need to increase size of TStorageQualifier bitfields!");
     TBuiltInVariable    builtIn   : 9;
     TBuiltInVariable    declaredBuiltIn : 9;
     static_assert(EbvLast < 256, "need to increase size of TBuiltInVariable bitfields!");
@@ -852,6 +853,8 @@ public:
         // -2048 as the default value indicating layoutSecondaryViewportRelative is not set
         layoutSecondaryViewportRelativeOffset = -2048;
         layoutShaderRecord = false;
+        layoutFullQuads = false;
+        layoutQuadDeriv = false;
         layoutHitObjectShaderRecordNV = false;
         layoutBindlessSampler = false;
         layoutBindlessImage = false;
@@ -948,6 +951,8 @@ public:
     bool layoutViewportRelative;
     int layoutSecondaryViewportRelativeOffset;
     bool layoutShaderRecord;
+    bool layoutFullQuads;
+    bool layoutQuadDeriv;
     bool layoutHitObjectShaderRecordNV;
 
     // GL_EXT_spirv_intrinsics
@@ -1055,6 +1060,8 @@ public:
     TLayoutFormat getFormat() const { return layoutFormat; }
     bool isPushConstant() const { return layoutPushConstant; }
     bool isShaderRecord() const { return layoutShaderRecord; }
+    bool isFullQuads() const { return layoutFullQuads; }
+    bool isQuadDeriv() const { return layoutQuadDeriv; }
     bool hasHitObjectShaderRecordNV() const { return layoutHitObjectShaderRecordNV; }
     bool hasBufferReference() const { return layoutBufferReference; }
     bool hasBufferReferenceAlign() const
@@ -1428,13 +1435,25 @@ class TTypeParameters {
 public:
     POOL_ALLOCATOR_NEW_DELETE(GetThreadPoolAllocator())
 
-    TTypeParameters() : basicType(EbtVoid), arraySizes(nullptr) {}
+    TTypeParameters() : basicType(EbtVoid), arraySizes(nullptr), spirvType(nullptr) {}
 
     TBasicType basicType;
     TArraySizes *arraySizes;
+    TSpirvType *spirvType;
 
-    bool operator==(const TTypeParameters& rhs) const { return basicType == rhs.basicType && *arraySizes == *rhs.arraySizes; }
-    bool operator!=(const TTypeParameters& rhs) const { return basicType != rhs.basicType || *arraySizes != *rhs.arraySizes; }
+    bool operator==(const TTypeParameters& rhs) const
+    {
+        bool same = basicType == rhs.basicType && *arraySizes == *rhs.arraySizes;
+        if (same && basicType == EbtSpirvType) {
+            assert(spirvType && rhs.spirvType);
+            return *spirvType == *rhs.spirvType;
+        }
+        return same;
+    }
+    bool operator!=(const TTypeParameters& rhs) const
+    {
+        return !(*this == rhs);
+    }
 };
 
 //
@@ -1611,6 +1630,10 @@ public:
                                 }
                                 if (p.isCoopmatKHR() && p.typeParameters && p.typeParameters->arraySizes->getNumDims() > 0) {
                                     basicType = p.typeParameters->basicType;
+                                    if (isSpirvType()) {
+                                        assert(p.typeParameters->spirvType);
+                                        spirvType = p.typeParameters->spirvType;
+                                    }
 
                                     if (p.typeParameters->arraySizes->getNumDims() == 4) {
                                         const int dimSize = p.typeParameters->arraySizes->getDimSize(3);
@@ -2206,6 +2229,10 @@ public:
               
               if (qualifier.layoutShaderRecord)
                 appendStr(" shaderRecordNV");
+              if (qualifier.layoutFullQuads)
+                appendStr(" full_quads");
+              if (qualifier.layoutQuadDeriv)
+                appendStr(" quad_derivatives");
               if (qualifier.layoutHitObjectShaderRecordNV)
                 appendStr(" hitobjectshaderrecordnv");
 
@@ -2708,7 +2735,8 @@ public:
         if (isCoopMatKHR() && right.isCoopMatKHR()) {
             return ((getBasicType() == right.getBasicType()) || (getBasicType() == EbtCoopmat) ||
                     (right.getBasicType() == EbtCoopmat)) &&
-                   typeParameters == nullptr && right.typeParameters != nullptr;
+                   ((typeParameters == nullptr && right.typeParameters != nullptr) ||
+                    (typeParameters != nullptr && right.typeParameters == nullptr));
         }
         return false;
     }
@@ -2814,6 +2842,7 @@ protected:
             typeParameters = new TTypeParameters;
             typeParameters->arraySizes = new TArraySizes;
             *typeParameters->arraySizes = *copyOf.typeParameters->arraySizes;
+            *typeParameters->spirvType = *copyOf.typeParameters->spirvType;
             typeParameters->basicType = copyOf.basicType;
         }
 

+ 15 - 1
src/libraries/glslang/glslang/Include/intermediate.h

@@ -1,7 +1,7 @@
 //
 // Copyright (C) 2002-2005  3Dlabs Inc. Ltd.
 // Copyright (C) 2012-2016 LunarG, Inc.
-// Copyright (C) 2017 ARM Limited.
+// Copyright (C) 2017, 2022-2024 Arm Limited.
 // Modifications Copyright (C) 2020 Advanced Micro Devices, Inc. All rights reserved.
 //
 // All rights reserved.
@@ -506,6 +506,8 @@ enum TOperator {
     EOpSubgroupShuffleXor,
     EOpSubgroupShuffleUp,
     EOpSubgroupShuffleDown,
+    EOpSubgroupRotate,
+    EOpSubgroupClusteredRotate,
     EOpSubgroupAdd,
     EOpSubgroupMul,
     EOpSubgroupMin,
@@ -538,6 +540,8 @@ enum TOperator {
     EOpSubgroupQuadSwapHorizontal,
     EOpSubgroupQuadSwapVertical,
     EOpSubgroupQuadSwapDiagonal,
+    EOpSubgroupQuadAll,
+    EOpSubgroupQuadAny,
 
     EOpSubgroupPartition,
     EOpSubgroupPartitionedAdd,
@@ -1087,6 +1091,10 @@ enum TOperator {
     EOpWaveActiveCountBits,              // Will decompose to subgroupBallotBitCount(subgroupBallot()).
     EOpWavePrefixCountBits,              // Will decompose to subgroupBallotInclusiveBitCount(subgroupBallot()).
 
+    // GL_EXT_expect_assume
+    EOpAssumeEXT,
+    EOpExpectEXT,
+
     // Shader Clock Ops
     EOpReadClockSubgroupKHR,
     EOpReadClockDeviceKHR,
@@ -1103,6 +1111,12 @@ enum TOperator {
     EOpImageBoxFilterQCOM,
     EOpImageBlockMatchSADQCOM,
     EOpImageBlockMatchSSDQCOM,
+
+    // Image processing2
+    EOpImageBlockMatchWindowSSDQCOM,
+    EOpImageBlockMatchWindowSADQCOM,
+    EOpImageBlockMatchGatherSSDQCOM,
+    EOpImageBlockMatchGatherSADQCOM,
 };
 
 enum TLinkType {

+ 155 - 4
src/libraries/glslang/glslang/MachineIndependent/Initialize.cpp

@@ -2,7 +2,7 @@
 // Copyright (C) 2002-2005  3Dlabs Inc. Ltd.
 // Copyright (C) 2012-2016 LunarG, Inc.
 // Copyright (C) 2015-2020 Google, Inc.
-// Copyright (C) 2017 ARM Limited.
+// Copyright (C) 2017, 2022-2024 Arm Limited.
 // Modifications Copyright (C) 2020-2021 Advanced Micro Devices, Inc. All rights reserved.
 //
 // All rights reserved.
@@ -1465,6 +1465,20 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
             "\n");
     }
 
+    // NV_shader_atomic_fp16_vector
+    if (profile != EEsProfile && version >= 430) {
+        commonBuiltins.append(
+            "f16vec2 atomicAdd(coherent volatile inout f16vec2, f16vec2);"
+            "f16vec4 atomicAdd(coherent volatile inout f16vec4, f16vec4);"
+            "f16vec2 atomicMin(coherent volatile inout f16vec2, f16vec2);"
+            "f16vec4 atomicMin(coherent volatile inout f16vec4, f16vec4);"
+            "f16vec2 atomicMax(coherent volatile inout f16vec2, f16vec2);"
+            "f16vec4 atomicMax(coherent volatile inout f16vec4, f16vec4);"
+            "f16vec2 atomicExchange(coherent volatile inout f16vec2, f16vec2);"
+            "f16vec4 atomicExchange(coherent volatile inout f16vec4, f16vec4);"
+            "\n");
+    }
+
     if ((profile == EEsProfile && version >= 300) ||
         (profile != EEsProfile && version >= 150)) { // GL_ARB_shader_bit_encoding
         commonBuiltins.append(
@@ -2100,6 +2114,8 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
             "%s     subgroupShuffleXor(%s, uint);\n",
             "%s     subgroupShuffleUp(%s, uint delta);\n",
             "%s     subgroupShuffleDown(%s, uint delta);\n",
+            "%s     subgroupRotate(%s, uint);\n",
+            "%s     subgroupClusteredRotate(%s, uint, uint);\n",
             "%s     subgroupAdd(%s);\n",
             "%s     subgroupMul(%s);\n",
             "%s     subgroupMin(%s);\n",
@@ -2228,6 +2244,15 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
             );
     }
 
+    // GL_EXT_shader_quad_control
+    if ((profile == EEsProfile && version >= 310) ||
+        (profile != EEsProfile && version >= 140)) {
+        commonBuiltins.append(
+            "bool subgroupQuadAll(bool);\n"
+            "bool subgroupQuadAny(bool);\n"
+            );
+    }
+
     if (profile != EEsProfile && version >= 460) {
         commonBuiltins.append(
             "bool anyInvocation(bool);"
@@ -4108,6 +4133,37 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
             "u16vec4  unpack16(uint64_t);"
             "i32vec2  unpack32(int64_t);"
             "u32vec2  unpack32(uint64_t);"
+
+            // GL_EXT_expect_assume
+            "int8_t expectEXT(int8_t, int8_t);"
+            "i8vec2 expectEXT(i8vec2, i8vec2);"
+            "i8vec3 expectEXT(i8vec3, i8vec3);"
+            "i8vec4 expectEXT(i8vec4, i8vec4);"
+
+            "uint8_t expectEXT(uint8_t, uint8_t);"
+            "u8vec2 expectEXT(u8vec2, u8vec2);"
+            "u8vec3 expectEXT(u8vec3, u8vec3);"
+            "u8vec4 expectEXT(u8vec4, u8vec4);"
+
+            "int16_t expectEXT(int16_t, int16_t);"
+            "i16vec2 expectEXT(i16vec2, i16vec2);"
+            "i16vec3 expectEXT(i16vec3, i16vec3);"
+            "i16vec4 expectEXT(i16vec4, i16vec4);"
+
+            "uint16_t expectEXT(uint16_t, uint16_t);"
+            "u16vec2 expectEXT(u16vec2, u16vec2);"
+            "u16vec3 expectEXT(u16vec3, u16vec3);"
+            "u16vec4 expectEXT(u16vec4, u16vec4);"
+
+            "int64_t expectEXT(int64_t, int64_t);"
+            "i64vec2 expectEXT(i64vec2, i64vec2);"
+            "i64vec3 expectEXT(i64vec3, i64vec3);"
+            "i64vec4 expectEXT(i64vec4, i64vec4);"
+
+            "uint64_t expectEXT(uint64_t, uint64_t);"
+            "u64vec2 expectEXT(u64vec2, u64vec2);"
+            "u64vec3 expectEXT(u64vec3, u64vec3);"
+            "u64vec4 expectEXT(u64vec4, u64vec4);"
             "\n");
     }
 
@@ -4146,6 +4202,29 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
 
     }
 
+    // GL_EXT_expect_assume
+    if ((profile == EEsProfile && version >= 310) ||
+         ((profile != EEsProfile && version >= 140))) {
+        commonBuiltins.append(
+            "void assumeEXT(bool);"
+
+            "bool expectEXT(bool, bool);"
+            "bvec2 expectEXT(bvec2, bvec2);"
+            "bvec3 expectEXT(bvec3, bvec3);"
+            "bvec4 expectEXT(bvec4, bvec4);"
+
+            "int expectEXT(int, int);"
+            "ivec2 expectEXT(ivec2, ivec2);"
+            "ivec3 expectEXT(ivec3, ivec3);"
+            "ivec4 expectEXT(ivec4, ivec4);"
+
+            "uint expectEXT(uint, uint);"
+            "uvec2 expectEXT(uvec2, uvec2);"
+            "uvec3 expectEXT(uvec3, uvec3);"
+            "uvec4 expectEXT(uvec4, uvec4);"
+            "\n");
+    }
+
     // QCOM_image_processing
     if ((profile == EEsProfile && version >= 310) ||
          (profile != EEsProfile && version >= 140)) {
@@ -4155,6 +4234,11 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
            "vec4 textureBoxFilterQCOM(sampler2D, vec2, vec2);"
            "vec4 textureBlockMatchSADQCOM(sampler2D, uvec2, sampler2D, uvec2, uvec2);"
            "vec4 textureBlockMatchSSDQCOM(sampler2D, uvec2, sampler2D, uvec2, uvec2);"
+
+           "vec4 textureBlockMatchWindowSSDQCOM(sampler2D, uvec2, sampler2D, uvec2, uvec2);"
+           "vec4 textureBlockMatchWindowSADQCOM(sampler2D, uvec2, sampler2D, uvec2, uvec2);"
+           "vec4 textureBlockMatchGatherSSDQCOM(sampler2D, uvec2, sampler2D, uvec2, uvec2);"
+           "vec4 textureBlockMatchGatherSADQCOM(sampler2D, uvec2, sampler2D, uvec2, uvec2);"
            "\n");
     }
 
@@ -6614,6 +6698,34 @@ void TBuiltIns::addImageFunctions(TSampler sampler, const TString& typeName, int
                 commonBuiltins.append(imageParams);
                 commonBuiltins.append(", float);\n");
             }
+
+            // GL_NV_shader_atomic_fp16_vector
+            if (profile != EEsProfile && version >= 430) {
+                const int numFp16Builtins = 4;
+                const char* atomicFp16Func[numFp16Builtins] = {
+                    " imageAtomicAdd(volatile coherent ",
+                    " imageAtomicMin(volatile coherent ",
+                    " imageAtomicMax(volatile coherent ",
+                    " imageAtomicExchange(volatile coherent "
+                };
+                const int numFp16DataTypes = 2;
+                const char* atomicFp16DataTypes[numFp16DataTypes] = {
+                    "f16vec2",
+                    "f16vec4"
+                };
+                // Loop twice to add prototypes with/without scope/semantics
+                for (int j = 0; j < numFp16DataTypes; ++j) {
+                    for (int i = 0; i < numFp16Builtins; ++i) {
+                        commonBuiltins.append(atomicFp16DataTypes[j]);
+                        commonBuiltins.append(atomicFp16Func[i]);
+                        commonBuiltins.append(imageParams);
+                        commonBuiltins.append(", ");
+                        commonBuiltins.append(atomicFp16DataTypes[j]);
+                        commonBuiltins.append(");\n");
+                    }
+                }
+            }
+
             if (profile != EEsProfile && version >= 450) {
                 commonBuiltins.append("float imageAtomicAdd(volatile coherent ");
                 commonBuiltins.append(imageParams);
@@ -8022,7 +8134,7 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion
             symbolTable.setFunctionExtensions("texture2DArrayLod", 1, &E_GL_EXT_texture_array);
             symbolTable.setFunctionExtensions("shadow1DArrayLod", 1, &E_GL_EXT_texture_array);
         }
-        // Fall through
+        [[fallthrough]];
 
     case EShLangTessControl:
         if (profile == EEsProfile && version >= 310) {
@@ -8037,7 +8149,7 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion
                 BuiltInVariable("gl_BoundingBox", EbvBoundingBox, symbolTable);
             }
         }
-        // Fall through
+        [[fallthrough]];
 
     case EShLangTessEvaluation:
     case EShLangGeometry:
@@ -8623,6 +8735,13 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion
                 BuiltInVariable("gl_SubGroupSizeARB", EbvSubGroupSize, symbolTable);
         }
 
+        // GL_EXT_expect_assume
+        if ((profile == EEsProfile && version >= 310) ||
+            (profile != EEsProfile && version >= 140)) {
+            symbolTable.setFunctionExtensions("assumeEXT", 1, &E_GL_EXT_expect_assume);
+            symbolTable.setFunctionExtensions("expectEXT", 1, &E_GL_EXT_expect_assume);
+        }
+
         // GL_KHR_shader_subgroup
         if ((profile == EEsProfile && version >= 310) ||
             (profile != EEsProfile && version >= 140)) {
@@ -8664,6 +8783,8 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion
             symbolTable.setFunctionExtensions("subgroupShuffleXor",              1, &E_GL_KHR_shader_subgroup_shuffle);
             symbolTable.setFunctionExtensions("subgroupShuffleUp",               1, &E_GL_KHR_shader_subgroup_shuffle_relative);
             symbolTable.setFunctionExtensions("subgroupShuffleDown",             1, &E_GL_KHR_shader_subgroup_shuffle_relative);
+            symbolTable.setFunctionExtensions("subgroupRotate",                  1, &E_GL_KHR_shader_subgroup_rotate);
+            symbolTable.setFunctionExtensions("subgroupClusteredRotate",         1, &E_GL_KHR_shader_subgroup_rotate);
             symbolTable.setFunctionExtensions("subgroupAdd",                     1, &E_GL_KHR_shader_subgroup_arithmetic);
             symbolTable.setFunctionExtensions("subgroupMul",                     1, &E_GL_KHR_shader_subgroup_arithmetic);
             symbolTable.setFunctionExtensions("subgroupMin",                     1, &E_GL_KHR_shader_subgroup_arithmetic);
@@ -8782,6 +8903,13 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion
             symbolTable.setVariableExtensions("gl_ShadingRateFlag4HorizontalPixelsEXT", 1, &E_GL_EXT_fragment_shading_rate);
         }
 
+        // GL_EXT_shader_quad_control
+        if ((profile != EEsProfile && version >= 140) ||
+            (profile == EEsProfile && version >= 310)) {
+            symbolTable.setFunctionExtensions("subgroupQuadAll",                     1,  &E_GL_KHR_shader_subgroup_vote);
+            symbolTable.setFunctionExtensions("subgroupQuadAny",                     1,  &E_GL_KHR_shader_subgroup_vote);
+        }
+
         // GL_EXT_shader_tile_image
         symbolTable.setFunctionExtensions("stencilAttachmentReadEXT", 1, &E_GL_EXT_shader_tile_image);
         symbolTable.setFunctionExtensions("depthAttachmentReadEXT", 1, &E_GL_EXT_shader_tile_image);
@@ -8789,10 +8917,16 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion
 
         if ((profile == EEsProfile && version >= 310) ||
             (profile != EEsProfile && version >= 140)) {
+
             symbolTable.setFunctionExtensions("textureWeightedQCOM",      1, &E_GL_QCOM_image_processing);
             symbolTable.setFunctionExtensions("textureBoxFilterQCOM",     1, &E_GL_QCOM_image_processing);
             symbolTable.setFunctionExtensions("textureBlockMatchSADQCOM", 1, &E_GL_QCOM_image_processing);
             symbolTable.setFunctionExtensions("textureBlockMatchSSDQCOM", 1, &E_GL_QCOM_image_processing);
+
+            symbolTable.setFunctionExtensions("textureBlockMatchWindowSSDQCOM", 1, &E_GL_QCOM_image_processing2);
+            symbolTable.setFunctionExtensions("textureBlockMatchWindowSADQCOM", 1, &E_GL_QCOM_image_processing2);
+            symbolTable.setFunctionExtensions("textureBlockMatchGatherSSDQCOM", 1, &E_GL_QCOM_image_processing2);
+            symbolTable.setFunctionExtensions("textureBlockMatchGatherSADQCOM", 1, &E_GL_QCOM_image_processing2);
         }
         break;
 
@@ -9715,6 +9849,8 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion
     symbolTable.relateToOperator("averageRounded",     EOpAverageRounded);
     symbolTable.relateToOperator("multiply32x16",      EOpMul32x16);
     symbolTable.relateToOperator("debugPrintfEXT",     EOpDebugPrintf);
+    symbolTable.relateToOperator("assumeEXT",          EOpAssumeEXT);
+    symbolTable.relateToOperator("expectEXT",          EOpExpectEXT);
 
 
     if (PureOperatorBuiltins) {
@@ -9918,6 +10054,8 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion
             symbolTable.relateToOperator("subgroupShuffleXor",              EOpSubgroupShuffleXor);
             symbolTable.relateToOperator("subgroupShuffleUp",               EOpSubgroupShuffleUp);
             symbolTable.relateToOperator("subgroupShuffleDown",             EOpSubgroupShuffleDown);
+            symbolTable.relateToOperator("subgroupRotate",                  EOpSubgroupRotate);
+            symbolTable.relateToOperator("subgroupClusteredRotate",         EOpSubgroupClusteredRotate);
             symbolTable.relateToOperator("subgroupAdd",                     EOpSubgroupAdd);
             symbolTable.relateToOperator("subgroupMul",                     EOpSubgroupMul);
             symbolTable.relateToOperator("subgroupMin",                     EOpSubgroupMin);
@@ -9980,12 +10118,24 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion
             symbolTable.relateToOperator("shadow2DProjEXT",          EOpTextureProj);
         }
 
+        // GL_EXT_shader_quad_control
+        if ((profile == EEsProfile && version >= 310) ||
+            (profile != EEsProfile && version >= 140)) {
+            symbolTable.relateToOperator("subgroupQuadAll",                     EOpSubgroupQuadAll);
+            symbolTable.relateToOperator("subgroupQuadAny",                     EOpSubgroupQuadAny);
+        }
+
         if ((profile == EEsProfile && version >= 310) ||
             (profile != EEsProfile && version >= 140)) {
             symbolTable.relateToOperator("textureWeightedQCOM",      EOpImageSampleWeightedQCOM);
             symbolTable.relateToOperator("textureBoxFilterQCOM",     EOpImageBoxFilterQCOM);
             symbolTable.relateToOperator("textureBlockMatchSADQCOM", EOpImageBlockMatchSADQCOM);
             symbolTable.relateToOperator("textureBlockMatchSSDQCOM", EOpImageBlockMatchSSDQCOM);
+
+            symbolTable.relateToOperator("textureBlockMatchWindowSSDQCOM", EOpImageBlockMatchWindowSSDQCOM);
+            symbolTable.relateToOperator("textureBlockMatchWindowSADQCOM", EOpImageBlockMatchWindowSADQCOM);
+            symbolTable.relateToOperator("textureBlockMatchGatherSSDQCOM", EOpImageBlockMatchGatherSSDQCOM);
+            symbolTable.relateToOperator("textureBlockMatchGatherSADQCOM", EOpImageBlockMatchGatherSADQCOM);
         }
 
         if (spvVersion.spv == 0) {
@@ -10102,7 +10252,8 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion
         if (profile != EEsProfile && version >= 460) {
             symbolTable.relateToOperator("fetchMicroTriangleVertexPositionNV", EOpFetchMicroTriangleVertexPositionNV);
             symbolTable.relateToOperator("fetchMicroTriangleVertexBarycentricNV", EOpFetchMicroTriangleVertexBarycentricNV);
-        } // fallthrough
+        }
+        [[fallthrough]];
     case EShLangClosestHit:
     case EShLangMiss:
         if (profile != EEsProfile && version >= 460) {

+ 6 - 2
src/libraries/glslang/glslang/MachineIndependent/Intermediate.cpp

@@ -376,6 +376,7 @@ TIntermTyped* TIntermediate::addUnaryMath(TOperator op, TIntermTyped* child,
     case EOpNegative:
         if (child->getType().getBasicType() == EbtStruct || child->getType().isArray())
             return nullptr;
+        break;
     default: break; // some compilers want this
     }
 
@@ -1277,6 +1278,7 @@ void TIntermediate::addBiShapeConversion(TOperator op, TIntermTyped*& lhsNode, T
         // matrix multiply does not change shapes
         if (lhsNode->isMatrix() && rhsNode->isMatrix())
             return;
+        [[fallthrough]];
     case EOpAdd:
     case EOpSub:
     case EOpDiv:
@@ -3489,6 +3491,7 @@ bool TIntermediate::promoteBinary(TIntermBinary& node)
         // check for non-Boolean operands
         if (left->getBasicType() == EbtBool || right->getBasicType() == EbtBool)
             return false;
+        break;
 
     default:
         break;
@@ -3532,13 +3535,14 @@ bool TIntermediate::promoteBinary(TIntermBinary& node)
         if (left->getType() == right->getType())
             return true;
 
-        // Fall through
+        [[fallthrough]];
 
     case EOpMul:
     case EOpMulAssign:
         // At least the basic type has to match
         if (left->getBasicType() != right->getBasicType())
             return false;
+        break;
 
     default:
         break;
@@ -3681,7 +3685,7 @@ bool TIntermediate::promoteBinary(TIntermBinary& node)
     case EOpAssign:
         if (left->getVectorSize() != right->getVectorSize() || left->getMatrixCols() != right->getMatrixCols() || left->getMatrixRows() != right->getMatrixRows())
             return false;
-        // fall through
+        [[fallthrough]];
 
     case EOpAdd:
     case EOpSub:

+ 2 - 1
src/libraries/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);
+    infoSink.info.location(loc, messages & EShMsgAbsolutePath);
     infoSink.info << "'" << szToken <<  "' : " << szReason << " " << szExtraInfo << "\n";
 
     if (prefix == EPrefixError) {
@@ -257,6 +257,7 @@ void TParseContextBase::rValueErrorCheck(const TSourceLoc& loc, const char* op,
             case EOpVectorSwizzle:
             case EOpMatrixSwizzle:
                 rValueErrorCheck(loc, op, binaryNode->getLeft());
+                break;
             default:
                 break;
             }

+ 84 - 13
src/libraries/glslang/glslang/MachineIndependent/ParseHelper.cpp

@@ -1351,6 +1351,10 @@ TIntermTyped* TParseContext::handleFunctionCall(const TSourceLoc& loc, TFunction
             //  - a user function.
 
             // Error check for a function requiring specific extensions present.
+            if (builtIn &&
+                (fnCandidate->getBuiltInOp() == EOpSubgroupQuadAll || fnCandidate->getBuiltInOp() == EOpSubgroupQuadAny))
+                requireExtensions(loc, 1, &E_GL_EXT_shader_quad_control, fnCandidate->getName().c_str());
+
             if (builtIn && fnCandidate->getNumExtensions())
                 requireExtensions(loc, fnCandidate->getNumExtensions(), fnCandidate->getExtensions(), fnCandidate->getName().c_str());
 
@@ -2520,15 +2524,26 @@ void TParseContext::builtInOpCheck(const TSourceLoc& loc, const TFunction& fnCan
                 error(loc, "only supported on image with format r64i", fnCandidate.getName().c_str(), "");
             else if (callNode.getType().getBasicType() == EbtUint64 && imageType.getQualifier().getFormat() != ElfR64ui)
                 error(loc, "only supported on image with format r64ui", fnCandidate.getName().c_str(), "");
+        } else if(callNode.getType().getBasicType() == EbtFloat16 && 
+                ((callNode.getType().getVectorSize() == 2 && arg0->getType().getQualifier().getFormat() == ElfRg16f) ||
+                  (callNode.getType().getVectorSize() == 4 && arg0->getType().getQualifier().getFormat() == ElfRgba16f))) {
+            if (StartsWith(fnCandidate.getName(), "imageAtomicAdd") ||
+                StartsWith(fnCandidate.getName(), "imageAtomicExchange") ||
+                StartsWith(fnCandidate.getName(), "imageAtomicMin") ||
+                StartsWith(fnCandidate.getName(), "imageAtomicMax")) {
+                requireExtensions(loc, 1, &E_GL_NV_shader_atomic_fp16_vector, fnCandidate.getName().c_str());
+            } else {
+                error(loc, "f16vec2/4 operation not supported on: ", fnCandidate.getName().c_str(), "");
+            }
         } else if (imageType.getSampler().type == EbtFloat) {
-            if (fnCandidate.getName().compare(0, 19, "imageAtomicExchange") == 0) {
+            if (StartsWith(fnCandidate.getName(), "imageAtomicExchange")) {
                 // imageAtomicExchange doesn't require an extension
-            } else if ((fnCandidate.getName().compare(0, 14, "imageAtomicAdd") == 0) ||
-                       (fnCandidate.getName().compare(0, 15, "imageAtomicLoad") == 0) ||
-                       (fnCandidate.getName().compare(0, 16, "imageAtomicStore") == 0)) {
+            } else if (StartsWith(fnCandidate.getName(), "imageAtomicAdd") ||
+                       StartsWith(fnCandidate.getName(), "imageAtomicLoad") ||
+                       StartsWith(fnCandidate.getName(), "imageAtomicStore")) {
                 requireExtensions(loc, 1, &E_GL_EXT_shader_atomic_float, fnCandidate.getName().c_str());
-            } else if ((fnCandidate.getName().compare(0, 14, "imageAtomicMin") == 0) ||
-                       (fnCandidate.getName().compare(0, 14, "imageAtomicMax") == 0)) {
+            } else if (StartsWith(fnCandidate.getName(), "imageAtomicMin") ||
+                       StartsWith(fnCandidate.getName(), "imageAtomicMax")) {
                 requireExtensions(loc, 1, &E_GL_EXT_shader_atomic_float2, fnCandidate.getName().c_str());
             } else {
                 error(loc, "only supported on integer images", fnCandidate.getName().c_str(), "");
@@ -2578,6 +2593,11 @@ void TParseContext::builtInOpCheck(const TSourceLoc& loc, const TFunction& fnCan
             const char* const extensions[2] = { E_GL_NV_shader_atomic_int64,
                                                 E_GL_EXT_shader_atomic_int64 };
             requireExtensions(loc, 2, extensions, fnCandidate.getName().c_str());
+        } else if ((callNode.getOp() == EOpAtomicAdd || callNode.getOp() == EOpAtomicExchange ||
+                    callNode.getOp() == EOpAtomicMin || callNode.getOp() == EOpAtomicMax) &&
+                   arg0->getType().getBasicType() == EbtFloat16 && 
+                   (arg0->getType().getVectorSize() == 2 || arg0->getType().getVectorSize() == 4 )) {
+            requireExtensions(loc, 1, &E_GL_NV_shader_atomic_fp16_vector, fnCandidate.getName().c_str());
         } else if ((callNode.getOp() == EOpAtomicAdd || callNode.getOp() == EOpAtomicExchange) &&
                    (arg0->getType().getBasicType() == EbtFloat ||
                     arg0->getType().getBasicType() == EbtDouble)) {
@@ -3986,6 +4006,18 @@ void TParseContext::globalQualifierFixCheck(const TSourceLoc& loc, TQualifier& q
     // Storage qualifier isn't ready for memberQualifierCheck, we should skip invariantCheck for it.
     if (!isMemberCheck || structNestingLevel > 0)
         invariantCheck(loc, qualifier);
+
+    if (qualifier.isFullQuads()) {
+        if (qualifier.storage != EvqVaryingIn)
+            error(loc, "can only apply to input layout", "full_quads ", "");
+        intermediate.setReqFullQuadsMode();
+    }
+
+    if (qualifier.isQuadDeriv()) {
+        if (qualifier.storage != EvqVaryingIn)
+            error(loc, "can only apply to input layout", "quad_derivatives", "");
+        intermediate.setQuadDerivMode();
+    }
 }
 
 //
@@ -5859,6 +5891,15 @@ void TParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publi
             publicType.shaderQualifiers.layoutOverrideCoverage = true;
             return;
         }
+        if (id == "full_quads")
+        {
+            const char* feature = "full_quads qualifier";
+            requireProfile(loc, ECompatibilityProfile | ECoreProfile | EEsProfile, feature);
+            profileRequires(loc, ECoreProfile | ECompatibilityProfile, 140, E_GL_EXT_shader_quad_control, feature);
+            profileRequires(loc, EEsProfile, 310, E_GL_EXT_shader_quad_control, feature);
+            publicType.qualifier.layoutFullQuads = true;
+            return;
+        }
     }
     if (language == EShLangVertex ||
         language == EShLangTessControl ||
@@ -5908,6 +5949,16 @@ void TParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publi
         return;
     }
 
+    if (id == "quad_derivatives")
+    {
+        const char* feature = "quad_derivatives qualifier";
+        requireProfile(loc, ECompatibilityProfile | ECoreProfile | EEsProfile, feature);
+        profileRequires(loc, ECoreProfile | ECompatibilityProfile, 140, E_GL_EXT_shader_quad_control, feature);
+        profileRequires(loc, EEsProfile, 310, E_GL_EXT_shader_quad_control, feature);
+        publicType.qualifier.layoutQuadDeriv = true;
+        return;
+    }
+
     error(loc, "unrecognized layout identifier, or qualifier requires assignment (e.g., binding = 4)", id.c_str(), "");
 }
 
@@ -6209,7 +6260,7 @@ void TParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publi
                 error(loc, "needs a literal integer", "max_primitives", "");
             return;
         }
-        // Fall through
+        [[fallthrough]];
 
     case EShLangTask:
         // Fall through
@@ -6336,6 +6387,10 @@ void TParseContext::mergeObjectLayoutQualifiers(TQualifier& dst, const TQualifie
             dst.layoutSecondaryViewportRelativeOffset = src.layoutSecondaryViewportRelativeOffset;
         if (src.layoutShaderRecord)
             dst.layoutShaderRecord = true;
+        if (src.layoutFullQuads)
+            dst.layoutFullQuads = true;
+        if (src.layoutQuadDeriv)
+            dst.layoutQuadDeriv = true;
         if (src.layoutBindlessSampler)
             dst.layoutBindlessSampler = true;
         if (src.layoutBindlessImage)
@@ -7281,7 +7336,7 @@ TIntermTyped* TParseContext::vkRelaxedRemapFunctionCall(const TSourceLoc& loc, T
             realFunc.addParameter(TParameter().copyParam((*function)[i]));
         }
 
-        TParameter tmpP = { nullptr, &uintType };
+        TParameter tmpP = { nullptr, &uintType, {} };
         realFunc.addParameter(TParameter().copyParam(tmpP));
         arguments = intermediate.growAggregate(arguments, intermediate.addConstantUnion(1, loc, true));
 
@@ -7298,7 +7353,7 @@ TIntermTyped* TParseContext::vkRelaxedRemapFunctionCall(const TSourceLoc& loc, T
             realFunc.addParameter(TParameter().copyParam((*function)[i]));
         }
 
-        TParameter tmpP = { nullptr, &uintType };
+        TParameter tmpP = { nullptr, &uintType, {} };
         realFunc.addParameter(TParameter().copyParam(tmpP));
         arguments = intermediate.growAggregate(arguments, intermediate.addConstantUnion(-1, loc, true));
 
@@ -7358,6 +7413,7 @@ void TParseContext::coopMatTypeParametersCheck(const TSourceLoc& loc, const TPub
         case EbtUint:
         case EbtUint8:
         case EbtUint16:
+        case EbtSpirvType:
             break;
         default:
             error(loc, "coopmat invalid basic type", TType::getBasicString(publicType.typeParameters->basicType), "");
@@ -7581,6 +7637,7 @@ struct AccessChainTraverser : public TIntermTraverser {
     {}
 
     TString path = "";
+    TStorageQualifier topLevelStorageQualifier = TStorageQualifier::EvqLast;
 
     bool visitBinary(TVisit, TIntermBinary* binary) override {
         if (binary->getOp() == EOpIndexDirectStruct)
@@ -7611,6 +7668,8 @@ struct AccessChainTraverser : public TIntermTraverser {
     }
 
     void visitSymbol(TIntermSymbol* symbol) override {
+        if (symbol->getType().isOpaque())
+            topLevelStorageQualifier = symbol->getQualifier().storage;
         if (!IsAnonymous(symbol->getName()))
             path.append(symbol->getName());
     }
@@ -7621,7 +7680,16 @@ TIntermNode* TParseContext::vkRelaxedRemapFunctionArgument(const TSourceLoc& loc
     AccessChainTraverser accessChainTraverser{};
     intermTyped->traverse(&accessChainTraverser);
 
-    TParameter param = { NewPoolTString(accessChainTraverser.path.c_str()), new TType };
+    if (accessChainTraverser.topLevelStorageQualifier == TStorageQualifier::EvqUniform)
+    {
+        TParameter param = { 0, new TType, {} };
+        param.type->shallowCopy(intermTyped->getType());
+
+        function->addParameter(param);
+        return intermTyped;
+    }
+
+    TParameter param = { NewPoolTString(accessChainTraverser.path.c_str()), new TType, {} };
     param.type->shallowCopy(intermTyped->getType());
 
     std::vector<int> newParams = {};
@@ -7740,7 +7808,8 @@ TIntermNode* TParseContext::declareVariable(const TSourceLoc& loc, TString& iden
             error(loc, "unexpected number type parameters", identifier.c_str(), "");
         }
         if (publicType.typeParameters) {
-            if (!isTypeFloat(publicType.typeParameters->basicType) && !isTypeInt(publicType.typeParameters->basicType)) {
+            if (!isTypeFloat(publicType.typeParameters->basicType) &&
+                !isTypeInt(publicType.typeParameters->basicType) && publicType.typeParameters->basicType != EbtSpirvType) {
                 error(loc, "expected 8, 16, 32, or 64 bit signed or unsigned integer or 16, 32, or 64 bit float type", identifier.c_str(), "");
             }
         }
@@ -8379,6 +8448,7 @@ TIntermTyped* TParseContext::constructBuiltIn(const TType& type, TOperator op, T
                 intermediate.addBuiltInFunctionCall(node->getLoc(), EOpConstructUVec2, false, newSrcNode, type);
             return newNode;
         }
+        [[fallthrough]];
     case EOpConstructUVec3:
     case EOpConstructUVec4:
     case EOpConstructUint:
@@ -8400,6 +8470,7 @@ TIntermTyped* TParseContext::constructBuiltIn(const TType& type, TOperator op, T
                 intermediate.addBuiltInFunctionCall(node->getLoc(), EOpPackUint2x32, true, node, type);
             return newNode;
         }
+        [[fallthrough]];
     case EOpConstructDVec2:
     case EOpConstructDVec3:
     case EOpConstructDVec4:
@@ -8552,7 +8623,7 @@ TIntermTyped* TParseContext::constructBuiltIn(const TType& type, TOperator op, T
             TIntermTyped* newNode = intermediate.addBuiltInFunctionCall(node->getLoc(), EOpConvPtrToUint64, true, node, type);
             return newNode;
         }
-        // fall through
+        [[fallthrough]];
     case EOpConstructU64Vec2:
     case EOpConstructU64Vec3:
     case EOpConstructU64Vec4:
@@ -9617,7 +9688,7 @@ void TParseContext::updateStandaloneQualifierDefaults(const TSourceLoc& loc, con
                     error(loc, "cannot apply to 'out'", TQualifier::getGeometryString(publicType.shaderQualifiers.geometry), "");
                     break;
                 }
-                // Fall through
+                [[fallthrough]];
             case ElgPoints:
             case ElgLineStrip:
             case ElgTriangleStrip:

+ 6 - 1
src/libraries/glslang/glslang/MachineIndependent/ShaderLang.cpp

@@ -633,6 +633,7 @@ bool DeduceVersionProfile(TInfoSink& infoSink, EShLanguage stage, bool versionNo
             infoSink.info.message(EPrefixError, "#version: mesh/task shaders require es profile with version 320 or above, or non-es profile with version 450 or above");
             version = profile == EEsProfile ? 320 : 450;
         }
+        break;
     default:
         break;
     }
@@ -1433,7 +1434,8 @@ int ShCompile(
     int /*debugOptions*/,
     int defaultVersion,        // use 100 for ES environment, 110 for desktop
     bool forwardCompatible,    // give errors for use of deprecated features
-    EShMessages messages       // warnings/errors/AST; things to print out
+    EShMessages messages,       // warnings/errors/AST; things to print out,
+    const char *shaderFileName // the filename
     )
 {
     // Map the generic handle to the C++ object
@@ -1449,6 +1451,9 @@ int ShCompile(
 
     compiler->infoSink.info.erase();
     compiler->infoSink.debug.erase();
+    compiler->infoSink.info.setShaderFileName(shaderFileName);
+    compiler->infoSink.debug.setShaderFileName(shaderFileName);
+
 
     TIntermediate intermediate(compiler->getLanguage());
     TShader::ForbidIncluder includer;

+ 1 - 0
src/libraries/glslang/glslang/MachineIndependent/SymbolTable.cpp

@@ -149,6 +149,7 @@ void TType::buildMangledName(TString& mangledName) const
             mangledName += '-';
             (*structure)[i].type->buildMangledName(mangledName);
         }
+        break;
     default:
         break;
     }

+ 20 - 2
src/libraries/glslang/glslang/MachineIndependent/Versions.cpp

@@ -1,7 +1,7 @@
 //
 // Copyright (C) 2002-2005  3Dlabs Inc. Ltd.
 // Copyright (C) 2012-2013 LunarG, Inc.
-// Copyright (C) 2017 ARM Limited.
+// Copyright (C) 2017, 2022-2024 Arm Limited.
 // Copyright (C) 2015-2020 Google, Inc.
 // Modifications Copyright (C) 2020 Advanced Micro Devices, Inc. All rights reserved.
 //
@@ -235,6 +235,7 @@ void TParseVersions::initializeExtensionBehavior()
     extensionBehavior[E_GL_KHR_shader_subgroup_ballot]           = EBhDisable;
     extensionBehavior[E_GL_KHR_shader_subgroup_shuffle]          = EBhDisable;
     extensionBehavior[E_GL_KHR_shader_subgroup_shuffle_relative] = EBhDisable;
+    extensionBehavior[E_GL_KHR_shader_subgroup_rotate]           = EBhDisable;
     extensionBehavior[E_GL_KHR_shader_subgroup_clustered]        = EBhDisable;
     extensionBehavior[E_GL_KHR_shader_subgroup_quad]             = EBhDisable;
     extensionBehavior[E_GL_KHR_memory_scope_semantics]           = EBhDisable;
@@ -258,14 +259,19 @@ void TParseVersions::initializeExtensionBehavior()
     extensionBehavior[E_GL_EXT_shader_16bit_storage]                    = EBhDisable;
     extensionBehavior[E_GL_EXT_shader_8bit_storage]                     = EBhDisable;
     extensionBehavior[E_GL_EXT_subgroup_uniform_control_flow]           = EBhDisable;
+    extensionBehavior[E_GL_EXT_maximal_reconvergence]                   = EBhDisable;
 
     extensionBehavior[E_GL_EXT_fragment_shader_barycentric]             = EBhDisable;
+    extensionBehavior[E_GL_EXT_expect_assume]                           = EBhDisable;
+
+    extensionBehavior[E_GL_EXT_control_flow_attributes2]                = EBhDisable;
 
     extensionBehavior[E_GL_KHR_cooperative_matrix]                      = EBhDisable;
 
     // #line and #include
     extensionBehavior[E_GL_GOOGLE_cpp_style_line_directive]          = EBhDisable;
     extensionBehavior[E_GL_GOOGLE_include_directive]                 = EBhDisable;
+    extensionBehavior[E_GL_ARB_shading_language_include]             = EBhDisable;
 
     extensionBehavior[E_GL_AMD_shader_ballot]                        = EBhDisable;
     extensionBehavior[E_GL_AMD_shader_trinary_minmax]                = EBhDisable;
@@ -302,12 +308,14 @@ void TParseVersions::initializeExtensionBehavior()
     extensionBehavior[E_GL_NV_integer_cooperative_matrix]            = EBhDisable;
     extensionBehavior[E_GL_NV_shader_invocation_reorder]             = EBhDisable;
     extensionBehavior[E_GL_NV_displacement_micromap]                 = EBhDisable;
+    extensionBehavior[E_GL_NV_shader_atomic_fp16_vector]             = EBhDisable;
 
     // ARM
     extensionBehavior[E_GL_ARM_shader_core_builtins]                 = EBhDisable;
 
     // QCOM
     extensionBehavior[E_GL_QCOM_image_processing]                    = EBhDisable;
+    extensionBehavior[E_GL_QCOM_image_processing2]                   = EBhDisable;
 
     // AEP
     extensionBehavior[E_GL_ANDROID_extension_pack_es31a]             = EBhDisable;
@@ -356,6 +364,7 @@ void TParseVersions::initializeExtensionBehavior()
     extensionBehavior[E_GL_EXT_spirv_intrinsics]            = EBhDisable;
     extensionBehavior[E_GL_EXT_mesh_shader]                 = EBhDisable;
     extensionBehavior[E_GL_EXT_opacity_micromap]            = EBhDisable;
+    extensionBehavior[E_GL_EXT_shader_quad_control]         = EBhDisable;
     extensionBehavior[E_GL_EXT_ray_tracing_position_fetch]  = EBhDisable;
     extensionBehavior[E_GL_EXT_shader_tile_image]           = EBhDisable;
     extensionBehavior[E_GL_EXT_texture_shadow_lod]          = EBhDisable;
@@ -439,6 +448,7 @@ void TParseVersions::getPreamble(std::string& preamble)
             "#define GL_EXT_shader_non_constant_global_initializers 1\n"
 
             "#define GL_QCOM_image_processing 1\n"
+            "#define GL_QCOM_image_processing2 1\n"
             ;
 
             if (version >= 300) {
@@ -447,6 +457,7 @@ void TParseVersions::getPreamble(std::string& preamble)
             if (version >= 310) {
                 preamble += "#define GL_EXT_null_initializer 1\n";
                 preamble += "#define GL_EXT_subgroup_uniform_control_flow 1\n";
+                preamble += "#define GL_EXT_maximal_reconvergence 1\n";
             }
 
     } else { // !isEsProfile()
@@ -564,6 +575,7 @@ void TParseVersions::getPreamble(std::string& preamble)
             "#define GL_NV_shader_invocation_reorder 1\n"
 
             "#define GL_QCOM_image_processing 1\n"
+            "#define GL_QCOM_image_processing2 1\n"
 
             "#define GL_EXT_shader_explicit_arithmetic_types 1\n"
             "#define GL_EXT_shader_explicit_arithmetic_types_int8 1\n"
@@ -583,7 +595,10 @@ void TParseVersions::getPreamble(std::string& preamble)
             "#define GL_EXT_shader_atomic_float2 1\n"
 
             "#define GL_EXT_fragment_shader_barycentric 1\n"
+            "#define GL_EXT_shader_quad_control 1\n"
             "#define GL_EXT_texture_array 1\n"
+
+            "#define GL_EXT_control_flow_attributes2 1\n"
             ;
 
         if (spvVersion.spv == 0) {
@@ -600,6 +615,7 @@ void TParseVersions::getPreamble(std::string& preamble)
         if (version >= 140) {
             preamble += "#define GL_EXT_null_initializer 1\n";
             preamble += "#define GL_EXT_subgroup_uniform_control_flow 1\n";
+            preamble += "#define GL_EXT_maximal_reconvergence 1\n";
         }
         if (version >= 130) {
             preamble +="#define GL_FRAGMENT_PRECISION_HIGH 1\n";
@@ -759,7 +775,7 @@ void TParseVersions::profileRequires(const TSourceLoc& loc, int profileMask, int
             switch (getExtensionBehavior(extensions[i])) {
             case EBhWarn:
                 infoSink.info.message(EPrefixWarning, ("extension " + TString(extensions[i]) + " is being used for " + featureDesc).c_str(), loc);
-                // fall through
+                [[fallthrough]];
             case EBhRequire:
             case EBhEnable:
                 okay = true;
@@ -976,6 +992,8 @@ void TParseVersions::updateExtensionBehavior(int line, const char* extension, co
         updateExtensionBehavior(line, "GL_OES_shader_io_blocks", behaviorString);
     else if (strcmp(extension, "GL_GOOGLE_include_directive") == 0)
         updateExtensionBehavior(line, "GL_GOOGLE_cpp_style_line_directive", behaviorString);
+    else if (strcmp(extension, "GL_ARB_shading_language_include") == 0)
+        updateExtensionBehavior(line, "GL_GOOGLE_cpp_style_line_directive", behaviorString);
     // subgroup_* to subgroup_basic
     else if (strcmp(extension, "GL_KHR_shader_subgroup_vote") == 0)
         updateExtensionBehavior(line, "GL_KHR_shader_subgroup_basic", behaviorString);

+ 9 - 1
src/libraries/glslang/glslang/MachineIndependent/Versions.h

@@ -1,7 +1,7 @@
 //
 // Copyright (C) 2002-2005  3Dlabs Inc. Ltd.
 // Copyright (C) 2012-2013 LunarG, Inc.
-// Copyright (C) 2017 ARM Limited.
+// Copyright (C) 2017, 2022-2024 Arm Limited.
 // Copyright (C) 2015-2018 Google, Inc.
 // Modifications Copyright (C) 2020 Advanced Micro Devices, Inc. All rights reserved.
 //
@@ -171,6 +171,7 @@ const char* const E_GL_KHR_shader_subgroup_arithmetic       = "GL_KHR_shader_sub
 const char* const E_GL_KHR_shader_subgroup_ballot           = "GL_KHR_shader_subgroup_ballot";
 const char* const E_GL_KHR_shader_subgroup_shuffle          = "GL_KHR_shader_subgroup_shuffle";
 const char* const E_GL_KHR_shader_subgroup_shuffle_relative = "GL_KHR_shader_subgroup_shuffle_relative";
+const char* const E_GL_KHR_shader_subgroup_rotate           = "GL_KHR_shader_subgroup_rotate";
 const char* const E_GL_KHR_shader_subgroup_clustered        = "GL_KHR_shader_subgroup_clustered";
 const char* const E_GL_KHR_shader_subgroup_quad             = "GL_KHR_shader_subgroup_quad";
 const char* const E_GL_KHR_memory_scope_semantics           = "GL_KHR_memory_scope_semantics";
@@ -215,8 +216,12 @@ const char* const E_GL_EXT_spirv_intrinsics                 = "GL_EXT_spirv_intr
 const char* const E_GL_EXT_fragment_shader_barycentric      = "GL_EXT_fragment_shader_barycentric";
 const char* const E_GL_EXT_mesh_shader                      = "GL_EXT_mesh_shader";
 const char* const E_GL_EXT_opacity_micromap                 = "GL_EXT_opacity_micromap";
+const char* const E_GL_EXT_shader_quad_control              = "GL_EXT_shader_quad_control";
 const char* const E_GL_EXT_draw_instanced                   = "GL_EXT_draw_instanced";
 const char* const E_GL_EXT_texture_array                    = "GL_EXT_texture_array";
+const char* const E_GL_EXT_maximal_reconvergence            = "GL_EXT_maximal_reconvergence";
+const char* const E_GL_EXT_expect_assume                    = "GL_EXT_expect_assume";
+const char* const E_GL_EXT_control_flow_attributes2         = "GL_EXT_control_flow_attributes2";
 
 // Arrays of extensions for the above viewportEXTs duplications
 
@@ -237,6 +242,7 @@ const int Num_OVR_multiview_EXTs = sizeof(OVR_multiview_EXTs) / sizeof(OVR_multi
 // #line and #include
 const char* const E_GL_GOOGLE_cpp_style_line_directive          = "GL_GOOGLE_cpp_style_line_directive";
 const char* const E_GL_GOOGLE_include_directive                 = "GL_GOOGLE_include_directive";
+const char* const E_GL_ARB_shading_language_include             = "GL_ARB_shading_language_include";
 
 const char* const E_GL_AMD_shader_ballot                        = "GL_AMD_shader_ballot";
 const char* const E_GL_AMD_shader_trinary_minmax                = "GL_AMD_shader_trinary_minmax";
@@ -274,6 +280,7 @@ const char* const E_GL_NV_integer_cooperative_matrix            = "GL_NV_integer
 const char* const E_GL_NV_shader_invocation_reorder             = "GL_NV_shader_invocation_reorder";
 const char* const E_GL_EXT_ray_tracing_position_fetch           = "GL_EXT_ray_tracing_position_fetch";
 const char* const E_GL_NV_displacement_micromap                 = "GL_NV_displacement_micromap";
+const char* const E_GL_NV_shader_atomic_fp16_vector             = "GL_NV_shader_atomic_fp16_vector";
 
 // ARM
 const char* const E_GL_ARM_shader_core_builtins                 = "GL_ARM_shader_core_builtins";
@@ -285,6 +292,7 @@ const int Num_viewportEXTs = sizeof(viewportEXTs) / sizeof(viewportEXTs[0]);
 
 
 const char* const E_GL_QCOM_image_processing                    = "GL_QCOM_image_processing";
+const char* const E_GL_QCOM_image_processing2                   = "GL_QCOM_image_processing2";
 
 // AEP
 const char* const E_GL_ANDROID_extension_pack_es31a             = "GL_ANDROID_extension_pack_es31a";

+ 6 - 0
src/libraries/glslang/glslang/MachineIndependent/attribute.cpp

@@ -125,6 +125,8 @@ TAttributeType TParseContext::attributeFromName(const TString& name) const
         return EatSubgroupUniformControlFlow;
     else if (name == "export")
         return EatExport;
+    else if (name == "maximally_reconverges")
+        return EatMaximallyReconverges;
     else
         return EatNone;
 }
@@ -360,6 +362,10 @@ void TParseContext::handleFunctionAttributes(const TSourceLoc& loc, const TAttri
             requireExtensions(loc, 1, &E_GL_EXT_subgroup_uniform_control_flow, "attribute");
             intermediate.setSubgroupUniformControlFlow();
             break;
+        case EatMaximallyReconverges:
+            requireExtensions(loc, 1, &E_GL_EXT_maximal_reconvergence, "attribute");
+            intermediate.setMaximallyReconverges();
+            break;
         default:
             warn(loc, "attribute does not apply to a function", "", "");
             break;

+ 1 - 0
src/libraries/glslang/glslang/MachineIndependent/attribute.h

@@ -121,6 +121,7 @@ namespace glslang {
         EatNonReadable,
         EatSubgroupUniformControlFlow,
         EatExport,
+        EatMaximallyReconverges,
     };
 
     class TIntermAggregate;

File diff suppressed because it is too large
+ 246 - 237
src/libraries/glslang/glslang/MachineIndependent/glslang_tab.cpp


+ 13 - 2
src/libraries/glslang/glslang/MachineIndependent/intermOut.cpp

@@ -1,7 +1,7 @@
 //
 // Copyright (C) 2002-2005  3Dlabs Inc. Ltd.
 // Copyright (C) 2012-2016 LunarG, Inc.
-// Copyright (C) 2017 ARM Limited.
+// Copyright (C) 2017, 2022-2024 Arm Limited.
 // Modifications Copyright (C) 2020 Advanced Micro Devices, Inc. All rights reserved.
 //
 // All rights reserved.
@@ -565,6 +565,8 @@ bool TOutputTraverser::visitUnary(TVisit /* visit */, TIntermUnary* node)
     case EOpSubgroupShuffleXor:              out.debug << "subgroupShuffleXor";              break;
     case EOpSubgroupShuffleUp:               out.debug << "subgroupShuffleUp";               break;
     case EOpSubgroupShuffleDown:             out.debug << "subgroupShuffleDown";             break;
+    case EOpSubgroupRotate:                  out.debug << "subgroupRotate";                  break;
+    case EOpSubgroupClusteredRotate:         out.debug << "subgroupClusteredRotate";         break;
     case EOpSubgroupAdd:                     out.debug << "subgroupAdd";                     break;
     case EOpSubgroupMul:                     out.debug << "subgroupMul";                     break;
     case EOpSubgroupMin:                     out.debug << "subgroupMin";                     break;
@@ -597,6 +599,8 @@ bool TOutputTraverser::visitUnary(TVisit /* visit */, TIntermUnary* node)
     case EOpSubgroupQuadSwapHorizontal:      out.debug << "subgroupQuadSwapHorizontal";      break;
     case EOpSubgroupQuadSwapVertical:        out.debug << "subgroupQuadSwapVertical";        break;
     case EOpSubgroupQuadSwapDiagonal:        out.debug << "subgroupQuadSwapDiagonal";        break;
+    case EOpSubgroupQuadAll:                 out.debug << "subgroupQuadAll";                 break;
+    case EOpSubgroupQuadAny:                 out.debug << "subgroupQuadAny";                 break;
 
     case EOpSubgroupPartition:                          out.debug << "subgroupPartitionNV";                          break;
     case EOpSubgroupPartitionedAdd:                     out.debug << "subgroupPartitionedAddNV";                     break;
@@ -1000,6 +1004,8 @@ bool TOutputTraverser::visitAggregate(TVisit /* visit */, TIntermAggregate* node
     case EOpSubgroupShuffleXor:              out.debug << "subgroupShuffleXor"; break;
     case EOpSubgroupShuffleUp:               out.debug << "subgroupShuffleUp"; break;
     case EOpSubgroupShuffleDown:             out.debug << "subgroupShuffleDown"; break;
+    case EOpSubgroupRotate:                  out.debug << "subgroupRotate"; break;
+    case EOpSubgroupClusteredRotate:         out.debug << "subgroupClusteredRotate"; break;
     case EOpSubgroupAdd:                     out.debug << "subgroupAdd"; break;
     case EOpSubgroupMul:                     out.debug << "subgroupMul"; break;
     case EOpSubgroupMin:                     out.debug << "subgroupMin"; break;
@@ -1032,6 +1038,8 @@ bool TOutputTraverser::visitAggregate(TVisit /* visit */, TIntermAggregate* node
     case EOpSubgroupQuadSwapHorizontal:      out.debug << "subgroupQuadSwapHorizontal"; break;
     case EOpSubgroupQuadSwapVertical:        out.debug << "subgroupQuadSwapVertical"; break;
     case EOpSubgroupQuadSwapDiagonal:        out.debug << "subgroupQuadSwapDiagonal"; break;
+    case EOpSubgroupQuadAll:                 out.debug << "subgroupQuadAll"; break;
+    case EOpSubgroupQuadAny:                 out.debug << "subgroupQuadAny"; break;
 
     case EOpSubgroupPartition:                          out.debug << "subgroupPartitionNV";                          break;
     case EOpSubgroupPartitionedAdd:                     out.debug << "subgroupPartitionedAddNV";                     break;
@@ -1512,6 +1520,9 @@ void TIntermediate::output(TInfoSink& infoSink, bool tree)
     if (getSubgroupUniformControlFlow())
         infoSink.debug << "subgroup_uniform_control_flow\n";
 
+    if (getMaximallyReconverges())
+        infoSink.debug << "maximally_reconverges\n";
+
     switch (language) {
     case EShLangVertex:
         break;
@@ -1576,7 +1587,7 @@ void TIntermediate::output(TInfoSink& infoSink, bool tree)
         infoSink.debug << "max_vertices = " << vertices << "\n";
         infoSink.debug << "max_primitives = " << primitives << "\n";
         infoSink.debug << "output primitive = " << TQualifier::getGeometryString(outputPrimitive) << "\n";
-        // Fall through
+        [[fallthrough]];
     case EShLangTask:
         // Fall through
     case EShLangCompute:

+ 2 - 2
src/libraries/glslang/glslang/MachineIndependent/iomapper.cpp

@@ -85,7 +85,7 @@ public:
             addGlobalReference(base->getAccessName());
 
         if (target) {
-            TVarEntryInfo ent = {base->getId(), base, ! traverseAll};
+            TVarEntryInfo ent = {base->getId(), base, ! traverseAll, {}, {}, {}, {}, {}, {}, {}};
             ent.stage = intermediate.getStage();
             TVarLiveMap::iterator at = target->find(
                 ent.symbol->getAccessName()); // std::lower_bound(target->begin(), target->end(), ent, TVarEntryInfo::TOrderById());
@@ -124,7 +124,7 @@ public:
         else
             return;
 
-        TVarEntryInfo ent = { base->getId() };
+        TVarEntryInfo ent = { base->getId(), {}, {}, {}, {}, {}, {}, {}, {}, {} };
         // Fix a defect, when block has no instance name, we need to find its block name
         TVarLiveMap::const_iterator at = source->find(base->getAccessName());
         if (at == source->end())

+ 1 - 1
src/libraries/glslang/glslang/MachineIndependent/linkValidate.cpp

@@ -1350,7 +1350,7 @@ void TIntermediate::finalCheck(TInfoSink& infoSink, bool keepUncalled)
             error(infoSink, "At least one shader must specify a layout(max_vertices = value)");
         if (primitives == TQualifier::layoutNotSet)
             error(infoSink, "At least one shader must specify a layout(max_primitives = value)");
-        // fall through
+        [[fallthrough]];
     case EShLangTask:
         if (numTaskNVBlocks > 1)
             error(infoSink, "Only one taskNV interface block is allowed per shader");

+ 13 - 1
src/libraries/glslang/glslang/MachineIndependent/localintermediate.h

@@ -345,10 +345,12 @@ public:
         needToLegalize(false),
         binaryDoubleOutput(false),
         subgroupUniformControlFlow(false),
+        maximallyReconverges(false),
         usePhysicalStorageBuffer(false),
         spirvRequirement(nullptr),
         spirvExecutionMode(nullptr),
-        uniformLocationBase(0)
+        uniformLocationBase(0),
+        quadDerivMode(false), reqFullQuadsMode(false)
     {
         localSize[0] = 1;
         localSize[1] = 1;
@@ -857,6 +859,10 @@ public:
 
     void setXfbMode() { xfbMode = true; }
     bool getXfbMode() const { return xfbMode; }
+    void setQuadDerivMode(bool mode = true) { quadDerivMode = mode; }
+    bool getQuadDerivMode() const { return quadDerivMode; }
+    void setReqFullQuadsMode(bool mode = true) { reqFullQuadsMode = mode; }
+    bool getReqFullQuadsMode() const { return reqFullQuadsMode; }
     void setMultiStream() { multiStream = true; }
     bool isMultiStream() const { return multiStream; }
     bool setOutputPrimitive(TLayoutGeometry p)
@@ -963,6 +969,9 @@ public:
     void setSubgroupUniformControlFlow() { subgroupUniformControlFlow = true; }
     bool getSubgroupUniformControlFlow() const { return subgroupUniformControlFlow; }
 
+    void setMaximallyReconverges() { maximallyReconverges = true; }
+    bool getMaximallyReconverges() const { return maximallyReconverges; }
+
     // GL_EXT_spirv_intrinsics
     void insertSpirvRequirement(const TSpirvRequirement* spirvReq);
     bool hasSpirvRequirement() const { return spirvRequirement != nullptr; }
@@ -1226,6 +1235,7 @@ protected:
     bool needToLegalize;
     bool binaryDoubleOutput;
     bool subgroupUniformControlFlow;
+    bool maximallyReconverges;
     bool usePhysicalStorageBuffer;
 
     TSpirvRequirement* spirvRequirement;
@@ -1234,6 +1244,8 @@ protected:
     std::map<TString, AstRefType> bindlessImageModeCaller;
     std::unordered_map<std::string, int> uniformLocationOverrides;
     int uniformLocationBase;
+    bool quadDerivMode;
+    bool reqFullQuadsMode;
     TNumericFeatures numericFeatures;
     std::unordered_map<std::string, TBlockStorageClass> blockBackingOverrides;
 

+ 5 - 0
src/libraries/glslang/glslang/MachineIndependent/parseVersions.h

@@ -83,6 +83,11 @@ public:
         const char* featureDesc);
     virtual void ppRequireExtensions(const TSourceLoc&, int numExtensions, const char* const extensions[],
         const char* featureDesc);
+    template<typename Container>
+    constexpr void ppRequireExtensions(const TSourceLoc& loc, Container extensions, const char* featureDesc) {
+        ppRequireExtensions(loc, static_cast<int>(extensions.size()), extensions.data(), featureDesc);
+    }
+
     virtual TExtensionBehavior getExtensionBehavior(const char*);
     virtual bool extensionTurnedOn(const char* const extension);
     virtual bool extensionsTurnedOn(int numExtensions, const char* const extensions[]);

+ 2 - 1
src/libraries/glslang/glslang/MachineIndependent/preprocessor/Pp.cpp

@@ -973,7 +973,8 @@ int TPpContext::readCPPline(TPpToken* ppToken)
             break;
         case PpAtomInclude:
             if(!parseContext.isReadingHLSL()) {
-                parseContext.ppRequireExtensions(ppToken->loc, 1, &E_GL_GOOGLE_include_directive, "#include");
+                const std::array exts = { E_GL_GOOGLE_include_directive, E_GL_ARB_shading_language_include };
+                parseContext.ppRequireExtensions(ppToken->loc, exts, "#include");
             }
             token = CPPinclude(ppToken);
             break;

+ 76 - 57
src/libraries/glslang/glslang/MachineIndependent/reflection.cpp

@@ -714,69 +714,73 @@ public:
             case EbtFloat:
                 switch ((int)sampler.dim) {
                 case Esd1D:
-                    switch ((int)sampler.shadow) {
-                    case false: return sampler.arrayed ? GL_SAMPLER_1D_ARRAY : GL_SAMPLER_1D;
-                    case true:  return sampler.arrayed ? GL_SAMPLER_1D_ARRAY_SHADOW : GL_SAMPLER_1D_SHADOW;
-                    }
+                    if (sampler.shadow)
+                        return sampler.arrayed ? GL_SAMPLER_1D_ARRAY_SHADOW : GL_SAMPLER_1D_SHADOW;
+                    else
+                        return sampler.arrayed ? GL_SAMPLER_1D_ARRAY : GL_SAMPLER_1D;
                 case Esd2D:
-                    switch ((int)sampler.ms) {
-                    case false:
-                        switch ((int)sampler.shadow) {
-                        case false: return sampler.arrayed ? GL_SAMPLER_2D_ARRAY : GL_SAMPLER_2D;
-                        case true:  return sampler.arrayed ? GL_SAMPLER_2D_ARRAY_SHADOW : GL_SAMPLER_2D_SHADOW;
-                        }
-                    case true:      return sampler.arrayed ? GL_SAMPLER_2D_MULTISAMPLE_ARRAY : GL_SAMPLER_2D_MULTISAMPLE;
+                    if (sampler.ms) {
+                        return sampler.arrayed ? GL_SAMPLER_2D_MULTISAMPLE_ARRAY : GL_SAMPLER_2D_MULTISAMPLE;
+                    } else {
+                        if (sampler.shadow)
+                            return sampler.arrayed ? GL_SAMPLER_2D_ARRAY_SHADOW : GL_SAMPLER_2D_SHADOW;
+                        else
+                            return sampler.arrayed ? GL_SAMPLER_2D_ARRAY : GL_SAMPLER_2D;
                     }
                 case Esd3D:
                     return GL_SAMPLER_3D;
                 case EsdCube:
-                    switch ((int)sampler.shadow) {
-                    case false: return sampler.arrayed ? GL_SAMPLER_CUBE_MAP_ARRAY : GL_SAMPLER_CUBE;
-                    case true:  return sampler.arrayed ? GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW : GL_SAMPLER_CUBE_SHADOW;
-                    }
+                    if (sampler.shadow)
+                        return sampler.arrayed ? GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW : GL_SAMPLER_CUBE_SHADOW;
+                    else
+                        return sampler.arrayed ? GL_SAMPLER_CUBE_MAP_ARRAY : GL_SAMPLER_CUBE;
                 case EsdRect:
                     return sampler.shadow ? GL_SAMPLER_2D_RECT_SHADOW : GL_SAMPLER_2D_RECT;
                 case EsdBuffer:
                     return GL_SAMPLER_BUFFER;
+                default:
+                    return 0;
                 }
             case EbtFloat16:
                 switch ((int)sampler.dim) {
                 case Esd1D:
-                    switch ((int)sampler.shadow) {
-                    case false: return sampler.arrayed ? GL_FLOAT16_SAMPLER_1D_ARRAY_AMD : GL_FLOAT16_SAMPLER_1D_AMD;
-                    case true:  return sampler.arrayed ? GL_FLOAT16_SAMPLER_1D_ARRAY_SHADOW_AMD : GL_FLOAT16_SAMPLER_1D_SHADOW_AMD;
-                    }
+                    if (sampler.shadow)
+                        return sampler.arrayed ? GL_FLOAT16_SAMPLER_1D_ARRAY_SHADOW_AMD : GL_FLOAT16_SAMPLER_1D_SHADOW_AMD;
+                    else
+                        return sampler.arrayed ? GL_FLOAT16_SAMPLER_1D_ARRAY_AMD : GL_FLOAT16_SAMPLER_1D_AMD;
                 case Esd2D:
-                    switch ((int)sampler.ms) {
-                    case false:
-                        switch ((int)sampler.shadow) {
-                        case false: return sampler.arrayed ? GL_FLOAT16_SAMPLER_2D_ARRAY_AMD : GL_FLOAT16_SAMPLER_2D_AMD;
-                        case true:  return sampler.arrayed ? GL_FLOAT16_SAMPLER_2D_ARRAY_SHADOW_AMD : GL_FLOAT16_SAMPLER_2D_SHADOW_AMD;
-                        }
-                    case true:      return sampler.arrayed ? GL_FLOAT16_SAMPLER_2D_MULTISAMPLE_ARRAY_AMD : GL_FLOAT16_SAMPLER_2D_MULTISAMPLE_AMD;
+                    if (sampler.ms) {
+                        return sampler.arrayed ? GL_FLOAT16_SAMPLER_2D_MULTISAMPLE_ARRAY_AMD : GL_FLOAT16_SAMPLER_2D_MULTISAMPLE_AMD;
+                    } else {
+                        if (sampler.shadow)
+                            return sampler.arrayed ? GL_FLOAT16_SAMPLER_2D_ARRAY_SHADOW_AMD : GL_FLOAT16_SAMPLER_2D_SHADOW_AMD;
+                        else
+                            return sampler.arrayed ? GL_FLOAT16_SAMPLER_2D_ARRAY_AMD : GL_FLOAT16_SAMPLER_2D_AMD;
                     }
                 case Esd3D:
                     return GL_FLOAT16_SAMPLER_3D_AMD;
                 case EsdCube:
-                    switch ((int)sampler.shadow) {
-                    case false: return sampler.arrayed ? GL_FLOAT16_SAMPLER_CUBE_MAP_ARRAY_AMD : GL_FLOAT16_SAMPLER_CUBE_AMD;
-                    case true:  return sampler.arrayed ? GL_FLOAT16_SAMPLER_CUBE_MAP_ARRAY_SHADOW_AMD : GL_FLOAT16_SAMPLER_CUBE_SHADOW_AMD;
-                    }
+                    if (sampler.shadow)
+                        return sampler.arrayed ? GL_FLOAT16_SAMPLER_CUBE_MAP_ARRAY_SHADOW_AMD : GL_FLOAT16_SAMPLER_CUBE_SHADOW_AMD;
+                    else
+                        return sampler.arrayed ? GL_FLOAT16_SAMPLER_CUBE_MAP_ARRAY_AMD : GL_FLOAT16_SAMPLER_CUBE_AMD;
                 case EsdRect:
                     return sampler.shadow ? GL_FLOAT16_SAMPLER_2D_RECT_SHADOW_AMD : GL_FLOAT16_SAMPLER_2D_RECT_AMD;
                 case EsdBuffer:
                     return GL_FLOAT16_SAMPLER_BUFFER_AMD;
+                default:
+                    return 0;
                 }
             case EbtInt:
                 switch ((int)sampler.dim) {
                 case Esd1D:
                     return sampler.arrayed ? GL_INT_SAMPLER_1D_ARRAY : GL_INT_SAMPLER_1D;
                 case Esd2D:
-                    switch ((int)sampler.ms) {
-                    case false:  return sampler.arrayed ? GL_INT_SAMPLER_2D_ARRAY : GL_INT_SAMPLER_2D;
-                    case true:   return sampler.arrayed ? GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY
-                                                        : GL_INT_SAMPLER_2D_MULTISAMPLE;
-                    }
+                    if (sampler.ms)
+                        return sampler.arrayed ? GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY
+                                               : GL_INT_SAMPLER_2D_MULTISAMPLE;
+                    else
+                        return sampler.arrayed ? GL_INT_SAMPLER_2D_ARRAY : GL_INT_SAMPLER_2D;
                 case Esd3D:
                     return GL_INT_SAMPLER_3D;
                 case EsdCube:
@@ -785,17 +789,19 @@ public:
                     return GL_INT_SAMPLER_2D_RECT;
                 case EsdBuffer:
                     return GL_INT_SAMPLER_BUFFER;
+                default:
+                    return 0;
                 }
             case EbtUint:
                 switch ((int)sampler.dim) {
                 case Esd1D:
                     return sampler.arrayed ? GL_UNSIGNED_INT_SAMPLER_1D_ARRAY : GL_UNSIGNED_INT_SAMPLER_1D;
                 case Esd2D:
-                    switch ((int)sampler.ms) {
-                    case false:  return sampler.arrayed ? GL_UNSIGNED_INT_SAMPLER_2D_ARRAY : GL_UNSIGNED_INT_SAMPLER_2D;
-                    case true:   return sampler.arrayed ? GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY
-                                                        : GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE;
-                    }
+                    if (sampler.ms)
+                        return sampler.arrayed ? GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY
+                                               : GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE;
+                    else
+                        return sampler.arrayed ? GL_UNSIGNED_INT_SAMPLER_2D_ARRAY : GL_UNSIGNED_INT_SAMPLER_2D;
                 case Esd3D:
                     return GL_UNSIGNED_INT_SAMPLER_3D;
                 case EsdCube:
@@ -804,6 +810,8 @@ public:
                     return GL_UNSIGNED_INT_SAMPLER_2D_RECT;
                 case EsdBuffer:
                     return GL_UNSIGNED_INT_SAMPLER_BUFFER;
+                default:
+                    return 0;
                 }
             default:
                 return 0;
@@ -816,10 +824,10 @@ public:
                 case Esd1D:
                     return sampler.arrayed ? GL_IMAGE_1D_ARRAY : GL_IMAGE_1D;
                 case Esd2D:
-                    switch ((int)sampler.ms) {
-                    case false:     return sampler.arrayed ? GL_IMAGE_2D_ARRAY : GL_IMAGE_2D;
-                    case true:      return sampler.arrayed ? GL_IMAGE_2D_MULTISAMPLE_ARRAY : GL_IMAGE_2D_MULTISAMPLE;
-                    }
+                    if (sampler.ms)
+                        return sampler.arrayed ? GL_IMAGE_2D_MULTISAMPLE_ARRAY : GL_IMAGE_2D_MULTISAMPLE;
+                    else
+                        return sampler.arrayed ? GL_IMAGE_2D_ARRAY : GL_IMAGE_2D;
                 case Esd3D:
                     return GL_IMAGE_3D;
                 case EsdCube:
@@ -828,16 +836,18 @@ public:
                     return GL_IMAGE_2D_RECT;
                 case EsdBuffer:
                     return GL_IMAGE_BUFFER;
+                default:
+                    return 0;
                 }
             case EbtFloat16:
                 switch ((int)sampler.dim) {
                 case Esd1D:
                     return sampler.arrayed ? GL_FLOAT16_IMAGE_1D_ARRAY_AMD : GL_FLOAT16_IMAGE_1D_AMD;
                 case Esd2D:
-                    switch ((int)sampler.ms) {
-                    case false:     return sampler.arrayed ? GL_FLOAT16_IMAGE_2D_ARRAY_AMD : GL_FLOAT16_IMAGE_2D_AMD;
-                    case true:      return sampler.arrayed ? GL_FLOAT16_IMAGE_2D_MULTISAMPLE_ARRAY_AMD : GL_FLOAT16_IMAGE_2D_MULTISAMPLE_AMD;
-                    }
+                    if (sampler.ms)
+                        return sampler.arrayed ? GL_FLOAT16_IMAGE_2D_MULTISAMPLE_ARRAY_AMD : GL_FLOAT16_IMAGE_2D_MULTISAMPLE_AMD;
+                    else
+                        return sampler.arrayed ? GL_FLOAT16_IMAGE_2D_ARRAY_AMD : GL_FLOAT16_IMAGE_2D_AMD;
                 case Esd3D:
                     return GL_FLOAT16_IMAGE_3D_AMD;
                 case EsdCube:
@@ -846,16 +856,18 @@ public:
                     return GL_FLOAT16_IMAGE_2D_RECT_AMD;
                 case EsdBuffer:
                     return GL_FLOAT16_IMAGE_BUFFER_AMD;
+                default:
+                    return 0;
                 }
             case EbtInt:
                 switch ((int)sampler.dim) {
                 case Esd1D:
                     return sampler.arrayed ? GL_INT_IMAGE_1D_ARRAY : GL_INT_IMAGE_1D;
                 case Esd2D:
-                    switch ((int)sampler.ms) {
-                    case false:  return sampler.arrayed ? GL_INT_IMAGE_2D_ARRAY : GL_INT_IMAGE_2D;
-                    case true:   return sampler.arrayed ? GL_INT_IMAGE_2D_MULTISAMPLE_ARRAY : GL_INT_IMAGE_2D_MULTISAMPLE;
-                    }
+                    if (sampler.ms)
+                        return sampler.arrayed ? GL_INT_IMAGE_2D_MULTISAMPLE_ARRAY : GL_INT_IMAGE_2D_MULTISAMPLE;
+                    else
+                        return sampler.arrayed ? GL_INT_IMAGE_2D_ARRAY : GL_INT_IMAGE_2D;
                 case Esd3D:
                     return GL_INT_IMAGE_3D;
                 case EsdCube:
@@ -864,17 +876,19 @@ public:
                     return GL_INT_IMAGE_2D_RECT;
                 case EsdBuffer:
                     return GL_INT_IMAGE_BUFFER;
+                default:
+                    return 0;
                 }
             case EbtUint:
                 switch ((int)sampler.dim) {
                 case Esd1D:
                     return sampler.arrayed ? GL_UNSIGNED_INT_IMAGE_1D_ARRAY : GL_UNSIGNED_INT_IMAGE_1D;
                 case Esd2D:
-                    switch ((int)sampler.ms) {
-                    case false:  return sampler.arrayed ? GL_UNSIGNED_INT_IMAGE_2D_ARRAY : GL_UNSIGNED_INT_IMAGE_2D;
-                    case true:   return sampler.arrayed ? GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE_ARRAY
-                                                        : GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE;
-                    }
+                    if (sampler.ms)
+                        return sampler.arrayed ? GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE_ARRAY
+                                               : GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE;
+                    else
+                        return sampler.arrayed ? GL_UNSIGNED_INT_IMAGE_2D_ARRAY : GL_UNSIGNED_INT_IMAGE_2D;
                 case Esd3D:
                     return GL_UNSIGNED_INT_IMAGE_3D;
                 case EsdCube:
@@ -883,6 +897,8 @@ public:
                     return GL_UNSIGNED_INT_IMAGE_2D_RECT;
                 case EsdBuffer:
                     return GL_UNSIGNED_INT_IMAGE_BUFFER;
+                default:
+                    return 0;
                 }
             default:
                 return 0;
@@ -947,6 +963,7 @@ public:
                     case 4:    return GL_FLOAT_MAT4;
                     default:   return 0;
                     }
+                default: return 0;
                 }
             case EbtDouble:
                 switch (type.getMatrixCols()) {
@@ -971,6 +988,7 @@ public:
                     case 4:    return GL_DOUBLE_MAT4;
                     default:   return 0;
                     }
+                default: return 0;
                 }
             case EbtFloat16:
                 switch (type.getMatrixCols()) {
@@ -995,6 +1013,7 @@ public:
                     case 4:    return GL_FLOAT16_MAT4_AMD;
                     default:   return 0;
                     }
+                default: return 0;
                 }
             default:
                 return 0;

+ 20 - 18
src/libraries/glslang/glslang/Public/ShaderLang.h

@@ -253,23 +253,24 @@ typedef enum {
 // Message choices for what errors and warnings are given.
 //
 enum EShMessages : unsigned {
-    EShMsgDefault          = 0,         // default is to give all required errors and extra warnings
-    EShMsgRelaxedErrors    = (1 << 0),  // be liberal in accepting input
-    EShMsgSuppressWarnings = (1 << 1),  // suppress all warnings, except those required by the specification
-    EShMsgAST              = (1 << 2),  // print the AST intermediate representation
-    EShMsgSpvRules         = (1 << 3),  // issue messages for SPIR-V generation
-    EShMsgVulkanRules      = (1 << 4),  // issue messages for Vulkan-requirements of GLSL for SPIR-V
-    EShMsgOnlyPreprocessor = (1 << 5),  // only print out errors produced by the preprocessor
-    EShMsgReadHlsl         = (1 << 6),  // use HLSL parsing rules and semantics
-    EShMsgCascadingErrors  = (1 << 7),  // get cascading errors; risks error-recovery issues, instead of an early exit
-    EShMsgKeepUncalled     = (1 << 8),  // for testing, don't eliminate uncalled functions
-    EShMsgHlslOffsets      = (1 << 9),  // allow block offsets to follow HLSL rules instead of GLSL rules
-    EShMsgDebugInfo        = (1 << 10), // save debug information
-    EShMsgHlslEnable16BitTypes  = (1 << 11), // enable use of 16-bit types in SPIR-V for HLSL
-    EShMsgHlslLegalization  = (1 << 12), // enable HLSL Legalization messages
-    EShMsgHlslDX9Compatible = (1 << 13), // enable HLSL DX9 compatible mode (for samplers and semantics)
-    EShMsgBuiltinSymbolTable = (1 << 14), // print the builtin symbol table
-    EShMsgEnhanced         = (1 << 15), // enhanced message readability
+    EShMsgDefault              = 0,         // default is to give all required errors and extra warnings
+    EShMsgRelaxedErrors        = (1 << 0),  // be liberal in accepting input
+    EShMsgSuppressWarnings     = (1 << 1),  // suppress all warnings, except those required by the specification
+    EShMsgAST                  = (1 << 2),  // print the AST intermediate representation
+    EShMsgSpvRules             = (1 << 3),  // issue messages for SPIR-V generation
+    EShMsgVulkanRules          = (1 << 4),  // issue messages for Vulkan-requirements of GLSL for SPIR-V
+    EShMsgOnlyPreprocessor     = (1 << 5),  // only print out errors produced by the preprocessor
+    EShMsgReadHlsl             = (1 << 6),  // use HLSL parsing rules and semantics
+    EShMsgCascadingErrors      = (1 << 7),  // get cascading errors; risks error-recovery issues, instead of an early exit
+    EShMsgKeepUncalled         = (1 << 8),  // for testing, don't eliminate uncalled functions
+    EShMsgHlslOffsets          = (1 << 9),  // allow block offsets to follow HLSL rules instead of GLSL rules
+    EShMsgDebugInfo            = (1 << 10), // save debug information
+    EShMsgHlslEnable16BitTypes = (1 << 11), // enable use of 16-bit types in SPIR-V for HLSL
+    EShMsgHlslLegalization     = (1 << 12), // enable HLSL Legalization messages
+    EShMsgHlslDX9Compatible    = (1 << 13), // enable HLSL DX9 compatible mode (for samplers and semantics)
+    EShMsgBuiltinSymbolTable   = (1 << 14), // print the builtin symbol table
+    EShMsgEnhanced             = (1 << 15), // enhanced message readability
+    EShMsgAbsolutePath         = (1 << 16), // Output Absolute path for messages
     LAST_ELEMENT_MARKER(EShMsgCount),
 };
 
@@ -336,7 +337,8 @@ GLSLANG_EXPORT int ShCompile(const ShHandle, const char* const shaderStrings[],
                              int,                      // debugOptions unused
                              int defaultVersion = 110, // use 100 for ES environment, overridden by #version in shader
                              bool forwardCompatible = false,      // give errors for use of deprecated features
-                             EShMessages messages = EShMsgDefault // warnings and errors
+                             EShMessages messages = EShMsgDefault, // warnings and errors
+                             const char* fileName = nullptr
 );
 
 GLSLANG_EXPORT int ShLinkExt(

Some files were not shown because too many files changed in this diff