build: Update to header 1.4.312
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 82173ad..5a6b83f 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -18,7 +18,7 @@
 # ~~~
 cmake_minimum_required(VERSION 3.22.1)
 
-project(VULKAN_LOADER VERSION 1.4.311 LANGUAGES C)
+project(VULKAN_LOADER VERSION 1.4.312 LANGUAGES C)
 
 option(CODE_COVERAGE "Enable Code Coverage" OFF)
 if (CODE_COVERAGE)
diff --git a/loader/generated/vk_layer_dispatch_table.h b/loader/generated/vk_layer_dispatch_table.h
index 33e28e6..65dc7cf 100644
--- a/loader/generated/vk_layer_dispatch_table.h
+++ b/loader/generated/vk_layer_dispatch_table.h
@@ -988,6 +988,11 @@
     PFN_vkCmdCudaLaunchKernelNV CmdCudaLaunchKernelNV;
 #endif // VK_ENABLE_BETA_EXTENSIONS
 
+    // ---- VK_QCOM_tile_shading extension commands
+    PFN_vkCmdDispatchTileQCOM CmdDispatchTileQCOM;
+    PFN_vkCmdBeginPerTileExecutionQCOM CmdBeginPerTileExecutionQCOM;
+    PFN_vkCmdEndPerTileExecutionQCOM CmdEndPerTileExecutionQCOM;
+
     // ---- VK_EXT_metal_objects extension commands
 #if defined(VK_USE_PLATFORM_METAL_EXT)
     PFN_vkExportMetalObjectsEXT ExportMetalObjectsEXT;
@@ -1191,6 +1196,11 @@
     PFN_vkGetScreenBufferPropertiesQNX GetScreenBufferPropertiesQNX;
 #endif // VK_USE_PLATFORM_SCREEN_QNX
 
+    // ---- VK_NV_external_compute_queue extension commands
+    PFN_vkCreateExternalComputeQueueNV CreateExternalComputeQueueNV;
+    PFN_vkDestroyExternalComputeQueueNV DestroyExternalComputeQueueNV;
+    PFN_vkGetExternalComputeQueueDataNV GetExternalComputeQueueDataNV;
+
     // ---- VK_NV_cluster_acceleration_structure extension commands
     PFN_vkGetClusterAccelerationStructureBuildSizesNV GetClusterAccelerationStructureBuildSizesNV;
     PFN_vkCmdBuildClusterAccelerationStructureIndirectNV CmdBuildClusterAccelerationStructureIndirectNV;
diff --git a/loader/generated/vk_loader_extensions.c b/loader/generated/vk_loader_extensions.c
index dcdfa81..dcd4a4d 100644
--- a/loader/generated/vk_loader_extensions.c
+++ b/loader/generated/vk_loader_extensions.c
@@ -1026,6 +1026,11 @@
     table->CmdCudaLaunchKernelNV = (PFN_vkCmdCudaLaunchKernelNV)gdpa(dev, "vkCmdCudaLaunchKernelNV");
 #endif // VK_ENABLE_BETA_EXTENSIONS
 
+    // ---- VK_QCOM_tile_shading extension commands
+    table->CmdDispatchTileQCOM = (PFN_vkCmdDispatchTileQCOM)gdpa(dev, "vkCmdDispatchTileQCOM");
+    table->CmdBeginPerTileExecutionQCOM = (PFN_vkCmdBeginPerTileExecutionQCOM)gdpa(dev, "vkCmdBeginPerTileExecutionQCOM");
+    table->CmdEndPerTileExecutionQCOM = (PFN_vkCmdEndPerTileExecutionQCOM)gdpa(dev, "vkCmdEndPerTileExecutionQCOM");
+
     // ---- VK_EXT_metal_objects extension commands
 #if defined(VK_USE_PLATFORM_METAL_EXT)
     table->ExportMetalObjectsEXT = (PFN_vkExportMetalObjectsEXT)gdpa(dev, "vkExportMetalObjectsEXT");
@@ -1229,6 +1234,11 @@
     table->GetScreenBufferPropertiesQNX = (PFN_vkGetScreenBufferPropertiesQNX)gdpa(dev, "vkGetScreenBufferPropertiesQNX");
 #endif // VK_USE_PLATFORM_SCREEN_QNX
 
