Merge pull request #1796 from Igalia/siglesias/fix-gl_SubGroupSizeARB-tese-geom

Add missing GL_ARB_shader_ballot builtins to Geometry and Tessellatio…
diff --git a/SPIRV/GLSL.ext.KHR.h b/SPIRV/GLSL.ext.KHR.h
index 333442b..bcc6087 100644
--- a/SPIRV/GLSL.ext.KHR.h
+++ b/SPIRV/GLSL.ext.KHR.h
@@ -41,5 +41,6 @@
 static const char* const E_SPV_KHR_post_depth_coverage          = "SPV_KHR_post_depth_coverage";
 static const char* const E_SPV_KHR_vulkan_memory_model          = "SPV_KHR_vulkan_memory_model";
 static const char* const E_SPV_EXT_physical_storage_buffer      = "SPV_EXT_physical_storage_buffer";
+static const char* const E_SPV_EXT_fragment_shader_interlock    = "SPV_EXT_fragment_shader_interlock";
 
 #endif  // #ifndef GLSLextKHR_H
diff --git a/SPIRV/GLSL.ext.NV.h b/SPIRV/GLSL.ext.NV.h
index ede2c57..50146da 100644
--- a/SPIRV/GLSL.ext.NV.h
+++ b/SPIRV/GLSL.ext.NV.h
@@ -75,4 +75,7 @@
 //SPV_NV_cooperative_matrix
 const char* const E_SPV_NV_cooperative_matrix = "SPV_NV_cooperative_matrix";
 
+//SPV_NV_shader_sm_builtins
+const char* const E_SPV_NV_shader_sm_builtins = "SPV_NV_shader_sm_builtins";
+
 #endif  // #ifndef GLSLextNV_H
diff --git a/SPIRV/GlslangToSpv.cpp b/SPIRV/GlslangToSpv.cpp
index c513cd1..9ad19b5 100644
--- a/SPIRV/GlslangToSpv.cpp
+++ b/SPIRV/GlslangToSpv.cpp
@@ -169,7 +169,7 @@
     void makeGlobalInitializers(const glslang::TIntermSequence&);
     void visitFunctions(const glslang::TIntermSequence&);
     void handleFunctionEntry(const glslang::TIntermAggregate* node);
-    void translateArguments(const glslang::TIntermAggregate& node, std::vector<spv::Id>& arguments);
+    void translateArguments(const glslang::TIntermAggregate& node, std::vector<spv::Id>& arguments, spv::Builder::AccessChain::CoherentFlags &lvalueCoherentFlags);
     void translateArguments(glslang::TIntermUnary& node, std::vector<spv::Id>& arguments);
     spv::Id createImageTextureFunctionCall(glslang::TIntermOperator* node);
     spv::Id handleUserFunctionCall(const glslang::TIntermAggregate*);
@@ -178,14 +178,14 @@
                                   glslang::TBasicType typeProxy, bool reduceComparison = true);
     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);
+                                 glslang::TBasicType typeProxy, const spv::Builder::AccessChain::CoherentFlags &lvalueCoherentFlags);
     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,
                              glslang::TBasicType typeProxy);
     spv::Id createIntWidthConversion(glslang::TOperator op, spv::Id operand, int vectorSize);
     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);
+    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);
     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, spv::Id typeId, std::vector<spv::Id>& operands);
     spv::Id createSubgroupOperation(glslang::TOperator op, spv::Id typeId, std::vector<spv::Id>& operands, glslang::TBasicType typeProxy);
@@ -946,6 +946,24 @@
     case glslang::EbvMeshViewIndicesNV:
         return spv::BuiltInMeshViewIndicesNV;
 #endif
+
+    // sm builtins
+    case glslang::EbvWarpsPerSM:
+        builder.addExtension(spv::E_SPV_NV_shader_sm_builtins);
+        builder.addCapability(spv::CapabilityShaderSMBuiltinsNV);
+        return spv::BuiltInWarpsPerSMNV;
+    case glslang::EbvSMCount:
+        builder.addExtension(spv::E_SPV_NV_shader_sm_builtins);
+        builder.addCapability(spv::CapabilityShaderSMBuiltinsNV);
+        return spv::BuiltInSMCountNV;
+    case glslang::EbvWarpID:
+        builder.addExtension(spv::E_SPV_NV_shader_sm_builtins);
+        builder.addCapability(spv::CapabilityShaderSMBuiltinsNV);
+        return spv::BuiltInWarpIDNV;
+    case glslang::EbvSMID:
+        builder.addExtension(spv::E_SPV_NV_shader_sm_builtins);
+        builder.addCapability(spv::CapabilityShaderSMBuiltinsNV);
+        return spv::BuiltInSMIDNV;
     default:
         return spv::BuiltInMax;
     }
@@ -1469,6 +1487,30 @@
 
         if (glslangIntermediate->getDepth() != glslang::EldUnchanged && glslangIntermediate->isDepthReplacing())
             builder.addExecutionMode(shaderEntry, spv::ExecutionModeDepthReplacing);
+
+        switch (glslangIntermediate->getInterlockOrdering()) {
+        case glslang::EioPixelInterlockOrdered:         mode = spv::ExecutionModePixelInterlockOrderedEXT;          break;
+        case glslang::EioPixelInterlockUnordered:       mode = spv::ExecutionModePixelInterlockUnorderedEXT;          break;
+        case glslang::EioSampleInterlockOrdered:        mode = spv::ExecutionModeSampleInterlockOrderedEXT;          break;
+        case glslang::EioSampleInterlockUnordered:      mode = spv::ExecutionModeSampleInterlockUnorderedEXT;          break;
+        case glslang::EioShadingRateInterlockOrdered:   mode = spv::ExecutionModeShadingRateInterlockOrderedEXT;          break;
+        case glslang::EioShadingRateInterlockUnordered: mode = spv::ExecutionModeShadingRateInterlockUnorderedEXT;          break;
+        default:                                        mode = spv::ExecutionModeMax;                   break;
+        }
+        if (mode != spv::ExecutionModeMax) {
+            builder.addExecutionMode(shaderEntry, (spv::ExecutionMode)mode);
+            if (mode == spv::ExecutionModeShadingRateInterlockOrderedEXT ||
+                mode == spv::ExecutionModeShadingRateInterlockUnorderedEXT) {
+                builder.addCapability(spv::CapabilityFragmentShaderShadingRateInterlockEXT);
+            } else if (mode == spv::ExecutionModePixelInterlockOrderedEXT ||
+                       mode == spv::ExecutionModePixelInterlockUnorderedEXT) {
+                builder.addCapability(spv::CapabilityFragmentShaderPixelInterlockEXT);
+            } else {
+                builder.addCapability(spv::CapabilityFragmentShaderSampleInterlockEXT);
+            }
+            builder.addExtension(spv::E_SPV_EXT_fragment_shader_interlock);
+        }
+
         break;
 
     case EShLangCompute:
@@ -1939,19 +1981,26 @@
         invertedType = getInvertedSwizzleType(*node->getOperand());
 
     builder.clearAccessChain();
+    TIntermNode *operandNode;
     if (invertedType != spv::NoType)
-        node->getOperand()->getAsBinaryNode()->getLeft()->traverse(this);
+        operandNode = node->getOperand()->getAsBinaryNode()->getLeft();
     else
-        node->getOperand()->traverse(this);
+        operandNode = node->getOperand();
+    
+    operandNode->traverse(this);
 
     spv::Id operand = spv::NoResult;
 
+    spv::Builder::AccessChain::CoherentFlags lvalueCoherentFlags;
+
     if (node->getOp() == glslang::EOpAtomicCounterIncrement ||
         node->getOp() == glslang::EOpAtomicCounterDecrement ||
         node->getOp() == glslang::EOpAtomicCounter          ||
-        node->getOp() == glslang::EOpInterpolateAtCentroid)
+        node->getOp() == glslang::EOpInterpolateAtCentroid) {
         operand = builder.accessChainGetLValue(); // Special case l-value operands
-    else
+        lvalueCoherentFlags = builder.getAccessChain().coherentFlags;
+        lvalueCoherentFlags |= TranslateCoherent(operandNode->getAsTyped()->getType());
+    } else
         operand = accessChainLoad(node->getOperand()->getType());
 
     OpDecorations decorations = { TranslatePrecisionDecoration(node->getOperationPrecision()),
@@ -1964,7 +2013,7 @@
 
     // if not, then possibly an operation
     if (! result)
-        result = createUnaryOperation(node->getOp(), decorations, resultType(), operand, node->getOperand()->getBasicType());
+        result = createUnaryOperation(node->getOp(), decorations, resultType(), operand, node->getOperand()->getBasicType(), lvalueCoherentFlags);
 
     if (result) {
         if (invertedType) {
@@ -2071,6 +2120,8 @@
     bool noReturnValue = false;
     bool atomic = false;
 
+    spv::Builder::AccessChain::CoherentFlags lvalueCoherentFlags;
+
     assert(node->getOp());
 
     spv::Decoration precision = TranslatePrecisionDecoration(node->getOperationPrecision());
@@ -2268,7 +2319,7 @@
     {
         builder.setLine(node->getLoc().line, node->getLoc().getFilename());
         std::vector<spv::Id> arguments;
-        translateArguments(*node, arguments);
+        translateArguments(*node, arguments, lvalueCoherentFlags);
         spv::Id constructed;
         if (node->getOp() == glslang::EOpConstructTextureSampler)
             constructed = builder.createOp(spv::OpSampledImage, resultType(), arguments);
@@ -2396,6 +2447,11 @@
     case glslang::EOpCooperativeMatrixStore:
         noReturnValue = true;
         break;
+    case glslang::EOpBeginInvocationInterlock:
+    case glslang::EOpEndInvocationInterlock:
+        builder.addExtension(spv::E_SPV_EXT_fragment_shader_interlock);
+        noReturnValue = true;
+        break;
 
     default:
         break;
@@ -2555,9 +2611,11 @@
             }
         }
 
-        if (lvalue)
+        if (lvalue) {
             operands.push_back(builder.accessChainGetLValue());
-        else {
+            lvalueCoherentFlags = builder.getAccessChain().coherentFlags;
+            lvalueCoherentFlags |= TranslateCoherent(glslangOperands[arg]->getAsTyped()->getType());
+        } else {
             builder.setLine(node->getLoc().line, node->getLoc().getFilename());
             operands.push_back(accessChainLoad(glslangOperands[arg]->getAsTyped()->getType()));
         }
@@ -2592,7 +2650,7 @@
         result = 0;
     } else if (atomic) {
         // Handle all atomics
-        result = createAtomicOperation(node->getOp(), precision, resultType(), operands, node->getBasicType());
+        result = createAtomicOperation(node->getOp(), precision, resultType(), operands, node->getBasicType(), lvalueCoherentFlags);
     } else {
         // Pass through to generic operations.
         switch (glslangOperands.size()) {
@@ -2607,7 +2665,7 @@
                 result = createUnaryOperation(
                     node->getOp(), decorations,
                     resultType(), operands.front(),
-                    glslangOperands[0]->getAsTyped()->getBasicType());
+                    glslangOperands[0]->getAsTyped()->getBasicType(), lvalueCoherentFlags);
             }
             break;
         default:
@@ -4005,7 +4063,7 @@
     builder.setBuildPoint(functionBlock);
 }
 
-void TGlslangToSpvTraverser::translateArguments(const glslang::TIntermAggregate& node, std::vector<spv::Id>& arguments)
+void TGlslangToSpvTraverser::translateArguments(const glslang::TIntermAggregate& node, std::vector<spv::Id>& arguments, spv::Builder::AccessChain::CoherentFlags &lvalueCoherentFlags)
 {
     const glslang::TIntermSequence& glslangArguments = node.getSequence();
 
@@ -4163,9 +4221,11 @@
             break;
         }
 
-        if (lvalue)
+        if (lvalue) {
             arguments.push_back(builder.accessChainGetLValue());
-        else
+            lvalueCoherentFlags = builder.getAccessChain().coherentFlags;
+            lvalueCoherentFlags |= TranslateCoherent(glslangArguments[i]->getAsTyped()->getType());
+        } else
             arguments.push_back(accessChainLoad(glslangArguments[i]->getAsTyped()->getType()));
     }
 }
@@ -4206,9 +4266,11 @@
         return spv::ImageOperandsMaskNone;
     };
 
+    spv::Builder::AccessChain::CoherentFlags lvalueCoherentFlags;
+
     std::vector<spv::Id> arguments;
     if (node->getAsAggregate())
-        translateArguments(*node->getAsAggregate(), arguments);
+        translateArguments(*node->getAsAggregate(), arguments, lvalueCoherentFlags);
     else
         translateArguments(*node->getAsUnaryNode(), arguments);
     spv::Decoration precision = TranslatePrecisionDecoration(node->getOperationPrecision());
@@ -4489,7 +4551,7 @@
             for (; opIt != arguments.end(); ++opIt)
                 operands.push_back(*opIt);
 
-            return createAtomicOperation(node->getOp(), precision, resultType(), operands, node->getBasicType());
+            return createAtomicOperation(node->getOp(), precision, resultType(), operands, node->getBasicType(), lvalueCoherentFlags);
         }
     }
 
@@ -5245,7 +5307,7 @@
 }
 
 spv::Id TGlslangToSpvTraverser::createUnaryOperation(glslang::TOperator op, OpDecorations& decorations, spv::Id typeId,
-                                                     spv::Id operand, glslang::TBasicType typeProxy)
+                                                     spv::Id operand, glslang::TBasicType typeProxy, const spv::Builder::AccessChain::CoherentFlags &lvalueCoherentFlags)
 {
     spv::Op unaryOp = spv::OpNop;
     int extBuiltins = -1;
@@ -5516,7 +5578,7 @@
         // 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);
+        return createAtomicOperation(op, decorations.precision, typeId, operands, typeProxy, lvalueCoherentFlags);
     }
 
     case glslang::EOpBitFieldReverse:
@@ -6124,7 +6186,7 @@
 }
 
 // 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)
+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)
 {
     spv::Op opCode = spv::OpNop;
 
@@ -6210,7 +6272,7 @@
         scopeId = builder.makeUintConstant(spv::ScopeDevice);
     }
     // semantics default to relaxed 
-    spv::Id semanticsId = builder.makeUintConstant(spv::MemorySemanticsMaskNone);
+    spv::Id semanticsId = builder.makeUintConstant(lvalueCoherentFlags.volatil ? spv::MemorySemanticsVolatileMask : spv::MemorySemanticsMaskNone);
     spv::Id semanticsId2 = semanticsId;
 
     pointerId = operands[0];
@@ -6240,7 +6302,10 @@
 
     // Check for capabilities
     unsigned semanticsImmediate = builder.getConstantScalar(semanticsId) | builder.getConstantScalar(semanticsId2);
-    if (semanticsImmediate & (spv::MemorySemanticsMakeAvailableKHRMask | spv::MemorySemanticsMakeVisibleKHRMask | spv::MemorySemanticsOutputMemoryKHRMask)) {
+    if (semanticsImmediate & (spv::MemorySemanticsMakeAvailableKHRMask |
+                              spv::MemorySemanticsMakeVisibleKHRMask |
+                              spv::MemorySemanticsOutputMemoryKHRMask |
+                              spv::MemorySemanticsVolatileMask)) {
         builder.addCapability(spv::CapabilityVulkanMemoryModelKHR);
     }
 
@@ -7182,7 +7247,10 @@
             unsigned int memoryScope = builder.getConstantScalar(operands[1]);
             unsigned int semantics = builder.getConstantScalar(operands[2]) | builder.getConstantScalar(operands[3]);
             builder.createControlBarrier((spv::Scope)executionScope, (spv::Scope)memoryScope, (spv::MemorySemanticsMask)semantics);
-            if (semantics & (spv::MemorySemanticsMakeAvailableKHRMask | spv::MemorySemanticsMakeVisibleKHRMask | spv::MemorySemanticsOutputMemoryKHRMask)) {
+            if (semantics & (spv::MemorySemanticsMakeAvailableKHRMask |
+                             spv::MemorySemanticsMakeVisibleKHRMask |
+                             spv::MemorySemanticsOutputMemoryKHRMask |
+                             spv::MemorySemanticsVolatileMask)) {
                 builder.addCapability(spv::CapabilityVulkanMemoryModelKHR);
             }
             if (glslangIntermediate->usingVulkanMemoryModel() && (executionScope == spv::ScopeDevice || memoryScope == spv::ScopeDevice)) {
@@ -7199,7 +7267,10 @@
             unsigned int memoryScope = builder.getConstantScalar(operands[0]);
             unsigned int semantics = builder.getConstantScalar(operands[1]) | builder.getConstantScalar(operands[2]);
             builder.createMemoryBarrier((spv::Scope)memoryScope, (spv::MemorySemanticsMask)semantics);
-            if (semantics & (spv::MemorySemanticsMakeAvailableKHRMask | spv::MemorySemanticsMakeVisibleKHRMask | spv::MemorySemanticsOutputMemoryKHRMask)) {
+            if (semantics & (spv::MemorySemanticsMakeAvailableKHRMask |
+                             spv::MemorySemanticsMakeVisibleKHRMask |
+                             spv::MemorySemanticsOutputMemoryKHRMask |
+                             spv::MemorySemanticsVolatileMask)) {
                 builder.addCapability(spv::CapabilityVulkanMemoryModelKHR);
             }
             if (glslangIntermediate->usingVulkanMemoryModel() && memoryScope == spv::ScopeDevice) {
@@ -7429,6 +7500,14 @@
         builder.createNoResultOp(spv::OpTerminateRayNV);
         return 0;
 #endif
+
+    case glslang::EOpBeginInvocationInterlock:
+        builder.createNoResultOp(spv::OpBeginInvocationInterlockEXT);
+        return 0;
+    case glslang::EOpEndInvocationInterlock:
+        builder.createNoResultOp(spv::OpEndInvocationInterlockEXT);
+        return 0;
+
     default:
         logger->missingFunctionality("unknown operation with no arguments");
         return 0;
@@ -8053,11 +8132,14 @@
 #if ENABLE_OPT
     // If from HLSL, run spirv-opt to "legalize" the SPIR-V for Vulkan
     // eg. forward and remove memory writes of opaque types.
-    if ((intermediate.getSource() == EShSourceHlsl || options->optimizeSize) && !options->disableOptimizer)
+    bool prelegalization = intermediate.getSource() == EShSourceHlsl;
+    if ((intermediate.getSource() == EShSourceHlsl || options->optimizeSize) && !options->disableOptimizer) {
         SpirvToolsLegalize(intermediate, spirv, logger, options);
+        prelegalization = false;
+    }
 
     if (options->validate)
-        SpirvToolsValidate(intermediate, spirv, logger);
+        SpirvToolsValidate(intermediate, spirv, logger, prelegalization);
 
     if (options->disassemble)
         SpirvToolsDisassemble(std::cout, spirv);
diff --git a/SPIRV/SpvTools.cpp b/SPIRV/SpvTools.cpp
index db26d59..698f154 100644
--- a/SPIRV/SpvTools.cpp
+++ b/SPIRV/SpvTools.cpp
@@ -103,7 +103,7 @@
 
 // Apply the SPIRV-Tools validator to generated SPIR-V.
 void SpirvToolsValidate(const glslang::TIntermediate& intermediate, std::vector<unsigned int>& spirv,
-                        spv::SpvBuildLogger* logger)
+                        spv::SpvBuildLogger* logger, bool prelegalization)
 {
     // validate
     spv_context context = spvContextCreate(MapToSpirvToolsEnv(intermediate.getSpv(), logger));
@@ -111,6 +111,7 @@
     spv_diagnostic diagnostic = nullptr;
     spv_validator_options options = spvValidatorOptionsCreate();
     spvValidatorOptionsSetRelaxBlockLayout(options, intermediate.usingHlslOffsets());
+    spvValidatorOptionsSetBeforeHlslLegalization(options, prelegalization);
     spvValidateWithOptions(context, options, &binary, &diagnostic);
 
     // report
diff --git a/SPIRV/SpvTools.h b/SPIRV/SpvTools.h
index 7e49ae0..cf8fc85 100644
--- a/SPIRV/SpvTools.h
+++ b/SPIRV/SpvTools.h
@@ -66,7 +66,7 @@
 
 // Apply the SPIRV-Tools validator to generated SPIR-V.
 void SpirvToolsValidate(const glslang::TIntermediate& intermediate, std::vector<unsigned int>& spirv,
-                        spv::SpvBuildLogger*);
+                        spv::SpvBuildLogger*, bool prelegalization);
 
 // Apply the SPIRV-Tools optimizer to generated SPIR-V, for the purpose of
 // legalizing HLSL SPIR-V.
diff --git a/SPIRV/doc.cpp b/SPIRV/doc.cpp
index a0c384a..3e68345 100644
--- a/SPIRV/doc.cpp
+++ b/SPIRV/doc.cpp
@@ -191,6 +191,13 @@
     case ExecutionModeDerivativeGroupLinearNV:  return "DerivativeGroupLinearNV";
 #endif
 
+    case ExecutionModePixelInterlockOrderedEXT:         return "PixelInterlockOrderedEXT";
+    case ExecutionModePixelInterlockUnorderedEXT:       return "PixelInterlockUnorderedEXT";
+    case ExecutionModeSampleInterlockOrderedEXT:        return "SampleInterlockOrderedEXT";
+    case ExecutionModeSampleInterlockUnorderedEXT:      return "SampleInterlockUnorderedEXT";
+    case ExecutionModeShadingRateInterlockOrderedEXT:   return "ShadingRateInterlockOrderedEXT";
+    case ExecutionModeShadingRateInterlockUnorderedEXT: return "ShadingRateInterlockUnorderedEXT";
+
     case ExecutionModeCeiling:
     default: return "Bad";
     }
@@ -416,6 +423,10 @@
     case BuiltInMeshViewCountNV:       return "MeshViewCountNV";
     case BuiltInMeshViewIndicesNV:     return "MeshViewIndicesNV";
 #endif
+    case BuiltInWarpsPerSMNV:           return "WarpsPerSMNV";
+    case BuiltInSMCountNV:              return "SMCountNV";
+    case BuiltInWarpIDNV:               return "WarpIDNV";
+    case BuiltInSMIDNV:                 return "SMIDNV";
 
     default: return "Bad";
     }
@@ -941,6 +952,11 @@
     case CapabilityVariablePointers:                    return "VariablePointers";
 
     case CapabilityCooperativeMatrixNV:     return "CooperativeMatrixNV";
+    case CapabilityShaderSMBuiltinsNV:      return "ShaderSMBuiltinsNV";
+
+    case CapabilityFragmentShaderSampleInterlockEXT:        return "CapabilityFragmentShaderSampleInterlockEXT";
+    case CapabilityFragmentShaderPixelInterlockEXT:         return "CapabilityFragmentShaderPixelInterlockEXT";
+    case CapabilityFragmentShaderShadingRateInterlockEXT:   return "CapabilityFragmentShaderShadingRateInterlockEXT";
 
     default: return "Bad";
     }
@@ -1352,6 +1368,9 @@
     case OpCooperativeMatrixMulAddNV:       return "OpCooperativeMatrixMulAddNV";
     case OpCooperativeMatrixLengthNV:       return "OpCooperativeMatrixLengthNV";
 
+    case OpBeginInvocationInterlockEXT:     return "OpBeginInvocationInterlockEXT";
+    case OpEndInvocationInterlockEXT:       return "OpEndInvocationInterlockEXT";
+
     default:
         return "Bad";
     }
