Add support for SPV_KHR_shader_clock
diff --git a/SPIRV/GLSL.ext.KHR.h b/SPIRV/GLSL.ext.KHR.h
index bcc6087..1140bef 100644
--- a/SPIRV/GLSL.ext.KHR.h
+++ b/SPIRV/GLSL.ext.KHR.h
@@ -42,5 +42,6 @@
 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";
+static const char* const E_SPV_KHR_shader_clock                 = "SPV_KHR_shader_clock";
 
 #endif  // #ifndef GLSLextKHR_H
diff --git a/SPIRV/GlslangToSpv.cpp b/SPIRV/GlslangToSpv.cpp
index 7b1393c..73a8f6a 100644
--- a/SPIRV/GlslangToSpv.cpp
+++ b/SPIRV/GlslangToSpv.cpp
@@ -7623,6 +7623,22 @@
         return id;
     }
 
+    case glslang::EOpReadClockSubgroupKHR: {
+        std::vector<spv::Id> args;
+        args.push_back(builder.makeUintConstant(spv::ScopeSubgroup));
+        builder.addExtension(spv::E_SPV_KHR_shader_clock);
+        builder.addCapability(spv::CapabilityShaderClockKHR);
+        return builder.createOp(spv::OpReadClockKHR, typeId, args);
+    }
+
+    case glslang::EOpReadClockDeviceKHR: {
+        std::vector<spv::Id> args;
+        args.push_back(builder.makeUintConstant(spv::ScopeDevice));
+        builder.addExtension(spv::E_SPV_KHR_shader_clock);
+        builder.addCapability(spv::CapabilityShaderClockKHR);
+        return builder.createOp(spv::OpReadClockKHR, typeId, args);
+    }
+
     default:
         logger->missingFunctionality("unknown operation with no arguments");
         return 0;
diff --git a/SPIRV/doc.cpp b/SPIRV/doc.cpp
index bd639ae..85a3a2e 100644
--- a/SPIRV/doc.cpp
+++ b/SPIRV/doc.cpp
@@ -959,6 +959,7 @@
     case CapabilityFragmentShaderShadingRateInterlockEXT:   return "CapabilityFragmentShaderShadingRateInterlockEXT";
 
     case CapabilityDemoteToHelperInvocationEXT:             return "DemoteToHelperInvocationEXT";
+    case CapabilityShaderClockKHR:                          return "ShaderClockKHR";
 
     default: return "Bad";
     }
@@ -1349,6 +1350,8 @@
     case 5012: return "OpFragmentFetchAMD";
 #endif
 
+    case OpReadClockKHR:               return "OpReadClockKHR";
+
     case OpDecorateStringGOOGLE:       return "OpDecorateStringGOOGLE";
     case OpMemberDecorateStringGOOGLE: return "OpMemberDecorateStringGOOGLE";
 
@@ -2790,6 +2793,8 @@
     InstructionDesc[OpCooperativeMatrixLengthNV].operands.push(OperandId, "'Type'");
 
     InstructionDesc[OpDemoteToHelperInvocationEXT].setResultAndType(false, false);
+
+    InstructionDesc[OpReadClockKHR].operands.push(OperandScope, "'Scope'");
 }
 
 }; // end spv namespace
diff --git a/SPIRV/spirv.hpp b/SPIRV/spirv.hpp
index a584aaf..16fb78c 100644
--- a/SPIRV/spirv.hpp
+++ b/SPIRV/spirv.hpp
@@ -809,6 +809,7 @@
     CapabilityFragmentMaskAMD = 5010,
     CapabilityStencilExportEXT = 5013,
     CapabilityImageReadWriteLodAMD = 5015,
+    CapabilityShaderClockKHR = 5055,
     CapabilitySampleMaskOverrideCoverageNV = 5249,
     CapabilityGeometryShaderPassthroughNV = 5251,
     CapabilityShaderViewportIndexLayerEXT = 5254,
@@ -1219,6 +1220,7 @@
     OpGroupSMaxNonUniformAMD = 5007,
     OpFragmentMaskFetchAMD = 5011,
     OpFragmentFetchAMD = 5012,
+    OpReadClockKHR = 5056,
     OpImageSampleFootprintNV = 5283,
     OpGroupNonUniformPartitionNV = 5296,
     OpWritePackedPrimitiveIndices4x8NV = 5299,
diff --git a/glslang/Include/intermediate.h b/glslang/Include/intermediate.h
index 903a75d..8b55b08 100644
--- a/glslang/Include/intermediate.h
+++ b/glslang/Include/intermediate.h
@@ -1002,6 +1002,10 @@
     EOpWaveGetLaneIndex,                 // Will decompose to gl_SubgroupInvocationID.
     EOpWaveActiveCountBits,              // Will decompose to subgroupBallotBitCount(subgroupBallot()).
     EOpWavePrefixCountBits,              // Will decompose to subgroupBallotInclusiveBitCount(subgroupBallot()).
+
+    // Shader Clock Ops
+    EOpReadClockSubgroupKHR,
+    EOpReadClockDeviceKHR,
 };
 
 class TIntermTraverser;