+    // ---- VK_NV_external_compute_queue extension commands
+    table->CreateExternalComputeQueueNV = (PFN_vkCreateExternalComputeQueueNV)gdpa(dev, "vkCreateExternalComputeQueueNV");
+    table->DestroyExternalComputeQueueNV = (PFN_vkDestroyExternalComputeQueueNV)gdpa(dev, "vkDestroyExternalComputeQueueNV");
+    table->GetExternalComputeQueueDataNV = (PFN_vkGetExternalComputeQueueDataNV)gdpa(dev, "vkGetExternalComputeQueueDataNV");
+
     // ---- VK_NV_cluster_acceleration_structure extension commands
     table->GetClusterAccelerationStructureBuildSizesNV = (PFN_vkGetClusterAccelerationStructureBuildSizesNV)gdpa(dev, "vkGetClusterAccelerationStructureBuildSizesNV");
     table->CmdBuildClusterAccelerationStructureIndirectNV = (PFN_vkCmdBuildClusterAccelerationStructureIndirectNV)gdpa(dev, "vkCmdBuildClusterAccelerationStructureIndirectNV");
@@ -2934,6 +2944,11 @@
     if (!strcmp(name, "CmdCudaLaunchKernelNV")) return (void *)table->CmdCudaLaunchKernelNV;
 #endif // VK_ENABLE_BETA_EXTENSIONS
 
+    // ---- VK_QCOM_tile_shading extension commands
+    if (!strcmp(name, "CmdDispatchTileQCOM")) return (void *)table->CmdDispatchTileQCOM;
+    if (!strcmp(name, "CmdBeginPerTileExecutionQCOM")) return (void *)table->CmdBeginPerTileExecutionQCOM;
+    if (!strcmp(name, "CmdEndPerTileExecutionQCOM")) return (void *)table->CmdEndPerTileExecutionQCOM;
+
     // ---- VK_EXT_metal_objects extension commands
 #if defined(VK_USE_PLATFORM_METAL_EXT)
     if (!strcmp(name, "ExportMetalObjectsEXT")) return (void *)table->ExportMetalObjectsEXT;
@@ -3137,6 +3152,11 @@
     if (!strcmp(name, "GetScreenBufferPropertiesQNX")) return (void *)table->GetScreenBufferPropertiesQNX;
 #endif // VK_USE_PLATFORM_SCREEN_QNX
 
+    // ---- VK_NV_external_compute_queue extension commands
+    if (!strcmp(name, "CreateExternalComputeQueueNV")) return (void *)table->CreateExternalComputeQueueNV;
+    if (!strcmp(name, "DestroyExternalComputeQueueNV")) return (void *)table->DestroyExternalComputeQueueNV;
+    if (!strcmp(name, "GetExternalComputeQueueDataNV")) return (void *)table->GetExternalComputeQueueDataNV;
+
     // ---- VK_NV_cluster_acceleration_structure extension commands
     if (!strcmp(name, "GetClusterAccelerationStructureBuildSizesNV")) return (void *)table->GetClusterAccelerationStructureBuildSizesNV;
     if (!strcmp(name, "CmdBuildClusterAccelerationStructureIndirectNV")) return (void *)table->CmdBuildClusterAccelerationStructureIndirectNV;
@@ -7951,6 +7971,47 @@
 
 #endif // VK_ENABLE_BETA_EXTENSIONS
 
