SPV: Implement Vulkan 1.1 features and extensions.
diff --git a/SPIRV/GlslangToSpv.cpp b/SPIRV/GlslangToSpv.cpp
old mode 100755
new mode 100644
index 21cd869..45e76ad
--- a/SPIRV/GlslangToSpv.cpp
+++ b/SPIRV/GlslangToSpv.cpp
@@ -1,6 +1,7 @@
 //
 // Copyright (C) 2014-2016 LunarG, Inc.
 // Copyright (C) 2015-2016 Google, Inc.
+// Copyright (C) 2017 ARM Limited.
 //
 // All rights reserved.
 //
@@ -172,10 +173,12 @@
     spv::Id createUnaryOperation(glslang::TOperator op, spv::Decoration precision, spv::Decoration noContraction, spv::Id typeId, spv::Id operand,glslang::TBasicType typeProxy);
     spv::Id createUnaryMatrixOperation(spv::Op op, spv::Decoration precision, spv::Decoration noContraction, spv::Id typeId, spv::Id operand,glslang::TBasicType typeProxy);
     spv::Id createConversion(glslang::TOperator op, spv::Decoration precision, spv::Decoration noContraction, spv::Id destTypeId, spv::Id operand, glslang::TBasicType typeProxy);
+    spv::Id createConversionOperation(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 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);
     spv::Id createMiscOperation(glslang::TOperator op, spv::Decoration precision, spv::Id typeId, std::vector<spv::Id>& operands, glslang::TBasicType typeProxy);
     spv::Id createNoArgOperation(glslang::TOperator op, spv::Decoration precision, spv::Id typeId);
     spv::Id getSymbolId(const glslang::TIntermSymbol* node);
@@ -191,6 +194,11 @@
 #ifdef AMD_EXTENSIONS
     spv::Id getExtBuiltins(const char* name);
 #endif
+    void addPre13Extension(const char* ext)
+    {
+        if (builder.getSpvVersion() < glslang::EShTargetSpv_1_3)
+            builder.addExtension(ext);
+    }
 
     glslang::SpvOptions& options;
     spv::Function* shaderEntry;
@@ -504,17 +512,17 @@
     case glslang::EbvInstanceIndex:        return spv::BuiltInInstanceIndex;
 
     case glslang::EbvBaseVertex:
-        builder.addExtension(spv::E_SPV_KHR_shader_draw_parameters);
+        addPre13Extension(spv::E_SPV_KHR_shader_draw_parameters);
         builder.addCapability(spv::CapabilityDrawParameters);
         return spv::BuiltInBaseVertex;
 
     case glslang::EbvBaseInstance:
-        builder.addExtension(spv::E_SPV_KHR_shader_draw_parameters);
+        addPre13Extension(spv::E_SPV_KHR_shader_draw_parameters);
         builder.addCapability(spv::CapabilityDrawParameters);
         return spv::BuiltInBaseInstance;
 
     case glslang::EbvDrawId:
-        builder.addExtension(spv::E_SPV_KHR_shader_draw_parameters);
+        addPre13Extension(spv::E_SPV_KHR_shader_draw_parameters);
         builder.addCapability(spv::CapabilityDrawParameters);
         return spv::BuiltInDrawIndex;
 
@@ -580,6 +588,46 @@
         builder.addCapability(spv::CapabilitySubgroupBallotKHR);
         return spv::BuiltInSubgroupLtMaskKHR;
 
+    case glslang::EbvNumSubgroups:
+        builder.addCapability(spv::CapabilityGroupNonUniform);
+        return spv::BuiltInNumSubgroups;
+
+    case glslang::EbvSubgroupID:
+        builder.addCapability(spv::CapabilityGroupNonUniform);
+        return spv::BuiltInSubgroupId;
+
+    case glslang::EbvSubgroupSize2:
+        builder.addCapability(spv::CapabilityGroupNonUniform);
+        return spv::BuiltInSubgroupSize;
+
+    case glslang::EbvSubgroupInvocation2:
+        builder.addCapability(spv::CapabilityGroupNonUniform);
+        return spv::BuiltInSubgroupLocalInvocationId;
+
+    case glslang::EbvSubgroupEqMask2:
+        builder.addCapability(spv::CapabilityGroupNonUniform);
+        builder.addCapability(spv::CapabilityGroupNonUniformBallot);
+        return spv::BuiltInSubgroupEqMask;
+
+    case glslang::EbvSubgroupGeMask2:
+        builder.addCapability(spv::CapabilityGroupNonUniform);
+        builder.addCapability(spv::CapabilityGroupNonUniformBallot);
+        return spv::BuiltInSubgroupGeMask;
+
+    case glslang::EbvSubgroupGtMask2:
+        builder.addCapability(spv::CapabilityGroupNonUniform);
+        builder.addCapability(spv::CapabilityGroupNonUniformBallot);
+        return spv::BuiltInSubgroupGtMask;
+
+    case glslang::EbvSubgroupLeMask2:
+        builder.addCapability(spv::CapabilityGroupNonUniform);
+        builder.addCapability(spv::CapabilityGroupNonUniformBallot);
+        return spv::BuiltInSubgroupLeMask;
+
+    case glslang::EbvSubgroupLtMask2:
+        builder.addCapability(spv::CapabilityGroupNonUniform);
+        builder.addCapability(spv::CapabilityGroupNonUniformBallot);
+        return spv::BuiltInSubgroupLtMask;
 #ifdef AMD_EXTENSIONS
     case glslang::EbvBaryCoordNoPersp:
         builder.addExtension(spv::E_SPV_AMD_shader_explicit_vertex_parameter);
@@ -611,12 +659,12 @@
 #endif
 
     case glslang::EbvDeviceIndex:
-        builder.addExtension(spv::E_SPV_KHR_device_group);
+        addPre13Extension(spv::E_SPV_KHR_device_group);
         builder.addCapability(spv::CapabilityDeviceGroup);
         return spv::BuiltInDeviceIndex;
 
     case glslang::EbvViewIndex:
-        builder.addExtension(spv::E_SPV_KHR_multiview);
+        addPre13Extension(spv::E_SPV_KHR_multiview);
         builder.addCapability(spv::CapabilityMultiView);
         return spv::BuiltInViewIndex;
 
@@ -804,7 +852,7 @@
     }
 
     if (glslangIntermediate->usingStorageBuffer() && type.getQualifier().storage == glslang::EvqBuffer) {
-        builder.addExtension(spv::E_SPV_KHR_storage_buffer_storage_class);
+        addPre13Extension(spv::E_SPV_KHR_storage_buffer_storage_class);
         return spv::StorageClassStorageBuffer;
     }
 
@@ -1436,16 +1484,14 @@
                 one = builder.makeFloatConstant(1.0F);
             else if (node->getBasicType() == glslang::EbtDouble)
                 one = builder.makeDoubleConstant(1.0);
-#ifdef AMD_EXTENSIONS
             else if (node->getBasicType() == glslang::EbtFloat16)
                 one = builder.makeFloat16Constant(1.0F);
-#endif
-            else if (node->getBasicType() == glslang::EbtInt64 || node->getBasicType() == glslang::EbtUint64)
-                one = builder.makeInt64Constant(1);
-#ifdef AMD_EXTENSIONS
+            else if (node->getBasicType() == glslang::EbtInt8  || node->getBasicType() == glslang::EbtUint8)
+                one = builder.makeInt8Constant(1);
             else if (node->getBasicType() == glslang::EbtInt16 || node->getBasicType() == glslang::EbtUint16)
                 one = builder.makeInt16Constant(1);
-#endif
+            else if (node->getBasicType() == glslang::EbtInt64 || node->getBasicType() == glslang::EbtUint64)
+                one = builder.makeInt64Constant(1);
             else
                 one = builder.makeIntConstant(1);
             glslang::TOperator op;
@@ -1650,7 +1696,6 @@
     case glslang::EOpConstructBMat4x2:
     case glslang::EOpConstructBMat4x3:
     case glslang::EOpConstructBMat4x4:
-#ifdef AMD_EXTENSIONS
     case glslang::EOpConstructF16Mat2x2:
     case glslang::EOpConstructF16Mat2x3:
     case glslang::EOpConstructF16Mat2x4:
@@ -1660,7 +1705,6 @@
     case glslang::EOpConstructF16Mat4x2:
     case glslang::EOpConstructF16Mat4x3:
     case glslang::EOpConstructF16Mat4x4:
-#endif
         isMatrix = true;
         // fall through
     case glslang::EOpConstructFloat:
@@ -1671,16 +1715,30 @@
     case glslang::EOpConstructDVec2:
     case glslang::EOpConstructDVec3:
     case glslang::EOpConstructDVec4:
-#ifdef AMD_EXTENSIONS
     case glslang::EOpConstructFloat16:
     case glslang::EOpConstructF16Vec2:
     case glslang::EOpConstructF16Vec3:
     case glslang::EOpConstructF16Vec4:
-#endif
     case glslang::EOpConstructBool:
     case glslang::EOpConstructBVec2:
     case glslang::EOpConstructBVec3:
     case glslang::EOpConstructBVec4:
+    case glslang::EOpConstructInt8:
+    case glslang::EOpConstructI8Vec2:
+    case glslang::EOpConstructI8Vec3:
+    case glslang::EOpConstructI8Vec4:
+    case glslang::EOpConstructUint8:
+    case glslang::EOpConstructU8Vec2:
+    case glslang::EOpConstructU8Vec3:
+    case glslang::EOpConstructU8Vec4:
+    case glslang::EOpConstructInt16:
+    case glslang::EOpConstructI16Vec2:
+    case glslang::EOpConstructI16Vec3:
+    case glslang::EOpConstructI16Vec4:
+    case glslang::EOpConstructUint16:
+    case glslang::EOpConstructU16Vec2:
+    case glslang::EOpConstructU16Vec3:
+    case glslang::EOpConstructU16Vec4:
     case glslang::EOpConstructInt:
     case glslang::EOpConstructIVec2:
     case glslang::EOpConstructIVec3:
@@ -1697,16 +1755,6 @@
     case glslang::EOpConstructU64Vec2:
     case glslang::EOpConstructU64Vec3:
     case glslang::EOpConstructU64Vec4:
-#ifdef AMD_EXTENSIONS
-    case glslang::EOpConstructInt16:
-    case glslang::EOpConstructI16Vec2:
-    case glslang::EOpConstructI16Vec3:
-    case glslang::EOpConstructI16Vec4:
-    case glslang::EOpConstructUint16:
-    case glslang::EOpConstructU16Vec2:
-    case glslang::EOpConstructU16Vec3:
-    case glslang::EOpConstructU16Vec4:
-#endif
     case glslang::EOpConstructStruct:
     case glslang::EOpConstructTextureSampler:
     {
@@ -1787,6 +1835,11 @@
     case glslang::EOpDeviceMemoryBarrierWithGroupSync:
     case glslang::EOpWorkgroupMemoryBarrier:
     case glslang::EOpWorkgroupMemoryBarrierWithGroupSync:
+    case glslang::EOpSubgroupBarrier:
+    case glslang::EOpSubgroupMemoryBarrier:
+    case glslang::EOpSubgroupMemoryBarrierBuffer:
+    case glslang::EOpSubgroupMemoryBarrierImage:
+    case glslang::EOpSubgroupMemoryBarrierShared:
         noReturnValue = true;
         // These all have 0 operands and will naturally finish up in the code below for 0 operands
         break;
@@ -2308,25 +2361,23 @@
     spv::StorageClass storageClass = TranslateStorageClass(node->getType());
     spv::Id spvType = convertGlslangToSpvType(node->getType());
 
-#ifdef AMD_EXTENSIONS
     const bool contains16BitType = node->getType().containsBasicType(glslang::EbtFloat16) ||
                                    node->getType().containsBasicType(glslang::EbtInt16)   ||
                                    node->getType().containsBasicType(glslang::EbtUint16);
     if (contains16BitType) {
         if (storageClass == spv::StorageClassInput || storageClass == spv::StorageClassOutput) {
-            builder.addExtension(spv::E_SPV_KHR_16bit_storage);
+            addPre13Extension(spv::E_SPV_KHR_16bit_storage);
             builder.addCapability(spv::CapabilityStorageInputOutput16);
         } else if (storageClass == spv::StorageClassPushConstant) {
-            builder.addExtension(spv::E_SPV_KHR_16bit_storage);
+            addPre13Extension(spv::E_SPV_KHR_16bit_storage);
             builder.addCapability(spv::CapabilityStoragePushConstant16);
         } else if (storageClass == spv::StorageClassUniform) {
-            builder.addExtension(spv::E_SPV_KHR_16bit_storage);
+            addPre13Extension(spv::E_SPV_KHR_16bit_storage);
             builder.addCapability(spv::CapabilityStorageUniform16);
             if (node->getType().getQualifier().storage == glslang::EvqBuffer)
                 builder.addCapability(spv::CapabilityStorageUniformBufferBlock16);
         }
     }
-#endif
 
     const char* name = node->getName().c_str();
     if (glslang::IsAnonymous(name))
@@ -2409,12 +2460,14 @@
     case glslang::EbtDouble:
         spvType = builder.makeFloatType(64);
         break;
-#ifdef AMD_EXTENSIONS
     case glslang::EbtFloat16:
-        builder.addExtension(spv::E_SPV_AMD_gpu_shader_half_float);
+        builder.addCapability(spv::CapabilityFloat16);
+#if AMD_EXTENSIONS
+        if (builder.getSpvVersion() < glslang::EShTargetSpv_1_3)
+            builder.addExtension(spv::E_SPV_AMD_gpu_shader_half_float);
+#endif
         spvType = builder.makeFloatType(16);
         break;
-#endif
     case glslang::EbtBool:
         // "transparent" bool doesn't exist in SPIR-V.  The GLSL convention is
         // a 32-bit int where non-0 means true.
@@ -2423,6 +2476,30 @@
         else
             spvType = builder.makeBoolType();
         break;
+   case glslang::EbtInt8:
+        builder.addCapability(spv::CapabilityInt8);
+        spvType = builder.makeIntType(8);
+        break;
+    case glslang::EbtUint8:
+        builder.addCapability(spv::CapabilityInt8);
+        spvType = builder.makeUintType(8);
+        break;
+   case glslang::EbtInt16:
+        builder.addCapability(spv::CapabilityInt16);
+#ifdef AMD_EXTENSIONS
+        if (builder.getSpvVersion() < glslang::EShTargetSpv_1_3)
+            builder.addExtension(spv::E_SPV_AMD_gpu_shader_int16);
+#endif
+        spvType = builder.makeIntType(16);
+        break;
+    case glslang::EbtUint16:
+        builder.addCapability(spv::CapabilityInt16);
+#ifdef AMD_EXTENSIONS
+        if (builder.getSpvVersion() < glslang::EShTargetSpv_1_3)
+            builder.addExtension(spv::E_SPV_AMD_gpu_shader_int16);
+#endif
+        spvType = builder.makeUintType(16);
+        break;
     case glslang::EbtInt:
         spvType = builder.makeIntType(32);
         break;
@@ -2435,16 +2512,6 @@
     case glslang::EbtUint64:
         spvType = builder.makeUintType(64);
         break;
-#ifdef AMD_EXTENSIONS
-    case glslang::EbtInt16:
-        builder.addExtension(spv::E_SPV_AMD_gpu_shader_int16);
-        spvType = builder.makeIntType(16);
-        break;
-    case glslang::EbtUint16:
-        builder.addExtension(spv::E_SPV_AMD_gpu_shader_int16);
-        spvType = builder.makeUintType(16);
-        break;
-#endif
     case glslang::EbtAtomicUint:
         builder.addCapability(spv::CapabilityAtomicStorage);
         spvType = builder.makeUintType(32);
@@ -3830,13 +3897,8 @@
                                                       spv::Id typeId, spv::Id left, spv::Id right,
                                                       glslang::TBasicType typeProxy, bool reduceComparison)
 {
-#ifdef AMD_EXTENSIONS
-    bool isUnsigned = typeProxy == glslang::EbtUint || typeProxy == glslang::EbtUint64 || typeProxy == glslang::EbtUint16;
-    bool isFloat = typeProxy == glslang::EbtFloat || typeProxy == glslang::EbtDouble || typeProxy == glslang::EbtFloat16;
-#else
-    bool isUnsigned = typeProxy == glslang::EbtUint || typeProxy == glslang::EbtUint64;
-    bool isFloat = typeProxy == glslang::EbtFloat || typeProxy == glslang::EbtDouble;
-#endif
+    bool isUnsigned = isTypeUnsignedInt(typeProxy);
+    bool isFloat = isTypeFloat(typeProxy);
     bool isBool = typeProxy == glslang::EbtBool;
 
     spv::Op binOp = spv::OpNop;
@@ -4161,13 +4223,8 @@
     spv::Op unaryOp = spv::OpNop;
     int extBuiltins = -1;
     int libCall = -1;
-#ifdef AMD_EXTENSIONS
-    bool isUnsigned = typeProxy == glslang::EbtUint || typeProxy == glslang::EbtUint64 || typeProxy == glslang::EbtUint16;
-    bool isFloat = typeProxy == glslang::EbtFloat || typeProxy == glslang::EbtDouble || typeProxy == glslang::EbtFloat16;
-#else
-    bool isUnsigned = typeProxy == glslang::EbtUint || typeProxy == glslang::EbtUint64;
-    bool isFloat = typeProxy == glslang::EbtFloat || typeProxy == glslang::EbtDouble;
-#endif
+    bool isUnsigned = isTypeUnsignedInt(typeProxy);
+    bool isFloat = isTypeFloat(typeProxy);
 
     switch (op) {
     case glslang::EOpNegative:
@@ -4304,12 +4361,10 @@
     case glslang::EOpDoubleBitsToUint64:
     case glslang::EOpInt64BitsToDouble:
     case glslang::EOpUint64BitsToDouble:
-#ifdef AMD_EXTENSIONS
     case glslang::EOpFloat16BitsToInt16:
     case glslang::EOpFloat16BitsToUint16:
     case glslang::EOpInt16BitsToFloat16:
     case glslang::EOpUint16BitsToFloat16:
-#endif
         unaryOp = spv::OpBitcast;
         break;
 
@@ -4354,10 +4409,12 @@
     case glslang::EOpUnpackInt2x32:
     case glslang::EOpPackUint2x32:
     case glslang::EOpUnpackUint2x32:
-        unaryOp = spv::OpBitcast;
-        break;
-
-#ifdef AMD_EXTENSIONS
+    case glslang::EOpPack16:
+    case glslang::EOpPack32:
+    case glslang::EOpPack64:
+    case glslang::EOpUnpack32:
+    case glslang::EOpUnpack16:
+    case glslang::EOpUnpack8:
     case glslang::EOpPackInt2x16:
     case glslang::EOpUnpackInt2x16:
     case glslang::EOpPackUint2x16:
@@ -4370,7 +4427,6 @@
     case glslang::EOpUnpackFloat2x16:
         unaryOp = spv::OpBitcast;
         break;
-#endif
 
     case glslang::EOpDPdx:
         unaryOp = spv::OpDPdx;
@@ -4485,7 +4541,45 @@
         operands.push_back(operand);
         return createInvocationsOperation(op, typeId, operands, typeProxy);
     }
-
+    case glslang::EOpSubgroupAll:
+    case glslang::EOpSubgroupAny:
+    case glslang::EOpSubgroupAllEqual:
+    case glslang::EOpSubgroupBroadcastFirst:
+    case glslang::EOpSubgroupBallot:
+    case glslang::EOpSubgroupInverseBallot:
+    case glslang::EOpSubgroupBallotBitCount:
+    case glslang::EOpSubgroupBallotInclusiveBitCount:
+    case glslang::EOpSubgroupBallotExclusiveBitCount:
+    case glslang::EOpSubgroupBallotFindLSB:
+    case glslang::EOpSubgroupBallotFindMSB:
+    case glslang::EOpSubgroupAdd:
+    case glslang::EOpSubgroupMul:
+    case glslang::EOpSubgroupMin:
+    case glslang::EOpSubgroupMax:
+    case glslang::EOpSubgroupAnd:
+    case glslang::EOpSubgroupOr:
+    case glslang::EOpSubgroupXor:
+    case glslang::EOpSubgroupInclusiveAdd:
+    case glslang::EOpSubgroupInclusiveMul:
+    case glslang::EOpSubgroupInclusiveMin:
+    case glslang::EOpSubgroupInclusiveMax:
+    case glslang::EOpSubgroupInclusiveAnd:
+    case glslang::EOpSubgroupInclusiveOr:
+    case glslang::EOpSubgroupInclusiveXor:
+    case glslang::EOpSubgroupExclusiveAdd:
+    case glslang::EOpSubgroupExclusiveMul:
+    case glslang::EOpSubgroupExclusiveMin:
+    case glslang::EOpSubgroupExclusiveMax:
+    case glslang::EOpSubgroupExclusiveAnd:
+    case glslang::EOpSubgroupExclusiveOr:
+    case glslang::EOpSubgroupExclusiveXor:
+    case glslang::EOpSubgroupQuadSwapHorizontal:
+    case glslang::EOpSubgroupQuadSwapVertical:
+    case glslang::EOpSubgroupQuadSwapDiagonal: {
+        std::vector<spv::Id> operands;
+        operands.push_back(operand);
+        return createSubgroupOperation(op, typeId, operands, typeProxy);
+    }
 #ifdef AMD_EXTENSIONS
     case glslang::EOpMbcnt:
         extBuiltins = getExtBuiltins(spv::E_SPV_AMD_shader_ballot);
@@ -4551,32 +4645,150 @@
     return builder.setPrecision(builder.createCompositeConstruct(typeId, results), precision);
 }
 