diff --git a/glslang/MachineIndependent/Initialize.cpp b/glslang/MachineIndependent/Initialize.cpp
index 35b1c74..fddb1d1 100644
--- a/glslang/MachineIndependent/Initialize.cpp
+++ b/glslang/MachineIndependent/Initialize.cpp
@@ -5090,6 +5090,16 @@
             "\n");
     }
 
+    // GL_ARB_shader_clock & GL_EXT_shader_realtime_clock
+    if (profile != EEsProfile && version >= 450) {
+        commonBuiltins.append(
+            "uvec2 clock2x32ARB();"
+            "uint64_t clockARB();"
+            "uvec2 clockRealtime2x32EXT();"
+            "uint64_t clockRealtimeEXT();"
+            "\n");
+    }
+
     // GL_AMD_shader_fragment_mask
     if (profile != EEsProfile && version >= 450 && spvVersion.vulkan > 0) {
         stageBuiltins[EShLangFragment].append(
@@ -8458,6 +8468,12 @@
 
         symbolTable.setVariableExtensions("gl_FragDepthEXT", 1, &E_GL_EXT_frag_depth);
 
+        symbolTable.setFunctionExtensions("clockARB",     1, &E_GL_ARB_shader_clock);
+        symbolTable.setFunctionExtensions("clock2x32ARB", 1, &E_GL_ARB_shader_clock);
+
+        symbolTable.setFunctionExtensions("clockRealtimeEXT",     1, &E_GL_EXT_shader_realtime_clock);
+        symbolTable.setFunctionExtensions("clockRealtime2x32EXT", 1, &E_GL_EXT_shader_realtime_clock);
+
         if (profile == EEsProfile && version < 320) {
             symbolTable.setVariableExtensions("gl_PrimitiveID",  Num_AEP_geometry_shader, AEP_geometry_shader);
             symbolTable.setVariableExtensions("gl_Layer",        Num_AEP_geometry_shader, AEP_geometry_shader);
@@ -9272,6 +9288,12 @@
     symbolTable.relateToOperator("atomicCounterDecrement", EOpAtomicCounterDecrement);
     symbolTable.relateToOperator("atomicCounter",          EOpAtomicCounter);
 
+    symbolTable.relateToOperator("clockARB",     EOpReadClockSubgroupKHR);
+    symbolTable.relateToOperator("clock2x32ARB", EOpReadClockSubgroupKHR);
+
+    symbolTable.relateToOperator("clockRealtimeEXT",     EOpReadClockDeviceKHR);
+    symbolTable.relateToOperator("clockRealtime2x32EXT", EOpReadClockDeviceKHR);
+
     if (profile != EEsProfile && version >= 460) {
         symbolTable.relateToOperator("atomicCounterAdd",      EOpAtomicCounterAdd);
         symbolTable.relateToOperator("atomicCounterSubtract", EOpAtomicCounterSubtract);
diff --git a/glslang/MachineIndependent/Versions.cpp b/glslang/MachineIndependent/Versions.cpp
index 253f6cd..e251918 100644
--- a/glslang/MachineIndependent/Versions.cpp
+++ b/glslang/MachineIndependent/Versions.cpp
@@ -188,6 +188,7 @@
     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_ARB_shader_clock]                 = EBhDisable;
 
     extensionBehavior[E_GL_KHR_shader_subgroup_basic]            = EBhDisable;
     extensionBehavior[E_GL_KHR_shader_subgroup_vote]             = EBhDisable;
@@ -285,6 +286,7 @@
     // EXT extensions
     extensionBehavior[E_GL_EXT_device_group]             = EBhDisable;
     extensionBehavior[E_GL_EXT_multiview]                = EBhDisable;
+    extensionBehavior[E_GL_EXT_shader_realtime_clock]    = EBhDisable;
 
     // OVR extensions
     extensionBehavior[E_GL_OVR_multiview]                = EBhDisable;
@@ -408,6 +410,7 @@
             "#define GL_KHR_shader_subgroup_quad 1\n"
 
             "#define E_GL_EXT_shader_atomic_int64 1\n"
+            "#define E_GL_EXT_shader_realtime_clock 1\n"
 
 #ifdef AMD_EXTENSIONS
             "#define GL_AMD_shader_ballot 1\n"
diff --git a/glslang/MachineIndependent/Versions.h b/glslang/MachineIndependent/Versions.h
index 02d2266..809ba74 100644
--- a/glslang/MachineIndependent/Versions.h
+++ b/glslang/MachineIndependent/Versions.h
@@ -142,6 +142,7 @@
 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_ARB_shader_clock                 = "GL_ARB_shader_clock";
 
 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";
@@ -174,6 +175,7 @@
 const char* const E_GL_EXT_buffer_reference                 = "GL_EXT_buffer_reference";
 const char* const E_GL_EXT_buffer_reference2                = "GL_EXT_buffer_reference2";
 const char* const E_GL_EXT_demote_to_helper_invocation      = "GL_EXT_demote_to_helper_invocation";
+const char* const E_GL_EXT_shader_realtime_clock            = "GL_EXT_shader_realtime_clock";
 
 // Arrays of extensions for the above viewportEXTs duplications