+// ---- VK_QCOM_tile_shading extension trampoline/terminators
+
+VKAPI_ATTR void VKAPI_CALL CmdDispatchTileQCOM(
+    VkCommandBuffer                             commandBuffer) {
+    const VkLayerDispatchTable *disp = loader_get_dispatch(commandBuffer);
+    if (NULL == disp) {
+        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
+                   "vkCmdDispatchTileQCOM: Invalid commandBuffer "
+                   "[VUID-vkCmdDispatchTileQCOM-commandBuffer-parameter]");
+        abort(); /* Intentionally fail so user can correct issue. */
+    }
+    disp->CmdDispatchTileQCOM(commandBuffer);
+}
+
+VKAPI_ATTR void VKAPI_CALL CmdBeginPerTileExecutionQCOM(
+    VkCommandBuffer                             commandBuffer,
+    const VkPerTileBeginInfoQCOM*               pPerTileBeginInfo) {
+    const VkLayerDispatchTable *disp = loader_get_dispatch(commandBuffer);
+    if (NULL == disp) {
+        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
+                   "vkCmdBeginPerTileExecutionQCOM: Invalid commandBuffer "
+                   "[VUID-vkCmdBeginPerTileExecutionQCOM-commandBuffer-parameter]");
+        abort(); /* Intentionally fail so user can correct issue. */
+    }
+    disp->CmdBeginPerTileExecutionQCOM(commandBuffer, pPerTileBeginInfo);
+}
+
+VKAPI_ATTR void VKAPI_CALL CmdEndPerTileExecutionQCOM(
+    VkCommandBuffer                             commandBuffer,
+    const VkPerTileEndInfoQCOM*                 pPerTileEndInfo) {
+    const VkLayerDispatchTable *disp = loader_get_dispatch(commandBuffer);
+    if (NULL == disp) {
+        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
+                   "vkCmdEndPerTileExecutionQCOM: Invalid commandBuffer "
+                   "[VUID-vkCmdEndPerTileExecutionQCOM-commandBuffer-parameter]");
+        abort(); /* Intentionally fail so user can correct issue. */
+    }
+    disp->CmdEndPerTileExecutionQCOM(commandBuffer, pPerTileEndInfo);
+}
+
+
 // ---- VK_EXT_metal_objects extension trampoline/terminators
 
 #if defined(VK_USE_PLATFORM_METAL_EXT)
@@ -9841,6 +9902,52 @@
 
 #endif // VK_USE_PLATFORM_SCREEN_QNX
 
+// ---- VK_NV_external_compute_queue extension trampoline/terminators
+
+VKAPI_ATTR VkResult VKAPI_CALL CreateExternalComputeQueueNV(
+    VkDevice                                    device,
+    const VkExternalComputeQueueCreateInfoNV*   pCreateInfo,
+    const VkAllocationCallbacks*                pAllocator,
+    VkExternalComputeQueueNV*                   pExternalQueue) {
+    const VkLayerDispatchTable *disp = loader_get_dispatch(device);
+    if (NULL == disp) {
+        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
+                   "vkCreateExternalComputeQueueNV: Invalid device "
+                   "[VUID-vkCreateExternalComputeQueueNV-device-parameter]");
+        abort(); /* Intentionally fail so user can correct issue. */
+    }
+    return disp->CreateExternalComputeQueueNV(device, pCreateInfo, pAllocator, pExternalQueue);
+}
+
+VKAPI_ATTR void VKAPI_CALL DestroyExternalComputeQueueNV(
+    VkDevice                                    device,
+    VkExternalComputeQueueNV                    externalQueue,
+    const VkAllocationCallbacks*                pAllocator) {
+    const VkLayerDispatchTable *disp = loader_get_dispatch(device);
+    if (NULL == disp) {
+        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
+                   "vkDestroyExternalComputeQueueNV: Invalid device "
+                   "[VUID-vkDestroyExternalComputeQueueNV-device-parameter]");
+        abort(); /* Intentionally fail so user can correct issue. */
+    }
+    disp->DestroyExternalComputeQueueNV(device, externalQueue, pAllocator);
+}
+
+VKAPI_ATTR void VKAPI_CALL GetExternalComputeQueueDataNV(
+    VkExternalComputeQueueNV                    externalQueue,
+    VkExternalComputeQueueDataParamsNV*         params,
+    void*                                       pData) {
+    const VkLayerDispatchTable *disp = loader_get_dispatch(externalQueue);
+    if (NULL == disp) {
+        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
+                   "vkGetExternalComputeQueueDataNV: Invalid externalQueue "
+                   "[VUID-vkGetExternalComputeQueueDataNV-externalQueue-parameter]");
+        abort(); /* Intentionally fail so user can correct issue. */
+    }
+    disp->GetExternalComputeQueueDataNV(externalQueue, params, pData);
+}
+
+
 // ---- VK_NV_cluster_acceleration_structure extension trampoline/terminators
 
 VKAPI_ATTR void VKAPI_CALL GetClusterAccelerationStructureBuildSizesNV(
@@ -11918,6 +12025,20 @@
     }
 #endif // VK_ENABLE_BETA_EXTENSIONS
 