+spv::Id TGlslangToSpvTraverser::createConversionOperation(glslang::TOperator op, spv::Id operand, int vectorSize)
+{
+    spv::Op convOp = spv::OpNop;
+    spv::Id type = 0;
+
+    spv::Id result = 0;
+
+    switch(op) {
+    case glslang::EOpConvInt8ToUint16:
+        convOp = spv::OpSConvert;
+        type   = builder.makeIntType(16);
+        break;
+    case glslang::EOpConvInt8ToUint:
+        convOp = spv::OpSConvert;
+        type   = builder.makeIntType(32);
+        break;
+    case glslang::EOpConvInt8ToUint64:
+        convOp = spv::OpSConvert;
+        type   = builder.makeIntType(64);
+        break;
+    case glslang::EOpConvInt16ToUint8:
+        convOp = spv::OpSConvert;
+        type   = builder.makeIntType(8);
+        break;
+    case glslang::EOpConvInt16ToUint:
+        convOp = spv::OpSConvert;
+        type   = builder.makeIntType(32);
+        break;
+    case glslang::EOpConvInt16ToUint64:
+        convOp = spv::OpSConvert;
+        type   = builder.makeIntType(64);
+        break;
+    case glslang::EOpConvIntToUint8:
+        convOp = spv::OpSConvert;
+        type   = builder.makeIntType(8);
+        break;
+    case glslang::EOpConvIntToUint16:
+        convOp = spv::OpSConvert;
+        type   = builder.makeIntType(16);
+        break;
+    case glslang::EOpConvIntToUint64:
+        convOp = spv::OpSConvert;
+        type   = builder.makeIntType(64);
+        break;
+    case glslang::EOpConvInt64ToUint8:
+        convOp = spv::OpSConvert;
+        type   = builder.makeIntType(8);
+        break;
+    case glslang::EOpConvInt64ToUint16:
+        convOp = spv::OpSConvert;
+        type   = builder.makeIntType(16);
+        break;
+    case glslang::EOpConvInt64ToUint:
+        convOp = spv::OpSConvert;
+        type   = builder.makeIntType(32);
+        break;
+    case glslang::EOpConvUint8ToInt16:
+        convOp = spv::OpUConvert;
+        type   = builder.makeIntType(16);
+        break;
+    case glslang::EOpConvUint8ToInt:
+        convOp = spv::OpUConvert;
+        type   = builder.makeIntType(32);
+        break;
+    case glslang::EOpConvUint8ToInt64:
+        convOp = spv::OpUConvert;
+        type   = builder.makeIntType(64);
+        break;
+    case glslang::EOpConvUint16ToInt8:
+        convOp = spv::OpUConvert;
+        type   = builder.makeIntType(8);
+        break;
+    case glslang::EOpConvUint16ToInt:
+        convOp = spv::OpUConvert;
+        type   = builder.makeIntType(32);
+        break;
+    case glslang::EOpConvUint16ToInt64:
+        convOp = spv::OpUConvert;
+        type   = builder.makeIntType(64);
+        break;
+    case glslang::EOpConvUintToInt8:
+        convOp = spv::OpUConvert;
+        type   = builder.makeIntType(8);
+        break;
+    case glslang::EOpConvUintToInt16:
+        convOp = spv::OpUConvert;
+        type   = builder.makeIntType(16);
+        break;
+    case glslang::EOpConvUintToInt64:
+        convOp = spv::OpUConvert;
+        type   = builder.makeIntType(64);
+        break;
+    case glslang::EOpConvUint64ToInt8:
+        convOp = spv::OpUConvert;
+        type   = builder.makeIntType(8);
+        break;
+    case glslang::EOpConvUint64ToInt16:
+        convOp = spv::OpUConvert;
+        type   = builder.makeIntType(16);
+        break;
+    case glslang::EOpConvUint64ToInt:
+        convOp = spv::OpUConvert;
+        type   = builder.makeIntType(32);
+        break;
+
+    default:
+        assert(false && "Default missing");
+        break;
+    }
+
+    if (vectorSize > 0)
+        type = builder.makeVectorType(type, vectorSize);
+
+    result = builder.createUnaryOp(convOp, type, operand);
+    return result;
+}
+
 spv::Id TGlslangToSpvTraverser::createConversion(glslang::TOperator op, spv::Decoration precision, spv::Decoration noContraction, spv::Id destType, spv::Id operand, glslang::TBasicType typeProxy)
 {
     spv::Op convOp = spv::OpNop;
     spv::Id zero = 0;
     spv::Id one = 0;
-    spv::Id type = 0;
 
     int vectorSize = builder.isVectorType(destType) ? builder.getNumTypeComponents(destType) : 0;
 
     switch (op) {
-    case glslang::EOpConvIntToBool:
-    case glslang::EOpConvUintToBool:
-    case glslang::EOpConvInt64ToBool:
-    case glslang::EOpConvUint64ToBool:
-#ifdef AMD_EXTENSIONS
+    case glslang::EOpConvInt8ToBool:
+    case glslang::EOpConvUint8ToBool:
+        zero = builder.makeUint8Constant(0);
+        zero = makeSmearedConstant(zero, vectorSize);
+        return builder.createBinOp(spv::OpINotEqual, destType, operand, zero);
     case glslang::EOpConvInt16ToBool:
     case glslang::EOpConvUint16ToBool:
-#endif
-        if (op == glslang::EOpConvInt64ToBool || op == glslang::EOpConvUint64ToBool)
-            zero = builder.makeUint64Constant(0);
-#ifdef AMD_EXTENSIONS
-        else if (op == glslang::EOpConvInt16ToBool || op == glslang::EOpConvUint16ToBool)
-            zero = builder.makeUint16Constant(0);
-#endif
-        else
-            zero = builder.makeUintConstant(0);
+        zero = builder.makeUint16Constant(0);
+        zero = makeSmearedConstant(zero, vectorSize);
+        return builder.createBinOp(spv::OpINotEqual, destType, operand, zero);
+    case glslang::EOpConvIntToBool:
+    case glslang::EOpConvUintToBool:
+        zero = builder.makeUintConstant(0);
+        zero = makeSmearedConstant(zero, vectorSize);
+        return builder.createBinOp(spv::OpINotEqual, destType, operand, zero);
+    case glslang::EOpConvInt64ToBool:
+    case glslang::EOpConvUint64ToBool:
+        zero = builder.makeUint64Constant(0);
         zero = makeSmearedConstant(zero, vectorSize);
         return builder.createBinOp(spv::OpINotEqual, destType, operand, zero);
 
@@ -4590,12 +4802,10 @@
         zero = makeSmearedConstant(zero, vectorSize);
         return builder.createBinOp(spv::OpFOrdNotEqual, destType, operand, zero);
 
-#ifdef AMD_EXTENSIONS
     case glslang::EOpConvFloat16ToBool:
         zero = builder.makeFloat16Constant(0.0F);
         zero = makeSmearedConstant(zero, vectorSize);
         return builder.createBinOp(spv::OpFOrdNotEqual, destType, operand, zero);
-#endif
 
     case glslang::EOpConvBoolToFloat:
         convOp = spv::OpSelect;
@@ -4609,34 +4819,45 @@
         one  = builder.makeDoubleConstant(1.0);
         break;
 
-#ifdef AMD_EXTENSIONS
     case glslang::EOpConvBoolToFloat16:
         convOp = spv::OpSelect;
         zero = builder.makeFloat16Constant(0.0F);
         one = builder.makeFloat16Constant(1.0F);
         break;
-#endif
+
+    case glslang::EOpConvBoolToInt8:
+        zero = builder.makeInt8Constant(0);
+        one  = builder.makeInt8Constant(1);
+        convOp = spv::OpSelect;
+        break;
+
+    case glslang::EOpConvBoolToUint8:
+        zero = builder.makeUint8Constant(0);
+        one  = builder.makeUint8Constant(1);
+        convOp = spv::OpSelect;
+        break;
+
+    case glslang::EOpConvBoolToInt16:
+        zero = builder.makeInt16Constant(0);
+        one  = builder.makeInt16Constant(1);
+        convOp = spv::OpSelect;
+        break;
+
+    case glslang::EOpConvBoolToUint16:
+        zero = builder.makeUint16Constant(0);
+        one  = builder.makeUint16Constant(1);
+        convOp = spv::OpSelect;
+        break;
 
     case glslang::EOpConvBoolToInt:
     case glslang::EOpConvBoolToInt64:
-#ifdef AMD_EXTENSIONS
-    case glslang::EOpConvBoolToInt16:
-#endif
         if (op == glslang::EOpConvBoolToInt64)
             zero = builder.makeInt64Constant(0);
-#ifdef AMD_EXTENSIONS
-        else if (op == glslang::EOpConvBoolToInt16)
-            zero = builder.makeInt16Constant(0);
-#endif
         else
             zero = builder.makeIntConstant(0);
 
         if (op == glslang::EOpConvBoolToInt64)
             one = builder.makeInt64Constant(1);
-#ifdef AMD_EXTENSIONS
-        else if (op == glslang::EOpConvBoolToInt16)
-            one = builder.makeInt16Constant(1);
-#endif
         else
             one = builder.makeIntConstant(1);
 
@@ -4645,104 +4866,94 @@
 
     case glslang::EOpConvBoolToUint:
     case glslang::EOpConvBoolToUint64:
-#ifdef AMD_EXTENSIONS
-    case glslang::EOpConvBoolToUint16:
-#endif
         if (op == glslang::EOpConvBoolToUint64)
             zero = builder.makeUint64Constant(0);
-#ifdef AMD_EXTENSIONS
-        else if (op == glslang::EOpConvBoolToUint16)
-            zero = builder.makeUint16Constant(0);
-#endif
         else
             zero = builder.makeUintConstant(0);
 
         if (op == glslang::EOpConvBoolToUint64)
             one = builder.makeUint64Constant(1);
-#ifdef AMD_EXTENSIONS
-        else if (op == glslang::EOpConvBoolToUint16)
-            one = builder.makeUint16Constant(1);
-#endif
         else
             one = builder.makeUintConstant(1);
 
         convOp = spv::OpSelect;
         break;
 
+    case glslang::EOpConvInt8ToFloat16:
+    case glslang::EOpConvInt8ToFloat:
+    case glslang::EOpConvInt8ToDouble:
+    case glslang::EOpConvInt16ToFloat16:
+    case glslang::EOpConvInt16ToFloat:
+    case glslang::EOpConvInt16ToDouble:
+    case glslang::EOpConvIntToFloat16:
     case glslang::EOpConvIntToFloat:
     case glslang::EOpConvIntToDouble:
     case glslang::EOpConvInt64ToFloat:
     case glslang::EOpConvInt64ToDouble:
-#ifdef AMD_EXTENSIONS
-    case glslang::EOpConvInt16ToFloat:
-    case glslang::EOpConvInt16ToDouble:
-    case glslang::EOpConvInt16ToFloat16:
-    case glslang::EOpConvIntToFloat16:
     case glslang::EOpConvInt64ToFloat16:
-#endif
         convOp = spv::OpConvertSToF;
         break;
 
+    case glslang::EOpConvUint8ToFloat16:
+    case glslang::EOpConvUint8ToFloat:
+    case glslang::EOpConvUint8ToDouble:
+    case glslang::EOpConvUint16ToFloat16:
+    case glslang::EOpConvUint16ToFloat:
+    case glslang::EOpConvUint16ToDouble:
+    case glslang::EOpConvUintToFloat16:
     case glslang::EOpConvUintToFloat:
     case glslang::EOpConvUintToDouble:
     case glslang::EOpConvUint64ToFloat:
     case glslang::EOpConvUint64ToDouble:
-#ifdef AMD_EXTENSIONS
-    case glslang::EOpConvUint16ToFloat:
-    case glslang::EOpConvUint16ToDouble:
-    case glslang::EOpConvUint16ToFloat16:
-    case glslang::EOpConvUintToFloat16:
     case glslang::EOpConvUint64ToFloat16:
-#endif
         convOp = spv::OpConvertUToF;
         break;
 
     case glslang::EOpConvDoubleToFloat:
     case glslang::EOpConvFloatToDouble:
-#ifdef AMD_EXTENSIONS
     case glslang::EOpConvDoubleToFloat16:
     case glslang::EOpConvFloat16ToDouble:
     case glslang::EOpConvFloatToFloat16:
     case glslang::EOpConvFloat16ToFloat:
-#endif
         convOp = spv::OpFConvert;
         if (builder.isMatrixType(destType))
             return createUnaryMatrixOperation(convOp, precision, noContraction, destType, operand, typeProxy);
         break;
 
-    case glslang::EOpConvFloatToInt:
-    case glslang::EOpConvDoubleToInt:
-    case glslang::EOpConvFloatToInt64:
-    case glslang::EOpConvDoubleToInt64:
-#ifdef AMD_EXTENSIONS
+    case glslang::EOpConvFloat16ToInt8:
+    case glslang::EOpConvFloatToInt8:
+    case glslang::EOpConvDoubleToInt8:
+    case glslang::EOpConvFloat16ToInt16:
     case glslang::EOpConvFloatToInt16:
     case glslang::EOpConvDoubleToInt16:
-    case glslang::EOpConvFloat16ToInt16:
     case glslang::EOpConvFloat16ToInt:
+    case glslang::EOpConvFloatToInt:
+    case glslang::EOpConvDoubleToInt:
     case glslang::EOpConvFloat16ToInt64:
-#endif
+    case glslang::EOpConvFloatToInt64:
+    case glslang::EOpConvDoubleToInt64:
         convOp = spv::OpConvertFToS;
         break;
 
+    case glslang::EOpConvUint8ToInt8:
+    case glslang::EOpConvInt8ToUint8:
+    case glslang::EOpConvUint16ToInt16:
+    case glslang::EOpConvInt16ToUint16:
     case glslang::EOpConvUintToInt:
     case glslang::EOpConvIntToUint:
     case glslang::EOpConvUint64ToInt64:
     case glslang::EOpConvInt64ToUint64:
-#ifdef AMD_EXTENSIONS
-    case glslang::EOpConvUint16ToInt16:
-    case glslang::EOpConvInt16ToUint16:
-#endif
         if (builder.isInSpecConstCodeGenMode()) {
             // Build zero scalar or vector for OpIAdd.
-            if (op == glslang::EOpConvUint64ToInt64 || op == glslang::EOpConvInt64ToUint64)
-                zero = builder.makeUint64Constant(0);
-#ifdef AMD_EXTENSIONS
-            else if (op == glslang::EOpConvUint16ToInt16 || op == glslang::EOpConvInt16ToUint16)
+            if(op == glslang::EOpConvUint8ToInt8 || op == glslang::EOpConvInt8ToUint8) {
+                zero = builder.makeUint8Constant(0);
+            } else if (op == glslang::EOpConvUint16ToInt16 || op == glslang::EOpConvInt16ToUint16) {
                 zero = builder.makeUint16Constant(0);
-#endif
-            else
+            } else if (op == glslang::EOpConvUint64ToInt64 || op == glslang::EOpConvInt64ToUint64) {
+                zero = builder.makeUint64Constant(0);
+            } else {
                 zero = builder.makeUintConstant(0);
-
+            }
             zero = makeSmearedConstant(zero, vectorSize);
             // Use OpIAdd, instead of OpBitcast to do the conversion when
             // generating for OpSpecConstantOp instruction.
@@ -4752,126 +4963,117 @@
         convOp = spv::OpBitcast;
         break;
 
+    case glslang::EOpConvFloat16ToUint8:
+    case glslang::EOpConvFloatToUint8:
+    case glslang::EOpConvDoubleToUint8:
+    case glslang::EOpConvFloat16ToUint16:
+    case glslang::EOpConvFloatToUint16:
+    case glslang::EOpConvDoubleToUint16:
+    case glslang::EOpConvFloat16ToUint:
     case glslang::EOpConvFloatToUint:
     case glslang::EOpConvDoubleToUint:
     case glslang::EOpConvFloatToUint64:
     case glslang::EOpConvDoubleToUint64:
-#ifdef AMD_EXTENSIONS
-    case glslang::EOpConvFloatToUint16:
-    case glslang::EOpConvDoubleToUint16:
-    case glslang::EOpConvFloat16ToUint16:
-    case glslang::EOpConvFloat16ToUint:
     case glslang::EOpConvFloat16ToUint64:
-#endif
         convOp = spv::OpConvertFToU;
         break;
 
-    case glslang::EOpConvIntToInt64:
-    case glslang::EOpConvInt64ToInt:
-#ifdef AMD_EXTENSIONS
-    case glslang::EOpConvIntToInt16:
+    case glslang::EOpConvInt8ToInt16:
+    case glslang::EOpConvInt8ToInt:
+    case glslang::EOpConvInt8ToInt64:
+    case glslang::EOpConvInt16ToInt8:
     case glslang::EOpConvInt16ToInt:
-    case glslang::EOpConvInt64ToInt16:
     case glslang::EOpConvInt16ToInt64:
-#endif
+    case glslang::EOpConvIntToInt8:
+    case glslang::EOpConvIntToInt16:
+    case glslang::EOpConvIntToInt64:
+    case glslang::EOpConvInt64ToInt8:
+    case glslang::EOpConvInt64ToInt16:
+    case glslang::EOpConvInt64ToInt:
         convOp = spv::OpSConvert;
         break;
 
-    case glslang::EOpConvUintToUint64:
-    case glslang::EOpConvUint64ToUint:
-#ifdef AMD_EXTENSIONS
-    case glslang::EOpConvUintToUint16:
+    case glslang::EOpConvUint8ToUint16:
+    case glslang::EOpConvUint8ToUint:
+    case glslang::EOpConvUint8ToUint64:
+    case glslang::EOpConvUint16ToUint8:
     case glslang::EOpConvUint16ToUint:
-    case glslang::EOpConvUint64ToUint16:
     case glslang::EOpConvUint16ToUint64:
-#endif
+    case glslang::EOpConvUintToUint8:
+    case glslang::EOpConvUintToUint16:
+    case glslang::EOpConvUintToUint64:
+    case glslang::EOpConvUint64ToUint8:
+    case glslang::EOpConvUint64ToUint16:
+    case glslang::EOpConvUint64ToUint:
         convOp = spv::OpUConvert;
         break;
 
-    case glslang::EOpConvIntToUint64:
-    case glslang::EOpConvInt64ToUint:
-    case glslang::EOpConvUint64ToInt:
-    case glslang::EOpConvUintToInt64:
-#ifdef AMD_EXTENSIONS
+    case glslang::EOpConvInt8ToUint16:
+    case glslang::EOpConvInt8ToUint:
+    case glslang::EOpConvInt8ToUint64:
+    case glslang::EOpConvInt16ToUint8:
     case glslang::EOpConvInt16ToUint:
-    case glslang::EOpConvUintToInt16:
     case glslang::EOpConvInt16ToUint64:
-    case glslang::EOpConvUint64ToInt16:
-    case glslang::EOpConvUint16ToInt:
+    case glslang::EOpConvIntToUint8:
     case glslang::EOpConvIntToUint16:
-    case glslang::EOpConvUint16ToInt64:
+    case glslang::EOpConvIntToUint64:
+    case glslang::EOpConvInt64ToUint8:
     case glslang::EOpConvInt64ToUint16:
-#endif
+    case glslang::EOpConvInt64ToUint:
+    case glslang::EOpConvUint8ToInt16:
+    case glslang::EOpConvUint8ToInt:
+    case glslang::EOpConvUint8ToInt64:
+    case glslang::EOpConvUint16ToInt8:
+    case glslang::EOpConvUint16ToInt:
+    case glslang::EOpConvUint16ToInt64:
+    case glslang::EOpConvUintToInt8:
+    case glslang::EOpConvUintToInt16:
+    case glslang::EOpConvUintToInt64:
+    case glslang::EOpConvUint64ToInt8:
+    case glslang::EOpConvUint64ToInt16:
+    case glslang::EOpConvUint64ToInt:
         // OpSConvert/OpUConvert + OpBitCast
-        switch (op) {
-        case glslang::EOpConvIntToUint64:
-#ifdef AMD_EXTENSIONS
-        case glslang::EOpConvInt16ToUint64:
-#endif
-            convOp = spv::OpSConvert;
-            type   = builder.makeIntType(64);
-            break;
-        case glslang::EOpConvInt64ToUint:
-#ifdef AMD_EXTENSIONS
-        case glslang::EOpConvInt16ToUint:
-#endif
-            convOp = spv::OpSConvert;
-            type   = builder.makeIntType(32);
-            break;
-        case glslang::EOpConvUint64ToInt:
-#ifdef AMD_EXTENSIONS
-        case glslang::EOpConvUint16ToInt:
-#endif
-            convOp = spv::OpUConvert;
-            type   = builder.makeUintType(32);
-            break;
-        case glslang::EOpConvUintToInt64:
-#ifdef AMD_EXTENSIONS
-        case glslang::EOpConvUint16ToInt64:
-#endif
-            convOp = spv::OpUConvert;
-            type   = builder.makeUintType(64);
-            break;
-#ifdef AMD_EXTENSIONS
-        case glslang::EOpConvUintToInt16:
-        case glslang::EOpConvUint64ToInt16:
-            convOp = spv::OpUConvert;
-            type   = builder.makeUintType(16);
-            break;
-        case glslang::EOpConvIntToUint16:
-        case glslang::EOpConvInt64ToUint16:
-            convOp = spv::OpSConvert;
-            type   = builder.makeIntType(16);
-            break;
-#endif
-        default:
-            assert(0);
-            break;
-        }
-
-        if (vectorSize > 0)
-            type = builder.makeVectorType(type, vectorSize);
-
-        operand = builder.createUnaryOp(convOp, type, operand);
+        operand = createConversionOperation(op, operand, vectorSize);
 
         if (builder.isInSpecConstCodeGenMode()) {
             // Build zero scalar or vector for OpIAdd.
-#ifdef AMD_EXTENSIONS
-            if (op == glslang::EOpConvIntToUint64 || op == glslang::EOpConvUintToInt64 ||
-                op == glslang::EOpConvInt16ToUint64 || op == glslang::EOpConvUint16ToInt64)
-                zero = builder.makeUint64Constant(0);
-            else if (op == glslang::EOpConvIntToUint16 || op == glslang::EOpConvUintToInt16 ||
-                     op == glslang::EOpConvInt64ToUint16 || op == glslang::EOpConvUint64ToInt16)
+            switch(op) {
+            case glslang::EOpConvInt16ToUint8:
+            case glslang::EOpConvIntToUint8:
+            case glslang::EOpConvInt64ToUint8:
+            case glslang::EOpConvUint16ToInt8:
+            case glslang::EOpConvUintToInt8:
+            case glslang::EOpConvUint64ToInt8:
+                zero = builder.makeUint8Constant(0);
+                break;
+            case glslang::EOpConvInt8ToUint16:
+            case glslang::EOpConvIntToUint16:
+            case glslang::EOpConvInt64ToUint16:
+            case glslang::EOpConvUint8ToInt16:
+            case glslang::EOpConvUintToInt16:
+            case glslang::EOpConvUint64ToInt16:
                 zero = builder.makeUint16Constant(0);
-            else
+                break;
+            case glslang::EOpConvInt8ToUint:
+            case glslang::EOpConvInt16ToUint:
+            case glslang::EOpConvInt64ToUint:
+            case glslang::EOpConvUint8ToInt:
+            case glslang::EOpConvUint16ToInt:
+            case glslang::EOpConvUint64ToInt:
                 zero = builder.makeUintConstant(0);
-#else
-            if (op == glslang::EOpConvIntToUint64 || op == glslang::EOpConvUintToInt64)
+                break;
+            case glslang::EOpConvInt8ToUint64:
+            case glslang::EOpConvInt16ToUint64:
+            case glslang::EOpConvIntToUint64:
+            case glslang::EOpConvUint8ToInt64:
+            case glslang::EOpConvUint16ToInt64:
+            case glslang::EOpConvUintToInt64:
                 zero = builder.makeUint64Constant(0);
-            else
-                zero = builder.makeUintConstant(0);
-#endif
-
+                break;
+            default:
+                assert(false && "Default missing");
+                break;
+            }
             zero = makeSmearedConstant(zero, vectorSize);
             // Use OpIAdd, instead of OpBitcast to do the conversion when
             // generating for OpSpecConstantOp instruction.
@@ -5013,10 +5215,8 @@
 // Create group invocation operations.
 spv::Id TGlslangToSpvTraverser::createInvocationsOperation(glslang::TOperator op, spv::Id typeId, std::vector<spv::Id>& operands, glslang::TBasicType typeProxy)
 {
-#ifdef AMD_EXTENSIONS
-    bool isUnsigned = typeProxy == glslang::EbtUint || typeProxy == glslang::EbtUint64;
-    bool isFloat = typeProxy == glslang::EbtFloat || typeProxy == glslang::EbtDouble || typeProxy == glslang::EbtFloat16;
-#endif
+    bool isUnsigned = isTypeUnsignedInt(typeProxy);
+    bool isFloat = isTypeFloat(typeProxy);
 
     spv::Op opCode = spv::OpNop;
     std::vector<spv::Id> spvGroupOperands;
@@ -5277,15 +5477,263 @@
     return builder.createCompositeConstruct(typeId, results);
 }
 
+// Create subgroup invocation operations.
+spv::Id TGlslangToSpvTraverser::createSubgroupOperation(glslang::TOperator op, spv::Id typeId, std::vector<spv::Id>& operands, glslang::TBasicType typeProxy)
+{
+    // Add the required capabilities.
+    switch (op) {
+    case glslang::EOpSubgroupElect:
+        builder.addCapability(spv::CapabilityGroupNonUniform);
+        break;
+    case glslang::EOpSubgroupAll:
+    case glslang::EOpSubgroupAny:
+    case glslang::EOpSubgroupAllEqual:
+        builder.addCapability(spv::CapabilityGroupNonUniform);
+        builder.addCapability(spv::CapabilityGroupNonUniformVote);
+        break;
+    case glslang::EOpSubgroupBroadcast:
+    case glslang::EOpSubgroupBroadcastFirst:
+    case glslang::EOpSubgroupBallot:
+    case glslang::EOpSubgroupInverseBallot:
+    case glslang::EOpSubgroupBallotBitExtract:
+    case glslang::EOpSubgroupBallotBitCount:
+    case glslang::EOpSubgroupBallotInclusiveBitCount:
+    case glslang::EOpSubgroupBallotExclusiveBitCount:
+    case glslang::EOpSubgroupBallotFindLSB:
+    case glslang::EOpSubgroupBallotFindMSB:
+        builder.addCapability(spv::CapabilityGroupNonUniform);
+        builder.addCapability(spv::CapabilityGroupNonUniformBallot);
+        break;
+    case glslang::EOpSubgroupShuffle:
+    case glslang::EOpSubgroupShuffleXor:
+        builder.addCapability(spv::CapabilityGroupNonUniform);
+        builder.addCapability(spv::CapabilityGroupNonUniformShuffle);
+        break;
+    case glslang::EOpSubgroupShuffleUp:
+    case glslang::EOpSubgroupShuffleDown:
+        builder.addCapability(spv::CapabilityGroupNonUniform);
+        builder.addCapability(spv::CapabilityGroupNonUniformShuffleRelative);
+        break;
+    case glslang::EOpSubgroupAdd:
+    case glslang::EOpSubgroupMul:
+    case glslang::EOpSubgroupMin:
+    case glslang::EOpSubgroupMax:
+    case glslang::EOpSubgroupAnd:
+    case glslang::EOpSubgroupOr:
+    case glslang::EOpSubgroupXor:
+    case glslang::EOpSubgroupInclusiveAdd:
+    case glslang::EOpSubgroupInclusiveMul:
+    case glslang::EOpSubgroupInclusiveMin:
+    case glslang::EOpSubgroupInclusiveMax:
+    case glslang::EOpSubgroupInclusiveAnd:
+    case glslang::EOpSubgroupInclusiveOr:
+    case glslang::EOpSubgroupInclusiveXor:
+    case glslang::EOpSubgroupExclusiveAdd:
+    case glslang::EOpSubgroupExclusiveMul:
+    case glslang::EOpSubgroupExclusiveMin:
+    case glslang::EOpSubgroupExclusiveMax:
+    case glslang::EOpSubgroupExclusiveAnd:
+    case glslang::EOpSubgroupExclusiveOr:
+    case glslang::EOpSubgroupExclusiveXor:
+        builder.addCapability(spv::CapabilityGroupNonUniform);
+        builder.addCapability(spv::CapabilityGroupNonUniformArithmetic);
+        break;
+    case glslang::EOpSubgroupClusteredAdd:
+    case glslang::EOpSubgroupClusteredMul:
+    case glslang::EOpSubgroupClusteredMin:
+    case glslang::EOpSubgroupClusteredMax:
+    case glslang::EOpSubgroupClusteredAnd:
+    case glslang::EOpSubgroupClusteredOr:
+    case glslang::EOpSubgroupClusteredXor:
+        builder.addCapability(spv::CapabilityGroupNonUniform);
+        builder.addCapability(spv::CapabilityGroupNonUniformClustered);
+        break;
+    case glslang::EOpSubgroupQuadBroadcast:
+    case glslang::EOpSubgroupQuadSwapHorizontal:
+    case glslang::EOpSubgroupQuadSwapVertical:
+    case glslang::EOpSubgroupQuadSwapDiagonal:
+        builder.addCapability(spv::CapabilityGroupNonUniform);
+        builder.addCapability(spv::CapabilityGroupNonUniformQuad);
+        break;
+    default: assert(0 && "Unhandled subgroup operation!");
+    }
+
+    const bool isUnsigned = typeProxy == glslang::EbtUint || typeProxy == glslang::EbtUint64;
+    const bool isFloat = typeProxy == glslang::EbtFloat || typeProxy == glslang::EbtDouble;
+    const bool isBool = typeProxy == glslang::EbtBool;
+
+    spv::Op opCode = spv::OpNop;
+
+    // Figure out which opcode to use.
+    switch (op) {
+    case glslang::EOpSubgroupElect:                   opCode = spv::OpGroupNonUniformElect; break;
+    case glslang::EOpSubgroupAll:                     opCode = spv::OpGroupNonUniformAll; break;
+    case glslang::EOpSubgroupAny:                     opCode = spv::OpGroupNonUniformAny; break;
+    case glslang::EOpSubgroupAllEqual:                opCode = spv::OpGroupNonUniformAllEqual; break;
+    case glslang::EOpSubgroupBroadcast:               opCode = spv::OpGroupNonUniformBroadcast; break;
+    case glslang::EOpSubgroupBroadcastFirst:          opCode = spv::OpGroupNonUniformBroadcastFirst; break;
+    case glslang::EOpSubgroupBallot:                  opCode = spv::OpGroupNonUniformBallot; break;
+    case glslang::EOpSubgroupInverseBallot:           opCode = spv::OpGroupNonUniformInverseBallot; break;
+    case glslang::EOpSubgroupBallotBitExtract:        opCode = spv::OpGroupNonUniformBallotBitExtract; break;
+    case glslang::EOpSubgroupBallotBitCount:
+    case glslang::EOpSubgroupBallotInclusiveBitCount:
+    case glslang::EOpSubgroupBallotExclusiveBitCount: opCode = spv::OpGroupNonUniformBallotBitCount; break;
+    case glslang::EOpSubgroupBallotFindLSB:           opCode = spv::OpGroupNonUniformBallotFindLSB; break;
+    case glslang::EOpSubgroupBallotFindMSB:           opCode = spv::OpGroupNonUniformBallotFindMSB; break;
+    case glslang::EOpSubgroupShuffle:                 opCode = spv::OpGroupNonUniformShuffle; break;
+    case glslang::EOpSubgroupShuffleXor:              opCode = spv::OpGroupNonUniformShuffleXor; break;
+    case glslang::EOpSubgroupShuffleUp:               opCode = spv::OpGroupNonUniformShuffleUp; break;
+    case glslang::EOpSubgroupShuffleDown:             opCode = spv::OpGroupNonUniformShuffleDown; break;
+    case glslang::EOpSubgroupAdd:
+    case glslang::EOpSubgroupInclusiveAdd:
+    case glslang::EOpSubgroupExclusiveAdd:
+    case glslang::EOpSubgroupClusteredAdd:
+        if (isFloat) {
+            opCode = spv::OpGroupNonUniformFAdd;
+        } else {
+            opCode = spv::OpGroupNonUniformIAdd;
+        }
+        break;
+    case glslang::EOpSubgroupMul:
+    case glslang::EOpSubgroupInclusiveMul:
+    case glslang::EOpSubgroupExclusiveMul:
+    case glslang::EOpSubgroupClusteredMul:
+        if (isFloat) {
+            opCode = spv::OpGroupNonUniformFMul;
+        } else {
+            opCode = spv::OpGroupNonUniformIMul;
+        }
+        break;
+    case glslang::EOpSubgroupMin:
+    case glslang::EOpSubgroupInclusiveMin:
+    case glslang::EOpSubgroupExclusiveMin:
+    case glslang::EOpSubgroupClusteredMin:
+        if (isFloat) {
+            opCode = spv::OpGroupNonUniformFMin;
+        } else if (isUnsigned) {
+            opCode = spv::OpGroupNonUniformUMin;
+        } else {
+            opCode = spv::OpGroupNonUniformSMin;
+        }
+        break;
+    case glslang::EOpSubgroupMax:
+    case glslang::EOpSubgroupInclusiveMax:
+    case glslang::EOpSubgroupExclusiveMax:
+    case glslang::EOpSubgroupClusteredMax:
+        if (isFloat) {
+            opCode = spv::OpGroupNonUniformFMax;
+        } else if (isUnsigned) {
+            opCode = spv::OpGroupNonUniformUMax;
+        } else {
+            opCode = spv::OpGroupNonUniformSMax;
+        }
+        break;
+    case glslang::EOpSubgroupAnd:
+    case glslang::EOpSubgroupInclusiveAnd:
+    case glslang::EOpSubgroupExclusiveAnd:
+    case glslang::EOpSubgroupClusteredAnd:
+        if (isBool) {
+            opCode = spv::OpGroupNonUniformLogicalAnd;
+        } else {
+            opCode = spv::OpGroupNonUniformBitwiseAnd;
+        }
+        break;
+    case glslang::EOpSubgroupOr:
+    case glslang::EOpSubgroupInclusiveOr:
+    case glslang::EOpSubgroupExclusiveOr:
+    case glslang::EOpSubgroupClusteredOr:
+        if (isBool) {
+            opCode = spv::OpGroupNonUniformLogicalOr;
+        } else {
+            opCode = spv::OpGroupNonUniformBitwiseOr;
+        }
+        break;
+    case glslang::EOpSubgroupXor:
+    case glslang::EOpSubgroupInclusiveXor:
+    case glslang::EOpSubgroupExclusiveXor:
+    case glslang::EOpSubgroupClusteredXor:
+        if (isBool) {
+            opCode = spv::OpGroupNonUniformLogicalXor;
+        } else {
+            opCode = spv::OpGroupNonUniformBitwiseXor;
+        }
+        break;
+    case glslang::EOpSubgroupQuadBroadcast:      opCode = spv::OpGroupNonUniformQuadBroadcast; break;
+    case glslang::EOpSubgroupQuadSwapHorizontal:
+    case glslang::EOpSubgroupQuadSwapVertical:
+    case glslang::EOpSubgroupQuadSwapDiagonal:   opCode = spv::OpGroupNonUniformQuadSwap; break;
+    default: assert(0 && "Unhandled subgroup operation!");
+    }
+
+    std::vector<spv::Id> spvGroupOperands;
+
+    // Every operation begins with the Execution Scope operand.
+    spvGroupOperands.push_back(builder.makeUintConstant(spv::ScopeSubgroup));
+
+    // Next, for all operations that use a Group Operation, push that as an operand.
+    switch (op) {
+    default: break;
+    case glslang::EOpSubgroupBallotBitCount:
+    case glslang::EOpSubgroupAdd:
+    case glslang::EOpSubgroupMul:
+    case glslang::EOpSubgroupMin:
+    case glslang::EOpSubgroupMax:
+    case glslang::EOpSubgroupAnd:
+    case glslang::EOpSubgroupOr:
+    case glslang::EOpSubgroupXor:
+        spvGroupOperands.push_back(spv::GroupOperationReduce);
+        break;
+    case glslang::EOpSubgroupBallotInclusiveBitCount:
+    case glslang::EOpSubgroupInclusiveAdd:
+    case glslang::EOpSubgroupInclusiveMul:
+    case glslang::EOpSubgroupInclusiveMin:
+    case glslang::EOpSubgroupInclusiveMax:
+    case glslang::EOpSubgroupInclusiveAnd:
+    case glslang::EOpSubgroupInclusiveOr:
+    case glslang::EOpSubgroupInclusiveXor:
+        spvGroupOperands.push_back(spv::GroupOperationInclusiveScan);
+        break;
+    case glslang::EOpSubgroupBallotExclusiveBitCount:
+    case glslang::EOpSubgroupExclusiveAdd:
+    case glslang::EOpSubgroupExclusiveMul:
+    case glslang::EOpSubgroupExclusiveMin:
+    case glslang::EOpSubgroupExclusiveMax:
+    case glslang::EOpSubgroupExclusiveAnd:
+    case glslang::EOpSubgroupExclusiveOr:
+    case glslang::EOpSubgroupExclusiveXor:
+        spvGroupOperands.push_back(spv::GroupOperationExclusiveScan);
+        break;
+    case glslang::EOpSubgroupClusteredAdd:
+    case glslang::EOpSubgroupClusteredMul:
+    case glslang::EOpSubgroupClusteredMin:
+    case glslang::EOpSubgroupClusteredMax:
+    case glslang::EOpSubgroupClusteredAnd:
+    case glslang::EOpSubgroupClusteredOr:
+    case glslang::EOpSubgroupClusteredXor:
+        spvGroupOperands.push_back(spv::GroupOperationClusteredReduce);
+        break;
+    }
+
+    // Push back the operands next.
+    for (auto opIt : operands) {
+        spvGroupOperands.push_back(opIt);
+    }
+
+    // Some opcodes have additional operands.
+    switch (op) {
+    default: break;
+    case glslang::EOpSubgroupQuadSwapHorizontal: spvGroupOperands.push_back(builder.makeUintConstant(0)); break;
+    case glslang::EOpSubgroupQuadSwapVertical:   spvGroupOperands.push_back(builder.makeUintConstant(1)); break;
+    case glslang::EOpSubgroupQuadSwapDiagonal:   spvGroupOperands.push_back(builder.makeUintConstant(2)); break;
+    }
+
+    return builder.createOp(opCode, typeId, spvGroupOperands);
+}
+
 spv::Id TGlslangToSpvTraverser::createMiscOperation(glslang::TOperator op, spv::Decoration precision, spv::Id typeId, std::vector<spv::Id>& operands, glslang::TBasicType typeProxy)
 {
-#ifdef AMD_EXTENSIONS
-    bool isUnsigned = typeProxy == glslang::EbtUint || typeProxy == glslang::EbtUint64 || typeProxy == glslang::EbtUint16;
-    bool isFloat = typeProxy == glslang::EbtFloat || typeProxy == glslang::EbtDouble || typeProxy == glslang::EbtFloat16;
-#else
-    bool isUnsigned = typeProxy == glslang::EbtUint || typeProxy == glslang::EbtUint64;
-    bool isFloat = typeProxy == glslang::EbtFloat || typeProxy == glslang::EbtDouble;
-#endif
+    bool isUnsigned = isTypeUnsignedInt(typeProxy);
+    bool isFloat = isTypeFloat(typeProxy);
 
     spv::Op opCode = spv::OpNop;
     int extBuiltins = -1;
@@ -5422,11 +5870,7 @@
             libCall = spv::GLSLstd450FrexpStruct;
             assert(builder.isPointerType(typeId1));
             typeId1 = builder.getContainedTypeId(typeId1);
-#ifdef AMD_EXTENSIONS
             int width = builder.getScalarTypeWidth(typeId1);
-#else
-            int width = 32;
-#endif
             if (builder.getNumComponents(operands[0]) == 1)
                 frexpIntType = builder.makeIntegerType(width, true);
             else
@@ -5442,6 +5886,22 @@
     case glslang::EOpReadInvocation:
         return createInvocationsOperation(op, typeId, operands, typeProxy);
 
+    case glslang::EOpSubgroupBroadcast:
+    case glslang::EOpSubgroupBallotBitExtract:
+    case glslang::EOpSubgroupShuffle:
+    case glslang::EOpSubgroupShuffleXor:
+    case glslang::EOpSubgroupShuffleUp:
+    case glslang::EOpSubgroupShuffleDown:
+    case glslang::EOpSubgroupClusteredAdd:
+    case glslang::EOpSubgroupClusteredMul:
+    case glslang::EOpSubgroupClusteredMin:
+    case glslang::EOpSubgroupClusteredMax:
+    case glslang::EOpSubgroupClusteredAnd:
+    case glslang::EOpSubgroupClusteredOr:
+    case glslang::EOpSubgroupClusteredXor:
+    case glslang::EOpSubgroupQuadBroadcast:
+        return createSubgroupOperation(op, typeId, operands, typeProxy);
+
 #ifdef AMD_EXTENSIONS
     case glslang::EOpSwizzleInvocations:
         extBuiltins = getExtBuiltins(spv::E_SPV_AMD_shader_ballot);
@@ -5634,6 +6094,30 @@
                                         spv::MemorySemanticsWorkgroupMemoryMask |
                                         spv::MemorySemanticsAcquireReleaseMask);
         return 0;
+    case glslang::EOpSubgroupBarrier:
+        builder.createControlBarrier(spv::ScopeSubgroup, spv::ScopeSubgroup, spv::MemorySemanticsAllMemory |
+                                                                             spv::MemorySemanticsAcquireReleaseMask);
+        return spv::NoResult;
+    case glslang::EOpSubgroupMemoryBarrier:
+        builder.createMemoryBarrier(spv::ScopeSubgroup, spv::MemorySemanticsAllMemory |
+                                                        spv::MemorySemanticsAcquireReleaseMask);
+        return spv::NoResult;
+    case glslang::EOpSubgroupMemoryBarrierBuffer:
+        builder.createMemoryBarrier(spv::ScopeSubgroup, spv::MemorySemanticsUniformMemoryMask |
+                                                        spv::MemorySemanticsAcquireReleaseMask);
+        return spv::NoResult;
+    case glslang::EOpSubgroupMemoryBarrierImage:
+        builder.createMemoryBarrier(spv::ScopeSubgroup, spv::MemorySemanticsImageMemoryMask |
+                                                        spv::MemorySemanticsAcquireReleaseMask);
+        return spv::NoResult;
+    case glslang::EOpSubgroupMemoryBarrierShared:
+        builder.createMemoryBarrier(spv::ScopeSubgroup, spv::MemorySemanticsWorkgroupMemoryMask |
+                                                        spv::MemorySemanticsAcquireReleaseMask);
+        return spv::NoResult;
+    case glslang::EOpSubgroupElect: {
+        std::vector<spv::Id> operands;
+        return createSubgroupOperation(op, typeId, operands, glslang::EbtVoid);
+    }
 #ifdef AMD_EXTENSIONS
     case glslang::EOpTime:
     {
@@ -5876,6 +6360,18 @@
         for (unsigned int i = 0; i < (unsigned int)glslangType.getVectorSize(); ++i) {
             bool zero = nextConst >= consts.size();
             switch (glslangType.getBasicType()) {
+            case glslang::EbtInt8:
+                spvConsts.push_back(builder.makeInt8Constant(zero ? 0 : consts[nextConst].getI8Const()));
+                break;
+            case glslang::EbtUint8:
+                spvConsts.push_back(builder.makeUint8Constant(zero ? 0 : consts[nextConst].getU8Const()));
+                break;
+            case glslang::EbtInt16:
+                spvConsts.push_back(builder.makeInt16Constant(zero ? 0 : consts[nextConst].getI16Const()));
+                break;
+            case glslang::EbtUint16:
+                spvConsts.push_back(builder.makeUint16Constant(zero ? 0 : consts[nextConst].getU16Const()));
+                break;
             case glslang::EbtInt:
                 spvConsts.push_back(builder.makeIntConstant(zero ? 0 : consts[nextConst].getIConst()));
                 break;
@@ -5888,25 +6384,15 @@
             case glslang::EbtUint64:
                 spvConsts.push_back(builder.makeUint64Constant(zero ? 0 : consts[nextConst].getU64Const()));
                 break;
-#ifdef AMD_EXTENSIONS
-            case glslang::EbtInt16:
-                spvConsts.push_back(builder.makeInt16Constant(zero ? 0 : (short)consts[nextConst].getIConst()));
-                break;
-            case glslang::EbtUint16:
-                spvConsts.push_back(builder.makeUint16Constant(zero ? 0 : (unsigned short)consts[nextConst].getUConst()));
-                break;
-#endif
             case glslang::EbtFloat:
                 spvConsts.push_back(builder.makeFloatConstant(zero ? 0.0F : (float)consts[nextConst].getDConst()));
                 break;
             case glslang::EbtDouble:
                 spvConsts.push_back(builder.makeDoubleConstant(zero ? 0.0 : consts[nextConst].getDConst()));
                 break;
-#ifdef AMD_EXTENSIONS
             case glslang::EbtFloat16:
                 spvConsts.push_back(builder.makeFloat16Constant(zero ? 0.0F : (float)consts[nextConst].getDConst()));
                 break;
-#endif
             case glslang::EbtBool:
                 spvConsts.push_back(builder.makeBoolConstant(zero ? false : consts[nextConst].getBConst()));
                 break;
@@ -5921,6 +6407,18 @@
         bool zero = nextConst >= consts.size();
         spv::Id scalar = 0;
         switch (glslangType.getBasicType()) {
+        case glslang::EbtInt8:
+            scalar = builder.makeInt8Constant(zero ? 0 : consts[nextConst].getI8Const(), specConstant);
+            break;
+        case glslang::EbtUint8:
+            scalar = builder.makeUint8Constant(zero ? 0 : consts[nextConst].getU8Const(), specConstant);
+            break;
+        case glslang::EbtInt16:
+            scalar = builder.makeInt16Constant(zero ? 0 : consts[nextConst].getI16Const(), specConstant);
+            break;
+        case glslang::EbtUint16:
+            scalar = builder.makeUint16Constant(zero ? 0 : consts[nextConst].getU16Const(), specConstant);
+            break;
         case glslang::EbtInt:
             scalar = builder.makeIntConstant(zero ? 0 : consts[nextConst].getIConst(), specConstant);
             break;
@@ -5933,25 +6431,15 @@
         case glslang::EbtUint64:
             scalar = builder.makeUint64Constant(zero ? 0 : consts[nextConst].getU64Const(), specConstant);
             break;
-#ifdef AMD_EXTENSIONS
-        case glslang::EbtInt16:
-            scalar = builder.makeInt16Constant(zero ? 0 : (short)consts[nextConst].getIConst(), specConstant);
-            break;
-        case glslang::EbtUint16:
-            scalar = builder.makeUint16Constant(zero ? 0 : (unsigned short)consts[nextConst].getUConst(), specConstant);
-            break;
-#endif
         case glslang::EbtFloat:
             scalar = builder.makeFloatConstant(zero ? 0.0F : (float)consts[nextConst].getDConst(), specConstant);
             break;
         case glslang::EbtDouble:
             scalar = builder.makeDoubleConstant(zero ? 0.0 : consts[nextConst].getDConst(), specConstant);
             break;
-#ifdef AMD_EXTENSIONS
         case glslang::EbtFloat16:
             scalar = builder.makeFloat16Constant(zero ? 0.0F : (float)consts[nextConst].getDConst(), specConstant);
             break;
-#endif
         case glslang::EbtBool:
             scalar = builder.makeBoolConstant(zero ? false : consts[nextConst].getBConst(), specConstant);
             break;