@@ -1465,6 +1484,8 @@
     InstructionDesc[OpModuleProcessed].setResultAndType(false, false);
     InstructionDesc[OpTypeCooperativeMatrixNV].setResultAndType(true, false);
     InstructionDesc[OpCooperativeMatrixStoreNV].setResultAndType(false, false);
+    InstructionDesc[OpBeginInvocationInterlockEXT].setResultAndType(false, false);
+    InstructionDesc[OpEndInvocationInterlockEXT].setResultAndType(false, false);
 
     // Specific additional context-dependent operands
 
diff --git a/SPIRV/spirv.hpp b/SPIRV/spirv.hpp
index 5297fd3..bbaf47c 100644
--- a/SPIRV/spirv.hpp
+++ b/SPIRV/spirv.hpp
@@ -154,6 +154,12 @@
     ExecutionModeDerivativeGroupQuadsNV = 5289,
     ExecutionModeDerivativeGroupLinearNV = 5290,
     ExecutionModeOutputTrianglesNV = 5298,
+    ExecutionModePixelInterlockOrderedEXT = 5366,
+    ExecutionModePixelInterlockUnorderedEXT = 5367,
+    ExecutionModeSampleInterlockOrderedEXT = 5368,
+    ExecutionModeSampleInterlockUnorderedEXT = 5369,
+    ExecutionModeShadingRateInterlockOrderedEXT = 5370,
+    ExecutionModeShadingRateInterlockUnorderedEXT = 5371,
     ExecutionModeMax = 0x7fffffff,
 };
 
@@ -551,6 +557,10 @@
     BuiltInHitTNV = 5332,
     BuiltInHitKindNV = 5333,
     BuiltInIncomingRayFlagsNV = 5351,
+    BuiltInWarpsPerSMNV = 5374,
+    BuiltInSMCountNV = 5375,
+    BuiltInWarpIDNV = 5376,
+    BuiltInSMIDNV = 5377,
     BuiltInMax = 0x7fffffff,
 };
 
@@ -622,6 +632,7 @@
     MemorySemanticsOutputMemoryKHRShift = 12,
     MemorySemanticsMakeAvailableKHRShift = 13,
     MemorySemanticsMakeVisibleKHRShift = 14,
+    MemorySemanticsVolatileShift = 15,

     MemorySemanticsMax = 0x7fffffff,
 };
 
@@ -639,7 +650,8 @@
     MemorySemanticsImageMemoryMask = 0x00000800,
     MemorySemanticsOutputMemoryKHRMask = 0x00001000,
     MemorySemanticsMakeAvailableKHRMask = 0x00002000,
-    MemorySemanticsMakeVisibleKHRMask = 0x00004000,
+    MemorySemanticsMakeVisibleKHRMask = 0x00004000,

+    MemorySemanticsVolatileMask = 0x00008000,

 };
 
 enum MemoryAccessShift {
@@ -829,10 +841,15 @@
     CapabilityPhysicalStorageBufferAddressesEXT = 5347,
     CapabilityComputeDerivativeGroupLinearNV = 5350,
     CapabilityCooperativeMatrixNV = 5357,
+    CapabilityFragmentShaderSampleInterlockEXT = 5363,
+    CapabilityFragmentShaderShadingRateInterlockEXT = 5372,
+    CapabilityShaderSMBuiltinsNV = 5373,
+    CapabilityFragmentShaderPixelInterlockEXT = 5378,
     CapabilitySubgroupShuffleINTEL = 5568,
     CapabilitySubgroupBufferBlockIOINTEL = 5569,
     CapabilitySubgroupImageBlockIOINTEL = 5570,
     CapabilitySubgroupImageMediaBlockIOINTEL = 5579,
+    CapabilityIntegerFunctions2INTEL = 5584,
     CapabilitySubgroupAvcMotionEstimationINTEL = 5696,
     CapabilitySubgroupAvcMotionEstimationIntraINTEL = 5697,
     CapabilitySubgroupAvcMotionEstimationChromaINTEL = 5698,
@@ -1214,6 +1231,8 @@
     OpCooperativeMatrixStoreNV = 5360,
     OpCooperativeMatrixMulAddNV = 5361,
     OpCooperativeMatrixLengthNV = 5362,
+    OpBeginInvocationInterlockEXT = 5364,
+    OpEndInvocationInterlockEXT = 5365,
     OpSubgroupShuffleINTEL = 5571,
     OpSubgroupShuffleDownINTEL = 5572,
     OpSubgroupShuffleUpINTEL = 5573,
@@ -1224,6 +1243,20 @@
     OpSubgroupImageBlockWriteINTEL = 5578,
     OpSubgroupImageMediaBlockReadINTEL = 5580,
     OpSubgroupImageMediaBlockWriteINTEL = 5581,
+    OpUCountLeadingZerosINTEL = 5585,
+    OpUCountTrailingZerosINTEL = 5586,
+    OpAbsISubINTEL = 5587,
+    OpAbsUSubINTEL = 5588,
+    OpIAddSatINTEL = 5589,
+    OpUAddSatINTEL = 5590,
+    OpIAverageINTEL = 5591,
+    OpUAverageINTEL = 5592,
+    OpIAverageRoundedINTEL = 5593,
+    OpUAverageRoundedINTEL = 5594,
+    OpISubSatINTEL = 5595,
+    OpUSubSatINTEL = 5596,
+    OpIMul32x16INTEL = 5597,
+    OpUMul32x16INTEL = 5598,
     OpDecorateString = 5632,
     OpDecorateStringGOOGLE = 5632,
     OpMemberDecorateString = 5633,
@@ -1738,10 +1771,22 @@
     case OpSubgroupImageBlockWriteINTEL: *hasResult = false; *hasResultType = false; break;
     case OpSubgroupImageMediaBlockReadINTEL: *hasResult = true; *hasResultType = true; break;
     case OpSubgroupImageMediaBlockWriteINTEL: *hasResult = false; *hasResultType = false; break;
+    case OpUCountLeadingZerosINTEL: *hasResult = true; *hasResultType = true; break;
+    case OpUCountTrailingZerosINTEL: *hasResult = true; *hasResultType = true; break;
+    case OpAbsISubINTEL: *hasResult = true; *hasResultType = true; break;
+    case OpAbsUSubINTEL: *hasResult = true; *hasResultType = true; break;
+    case OpIAddSatINTEL: *hasResult = true; *hasResultType = true; break;
+    case OpUAddSatINTEL: *hasResult = true; *hasResultType = true; break;
+    case OpIAverageINTEL: *hasResult = true; *hasResultType = true; break;
+    case OpUAverageINTEL: *hasResult = true; *hasResultType = true; break;
+    case OpIAverageRoundedINTEL: *hasResult = true; *hasResultType = true; break;
+    case OpUAverageRoundedINTEL: *hasResult = true; *hasResultType = true; break;
+    case OpISubSatINTEL: *hasResult = true; *hasResultType = true; break;
+    case OpUSubSatINTEL: *hasResult = true; *hasResultType = true; break;
+    case OpIMul32x16INTEL: *hasResult = true; *hasResultType = true; break;
+    case OpUMul32x16INTEL: *hasResult = true; *hasResultType = true; break;
     case OpDecorateString: *hasResult = false; *hasResultType = false; break;
-    case OpDecorateStringGOOGLE: *hasResult = false; *hasResultType = false; break;
     case OpMemberDecorateString: *hasResult = false; *hasResultType = false; break;
-    case OpMemberDecorateStringGOOGLE: *hasResult = false; *hasResultType = false; break;
     case OpVmeImageINTEL: *hasResult = true; *hasResultType = true; break;
     case OpTypeVmeImageINTEL: *hasResult = true; *hasResultType = false; break;
     case OpTypeAvcImePayloadINTEL: *hasResult = true; *hasResultType = false; break;
@@ -1860,6 +1905,8 @@
     case OpSubgroupAvcSicGetPackedSkcLumaCountThresholdINTEL: *hasResult = true; *hasResultType = true; break;
     case OpSubgroupAvcSicGetPackedSkcLumaSumThresholdINTEL: *hasResult = true; *hasResultType = true; break;
     case OpSubgroupAvcSicGetInterRawSadsINTEL: *hasResult = true; *hasResultType = true; break;
+    case OpBeginInvocationInterlockEXT: *hasResult = false; *hasResultType = false; break;
+    case OpEndInvocationInterlockEXT: *hasResult = false; *hasResultType = false; break;
     }
 }
 #endif /* SPV_ENABLE_UTILITY_CODE */
diff --git a/Test/baseResults/310.comp.out b/Test/baseResults/310.comp.out
index 4b65ea1..b4136b0 100644
--- a/Test/baseResults/310.comp.out
+++ b/Test/baseResults/310.comp.out
@@ -29,7 +29,6 @@
 ERROR: 0:97: '' : memory qualifiers cannot be used on this type 
 ERROR: 0:98: '' : memory qualifiers cannot be used on this type 
 ERROR: 0:109: 'format' : image formats must match 
-ERROR: 0:110: 'restrict' : argument cannot drop memory qualifier when passed to formal parameter 
 ERROR: 0:110: 'format' : image formats must match 
 ERROR: 0:111: 'format' : image formats must match 
 ERROR: 0:114: 'image load-store format' : not supported with this profile: es
@@ -87,7 +86,7 @@
 ERROR: 0:244: 'gl_DeviceIndex' : required extension not requested: GL_EXT_device_group
 ERROR: 0:245: 'gl_ViewIndex' : undeclared identifier 
 ERROR: 0:255: 'gl_ViewIndex' : undeclared identifier 
-ERROR: 86 compilation errors.  No code generated.
+ERROR: 85 compilation errors.  No code generated.
 
 
 Shader version: 310
diff --git a/Test/baseResults/glsl.450.subgroup.frag.out b/Test/baseResults/glsl.450.subgroup.frag.out
index dd16c1f..e61523e 100644
--- a/Test/baseResults/glsl.450.subgroup.frag.out
+++ b/Test/baseResults/glsl.450.subgroup.frag.out
@@ -85,7 +85,11 @@
 ERROR: 0:96: 'subgroupPartitionedExclusiveAndNV' : required extension not requested: GL_NV_shader_subgroup_partitioned
 ERROR: 0:97: 'subgroupPartitionedExclusiveOrNV' : required extension not requested: GL_NV_shader_subgroup_partitioned
 ERROR: 0:98: 'subgroupPartitionedExclusiveXorNV' : required extension not requested: GL_NV_shader_subgroup_partitioned
-ERROR: 86 compilation errors.  No code generated.
+ERROR: 0:232: 'gl_WarpsPerSMNV' : required extension not requested: GL_NV_shader_sm_builtins
+ERROR: 0:233: 'gl_SMCountNV' : required extension not requested: GL_NV_shader_sm_builtins
+ERROR: 0:234: 'gl_WarpIDNV' : required extension not requested: GL_NV_shader_sm_builtins
+ERROR: 0:235: 'gl_SMIDNV' : required extension not requested: GL_NV_shader_sm_builtins
+ERROR: 90 compilation errors.  No code generated.
 
 
 Shader version: 450
@@ -97,6 +101,7 @@
 Requested GL_KHR_shader_subgroup_shuffle
 Requested GL_KHR_shader_subgroup_shuffle_relative
 Requested GL_KHR_shader_subgroup_vote