+    // ---- VK_QCOM_tile_shading extension commands
+    if (!strcmp("vkCmdDispatchTileQCOM", name)) {
+        *addr = (void *)CmdDispatchTileQCOM;
+        return true;
+    }
+    if (!strcmp("vkCmdBeginPerTileExecutionQCOM", name)) {
+        *addr = (void *)CmdBeginPerTileExecutionQCOM;
+        return true;
+    }
+    if (!strcmp("vkCmdEndPerTileExecutionQCOM", name)) {
+        *addr = (void *)CmdEndPerTileExecutionQCOM;
+        return true;
+    }
+
     // ---- VK_EXT_metal_objects extension commands
 #if defined(VK_USE_PLATFORM_METAL_EXT)
     if (!strcmp("vkExportMetalObjectsEXT", name)) {
@@ -12494,6 +12615,20 @@
     }
 #endif // VK_USE_PLATFORM_SCREEN_QNX
 
+    // ---- VK_NV_external_compute_queue extension commands
+    if (!strcmp("vkCreateExternalComputeQueueNV", name)) {
+        *addr = (void *)CreateExternalComputeQueueNV;
+        return true;
+    }
+    if (!strcmp("vkDestroyExternalComputeQueueNV", name)) {
+        *addr = (void *)DestroyExternalComputeQueueNV;
+        return true;
+    }
+    if (!strcmp("vkGetExternalComputeQueueDataNV", name)) {
+        *addr = (void *)GetExternalComputeQueueDataNV;
+        return true;
+    }
+
     // ---- VK_NV_cluster_acceleration_structure extension commands
     if (!strcmp("vkGetClusterAccelerationStructureBuildSizesNV", name)) {
         *addr = (void *)GetClusterAccelerationStructureBuildSizesNV;
diff --git a/loader/generated/vk_object_types.h b/loader/generated/vk_object_types.h
index 4605970..c2cf5e0 100644
--- a/loader/generated/vk_object_types.h
+++ b/loader/generated/vk_object_types.h
@@ -90,9 +90,10 @@
     kVulkanObjectTypeMicromapEXT = 49,
     kVulkanObjectTypeOpticalFlowSessionNV = 50,
     kVulkanObjectTypeShaderEXT = 51,
-    kVulkanObjectTypeIndirectExecutionSetEXT = 52,
-    kVulkanObjectTypeIndirectCommandsLayoutEXT = 53,
-    kVulkanObjectTypeMax = 54,
+    kVulkanObjectTypeExternalComputeQueueNV = 52,
+    kVulkanObjectTypeIndirectExecutionSetEXT = 53,
+    kVulkanObjectTypeIndirectCommandsLayoutEXT = 54,
+    kVulkanObjectTypeMax = 55,
     // Aliases for backwards compatibilty of "promoted" types
     kVulkanObjectTypeSamplerYcbcrConversionKHR = kVulkanObjectTypeSamplerYcbcrConversion,
     kVulkanObjectTypeDescriptorUpdateTemplateKHR = kVulkanObjectTypeDescriptorUpdateTemplate,
@@ -153,6 +154,7 @@
     "MicromapEXT",
     "OpticalFlowSessionNV",
     "ShaderEXT",
+    "ExternalComputeQueueNV",
     "IndirectExecutionSetEXT",
     "IndirectCommandsLayoutEXT",
 };
@@ -211,6 +213,7 @@
     VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT,   // kVulkanObjectTypeMicromapEXT
     VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT,   // kVulkanObjectTypeOpticalFlowSessionNV
     VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT,   // kVulkanObjectTypeShaderEXT
+    VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT,   // kVulkanObjectTypeExternalComputeQueueNV
     VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT,   // kVulkanObjectTypeIndirectExecutionSetEXT
     VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT,   // kVulkanObjectTypeIndirectCommandsLayoutEXT
 };
@@ -269,6 +272,7 @@
     VK_OBJECT_TYPE_MICROMAP_EXT,   // kVulkanObjectTypeMicromapEXT
     VK_OBJECT_TYPE_OPTICAL_FLOW_SESSION_NV,   // kVulkanObjectTypeOpticalFlowSessionNV
     VK_OBJECT_TYPE_SHADER_EXT,   // kVulkanObjectTypeShaderEXT