+Requested GL_NV_shader_sm_builtins
 Requested GL_NV_shader_subgroup_partitioned
 ERROR: node is still EOpNull!
 0:3  Function Definition: undeclared_errors(vf4; ( global 4-component vector of float)
@@ -597,6 +602,20 @@
 0:226      subgroupPartitionedExclusiveXorNV ( global 4-component vector of uint)
 0:226        'ballot' ( temp 4-component vector of uint)
 0:226        'parti' ( temp 4-component vector of uint)
+0:230  Function Definition: sm_builtins_err( ( global void)
+0:230    Function Parameters: 
+0:232    Sequence
+0:232      'gl_WarpsPerSMNV' ( flat in uint WarpsPerSMNV)
+0:233      'gl_SMCountNV' ( flat in uint SMCountNV)
+0:234      'gl_WarpIDNV' ( flat in uint WarpIDNV)
+0:235      'gl_SMIDNV' ( flat in uint SMIDNV)
+0:242  Function Definition: sm_builtins( ( global void)
+0:242    Function Parameters: 
+0:244    Sequence
+0:244      'gl_WarpsPerSMNV' ( flat in uint WarpsPerSMNV)
+0:245      'gl_SMCountNV' ( flat in uint SMCountNV)
+0:246      'gl_WarpIDNV' ( flat in uint WarpIDNV)
+0:247      'gl_SMIDNV' ( flat in uint SMIDNV)
 0:?   Linker Objects
 0:?     'data' (layout( location=0) out 4-component vector of uint)
 
@@ -613,6 +632,7 @@
 Requested GL_KHR_shader_subgroup_shuffle
 Requested GL_KHR_shader_subgroup_shuffle_relative
 Requested GL_KHR_shader_subgroup_vote
+Requested GL_NV_shader_sm_builtins
 Requested GL_NV_shader_subgroup_partitioned
 ERROR: node is still EOpNull!
 0:105  Function Definition: main( ( global void)
diff --git a/Test/baseResults/glsl.450.subgroup.geom.out b/Test/baseResults/glsl.450.subgroup.geom.out
index 998f6c2..baf82dc 100644
--- a/Test/baseResults/glsl.450.subgroup.geom.out
+++ b/Test/baseResults/glsl.450.subgroup.geom.out
@@ -85,7 +85,11 @@
 ERROR: 0:96: 'subgroupPartitionedExclusiveAndNV' : required extension not requested: GL_NV_shader_subgroup_partitioned
 ERROR: 0:97: 'subgroupPartitionedExclusiveOrNV' : required extension not requested: GL_NV_shader_subgroup_partitioned
 ERROR: 0:98: 'subgroupPartitionedExclusiveXorNV' : required extension not requested: GL_NV_shader_subgroup_partitioned
-ERROR: 86 compilation errors.  No code generated.
+ERROR: 0:238: 'gl_WarpsPerSMNV' : required extension not requested: GL_NV_shader_sm_builtins
+ERROR: 0:239: 'gl_SMCountNV' : required extension not requested: GL_NV_shader_sm_builtins
+ERROR: 0:240: 'gl_WarpIDNV' : required extension not requested: GL_NV_shader_sm_builtins
+ERROR: 0:241: 'gl_SMIDNV' : required extension not requested: GL_NV_shader_sm_builtins
+ERROR: 90 compilation errors.  No code generated.
 
 
 Shader version: 450
@@ -97,6 +101,7 @@
 Requested GL_KHR_shader_subgroup_shuffle
 Requested GL_KHR_shader_subgroup_shuffle_relative
 Requested GL_KHR_shader_subgroup_vote
+Requested GL_NV_shader_sm_builtins
 Requested GL_NV_shader_subgroup_partitioned
 invocations = -1
 max_vertices = 1
@@ -606,6 +611,20 @@
 0:232      subgroupPartitionedExclusiveXorNV ( global 4-component vector of uint)
 0:232        'ballot' ( temp 4-component vector of uint)
 0:232        'parti' ( temp 4-component vector of uint)
+0:236  Function Definition: sm_builtins_err( ( global void)
+0:236    Function Parameters: 
+0:238    Sequence
+0:238      'gl_WarpsPerSMNV' ( in uint WarpsPerSMNV)
+0:239      'gl_SMCountNV' ( in uint SMCountNV)
+0:240      'gl_WarpIDNV' ( in uint WarpIDNV)
+0:241      'gl_SMIDNV' ( in uint SMIDNV)
+0:248  Function Definition: sm_builtins( ( global void)
+0:248    Function Parameters: 
+0:250    Sequence
+0:250      'gl_WarpsPerSMNV' ( in uint WarpsPerSMNV)
+0:251      'gl_SMCountNV' ( in uint SMCountNV)
+0:252      'gl_WarpIDNV' ( in uint WarpIDNV)
+0:253      'gl_SMIDNV' ( in uint SMIDNV)
 0:?   Linker Objects
 0:?     'anon@0' (layout( set=0 binding=0 column_major std430) buffer block{layout( column_major std430 offset=0) buffer runtime-sized array of 4-component vector of uint result})
 
@@ -622,6 +641,7 @@
 Requested GL_KHR_shader_subgroup_shuffle
 Requested GL_KHR_shader_subgroup_shuffle_relative
 Requested GL_KHR_shader_subgroup_vote
+Requested GL_NV_shader_sm_builtins
 Requested GL_NV_shader_subgroup_partitioned
 invocations = 1
 max_vertices = 1
diff --git a/Test/baseResults/glsl.450.subgroup.tesc.out b/Test/baseResults/glsl.450.subgroup.tesc.out
index fef9a04..eeee387 100644
--- a/Test/baseResults/glsl.450.subgroup.tesc.out
+++ b/Test/baseResults/glsl.450.subgroup.tesc.out
@@ -85,7 +85,11 @@
 ERROR: 0:96: 'subgroupPartitionedExclusiveAndNV' : required extension not requested: GL_NV_shader_subgroup_partitioned
 ERROR: 0:97: 'subgroupPartitionedExclusiveOrNV' : required extension not requested: GL_NV_shader_subgroup_partitioned
 ERROR: 0:98: 'subgroupPartitionedExclusiveXorNV' : required extension not requested: GL_NV_shader_subgroup_partitioned
-ERROR: 86 compilation errors.  No code generated.
+ERROR: 0:237: 'gl_WarpsPerSMNV' : required extension not requested: GL_NV_shader_sm_builtins
+ERROR: 0:238: 'gl_SMCountNV' : required extension not requested: GL_NV_shader_sm_builtins
+ERROR: 0:239: 'gl_WarpIDNV' : required extension not requested: GL_NV_shader_sm_builtins
+ERROR: 0:240: 'gl_SMIDNV' : required extension not requested: GL_NV_shader_sm_builtins
+ERROR: 90 compilation errors.  No code generated.
 
 
 Shader version: 450
@@ -97,6 +101,7 @@
 Requested GL_KHR_shader_subgroup_shuffle
 Requested GL_KHR_shader_subgroup_shuffle_relative
 Requested GL_KHR_shader_subgroup_vote
+Requested GL_NV_shader_sm_builtins
 Requested GL_NV_shader_subgroup_partitioned
 vertices = 1
 ERROR: node is still EOpNull!
@@ -603,6 +608,20 @@
 0:231      subgroupPartitionedExclusiveXorNV ( global 4-component vector of uint)
 0:231        'ballot' ( temp 4-component vector of uint)
 0:231        'parti' ( temp 4-component vector of uint)
+0:235  Function Definition: sm_builtins_err( ( global void)
+0:235    Function Parameters: 
+0:237    Sequence
+0:237      'gl_WarpsPerSMNV' ( in uint WarpsPerSMNV)
+0:238      'gl_SMCountNV' ( in uint SMCountNV)
+0:239      'gl_WarpIDNV' ( in uint WarpIDNV)
+0:240      'gl_SMIDNV' ( in uint SMIDNV)
+0:247  Function Definition: sm_builtins( ( global void)
+0:247    Function Parameters: 
+0:249    Sequence
+0:249      'gl_WarpsPerSMNV' ( in uint WarpsPerSMNV)
+0:250      'gl_SMCountNV' ( in uint SMCountNV)
+0:251      'gl_WarpIDNV' ( in uint WarpIDNV)
+0:252      'gl_SMIDNV' ( in uint SMIDNV)
 0:?   Linker Objects
 0:?     'anon@0' (layout( set=0 binding=0 column_major std430) buffer block{layout( column_major std430 offset=0) buffer runtime-sized array of 4-component vector of uint result})
 
@@ -619,6 +638,7 @@
 Requested GL_KHR_shader_subgroup_shuffle
 Requested GL_KHR_shader_subgroup_shuffle_relative
 Requested GL_KHR_shader_subgroup_vote
+Requested GL_NV_shader_sm_builtins
 Requested GL_NV_shader_subgroup_partitioned
 vertices = 1
 ERROR: node is still EOpNull!
diff --git a/Test/baseResults/glsl.450.subgroup.tese.out b/Test/baseResults/glsl.450.subgroup.tese.out
index de44d55..3f05d77 100644
--- a/Test/baseResults/glsl.450.subgroup.tese.out
+++ b/Test/baseResults/glsl.450.subgroup.tese.out
@@ -85,7 +85,11 @@
 ERROR: 0:96: 'subgroupPartitionedExclusiveAndNV' : required extension not requested: GL_NV_shader_subgroup_partitioned
 ERROR: 0:97: 'subgroupPartitionedExclusiveOrNV' : required extension not requested: GL_NV_shader_subgroup_partitioned
 ERROR: 0:98: 'subgroupPartitionedExclusiveXorNV' : required extension not requested: GL_NV_shader_subgroup_partitioned
-ERROR: 86 compilation errors.  No code generated.
+ERROR: 0:237: 'gl_WarpsPerSMNV' : required extension not requested: GL_NV_shader_sm_builtins
+ERROR: 0:238: 'gl_SMCountNV' : required extension not requested: GL_NV_shader_sm_builtins
+ERROR: 0:239: 'gl_WarpIDNV' : required extension not requested: GL_NV_shader_sm_builtins
+ERROR: 0:240: 'gl_SMIDNV' : required extension not requested: GL_NV_shader_sm_builtins
+ERROR: 90 compilation errors.  No code generated.
 
 
 Shader version: 450
@@ -97,6 +101,7 @@
 Requested GL_KHR_shader_subgroup_shuffle
 Requested GL_KHR_shader_subgroup_shuffle_relative
 Requested GL_KHR_shader_subgroup_vote
+Requested GL_NV_shader_sm_builtins
 Requested GL_NV_shader_subgroup_partitioned
 input primitive = isolines
 vertex spacing = none
@@ -605,6 +610,20 @@
 0:231      subgroupPartitionedExclusiveXorNV ( global 4-component vector of uint)
 0:231        'ballot' ( temp 4-component vector of uint)
 0:231        'parti' ( temp 4-component vector of uint)
+0:235  Function Definition: sm_builtins_err( ( global void)
+0:235    Function Parameters: 
+0:237    Sequence
+0:237      'gl_WarpsPerSMNV' ( in uint WarpsPerSMNV)
+0:238      'gl_SMCountNV' ( in uint SMCountNV)
+0:239      'gl_WarpIDNV' ( in uint WarpIDNV)
+0:240      'gl_SMIDNV' ( in uint SMIDNV)
+0:247  Function Definition: sm_builtins( ( global void)
+0:247    Function Parameters: 
+0:249    Sequence
+0:249      'gl_WarpsPerSMNV' ( in uint WarpsPerSMNV)
+0:250      'gl_SMCountNV' ( in uint SMCountNV)
+0:251      'gl_WarpIDNV' ( in uint WarpIDNV)
+0:252      'gl_SMIDNV' ( in uint SMIDNV)
 0:?   Linker Objects
 0:?     'anon@0' (layout( set=0 binding=0 column_major std430) buffer block{layout( column_major std430 offset=0) buffer runtime-sized array of 4-component vector of uint result})
 
@@ -621,6 +640,7 @@
 Requested GL_KHR_shader_subgroup_shuffle
 Requested GL_KHR_shader_subgroup_shuffle_relative
 Requested GL_KHR_shader_subgroup_vote
+Requested GL_NV_shader_sm_builtins
 Requested GL_NV_shader_subgroup_partitioned
 input primitive = isolines
 vertex spacing = equal_spacing
diff --git a/Test/baseResults/glsl.450.subgroup.vert.out b/Test/baseResults/glsl.450.subgroup.vert.out
index 8fad613..8850bf4 100644
--- a/Test/baseResults/glsl.450.subgroup.vert.out
+++ b/Test/baseResults/glsl.450.subgroup.vert.out
@@ -85,7 +85,11 @@
 ERROR: 0:96: 'subgroupPartitionedExclusiveAndNV' : required extension not requested: GL_NV_shader_subgroup_partitioned
 ERROR: 0:97: 'subgroupPartitionedExclusiveOrNV' : required extension not requested: GL_NV_shader_subgroup_partitioned
 ERROR: 0:98: 'subgroupPartitionedExclusiveXorNV' : required extension not requested: GL_NV_shader_subgroup_partitioned
-ERROR: 86 compilation errors.  No code generated.
+ERROR: 0:236: 'gl_WarpsPerSMNV' : required extension not requested: GL_NV_shader_sm_builtins
+ERROR: 0:237: 'gl_SMCountNV' : required extension not requested: GL_NV_shader_sm_builtins
+ERROR: 0:238: 'gl_WarpIDNV' : required extension not requested: GL_NV_shader_sm_builtins
+ERROR: 0:239: 'gl_SMIDNV' : required extension not requested: GL_NV_shader_sm_builtins
+ERROR: 90 compilation errors.  No code generated.
 
 
 Shader version: 450
@@ -97,6 +101,7 @@
 Requested GL_KHR_shader_subgroup_shuffle
 Requested GL_KHR_shader_subgroup_shuffle_relative
 Requested GL_KHR_shader_subgroup_vote
+Requested GL_NV_shader_sm_builtins
 Requested GL_NV_shader_subgroup_partitioned
 ERROR: node is still EOpNull!
 0:3  Function Definition: undeclared_errors(vf4; ( global 4-component vector of float)
@@ -602,6 +607,20 @@
 0:230      subgroupPartitionedExclusiveXorNV ( global 4-component vector of uint)
 0:230        'ballot' ( temp 4-component vector of uint)
 0:230        'parti' ( temp 4-component vector of uint)
+0:234  Function Definition: sm_builtins_err( ( global void)
+0:234    Function Parameters: 
+0:236    Sequence
+0:236      'gl_WarpsPerSMNV' ( in uint WarpsPerSMNV)
+0:237      'gl_SMCountNV' ( in uint SMCountNV)
+0:238      'gl_WarpIDNV' ( in uint WarpIDNV)
+0:239      'gl_SMIDNV' ( in uint SMIDNV)
+0:246  Function Definition: sm_builtins( ( global void)
+0:246    Function Parameters: 
+0:248    Sequence
+0:248      'gl_WarpsPerSMNV' ( in uint WarpsPerSMNV)
+0:249      'gl_SMCountNV' ( in uint SMCountNV)
+0:250      'gl_WarpIDNV' ( in uint WarpIDNV)
+0:251      'gl_SMIDNV' ( in uint SMIDNV)
 0:?   Linker Objects
 0:?     'anon@0' (layout( set=0 binding=0 column_major std430) buffer block{layout( column_major std430 offset=0) buffer runtime-sized array of 4-component vector of uint result})
 0:?     'gl_VertexID' ( gl_VertexId int VertexId)
@@ -620,6 +639,7 @@
 Requested GL_KHR_shader_subgroup_shuffle
 Requested GL_KHR_shader_subgroup_shuffle_relative
 Requested GL_KHR_shader_subgroup_vote
+Requested GL_NV_shader_sm_builtins
 Requested GL_NV_shader_subgroup_partitioned
 ERROR: node is still EOpNull!
 0:109  Function Definition: main( ( global void)
diff --git a/Test/baseResults/glsl.450.subgroupBasic.comp.out b/Test/baseResults/glsl.450.subgroupBasic.comp.out
index 168d80d..654138b 100644
--- a/Test/baseResults/glsl.450.subgroupBasic.comp.out
+++ b/Test/baseResults/glsl.450.subgroupBasic.comp.out
@@ -85,7 +85,11 @@
 ERROR: 0:96: 'subgroupPartitionedExclusiveAndNV' : required extension not requested: GL_NV_shader_subgroup_partitioned
 ERROR: 0:97: 'subgroupPartitionedExclusiveOrNV' : required extension not requested: GL_NV_shader_subgroup_partitioned
 ERROR: 0:98: 'subgroupPartitionedExclusiveXorNV' : required extension not requested: GL_NV_shader_subgroup_partitioned
-ERROR: 86 compilation errors.  No code generated.
+ERROR: 0:242: 'gl_WarpsPerSMNV' : required extension not requested: GL_NV_shader_sm_builtins
+ERROR: 0:243: 'gl_SMCountNV' : required extension not requested: GL_NV_shader_sm_builtins
+ERROR: 0:244: 'gl_WarpIDNV' : required extension not requested: GL_NV_shader_sm_builtins
+ERROR: 0:245: 'gl_SMIDNV' : required extension not requested: GL_NV_shader_sm_builtins
+ERROR: 90 compilation errors.  No code generated.
 
 
 Shader version: 450
@@ -97,6 +101,7 @@
 Requested GL_KHR_shader_subgroup_shuffle
 Requested GL_KHR_shader_subgroup_shuffle_relative
 Requested GL_KHR_shader_subgroup_vote
+Requested GL_NV_shader_sm_builtins
 Requested GL_NV_shader_subgroup_partitioned
 local_size = (8, 8, 1)
 ERROR: node is still EOpNull!
@@ -631,6 +636,20 @@
 0:236      subgroupPartitionedExclusiveXorNV ( global 4-component vector of uint)
 0:236        'ballot' ( temp 4-component vector of uint)
 0:236        'parti' ( temp 4-component vector of uint)
+0:240  Function Definition: sm_builtins_err( ( global void)
+0:240    Function Parameters: 
+0:242    Sequence
+0:242      'gl_WarpsPerSMNV' ( in uint WarpsPerSMNV)
+0:243      'gl_SMCountNV' ( in uint SMCountNV)
+0:244      'gl_WarpIDNV' ( in uint WarpIDNV)
+0:245      'gl_SMIDNV' ( in uint SMIDNV)
+0:252  Function Definition: sm_builtins( ( global void)
+0:252    Function Parameters: 
+0:254    Sequence
+0:254      'gl_WarpsPerSMNV' ( in uint WarpsPerSMNV)
+0:255      'gl_SMCountNV' ( in uint SMCountNV)
+0:256      'gl_WarpIDNV' ( in uint WarpIDNV)
+0:257      'gl_SMIDNV' ( in uint SMIDNV)
 0:?   Linker Objects
 0:?     'gl_WorkGroupSize' ( const 3-component vector of uint WorkGroupSize)
 0:?       8 (const uint)
@@ -651,6 +670,7 @@
 Requested GL_KHR_shader_subgroup_shuffle
 Requested GL_KHR_shader_subgroup_shuffle_relative
 Requested GL_KHR_shader_subgroup_vote
+Requested GL_NV_shader_sm_builtins
 Requested GL_NV_shader_subgroup_partitioned
 local_size = (8, 8, 1)
 ERROR: node is still EOpNull!
diff --git a/Test/baseResults/glsl.460.subgroup.mesh.out b/Test/baseResults/glsl.460.subgroup.mesh.out
index c819881..bb0e4eb 100644
--- a/Test/baseResults/glsl.460.subgroup.mesh.out
+++ b/Test/baseResults/glsl.460.subgroup.mesh.out
@@ -85,7 +85,11 @@
 ERROR: 0:96: 'subgroupPartitionedExclusiveAndNV' : required extension not requested: GL_NV_shader_subgroup_partitioned
 ERROR: 0:97: 'subgroupPartitionedExclusiveOrNV' : required extension not requested: GL_NV_shader_subgroup_partitioned
 ERROR: 0:98: 'subgroupPartitionedExclusiveXorNV' : required extension not requested: GL_NV_shader_subgroup_partitioned
-ERROR: 86 compilation errors.  No code generated.
+ERROR: 0:298: 'gl_WarpsPerSMNV' : required extension not requested: GL_NV_shader_sm_builtins
+ERROR: 0:299: 'gl_SMCountNV' : required extension not requested: GL_NV_shader_sm_builtins
+ERROR: 0:300: 'gl_WarpIDNV' : required extension not requested: GL_NV_shader_sm_builtins
+ERROR: 0:301: 'gl_SMIDNV' : required extension not requested: GL_NV_shader_sm_builtins
+ERROR: 90 compilation errors.  No code generated.
 
 
 Shader version: 460
@@ -98,6 +102,7 @@
 Requested GL_KHR_shader_subgroup_shuffle_relative
 Requested GL_KHR_shader_subgroup_vote
 Requested GL_NV_mesh_shader
+Requested GL_NV_shader_sm_builtins
 Requested GL_NV_shader_subgroup_partitioned
 max_vertices = 81
 max_primitives = 32
@@ -887,6 +892,20 @@
 0:292      subgroupPartitionedExclusiveXorNV ( global 4-component vector of uint)
 0:292        'ballot' ( temp 4-component vector of uint)
 0:292        'parti' ( temp 4-component vector of uint)
+0:296  Function Definition: sm_builtins_err( ( global void)
+0:296    Function Parameters: 
+0:298    Sequence
+0:298      'gl_WarpsPerSMNV' ( in uint WarpsPerSMNV)
+0:299      'gl_SMCountNV' ( in uint SMCountNV)
+0:300      'gl_WarpIDNV' ( in uint WarpIDNV)
+0:301      'gl_SMIDNV' ( in uint SMIDNV)
+0:308  Function Definition: sm_builtins( ( global void)
+0:308    Function Parameters: 
+0:310    Sequence
+0:310      'gl_WarpsPerSMNV' ( in uint WarpsPerSMNV)
+0:311      'gl_SMCountNV' ( in uint SMCountNV)
+0:312      'gl_WarpIDNV' ( in uint WarpIDNV)
+0:313      'gl_SMIDNV' ( in uint SMIDNV)
 0:?   Linker Objects
 0:?     'gl_WorkGroupSize' ( const 3-component vector of uint WorkGroupSize)
 0:?       32 (const uint)
@@ -910,6 +929,7 @@
 Requested GL_KHR_shader_subgroup_shuffle_relative
 Requested GL_KHR_shader_subgroup_vote
 Requested GL_NV_mesh_shader
+Requested GL_NV_shader_sm_builtins
 Requested GL_NV_shader_subgroup_partitioned
 max_vertices = 81
 max_primitives = 32
diff --git a/Test/baseResults/glsl.460.subgroup.rahit.out b/Test/baseResults/glsl.460.subgroup.rahit.out
index aba573a..0a1e4f4 100644
--- a/Test/baseResults/glsl.460.subgroup.rahit.out
+++ b/Test/baseResults/glsl.460.subgroup.rahit.out
@@ -85,7 +85,11 @@
 ERROR: 0:97: 'subgroupPartitionedExclusiveAndNV' : required extension not requested: GL_NV_shader_subgroup_partitioned
 ERROR: 0:98: 'subgroupPartitionedExclusiveOrNV' : required extension not requested: GL_NV_shader_subgroup_partitioned
 ERROR: 0:99: 'subgroupPartitionedExclusiveXorNV' : required extension not requested: GL_NV_shader_subgroup_partitioned
-ERROR: 86 compilation errors.  No code generated.
+ERROR: 0:259: 'gl_WarpsPerSMNV' : required extension not requested: GL_NV_shader_sm_builtins
+ERROR: 0:260: 'gl_SMCountNV' : required extension not requested: GL_NV_shader_sm_builtins
+ERROR: 0:261: 'gl_WarpIDNV' : required extension not requested: GL_NV_shader_sm_builtins
+ERROR: 0:262: 'gl_SMIDNV' : required extension not requested: GL_NV_shader_sm_builtins
+ERROR: 90 compilation errors.  No code generated.
 
 
 Shader version: 460
@@ -98,6 +102,7 @@
 Requested GL_KHR_shader_subgroup_shuffle_relative
 Requested GL_KHR_shader_subgroup_vote
 Requested GL_NV_ray_tracing
+Requested GL_NV_shader_sm_builtins
 Requested GL_NV_shader_subgroup_partitioned
 ERROR: node is still EOpNull!
 0:4  Function Definition: undeclared_errors(vf4; ( global 4-component vector of float)
@@ -671,6 +676,20 @@
 0:253      subgroupPartitionedExclusiveXorNV ( global 4-component vector of uint)
 0:253        'ballot' ( temp 4-component vector of uint)
 0:253        'parti' ( temp 4-component vector of uint)
+0:257  Function Definition: sm_builtins_err( ( global void)
+0:257    Function Parameters: 
+0:259    Sequence
+0:259      'gl_WarpsPerSMNV' ( in uint WarpsPerSMNV)
+0:260      'gl_SMCountNV' ( in uint SMCountNV)
+0:261      'gl_WarpIDNV' ( in uint WarpIDNV)
+0:262      'gl_SMIDNV' ( in uint SMIDNV)
+0:269  Function Definition: sm_builtins( ( global void)
+0:269    Function Parameters: 
+0:271    Sequence
+0:271      'gl_WarpsPerSMNV' ( in uint WarpsPerSMNV)
+0:272      'gl_SMCountNV' ( in uint SMCountNV)
+0:273      'gl_WarpIDNV' ( in uint WarpIDNV)
+0:274      'gl_SMIDNV' ( in uint SMIDNV)
 0:?   Linker Objects
 0:?     'incomingPayload' (layout( location=1) rayPayloadInNV 4-component vector of float)
 
@@ -688,6 +707,7 @@
 Requested GL_KHR_shader_subgroup_shuffle_relative
 Requested GL_KHR_shader_subgroup_vote
 Requested GL_NV_ray_tracing
+Requested GL_NV_shader_sm_builtins
 Requested GL_NV_shader_subgroup_partitioned
 ERROR: node is still EOpNull!
 0:106  Function Definition: main( ( global void)
diff --git a/Test/baseResults/glsl.460.subgroup.rcall.out b/Test/baseResults/glsl.460.subgroup.rcall.out
index d6b4895..6bffdc9 100644
--- a/Test/baseResults/glsl.460.subgroup.rcall.out
+++ b/Test/baseResults/glsl.460.subgroup.rcall.out
@@ -85,7 +85,11 @@
 ERROR: 0:97: 'subgroupPartitionedExclusiveAndNV' : required extension not requested: GL_NV_shader_subgroup_partitioned
 ERROR: 0:98: 'subgroupPartitionedExclusiveOrNV' : required extension not requested: GL_NV_shader_subgroup_partitioned
 ERROR: 0:99: 'subgroupPartitionedExclusiveXorNV' : required extension not requested: GL_NV_shader_subgroup_partitioned
-ERROR: 86 compilation errors.  No code generated.
+ERROR: 0:247: 'gl_WarpsPerSMNV' : required extension not requested: GL_NV_shader_sm_builtins
+ERROR: 0:248: 'gl_SMCountNV' : required extension not requested: GL_NV_shader_sm_builtins
+ERROR: 0:249: 'gl_WarpIDNV' : required extension not requested: GL_NV_shader_sm_builtins
+ERROR: 0:250: 'gl_SMIDNV' : required extension not requested: GL_NV_shader_sm_builtins
+ERROR: 90 compilation errors.  No code generated.
 
 
 Shader version: 460
@@ -98,6 +102,7 @@
 Requested GL_KHR_shader_subgroup_shuffle_relative
 Requested GL_KHR_shader_subgroup_vote
 Requested GL_NV_ray_tracing
+Requested GL_NV_shader_sm_builtins
 Requested GL_NV_shader_subgroup_partitioned
 ERROR: node is still EOpNull!
 0:4  Function Definition: undeclared_errors(vf4; ( global 4-component vector of float)
@@ -614,6 +619,20 @@
 0:241      subgroupPartitionedExclusiveXorNV ( global 4-component vector of uint)
 0:241        'ballot' ( temp 4-component vector of uint)
 0:241        'parti' ( temp 4-component vector of uint)
+0:245  Function Definition: sm_builtins_err( ( global void)
+0:245    Function Parameters: 
+0:247    Sequence
+0:247      'gl_WarpsPerSMNV' ( in uint WarpsPerSMNV)
+0:248      'gl_SMCountNV' ( in uint SMCountNV)
+0:249      'gl_WarpIDNV' ( in uint WarpIDNV)
+0:250      'gl_SMIDNV' ( in uint SMIDNV)
+0:257  Function Definition: sm_builtins( ( global void)
+0:257    Function Parameters: 
+0:259    Sequence
+0:259      'gl_WarpsPerSMNV' ( in uint WarpsPerSMNV)
+0:260      'gl_SMCountNV' ( in uint SMCountNV)
+0:261      'gl_WarpIDNV' ( in uint WarpIDNV)
+0:262      'gl_SMIDNV' ( in uint SMIDNV)
 0:?   Linker Objects
 0:?     'data0' (layout( location=0) callableDataNV 4-component vector of float)
 0:?     'anon@0' (layout( location=1) callableDataInNV block{ callableDataInNV uint data1})
@@ -632,6 +651,7 @@
 Requested GL_KHR_shader_subgroup_shuffle_relative
 Requested GL_KHR_shader_subgroup_vote
 Requested GL_NV_ray_tracing
+Requested GL_NV_shader_sm_builtins
 Requested GL_NV_shader_subgroup_partitioned
 ERROR: node is still EOpNull!
 0:109  Function Definition: main( ( global void)
diff --git a/Test/baseResults/glsl.460.subgroup.rchit.out b/Test/baseResults/glsl.460.subgroup.rchit.out
index 14a8d84..1ea9e69 100644
--- a/Test/baseResults/glsl.460.subgroup.rchit.out
+++ b/Test/baseResults/glsl.460.subgroup.rchit.out
@@ -85,7 +85,11 @@
 ERROR: 0:97: 'subgroupPartitionedExclusiveAndNV' : required extension not requested: GL_NV_shader_subgroup_partitioned
 ERROR: 0:98: 'subgroupPartitionedExclusiveOrNV' : required extension not requested: GL_NV_shader_subgroup_partitioned
 ERROR: 0:99: 'subgroupPartitionedExclusiveXorNV' : required extension not requested: GL_NV_shader_subgroup_partitioned
-ERROR: 86 compilation errors.  No code generated.
+ERROR: 0:257: 'gl_WarpsPerSMNV' : required extension not requested: GL_NV_shader_sm_builtins
+ERROR: 0:258: 'gl_SMCountNV' : required extension not requested: GL_NV_shader_sm_builtins
+ERROR: 0:259: 'gl_WarpIDNV' : required extension not requested: GL_NV_shader_sm_builtins
+ERROR: 0:260: 'gl_SMIDNV' : required extension not requested: GL_NV_shader_sm_builtins
+ERROR: 90 compilation errors.  No code generated.
 
 
 Shader version: 460
@@ -98,6 +102,7 @@
 Requested GL_KHR_shader_subgroup_shuffle_relative
 Requested GL_KHR_shader_subgroup_vote
 Requested GL_NV_ray_tracing
+Requested GL_NV_shader_sm_builtins
 Requested GL_NV_shader_subgroup_partitioned
 ERROR: node is still EOpNull!
 0:4  Function Definition: undeclared_errors(vf4; ( global 4-component vector of float)
@@ -680,6 +685,20 @@
 0:251      subgroupPartitionedExclusiveXorNV ( global 4-component vector of uint)
 0:251        'ballot' ( temp 4-component vector of uint)
 0:251        'parti' ( temp 4-component vector of uint)
+0:255  Function Definition: sm_builtins_err( ( global void)
+0:255    Function Parameters: 
+0:257    Sequence
+0:257      'gl_WarpsPerSMNV' ( in uint WarpsPerSMNV)
+0:258      'gl_SMCountNV' ( in uint SMCountNV)
+0:259      'gl_WarpIDNV' ( in uint WarpIDNV)
+0:260      'gl_SMIDNV' ( in uint SMIDNV)
+0:267  Function Definition: sm_builtins( ( global void)
+0:267    Function Parameters: 
+0:269    Sequence
+0:269      'gl_WarpsPerSMNV' ( in uint WarpsPerSMNV)
+0:270      'gl_SMCountNV' ( in uint SMCountNV)
+0:271      'gl_WarpIDNV' ( in uint WarpIDNV)
+0:272      'gl_SMIDNV' ( in uint SMIDNV)
 0:?   Linker Objects
 0:?     'accNV' (layout( set=0 binding=0) uniform accelerationStructureNV)
 0:?     'localPayload' (layout( location=0) rayPayloadNV 4-component vector of float)
@@ -699,6 +718,7 @@
 Requested GL_KHR_shader_subgroup_shuffle_relative
 Requested GL_KHR_shader_subgroup_vote
 Requested GL_NV_ray_tracing
+Requested GL_NV_shader_sm_builtins
 Requested GL_NV_shader_subgroup_partitioned
 ERROR: node is still EOpNull!
 0:108  Function Definition: main( ( global void)
diff --git a/Test/baseResults/glsl.460.subgroup.rgen.out b/Test/baseResults/glsl.460.subgroup.rgen.out
index a3c5bbb..dfe1e2b 100644
--- a/Test/baseResults/glsl.460.subgroup.rgen.out
+++ b/Test/baseResults/glsl.460.subgroup.rgen.out
@@ -85,7 +85,11 @@
 ERROR: 0:97: 'subgroupPartitionedExclusiveAndNV' : required extension not requested: GL_NV_shader_subgroup_partitioned
 ERROR: 0:98: 'subgroupPartitionedExclusiveOrNV' : required extension not requested: GL_NV_shader_subgroup_partitioned
 ERROR: 0:99: 'subgroupPartitionedExclusiveXorNV' : required extension not requested: GL_NV_shader_subgroup_partitioned
-ERROR: 86 compilation errors.  No code generated.
+ERROR: 0:251: 'gl_WarpsPerSMNV' : required extension not requested: GL_NV_shader_sm_builtins
+ERROR: 0:252: 'gl_SMCountNV' : required extension not requested: GL_NV_shader_sm_builtins
+ERROR: 0:253: 'gl_WarpIDNV' : required extension not requested: GL_NV_shader_sm_builtins
+ERROR: 0:254: 'gl_SMIDNV' : required extension not requested: GL_NV_shader_sm_builtins
+ERROR: 90 compilation errors.  No code generated.
 
 
 Shader version: 460
@@ -98,6 +102,7 @@
 Requested GL_KHR_shader_subgroup_shuffle_relative
 Requested GL_KHR_shader_subgroup_vote
 Requested GL_NV_ray_tracing
+Requested GL_NV_shader_sm_builtins
 Requested GL_NV_shader_subgroup_partitioned
 ERROR: node is still EOpNull!
 0:4  Function Definition: undeclared_errors(vf4; ( global 4-component vector of float)
@@ -644,6 +649,20 @@
 0:245      subgroupPartitionedExclusiveXorNV ( global 4-component vector of uint)
 0:245        'ballot' ( temp 4-component vector of uint)
 0:245        'parti' ( temp 4-component vector of uint)
+0:249  Function Definition: sm_builtins_err( ( global void)
+0:249    Function Parameters: 
+0:251    Sequence
+0:251      'gl_WarpsPerSMNV' ( in uint WarpsPerSMNV)
+0:252      'gl_SMCountNV' ( in uint SMCountNV)
+0:253      'gl_WarpIDNV' ( in uint WarpIDNV)
+0:254      'gl_SMIDNV' ( in uint SMIDNV)
+0:261  Function Definition: sm_builtins( ( global void)
+0:261    Function Parameters: 
+0:263    Sequence
+0:263      'gl_WarpsPerSMNV' ( in uint WarpsPerSMNV)
+0:264      'gl_SMCountNV' ( in uint SMCountNV)
+0:265      'gl_WarpIDNV' ( in uint WarpIDNV)
+0:266      'gl_SMIDNV' ( in uint SMIDNV)
 0:?   Linker Objects
 0:?     'accNV0' (layout( set=0 binding=0) uniform accelerationStructureNV)
 0:?     'accNV1' (layout( set=0 binding=1) uniform accelerationStructureNV)
@@ -664,6 +683,7 @@
 Requested GL_KHR_shader_subgroup_shuffle_relative
 Requested GL_KHR_shader_subgroup_vote
 Requested GL_NV_ray_tracing
+Requested GL_NV_shader_sm_builtins
 Requested GL_NV_shader_subgroup_partitioned
 ERROR: node is still EOpNull!
 0:113  Function Definition: main( ( global void)
diff --git a/Test/baseResults/glsl.460.subgroup.rint.out b/Test/baseResults/glsl.460.subgroup.rint.out
index 31a8a59..9915ecf 100644
--- a/Test/baseResults/glsl.460.subgroup.rint.out
+++ b/Test/baseResults/glsl.460.subgroup.rint.out
@@ -85,7 +85,11 @@
 ERROR: 0:98: 'subgroupPartitionedExclusiveAndNV' : required extension not requested: GL_NV_shader_subgroup_partitioned
 ERROR: 0:99: 'subgroupPartitionedExclusiveOrNV' : required extension not requested: GL_NV_shader_subgroup_partitioned
 ERROR: 0:100: 'subgroupPartitionedExclusiveXorNV' : required extension not requested: GL_NV_shader_subgroup_partitioned
-ERROR: 86 compilation errors.  No code generated.
+ERROR: 0:257: 'gl_WarpsPerSMNV' : required extension not requested: GL_NV_shader_sm_builtins
+ERROR: 0:258: 'gl_SMCountNV' : required extension not requested: GL_NV_shader_sm_builtins
+ERROR: 0:259: 'gl_WarpIDNV' : required extension not requested: GL_NV_shader_sm_builtins
+ERROR: 0:260: 'gl_SMIDNV' : required extension not requested: GL_NV_shader_sm_builtins
+ERROR: 90 compilation errors.  No code generated.
 
 
 Shader version: 460
@@ -98,6 +102,7 @@
 Requested GL_KHR_shader_subgroup_shuffle_relative
 Requested GL_KHR_shader_subgroup_vote
 Requested GL_NV_ray_tracing
+Requested GL_NV_shader_sm_builtins
 Requested GL_NV_shader_subgroup_partitioned
 ERROR: node is still EOpNull!
 0:5  Function Definition: undeclared_errors(vf4; ( global 4-component vector of float)
@@ -658,6 +663,20 @@
 0:251      subgroupPartitionedExclusiveXorNV ( global 4-component vector of uint)
 0:251        'ballot' ( temp 4-component vector of uint)
 0:251        'parti' ( temp 4-component vector of uint)
+0:255  Function Definition: sm_builtins_err( ( global void)
+0:255    Function Parameters: 
+0:257    Sequence
+0:257      'gl_WarpsPerSMNV' ( in uint WarpsPerSMNV)
+0:258      'gl_SMCountNV' ( in uint SMCountNV)
+0:259      'gl_WarpIDNV' ( in uint WarpIDNV)
+0:260      'gl_SMIDNV' ( in uint SMIDNV)
+0:267  Function Definition: sm_builtins( ( global void)
+0:267    Function Parameters: 
+0:269    Sequence
+0:269      'gl_WarpsPerSMNV' ( in uint WarpsPerSMNV)
+0:270      'gl_SMCountNV' ( in uint SMCountNV)
+0:271      'gl_WarpIDNV' ( in uint WarpIDNV)
+0:272      'gl_SMIDNV' ( in uint SMIDNV)
 0:?   Linker Objects
 0:?     'iAttr' ( hitAttributeNV 4-component vector of float)
 
@@ -675,6 +694,7 @@
 Requested GL_KHR_shader_subgroup_shuffle_relative
 Requested GL_KHR_shader_subgroup_vote
 Requested GL_NV_ray_tracing
+Requested GL_NV_shader_sm_builtins
 Requested GL_NV_shader_subgroup_partitioned
 ERROR: node is still EOpNull!
 0:108  Function Definition: main( ( global void)
diff --git a/Test/baseResults/glsl.460.subgroup.rmiss.out b/Test/baseResults/glsl.460.subgroup.rmiss.out
index 2ca136d..ddf7d1b 100644
--- a/Test/baseResults/glsl.460.subgroup.rmiss.out
+++ b/Test/baseResults/glsl.460.subgroup.rmiss.out
@@ -85,7 +85,11 @@
 ERROR: 0:98: 'subgroupPartitionedExclusiveAndNV' : required extension not requested: GL_NV_shader_subgroup_partitioned
 ERROR: 0:99: 'subgroupPartitionedExclusiveOrNV' : required extension not requested: GL_NV_shader_subgroup_partitioned
 ERROR: 0:100: 'subgroupPartitionedExclusiveXorNV' : required extension not requested: GL_NV_shader_subgroup_partitioned
-ERROR: 86 compilation errors.  No code generated.
+ERROR: 0:251: 'gl_WarpsPerSMNV' : required extension not requested: GL_NV_shader_sm_builtins
+ERROR: 0:252: 'gl_SMCountNV' : required extension not requested: GL_NV_shader_sm_builtins
+ERROR: 0:253: 'gl_WarpIDNV' : required extension not requested: GL_NV_shader_sm_builtins
+ERROR: 0:254: 'gl_SMIDNV' : required extension not requested: GL_NV_shader_sm_builtins
+ERROR: 90 compilation errors.  No code generated.
 
 
 Shader version: 460
@@ -98,6 +102,7 @@
 Requested GL_KHR_shader_subgroup_shuffle_relative
 Requested GL_KHR_shader_subgroup_vote
 Requested GL_NV_ray_tracing
+Requested GL_NV_shader_sm_builtins
 Requested GL_NV_shader_subgroup_partitioned
 ERROR: node is still EOpNull!
 0:5  Function Definition: undeclared_errors(vf4; ( global 4-component vector of float)
@@ -652,6 +657,20 @@
 0:245      subgroupPartitionedExclusiveXorNV ( global 4-component vector of uint)
 0:245        'ballot' ( temp 4-component vector of uint)
 0:245        'parti' ( temp 4-component vector of uint)
+0:249  Function Definition: sm_builtins_err( ( global void)
+0:249    Function Parameters: 
+0:251    Sequence
+0:251      'gl_WarpsPerSMNV' ( in uint WarpsPerSMNV)
+0:252      'gl_SMCountNV' ( in uint SMCountNV)
+0:253      'gl_WarpIDNV' ( in uint WarpIDNV)
+0:254      'gl_SMIDNV' ( in uint SMIDNV)
+0:261  Function Definition: sm_builtins( ( global void)
+0:261    Function Parameters: 
+0:263    Sequence
+0:263      'gl_WarpsPerSMNV' ( in uint WarpsPerSMNV)
+0:264      'gl_SMCountNV' ( in uint SMCountNV)
+0:265      'gl_WarpIDNV' ( in uint WarpIDNV)
+0:266      'gl_SMIDNV' ( in uint SMIDNV)
 0:?   Linker Objects
 0:?     'accNV' (layout( set=0 binding=0) uniform accelerationStructureNV)
 0:?     'localPayload' (layout( location=0) rayPayloadNV 4-component vector of float)
@@ -671,6 +690,7 @@
 Requested GL_KHR_shader_subgroup_shuffle_relative
 Requested GL_KHR_shader_subgroup_vote
 Requested GL_NV_ray_tracing
+Requested GL_NV_shader_sm_builtins
 Requested GL_NV_shader_subgroup_partitioned
 ERROR: node is still EOpNull!
 0:109  Function Definition: main( ( global void)
diff --git a/Test/baseResults/glsl.460.subgroup.task.out b/Test/baseResults/glsl.460.subgroup.task.out
index d953646..8d2a1d3 100644
--- a/Test/baseResults/glsl.460.subgroup.task.out
+++ b/Test/baseResults/glsl.460.subgroup.task.out
@@ -85,7 +85,11 @@
 ERROR: 0:96: 'subgroupPartitionedExclusiveAndNV' : required extension not requested: GL_NV_shader_subgroup_partitioned
 ERROR: 0:97: 'subgroupPartitionedExclusiveOrNV' : required extension not requested: GL_NV_shader_subgroup_partitioned
 ERROR: 0:98: 'subgroupPartitionedExclusiveXorNV' : required extension not requested: GL_NV_shader_subgroup_partitioned
-ERROR: 86 compilation errors.  No code generated.
+ERROR: 0:288: 'gl_WarpsPerSMNV' : required extension not requested: GL_NV_shader_sm_builtins
+ERROR: 0:289: 'gl_SMCountNV' : required extension not requested: GL_NV_shader_sm_builtins
+ERROR: 0:290: 'gl_WarpIDNV' : required extension not requested: GL_NV_shader_sm_builtins
+ERROR: 0:291: 'gl_SMIDNV' : required extension not requested: GL_NV_shader_sm_builtins
+ERROR: 90 compilation errors.  No code generated.
 
 
 Shader version: 460
@@ -98,6 +102,7 @@
 Requested GL_KHR_shader_subgroup_shuffle_relative
 Requested GL_KHR_shader_subgroup_vote
 Requested GL_NV_mesh_shader
+Requested GL_NV_shader_sm_builtins
 Requested GL_NV_shader_subgroup_partitioned
 local_size = (32, 1, 1)
 ERROR: node is still EOpNull!
@@ -729,6 +734,20 @@
 0:282      subgroupPartitionedExclusiveXorNV ( global 4-component vector of uint)
 0:282        'ballot' ( temp 4-component vector of uint)
 0:282        'parti' ( temp 4-component vector of uint)
+0:286  Function Definition: sm_builtins_err( ( global void)
+0:286    Function Parameters: 
+0:288    Sequence
+0:288      'gl_WarpsPerSMNV' ( in uint WarpsPerSMNV)
+0:289      'gl_SMCountNV' ( in uint SMCountNV)
+0:290      'gl_WarpIDNV' ( in uint WarpIDNV)
+0:291      'gl_SMIDNV' ( in uint SMIDNV)
+0:298  Function Definition: sm_builtins( ( global void)
+0:298    Function Parameters: 
+0:300    Sequence
+0:300      'gl_WarpsPerSMNV' ( in uint WarpsPerSMNV)
+0:301      'gl_SMCountNV' ( in uint SMCountNV)
+0:302      'gl_WarpIDNV' ( in uint WarpIDNV)
+0:303      'gl_SMIDNV' ( in uint SMIDNV)
 0:?   Linker Objects
 0:?     'gl_WorkGroupSize' ( const 3-component vector of uint WorkGroupSize)
 0:?       32 (const uint)
@@ -753,6 +772,7 @@
 Requested GL_KHR_shader_subgroup_shuffle_relative
 Requested GL_KHR_shader_subgroup_vote
 Requested GL_NV_mesh_shader
+Requested GL_NV_shader_sm_builtins
 Requested GL_NV_shader_subgroup_partitioned
 local_size = (32, 1, 1)
 ERROR: node is still EOpNull!
diff --git a/Test/baseResults/hlsl.structbuffer.fn2.comp.out b/Test/baseResults/hlsl.structbuffer.fn2.comp.out
index c9633cd..517b48c 100644
--- a/Test/baseResults/hlsl.structbuffer.fn2.comp.out
+++ b/Test/baseResults/hlsl.structbuffer.fn2.comp.out
@@ -135,7 +135,6 @@
 0:?     'g_output' (layout( binding=1 rg32ui) uniform uimageBuffer)
 0:?     'dispatchId' ( in 3-component vector of uint GlobalInvocationID)
 
-Validation failed
 // Module Version 10000
 // Generated by (magic number): 80007
 // Id's are bound by 63
diff --git a/Test/baseResults/spv.fsi.frag.out b/Test/baseResults/spv.fsi.frag.out
new file mode 100644
index 0000000..51fb068
--- /dev/null
+++ b/Test/baseResults/spv.fsi.frag.out
@@ -0,0 +1,56 @@
+spv.fsi.frag
+// Module Version 10000
+// Generated by (magic number): 80007
+// Id's are bound by 24
+
+                              Capability Shader
+                              Capability CapabilityFragmentShaderSampleInterlockEXT
+                              Extension  "SPV_EXT_fragment_shader_interlock"
+               1:             ExtInstImport  "GLSL.std.450"
+                              MemoryModel Logical GLSL450
+                              EntryPoint Fragment 4  "main"
+                              ExecutionMode 4 OriginUpperLeft
+                              ExecutionMode 4 SampleInterlockOrderedEXT
+                              Source GLSL 450
+                              SourceExtension  "GL_ARB_fragment_shader_interlock"
+                              Name 4  "main"
+                              Name 7  "B1"
+                              MemberName 7(B1) 0  "x"
+                              Name 9  "b1"
+                              Name 17  "im"
+                              MemberDecorate 7(B1) 0 Coherent
+                              MemberDecorate 7(B1) 0 Offset 0
+                              Decorate 7(B1) BufferBlock
+                              Decorate 9(b1) DescriptorSet 0
+                              Decorate 9(b1) Binding 0
+                              Decorate 17(im) DescriptorSet 0
+                              Decorate 17(im) Binding 1
+                              Decorate 17(im) Coherent
+               2:             TypeVoid
+               3:             TypeFunction 2
+               6:             TypeInt 32 1
+           7(B1):             TypeStruct 6(int)
+               8:             TypePointer Uniform 7(B1)
+           9(b1):      8(ptr) Variable Uniform
+              10:      6(int) Constant 0
+              11:      6(int) Constant 1
+              12:             TypePointer Uniform 6(int)
+              14:             TypeFloat 32
+              15:             TypeImage 14(float) 2D nonsampled format:Rgba32f
+              16:             TypePointer UniformConstant 15
+          17(im):     16(ptr) Variable UniformConstant
+              19:             TypeVector 6(int) 2
+              20:   19(ivec2) ConstantComposite 10 10
+              21:             TypeVector 14(float) 4
+              22:   14(float) Constant 0
+              23:   21(fvec4) ConstantComposite 22 22 22 22
+         4(main):           2 Function None 3
+               5:             Label
+                              BeginInvocationInterlockEXT
+              13:     12(ptr) AccessChain 9(b1) 10
+                              Store 13 11
+              18:          15 Load 17(im)
+                              ImageWrite 18 20 23
+                              EndInvocationInterlockEXT
+                              Return
+                              FunctionEnd
diff --git a/Test/baseResults/spv.fsi_Error.frag.out b/Test/baseResults/spv.fsi_Error.frag.out
new file mode 100644
index 0000000..4a03436
--- /dev/null
+++ b/Test/baseResults/spv.fsi_Error.frag.out
@@ -0,0 +1,14 @@
+spv.fsi_Error.frag
+ERROR: 0:4: 'pixel_interlock_ordered' : can only apply to 'in' 
+ERROR: 0:7: 'pixel_interlock_unordered' : cannot change previously set fragment shader interlock ordering 
+ERROR: 0:11: '' : beginInvocationInterlockARB() must be in main() 
+ERROR: 0:12: '' : endInvocationInterlockARB() must be in main() 
+ERROR: 0:17: '' : endInvocationInterlockARB() must only be called once 
+ERROR: 0:18: '' : beginInvocationInterlockARB() must only be called once 
+ERROR: 0:18: '' : beginInvocationInterlockARB() must be called before endInvocationInterlockARB() 
+ERROR: 0:22: '' : endInvocationInterlockARB() cannot be placed after a return from main() 
+ERROR: 0:22: '' : endInvocationInterlockARB() must only be called once 
+ERROR: 9 compilation errors.  No code generated.
+
+
+SPIR-V is not generated for failed compile or link
diff --git a/Test/baseResults/spv.memoryScopeSemantics.comp.out b/Test/baseResults/spv.memoryScopeSemantics.comp.out
index 9361e76..8c4e576 100644
--- a/Test/baseResults/spv.memoryScopeSemantics.comp.out
+++ b/Test/baseResults/spv.memoryScopeSemantics.comp.out
@@ -1,7 +1,7 @@
 spv.memoryScopeSemantics.comp
 // Module Version 10300
 // Generated by (magic number): 80007
-// Id's are bound by 148
+// Id's are bound by 163
 
                               Capability Shader
                               Capability Int64
@@ -23,59 +23,66 @@
                               Name 23  "atomu"
                               Name 24  "value"
                               Name 36  "imagei"
-                              Name 45  "imageu"
-                              Name 65  "BufferU"
-                              MemberName 65(BufferU) 0  "x"
-                              Name 67  "bufferu"
-                              Name 72  "y"
-                              Name 77  "BufferI"
-                              MemberName 77(BufferI) 0  "x"
-                              Name 79  "bufferi"
-                              Name 83  "A"
-                              MemberName 83(A) 0  "x"
-                              Name 84  "BufferJ"
-                              MemberName 84(BufferJ) 0  "a"
-                              Name 87  "bufferj"
-                              Name 98  "BufferK"
-                              MemberName 98(BufferK) 0  "x"
-                              Name 100  "bufferk"
-                              Name 110  "imagej"
-                              Name 122  "samp"
-                              Name 133  "atomu64"
-                              Name 138  "atomi64"
-                              Name 143  "BufferL"
-                              MemberName 143(BufferL) 0  "x"
-                              Name 145  "bufferl"
+                              Name 46  "imageu"
+                              Name 66  "BufferU"
+                              MemberName 66(BufferU) 0  "x"
+                              Name 68  "bufferu"
+                              Name 73  "y"
+                              Name 78  "BufferI"
+                              MemberName 78(BufferI) 0  "x"
+                              Name 80  "bufferi"
+                              Name 84  "A"
+                              MemberName 84(A) 0  "x"
+                              Name 85  "BufferJ"
+                              MemberName 85(BufferJ) 0  "a"
+                              Name 88  "bufferj"
+                              Name 99  "BufferK"
+                              MemberName 99(BufferK) 0  "x"
+                              Name 101  "bufferk"
+                              Name 111  "imagej"
+                              Name 123  "samp"
+                              Name 134  "atomu64"
+                              Name 139  "atomi64"
+                              Name 144  "BufferL"
+                              MemberName 144(BufferL) 0  "x"
+                              Name 146  "bufferl"
+                              Name 151  "BufferM"
+                              MemberName 151(BufferM) 0  "x"
+                              Name 153  "bufferm"
                               Decorate 36(imagei) DescriptorSet 0
                               Decorate 36(imagei) Binding 1
-                              Decorate 45(imageu) DescriptorSet 0
-                              Decorate 45(imageu) Binding 0
-                              MemberDecorate 65(BufferU) 0 Offset 0
-                              Decorate 65(BufferU) Block
-                              Decorate 67(bufferu) DescriptorSet 0
-                              Decorate 67(bufferu) Binding 2
-                              MemberDecorate 77(BufferI) 0 Offset 0
-                              Decorate 77(BufferI) Block
-                              Decorate 79(bufferi) DescriptorSet 0
-                              Decorate 79(bufferi) Binding 3
-                              Decorate 82 ArrayStride 4
-                              MemberDecorate 83(A) 0 Offset 0
-                              MemberDecorate 84(BufferJ) 0 Offset 0
-                              Decorate 84(BufferJ) Block
-                              Decorate 87(bufferj) DescriptorSet 0
-                              Decorate 87(bufferj) Binding 4
-                              MemberDecorate 98(BufferK) 0 Offset 0
-                              Decorate 98(BufferK) Block
-                              Decorate 100(bufferk) DescriptorSet 0
-                              Decorate 100(bufferk) Binding 7
-                              Decorate 110(imagej) DescriptorSet 0
-                              Decorate 110(imagej) Binding 5
-                              Decorate 122(samp) DescriptorSet 0
-                              Decorate 122(samp) Binding 6
-                              MemberDecorate 143(BufferL) 0 Offset 0
-                              Decorate 143(BufferL) Block
-                              Decorate 145(bufferl) DescriptorSet 0
-                              Decorate 145(bufferl) Binding 8
+                              Decorate 46(imageu) DescriptorSet 0
+                              Decorate 46(imageu) Binding 0
+                              MemberDecorate 66(BufferU) 0 Offset 0
+                              Decorate 66(BufferU) Block
+                              Decorate 68(bufferu) DescriptorSet 0
+                              Decorate 68(bufferu) Binding 2
+                              MemberDecorate 78(BufferI) 0 Offset 0
+                              Decorate 78(BufferI) Block
+                              Decorate 80(bufferi) DescriptorSet 0
+                              Decorate 80(bufferi) Binding 3
+                              Decorate 83 ArrayStride 4
+                              MemberDecorate 84(A) 0 Offset 0
+                              MemberDecorate 85(BufferJ) 0 Offset 0
+                              Decorate 85(BufferJ) Block
+                              Decorate 88(bufferj) DescriptorSet 0
+                              Decorate 88(bufferj) Binding 4
+                              MemberDecorate 99(BufferK) 0 Offset 0
+                              Decorate 99(BufferK) Block
+                              Decorate 101(bufferk) DescriptorSet 0
+                              Decorate 101(bufferk) Binding 7
+                              Decorate 111(imagej) DescriptorSet 0
+                              Decorate 111(imagej) Binding 5
+                              Decorate 123(samp) DescriptorSet 0
+                              Decorate 123(samp) Binding 6
+                              MemberDecorate 144(BufferL) 0 Offset 0
+                              Decorate 144(BufferL) Block
+                              Decorate 146(bufferl) DescriptorSet 0
+                              Decorate 146(bufferl) Binding 8
+                              MemberDecorate 151(BufferM) 0 Offset 0
+                              Decorate 151(BufferM) Block
+                              Decorate 153(bufferm) DescriptorSet 0
+                              Decorate 153(bufferm) Binding 9
                2:             TypeVoid
                3:             TypeFunction 2
                6:             TypeInt 32 1
@@ -106,67 +113,72 @@
               38:      6(int) Constant 0
               39:   37(ivec2) ConstantComposite 38 38
               40:             TypePointer Image 6(int)
-              43:             TypeImage 15(int) 2D nonsampled format:R32ui
-              44:             TypePointer UniformConstant 43
-      45(imageu):     44(ptr) Variable UniformConstant
-              46:     15(int) Constant 3
-              47:             TypePointer Image 15(int)
-              50:     15(int) Constant 4
-              52:     15(int) Constant 7
-              57:      6(int) Constant 7
-              61:     15(int) Constant 10
-              63:     15(int) Constant 322
-     65(BufferU):             TypeStruct 15(int)
-              66:             TypePointer StorageBuffer 65(BufferU)
-     67(bufferu):     66(ptr) Variable StorageBuffer
-              68:             TypePointer StorageBuffer 15(int)
-              70:     15(int) Constant 1
-     77(BufferI):             TypeStruct 15(int)
-              78:             TypePointer StorageBuffer 77(BufferI)
-     79(bufferi):     78(ptr) Variable StorageBuffer
-              82:             TypeArray 15(int) 26
-           83(A):             TypeStruct 82
-     84(BufferJ):             TypeStruct 83(A)
-              85:             TypeArray 84(BufferJ) 26
-              86:             TypePointer StorageBuffer 85
-     87(bufferj):     86(ptr) Variable StorageBuffer
-              94:             TypePointer StorageBuffer 83(A)
-     98(BufferK):             TypeStruct 15(int)
-              99:             TypePointer Uniform 98(BufferK)
-    100(bufferk):     99(ptr) Variable Uniform
-             101:             TypePointer Uniform 15(int)
-             106:             TypeVector 6(int) 4
-             108:             TypeArray 34 26
-             109:             TypePointer UniformConstant 108
-     110(imagej):    109(ptr) Variable UniformConstant
-             116:  106(ivec4) ConstantComposite 38 38 38 38
-             117:             TypeFloat 32
-             118:             TypeImage 117(float) 2D sampled format:Unknown
-             119:             TypeSampledImage 118
-             120:             TypeArray 119 26
-             121:             TypePointer UniformConstant 120
-       122(samp):    121(ptr) Variable UniformConstant
-             123:             TypePointer UniformConstant 119
-             126:             TypeVector 117(float) 2
-             127:  117(float) Constant 0
-             128:  126(fvec2) ConstantComposite 127 127
-             129:             TypeVector 117(float) 4
-             131:             TypeInt 64 0
-             132:             TypePointer Workgroup 131(int64_t)
-    133(atomu64):    132(ptr) Variable Workgroup
-             134:131(int64_t) Constant 7 0
-             136:             TypeInt 64 1
-             137:             TypePointer Workgroup 136(int64_t)
-    138(atomi64):    137(ptr) Variable Workgroup
-             139:136(int64_t) Constant 10 0
-    143(BufferL):             TypeStruct 15(int)
-             144:             TypePointer StorageBuffer 143(BufferL)
-    145(bufferl):    144(ptr) Variable StorageBuffer
+              42:     15(int) Constant 32768
+              44:             TypeImage 15(int) 2D nonsampled format:R32ui
+              45:             TypePointer UniformConstant 44
+      46(imageu):     45(ptr) Variable UniformConstant
+              47:     15(int) Constant 3
+              48:             TypePointer Image 15(int)
+              51:     15(int) Constant 4
+              53:     15(int) Constant 7
+              58:      6(int) Constant 7
+              62:     15(int) Constant 10
+              64:     15(int) Constant 322
+     66(BufferU):             TypeStruct 15(int)
+              67:             TypePointer StorageBuffer 66(BufferU)
+     68(bufferu):     67(ptr) Variable StorageBuffer
+              69:             TypePointer StorageBuffer 15(int)
+              71:     15(int) Constant 1
+     78(BufferI):             TypeStruct 15(int)
+              79:             TypePointer StorageBuffer 78(BufferI)
+     80(bufferi):     79(ptr) Variable StorageBuffer
+              83:             TypeArray 15(int) 26
+           84(A):             TypeStruct 83
+     85(BufferJ):             TypeStruct 84(A)
+              86:             TypeArray 85(BufferJ) 26
+              87:             TypePointer StorageBuffer 86
+     88(bufferj):     87(ptr) Variable StorageBuffer
+              95:             TypePointer StorageBuffer 84(A)
+     99(BufferK):             TypeStruct 15(int)
+             100:             TypePointer Uniform 99(BufferK)
+    101(bufferk):    100(ptr) Variable Uniform
+             102:             TypePointer Uniform 15(int)
+             107:             TypeVector 6(int) 4
+             109:             TypeArray 34 26
+             110:             TypePointer UniformConstant 109
+     111(imagej):    110(ptr) Variable UniformConstant
+             117:  107(ivec4) ConstantComposite 38 38 38 38
+             118:             TypeFloat 32
+             119:             TypeImage 118(float) 2D sampled format:Unknown
+             120:             TypeSampledImage 119
+             121:             TypeArray 120 26
+             122:             TypePointer UniformConstant 121
+       123(samp):    122(ptr) Variable UniformConstant
+             124:             TypePointer UniformConstant 120
+             127:             TypeVector 118(float) 2
+             128:  118(float) Constant 0
+             129:  127(fvec2) ConstantComposite 128 128
+             130:             TypeVector 118(float) 4
+             132:             TypeInt 64 0
+             133:             TypePointer Workgroup 132(int64_t)
+    134(atomu64):    133(ptr) Variable Workgroup
+             135:132(int64_t) Constant 7 0
+             137:             TypeInt 64 1
+             138:             TypePointer Workgroup 137(int64_t)
+    139(atomi64):    138(ptr) Variable Workgroup
+             140:137(int64_t) Constant 10 0
+    144(BufferL):             TypeStruct 15(int)
+             145:             TypePointer StorageBuffer 144(BufferL)
+    146(bufferl):    145(ptr) Variable StorageBuffer
+    151(BufferM):             TypeStruct 15(int)
+             152:             TypePointer StorageBuffer 151(BufferM)
+    153(bufferm):    152(ptr) Variable StorageBuffer
+             161:      6(int) Constant 32768
          4(main):           2 Function None 3
                5:             Label
         8(origi):      7(ptr) Variable Function
        21(origu):     20(ptr) Variable Function
-           72(y):     20(ptr) Variable Function
+           73(y):     20(ptr) Variable Function
               19:      6(int) AtomicIAdd 10(atomi) 12 18 11
                               Store 8(origi) 19
               25:     15(int) Load 24(value) MakePointerVisibleKHR NonPrivatePointerKHR 26
@@ -177,77 +189,87 @@
               32:     15(int) Load 24(value) MakePointerVisibleKHR NonPrivatePointerKHR 26
                               AtomicStore 23(atomu) 12 33 32
               41:     40(ptr) ImageTexelPointer 36(imagei) 39 17
-              42:      6(int) AtomicLoad 41 12 30
-                              Store 8(origi) 42
-              48:     47(ptr) ImageTexelPointer 45(imageu) 39 17
-              49:     15(int) AtomicIAdd 48 12 30 46
-                              Store 21(origu) 49
-              51:     47(ptr) ImageTexelPointer 45(imageu) 39 17
-                              AtomicStore 51 12 33 50
-              53:     15(int) AtomicOr 23(atomu) 12 17 52
-                              Store 21(origu) 53
-              54:     15(int) AtomicXor 23(atomu) 12 17 52
+              43:      6(int) AtomicLoad 41 12 30
+                              Store 8(origi) 43
+              49:     48(ptr) ImageTexelPointer 46(imageu) 39 17
+              50:     15(int) AtomicIAdd 49 12 30 47
+                              Store 21(origu) 50
+              52:     48(ptr) ImageTexelPointer 46(imageu) 39 17
+                              AtomicStore 52 12 33 51
+              54:     15(int) AtomicOr 23(atomu) 12 17 53
                               Store 21(origu) 54
-              55:     15(int) Load 24(value) MakePointerVisibleKHR NonPrivatePointerKHR 26
-              56:     15(int) AtomicUMin 23(atomu) 12 17 55
-                              Store 21(origu) 56
-              58:      6(int) AtomicSMax 10(atomi) 12 17 57
-                              Store 8(origi) 58
-              59:      6(int) Load 8(origi)
-              60:      6(int) AtomicExchange 10(atomi) 12 17 59
-                              Store 8(origi) 60
-              62:     15(int) Load 24(value) MakePointerVisibleKHR NonPrivatePointerKHR 26
-              64:     15(int) AtomicCompareExchange 23(atomu) 12 63 63 62 61
-                              Store 21(origu) 64
-              69:     68(ptr) AccessChain 67(bufferu) 38
-              71:     15(int) AtomicIAdd 69 12 18 70
+              55:     15(int) AtomicXor 23(atomu) 12 17 53
+                              Store 21(origu) 55
+              56:     15(int) Load 24(value) MakePointerVisibleKHR NonPrivatePointerKHR 26
+              57:     15(int) AtomicUMin 23(atomu) 12 17 56
+                              Store 21(origu) 57
+              59:      6(int) AtomicSMax 10(atomi) 12 17 58
+                              Store 8(origi) 59
+              60:      6(int) Load 8(origi)
+              61:      6(int) AtomicExchange 10(atomi) 12 17 60
+                              Store 8(origi) 61
+              63:     15(int) Load 24(value) MakePointerVisibleKHR NonPrivatePointerKHR 26
+              65:     15(int) AtomicCompareExchange 23(atomu) 12 64 64 63 62
+                              Store 21(origu) 65
+              70:     69(ptr) AccessChain 68(bufferu) 38
+              72:     15(int) AtomicIAdd 70 12 18 71
                               MemoryBarrier 26 18
-                              ControlBarrier 26 26 63
+                              ControlBarrier 26 26 64
                               ControlBarrier 26 26 17
-              73:     68(ptr) AccessChain 67(bufferu) 38
-              74:     15(int) Load 73 MakePointerVisibleKHR NonPrivatePointerKHR 26
-                              Store 72(y) 74
-              75:     15(int) Load 72(y)
-              76:     68(ptr) AccessChain 67(bufferu) 38
-                              Store 76 75 MakePointerAvailableKHR NonPrivatePointerKHR 26
-              80:     68(ptr) AccessChain 79(bufferi) 38
-              81:     15(int) Load 80 MakePointerVisibleKHR NonPrivatePointerKHR 16
-                              Store 72(y) 81
-              88:     68(ptr) AccessChain 87(bufferj) 38 38 38 12
-              89:     15(int) Load 88 Volatile MakePointerVisibleKHR NonPrivatePointerKHR 16
-                              Store 72(y) 89
-              90:     15(int) Load 72(y)
-              91:     68(ptr) AccessChain 79(bufferi) 38
-                              Store 91 90 MakePointerAvailableKHR NonPrivatePointerKHR 16
-              92:     15(int) Load 72(y)
-              93:     68(ptr) AccessChain 87(bufferj) 38 38 38 12
-                              Store 93 92 Volatile MakePointerAvailableKHR NonPrivatePointerKHR 16
-              95:     94(ptr) AccessChain 87(bufferj) 12 38
-              96:       83(A) Load 95 Volatile MakePointerVisibleKHR NonPrivatePointerKHR 16
-              97:     94(ptr) AccessChain 87(bufferj) 38 38
-                              Store 97 96 Volatile MakePointerAvailableKHR NonPrivatePointerKHR 16
-             102:    101(ptr) AccessChain 100(bufferk) 38
-             103:     15(int) Load 102 NonPrivatePointerKHR 
-             104:     68(ptr) AccessChain 79(bufferi) 38
-                              Store 104 103 MakePointerAvailableKHR NonPrivatePointerKHR 16
-             105:          34 Load 36(imagei)
-             107:  106(ivec4) ImageRead 105 39 MakeTexelVisibleKHR NonPrivateTexelKHR VolatileTexelKHR 16
-             111:     35(ptr) AccessChain 110(imagej) 38
-             112:          34 Load 111
-             113:  106(ivec4) ImageRead 112 39 NonPrivateTexelKHR 
-             114:     35(ptr) AccessChain 110(imagej) 12
-             115:          34 Load 114
-                              ImageWrite 115 39 116 NonPrivateTexelKHR 
-             124:    123(ptr) AccessChain 122(samp) 38
-             125:         119 Load 124
-             130:  129(fvec4) ImageSampleExplicitLod 125 128 Lod NonPrivateTexelKHR 127
-             135:131(int64_t) AtomicUMax 133(atomu64) 12 17 134
-                              Store 133(atomu64) 135 MakePointerAvailableKHR NonPrivatePointerKHR 26
-             140:131(int64_t) Load 133(atomu64) MakePointerVisibleKHR NonPrivatePointerKHR 26
-             141:136(int64_t) Bitcast 140
-             142:136(int64_t) AtomicCompareExchange 138(atomi64) 12 63 63 141 139
-             146:     68(ptr) AccessChain 145(bufferl) 38
-             147:     15(int) Load 146 Volatile MakePointerVisibleKHR NonPrivatePointerKHR 16
-                              Store 72(y) 147
+              74:     69(ptr) AccessChain 68(bufferu) 38
+              75:     15(int) Load 74 MakePointerVisibleKHR NonPrivatePointerKHR 26
+                              Store 73(y) 75
+              76:     15(int) Load 73(y)
+              77:     69(ptr) AccessChain 68(bufferu) 38
+                              Store 77 76 MakePointerAvailableKHR NonPrivatePointerKHR 26
+              81:     69(ptr) AccessChain 80(bufferi) 38
+              82:     15(int) Load 81 MakePointerVisibleKHR NonPrivatePointerKHR 16
+                              Store 73(y) 82
+              89:     69(ptr) AccessChain 88(bufferj) 38 38 38 12
+              90:     15(int) Load 89 Volatile MakePointerVisibleKHR NonPrivatePointerKHR 16
+                              Store 73(y) 90
+              91:     15(int) Load 73(y)
+              92:     69(ptr) AccessChain 80(bufferi) 38
+                              Store 92 91 MakePointerAvailableKHR NonPrivatePointerKHR 16
+              93:     15(int) Load 73(y)
+              94:     69(ptr) AccessChain 88(bufferj) 38 38 38 12
+                              Store 94 93 Volatile MakePointerAvailableKHR NonPrivatePointerKHR 16
+              96:     95(ptr) AccessChain 88(bufferj) 12 38
+              97:       84(A) Load 96 Volatile MakePointerVisibleKHR NonPrivatePointerKHR 16
+              98:     95(ptr) AccessChain 88(bufferj) 38 38
+                              Store 98 97 Volatile MakePointerAvailableKHR NonPrivatePointerKHR 16
+             103:    102(ptr) AccessChain 101(bufferk) 38
+             104:     15(int) Load 103 NonPrivatePointerKHR 
+             105:     69(ptr) AccessChain 80(bufferi) 38
+                              Store 105 104 MakePointerAvailableKHR NonPrivatePointerKHR 16
+             106:          34 Load 36(imagei)
+             108:  107(ivec4) ImageRead 106 39 MakeTexelVisibleKHR NonPrivateTexelKHR VolatileTexelKHR 16
+             112:     35(ptr) AccessChain 111(imagej) 38
+             113:          34 Load 112
+             114:  107(ivec4) ImageRead 113 39 NonPrivateTexelKHR 
+             115:     35(ptr) AccessChain 111(imagej) 12
+             116:          34 Load 115
+                              ImageWrite 116 39 117 NonPrivateTexelKHR 
+             125:    124(ptr) AccessChain 123(samp) 38
+             126:         120 Load 125
+             131:  130(fvec4) ImageSampleExplicitLod 126 129 Lod NonPrivateTexelKHR 128
+             136:132(int64_t) AtomicUMax 134(atomu64) 12 17 135
+                              Store 134(atomu64) 136 MakePointerAvailableKHR NonPrivatePointerKHR 26
+             141:132(int64_t) Load 134(atomu64) MakePointerVisibleKHR NonPrivatePointerKHR 26
+             142:137(int64_t) Bitcast 141
+             143:137(int64_t) AtomicCompareExchange 139(atomi64) 12 64 64 142 140
+             147:     69(ptr) AccessChain 146(bufferl) 38
+             148:     15(int) Load 147 Volatile MakePointerVisibleKHR NonPrivatePointerKHR 16
+                              Store 73(y) 148
+             149:     69(ptr) AccessChain 146(bufferl) 38
+             150:     15(int) AtomicIAdd 149 16 42 71
+             154:     69(ptr) AccessChain 153(bufferm) 38
+             155:     15(int) AtomicOr 154 16 42 26
+             156:     40(ptr) ImageTexelPointer 36(imagei) 39 17
+             157:      6(int) AtomicIAdd 156 16 42 11
+             158:     69(ptr) AccessChain 68(bufferu) 38
+             159:     15(int) AtomicIAdd 158 12 17 51
+             160:     69(ptr) AccessChain 68(bufferu) 38
+             162:     15(int) AtomicIAdd 160 12 42 16
                               Return
                               FunctionEnd
diff --git a/Test/baseResults/spv.memoryScopeSemantics_Error.comp.out b/Test/baseResults/spv.memoryScopeSemantics_Error.comp.out
index c4149d8..6de93fd 100644
--- a/Test/baseResults/spv.memoryScopeSemantics_Error.comp.out
+++ b/Test/baseResults/spv.memoryScopeSemantics_Error.comp.out
@@ -11,7 +11,9 @@
 ERROR: 0:24: 'atomicCompSwap' : semUnequal must not be gl_SemanticsRelease or gl_SemanticsAcquireRelease 
 ERROR: 0:25: 'memoryBarrier' : gl_SemanticsMakeVisible requires gl_SemanticsAcquire or gl_SemanticsAcquireRelease 
 ERROR: 0:26: 'memoryBarrier' : gl_SemanticsMakeAvailable requires gl_SemanticsRelease or gl_SemanticsAcquireRelease 
-ERROR: 12 compilation errors.  No code generated.
+ERROR: 0:27: 'memoryBarrier' : gl_SemanticsVolatile must not be used with memoryBarrier or controlBarrier 
+ERROR: 0:28: 'atomicCompSwap' : semEqual and semUnequal must either both include gl_SemanticsVolatile or neither 
+ERROR: 14 compilation errors.  No code generated.
 
 
 SPIR-V is not generated for failed compile or link
diff --git a/Test/baseResults/spv.shaderBallot.comp.out b/Test/baseResults/spv.shaderBallot.comp.out
index 2f0e5a0..d25eec7 100644
--- a/Test/baseResults/spv.shaderBallot.comp.out
+++ b/Test/baseResults/spv.shaderBallot.comp.out
@@ -1,4 +1,5 @@
 spv.shaderBallot.comp
+Validation failed
 // Module Version 10000
 // Generated by (magic number): 80007
 // Id's are bound by 298
diff --git a/Test/baseResults/spv.smBuiltins.frag.out b/Test/baseResults/spv.smBuiltins.frag.out
new file mode 100644
index 0000000..fda06eb
--- /dev/null
+++ b/Test/baseResults/spv.smBuiltins.frag.out
@@ -0,0 +1,50 @@
+spv.smBuiltins.frag
+// Module Version 10000
+// Generated by (magic number): 80007
+// Id's are bound by 20
+
+                              Capability Shader
+                              Capability ShaderSMBuiltinsNV
+                              Extension  "SPV_NV_shader_sm_builtins"
+               1:             ExtInstImport  "GLSL.std.450"
+                              MemoryModel Logical GLSL450
+                              EntryPoint Fragment 4  "main" 9 11 13 15 17
+                              ExecutionMode 4 OriginUpperLeft
+                              Source GLSL 450
+                              SourceExtension  "GL_NV_shader_sm_builtins"
+                              Name 4  "main"
+                              Name 9  "data"
+                              Name 11  "gl_WarpsPerSMNV"
+                              Name 13  "gl_SMCountNV"
+                              Name 15  "gl_WarpIDNV"
+                              Name 17  "gl_SMIDNV"
+                              Decorate 9(data) Location 0
+                              Decorate 11(gl_WarpsPerSMNV) Flat
+                              Decorate 11(gl_WarpsPerSMNV) BuiltIn WarpsPerSMNV
+                              Decorate 13(gl_SMCountNV) Flat
+                              Decorate 13(gl_SMCountNV) BuiltIn SMCountNV
+                              Decorate 15(gl_WarpIDNV) Flat
+                              Decorate 15(gl_WarpIDNV) BuiltIn WarpIDNV
+                              Decorate 17(gl_SMIDNV) Flat
+                              Decorate 17(gl_SMIDNV) BuiltIn SMIDNV
+               2:             TypeVoid
+               3:             TypeFunction 2
+               6:             TypeInt 32 0
+               7:             TypeVector 6(int) 4
+               8:             TypePointer Output 7(ivec4)
+         9(data):      8(ptr) Variable Output
+              10:             TypePointer Input 6(int)
+11(gl_WarpsPerSMNV):     10(ptr) Variable Input
+13(gl_SMCountNV):     10(ptr) Variable Input
+ 15(gl_WarpIDNV):     10(ptr) Variable Input
+   17(gl_SMIDNV):     10(ptr) Variable Input
+         4(main):           2 Function None 3
+               5:             Label
+              12:      6(int) Load 11(gl_WarpsPerSMNV)
+              14:      6(int) Load 13(gl_SMCountNV)
+              16:      6(int) Load 15(gl_WarpIDNV)
+              18:      6(int) Load 17(gl_SMIDNV)
+              19:    7(ivec4) CompositeConstruct 12 14 16 18
+                              Store 9(data) 19
+                              Return
+                              FunctionEnd
diff --git a/Test/baseResults/spv.smBuiltins.vert.out b/Test/baseResults/spv.smBuiltins.vert.out
new file mode 100644
index 0000000..8423e5b
--- /dev/null
+++ b/Test/baseResults/spv.smBuiltins.vert.out
@@ -0,0 +1,62 @@
+spv.smBuiltins.vert
+// Module Version 10000
+// Generated by (magic number): 80007
+// Id's are bound by 29
+
+                              Capability Shader
+                              Capability ShaderSMBuiltinsNV
+                              Extension  "SPV_NV_shader_sm_builtins"
+               1:             ExtInstImport  "GLSL.std.450"
+                              MemoryModel Logical GLSL450
+                              EntryPoint Vertex 4  "main" 15 18 20 22 24
+                              Source GLSL 450
+                              SourceExtension  "GL_NV_shader_sm_builtins"
+                              Name 4  "main"
+                              Name 9  "Output"
+                              MemberName 9(Output) 0  "result"
+                              Name 11  ""
+                              Name 15  "gl_VertexIndex"
+                              Name 18  "gl_WarpsPerSMNV"
+                              Name 20  "gl_SMCountNV"
+                              Name 22  "gl_WarpIDNV"
+                              Name 24  "gl_SMIDNV"
+                              Decorate 8 ArrayStride 16
+                              MemberDecorate 9(Output) 0 Offset 0
+                              Decorate 9(Output) BufferBlock
+                              Decorate 11 DescriptorSet 0
+                              Decorate 11 Binding 0
+                              Decorate 15(gl_VertexIndex) BuiltIn VertexIndex
+                              Decorate 18(gl_WarpsPerSMNV) BuiltIn WarpsPerSMNV
+                              Decorate 20(gl_SMCountNV) BuiltIn SMCountNV
+                              Decorate 22(gl_WarpIDNV) BuiltIn WarpIDNV
+                              Decorate 24(gl_SMIDNV) BuiltIn SMIDNV
+               2:             TypeVoid
+               3:             TypeFunction 2
+               6:             TypeInt 32 0
+               7:             TypeVector 6(int) 4
+               8:             TypeRuntimeArray 7(ivec4)
+       9(Output):             TypeStruct 8
+              10:             TypePointer Uniform 9(Output)
+              11:     10(ptr) Variable Uniform
+              12:             TypeInt 32 1
+              13:     12(int) Constant 0
+              14:             TypePointer Input 12(int)
+15(gl_VertexIndex):     14(ptr) Variable Input
+              17:             TypePointer Input 6(int)
+18(gl_WarpsPerSMNV):     17(ptr) Variable Input
+20(gl_SMCountNV):     17(ptr) Variable Input
+ 22(gl_WarpIDNV):     17(ptr) Variable Input
+   24(gl_SMIDNV):     17(ptr) Variable Input
+              27:             TypePointer Uniform 7(ivec4)
+         4(main):           2 Function None 3
+               5:             Label
+              16:     12(int) Load 15(gl_VertexIndex)
+              19:      6(int) Load 18(gl_WarpsPerSMNV)
+              21:      6(int) Load 20(gl_SMCountNV)
+              23:      6(int) Load 22(gl_WarpIDNV)
+              25:      6(int) Load 24(gl_SMIDNV)
+              26:    7(ivec4) CompositeConstruct 19 21 23 25
+              28:     27(ptr) AccessChain 11 13 16
+                              Store 28 26
+                              Return
+                              FunctionEnd
diff --git a/Test/baseResults/spv.specConstant.vert.out b/Test/baseResults/spv.specConstant.vert.out
index 0d47dce..931ba8d 100644
--- a/Test/baseResults/spv.specConstant.vert.out
+++ b/Test/baseResults/spv.specConstant.vert.out
@@ -11,7 +11,7 @@
                               Source GLSL 400
                               Name 4  "main"
                               Name 9  "arraySize"
-                              Name 14  "foo(vf4[s2765];"
+                              Name 14  "foo(vf4[s2769];"
                               Name 13  "p"
                               Name 17  "builtin_spec_constant("
                               Name 20  "color"
@@ -102,10 +102,10 @@
                               Store 20(color) 46
               48:          10 Load 22(ucol)
                               Store 47(param) 48
-              49:           2 FunctionCall 14(foo(vf4[s2765];) 47(param)
+              49:           2 FunctionCall 14(foo(vf4[s2769];) 47(param)
                               Return
                               FunctionEnd
-14(foo(vf4[s2765];):           2 Function None 12
+14(foo(vf4[s2769];):           2 Function None 12
            13(p):     11(ptr) FunctionParameter
               15:             Label
               54:     24(ptr) AccessChain 53(dupUcol) 23
diff --git a/Test/glsl.450.subgroup.frag b/Test/glsl.450.subgroup.frag
index 26011ed..61cfc8f 100644
--- a/Test/glsl.450.subgroup.frag
+++ b/Test/glsl.450.subgroup.frag
@@ -226,3 +226,23 @@
   subgroupPartitionedExclusiveXorNV(ballot, parti);

 }

 

+// tests for NV_shader_sm_builtins

+void sm_builtins_err()

+{

+    gl_WarpsPerSMNV;    // ERROR, no extension

+    gl_SMCountNV;       // ERROR, no extension

+    gl_WarpIDNV;        // ERROR, no extension

+    gl_SMIDNV;          // ERROR, no extension

+}

+

+#ifdef GL_NV_shader_sm_builtins

+#extension GL_NV_shader_sm_builtins : enable

+#endif

+

+void sm_builtins()

+{

+    gl_WarpsPerSMNV;

+    gl_SMCountNV;

+    gl_WarpIDNV;

+    gl_SMIDNV;

+}

diff --git a/Test/glsl.450.subgroup.geom b/Test/glsl.450.subgroup.geom
index affe045..d5d2f25 100644
--- a/Test/glsl.450.subgroup.geom
+++ b/Test/glsl.450.subgroup.geom
@@ -232,3 +232,23 @@
   subgroupPartitionedExclusiveXorNV(ballot, parti);

 }

 

+// tests for NV_shader_sm_builtins

+void sm_builtins_err()

+{

+    gl_WarpsPerSMNV;    // ERROR, no extension

+    gl_SMCountNV;       // ERROR, no extension

+    gl_WarpIDNV;        // ERROR, no extension

+    gl_SMIDNV;          // ERROR, no extension

+}

+

+#ifdef GL_NV_shader_sm_builtins

+#extension GL_NV_shader_sm_builtins : enable

+#endif

+

+void sm_builtins()

+{

+    gl_WarpsPerSMNV;

+    gl_SMCountNV;

+    gl_WarpIDNV;

+    gl_SMIDNV;

+}

diff --git a/Test/glsl.450.subgroup.tesc b/Test/glsl.450.subgroup.tesc
index a67af25..92cb1ae 100644
--- a/Test/glsl.450.subgroup.tesc
+++ b/Test/glsl.450.subgroup.tesc
@@ -231,3 +231,23 @@
   subgroupPartitionedExclusiveXorNV(ballot, parti);

 }

 

+// tests for NV_shader_sm_builtins

+void sm_builtins_err()

+{

+    gl_WarpsPerSMNV;    // ERROR, no extension

+    gl_SMCountNV;       // ERROR, no extension

+    gl_WarpIDNV;        // ERROR, no extension

+    gl_SMIDNV;          // ERROR, no extension

+}

+

+#ifdef GL_NV_shader_sm_builtins

+#extension GL_NV_shader_sm_builtins : enable

+#endif

+

+void sm_builtins()

+{

+    gl_WarpsPerSMNV;

+    gl_SMCountNV;

+    gl_WarpIDNV;

+    gl_SMIDNV;

+}

diff --git a/Test/glsl.450.subgroup.tese b/Test/glsl.450.subgroup.tese
index ebfd123..bfb2b72 100644
--- a/Test/glsl.450.subgroup.tese
+++ b/Test/glsl.450.subgroup.tese
@@ -230,3 +230,24 @@
   subgroupPartitionedExclusiveOrNV(ballot, parti);

   subgroupPartitionedExclusiveXorNV(ballot, parti);

 }

+

+// tests for NV_shader_sm_builtins

+void sm_builtins_err()

+{

+    gl_WarpsPerSMNV;    // ERROR, no extension

+    gl_SMCountNV;       // ERROR, no extension

+    gl_WarpIDNV;        // ERROR, no extension

+    gl_SMIDNV;          // ERROR, no extension

+}

+

+#ifdef GL_NV_shader_sm_builtins

+#extension GL_NV_shader_sm_builtins : enable

+#endif

+

+void sm_builtins()

+{

+    gl_WarpsPerSMNV;

+    gl_SMCountNV;

+    gl_WarpIDNV;

+    gl_SMIDNV;

+}

diff --git a/Test/glsl.450.subgroup.vert b/Test/glsl.450.subgroup.vert
index 0be08b5..110b1d0 100644
--- a/Test/glsl.450.subgroup.vert
+++ b/Test/glsl.450.subgroup.vert
@@ -230,3 +230,24 @@
   subgroupPartitionedExclusiveXorNV(ballot, parti);

 }

 

+// tests for NV_shader_sm_builtins

+void sm_builtins_err()

+{

+    gl_WarpsPerSMNV;    // ERROR, no extension

+    gl_SMCountNV;       // ERROR, no extension

+    gl_WarpIDNV;        // ERROR, no extension

+    gl_SMIDNV;          // ERROR, no extension

+}

+

+#ifdef GL_NV_shader_sm_builtins

+#extension GL_NV_shader_sm_builtins : enable

+#endif

+

+void sm_builtins()

+{

+    gl_WarpsPerSMNV;

+    gl_SMCountNV;

+    gl_WarpIDNV;

+    gl_SMIDNV;

+}

+

diff --git a/Test/glsl.450.subgroupBasic.comp b/Test/glsl.450.subgroupBasic.comp
index 1bcd486..7b42878 100644
--- a/Test/glsl.450.subgroupBasic.comp
+++ b/Test/glsl.450.subgroupBasic.comp
@@ -236,3 +236,23 @@
   subgroupPartitionedExclusiveXorNV(ballot, parti);

 }

 

+// tests for NV_shader_sm_builtins

+void sm_builtins_err()

+{

+    gl_WarpsPerSMNV;    // ERROR, no extension

+    gl_SMCountNV;       // ERROR, no extension

+    gl_WarpIDNV;        // ERROR, no extension

+    gl_SMIDNV;          // ERROR, no extension

+}

+

+#ifdef GL_NV_shader_sm_builtins

+#extension GL_NV_shader_sm_builtins : enable

+#endif

+

+void sm_builtins()

+{

+    gl_WarpsPerSMNV;

+    gl_SMCountNV;

+    gl_WarpIDNV;

+    gl_SMIDNV;

+}

diff --git a/Test/glsl.460.subgroup.mesh b/Test/glsl.460.subgroup.mesh
index 19a4757..1071cac 100644
--- a/Test/glsl.460.subgroup.mesh
+++ b/Test/glsl.460.subgroup.mesh
@@ -291,3 +291,24 @@
   subgroupPartitionedExclusiveOrNV(ballot, parti);
   subgroupPartitionedExclusiveXorNV(ballot, parti);
 }
+
+// tests for NV_shader_sm_builtins
+void sm_builtins_err()
+{
+    gl_WarpsPerSMNV;    // ERROR, no extension
+    gl_SMCountNV;       // ERROR, no extension
+    gl_WarpIDNV;        // ERROR, no extension
+    gl_SMIDNV;          // ERROR, no extension
+}
+
+#ifdef GL_NV_shader_sm_builtins
+#extension GL_NV_shader_sm_builtins : enable
+#endif
+
+void sm_builtins()
+{
+    gl_WarpsPerSMNV;
+    gl_SMCountNV;
+    gl_WarpIDNV;
+    gl_SMIDNV;
+}
diff --git a/Test/glsl.460.subgroup.rahit b/Test/glsl.460.subgroup.rahit
index 3ee7378..a1bce28 100644
--- a/Test/glsl.460.subgroup.rahit
+++ b/Test/glsl.460.subgroup.rahit
@@ -253,3 +253,23 @@
   subgroupPartitionedExclusiveXorNV(ballot, parti);
 }
 
+// tests for NV_shader_sm_builtins
+void sm_builtins_err()
+{
+    gl_WarpsPerSMNV;    // ERROR, no extension
+    gl_SMCountNV;       // ERROR, no extension
+    gl_WarpIDNV;        // ERROR, no extension
+    gl_SMIDNV;          // ERROR, no extension
+}
+
+#ifdef GL_NV_shader_sm_builtins
+#extension GL_NV_shader_sm_builtins : enable
+#endif
+
+void sm_builtins()
+{
+    gl_WarpsPerSMNV;
+    gl_SMCountNV;
+    gl_WarpIDNV;
+    gl_SMIDNV;
+}
diff --git a/Test/glsl.460.subgroup.rcall b/Test/glsl.460.subgroup.rcall
index dc7ad2e..9c2ede8 100644
--- a/Test/glsl.460.subgroup.rcall
+++ b/Test/glsl.460.subgroup.rcall
@@ -241,3 +241,23 @@
   subgroupPartitionedExclusiveXorNV(ballot, parti);
 }
 
+// tests for NV_shader_sm_builtins
+void sm_builtins_err()
+{
+    gl_WarpsPerSMNV;    // ERROR, no extension
+    gl_SMCountNV;       // ERROR, no extension
+    gl_WarpIDNV;        // ERROR, no extension
+    gl_SMIDNV;          // ERROR, no extension
+}
+
+#ifdef GL_NV_shader_sm_builtins
+#extension GL_NV_shader_sm_builtins : enable
+#endif
+
+void sm_builtins()
+{
+    gl_WarpsPerSMNV;
+    gl_SMCountNV;
+    gl_WarpIDNV;
+    gl_SMIDNV;
+}
diff --git a/Test/glsl.460.subgroup.rchit b/Test/glsl.460.subgroup.rchit
index cbe3517..aae5b54 100644
--- a/Test/glsl.460.subgroup.rchit
+++ b/Test/glsl.460.subgroup.rchit
@@ -251,3 +251,23 @@
   subgroupPartitionedExclusiveXorNV(ballot, parti);
 }
 
+// tests for NV_shader_sm_builtins
+void sm_builtins_err()
+{
+    gl_WarpsPerSMNV;    // ERROR, no extension
+    gl_SMCountNV;       // ERROR, no extension
+    gl_WarpIDNV;        // ERROR, no extension
+    gl_SMIDNV;          // ERROR, no extension
+}
+
+#ifdef GL_NV_shader_sm_builtins
+#extension GL_NV_shader_sm_builtins : enable
+#endif
+
+void sm_builtins()
+{
+    gl_WarpsPerSMNV;
+    gl_SMCountNV;
+    gl_WarpIDNV;
+    gl_SMIDNV;
+}
diff --git a/Test/glsl.460.subgroup.rgen b/Test/glsl.460.subgroup.rgen
index 9184e15..a3c78c9 100644
--- a/Test/glsl.460.subgroup.rgen
+++ b/Test/glsl.460.subgroup.rgen
@@ -245,3 +245,23 @@
   subgroupPartitionedExclusiveXorNV(ballot, parti);
 }
 
+// tests for NV_shader_sm_builtins
+void sm_builtins_err()
+{
+    gl_WarpsPerSMNV;    // ERROR, no extension
+    gl_SMCountNV;       // ERROR, no extension
+    gl_WarpIDNV;        // ERROR, no extension
+    gl_SMIDNV;          // ERROR, no extension
+}
+
+#ifdef GL_NV_shader_sm_builtins
+#extension GL_NV_shader_sm_builtins : enable
+#endif
+
+void sm_builtins()
+{
+    gl_WarpsPerSMNV;
+    gl_SMCountNV;
+    gl_WarpIDNV;
+    gl_SMIDNV;
+}
diff --git a/Test/glsl.460.subgroup.rint b/Test/glsl.460.subgroup.rint
index 7a58804..1909c5a 100644
--- a/Test/glsl.460.subgroup.rint
+++ b/Test/glsl.460.subgroup.rint
@@ -251,3 +251,23 @@
   subgroupPartitionedExclusiveXorNV(ballot, parti);
 }
 
+// tests for NV_shader_sm_builtins
+void sm_builtins_err()
+{
+    gl_WarpsPerSMNV;    // ERROR, no extension
+    gl_SMCountNV;       // ERROR, no extension
+    gl_WarpIDNV;        // ERROR, no extension
+    gl_SMIDNV;          // ERROR, no extension
+}
+
+#ifdef GL_NV_shader_sm_builtins
+#extension GL_NV_shader_sm_builtins : enable
+#endif
+
+void sm_builtins()
+{
+    gl_WarpsPerSMNV;
+    gl_SMCountNV;
+    gl_WarpIDNV;
+    gl_SMIDNV;
+}
diff --git a/Test/glsl.460.subgroup.rmiss b/Test/glsl.460.subgroup.rmiss
index 4d629d6..96c4411 100644
--- a/Test/glsl.460.subgroup.rmiss
+++ b/Test/glsl.460.subgroup.rmiss
@@ -245,3 +245,23 @@
   subgroupPartitionedExclusiveXorNV(ballot, parti);
 }
 
+// tests for NV_shader_sm_builtins
+void sm_builtins_err()
+{
+    gl_WarpsPerSMNV;    // ERROR, no extension
+    gl_SMCountNV;       // ERROR, no extension
+    gl_WarpIDNV;        // ERROR, no extension
+    gl_SMIDNV;          // ERROR, no extension
+}
+
+#ifdef GL_NV_shader_sm_builtins
+#extension GL_NV_shader_sm_builtins : enable
+#endif
+
+void sm_builtins()
+{
+    gl_WarpsPerSMNV;
+    gl_SMCountNV;
+    gl_WarpIDNV;
+    gl_SMIDNV;
+}
diff --git a/Test/glsl.460.subgroup.task b/Test/glsl.460.subgroup.task
index 84d3140..9b147f8 100644
--- a/Test/glsl.460.subgroup.task
+++ b/Test/glsl.460.subgroup.task
@@ -282,3 +282,23 @@
   subgroupPartitionedExclusiveXorNV(ballot, parti);
 }
 
+// tests for NV_shader_sm_builtins
+void sm_builtins_err()
+{
+    gl_WarpsPerSMNV;    // ERROR, no extension
+    gl_SMCountNV;       // ERROR, no extension
+    gl_WarpIDNV;        // ERROR, no extension
+    gl_SMIDNV;          // ERROR, no extension
+}
+
+#ifdef GL_NV_shader_sm_builtins
+#extension GL_NV_shader_sm_builtins : enable
+#endif
+
+void sm_builtins()
+{
+    gl_WarpsPerSMNV;
+    gl_SMCountNV;
+    gl_WarpIDNV;
+    gl_SMIDNV;
+}
diff --git a/Test/spv.fsi.frag b/Test/spv.fsi.frag
new file mode 100644
index 0000000..5e6fb5f
--- /dev/null
+++ b/Test/spv.fsi.frag
@@ -0,0 +1,20 @@
+#version 450

+#extension GL_ARB_fragment_shader_interlock : enable

+

+layout(set = 0, binding = 0) coherent buffer B1 {

+    layout(offset = 0)  int x;

+} b1;

+

+layout(set = 0, binding = 1, rgba32f) coherent uniform image2D im;

+

+layout(sample_interlock_ordered) in;

+

+void main() {

+

+    beginInvocationInterlockARB();

+

+    b1.x = 1;

+    imageStore(im, ivec2(0,0), vec4(0));

+

+    endInvocationInterlockARB();

+}

diff --git a/Test/spv.fsi_Error.frag b/Test/spv.fsi_Error.frag
new file mode 100644
index 0000000..adddf3e
--- /dev/null
+++ b/Test/spv.fsi_Error.frag
@@ -0,0 +1,23 @@
+#version 450

+#extension GL_ARB_fragment_shader_interlock : enable

+

+layout(pixel_interlock_ordered) out;

+

+layout(pixel_interlock_ordered) in;

+layout(pixel_interlock_unordered) in;

+

+void foo()

+{

+    beginInvocationInterlockARB();

+    endInvocationInterlockARB();

+}

+

+void main() {

+

+    endInvocationInterlockARB();

+    beginInvocationInterlockARB();

+

+    return;

+

+    endInvocationInterlockARB();

+}

diff --git a/Test/spv.memoryScopeSemantics.comp b/Test/spv.memoryScopeSemantics.comp
index 88f5481..037e6d7 100644
--- a/Test/spv.memoryScopeSemantics.comp
+++ b/Test/spv.memoryScopeSemantics.comp
@@ -19,6 +19,7 @@
 shared uint64_t atomu64;

 shared int64_t atomi64;

 layout (binding = 8) volatile buffer BufferL { uint x; } bufferl;

+layout (binding = 9) buffer BufferM { volatile uint x; } bufferm;

 

 

 void main()

@@ -60,5 +61,10 @@
     atomicCompSwap(atomi64, int64_t(10), int64_t(atomu64), gl_ScopeDevice, gl_StorageSemanticsBuffer | gl_StorageSemanticsShared, gl_SemanticsAcquire, gl_StorageSemanticsBuffer | gl_StorageSemanticsShared, gl_SemanticsAcquire);

 

     y = bufferl.x;

+    atomicAdd(bufferl.x, 1);

+    atomicOr(bufferm.x, 2);

+    imageAtomicAdd(imagei, ivec2(0,0), 3);

+    atomicAdd(bufferu.x, 4u, gl_ScopeDevice, 0, 0);

+    atomicAdd(bufferu.x, 5u, gl_ScopeDevice, 0, gl_SemanticsVolatile);

 }

 

diff --git a/Test/spv.memoryScopeSemantics_Error.comp b/Test/spv.memoryScopeSemantics_Error.comp
index 4e18b2e..1b85671 100644
--- a/Test/spv.memoryScopeSemantics_Error.comp
+++ b/Test/spv.memoryScopeSemantics_Error.comp
@@ -24,5 +24,7 @@
     uint origu = atomicCompSwap(atomu, 10u, value, gl_ScopeDevice, gl_StorageSemanticsBuffer | gl_StorageSemanticsShared, gl_SemanticsAcquire, gl_StorageSemanticsBuffer | gl_StorageSemanticsShared, gl_SemanticsAcquireRelease);

     memoryBarrier(gl_ScopeWorkgroup, gl_StorageSemanticsBuffer, gl_SemanticsRelease | gl_SemanticsMakeVisible);

     memoryBarrier(gl_ScopeWorkgroup, gl_StorageSemanticsBuffer, gl_SemanticsAcquire | gl_SemanticsMakeAvailable);

+    memoryBarrier(gl_ScopeWorkgroup, gl_StorageSemanticsBuffer, gl_SemanticsRelease | gl_SemanticsVolatile);

+    atomicCompSwap(bufferi.x, 10u, 10u, gl_ScopeDevice, gl_StorageSemanticsBuffer, gl_SemanticsAcquire | gl_SemanticsVolatile, gl_StorageSemanticsBuffer, gl_SemanticsAcquire);

 }

 

diff --git a/Test/spv.smBuiltins.frag b/Test/spv.smBuiltins.frag
new file mode 100644
index 0000000..b676e60
--- /dev/null
+++ b/Test/spv.smBuiltins.frag
@@ -0,0 +1,7 @@
+#version 450
+#extension GL_NV_shader_sm_builtins: enable
+layout(location = 0) out uvec4 data;
+void main (void)
+{
+  data = uvec4(gl_WarpsPerSMNV, gl_SMCountNV, gl_WarpIDNV, gl_SMIDNV);
+}
diff --git a/Test/spv.smBuiltins.vert b/Test/spv.smBuiltins.vert
new file mode 100644
index 0000000..0b3db02
--- /dev/null
+++ b/Test/spv.smBuiltins.vert
@@ -0,0 +1,11 @@
+#version 450
+#extension GL_NV_shader_sm_builtins: enable
+layout(set = 0, binding = 0, std430) buffer Output
+{
+  uvec4 result[];
+};
+
+void main (void)
+{
+  result[gl_VertexIndex] = uvec4(gl_WarpsPerSMNV, gl_SMCountNV, gl_WarpIDNV, gl_SMIDNV);
+}
diff --git a/glslang/Include/BaseTypes.h b/glslang/Include/BaseTypes.h
index e4a4572..1a99e1b 100644
--- a/glslang/Include/BaseTypes.h
+++ b/glslang/Include/BaseTypes.h
@@ -275,6 +275,12 @@
     EbvMeshViewIndicesNV,
 #endif
 
+    // sm builtins
+    EbvWarpsPerSM,
+    EbvSMCount,
+    EbvWarpID,
+    EbvSMID,
+
     // HLSL built-ins that live only temporarily, until they get remapped
     // to one of the above.
     EbvFragDepthGreater,
@@ -460,6 +466,11 @@
     case EbvMeshViewIndicesNV:          return "MeshViewIndicesNV";
 #endif
 
+    case EbvWarpsPerSM:                 return "WarpsPerSMNV";
+    case EbvSMCount:                    return "SMCountNV";
+    case EbvWarpID:                     return "WarpIDNV";
+    case EbvSMID:                       return "SMIDNV";
+
     default:                      return "unknown built-in variable";
     }
 }
diff --git a/glslang/Include/Types.h b/glslang/Include/Types.h
index 90341dc..989c34a 100644
--- a/glslang/Include/Types.h
+++ b/glslang/Include/Types.h
@@ -422,6 +422,18 @@
     EBlendCount
 };
 
+enum TInterlockOrdering {
+    EioNone,
+    EioPixelInterlockOrdered,
+    EioPixelInterlockUnordered,
+    EioSampleInterlockOrdered,
+    EioSampleInterlockUnordered,
+    EioShadingRateInterlockOrdered,
+    EioShadingRateInterlockUnordered,
+
+    EioCount,
+};
+
 class TQualifier {
 public:
     static const int layoutNotSet = -1;
@@ -502,8 +514,9 @@
 
     const char*         semanticName;
     TStorageQualifier   storage   : 6;
-    TBuiltInVariable    builtIn   : 8;
-    TBuiltInVariable    declaredBuiltIn : 8;
+    TBuiltInVariable    builtIn   : 9;
+    TBuiltInVariable    declaredBuiltIn : 9;
+    static_assert(EbvLast < 256, "need to increase size of TBuiltInVariable bitfields!");
     TPrecisionQualifier precision : 3;
     bool invariant    : 1; // require canonical treatment for cross-shader invariance
     bool noContraction: 1; // prevent contraction and reassociation, e.g., for 'precise' keyword, and expressions it affects
@@ -1110,6 +1123,18 @@
         default:                    return 0;
         }
     }
+    static const char* getInterlockOrderingString(TInterlockOrdering order)
+    {
+        switch (order) {
+        case EioPixelInterlockOrdered:          return "pixel_interlock_ordered";
+        case EioPixelInterlockUnordered:        return "pixel_interlock_unordered";
+        case EioSampleInterlockOrdered:         return "sample_interlock_ordered";
+        case EioSampleInterlockUnordered:       return "sample_interlock_unordered";
+        case EioShadingRateInterlockOrdered:    return "shading_rate_interlock_ordered";
+        case EioShadingRateInterlockUnordered:  return "shading_rate_interlock_unordered";
+        default:                                return "none";
+        }
+    }
 };
 
 // Qualifiers that don't need to be keep per object.  They have shader scope, not object scope.
@@ -1130,6 +1155,7 @@
     TLayoutDepth layoutDepth;
     bool blendEquation;       // true if any blend equation was specified
     int numViews;             // multiview extenstions
+    TInterlockOrdering interlockOrdering;
 
 #ifdef NV_EXTENSIONS
     bool layoutOverrideCoverage;        // true if layout override_coverage set
@@ -1165,6 +1191,7 @@
         layoutDerivativeGroupLinear = false;
         primitives                  = TQualifier::layoutNotSet;
 #endif
+        interlockOrdering = EioNone;
     }
 
     // Merge in characteristics from the 'src' qualifier.  They can override when
@@ -1215,6 +1242,9 @@
         if (src.primitives != TQualifier::layoutNotSet)
             primitives = src.primitives;
 #endif
+
+        if (src.interlockOrdering != EioNone)
+            interlockOrdering = src.interlockOrdering;
     }
 };
 
diff --git a/glslang/Include/intermediate.h b/glslang/Include/intermediate.h
index 89d1954..f7424e8 100644
--- a/glslang/Include/intermediate.h
+++ b/glslang/Include/intermediate.h
@@ -621,6 +621,9 @@
     EOpCooperativeMatrixStore,
     EOpCooperativeMatrixMulAdd,
 
+    EOpBeginInvocationInterlock, // Fragment only
+    EOpEndInvocationInterlock, // Fragment only
+
     //
     // Branch
     //
diff --git a/glslang/MachineIndependent/Initialize.cpp b/glslang/MachineIndependent/Initialize.cpp
index 4231dc6..ba79e18 100644
--- a/glslang/MachineIndependent/Initialize.cpp
+++ b/glslang/MachineIndependent/Initialize.cpp
@@ -5030,6 +5030,10 @@
             "\n");
     }
 
+    stageBuiltins[EShLangFragment].append(
+        "void beginInvocationInterlockARB(void);"
+        "void endInvocationInterlockARB(void);");
+
 #ifdef AMD_EXTENSIONS
     // GL_AMD_shader_explicit_vertex_parameter
     if (profile != EEsProfile && version >= 450) {
@@ -6137,6 +6141,11 @@
             "in highp   uvec4 gl_SubgroupGtMask;"
             "in highp   uvec4 gl_SubgroupLeMask;"
             "in highp   uvec4 gl_SubgroupLtMask;"
+            // GL_NV_shader_sm_builtins
+            "in highp   uint  gl_WarpsPerSMNV;"
+            "in highp   uint  gl_SMCountNV;"
+            "in highp   uint  gl_WarpIDNV;"
+            "in highp   uint  gl_SMIDNV;"
             "\n";
         const char* fragmentSubgroupDecls =
             "flat in mediump uint  gl_SubgroupSize;"
@@ -6146,6 +6155,11 @@
             "flat in highp   uvec4 gl_SubgroupGtMask;"
             "flat in highp   uvec4 gl_SubgroupLeMask;"
             "flat in highp   uvec4 gl_SubgroupLtMask;"
+            // GL_NV_shader_sm_builtins
+            "flat in highp   uint  gl_WarpsPerSMNV;"
+            "flat in highp   uint  gl_SMCountNV;"
+            "flat in highp   uint  gl_WarpIDNV;"
+            "flat in highp   uint  gl_SMIDNV;"
             "\n";
         const char* computeSubgroupDecls =
             "in highp   uint  gl_NumSubgroups;"
@@ -6295,6 +6309,7 @@
         commonBuiltins.append("const int gl_SemanticsAcquireRelease  = 0x8;\n");
         commonBuiltins.append("const int gl_SemanticsMakeAvailable   = 0x2000;\n");
         commonBuiltins.append("const int gl_SemanticsMakeVisible     = 0x4000;\n");
+        commonBuiltins.append("const int gl_SemanticsVolatile        = 0x8000;\n");
 
         commonBuiltins.append("const int gl_StorageSemanticsNone     = 0x0;\n");
         commonBuiltins.append("const int gl_StorageSemanticsBuffer   = 0x40;\n");
@@ -8185,6 +8200,16 @@
             BuiltInVariable("gl_SubgroupGtMask",       EbvSubgroupGtMask2,     symbolTable);
             BuiltInVariable("gl_SubgroupLeMask",       EbvSubgroupLeMask2,     symbolTable);
             BuiltInVariable("gl_SubgroupLtMask",       EbvSubgroupLtMask2,     symbolTable);
+
+            // GL_NV_shader_sm_builtins
+            symbolTable.setVariableExtensions("gl_WarpsPerSMNV",         1, &E_GL_NV_shader_sm_builtins);
+            symbolTable.setVariableExtensions("gl_SMCountNV",            1, &E_GL_NV_shader_sm_builtins);
+            symbolTable.setVariableExtensions("gl_WarpIDNV",             1, &E_GL_NV_shader_sm_builtins);
+            symbolTable.setVariableExtensions("gl_SMIDNV",               1, &E_GL_NV_shader_sm_builtins);
+            BuiltInVariable("gl_WarpsPerSMNV",          EbvWarpsPerSM,      symbolTable);
+            BuiltInVariable("gl_SMCountNV",             EbvSMCount,         symbolTable);
+            BuiltInVariable("gl_WarpIDNV",              EbvWarpID,          symbolTable);
+            BuiltInVariable("gl_SMIDNV",                EbvSMID,            symbolTable);
         }
 
         break;
@@ -8586,6 +8611,15 @@
             symbolTable.setFunctionExtensions("subgroupPartitionedExclusiveXorNV",            1, &E_GL_NV_shader_subgroup_partitioned);
 #endif
 
+            // GL_NV_shader_sm_builtins
+            symbolTable.setVariableExtensions("gl_WarpsPerSMNV",         1, &E_GL_NV_shader_sm_builtins);
+            symbolTable.setVariableExtensions("gl_SMCountNV",            1, &E_GL_NV_shader_sm_builtins);
+            symbolTable.setVariableExtensions("gl_WarpIDNV",             1, &E_GL_NV_shader_sm_builtins);
+            symbolTable.setVariableExtensions("gl_SMIDNV",               1, &E_GL_NV_shader_sm_builtins);
+            BuiltInVariable("gl_WarpsPerSMNV",          EbvWarpsPerSM,      symbolTable);
+            BuiltInVariable("gl_SMCountNV",             EbvSMCount,         symbolTable);
+            BuiltInVariable("gl_WarpIDNV",              EbvWarpID,          symbolTable);
+            BuiltInVariable("gl_SMIDNV",                EbvSMID,            symbolTable);
         }
 
         if (profile == EEsProfile) {
@@ -8605,6 +8639,7 @@
             symbolTable.setVariableExtensions("gl_SemanticsAcquireRelease", 1, &E_GL_KHR_memory_scope_semantics);
             symbolTable.setVariableExtensions("gl_SemanticsMakeAvailable",  1, &E_GL_KHR_memory_scope_semantics);
             symbolTable.setVariableExtensions("gl_SemanticsMakeVisible",    1, &E_GL_KHR_memory_scope_semantics);
+            symbolTable.setVariableExtensions("gl_SemanticsVolatile",       1, &E_GL_KHR_memory_scope_semantics);
 
             symbolTable.setVariableExtensions("gl_StorageSemanticsNone",    1, &E_GL_KHR_memory_scope_semantics);
             symbolTable.setVariableExtensions("gl_StorageSemanticsBuffer",  1, &E_GL_KHR_memory_scope_semantics);
@@ -8690,6 +8725,16 @@
             BuiltInVariable("gl_SubgroupGtMask",       EbvSubgroupGtMask2,     symbolTable);
             BuiltInVariable("gl_SubgroupLeMask",       EbvSubgroupLeMask2,     symbolTable);
             BuiltInVariable("gl_SubgroupLtMask",       EbvSubgroupLtMask2,     symbolTable);
+
+            // GL_NV_shader_sm_builtins
+            symbolTable.setVariableExtensions("gl_WarpsPerSMNV",         1, &E_GL_NV_shader_sm_builtins);
+            symbolTable.setVariableExtensions("gl_SMCountNV",            1, &E_GL_NV_shader_sm_builtins);
+            symbolTable.setVariableExtensions("gl_WarpIDNV",             1, &E_GL_NV_shader_sm_builtins);
+            symbolTable.setVariableExtensions("gl_SMIDNV",               1, &E_GL_NV_shader_sm_builtins);
+            BuiltInVariable("gl_WarpsPerSMNV",          EbvWarpsPerSM,      symbolTable);
+            BuiltInVariable("gl_SMCountNV",             EbvSMCount,         symbolTable);
+            BuiltInVariable("gl_WarpIDNV",              EbvWarpID,          symbolTable);
+            BuiltInVariable("gl_SMIDNV",                EbvSMID,            symbolTable);
         }
 
         if ((profile != EEsProfile && version >= 140) ||
@@ -8804,6 +8849,16 @@
             BuiltInVariable("gl_SubgroupGtMask",       EbvSubgroupGtMask2,     symbolTable);
             BuiltInVariable("gl_SubgroupLeMask",       EbvSubgroupLeMask2,     symbolTable);
             BuiltInVariable("gl_SubgroupLtMask",       EbvSubgroupLtMask2,     symbolTable);
+
+            // GL_NV_shader_sm_builtins
+            symbolTable.setVariableExtensions("gl_WarpsPerSMNV",         1, &E_GL_NV_shader_sm_builtins);
+            symbolTable.setVariableExtensions("gl_SMCountNV",            1, &E_GL_NV_shader_sm_builtins);
+            symbolTable.setVariableExtensions("gl_WarpIDNV",             1, &E_GL_NV_shader_sm_builtins);
+            symbolTable.setVariableExtensions("gl_SMIDNV",               1, &E_GL_NV_shader_sm_builtins);
+            BuiltInVariable("gl_WarpsPerSMNV",          EbvWarpsPerSM,      symbolTable);
+            BuiltInVariable("gl_SMCountNV",             EbvSMCount,         symbolTable);
+            BuiltInVariable("gl_WarpIDNV",              EbvWarpID,          symbolTable);
+            BuiltInVariable("gl_SMIDNV",                EbvSMID,            symbolTable);
         }
         break;
 
@@ -8938,6 +8993,16 @@
             BuiltInVariable("gl_SubgroupLtMask",       EbvSubgroupLtMask2,     symbolTable);
 
             symbolTable.setFunctionExtensions("subgroupMemoryBarrierShared", 1, &E_GL_KHR_shader_subgroup_basic);
+
+            // GL_NV_shader_sm_builtins
+            symbolTable.setVariableExtensions("gl_WarpsPerSMNV",         1, &E_GL_NV_shader_sm_builtins);
+            symbolTable.setVariableExtensions("gl_SMCountNV",            1, &E_GL_NV_shader_sm_builtins);
+            symbolTable.setVariableExtensions("gl_WarpIDNV",             1, &E_GL_NV_shader_sm_builtins);
+            symbolTable.setVariableExtensions("gl_SMIDNV",               1, &E_GL_NV_shader_sm_builtins);
+            BuiltInVariable("gl_WarpsPerSMNV",          EbvWarpsPerSM,      symbolTable);
+            BuiltInVariable("gl_SMCountNV",             EbvSMCount,         symbolTable);
+            BuiltInVariable("gl_WarpIDNV",              EbvWarpID,          symbolTable);
+            BuiltInVariable("gl_SMIDNV",                EbvSMID,            symbolTable);
         }
         break;
 
@@ -9028,6 +9093,16 @@
             BuiltInVariable("gl_SubgroupLtMask",       EbvSubgroupLtMask2,     symbolTable);
 
             symbolTable.setFunctionExtensions("subgroupMemoryBarrierShared", 1, &E_GL_KHR_shader_subgroup_basic);
+
+            // GL_NV_shader_sm_builtins
+            symbolTable.setVariableExtensions("gl_WarpsPerSMNV",         1, &E_GL_NV_shader_sm_builtins);
+            symbolTable.setVariableExtensions("gl_SMCountNV",            1, &E_GL_NV_shader_sm_builtins);
+            symbolTable.setVariableExtensions("gl_WarpIDNV",             1, &E_GL_NV_shader_sm_builtins);
+            symbolTable.setVariableExtensions("gl_SMIDNV",               1, &E_GL_NV_shader_sm_builtins);
+            BuiltInVariable("gl_WarpsPerSMNV",          EbvWarpsPerSM,      symbolTable);
+            BuiltInVariable("gl_SMCountNV",             EbvSMCount,         symbolTable);
+            BuiltInVariable("gl_WarpIDNV",              EbvWarpID,          symbolTable);
+            BuiltInVariable("gl_SMIDNV",                EbvSMID,            symbolTable);
         }
         break;
 #endif
@@ -9547,6 +9622,10 @@
         if (profile != EEsProfile)
             symbolTable.relateToOperator("interpolateAtVertexAMD", EOpInterpolateAtVertex);
 #endif
+
+        symbolTable.relateToOperator("beginInvocationInterlockARB", EOpBeginInvocationInterlock);
+        symbolTable.relateToOperator("endInvocationInterlockARB",   EOpEndInvocationInterlock);
+
         break;
 
     case EShLangCompute:
diff --git a/glslang/MachineIndependent/ParseHelper.cpp b/glslang/MachineIndependent/ParseHelper.cpp
index 8384eb9..57cc5f9 100644
--- a/glslang/MachineIndependent/ParseHelper.cpp
+++ b/glslang/MachineIndependent/ParseHelper.cpp
@@ -1165,8 +1165,9 @@
                             error(arguments->getLoc(), message, "readonly", "");
                         if (argQualifier.writeonly && ! formalQualifier.writeonly)
                             error(arguments->getLoc(), message, "writeonly", "");
-                        if (!builtIn && argQualifier.restrict && ! formalQualifier.restrict)
-                            error(arguments->getLoc(), message, "restrict", "");
+                        // Don't check 'restrict', it is different than the rest:
+                        // "...but only restrict can be taken away from a calling argument, by a formal parameter that
+                        // lacks the restrict qualifier..."
                     }
                     if (!builtIn && argQualifier.layoutFormat != formalQualifier.layoutFormat) {
                         // we have mismatched formats, which should only be allowed if writeonly
@@ -1410,6 +1411,44 @@
                 error(loc, "tessellation control barrier() cannot be placed after a return from main()", "", "");
         }
         break;
+    case EOpBeginInvocationInterlock:
+        if (language != EShLangFragment)
+            error(loc, "beginInvocationInterlockARB() must be in a fragment shader", "", "");
+        if (! inMain)
+            error(loc, "beginInvocationInterlockARB() must be in main()", "", "");
+        else if (postEntryPointReturn)
+            error(loc, "beginInvocationInterlockARB() cannot be placed after a return from main()", "", "");
+        if (controlFlowNestingLevel > 0)
+            error(loc, "beginInvocationInterlockARB() cannot be placed within flow control", "", "");
+
+        if (beginInvocationInterlockCount > 0)
+            error(loc, "beginInvocationInterlockARB() must only be called once", "", "");
+        if (endInvocationInterlockCount > 0)
+            error(loc, "beginInvocationInterlockARB() must be called before endInvocationInterlockARB()", "", "");
+
+        beginInvocationInterlockCount++;
+
+        // default to pixel_interlock_ordered
+        if (intermediate.getInterlockOrdering() == EioNone)
+            intermediate.setInterlockOrdering(EioPixelInterlockOrdered);
+        break;
+    case EOpEndInvocationInterlock:
+        if (language != EShLangFragment)
+            error(loc, "endInvocationInterlockARB() must be in a fragment shader", "", "");
+        if (! inMain)
+            error(loc, "endInvocationInterlockARB() must be in main()", "", "");
+        else if (postEntryPointReturn)
+            error(loc, "endInvocationInterlockARB() cannot be placed after a return from main()", "", "");
+        if (controlFlowNestingLevel > 0)
+            error(loc, "endInvocationInterlockARB() cannot be placed within flow control", "", "");
+
+        if (endInvocationInterlockCount > 0)
+            error(loc, "endInvocationInterlockARB() must only be called once", "", "");
+        if (beginInvocationInterlockCount == 0)
+            error(loc, "beginInvocationInterlockARB() must be called before endInvocationInterlockARB()", "", "");
+
+        endInvocationInterlockCount++;
+        break;
     default:
         break;
     }
@@ -1602,6 +1641,7 @@
     const int gl_SemanticsAcquireRelease  = 0x8;
     const int gl_SemanticsMakeAvailable   = 0x2000;
     const int gl_SemanticsMakeVisible     = 0x4000;
+    const int gl_SemanticsVolatile        = 0x8000;
 
     //const int gl_StorageSemanticsNone     = 0x0;
     const int gl_StorageSemanticsBuffer   = 0x40;
@@ -1691,7 +1731,8 @@
                                       gl_SemanticsRelease |
                                       gl_SemanticsAcquireRelease |
                                       gl_SemanticsMakeAvailable |
-                                      gl_SemanticsMakeVisible))) {
+                                      gl_SemanticsMakeVisible |
+                                      gl_SemanticsVolatile))) {
         error(loc, "Invalid semantics value", fnCandidate.getName().c_str(), "");
     }
     if (((storageClassSemantics | storageClassSemantics2) & ~(gl_StorageSemanticsBuffer |
@@ -1743,7 +1784,16 @@
         error(loc, "gl_SemanticsMakeVisible requires gl_SemanticsAcquire or gl_SemanticsAcquireRelease",
               fnCandidate.getName().c_str(), "");
     }
-
+    if ((semantics & gl_SemanticsVolatile) &&
+        (callNode.getOp() == EOpMemoryBarrier || callNode.getOp() == EOpBarrier)) {
+        error(loc, "gl_SemanticsVolatile must not be used with memoryBarrier or controlBarrier",
+              fnCandidate.getName().c_str(), "");
+    }
+    if ((callNode.getOp() == EOpAtomicCompSwap || callNode.getOp() == EOpImageAtomicCompSwap) &&
+        ((semantics ^ semantics2) & gl_SemanticsVolatile)) {
+        error(loc, "semEqual and semUnequal must either both include gl_SemanticsVolatile or neither",
+              fnCandidate.getName().c_str(), "");
+    }
 }
 
 
@@ -4945,6 +4995,19 @@
                 return;
             }
         }
+        for (TInterlockOrdering order = (TInterlockOrdering)(EioNone + 1); order < EioCount; order = (TInterlockOrdering)(order+1)) {
+            if (id == TQualifier::getInterlockOrderingString(order)) {
+                requireProfile(loc, ECoreProfile | ECompatibilityProfile, "fragment shader interlock layout qualifier");
+                profileRequires(loc, ECoreProfile | ECompatibilityProfile, 450, nullptr, "fragment shader interlock layout qualifier");
+                requireExtensions(loc, 1, &E_GL_ARB_fragment_shader_interlock, TQualifier::getInterlockOrderingString(order));
+#ifdef NV_EXTENSIONS
+                if (order == EioShadingRateInterlockOrdered || order == EioShadingRateInterlockUnordered)
+                    requireExtensions(loc, 1, &E_GL_NV_shading_rate_image, TQualifier::getInterlockOrderingString(order));
+#endif
+                publicType.shaderQualifiers.interlockOrdering = order;
+                return;
+            }
+        }
         if (id.compare(0, 13, "blend_support") == 0) {
             bool found = false;
             for (TBlendEquationShift be = (TBlendEquationShift)0; be < EBlendCount; be = (TBlendEquationShift)(be + 1)) {
@@ -5945,6 +6008,8 @@
         error(loc, message, "blend equation", "");
     if (shaderQualifiers.numViews != TQualifier::layoutNotSet)
         error(loc, message, "num_views", "");
+    if (shaderQualifiers.interlockOrdering != EioNone)
+        error(loc, message, TQualifier::getInterlockOrderingString(shaderQualifiers.interlockOrdering), "");
 }
 
 // Correct and/or advance an object's offset layout qualifier.
@@ -7874,6 +7939,14 @@
         if (publicType.qualifier.storage != EvqVaryingOut)
             error(loc, "can only apply to 'out'", "blend equation", "");
     }
+    if (publicType.shaderQualifiers.interlockOrdering) {
+        if (publicType.qualifier.storage == EvqVaryingIn) {
+            if (!intermediate.setInterlockOrdering(publicType.shaderQualifiers.interlockOrdering))
+                error(loc, "cannot change previously set fragment shader interlock ordering", TQualifier::getInterlockOrderingString(publicType.shaderQualifiers.interlockOrdering), "");
+        }
+        else
+            error(loc, "can only apply to 'in'", TQualifier::getInterlockOrderingString(publicType.shaderQualifiers.interlockOrdering), "");
+    }
 
 #ifdef NV_EXTENSIONS
     if (publicType.shaderQualifiers.layoutDerivativeGroupQuads &&
diff --git a/glslang/MachineIndependent/ParseHelper.h b/glslang/MachineIndependent/ParseHelper.h
index a1ffe64..04ede1e 100644
--- a/glslang/MachineIndependent/ParseHelper.h
+++ b/glslang/MachineIndependent/ParseHelper.h
@@ -85,6 +85,7 @@
             statementNestingLevel(0), loopNestingLevel(0), structNestingLevel(0), controlFlowNestingLevel(0),
             postEntryPointReturn(false),
             contextPragma(true, false),
+            beginInvocationInterlockCount(0), endInvocationInterlockCount(0),
             parsingBuiltins(parsingBuiltins), scanContext(nullptr), ppContext(nullptr),
             limits(resources.limits),
             globalUniformBlock(nullptr),
@@ -182,6 +183,8 @@
     // the statementNestingLevel the current switch statement is at, which must match the level of its case statements
     TList<int> switchLevel;
     struct TPragma contextPragma;
+    int beginInvocationInterlockCount;
+    int endInvocationInterlockCount;
 
 protected:
     TParseContextBase(TParseContextBase&);
diff --git a/glslang/MachineIndependent/SymbolTable.cpp b/glslang/MachineIndependent/SymbolTable.cpp
index c0a02e6..f4d97d2 100755
--- a/glslang/MachineIndependent/SymbolTable.cpp
+++ b/glslang/MachineIndependent/SymbolTable.cpp
@@ -184,7 +184,7 @@
 
         for (int i = 0; i < numExtensions; i++)
             infoSink.debug << getExtensions()[i] << ",";
-        
+
         infoSink.debug << ">";
     }
 }
@@ -229,7 +229,7 @@
     infoSink.debug << "\n";
 }
 
-void TAnonMember::dump(TInfoSink& TInfoSink, bool complete) const
+void TAnonMember::dump(TInfoSink& TInfoSink, bool) const
 {
     TInfoSink.debug << "anonymous member " << getMemberNumber() << " of " << getAnonContainer().getName().c_str()
                     << "\n";
diff --git a/glslang/MachineIndependent/Versions.cpp b/glslang/MachineIndependent/Versions.cpp
index f19c385..4054ac8 100644
--- a/glslang/MachineIndependent/Versions.cpp
+++ b/glslang/MachineIndependent/Versions.cpp
@@ -187,6 +187,7 @@
 //    extensionBehavior[E_GL_ARB_cull_distance]                = EBhDisable;    // present for 4.5, but need extension control over block members
     extensionBehavior[E_GL_ARB_post_depth_coverage]          = EBhDisable;
     extensionBehavior[E_GL_ARB_shader_viewport_layer_array]  = EBhDisable;
+    extensionBehavior[E_GL_ARB_fragment_shader_interlock]    = EBhDisable;
 
     extensionBehavior[E_GL_KHR_shader_subgroup_basic]            = EBhDisable;
     extensionBehavior[E_GL_KHR_shader_subgroup_vote]             = EBhDisable;
@@ -250,6 +251,7 @@
 #endif
 
     extensionBehavior[E_GL_NV_cooperative_matrix]                    = EBhDisable;
+    extensionBehavior[E_GL_NV_shader_sm_builtins]                    = EBhDisable;
 
     // AEP
     extensionBehavior[E_GL_ANDROID_extension_pack_es31a]             = EBhDisable;
@@ -379,6 +381,7 @@
             "#define GL_ARB_shader_stencil_export 1\n"
 //            "#define GL_ARB_cull_distance 1\n"    // present for 4.5, but need extension control over block members
             "#define GL_ARB_post_depth_coverage 1\n"
+            "#define GL_ARB_fragment_shader_interlock 1\n"
             "#define GL_EXT_shader_non_constant_global_initializers 1\n"
             "#define GL_EXT_shader_image_load_formatted 1\n"
             "#define GL_EXT_post_depth_coverage 1\n"
@@ -457,6 +460,7 @@
         preamble +=
             "#define GL_EXT_device_group 1\n"
             "#define GL_EXT_multiview 1\n"
+            "#define GL_NV_shader_sm_builtins 1\n"
             ;
     }
 
diff --git a/glslang/MachineIndependent/Versions.h b/glslang/MachineIndependent/Versions.h
index bff0827..6c94502 100644
--- a/glslang/MachineIndependent/Versions.h
+++ b/glslang/MachineIndependent/Versions.h
@@ -141,6 +141,7 @@
 // const char* const E_GL_ARB_cull_distance            = "GL_ARB_cull_distance";  // present for 4.5, but need extension control over block members
 const char* const E_GL_ARB_post_depth_coverage          = "GL_ARB_post_depth_coverage";
 const char* const E_GL_ARB_shader_viewport_layer_array  = "GL_ARB_shader_viewport_layer_array";
+const char* const E_GL_ARB_fragment_shader_interlock    = "GL_ARB_fragment_shader_interlock";
 
 const char* const E_GL_KHR_shader_subgroup_basic            = "GL_KHR_shader_subgroup_basic";
 const char* const E_GL_KHR_shader_subgroup_vote             = "GL_KHR_shader_subgroup_vote";
@@ -227,6 +228,7 @@
 #endif
 
 const char* const E_GL_NV_cooperative_matrix                    = "GL_NV_cooperative_matrix";
+const char* const E_GL_NV_shader_sm_builtins                    = "GL_NV_shader_sm_builtins";
 
 // AEP
 const char* const E_GL_ANDROID_extension_pack_es31a             = "GL_ANDROID_extension_pack_es31a";
diff --git a/glslang/MachineIndependent/intermOut.cpp b/glslang/MachineIndependent/intermOut.cpp
index f9f285e..abf5681 100644
--- a/glslang/MachineIndependent/intermOut.cpp
+++ b/glslang/MachineIndependent/intermOut.cpp
@@ -1502,6 +1502,8 @@
             }
             infoSink.debug << "\n";
         }
+        if (interlockOrdering != EioNone)
+            infoSink.debug << "interlock ordering = " << TQualifier::getInterlockOrderingString(interlockOrdering) << "\n";
         break;
 
 #ifdef NV_EXTENSIONS
diff --git a/glslang/MachineIndependent/localintermediate.h b/glslang/MachineIndependent/localintermediate.h
index f29c93c..30ba98d 100644
--- a/glslang/MachineIndependent/localintermediate.h
+++ b/glslang/MachineIndependent/localintermediate.h
@@ -240,7 +240,7 @@
         invocations(TQualifier::layoutNotSet), vertices(TQualifier::layoutNotSet),
         inputPrimitive(ElgNone), outputPrimitive(ElgNone),
         pixelCenterInteger(false), originUpperLeft(false),
-        vertexSpacing(EvsNone), vertexOrder(EvoNone), pointMode(false), earlyFragmentTests(false),
+        vertexSpacing(EvsNone), vertexOrder(EvoNone), interlockOrdering(EioNone), pointMode(false), earlyFragmentTests(false),
         postDepthCoverage(false), depthLayout(EldNone), depthReplacing(false),
         hlslFunctionality1(false),
         blendEquations(0), xfbMode(false), multiStream(false),
@@ -608,6 +608,15 @@
     void setPointMode() { pointMode = true; }
     bool getPointMode() const { return pointMode; }
 
+    bool setInterlockOrdering(TInterlockOrdering o)
+    {
+        if (interlockOrdering != EioNone)
+            return interlockOrdering == o;
+        interlockOrdering = o;
+        return true;
+    }
+    TInterlockOrdering getInterlockOrdering() const { return interlockOrdering; }
+
     bool setLocalSize(int dim, int size)
     {
         if (localSize[dim] > 1)
@@ -826,6 +835,7 @@
     bool originUpperLeft;
     TVertexSpacing vertexSpacing;
     TVertexOrder vertexOrder;
+    TInterlockOrdering interlockOrdering;
     bool pointMode;
     int localSize[3];
     int localSizeSpecId[3];
diff --git a/gtests/Spv.FromFile.cpp b/gtests/Spv.FromFile.cpp
index 5a126f1..e28f7aa 100644
--- a/gtests/Spv.FromFile.cpp
+++ b/gtests/Spv.FromFile.cpp
@@ -319,6 +319,8 @@
         "spv.fragmentDensity.vert",
         "spv.fragmentDensity-es.frag",
         "spv.fragmentDensity-neg.frag",
+        "spv.fsi.frag",
+        "spv.fsi_Error.frag",
         "spv.fullyCovered.frag",
         "spv.functionCall.frag",
         "spv.functionNestedOpaque.vert",
@@ -408,6 +410,8 @@
         "spv.xfb2.vert",
         "spv.xfb3.vert",
         "spv.samplerlessTextureFunctions.frag",
+        "spv.smBuiltins.vert",
+        "spv.smBuiltins.frag",
     })),
     FileNameAsCustomTestSuffix
 );
diff --git a/known_good.json b/known_good.json
index 95f1f0a..16716fd 100644
--- a/known_good.json
+++ b/known_good.json
@@ -5,14 +5,14 @@
       "site" : "github",
       "subrepo" : "KhronosGroup/SPIRV-Tools",
       "subdir" : "External/spirv-tools",
-      "commit" : "9dfd4b8358077bdbe8e2f9388572b5376c370f5d"
+      "commit" : "b4bf7bcf0ad3a7eb6857e8d6d594e23f1be6f27a"
     },
     {
       "name" : "spirv-tools/external/spirv-headers",
       "site" : "github",
       "subrepo" : "KhronosGroup/SPIRV-Headers",
       "subdir" : "External/spirv-tools/external/spirv-headers",
-      "commit" : "4b0985f29277a81f5ce88feb0502cc44d6d5e7c3"
+      "commit" : "8b911bd2ba37677037b38c9bd286c7c05701bcda"
     }
   ]
 }