+    VK_OBJECT_TYPE_EXTERNAL_COMPUTE_QUEUE_NV,   // kVulkanObjectTypeExternalComputeQueueNV
     VK_OBJECT_TYPE_INDIRECT_EXECUTION_SET_EXT,   // kVulkanObjectTypeIndirectExecutionSetEXT
     VK_OBJECT_TYPE_INDIRECT_COMMANDS_LAYOUT_EXT,   // kVulkanObjectTypeIndirectCommandsLayoutEXT
 };
diff --git a/loader/loader.rc b/loader/loader.rc
index c6865de..335ea3c 100644
--- a/loader/loader.rc
+++ b/loader/loader.rc
@@ -22,8 +22,8 @@
 #include "winres.h"
 
 // All set through CMake
-#define VER_FILE_VERSION 1, 4, 311, 0
-#define VER_FILE_DESCRIPTION_STR "1.4.311.Dev Build"
+#define VER_FILE_VERSION 1, 4, 312, 0
+#define VER_FILE_DESCRIPTION_STR "1.4.312.Dev Build"
 #define VER_FILE_VERSION_STR "Vulkan Loader - Dev Build"
 #define VER_COPYRIGHT_STR "Copyright (C) 2015-2025"
 
diff --git a/scripts/known_good.json b/scripts/known_good.json
index 3f7c971..6a03f07 100644
--- a/scripts/known_good.json
+++ b/scripts/known_good.json
@@ -7,7 +7,7 @@
             "sub_dir": "Vulkan-Headers",
             "build_dir": "Vulkan-Headers/build",
             "install_dir": "Vulkan-Headers/build/install",
-            "commit": "v1.4.311"
+            "commit": "v1.4.312"
         },
         {
             "name": "googletest",
diff --git a/tests/framework/layer/vk_dispatch_table_helper.h b/tests/framework/layer/vk_dispatch_table_helper.h
index 804b992..a692c27 100644
--- a/tests/framework/layer/vk_dispatch_table_helper.h
+++ b/tests/framework/layer/vk_dispatch_table_helper.h
@@ -623,6 +623,9 @@
 #if defined(VK_ENABLE_BETA_EXTENSIONS)
     table->CmdCudaLaunchKernelNV = (PFN_vkCmdCudaLaunchKernelNV)gpa(device, "vkCmdCudaLaunchKernelNV");
 #endif  // VK_ENABLE_BETA_EXTENSIONS
+    table->CmdDispatchTileQCOM = (PFN_vkCmdDispatchTileQCOM)gpa(device, "vkCmdDispatchTileQCOM");
+    table->CmdBeginPerTileExecutionQCOM = (PFN_vkCmdBeginPerTileExecutionQCOM)gpa(device, "vkCmdBeginPerTileExecutionQCOM");
+    table->CmdEndPerTileExecutionQCOM = (PFN_vkCmdEndPerTileExecutionQCOM)gpa(device, "vkCmdEndPerTileExecutionQCOM");
 #if defined(VK_USE_PLATFORM_METAL_EXT)
     table->ExportMetalObjectsEXT = (PFN_vkExportMetalObjectsEXT)gpa(device, "vkExportMetalObjectsEXT");
 #endif  // VK_USE_PLATFORM_METAL_EXT
@@ -802,6 +805,9 @@
 #if defined(VK_USE_PLATFORM_SCREEN_QNX)
     table->GetScreenBufferPropertiesQNX = (PFN_vkGetScreenBufferPropertiesQNX)gpa(device, "vkGetScreenBufferPropertiesQNX");
 #endif  // VK_USE_PLATFORM_SCREEN_QNX
+    table->CreateExternalComputeQueueNV = (PFN_vkCreateExternalComputeQueueNV)gpa(device, "vkCreateExternalComputeQueueNV");
+    table->DestroyExternalComputeQueueNV = (PFN_vkDestroyExternalComputeQueueNV)gpa(device, "vkDestroyExternalComputeQueueNV");
+    table->GetExternalComputeQueueDataNV = (PFN_vkGetExternalComputeQueueDataNV)gpa(device, "vkGetExternalComputeQueueDataNV");
     table->GetClusterAccelerationStructureBuildSizesNV =
         (PFN_vkGetClusterAccelerationStructureBuildSizesNV)gpa(device, "vkGetClusterAccelerationStructureBuildSizesNV");
     table->CmdBuildClusterAccelerationStructureIndirectNV =