// *** THIS FILE IS GENERATED - DO NOT EDIT ***
// See layer_chassis_generator.py for modifications

/***************************************************************************
 *
 * Copyright (c) 2015-2026 The Khronos Group Inc.
 * Copyright (c) 2015-2026 Valve Corporation
 * Copyright (c) 2015-2026 LunarG, Inc.
 * Copyright (c) 2015-2024 Google Inc.
 * Copyright (c) 2023-2024 RasterGrid Kft.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 ****************************************************************************/

// NOLINTBEGIN

#include "chassis/chassis.h"
#include <array>
#include <cstring>

#include "chassis/dispatch_object.h"
#include "chassis/validation_object.h"
#include "generated/dispatch_vector.h"
#include "utils/vk_layer_extension_utils.h"
#include "layer_options.h"

#include "profiling/profiling.h"

// Extension exposed by the validation layer
static constexpr std::array<VkExtensionProperties, 4> kInstanceExtensions = {
    VkExtensionProperties{VK_EXT_DEBUG_REPORT_EXTENSION_NAME, VK_EXT_DEBUG_REPORT_SPEC_VERSION},
    VkExtensionProperties{VK_EXT_DEBUG_UTILS_EXTENSION_NAME, VK_EXT_DEBUG_UTILS_SPEC_VERSION},
    VkExtensionProperties{VK_EXT_VALIDATION_FEATURES_EXTENSION_NAME, VK_EXT_VALIDATION_FEATURES_SPEC_VERSION},
    VkExtensionProperties{VK_EXT_LAYER_SETTINGS_EXTENSION_NAME, VK_EXT_LAYER_SETTINGS_SPEC_VERSION},
};
static constexpr std::array<VkExtensionProperties, 3> kDeviceExtensions = {
    VkExtensionProperties{VK_EXT_VALIDATION_CACHE_EXTENSION_NAME, VK_EXT_VALIDATION_CACHE_SPEC_VERSION},
    VkExtensionProperties{VK_EXT_DEBUG_MARKER_EXTENSION_NAME, VK_EXT_DEBUG_MARKER_SPEC_VERSION},
    VkExtensionProperties{VK_EXT_TOOLING_INFO_EXTENSION_NAME, VK_EXT_TOOLING_INFO_SPEC_VERSION},
};
namespace vulkan_layer_chassis {
static const VkLayerProperties global_layer = {
    OBJECT_LAYER_NAME,
    VK_HEADER_VERSION_COMPLETE,
    1,
    "LunarG validation Layer",
};

// These functions reference generated data so they cannot be part of chassis_main.cpp
VKAPI_ATTR VkResult VKAPI_CALL EnumerateInstanceVersion(uint32_t* pApiVersion) {
    if (pApiVersion) {
        *pApiVersion = VK_HEADER_VERSION_COMPLETE;
    }
    return VK_SUCCESS;
}

VKAPI_ATTR VkResult VKAPI_CALL EnumerateInstanceLayerProperties(uint32_t* pCount, VkLayerProperties* pProperties) {
    return util_GetLayerProperties(1, &global_layer, pCount, pProperties);
}

VKAPI_ATTR VkResult VKAPI_CALL EnumerateDeviceLayerProperties(VkPhysicalDevice physicalDevice, uint32_t* pCount,
                                                              VkLayerProperties* pProperties) {
    return util_GetLayerProperties(1, &global_layer, pCount, pProperties);
}

VKAPI_ATTR VkResult VKAPI_CALL EnumerateInstanceExtensionProperties(const char* pLayerName, uint32_t* pCount,
                                                                    VkExtensionProperties* pProperties) {
    if (pLayerName && !strcmp(pLayerName, global_layer.layerName)) {
        return util_GetExtensionProperties(static_cast<uint32_t>(kInstanceExtensions.size()), kInstanceExtensions.data(), pCount,
                                           pProperties);
    }

    return VK_ERROR_LAYER_NOT_PRESENT;
}

VKAPI_ATTR VkResult VKAPI_CALL EnumerateDeviceExtensionProperties(VkPhysicalDevice physicalDevice, const char* pLayerName,
                                                                  uint32_t* pCount, VkExtensionProperties* pProperties) {
    if (pLayerName && !strcmp(pLayerName, global_layer.layerName)) {
        return util_GetExtensionProperties(static_cast<uint32_t>(kDeviceExtensions.size()), kDeviceExtensions.data(), pCount,
                                           pProperties);
    }

    assert(physicalDevice);
    auto layer_data = vvl::dispatch::GetData(physicalDevice);
    return layer_data->instance_dispatch_table.EnumerateDeviceExtensionProperties(physicalDevice, pLayerName, pCount, pProperties);
}
VKAPI_ATTR VkResult VKAPI_CALL EnumeratePhysicalDevices(VkInstance instance, uint32_t* pPhysicalDeviceCount,
                                                        VkPhysicalDevice* pPhysicalDevices) {
    VVL_ZoneScoped;

    auto instance_dispatch = vvl::dispatch::GetData(instance);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkEnumeratePhysicalDevices, VulkanTypedHandle(instance, kVulkanObjectTypeInstance));
    {
        VVL_ZoneScopedN("PreCallValidate_vkEnumeratePhysicalDevices");
        for (const auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            skip |= vo->PreCallValidateEnumeratePhysicalDevices(instance, pPhysicalDeviceCount, pPhysicalDevices, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkEnumeratePhysicalDevices);
    {
        VVL_ZoneScopedN("PreCallRecord_vkEnumeratePhysicalDevices");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PreCallRecordEnumeratePhysicalDevices(instance, pPhysicalDeviceCount, pPhysicalDevices, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkEnumeratePhysicalDevices");
        result = instance_dispatch->EnumeratePhysicalDevices(instance, pPhysicalDeviceCount, pPhysicalDevices);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkEnumeratePhysicalDevices");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PostCallRecordEnumeratePhysicalDevices(instance, pPhysicalDeviceCount, pPhysicalDevices, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR void VKAPI_CALL GetPhysicalDeviceFeatures(VkPhysicalDevice physicalDevice, VkPhysicalDeviceFeatures* pFeatures) {
    VVL_ZoneScoped;

    auto instance_dispatch = vvl::dispatch::GetData(physicalDevice);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetPhysicalDeviceFeatures,
                          VulkanTypedHandle(physicalDevice, kVulkanObjectTypePhysicalDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetPhysicalDeviceFeatures");
        for (const auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            skip |= vo->PreCallValidateGetPhysicalDeviceFeatures(physicalDevice, pFeatures, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetPhysicalDeviceFeatures);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetPhysicalDeviceFeatures");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PreCallRecordGetPhysicalDeviceFeatures(physicalDevice, pFeatures, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkGetPhysicalDeviceFeatures");
        instance_dispatch->GetPhysicalDeviceFeatures(physicalDevice, pFeatures);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetPhysicalDeviceFeatures");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PostCallRecordGetPhysicalDeviceFeatures(physicalDevice, pFeatures, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL GetPhysicalDeviceFormatProperties(VkPhysicalDevice physicalDevice, VkFormat format,
                                                             VkFormatProperties* pFormatProperties) {
    VVL_ZoneScoped;

    auto instance_dispatch = vvl::dispatch::GetData(physicalDevice);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetPhysicalDeviceFormatProperties,
                          VulkanTypedHandle(physicalDevice, kVulkanObjectTypePhysicalDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetPhysicalDeviceFormatProperties");
        for (const auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            skip |= vo->PreCallValidateGetPhysicalDeviceFormatProperties(physicalDevice, format, pFormatProperties, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetPhysicalDeviceFormatProperties);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetPhysicalDeviceFormatProperties");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PreCallRecordGetPhysicalDeviceFormatProperties(physicalDevice, format, pFormatProperties, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkGetPhysicalDeviceFormatProperties");
        instance_dispatch->GetPhysicalDeviceFormatProperties(physicalDevice, format, pFormatProperties);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetPhysicalDeviceFormatProperties");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PostCallRecordGetPhysicalDeviceFormatProperties(physicalDevice, format, pFormatProperties, record_obj);
        }
    }
}

VKAPI_ATTR VkResult VKAPI_CALL GetPhysicalDeviceImageFormatProperties(VkPhysicalDevice physicalDevice, VkFormat format,
                                                                      VkImageType type, VkImageTiling tiling,
                                                                      VkImageUsageFlags usage, VkImageCreateFlags flags,
                                                                      VkImageFormatProperties* pImageFormatProperties) {
    VVL_ZoneScoped;

    auto instance_dispatch = vvl::dispatch::GetData(physicalDevice);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetPhysicalDeviceImageFormatProperties,
                          VulkanTypedHandle(physicalDevice, kVulkanObjectTypePhysicalDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetPhysicalDeviceImageFormatProperties");
        for (const auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            skip |= vo->PreCallValidateGetPhysicalDeviceImageFormatProperties(physicalDevice, format, type, tiling, usage, flags,
                                                                              pImageFormatProperties, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetPhysicalDeviceImageFormatProperties);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetPhysicalDeviceImageFormatProperties");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PreCallRecordGetPhysicalDeviceImageFormatProperties(physicalDevice, format, type, tiling, usage, flags,
                                                                    pImageFormatProperties, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkGetPhysicalDeviceImageFormatProperties");
        result = instance_dispatch->GetPhysicalDeviceImageFormatProperties(physicalDevice, format, type, tiling, usage, flags,
                                                                           pImageFormatProperties);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetPhysicalDeviceImageFormatProperties");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PostCallRecordGetPhysicalDeviceImageFormatProperties(physicalDevice, format, type, tiling, usage, flags,
                                                                     pImageFormatProperties, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR void VKAPI_CALL GetPhysicalDeviceProperties(VkPhysicalDevice physicalDevice, VkPhysicalDeviceProperties* pProperties) {
    VVL_ZoneScoped;

    auto instance_dispatch = vvl::dispatch::GetData(physicalDevice);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetPhysicalDeviceProperties,
                          VulkanTypedHandle(physicalDevice, kVulkanObjectTypePhysicalDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetPhysicalDeviceProperties");
        for (const auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            skip |= vo->PreCallValidateGetPhysicalDeviceProperties(physicalDevice, pProperties, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetPhysicalDeviceProperties);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetPhysicalDeviceProperties");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PreCallRecordGetPhysicalDeviceProperties(physicalDevice, pProperties, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkGetPhysicalDeviceProperties");
        instance_dispatch->GetPhysicalDeviceProperties(physicalDevice, pProperties);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetPhysicalDeviceProperties");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PostCallRecordGetPhysicalDeviceProperties(physicalDevice, pProperties, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL GetPhysicalDeviceQueueFamilyProperties(VkPhysicalDevice physicalDevice,
                                                                  uint32_t* pQueueFamilyPropertyCount,
                                                                  VkQueueFamilyProperties* pQueueFamilyProperties) {
    VVL_ZoneScoped;

    auto instance_dispatch = vvl::dispatch::GetData(physicalDevice);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetPhysicalDeviceQueueFamilyProperties,
                          VulkanTypedHandle(physicalDevice, kVulkanObjectTypePhysicalDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetPhysicalDeviceQueueFamilyProperties");
        for (const auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            skip |= vo->PreCallValidateGetPhysicalDeviceQueueFamilyProperties(physicalDevice, pQueueFamilyPropertyCount,
                                                                              pQueueFamilyProperties, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetPhysicalDeviceQueueFamilyProperties);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetPhysicalDeviceQueueFamilyProperties");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PreCallRecordGetPhysicalDeviceQueueFamilyProperties(physicalDevice, pQueueFamilyPropertyCount,
                                                                    pQueueFamilyProperties, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkGetPhysicalDeviceQueueFamilyProperties");
        instance_dispatch->GetPhysicalDeviceQueueFamilyProperties(physicalDevice, pQueueFamilyPropertyCount,
                                                                  pQueueFamilyProperties);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetPhysicalDeviceQueueFamilyProperties");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PostCallRecordGetPhysicalDeviceQueueFamilyProperties(physicalDevice, pQueueFamilyPropertyCount,
                                                                     pQueueFamilyProperties, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL GetPhysicalDeviceMemoryProperties(VkPhysicalDevice physicalDevice,
                                                             VkPhysicalDeviceMemoryProperties* pMemoryProperties) {
    VVL_ZoneScoped;

    auto instance_dispatch = vvl::dispatch::GetData(physicalDevice);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetPhysicalDeviceMemoryProperties,
                          VulkanTypedHandle(physicalDevice, kVulkanObjectTypePhysicalDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetPhysicalDeviceMemoryProperties");
        for (const auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            skip |= vo->PreCallValidateGetPhysicalDeviceMemoryProperties(physicalDevice, pMemoryProperties, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetPhysicalDeviceMemoryProperties);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetPhysicalDeviceMemoryProperties");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PreCallRecordGetPhysicalDeviceMemoryProperties(physicalDevice, pMemoryProperties, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkGetPhysicalDeviceMemoryProperties");
        instance_dispatch->GetPhysicalDeviceMemoryProperties(physicalDevice, pMemoryProperties);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetPhysicalDeviceMemoryProperties");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PostCallRecordGetPhysicalDeviceMemoryProperties(physicalDevice, pMemoryProperties, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL GetDeviceQueue(VkDevice device, uint32_t queueFamilyIndex, uint32_t queueIndex, VkQueue* pQueue) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetDeviceQueue, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetDeviceQueue");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateGetDeviceQueue]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateGetDeviceQueue(device, queueFamilyIndex, queueIndex, pQueue, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetDeviceQueue);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetDeviceQueue");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordGetDeviceQueue]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordGetDeviceQueue(device, queueFamilyIndex, queueIndex, pQueue, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkGetDeviceQueue");
        device_dispatch->GetDeviceQueue(device, queueFamilyIndex, queueIndex, pQueue);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetDeviceQueue");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordGetDeviceQueue]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordGetDeviceQueue(device, queueFamilyIndex, queueIndex, pQueue, record_obj);
        }
    }
#if defined(VVL_TRACY_GPU)
    TracyVkCollector::Create(device, *pQueue, queueFamilyIndex);
#endif
}

VKAPI_ATTR VkResult VKAPI_CALL QueueSubmit(VkQueue queue, uint32_t submitCount, const VkSubmitInfo* pSubmits, VkFence fence) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(queue);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkQueueSubmit, VulkanTypedHandle(queue, kVulkanObjectTypeQueue));
    {
        VVL_ZoneScopedN("PreCallValidate_vkQueueSubmit");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateQueueSubmit]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateQueueSubmit(queue, submitCount, pSubmits, fence, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkQueueSubmit);
    {
        VVL_ZoneScopedN("PreCallRecord_vkQueueSubmit");
        VVL_TracyVkNamedZoneStart(GetTracyVkCtx(), queue, "gpu_PreCallRecordvkQueueSubmit", pre_call_record_gpu_zone);

        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordQueueSubmit]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordQueueSubmit(queue, submitCount, pSubmits, fence, record_obj);
        }

        VVL_TracyVkNamedZoneEnd(pre_call_record_gpu_zone, queue);
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkQueueSubmit");

        VVL_TracyVkNamedZoneStart(GetTracyVkCtx(), queue, "gpu_vkQueueSubmit", submit_gpu_zone);
        result = device_dispatch->QueueSubmit(queue, submitCount, pSubmits, fence);

        VVL_TracyVkNamedZoneEnd(submit_gpu_zone, queue);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkQueueSubmit");

        VVL_TracyVkNamedZoneStart(GetTracyVkCtx(), queue, "gpu_PostCallRecordvkQueueSubmit", post_call_record_gpu_zone);

        if (result == VK_ERROR_DEVICE_LOST) {
            for (auto& vo : device_dispatch->object_dispatch) {
                vo->is_device_lost = true;
            }
        }
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordQueueSubmit]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordQueueSubmit(queue, submitCount, pSubmits, fence, record_obj);
        }

        VVL_TracyVkNamedZoneEnd(post_call_record_gpu_zone, queue);
    }
#if defined(VVL_TRACY_GPU)
    TracyVkCollector::TrySubmitCollectCb(queue);
#endif
    return result;
}

VKAPI_ATTR VkResult VKAPI_CALL QueueWaitIdle(VkQueue queue) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(queue);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkQueueWaitIdle, VulkanTypedHandle(queue, kVulkanObjectTypeQueue));
    {
        VVL_ZoneScopedN("PreCallValidate_vkQueueWaitIdle");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateQueueWaitIdle]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateQueueWaitIdle(queue, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkQueueWaitIdle);
    {
        VVL_ZoneScopedN("PreCallRecord_vkQueueWaitIdle");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordQueueWaitIdle]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordQueueWaitIdle(queue, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkQueueWaitIdle");
        result = device_dispatch->QueueWaitIdle(queue);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkQueueWaitIdle");

        if (result == VK_ERROR_DEVICE_LOST) {
            for (auto& vo : device_dispatch->object_dispatch) {
                vo->is_device_lost = true;
            }
        }
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordQueueWaitIdle]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordQueueWaitIdle(queue, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR VkResult VKAPI_CALL DeviceWaitIdle(VkDevice device) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkDeviceWaitIdle, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkDeviceWaitIdle");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateDeviceWaitIdle]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateDeviceWaitIdle(device, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkDeviceWaitIdle);
    {
        VVL_ZoneScopedN("PreCallRecord_vkDeviceWaitIdle");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordDeviceWaitIdle]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordDeviceWaitIdle(device, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkDeviceWaitIdle");
        result = device_dispatch->DeviceWaitIdle(device);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkDeviceWaitIdle");

        if (result == VK_ERROR_DEVICE_LOST) {
            for (auto& vo : device_dispatch->object_dispatch) {
                vo->is_device_lost = true;
            }
        }
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordDeviceWaitIdle]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordDeviceWaitIdle(device, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR VkResult VKAPI_CALL AllocateMemory(VkDevice device, const VkMemoryAllocateInfo* pAllocateInfo,
                                              const VkAllocationCallbacks* pAllocator, VkDeviceMemory* pMemory) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkAllocateMemory, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkAllocateMemory");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateAllocateMemory]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateAllocateMemory(device, pAllocateInfo, pAllocator, pMemory, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkAllocateMemory);
    {
        VVL_ZoneScopedN("PreCallRecord_vkAllocateMemory");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordAllocateMemory]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordAllocateMemory(device, pAllocateInfo, pAllocator, pMemory, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkAllocateMemory");
        result = device_dispatch->AllocateMemory(device, pAllocateInfo, pAllocator, pMemory);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkAllocateMemory");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordAllocateMemory]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordAllocateMemory(device, pAllocateInfo, pAllocator, pMemory, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR void VKAPI_CALL FreeMemory(VkDevice device, VkDeviceMemory memory, const VkAllocationCallbacks* pAllocator) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkFreeMemory, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkFreeMemory");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateFreeMemory]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateFreeMemory(device, memory, pAllocator, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkFreeMemory);
    {
        VVL_ZoneScopedN("PreCallRecord_vkFreeMemory");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordFreeMemory]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordFreeMemory(device, memory, pAllocator, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkFreeMemory");
        device_dispatch->FreeMemory(device, memory, pAllocator);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkFreeMemory");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordFreeMemory]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordFreeMemory(device, memory, pAllocator, record_obj);
        }
    }
}

VKAPI_ATTR VkResult VKAPI_CALL MapMemory(VkDevice device, VkDeviceMemory memory, VkDeviceSize offset, VkDeviceSize size,
                                         VkMemoryMapFlags flags, void** ppData) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkMapMemory, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkMapMemory");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateMapMemory]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateMapMemory(device, memory, offset, size, flags, ppData, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkMapMemory);
    {
        VVL_ZoneScopedN("PreCallRecord_vkMapMemory");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordMapMemory]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordMapMemory(device, memory, offset, size, flags, ppData, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkMapMemory");
        result = device_dispatch->MapMemory(device, memory, offset, size, flags, ppData);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkMapMemory");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordMapMemory]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordMapMemory(device, memory, offset, size, flags, ppData, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR void VKAPI_CALL UnmapMemory(VkDevice device, VkDeviceMemory memory) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkUnmapMemory, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkUnmapMemory");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateUnmapMemory]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateUnmapMemory(device, memory, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkUnmapMemory);
    {
        VVL_ZoneScopedN("PreCallRecord_vkUnmapMemory");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordUnmapMemory]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordUnmapMemory(device, memory, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkUnmapMemory");
        device_dispatch->UnmapMemory(device, memory);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkUnmapMemory");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordUnmapMemory]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordUnmapMemory(device, memory, record_obj);
        }
    }
}

VKAPI_ATTR VkResult VKAPI_CALL FlushMappedMemoryRanges(VkDevice device, uint32_t memoryRangeCount,
                                                       const VkMappedMemoryRange* pMemoryRanges) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkFlushMappedMemoryRanges, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkFlushMappedMemoryRanges");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateFlushMappedMemoryRanges]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateFlushMappedMemoryRanges(device, memoryRangeCount, pMemoryRanges, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkFlushMappedMemoryRanges);
    {
        VVL_ZoneScopedN("PreCallRecord_vkFlushMappedMemoryRanges");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordFlushMappedMemoryRanges]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordFlushMappedMemoryRanges(device, memoryRangeCount, pMemoryRanges, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkFlushMappedMemoryRanges");
        result = device_dispatch->FlushMappedMemoryRanges(device, memoryRangeCount, pMemoryRanges);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkFlushMappedMemoryRanges");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordFlushMappedMemoryRanges]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordFlushMappedMemoryRanges(device, memoryRangeCount, pMemoryRanges, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR VkResult VKAPI_CALL InvalidateMappedMemoryRanges(VkDevice device, uint32_t memoryRangeCount,
                                                            const VkMappedMemoryRange* pMemoryRanges) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkInvalidateMappedMemoryRanges, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkInvalidateMappedMemoryRanges");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateInvalidateMappedMemoryRanges]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateInvalidateMappedMemoryRanges(device, memoryRangeCount, pMemoryRanges, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkInvalidateMappedMemoryRanges);
    {
        VVL_ZoneScopedN("PreCallRecord_vkInvalidateMappedMemoryRanges");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordInvalidateMappedMemoryRanges]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordInvalidateMappedMemoryRanges(device, memoryRangeCount, pMemoryRanges, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkInvalidateMappedMemoryRanges");
        result = device_dispatch->InvalidateMappedMemoryRanges(device, memoryRangeCount, pMemoryRanges);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkInvalidateMappedMemoryRanges");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordInvalidateMappedMemoryRanges]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordInvalidateMappedMemoryRanges(device, memoryRangeCount, pMemoryRanges, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR void VKAPI_CALL GetDeviceMemoryCommitment(VkDevice device, VkDeviceMemory memory,
                                                     VkDeviceSize* pCommittedMemoryInBytes) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetDeviceMemoryCommitment, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetDeviceMemoryCommitment");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateGetDeviceMemoryCommitment]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateGetDeviceMemoryCommitment(device, memory, pCommittedMemoryInBytes, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetDeviceMemoryCommitment);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetDeviceMemoryCommitment");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordGetDeviceMemoryCommitment]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordGetDeviceMemoryCommitment(device, memory, pCommittedMemoryInBytes, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkGetDeviceMemoryCommitment");
        device_dispatch->GetDeviceMemoryCommitment(device, memory, pCommittedMemoryInBytes);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetDeviceMemoryCommitment");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordGetDeviceMemoryCommitment]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordGetDeviceMemoryCommitment(device, memory, pCommittedMemoryInBytes, record_obj);
        }
    }
}

VKAPI_ATTR VkResult VKAPI_CALL BindBufferMemory(VkDevice device, VkBuffer buffer, VkDeviceMemory memory,
                                                VkDeviceSize memoryOffset) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkBindBufferMemory, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkBindBufferMemory");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateBindBufferMemory]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateBindBufferMemory(device, buffer, memory, memoryOffset, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkBindBufferMemory);
    {
        VVL_ZoneScopedN("PreCallRecord_vkBindBufferMemory");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordBindBufferMemory]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordBindBufferMemory(device, buffer, memory, memoryOffset, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkBindBufferMemory");
        result = device_dispatch->BindBufferMemory(device, buffer, memory, memoryOffset);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkBindBufferMemory");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordBindBufferMemory]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordBindBufferMemory(device, buffer, memory, memoryOffset, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR VkResult VKAPI_CALL BindImageMemory(VkDevice device, VkImage image, VkDeviceMemory memory, VkDeviceSize memoryOffset) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkBindImageMemory, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkBindImageMemory");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateBindImageMemory]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateBindImageMemory(device, image, memory, memoryOffset, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkBindImageMemory);
    {
        VVL_ZoneScopedN("PreCallRecord_vkBindImageMemory");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordBindImageMemory]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordBindImageMemory(device, image, memory, memoryOffset, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkBindImageMemory");
        result = device_dispatch->BindImageMemory(device, image, memory, memoryOffset);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkBindImageMemory");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordBindImageMemory]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordBindImageMemory(device, image, memory, memoryOffset, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR void VKAPI_CALL GetBufferMemoryRequirements(VkDevice device, VkBuffer buffer,
                                                       VkMemoryRequirements* pMemoryRequirements) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetBufferMemoryRequirements, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetBufferMemoryRequirements");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateGetBufferMemoryRequirements]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateGetBufferMemoryRequirements(device, buffer, pMemoryRequirements, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetBufferMemoryRequirements);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetBufferMemoryRequirements");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordGetBufferMemoryRequirements]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordGetBufferMemoryRequirements(device, buffer, pMemoryRequirements, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkGetBufferMemoryRequirements");
        device_dispatch->GetBufferMemoryRequirements(device, buffer, pMemoryRequirements);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetBufferMemoryRequirements");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordGetBufferMemoryRequirements]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordGetBufferMemoryRequirements(device, buffer, pMemoryRequirements, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL GetImageMemoryRequirements(VkDevice device, VkImage image, VkMemoryRequirements* pMemoryRequirements) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetImageMemoryRequirements, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetImageMemoryRequirements");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateGetImageMemoryRequirements]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateGetImageMemoryRequirements(device, image, pMemoryRequirements, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetImageMemoryRequirements);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetImageMemoryRequirements");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordGetImageMemoryRequirements]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordGetImageMemoryRequirements(device, image, pMemoryRequirements, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkGetImageMemoryRequirements");
        device_dispatch->GetImageMemoryRequirements(device, image, pMemoryRequirements);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetImageMemoryRequirements");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordGetImageMemoryRequirements]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordGetImageMemoryRequirements(device, image, pMemoryRequirements, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL GetImageSparseMemoryRequirements(VkDevice device, VkImage image, uint32_t* pSparseMemoryRequirementCount,
                                                            VkSparseImageMemoryRequirements* pSparseMemoryRequirements) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetImageSparseMemoryRequirements, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetImageSparseMemoryRequirements");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateGetImageSparseMemoryRequirements]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateGetImageSparseMemoryRequirements(device, image, pSparseMemoryRequirementCount,
                                                                        pSparseMemoryRequirements, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetImageSparseMemoryRequirements);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetImageSparseMemoryRequirements");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordGetImageSparseMemoryRequirements]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordGetImageSparseMemoryRequirements(device, image, pSparseMemoryRequirementCount,
                                                              pSparseMemoryRequirements, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkGetImageSparseMemoryRequirements");
        device_dispatch->GetImageSparseMemoryRequirements(device, image, pSparseMemoryRequirementCount, pSparseMemoryRequirements);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetImageSparseMemoryRequirements");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordGetImageSparseMemoryRequirements]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordGetImageSparseMemoryRequirements(device, image, pSparseMemoryRequirementCount,
                                                               pSparseMemoryRequirements, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL GetPhysicalDeviceSparseImageFormatProperties(VkPhysicalDevice physicalDevice, VkFormat format,
                                                                        VkImageType type, VkSampleCountFlagBits samples,
                                                                        VkImageUsageFlags usage, VkImageTiling tiling,
                                                                        uint32_t* pPropertyCount,
                                                                        VkSparseImageFormatProperties* pProperties) {
    VVL_ZoneScoped;

    auto instance_dispatch = vvl::dispatch::GetData(physicalDevice);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetPhysicalDeviceSparseImageFormatProperties,
                          VulkanTypedHandle(physicalDevice, kVulkanObjectTypePhysicalDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetPhysicalDeviceSparseImageFormatProperties");
        for (const auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            skip |= vo->PreCallValidateGetPhysicalDeviceSparseImageFormatProperties(physicalDevice, format, type, samples, usage,
                                                                                    tiling, pPropertyCount, pProperties, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetPhysicalDeviceSparseImageFormatProperties);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetPhysicalDeviceSparseImageFormatProperties");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PreCallRecordGetPhysicalDeviceSparseImageFormatProperties(physicalDevice, format, type, samples, usage, tiling,
                                                                          pPropertyCount, pProperties, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkGetPhysicalDeviceSparseImageFormatProperties");
        instance_dispatch->GetPhysicalDeviceSparseImageFormatProperties(physicalDevice, format, type, samples, usage, tiling,
                                                                        pPropertyCount, pProperties);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetPhysicalDeviceSparseImageFormatProperties");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PostCallRecordGetPhysicalDeviceSparseImageFormatProperties(physicalDevice, format, type, samples, usage, tiling,
                                                                           pPropertyCount, pProperties, record_obj);
        }
    }
}

VKAPI_ATTR VkResult VKAPI_CALL QueueBindSparse(VkQueue queue, uint32_t bindInfoCount, const VkBindSparseInfo* pBindInfo,
                                               VkFence fence) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(queue);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkQueueBindSparse, VulkanTypedHandle(queue, kVulkanObjectTypeQueue));
    {
        VVL_ZoneScopedN("PreCallValidate_vkQueueBindSparse");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateQueueBindSparse]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateQueueBindSparse(queue, bindInfoCount, pBindInfo, fence, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkQueueBindSparse);
    {
        VVL_ZoneScopedN("PreCallRecord_vkQueueBindSparse");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordQueueBindSparse]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordQueueBindSparse(queue, bindInfoCount, pBindInfo, fence, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkQueueBindSparse");
        result = device_dispatch->QueueBindSparse(queue, bindInfoCount, pBindInfo, fence);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkQueueBindSparse");

        if (result == VK_ERROR_DEVICE_LOST) {
            for (auto& vo : device_dispatch->object_dispatch) {
                vo->is_device_lost = true;
            }
        }
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordQueueBindSparse]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordQueueBindSparse(queue, bindInfoCount, pBindInfo, fence, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR VkResult VKAPI_CALL CreateFence(VkDevice device, const VkFenceCreateInfo* pCreateInfo,
                                           const VkAllocationCallbacks* pAllocator, VkFence* pFence) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCreateFence, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCreateFence");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCreateFence]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCreateFence(device, pCreateInfo, pAllocator, pFence, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkCreateFence);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCreateFence");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCreateFence]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCreateFence(device, pCreateInfo, pAllocator, pFence, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkCreateFence");
        result = device_dispatch->CreateFence(device, pCreateInfo, pAllocator, pFence);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkCreateFence");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCreateFence]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCreateFence(device, pCreateInfo, pAllocator, pFence, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR void VKAPI_CALL DestroyFence(VkDevice device, VkFence fence, const VkAllocationCallbacks* pAllocator) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkDestroyFence, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkDestroyFence");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateDestroyFence]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateDestroyFence(device, fence, pAllocator, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkDestroyFence);
    {
        VVL_ZoneScopedN("PreCallRecord_vkDestroyFence");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordDestroyFence]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordDestroyFence(device, fence, pAllocator, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkDestroyFence");
        device_dispatch->DestroyFence(device, fence, pAllocator);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkDestroyFence");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordDestroyFence]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordDestroyFence(device, fence, pAllocator, record_obj);
        }
    }
}

VKAPI_ATTR VkResult VKAPI_CALL ResetFences(VkDevice device, uint32_t fenceCount, const VkFence* pFences) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkResetFences, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkResetFences");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateResetFences]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateResetFences(device, fenceCount, pFences, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkResetFences);
    {
        VVL_ZoneScopedN("PreCallRecord_vkResetFences");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordResetFences]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordResetFences(device, fenceCount, pFences, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkResetFences");
        result = device_dispatch->ResetFences(device, fenceCount, pFences);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkResetFences");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordResetFences]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordResetFences(device, fenceCount, pFences, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR VkResult VKAPI_CALL GetFenceStatus(VkDevice device, VkFence fence) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetFenceStatus, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetFenceStatus");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateGetFenceStatus]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateGetFenceStatus(device, fence, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetFenceStatus);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetFenceStatus");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordGetFenceStatus]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordGetFenceStatus(device, fence, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkGetFenceStatus");
        result = device_dispatch->GetFenceStatus(device, fence);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetFenceStatus");

        if (result == VK_ERROR_DEVICE_LOST) {
            for (auto& vo : device_dispatch->object_dispatch) {
                vo->is_device_lost = true;
            }
        }
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordGetFenceStatus]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordGetFenceStatus(device, fence, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR VkResult VKAPI_CALL WaitForFences(VkDevice device, uint32_t fenceCount, const VkFence* pFences, VkBool32 waitAll,
                                             uint64_t timeout) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkWaitForFences, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkWaitForFences");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateWaitForFences]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateWaitForFences(device, fenceCount, pFences, waitAll, timeout, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkWaitForFences);
    {
        VVL_ZoneScopedN("PreCallRecord_vkWaitForFences");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordWaitForFences]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordWaitForFences(device, fenceCount, pFences, waitAll, timeout, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkWaitForFences");
        result = device_dispatch->WaitForFences(device, fenceCount, pFences, waitAll, timeout);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkWaitForFences");

        if (result == VK_ERROR_DEVICE_LOST) {
            for (auto& vo : device_dispatch->object_dispatch) {
                vo->is_device_lost = true;
            }
        }
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordWaitForFences]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordWaitForFences(device, fenceCount, pFences, waitAll, timeout, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR VkResult VKAPI_CALL CreateSemaphore(VkDevice device, const VkSemaphoreCreateInfo* pCreateInfo,
                                               const VkAllocationCallbacks* pAllocator, VkSemaphore* pSemaphore) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCreateSemaphore, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCreateSemaphore");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCreateSemaphore]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCreateSemaphore(device, pCreateInfo, pAllocator, pSemaphore, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkCreateSemaphore);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCreateSemaphore");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCreateSemaphore]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCreateSemaphore(device, pCreateInfo, pAllocator, pSemaphore, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkCreateSemaphore");
        result = device_dispatch->CreateSemaphore(device, pCreateInfo, pAllocator, pSemaphore);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkCreateSemaphore");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCreateSemaphore]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCreateSemaphore(device, pCreateInfo, pAllocator, pSemaphore, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR void VKAPI_CALL DestroySemaphore(VkDevice device, VkSemaphore semaphore, const VkAllocationCallbacks* pAllocator) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkDestroySemaphore, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkDestroySemaphore");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateDestroySemaphore]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateDestroySemaphore(device, semaphore, pAllocator, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkDestroySemaphore);
    {
        VVL_ZoneScopedN("PreCallRecord_vkDestroySemaphore");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordDestroySemaphore]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordDestroySemaphore(device, semaphore, pAllocator, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkDestroySemaphore");
        device_dispatch->DestroySemaphore(device, semaphore, pAllocator);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkDestroySemaphore");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordDestroySemaphore]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordDestroySemaphore(device, semaphore, pAllocator, record_obj);
        }
    }
}

VKAPI_ATTR VkResult VKAPI_CALL CreateQueryPool(VkDevice device, const VkQueryPoolCreateInfo* pCreateInfo,
                                               const VkAllocationCallbacks* pAllocator, VkQueryPool* pQueryPool) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCreateQueryPool, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCreateQueryPool");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCreateQueryPool]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCreateQueryPool(device, pCreateInfo, pAllocator, pQueryPool, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkCreateQueryPool);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCreateQueryPool");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCreateQueryPool]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCreateQueryPool(device, pCreateInfo, pAllocator, pQueryPool, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkCreateQueryPool");
        result = device_dispatch->CreateQueryPool(device, pCreateInfo, pAllocator, pQueryPool);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkCreateQueryPool");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCreateQueryPool]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCreateQueryPool(device, pCreateInfo, pAllocator, pQueryPool, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR void VKAPI_CALL DestroyQueryPool(VkDevice device, VkQueryPool queryPool, const VkAllocationCallbacks* pAllocator) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkDestroyQueryPool, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkDestroyQueryPool");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateDestroyQueryPool]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateDestroyQueryPool(device, queryPool, pAllocator, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkDestroyQueryPool);
    {
        VVL_ZoneScopedN("PreCallRecord_vkDestroyQueryPool");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordDestroyQueryPool]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordDestroyQueryPool(device, queryPool, pAllocator, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkDestroyQueryPool");
        device_dispatch->DestroyQueryPool(device, queryPool, pAllocator);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkDestroyQueryPool");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordDestroyQueryPool]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordDestroyQueryPool(device, queryPool, pAllocator, record_obj);
        }
    }
}

VKAPI_ATTR VkResult VKAPI_CALL GetQueryPoolResults(VkDevice device, VkQueryPool queryPool, uint32_t firstQuery, uint32_t queryCount,
                                                   size_t dataSize, void* pData, VkDeviceSize stride, VkQueryResultFlags flags) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetQueryPoolResults, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetQueryPoolResults");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateGetQueryPoolResults]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateGetQueryPoolResults(device, queryPool, firstQuery, queryCount, dataSize, pData, stride,
                                                           flags, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetQueryPoolResults);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetQueryPoolResults");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordGetQueryPoolResults]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordGetQueryPoolResults(device, queryPool, firstQuery, queryCount, dataSize, pData, stride, flags,
                                                 record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkGetQueryPoolResults");
        result = device_dispatch->GetQueryPoolResults(device, queryPool, firstQuery, queryCount, dataSize, pData, stride, flags);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetQueryPoolResults");

        if (result == VK_ERROR_DEVICE_LOST) {
            for (auto& vo : device_dispatch->object_dispatch) {
                vo->is_device_lost = true;
            }
        }
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordGetQueryPoolResults]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordGetQueryPoolResults(device, queryPool, firstQuery, queryCount, dataSize, pData, stride, flags,
                                                  record_obj);
        }
    }
    return result;
}

VKAPI_ATTR void VKAPI_CALL DestroyBuffer(VkDevice device, VkBuffer buffer, const VkAllocationCallbacks* pAllocator) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkDestroyBuffer, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkDestroyBuffer");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateDestroyBuffer]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateDestroyBuffer(device, buffer, pAllocator, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkDestroyBuffer);
    {
        VVL_ZoneScopedN("PreCallRecord_vkDestroyBuffer");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordDestroyBuffer]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordDestroyBuffer(device, buffer, pAllocator, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkDestroyBuffer");
        device_dispatch->DestroyBuffer(device, buffer, pAllocator);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkDestroyBuffer");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordDestroyBuffer]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordDestroyBuffer(device, buffer, pAllocator, record_obj);
        }
    }
}

VKAPI_ATTR VkResult VKAPI_CALL CreateImage(VkDevice device, const VkImageCreateInfo* pCreateInfo,
                                           const VkAllocationCallbacks* pAllocator, VkImage* pImage) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCreateImage, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCreateImage");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCreateImage]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCreateImage(device, pCreateInfo, pAllocator, pImage, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkCreateImage);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCreateImage");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCreateImage]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCreateImage(device, pCreateInfo, pAllocator, pImage, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkCreateImage");
        result = device_dispatch->CreateImage(device, pCreateInfo, pAllocator, pImage);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkCreateImage");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCreateImage]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCreateImage(device, pCreateInfo, pAllocator, pImage, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR void VKAPI_CALL DestroyImage(VkDevice device, VkImage image, const VkAllocationCallbacks* pAllocator) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkDestroyImage, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkDestroyImage");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateDestroyImage]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateDestroyImage(device, image, pAllocator, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkDestroyImage);
    {
        VVL_ZoneScopedN("PreCallRecord_vkDestroyImage");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordDestroyImage]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordDestroyImage(device, image, pAllocator, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkDestroyImage");
        device_dispatch->DestroyImage(device, image, pAllocator);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkDestroyImage");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordDestroyImage]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordDestroyImage(device, image, pAllocator, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL GetImageSubresourceLayout(VkDevice device, VkImage image, const VkImageSubresource* pSubresource,
                                                     VkSubresourceLayout* pLayout) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetImageSubresourceLayout, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetImageSubresourceLayout");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateGetImageSubresourceLayout]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateGetImageSubresourceLayout(device, image, pSubresource, pLayout, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetImageSubresourceLayout);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetImageSubresourceLayout");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordGetImageSubresourceLayout]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordGetImageSubresourceLayout(device, image, pSubresource, pLayout, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkGetImageSubresourceLayout");
        device_dispatch->GetImageSubresourceLayout(device, image, pSubresource, pLayout);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetImageSubresourceLayout");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordGetImageSubresourceLayout]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordGetImageSubresourceLayout(device, image, pSubresource, pLayout, record_obj);
        }
    }
}

VKAPI_ATTR VkResult VKAPI_CALL CreateImageView(VkDevice device, const VkImageViewCreateInfo* pCreateInfo,
                                               const VkAllocationCallbacks* pAllocator, VkImageView* pView) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCreateImageView, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCreateImageView");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCreateImageView]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCreateImageView(device, pCreateInfo, pAllocator, pView, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkCreateImageView);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCreateImageView");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCreateImageView]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCreateImageView(device, pCreateInfo, pAllocator, pView, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkCreateImageView");
        result = device_dispatch->CreateImageView(device, pCreateInfo, pAllocator, pView);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkCreateImageView");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCreateImageView]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCreateImageView(device, pCreateInfo, pAllocator, pView, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR void VKAPI_CALL DestroyImageView(VkDevice device, VkImageView imageView, const VkAllocationCallbacks* pAllocator) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkDestroyImageView, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkDestroyImageView");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateDestroyImageView]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateDestroyImageView(device, imageView, pAllocator, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkDestroyImageView);
    {
        VVL_ZoneScopedN("PreCallRecord_vkDestroyImageView");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordDestroyImageView]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordDestroyImageView(device, imageView, pAllocator, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkDestroyImageView");
        device_dispatch->DestroyImageView(device, imageView, pAllocator);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkDestroyImageView");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordDestroyImageView]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordDestroyImageView(device, imageView, pAllocator, record_obj);
        }
    }
}

VKAPI_ATTR VkResult VKAPI_CALL CreateCommandPool(VkDevice device, const VkCommandPoolCreateInfo* pCreateInfo,
                                                 const VkAllocationCallbacks* pAllocator, VkCommandPool* pCommandPool) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCreateCommandPool, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCreateCommandPool");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCreateCommandPool]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCreateCommandPool(device, pCreateInfo, pAllocator, pCommandPool, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkCreateCommandPool);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCreateCommandPool");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCreateCommandPool]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCreateCommandPool(device, pCreateInfo, pAllocator, pCommandPool, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkCreateCommandPool");
        result = device_dispatch->CreateCommandPool(device, pCreateInfo, pAllocator, pCommandPool);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkCreateCommandPool");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCreateCommandPool]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCreateCommandPool(device, pCreateInfo, pAllocator, pCommandPool, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR void VKAPI_CALL DestroyCommandPool(VkDevice device, VkCommandPool commandPool, const VkAllocationCallbacks* pAllocator) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkDestroyCommandPool, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkDestroyCommandPool");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateDestroyCommandPool]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateDestroyCommandPool(device, commandPool, pAllocator, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkDestroyCommandPool);
    {
        VVL_ZoneScopedN("PreCallRecord_vkDestroyCommandPool");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordDestroyCommandPool]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordDestroyCommandPool(device, commandPool, pAllocator, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkDestroyCommandPool");
        device_dispatch->DestroyCommandPool(device, commandPool, pAllocator);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkDestroyCommandPool");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordDestroyCommandPool]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordDestroyCommandPool(device, commandPool, pAllocator, record_obj);
        }
    }
}

VKAPI_ATTR VkResult VKAPI_CALL ResetCommandPool(VkDevice device, VkCommandPool commandPool, VkCommandPoolResetFlags flags) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkResetCommandPool, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkResetCommandPool");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateResetCommandPool]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateResetCommandPool(device, commandPool, flags, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkResetCommandPool);
    {
        VVL_ZoneScopedN("PreCallRecord_vkResetCommandPool");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordResetCommandPool]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordResetCommandPool(device, commandPool, flags, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkResetCommandPool");
        result = device_dispatch->ResetCommandPool(device, commandPool, flags);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkResetCommandPool");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordResetCommandPool]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordResetCommandPool(device, commandPool, flags, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR VkResult VKAPI_CALL AllocateCommandBuffers(VkDevice device, const VkCommandBufferAllocateInfo* pAllocateInfo,
                                                      VkCommandBuffer* pCommandBuffers) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkAllocateCommandBuffers, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkAllocateCommandBuffers");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateAllocateCommandBuffers]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateAllocateCommandBuffers(device, pAllocateInfo, pCommandBuffers, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkAllocateCommandBuffers);
    {
        VVL_ZoneScopedN("PreCallRecord_vkAllocateCommandBuffers");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordAllocateCommandBuffers]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordAllocateCommandBuffers(device, pAllocateInfo, pCommandBuffers, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkAllocateCommandBuffers");
        result = device_dispatch->AllocateCommandBuffers(device, pAllocateInfo, pCommandBuffers);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkAllocateCommandBuffers");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordAllocateCommandBuffers]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordAllocateCommandBuffers(device, pAllocateInfo, pCommandBuffers, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR void VKAPI_CALL FreeCommandBuffers(VkDevice device, VkCommandPool commandPool, uint32_t commandBufferCount,
                                              const VkCommandBuffer* pCommandBuffers) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkFreeCommandBuffers, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkFreeCommandBuffers");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateFreeCommandBuffers]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateFreeCommandBuffers(device, commandPool, commandBufferCount, pCommandBuffers, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkFreeCommandBuffers);
    {
        VVL_ZoneScopedN("PreCallRecord_vkFreeCommandBuffers");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordFreeCommandBuffers]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordFreeCommandBuffers(device, commandPool, commandBufferCount, pCommandBuffers, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkFreeCommandBuffers");
        device_dispatch->FreeCommandBuffers(device, commandPool, commandBufferCount, pCommandBuffers);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkFreeCommandBuffers");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordFreeCommandBuffers]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordFreeCommandBuffers(device, commandPool, commandBufferCount, pCommandBuffers, record_obj);
        }
    }
}

VKAPI_ATTR VkResult VKAPI_CALL EndCommandBuffer(VkCommandBuffer commandBuffer) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkEndCommandBuffer, VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkEndCommandBuffer");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateEndCommandBuffer]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateEndCommandBuffer(commandBuffer, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkEndCommandBuffer);
    {
        VVL_ZoneScopedN("PreCallRecord_vkEndCommandBuffer");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordEndCommandBuffer]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordEndCommandBuffer(commandBuffer, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkEndCommandBuffer");
        result = device_dispatch->EndCommandBuffer(commandBuffer);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkEndCommandBuffer");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordEndCommandBuffer]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordEndCommandBuffer(commandBuffer, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR VkResult VKAPI_CALL ResetCommandBuffer(VkCommandBuffer commandBuffer, VkCommandBufferResetFlags flags) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkResetCommandBuffer, VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkResetCommandBuffer");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateResetCommandBuffer]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateResetCommandBuffer(commandBuffer, flags, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkResetCommandBuffer);
    {
        VVL_ZoneScopedN("PreCallRecord_vkResetCommandBuffer");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordResetCommandBuffer]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordResetCommandBuffer(commandBuffer, flags, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkResetCommandBuffer");
        result = device_dispatch->ResetCommandBuffer(commandBuffer, flags);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkResetCommandBuffer");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordResetCommandBuffer]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordResetCommandBuffer(commandBuffer, flags, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR void VKAPI_CALL CmdCopyBuffer(VkCommandBuffer commandBuffer, VkBuffer srcBuffer, VkBuffer dstBuffer,
                                         uint32_t regionCount, const VkBufferCopy* pRegions) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdCopyBuffer, VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdCopyBuffer");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdCopyBuffer]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdCopyBuffer(commandBuffer, srcBuffer, dstBuffer, regionCount, pRegions, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdCopyBuffer);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdCopyBuffer");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdCopyBuffer]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdCopyBuffer(commandBuffer, srcBuffer, dstBuffer, regionCount, pRegions, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdCopyBuffer");
        device_dispatch->CmdCopyBuffer(commandBuffer, srcBuffer, dstBuffer, regionCount, pRegions);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdCopyBuffer");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdCopyBuffer]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdCopyBuffer(commandBuffer, srcBuffer, dstBuffer, regionCount, pRegions, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdCopyImage(VkCommandBuffer commandBuffer, VkImage srcImage, VkImageLayout srcImageLayout,
                                        VkImage dstImage, VkImageLayout dstImageLayout, uint32_t regionCount,
                                        const VkImageCopy* pRegions) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdCopyImage, VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdCopyImage");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdCopyImage]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdCopyImage(commandBuffer, srcImage, srcImageLayout, dstImage, dstImageLayout, regionCount,
                                                    pRegions, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdCopyImage);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdCopyImage");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdCopyImage]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdCopyImage(commandBuffer, srcImage, srcImageLayout, dstImage, dstImageLayout, regionCount, pRegions,
                                          record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdCopyImage");
        device_dispatch->CmdCopyImage(commandBuffer, srcImage, srcImageLayout, dstImage, dstImageLayout, regionCount, pRegions);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdCopyImage");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdCopyImage]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdCopyImage(commandBuffer, srcImage, srcImageLayout, dstImage, dstImageLayout, regionCount, pRegions,
                                           record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdCopyBufferToImage(VkCommandBuffer commandBuffer, VkBuffer srcBuffer, VkImage dstImage,
                                                VkImageLayout dstImageLayout, uint32_t regionCount,
                                                const VkBufferImageCopy* pRegions) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdCopyBufferToImage, VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdCopyBufferToImage");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdCopyBufferToImage]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdCopyBufferToImage(commandBuffer, srcBuffer, dstImage, dstImageLayout, regionCount,
                                                            pRegions, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdCopyBufferToImage);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdCopyBufferToImage");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdCopyBufferToImage]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdCopyBufferToImage(commandBuffer, srcBuffer, dstImage, dstImageLayout, regionCount, pRegions,
                                                  record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdCopyBufferToImage");
        device_dispatch->CmdCopyBufferToImage(commandBuffer, srcBuffer, dstImage, dstImageLayout, regionCount, pRegions);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdCopyBufferToImage");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdCopyBufferToImage]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdCopyBufferToImage(commandBuffer, srcBuffer, dstImage, dstImageLayout, regionCount, pRegions,
                                                   record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdCopyImageToBuffer(VkCommandBuffer commandBuffer, VkImage srcImage, VkImageLayout srcImageLayout,
                                                VkBuffer dstBuffer, uint32_t regionCount, const VkBufferImageCopy* pRegions) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdCopyImageToBuffer, VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdCopyImageToBuffer");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdCopyImageToBuffer]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdCopyImageToBuffer(commandBuffer, srcImage, srcImageLayout, dstBuffer, regionCount,
                                                            pRegions, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdCopyImageToBuffer);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdCopyImageToBuffer");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdCopyImageToBuffer]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdCopyImageToBuffer(commandBuffer, srcImage, srcImageLayout, dstBuffer, regionCount, pRegions,
                                                  record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdCopyImageToBuffer");
        device_dispatch->CmdCopyImageToBuffer(commandBuffer, srcImage, srcImageLayout, dstBuffer, regionCount, pRegions);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdCopyImageToBuffer");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdCopyImageToBuffer]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdCopyImageToBuffer(commandBuffer, srcImage, srcImageLayout, dstBuffer, regionCount, pRegions,
                                                   record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdUpdateBuffer(VkCommandBuffer commandBuffer, VkBuffer dstBuffer, VkDeviceSize dstOffset,
                                           VkDeviceSize dataSize, const void* pData) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdUpdateBuffer, VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdUpdateBuffer");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdUpdateBuffer]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdUpdateBuffer(commandBuffer, dstBuffer, dstOffset, dataSize, pData, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdUpdateBuffer);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdUpdateBuffer");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdUpdateBuffer]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdUpdateBuffer(commandBuffer, dstBuffer, dstOffset, dataSize, pData, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdUpdateBuffer");
        device_dispatch->CmdUpdateBuffer(commandBuffer, dstBuffer, dstOffset, dataSize, pData);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdUpdateBuffer");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdUpdateBuffer]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdUpdateBuffer(commandBuffer, dstBuffer, dstOffset, dataSize, pData, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdFillBuffer(VkCommandBuffer commandBuffer, VkBuffer dstBuffer, VkDeviceSize dstOffset,
                                         VkDeviceSize size, uint32_t data) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdFillBuffer, VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdFillBuffer");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdFillBuffer]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdFillBuffer(commandBuffer, dstBuffer, dstOffset, size, data, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdFillBuffer);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdFillBuffer");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdFillBuffer]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdFillBuffer(commandBuffer, dstBuffer, dstOffset, size, data, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdFillBuffer");
        device_dispatch->CmdFillBuffer(commandBuffer, dstBuffer, dstOffset, size, data);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdFillBuffer");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdFillBuffer]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdFillBuffer(commandBuffer, dstBuffer, dstOffset, size, data, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdPipelineBarrier(VkCommandBuffer commandBuffer, VkPipelineStageFlags srcStageMask,
                                              VkPipelineStageFlags dstStageMask, VkDependencyFlags dependencyFlags,
                                              uint32_t memoryBarrierCount, const VkMemoryBarrier* pMemoryBarriers,
                                              uint32_t bufferMemoryBarrierCount, const VkBufferMemoryBarrier* pBufferMemoryBarriers,
                                              uint32_t imageMemoryBarrierCount, const VkImageMemoryBarrier* pImageMemoryBarriers) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdPipelineBarrier, VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdPipelineBarrier");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdPipelineBarrier]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdPipelineBarrier(
                commandBuffer, srcStageMask, dstStageMask, dependencyFlags, memoryBarrierCount, pMemoryBarriers,
                bufferMemoryBarrierCount, pBufferMemoryBarriers, imageMemoryBarrierCount, pImageMemoryBarriers, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdPipelineBarrier);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdPipelineBarrier");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdPipelineBarrier]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdPipelineBarrier(commandBuffer, srcStageMask, dstStageMask, dependencyFlags, memoryBarrierCount,
                                                pMemoryBarriers, bufferMemoryBarrierCount, pBufferMemoryBarriers,
                                                imageMemoryBarrierCount, pImageMemoryBarriers, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdPipelineBarrier");
        device_dispatch->CmdPipelineBarrier(commandBuffer, srcStageMask, dstStageMask, dependencyFlags, memoryBarrierCount,
                                            pMemoryBarriers, bufferMemoryBarrierCount, pBufferMemoryBarriers,
                                            imageMemoryBarrierCount, pImageMemoryBarriers);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdPipelineBarrier");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdPipelineBarrier]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdPipelineBarrier(commandBuffer, srcStageMask, dstStageMask, dependencyFlags, memoryBarrierCount,
                                                 pMemoryBarriers, bufferMemoryBarrierCount, pBufferMemoryBarriers,
                                                 imageMemoryBarrierCount, pImageMemoryBarriers, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdBeginQuery(VkCommandBuffer commandBuffer, VkQueryPool queryPool, uint32_t query,
                                         VkQueryControlFlags flags) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdBeginQuery, VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdBeginQuery");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdBeginQuery]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdBeginQuery(commandBuffer, queryPool, query, flags, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdBeginQuery);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdBeginQuery");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdBeginQuery]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdBeginQuery(commandBuffer, queryPool, query, flags, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdBeginQuery");
        device_dispatch->CmdBeginQuery(commandBuffer, queryPool, query, flags);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdBeginQuery");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdBeginQuery]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdBeginQuery(commandBuffer, queryPool, query, flags, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdEndQuery(VkCommandBuffer commandBuffer, VkQueryPool queryPool, uint32_t query) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdEndQuery, VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdEndQuery");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdEndQuery]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdEndQuery(commandBuffer, queryPool, query, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdEndQuery);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdEndQuery");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdEndQuery]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdEndQuery(commandBuffer, queryPool, query, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdEndQuery");
        device_dispatch->CmdEndQuery(commandBuffer, queryPool, query);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdEndQuery");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdEndQuery]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdEndQuery(commandBuffer, queryPool, query, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdResetQueryPool(VkCommandBuffer commandBuffer, VkQueryPool queryPool, uint32_t firstQuery,
                                             uint32_t queryCount) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdResetQueryPool, VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdResetQueryPool");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdResetQueryPool]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdResetQueryPool(commandBuffer, queryPool, firstQuery, queryCount, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdResetQueryPool);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdResetQueryPool");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdResetQueryPool]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdResetQueryPool(commandBuffer, queryPool, firstQuery, queryCount, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdResetQueryPool");
        device_dispatch->CmdResetQueryPool(commandBuffer, queryPool, firstQuery, queryCount);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdResetQueryPool");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdResetQueryPool]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdResetQueryPool(commandBuffer, queryPool, firstQuery, queryCount, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdWriteTimestamp(VkCommandBuffer commandBuffer, VkPipelineStageFlagBits pipelineStage,
                                             VkQueryPool queryPool, uint32_t query) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdWriteTimestamp, VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdWriteTimestamp");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdWriteTimestamp]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdWriteTimestamp(commandBuffer, pipelineStage, queryPool, query, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdWriteTimestamp);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdWriteTimestamp");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdWriteTimestamp]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdWriteTimestamp(commandBuffer, pipelineStage, queryPool, query, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdWriteTimestamp");
        device_dispatch->CmdWriteTimestamp(commandBuffer, pipelineStage, queryPool, query);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdWriteTimestamp");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdWriteTimestamp]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdWriteTimestamp(commandBuffer, pipelineStage, queryPool, query, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdCopyQueryPoolResults(VkCommandBuffer commandBuffer, VkQueryPool queryPool, uint32_t firstQuery,
                                                   uint32_t queryCount, VkBuffer dstBuffer, VkDeviceSize dstOffset,
                                                   VkDeviceSize stride, VkQueryResultFlags flags) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdCopyQueryPoolResults, VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdCopyQueryPoolResults");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdCopyQueryPoolResults]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdCopyQueryPoolResults(commandBuffer, queryPool, firstQuery, queryCount, dstBuffer,
                                                               dstOffset, stride, flags, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdCopyQueryPoolResults);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdCopyQueryPoolResults");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdCopyQueryPoolResults]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdCopyQueryPoolResults(commandBuffer, queryPool, firstQuery, queryCount, dstBuffer, dstOffset, stride,
                                                     flags, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdCopyQueryPoolResults");
        device_dispatch->CmdCopyQueryPoolResults(commandBuffer, queryPool, firstQuery, queryCount, dstBuffer, dstOffset, stride,
                                                 flags);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdCopyQueryPoolResults");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdCopyQueryPoolResults]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdCopyQueryPoolResults(commandBuffer, queryPool, firstQuery, queryCount, dstBuffer, dstOffset,
                                                      stride, flags, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdExecuteCommands(VkCommandBuffer commandBuffer, uint32_t commandBufferCount,
                                              const VkCommandBuffer* pCommandBuffers) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdExecuteCommands, VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdExecuteCommands");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdExecuteCommands]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdExecuteCommands(commandBuffer, commandBufferCount, pCommandBuffers, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdExecuteCommands);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdExecuteCommands");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdExecuteCommands]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdExecuteCommands(commandBuffer, commandBufferCount, pCommandBuffers, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdExecuteCommands");
        device_dispatch->CmdExecuteCommands(commandBuffer, commandBufferCount, pCommandBuffers);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdExecuteCommands");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdExecuteCommands]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdExecuteCommands(commandBuffer, commandBufferCount, pCommandBuffers, record_obj);
        }
    }
}

VKAPI_ATTR VkResult VKAPI_CALL CreateEvent(VkDevice device, const VkEventCreateInfo* pCreateInfo,
                                           const VkAllocationCallbacks* pAllocator, VkEvent* pEvent) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCreateEvent, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCreateEvent");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCreateEvent]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCreateEvent(device, pCreateInfo, pAllocator, pEvent, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkCreateEvent);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCreateEvent");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCreateEvent]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCreateEvent(device, pCreateInfo, pAllocator, pEvent, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkCreateEvent");
        result = device_dispatch->CreateEvent(device, pCreateInfo, pAllocator, pEvent);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkCreateEvent");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCreateEvent]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCreateEvent(device, pCreateInfo, pAllocator, pEvent, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR void VKAPI_CALL DestroyEvent(VkDevice device, VkEvent event, const VkAllocationCallbacks* pAllocator) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkDestroyEvent, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkDestroyEvent");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateDestroyEvent]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateDestroyEvent(device, event, pAllocator, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkDestroyEvent);
    {
        VVL_ZoneScopedN("PreCallRecord_vkDestroyEvent");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordDestroyEvent]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordDestroyEvent(device, event, pAllocator, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkDestroyEvent");
        device_dispatch->DestroyEvent(device, event, pAllocator);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkDestroyEvent");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordDestroyEvent]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordDestroyEvent(device, event, pAllocator, record_obj);
        }
    }
}

VKAPI_ATTR VkResult VKAPI_CALL GetEventStatus(VkDevice device, VkEvent event) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetEventStatus, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetEventStatus");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateGetEventStatus]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateGetEventStatus(device, event, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetEventStatus);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetEventStatus");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordGetEventStatus]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordGetEventStatus(device, event, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkGetEventStatus");
        result = device_dispatch->GetEventStatus(device, event);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetEventStatus");

        if (result == VK_ERROR_DEVICE_LOST) {
            for (auto& vo : device_dispatch->object_dispatch) {
                vo->is_device_lost = true;
            }
        }
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordGetEventStatus]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordGetEventStatus(device, event, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR VkResult VKAPI_CALL SetEvent(VkDevice device, VkEvent event) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkSetEvent, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkSetEvent");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateSetEvent]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateSetEvent(device, event, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkSetEvent);
    {
        VVL_ZoneScopedN("PreCallRecord_vkSetEvent");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordSetEvent]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordSetEvent(device, event, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkSetEvent");
        result = device_dispatch->SetEvent(device, event);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkSetEvent");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordSetEvent]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordSetEvent(device, event, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR VkResult VKAPI_CALL ResetEvent(VkDevice device, VkEvent event) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkResetEvent, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkResetEvent");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateResetEvent]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateResetEvent(device, event, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkResetEvent);
    {
        VVL_ZoneScopedN("PreCallRecord_vkResetEvent");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordResetEvent]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordResetEvent(device, event, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkResetEvent");
        result = device_dispatch->ResetEvent(device, event);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkResetEvent");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordResetEvent]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordResetEvent(device, event, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR VkResult VKAPI_CALL CreateBufferView(VkDevice device, const VkBufferViewCreateInfo* pCreateInfo,
                                                const VkAllocationCallbacks* pAllocator, VkBufferView* pView) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCreateBufferView, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCreateBufferView");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCreateBufferView]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCreateBufferView(device, pCreateInfo, pAllocator, pView, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkCreateBufferView);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCreateBufferView");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCreateBufferView]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCreateBufferView(device, pCreateInfo, pAllocator, pView, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkCreateBufferView");
        result = device_dispatch->CreateBufferView(device, pCreateInfo, pAllocator, pView);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkCreateBufferView");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCreateBufferView]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCreateBufferView(device, pCreateInfo, pAllocator, pView, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR void VKAPI_CALL DestroyBufferView(VkDevice device, VkBufferView bufferView, const VkAllocationCallbacks* pAllocator) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkDestroyBufferView, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkDestroyBufferView");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateDestroyBufferView]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateDestroyBufferView(device, bufferView, pAllocator, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkDestroyBufferView);
    {
        VVL_ZoneScopedN("PreCallRecord_vkDestroyBufferView");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordDestroyBufferView]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordDestroyBufferView(device, bufferView, pAllocator, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkDestroyBufferView");
        device_dispatch->DestroyBufferView(device, bufferView, pAllocator);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkDestroyBufferView");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordDestroyBufferView]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordDestroyBufferView(device, bufferView, pAllocator, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL DestroyShaderModule(VkDevice device, VkShaderModule shaderModule,
                                               const VkAllocationCallbacks* pAllocator) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkDestroyShaderModule, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkDestroyShaderModule");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateDestroyShaderModule]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateDestroyShaderModule(device, shaderModule, pAllocator, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkDestroyShaderModule);
    {
        VVL_ZoneScopedN("PreCallRecord_vkDestroyShaderModule");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordDestroyShaderModule]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordDestroyShaderModule(device, shaderModule, pAllocator, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkDestroyShaderModule");
        device_dispatch->DestroyShaderModule(device, shaderModule, pAllocator);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkDestroyShaderModule");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordDestroyShaderModule]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordDestroyShaderModule(device, shaderModule, pAllocator, record_obj);
        }
    }
}

VKAPI_ATTR VkResult VKAPI_CALL CreatePipelineCache(VkDevice device, const VkPipelineCacheCreateInfo* pCreateInfo,
                                                   const VkAllocationCallbacks* pAllocator, VkPipelineCache* pPipelineCache) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCreatePipelineCache, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCreatePipelineCache");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCreatePipelineCache]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCreatePipelineCache(device, pCreateInfo, pAllocator, pPipelineCache, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkCreatePipelineCache);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCreatePipelineCache");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCreatePipelineCache]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCreatePipelineCache(device, pCreateInfo, pAllocator, pPipelineCache, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkCreatePipelineCache");
        result = device_dispatch->CreatePipelineCache(device, pCreateInfo, pAllocator, pPipelineCache);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkCreatePipelineCache");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCreatePipelineCache]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCreatePipelineCache(device, pCreateInfo, pAllocator, pPipelineCache, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR void VKAPI_CALL DestroyPipelineCache(VkDevice device, VkPipelineCache pipelineCache,
                                                const VkAllocationCallbacks* pAllocator) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkDestroyPipelineCache, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkDestroyPipelineCache");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateDestroyPipelineCache]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateDestroyPipelineCache(device, pipelineCache, pAllocator, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkDestroyPipelineCache);
    {
        VVL_ZoneScopedN("PreCallRecord_vkDestroyPipelineCache");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordDestroyPipelineCache]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordDestroyPipelineCache(device, pipelineCache, pAllocator, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkDestroyPipelineCache");
        device_dispatch->DestroyPipelineCache(device, pipelineCache, pAllocator);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkDestroyPipelineCache");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordDestroyPipelineCache]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordDestroyPipelineCache(device, pipelineCache, pAllocator, record_obj);
        }
    }
}

VKAPI_ATTR VkResult VKAPI_CALL GetPipelineCacheData(VkDevice device, VkPipelineCache pipelineCache, size_t* pDataSize,
                                                    void* pData) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetPipelineCacheData, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetPipelineCacheData");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateGetPipelineCacheData]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateGetPipelineCacheData(device, pipelineCache, pDataSize, pData, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetPipelineCacheData);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetPipelineCacheData");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordGetPipelineCacheData]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordGetPipelineCacheData(device, pipelineCache, pDataSize, pData, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkGetPipelineCacheData");
        result = device_dispatch->GetPipelineCacheData(device, pipelineCache, pDataSize, pData);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetPipelineCacheData");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordGetPipelineCacheData]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordGetPipelineCacheData(device, pipelineCache, pDataSize, pData, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR VkResult VKAPI_CALL MergePipelineCaches(VkDevice device, VkPipelineCache dstCache, uint32_t srcCacheCount,
                                                   const VkPipelineCache* pSrcCaches) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkMergePipelineCaches, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkMergePipelineCaches");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateMergePipelineCaches]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateMergePipelineCaches(device, dstCache, srcCacheCount, pSrcCaches, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkMergePipelineCaches);
    {
        VVL_ZoneScopedN("PreCallRecord_vkMergePipelineCaches");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordMergePipelineCaches]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordMergePipelineCaches(device, dstCache, srcCacheCount, pSrcCaches, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkMergePipelineCaches");
        result = device_dispatch->MergePipelineCaches(device, dstCache, srcCacheCount, pSrcCaches);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkMergePipelineCaches");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordMergePipelineCaches]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordMergePipelineCaches(device, dstCache, srcCacheCount, pSrcCaches, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR void VKAPI_CALL DestroyPipeline(VkDevice device, VkPipeline pipeline, const VkAllocationCallbacks* pAllocator) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkDestroyPipeline, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkDestroyPipeline");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateDestroyPipeline]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateDestroyPipeline(device, pipeline, pAllocator, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkDestroyPipeline);
    {
        VVL_ZoneScopedN("PreCallRecord_vkDestroyPipeline");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordDestroyPipeline]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordDestroyPipeline(device, pipeline, pAllocator, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkDestroyPipeline");
        device_dispatch->DestroyPipeline(device, pipeline, pAllocator);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkDestroyPipeline");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordDestroyPipeline]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordDestroyPipeline(device, pipeline, pAllocator, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL DestroyPipelineLayout(VkDevice device, VkPipelineLayout pipelineLayout,
                                                 const VkAllocationCallbacks* pAllocator) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkDestroyPipelineLayout, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkDestroyPipelineLayout");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateDestroyPipelineLayout]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateDestroyPipelineLayout(device, pipelineLayout, pAllocator, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkDestroyPipelineLayout);
    {
        VVL_ZoneScopedN("PreCallRecord_vkDestroyPipelineLayout");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordDestroyPipelineLayout]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordDestroyPipelineLayout(device, pipelineLayout, pAllocator, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkDestroyPipelineLayout");
        device_dispatch->DestroyPipelineLayout(device, pipelineLayout, pAllocator);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkDestroyPipelineLayout");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordDestroyPipelineLayout]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordDestroyPipelineLayout(device, pipelineLayout, pAllocator, record_obj);
        }
    }
}

VKAPI_ATTR VkResult VKAPI_CALL CreateSampler(VkDevice device, const VkSamplerCreateInfo* pCreateInfo,
                                             const VkAllocationCallbacks* pAllocator, VkSampler* pSampler) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCreateSampler, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCreateSampler");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCreateSampler]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCreateSampler(device, pCreateInfo, pAllocator, pSampler, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkCreateSampler);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCreateSampler");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCreateSampler]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCreateSampler(device, pCreateInfo, pAllocator, pSampler, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkCreateSampler");
        result = device_dispatch->CreateSampler(device, pCreateInfo, pAllocator, pSampler);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkCreateSampler");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCreateSampler]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCreateSampler(device, pCreateInfo, pAllocator, pSampler, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR void VKAPI_CALL DestroySampler(VkDevice device, VkSampler sampler, const VkAllocationCallbacks* pAllocator) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkDestroySampler, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkDestroySampler");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateDestroySampler]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateDestroySampler(device, sampler, pAllocator, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkDestroySampler);
    {
        VVL_ZoneScopedN("PreCallRecord_vkDestroySampler");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordDestroySampler]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordDestroySampler(device, sampler, pAllocator, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkDestroySampler");
        device_dispatch->DestroySampler(device, sampler, pAllocator);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkDestroySampler");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordDestroySampler]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordDestroySampler(device, sampler, pAllocator, record_obj);
        }
    }
}

VKAPI_ATTR VkResult VKAPI_CALL CreateDescriptorSetLayout(VkDevice device, const VkDescriptorSetLayoutCreateInfo* pCreateInfo,
                                                         const VkAllocationCallbacks* pAllocator,
                                                         VkDescriptorSetLayout* pSetLayout) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCreateDescriptorSetLayout, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCreateDescriptorSetLayout");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCreateDescriptorSetLayout]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCreateDescriptorSetLayout(device, pCreateInfo, pAllocator, pSetLayout, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkCreateDescriptorSetLayout);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCreateDescriptorSetLayout");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCreateDescriptorSetLayout]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCreateDescriptorSetLayout(device, pCreateInfo, pAllocator, pSetLayout, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkCreateDescriptorSetLayout");
        result = device_dispatch->CreateDescriptorSetLayout(device, pCreateInfo, pAllocator, pSetLayout);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkCreateDescriptorSetLayout");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCreateDescriptorSetLayout]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCreateDescriptorSetLayout(device, pCreateInfo, pAllocator, pSetLayout, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR void VKAPI_CALL DestroyDescriptorSetLayout(VkDevice device, VkDescriptorSetLayout descriptorSetLayout,
                                                      const VkAllocationCallbacks* pAllocator) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkDestroyDescriptorSetLayout, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkDestroyDescriptorSetLayout");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateDestroyDescriptorSetLayout]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateDestroyDescriptorSetLayout(device, descriptorSetLayout, pAllocator, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkDestroyDescriptorSetLayout);
    {
        VVL_ZoneScopedN("PreCallRecord_vkDestroyDescriptorSetLayout");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordDestroyDescriptorSetLayout]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordDestroyDescriptorSetLayout(device, descriptorSetLayout, pAllocator, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkDestroyDescriptorSetLayout");
        device_dispatch->DestroyDescriptorSetLayout(device, descriptorSetLayout, pAllocator);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkDestroyDescriptorSetLayout");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordDestroyDescriptorSetLayout]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordDestroyDescriptorSetLayout(device, descriptorSetLayout, pAllocator, record_obj);
        }
    }
}

VKAPI_ATTR VkResult VKAPI_CALL CreateDescriptorPool(VkDevice device, const VkDescriptorPoolCreateInfo* pCreateInfo,
                                                    const VkAllocationCallbacks* pAllocator, VkDescriptorPool* pDescriptorPool) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCreateDescriptorPool, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCreateDescriptorPool");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCreateDescriptorPool]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCreateDescriptorPool(device, pCreateInfo, pAllocator, pDescriptorPool, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkCreateDescriptorPool);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCreateDescriptorPool");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCreateDescriptorPool]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCreateDescriptorPool(device, pCreateInfo, pAllocator, pDescriptorPool, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkCreateDescriptorPool");
        result = device_dispatch->CreateDescriptorPool(device, pCreateInfo, pAllocator, pDescriptorPool);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkCreateDescriptorPool");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCreateDescriptorPool]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCreateDescriptorPool(device, pCreateInfo, pAllocator, pDescriptorPool, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR void VKAPI_CALL DestroyDescriptorPool(VkDevice device, VkDescriptorPool descriptorPool,
                                                 const VkAllocationCallbacks* pAllocator) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkDestroyDescriptorPool, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkDestroyDescriptorPool");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateDestroyDescriptorPool]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateDestroyDescriptorPool(device, descriptorPool, pAllocator, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkDestroyDescriptorPool);
    {
        VVL_ZoneScopedN("PreCallRecord_vkDestroyDescriptorPool");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordDestroyDescriptorPool]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordDestroyDescriptorPool(device, descriptorPool, pAllocator, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkDestroyDescriptorPool");
        device_dispatch->DestroyDescriptorPool(device, descriptorPool, pAllocator);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkDestroyDescriptorPool");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordDestroyDescriptorPool]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordDestroyDescriptorPool(device, descriptorPool, pAllocator, record_obj);
        }
    }
}

VKAPI_ATTR VkResult VKAPI_CALL ResetDescriptorPool(VkDevice device, VkDescriptorPool descriptorPool,
                                                   VkDescriptorPoolResetFlags flags) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkResetDescriptorPool, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkResetDescriptorPool");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateResetDescriptorPool]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateResetDescriptorPool(device, descriptorPool, flags, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkResetDescriptorPool);
    {
        VVL_ZoneScopedN("PreCallRecord_vkResetDescriptorPool");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordResetDescriptorPool]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordResetDescriptorPool(device, descriptorPool, flags, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkResetDescriptorPool");
        result = device_dispatch->ResetDescriptorPool(device, descriptorPool, flags);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkResetDescriptorPool");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordResetDescriptorPool]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordResetDescriptorPool(device, descriptorPool, flags, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR VkResult VKAPI_CALL FreeDescriptorSets(VkDevice device, VkDescriptorPool descriptorPool, uint32_t descriptorSetCount,
                                                  const VkDescriptorSet* pDescriptorSets) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkFreeDescriptorSets, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkFreeDescriptorSets");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateFreeDescriptorSets]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateFreeDescriptorSets(device, descriptorPool, descriptorSetCount, pDescriptorSets, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkFreeDescriptorSets);
    {
        VVL_ZoneScopedN("PreCallRecord_vkFreeDescriptorSets");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordFreeDescriptorSets]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordFreeDescriptorSets(device, descriptorPool, descriptorSetCount, pDescriptorSets, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkFreeDescriptorSets");
        result = device_dispatch->FreeDescriptorSets(device, descriptorPool, descriptorSetCount, pDescriptorSets);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkFreeDescriptorSets");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordFreeDescriptorSets]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordFreeDescriptorSets(device, descriptorPool, descriptorSetCount, pDescriptorSets, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR void VKAPI_CALL UpdateDescriptorSets(VkDevice device, uint32_t descriptorWriteCount,
                                                const VkWriteDescriptorSet* pDescriptorWrites, uint32_t descriptorCopyCount,
                                                const VkCopyDescriptorSet* pDescriptorCopies) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkUpdateDescriptorSets, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkUpdateDescriptorSets");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateUpdateDescriptorSets]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateUpdateDescriptorSets(device, descriptorWriteCount, pDescriptorWrites, descriptorCopyCount,
                                                            pDescriptorCopies, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkUpdateDescriptorSets);
    {
        VVL_ZoneScopedN("PreCallRecord_vkUpdateDescriptorSets");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordUpdateDescriptorSets]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordUpdateDescriptorSets(device, descriptorWriteCount, pDescriptorWrites, descriptorCopyCount,
                                                  pDescriptorCopies, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkUpdateDescriptorSets");
        device_dispatch->UpdateDescriptorSets(device, descriptorWriteCount, pDescriptorWrites, descriptorCopyCount,
                                              pDescriptorCopies);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkUpdateDescriptorSets");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordUpdateDescriptorSets]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordUpdateDescriptorSets(device, descriptorWriteCount, pDescriptorWrites, descriptorCopyCount,
                                                   pDescriptorCopies, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdBindPipeline(VkCommandBuffer commandBuffer, VkPipelineBindPoint pipelineBindPoint,
                                           VkPipeline pipeline) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdBindPipeline, VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdBindPipeline");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdBindPipeline]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdBindPipeline(commandBuffer, pipelineBindPoint, pipeline, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdBindPipeline);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdBindPipeline");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdBindPipeline]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdBindPipeline(commandBuffer, pipelineBindPoint, pipeline, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdBindPipeline");
        device_dispatch->CmdBindPipeline(commandBuffer, pipelineBindPoint, pipeline);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdBindPipeline");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdBindPipeline]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdBindPipeline(commandBuffer, pipelineBindPoint, pipeline, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdBindDescriptorSets(VkCommandBuffer commandBuffer, VkPipelineBindPoint pipelineBindPoint,
                                                 VkPipelineLayout layout, uint32_t firstSet, uint32_t descriptorSetCount,
                                                 const VkDescriptorSet* pDescriptorSets, uint32_t dynamicOffsetCount,
                                                 const uint32_t* pDynamicOffsets) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdBindDescriptorSets, VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdBindDescriptorSets");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdBindDescriptorSets]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdBindDescriptorSets(commandBuffer, pipelineBindPoint, layout, firstSet, descriptorSetCount,
                                                             pDescriptorSets, dynamicOffsetCount, pDynamicOffsets, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdBindDescriptorSets);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdBindDescriptorSets");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdBindDescriptorSets]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdBindDescriptorSets(commandBuffer, pipelineBindPoint, layout, firstSet, descriptorSetCount,
                                                   pDescriptorSets, dynamicOffsetCount, pDynamicOffsets, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdBindDescriptorSets");
        device_dispatch->CmdBindDescriptorSets(commandBuffer, pipelineBindPoint, layout, firstSet, descriptorSetCount,
                                               pDescriptorSets, dynamicOffsetCount, pDynamicOffsets);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdBindDescriptorSets");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdBindDescriptorSets]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdBindDescriptorSets(commandBuffer, pipelineBindPoint, layout, firstSet, descriptorSetCount,
                                                    pDescriptorSets, dynamicOffsetCount, pDynamicOffsets, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdClearColorImage(VkCommandBuffer commandBuffer, VkImage image, VkImageLayout imageLayout,
                                              const VkClearColorValue* pColor, uint32_t rangeCount,
                                              const VkImageSubresourceRange* pRanges) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdClearColorImage, VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdClearColorImage");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdClearColorImage]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |=
                vo->PreCallValidateCmdClearColorImage(commandBuffer, image, imageLayout, pColor, rangeCount, pRanges, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdClearColorImage);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdClearColorImage");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdClearColorImage]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdClearColorImage(commandBuffer, image, imageLayout, pColor, rangeCount, pRanges, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdClearColorImage");
        device_dispatch->CmdClearColorImage(commandBuffer, image, imageLayout, pColor, rangeCount, pRanges);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdClearColorImage");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdClearColorImage]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdClearColorImage(commandBuffer, image, imageLayout, pColor, rangeCount, pRanges, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdDispatch(VkCommandBuffer commandBuffer, uint32_t groupCountX, uint32_t groupCountY,
                                       uint32_t groupCountZ) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdDispatch, VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdDispatch");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdDispatch]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdDispatch(commandBuffer, groupCountX, groupCountY, groupCountZ, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdDispatch);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdDispatch");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdDispatch]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdDispatch(commandBuffer, groupCountX, groupCountY, groupCountZ, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdDispatch");
        device_dispatch->CmdDispatch(commandBuffer, groupCountX, groupCountY, groupCountZ);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdDispatch");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdDispatch]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdDispatch(commandBuffer, groupCountX, groupCountY, groupCountZ, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdDispatchIndirect(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdDispatchIndirect, VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdDispatchIndirect");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdDispatchIndirect]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdDispatchIndirect(commandBuffer, buffer, offset, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdDispatchIndirect);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdDispatchIndirect");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdDispatchIndirect]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdDispatchIndirect(commandBuffer, buffer, offset, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdDispatchIndirect");
        device_dispatch->CmdDispatchIndirect(commandBuffer, buffer, offset);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdDispatchIndirect");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdDispatchIndirect]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdDispatchIndirect(commandBuffer, buffer, offset, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdSetEvent(VkCommandBuffer commandBuffer, VkEvent event, VkPipelineStageFlags stageMask) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdSetEvent, VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdSetEvent");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdSetEvent]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdSetEvent(commandBuffer, event, stageMask, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdSetEvent);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdSetEvent");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdSetEvent]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdSetEvent(commandBuffer, event, stageMask, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdSetEvent");
        device_dispatch->CmdSetEvent(commandBuffer, event, stageMask);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdSetEvent");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdSetEvent]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdSetEvent(commandBuffer, event, stageMask, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdResetEvent(VkCommandBuffer commandBuffer, VkEvent event, VkPipelineStageFlags stageMask) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdResetEvent, VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdResetEvent");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdResetEvent]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdResetEvent(commandBuffer, event, stageMask, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdResetEvent);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdResetEvent");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdResetEvent]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdResetEvent(commandBuffer, event, stageMask, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdResetEvent");
        device_dispatch->CmdResetEvent(commandBuffer, event, stageMask);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdResetEvent");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdResetEvent]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdResetEvent(commandBuffer, event, stageMask, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdWaitEvents(VkCommandBuffer commandBuffer, uint32_t eventCount, const VkEvent* pEvents,
                                         VkPipelineStageFlags srcStageMask, VkPipelineStageFlags dstStageMask,
                                         uint32_t memoryBarrierCount, const VkMemoryBarrier* pMemoryBarriers,
                                         uint32_t bufferMemoryBarrierCount, const VkBufferMemoryBarrier* pBufferMemoryBarriers,
                                         uint32_t imageMemoryBarrierCount, const VkImageMemoryBarrier* pImageMemoryBarriers) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdWaitEvents, VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdWaitEvents");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdWaitEvents]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdWaitEvents(
                commandBuffer, eventCount, pEvents, srcStageMask, dstStageMask, memoryBarrierCount, pMemoryBarriers,
                bufferMemoryBarrierCount, pBufferMemoryBarriers, imageMemoryBarrierCount, pImageMemoryBarriers, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdWaitEvents);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdWaitEvents");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdWaitEvents]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdWaitEvents(commandBuffer, eventCount, pEvents, srcStageMask, dstStageMask, memoryBarrierCount,
                                           pMemoryBarriers, bufferMemoryBarrierCount, pBufferMemoryBarriers,
                                           imageMemoryBarrierCount, pImageMemoryBarriers, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdWaitEvents");
        device_dispatch->CmdWaitEvents(commandBuffer, eventCount, pEvents, srcStageMask, dstStageMask, memoryBarrierCount,
                                       pMemoryBarriers, bufferMemoryBarrierCount, pBufferMemoryBarriers, imageMemoryBarrierCount,
                                       pImageMemoryBarriers);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdWaitEvents");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdWaitEvents]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdWaitEvents(commandBuffer, eventCount, pEvents, srcStageMask, dstStageMask, memoryBarrierCount,
                                            pMemoryBarriers, bufferMemoryBarrierCount, pBufferMemoryBarriers,
                                            imageMemoryBarrierCount, pImageMemoryBarriers, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdPushConstants(VkCommandBuffer commandBuffer, VkPipelineLayout layout, VkShaderStageFlags stageFlags,
                                            uint32_t offset, uint32_t size, const void* pValues) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdPushConstants, VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdPushConstants");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdPushConstants]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdPushConstants(commandBuffer, layout, stageFlags, offset, size, pValues, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdPushConstants);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdPushConstants");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdPushConstants]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdPushConstants(commandBuffer, layout, stageFlags, offset, size, pValues, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdPushConstants");
        device_dispatch->CmdPushConstants(commandBuffer, layout, stageFlags, offset, size, pValues);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdPushConstants");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdPushConstants]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdPushConstants(commandBuffer, layout, stageFlags, offset, size, pValues, record_obj);
        }
    }
}

VKAPI_ATTR VkResult VKAPI_CALL CreateFramebuffer(VkDevice device, const VkFramebufferCreateInfo* pCreateInfo,
                                                 const VkAllocationCallbacks* pAllocator, VkFramebuffer* pFramebuffer) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCreateFramebuffer, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCreateFramebuffer");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCreateFramebuffer]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCreateFramebuffer(device, pCreateInfo, pAllocator, pFramebuffer, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkCreateFramebuffer);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCreateFramebuffer");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCreateFramebuffer]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCreateFramebuffer(device, pCreateInfo, pAllocator, pFramebuffer, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkCreateFramebuffer");
        result = device_dispatch->CreateFramebuffer(device, pCreateInfo, pAllocator, pFramebuffer);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkCreateFramebuffer");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCreateFramebuffer]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCreateFramebuffer(device, pCreateInfo, pAllocator, pFramebuffer, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR void VKAPI_CALL DestroyFramebuffer(VkDevice device, VkFramebuffer framebuffer, const VkAllocationCallbacks* pAllocator) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkDestroyFramebuffer, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkDestroyFramebuffer");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateDestroyFramebuffer]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateDestroyFramebuffer(device, framebuffer, pAllocator, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkDestroyFramebuffer);
    {
        VVL_ZoneScopedN("PreCallRecord_vkDestroyFramebuffer");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordDestroyFramebuffer]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordDestroyFramebuffer(device, framebuffer, pAllocator, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkDestroyFramebuffer");
        device_dispatch->DestroyFramebuffer(device, framebuffer, pAllocator);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkDestroyFramebuffer");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordDestroyFramebuffer]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordDestroyFramebuffer(device, framebuffer, pAllocator, record_obj);
        }
    }
}

VKAPI_ATTR VkResult VKAPI_CALL CreateRenderPass(VkDevice device, const VkRenderPassCreateInfo* pCreateInfo,
                                                const VkAllocationCallbacks* pAllocator, VkRenderPass* pRenderPass) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCreateRenderPass, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCreateRenderPass");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCreateRenderPass]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCreateRenderPass(device, pCreateInfo, pAllocator, pRenderPass, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkCreateRenderPass);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCreateRenderPass");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCreateRenderPass]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCreateRenderPass(device, pCreateInfo, pAllocator, pRenderPass, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkCreateRenderPass");
        result = device_dispatch->CreateRenderPass(device, pCreateInfo, pAllocator, pRenderPass);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkCreateRenderPass");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCreateRenderPass]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCreateRenderPass(device, pCreateInfo, pAllocator, pRenderPass, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR void VKAPI_CALL DestroyRenderPass(VkDevice device, VkRenderPass renderPass, const VkAllocationCallbacks* pAllocator) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkDestroyRenderPass, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkDestroyRenderPass");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateDestroyRenderPass]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateDestroyRenderPass(device, renderPass, pAllocator, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkDestroyRenderPass);
    {
        VVL_ZoneScopedN("PreCallRecord_vkDestroyRenderPass");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordDestroyRenderPass]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordDestroyRenderPass(device, renderPass, pAllocator, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkDestroyRenderPass");
        device_dispatch->DestroyRenderPass(device, renderPass, pAllocator);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkDestroyRenderPass");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordDestroyRenderPass]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordDestroyRenderPass(device, renderPass, pAllocator, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL GetRenderAreaGranularity(VkDevice device, VkRenderPass renderPass, VkExtent2D* pGranularity) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetRenderAreaGranularity, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetRenderAreaGranularity");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateGetRenderAreaGranularity]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateGetRenderAreaGranularity(device, renderPass, pGranularity, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetRenderAreaGranularity);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetRenderAreaGranularity");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordGetRenderAreaGranularity]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordGetRenderAreaGranularity(device, renderPass, pGranularity, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkGetRenderAreaGranularity");
        device_dispatch->GetRenderAreaGranularity(device, renderPass, pGranularity);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetRenderAreaGranularity");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordGetRenderAreaGranularity]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordGetRenderAreaGranularity(device, renderPass, pGranularity, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdSetViewport(VkCommandBuffer commandBuffer, uint32_t firstViewport, uint32_t viewportCount,
                                          const VkViewport* pViewports) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdSetViewport, VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdSetViewport");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdSetViewport]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdSetViewport(commandBuffer, firstViewport, viewportCount, pViewports, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdSetViewport);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdSetViewport");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdSetViewport]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdSetViewport(commandBuffer, firstViewport, viewportCount, pViewports, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdSetViewport");
        device_dispatch->CmdSetViewport(commandBuffer, firstViewport, viewportCount, pViewports);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdSetViewport");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdSetViewport]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdSetViewport(commandBuffer, firstViewport, viewportCount, pViewports, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdSetScissor(VkCommandBuffer commandBuffer, uint32_t firstScissor, uint32_t scissorCount,
                                         const VkRect2D* pScissors) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdSetScissor, VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdSetScissor");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdSetScissor]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdSetScissor(commandBuffer, firstScissor, scissorCount, pScissors, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdSetScissor);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdSetScissor");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdSetScissor]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdSetScissor(commandBuffer, firstScissor, scissorCount, pScissors, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdSetScissor");
        device_dispatch->CmdSetScissor(commandBuffer, firstScissor, scissorCount, pScissors);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdSetScissor");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdSetScissor]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdSetScissor(commandBuffer, firstScissor, scissorCount, pScissors, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdSetLineWidth(VkCommandBuffer commandBuffer, float lineWidth) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdSetLineWidth, VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdSetLineWidth");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdSetLineWidth]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdSetLineWidth(commandBuffer, lineWidth, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdSetLineWidth);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdSetLineWidth");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdSetLineWidth]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdSetLineWidth(commandBuffer, lineWidth, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdSetLineWidth");
        device_dispatch->CmdSetLineWidth(commandBuffer, lineWidth);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdSetLineWidth");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdSetLineWidth]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdSetLineWidth(commandBuffer, lineWidth, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdSetDepthBias(VkCommandBuffer commandBuffer, float depthBiasConstantFactor, float depthBiasClamp,
                                           float depthBiasSlopeFactor) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdSetDepthBias, VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdSetDepthBias");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdSetDepthBias]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdSetDepthBias(commandBuffer, depthBiasConstantFactor, depthBiasClamp, depthBiasSlopeFactor,
                                                       error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdSetDepthBias);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdSetDepthBias");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdSetDepthBias]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdSetDepthBias(commandBuffer, depthBiasConstantFactor, depthBiasClamp, depthBiasSlopeFactor,
                                             record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdSetDepthBias");
        device_dispatch->CmdSetDepthBias(commandBuffer, depthBiasConstantFactor, depthBiasClamp, depthBiasSlopeFactor);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdSetDepthBias");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdSetDepthBias]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdSetDepthBias(commandBuffer, depthBiasConstantFactor, depthBiasClamp, depthBiasSlopeFactor,
                                              record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdSetBlendConstants(VkCommandBuffer commandBuffer, const float blendConstants[4]) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdSetBlendConstants, VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdSetBlendConstants");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdSetBlendConstants]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdSetBlendConstants(commandBuffer, blendConstants, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdSetBlendConstants);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdSetBlendConstants");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdSetBlendConstants]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdSetBlendConstants(commandBuffer, blendConstants, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdSetBlendConstants");
        device_dispatch->CmdSetBlendConstants(commandBuffer, blendConstants);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdSetBlendConstants");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdSetBlendConstants]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdSetBlendConstants(commandBuffer, blendConstants, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdSetDepthBounds(VkCommandBuffer commandBuffer, float minDepthBounds, float maxDepthBounds) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdSetDepthBounds, VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdSetDepthBounds");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdSetDepthBounds]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdSetDepthBounds(commandBuffer, minDepthBounds, maxDepthBounds, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdSetDepthBounds);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdSetDepthBounds");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdSetDepthBounds]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdSetDepthBounds(commandBuffer, minDepthBounds, maxDepthBounds, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdSetDepthBounds");
        device_dispatch->CmdSetDepthBounds(commandBuffer, minDepthBounds, maxDepthBounds);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdSetDepthBounds");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdSetDepthBounds]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdSetDepthBounds(commandBuffer, minDepthBounds, maxDepthBounds, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdSetStencilCompareMask(VkCommandBuffer commandBuffer, VkStencilFaceFlags faceMask,
                                                    uint32_t compareMask) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdSetStencilCompareMask, VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdSetStencilCompareMask");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdSetStencilCompareMask]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdSetStencilCompareMask(commandBuffer, faceMask, compareMask, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdSetStencilCompareMask);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdSetStencilCompareMask");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdSetStencilCompareMask]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdSetStencilCompareMask(commandBuffer, faceMask, compareMask, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdSetStencilCompareMask");
        device_dispatch->CmdSetStencilCompareMask(commandBuffer, faceMask, compareMask);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdSetStencilCompareMask");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdSetStencilCompareMask]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdSetStencilCompareMask(commandBuffer, faceMask, compareMask, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdSetStencilWriteMask(VkCommandBuffer commandBuffer, VkStencilFaceFlags faceMask, uint32_t writeMask) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdSetStencilWriteMask, VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdSetStencilWriteMask");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdSetStencilWriteMask]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdSetStencilWriteMask(commandBuffer, faceMask, writeMask, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdSetStencilWriteMask);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdSetStencilWriteMask");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdSetStencilWriteMask]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdSetStencilWriteMask(commandBuffer, faceMask, writeMask, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdSetStencilWriteMask");
        device_dispatch->CmdSetStencilWriteMask(commandBuffer, faceMask, writeMask);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdSetStencilWriteMask");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdSetStencilWriteMask]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdSetStencilWriteMask(commandBuffer, faceMask, writeMask, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdSetStencilReference(VkCommandBuffer commandBuffer, VkStencilFaceFlags faceMask, uint32_t reference) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdSetStencilReference, VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdSetStencilReference");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdSetStencilReference]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdSetStencilReference(commandBuffer, faceMask, reference, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdSetStencilReference);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdSetStencilReference");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdSetStencilReference]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdSetStencilReference(commandBuffer, faceMask, reference, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdSetStencilReference");
        device_dispatch->CmdSetStencilReference(commandBuffer, faceMask, reference);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdSetStencilReference");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdSetStencilReference]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdSetStencilReference(commandBuffer, faceMask, reference, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdBindIndexBuffer(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
                                              VkIndexType indexType) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdBindIndexBuffer, VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdBindIndexBuffer");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdBindIndexBuffer]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdBindIndexBuffer(commandBuffer, buffer, offset, indexType, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdBindIndexBuffer);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdBindIndexBuffer");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdBindIndexBuffer]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdBindIndexBuffer(commandBuffer, buffer, offset, indexType, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdBindIndexBuffer");
        device_dispatch->CmdBindIndexBuffer(commandBuffer, buffer, offset, indexType);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdBindIndexBuffer");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdBindIndexBuffer]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdBindIndexBuffer(commandBuffer, buffer, offset, indexType, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdBindVertexBuffers(VkCommandBuffer commandBuffer, uint32_t firstBinding, uint32_t bindingCount,
                                                const VkBuffer* pBuffers, const VkDeviceSize* pOffsets) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdBindVertexBuffers, VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdBindVertexBuffers");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdBindVertexBuffers]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |=
                vo->PreCallValidateCmdBindVertexBuffers(commandBuffer, firstBinding, bindingCount, pBuffers, pOffsets, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdBindVertexBuffers);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdBindVertexBuffers");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdBindVertexBuffers]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdBindVertexBuffers(commandBuffer, firstBinding, bindingCount, pBuffers, pOffsets, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdBindVertexBuffers");
        device_dispatch->CmdBindVertexBuffers(commandBuffer, firstBinding, bindingCount, pBuffers, pOffsets);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdBindVertexBuffers");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdBindVertexBuffers]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdBindVertexBuffers(commandBuffer, firstBinding, bindingCount, pBuffers, pOffsets, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdDraw(VkCommandBuffer commandBuffer, uint32_t vertexCount, uint32_t instanceCount,
                                   uint32_t firstVertex, uint32_t firstInstance) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdDraw, VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdDraw");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdDraw]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdDraw(commandBuffer, vertexCount, instanceCount, firstVertex, firstInstance, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdDraw);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdDraw");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdDraw]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdDraw(commandBuffer, vertexCount, instanceCount, firstVertex, firstInstance, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdDraw");
        device_dispatch->CmdDraw(commandBuffer, vertexCount, instanceCount, firstVertex, firstInstance);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdDraw");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdDraw]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdDraw(commandBuffer, vertexCount, instanceCount, firstVertex, firstInstance, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdDrawIndexed(VkCommandBuffer commandBuffer, uint32_t indexCount, uint32_t instanceCount,
                                          uint32_t firstIndex, int32_t vertexOffset, uint32_t firstInstance) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdDrawIndexed, VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdDrawIndexed");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdDrawIndexed]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdDrawIndexed(commandBuffer, indexCount, instanceCount, firstIndex, vertexOffset,
                                                      firstInstance, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdDrawIndexed);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdDrawIndexed");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdDrawIndexed]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdDrawIndexed(commandBuffer, indexCount, instanceCount, firstIndex, vertexOffset, firstInstance,
                                            record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdDrawIndexed");
        device_dispatch->CmdDrawIndexed(commandBuffer, indexCount, instanceCount, firstIndex, vertexOffset, firstInstance);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdDrawIndexed");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdDrawIndexed]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdDrawIndexed(commandBuffer, indexCount, instanceCount, firstIndex, vertexOffset, firstInstance,
                                             record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdDrawIndirect(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, uint32_t drawCount,
                                           uint32_t stride) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdDrawIndirect, VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdDrawIndirect");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdDrawIndirect]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdDrawIndirect(commandBuffer, buffer, offset, drawCount, stride, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdDrawIndirect);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdDrawIndirect");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdDrawIndirect]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdDrawIndirect(commandBuffer, buffer, offset, drawCount, stride, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdDrawIndirect");
        device_dispatch->CmdDrawIndirect(commandBuffer, buffer, offset, drawCount, stride);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdDrawIndirect");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdDrawIndirect]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdDrawIndirect(commandBuffer, buffer, offset, drawCount, stride, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdDrawIndexedIndirect(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
                                                  uint32_t drawCount, uint32_t stride) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdDrawIndexedIndirect, VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdDrawIndexedIndirect");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdDrawIndexedIndirect]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdDrawIndexedIndirect(commandBuffer, buffer, offset, drawCount, stride, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdDrawIndexedIndirect);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdDrawIndexedIndirect");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdDrawIndexedIndirect]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdDrawIndexedIndirect(commandBuffer, buffer, offset, drawCount, stride, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdDrawIndexedIndirect");
        device_dispatch->CmdDrawIndexedIndirect(commandBuffer, buffer, offset, drawCount, stride);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdDrawIndexedIndirect");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdDrawIndexedIndirect]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdDrawIndexedIndirect(commandBuffer, buffer, offset, drawCount, stride, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdBlitImage(VkCommandBuffer commandBuffer, VkImage srcImage, VkImageLayout srcImageLayout,
                                        VkImage dstImage, VkImageLayout dstImageLayout, uint32_t regionCount,
                                        const VkImageBlit* pRegions, VkFilter filter) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdBlitImage, VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdBlitImage");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdBlitImage]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdBlitImage(commandBuffer, srcImage, srcImageLayout, dstImage, dstImageLayout, regionCount,
                                                    pRegions, filter, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdBlitImage);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdBlitImage");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdBlitImage]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdBlitImage(commandBuffer, srcImage, srcImageLayout, dstImage, dstImageLayout, regionCount, pRegions,
                                          filter, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdBlitImage");
        device_dispatch->CmdBlitImage(commandBuffer, srcImage, srcImageLayout, dstImage, dstImageLayout, regionCount, pRegions,
                                      filter);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdBlitImage");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdBlitImage]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdBlitImage(commandBuffer, srcImage, srcImageLayout, dstImage, dstImageLayout, regionCount, pRegions,
                                           filter, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdClearDepthStencilImage(VkCommandBuffer commandBuffer, VkImage image, VkImageLayout imageLayout,
                                                     const VkClearDepthStencilValue* pDepthStencil, uint32_t rangeCount,
                                                     const VkImageSubresourceRange* pRanges) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdClearDepthStencilImage, VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdClearDepthStencilImage");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdClearDepthStencilImage]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdClearDepthStencilImage(commandBuffer, image, imageLayout, pDepthStencil, rangeCount,
                                                                 pRanges, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdClearDepthStencilImage);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdClearDepthStencilImage");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdClearDepthStencilImage]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdClearDepthStencilImage(commandBuffer, image, imageLayout, pDepthStencil, rangeCount, pRanges,
                                                       record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdClearDepthStencilImage");
        device_dispatch->CmdClearDepthStencilImage(commandBuffer, image, imageLayout, pDepthStencil, rangeCount, pRanges);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdClearDepthStencilImage");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdClearDepthStencilImage]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdClearDepthStencilImage(commandBuffer, image, imageLayout, pDepthStencil, rangeCount, pRanges,
                                                        record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdClearAttachments(VkCommandBuffer commandBuffer, uint32_t attachmentCount,
                                               const VkClearAttachment* pAttachments, uint32_t rectCount,
                                               const VkClearRect* pRects) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdClearAttachments, VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdClearAttachments");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdClearAttachments]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |=
                vo->PreCallValidateCmdClearAttachments(commandBuffer, attachmentCount, pAttachments, rectCount, pRects, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdClearAttachments);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdClearAttachments");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdClearAttachments]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdClearAttachments(commandBuffer, attachmentCount, pAttachments, rectCount, pRects, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdClearAttachments");
        device_dispatch->CmdClearAttachments(commandBuffer, attachmentCount, pAttachments, rectCount, pRects);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdClearAttachments");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdClearAttachments]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdClearAttachments(commandBuffer, attachmentCount, pAttachments, rectCount, pRects, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdResolveImage(VkCommandBuffer commandBuffer, VkImage srcImage, VkImageLayout srcImageLayout,
                                           VkImage dstImage, VkImageLayout dstImageLayout, uint32_t regionCount,
                                           const VkImageResolve* pRegions) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdResolveImage, VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdResolveImage");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdResolveImage]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdResolveImage(commandBuffer, srcImage, srcImageLayout, dstImage, dstImageLayout,
                                                       regionCount, pRegions, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdResolveImage);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdResolveImage");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdResolveImage]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdResolveImage(commandBuffer, srcImage, srcImageLayout, dstImage, dstImageLayout, regionCount,
                                             pRegions, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdResolveImage");
        device_dispatch->CmdResolveImage(commandBuffer, srcImage, srcImageLayout, dstImage, dstImageLayout, regionCount, pRegions);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdResolveImage");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdResolveImage]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdResolveImage(commandBuffer, srcImage, srcImageLayout, dstImage, dstImageLayout, regionCount,
                                              pRegions, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdBeginRenderPass(VkCommandBuffer commandBuffer, const VkRenderPassBeginInfo* pRenderPassBegin,
                                              VkSubpassContents contents) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdBeginRenderPass, VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdBeginRenderPass");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdBeginRenderPass]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdBeginRenderPass(commandBuffer, pRenderPassBegin, contents, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdBeginRenderPass);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdBeginRenderPass");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdBeginRenderPass]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdBeginRenderPass(commandBuffer, pRenderPassBegin, contents, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdBeginRenderPass");
        device_dispatch->CmdBeginRenderPass(commandBuffer, pRenderPassBegin, contents);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdBeginRenderPass");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdBeginRenderPass]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdBeginRenderPass(commandBuffer, pRenderPassBegin, contents, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdNextSubpass(VkCommandBuffer commandBuffer, VkSubpassContents contents) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdNextSubpass, VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdNextSubpass");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdNextSubpass]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdNextSubpass(commandBuffer, contents, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdNextSubpass);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdNextSubpass");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdNextSubpass]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdNextSubpass(commandBuffer, contents, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdNextSubpass");
        device_dispatch->CmdNextSubpass(commandBuffer, contents);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdNextSubpass");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdNextSubpass]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdNextSubpass(commandBuffer, contents, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdEndRenderPass(VkCommandBuffer commandBuffer) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdEndRenderPass, VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdEndRenderPass");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdEndRenderPass]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdEndRenderPass(commandBuffer, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdEndRenderPass);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdEndRenderPass");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdEndRenderPass]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdEndRenderPass(commandBuffer, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdEndRenderPass");
        device_dispatch->CmdEndRenderPass(commandBuffer);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdEndRenderPass");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdEndRenderPass]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdEndRenderPass(commandBuffer, record_obj);
        }
    }
}

VKAPI_ATTR VkResult VKAPI_CALL BindBufferMemory2(VkDevice device, uint32_t bindInfoCount,
                                                 const VkBindBufferMemoryInfo* pBindInfos) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkBindBufferMemory2, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkBindBufferMemory2");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateBindBufferMemory2]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateBindBufferMemory2(device, bindInfoCount, pBindInfos, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkBindBufferMemory2);
    {
        VVL_ZoneScopedN("PreCallRecord_vkBindBufferMemory2");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordBindBufferMemory2]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordBindBufferMemory2(device, bindInfoCount, pBindInfos, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkBindBufferMemory2");
        result = device_dispatch->BindBufferMemory2(device, bindInfoCount, pBindInfos);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkBindBufferMemory2");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordBindBufferMemory2]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordBindBufferMemory2(device, bindInfoCount, pBindInfos, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR VkResult VKAPI_CALL BindImageMemory2(VkDevice device, uint32_t bindInfoCount, const VkBindImageMemoryInfo* pBindInfos) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkBindImageMemory2, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkBindImageMemory2");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateBindImageMemory2]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateBindImageMemory2(device, bindInfoCount, pBindInfos, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkBindImageMemory2);
    {
        VVL_ZoneScopedN("PreCallRecord_vkBindImageMemory2");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordBindImageMemory2]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordBindImageMemory2(device, bindInfoCount, pBindInfos, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkBindImageMemory2");
        result = device_dispatch->BindImageMemory2(device, bindInfoCount, pBindInfos);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkBindImageMemory2");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordBindImageMemory2]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordBindImageMemory2(device, bindInfoCount, pBindInfos, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR void VKAPI_CALL GetDeviceGroupPeerMemoryFeatures(VkDevice device, uint32_t heapIndex, uint32_t localDeviceIndex,
                                                            uint32_t remoteDeviceIndex,
                                                            VkPeerMemoryFeatureFlags* pPeerMemoryFeatures) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetDeviceGroupPeerMemoryFeatures, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetDeviceGroupPeerMemoryFeatures");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateGetDeviceGroupPeerMemoryFeatures]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateGetDeviceGroupPeerMemoryFeatures(device, heapIndex, localDeviceIndex, remoteDeviceIndex,
                                                                        pPeerMemoryFeatures, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetDeviceGroupPeerMemoryFeatures);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetDeviceGroupPeerMemoryFeatures");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordGetDeviceGroupPeerMemoryFeatures]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordGetDeviceGroupPeerMemoryFeatures(device, heapIndex, localDeviceIndex, remoteDeviceIndex,
                                                              pPeerMemoryFeatures, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkGetDeviceGroupPeerMemoryFeatures");
        device_dispatch->GetDeviceGroupPeerMemoryFeatures(device, heapIndex, localDeviceIndex, remoteDeviceIndex,
                                                          pPeerMemoryFeatures);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetDeviceGroupPeerMemoryFeatures");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordGetDeviceGroupPeerMemoryFeatures]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordGetDeviceGroupPeerMemoryFeatures(device, heapIndex, localDeviceIndex, remoteDeviceIndex,
                                                               pPeerMemoryFeatures, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdSetDeviceMask(VkCommandBuffer commandBuffer, uint32_t deviceMask) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdSetDeviceMask, VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdSetDeviceMask");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdSetDeviceMask]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdSetDeviceMask(commandBuffer, deviceMask, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdSetDeviceMask);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdSetDeviceMask");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdSetDeviceMask]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdSetDeviceMask(commandBuffer, deviceMask, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdSetDeviceMask");
        device_dispatch->CmdSetDeviceMask(commandBuffer, deviceMask);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdSetDeviceMask");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdSetDeviceMask]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdSetDeviceMask(commandBuffer, deviceMask, record_obj);
        }
    }
}

VKAPI_ATTR VkResult VKAPI_CALL EnumeratePhysicalDeviceGroups(VkInstance instance, uint32_t* pPhysicalDeviceGroupCount,
                                                             VkPhysicalDeviceGroupProperties* pPhysicalDeviceGroupProperties) {
    VVL_ZoneScoped;

    auto instance_dispatch = vvl::dispatch::GetData(instance);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkEnumeratePhysicalDeviceGroups, VulkanTypedHandle(instance, kVulkanObjectTypeInstance));
    {
        VVL_ZoneScopedN("PreCallValidate_vkEnumeratePhysicalDeviceGroups");
        for (const auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            skip |= vo->PreCallValidateEnumeratePhysicalDeviceGroups(instance, pPhysicalDeviceGroupCount,
                                                                     pPhysicalDeviceGroupProperties, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkEnumeratePhysicalDeviceGroups);
    {
        VVL_ZoneScopedN("PreCallRecord_vkEnumeratePhysicalDeviceGroups");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PreCallRecordEnumeratePhysicalDeviceGroups(instance, pPhysicalDeviceGroupCount, pPhysicalDeviceGroupProperties,
                                                           record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkEnumeratePhysicalDeviceGroups");
        result =
            instance_dispatch->EnumeratePhysicalDeviceGroups(instance, pPhysicalDeviceGroupCount, pPhysicalDeviceGroupProperties);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkEnumeratePhysicalDeviceGroups");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PostCallRecordEnumeratePhysicalDeviceGroups(instance, pPhysicalDeviceGroupCount, pPhysicalDeviceGroupProperties,
                                                            record_obj);
        }
    }
    return result;
}

VKAPI_ATTR void VKAPI_CALL GetImageMemoryRequirements2(VkDevice device, const VkImageMemoryRequirementsInfo2* pInfo,
                                                       VkMemoryRequirements2* pMemoryRequirements) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetImageMemoryRequirements2, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetImageMemoryRequirements2");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateGetImageMemoryRequirements2]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateGetImageMemoryRequirements2(device, pInfo, pMemoryRequirements, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetImageMemoryRequirements2);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetImageMemoryRequirements2");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordGetImageMemoryRequirements2]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordGetImageMemoryRequirements2(device, pInfo, pMemoryRequirements, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkGetImageMemoryRequirements2");
        device_dispatch->GetImageMemoryRequirements2(device, pInfo, pMemoryRequirements);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetImageMemoryRequirements2");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordGetImageMemoryRequirements2]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordGetImageMemoryRequirements2(device, pInfo, pMemoryRequirements, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL GetBufferMemoryRequirements2(VkDevice device, const VkBufferMemoryRequirementsInfo2* pInfo,
                                                        VkMemoryRequirements2* pMemoryRequirements) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetBufferMemoryRequirements2, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetBufferMemoryRequirements2");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateGetBufferMemoryRequirements2]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateGetBufferMemoryRequirements2(device, pInfo, pMemoryRequirements, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetBufferMemoryRequirements2);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetBufferMemoryRequirements2");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordGetBufferMemoryRequirements2]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordGetBufferMemoryRequirements2(device, pInfo, pMemoryRequirements, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkGetBufferMemoryRequirements2");
        device_dispatch->GetBufferMemoryRequirements2(device, pInfo, pMemoryRequirements);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetBufferMemoryRequirements2");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordGetBufferMemoryRequirements2]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordGetBufferMemoryRequirements2(device, pInfo, pMemoryRequirements, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL GetImageSparseMemoryRequirements2(VkDevice device, const VkImageSparseMemoryRequirementsInfo2* pInfo,
                                                             uint32_t* pSparseMemoryRequirementCount,
                                                             VkSparseImageMemoryRequirements2* pSparseMemoryRequirements) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetImageSparseMemoryRequirements2, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetImageSparseMemoryRequirements2");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateGetImageSparseMemoryRequirements2]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateGetImageSparseMemoryRequirements2(device, pInfo, pSparseMemoryRequirementCount,
                                                                         pSparseMemoryRequirements, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetImageSparseMemoryRequirements2);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetImageSparseMemoryRequirements2");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordGetImageSparseMemoryRequirements2]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordGetImageSparseMemoryRequirements2(device, pInfo, pSparseMemoryRequirementCount,
                                                               pSparseMemoryRequirements, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkGetImageSparseMemoryRequirements2");
        device_dispatch->GetImageSparseMemoryRequirements2(device, pInfo, pSparseMemoryRequirementCount, pSparseMemoryRequirements);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetImageSparseMemoryRequirements2");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordGetImageSparseMemoryRequirements2]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordGetImageSparseMemoryRequirements2(device, pInfo, pSparseMemoryRequirementCount,
                                                                pSparseMemoryRequirements, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL GetPhysicalDeviceFeatures2(VkPhysicalDevice physicalDevice, VkPhysicalDeviceFeatures2* pFeatures) {
    VVL_ZoneScoped;

    auto instance_dispatch = vvl::dispatch::GetData(physicalDevice);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetPhysicalDeviceFeatures2,
                          VulkanTypedHandle(physicalDevice, kVulkanObjectTypePhysicalDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetPhysicalDeviceFeatures2");
        for (const auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            skip |= vo->PreCallValidateGetPhysicalDeviceFeatures2(physicalDevice, pFeatures, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetPhysicalDeviceFeatures2);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetPhysicalDeviceFeatures2");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PreCallRecordGetPhysicalDeviceFeatures2(physicalDevice, pFeatures, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkGetPhysicalDeviceFeatures2");
        instance_dispatch->GetPhysicalDeviceFeatures2(physicalDevice, pFeatures);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetPhysicalDeviceFeatures2");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PostCallRecordGetPhysicalDeviceFeatures2(physicalDevice, pFeatures, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL GetPhysicalDeviceProperties2(VkPhysicalDevice physicalDevice, VkPhysicalDeviceProperties2* pProperties) {
    VVL_ZoneScoped;

    auto instance_dispatch = vvl::dispatch::GetData(physicalDevice);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetPhysicalDeviceProperties2,
                          VulkanTypedHandle(physicalDevice, kVulkanObjectTypePhysicalDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetPhysicalDeviceProperties2");
        for (const auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            skip |= vo->PreCallValidateGetPhysicalDeviceProperties2(physicalDevice, pProperties, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetPhysicalDeviceProperties2);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetPhysicalDeviceProperties2");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PreCallRecordGetPhysicalDeviceProperties2(physicalDevice, pProperties, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkGetPhysicalDeviceProperties2");
        instance_dispatch->GetPhysicalDeviceProperties2(physicalDevice, pProperties);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetPhysicalDeviceProperties2");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PostCallRecordGetPhysicalDeviceProperties2(physicalDevice, pProperties, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL GetPhysicalDeviceFormatProperties2(VkPhysicalDevice physicalDevice, VkFormat format,
                                                              VkFormatProperties2* pFormatProperties) {
    VVL_ZoneScoped;

    auto instance_dispatch = vvl::dispatch::GetData(physicalDevice);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetPhysicalDeviceFormatProperties2,
                          VulkanTypedHandle(physicalDevice, kVulkanObjectTypePhysicalDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetPhysicalDeviceFormatProperties2");
        for (const auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            skip |= vo->PreCallValidateGetPhysicalDeviceFormatProperties2(physicalDevice, format, pFormatProperties, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetPhysicalDeviceFormatProperties2);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetPhysicalDeviceFormatProperties2");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PreCallRecordGetPhysicalDeviceFormatProperties2(physicalDevice, format, pFormatProperties, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkGetPhysicalDeviceFormatProperties2");
        instance_dispatch->GetPhysicalDeviceFormatProperties2(physicalDevice, format, pFormatProperties);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetPhysicalDeviceFormatProperties2");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PostCallRecordGetPhysicalDeviceFormatProperties2(physicalDevice, format, pFormatProperties, record_obj);
        }
    }
}

VKAPI_ATTR VkResult VKAPI_CALL GetPhysicalDeviceImageFormatProperties2(VkPhysicalDevice physicalDevice,
                                                                       const VkPhysicalDeviceImageFormatInfo2* pImageFormatInfo,
                                                                       VkImageFormatProperties2* pImageFormatProperties) {
    VVL_ZoneScoped;

    auto instance_dispatch = vvl::dispatch::GetData(physicalDevice);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetPhysicalDeviceImageFormatProperties2,
                          VulkanTypedHandle(physicalDevice, kVulkanObjectTypePhysicalDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetPhysicalDeviceImageFormatProperties2");
        for (const auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            skip |= vo->PreCallValidateGetPhysicalDeviceImageFormatProperties2(physicalDevice, pImageFormatInfo,
                                                                               pImageFormatProperties, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetPhysicalDeviceImageFormatProperties2);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetPhysicalDeviceImageFormatProperties2");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PreCallRecordGetPhysicalDeviceImageFormatProperties2(physicalDevice, pImageFormatInfo, pImageFormatProperties,
                                                                     record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkGetPhysicalDeviceImageFormatProperties2");
        result =
            instance_dispatch->GetPhysicalDeviceImageFormatProperties2(physicalDevice, pImageFormatInfo, pImageFormatProperties);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetPhysicalDeviceImageFormatProperties2");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PostCallRecordGetPhysicalDeviceImageFormatProperties2(physicalDevice, pImageFormatInfo, pImageFormatProperties,
                                                                      record_obj);
        }
    }
    return result;
}

VKAPI_ATTR void VKAPI_CALL GetPhysicalDeviceQueueFamilyProperties2(VkPhysicalDevice physicalDevice,
                                                                   uint32_t* pQueueFamilyPropertyCount,
                                                                   VkQueueFamilyProperties2* pQueueFamilyProperties) {
    VVL_ZoneScoped;

    auto instance_dispatch = vvl::dispatch::GetData(physicalDevice);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetPhysicalDeviceQueueFamilyProperties2,
                          VulkanTypedHandle(physicalDevice, kVulkanObjectTypePhysicalDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetPhysicalDeviceQueueFamilyProperties2");
        for (const auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            skip |= vo->PreCallValidateGetPhysicalDeviceQueueFamilyProperties2(physicalDevice, pQueueFamilyPropertyCount,
                                                                               pQueueFamilyProperties, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetPhysicalDeviceQueueFamilyProperties2);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetPhysicalDeviceQueueFamilyProperties2");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PreCallRecordGetPhysicalDeviceQueueFamilyProperties2(physicalDevice, pQueueFamilyPropertyCount,
                                                                     pQueueFamilyProperties, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkGetPhysicalDeviceQueueFamilyProperties2");
        instance_dispatch->GetPhysicalDeviceQueueFamilyProperties2(physicalDevice, pQueueFamilyPropertyCount,
                                                                   pQueueFamilyProperties);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetPhysicalDeviceQueueFamilyProperties2");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PostCallRecordGetPhysicalDeviceQueueFamilyProperties2(physicalDevice, pQueueFamilyPropertyCount,
                                                                      pQueueFamilyProperties, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL GetPhysicalDeviceMemoryProperties2(VkPhysicalDevice physicalDevice,
                                                              VkPhysicalDeviceMemoryProperties2* pMemoryProperties) {
    VVL_ZoneScoped;

    auto instance_dispatch = vvl::dispatch::GetData(physicalDevice);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetPhysicalDeviceMemoryProperties2,
                          VulkanTypedHandle(physicalDevice, kVulkanObjectTypePhysicalDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetPhysicalDeviceMemoryProperties2");
        for (const auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            skip |= vo->PreCallValidateGetPhysicalDeviceMemoryProperties2(physicalDevice, pMemoryProperties, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetPhysicalDeviceMemoryProperties2);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetPhysicalDeviceMemoryProperties2");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PreCallRecordGetPhysicalDeviceMemoryProperties2(physicalDevice, pMemoryProperties, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkGetPhysicalDeviceMemoryProperties2");
        instance_dispatch->GetPhysicalDeviceMemoryProperties2(physicalDevice, pMemoryProperties);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetPhysicalDeviceMemoryProperties2");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PostCallRecordGetPhysicalDeviceMemoryProperties2(physicalDevice, pMemoryProperties, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL GetPhysicalDeviceSparseImageFormatProperties2(VkPhysicalDevice physicalDevice,
                                                                         const VkPhysicalDeviceSparseImageFormatInfo2* pFormatInfo,
                                                                         uint32_t* pPropertyCount,
                                                                         VkSparseImageFormatProperties2* pProperties) {
    VVL_ZoneScoped;

    auto instance_dispatch = vvl::dispatch::GetData(physicalDevice);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetPhysicalDeviceSparseImageFormatProperties2,
                          VulkanTypedHandle(physicalDevice, kVulkanObjectTypePhysicalDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetPhysicalDeviceSparseImageFormatProperties2");
        for (const auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            skip |= vo->PreCallValidateGetPhysicalDeviceSparseImageFormatProperties2(physicalDevice, pFormatInfo, pPropertyCount,
                                                                                     pProperties, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetPhysicalDeviceSparseImageFormatProperties2);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetPhysicalDeviceSparseImageFormatProperties2");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PreCallRecordGetPhysicalDeviceSparseImageFormatProperties2(physicalDevice, pFormatInfo, pPropertyCount, pProperties,
                                                                           record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkGetPhysicalDeviceSparseImageFormatProperties2");
        instance_dispatch->GetPhysicalDeviceSparseImageFormatProperties2(physicalDevice, pFormatInfo, pPropertyCount, pProperties);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetPhysicalDeviceSparseImageFormatProperties2");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PostCallRecordGetPhysicalDeviceSparseImageFormatProperties2(physicalDevice, pFormatInfo, pPropertyCount,
                                                                            pProperties, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL TrimCommandPool(VkDevice device, VkCommandPool commandPool, VkCommandPoolTrimFlags flags) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkTrimCommandPool, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkTrimCommandPool");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateTrimCommandPool]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateTrimCommandPool(device, commandPool, flags, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkTrimCommandPool);
    {
        VVL_ZoneScopedN("PreCallRecord_vkTrimCommandPool");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordTrimCommandPool]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordTrimCommandPool(device, commandPool, flags, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkTrimCommandPool");
        device_dispatch->TrimCommandPool(device, commandPool, flags);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkTrimCommandPool");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordTrimCommandPool]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordTrimCommandPool(device, commandPool, flags, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL GetDeviceQueue2(VkDevice device, const VkDeviceQueueInfo2* pQueueInfo, VkQueue* pQueue) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetDeviceQueue2, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetDeviceQueue2");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateGetDeviceQueue2]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateGetDeviceQueue2(device, pQueueInfo, pQueue, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetDeviceQueue2);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetDeviceQueue2");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordGetDeviceQueue2]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordGetDeviceQueue2(device, pQueueInfo, pQueue, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkGetDeviceQueue2");
        device_dispatch->GetDeviceQueue2(device, pQueueInfo, pQueue);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetDeviceQueue2");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordGetDeviceQueue2]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordGetDeviceQueue2(device, pQueueInfo, pQueue, record_obj);
        }
    }
#if defined(VVL_TRACY_GPU)
    TracyVkCollector::Create(device, *pQueue, pQueueInfo->queueFamilyIndex);
#endif
}

VKAPI_ATTR void VKAPI_CALL GetPhysicalDeviceExternalBufferProperties(VkPhysicalDevice physicalDevice,
                                                                     const VkPhysicalDeviceExternalBufferInfo* pExternalBufferInfo,
                                                                     VkExternalBufferProperties* pExternalBufferProperties) {
    VVL_ZoneScoped;

    auto instance_dispatch = vvl::dispatch::GetData(physicalDevice);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetPhysicalDeviceExternalBufferProperties,
                          VulkanTypedHandle(physicalDevice, kVulkanObjectTypePhysicalDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetPhysicalDeviceExternalBufferProperties");
        for (const auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            skip |= vo->PreCallValidateGetPhysicalDeviceExternalBufferProperties(physicalDevice, pExternalBufferInfo,
                                                                                 pExternalBufferProperties, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetPhysicalDeviceExternalBufferProperties);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetPhysicalDeviceExternalBufferProperties");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PreCallRecordGetPhysicalDeviceExternalBufferProperties(physicalDevice, pExternalBufferInfo,
                                                                       pExternalBufferProperties, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkGetPhysicalDeviceExternalBufferProperties");
        instance_dispatch->GetPhysicalDeviceExternalBufferProperties(physicalDevice, pExternalBufferInfo,
                                                                     pExternalBufferProperties);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetPhysicalDeviceExternalBufferProperties");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PostCallRecordGetPhysicalDeviceExternalBufferProperties(physicalDevice, pExternalBufferInfo,
                                                                        pExternalBufferProperties, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL GetPhysicalDeviceExternalFenceProperties(VkPhysicalDevice physicalDevice,
                                                                    const VkPhysicalDeviceExternalFenceInfo* pExternalFenceInfo,
                                                                    VkExternalFenceProperties* pExternalFenceProperties) {
    VVL_ZoneScoped;

    auto instance_dispatch = vvl::dispatch::GetData(physicalDevice);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetPhysicalDeviceExternalFenceProperties,
                          VulkanTypedHandle(physicalDevice, kVulkanObjectTypePhysicalDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetPhysicalDeviceExternalFenceProperties");
        for (const auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            skip |= vo->PreCallValidateGetPhysicalDeviceExternalFenceProperties(physicalDevice, pExternalFenceInfo,
                                                                                pExternalFenceProperties, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetPhysicalDeviceExternalFenceProperties);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetPhysicalDeviceExternalFenceProperties");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PreCallRecordGetPhysicalDeviceExternalFenceProperties(physicalDevice, pExternalFenceInfo, pExternalFenceProperties,
                                                                      record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkGetPhysicalDeviceExternalFenceProperties");
        instance_dispatch->GetPhysicalDeviceExternalFenceProperties(physicalDevice, pExternalFenceInfo, pExternalFenceProperties);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetPhysicalDeviceExternalFenceProperties");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PostCallRecordGetPhysicalDeviceExternalFenceProperties(physicalDevice, pExternalFenceInfo, pExternalFenceProperties,
                                                                       record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL GetPhysicalDeviceExternalSemaphoreProperties(
    VkPhysicalDevice physicalDevice, const VkPhysicalDeviceExternalSemaphoreInfo* pExternalSemaphoreInfo,
    VkExternalSemaphoreProperties* pExternalSemaphoreProperties) {
    VVL_ZoneScoped;

    auto instance_dispatch = vvl::dispatch::GetData(physicalDevice);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetPhysicalDeviceExternalSemaphoreProperties,
                          VulkanTypedHandle(physicalDevice, kVulkanObjectTypePhysicalDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetPhysicalDeviceExternalSemaphoreProperties");
        for (const auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            skip |= vo->PreCallValidateGetPhysicalDeviceExternalSemaphoreProperties(physicalDevice, pExternalSemaphoreInfo,
                                                                                    pExternalSemaphoreProperties, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetPhysicalDeviceExternalSemaphoreProperties);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetPhysicalDeviceExternalSemaphoreProperties");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PreCallRecordGetPhysicalDeviceExternalSemaphoreProperties(physicalDevice, pExternalSemaphoreInfo,
                                                                          pExternalSemaphoreProperties, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkGetPhysicalDeviceExternalSemaphoreProperties");
        instance_dispatch->GetPhysicalDeviceExternalSemaphoreProperties(physicalDevice, pExternalSemaphoreInfo,
                                                                        pExternalSemaphoreProperties);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetPhysicalDeviceExternalSemaphoreProperties");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PostCallRecordGetPhysicalDeviceExternalSemaphoreProperties(physicalDevice, pExternalSemaphoreInfo,
                                                                           pExternalSemaphoreProperties, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdDispatchBase(VkCommandBuffer commandBuffer, uint32_t baseGroupX, uint32_t baseGroupY,
                                           uint32_t baseGroupZ, uint32_t groupCountX, uint32_t groupCountY, uint32_t groupCountZ) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdDispatchBase, VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdDispatchBase");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdDispatchBase]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdDispatchBase(commandBuffer, baseGroupX, baseGroupY, baseGroupZ, groupCountX, groupCountY,
                                                       groupCountZ, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdDispatchBase);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdDispatchBase");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdDispatchBase]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdDispatchBase(commandBuffer, baseGroupX, baseGroupY, baseGroupZ, groupCountX, groupCountY,
                                             groupCountZ, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdDispatchBase");
        device_dispatch->CmdDispatchBase(commandBuffer, baseGroupX, baseGroupY, baseGroupZ, groupCountX, groupCountY, groupCountZ);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdDispatchBase");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdDispatchBase]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdDispatchBase(commandBuffer, baseGroupX, baseGroupY, baseGroupZ, groupCountX, groupCountY,
                                              groupCountZ, record_obj);
        }
    }
}

VKAPI_ATTR VkResult VKAPI_CALL CreateDescriptorUpdateTemplate(VkDevice device,
                                                              const VkDescriptorUpdateTemplateCreateInfo* pCreateInfo,
                                                              const VkAllocationCallbacks* pAllocator,
                                                              VkDescriptorUpdateTemplate* pDescriptorUpdateTemplate) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCreateDescriptorUpdateTemplate, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCreateDescriptorUpdateTemplate");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCreateDescriptorUpdateTemplate]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCreateDescriptorUpdateTemplate(device, pCreateInfo, pAllocator, pDescriptorUpdateTemplate,
                                                                      error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkCreateDescriptorUpdateTemplate);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCreateDescriptorUpdateTemplate");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCreateDescriptorUpdateTemplate]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCreateDescriptorUpdateTemplate(device, pCreateInfo, pAllocator, pDescriptorUpdateTemplate, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkCreateDescriptorUpdateTemplate");
        result = device_dispatch->CreateDescriptorUpdateTemplate(device, pCreateInfo, pAllocator, pDescriptorUpdateTemplate);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkCreateDescriptorUpdateTemplate");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCreateDescriptorUpdateTemplate]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCreateDescriptorUpdateTemplate(device, pCreateInfo, pAllocator, pDescriptorUpdateTemplate,
                                                             record_obj);
        }
    }
    return result;
}

VKAPI_ATTR void VKAPI_CALL DestroyDescriptorUpdateTemplate(VkDevice device, VkDescriptorUpdateTemplate descriptorUpdateTemplate,
                                                           const VkAllocationCallbacks* pAllocator) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkDestroyDescriptorUpdateTemplate, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkDestroyDescriptorUpdateTemplate");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateDestroyDescriptorUpdateTemplate]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateDestroyDescriptorUpdateTemplate(device, descriptorUpdateTemplate, pAllocator, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkDestroyDescriptorUpdateTemplate);
    {
        VVL_ZoneScopedN("PreCallRecord_vkDestroyDescriptorUpdateTemplate");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordDestroyDescriptorUpdateTemplate]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordDestroyDescriptorUpdateTemplate(device, descriptorUpdateTemplate, pAllocator, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkDestroyDescriptorUpdateTemplate");
        device_dispatch->DestroyDescriptorUpdateTemplate(device, descriptorUpdateTemplate, pAllocator);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkDestroyDescriptorUpdateTemplate");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordDestroyDescriptorUpdateTemplate]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordDestroyDescriptorUpdateTemplate(device, descriptorUpdateTemplate, pAllocator, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL UpdateDescriptorSetWithTemplate(VkDevice device, VkDescriptorSet descriptorSet,
                                                           VkDescriptorUpdateTemplate descriptorUpdateTemplate, const void* pData) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkUpdateDescriptorSetWithTemplate, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkUpdateDescriptorSetWithTemplate");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateUpdateDescriptorSetWithTemplate]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateUpdateDescriptorSetWithTemplate(device, descriptorSet, descriptorUpdateTemplate, pData,
                                                                       error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkUpdateDescriptorSetWithTemplate);
    {
        VVL_ZoneScopedN("PreCallRecord_vkUpdateDescriptorSetWithTemplate");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordUpdateDescriptorSetWithTemplate]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordUpdateDescriptorSetWithTemplate(device, descriptorSet, descriptorUpdateTemplate, pData, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkUpdateDescriptorSetWithTemplate");
        device_dispatch->UpdateDescriptorSetWithTemplate(device, descriptorSet, descriptorUpdateTemplate, pData);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkUpdateDescriptorSetWithTemplate");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordUpdateDescriptorSetWithTemplate]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordUpdateDescriptorSetWithTemplate(device, descriptorSet, descriptorUpdateTemplate, pData, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL GetDescriptorSetLayoutSupport(VkDevice device, const VkDescriptorSetLayoutCreateInfo* pCreateInfo,
                                                         VkDescriptorSetLayoutSupport* pSupport) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetDescriptorSetLayoutSupport, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetDescriptorSetLayoutSupport");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateGetDescriptorSetLayoutSupport]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateGetDescriptorSetLayoutSupport(device, pCreateInfo, pSupport, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetDescriptorSetLayoutSupport);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetDescriptorSetLayoutSupport");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordGetDescriptorSetLayoutSupport]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordGetDescriptorSetLayoutSupport(device, pCreateInfo, pSupport, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkGetDescriptorSetLayoutSupport");
        device_dispatch->GetDescriptorSetLayoutSupport(device, pCreateInfo, pSupport);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetDescriptorSetLayoutSupport");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordGetDescriptorSetLayoutSupport]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordGetDescriptorSetLayoutSupport(device, pCreateInfo, pSupport, record_obj);
        }
    }
}

VKAPI_ATTR VkResult VKAPI_CALL CreateSamplerYcbcrConversion(VkDevice device, const VkSamplerYcbcrConversionCreateInfo* pCreateInfo,
                                                            const VkAllocationCallbacks* pAllocator,
                                                            VkSamplerYcbcrConversion* pYcbcrConversion) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCreateSamplerYcbcrConversion, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCreateSamplerYcbcrConversion");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCreateSamplerYcbcrConversion]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCreateSamplerYcbcrConversion(device, pCreateInfo, pAllocator, pYcbcrConversion, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkCreateSamplerYcbcrConversion);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCreateSamplerYcbcrConversion");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCreateSamplerYcbcrConversion]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCreateSamplerYcbcrConversion(device, pCreateInfo, pAllocator, pYcbcrConversion, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkCreateSamplerYcbcrConversion");
        result = device_dispatch->CreateSamplerYcbcrConversion(device, pCreateInfo, pAllocator, pYcbcrConversion);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkCreateSamplerYcbcrConversion");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCreateSamplerYcbcrConversion]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCreateSamplerYcbcrConversion(device, pCreateInfo, pAllocator, pYcbcrConversion, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR void VKAPI_CALL DestroySamplerYcbcrConversion(VkDevice device, VkSamplerYcbcrConversion ycbcrConversion,
                                                         const VkAllocationCallbacks* pAllocator) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkDestroySamplerYcbcrConversion, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkDestroySamplerYcbcrConversion");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateDestroySamplerYcbcrConversion]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateDestroySamplerYcbcrConversion(device, ycbcrConversion, pAllocator, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkDestroySamplerYcbcrConversion);
    {
        VVL_ZoneScopedN("PreCallRecord_vkDestroySamplerYcbcrConversion");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordDestroySamplerYcbcrConversion]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordDestroySamplerYcbcrConversion(device, ycbcrConversion, pAllocator, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkDestroySamplerYcbcrConversion");
        device_dispatch->DestroySamplerYcbcrConversion(device, ycbcrConversion, pAllocator);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkDestroySamplerYcbcrConversion");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordDestroySamplerYcbcrConversion]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordDestroySamplerYcbcrConversion(device, ycbcrConversion, pAllocator, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL ResetQueryPool(VkDevice device, VkQueryPool queryPool, uint32_t firstQuery, uint32_t queryCount) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkResetQueryPool, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkResetQueryPool");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateResetQueryPool]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateResetQueryPool(device, queryPool, firstQuery, queryCount, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkResetQueryPool);
    {
        VVL_ZoneScopedN("PreCallRecord_vkResetQueryPool");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordResetQueryPool]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordResetQueryPool(device, queryPool, firstQuery, queryCount, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkResetQueryPool");
        device_dispatch->ResetQueryPool(device, queryPool, firstQuery, queryCount);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkResetQueryPool");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordResetQueryPool]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordResetQueryPool(device, queryPool, firstQuery, queryCount, record_obj);
        }
    }
}

VKAPI_ATTR VkResult VKAPI_CALL GetSemaphoreCounterValue(VkDevice device, VkSemaphore semaphore, uint64_t* pValue) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetSemaphoreCounterValue, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetSemaphoreCounterValue");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateGetSemaphoreCounterValue]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateGetSemaphoreCounterValue(device, semaphore, pValue, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetSemaphoreCounterValue);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetSemaphoreCounterValue");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordGetSemaphoreCounterValue]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordGetSemaphoreCounterValue(device, semaphore, pValue, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkGetSemaphoreCounterValue");
        result = device_dispatch->GetSemaphoreCounterValue(device, semaphore, pValue);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetSemaphoreCounterValue");

        if (result == VK_ERROR_DEVICE_LOST) {
            for (auto& vo : device_dispatch->object_dispatch) {
                vo->is_device_lost = true;
            }
        }
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordGetSemaphoreCounterValue]) {
            if (!vo) {
                continue;
            }
            vvl::base::Device::BlockingOperationGuard lock(vo);
            vo->PostCallRecordGetSemaphoreCounterValue(device, semaphore, pValue, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR VkResult VKAPI_CALL WaitSemaphores(VkDevice device, const VkSemaphoreWaitInfo* pWaitInfo, uint64_t timeout) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkWaitSemaphores, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkWaitSemaphores");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateWaitSemaphores]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateWaitSemaphores(device, pWaitInfo, timeout, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkWaitSemaphores);
    {
        VVL_ZoneScopedN("PreCallRecord_vkWaitSemaphores");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordWaitSemaphores]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordWaitSemaphores(device, pWaitInfo, timeout, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkWaitSemaphores");
        result = device_dispatch->WaitSemaphores(device, pWaitInfo, timeout);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkWaitSemaphores");

        if (result == VK_ERROR_DEVICE_LOST) {
            for (auto& vo : device_dispatch->object_dispatch) {
                vo->is_device_lost = true;
            }
        }
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordWaitSemaphores]) {
            if (!vo) {
                continue;
            }
            vvl::base::Device::BlockingOperationGuard lock(vo);
            vo->PostCallRecordWaitSemaphores(device, pWaitInfo, timeout, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR VkResult VKAPI_CALL SignalSemaphore(VkDevice device, const VkSemaphoreSignalInfo* pSignalInfo) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkSignalSemaphore, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkSignalSemaphore");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateSignalSemaphore]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateSignalSemaphore(device, pSignalInfo, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkSignalSemaphore);
    {
        VVL_ZoneScopedN("PreCallRecord_vkSignalSemaphore");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordSignalSemaphore]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordSignalSemaphore(device, pSignalInfo, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkSignalSemaphore");
        result = device_dispatch->SignalSemaphore(device, pSignalInfo);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkSignalSemaphore");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordSignalSemaphore]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordSignalSemaphore(device, pSignalInfo, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR VkDeviceAddress VKAPI_CALL GetBufferDeviceAddress(VkDevice device, const VkBufferDeviceAddressInfo* pInfo) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetBufferDeviceAddress, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetBufferDeviceAddress");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateGetBufferDeviceAddress]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateGetBufferDeviceAddress(device, pInfo, error_obj);
            if (skip) return 0;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetBufferDeviceAddress);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetBufferDeviceAddress");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordGetBufferDeviceAddress]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordGetBufferDeviceAddress(device, pInfo, record_obj);
        }
    }
    VkDeviceAddress result;
    {
        VVL_ZoneScopedN("Dispatch_vkGetBufferDeviceAddress");
        result = device_dispatch->GetBufferDeviceAddress(device, pInfo);
    }
    record_obj.device_address = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetBufferDeviceAddress");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordGetBufferDeviceAddress]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordGetBufferDeviceAddress(device, pInfo, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR uint64_t VKAPI_CALL GetBufferOpaqueCaptureAddress(VkDevice device, const VkBufferDeviceAddressInfo* pInfo) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetBufferOpaqueCaptureAddress, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetBufferOpaqueCaptureAddress");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateGetBufferOpaqueCaptureAddress]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateGetBufferOpaqueCaptureAddress(device, pInfo, error_obj);
            if (skip) return 0;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetBufferOpaqueCaptureAddress);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetBufferOpaqueCaptureAddress");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordGetBufferOpaqueCaptureAddress]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordGetBufferOpaqueCaptureAddress(device, pInfo, record_obj);
        }
    }
    uint64_t result;
    {
        VVL_ZoneScopedN("Dispatch_vkGetBufferOpaqueCaptureAddress");
        result = device_dispatch->GetBufferOpaqueCaptureAddress(device, pInfo);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetBufferOpaqueCaptureAddress");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordGetBufferOpaqueCaptureAddress]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordGetBufferOpaqueCaptureAddress(device, pInfo, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR uint64_t VKAPI_CALL GetDeviceMemoryOpaqueCaptureAddress(VkDevice device,
                                                                   const VkDeviceMemoryOpaqueCaptureAddressInfo* pInfo) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetDeviceMemoryOpaqueCaptureAddress, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetDeviceMemoryOpaqueCaptureAddress");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateGetDeviceMemoryOpaqueCaptureAddress]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateGetDeviceMemoryOpaqueCaptureAddress(device, pInfo, error_obj);
            if (skip) return 0;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetDeviceMemoryOpaqueCaptureAddress);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetDeviceMemoryOpaqueCaptureAddress");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordGetDeviceMemoryOpaqueCaptureAddress]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordGetDeviceMemoryOpaqueCaptureAddress(device, pInfo, record_obj);
        }
    }
    uint64_t result;
    {
        VVL_ZoneScopedN("Dispatch_vkGetDeviceMemoryOpaqueCaptureAddress");
        result = device_dispatch->GetDeviceMemoryOpaqueCaptureAddress(device, pInfo);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetDeviceMemoryOpaqueCaptureAddress");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordGetDeviceMemoryOpaqueCaptureAddress]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordGetDeviceMemoryOpaqueCaptureAddress(device, pInfo, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR void VKAPI_CALL CmdDrawIndirectCount(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
                                                VkBuffer countBuffer, VkDeviceSize countBufferOffset, uint32_t maxDrawCount,
                                                uint32_t stride) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdDrawIndirectCount, VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdDrawIndirectCount");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdDrawIndirectCount]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdDrawIndirectCount(commandBuffer, buffer, offset, countBuffer, countBufferOffset,
                                                            maxDrawCount, stride, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdDrawIndirectCount);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdDrawIndirectCount");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdDrawIndirectCount]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdDrawIndirectCount(commandBuffer, buffer, offset, countBuffer, countBufferOffset, maxDrawCount,
                                                  stride, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdDrawIndirectCount");
        device_dispatch->CmdDrawIndirectCount(commandBuffer, buffer, offset, countBuffer, countBufferOffset, maxDrawCount, stride);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdDrawIndirectCount");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdDrawIndirectCount]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdDrawIndirectCount(commandBuffer, buffer, offset, countBuffer, countBufferOffset, maxDrawCount,
                                                   stride, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdDrawIndexedIndirectCount(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
                                                       VkBuffer countBuffer, VkDeviceSize countBufferOffset, uint32_t maxDrawCount,
                                                       uint32_t stride) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdDrawIndexedIndirectCount,
                          VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdDrawIndexedIndirectCount");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdDrawIndexedIndirectCount]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdDrawIndexedIndirectCount(commandBuffer, buffer, offset, countBuffer, countBufferOffset,
                                                                   maxDrawCount, stride, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdDrawIndexedIndirectCount);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdDrawIndexedIndirectCount");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdDrawIndexedIndirectCount]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdDrawIndexedIndirectCount(commandBuffer, buffer, offset, countBuffer, countBufferOffset,
                                                         maxDrawCount, stride, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdDrawIndexedIndirectCount");
        device_dispatch->CmdDrawIndexedIndirectCount(commandBuffer, buffer, offset, countBuffer, countBufferOffset, maxDrawCount,
                                                     stride);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdDrawIndexedIndirectCount");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdDrawIndexedIndirectCount]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdDrawIndexedIndirectCount(commandBuffer, buffer, offset, countBuffer, countBufferOffset,
                                                          maxDrawCount, stride, record_obj);
        }
    }
}

VKAPI_ATTR VkResult VKAPI_CALL CreateRenderPass2(VkDevice device, const VkRenderPassCreateInfo2* pCreateInfo,
                                                 const VkAllocationCallbacks* pAllocator, VkRenderPass* pRenderPass) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCreateRenderPass2, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCreateRenderPass2");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCreateRenderPass2]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCreateRenderPass2(device, pCreateInfo, pAllocator, pRenderPass, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkCreateRenderPass2);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCreateRenderPass2");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCreateRenderPass2]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCreateRenderPass2(device, pCreateInfo, pAllocator, pRenderPass, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkCreateRenderPass2");
        result = device_dispatch->CreateRenderPass2(device, pCreateInfo, pAllocator, pRenderPass);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkCreateRenderPass2");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCreateRenderPass2]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCreateRenderPass2(device, pCreateInfo, pAllocator, pRenderPass, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR void VKAPI_CALL CmdBeginRenderPass2(VkCommandBuffer commandBuffer, const VkRenderPassBeginInfo* pRenderPassBegin,
                                               const VkSubpassBeginInfo* pSubpassBeginInfo) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdBeginRenderPass2, VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdBeginRenderPass2");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdBeginRenderPass2]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdBeginRenderPass2(commandBuffer, pRenderPassBegin, pSubpassBeginInfo, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdBeginRenderPass2);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdBeginRenderPass2");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdBeginRenderPass2]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdBeginRenderPass2(commandBuffer, pRenderPassBegin, pSubpassBeginInfo, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdBeginRenderPass2");
        device_dispatch->CmdBeginRenderPass2(commandBuffer, pRenderPassBegin, pSubpassBeginInfo);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdBeginRenderPass2");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdBeginRenderPass2]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdBeginRenderPass2(commandBuffer, pRenderPassBegin, pSubpassBeginInfo, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdNextSubpass2(VkCommandBuffer commandBuffer, const VkSubpassBeginInfo* pSubpassBeginInfo,
                                           const VkSubpassEndInfo* pSubpassEndInfo) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdNextSubpass2, VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdNextSubpass2");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdNextSubpass2]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdNextSubpass2(commandBuffer, pSubpassBeginInfo, pSubpassEndInfo, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdNextSubpass2);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdNextSubpass2");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdNextSubpass2]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdNextSubpass2(commandBuffer, pSubpassBeginInfo, pSubpassEndInfo, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdNextSubpass2");
        device_dispatch->CmdNextSubpass2(commandBuffer, pSubpassBeginInfo, pSubpassEndInfo);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdNextSubpass2");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdNextSubpass2]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdNextSubpass2(commandBuffer, pSubpassBeginInfo, pSubpassEndInfo, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdEndRenderPass2(VkCommandBuffer commandBuffer, const VkSubpassEndInfo* pSubpassEndInfo) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdEndRenderPass2, VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdEndRenderPass2");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdEndRenderPass2]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdEndRenderPass2(commandBuffer, pSubpassEndInfo, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdEndRenderPass2);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdEndRenderPass2");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdEndRenderPass2]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdEndRenderPass2(commandBuffer, pSubpassEndInfo, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdEndRenderPass2");
        device_dispatch->CmdEndRenderPass2(commandBuffer, pSubpassEndInfo);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdEndRenderPass2");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdEndRenderPass2]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdEndRenderPass2(commandBuffer, pSubpassEndInfo, record_obj);
        }
    }
}

VKAPI_ATTR VkResult VKAPI_CALL CreatePrivateDataSlot(VkDevice device, const VkPrivateDataSlotCreateInfo* pCreateInfo,
                                                     const VkAllocationCallbacks* pAllocator, VkPrivateDataSlot* pPrivateDataSlot) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCreatePrivateDataSlot, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCreatePrivateDataSlot");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCreatePrivateDataSlot]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCreatePrivateDataSlot(device, pCreateInfo, pAllocator, pPrivateDataSlot, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkCreatePrivateDataSlot);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCreatePrivateDataSlot");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCreatePrivateDataSlot]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCreatePrivateDataSlot(device, pCreateInfo, pAllocator, pPrivateDataSlot, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkCreatePrivateDataSlot");
        result = device_dispatch->CreatePrivateDataSlot(device, pCreateInfo, pAllocator, pPrivateDataSlot);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkCreatePrivateDataSlot");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCreatePrivateDataSlot]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCreatePrivateDataSlot(device, pCreateInfo, pAllocator, pPrivateDataSlot, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR void VKAPI_CALL DestroyPrivateDataSlot(VkDevice device, VkPrivateDataSlot privateDataSlot,
                                                  const VkAllocationCallbacks* pAllocator) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkDestroyPrivateDataSlot, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkDestroyPrivateDataSlot");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateDestroyPrivateDataSlot]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateDestroyPrivateDataSlot(device, privateDataSlot, pAllocator, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkDestroyPrivateDataSlot);
    {
        VVL_ZoneScopedN("PreCallRecord_vkDestroyPrivateDataSlot");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordDestroyPrivateDataSlot]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordDestroyPrivateDataSlot(device, privateDataSlot, pAllocator, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkDestroyPrivateDataSlot");
        device_dispatch->DestroyPrivateDataSlot(device, privateDataSlot, pAllocator);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkDestroyPrivateDataSlot");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordDestroyPrivateDataSlot]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordDestroyPrivateDataSlot(device, privateDataSlot, pAllocator, record_obj);
        }
    }
}

VKAPI_ATTR VkResult VKAPI_CALL SetPrivateData(VkDevice device, VkObjectType objectType, uint64_t objectHandle,
                                              VkPrivateDataSlot privateDataSlot, uint64_t data) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkSetPrivateData, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkSetPrivateData");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateSetPrivateData]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateSetPrivateData(device, objectType, objectHandle, privateDataSlot, data, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkSetPrivateData);
    {
        VVL_ZoneScopedN("PreCallRecord_vkSetPrivateData");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordSetPrivateData]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordSetPrivateData(device, objectType, objectHandle, privateDataSlot, data, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkSetPrivateData");
        result = device_dispatch->SetPrivateData(device, objectType, objectHandle, privateDataSlot, data);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkSetPrivateData");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordSetPrivateData]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordSetPrivateData(device, objectType, objectHandle, privateDataSlot, data, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR void VKAPI_CALL GetPrivateData(VkDevice device, VkObjectType objectType, uint64_t objectHandle,
                                          VkPrivateDataSlot privateDataSlot, uint64_t* pData) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetPrivateData, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetPrivateData");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateGetPrivateData]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateGetPrivateData(device, objectType, objectHandle, privateDataSlot, pData, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetPrivateData);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetPrivateData");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordGetPrivateData]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordGetPrivateData(device, objectType, objectHandle, privateDataSlot, pData, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkGetPrivateData");
        device_dispatch->GetPrivateData(device, objectType, objectHandle, privateDataSlot, pData);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetPrivateData");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordGetPrivateData]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordGetPrivateData(device, objectType, objectHandle, privateDataSlot, pData, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdPipelineBarrier2(VkCommandBuffer commandBuffer, const VkDependencyInfo* pDependencyInfo) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdPipelineBarrier2, VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdPipelineBarrier2");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdPipelineBarrier2]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdPipelineBarrier2(commandBuffer, pDependencyInfo, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdPipelineBarrier2);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdPipelineBarrier2");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdPipelineBarrier2]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdPipelineBarrier2(commandBuffer, pDependencyInfo, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdPipelineBarrier2");
        device_dispatch->CmdPipelineBarrier2(commandBuffer, pDependencyInfo);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdPipelineBarrier2");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdPipelineBarrier2]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdPipelineBarrier2(commandBuffer, pDependencyInfo, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdWriteTimestamp2(VkCommandBuffer commandBuffer, VkPipelineStageFlags2 stage, VkQueryPool queryPool,
                                              uint32_t query) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdWriteTimestamp2, VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdWriteTimestamp2");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdWriteTimestamp2]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdWriteTimestamp2(commandBuffer, stage, queryPool, query, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdWriteTimestamp2);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdWriteTimestamp2");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdWriteTimestamp2]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdWriteTimestamp2(commandBuffer, stage, queryPool, query, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdWriteTimestamp2");
        device_dispatch->CmdWriteTimestamp2(commandBuffer, stage, queryPool, query);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdWriteTimestamp2");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdWriteTimestamp2]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdWriteTimestamp2(commandBuffer, stage, queryPool, query, record_obj);
        }
    }
}

VKAPI_ATTR VkResult VKAPI_CALL QueueSubmit2(VkQueue queue, uint32_t submitCount, const VkSubmitInfo2* pSubmits, VkFence fence) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(queue);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkQueueSubmit2, VulkanTypedHandle(queue, kVulkanObjectTypeQueue));
    {
        VVL_ZoneScopedN("PreCallValidate_vkQueueSubmit2");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateQueueSubmit2]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateQueueSubmit2(queue, submitCount, pSubmits, fence, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkQueueSubmit2);
    {
        VVL_ZoneScopedN("PreCallRecord_vkQueueSubmit2");
        VVL_TracyVkNamedZoneStart(GetTracyVkCtx(), queue, "gpu_PreCallRecordvkQueueSubmit2", pre_call_record_gpu_zone);

        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordQueueSubmit2]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordQueueSubmit2(queue, submitCount, pSubmits, fence, record_obj);
        }

        VVL_TracyVkNamedZoneEnd(pre_call_record_gpu_zone, queue);
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkQueueSubmit2");

        VVL_TracyVkNamedZoneStart(GetTracyVkCtx(), queue, "gpu_vkQueueSubmit2", submit_gpu_zone);
        result = device_dispatch->QueueSubmit2(queue, submitCount, pSubmits, fence);

        VVL_TracyVkNamedZoneEnd(submit_gpu_zone, queue);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkQueueSubmit2");

        VVL_TracyVkNamedZoneStart(GetTracyVkCtx(), queue, "gpu_PostCallRecordvkQueueSubmit2", post_call_record_gpu_zone);

        if (result == VK_ERROR_DEVICE_LOST) {
            for (auto& vo : device_dispatch->object_dispatch) {
                vo->is_device_lost = true;
            }
        }
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordQueueSubmit2]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordQueueSubmit2(queue, submitCount, pSubmits, fence, record_obj);
        }

        VVL_TracyVkNamedZoneEnd(post_call_record_gpu_zone, queue);
    }
#if defined(VVL_TRACY_GPU)
    TracyVkCollector::TrySubmitCollectCb(queue);
#endif
    return result;
}

VKAPI_ATTR void VKAPI_CALL CmdCopyBuffer2(VkCommandBuffer commandBuffer, const VkCopyBufferInfo2* pCopyBufferInfo) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdCopyBuffer2, VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdCopyBuffer2");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdCopyBuffer2]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdCopyBuffer2(commandBuffer, pCopyBufferInfo, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdCopyBuffer2);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdCopyBuffer2");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdCopyBuffer2]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdCopyBuffer2(commandBuffer, pCopyBufferInfo, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdCopyBuffer2");
        device_dispatch->CmdCopyBuffer2(commandBuffer, pCopyBufferInfo);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdCopyBuffer2");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdCopyBuffer2]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdCopyBuffer2(commandBuffer, pCopyBufferInfo, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdCopyImage2(VkCommandBuffer commandBuffer, const VkCopyImageInfo2* pCopyImageInfo) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdCopyImage2, VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdCopyImage2");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdCopyImage2]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdCopyImage2(commandBuffer, pCopyImageInfo, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdCopyImage2);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdCopyImage2");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdCopyImage2]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdCopyImage2(commandBuffer, pCopyImageInfo, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdCopyImage2");
        device_dispatch->CmdCopyImage2(commandBuffer, pCopyImageInfo);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdCopyImage2");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdCopyImage2]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdCopyImage2(commandBuffer, pCopyImageInfo, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdCopyBufferToImage2(VkCommandBuffer commandBuffer,
                                                 const VkCopyBufferToImageInfo2* pCopyBufferToImageInfo) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdCopyBufferToImage2, VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdCopyBufferToImage2");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdCopyBufferToImage2]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdCopyBufferToImage2(commandBuffer, pCopyBufferToImageInfo, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdCopyBufferToImage2);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdCopyBufferToImage2");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdCopyBufferToImage2]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdCopyBufferToImage2(commandBuffer, pCopyBufferToImageInfo, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdCopyBufferToImage2");
        device_dispatch->CmdCopyBufferToImage2(commandBuffer, pCopyBufferToImageInfo);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdCopyBufferToImage2");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdCopyBufferToImage2]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdCopyBufferToImage2(commandBuffer, pCopyBufferToImageInfo, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdCopyImageToBuffer2(VkCommandBuffer commandBuffer,
                                                 const VkCopyImageToBufferInfo2* pCopyImageToBufferInfo) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdCopyImageToBuffer2, VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdCopyImageToBuffer2");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdCopyImageToBuffer2]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdCopyImageToBuffer2(commandBuffer, pCopyImageToBufferInfo, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdCopyImageToBuffer2);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdCopyImageToBuffer2");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdCopyImageToBuffer2]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdCopyImageToBuffer2(commandBuffer, pCopyImageToBufferInfo, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdCopyImageToBuffer2");
        device_dispatch->CmdCopyImageToBuffer2(commandBuffer, pCopyImageToBufferInfo);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdCopyImageToBuffer2");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdCopyImageToBuffer2]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdCopyImageToBuffer2(commandBuffer, pCopyImageToBufferInfo, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL GetDeviceBufferMemoryRequirements(VkDevice device, const VkDeviceBufferMemoryRequirements* pInfo,
                                                             VkMemoryRequirements2* pMemoryRequirements) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetDeviceBufferMemoryRequirements, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetDeviceBufferMemoryRequirements");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateGetDeviceBufferMemoryRequirements]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateGetDeviceBufferMemoryRequirements(device, pInfo, pMemoryRequirements, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetDeviceBufferMemoryRequirements);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetDeviceBufferMemoryRequirements");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordGetDeviceBufferMemoryRequirements]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordGetDeviceBufferMemoryRequirements(device, pInfo, pMemoryRequirements, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkGetDeviceBufferMemoryRequirements");
        device_dispatch->GetDeviceBufferMemoryRequirements(device, pInfo, pMemoryRequirements);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetDeviceBufferMemoryRequirements");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordGetDeviceBufferMemoryRequirements]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordGetDeviceBufferMemoryRequirements(device, pInfo, pMemoryRequirements, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL GetDeviceImageMemoryRequirements(VkDevice device, const VkDeviceImageMemoryRequirements* pInfo,
                                                            VkMemoryRequirements2* pMemoryRequirements) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetDeviceImageMemoryRequirements, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetDeviceImageMemoryRequirements");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateGetDeviceImageMemoryRequirements]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateGetDeviceImageMemoryRequirements(device, pInfo, pMemoryRequirements, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetDeviceImageMemoryRequirements);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetDeviceImageMemoryRequirements");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordGetDeviceImageMemoryRequirements]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordGetDeviceImageMemoryRequirements(device, pInfo, pMemoryRequirements, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkGetDeviceImageMemoryRequirements");
        device_dispatch->GetDeviceImageMemoryRequirements(device, pInfo, pMemoryRequirements);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetDeviceImageMemoryRequirements");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordGetDeviceImageMemoryRequirements]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordGetDeviceImageMemoryRequirements(device, pInfo, pMemoryRequirements, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL GetDeviceImageSparseMemoryRequirements(VkDevice device, const VkDeviceImageMemoryRequirements* pInfo,
                                                                  uint32_t* pSparseMemoryRequirementCount,
                                                                  VkSparseImageMemoryRequirements2* pSparseMemoryRequirements) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetDeviceImageSparseMemoryRequirements, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetDeviceImageSparseMemoryRequirements");
        for (const auto& vo :
             device_dispatch->intercept_vectors[InterceptIdPreCallValidateGetDeviceImageSparseMemoryRequirements]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateGetDeviceImageSparseMemoryRequirements(device, pInfo, pSparseMemoryRequirementCount,
                                                                              pSparseMemoryRequirements, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetDeviceImageSparseMemoryRequirements);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetDeviceImageSparseMemoryRequirements");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordGetDeviceImageSparseMemoryRequirements]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordGetDeviceImageSparseMemoryRequirements(device, pInfo, pSparseMemoryRequirementCount,
                                                                    pSparseMemoryRequirements, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkGetDeviceImageSparseMemoryRequirements");
        device_dispatch->GetDeviceImageSparseMemoryRequirements(device, pInfo, pSparseMemoryRequirementCount,
                                                                pSparseMemoryRequirements);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetDeviceImageSparseMemoryRequirements");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordGetDeviceImageSparseMemoryRequirements]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordGetDeviceImageSparseMemoryRequirements(device, pInfo, pSparseMemoryRequirementCount,
                                                                     pSparseMemoryRequirements, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdSetEvent2(VkCommandBuffer commandBuffer, VkEvent event, const VkDependencyInfo* pDependencyInfo) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdSetEvent2, VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdSetEvent2");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdSetEvent2]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdSetEvent2(commandBuffer, event, pDependencyInfo, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdSetEvent2);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdSetEvent2");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdSetEvent2]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdSetEvent2(commandBuffer, event, pDependencyInfo, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdSetEvent2");
        device_dispatch->CmdSetEvent2(commandBuffer, event, pDependencyInfo);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdSetEvent2");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdSetEvent2]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdSetEvent2(commandBuffer, event, pDependencyInfo, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdResetEvent2(VkCommandBuffer commandBuffer, VkEvent event, VkPipelineStageFlags2 stageMask) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdResetEvent2, VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdResetEvent2");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdResetEvent2]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdResetEvent2(commandBuffer, event, stageMask, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdResetEvent2);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdResetEvent2");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdResetEvent2]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdResetEvent2(commandBuffer, event, stageMask, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdResetEvent2");
        device_dispatch->CmdResetEvent2(commandBuffer, event, stageMask);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdResetEvent2");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdResetEvent2]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdResetEvent2(commandBuffer, event, stageMask, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdWaitEvents2(VkCommandBuffer commandBuffer, uint32_t eventCount, const VkEvent* pEvents,
                                          const VkDependencyInfo* pDependencyInfos) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdWaitEvents2, VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdWaitEvents2");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdWaitEvents2]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdWaitEvents2(commandBuffer, eventCount, pEvents, pDependencyInfos, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdWaitEvents2);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdWaitEvents2");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdWaitEvents2]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdWaitEvents2(commandBuffer, eventCount, pEvents, pDependencyInfos, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdWaitEvents2");
        device_dispatch->CmdWaitEvents2(commandBuffer, eventCount, pEvents, pDependencyInfos);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdWaitEvents2");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdWaitEvents2]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdWaitEvents2(commandBuffer, eventCount, pEvents, pDependencyInfos, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdBlitImage2(VkCommandBuffer commandBuffer, const VkBlitImageInfo2* pBlitImageInfo) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdBlitImage2, VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdBlitImage2");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdBlitImage2]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdBlitImage2(commandBuffer, pBlitImageInfo, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdBlitImage2);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdBlitImage2");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdBlitImage2]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdBlitImage2(commandBuffer, pBlitImageInfo, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdBlitImage2");
        device_dispatch->CmdBlitImage2(commandBuffer, pBlitImageInfo);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdBlitImage2");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdBlitImage2]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdBlitImage2(commandBuffer, pBlitImageInfo, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdResolveImage2(VkCommandBuffer commandBuffer, const VkResolveImageInfo2* pResolveImageInfo) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdResolveImage2, VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdResolveImage2");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdResolveImage2]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdResolveImage2(commandBuffer, pResolveImageInfo, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdResolveImage2);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdResolveImage2");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdResolveImage2]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdResolveImage2(commandBuffer, pResolveImageInfo, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdResolveImage2");
        device_dispatch->CmdResolveImage2(commandBuffer, pResolveImageInfo);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdResolveImage2");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdResolveImage2]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdResolveImage2(commandBuffer, pResolveImageInfo, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdBeginRendering(VkCommandBuffer commandBuffer, const VkRenderingInfo* pRenderingInfo) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdBeginRendering, VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdBeginRendering");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdBeginRendering]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdBeginRendering(commandBuffer, pRenderingInfo, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdBeginRendering);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdBeginRendering");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdBeginRendering]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdBeginRendering(commandBuffer, pRenderingInfo, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdBeginRendering");
        device_dispatch->CmdBeginRendering(commandBuffer, pRenderingInfo);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdBeginRendering");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdBeginRendering]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdBeginRendering(commandBuffer, pRenderingInfo, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdEndRendering(VkCommandBuffer commandBuffer) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdEndRendering, VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdEndRendering");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdEndRendering]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdEndRendering(commandBuffer, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdEndRendering);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdEndRendering");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdEndRendering]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdEndRendering(commandBuffer, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdEndRendering");
        device_dispatch->CmdEndRendering(commandBuffer);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdEndRendering");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdEndRendering]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdEndRendering(commandBuffer, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdSetCullMode(VkCommandBuffer commandBuffer, VkCullModeFlags cullMode) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdSetCullMode, VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdSetCullMode");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdSetCullMode]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdSetCullMode(commandBuffer, cullMode, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdSetCullMode);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdSetCullMode");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdSetCullMode]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdSetCullMode(commandBuffer, cullMode, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdSetCullMode");
        device_dispatch->CmdSetCullMode(commandBuffer, cullMode);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdSetCullMode");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdSetCullMode]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdSetCullMode(commandBuffer, cullMode, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdSetFrontFace(VkCommandBuffer commandBuffer, VkFrontFace frontFace) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdSetFrontFace, VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdSetFrontFace");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdSetFrontFace]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdSetFrontFace(commandBuffer, frontFace, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdSetFrontFace);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdSetFrontFace");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdSetFrontFace]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdSetFrontFace(commandBuffer, frontFace, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdSetFrontFace");
        device_dispatch->CmdSetFrontFace(commandBuffer, frontFace);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdSetFrontFace");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdSetFrontFace]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdSetFrontFace(commandBuffer, frontFace, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdSetPrimitiveTopology(VkCommandBuffer commandBuffer, VkPrimitiveTopology primitiveTopology) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdSetPrimitiveTopology, VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdSetPrimitiveTopology");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdSetPrimitiveTopology]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdSetPrimitiveTopology(commandBuffer, primitiveTopology, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdSetPrimitiveTopology);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdSetPrimitiveTopology");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdSetPrimitiveTopology]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdSetPrimitiveTopology(commandBuffer, primitiveTopology, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdSetPrimitiveTopology");
        device_dispatch->CmdSetPrimitiveTopology(commandBuffer, primitiveTopology);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdSetPrimitiveTopology");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdSetPrimitiveTopology]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdSetPrimitiveTopology(commandBuffer, primitiveTopology, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdSetViewportWithCount(VkCommandBuffer commandBuffer, uint32_t viewportCount,
                                                   const VkViewport* pViewports) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdSetViewportWithCount, VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdSetViewportWithCount");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdSetViewportWithCount]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdSetViewportWithCount(commandBuffer, viewportCount, pViewports, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdSetViewportWithCount);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdSetViewportWithCount");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdSetViewportWithCount]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdSetViewportWithCount(commandBuffer, viewportCount, pViewports, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdSetViewportWithCount");
        device_dispatch->CmdSetViewportWithCount(commandBuffer, viewportCount, pViewports);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdSetViewportWithCount");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdSetViewportWithCount]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdSetViewportWithCount(commandBuffer, viewportCount, pViewports, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdSetScissorWithCount(VkCommandBuffer commandBuffer, uint32_t scissorCount, const VkRect2D* pScissors) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdSetScissorWithCount, VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdSetScissorWithCount");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdSetScissorWithCount]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdSetScissorWithCount(commandBuffer, scissorCount, pScissors, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdSetScissorWithCount);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdSetScissorWithCount");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdSetScissorWithCount]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdSetScissorWithCount(commandBuffer, scissorCount, pScissors, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdSetScissorWithCount");
        device_dispatch->CmdSetScissorWithCount(commandBuffer, scissorCount, pScissors);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdSetScissorWithCount");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdSetScissorWithCount]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdSetScissorWithCount(commandBuffer, scissorCount, pScissors, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdBindVertexBuffers2(VkCommandBuffer commandBuffer, uint32_t firstBinding, uint32_t bindingCount,
                                                 const VkBuffer* pBuffers, const VkDeviceSize* pOffsets, const VkDeviceSize* pSizes,
                                                 const VkDeviceSize* pStrides) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdBindVertexBuffers2, VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdBindVertexBuffers2");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdBindVertexBuffers2]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdBindVertexBuffers2(commandBuffer, firstBinding, bindingCount, pBuffers, pOffsets, pSizes,
                                                             pStrides, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdBindVertexBuffers2);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdBindVertexBuffers2");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdBindVertexBuffers2]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdBindVertexBuffers2(commandBuffer, firstBinding, bindingCount, pBuffers, pOffsets, pSizes, pStrides,
                                                   record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdBindVertexBuffers2");
        device_dispatch->CmdBindVertexBuffers2(commandBuffer, firstBinding, bindingCount, pBuffers, pOffsets, pSizes, pStrides);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdBindVertexBuffers2");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdBindVertexBuffers2]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdBindVertexBuffers2(commandBuffer, firstBinding, bindingCount, pBuffers, pOffsets, pSizes, pStrides,
                                                    record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdSetDepthTestEnable(VkCommandBuffer commandBuffer, VkBool32 depthTestEnable) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdSetDepthTestEnable, VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdSetDepthTestEnable");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdSetDepthTestEnable]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdSetDepthTestEnable(commandBuffer, depthTestEnable, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdSetDepthTestEnable);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdSetDepthTestEnable");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdSetDepthTestEnable]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdSetDepthTestEnable(commandBuffer, depthTestEnable, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdSetDepthTestEnable");
        device_dispatch->CmdSetDepthTestEnable(commandBuffer, depthTestEnable);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdSetDepthTestEnable");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdSetDepthTestEnable]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdSetDepthTestEnable(commandBuffer, depthTestEnable, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdSetDepthWriteEnable(VkCommandBuffer commandBuffer, VkBool32 depthWriteEnable) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdSetDepthWriteEnable, VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdSetDepthWriteEnable");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdSetDepthWriteEnable]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdSetDepthWriteEnable(commandBuffer, depthWriteEnable, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdSetDepthWriteEnable);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdSetDepthWriteEnable");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdSetDepthWriteEnable]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdSetDepthWriteEnable(commandBuffer, depthWriteEnable, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdSetDepthWriteEnable");
        device_dispatch->CmdSetDepthWriteEnable(commandBuffer, depthWriteEnable);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdSetDepthWriteEnable");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdSetDepthWriteEnable]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdSetDepthWriteEnable(commandBuffer, depthWriteEnable, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdSetDepthCompareOp(VkCommandBuffer commandBuffer, VkCompareOp depthCompareOp) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdSetDepthCompareOp, VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdSetDepthCompareOp");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdSetDepthCompareOp]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdSetDepthCompareOp(commandBuffer, depthCompareOp, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdSetDepthCompareOp);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdSetDepthCompareOp");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdSetDepthCompareOp]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdSetDepthCompareOp(commandBuffer, depthCompareOp, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdSetDepthCompareOp");
        device_dispatch->CmdSetDepthCompareOp(commandBuffer, depthCompareOp);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdSetDepthCompareOp");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdSetDepthCompareOp]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdSetDepthCompareOp(commandBuffer, depthCompareOp, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdSetDepthBoundsTestEnable(VkCommandBuffer commandBuffer, VkBool32 depthBoundsTestEnable) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdSetDepthBoundsTestEnable,
                          VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdSetDepthBoundsTestEnable");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdSetDepthBoundsTestEnable]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdSetDepthBoundsTestEnable(commandBuffer, depthBoundsTestEnable, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdSetDepthBoundsTestEnable);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdSetDepthBoundsTestEnable");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdSetDepthBoundsTestEnable]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdSetDepthBoundsTestEnable(commandBuffer, depthBoundsTestEnable, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdSetDepthBoundsTestEnable");
        device_dispatch->CmdSetDepthBoundsTestEnable(commandBuffer, depthBoundsTestEnable);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdSetDepthBoundsTestEnable");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdSetDepthBoundsTestEnable]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdSetDepthBoundsTestEnable(commandBuffer, depthBoundsTestEnable, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdSetStencilTestEnable(VkCommandBuffer commandBuffer, VkBool32 stencilTestEnable) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdSetStencilTestEnable, VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdSetStencilTestEnable");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdSetStencilTestEnable]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdSetStencilTestEnable(commandBuffer, stencilTestEnable, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdSetStencilTestEnable);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdSetStencilTestEnable");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdSetStencilTestEnable]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdSetStencilTestEnable(commandBuffer, stencilTestEnable, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdSetStencilTestEnable");
        device_dispatch->CmdSetStencilTestEnable(commandBuffer, stencilTestEnable);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdSetStencilTestEnable");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdSetStencilTestEnable]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdSetStencilTestEnable(commandBuffer, stencilTestEnable, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdSetStencilOp(VkCommandBuffer commandBuffer, VkStencilFaceFlags faceMask, VkStencilOp failOp,
                                           VkStencilOp passOp, VkStencilOp depthFailOp, VkCompareOp compareOp) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdSetStencilOp, VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdSetStencilOp");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdSetStencilOp]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdSetStencilOp(commandBuffer, faceMask, failOp, passOp, depthFailOp, compareOp, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdSetStencilOp);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdSetStencilOp");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdSetStencilOp]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdSetStencilOp(commandBuffer, faceMask, failOp, passOp, depthFailOp, compareOp, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdSetStencilOp");
        device_dispatch->CmdSetStencilOp(commandBuffer, faceMask, failOp, passOp, depthFailOp, compareOp);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdSetStencilOp");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdSetStencilOp]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdSetStencilOp(commandBuffer, faceMask, failOp, passOp, depthFailOp, compareOp, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdSetRasterizerDiscardEnable(VkCommandBuffer commandBuffer, VkBool32 rasterizerDiscardEnable) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdSetRasterizerDiscardEnable,
                          VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdSetRasterizerDiscardEnable");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdSetRasterizerDiscardEnable]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdSetRasterizerDiscardEnable(commandBuffer, rasterizerDiscardEnable, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdSetRasterizerDiscardEnable);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdSetRasterizerDiscardEnable");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdSetRasterizerDiscardEnable]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdSetRasterizerDiscardEnable(commandBuffer, rasterizerDiscardEnable, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdSetRasterizerDiscardEnable");
        device_dispatch->CmdSetRasterizerDiscardEnable(commandBuffer, rasterizerDiscardEnable);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdSetRasterizerDiscardEnable");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdSetRasterizerDiscardEnable]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdSetRasterizerDiscardEnable(commandBuffer, rasterizerDiscardEnable, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdSetDepthBiasEnable(VkCommandBuffer commandBuffer, VkBool32 depthBiasEnable) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdSetDepthBiasEnable, VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdSetDepthBiasEnable");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdSetDepthBiasEnable]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdSetDepthBiasEnable(commandBuffer, depthBiasEnable, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdSetDepthBiasEnable);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdSetDepthBiasEnable");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdSetDepthBiasEnable]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdSetDepthBiasEnable(commandBuffer, depthBiasEnable, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdSetDepthBiasEnable");
        device_dispatch->CmdSetDepthBiasEnable(commandBuffer, depthBiasEnable);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdSetDepthBiasEnable");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdSetDepthBiasEnable]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdSetDepthBiasEnable(commandBuffer, depthBiasEnable, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdSetPrimitiveRestartEnable(VkCommandBuffer commandBuffer, VkBool32 primitiveRestartEnable) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdSetPrimitiveRestartEnable,
                          VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdSetPrimitiveRestartEnable");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdSetPrimitiveRestartEnable]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdSetPrimitiveRestartEnable(commandBuffer, primitiveRestartEnable, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdSetPrimitiveRestartEnable);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdSetPrimitiveRestartEnable");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdSetPrimitiveRestartEnable]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdSetPrimitiveRestartEnable(commandBuffer, primitiveRestartEnable, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdSetPrimitiveRestartEnable");
        device_dispatch->CmdSetPrimitiveRestartEnable(commandBuffer, primitiveRestartEnable);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdSetPrimitiveRestartEnable");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdSetPrimitiveRestartEnable]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdSetPrimitiveRestartEnable(commandBuffer, primitiveRestartEnable, record_obj);
        }
    }
}

VKAPI_ATTR VkResult VKAPI_CALL MapMemory2(VkDevice device, const VkMemoryMapInfo* pMemoryMapInfo, void** ppData) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkMapMemory2, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkMapMemory2");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateMapMemory2]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateMapMemory2(device, pMemoryMapInfo, ppData, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkMapMemory2);
    {
        VVL_ZoneScopedN("PreCallRecord_vkMapMemory2");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordMapMemory2]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordMapMemory2(device, pMemoryMapInfo, ppData, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkMapMemory2");
        result = device_dispatch->MapMemory2(device, pMemoryMapInfo, ppData);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkMapMemory2");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordMapMemory2]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordMapMemory2(device, pMemoryMapInfo, ppData, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR VkResult VKAPI_CALL UnmapMemory2(VkDevice device, const VkMemoryUnmapInfo* pMemoryUnmapInfo) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkUnmapMemory2, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkUnmapMemory2");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateUnmapMemory2]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateUnmapMemory2(device, pMemoryUnmapInfo, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkUnmapMemory2);
    {
        VVL_ZoneScopedN("PreCallRecord_vkUnmapMemory2");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordUnmapMemory2]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordUnmapMemory2(device, pMemoryUnmapInfo, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkUnmapMemory2");
        result = device_dispatch->UnmapMemory2(device, pMemoryUnmapInfo);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkUnmapMemory2");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordUnmapMemory2]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordUnmapMemory2(device, pMemoryUnmapInfo, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR void VKAPI_CALL GetDeviceImageSubresourceLayout(VkDevice device, const VkDeviceImageSubresourceInfo* pInfo,
                                                           VkSubresourceLayout2* pLayout) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetDeviceImageSubresourceLayout, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetDeviceImageSubresourceLayout");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateGetDeviceImageSubresourceLayout]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateGetDeviceImageSubresourceLayout(device, pInfo, pLayout, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetDeviceImageSubresourceLayout);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetDeviceImageSubresourceLayout");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordGetDeviceImageSubresourceLayout]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordGetDeviceImageSubresourceLayout(device, pInfo, pLayout, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkGetDeviceImageSubresourceLayout");
        device_dispatch->GetDeviceImageSubresourceLayout(device, pInfo, pLayout);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetDeviceImageSubresourceLayout");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordGetDeviceImageSubresourceLayout]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordGetDeviceImageSubresourceLayout(device, pInfo, pLayout, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL GetImageSubresourceLayout2(VkDevice device, VkImage image, const VkImageSubresource2* pSubresource,
                                                      VkSubresourceLayout2* pLayout) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetImageSubresourceLayout2, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetImageSubresourceLayout2");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateGetImageSubresourceLayout2]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateGetImageSubresourceLayout2(device, image, pSubresource, pLayout, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetImageSubresourceLayout2);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetImageSubresourceLayout2");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordGetImageSubresourceLayout2]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordGetImageSubresourceLayout2(device, image, pSubresource, pLayout, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkGetImageSubresourceLayout2");
        device_dispatch->GetImageSubresourceLayout2(device, image, pSubresource, pLayout);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetImageSubresourceLayout2");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordGetImageSubresourceLayout2]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordGetImageSubresourceLayout2(device, image, pSubresource, pLayout, record_obj);
        }
    }
}

VKAPI_ATTR VkResult VKAPI_CALL CopyMemoryToImage(VkDevice device, const VkCopyMemoryToImageInfo* pCopyMemoryToImageInfo) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCopyMemoryToImage, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCopyMemoryToImage");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCopyMemoryToImage]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCopyMemoryToImage(device, pCopyMemoryToImageInfo, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkCopyMemoryToImage);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCopyMemoryToImage");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCopyMemoryToImage]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCopyMemoryToImage(device, pCopyMemoryToImageInfo, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkCopyMemoryToImage");
        result = device_dispatch->CopyMemoryToImage(device, pCopyMemoryToImageInfo);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkCopyMemoryToImage");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCopyMemoryToImage]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCopyMemoryToImage(device, pCopyMemoryToImageInfo, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR VkResult VKAPI_CALL CopyImageToMemory(VkDevice device, const VkCopyImageToMemoryInfo* pCopyImageToMemoryInfo) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCopyImageToMemory, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCopyImageToMemory");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCopyImageToMemory]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCopyImageToMemory(device, pCopyImageToMemoryInfo, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkCopyImageToMemory);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCopyImageToMemory");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCopyImageToMemory]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCopyImageToMemory(device, pCopyImageToMemoryInfo, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkCopyImageToMemory");
        result = device_dispatch->CopyImageToMemory(device, pCopyImageToMemoryInfo);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkCopyImageToMemory");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCopyImageToMemory]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCopyImageToMemory(device, pCopyImageToMemoryInfo, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR VkResult VKAPI_CALL CopyImageToImage(VkDevice device, const VkCopyImageToImageInfo* pCopyImageToImageInfo) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCopyImageToImage, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCopyImageToImage");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCopyImageToImage]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCopyImageToImage(device, pCopyImageToImageInfo, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkCopyImageToImage);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCopyImageToImage");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCopyImageToImage]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCopyImageToImage(device, pCopyImageToImageInfo, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkCopyImageToImage");
        result = device_dispatch->CopyImageToImage(device, pCopyImageToImageInfo);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkCopyImageToImage");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCopyImageToImage]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCopyImageToImage(device, pCopyImageToImageInfo, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR VkResult VKAPI_CALL TransitionImageLayout(VkDevice device, uint32_t transitionCount,
                                                     const VkHostImageLayoutTransitionInfo* pTransitions) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkTransitionImageLayout, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkTransitionImageLayout");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateTransitionImageLayout]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateTransitionImageLayout(device, transitionCount, pTransitions, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkTransitionImageLayout);
    {
        VVL_ZoneScopedN("PreCallRecord_vkTransitionImageLayout");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordTransitionImageLayout]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordTransitionImageLayout(device, transitionCount, pTransitions, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkTransitionImageLayout");
        result = device_dispatch->TransitionImageLayout(device, transitionCount, pTransitions);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkTransitionImageLayout");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordTransitionImageLayout]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordTransitionImageLayout(device, transitionCount, pTransitions, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR void VKAPI_CALL CmdPushDescriptorSet(VkCommandBuffer commandBuffer, VkPipelineBindPoint pipelineBindPoint,
                                                VkPipelineLayout layout, uint32_t set, uint32_t descriptorWriteCount,
                                                const VkWriteDescriptorSet* pDescriptorWrites) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdPushDescriptorSet, VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdPushDescriptorSet");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdPushDescriptorSet]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdPushDescriptorSet(commandBuffer, pipelineBindPoint, layout, set, descriptorWriteCount,
                                                            pDescriptorWrites, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdPushDescriptorSet);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdPushDescriptorSet");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdPushDescriptorSet]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdPushDescriptorSet(commandBuffer, pipelineBindPoint, layout, set, descriptorWriteCount,
                                                  pDescriptorWrites, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdPushDescriptorSet");
        device_dispatch->CmdPushDescriptorSet(commandBuffer, pipelineBindPoint, layout, set, descriptorWriteCount,
                                              pDescriptorWrites);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdPushDescriptorSet");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdPushDescriptorSet]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdPushDescriptorSet(commandBuffer, pipelineBindPoint, layout, set, descriptorWriteCount,
                                                   pDescriptorWrites, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdPushDescriptorSetWithTemplate(VkCommandBuffer commandBuffer,
                                                            VkDescriptorUpdateTemplate descriptorUpdateTemplate,
                                                            VkPipelineLayout layout, uint32_t set, const void* pData) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdPushDescriptorSetWithTemplate,
                          VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdPushDescriptorSetWithTemplate");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdPushDescriptorSetWithTemplate]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdPushDescriptorSetWithTemplate(commandBuffer, descriptorUpdateTemplate, layout, set, pData,
                                                                        error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdPushDescriptorSetWithTemplate);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdPushDescriptorSetWithTemplate");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdPushDescriptorSetWithTemplate]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdPushDescriptorSetWithTemplate(commandBuffer, descriptorUpdateTemplate, layout, set, pData,
                                                              record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdPushDescriptorSetWithTemplate");
        device_dispatch->CmdPushDescriptorSetWithTemplate(commandBuffer, descriptorUpdateTemplate, layout, set, pData);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdPushDescriptorSetWithTemplate");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdPushDescriptorSetWithTemplate]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdPushDescriptorSetWithTemplate(commandBuffer, descriptorUpdateTemplate, layout, set, pData,
                                                               record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdBindDescriptorSets2(VkCommandBuffer commandBuffer,
                                                  const VkBindDescriptorSetsInfo* pBindDescriptorSetsInfo) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdBindDescriptorSets2, VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdBindDescriptorSets2");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdBindDescriptorSets2]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdBindDescriptorSets2(commandBuffer, pBindDescriptorSetsInfo, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdBindDescriptorSets2);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdBindDescriptorSets2");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdBindDescriptorSets2]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdBindDescriptorSets2(commandBuffer, pBindDescriptorSetsInfo, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdBindDescriptorSets2");
        device_dispatch->CmdBindDescriptorSets2(commandBuffer, pBindDescriptorSetsInfo);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdBindDescriptorSets2");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdBindDescriptorSets2]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdBindDescriptorSets2(commandBuffer, pBindDescriptorSetsInfo, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdPushConstants2(VkCommandBuffer commandBuffer, const VkPushConstantsInfo* pPushConstantsInfo) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdPushConstants2, VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdPushConstants2");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdPushConstants2]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdPushConstants2(commandBuffer, pPushConstantsInfo, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdPushConstants2);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdPushConstants2");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdPushConstants2]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdPushConstants2(commandBuffer, pPushConstantsInfo, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdPushConstants2");
        device_dispatch->CmdPushConstants2(commandBuffer, pPushConstantsInfo);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdPushConstants2");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdPushConstants2]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdPushConstants2(commandBuffer, pPushConstantsInfo, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdPushDescriptorSet2(VkCommandBuffer commandBuffer,
                                                 const VkPushDescriptorSetInfo* pPushDescriptorSetInfo) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdPushDescriptorSet2, VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdPushDescriptorSet2");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdPushDescriptorSet2]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdPushDescriptorSet2(commandBuffer, pPushDescriptorSetInfo, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdPushDescriptorSet2);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdPushDescriptorSet2");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdPushDescriptorSet2]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdPushDescriptorSet2(commandBuffer, pPushDescriptorSetInfo, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdPushDescriptorSet2");
        device_dispatch->CmdPushDescriptorSet2(commandBuffer, pPushDescriptorSetInfo);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdPushDescriptorSet2");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdPushDescriptorSet2]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdPushDescriptorSet2(commandBuffer, pPushDescriptorSetInfo, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdPushDescriptorSetWithTemplate2(
    VkCommandBuffer commandBuffer, const VkPushDescriptorSetWithTemplateInfo* pPushDescriptorSetWithTemplateInfo) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdPushDescriptorSetWithTemplate2,
                          VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdPushDescriptorSetWithTemplate2");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdPushDescriptorSetWithTemplate2]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |=
                vo->PreCallValidateCmdPushDescriptorSetWithTemplate2(commandBuffer, pPushDescriptorSetWithTemplateInfo, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdPushDescriptorSetWithTemplate2);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdPushDescriptorSetWithTemplate2");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdPushDescriptorSetWithTemplate2]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdPushDescriptorSetWithTemplate2(commandBuffer, pPushDescriptorSetWithTemplateInfo, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdPushDescriptorSetWithTemplate2");
        device_dispatch->CmdPushDescriptorSetWithTemplate2(commandBuffer, pPushDescriptorSetWithTemplateInfo);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdPushDescriptorSetWithTemplate2");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdPushDescriptorSetWithTemplate2]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdPushDescriptorSetWithTemplate2(commandBuffer, pPushDescriptorSetWithTemplateInfo, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdSetLineStipple(VkCommandBuffer commandBuffer, uint32_t lineStippleFactor,
                                             uint16_t lineStipplePattern) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdSetLineStipple, VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdSetLineStipple");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdSetLineStipple]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdSetLineStipple(commandBuffer, lineStippleFactor, lineStipplePattern, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdSetLineStipple);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdSetLineStipple");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdSetLineStipple]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdSetLineStipple(commandBuffer, lineStippleFactor, lineStipplePattern, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdSetLineStipple");
        device_dispatch->CmdSetLineStipple(commandBuffer, lineStippleFactor, lineStipplePattern);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdSetLineStipple");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdSetLineStipple]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdSetLineStipple(commandBuffer, lineStippleFactor, lineStipplePattern, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdBindIndexBuffer2(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
                                               VkDeviceSize size, VkIndexType indexType) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdBindIndexBuffer2, VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdBindIndexBuffer2");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdBindIndexBuffer2]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdBindIndexBuffer2(commandBuffer, buffer, offset, size, indexType, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdBindIndexBuffer2);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdBindIndexBuffer2");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdBindIndexBuffer2]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdBindIndexBuffer2(commandBuffer, buffer, offset, size, indexType, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdBindIndexBuffer2");
        device_dispatch->CmdBindIndexBuffer2(commandBuffer, buffer, offset, size, indexType);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdBindIndexBuffer2");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdBindIndexBuffer2]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdBindIndexBuffer2(commandBuffer, buffer, offset, size, indexType, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL GetRenderingAreaGranularity(VkDevice device, const VkRenderingAreaInfo* pRenderingAreaInfo,
                                                       VkExtent2D* pGranularity) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetRenderingAreaGranularity, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetRenderingAreaGranularity");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateGetRenderingAreaGranularity]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateGetRenderingAreaGranularity(device, pRenderingAreaInfo, pGranularity, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetRenderingAreaGranularity);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetRenderingAreaGranularity");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordGetRenderingAreaGranularity]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordGetRenderingAreaGranularity(device, pRenderingAreaInfo, pGranularity, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkGetRenderingAreaGranularity");
        device_dispatch->GetRenderingAreaGranularity(device, pRenderingAreaInfo, pGranularity);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetRenderingAreaGranularity");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordGetRenderingAreaGranularity]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordGetRenderingAreaGranularity(device, pRenderingAreaInfo, pGranularity, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdSetRenderingAttachmentLocations(VkCommandBuffer commandBuffer,
                                                              const VkRenderingAttachmentLocationInfo* pLocationInfo) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdSetRenderingAttachmentLocations,
                          VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdSetRenderingAttachmentLocations");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdSetRenderingAttachmentLocations]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdSetRenderingAttachmentLocations(commandBuffer, pLocationInfo, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdSetRenderingAttachmentLocations);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdSetRenderingAttachmentLocations");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdSetRenderingAttachmentLocations]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdSetRenderingAttachmentLocations(commandBuffer, pLocationInfo, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdSetRenderingAttachmentLocations");
        device_dispatch->CmdSetRenderingAttachmentLocations(commandBuffer, pLocationInfo);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdSetRenderingAttachmentLocations");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdSetRenderingAttachmentLocations]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdSetRenderingAttachmentLocations(commandBuffer, pLocationInfo, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdSetRenderingInputAttachmentIndices(
    VkCommandBuffer commandBuffer, const VkRenderingInputAttachmentIndexInfo* pInputAttachmentIndexInfo) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdSetRenderingInputAttachmentIndices,
                          VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdSetRenderingInputAttachmentIndices");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdSetRenderingInputAttachmentIndices]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdSetRenderingInputAttachmentIndices(commandBuffer, pInputAttachmentIndexInfo, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdSetRenderingInputAttachmentIndices);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdSetRenderingInputAttachmentIndices");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdSetRenderingInputAttachmentIndices]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdSetRenderingInputAttachmentIndices(commandBuffer, pInputAttachmentIndexInfo, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdSetRenderingInputAttachmentIndices");
        device_dispatch->CmdSetRenderingInputAttachmentIndices(commandBuffer, pInputAttachmentIndexInfo);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdSetRenderingInputAttachmentIndices");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdSetRenderingInputAttachmentIndices]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdSetRenderingInputAttachmentIndices(commandBuffer, pInputAttachmentIndexInfo, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL DestroySurfaceKHR(VkInstance instance, VkSurfaceKHR surface, const VkAllocationCallbacks* pAllocator) {
    VVL_ZoneScoped;

    auto instance_dispatch = vvl::dispatch::GetData(instance);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkDestroySurfaceKHR, VulkanTypedHandle(instance, kVulkanObjectTypeInstance));
    {
        VVL_ZoneScopedN("PreCallValidate_vkDestroySurfaceKHR");
        for (const auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            skip |= vo->PreCallValidateDestroySurfaceKHR(instance, surface, pAllocator, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkDestroySurfaceKHR);
    {
        VVL_ZoneScopedN("PreCallRecord_vkDestroySurfaceKHR");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PreCallRecordDestroySurfaceKHR(instance, surface, pAllocator, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkDestroySurfaceKHR");
        instance_dispatch->DestroySurfaceKHR(instance, surface, pAllocator);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkDestroySurfaceKHR");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PostCallRecordDestroySurfaceKHR(instance, surface, pAllocator, record_obj);
        }
    }
}

VKAPI_ATTR VkResult VKAPI_CALL GetPhysicalDeviceSurfaceSupportKHR(VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex,
                                                                  VkSurfaceKHR surface, VkBool32* pSupported) {
    VVL_ZoneScoped;

    auto instance_dispatch = vvl::dispatch::GetData(physicalDevice);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetPhysicalDeviceSurfaceSupportKHR,
                          VulkanTypedHandle(physicalDevice, kVulkanObjectTypePhysicalDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetPhysicalDeviceSurfaceSupportKHR");
        for (const auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            skip |= vo->PreCallValidateGetPhysicalDeviceSurfaceSupportKHR(physicalDevice, queueFamilyIndex, surface, pSupported,
                                                                          error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetPhysicalDeviceSurfaceSupportKHR);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetPhysicalDeviceSurfaceSupportKHR");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PreCallRecordGetPhysicalDeviceSurfaceSupportKHR(physicalDevice, queueFamilyIndex, surface, pSupported, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkGetPhysicalDeviceSurfaceSupportKHR");
        result = instance_dispatch->GetPhysicalDeviceSurfaceSupportKHR(physicalDevice, queueFamilyIndex, surface, pSupported);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetPhysicalDeviceSurfaceSupportKHR");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PostCallRecordGetPhysicalDeviceSurfaceSupportKHR(physicalDevice, queueFamilyIndex, surface, pSupported, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR VkResult VKAPI_CALL GetPhysicalDeviceSurfaceCapabilitiesKHR(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface,
                                                                       VkSurfaceCapabilitiesKHR* pSurfaceCapabilities) {
    VVL_ZoneScoped;

    auto instance_dispatch = vvl::dispatch::GetData(physicalDevice);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetPhysicalDeviceSurfaceCapabilitiesKHR,
                          VulkanTypedHandle(physicalDevice, kVulkanObjectTypePhysicalDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetPhysicalDeviceSurfaceCapabilitiesKHR");
        for (const auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            skip |= vo->PreCallValidateGetPhysicalDeviceSurfaceCapabilitiesKHR(physicalDevice, surface, pSurfaceCapabilities,
                                                                               error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetPhysicalDeviceSurfaceCapabilitiesKHR);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetPhysicalDeviceSurfaceCapabilitiesKHR");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PreCallRecordGetPhysicalDeviceSurfaceCapabilitiesKHR(physicalDevice, surface, pSurfaceCapabilities, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkGetPhysicalDeviceSurfaceCapabilitiesKHR");
        result = instance_dispatch->GetPhysicalDeviceSurfaceCapabilitiesKHR(physicalDevice, surface, pSurfaceCapabilities);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetPhysicalDeviceSurfaceCapabilitiesKHR");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PostCallRecordGetPhysicalDeviceSurfaceCapabilitiesKHR(physicalDevice, surface, pSurfaceCapabilities, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR VkResult VKAPI_CALL GetPhysicalDeviceSurfaceFormatsKHR(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface,
                                                                  uint32_t* pSurfaceFormatCount,
                                                                  VkSurfaceFormatKHR* pSurfaceFormats) {
    VVL_ZoneScoped;

    auto instance_dispatch = vvl::dispatch::GetData(physicalDevice);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetPhysicalDeviceSurfaceFormatsKHR,
                          VulkanTypedHandle(physicalDevice, kVulkanObjectTypePhysicalDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetPhysicalDeviceSurfaceFormatsKHR");
        for (const auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            skip |= vo->PreCallValidateGetPhysicalDeviceSurfaceFormatsKHR(physicalDevice, surface, pSurfaceFormatCount,
                                                                          pSurfaceFormats, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetPhysicalDeviceSurfaceFormatsKHR);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetPhysicalDeviceSurfaceFormatsKHR");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PreCallRecordGetPhysicalDeviceSurfaceFormatsKHR(physicalDevice, surface, pSurfaceFormatCount, pSurfaceFormats,
                                                                record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkGetPhysicalDeviceSurfaceFormatsKHR");
        result =
            instance_dispatch->GetPhysicalDeviceSurfaceFormatsKHR(physicalDevice, surface, pSurfaceFormatCount, pSurfaceFormats);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetPhysicalDeviceSurfaceFormatsKHR");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PostCallRecordGetPhysicalDeviceSurfaceFormatsKHR(physicalDevice, surface, pSurfaceFormatCount, pSurfaceFormats,
                                                                 record_obj);
        }
    }
    return result;
}

VKAPI_ATTR VkResult VKAPI_CALL GetPhysicalDeviceSurfacePresentModesKHR(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface,
                                                                       uint32_t* pPresentModeCount,
                                                                       VkPresentModeKHR* pPresentModes) {
    VVL_ZoneScoped;

    auto instance_dispatch = vvl::dispatch::GetData(physicalDevice);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetPhysicalDeviceSurfacePresentModesKHR,
                          VulkanTypedHandle(physicalDevice, kVulkanObjectTypePhysicalDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetPhysicalDeviceSurfacePresentModesKHR");
        for (const auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            skip |= vo->PreCallValidateGetPhysicalDeviceSurfacePresentModesKHR(physicalDevice, surface, pPresentModeCount,
                                                                               pPresentModes, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetPhysicalDeviceSurfacePresentModesKHR);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetPhysicalDeviceSurfacePresentModesKHR");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PreCallRecordGetPhysicalDeviceSurfacePresentModesKHR(physicalDevice, surface, pPresentModeCount, pPresentModes,
                                                                     record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkGetPhysicalDeviceSurfacePresentModesKHR");
        result =
            instance_dispatch->GetPhysicalDeviceSurfacePresentModesKHR(physicalDevice, surface, pPresentModeCount, pPresentModes);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetPhysicalDeviceSurfacePresentModesKHR");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PostCallRecordGetPhysicalDeviceSurfacePresentModesKHR(physicalDevice, surface, pPresentModeCount, pPresentModes,
                                                                      record_obj);
        }
    }
    return result;
}

VKAPI_ATTR VkResult VKAPI_CALL CreateSwapchainKHR(VkDevice device, const VkSwapchainCreateInfoKHR* pCreateInfo,
                                                  const VkAllocationCallbacks* pAllocator, VkSwapchainKHR* pSwapchain) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCreateSwapchainKHR, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCreateSwapchainKHR");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCreateSwapchainKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCreateSwapchainKHR(device, pCreateInfo, pAllocator, pSwapchain, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkCreateSwapchainKHR);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCreateSwapchainKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCreateSwapchainKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCreateSwapchainKHR(device, pCreateInfo, pAllocator, pSwapchain, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkCreateSwapchainKHR");
        result = device_dispatch->CreateSwapchainKHR(device, pCreateInfo, pAllocator, pSwapchain);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkCreateSwapchainKHR");

        if (result == VK_ERROR_DEVICE_LOST) {
            for (auto& vo : device_dispatch->object_dispatch) {
                vo->is_device_lost = true;
            }
        }
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCreateSwapchainKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCreateSwapchainKHR(device, pCreateInfo, pAllocator, pSwapchain, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR void VKAPI_CALL DestroySwapchainKHR(VkDevice device, VkSwapchainKHR swapchain, const VkAllocationCallbacks* pAllocator) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkDestroySwapchainKHR, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkDestroySwapchainKHR");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateDestroySwapchainKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateDestroySwapchainKHR(device, swapchain, pAllocator, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkDestroySwapchainKHR);
    {
        VVL_ZoneScopedN("PreCallRecord_vkDestroySwapchainKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordDestroySwapchainKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordDestroySwapchainKHR(device, swapchain, pAllocator, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkDestroySwapchainKHR");
        device_dispatch->DestroySwapchainKHR(device, swapchain, pAllocator);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkDestroySwapchainKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordDestroySwapchainKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordDestroySwapchainKHR(device, swapchain, pAllocator, record_obj);
        }
    }
}

VKAPI_ATTR VkResult VKAPI_CALL GetSwapchainImagesKHR(VkDevice device, VkSwapchainKHR swapchain, uint32_t* pSwapchainImageCount,
                                                     VkImage* pSwapchainImages) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetSwapchainImagesKHR, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetSwapchainImagesKHR");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateGetSwapchainImagesKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateGetSwapchainImagesKHR(device, swapchain, pSwapchainImageCount, pSwapchainImages, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetSwapchainImagesKHR);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetSwapchainImagesKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordGetSwapchainImagesKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordGetSwapchainImagesKHR(device, swapchain, pSwapchainImageCount, pSwapchainImages, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkGetSwapchainImagesKHR");
        result = device_dispatch->GetSwapchainImagesKHR(device, swapchain, pSwapchainImageCount, pSwapchainImages);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetSwapchainImagesKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordGetSwapchainImagesKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordGetSwapchainImagesKHR(device, swapchain, pSwapchainImageCount, pSwapchainImages, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR VkResult VKAPI_CALL AcquireNextImageKHR(VkDevice device, VkSwapchainKHR swapchain, uint64_t timeout,
                                                   VkSemaphore semaphore, VkFence fence, uint32_t* pImageIndex) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkAcquireNextImageKHR, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkAcquireNextImageKHR");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateAcquireNextImageKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateAcquireNextImageKHR(device, swapchain, timeout, semaphore, fence, pImageIndex, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkAcquireNextImageKHR);
    {
        VVL_ZoneScopedN("PreCallRecord_vkAcquireNextImageKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordAcquireNextImageKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordAcquireNextImageKHR(device, swapchain, timeout, semaphore, fence, pImageIndex, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkAcquireNextImageKHR");
        result = device_dispatch->AcquireNextImageKHR(device, swapchain, timeout, semaphore, fence, pImageIndex);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkAcquireNextImageKHR");

        if (result == VK_ERROR_DEVICE_LOST) {
            for (auto& vo : device_dispatch->object_dispatch) {
                vo->is_device_lost = true;
            }
        }
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordAcquireNextImageKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordAcquireNextImageKHR(device, swapchain, timeout, semaphore, fence, pImageIndex, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR VkResult VKAPI_CALL
GetDeviceGroupPresentCapabilitiesKHR(VkDevice device, VkDeviceGroupPresentCapabilitiesKHR* pDeviceGroupPresentCapabilities) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetDeviceGroupPresentCapabilitiesKHR, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetDeviceGroupPresentCapabilitiesKHR");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateGetDeviceGroupPresentCapabilitiesKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateGetDeviceGroupPresentCapabilitiesKHR(device, pDeviceGroupPresentCapabilities, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetDeviceGroupPresentCapabilitiesKHR);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetDeviceGroupPresentCapabilitiesKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordGetDeviceGroupPresentCapabilitiesKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordGetDeviceGroupPresentCapabilitiesKHR(device, pDeviceGroupPresentCapabilities, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkGetDeviceGroupPresentCapabilitiesKHR");
        result = device_dispatch->GetDeviceGroupPresentCapabilitiesKHR(device, pDeviceGroupPresentCapabilities);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetDeviceGroupPresentCapabilitiesKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordGetDeviceGroupPresentCapabilitiesKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordGetDeviceGroupPresentCapabilitiesKHR(device, pDeviceGroupPresentCapabilities, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR VkResult VKAPI_CALL GetDeviceGroupSurfacePresentModesKHR(VkDevice device, VkSurfaceKHR surface,
                                                                    VkDeviceGroupPresentModeFlagsKHR* pModes) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetDeviceGroupSurfacePresentModesKHR, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetDeviceGroupSurfacePresentModesKHR");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateGetDeviceGroupSurfacePresentModesKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateGetDeviceGroupSurfacePresentModesKHR(device, surface, pModes, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetDeviceGroupSurfacePresentModesKHR);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetDeviceGroupSurfacePresentModesKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordGetDeviceGroupSurfacePresentModesKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordGetDeviceGroupSurfacePresentModesKHR(device, surface, pModes, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkGetDeviceGroupSurfacePresentModesKHR");
        result = device_dispatch->GetDeviceGroupSurfacePresentModesKHR(device, surface, pModes);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetDeviceGroupSurfacePresentModesKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordGetDeviceGroupSurfacePresentModesKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordGetDeviceGroupSurfacePresentModesKHR(device, surface, pModes, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR VkResult VKAPI_CALL GetPhysicalDevicePresentRectanglesKHR(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface,
                                                                     uint32_t* pRectCount, VkRect2D* pRects) {
    VVL_ZoneScoped;

    auto instance_dispatch = vvl::dispatch::GetData(physicalDevice);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetPhysicalDevicePresentRectanglesKHR,
                          VulkanTypedHandle(physicalDevice, kVulkanObjectTypePhysicalDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetPhysicalDevicePresentRectanglesKHR");
        for (const auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            skip |=
                vo->PreCallValidateGetPhysicalDevicePresentRectanglesKHR(physicalDevice, surface, pRectCount, pRects, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetPhysicalDevicePresentRectanglesKHR);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetPhysicalDevicePresentRectanglesKHR");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PreCallRecordGetPhysicalDevicePresentRectanglesKHR(physicalDevice, surface, pRectCount, pRects, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkGetPhysicalDevicePresentRectanglesKHR");
        result = instance_dispatch->GetPhysicalDevicePresentRectanglesKHR(physicalDevice, surface, pRectCount, pRects);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetPhysicalDevicePresentRectanglesKHR");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PostCallRecordGetPhysicalDevicePresentRectanglesKHR(physicalDevice, surface, pRectCount, pRects, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR VkResult VKAPI_CALL AcquireNextImage2KHR(VkDevice device, const VkAcquireNextImageInfoKHR* pAcquireInfo,
                                                    uint32_t* pImageIndex) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkAcquireNextImage2KHR, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkAcquireNextImage2KHR");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateAcquireNextImage2KHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateAcquireNextImage2KHR(device, pAcquireInfo, pImageIndex, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkAcquireNextImage2KHR);
    {
        VVL_ZoneScopedN("PreCallRecord_vkAcquireNextImage2KHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordAcquireNextImage2KHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordAcquireNextImage2KHR(device, pAcquireInfo, pImageIndex, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkAcquireNextImage2KHR");
        result = device_dispatch->AcquireNextImage2KHR(device, pAcquireInfo, pImageIndex);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkAcquireNextImage2KHR");

        if (result == VK_ERROR_DEVICE_LOST) {
            for (auto& vo : device_dispatch->object_dispatch) {
                vo->is_device_lost = true;
            }
        }
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordAcquireNextImage2KHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordAcquireNextImage2KHR(device, pAcquireInfo, pImageIndex, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR VkResult VKAPI_CALL GetPhysicalDeviceDisplayPropertiesKHR(VkPhysicalDevice physicalDevice, uint32_t* pPropertyCount,
                                                                     VkDisplayPropertiesKHR* pProperties) {
    VVL_ZoneScoped;

    auto instance_dispatch = vvl::dispatch::GetData(physicalDevice);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetPhysicalDeviceDisplayPropertiesKHR,
                          VulkanTypedHandle(physicalDevice, kVulkanObjectTypePhysicalDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetPhysicalDeviceDisplayPropertiesKHR");
        for (const auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            skip |=
                vo->PreCallValidateGetPhysicalDeviceDisplayPropertiesKHR(physicalDevice, pPropertyCount, pProperties, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetPhysicalDeviceDisplayPropertiesKHR);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetPhysicalDeviceDisplayPropertiesKHR");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PreCallRecordGetPhysicalDeviceDisplayPropertiesKHR(physicalDevice, pPropertyCount, pProperties, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkGetPhysicalDeviceDisplayPropertiesKHR");
        result = instance_dispatch->GetPhysicalDeviceDisplayPropertiesKHR(physicalDevice, pPropertyCount, pProperties);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetPhysicalDeviceDisplayPropertiesKHR");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PostCallRecordGetPhysicalDeviceDisplayPropertiesKHR(physicalDevice, pPropertyCount, pProperties, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR VkResult VKAPI_CALL GetPhysicalDeviceDisplayPlanePropertiesKHR(VkPhysicalDevice physicalDevice, uint32_t* pPropertyCount,
                                                                          VkDisplayPlanePropertiesKHR* pProperties) {
    VVL_ZoneScoped;

    auto instance_dispatch = vvl::dispatch::GetData(physicalDevice);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetPhysicalDeviceDisplayPlanePropertiesKHR,
                          VulkanTypedHandle(physicalDevice, kVulkanObjectTypePhysicalDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetPhysicalDeviceDisplayPlanePropertiesKHR");
        for (const auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            skip |= vo->PreCallValidateGetPhysicalDeviceDisplayPlanePropertiesKHR(physicalDevice, pPropertyCount, pProperties,
                                                                                  error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetPhysicalDeviceDisplayPlanePropertiesKHR);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetPhysicalDeviceDisplayPlanePropertiesKHR");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PreCallRecordGetPhysicalDeviceDisplayPlanePropertiesKHR(physicalDevice, pPropertyCount, pProperties, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkGetPhysicalDeviceDisplayPlanePropertiesKHR");
        result = instance_dispatch->GetPhysicalDeviceDisplayPlanePropertiesKHR(physicalDevice, pPropertyCount, pProperties);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetPhysicalDeviceDisplayPlanePropertiesKHR");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PostCallRecordGetPhysicalDeviceDisplayPlanePropertiesKHR(physicalDevice, pPropertyCount, pProperties, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR VkResult VKAPI_CALL GetDisplayPlaneSupportedDisplaysKHR(VkPhysicalDevice physicalDevice, uint32_t planeIndex,
                                                                   uint32_t* pDisplayCount, VkDisplayKHR* pDisplays) {
    VVL_ZoneScoped;

    auto instance_dispatch = vvl::dispatch::GetData(physicalDevice);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetDisplayPlaneSupportedDisplaysKHR,
                          VulkanTypedHandle(physicalDevice, kVulkanObjectTypePhysicalDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetDisplayPlaneSupportedDisplaysKHR");
        for (const auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            skip |= vo->PreCallValidateGetDisplayPlaneSupportedDisplaysKHR(physicalDevice, planeIndex, pDisplayCount, pDisplays,
                                                                           error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetDisplayPlaneSupportedDisplaysKHR);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetDisplayPlaneSupportedDisplaysKHR");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PreCallRecordGetDisplayPlaneSupportedDisplaysKHR(physicalDevice, planeIndex, pDisplayCount, pDisplays, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkGetDisplayPlaneSupportedDisplaysKHR");
        result = instance_dispatch->GetDisplayPlaneSupportedDisplaysKHR(physicalDevice, planeIndex, pDisplayCount, pDisplays);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetDisplayPlaneSupportedDisplaysKHR");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PostCallRecordGetDisplayPlaneSupportedDisplaysKHR(physicalDevice, planeIndex, pDisplayCount, pDisplays, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR VkResult VKAPI_CALL GetDisplayModePropertiesKHR(VkPhysicalDevice physicalDevice, VkDisplayKHR display,
                                                           uint32_t* pPropertyCount, VkDisplayModePropertiesKHR* pProperties) {
    VVL_ZoneScoped;

    auto instance_dispatch = vvl::dispatch::GetData(physicalDevice);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetDisplayModePropertiesKHR,
                          VulkanTypedHandle(physicalDevice, kVulkanObjectTypePhysicalDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetDisplayModePropertiesKHR");
        for (const auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            skip |= vo->PreCallValidateGetDisplayModePropertiesKHR(physicalDevice, display, pPropertyCount, pProperties, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetDisplayModePropertiesKHR);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetDisplayModePropertiesKHR");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PreCallRecordGetDisplayModePropertiesKHR(physicalDevice, display, pPropertyCount, pProperties, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkGetDisplayModePropertiesKHR");
        result = instance_dispatch->GetDisplayModePropertiesKHR(physicalDevice, display, pPropertyCount, pProperties);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetDisplayModePropertiesKHR");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PostCallRecordGetDisplayModePropertiesKHR(physicalDevice, display, pPropertyCount, pProperties, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR VkResult VKAPI_CALL CreateDisplayModeKHR(VkPhysicalDevice physicalDevice, VkDisplayKHR display,
                                                    const VkDisplayModeCreateInfoKHR* pCreateInfo,
                                                    const VkAllocationCallbacks* pAllocator, VkDisplayModeKHR* pMode) {
    VVL_ZoneScoped;

    auto instance_dispatch = vvl::dispatch::GetData(physicalDevice);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCreateDisplayModeKHR, VulkanTypedHandle(physicalDevice, kVulkanObjectTypePhysicalDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCreateDisplayModeKHR");
        for (const auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            skip |= vo->PreCallValidateCreateDisplayModeKHR(physicalDevice, display, pCreateInfo, pAllocator, pMode, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkCreateDisplayModeKHR);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCreateDisplayModeKHR");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PreCallRecordCreateDisplayModeKHR(physicalDevice, display, pCreateInfo, pAllocator, pMode, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkCreateDisplayModeKHR");
        result = instance_dispatch->CreateDisplayModeKHR(physicalDevice, display, pCreateInfo, pAllocator, pMode);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkCreateDisplayModeKHR");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PostCallRecordCreateDisplayModeKHR(physicalDevice, display, pCreateInfo, pAllocator, pMode, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR VkResult VKAPI_CALL GetDisplayPlaneCapabilitiesKHR(VkPhysicalDevice physicalDevice, VkDisplayModeKHR mode,
                                                              uint32_t planeIndex, VkDisplayPlaneCapabilitiesKHR* pCapabilities) {
    VVL_ZoneScoped;

    auto instance_dispatch = vvl::dispatch::GetData(physicalDevice);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetDisplayPlaneCapabilitiesKHR,
                          VulkanTypedHandle(physicalDevice, kVulkanObjectTypePhysicalDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetDisplayPlaneCapabilitiesKHR");
        for (const auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            skip |= vo->PreCallValidateGetDisplayPlaneCapabilitiesKHR(physicalDevice, mode, planeIndex, pCapabilities, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetDisplayPlaneCapabilitiesKHR);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetDisplayPlaneCapabilitiesKHR");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PreCallRecordGetDisplayPlaneCapabilitiesKHR(physicalDevice, mode, planeIndex, pCapabilities, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkGetDisplayPlaneCapabilitiesKHR");
        result = instance_dispatch->GetDisplayPlaneCapabilitiesKHR(physicalDevice, mode, planeIndex, pCapabilities);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetDisplayPlaneCapabilitiesKHR");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PostCallRecordGetDisplayPlaneCapabilitiesKHR(physicalDevice, mode, planeIndex, pCapabilities, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR VkResult VKAPI_CALL CreateDisplayPlaneSurfaceKHR(VkInstance instance, const VkDisplaySurfaceCreateInfoKHR* pCreateInfo,
                                                            const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface) {
    VVL_ZoneScoped;

    auto instance_dispatch = vvl::dispatch::GetData(instance);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCreateDisplayPlaneSurfaceKHR, VulkanTypedHandle(instance, kVulkanObjectTypeInstance));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCreateDisplayPlaneSurfaceKHR");
        for (const auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            skip |= vo->PreCallValidateCreateDisplayPlaneSurfaceKHR(instance, pCreateInfo, pAllocator, pSurface, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkCreateDisplayPlaneSurfaceKHR);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCreateDisplayPlaneSurfaceKHR");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PreCallRecordCreateDisplayPlaneSurfaceKHR(instance, pCreateInfo, pAllocator, pSurface, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkCreateDisplayPlaneSurfaceKHR");
        result = instance_dispatch->CreateDisplayPlaneSurfaceKHR(instance, pCreateInfo, pAllocator, pSurface);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkCreateDisplayPlaneSurfaceKHR");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PostCallRecordCreateDisplayPlaneSurfaceKHR(instance, pCreateInfo, pAllocator, pSurface, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR VkResult VKAPI_CALL CreateSharedSwapchainsKHR(VkDevice device, uint32_t swapchainCount,
                                                         const VkSwapchainCreateInfoKHR* pCreateInfos,
                                                         const VkAllocationCallbacks* pAllocator, VkSwapchainKHR* pSwapchains) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCreateSharedSwapchainsKHR, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCreateSharedSwapchainsKHR");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCreateSharedSwapchainsKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCreateSharedSwapchainsKHR(device, swapchainCount, pCreateInfos, pAllocator, pSwapchains,
                                                                 error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkCreateSharedSwapchainsKHR);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCreateSharedSwapchainsKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCreateSharedSwapchainsKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCreateSharedSwapchainsKHR(device, swapchainCount, pCreateInfos, pAllocator, pSwapchains, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkCreateSharedSwapchainsKHR");
        result = device_dispatch->CreateSharedSwapchainsKHR(device, swapchainCount, pCreateInfos, pAllocator, pSwapchains);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkCreateSharedSwapchainsKHR");

        if (result == VK_ERROR_DEVICE_LOST) {
            for (auto& vo : device_dispatch->object_dispatch) {
                vo->is_device_lost = true;
            }
        }
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCreateSharedSwapchainsKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCreateSharedSwapchainsKHR(device, swapchainCount, pCreateInfos, pAllocator, pSwapchains, record_obj);
        }
    }
    return result;
}

#ifdef VK_USE_PLATFORM_XLIB_KHR
VKAPI_ATTR VkResult VKAPI_CALL CreateXlibSurfaceKHR(VkInstance instance, const VkXlibSurfaceCreateInfoKHR* pCreateInfo,
                                                    const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface) {
    VVL_ZoneScoped;

    auto instance_dispatch = vvl::dispatch::GetData(instance);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCreateXlibSurfaceKHR, VulkanTypedHandle(instance, kVulkanObjectTypeInstance));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCreateXlibSurfaceKHR");
        for (const auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            skip |= vo->PreCallValidateCreateXlibSurfaceKHR(instance, pCreateInfo, pAllocator, pSurface, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkCreateXlibSurfaceKHR);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCreateXlibSurfaceKHR");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PreCallRecordCreateXlibSurfaceKHR(instance, pCreateInfo, pAllocator, pSurface, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkCreateXlibSurfaceKHR");
        result = instance_dispatch->CreateXlibSurfaceKHR(instance, pCreateInfo, pAllocator, pSurface);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkCreateXlibSurfaceKHR");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PostCallRecordCreateXlibSurfaceKHR(instance, pCreateInfo, pAllocator, pSurface, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR VkBool32 VKAPI_CALL GetPhysicalDeviceXlibPresentationSupportKHR(VkPhysicalDevice physicalDevice,
                                                                           uint32_t queueFamilyIndex, Display* dpy,
                                                                           VisualID visualID) {
    VVL_ZoneScoped;

    auto instance_dispatch = vvl::dispatch::GetData(physicalDevice);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetPhysicalDeviceXlibPresentationSupportKHR,
                          VulkanTypedHandle(physicalDevice, kVulkanObjectTypePhysicalDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetPhysicalDeviceXlibPresentationSupportKHR");
        for (const auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            skip |= vo->PreCallValidateGetPhysicalDeviceXlibPresentationSupportKHR(physicalDevice, queueFamilyIndex, dpy, visualID,
                                                                                   error_obj);
            if (skip) return VK_FALSE;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetPhysicalDeviceXlibPresentationSupportKHR);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetPhysicalDeviceXlibPresentationSupportKHR");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PreCallRecordGetPhysicalDeviceXlibPresentationSupportKHR(physicalDevice, queueFamilyIndex, dpy, visualID,
                                                                         record_obj);
        }
    }
    VkBool32 result;
    {
        VVL_ZoneScopedN("Dispatch_vkGetPhysicalDeviceXlibPresentationSupportKHR");
        result = instance_dispatch->GetPhysicalDeviceXlibPresentationSupportKHR(physicalDevice, queueFamilyIndex, dpy, visualID);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetPhysicalDeviceXlibPresentationSupportKHR");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PostCallRecordGetPhysicalDeviceXlibPresentationSupportKHR(physicalDevice, queueFamilyIndex, dpy, visualID,
                                                                          record_obj);
        }
    }
    return result;
}

#endif  // VK_USE_PLATFORM_XLIB_KHR
#ifdef VK_USE_PLATFORM_XCB_KHR
VKAPI_ATTR VkResult VKAPI_CALL CreateXcbSurfaceKHR(VkInstance instance, const VkXcbSurfaceCreateInfoKHR* pCreateInfo,
                                                   const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface) {
    VVL_ZoneScoped;

    auto instance_dispatch = vvl::dispatch::GetData(instance);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCreateXcbSurfaceKHR, VulkanTypedHandle(instance, kVulkanObjectTypeInstance));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCreateXcbSurfaceKHR");
        for (const auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            skip |= vo->PreCallValidateCreateXcbSurfaceKHR(instance, pCreateInfo, pAllocator, pSurface, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkCreateXcbSurfaceKHR);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCreateXcbSurfaceKHR");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PreCallRecordCreateXcbSurfaceKHR(instance, pCreateInfo, pAllocator, pSurface, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkCreateXcbSurfaceKHR");
        result = instance_dispatch->CreateXcbSurfaceKHR(instance, pCreateInfo, pAllocator, pSurface);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkCreateXcbSurfaceKHR");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PostCallRecordCreateXcbSurfaceKHR(instance, pCreateInfo, pAllocator, pSurface, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR VkBool32 VKAPI_CALL GetPhysicalDeviceXcbPresentationSupportKHR(VkPhysicalDevice physicalDevice,
                                                                          uint32_t queueFamilyIndex, xcb_connection_t* connection,
                                                                          xcb_visualid_t visual_id) {
    VVL_ZoneScoped;

    auto instance_dispatch = vvl::dispatch::GetData(physicalDevice);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetPhysicalDeviceXcbPresentationSupportKHR,
                          VulkanTypedHandle(physicalDevice, kVulkanObjectTypePhysicalDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetPhysicalDeviceXcbPresentationSupportKHR");
        for (const auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            skip |= vo->PreCallValidateGetPhysicalDeviceXcbPresentationSupportKHR(physicalDevice, queueFamilyIndex, connection,
                                                                                  visual_id, error_obj);
            if (skip) return VK_FALSE;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetPhysicalDeviceXcbPresentationSupportKHR);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetPhysicalDeviceXcbPresentationSupportKHR");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PreCallRecordGetPhysicalDeviceXcbPresentationSupportKHR(physicalDevice, queueFamilyIndex, connection, visual_id,
                                                                        record_obj);
        }
    }
    VkBool32 result;
    {
        VVL_ZoneScopedN("Dispatch_vkGetPhysicalDeviceXcbPresentationSupportKHR");
        result =
            instance_dispatch->GetPhysicalDeviceXcbPresentationSupportKHR(physicalDevice, queueFamilyIndex, connection, visual_id);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetPhysicalDeviceXcbPresentationSupportKHR");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PostCallRecordGetPhysicalDeviceXcbPresentationSupportKHR(physicalDevice, queueFamilyIndex, connection, visual_id,
                                                                         record_obj);
        }
    }
    return result;
}

#endif  // VK_USE_PLATFORM_XCB_KHR
#ifdef VK_USE_PLATFORM_WAYLAND_KHR
VKAPI_ATTR VkResult VKAPI_CALL CreateWaylandSurfaceKHR(VkInstance instance, const VkWaylandSurfaceCreateInfoKHR* pCreateInfo,
                                                       const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface) {
    VVL_ZoneScoped;

    auto instance_dispatch = vvl::dispatch::GetData(instance);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCreateWaylandSurfaceKHR, VulkanTypedHandle(instance, kVulkanObjectTypeInstance));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCreateWaylandSurfaceKHR");
        for (const auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            skip |= vo->PreCallValidateCreateWaylandSurfaceKHR(instance, pCreateInfo, pAllocator, pSurface, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkCreateWaylandSurfaceKHR);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCreateWaylandSurfaceKHR");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PreCallRecordCreateWaylandSurfaceKHR(instance, pCreateInfo, pAllocator, pSurface, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkCreateWaylandSurfaceKHR");
        result = instance_dispatch->CreateWaylandSurfaceKHR(instance, pCreateInfo, pAllocator, pSurface);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkCreateWaylandSurfaceKHR");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PostCallRecordCreateWaylandSurfaceKHR(instance, pCreateInfo, pAllocator, pSurface, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR VkBool32 VKAPI_CALL GetPhysicalDeviceWaylandPresentationSupportKHR(VkPhysicalDevice physicalDevice,
                                                                              uint32_t queueFamilyIndex,
                                                                              struct wl_display* display) {
    VVL_ZoneScoped;

    auto instance_dispatch = vvl::dispatch::GetData(physicalDevice);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetPhysicalDeviceWaylandPresentationSupportKHR,
                          VulkanTypedHandle(physicalDevice, kVulkanObjectTypePhysicalDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetPhysicalDeviceWaylandPresentationSupportKHR");
        for (const auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            skip |= vo->PreCallValidateGetPhysicalDeviceWaylandPresentationSupportKHR(physicalDevice, queueFamilyIndex, display,
                                                                                      error_obj);
            if (skip) return VK_FALSE;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetPhysicalDeviceWaylandPresentationSupportKHR);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetPhysicalDeviceWaylandPresentationSupportKHR");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PreCallRecordGetPhysicalDeviceWaylandPresentationSupportKHR(physicalDevice, queueFamilyIndex, display, record_obj);
        }
    }
    VkBool32 result;
    {
        VVL_ZoneScopedN("Dispatch_vkGetPhysicalDeviceWaylandPresentationSupportKHR");
        result = instance_dispatch->GetPhysicalDeviceWaylandPresentationSupportKHR(physicalDevice, queueFamilyIndex, display);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetPhysicalDeviceWaylandPresentationSupportKHR");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PostCallRecordGetPhysicalDeviceWaylandPresentationSupportKHR(physicalDevice, queueFamilyIndex, display, record_obj);
        }
    }
    return result;
}

#endif  // VK_USE_PLATFORM_WAYLAND_KHR
#ifdef VK_USE_PLATFORM_ANDROID_KHR
VKAPI_ATTR VkResult VKAPI_CALL CreateAndroidSurfaceKHR(VkInstance instance, const VkAndroidSurfaceCreateInfoKHR* pCreateInfo,
                                                       const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface) {
    VVL_ZoneScoped;

    auto instance_dispatch = vvl::dispatch::GetData(instance);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCreateAndroidSurfaceKHR, VulkanTypedHandle(instance, kVulkanObjectTypeInstance));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCreateAndroidSurfaceKHR");
        for (const auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            skip |= vo->PreCallValidateCreateAndroidSurfaceKHR(instance, pCreateInfo, pAllocator, pSurface, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkCreateAndroidSurfaceKHR);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCreateAndroidSurfaceKHR");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PreCallRecordCreateAndroidSurfaceKHR(instance, pCreateInfo, pAllocator, pSurface, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkCreateAndroidSurfaceKHR");
        result = instance_dispatch->CreateAndroidSurfaceKHR(instance, pCreateInfo, pAllocator, pSurface);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkCreateAndroidSurfaceKHR");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PostCallRecordCreateAndroidSurfaceKHR(instance, pCreateInfo, pAllocator, pSurface, record_obj);
        }
    }
    return result;
}

#endif  // VK_USE_PLATFORM_ANDROID_KHR
#ifdef VK_USE_PLATFORM_WIN32_KHR
VKAPI_ATTR VkResult VKAPI_CALL CreateWin32SurfaceKHR(VkInstance instance, const VkWin32SurfaceCreateInfoKHR* pCreateInfo,
                                                     const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface) {
    VVL_ZoneScoped;

    auto instance_dispatch = vvl::dispatch::GetData(instance);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCreateWin32SurfaceKHR, VulkanTypedHandle(instance, kVulkanObjectTypeInstance));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCreateWin32SurfaceKHR");
        for (const auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            skip |= vo->PreCallValidateCreateWin32SurfaceKHR(instance, pCreateInfo, pAllocator, pSurface, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkCreateWin32SurfaceKHR);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCreateWin32SurfaceKHR");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PreCallRecordCreateWin32SurfaceKHR(instance, pCreateInfo, pAllocator, pSurface, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkCreateWin32SurfaceKHR");
        result = instance_dispatch->CreateWin32SurfaceKHR(instance, pCreateInfo, pAllocator, pSurface);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkCreateWin32SurfaceKHR");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PostCallRecordCreateWin32SurfaceKHR(instance, pCreateInfo, pAllocator, pSurface, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR VkBool32 VKAPI_CALL GetPhysicalDeviceWin32PresentationSupportKHR(VkPhysicalDevice physicalDevice,
                                                                            uint32_t queueFamilyIndex) {
    VVL_ZoneScoped;

    auto instance_dispatch = vvl::dispatch::GetData(physicalDevice);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetPhysicalDeviceWin32PresentationSupportKHR,
                          VulkanTypedHandle(physicalDevice, kVulkanObjectTypePhysicalDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetPhysicalDeviceWin32PresentationSupportKHR");
        for (const auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            skip |= vo->PreCallValidateGetPhysicalDeviceWin32PresentationSupportKHR(physicalDevice, queueFamilyIndex, error_obj);
            if (skip) return VK_FALSE;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetPhysicalDeviceWin32PresentationSupportKHR);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetPhysicalDeviceWin32PresentationSupportKHR");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PreCallRecordGetPhysicalDeviceWin32PresentationSupportKHR(physicalDevice, queueFamilyIndex, record_obj);
        }
    }
    VkBool32 result;
    {
        VVL_ZoneScopedN("Dispatch_vkGetPhysicalDeviceWin32PresentationSupportKHR");
        result = instance_dispatch->GetPhysicalDeviceWin32PresentationSupportKHR(physicalDevice, queueFamilyIndex);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetPhysicalDeviceWin32PresentationSupportKHR");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PostCallRecordGetPhysicalDeviceWin32PresentationSupportKHR(physicalDevice, queueFamilyIndex, record_obj);
        }
    }
    return result;
}

#endif  // VK_USE_PLATFORM_WIN32_KHR
VKAPI_ATTR VkResult VKAPI_CALL GetPhysicalDeviceVideoCapabilitiesKHR(VkPhysicalDevice physicalDevice,
                                                                     const VkVideoProfileInfoKHR* pVideoProfile,
                                                                     VkVideoCapabilitiesKHR* pCapabilities) {
    VVL_ZoneScoped;

    auto instance_dispatch = vvl::dispatch::GetData(physicalDevice);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetPhysicalDeviceVideoCapabilitiesKHR,
                          VulkanTypedHandle(physicalDevice, kVulkanObjectTypePhysicalDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetPhysicalDeviceVideoCapabilitiesKHR");
        for (const auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            skip |=
                vo->PreCallValidateGetPhysicalDeviceVideoCapabilitiesKHR(physicalDevice, pVideoProfile, pCapabilities, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetPhysicalDeviceVideoCapabilitiesKHR);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetPhysicalDeviceVideoCapabilitiesKHR");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PreCallRecordGetPhysicalDeviceVideoCapabilitiesKHR(physicalDevice, pVideoProfile, pCapabilities, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkGetPhysicalDeviceVideoCapabilitiesKHR");
        result = instance_dispatch->GetPhysicalDeviceVideoCapabilitiesKHR(physicalDevice, pVideoProfile, pCapabilities);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetPhysicalDeviceVideoCapabilitiesKHR");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PostCallRecordGetPhysicalDeviceVideoCapabilitiesKHR(physicalDevice, pVideoProfile, pCapabilities, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR VkResult VKAPI_CALL GetPhysicalDeviceVideoFormatPropertiesKHR(VkPhysicalDevice physicalDevice,
                                                                         const VkPhysicalDeviceVideoFormatInfoKHR* pVideoFormatInfo,
                                                                         uint32_t* pVideoFormatPropertyCount,
                                                                         VkVideoFormatPropertiesKHR* pVideoFormatProperties) {
    VVL_ZoneScoped;

    auto instance_dispatch = vvl::dispatch::GetData(physicalDevice);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetPhysicalDeviceVideoFormatPropertiesKHR,
                          VulkanTypedHandle(physicalDevice, kVulkanObjectTypePhysicalDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetPhysicalDeviceVideoFormatPropertiesKHR");
        for (const auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            skip |= vo->PreCallValidateGetPhysicalDeviceVideoFormatPropertiesKHR(
                physicalDevice, pVideoFormatInfo, pVideoFormatPropertyCount, pVideoFormatProperties, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetPhysicalDeviceVideoFormatPropertiesKHR);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetPhysicalDeviceVideoFormatPropertiesKHR");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PreCallRecordGetPhysicalDeviceVideoFormatPropertiesKHR(physicalDevice, pVideoFormatInfo, pVideoFormatPropertyCount,
                                                                       pVideoFormatProperties, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkGetPhysicalDeviceVideoFormatPropertiesKHR");
        result = instance_dispatch->GetPhysicalDeviceVideoFormatPropertiesKHR(physicalDevice, pVideoFormatInfo,
                                                                              pVideoFormatPropertyCount, pVideoFormatProperties);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetPhysicalDeviceVideoFormatPropertiesKHR");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PostCallRecordGetPhysicalDeviceVideoFormatPropertiesKHR(physicalDevice, pVideoFormatInfo, pVideoFormatPropertyCount,
                                                                        pVideoFormatProperties, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR VkResult VKAPI_CALL CreateVideoSessionKHR(VkDevice device, const VkVideoSessionCreateInfoKHR* pCreateInfo,
                                                     const VkAllocationCallbacks* pAllocator, VkVideoSessionKHR* pVideoSession) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCreateVideoSessionKHR, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCreateVideoSessionKHR");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCreateVideoSessionKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCreateVideoSessionKHR(device, pCreateInfo, pAllocator, pVideoSession, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkCreateVideoSessionKHR);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCreateVideoSessionKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCreateVideoSessionKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCreateVideoSessionKHR(device, pCreateInfo, pAllocator, pVideoSession, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkCreateVideoSessionKHR");
        result = device_dispatch->CreateVideoSessionKHR(device, pCreateInfo, pAllocator, pVideoSession);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkCreateVideoSessionKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCreateVideoSessionKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCreateVideoSessionKHR(device, pCreateInfo, pAllocator, pVideoSession, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR void VKAPI_CALL DestroyVideoSessionKHR(VkDevice device, VkVideoSessionKHR videoSession,
                                                  const VkAllocationCallbacks* pAllocator) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkDestroyVideoSessionKHR, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkDestroyVideoSessionKHR");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateDestroyVideoSessionKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateDestroyVideoSessionKHR(device, videoSession, pAllocator, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkDestroyVideoSessionKHR);
    {
        VVL_ZoneScopedN("PreCallRecord_vkDestroyVideoSessionKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordDestroyVideoSessionKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordDestroyVideoSessionKHR(device, videoSession, pAllocator, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkDestroyVideoSessionKHR");
        device_dispatch->DestroyVideoSessionKHR(device, videoSession, pAllocator);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkDestroyVideoSessionKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordDestroyVideoSessionKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordDestroyVideoSessionKHR(device, videoSession, pAllocator, record_obj);
        }
    }
}

VKAPI_ATTR VkResult VKAPI_CALL GetVideoSessionMemoryRequirementsKHR(VkDevice device, VkVideoSessionKHR videoSession,
                                                                    uint32_t* pMemoryRequirementsCount,
                                                                    VkVideoSessionMemoryRequirementsKHR* pMemoryRequirements) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetVideoSessionMemoryRequirementsKHR, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetVideoSessionMemoryRequirementsKHR");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateGetVideoSessionMemoryRequirementsKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateGetVideoSessionMemoryRequirementsKHR(device, videoSession, pMemoryRequirementsCount,
                                                                            pMemoryRequirements, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetVideoSessionMemoryRequirementsKHR);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetVideoSessionMemoryRequirementsKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordGetVideoSessionMemoryRequirementsKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordGetVideoSessionMemoryRequirementsKHR(device, videoSession, pMemoryRequirementsCount,
                                                                  pMemoryRequirements, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkGetVideoSessionMemoryRequirementsKHR");
        result = device_dispatch->GetVideoSessionMemoryRequirementsKHR(device, videoSession, pMemoryRequirementsCount,
                                                                       pMemoryRequirements);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetVideoSessionMemoryRequirementsKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordGetVideoSessionMemoryRequirementsKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordGetVideoSessionMemoryRequirementsKHR(device, videoSession, pMemoryRequirementsCount,
                                                                   pMemoryRequirements, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR VkResult VKAPI_CALL BindVideoSessionMemoryKHR(VkDevice device, VkVideoSessionKHR videoSession,
                                                         uint32_t bindSessionMemoryInfoCount,
                                                         const VkBindVideoSessionMemoryInfoKHR* pBindSessionMemoryInfos) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkBindVideoSessionMemoryKHR, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkBindVideoSessionMemoryKHR");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateBindVideoSessionMemoryKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateBindVideoSessionMemoryKHR(device, videoSession, bindSessionMemoryInfoCount,
                                                                 pBindSessionMemoryInfos, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkBindVideoSessionMemoryKHR);
    {
        VVL_ZoneScopedN("PreCallRecord_vkBindVideoSessionMemoryKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordBindVideoSessionMemoryKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordBindVideoSessionMemoryKHR(device, videoSession, bindSessionMemoryInfoCount, pBindSessionMemoryInfos,
                                                       record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkBindVideoSessionMemoryKHR");
        result =
            device_dispatch->BindVideoSessionMemoryKHR(device, videoSession, bindSessionMemoryInfoCount, pBindSessionMemoryInfos);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkBindVideoSessionMemoryKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordBindVideoSessionMemoryKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordBindVideoSessionMemoryKHR(device, videoSession, bindSessionMemoryInfoCount, pBindSessionMemoryInfos,
                                                        record_obj);
        }
    }
    return result;
}

VKAPI_ATTR VkResult VKAPI_CALL CreateVideoSessionParametersKHR(VkDevice device,
                                                               const VkVideoSessionParametersCreateInfoKHR* pCreateInfo,
                                                               const VkAllocationCallbacks* pAllocator,
                                                               VkVideoSessionParametersKHR* pVideoSessionParameters) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCreateVideoSessionParametersKHR, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCreateVideoSessionParametersKHR");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCreateVideoSessionParametersKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCreateVideoSessionParametersKHR(device, pCreateInfo, pAllocator, pVideoSessionParameters,
                                                                       error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkCreateVideoSessionParametersKHR);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCreateVideoSessionParametersKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCreateVideoSessionParametersKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCreateVideoSessionParametersKHR(device, pCreateInfo, pAllocator, pVideoSessionParameters, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkCreateVideoSessionParametersKHR");
        result = device_dispatch->CreateVideoSessionParametersKHR(device, pCreateInfo, pAllocator, pVideoSessionParameters);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkCreateVideoSessionParametersKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCreateVideoSessionParametersKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCreateVideoSessionParametersKHR(device, pCreateInfo, pAllocator, pVideoSessionParameters, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR VkResult VKAPI_CALL UpdateVideoSessionParametersKHR(VkDevice device, VkVideoSessionParametersKHR videoSessionParameters,
                                                               const VkVideoSessionParametersUpdateInfoKHR* pUpdateInfo) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkUpdateVideoSessionParametersKHR, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkUpdateVideoSessionParametersKHR");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateUpdateVideoSessionParametersKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateUpdateVideoSessionParametersKHR(device, videoSessionParameters, pUpdateInfo, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkUpdateVideoSessionParametersKHR);
    {
        VVL_ZoneScopedN("PreCallRecord_vkUpdateVideoSessionParametersKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordUpdateVideoSessionParametersKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordUpdateVideoSessionParametersKHR(device, videoSessionParameters, pUpdateInfo, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkUpdateVideoSessionParametersKHR");
        result = device_dispatch->UpdateVideoSessionParametersKHR(device, videoSessionParameters, pUpdateInfo);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkUpdateVideoSessionParametersKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordUpdateVideoSessionParametersKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordUpdateVideoSessionParametersKHR(device, videoSessionParameters, pUpdateInfo, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR void VKAPI_CALL DestroyVideoSessionParametersKHR(VkDevice device, VkVideoSessionParametersKHR videoSessionParameters,
                                                            const VkAllocationCallbacks* pAllocator) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkDestroyVideoSessionParametersKHR, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkDestroyVideoSessionParametersKHR");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateDestroyVideoSessionParametersKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateDestroyVideoSessionParametersKHR(device, videoSessionParameters, pAllocator, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkDestroyVideoSessionParametersKHR);
    {
        VVL_ZoneScopedN("PreCallRecord_vkDestroyVideoSessionParametersKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordDestroyVideoSessionParametersKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordDestroyVideoSessionParametersKHR(device, videoSessionParameters, pAllocator, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkDestroyVideoSessionParametersKHR");
        device_dispatch->DestroyVideoSessionParametersKHR(device, videoSessionParameters, pAllocator);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkDestroyVideoSessionParametersKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordDestroyVideoSessionParametersKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordDestroyVideoSessionParametersKHR(device, videoSessionParameters, pAllocator, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdBeginVideoCodingKHR(VkCommandBuffer commandBuffer, const VkVideoBeginCodingInfoKHR* pBeginInfo) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdBeginVideoCodingKHR, VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdBeginVideoCodingKHR");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdBeginVideoCodingKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdBeginVideoCodingKHR(commandBuffer, pBeginInfo, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdBeginVideoCodingKHR);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdBeginVideoCodingKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdBeginVideoCodingKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdBeginVideoCodingKHR(commandBuffer, pBeginInfo, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdBeginVideoCodingKHR");
        device_dispatch->CmdBeginVideoCodingKHR(commandBuffer, pBeginInfo);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdBeginVideoCodingKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdBeginVideoCodingKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdBeginVideoCodingKHR(commandBuffer, pBeginInfo, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdEndVideoCodingKHR(VkCommandBuffer commandBuffer, const VkVideoEndCodingInfoKHR* pEndCodingInfo) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdEndVideoCodingKHR, VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdEndVideoCodingKHR");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdEndVideoCodingKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdEndVideoCodingKHR(commandBuffer, pEndCodingInfo, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdEndVideoCodingKHR);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdEndVideoCodingKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdEndVideoCodingKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdEndVideoCodingKHR(commandBuffer, pEndCodingInfo, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdEndVideoCodingKHR");
        device_dispatch->CmdEndVideoCodingKHR(commandBuffer, pEndCodingInfo);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdEndVideoCodingKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdEndVideoCodingKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdEndVideoCodingKHR(commandBuffer, pEndCodingInfo, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdControlVideoCodingKHR(VkCommandBuffer commandBuffer,
                                                    const VkVideoCodingControlInfoKHR* pCodingControlInfo) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdControlVideoCodingKHR, VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdControlVideoCodingKHR");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdControlVideoCodingKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdControlVideoCodingKHR(commandBuffer, pCodingControlInfo, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdControlVideoCodingKHR);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdControlVideoCodingKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdControlVideoCodingKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdControlVideoCodingKHR(commandBuffer, pCodingControlInfo, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdControlVideoCodingKHR");
        device_dispatch->CmdControlVideoCodingKHR(commandBuffer, pCodingControlInfo);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdControlVideoCodingKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdControlVideoCodingKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdControlVideoCodingKHR(commandBuffer, pCodingControlInfo, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdDecodeVideoKHR(VkCommandBuffer commandBuffer, const VkVideoDecodeInfoKHR* pDecodeInfo) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdDecodeVideoKHR, VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdDecodeVideoKHR");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdDecodeVideoKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdDecodeVideoKHR(commandBuffer, pDecodeInfo, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdDecodeVideoKHR);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdDecodeVideoKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdDecodeVideoKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdDecodeVideoKHR(commandBuffer, pDecodeInfo, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdDecodeVideoKHR");
        device_dispatch->CmdDecodeVideoKHR(commandBuffer, pDecodeInfo);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdDecodeVideoKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdDecodeVideoKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdDecodeVideoKHR(commandBuffer, pDecodeInfo, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdBeginRenderingKHR(VkCommandBuffer commandBuffer, const VkRenderingInfo* pRenderingInfo) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdBeginRenderingKHR, VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdBeginRenderingKHR");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdBeginRenderingKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdBeginRenderingKHR(commandBuffer, pRenderingInfo, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdBeginRenderingKHR);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdBeginRenderingKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdBeginRenderingKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdBeginRenderingKHR(commandBuffer, pRenderingInfo, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdBeginRenderingKHR");
        device_dispatch->CmdBeginRenderingKHR(commandBuffer, pRenderingInfo);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdBeginRenderingKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdBeginRenderingKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdBeginRenderingKHR(commandBuffer, pRenderingInfo, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdEndRenderingKHR(VkCommandBuffer commandBuffer) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdEndRenderingKHR, VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdEndRenderingKHR");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdEndRenderingKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdEndRenderingKHR(commandBuffer, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdEndRenderingKHR);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdEndRenderingKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdEndRenderingKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdEndRenderingKHR(commandBuffer, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdEndRenderingKHR");
        device_dispatch->CmdEndRenderingKHR(commandBuffer);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdEndRenderingKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdEndRenderingKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdEndRenderingKHR(commandBuffer, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL GetPhysicalDeviceFeatures2KHR(VkPhysicalDevice physicalDevice, VkPhysicalDeviceFeatures2* pFeatures) {
    VVL_ZoneScoped;

    auto instance_dispatch = vvl::dispatch::GetData(physicalDevice);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetPhysicalDeviceFeatures2KHR,
                          VulkanTypedHandle(physicalDevice, kVulkanObjectTypePhysicalDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetPhysicalDeviceFeatures2KHR");
        for (const auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            skip |= vo->PreCallValidateGetPhysicalDeviceFeatures2KHR(physicalDevice, pFeatures, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetPhysicalDeviceFeatures2KHR);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetPhysicalDeviceFeatures2KHR");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PreCallRecordGetPhysicalDeviceFeatures2KHR(physicalDevice, pFeatures, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkGetPhysicalDeviceFeatures2KHR");
        instance_dispatch->GetPhysicalDeviceFeatures2KHR(physicalDevice, pFeatures);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetPhysicalDeviceFeatures2KHR");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PostCallRecordGetPhysicalDeviceFeatures2KHR(physicalDevice, pFeatures, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL GetPhysicalDeviceProperties2KHR(VkPhysicalDevice physicalDevice,
                                                           VkPhysicalDeviceProperties2* pProperties) {
    VVL_ZoneScoped;

    auto instance_dispatch = vvl::dispatch::GetData(physicalDevice);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetPhysicalDeviceProperties2KHR,
                          VulkanTypedHandle(physicalDevice, kVulkanObjectTypePhysicalDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetPhysicalDeviceProperties2KHR");
        for (const auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            skip |= vo->PreCallValidateGetPhysicalDeviceProperties2KHR(physicalDevice, pProperties, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetPhysicalDeviceProperties2KHR);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetPhysicalDeviceProperties2KHR");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PreCallRecordGetPhysicalDeviceProperties2KHR(physicalDevice, pProperties, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkGetPhysicalDeviceProperties2KHR");
        instance_dispatch->GetPhysicalDeviceProperties2KHR(physicalDevice, pProperties);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetPhysicalDeviceProperties2KHR");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PostCallRecordGetPhysicalDeviceProperties2KHR(physicalDevice, pProperties, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL GetPhysicalDeviceFormatProperties2KHR(VkPhysicalDevice physicalDevice, VkFormat format,
                                                                 VkFormatProperties2* pFormatProperties) {
    VVL_ZoneScoped;

    auto instance_dispatch = vvl::dispatch::GetData(physicalDevice);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetPhysicalDeviceFormatProperties2KHR,
                          VulkanTypedHandle(physicalDevice, kVulkanObjectTypePhysicalDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetPhysicalDeviceFormatProperties2KHR");
        for (const auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            skip |= vo->PreCallValidateGetPhysicalDeviceFormatProperties2KHR(physicalDevice, format, pFormatProperties, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetPhysicalDeviceFormatProperties2KHR);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetPhysicalDeviceFormatProperties2KHR");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PreCallRecordGetPhysicalDeviceFormatProperties2KHR(physicalDevice, format, pFormatProperties, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkGetPhysicalDeviceFormatProperties2KHR");
        instance_dispatch->GetPhysicalDeviceFormatProperties2KHR(physicalDevice, format, pFormatProperties);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetPhysicalDeviceFormatProperties2KHR");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PostCallRecordGetPhysicalDeviceFormatProperties2KHR(physicalDevice, format, pFormatProperties, record_obj);
        }
    }
}

VKAPI_ATTR VkResult VKAPI_CALL GetPhysicalDeviceImageFormatProperties2KHR(VkPhysicalDevice physicalDevice,
                                                                          const VkPhysicalDeviceImageFormatInfo2* pImageFormatInfo,
                                                                          VkImageFormatProperties2* pImageFormatProperties) {
    VVL_ZoneScoped;

    auto instance_dispatch = vvl::dispatch::GetData(physicalDevice);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetPhysicalDeviceImageFormatProperties2KHR,
                          VulkanTypedHandle(physicalDevice, kVulkanObjectTypePhysicalDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetPhysicalDeviceImageFormatProperties2KHR");
        for (const auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            skip |= vo->PreCallValidateGetPhysicalDeviceImageFormatProperties2KHR(physicalDevice, pImageFormatInfo,
                                                                                  pImageFormatProperties, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetPhysicalDeviceImageFormatProperties2KHR);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetPhysicalDeviceImageFormatProperties2KHR");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PreCallRecordGetPhysicalDeviceImageFormatProperties2KHR(physicalDevice, pImageFormatInfo, pImageFormatProperties,
                                                                        record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkGetPhysicalDeviceImageFormatProperties2KHR");
        result =
            instance_dispatch->GetPhysicalDeviceImageFormatProperties2KHR(physicalDevice, pImageFormatInfo, pImageFormatProperties);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetPhysicalDeviceImageFormatProperties2KHR");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PostCallRecordGetPhysicalDeviceImageFormatProperties2KHR(physicalDevice, pImageFormatInfo, pImageFormatProperties,
                                                                         record_obj);
        }
    }
    return result;
}

VKAPI_ATTR void VKAPI_CALL GetPhysicalDeviceQueueFamilyProperties2KHR(VkPhysicalDevice physicalDevice,
                                                                      uint32_t* pQueueFamilyPropertyCount,
                                                                      VkQueueFamilyProperties2* pQueueFamilyProperties) {
    VVL_ZoneScoped;

    auto instance_dispatch = vvl::dispatch::GetData(physicalDevice);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetPhysicalDeviceQueueFamilyProperties2KHR,
                          VulkanTypedHandle(physicalDevice, kVulkanObjectTypePhysicalDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetPhysicalDeviceQueueFamilyProperties2KHR");
        for (const auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            skip |= vo->PreCallValidateGetPhysicalDeviceQueueFamilyProperties2KHR(physicalDevice, pQueueFamilyPropertyCount,
                                                                                  pQueueFamilyProperties, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetPhysicalDeviceQueueFamilyProperties2KHR);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetPhysicalDeviceQueueFamilyProperties2KHR");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PreCallRecordGetPhysicalDeviceQueueFamilyProperties2KHR(physicalDevice, pQueueFamilyPropertyCount,
                                                                        pQueueFamilyProperties, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkGetPhysicalDeviceQueueFamilyProperties2KHR");
        instance_dispatch->GetPhysicalDeviceQueueFamilyProperties2KHR(physicalDevice, pQueueFamilyPropertyCount,
                                                                      pQueueFamilyProperties);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetPhysicalDeviceQueueFamilyProperties2KHR");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PostCallRecordGetPhysicalDeviceQueueFamilyProperties2KHR(physicalDevice, pQueueFamilyPropertyCount,
                                                                         pQueueFamilyProperties, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL GetPhysicalDeviceMemoryProperties2KHR(VkPhysicalDevice physicalDevice,
                                                                 VkPhysicalDeviceMemoryProperties2* pMemoryProperties) {
    VVL_ZoneScoped;

    auto instance_dispatch = vvl::dispatch::GetData(physicalDevice);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetPhysicalDeviceMemoryProperties2KHR,
                          VulkanTypedHandle(physicalDevice, kVulkanObjectTypePhysicalDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetPhysicalDeviceMemoryProperties2KHR");
        for (const auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            skip |= vo->PreCallValidateGetPhysicalDeviceMemoryProperties2KHR(physicalDevice, pMemoryProperties, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetPhysicalDeviceMemoryProperties2KHR);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetPhysicalDeviceMemoryProperties2KHR");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PreCallRecordGetPhysicalDeviceMemoryProperties2KHR(physicalDevice, pMemoryProperties, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkGetPhysicalDeviceMemoryProperties2KHR");
        instance_dispatch->GetPhysicalDeviceMemoryProperties2KHR(physicalDevice, pMemoryProperties);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetPhysicalDeviceMemoryProperties2KHR");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PostCallRecordGetPhysicalDeviceMemoryProperties2KHR(physicalDevice, pMemoryProperties, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL GetPhysicalDeviceSparseImageFormatProperties2KHR(
    VkPhysicalDevice physicalDevice, const VkPhysicalDeviceSparseImageFormatInfo2* pFormatInfo, uint32_t* pPropertyCount,
    VkSparseImageFormatProperties2* pProperties) {
    VVL_ZoneScoped;

    auto instance_dispatch = vvl::dispatch::GetData(physicalDevice);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetPhysicalDeviceSparseImageFormatProperties2KHR,
                          VulkanTypedHandle(physicalDevice, kVulkanObjectTypePhysicalDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetPhysicalDeviceSparseImageFormatProperties2KHR");
        for (const auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            skip |= vo->PreCallValidateGetPhysicalDeviceSparseImageFormatProperties2KHR(physicalDevice, pFormatInfo, pPropertyCount,
                                                                                        pProperties, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetPhysicalDeviceSparseImageFormatProperties2KHR);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetPhysicalDeviceSparseImageFormatProperties2KHR");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PreCallRecordGetPhysicalDeviceSparseImageFormatProperties2KHR(physicalDevice, pFormatInfo, pPropertyCount,
                                                                              pProperties, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkGetPhysicalDeviceSparseImageFormatProperties2KHR");
        instance_dispatch->GetPhysicalDeviceSparseImageFormatProperties2KHR(physicalDevice, pFormatInfo, pPropertyCount,
                                                                            pProperties);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetPhysicalDeviceSparseImageFormatProperties2KHR");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PostCallRecordGetPhysicalDeviceSparseImageFormatProperties2KHR(physicalDevice, pFormatInfo, pPropertyCount,
                                                                               pProperties, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL GetDeviceGroupPeerMemoryFeaturesKHR(VkDevice device, uint32_t heapIndex, uint32_t localDeviceIndex,
                                                               uint32_t remoteDeviceIndex,
                                                               VkPeerMemoryFeatureFlags* pPeerMemoryFeatures) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetDeviceGroupPeerMemoryFeaturesKHR, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetDeviceGroupPeerMemoryFeaturesKHR");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateGetDeviceGroupPeerMemoryFeaturesKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateGetDeviceGroupPeerMemoryFeaturesKHR(device, heapIndex, localDeviceIndex, remoteDeviceIndex,
                                                                           pPeerMemoryFeatures, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetDeviceGroupPeerMemoryFeaturesKHR);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetDeviceGroupPeerMemoryFeaturesKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordGetDeviceGroupPeerMemoryFeaturesKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordGetDeviceGroupPeerMemoryFeaturesKHR(device, heapIndex, localDeviceIndex, remoteDeviceIndex,
                                                                 pPeerMemoryFeatures, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkGetDeviceGroupPeerMemoryFeaturesKHR");
        device_dispatch->GetDeviceGroupPeerMemoryFeaturesKHR(device, heapIndex, localDeviceIndex, remoteDeviceIndex,
                                                             pPeerMemoryFeatures);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetDeviceGroupPeerMemoryFeaturesKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordGetDeviceGroupPeerMemoryFeaturesKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordGetDeviceGroupPeerMemoryFeaturesKHR(device, heapIndex, localDeviceIndex, remoteDeviceIndex,
                                                                  pPeerMemoryFeatures, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdSetDeviceMaskKHR(VkCommandBuffer commandBuffer, uint32_t deviceMask) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdSetDeviceMaskKHR, VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdSetDeviceMaskKHR");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdSetDeviceMaskKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdSetDeviceMaskKHR(commandBuffer, deviceMask, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdSetDeviceMaskKHR);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdSetDeviceMaskKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdSetDeviceMaskKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdSetDeviceMaskKHR(commandBuffer, deviceMask, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdSetDeviceMaskKHR");
        device_dispatch->CmdSetDeviceMaskKHR(commandBuffer, deviceMask);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdSetDeviceMaskKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdSetDeviceMaskKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdSetDeviceMaskKHR(commandBuffer, deviceMask, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdDispatchBaseKHR(VkCommandBuffer commandBuffer, uint32_t baseGroupX, uint32_t baseGroupY,
                                              uint32_t baseGroupZ, uint32_t groupCountX, uint32_t groupCountY,
                                              uint32_t groupCountZ) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdDispatchBaseKHR, VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdDispatchBaseKHR");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdDispatchBaseKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdDispatchBaseKHR(commandBuffer, baseGroupX, baseGroupY, baseGroupZ, groupCountX,
                                                          groupCountY, groupCountZ, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdDispatchBaseKHR);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdDispatchBaseKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdDispatchBaseKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdDispatchBaseKHR(commandBuffer, baseGroupX, baseGroupY, baseGroupZ, groupCountX, groupCountY,
                                                groupCountZ, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdDispatchBaseKHR");
        device_dispatch->CmdDispatchBaseKHR(commandBuffer, baseGroupX, baseGroupY, baseGroupZ, groupCountX, groupCountY,
                                            groupCountZ);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdDispatchBaseKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdDispatchBaseKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdDispatchBaseKHR(commandBuffer, baseGroupX, baseGroupY, baseGroupZ, groupCountX, groupCountY,
                                                 groupCountZ, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL TrimCommandPoolKHR(VkDevice device, VkCommandPool commandPool, VkCommandPoolTrimFlags flags) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkTrimCommandPoolKHR, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkTrimCommandPoolKHR");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateTrimCommandPoolKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateTrimCommandPoolKHR(device, commandPool, flags, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkTrimCommandPoolKHR);
    {
        VVL_ZoneScopedN("PreCallRecord_vkTrimCommandPoolKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordTrimCommandPoolKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordTrimCommandPoolKHR(device, commandPool, flags, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkTrimCommandPoolKHR");
        device_dispatch->TrimCommandPoolKHR(device, commandPool, flags);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkTrimCommandPoolKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordTrimCommandPoolKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordTrimCommandPoolKHR(device, commandPool, flags, record_obj);
        }
    }
}

VKAPI_ATTR VkResult VKAPI_CALL EnumeratePhysicalDeviceGroupsKHR(VkInstance instance, uint32_t* pPhysicalDeviceGroupCount,
                                                                VkPhysicalDeviceGroupProperties* pPhysicalDeviceGroupProperties) {
    VVL_ZoneScoped;

    auto instance_dispatch = vvl::dispatch::GetData(instance);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkEnumeratePhysicalDeviceGroupsKHR, VulkanTypedHandle(instance, kVulkanObjectTypeInstance));
    {
        VVL_ZoneScopedN("PreCallValidate_vkEnumeratePhysicalDeviceGroupsKHR");
        for (const auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            skip |= vo->PreCallValidateEnumeratePhysicalDeviceGroupsKHR(instance, pPhysicalDeviceGroupCount,
                                                                        pPhysicalDeviceGroupProperties, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkEnumeratePhysicalDeviceGroupsKHR);
    {
        VVL_ZoneScopedN("PreCallRecord_vkEnumeratePhysicalDeviceGroupsKHR");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PreCallRecordEnumeratePhysicalDeviceGroupsKHR(instance, pPhysicalDeviceGroupCount, pPhysicalDeviceGroupProperties,
                                                              record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkEnumeratePhysicalDeviceGroupsKHR");
        result = instance_dispatch->EnumeratePhysicalDeviceGroupsKHR(instance, pPhysicalDeviceGroupCount,
                                                                     pPhysicalDeviceGroupProperties);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkEnumeratePhysicalDeviceGroupsKHR");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PostCallRecordEnumeratePhysicalDeviceGroupsKHR(instance, pPhysicalDeviceGroupCount, pPhysicalDeviceGroupProperties,
                                                               record_obj);
        }
    }
    return result;
}

VKAPI_ATTR void VKAPI_CALL GetPhysicalDeviceExternalBufferPropertiesKHR(
    VkPhysicalDevice physicalDevice, const VkPhysicalDeviceExternalBufferInfo* pExternalBufferInfo,
    VkExternalBufferProperties* pExternalBufferProperties) {
    VVL_ZoneScoped;

    auto instance_dispatch = vvl::dispatch::GetData(physicalDevice);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetPhysicalDeviceExternalBufferPropertiesKHR,
                          VulkanTypedHandle(physicalDevice, kVulkanObjectTypePhysicalDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetPhysicalDeviceExternalBufferPropertiesKHR");
        for (const auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            skip |= vo->PreCallValidateGetPhysicalDeviceExternalBufferPropertiesKHR(physicalDevice, pExternalBufferInfo,
                                                                                    pExternalBufferProperties, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetPhysicalDeviceExternalBufferPropertiesKHR);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetPhysicalDeviceExternalBufferPropertiesKHR");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PreCallRecordGetPhysicalDeviceExternalBufferPropertiesKHR(physicalDevice, pExternalBufferInfo,
                                                                          pExternalBufferProperties, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkGetPhysicalDeviceExternalBufferPropertiesKHR");
        instance_dispatch->GetPhysicalDeviceExternalBufferPropertiesKHR(physicalDevice, pExternalBufferInfo,
                                                                        pExternalBufferProperties);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetPhysicalDeviceExternalBufferPropertiesKHR");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PostCallRecordGetPhysicalDeviceExternalBufferPropertiesKHR(physicalDevice, pExternalBufferInfo,
                                                                           pExternalBufferProperties, record_obj);
        }
    }
}

#ifdef VK_USE_PLATFORM_WIN32_KHR
VKAPI_ATTR VkResult VKAPI_CALL GetMemoryWin32HandleKHR(VkDevice device, const VkMemoryGetWin32HandleInfoKHR* pGetWin32HandleInfo,
                                                       HANDLE* pHandle) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetMemoryWin32HandleKHR, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetMemoryWin32HandleKHR");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateGetMemoryWin32HandleKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateGetMemoryWin32HandleKHR(device, pGetWin32HandleInfo, pHandle, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetMemoryWin32HandleKHR);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetMemoryWin32HandleKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordGetMemoryWin32HandleKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordGetMemoryWin32HandleKHR(device, pGetWin32HandleInfo, pHandle, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkGetMemoryWin32HandleKHR");
        result = device_dispatch->GetMemoryWin32HandleKHR(device, pGetWin32HandleInfo, pHandle);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetMemoryWin32HandleKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordGetMemoryWin32HandleKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordGetMemoryWin32HandleKHR(device, pGetWin32HandleInfo, pHandle, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR VkResult VKAPI_CALL GetMemoryWin32HandlePropertiesKHR(VkDevice device, VkExternalMemoryHandleTypeFlagBits handleType,
                                                                 HANDLE handle,
                                                                 VkMemoryWin32HandlePropertiesKHR* pMemoryWin32HandleProperties) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetMemoryWin32HandlePropertiesKHR, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetMemoryWin32HandlePropertiesKHR");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateGetMemoryWin32HandlePropertiesKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateGetMemoryWin32HandlePropertiesKHR(device, handleType, handle, pMemoryWin32HandleProperties,
                                                                         error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetMemoryWin32HandlePropertiesKHR);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetMemoryWin32HandlePropertiesKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordGetMemoryWin32HandlePropertiesKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordGetMemoryWin32HandlePropertiesKHR(device, handleType, handle, pMemoryWin32HandleProperties,
                                                               record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkGetMemoryWin32HandlePropertiesKHR");
        result = device_dispatch->GetMemoryWin32HandlePropertiesKHR(device, handleType, handle, pMemoryWin32HandleProperties);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetMemoryWin32HandlePropertiesKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordGetMemoryWin32HandlePropertiesKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordGetMemoryWin32HandlePropertiesKHR(device, handleType, handle, pMemoryWin32HandleProperties,
                                                                record_obj);
        }
    }
    return result;
}

#endif  // VK_USE_PLATFORM_WIN32_KHR
VKAPI_ATTR VkResult VKAPI_CALL GetMemoryFdKHR(VkDevice device, const VkMemoryGetFdInfoKHR* pGetFdInfo, int* pFd) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetMemoryFdKHR, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetMemoryFdKHR");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateGetMemoryFdKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateGetMemoryFdKHR(device, pGetFdInfo, pFd, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetMemoryFdKHR);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetMemoryFdKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordGetMemoryFdKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordGetMemoryFdKHR(device, pGetFdInfo, pFd, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkGetMemoryFdKHR");
        result = device_dispatch->GetMemoryFdKHR(device, pGetFdInfo, pFd);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetMemoryFdKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordGetMemoryFdKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordGetMemoryFdKHR(device, pGetFdInfo, pFd, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR VkResult VKAPI_CALL GetMemoryFdPropertiesKHR(VkDevice device, VkExternalMemoryHandleTypeFlagBits handleType, int fd,
                                                        VkMemoryFdPropertiesKHR* pMemoryFdProperties) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetMemoryFdPropertiesKHR, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetMemoryFdPropertiesKHR");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateGetMemoryFdPropertiesKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateGetMemoryFdPropertiesKHR(device, handleType, fd, pMemoryFdProperties, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetMemoryFdPropertiesKHR);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetMemoryFdPropertiesKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordGetMemoryFdPropertiesKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordGetMemoryFdPropertiesKHR(device, handleType, fd, pMemoryFdProperties, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkGetMemoryFdPropertiesKHR");
        result = device_dispatch->GetMemoryFdPropertiesKHR(device, handleType, fd, pMemoryFdProperties);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetMemoryFdPropertiesKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordGetMemoryFdPropertiesKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordGetMemoryFdPropertiesKHR(device, handleType, fd, pMemoryFdProperties, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR void VKAPI_CALL GetPhysicalDeviceExternalSemaphorePropertiesKHR(
    VkPhysicalDevice physicalDevice, const VkPhysicalDeviceExternalSemaphoreInfo* pExternalSemaphoreInfo,
    VkExternalSemaphoreProperties* pExternalSemaphoreProperties) {
    VVL_ZoneScoped;

    auto instance_dispatch = vvl::dispatch::GetData(physicalDevice);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetPhysicalDeviceExternalSemaphorePropertiesKHR,
                          VulkanTypedHandle(physicalDevice, kVulkanObjectTypePhysicalDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetPhysicalDeviceExternalSemaphorePropertiesKHR");
        for (const auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            skip |= vo->PreCallValidateGetPhysicalDeviceExternalSemaphorePropertiesKHR(physicalDevice, pExternalSemaphoreInfo,
                                                                                       pExternalSemaphoreProperties, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetPhysicalDeviceExternalSemaphorePropertiesKHR);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetPhysicalDeviceExternalSemaphorePropertiesKHR");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PreCallRecordGetPhysicalDeviceExternalSemaphorePropertiesKHR(physicalDevice, pExternalSemaphoreInfo,
                                                                             pExternalSemaphoreProperties, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkGetPhysicalDeviceExternalSemaphorePropertiesKHR");
        instance_dispatch->GetPhysicalDeviceExternalSemaphorePropertiesKHR(physicalDevice, pExternalSemaphoreInfo,
                                                                           pExternalSemaphoreProperties);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetPhysicalDeviceExternalSemaphorePropertiesKHR");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PostCallRecordGetPhysicalDeviceExternalSemaphorePropertiesKHR(physicalDevice, pExternalSemaphoreInfo,
                                                                              pExternalSemaphoreProperties, record_obj);
        }
    }
}

#ifdef VK_USE_PLATFORM_WIN32_KHR
VKAPI_ATTR VkResult VKAPI_CALL
ImportSemaphoreWin32HandleKHR(VkDevice device, const VkImportSemaphoreWin32HandleInfoKHR* pImportSemaphoreWin32HandleInfo) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkImportSemaphoreWin32HandleKHR, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkImportSemaphoreWin32HandleKHR");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateImportSemaphoreWin32HandleKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateImportSemaphoreWin32HandleKHR(device, pImportSemaphoreWin32HandleInfo, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkImportSemaphoreWin32HandleKHR);
    {
        VVL_ZoneScopedN("PreCallRecord_vkImportSemaphoreWin32HandleKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordImportSemaphoreWin32HandleKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordImportSemaphoreWin32HandleKHR(device, pImportSemaphoreWin32HandleInfo, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkImportSemaphoreWin32HandleKHR");
        result = device_dispatch->ImportSemaphoreWin32HandleKHR(device, pImportSemaphoreWin32HandleInfo);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkImportSemaphoreWin32HandleKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordImportSemaphoreWin32HandleKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordImportSemaphoreWin32HandleKHR(device, pImportSemaphoreWin32HandleInfo, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR VkResult VKAPI_CALL GetSemaphoreWin32HandleKHR(VkDevice device,
                                                          const VkSemaphoreGetWin32HandleInfoKHR* pGetWin32HandleInfo,
                                                          HANDLE* pHandle) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetSemaphoreWin32HandleKHR, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetSemaphoreWin32HandleKHR");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateGetSemaphoreWin32HandleKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateGetSemaphoreWin32HandleKHR(device, pGetWin32HandleInfo, pHandle, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetSemaphoreWin32HandleKHR);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetSemaphoreWin32HandleKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordGetSemaphoreWin32HandleKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordGetSemaphoreWin32HandleKHR(device, pGetWin32HandleInfo, pHandle, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkGetSemaphoreWin32HandleKHR");
        result = device_dispatch->GetSemaphoreWin32HandleKHR(device, pGetWin32HandleInfo, pHandle);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetSemaphoreWin32HandleKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordGetSemaphoreWin32HandleKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordGetSemaphoreWin32HandleKHR(device, pGetWin32HandleInfo, pHandle, record_obj);
        }
    }
    return result;
}

#endif  // VK_USE_PLATFORM_WIN32_KHR
VKAPI_ATTR VkResult VKAPI_CALL ImportSemaphoreFdKHR(VkDevice device, const VkImportSemaphoreFdInfoKHR* pImportSemaphoreFdInfo) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkImportSemaphoreFdKHR, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkImportSemaphoreFdKHR");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateImportSemaphoreFdKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateImportSemaphoreFdKHR(device, pImportSemaphoreFdInfo, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkImportSemaphoreFdKHR);
    {
        VVL_ZoneScopedN("PreCallRecord_vkImportSemaphoreFdKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordImportSemaphoreFdKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordImportSemaphoreFdKHR(device, pImportSemaphoreFdInfo, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkImportSemaphoreFdKHR");
        result = device_dispatch->ImportSemaphoreFdKHR(device, pImportSemaphoreFdInfo);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkImportSemaphoreFdKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordImportSemaphoreFdKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordImportSemaphoreFdKHR(device, pImportSemaphoreFdInfo, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR VkResult VKAPI_CALL GetSemaphoreFdKHR(VkDevice device, const VkSemaphoreGetFdInfoKHR* pGetFdInfo, int* pFd) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetSemaphoreFdKHR, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetSemaphoreFdKHR");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateGetSemaphoreFdKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateGetSemaphoreFdKHR(device, pGetFdInfo, pFd, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetSemaphoreFdKHR);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetSemaphoreFdKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordGetSemaphoreFdKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordGetSemaphoreFdKHR(device, pGetFdInfo, pFd, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkGetSemaphoreFdKHR");
        result = device_dispatch->GetSemaphoreFdKHR(device, pGetFdInfo, pFd);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetSemaphoreFdKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordGetSemaphoreFdKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordGetSemaphoreFdKHR(device, pGetFdInfo, pFd, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR void VKAPI_CALL CmdPushDescriptorSetKHR(VkCommandBuffer commandBuffer, VkPipelineBindPoint pipelineBindPoint,
                                                   VkPipelineLayout layout, uint32_t set, uint32_t descriptorWriteCount,
                                                   const VkWriteDescriptorSet* pDescriptorWrites) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdPushDescriptorSetKHR, VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdPushDescriptorSetKHR");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdPushDescriptorSetKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdPushDescriptorSetKHR(commandBuffer, pipelineBindPoint, layout, set, descriptorWriteCount,
                                                               pDescriptorWrites, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdPushDescriptorSetKHR);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdPushDescriptorSetKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdPushDescriptorSetKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdPushDescriptorSetKHR(commandBuffer, pipelineBindPoint, layout, set, descriptorWriteCount,
                                                     pDescriptorWrites, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdPushDescriptorSetKHR");
        device_dispatch->CmdPushDescriptorSetKHR(commandBuffer, pipelineBindPoint, layout, set, descriptorWriteCount,
                                                 pDescriptorWrites);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdPushDescriptorSetKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdPushDescriptorSetKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdPushDescriptorSetKHR(commandBuffer, pipelineBindPoint, layout, set, descriptorWriteCount,
                                                      pDescriptorWrites, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdPushDescriptorSetWithTemplateKHR(VkCommandBuffer commandBuffer,
                                                               VkDescriptorUpdateTemplate descriptorUpdateTemplate,
                                                               VkPipelineLayout layout, uint32_t set, const void* pData) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdPushDescriptorSetWithTemplateKHR,
                          VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdPushDescriptorSetWithTemplateKHR");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdPushDescriptorSetWithTemplateKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdPushDescriptorSetWithTemplateKHR(commandBuffer, descriptorUpdateTemplate, layout, set,
                                                                           pData, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdPushDescriptorSetWithTemplateKHR);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdPushDescriptorSetWithTemplateKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdPushDescriptorSetWithTemplateKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdPushDescriptorSetWithTemplateKHR(commandBuffer, descriptorUpdateTemplate, layout, set, pData,
                                                                 record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdPushDescriptorSetWithTemplateKHR");
        device_dispatch->CmdPushDescriptorSetWithTemplateKHR(commandBuffer, descriptorUpdateTemplate, layout, set, pData);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdPushDescriptorSetWithTemplateKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdPushDescriptorSetWithTemplateKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdPushDescriptorSetWithTemplateKHR(commandBuffer, descriptorUpdateTemplate, layout, set, pData,
                                                                  record_obj);
        }
    }
}

VKAPI_ATTR VkResult VKAPI_CALL CreateDescriptorUpdateTemplateKHR(VkDevice device,
                                                                 const VkDescriptorUpdateTemplateCreateInfo* pCreateInfo,
                                                                 const VkAllocationCallbacks* pAllocator,
                                                                 VkDescriptorUpdateTemplate* pDescriptorUpdateTemplate) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCreateDescriptorUpdateTemplateKHR, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCreateDescriptorUpdateTemplateKHR");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCreateDescriptorUpdateTemplateKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCreateDescriptorUpdateTemplateKHR(device, pCreateInfo, pAllocator, pDescriptorUpdateTemplate,
                                                                         error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkCreateDescriptorUpdateTemplateKHR);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCreateDescriptorUpdateTemplateKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCreateDescriptorUpdateTemplateKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCreateDescriptorUpdateTemplateKHR(device, pCreateInfo, pAllocator, pDescriptorUpdateTemplate,
                                                               record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkCreateDescriptorUpdateTemplateKHR");
        result = device_dispatch->CreateDescriptorUpdateTemplateKHR(device, pCreateInfo, pAllocator, pDescriptorUpdateTemplate);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkCreateDescriptorUpdateTemplateKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCreateDescriptorUpdateTemplateKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCreateDescriptorUpdateTemplateKHR(device, pCreateInfo, pAllocator, pDescriptorUpdateTemplate,
                                                                record_obj);
        }
    }
    return result;
}

VKAPI_ATTR void VKAPI_CALL DestroyDescriptorUpdateTemplateKHR(VkDevice device, VkDescriptorUpdateTemplate descriptorUpdateTemplate,
                                                              const VkAllocationCallbacks* pAllocator) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkDestroyDescriptorUpdateTemplateKHR, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkDestroyDescriptorUpdateTemplateKHR");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateDestroyDescriptorUpdateTemplateKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateDestroyDescriptorUpdateTemplateKHR(device, descriptorUpdateTemplate, pAllocator, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkDestroyDescriptorUpdateTemplateKHR);
    {
        VVL_ZoneScopedN("PreCallRecord_vkDestroyDescriptorUpdateTemplateKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordDestroyDescriptorUpdateTemplateKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordDestroyDescriptorUpdateTemplateKHR(device, descriptorUpdateTemplate, pAllocator, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkDestroyDescriptorUpdateTemplateKHR");
        device_dispatch->DestroyDescriptorUpdateTemplateKHR(device, descriptorUpdateTemplate, pAllocator);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkDestroyDescriptorUpdateTemplateKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordDestroyDescriptorUpdateTemplateKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordDestroyDescriptorUpdateTemplateKHR(device, descriptorUpdateTemplate, pAllocator, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL UpdateDescriptorSetWithTemplateKHR(VkDevice device, VkDescriptorSet descriptorSet,
                                                              VkDescriptorUpdateTemplate descriptorUpdateTemplate,
                                                              const void* pData) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkUpdateDescriptorSetWithTemplateKHR, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkUpdateDescriptorSetWithTemplateKHR");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateUpdateDescriptorSetWithTemplateKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateUpdateDescriptorSetWithTemplateKHR(device, descriptorSet, descriptorUpdateTemplate, pData,
                                                                          error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkUpdateDescriptorSetWithTemplateKHR);
    {
        VVL_ZoneScopedN("PreCallRecord_vkUpdateDescriptorSetWithTemplateKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordUpdateDescriptorSetWithTemplateKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordUpdateDescriptorSetWithTemplateKHR(device, descriptorSet, descriptorUpdateTemplate, pData, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkUpdateDescriptorSetWithTemplateKHR");
        device_dispatch->UpdateDescriptorSetWithTemplateKHR(device, descriptorSet, descriptorUpdateTemplate, pData);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkUpdateDescriptorSetWithTemplateKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordUpdateDescriptorSetWithTemplateKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordUpdateDescriptorSetWithTemplateKHR(device, descriptorSet, descriptorUpdateTemplate, pData,
                                                                 record_obj);
        }
    }
}

VKAPI_ATTR VkResult VKAPI_CALL CreateRenderPass2KHR(VkDevice device, const VkRenderPassCreateInfo2* pCreateInfo,
                                                    const VkAllocationCallbacks* pAllocator, VkRenderPass* pRenderPass) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCreateRenderPass2KHR, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCreateRenderPass2KHR");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCreateRenderPass2KHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCreateRenderPass2KHR(device, pCreateInfo, pAllocator, pRenderPass, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkCreateRenderPass2KHR);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCreateRenderPass2KHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCreateRenderPass2KHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCreateRenderPass2KHR(device, pCreateInfo, pAllocator, pRenderPass, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkCreateRenderPass2KHR");
        result = device_dispatch->CreateRenderPass2KHR(device, pCreateInfo, pAllocator, pRenderPass);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkCreateRenderPass2KHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCreateRenderPass2KHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCreateRenderPass2KHR(device, pCreateInfo, pAllocator, pRenderPass, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR void VKAPI_CALL CmdBeginRenderPass2KHR(VkCommandBuffer commandBuffer, const VkRenderPassBeginInfo* pRenderPassBegin,
                                                  const VkSubpassBeginInfo* pSubpassBeginInfo) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdBeginRenderPass2KHR, VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdBeginRenderPass2KHR");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdBeginRenderPass2KHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdBeginRenderPass2KHR(commandBuffer, pRenderPassBegin, pSubpassBeginInfo, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdBeginRenderPass2KHR);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdBeginRenderPass2KHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdBeginRenderPass2KHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdBeginRenderPass2KHR(commandBuffer, pRenderPassBegin, pSubpassBeginInfo, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdBeginRenderPass2KHR");
        device_dispatch->CmdBeginRenderPass2KHR(commandBuffer, pRenderPassBegin, pSubpassBeginInfo);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdBeginRenderPass2KHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdBeginRenderPass2KHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdBeginRenderPass2KHR(commandBuffer, pRenderPassBegin, pSubpassBeginInfo, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdNextSubpass2KHR(VkCommandBuffer commandBuffer, const VkSubpassBeginInfo* pSubpassBeginInfo,
                                              const VkSubpassEndInfo* pSubpassEndInfo) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdNextSubpass2KHR, VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdNextSubpass2KHR");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdNextSubpass2KHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdNextSubpass2KHR(commandBuffer, pSubpassBeginInfo, pSubpassEndInfo, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdNextSubpass2KHR);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdNextSubpass2KHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdNextSubpass2KHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdNextSubpass2KHR(commandBuffer, pSubpassBeginInfo, pSubpassEndInfo, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdNextSubpass2KHR");
        device_dispatch->CmdNextSubpass2KHR(commandBuffer, pSubpassBeginInfo, pSubpassEndInfo);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdNextSubpass2KHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdNextSubpass2KHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdNextSubpass2KHR(commandBuffer, pSubpassBeginInfo, pSubpassEndInfo, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdEndRenderPass2KHR(VkCommandBuffer commandBuffer, const VkSubpassEndInfo* pSubpassEndInfo) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdEndRenderPass2KHR, VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdEndRenderPass2KHR");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdEndRenderPass2KHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdEndRenderPass2KHR(commandBuffer, pSubpassEndInfo, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdEndRenderPass2KHR);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdEndRenderPass2KHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdEndRenderPass2KHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdEndRenderPass2KHR(commandBuffer, pSubpassEndInfo, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdEndRenderPass2KHR");
        device_dispatch->CmdEndRenderPass2KHR(commandBuffer, pSubpassEndInfo);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdEndRenderPass2KHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdEndRenderPass2KHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdEndRenderPass2KHR(commandBuffer, pSubpassEndInfo, record_obj);
        }
    }
}

VKAPI_ATTR VkResult VKAPI_CALL GetSwapchainStatusKHR(VkDevice device, VkSwapchainKHR swapchain) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetSwapchainStatusKHR, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetSwapchainStatusKHR");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateGetSwapchainStatusKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateGetSwapchainStatusKHR(device, swapchain, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetSwapchainStatusKHR);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetSwapchainStatusKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordGetSwapchainStatusKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordGetSwapchainStatusKHR(device, swapchain, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkGetSwapchainStatusKHR");
        result = device_dispatch->GetSwapchainStatusKHR(device, swapchain);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetSwapchainStatusKHR");

        if (result == VK_ERROR_DEVICE_LOST) {
            for (auto& vo : device_dispatch->object_dispatch) {
                vo->is_device_lost = true;
            }
        }
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordGetSwapchainStatusKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordGetSwapchainStatusKHR(device, swapchain, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR void VKAPI_CALL GetPhysicalDeviceExternalFencePropertiesKHR(VkPhysicalDevice physicalDevice,
                                                                       const VkPhysicalDeviceExternalFenceInfo* pExternalFenceInfo,
                                                                       VkExternalFenceProperties* pExternalFenceProperties) {
    VVL_ZoneScoped;

    auto instance_dispatch = vvl::dispatch::GetData(physicalDevice);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetPhysicalDeviceExternalFencePropertiesKHR,
                          VulkanTypedHandle(physicalDevice, kVulkanObjectTypePhysicalDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetPhysicalDeviceExternalFencePropertiesKHR");
        for (const auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            skip |= vo->PreCallValidateGetPhysicalDeviceExternalFencePropertiesKHR(physicalDevice, pExternalFenceInfo,
                                                                                   pExternalFenceProperties, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetPhysicalDeviceExternalFencePropertiesKHR);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetPhysicalDeviceExternalFencePropertiesKHR");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PreCallRecordGetPhysicalDeviceExternalFencePropertiesKHR(physicalDevice, pExternalFenceInfo,
                                                                         pExternalFenceProperties, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkGetPhysicalDeviceExternalFencePropertiesKHR");
        instance_dispatch->GetPhysicalDeviceExternalFencePropertiesKHR(physicalDevice, pExternalFenceInfo,
                                                                       pExternalFenceProperties);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetPhysicalDeviceExternalFencePropertiesKHR");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PostCallRecordGetPhysicalDeviceExternalFencePropertiesKHR(physicalDevice, pExternalFenceInfo,
                                                                          pExternalFenceProperties, record_obj);
        }
    }
}

#ifdef VK_USE_PLATFORM_WIN32_KHR
VKAPI_ATTR VkResult VKAPI_CALL ImportFenceWin32HandleKHR(VkDevice device,
                                                         const VkImportFenceWin32HandleInfoKHR* pImportFenceWin32HandleInfo) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkImportFenceWin32HandleKHR, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkImportFenceWin32HandleKHR");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateImportFenceWin32HandleKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateImportFenceWin32HandleKHR(device, pImportFenceWin32HandleInfo, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkImportFenceWin32HandleKHR);
    {
        VVL_ZoneScopedN("PreCallRecord_vkImportFenceWin32HandleKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordImportFenceWin32HandleKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordImportFenceWin32HandleKHR(device, pImportFenceWin32HandleInfo, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkImportFenceWin32HandleKHR");
        result = device_dispatch->ImportFenceWin32HandleKHR(device, pImportFenceWin32HandleInfo);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkImportFenceWin32HandleKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordImportFenceWin32HandleKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordImportFenceWin32HandleKHR(device, pImportFenceWin32HandleInfo, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR VkResult VKAPI_CALL GetFenceWin32HandleKHR(VkDevice device, const VkFenceGetWin32HandleInfoKHR* pGetWin32HandleInfo,
                                                      HANDLE* pHandle) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetFenceWin32HandleKHR, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetFenceWin32HandleKHR");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateGetFenceWin32HandleKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateGetFenceWin32HandleKHR(device, pGetWin32HandleInfo, pHandle, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetFenceWin32HandleKHR);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetFenceWin32HandleKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordGetFenceWin32HandleKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordGetFenceWin32HandleKHR(device, pGetWin32HandleInfo, pHandle, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkGetFenceWin32HandleKHR");
        result = device_dispatch->GetFenceWin32HandleKHR(device, pGetWin32HandleInfo, pHandle);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetFenceWin32HandleKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordGetFenceWin32HandleKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordGetFenceWin32HandleKHR(device, pGetWin32HandleInfo, pHandle, record_obj);
        }
    }
    return result;
}

#endif  // VK_USE_PLATFORM_WIN32_KHR
VKAPI_ATTR VkResult VKAPI_CALL ImportFenceFdKHR(VkDevice device, const VkImportFenceFdInfoKHR* pImportFenceFdInfo) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkImportFenceFdKHR, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkImportFenceFdKHR");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateImportFenceFdKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateImportFenceFdKHR(device, pImportFenceFdInfo, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkImportFenceFdKHR);
    {
        VVL_ZoneScopedN("PreCallRecord_vkImportFenceFdKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordImportFenceFdKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordImportFenceFdKHR(device, pImportFenceFdInfo, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkImportFenceFdKHR");
        result = device_dispatch->ImportFenceFdKHR(device, pImportFenceFdInfo);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkImportFenceFdKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordImportFenceFdKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordImportFenceFdKHR(device, pImportFenceFdInfo, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR VkResult VKAPI_CALL GetFenceFdKHR(VkDevice device, const VkFenceGetFdInfoKHR* pGetFdInfo, int* pFd) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetFenceFdKHR, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetFenceFdKHR");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateGetFenceFdKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateGetFenceFdKHR(device, pGetFdInfo, pFd, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetFenceFdKHR);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetFenceFdKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordGetFenceFdKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordGetFenceFdKHR(device, pGetFdInfo, pFd, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkGetFenceFdKHR");
        result = device_dispatch->GetFenceFdKHR(device, pGetFdInfo, pFd);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetFenceFdKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordGetFenceFdKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordGetFenceFdKHR(device, pGetFdInfo, pFd, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR VkResult VKAPI_CALL EnumeratePhysicalDeviceQueueFamilyPerformanceQueryCountersKHR(
    VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex, uint32_t* pCounterCount, VkPerformanceCounterKHR* pCounters,
    VkPerformanceCounterDescriptionKHR* pCounterDescriptions) {
    VVL_ZoneScoped;

    auto instance_dispatch = vvl::dispatch::GetData(physicalDevice);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkEnumeratePhysicalDeviceQueueFamilyPerformanceQueryCountersKHR,
                          VulkanTypedHandle(physicalDevice, kVulkanObjectTypePhysicalDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkEnumeratePhysicalDeviceQueueFamilyPerformanceQueryCountersKHR");
        for (const auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            skip |= vo->PreCallValidateEnumeratePhysicalDeviceQueueFamilyPerformanceQueryCountersKHR(
                physicalDevice, queueFamilyIndex, pCounterCount, pCounters, pCounterDescriptions, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkEnumeratePhysicalDeviceQueueFamilyPerformanceQueryCountersKHR);
    {
        VVL_ZoneScopedN("PreCallRecord_vkEnumeratePhysicalDeviceQueueFamilyPerformanceQueryCountersKHR");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PreCallRecordEnumeratePhysicalDeviceQueueFamilyPerformanceQueryCountersKHR(
                physicalDevice, queueFamilyIndex, pCounterCount, pCounters, pCounterDescriptions, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkEnumeratePhysicalDeviceQueueFamilyPerformanceQueryCountersKHR");
        result = instance_dispatch->EnumeratePhysicalDeviceQueueFamilyPerformanceQueryCountersKHR(
            physicalDevice, queueFamilyIndex, pCounterCount, pCounters, pCounterDescriptions);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkEnumeratePhysicalDeviceQueueFamilyPerformanceQueryCountersKHR");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PostCallRecordEnumeratePhysicalDeviceQueueFamilyPerformanceQueryCountersKHR(
                physicalDevice, queueFamilyIndex, pCounterCount, pCounters, pCounterDescriptions, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR void VKAPI_CALL GetPhysicalDeviceQueueFamilyPerformanceQueryPassesKHR(
    VkPhysicalDevice physicalDevice, const VkQueryPoolPerformanceCreateInfoKHR* pPerformanceQueryCreateInfo, uint32_t* pNumPasses) {
    VVL_ZoneScoped;

    auto instance_dispatch = vvl::dispatch::GetData(physicalDevice);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetPhysicalDeviceQueueFamilyPerformanceQueryPassesKHR,
                          VulkanTypedHandle(physicalDevice, kVulkanObjectTypePhysicalDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetPhysicalDeviceQueueFamilyPerformanceQueryPassesKHR");
        for (const auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            skip |= vo->PreCallValidateGetPhysicalDeviceQueueFamilyPerformanceQueryPassesKHR(
                physicalDevice, pPerformanceQueryCreateInfo, pNumPasses, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetPhysicalDeviceQueueFamilyPerformanceQueryPassesKHR);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetPhysicalDeviceQueueFamilyPerformanceQueryPassesKHR");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PreCallRecordGetPhysicalDeviceQueueFamilyPerformanceQueryPassesKHR(physicalDevice, pPerformanceQueryCreateInfo,
                                                                                   pNumPasses, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkGetPhysicalDeviceQueueFamilyPerformanceQueryPassesKHR");
        instance_dispatch->GetPhysicalDeviceQueueFamilyPerformanceQueryPassesKHR(physicalDevice, pPerformanceQueryCreateInfo,
                                                                                 pNumPasses);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetPhysicalDeviceQueueFamilyPerformanceQueryPassesKHR");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PostCallRecordGetPhysicalDeviceQueueFamilyPerformanceQueryPassesKHR(physicalDevice, pPerformanceQueryCreateInfo,
                                                                                    pNumPasses, record_obj);
        }
    }
}

VKAPI_ATTR VkResult VKAPI_CALL AcquireProfilingLockKHR(VkDevice device, const VkAcquireProfilingLockInfoKHR* pInfo) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkAcquireProfilingLockKHR, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkAcquireProfilingLockKHR");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateAcquireProfilingLockKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateAcquireProfilingLockKHR(device, pInfo, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkAcquireProfilingLockKHR);
    {
        VVL_ZoneScopedN("PreCallRecord_vkAcquireProfilingLockKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordAcquireProfilingLockKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordAcquireProfilingLockKHR(device, pInfo, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkAcquireProfilingLockKHR");
        result = device_dispatch->AcquireProfilingLockKHR(device, pInfo);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkAcquireProfilingLockKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordAcquireProfilingLockKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordAcquireProfilingLockKHR(device, pInfo, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR void VKAPI_CALL ReleaseProfilingLockKHR(VkDevice device) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkReleaseProfilingLockKHR, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkReleaseProfilingLockKHR");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateReleaseProfilingLockKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateReleaseProfilingLockKHR(device, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkReleaseProfilingLockKHR);
    {
        VVL_ZoneScopedN("PreCallRecord_vkReleaseProfilingLockKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordReleaseProfilingLockKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordReleaseProfilingLockKHR(device, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkReleaseProfilingLockKHR");
        device_dispatch->ReleaseProfilingLockKHR(device);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkReleaseProfilingLockKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordReleaseProfilingLockKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordReleaseProfilingLockKHR(device, record_obj);
        }
    }
}

VKAPI_ATTR VkResult VKAPI_CALL GetPhysicalDeviceSurfaceCapabilities2KHR(VkPhysicalDevice physicalDevice,
                                                                        const VkPhysicalDeviceSurfaceInfo2KHR* pSurfaceInfo,
                                                                        VkSurfaceCapabilities2KHR* pSurfaceCapabilities) {
    VVL_ZoneScoped;

    auto instance_dispatch = vvl::dispatch::GetData(physicalDevice);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetPhysicalDeviceSurfaceCapabilities2KHR,
                          VulkanTypedHandle(physicalDevice, kVulkanObjectTypePhysicalDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetPhysicalDeviceSurfaceCapabilities2KHR");
        for (const auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            skip |= vo->PreCallValidateGetPhysicalDeviceSurfaceCapabilities2KHR(physicalDevice, pSurfaceInfo, pSurfaceCapabilities,
                                                                                error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetPhysicalDeviceSurfaceCapabilities2KHR);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetPhysicalDeviceSurfaceCapabilities2KHR");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PreCallRecordGetPhysicalDeviceSurfaceCapabilities2KHR(physicalDevice, pSurfaceInfo, pSurfaceCapabilities,
                                                                      record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkGetPhysicalDeviceSurfaceCapabilities2KHR");
        result = instance_dispatch->GetPhysicalDeviceSurfaceCapabilities2KHR(physicalDevice, pSurfaceInfo, pSurfaceCapabilities);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetPhysicalDeviceSurfaceCapabilities2KHR");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PostCallRecordGetPhysicalDeviceSurfaceCapabilities2KHR(physicalDevice, pSurfaceInfo, pSurfaceCapabilities,
                                                                       record_obj);
        }
    }
    return result;
}

VKAPI_ATTR VkResult VKAPI_CALL GetPhysicalDeviceSurfaceFormats2KHR(VkPhysicalDevice physicalDevice,
                                                                   const VkPhysicalDeviceSurfaceInfo2KHR* pSurfaceInfo,
                                                                   uint32_t* pSurfaceFormatCount,
                                                                   VkSurfaceFormat2KHR* pSurfaceFormats) {
    VVL_ZoneScoped;

    auto instance_dispatch = vvl::dispatch::GetData(physicalDevice);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetPhysicalDeviceSurfaceFormats2KHR,
                          VulkanTypedHandle(physicalDevice, kVulkanObjectTypePhysicalDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetPhysicalDeviceSurfaceFormats2KHR");
        for (const auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            skip |= vo->PreCallValidateGetPhysicalDeviceSurfaceFormats2KHR(physicalDevice, pSurfaceInfo, pSurfaceFormatCount,
                                                                           pSurfaceFormats, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetPhysicalDeviceSurfaceFormats2KHR);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetPhysicalDeviceSurfaceFormats2KHR");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PreCallRecordGetPhysicalDeviceSurfaceFormats2KHR(physicalDevice, pSurfaceInfo, pSurfaceFormatCount, pSurfaceFormats,
                                                                 record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkGetPhysicalDeviceSurfaceFormats2KHR");
        result = instance_dispatch->GetPhysicalDeviceSurfaceFormats2KHR(physicalDevice, pSurfaceInfo, pSurfaceFormatCount,
                                                                        pSurfaceFormats);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetPhysicalDeviceSurfaceFormats2KHR");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PostCallRecordGetPhysicalDeviceSurfaceFormats2KHR(physicalDevice, pSurfaceInfo, pSurfaceFormatCount,
                                                                  pSurfaceFormats, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR VkResult VKAPI_CALL GetPhysicalDeviceDisplayProperties2KHR(VkPhysicalDevice physicalDevice, uint32_t* pPropertyCount,
                                                                      VkDisplayProperties2KHR* pProperties) {
    VVL_ZoneScoped;

    auto instance_dispatch = vvl::dispatch::GetData(physicalDevice);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetPhysicalDeviceDisplayProperties2KHR,
                          VulkanTypedHandle(physicalDevice, kVulkanObjectTypePhysicalDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetPhysicalDeviceDisplayProperties2KHR");
        for (const auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            skip |=
                vo->PreCallValidateGetPhysicalDeviceDisplayProperties2KHR(physicalDevice, pPropertyCount, pProperties, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetPhysicalDeviceDisplayProperties2KHR);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetPhysicalDeviceDisplayProperties2KHR");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PreCallRecordGetPhysicalDeviceDisplayProperties2KHR(physicalDevice, pPropertyCount, pProperties, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkGetPhysicalDeviceDisplayProperties2KHR");
        result = instance_dispatch->GetPhysicalDeviceDisplayProperties2KHR(physicalDevice, pPropertyCount, pProperties);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetPhysicalDeviceDisplayProperties2KHR");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PostCallRecordGetPhysicalDeviceDisplayProperties2KHR(physicalDevice, pPropertyCount, pProperties, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR VkResult VKAPI_CALL GetPhysicalDeviceDisplayPlaneProperties2KHR(VkPhysicalDevice physicalDevice,
                                                                           uint32_t* pPropertyCount,
                                                                           VkDisplayPlaneProperties2KHR* pProperties) {
    VVL_ZoneScoped;

    auto instance_dispatch = vvl::dispatch::GetData(physicalDevice);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetPhysicalDeviceDisplayPlaneProperties2KHR,
                          VulkanTypedHandle(physicalDevice, kVulkanObjectTypePhysicalDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetPhysicalDeviceDisplayPlaneProperties2KHR");
        for (const auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            skip |= vo->PreCallValidateGetPhysicalDeviceDisplayPlaneProperties2KHR(physicalDevice, pPropertyCount, pProperties,
                                                                                   error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetPhysicalDeviceDisplayPlaneProperties2KHR);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetPhysicalDeviceDisplayPlaneProperties2KHR");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PreCallRecordGetPhysicalDeviceDisplayPlaneProperties2KHR(physicalDevice, pPropertyCount, pProperties, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkGetPhysicalDeviceDisplayPlaneProperties2KHR");
        result = instance_dispatch->GetPhysicalDeviceDisplayPlaneProperties2KHR(physicalDevice, pPropertyCount, pProperties);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetPhysicalDeviceDisplayPlaneProperties2KHR");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PostCallRecordGetPhysicalDeviceDisplayPlaneProperties2KHR(physicalDevice, pPropertyCount, pProperties, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR VkResult VKAPI_CALL GetDisplayModeProperties2KHR(VkPhysicalDevice physicalDevice, VkDisplayKHR display,
                                                            uint32_t* pPropertyCount, VkDisplayModeProperties2KHR* pProperties) {
    VVL_ZoneScoped;

    auto instance_dispatch = vvl::dispatch::GetData(physicalDevice);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetDisplayModeProperties2KHR,
                          VulkanTypedHandle(physicalDevice, kVulkanObjectTypePhysicalDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetDisplayModeProperties2KHR");
        for (const auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            skip |=
                vo->PreCallValidateGetDisplayModeProperties2KHR(physicalDevice, display, pPropertyCount, pProperties, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetDisplayModeProperties2KHR);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetDisplayModeProperties2KHR");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PreCallRecordGetDisplayModeProperties2KHR(physicalDevice, display, pPropertyCount, pProperties, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkGetDisplayModeProperties2KHR");
        result = instance_dispatch->GetDisplayModeProperties2KHR(physicalDevice, display, pPropertyCount, pProperties);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetDisplayModeProperties2KHR");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PostCallRecordGetDisplayModeProperties2KHR(physicalDevice, display, pPropertyCount, pProperties, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR VkResult VKAPI_CALL GetDisplayPlaneCapabilities2KHR(VkPhysicalDevice physicalDevice,
                                                               const VkDisplayPlaneInfo2KHR* pDisplayPlaneInfo,
                                                               VkDisplayPlaneCapabilities2KHR* pCapabilities) {
    VVL_ZoneScoped;

    auto instance_dispatch = vvl::dispatch::GetData(physicalDevice);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetDisplayPlaneCapabilities2KHR,
                          VulkanTypedHandle(physicalDevice, kVulkanObjectTypePhysicalDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetDisplayPlaneCapabilities2KHR");
        for (const auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            skip |= vo->PreCallValidateGetDisplayPlaneCapabilities2KHR(physicalDevice, pDisplayPlaneInfo, pCapabilities, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetDisplayPlaneCapabilities2KHR);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetDisplayPlaneCapabilities2KHR");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PreCallRecordGetDisplayPlaneCapabilities2KHR(physicalDevice, pDisplayPlaneInfo, pCapabilities, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkGetDisplayPlaneCapabilities2KHR");
        result = instance_dispatch->GetDisplayPlaneCapabilities2KHR(physicalDevice, pDisplayPlaneInfo, pCapabilities);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetDisplayPlaneCapabilities2KHR");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PostCallRecordGetDisplayPlaneCapabilities2KHR(physicalDevice, pDisplayPlaneInfo, pCapabilities, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR void VKAPI_CALL GetImageMemoryRequirements2KHR(VkDevice device, const VkImageMemoryRequirementsInfo2* pInfo,
                                                          VkMemoryRequirements2* pMemoryRequirements) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetImageMemoryRequirements2KHR, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetImageMemoryRequirements2KHR");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateGetImageMemoryRequirements2KHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateGetImageMemoryRequirements2KHR(device, pInfo, pMemoryRequirements, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetImageMemoryRequirements2KHR);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetImageMemoryRequirements2KHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordGetImageMemoryRequirements2KHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordGetImageMemoryRequirements2KHR(device, pInfo, pMemoryRequirements, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkGetImageMemoryRequirements2KHR");
        device_dispatch->GetImageMemoryRequirements2KHR(device, pInfo, pMemoryRequirements);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetImageMemoryRequirements2KHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordGetImageMemoryRequirements2KHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordGetImageMemoryRequirements2KHR(device, pInfo, pMemoryRequirements, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL GetBufferMemoryRequirements2KHR(VkDevice device, const VkBufferMemoryRequirementsInfo2* pInfo,
                                                           VkMemoryRequirements2* pMemoryRequirements) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetBufferMemoryRequirements2KHR, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetBufferMemoryRequirements2KHR");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateGetBufferMemoryRequirements2KHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateGetBufferMemoryRequirements2KHR(device, pInfo, pMemoryRequirements, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetBufferMemoryRequirements2KHR);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetBufferMemoryRequirements2KHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordGetBufferMemoryRequirements2KHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordGetBufferMemoryRequirements2KHR(device, pInfo, pMemoryRequirements, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkGetBufferMemoryRequirements2KHR");
        device_dispatch->GetBufferMemoryRequirements2KHR(device, pInfo, pMemoryRequirements);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetBufferMemoryRequirements2KHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordGetBufferMemoryRequirements2KHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordGetBufferMemoryRequirements2KHR(device, pInfo, pMemoryRequirements, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL GetImageSparseMemoryRequirements2KHR(VkDevice device, const VkImageSparseMemoryRequirementsInfo2* pInfo,
                                                                uint32_t* pSparseMemoryRequirementCount,
                                                                VkSparseImageMemoryRequirements2* pSparseMemoryRequirements) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetImageSparseMemoryRequirements2KHR, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetImageSparseMemoryRequirements2KHR");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateGetImageSparseMemoryRequirements2KHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateGetImageSparseMemoryRequirements2KHR(device, pInfo, pSparseMemoryRequirementCount,
                                                                            pSparseMemoryRequirements, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetImageSparseMemoryRequirements2KHR);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetImageSparseMemoryRequirements2KHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordGetImageSparseMemoryRequirements2KHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordGetImageSparseMemoryRequirements2KHR(device, pInfo, pSparseMemoryRequirementCount,
                                                                  pSparseMemoryRequirements, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkGetImageSparseMemoryRequirements2KHR");
        device_dispatch->GetImageSparseMemoryRequirements2KHR(device, pInfo, pSparseMemoryRequirementCount,
                                                              pSparseMemoryRequirements);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetImageSparseMemoryRequirements2KHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordGetImageSparseMemoryRequirements2KHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordGetImageSparseMemoryRequirements2KHR(device, pInfo, pSparseMemoryRequirementCount,
                                                                   pSparseMemoryRequirements, record_obj);
        }
    }
}

VKAPI_ATTR VkResult VKAPI_CALL CreateSamplerYcbcrConversionKHR(VkDevice device,
                                                               const VkSamplerYcbcrConversionCreateInfo* pCreateInfo,
                                                               const VkAllocationCallbacks* pAllocator,
                                                               VkSamplerYcbcrConversion* pYcbcrConversion) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCreateSamplerYcbcrConversionKHR, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCreateSamplerYcbcrConversionKHR");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCreateSamplerYcbcrConversionKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |=
                vo->PreCallValidateCreateSamplerYcbcrConversionKHR(device, pCreateInfo, pAllocator, pYcbcrConversion, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkCreateSamplerYcbcrConversionKHR);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCreateSamplerYcbcrConversionKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCreateSamplerYcbcrConversionKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCreateSamplerYcbcrConversionKHR(device, pCreateInfo, pAllocator, pYcbcrConversion, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkCreateSamplerYcbcrConversionKHR");
        result = device_dispatch->CreateSamplerYcbcrConversionKHR(device, pCreateInfo, pAllocator, pYcbcrConversion);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkCreateSamplerYcbcrConversionKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCreateSamplerYcbcrConversionKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCreateSamplerYcbcrConversionKHR(device, pCreateInfo, pAllocator, pYcbcrConversion, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR void VKAPI_CALL DestroySamplerYcbcrConversionKHR(VkDevice device, VkSamplerYcbcrConversion ycbcrConversion,
                                                            const VkAllocationCallbacks* pAllocator) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkDestroySamplerYcbcrConversionKHR, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkDestroySamplerYcbcrConversionKHR");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateDestroySamplerYcbcrConversionKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateDestroySamplerYcbcrConversionKHR(device, ycbcrConversion, pAllocator, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkDestroySamplerYcbcrConversionKHR);
    {
        VVL_ZoneScopedN("PreCallRecord_vkDestroySamplerYcbcrConversionKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordDestroySamplerYcbcrConversionKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordDestroySamplerYcbcrConversionKHR(device, ycbcrConversion, pAllocator, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkDestroySamplerYcbcrConversionKHR");
        device_dispatch->DestroySamplerYcbcrConversionKHR(device, ycbcrConversion, pAllocator);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkDestroySamplerYcbcrConversionKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordDestroySamplerYcbcrConversionKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordDestroySamplerYcbcrConversionKHR(device, ycbcrConversion, pAllocator, record_obj);
        }
    }
}

VKAPI_ATTR VkResult VKAPI_CALL BindBufferMemory2KHR(VkDevice device, uint32_t bindInfoCount,
                                                    const VkBindBufferMemoryInfo* pBindInfos) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkBindBufferMemory2KHR, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkBindBufferMemory2KHR");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateBindBufferMemory2KHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateBindBufferMemory2KHR(device, bindInfoCount, pBindInfos, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkBindBufferMemory2KHR);
    {
        VVL_ZoneScopedN("PreCallRecord_vkBindBufferMemory2KHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordBindBufferMemory2KHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordBindBufferMemory2KHR(device, bindInfoCount, pBindInfos, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkBindBufferMemory2KHR");
        result = device_dispatch->BindBufferMemory2KHR(device, bindInfoCount, pBindInfos);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkBindBufferMemory2KHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordBindBufferMemory2KHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordBindBufferMemory2KHR(device, bindInfoCount, pBindInfos, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR VkResult VKAPI_CALL BindImageMemory2KHR(VkDevice device, uint32_t bindInfoCount,
                                                   const VkBindImageMemoryInfo* pBindInfos) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkBindImageMemory2KHR, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkBindImageMemory2KHR");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateBindImageMemory2KHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateBindImageMemory2KHR(device, bindInfoCount, pBindInfos, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkBindImageMemory2KHR);
    {
        VVL_ZoneScopedN("PreCallRecord_vkBindImageMemory2KHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordBindImageMemory2KHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordBindImageMemory2KHR(device, bindInfoCount, pBindInfos, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkBindImageMemory2KHR");
        result = device_dispatch->BindImageMemory2KHR(device, bindInfoCount, pBindInfos);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkBindImageMemory2KHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordBindImageMemory2KHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordBindImageMemory2KHR(device, bindInfoCount, pBindInfos, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR void VKAPI_CALL GetDescriptorSetLayoutSupportKHR(VkDevice device, const VkDescriptorSetLayoutCreateInfo* pCreateInfo,
                                                            VkDescriptorSetLayoutSupport* pSupport) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetDescriptorSetLayoutSupportKHR, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetDescriptorSetLayoutSupportKHR");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateGetDescriptorSetLayoutSupportKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateGetDescriptorSetLayoutSupportKHR(device, pCreateInfo, pSupport, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetDescriptorSetLayoutSupportKHR);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetDescriptorSetLayoutSupportKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordGetDescriptorSetLayoutSupportKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordGetDescriptorSetLayoutSupportKHR(device, pCreateInfo, pSupport, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkGetDescriptorSetLayoutSupportKHR");
        device_dispatch->GetDescriptorSetLayoutSupportKHR(device, pCreateInfo, pSupport);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetDescriptorSetLayoutSupportKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordGetDescriptorSetLayoutSupportKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordGetDescriptorSetLayoutSupportKHR(device, pCreateInfo, pSupport, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdDrawIndirectCountKHR(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
                                                   VkBuffer countBuffer, VkDeviceSize countBufferOffset, uint32_t maxDrawCount,
                                                   uint32_t stride) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdDrawIndirectCountKHR, VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdDrawIndirectCountKHR");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdDrawIndirectCountKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdDrawIndirectCountKHR(commandBuffer, buffer, offset, countBuffer, countBufferOffset,
                                                               maxDrawCount, stride, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdDrawIndirectCountKHR);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdDrawIndirectCountKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdDrawIndirectCountKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdDrawIndirectCountKHR(commandBuffer, buffer, offset, countBuffer, countBufferOffset, maxDrawCount,
                                                     stride, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdDrawIndirectCountKHR");
        device_dispatch->CmdDrawIndirectCountKHR(commandBuffer, buffer, offset, countBuffer, countBufferOffset, maxDrawCount,
                                                 stride);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdDrawIndirectCountKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdDrawIndirectCountKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdDrawIndirectCountKHR(commandBuffer, buffer, offset, countBuffer, countBufferOffset, maxDrawCount,
                                                      stride, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdDrawIndexedIndirectCountKHR(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
                                                          VkBuffer countBuffer, VkDeviceSize countBufferOffset,
                                                          uint32_t maxDrawCount, uint32_t stride) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdDrawIndexedIndirectCountKHR,
                          VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdDrawIndexedIndirectCountKHR");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdDrawIndexedIndirectCountKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdDrawIndexedIndirectCountKHR(commandBuffer, buffer, offset, countBuffer, countBufferOffset,
                                                                      maxDrawCount, stride, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdDrawIndexedIndirectCountKHR);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdDrawIndexedIndirectCountKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdDrawIndexedIndirectCountKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdDrawIndexedIndirectCountKHR(commandBuffer, buffer, offset, countBuffer, countBufferOffset,
                                                            maxDrawCount, stride, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdDrawIndexedIndirectCountKHR");
        device_dispatch->CmdDrawIndexedIndirectCountKHR(commandBuffer, buffer, offset, countBuffer, countBufferOffset, maxDrawCount,
                                                        stride);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdDrawIndexedIndirectCountKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdDrawIndexedIndirectCountKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdDrawIndexedIndirectCountKHR(commandBuffer, buffer, offset, countBuffer, countBufferOffset,
                                                             maxDrawCount, stride, record_obj);
        }
    }
}

VKAPI_ATTR VkResult VKAPI_CALL GetSemaphoreCounterValueKHR(VkDevice device, VkSemaphore semaphore, uint64_t* pValue) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetSemaphoreCounterValueKHR, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetSemaphoreCounterValueKHR");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateGetSemaphoreCounterValueKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateGetSemaphoreCounterValueKHR(device, semaphore, pValue, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetSemaphoreCounterValueKHR);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetSemaphoreCounterValueKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordGetSemaphoreCounterValueKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordGetSemaphoreCounterValueKHR(device, semaphore, pValue, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkGetSemaphoreCounterValueKHR");
        result = device_dispatch->GetSemaphoreCounterValueKHR(device, semaphore, pValue);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetSemaphoreCounterValueKHR");

        if (result == VK_ERROR_DEVICE_LOST) {
            for (auto& vo : device_dispatch->object_dispatch) {
                vo->is_device_lost = true;
            }
        }
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordGetSemaphoreCounterValueKHR]) {
            if (!vo) {
                continue;
            }
            vvl::base::Device::BlockingOperationGuard lock(vo);
            vo->PostCallRecordGetSemaphoreCounterValueKHR(device, semaphore, pValue, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR VkResult VKAPI_CALL WaitSemaphoresKHR(VkDevice device, const VkSemaphoreWaitInfo* pWaitInfo, uint64_t timeout) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkWaitSemaphoresKHR, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkWaitSemaphoresKHR");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateWaitSemaphoresKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateWaitSemaphoresKHR(device, pWaitInfo, timeout, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkWaitSemaphoresKHR);
    {
        VVL_ZoneScopedN("PreCallRecord_vkWaitSemaphoresKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordWaitSemaphoresKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordWaitSemaphoresKHR(device, pWaitInfo, timeout, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkWaitSemaphoresKHR");
        result = device_dispatch->WaitSemaphoresKHR(device, pWaitInfo, timeout);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkWaitSemaphoresKHR");

        if (result == VK_ERROR_DEVICE_LOST) {
            for (auto& vo : device_dispatch->object_dispatch) {
                vo->is_device_lost = true;
            }
        }
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordWaitSemaphoresKHR]) {
            if (!vo) {
                continue;
            }
            vvl::base::Device::BlockingOperationGuard lock(vo);
            vo->PostCallRecordWaitSemaphoresKHR(device, pWaitInfo, timeout, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR VkResult VKAPI_CALL SignalSemaphoreKHR(VkDevice device, const VkSemaphoreSignalInfo* pSignalInfo) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkSignalSemaphoreKHR, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkSignalSemaphoreKHR");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateSignalSemaphoreKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateSignalSemaphoreKHR(device, pSignalInfo, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkSignalSemaphoreKHR);
    {
        VVL_ZoneScopedN("PreCallRecord_vkSignalSemaphoreKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordSignalSemaphoreKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordSignalSemaphoreKHR(device, pSignalInfo, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkSignalSemaphoreKHR");
        result = device_dispatch->SignalSemaphoreKHR(device, pSignalInfo);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkSignalSemaphoreKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordSignalSemaphoreKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordSignalSemaphoreKHR(device, pSignalInfo, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR VkResult VKAPI_CALL
GetPhysicalDeviceFragmentShadingRatesKHR(VkPhysicalDevice physicalDevice, uint32_t* pFragmentShadingRateCount,
                                         VkPhysicalDeviceFragmentShadingRateKHR* pFragmentShadingRates) {
    VVL_ZoneScoped;

    auto instance_dispatch = vvl::dispatch::GetData(physicalDevice);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetPhysicalDeviceFragmentShadingRatesKHR,
                          VulkanTypedHandle(physicalDevice, kVulkanObjectTypePhysicalDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetPhysicalDeviceFragmentShadingRatesKHR");
        for (const auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            skip |= vo->PreCallValidateGetPhysicalDeviceFragmentShadingRatesKHR(physicalDevice, pFragmentShadingRateCount,
                                                                                pFragmentShadingRates, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetPhysicalDeviceFragmentShadingRatesKHR);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetPhysicalDeviceFragmentShadingRatesKHR");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PreCallRecordGetPhysicalDeviceFragmentShadingRatesKHR(physicalDevice, pFragmentShadingRateCount,
                                                                      pFragmentShadingRates, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkGetPhysicalDeviceFragmentShadingRatesKHR");
        result = instance_dispatch->GetPhysicalDeviceFragmentShadingRatesKHR(physicalDevice, pFragmentShadingRateCount,
                                                                             pFragmentShadingRates);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetPhysicalDeviceFragmentShadingRatesKHR");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PostCallRecordGetPhysicalDeviceFragmentShadingRatesKHR(physicalDevice, pFragmentShadingRateCount,
                                                                       pFragmentShadingRates, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR void VKAPI_CALL CmdSetFragmentShadingRateKHR(VkCommandBuffer commandBuffer, const VkExtent2D* pFragmentSize,
                                                        const VkFragmentShadingRateCombinerOpKHR combinerOps[2]) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdSetFragmentShadingRateKHR,
                          VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdSetFragmentShadingRateKHR");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdSetFragmentShadingRateKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdSetFragmentShadingRateKHR(commandBuffer, pFragmentSize, combinerOps, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdSetFragmentShadingRateKHR);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdSetFragmentShadingRateKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdSetFragmentShadingRateKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdSetFragmentShadingRateKHR(commandBuffer, pFragmentSize, combinerOps, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdSetFragmentShadingRateKHR");
        device_dispatch->CmdSetFragmentShadingRateKHR(commandBuffer, pFragmentSize, combinerOps);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdSetFragmentShadingRateKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdSetFragmentShadingRateKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdSetFragmentShadingRateKHR(commandBuffer, pFragmentSize, combinerOps, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdSetRenderingAttachmentLocationsKHR(VkCommandBuffer commandBuffer,
                                                                 const VkRenderingAttachmentLocationInfo* pLocationInfo) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdSetRenderingAttachmentLocationsKHR,
                          VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdSetRenderingAttachmentLocationsKHR");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdSetRenderingAttachmentLocationsKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdSetRenderingAttachmentLocationsKHR(commandBuffer, pLocationInfo, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdSetRenderingAttachmentLocationsKHR);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdSetRenderingAttachmentLocationsKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdSetRenderingAttachmentLocationsKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdSetRenderingAttachmentLocationsKHR(commandBuffer, pLocationInfo, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdSetRenderingAttachmentLocationsKHR");
        device_dispatch->CmdSetRenderingAttachmentLocationsKHR(commandBuffer, pLocationInfo);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdSetRenderingAttachmentLocationsKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdSetRenderingAttachmentLocationsKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdSetRenderingAttachmentLocationsKHR(commandBuffer, pLocationInfo, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdSetRenderingInputAttachmentIndicesKHR(
    VkCommandBuffer commandBuffer, const VkRenderingInputAttachmentIndexInfo* pInputAttachmentIndexInfo) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdSetRenderingInputAttachmentIndicesKHR,
                          VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdSetRenderingInputAttachmentIndicesKHR");
        for (const auto& vo :
             device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdSetRenderingInputAttachmentIndicesKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |=
                vo->PreCallValidateCmdSetRenderingInputAttachmentIndicesKHR(commandBuffer, pInputAttachmentIndexInfo, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdSetRenderingInputAttachmentIndicesKHR);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdSetRenderingInputAttachmentIndicesKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdSetRenderingInputAttachmentIndicesKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdSetRenderingInputAttachmentIndicesKHR(commandBuffer, pInputAttachmentIndexInfo, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdSetRenderingInputAttachmentIndicesKHR");
        device_dispatch->CmdSetRenderingInputAttachmentIndicesKHR(commandBuffer, pInputAttachmentIndexInfo);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdSetRenderingInputAttachmentIndicesKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdSetRenderingInputAttachmentIndicesKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdSetRenderingInputAttachmentIndicesKHR(commandBuffer, pInputAttachmentIndexInfo, record_obj);
        }
    }
}

VKAPI_ATTR VkResult VKAPI_CALL WaitForPresentKHR(VkDevice device, VkSwapchainKHR swapchain, uint64_t presentId, uint64_t timeout) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkWaitForPresentKHR, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkWaitForPresentKHR");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateWaitForPresentKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateWaitForPresentKHR(device, swapchain, presentId, timeout, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkWaitForPresentKHR);
    {
        VVL_ZoneScopedN("PreCallRecord_vkWaitForPresentKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordWaitForPresentKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordWaitForPresentKHR(device, swapchain, presentId, timeout, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkWaitForPresentKHR");
        result = device_dispatch->WaitForPresentKHR(device, swapchain, presentId, timeout);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkWaitForPresentKHR");

        if (result == VK_ERROR_DEVICE_LOST) {
            for (auto& vo : device_dispatch->object_dispatch) {
                vo->is_device_lost = true;
            }
        }
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordWaitForPresentKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordWaitForPresentKHR(device, swapchain, presentId, timeout, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR VkDeviceAddress VKAPI_CALL GetBufferDeviceAddressKHR(VkDevice device, const VkBufferDeviceAddressInfo* pInfo) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetBufferDeviceAddressKHR, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetBufferDeviceAddressKHR");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateGetBufferDeviceAddressKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateGetBufferDeviceAddressKHR(device, pInfo, error_obj);
            if (skip) return 0;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetBufferDeviceAddressKHR);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetBufferDeviceAddressKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordGetBufferDeviceAddressKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordGetBufferDeviceAddressKHR(device, pInfo, record_obj);
        }
    }
    VkDeviceAddress result;
    {
        VVL_ZoneScopedN("Dispatch_vkGetBufferDeviceAddressKHR");
        result = device_dispatch->GetBufferDeviceAddressKHR(device, pInfo);
    }
    record_obj.device_address = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetBufferDeviceAddressKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordGetBufferDeviceAddressKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordGetBufferDeviceAddressKHR(device, pInfo, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR uint64_t VKAPI_CALL GetBufferOpaqueCaptureAddressKHR(VkDevice device, const VkBufferDeviceAddressInfo* pInfo) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetBufferOpaqueCaptureAddressKHR, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetBufferOpaqueCaptureAddressKHR");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateGetBufferOpaqueCaptureAddressKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateGetBufferOpaqueCaptureAddressKHR(device, pInfo, error_obj);
            if (skip) return 0;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetBufferOpaqueCaptureAddressKHR);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetBufferOpaqueCaptureAddressKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordGetBufferOpaqueCaptureAddressKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordGetBufferOpaqueCaptureAddressKHR(device, pInfo, record_obj);
        }
    }
    uint64_t result;
    {
        VVL_ZoneScopedN("Dispatch_vkGetBufferOpaqueCaptureAddressKHR");
        result = device_dispatch->GetBufferOpaqueCaptureAddressKHR(device, pInfo);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetBufferOpaqueCaptureAddressKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordGetBufferOpaqueCaptureAddressKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordGetBufferOpaqueCaptureAddressKHR(device, pInfo, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR uint64_t VKAPI_CALL GetDeviceMemoryOpaqueCaptureAddressKHR(VkDevice device,
                                                                      const VkDeviceMemoryOpaqueCaptureAddressInfo* pInfo) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetDeviceMemoryOpaqueCaptureAddressKHR, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetDeviceMemoryOpaqueCaptureAddressKHR");
        for (const auto& vo :
             device_dispatch->intercept_vectors[InterceptIdPreCallValidateGetDeviceMemoryOpaqueCaptureAddressKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateGetDeviceMemoryOpaqueCaptureAddressKHR(device, pInfo, error_obj);
            if (skip) return 0;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetDeviceMemoryOpaqueCaptureAddressKHR);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetDeviceMemoryOpaqueCaptureAddressKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordGetDeviceMemoryOpaqueCaptureAddressKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordGetDeviceMemoryOpaqueCaptureAddressKHR(device, pInfo, record_obj);
        }
    }
    uint64_t result;
    {
        VVL_ZoneScopedN("Dispatch_vkGetDeviceMemoryOpaqueCaptureAddressKHR");
        result = device_dispatch->GetDeviceMemoryOpaqueCaptureAddressKHR(device, pInfo);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetDeviceMemoryOpaqueCaptureAddressKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordGetDeviceMemoryOpaqueCaptureAddressKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordGetDeviceMemoryOpaqueCaptureAddressKHR(device, pInfo, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR VkResult VKAPI_CALL CreateDeferredOperationKHR(VkDevice device, const VkAllocationCallbacks* pAllocator,
                                                          VkDeferredOperationKHR* pDeferredOperation) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCreateDeferredOperationKHR, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCreateDeferredOperationKHR");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCreateDeferredOperationKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCreateDeferredOperationKHR(device, pAllocator, pDeferredOperation, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkCreateDeferredOperationKHR);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCreateDeferredOperationKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCreateDeferredOperationKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCreateDeferredOperationKHR(device, pAllocator, pDeferredOperation, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkCreateDeferredOperationKHR");
        result = device_dispatch->CreateDeferredOperationKHR(device, pAllocator, pDeferredOperation);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkCreateDeferredOperationKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCreateDeferredOperationKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCreateDeferredOperationKHR(device, pAllocator, pDeferredOperation, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR void VKAPI_CALL DestroyDeferredOperationKHR(VkDevice device, VkDeferredOperationKHR operation,
                                                       const VkAllocationCallbacks* pAllocator) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkDestroyDeferredOperationKHR, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkDestroyDeferredOperationKHR");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateDestroyDeferredOperationKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateDestroyDeferredOperationKHR(device, operation, pAllocator, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkDestroyDeferredOperationKHR);
    {
        VVL_ZoneScopedN("PreCallRecord_vkDestroyDeferredOperationKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordDestroyDeferredOperationKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordDestroyDeferredOperationKHR(device, operation, pAllocator, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkDestroyDeferredOperationKHR");
        device_dispatch->DestroyDeferredOperationKHR(device, operation, pAllocator);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkDestroyDeferredOperationKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordDestroyDeferredOperationKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordDestroyDeferredOperationKHR(device, operation, pAllocator, record_obj);
        }
    }
}

VKAPI_ATTR uint32_t VKAPI_CALL GetDeferredOperationMaxConcurrencyKHR(VkDevice device, VkDeferredOperationKHR operation) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetDeferredOperationMaxConcurrencyKHR, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetDeferredOperationMaxConcurrencyKHR");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateGetDeferredOperationMaxConcurrencyKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateGetDeferredOperationMaxConcurrencyKHR(device, operation, error_obj);
            if (skip) return 0;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetDeferredOperationMaxConcurrencyKHR);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetDeferredOperationMaxConcurrencyKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordGetDeferredOperationMaxConcurrencyKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordGetDeferredOperationMaxConcurrencyKHR(device, operation, record_obj);
        }
    }
    uint32_t result;
    {
        VVL_ZoneScopedN("Dispatch_vkGetDeferredOperationMaxConcurrencyKHR");
        result = device_dispatch->GetDeferredOperationMaxConcurrencyKHR(device, operation);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetDeferredOperationMaxConcurrencyKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordGetDeferredOperationMaxConcurrencyKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordGetDeferredOperationMaxConcurrencyKHR(device, operation, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR VkResult VKAPI_CALL GetDeferredOperationResultKHR(VkDevice device, VkDeferredOperationKHR operation) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetDeferredOperationResultKHR, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetDeferredOperationResultKHR");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateGetDeferredOperationResultKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateGetDeferredOperationResultKHR(device, operation, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetDeferredOperationResultKHR);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetDeferredOperationResultKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordGetDeferredOperationResultKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordGetDeferredOperationResultKHR(device, operation, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkGetDeferredOperationResultKHR");
        result = device_dispatch->GetDeferredOperationResultKHR(device, operation);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetDeferredOperationResultKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordGetDeferredOperationResultKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordGetDeferredOperationResultKHR(device, operation, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR VkResult VKAPI_CALL DeferredOperationJoinKHR(VkDevice device, VkDeferredOperationKHR operation) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkDeferredOperationJoinKHR, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkDeferredOperationJoinKHR");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateDeferredOperationJoinKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateDeferredOperationJoinKHR(device, operation, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkDeferredOperationJoinKHR);
    {
        VVL_ZoneScopedN("PreCallRecord_vkDeferredOperationJoinKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordDeferredOperationJoinKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordDeferredOperationJoinKHR(device, operation, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkDeferredOperationJoinKHR");
        result = device_dispatch->DeferredOperationJoinKHR(device, operation);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkDeferredOperationJoinKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordDeferredOperationJoinKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordDeferredOperationJoinKHR(device, operation, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR VkResult VKAPI_CALL GetPipelineExecutablePropertiesKHR(VkDevice device, const VkPipelineInfoKHR* pPipelineInfo,
                                                                  uint32_t* pExecutableCount,
                                                                  VkPipelineExecutablePropertiesKHR* pProperties) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetPipelineExecutablePropertiesKHR, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetPipelineExecutablePropertiesKHR");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateGetPipelineExecutablePropertiesKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateGetPipelineExecutablePropertiesKHR(device, pPipelineInfo, pExecutableCount, pProperties,
                                                                          error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetPipelineExecutablePropertiesKHR);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetPipelineExecutablePropertiesKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordGetPipelineExecutablePropertiesKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordGetPipelineExecutablePropertiesKHR(device, pPipelineInfo, pExecutableCount, pProperties, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkGetPipelineExecutablePropertiesKHR");
        result = device_dispatch->GetPipelineExecutablePropertiesKHR(device, pPipelineInfo, pExecutableCount, pProperties);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetPipelineExecutablePropertiesKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordGetPipelineExecutablePropertiesKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordGetPipelineExecutablePropertiesKHR(device, pPipelineInfo, pExecutableCount, pProperties, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR VkResult VKAPI_CALL GetPipelineExecutableStatisticsKHR(VkDevice device,
                                                                  const VkPipelineExecutableInfoKHR* pExecutableInfo,
                                                                  uint32_t* pStatisticCount,
                                                                  VkPipelineExecutableStatisticKHR* pStatistics) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetPipelineExecutableStatisticsKHR, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetPipelineExecutableStatisticsKHR");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateGetPipelineExecutableStatisticsKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateGetPipelineExecutableStatisticsKHR(device, pExecutableInfo, pStatisticCount, pStatistics,
                                                                          error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetPipelineExecutableStatisticsKHR);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetPipelineExecutableStatisticsKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordGetPipelineExecutableStatisticsKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordGetPipelineExecutableStatisticsKHR(device, pExecutableInfo, pStatisticCount, pStatistics, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkGetPipelineExecutableStatisticsKHR");
        result = device_dispatch->GetPipelineExecutableStatisticsKHR(device, pExecutableInfo, pStatisticCount, pStatistics);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetPipelineExecutableStatisticsKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordGetPipelineExecutableStatisticsKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordGetPipelineExecutableStatisticsKHR(device, pExecutableInfo, pStatisticCount, pStatistics, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR VkResult VKAPI_CALL GetPipelineExecutableInternalRepresentationsKHR(
    VkDevice device, const VkPipelineExecutableInfoKHR* pExecutableInfo, uint32_t* pInternalRepresentationCount,
    VkPipelineExecutableInternalRepresentationKHR* pInternalRepresentations) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetPipelineExecutableInternalRepresentationsKHR,
                          VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetPipelineExecutableInternalRepresentationsKHR");
        for (const auto& vo :
             device_dispatch->intercept_vectors[InterceptIdPreCallValidateGetPipelineExecutableInternalRepresentationsKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateGetPipelineExecutableInternalRepresentationsKHR(
                device, pExecutableInfo, pInternalRepresentationCount, pInternalRepresentations, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetPipelineExecutableInternalRepresentationsKHR);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetPipelineExecutableInternalRepresentationsKHR");
        for (auto& vo :
             device_dispatch->intercept_vectors[InterceptIdPreCallRecordGetPipelineExecutableInternalRepresentationsKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordGetPipelineExecutableInternalRepresentationsKHR(device, pExecutableInfo, pInternalRepresentationCount,
                                                                             pInternalRepresentations, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkGetPipelineExecutableInternalRepresentationsKHR");
        result = device_dispatch->GetPipelineExecutableInternalRepresentationsKHR(
            device, pExecutableInfo, pInternalRepresentationCount, pInternalRepresentations);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetPipelineExecutableInternalRepresentationsKHR");
        for (auto& vo :
             device_dispatch->intercept_vectors[InterceptIdPostCallRecordGetPipelineExecutableInternalRepresentationsKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordGetPipelineExecutableInternalRepresentationsKHR(device, pExecutableInfo, pInternalRepresentationCount,
                                                                              pInternalRepresentations, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR VkResult VKAPI_CALL MapMemory2KHR(VkDevice device, const VkMemoryMapInfo* pMemoryMapInfo, void** ppData) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkMapMemory2KHR, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkMapMemory2KHR");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateMapMemory2KHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateMapMemory2KHR(device, pMemoryMapInfo, ppData, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkMapMemory2KHR);
    {
        VVL_ZoneScopedN("PreCallRecord_vkMapMemory2KHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordMapMemory2KHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordMapMemory2KHR(device, pMemoryMapInfo, ppData, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkMapMemory2KHR");
        result = device_dispatch->MapMemory2KHR(device, pMemoryMapInfo, ppData);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkMapMemory2KHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordMapMemory2KHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordMapMemory2KHR(device, pMemoryMapInfo, ppData, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR VkResult VKAPI_CALL UnmapMemory2KHR(VkDevice device, const VkMemoryUnmapInfo* pMemoryUnmapInfo) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkUnmapMemory2KHR, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkUnmapMemory2KHR");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateUnmapMemory2KHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateUnmapMemory2KHR(device, pMemoryUnmapInfo, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkUnmapMemory2KHR);
    {
        VVL_ZoneScopedN("PreCallRecord_vkUnmapMemory2KHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordUnmapMemory2KHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordUnmapMemory2KHR(device, pMemoryUnmapInfo, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkUnmapMemory2KHR");
        result = device_dispatch->UnmapMemory2KHR(device, pMemoryUnmapInfo);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkUnmapMemory2KHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordUnmapMemory2KHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordUnmapMemory2KHR(device, pMemoryUnmapInfo, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR VkResult VKAPI_CALL GetPhysicalDeviceVideoEncodeQualityLevelPropertiesKHR(
    VkPhysicalDevice physicalDevice, const VkPhysicalDeviceVideoEncodeQualityLevelInfoKHR* pQualityLevelInfo,
    VkVideoEncodeQualityLevelPropertiesKHR* pQualityLevelProperties) {
    VVL_ZoneScoped;

    auto instance_dispatch = vvl::dispatch::GetData(physicalDevice);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetPhysicalDeviceVideoEncodeQualityLevelPropertiesKHR,
                          VulkanTypedHandle(physicalDevice, kVulkanObjectTypePhysicalDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetPhysicalDeviceVideoEncodeQualityLevelPropertiesKHR");
        for (const auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            skip |= vo->PreCallValidateGetPhysicalDeviceVideoEncodeQualityLevelPropertiesKHR(physicalDevice, pQualityLevelInfo,
                                                                                             pQualityLevelProperties, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetPhysicalDeviceVideoEncodeQualityLevelPropertiesKHR);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetPhysicalDeviceVideoEncodeQualityLevelPropertiesKHR");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PreCallRecordGetPhysicalDeviceVideoEncodeQualityLevelPropertiesKHR(physicalDevice, pQualityLevelInfo,
                                                                                   pQualityLevelProperties, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkGetPhysicalDeviceVideoEncodeQualityLevelPropertiesKHR");
        result = instance_dispatch->GetPhysicalDeviceVideoEncodeQualityLevelPropertiesKHR(physicalDevice, pQualityLevelInfo,
                                                                                          pQualityLevelProperties);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetPhysicalDeviceVideoEncodeQualityLevelPropertiesKHR");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PostCallRecordGetPhysicalDeviceVideoEncodeQualityLevelPropertiesKHR(physicalDevice, pQualityLevelInfo,
                                                                                    pQualityLevelProperties, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR VkResult VKAPI_CALL
GetEncodedVideoSessionParametersKHR(VkDevice device, const VkVideoEncodeSessionParametersGetInfoKHR* pVideoSessionParametersInfo,
                                    VkVideoEncodeSessionParametersFeedbackInfoKHR* pFeedbackInfo, size_t* pDataSize, void* pData) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetEncodedVideoSessionParametersKHR, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetEncodedVideoSessionParametersKHR");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateGetEncodedVideoSessionParametersKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateGetEncodedVideoSessionParametersKHR(device, pVideoSessionParametersInfo, pFeedbackInfo,
                                                                           pDataSize, pData, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetEncodedVideoSessionParametersKHR);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetEncodedVideoSessionParametersKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordGetEncodedVideoSessionParametersKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordGetEncodedVideoSessionParametersKHR(device, pVideoSessionParametersInfo, pFeedbackInfo, pDataSize,
                                                                 pData, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkGetEncodedVideoSessionParametersKHR");
        result = device_dispatch->GetEncodedVideoSessionParametersKHR(device, pVideoSessionParametersInfo, pFeedbackInfo, pDataSize,
                                                                      pData);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetEncodedVideoSessionParametersKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordGetEncodedVideoSessionParametersKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordGetEncodedVideoSessionParametersKHR(device, pVideoSessionParametersInfo, pFeedbackInfo, pDataSize,
                                                                  pData, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR void VKAPI_CALL CmdEncodeVideoKHR(VkCommandBuffer commandBuffer, const VkVideoEncodeInfoKHR* pEncodeInfo) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdEncodeVideoKHR, VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdEncodeVideoKHR");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdEncodeVideoKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdEncodeVideoKHR(commandBuffer, pEncodeInfo, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdEncodeVideoKHR);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdEncodeVideoKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdEncodeVideoKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdEncodeVideoKHR(commandBuffer, pEncodeInfo, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdEncodeVideoKHR");
        device_dispatch->CmdEncodeVideoKHR(commandBuffer, pEncodeInfo);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdEncodeVideoKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdEncodeVideoKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdEncodeVideoKHR(commandBuffer, pEncodeInfo, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdSetEvent2KHR(VkCommandBuffer commandBuffer, VkEvent event, const VkDependencyInfo* pDependencyInfo) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdSetEvent2KHR, VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdSetEvent2KHR");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdSetEvent2KHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdSetEvent2KHR(commandBuffer, event, pDependencyInfo, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdSetEvent2KHR);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdSetEvent2KHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdSetEvent2KHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdSetEvent2KHR(commandBuffer, event, pDependencyInfo, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdSetEvent2KHR");
        device_dispatch->CmdSetEvent2KHR(commandBuffer, event, pDependencyInfo);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdSetEvent2KHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdSetEvent2KHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdSetEvent2KHR(commandBuffer, event, pDependencyInfo, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdResetEvent2KHR(VkCommandBuffer commandBuffer, VkEvent event, VkPipelineStageFlags2 stageMask) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdResetEvent2KHR, VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdResetEvent2KHR");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdResetEvent2KHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdResetEvent2KHR(commandBuffer, event, stageMask, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdResetEvent2KHR);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdResetEvent2KHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdResetEvent2KHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdResetEvent2KHR(commandBuffer, event, stageMask, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdResetEvent2KHR");
        device_dispatch->CmdResetEvent2KHR(commandBuffer, event, stageMask);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdResetEvent2KHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdResetEvent2KHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdResetEvent2KHR(commandBuffer, event, stageMask, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdWaitEvents2KHR(VkCommandBuffer commandBuffer, uint32_t eventCount, const VkEvent* pEvents,
                                             const VkDependencyInfo* pDependencyInfos) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdWaitEvents2KHR, VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdWaitEvents2KHR");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdWaitEvents2KHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdWaitEvents2KHR(commandBuffer, eventCount, pEvents, pDependencyInfos, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdWaitEvents2KHR);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdWaitEvents2KHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdWaitEvents2KHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdWaitEvents2KHR(commandBuffer, eventCount, pEvents, pDependencyInfos, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdWaitEvents2KHR");
        device_dispatch->CmdWaitEvents2KHR(commandBuffer, eventCount, pEvents, pDependencyInfos);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdWaitEvents2KHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdWaitEvents2KHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdWaitEvents2KHR(commandBuffer, eventCount, pEvents, pDependencyInfos, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdPipelineBarrier2KHR(VkCommandBuffer commandBuffer, const VkDependencyInfo* pDependencyInfo) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdPipelineBarrier2KHR, VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdPipelineBarrier2KHR");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdPipelineBarrier2KHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdPipelineBarrier2KHR(commandBuffer, pDependencyInfo, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdPipelineBarrier2KHR);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdPipelineBarrier2KHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdPipelineBarrier2KHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdPipelineBarrier2KHR(commandBuffer, pDependencyInfo, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdPipelineBarrier2KHR");
        device_dispatch->CmdPipelineBarrier2KHR(commandBuffer, pDependencyInfo);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdPipelineBarrier2KHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdPipelineBarrier2KHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdPipelineBarrier2KHR(commandBuffer, pDependencyInfo, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdWriteTimestamp2KHR(VkCommandBuffer commandBuffer, VkPipelineStageFlags2 stage, VkQueryPool queryPool,
                                                 uint32_t query) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdWriteTimestamp2KHR, VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdWriteTimestamp2KHR");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdWriteTimestamp2KHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdWriteTimestamp2KHR(commandBuffer, stage, queryPool, query, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdWriteTimestamp2KHR);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdWriteTimestamp2KHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdWriteTimestamp2KHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdWriteTimestamp2KHR(commandBuffer, stage, queryPool, query, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdWriteTimestamp2KHR");
        device_dispatch->CmdWriteTimestamp2KHR(commandBuffer, stage, queryPool, query);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdWriteTimestamp2KHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdWriteTimestamp2KHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdWriteTimestamp2KHR(commandBuffer, stage, queryPool, query, record_obj);
        }
    }
}

VKAPI_ATTR VkResult VKAPI_CALL QueueSubmit2KHR(VkQueue queue, uint32_t submitCount, const VkSubmitInfo2* pSubmits, VkFence fence) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(queue);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkQueueSubmit2KHR, VulkanTypedHandle(queue, kVulkanObjectTypeQueue));
    {
        VVL_ZoneScopedN("PreCallValidate_vkQueueSubmit2KHR");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateQueueSubmit2KHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateQueueSubmit2KHR(queue, submitCount, pSubmits, fence, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkQueueSubmit2KHR);
    {
        VVL_ZoneScopedN("PreCallRecord_vkQueueSubmit2KHR");
        VVL_TracyVkNamedZoneStart(GetTracyVkCtx(), queue, "gpu_PreCallRecordvkQueueSubmit2KHR", pre_call_record_gpu_zone);

        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordQueueSubmit2KHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordQueueSubmit2KHR(queue, submitCount, pSubmits, fence, record_obj);
        }

        VVL_TracyVkNamedZoneEnd(pre_call_record_gpu_zone, queue);
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkQueueSubmit2KHR");

        VVL_TracyVkNamedZoneStart(GetTracyVkCtx(), queue, "gpu_vkQueueSubmit2KHR", submit_gpu_zone);
        result = device_dispatch->QueueSubmit2KHR(queue, submitCount, pSubmits, fence);

        VVL_TracyVkNamedZoneEnd(submit_gpu_zone, queue);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkQueueSubmit2KHR");

        VVL_TracyVkNamedZoneStart(GetTracyVkCtx(), queue, "gpu_PostCallRecordvkQueueSubmit2KHR", post_call_record_gpu_zone);

        if (result == VK_ERROR_DEVICE_LOST) {
            for (auto& vo : device_dispatch->object_dispatch) {
                vo->is_device_lost = true;
            }
        }
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordQueueSubmit2KHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordQueueSubmit2KHR(queue, submitCount, pSubmits, fence, record_obj);
        }

        VVL_TracyVkNamedZoneEnd(post_call_record_gpu_zone, queue);
    }
#if defined(VVL_TRACY_GPU)
    TracyVkCollector::TrySubmitCollectCb(queue);
#endif
    return result;
}

VKAPI_ATTR void VKAPI_CALL CmdCopyBuffer2KHR(VkCommandBuffer commandBuffer, const VkCopyBufferInfo2* pCopyBufferInfo) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdCopyBuffer2KHR, VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdCopyBuffer2KHR");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdCopyBuffer2KHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdCopyBuffer2KHR(commandBuffer, pCopyBufferInfo, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdCopyBuffer2KHR);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdCopyBuffer2KHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdCopyBuffer2KHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdCopyBuffer2KHR(commandBuffer, pCopyBufferInfo, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdCopyBuffer2KHR");
        device_dispatch->CmdCopyBuffer2KHR(commandBuffer, pCopyBufferInfo);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdCopyBuffer2KHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdCopyBuffer2KHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdCopyBuffer2KHR(commandBuffer, pCopyBufferInfo, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdCopyImage2KHR(VkCommandBuffer commandBuffer, const VkCopyImageInfo2* pCopyImageInfo) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdCopyImage2KHR, VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdCopyImage2KHR");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdCopyImage2KHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdCopyImage2KHR(commandBuffer, pCopyImageInfo, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdCopyImage2KHR);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdCopyImage2KHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdCopyImage2KHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdCopyImage2KHR(commandBuffer, pCopyImageInfo, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdCopyImage2KHR");
        device_dispatch->CmdCopyImage2KHR(commandBuffer, pCopyImageInfo);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdCopyImage2KHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdCopyImage2KHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdCopyImage2KHR(commandBuffer, pCopyImageInfo, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdCopyBufferToImage2KHR(VkCommandBuffer commandBuffer,
                                                    const VkCopyBufferToImageInfo2* pCopyBufferToImageInfo) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdCopyBufferToImage2KHR, VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdCopyBufferToImage2KHR");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdCopyBufferToImage2KHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdCopyBufferToImage2KHR(commandBuffer, pCopyBufferToImageInfo, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdCopyBufferToImage2KHR);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdCopyBufferToImage2KHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdCopyBufferToImage2KHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdCopyBufferToImage2KHR(commandBuffer, pCopyBufferToImageInfo, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdCopyBufferToImage2KHR");
        device_dispatch->CmdCopyBufferToImage2KHR(commandBuffer, pCopyBufferToImageInfo);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdCopyBufferToImage2KHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdCopyBufferToImage2KHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdCopyBufferToImage2KHR(commandBuffer, pCopyBufferToImageInfo, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdCopyImageToBuffer2KHR(VkCommandBuffer commandBuffer,
                                                    const VkCopyImageToBufferInfo2* pCopyImageToBufferInfo) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdCopyImageToBuffer2KHR, VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdCopyImageToBuffer2KHR");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdCopyImageToBuffer2KHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdCopyImageToBuffer2KHR(commandBuffer, pCopyImageToBufferInfo, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdCopyImageToBuffer2KHR);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdCopyImageToBuffer2KHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdCopyImageToBuffer2KHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdCopyImageToBuffer2KHR(commandBuffer, pCopyImageToBufferInfo, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdCopyImageToBuffer2KHR");
        device_dispatch->CmdCopyImageToBuffer2KHR(commandBuffer, pCopyImageToBufferInfo);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdCopyImageToBuffer2KHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdCopyImageToBuffer2KHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdCopyImageToBuffer2KHR(commandBuffer, pCopyImageToBufferInfo, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdBlitImage2KHR(VkCommandBuffer commandBuffer, const VkBlitImageInfo2* pBlitImageInfo) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdBlitImage2KHR, VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdBlitImage2KHR");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdBlitImage2KHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdBlitImage2KHR(commandBuffer, pBlitImageInfo, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdBlitImage2KHR);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdBlitImage2KHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdBlitImage2KHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdBlitImage2KHR(commandBuffer, pBlitImageInfo, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdBlitImage2KHR");
        device_dispatch->CmdBlitImage2KHR(commandBuffer, pBlitImageInfo);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdBlitImage2KHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdBlitImage2KHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdBlitImage2KHR(commandBuffer, pBlitImageInfo, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdResolveImage2KHR(VkCommandBuffer commandBuffer, const VkResolveImageInfo2* pResolveImageInfo) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdResolveImage2KHR, VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdResolveImage2KHR");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdResolveImage2KHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdResolveImage2KHR(commandBuffer, pResolveImageInfo, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdResolveImage2KHR);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdResolveImage2KHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdResolveImage2KHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdResolveImage2KHR(commandBuffer, pResolveImageInfo, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdResolveImage2KHR");
        device_dispatch->CmdResolveImage2KHR(commandBuffer, pResolveImageInfo);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdResolveImage2KHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdResolveImage2KHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdResolveImage2KHR(commandBuffer, pResolveImageInfo, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdTraceRaysIndirect2KHR(VkCommandBuffer commandBuffer, VkDeviceAddress indirectDeviceAddress) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdTraceRaysIndirect2KHR, VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdTraceRaysIndirect2KHR");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdTraceRaysIndirect2KHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdTraceRaysIndirect2KHR(commandBuffer, indirectDeviceAddress, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdTraceRaysIndirect2KHR);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdTraceRaysIndirect2KHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdTraceRaysIndirect2KHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdTraceRaysIndirect2KHR(commandBuffer, indirectDeviceAddress, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdTraceRaysIndirect2KHR");
        device_dispatch->CmdTraceRaysIndirect2KHR(commandBuffer, indirectDeviceAddress);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdTraceRaysIndirect2KHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdTraceRaysIndirect2KHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdTraceRaysIndirect2KHR(commandBuffer, indirectDeviceAddress, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL GetDeviceBufferMemoryRequirementsKHR(VkDevice device, const VkDeviceBufferMemoryRequirements* pInfo,
                                                                VkMemoryRequirements2* pMemoryRequirements) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetDeviceBufferMemoryRequirementsKHR, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetDeviceBufferMemoryRequirementsKHR");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateGetDeviceBufferMemoryRequirementsKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateGetDeviceBufferMemoryRequirementsKHR(device, pInfo, pMemoryRequirements, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetDeviceBufferMemoryRequirementsKHR);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetDeviceBufferMemoryRequirementsKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordGetDeviceBufferMemoryRequirementsKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordGetDeviceBufferMemoryRequirementsKHR(device, pInfo, pMemoryRequirements, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkGetDeviceBufferMemoryRequirementsKHR");
        device_dispatch->GetDeviceBufferMemoryRequirementsKHR(device, pInfo, pMemoryRequirements);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetDeviceBufferMemoryRequirementsKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordGetDeviceBufferMemoryRequirementsKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordGetDeviceBufferMemoryRequirementsKHR(device, pInfo, pMemoryRequirements, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL GetDeviceImageMemoryRequirementsKHR(VkDevice device, const VkDeviceImageMemoryRequirements* pInfo,
                                                               VkMemoryRequirements2* pMemoryRequirements) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetDeviceImageMemoryRequirementsKHR, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetDeviceImageMemoryRequirementsKHR");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateGetDeviceImageMemoryRequirementsKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateGetDeviceImageMemoryRequirementsKHR(device, pInfo, pMemoryRequirements, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetDeviceImageMemoryRequirementsKHR);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetDeviceImageMemoryRequirementsKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordGetDeviceImageMemoryRequirementsKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordGetDeviceImageMemoryRequirementsKHR(device, pInfo, pMemoryRequirements, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkGetDeviceImageMemoryRequirementsKHR");
        device_dispatch->GetDeviceImageMemoryRequirementsKHR(device, pInfo, pMemoryRequirements);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetDeviceImageMemoryRequirementsKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordGetDeviceImageMemoryRequirementsKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordGetDeviceImageMemoryRequirementsKHR(device, pInfo, pMemoryRequirements, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL GetDeviceImageSparseMemoryRequirementsKHR(VkDevice device, const VkDeviceImageMemoryRequirements* pInfo,
                                                                     uint32_t* pSparseMemoryRequirementCount,
                                                                     VkSparseImageMemoryRequirements2* pSparseMemoryRequirements) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetDeviceImageSparseMemoryRequirementsKHR,
                          VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetDeviceImageSparseMemoryRequirementsKHR");
        for (const auto& vo :
             device_dispatch->intercept_vectors[InterceptIdPreCallValidateGetDeviceImageSparseMemoryRequirementsKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateGetDeviceImageSparseMemoryRequirementsKHR(device, pInfo, pSparseMemoryRequirementCount,
                                                                                 pSparseMemoryRequirements, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetDeviceImageSparseMemoryRequirementsKHR);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetDeviceImageSparseMemoryRequirementsKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordGetDeviceImageSparseMemoryRequirementsKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordGetDeviceImageSparseMemoryRequirementsKHR(device, pInfo, pSparseMemoryRequirementCount,
                                                                       pSparseMemoryRequirements, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkGetDeviceImageSparseMemoryRequirementsKHR");
        device_dispatch->GetDeviceImageSparseMemoryRequirementsKHR(device, pInfo, pSparseMemoryRequirementCount,
                                                                   pSparseMemoryRequirements);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetDeviceImageSparseMemoryRequirementsKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordGetDeviceImageSparseMemoryRequirementsKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordGetDeviceImageSparseMemoryRequirementsKHR(device, pInfo, pSparseMemoryRequirementCount,
                                                                        pSparseMemoryRequirements, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdBindIndexBuffer2KHR(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
                                                  VkDeviceSize size, VkIndexType indexType) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdBindIndexBuffer2KHR, VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdBindIndexBuffer2KHR");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdBindIndexBuffer2KHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdBindIndexBuffer2KHR(commandBuffer, buffer, offset, size, indexType, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdBindIndexBuffer2KHR);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdBindIndexBuffer2KHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdBindIndexBuffer2KHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdBindIndexBuffer2KHR(commandBuffer, buffer, offset, size, indexType, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdBindIndexBuffer2KHR");
        device_dispatch->CmdBindIndexBuffer2KHR(commandBuffer, buffer, offset, size, indexType);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdBindIndexBuffer2KHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdBindIndexBuffer2KHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdBindIndexBuffer2KHR(commandBuffer, buffer, offset, size, indexType, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL GetRenderingAreaGranularityKHR(VkDevice device, const VkRenderingAreaInfo* pRenderingAreaInfo,
                                                          VkExtent2D* pGranularity) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetRenderingAreaGranularityKHR, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetRenderingAreaGranularityKHR");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateGetRenderingAreaGranularityKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateGetRenderingAreaGranularityKHR(device, pRenderingAreaInfo, pGranularity, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetRenderingAreaGranularityKHR);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetRenderingAreaGranularityKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordGetRenderingAreaGranularityKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordGetRenderingAreaGranularityKHR(device, pRenderingAreaInfo, pGranularity, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkGetRenderingAreaGranularityKHR");
        device_dispatch->GetRenderingAreaGranularityKHR(device, pRenderingAreaInfo, pGranularity);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetRenderingAreaGranularityKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordGetRenderingAreaGranularityKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordGetRenderingAreaGranularityKHR(device, pRenderingAreaInfo, pGranularity, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL GetDeviceImageSubresourceLayoutKHR(VkDevice device, const VkDeviceImageSubresourceInfo* pInfo,
                                                              VkSubresourceLayout2* pLayout) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetDeviceImageSubresourceLayoutKHR, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetDeviceImageSubresourceLayoutKHR");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateGetDeviceImageSubresourceLayoutKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateGetDeviceImageSubresourceLayoutKHR(device, pInfo, pLayout, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetDeviceImageSubresourceLayoutKHR);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetDeviceImageSubresourceLayoutKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordGetDeviceImageSubresourceLayoutKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordGetDeviceImageSubresourceLayoutKHR(device, pInfo, pLayout, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkGetDeviceImageSubresourceLayoutKHR");
        device_dispatch->GetDeviceImageSubresourceLayoutKHR(device, pInfo, pLayout);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetDeviceImageSubresourceLayoutKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordGetDeviceImageSubresourceLayoutKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordGetDeviceImageSubresourceLayoutKHR(device, pInfo, pLayout, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL GetImageSubresourceLayout2KHR(VkDevice device, VkImage image, const VkImageSubresource2* pSubresource,
                                                         VkSubresourceLayout2* pLayout) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetImageSubresourceLayout2KHR, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetImageSubresourceLayout2KHR");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateGetImageSubresourceLayout2KHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateGetImageSubresourceLayout2KHR(device, image, pSubresource, pLayout, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetImageSubresourceLayout2KHR);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetImageSubresourceLayout2KHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordGetImageSubresourceLayout2KHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordGetImageSubresourceLayout2KHR(device, image, pSubresource, pLayout, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkGetImageSubresourceLayout2KHR");
        device_dispatch->GetImageSubresourceLayout2KHR(device, image, pSubresource, pLayout);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetImageSubresourceLayout2KHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordGetImageSubresourceLayout2KHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordGetImageSubresourceLayout2KHR(device, image, pSubresource, pLayout, record_obj);
        }
    }
}

VKAPI_ATTR VkResult VKAPI_CALL WaitForPresent2KHR(VkDevice device, VkSwapchainKHR swapchain,
                                                  const VkPresentWait2InfoKHR* pPresentWait2Info) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkWaitForPresent2KHR, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkWaitForPresent2KHR");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateWaitForPresent2KHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateWaitForPresent2KHR(device, swapchain, pPresentWait2Info, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkWaitForPresent2KHR);
    {
        VVL_ZoneScopedN("PreCallRecord_vkWaitForPresent2KHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordWaitForPresent2KHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordWaitForPresent2KHR(device, swapchain, pPresentWait2Info, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkWaitForPresent2KHR");
        result = device_dispatch->WaitForPresent2KHR(device, swapchain, pPresentWait2Info);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkWaitForPresent2KHR");

        if (result == VK_ERROR_DEVICE_LOST) {
            for (auto& vo : device_dispatch->object_dispatch) {
                vo->is_device_lost = true;
            }
        }
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordWaitForPresent2KHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordWaitForPresent2KHR(device, swapchain, pPresentWait2Info, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR VkResult VKAPI_CALL CreatePipelineBinariesKHR(VkDevice device, const VkPipelineBinaryCreateInfoKHR* pCreateInfo,
                                                         const VkAllocationCallbacks* pAllocator,
                                                         VkPipelineBinaryHandlesInfoKHR* pBinaries) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCreatePipelineBinariesKHR, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCreatePipelineBinariesKHR");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCreatePipelineBinariesKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCreatePipelineBinariesKHR(device, pCreateInfo, pAllocator, pBinaries, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkCreatePipelineBinariesKHR);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCreatePipelineBinariesKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCreatePipelineBinariesKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCreatePipelineBinariesKHR(device, pCreateInfo, pAllocator, pBinaries, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkCreatePipelineBinariesKHR");
        result = device_dispatch->CreatePipelineBinariesKHR(device, pCreateInfo, pAllocator, pBinaries);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkCreatePipelineBinariesKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCreatePipelineBinariesKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCreatePipelineBinariesKHR(device, pCreateInfo, pAllocator, pBinaries, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR void VKAPI_CALL DestroyPipelineBinaryKHR(VkDevice device, VkPipelineBinaryKHR pipelineBinary,
                                                    const VkAllocationCallbacks* pAllocator) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkDestroyPipelineBinaryKHR, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkDestroyPipelineBinaryKHR");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateDestroyPipelineBinaryKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateDestroyPipelineBinaryKHR(device, pipelineBinary, pAllocator, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkDestroyPipelineBinaryKHR);
    {
        VVL_ZoneScopedN("PreCallRecord_vkDestroyPipelineBinaryKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordDestroyPipelineBinaryKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordDestroyPipelineBinaryKHR(device, pipelineBinary, pAllocator, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkDestroyPipelineBinaryKHR");
        device_dispatch->DestroyPipelineBinaryKHR(device, pipelineBinary, pAllocator);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkDestroyPipelineBinaryKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordDestroyPipelineBinaryKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordDestroyPipelineBinaryKHR(device, pipelineBinary, pAllocator, record_obj);
        }
    }
}

VKAPI_ATTR VkResult VKAPI_CALL GetPipelineKeyKHR(VkDevice device, const VkPipelineCreateInfoKHR* pPipelineCreateInfo,
                                                 VkPipelineBinaryKeyKHR* pPipelineKey) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetPipelineKeyKHR, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetPipelineKeyKHR");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateGetPipelineKeyKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateGetPipelineKeyKHR(device, pPipelineCreateInfo, pPipelineKey, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetPipelineKeyKHR);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetPipelineKeyKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordGetPipelineKeyKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordGetPipelineKeyKHR(device, pPipelineCreateInfo, pPipelineKey, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkGetPipelineKeyKHR");
        result = device_dispatch->GetPipelineKeyKHR(device, pPipelineCreateInfo, pPipelineKey);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetPipelineKeyKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordGetPipelineKeyKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordGetPipelineKeyKHR(device, pPipelineCreateInfo, pPipelineKey, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR VkResult VKAPI_CALL GetPipelineBinaryDataKHR(VkDevice device, const VkPipelineBinaryDataInfoKHR* pInfo,
                                                        VkPipelineBinaryKeyKHR* pPipelineBinaryKey, size_t* pPipelineBinaryDataSize,
                                                        void* pPipelineBinaryData) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetPipelineBinaryDataKHR, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetPipelineBinaryDataKHR");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateGetPipelineBinaryDataKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateGetPipelineBinaryDataKHR(device, pInfo, pPipelineBinaryKey, pPipelineBinaryDataSize,
                                                                pPipelineBinaryData, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetPipelineBinaryDataKHR);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetPipelineBinaryDataKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordGetPipelineBinaryDataKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordGetPipelineBinaryDataKHR(device, pInfo, pPipelineBinaryKey, pPipelineBinaryDataSize,
                                                      pPipelineBinaryData, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkGetPipelineBinaryDataKHR");
        result = device_dispatch->GetPipelineBinaryDataKHR(device, pInfo, pPipelineBinaryKey, pPipelineBinaryDataSize,
                                                           pPipelineBinaryData);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetPipelineBinaryDataKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordGetPipelineBinaryDataKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordGetPipelineBinaryDataKHR(device, pInfo, pPipelineBinaryKey, pPipelineBinaryDataSize,
                                                       pPipelineBinaryData, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR VkResult VKAPI_CALL ReleaseCapturedPipelineDataKHR(VkDevice device, const VkReleaseCapturedPipelineDataInfoKHR* pInfo,
                                                              const VkAllocationCallbacks* pAllocator) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkReleaseCapturedPipelineDataKHR, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkReleaseCapturedPipelineDataKHR");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateReleaseCapturedPipelineDataKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateReleaseCapturedPipelineDataKHR(device, pInfo, pAllocator, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkReleaseCapturedPipelineDataKHR);
    {
        VVL_ZoneScopedN("PreCallRecord_vkReleaseCapturedPipelineDataKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordReleaseCapturedPipelineDataKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordReleaseCapturedPipelineDataKHR(device, pInfo, pAllocator, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkReleaseCapturedPipelineDataKHR");
        result = device_dispatch->ReleaseCapturedPipelineDataKHR(device, pInfo, pAllocator);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkReleaseCapturedPipelineDataKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordReleaseCapturedPipelineDataKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordReleaseCapturedPipelineDataKHR(device, pInfo, pAllocator, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR VkResult VKAPI_CALL ReleaseSwapchainImagesKHR(VkDevice device, const VkReleaseSwapchainImagesInfoKHR* pReleaseInfo) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkReleaseSwapchainImagesKHR, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkReleaseSwapchainImagesKHR");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateReleaseSwapchainImagesKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateReleaseSwapchainImagesKHR(device, pReleaseInfo, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkReleaseSwapchainImagesKHR);
    {
        VVL_ZoneScopedN("PreCallRecord_vkReleaseSwapchainImagesKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordReleaseSwapchainImagesKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordReleaseSwapchainImagesKHR(device, pReleaseInfo, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkReleaseSwapchainImagesKHR");
        result = device_dispatch->ReleaseSwapchainImagesKHR(device, pReleaseInfo);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkReleaseSwapchainImagesKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordReleaseSwapchainImagesKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordReleaseSwapchainImagesKHR(device, pReleaseInfo, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR VkResult VKAPI_CALL GetPhysicalDeviceCooperativeMatrixPropertiesKHR(VkPhysicalDevice physicalDevice,
                                                                               uint32_t* pPropertyCount,
                                                                               VkCooperativeMatrixPropertiesKHR* pProperties) {
    VVL_ZoneScoped;

    auto instance_dispatch = vvl::dispatch::GetData(physicalDevice);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetPhysicalDeviceCooperativeMatrixPropertiesKHR,
                          VulkanTypedHandle(physicalDevice, kVulkanObjectTypePhysicalDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetPhysicalDeviceCooperativeMatrixPropertiesKHR");
        for (const auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            skip |= vo->PreCallValidateGetPhysicalDeviceCooperativeMatrixPropertiesKHR(physicalDevice, pPropertyCount, pProperties,
                                                                                       error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetPhysicalDeviceCooperativeMatrixPropertiesKHR);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetPhysicalDeviceCooperativeMatrixPropertiesKHR");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PreCallRecordGetPhysicalDeviceCooperativeMatrixPropertiesKHR(physicalDevice, pPropertyCount, pProperties,
                                                                             record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkGetPhysicalDeviceCooperativeMatrixPropertiesKHR");
        result = instance_dispatch->GetPhysicalDeviceCooperativeMatrixPropertiesKHR(physicalDevice, pPropertyCount, pProperties);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetPhysicalDeviceCooperativeMatrixPropertiesKHR");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PostCallRecordGetPhysicalDeviceCooperativeMatrixPropertiesKHR(physicalDevice, pPropertyCount, pProperties,
                                                                              record_obj);
        }
    }
    return result;
}

VKAPI_ATTR void VKAPI_CALL CmdSetLineStippleKHR(VkCommandBuffer commandBuffer, uint32_t lineStippleFactor,
                                                uint16_t lineStipplePattern) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdSetLineStippleKHR, VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdSetLineStippleKHR");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdSetLineStippleKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdSetLineStippleKHR(commandBuffer, lineStippleFactor, lineStipplePattern, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdSetLineStippleKHR);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdSetLineStippleKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdSetLineStippleKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdSetLineStippleKHR(commandBuffer, lineStippleFactor, lineStipplePattern, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdSetLineStippleKHR");
        device_dispatch->CmdSetLineStippleKHR(commandBuffer, lineStippleFactor, lineStipplePattern);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdSetLineStippleKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdSetLineStippleKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdSetLineStippleKHR(commandBuffer, lineStippleFactor, lineStipplePattern, record_obj);
        }
    }
}

VKAPI_ATTR VkResult VKAPI_CALL GetPhysicalDeviceCalibrateableTimeDomainsKHR(VkPhysicalDevice physicalDevice,
                                                                            uint32_t* pTimeDomainCount,
                                                                            VkTimeDomainKHR* pTimeDomains) {
    VVL_ZoneScoped;

    auto instance_dispatch = vvl::dispatch::GetData(physicalDevice);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetPhysicalDeviceCalibrateableTimeDomainsKHR,
                          VulkanTypedHandle(physicalDevice, kVulkanObjectTypePhysicalDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetPhysicalDeviceCalibrateableTimeDomainsKHR");
        for (const auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            skip |= vo->PreCallValidateGetPhysicalDeviceCalibrateableTimeDomainsKHR(physicalDevice, pTimeDomainCount, pTimeDomains,
                                                                                    error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetPhysicalDeviceCalibrateableTimeDomainsKHR);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetPhysicalDeviceCalibrateableTimeDomainsKHR");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PreCallRecordGetPhysicalDeviceCalibrateableTimeDomainsKHR(physicalDevice, pTimeDomainCount, pTimeDomains,
                                                                          record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkGetPhysicalDeviceCalibrateableTimeDomainsKHR");
        result = instance_dispatch->GetPhysicalDeviceCalibrateableTimeDomainsKHR(physicalDevice, pTimeDomainCount, pTimeDomains);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetPhysicalDeviceCalibrateableTimeDomainsKHR");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PostCallRecordGetPhysicalDeviceCalibrateableTimeDomainsKHR(physicalDevice, pTimeDomainCount, pTimeDomains,
                                                                           record_obj);
        }
    }
    return result;
}

VKAPI_ATTR VkResult VKAPI_CALL GetCalibratedTimestampsKHR(VkDevice device, uint32_t timestampCount,
                                                          const VkCalibratedTimestampInfoKHR* pTimestampInfos,
                                                          uint64_t* pTimestamps, uint64_t* pMaxDeviation) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetCalibratedTimestampsKHR, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetCalibratedTimestampsKHR");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateGetCalibratedTimestampsKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateGetCalibratedTimestampsKHR(device, timestampCount, pTimestampInfos, pTimestamps,
                                                                  pMaxDeviation, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetCalibratedTimestampsKHR);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetCalibratedTimestampsKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordGetCalibratedTimestampsKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordGetCalibratedTimestampsKHR(device, timestampCount, pTimestampInfos, pTimestamps, pMaxDeviation,
                                                        record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkGetCalibratedTimestampsKHR");
        result = device_dispatch->GetCalibratedTimestampsKHR(device, timestampCount, pTimestampInfos, pTimestamps, pMaxDeviation);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetCalibratedTimestampsKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordGetCalibratedTimestampsKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordGetCalibratedTimestampsKHR(device, timestampCount, pTimestampInfos, pTimestamps, pMaxDeviation,
                                                         record_obj);
        }
    }
    return result;
}

VKAPI_ATTR void VKAPI_CALL CmdBindDescriptorSets2KHR(VkCommandBuffer commandBuffer,
                                                     const VkBindDescriptorSetsInfo* pBindDescriptorSetsInfo) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdBindDescriptorSets2KHR, VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdBindDescriptorSets2KHR");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdBindDescriptorSets2KHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdBindDescriptorSets2KHR(commandBuffer, pBindDescriptorSetsInfo, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdBindDescriptorSets2KHR);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdBindDescriptorSets2KHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdBindDescriptorSets2KHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdBindDescriptorSets2KHR(commandBuffer, pBindDescriptorSetsInfo, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdBindDescriptorSets2KHR");
        device_dispatch->CmdBindDescriptorSets2KHR(commandBuffer, pBindDescriptorSetsInfo);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdBindDescriptorSets2KHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdBindDescriptorSets2KHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdBindDescriptorSets2KHR(commandBuffer, pBindDescriptorSetsInfo, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdPushConstants2KHR(VkCommandBuffer commandBuffer, const VkPushConstantsInfo* pPushConstantsInfo) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdPushConstants2KHR, VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdPushConstants2KHR");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdPushConstants2KHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdPushConstants2KHR(commandBuffer, pPushConstantsInfo, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdPushConstants2KHR);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdPushConstants2KHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdPushConstants2KHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdPushConstants2KHR(commandBuffer, pPushConstantsInfo, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdPushConstants2KHR");
        device_dispatch->CmdPushConstants2KHR(commandBuffer, pPushConstantsInfo);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdPushConstants2KHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdPushConstants2KHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdPushConstants2KHR(commandBuffer, pPushConstantsInfo, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdPushDescriptorSet2KHR(VkCommandBuffer commandBuffer,
                                                    const VkPushDescriptorSetInfo* pPushDescriptorSetInfo) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdPushDescriptorSet2KHR, VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdPushDescriptorSet2KHR");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdPushDescriptorSet2KHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdPushDescriptorSet2KHR(commandBuffer, pPushDescriptorSetInfo, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdPushDescriptorSet2KHR);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdPushDescriptorSet2KHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdPushDescriptorSet2KHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdPushDescriptorSet2KHR(commandBuffer, pPushDescriptorSetInfo, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdPushDescriptorSet2KHR");
        device_dispatch->CmdPushDescriptorSet2KHR(commandBuffer, pPushDescriptorSetInfo);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdPushDescriptorSet2KHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdPushDescriptorSet2KHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdPushDescriptorSet2KHR(commandBuffer, pPushDescriptorSetInfo, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdPushDescriptorSetWithTemplate2KHR(
    VkCommandBuffer commandBuffer, const VkPushDescriptorSetWithTemplateInfo* pPushDescriptorSetWithTemplateInfo) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdPushDescriptorSetWithTemplate2KHR,
                          VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdPushDescriptorSetWithTemplate2KHR");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdPushDescriptorSetWithTemplate2KHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdPushDescriptorSetWithTemplate2KHR(commandBuffer, pPushDescriptorSetWithTemplateInfo,
                                                                            error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdPushDescriptorSetWithTemplate2KHR);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdPushDescriptorSetWithTemplate2KHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdPushDescriptorSetWithTemplate2KHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdPushDescriptorSetWithTemplate2KHR(commandBuffer, pPushDescriptorSetWithTemplateInfo, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdPushDescriptorSetWithTemplate2KHR");
        device_dispatch->CmdPushDescriptorSetWithTemplate2KHR(commandBuffer, pPushDescriptorSetWithTemplateInfo);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdPushDescriptorSetWithTemplate2KHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdPushDescriptorSetWithTemplate2KHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdPushDescriptorSetWithTemplate2KHR(commandBuffer, pPushDescriptorSetWithTemplateInfo, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdSetDescriptorBufferOffsets2EXT(
    VkCommandBuffer commandBuffer, const VkSetDescriptorBufferOffsetsInfoEXT* pSetDescriptorBufferOffsetsInfo) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdSetDescriptorBufferOffsets2EXT,
                          VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdSetDescriptorBufferOffsets2EXT");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdSetDescriptorBufferOffsets2EXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdSetDescriptorBufferOffsets2EXT(commandBuffer, pSetDescriptorBufferOffsetsInfo, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdSetDescriptorBufferOffsets2EXT);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdSetDescriptorBufferOffsets2EXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdSetDescriptorBufferOffsets2EXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdSetDescriptorBufferOffsets2EXT(commandBuffer, pSetDescriptorBufferOffsetsInfo, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdSetDescriptorBufferOffsets2EXT");
        device_dispatch->CmdSetDescriptorBufferOffsets2EXT(commandBuffer, pSetDescriptorBufferOffsetsInfo);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdSetDescriptorBufferOffsets2EXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdSetDescriptorBufferOffsets2EXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdSetDescriptorBufferOffsets2EXT(commandBuffer, pSetDescriptorBufferOffsetsInfo, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdBindDescriptorBufferEmbeddedSamplers2EXT(
    VkCommandBuffer commandBuffer, const VkBindDescriptorBufferEmbeddedSamplersInfoEXT* pBindDescriptorBufferEmbeddedSamplersInfo) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdBindDescriptorBufferEmbeddedSamplers2EXT,
                          VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdBindDescriptorBufferEmbeddedSamplers2EXT");
        for (const auto& vo :
             device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdBindDescriptorBufferEmbeddedSamplers2EXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdBindDescriptorBufferEmbeddedSamplers2EXT(
                commandBuffer, pBindDescriptorBufferEmbeddedSamplersInfo, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdBindDescriptorBufferEmbeddedSamplers2EXT);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdBindDescriptorBufferEmbeddedSamplers2EXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdBindDescriptorBufferEmbeddedSamplers2EXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdBindDescriptorBufferEmbeddedSamplers2EXT(commandBuffer, pBindDescriptorBufferEmbeddedSamplersInfo,
                                                                         record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdBindDescriptorBufferEmbeddedSamplers2EXT");
        device_dispatch->CmdBindDescriptorBufferEmbeddedSamplers2EXT(commandBuffer, pBindDescriptorBufferEmbeddedSamplersInfo);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdBindDescriptorBufferEmbeddedSamplers2EXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdBindDescriptorBufferEmbeddedSamplers2EXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdBindDescriptorBufferEmbeddedSamplers2EXT(commandBuffer, pBindDescriptorBufferEmbeddedSamplersInfo,
                                                                          record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdCopyMemoryIndirectKHR(VkCommandBuffer commandBuffer,
                                                    const VkCopyMemoryIndirectInfoKHR* pCopyMemoryIndirectInfo) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdCopyMemoryIndirectKHR, VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdCopyMemoryIndirectKHR");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdCopyMemoryIndirectKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdCopyMemoryIndirectKHR(commandBuffer, pCopyMemoryIndirectInfo, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdCopyMemoryIndirectKHR);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdCopyMemoryIndirectKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdCopyMemoryIndirectKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdCopyMemoryIndirectKHR(commandBuffer, pCopyMemoryIndirectInfo, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdCopyMemoryIndirectKHR");
        device_dispatch->CmdCopyMemoryIndirectKHR(commandBuffer, pCopyMemoryIndirectInfo);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdCopyMemoryIndirectKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdCopyMemoryIndirectKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdCopyMemoryIndirectKHR(commandBuffer, pCopyMemoryIndirectInfo, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdCopyMemoryToImageIndirectKHR(
    VkCommandBuffer commandBuffer, const VkCopyMemoryToImageIndirectInfoKHR* pCopyMemoryToImageIndirectInfo) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdCopyMemoryToImageIndirectKHR,
                          VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdCopyMemoryToImageIndirectKHR");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdCopyMemoryToImageIndirectKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdCopyMemoryToImageIndirectKHR(commandBuffer, pCopyMemoryToImageIndirectInfo, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdCopyMemoryToImageIndirectKHR);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdCopyMemoryToImageIndirectKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdCopyMemoryToImageIndirectKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdCopyMemoryToImageIndirectKHR(commandBuffer, pCopyMemoryToImageIndirectInfo, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdCopyMemoryToImageIndirectKHR");
        device_dispatch->CmdCopyMemoryToImageIndirectKHR(commandBuffer, pCopyMemoryToImageIndirectInfo);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdCopyMemoryToImageIndirectKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdCopyMemoryToImageIndirectKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdCopyMemoryToImageIndirectKHR(commandBuffer, pCopyMemoryToImageIndirectInfo, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdEndRendering2KHR(VkCommandBuffer commandBuffer, const VkRenderingEndInfoKHR* pRenderingEndInfo) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdEndRendering2KHR, VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdEndRendering2KHR");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdEndRendering2KHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdEndRendering2KHR(commandBuffer, pRenderingEndInfo, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdEndRendering2KHR);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdEndRendering2KHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdEndRendering2KHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdEndRendering2KHR(commandBuffer, pRenderingEndInfo, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdEndRendering2KHR");
        device_dispatch->CmdEndRendering2KHR(commandBuffer, pRenderingEndInfo);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdEndRendering2KHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdEndRendering2KHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdEndRendering2KHR(commandBuffer, pRenderingEndInfo, record_obj);
        }
    }
}

VKAPI_ATTR VkResult VKAPI_CALL CreateDebugReportCallbackEXT(VkInstance instance,
                                                            const VkDebugReportCallbackCreateInfoEXT* pCreateInfo,
                                                            const VkAllocationCallbacks* pAllocator,
                                                            VkDebugReportCallbackEXT* pCallback) {
    VVL_ZoneScoped;

    auto instance_dispatch = vvl::dispatch::GetData(instance);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCreateDebugReportCallbackEXT, VulkanTypedHandle(instance, kVulkanObjectTypeInstance));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCreateDebugReportCallbackEXT");
        for (const auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            skip |= vo->PreCallValidateCreateDebugReportCallbackEXT(instance, pCreateInfo, pAllocator, pCallback, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkCreateDebugReportCallbackEXT);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCreateDebugReportCallbackEXT");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PreCallRecordCreateDebugReportCallbackEXT(instance, pCreateInfo, pAllocator, pCallback, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkCreateDebugReportCallbackEXT");
        result = instance_dispatch->CreateDebugReportCallbackEXT(instance, pCreateInfo, pAllocator, pCallback);
    }
    LayerCreateReportCallback(instance_dispatch->debug_report, false, pCreateInfo, pCallback);
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkCreateDebugReportCallbackEXT");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PostCallRecordCreateDebugReportCallbackEXT(instance, pCreateInfo, pAllocator, pCallback, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR void VKAPI_CALL DestroyDebugReportCallbackEXT(VkInstance instance, VkDebugReportCallbackEXT callback,
                                                         const VkAllocationCallbacks* pAllocator) {
    VVL_ZoneScoped;

    auto instance_dispatch = vvl::dispatch::GetData(instance);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkDestroyDebugReportCallbackEXT, VulkanTypedHandle(instance, kVulkanObjectTypeInstance));
    {
        VVL_ZoneScopedN("PreCallValidate_vkDestroyDebugReportCallbackEXT");
        for (const auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            skip |= vo->PreCallValidateDestroyDebugReportCallbackEXT(instance, callback, pAllocator, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkDestroyDebugReportCallbackEXT);
    {
        VVL_ZoneScopedN("PreCallRecord_vkDestroyDebugReportCallbackEXT");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PreCallRecordDestroyDebugReportCallbackEXT(instance, callback, pAllocator, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkDestroyDebugReportCallbackEXT");
        instance_dispatch->DestroyDebugReportCallbackEXT(instance, callback, pAllocator);
    }
    LayerDestroyCallback(instance_dispatch->debug_report, callback);
    {
        VVL_ZoneScopedN("PostCallRecord_vkDestroyDebugReportCallbackEXT");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PostCallRecordDestroyDebugReportCallbackEXT(instance, callback, pAllocator, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL DebugReportMessageEXT(VkInstance instance, VkDebugReportFlagsEXT flags,
                                                 VkDebugReportObjectTypeEXT objectType, uint64_t object, size_t location,
                                                 int32_t messageCode, const char* pLayerPrefix, const char* pMessage) {
    VVL_ZoneScoped;

    auto instance_dispatch = vvl::dispatch::GetData(instance);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkDebugReportMessageEXT, VulkanTypedHandle(instance, kVulkanObjectTypeInstance));
    {
        VVL_ZoneScopedN("PreCallValidate_vkDebugReportMessageEXT");
        for (const auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            skip |= vo->PreCallValidateDebugReportMessageEXT(instance, flags, objectType, object, location, messageCode,
                                                             pLayerPrefix, pMessage, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkDebugReportMessageEXT);
    {
        VVL_ZoneScopedN("PreCallRecord_vkDebugReportMessageEXT");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PreCallRecordDebugReportMessageEXT(instance, flags, objectType, object, location, messageCode, pLayerPrefix,
                                                   pMessage, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkDebugReportMessageEXT");
        instance_dispatch->DebugReportMessageEXT(instance, flags, objectType, object, location, messageCode, pLayerPrefix,
                                                 pMessage);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkDebugReportMessageEXT");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PostCallRecordDebugReportMessageEXT(instance, flags, objectType, object, location, messageCode, pLayerPrefix,
                                                    pMessage, record_obj);
        }
    }
}

VKAPI_ATTR VkResult VKAPI_CALL DebugMarkerSetObjectTagEXT(VkDevice device, const VkDebugMarkerObjectTagInfoEXT* pTagInfo) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkDebugMarkerSetObjectTagEXT, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkDebugMarkerSetObjectTagEXT");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateDebugMarkerSetObjectTagEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateDebugMarkerSetObjectTagEXT(device, pTagInfo, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkDebugMarkerSetObjectTagEXT);
    {
        VVL_ZoneScopedN("PreCallRecord_vkDebugMarkerSetObjectTagEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordDebugMarkerSetObjectTagEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordDebugMarkerSetObjectTagEXT(device, pTagInfo, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkDebugMarkerSetObjectTagEXT");
        result = device_dispatch->DebugMarkerSetObjectTagEXT(device, pTagInfo);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkDebugMarkerSetObjectTagEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordDebugMarkerSetObjectTagEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordDebugMarkerSetObjectTagEXT(device, pTagInfo, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR VkResult VKAPI_CALL DebugMarkerSetObjectNameEXT(VkDevice device, const VkDebugMarkerObjectNameInfoEXT* pNameInfo) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkDebugMarkerSetObjectNameEXT, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkDebugMarkerSetObjectNameEXT");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateDebugMarkerSetObjectNameEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateDebugMarkerSetObjectNameEXT(device, pNameInfo, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkDebugMarkerSetObjectNameEXT);
    {
        VVL_ZoneScopedN("PreCallRecord_vkDebugMarkerSetObjectNameEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordDebugMarkerSetObjectNameEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordDebugMarkerSetObjectNameEXT(device, pNameInfo, record_obj);
        }
    }
    device_dispatch->debug_report->SetMarkerObjectName(pNameInfo);
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkDebugMarkerSetObjectNameEXT");
        result = device_dispatch->DebugMarkerSetObjectNameEXT(device, pNameInfo);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkDebugMarkerSetObjectNameEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordDebugMarkerSetObjectNameEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordDebugMarkerSetObjectNameEXT(device, pNameInfo, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR void VKAPI_CALL CmdDebugMarkerBeginEXT(VkCommandBuffer commandBuffer, const VkDebugMarkerMarkerInfoEXT* pMarkerInfo) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdDebugMarkerBeginEXT, VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdDebugMarkerBeginEXT");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdDebugMarkerBeginEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdDebugMarkerBeginEXT(commandBuffer, pMarkerInfo, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdDebugMarkerBeginEXT);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdDebugMarkerBeginEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdDebugMarkerBeginEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdDebugMarkerBeginEXT(commandBuffer, pMarkerInfo, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdDebugMarkerBeginEXT");
        device_dispatch->CmdDebugMarkerBeginEXT(commandBuffer, pMarkerInfo);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdDebugMarkerBeginEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdDebugMarkerBeginEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdDebugMarkerBeginEXT(commandBuffer, pMarkerInfo, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdDebugMarkerEndEXT(VkCommandBuffer commandBuffer) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdDebugMarkerEndEXT, VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdDebugMarkerEndEXT");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdDebugMarkerEndEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdDebugMarkerEndEXT(commandBuffer, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdDebugMarkerEndEXT);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdDebugMarkerEndEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdDebugMarkerEndEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdDebugMarkerEndEXT(commandBuffer, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdDebugMarkerEndEXT");
        device_dispatch->CmdDebugMarkerEndEXT(commandBuffer);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdDebugMarkerEndEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdDebugMarkerEndEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdDebugMarkerEndEXT(commandBuffer, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdDebugMarkerInsertEXT(VkCommandBuffer commandBuffer, const VkDebugMarkerMarkerInfoEXT* pMarkerInfo) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdDebugMarkerInsertEXT, VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdDebugMarkerInsertEXT");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdDebugMarkerInsertEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdDebugMarkerInsertEXT(commandBuffer, pMarkerInfo, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdDebugMarkerInsertEXT);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdDebugMarkerInsertEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdDebugMarkerInsertEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdDebugMarkerInsertEXT(commandBuffer, pMarkerInfo, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdDebugMarkerInsertEXT");
        device_dispatch->CmdDebugMarkerInsertEXT(commandBuffer, pMarkerInfo);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdDebugMarkerInsertEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdDebugMarkerInsertEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdDebugMarkerInsertEXT(commandBuffer, pMarkerInfo, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdBindTransformFeedbackBuffersEXT(VkCommandBuffer commandBuffer, uint32_t firstBinding,
                                                              uint32_t bindingCount, const VkBuffer* pBuffers,
                                                              const VkDeviceSize* pOffsets, const VkDeviceSize* pSizes) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdBindTransformFeedbackBuffersEXT,
                          VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdBindTransformFeedbackBuffersEXT");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdBindTransformFeedbackBuffersEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdBindTransformFeedbackBuffersEXT(commandBuffer, firstBinding, bindingCount, pBuffers,
                                                                          pOffsets, pSizes, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdBindTransformFeedbackBuffersEXT);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdBindTransformFeedbackBuffersEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdBindTransformFeedbackBuffersEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdBindTransformFeedbackBuffersEXT(commandBuffer, firstBinding, bindingCount, pBuffers, pOffsets,
                                                                pSizes, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdBindTransformFeedbackBuffersEXT");
        device_dispatch->CmdBindTransformFeedbackBuffersEXT(commandBuffer, firstBinding, bindingCount, pBuffers, pOffsets, pSizes);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdBindTransformFeedbackBuffersEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdBindTransformFeedbackBuffersEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdBindTransformFeedbackBuffersEXT(commandBuffer, firstBinding, bindingCount, pBuffers, pOffsets,
                                                                 pSizes, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdBeginTransformFeedbackEXT(VkCommandBuffer commandBuffer, uint32_t firstCounterBuffer,
                                                        uint32_t counterBufferCount, const VkBuffer* pCounterBuffers,
                                                        const VkDeviceSize* pCounterBufferOffsets) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdBeginTransformFeedbackEXT,
                          VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdBeginTransformFeedbackEXT");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdBeginTransformFeedbackEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdBeginTransformFeedbackEXT(commandBuffer, firstCounterBuffer, counterBufferCount,
                                                                    pCounterBuffers, pCounterBufferOffsets, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdBeginTransformFeedbackEXT);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdBeginTransformFeedbackEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdBeginTransformFeedbackEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdBeginTransformFeedbackEXT(commandBuffer, firstCounterBuffer, counterBufferCount, pCounterBuffers,
                                                          pCounterBufferOffsets, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdBeginTransformFeedbackEXT");
        device_dispatch->CmdBeginTransformFeedbackEXT(commandBuffer, firstCounterBuffer, counterBufferCount, pCounterBuffers,
                                                      pCounterBufferOffsets);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdBeginTransformFeedbackEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdBeginTransformFeedbackEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdBeginTransformFeedbackEXT(commandBuffer, firstCounterBuffer, counterBufferCount, pCounterBuffers,
                                                           pCounterBufferOffsets, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdEndTransformFeedbackEXT(VkCommandBuffer commandBuffer, uint32_t firstCounterBuffer,
                                                      uint32_t counterBufferCount, const VkBuffer* pCounterBuffers,
                                                      const VkDeviceSize* pCounterBufferOffsets) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdEndTransformFeedbackEXT,
                          VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdEndTransformFeedbackEXT");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdEndTransformFeedbackEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdEndTransformFeedbackEXT(commandBuffer, firstCounterBuffer, counterBufferCount,
                                                                  pCounterBuffers, pCounterBufferOffsets, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdEndTransformFeedbackEXT);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdEndTransformFeedbackEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdEndTransformFeedbackEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdEndTransformFeedbackEXT(commandBuffer, firstCounterBuffer, counterBufferCount, pCounterBuffers,
                                                        pCounterBufferOffsets, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdEndTransformFeedbackEXT");
        device_dispatch->CmdEndTransformFeedbackEXT(commandBuffer, firstCounterBuffer, counterBufferCount, pCounterBuffers,
                                                    pCounterBufferOffsets);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdEndTransformFeedbackEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdEndTransformFeedbackEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdEndTransformFeedbackEXT(commandBuffer, firstCounterBuffer, counterBufferCount, pCounterBuffers,
                                                         pCounterBufferOffsets, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdBeginQueryIndexedEXT(VkCommandBuffer commandBuffer, VkQueryPool queryPool, uint32_t query,
                                                   VkQueryControlFlags flags, uint32_t index) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdBeginQueryIndexedEXT, VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdBeginQueryIndexedEXT");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdBeginQueryIndexedEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdBeginQueryIndexedEXT(commandBuffer, queryPool, query, flags, index, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdBeginQueryIndexedEXT);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdBeginQueryIndexedEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdBeginQueryIndexedEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdBeginQueryIndexedEXT(commandBuffer, queryPool, query, flags, index, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdBeginQueryIndexedEXT");
        device_dispatch->CmdBeginQueryIndexedEXT(commandBuffer, queryPool, query, flags, index);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdBeginQueryIndexedEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdBeginQueryIndexedEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdBeginQueryIndexedEXT(commandBuffer, queryPool, query, flags, index, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdEndQueryIndexedEXT(VkCommandBuffer commandBuffer, VkQueryPool queryPool, uint32_t query,
                                                 uint32_t index) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdEndQueryIndexedEXT, VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdEndQueryIndexedEXT");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdEndQueryIndexedEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdEndQueryIndexedEXT(commandBuffer, queryPool, query, index, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdEndQueryIndexedEXT);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdEndQueryIndexedEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdEndQueryIndexedEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdEndQueryIndexedEXT(commandBuffer, queryPool, query, index, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdEndQueryIndexedEXT");
        device_dispatch->CmdEndQueryIndexedEXT(commandBuffer, queryPool, query, index);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdEndQueryIndexedEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdEndQueryIndexedEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdEndQueryIndexedEXT(commandBuffer, queryPool, query, index, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdDrawIndirectByteCountEXT(VkCommandBuffer commandBuffer, uint32_t instanceCount,
                                                       uint32_t firstInstance, VkBuffer counterBuffer,
                                                       VkDeviceSize counterBufferOffset, uint32_t counterOffset,
                                                       uint32_t vertexStride) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdDrawIndirectByteCountEXT,
                          VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdDrawIndirectByteCountEXT");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdDrawIndirectByteCountEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdDrawIndirectByteCountEXT(commandBuffer, instanceCount, firstInstance, counterBuffer,
                                                                   counterBufferOffset, counterOffset, vertexStride, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdDrawIndirectByteCountEXT);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdDrawIndirectByteCountEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdDrawIndirectByteCountEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdDrawIndirectByteCountEXT(commandBuffer, instanceCount, firstInstance, counterBuffer,
                                                         counterBufferOffset, counterOffset, vertexStride, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdDrawIndirectByteCountEXT");
        device_dispatch->CmdDrawIndirectByteCountEXT(commandBuffer, instanceCount, firstInstance, counterBuffer,
                                                     counterBufferOffset, counterOffset, vertexStride);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdDrawIndirectByteCountEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdDrawIndirectByteCountEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdDrawIndirectByteCountEXT(commandBuffer, instanceCount, firstInstance, counterBuffer,
                                                          counterBufferOffset, counterOffset, vertexStride, record_obj);
        }
    }
}

VKAPI_ATTR VkResult VKAPI_CALL CreateCuModuleNVX(VkDevice device, const VkCuModuleCreateInfoNVX* pCreateInfo,
                                                 const VkAllocationCallbacks* pAllocator, VkCuModuleNVX* pModule) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCreateCuModuleNVX, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCreateCuModuleNVX");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCreateCuModuleNVX]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCreateCuModuleNVX(device, pCreateInfo, pAllocator, pModule, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkCreateCuModuleNVX);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCreateCuModuleNVX");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCreateCuModuleNVX]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCreateCuModuleNVX(device, pCreateInfo, pAllocator, pModule, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkCreateCuModuleNVX");
        result = device_dispatch->CreateCuModuleNVX(device, pCreateInfo, pAllocator, pModule);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkCreateCuModuleNVX");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCreateCuModuleNVX]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCreateCuModuleNVX(device, pCreateInfo, pAllocator, pModule, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR VkResult VKAPI_CALL CreateCuFunctionNVX(VkDevice device, const VkCuFunctionCreateInfoNVX* pCreateInfo,
                                                   const VkAllocationCallbacks* pAllocator, VkCuFunctionNVX* pFunction) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCreateCuFunctionNVX, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCreateCuFunctionNVX");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCreateCuFunctionNVX]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCreateCuFunctionNVX(device, pCreateInfo, pAllocator, pFunction, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkCreateCuFunctionNVX);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCreateCuFunctionNVX");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCreateCuFunctionNVX]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCreateCuFunctionNVX(device, pCreateInfo, pAllocator, pFunction, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkCreateCuFunctionNVX");
        result = device_dispatch->CreateCuFunctionNVX(device, pCreateInfo, pAllocator, pFunction);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkCreateCuFunctionNVX");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCreateCuFunctionNVX]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCreateCuFunctionNVX(device, pCreateInfo, pAllocator, pFunction, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR void VKAPI_CALL DestroyCuModuleNVX(VkDevice device, VkCuModuleNVX module, const VkAllocationCallbacks* pAllocator) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkDestroyCuModuleNVX, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkDestroyCuModuleNVX");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateDestroyCuModuleNVX]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateDestroyCuModuleNVX(device, module, pAllocator, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkDestroyCuModuleNVX);
    {
        VVL_ZoneScopedN("PreCallRecord_vkDestroyCuModuleNVX");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordDestroyCuModuleNVX]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordDestroyCuModuleNVX(device, module, pAllocator, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkDestroyCuModuleNVX");
        device_dispatch->DestroyCuModuleNVX(device, module, pAllocator);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkDestroyCuModuleNVX");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordDestroyCuModuleNVX]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordDestroyCuModuleNVX(device, module, pAllocator, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL DestroyCuFunctionNVX(VkDevice device, VkCuFunctionNVX function,
                                                const VkAllocationCallbacks* pAllocator) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkDestroyCuFunctionNVX, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkDestroyCuFunctionNVX");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateDestroyCuFunctionNVX]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateDestroyCuFunctionNVX(device, function, pAllocator, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkDestroyCuFunctionNVX);
    {
        VVL_ZoneScopedN("PreCallRecord_vkDestroyCuFunctionNVX");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordDestroyCuFunctionNVX]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordDestroyCuFunctionNVX(device, function, pAllocator, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkDestroyCuFunctionNVX");
        device_dispatch->DestroyCuFunctionNVX(device, function, pAllocator);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkDestroyCuFunctionNVX");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordDestroyCuFunctionNVX]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordDestroyCuFunctionNVX(device, function, pAllocator, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdCuLaunchKernelNVX(VkCommandBuffer commandBuffer, const VkCuLaunchInfoNVX* pLaunchInfo) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdCuLaunchKernelNVX, VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdCuLaunchKernelNVX");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdCuLaunchKernelNVX]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdCuLaunchKernelNVX(commandBuffer, pLaunchInfo, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdCuLaunchKernelNVX);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdCuLaunchKernelNVX");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdCuLaunchKernelNVX]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdCuLaunchKernelNVX(commandBuffer, pLaunchInfo, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdCuLaunchKernelNVX");
        device_dispatch->CmdCuLaunchKernelNVX(commandBuffer, pLaunchInfo);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdCuLaunchKernelNVX");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdCuLaunchKernelNVX]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdCuLaunchKernelNVX(commandBuffer, pLaunchInfo, record_obj);
        }
    }
}

VKAPI_ATTR uint32_t VKAPI_CALL GetImageViewHandleNVX(VkDevice device, const VkImageViewHandleInfoNVX* pInfo) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetImageViewHandleNVX, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetImageViewHandleNVX");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateGetImageViewHandleNVX]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateGetImageViewHandleNVX(device, pInfo, error_obj);
            if (skip) return 0;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetImageViewHandleNVX);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetImageViewHandleNVX");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordGetImageViewHandleNVX]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordGetImageViewHandleNVX(device, pInfo, record_obj);
        }
    }
    uint32_t result;
    {
        VVL_ZoneScopedN("Dispatch_vkGetImageViewHandleNVX");
        result = device_dispatch->GetImageViewHandleNVX(device, pInfo);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetImageViewHandleNVX");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordGetImageViewHandleNVX]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordGetImageViewHandleNVX(device, pInfo, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR uint64_t VKAPI_CALL GetImageViewHandle64NVX(VkDevice device, const VkImageViewHandleInfoNVX* pInfo) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetImageViewHandle64NVX, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetImageViewHandle64NVX");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateGetImageViewHandle64NVX]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateGetImageViewHandle64NVX(device, pInfo, error_obj);
            if (skip) return 0;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetImageViewHandle64NVX);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetImageViewHandle64NVX");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordGetImageViewHandle64NVX]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordGetImageViewHandle64NVX(device, pInfo, record_obj);
        }
    }
    uint64_t result;
    {
        VVL_ZoneScopedN("Dispatch_vkGetImageViewHandle64NVX");
        result = device_dispatch->GetImageViewHandle64NVX(device, pInfo);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetImageViewHandle64NVX");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordGetImageViewHandle64NVX]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordGetImageViewHandle64NVX(device, pInfo, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR VkResult VKAPI_CALL GetImageViewAddressNVX(VkDevice device, VkImageView imageView,
                                                      VkImageViewAddressPropertiesNVX* pProperties) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetImageViewAddressNVX, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetImageViewAddressNVX");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateGetImageViewAddressNVX]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateGetImageViewAddressNVX(device, imageView, pProperties, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetImageViewAddressNVX);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetImageViewAddressNVX");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordGetImageViewAddressNVX]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordGetImageViewAddressNVX(device, imageView, pProperties, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkGetImageViewAddressNVX");
        result = device_dispatch->GetImageViewAddressNVX(device, imageView, pProperties);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetImageViewAddressNVX");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordGetImageViewAddressNVX]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordGetImageViewAddressNVX(device, imageView, pProperties, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR uint64_t VKAPI_CALL GetDeviceCombinedImageSamplerIndexNVX(VkDevice device, uint64_t imageViewIndex,
                                                                     uint64_t samplerIndex) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetDeviceCombinedImageSamplerIndexNVX, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetDeviceCombinedImageSamplerIndexNVX");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateGetDeviceCombinedImageSamplerIndexNVX]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateGetDeviceCombinedImageSamplerIndexNVX(device, imageViewIndex, samplerIndex, error_obj);
            if (skip) return 0;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetDeviceCombinedImageSamplerIndexNVX);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetDeviceCombinedImageSamplerIndexNVX");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordGetDeviceCombinedImageSamplerIndexNVX]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordGetDeviceCombinedImageSamplerIndexNVX(device, imageViewIndex, samplerIndex, record_obj);
        }
    }
    uint64_t result;
    {
        VVL_ZoneScopedN("Dispatch_vkGetDeviceCombinedImageSamplerIndexNVX");
        result = device_dispatch->GetDeviceCombinedImageSamplerIndexNVX(device, imageViewIndex, samplerIndex);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetDeviceCombinedImageSamplerIndexNVX");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordGetDeviceCombinedImageSamplerIndexNVX]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordGetDeviceCombinedImageSamplerIndexNVX(device, imageViewIndex, samplerIndex, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR void VKAPI_CALL CmdDrawIndirectCountAMD(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
                                                   VkBuffer countBuffer, VkDeviceSize countBufferOffset, uint32_t maxDrawCount,
                                                   uint32_t stride) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdDrawIndirectCountAMD, VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdDrawIndirectCountAMD");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdDrawIndirectCountAMD]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdDrawIndirectCountAMD(commandBuffer, buffer, offset, countBuffer, countBufferOffset,
                                                               maxDrawCount, stride, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdDrawIndirectCountAMD);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdDrawIndirectCountAMD");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdDrawIndirectCountAMD]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdDrawIndirectCountAMD(commandBuffer, buffer, offset, countBuffer, countBufferOffset, maxDrawCount,
                                                     stride, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdDrawIndirectCountAMD");
        device_dispatch->CmdDrawIndirectCountAMD(commandBuffer, buffer, offset, countBuffer, countBufferOffset, maxDrawCount,
                                                 stride);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdDrawIndirectCountAMD");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdDrawIndirectCountAMD]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdDrawIndirectCountAMD(commandBuffer, buffer, offset, countBuffer, countBufferOffset, maxDrawCount,
                                                      stride, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdDrawIndexedIndirectCountAMD(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
                                                          VkBuffer countBuffer, VkDeviceSize countBufferOffset,
                                                          uint32_t maxDrawCount, uint32_t stride) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdDrawIndexedIndirectCountAMD,
                          VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdDrawIndexedIndirectCountAMD");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdDrawIndexedIndirectCountAMD]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdDrawIndexedIndirectCountAMD(commandBuffer, buffer, offset, countBuffer, countBufferOffset,
                                                                      maxDrawCount, stride, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdDrawIndexedIndirectCountAMD);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdDrawIndexedIndirectCountAMD");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdDrawIndexedIndirectCountAMD]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdDrawIndexedIndirectCountAMD(commandBuffer, buffer, offset, countBuffer, countBufferOffset,
                                                            maxDrawCount, stride, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdDrawIndexedIndirectCountAMD");
        device_dispatch->CmdDrawIndexedIndirectCountAMD(commandBuffer, buffer, offset, countBuffer, countBufferOffset, maxDrawCount,
                                                        stride);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdDrawIndexedIndirectCountAMD");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdDrawIndexedIndirectCountAMD]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdDrawIndexedIndirectCountAMD(commandBuffer, buffer, offset, countBuffer, countBufferOffset,
                                                             maxDrawCount, stride, record_obj);
        }
    }
}

VKAPI_ATTR VkResult VKAPI_CALL GetShaderInfoAMD(VkDevice device, VkPipeline pipeline, VkShaderStageFlagBits shaderStage,
                                                VkShaderInfoTypeAMD infoType, size_t* pInfoSize, void* pInfo) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetShaderInfoAMD, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetShaderInfoAMD");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateGetShaderInfoAMD]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateGetShaderInfoAMD(device, pipeline, shaderStage, infoType, pInfoSize, pInfo, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetShaderInfoAMD);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetShaderInfoAMD");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordGetShaderInfoAMD]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordGetShaderInfoAMD(device, pipeline, shaderStage, infoType, pInfoSize, pInfo, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkGetShaderInfoAMD");
        result = device_dispatch->GetShaderInfoAMD(device, pipeline, shaderStage, infoType, pInfoSize, pInfo);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetShaderInfoAMD");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordGetShaderInfoAMD]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordGetShaderInfoAMD(device, pipeline, shaderStage, infoType, pInfoSize, pInfo, record_obj);
        }
    }
    return result;
}

#ifdef VK_USE_PLATFORM_GGP
VKAPI_ATTR VkResult VKAPI_CALL CreateStreamDescriptorSurfaceGGP(VkInstance instance,
                                                                const VkStreamDescriptorSurfaceCreateInfoGGP* pCreateInfo,
                                                                const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface) {
    VVL_ZoneScoped;

    auto instance_dispatch = vvl::dispatch::GetData(instance);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCreateStreamDescriptorSurfaceGGP, VulkanTypedHandle(instance, kVulkanObjectTypeInstance));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCreateStreamDescriptorSurfaceGGP");
        for (const auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            skip |= vo->PreCallValidateCreateStreamDescriptorSurfaceGGP(instance, pCreateInfo, pAllocator, pSurface, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkCreateStreamDescriptorSurfaceGGP);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCreateStreamDescriptorSurfaceGGP");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PreCallRecordCreateStreamDescriptorSurfaceGGP(instance, pCreateInfo, pAllocator, pSurface, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkCreateStreamDescriptorSurfaceGGP");
        result = instance_dispatch->CreateStreamDescriptorSurfaceGGP(instance, pCreateInfo, pAllocator, pSurface);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkCreateStreamDescriptorSurfaceGGP");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PostCallRecordCreateStreamDescriptorSurfaceGGP(instance, pCreateInfo, pAllocator, pSurface, record_obj);
        }
    }
    return result;
}

#endif  // VK_USE_PLATFORM_GGP
VKAPI_ATTR VkResult VKAPI_CALL GetPhysicalDeviceExternalImageFormatPropertiesNV(
    VkPhysicalDevice physicalDevice, VkFormat format, VkImageType type, VkImageTiling tiling, VkImageUsageFlags usage,
    VkImageCreateFlags flags, VkExternalMemoryHandleTypeFlagsNV externalHandleType,
    VkExternalImageFormatPropertiesNV* pExternalImageFormatProperties) {
    VVL_ZoneScoped;

    auto instance_dispatch = vvl::dispatch::GetData(physicalDevice);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetPhysicalDeviceExternalImageFormatPropertiesNV,
                          VulkanTypedHandle(physicalDevice, kVulkanObjectTypePhysicalDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetPhysicalDeviceExternalImageFormatPropertiesNV");
        for (const auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            skip |= vo->PreCallValidateGetPhysicalDeviceExternalImageFormatPropertiesNV(
                physicalDevice, format, type, tiling, usage, flags, externalHandleType, pExternalImageFormatProperties, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetPhysicalDeviceExternalImageFormatPropertiesNV);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetPhysicalDeviceExternalImageFormatPropertiesNV");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PreCallRecordGetPhysicalDeviceExternalImageFormatPropertiesNV(
                physicalDevice, format, type, tiling, usage, flags, externalHandleType, pExternalImageFormatProperties, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkGetPhysicalDeviceExternalImageFormatPropertiesNV");
        result = instance_dispatch->GetPhysicalDeviceExternalImageFormatPropertiesNV(
            physicalDevice, format, type, tiling, usage, flags, externalHandleType, pExternalImageFormatProperties);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetPhysicalDeviceExternalImageFormatPropertiesNV");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PostCallRecordGetPhysicalDeviceExternalImageFormatPropertiesNV(
                physicalDevice, format, type, tiling, usage, flags, externalHandleType, pExternalImageFormatProperties, record_obj);
        }
    }
    return result;
}

#ifdef VK_USE_PLATFORM_WIN32_KHR
VKAPI_ATTR VkResult VKAPI_CALL GetMemoryWin32HandleNV(VkDevice device, VkDeviceMemory memory,
                                                      VkExternalMemoryHandleTypeFlagsNV handleType, HANDLE* pHandle) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetMemoryWin32HandleNV, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetMemoryWin32HandleNV");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateGetMemoryWin32HandleNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateGetMemoryWin32HandleNV(device, memory, handleType, pHandle, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetMemoryWin32HandleNV);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetMemoryWin32HandleNV");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordGetMemoryWin32HandleNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordGetMemoryWin32HandleNV(device, memory, handleType, pHandle, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkGetMemoryWin32HandleNV");
        result = device_dispatch->GetMemoryWin32HandleNV(device, memory, handleType, pHandle);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetMemoryWin32HandleNV");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordGetMemoryWin32HandleNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordGetMemoryWin32HandleNV(device, memory, handleType, pHandle, record_obj);
        }
    }
    return result;
}

#endif  // VK_USE_PLATFORM_WIN32_KHR
#ifdef VK_USE_PLATFORM_VI_NN
VKAPI_ATTR VkResult VKAPI_CALL CreateViSurfaceNN(VkInstance instance, const VkViSurfaceCreateInfoNN* pCreateInfo,
                                                 const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface) {
    VVL_ZoneScoped;

    auto instance_dispatch = vvl::dispatch::GetData(instance);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCreateViSurfaceNN, VulkanTypedHandle(instance, kVulkanObjectTypeInstance));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCreateViSurfaceNN");
        for (const auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            skip |= vo->PreCallValidateCreateViSurfaceNN(instance, pCreateInfo, pAllocator, pSurface, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkCreateViSurfaceNN);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCreateViSurfaceNN");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PreCallRecordCreateViSurfaceNN(instance, pCreateInfo, pAllocator, pSurface, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkCreateViSurfaceNN");
        result = instance_dispatch->CreateViSurfaceNN(instance, pCreateInfo, pAllocator, pSurface);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkCreateViSurfaceNN");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PostCallRecordCreateViSurfaceNN(instance, pCreateInfo, pAllocator, pSurface, record_obj);
        }
    }
    return result;
}

#endif  // VK_USE_PLATFORM_VI_NN
VKAPI_ATTR void VKAPI_CALL CmdBeginConditionalRenderingEXT(VkCommandBuffer commandBuffer,
                                                           const VkConditionalRenderingBeginInfoEXT* pConditionalRenderingBegin) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdBeginConditionalRenderingEXT,
                          VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdBeginConditionalRenderingEXT");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdBeginConditionalRenderingEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdBeginConditionalRenderingEXT(commandBuffer, pConditionalRenderingBegin, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdBeginConditionalRenderingEXT);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdBeginConditionalRenderingEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdBeginConditionalRenderingEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdBeginConditionalRenderingEXT(commandBuffer, pConditionalRenderingBegin, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdBeginConditionalRenderingEXT");
        device_dispatch->CmdBeginConditionalRenderingEXT(commandBuffer, pConditionalRenderingBegin);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdBeginConditionalRenderingEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdBeginConditionalRenderingEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdBeginConditionalRenderingEXT(commandBuffer, pConditionalRenderingBegin, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdEndConditionalRenderingEXT(VkCommandBuffer commandBuffer) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdEndConditionalRenderingEXT,
                          VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdEndConditionalRenderingEXT");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdEndConditionalRenderingEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdEndConditionalRenderingEXT(commandBuffer, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdEndConditionalRenderingEXT);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdEndConditionalRenderingEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdEndConditionalRenderingEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdEndConditionalRenderingEXT(commandBuffer, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdEndConditionalRenderingEXT");
        device_dispatch->CmdEndConditionalRenderingEXT(commandBuffer);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdEndConditionalRenderingEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdEndConditionalRenderingEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdEndConditionalRenderingEXT(commandBuffer, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdSetViewportWScalingNV(VkCommandBuffer commandBuffer, uint32_t firstViewport, uint32_t viewportCount,
                                                    const VkViewportWScalingNV* pViewportWScalings) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdSetViewportWScalingNV, VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdSetViewportWScalingNV");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdSetViewportWScalingNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdSetViewportWScalingNV(commandBuffer, firstViewport, viewportCount, pViewportWScalings,
                                                                error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdSetViewportWScalingNV);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdSetViewportWScalingNV");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdSetViewportWScalingNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdSetViewportWScalingNV(commandBuffer, firstViewport, viewportCount, pViewportWScalings, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdSetViewportWScalingNV");
        device_dispatch->CmdSetViewportWScalingNV(commandBuffer, firstViewport, viewportCount, pViewportWScalings);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdSetViewportWScalingNV");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdSetViewportWScalingNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdSetViewportWScalingNV(commandBuffer, firstViewport, viewportCount, pViewportWScalings, record_obj);
        }
    }
}

VKAPI_ATTR VkResult VKAPI_CALL ReleaseDisplayEXT(VkPhysicalDevice physicalDevice, VkDisplayKHR display) {
    VVL_ZoneScoped;

    auto instance_dispatch = vvl::dispatch::GetData(physicalDevice);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkReleaseDisplayEXT, VulkanTypedHandle(physicalDevice, kVulkanObjectTypePhysicalDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkReleaseDisplayEXT");
        for (const auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            skip |= vo->PreCallValidateReleaseDisplayEXT(physicalDevice, display, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkReleaseDisplayEXT);
    {
        VVL_ZoneScopedN("PreCallRecord_vkReleaseDisplayEXT");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PreCallRecordReleaseDisplayEXT(physicalDevice, display, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkReleaseDisplayEXT");
        result = instance_dispatch->ReleaseDisplayEXT(physicalDevice, display);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkReleaseDisplayEXT");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PostCallRecordReleaseDisplayEXT(physicalDevice, display, record_obj);
        }
    }
    return result;
}

#ifdef VK_USE_PLATFORM_XLIB_XRANDR_EXT
VKAPI_ATTR VkResult VKAPI_CALL AcquireXlibDisplayEXT(VkPhysicalDevice physicalDevice, Display* dpy, VkDisplayKHR display) {
    VVL_ZoneScoped;

    auto instance_dispatch = vvl::dispatch::GetData(physicalDevice);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkAcquireXlibDisplayEXT, VulkanTypedHandle(physicalDevice, kVulkanObjectTypePhysicalDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkAcquireXlibDisplayEXT");
        for (const auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            skip |= vo->PreCallValidateAcquireXlibDisplayEXT(physicalDevice, dpy, display, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkAcquireXlibDisplayEXT);
    {
        VVL_ZoneScopedN("PreCallRecord_vkAcquireXlibDisplayEXT");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PreCallRecordAcquireXlibDisplayEXT(physicalDevice, dpy, display, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkAcquireXlibDisplayEXT");
        result = instance_dispatch->AcquireXlibDisplayEXT(physicalDevice, dpy, display);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkAcquireXlibDisplayEXT");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PostCallRecordAcquireXlibDisplayEXT(physicalDevice, dpy, display, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR VkResult VKAPI_CALL GetRandROutputDisplayEXT(VkPhysicalDevice physicalDevice, Display* dpy, RROutput rrOutput,
                                                        VkDisplayKHR* pDisplay) {
    VVL_ZoneScoped;

    auto instance_dispatch = vvl::dispatch::GetData(physicalDevice);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetRandROutputDisplayEXT,
                          VulkanTypedHandle(physicalDevice, kVulkanObjectTypePhysicalDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetRandROutputDisplayEXT");
        for (const auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            skip |= vo->PreCallValidateGetRandROutputDisplayEXT(physicalDevice, dpy, rrOutput, pDisplay, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetRandROutputDisplayEXT);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetRandROutputDisplayEXT");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PreCallRecordGetRandROutputDisplayEXT(physicalDevice, dpy, rrOutput, pDisplay, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkGetRandROutputDisplayEXT");
        result = instance_dispatch->GetRandROutputDisplayEXT(physicalDevice, dpy, rrOutput, pDisplay);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetRandROutputDisplayEXT");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PostCallRecordGetRandROutputDisplayEXT(physicalDevice, dpy, rrOutput, pDisplay, record_obj);
        }
    }
    return result;
}

#endif  // VK_USE_PLATFORM_XLIB_XRANDR_EXT
VKAPI_ATTR VkResult VKAPI_CALL GetPhysicalDeviceSurfaceCapabilities2EXT(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface,
                                                                        VkSurfaceCapabilities2EXT* pSurfaceCapabilities) {
    VVL_ZoneScoped;

    auto instance_dispatch = vvl::dispatch::GetData(physicalDevice);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetPhysicalDeviceSurfaceCapabilities2EXT,
                          VulkanTypedHandle(physicalDevice, kVulkanObjectTypePhysicalDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetPhysicalDeviceSurfaceCapabilities2EXT");
        for (const auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            skip |= vo->PreCallValidateGetPhysicalDeviceSurfaceCapabilities2EXT(physicalDevice, surface, pSurfaceCapabilities,
                                                                                error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetPhysicalDeviceSurfaceCapabilities2EXT);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetPhysicalDeviceSurfaceCapabilities2EXT");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PreCallRecordGetPhysicalDeviceSurfaceCapabilities2EXT(physicalDevice, surface, pSurfaceCapabilities, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkGetPhysicalDeviceSurfaceCapabilities2EXT");
        result = instance_dispatch->GetPhysicalDeviceSurfaceCapabilities2EXT(physicalDevice, surface, pSurfaceCapabilities);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetPhysicalDeviceSurfaceCapabilities2EXT");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PostCallRecordGetPhysicalDeviceSurfaceCapabilities2EXT(physicalDevice, surface, pSurfaceCapabilities, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR VkResult VKAPI_CALL DisplayPowerControlEXT(VkDevice device, VkDisplayKHR display,
                                                      const VkDisplayPowerInfoEXT* pDisplayPowerInfo) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkDisplayPowerControlEXT, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkDisplayPowerControlEXT");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateDisplayPowerControlEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateDisplayPowerControlEXT(device, display, pDisplayPowerInfo, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkDisplayPowerControlEXT);
    {
        VVL_ZoneScopedN("PreCallRecord_vkDisplayPowerControlEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordDisplayPowerControlEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordDisplayPowerControlEXT(device, display, pDisplayPowerInfo, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkDisplayPowerControlEXT");
        result = device_dispatch->DisplayPowerControlEXT(device, display, pDisplayPowerInfo);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkDisplayPowerControlEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordDisplayPowerControlEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordDisplayPowerControlEXT(device, display, pDisplayPowerInfo, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR VkResult VKAPI_CALL RegisterDeviceEventEXT(VkDevice device, const VkDeviceEventInfoEXT* pDeviceEventInfo,
                                                      const VkAllocationCallbacks* pAllocator, VkFence* pFence) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkRegisterDeviceEventEXT, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkRegisterDeviceEventEXT");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateRegisterDeviceEventEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateRegisterDeviceEventEXT(device, pDeviceEventInfo, pAllocator, pFence, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkRegisterDeviceEventEXT);
    {
        VVL_ZoneScopedN("PreCallRecord_vkRegisterDeviceEventEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordRegisterDeviceEventEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordRegisterDeviceEventEXT(device, pDeviceEventInfo, pAllocator, pFence, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkRegisterDeviceEventEXT");
        result = device_dispatch->RegisterDeviceEventEXT(device, pDeviceEventInfo, pAllocator, pFence);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkRegisterDeviceEventEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordRegisterDeviceEventEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordRegisterDeviceEventEXT(device, pDeviceEventInfo, pAllocator, pFence, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR VkResult VKAPI_CALL RegisterDisplayEventEXT(VkDevice device, VkDisplayKHR display,
                                                       const VkDisplayEventInfoEXT* pDisplayEventInfo,
                                                       const VkAllocationCallbacks* pAllocator, VkFence* pFence) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkRegisterDisplayEventEXT, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkRegisterDisplayEventEXT");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateRegisterDisplayEventEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateRegisterDisplayEventEXT(device, display, pDisplayEventInfo, pAllocator, pFence, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkRegisterDisplayEventEXT);
    {
        VVL_ZoneScopedN("PreCallRecord_vkRegisterDisplayEventEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordRegisterDisplayEventEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordRegisterDisplayEventEXT(device, display, pDisplayEventInfo, pAllocator, pFence, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkRegisterDisplayEventEXT");
        result = device_dispatch->RegisterDisplayEventEXT(device, display, pDisplayEventInfo, pAllocator, pFence);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkRegisterDisplayEventEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordRegisterDisplayEventEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordRegisterDisplayEventEXT(device, display, pDisplayEventInfo, pAllocator, pFence, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR VkResult VKAPI_CALL GetSwapchainCounterEXT(VkDevice device, VkSwapchainKHR swapchain,
                                                      VkSurfaceCounterFlagBitsEXT counter, uint64_t* pCounterValue) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetSwapchainCounterEXT, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetSwapchainCounterEXT");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateGetSwapchainCounterEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateGetSwapchainCounterEXT(device, swapchain, counter, pCounterValue, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetSwapchainCounterEXT);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetSwapchainCounterEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordGetSwapchainCounterEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordGetSwapchainCounterEXT(device, swapchain, counter, pCounterValue, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkGetSwapchainCounterEXT");
        result = device_dispatch->GetSwapchainCounterEXT(device, swapchain, counter, pCounterValue);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetSwapchainCounterEXT");

        if (result == VK_ERROR_DEVICE_LOST) {
            for (auto& vo : device_dispatch->object_dispatch) {
                vo->is_device_lost = true;
            }
        }
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordGetSwapchainCounterEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordGetSwapchainCounterEXT(device, swapchain, counter, pCounterValue, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR VkResult VKAPI_CALL GetRefreshCycleDurationGOOGLE(VkDevice device, VkSwapchainKHR swapchain,
                                                             VkRefreshCycleDurationGOOGLE* pDisplayTimingProperties) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetRefreshCycleDurationGOOGLE, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetRefreshCycleDurationGOOGLE");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateGetRefreshCycleDurationGOOGLE]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateGetRefreshCycleDurationGOOGLE(device, swapchain, pDisplayTimingProperties, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetRefreshCycleDurationGOOGLE);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetRefreshCycleDurationGOOGLE");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordGetRefreshCycleDurationGOOGLE]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordGetRefreshCycleDurationGOOGLE(device, swapchain, pDisplayTimingProperties, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkGetRefreshCycleDurationGOOGLE");
        result = device_dispatch->GetRefreshCycleDurationGOOGLE(device, swapchain, pDisplayTimingProperties);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetRefreshCycleDurationGOOGLE");

        if (result == VK_ERROR_DEVICE_LOST) {
            for (auto& vo : device_dispatch->object_dispatch) {
                vo->is_device_lost = true;
            }
        }
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordGetRefreshCycleDurationGOOGLE]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordGetRefreshCycleDurationGOOGLE(device, swapchain, pDisplayTimingProperties, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR VkResult VKAPI_CALL GetPastPresentationTimingGOOGLE(VkDevice device, VkSwapchainKHR swapchain,
                                                               uint32_t* pPresentationTimingCount,
                                                               VkPastPresentationTimingGOOGLE* pPresentationTimings) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetPastPresentationTimingGOOGLE, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetPastPresentationTimingGOOGLE");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateGetPastPresentationTimingGOOGLE]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateGetPastPresentationTimingGOOGLE(device, swapchain, pPresentationTimingCount,
                                                                       pPresentationTimings, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetPastPresentationTimingGOOGLE);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetPastPresentationTimingGOOGLE");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordGetPastPresentationTimingGOOGLE]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordGetPastPresentationTimingGOOGLE(device, swapchain, pPresentationTimingCount, pPresentationTimings,
                                                             record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkGetPastPresentationTimingGOOGLE");
        result =
            device_dispatch->GetPastPresentationTimingGOOGLE(device, swapchain, pPresentationTimingCount, pPresentationTimings);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetPastPresentationTimingGOOGLE");

        if (result == VK_ERROR_DEVICE_LOST) {
            for (auto& vo : device_dispatch->object_dispatch) {
                vo->is_device_lost = true;
            }
        }
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordGetPastPresentationTimingGOOGLE]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordGetPastPresentationTimingGOOGLE(device, swapchain, pPresentationTimingCount, pPresentationTimings,
                                                              record_obj);
        }
    }
    return result;
}

VKAPI_ATTR void VKAPI_CALL CmdSetDiscardRectangleEXT(VkCommandBuffer commandBuffer, uint32_t firstDiscardRectangle,
                                                     uint32_t discardRectangleCount, const VkRect2D* pDiscardRectangles) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdSetDiscardRectangleEXT, VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdSetDiscardRectangleEXT");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdSetDiscardRectangleEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdSetDiscardRectangleEXT(commandBuffer, firstDiscardRectangle, discardRectangleCount,
                                                                 pDiscardRectangles, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdSetDiscardRectangleEXT);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdSetDiscardRectangleEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdSetDiscardRectangleEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdSetDiscardRectangleEXT(commandBuffer, firstDiscardRectangle, discardRectangleCount,
                                                       pDiscardRectangles, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdSetDiscardRectangleEXT");
        device_dispatch->CmdSetDiscardRectangleEXT(commandBuffer, firstDiscardRectangle, discardRectangleCount, pDiscardRectangles);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdSetDiscardRectangleEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdSetDiscardRectangleEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdSetDiscardRectangleEXT(commandBuffer, firstDiscardRectangle, discardRectangleCount,
                                                        pDiscardRectangles, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdSetDiscardRectangleEnableEXT(VkCommandBuffer commandBuffer, VkBool32 discardRectangleEnable) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdSetDiscardRectangleEnableEXT,
                          VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdSetDiscardRectangleEnableEXT");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdSetDiscardRectangleEnableEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdSetDiscardRectangleEnableEXT(commandBuffer, discardRectangleEnable, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdSetDiscardRectangleEnableEXT);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdSetDiscardRectangleEnableEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdSetDiscardRectangleEnableEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdSetDiscardRectangleEnableEXT(commandBuffer, discardRectangleEnable, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdSetDiscardRectangleEnableEXT");
        device_dispatch->CmdSetDiscardRectangleEnableEXT(commandBuffer, discardRectangleEnable);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdSetDiscardRectangleEnableEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdSetDiscardRectangleEnableEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdSetDiscardRectangleEnableEXT(commandBuffer, discardRectangleEnable, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdSetDiscardRectangleModeEXT(VkCommandBuffer commandBuffer,
                                                         VkDiscardRectangleModeEXT discardRectangleMode) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdSetDiscardRectangleModeEXT,
                          VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdSetDiscardRectangleModeEXT");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdSetDiscardRectangleModeEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdSetDiscardRectangleModeEXT(commandBuffer, discardRectangleMode, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdSetDiscardRectangleModeEXT);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdSetDiscardRectangleModeEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdSetDiscardRectangleModeEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdSetDiscardRectangleModeEXT(commandBuffer, discardRectangleMode, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdSetDiscardRectangleModeEXT");
        device_dispatch->CmdSetDiscardRectangleModeEXT(commandBuffer, discardRectangleMode);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdSetDiscardRectangleModeEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdSetDiscardRectangleModeEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdSetDiscardRectangleModeEXT(commandBuffer, discardRectangleMode, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL SetHdrMetadataEXT(VkDevice device, uint32_t swapchainCount, const VkSwapchainKHR* pSwapchains,
                                             const VkHdrMetadataEXT* pMetadata) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkSetHdrMetadataEXT, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkSetHdrMetadataEXT");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateSetHdrMetadataEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateSetHdrMetadataEXT(device, swapchainCount, pSwapchains, pMetadata, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkSetHdrMetadataEXT);
    {
        VVL_ZoneScopedN("PreCallRecord_vkSetHdrMetadataEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordSetHdrMetadataEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordSetHdrMetadataEXT(device, swapchainCount, pSwapchains, pMetadata, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkSetHdrMetadataEXT");
        device_dispatch->SetHdrMetadataEXT(device, swapchainCount, pSwapchains, pMetadata);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkSetHdrMetadataEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordSetHdrMetadataEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordSetHdrMetadataEXT(device, swapchainCount, pSwapchains, pMetadata, record_obj);
        }
    }
}

#ifdef VK_USE_PLATFORM_IOS_MVK
VKAPI_ATTR VkResult VKAPI_CALL CreateIOSSurfaceMVK(VkInstance instance, const VkIOSSurfaceCreateInfoMVK* pCreateInfo,
                                                   const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface) {
    VVL_ZoneScoped;

    auto instance_dispatch = vvl::dispatch::GetData(instance);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCreateIOSSurfaceMVK, VulkanTypedHandle(instance, kVulkanObjectTypeInstance));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCreateIOSSurfaceMVK");
        for (const auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            skip |= vo->PreCallValidateCreateIOSSurfaceMVK(instance, pCreateInfo, pAllocator, pSurface, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkCreateIOSSurfaceMVK);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCreateIOSSurfaceMVK");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PreCallRecordCreateIOSSurfaceMVK(instance, pCreateInfo, pAllocator, pSurface, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkCreateIOSSurfaceMVK");
        result = instance_dispatch->CreateIOSSurfaceMVK(instance, pCreateInfo, pAllocator, pSurface);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkCreateIOSSurfaceMVK");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PostCallRecordCreateIOSSurfaceMVK(instance, pCreateInfo, pAllocator, pSurface, record_obj);
        }
    }
    return result;
}

#endif  // VK_USE_PLATFORM_IOS_MVK
#ifdef VK_USE_PLATFORM_MACOS_MVK
VKAPI_ATTR VkResult VKAPI_CALL CreateMacOSSurfaceMVK(VkInstance instance, const VkMacOSSurfaceCreateInfoMVK* pCreateInfo,
                                                     const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface) {
    VVL_ZoneScoped;

    auto instance_dispatch = vvl::dispatch::GetData(instance);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCreateMacOSSurfaceMVK, VulkanTypedHandle(instance, kVulkanObjectTypeInstance));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCreateMacOSSurfaceMVK");
        for (const auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            skip |= vo->PreCallValidateCreateMacOSSurfaceMVK(instance, pCreateInfo, pAllocator, pSurface, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkCreateMacOSSurfaceMVK);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCreateMacOSSurfaceMVK");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PreCallRecordCreateMacOSSurfaceMVK(instance, pCreateInfo, pAllocator, pSurface, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkCreateMacOSSurfaceMVK");
        result = instance_dispatch->CreateMacOSSurfaceMVK(instance, pCreateInfo, pAllocator, pSurface);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkCreateMacOSSurfaceMVK");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PostCallRecordCreateMacOSSurfaceMVK(instance, pCreateInfo, pAllocator, pSurface, record_obj);
        }
    }
    return result;
}

#endif  // VK_USE_PLATFORM_MACOS_MVK
VKAPI_ATTR VkResult VKAPI_CALL SetDebugUtilsObjectNameEXT(VkDevice device, const VkDebugUtilsObjectNameInfoEXT* pNameInfo) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkSetDebugUtilsObjectNameEXT, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkSetDebugUtilsObjectNameEXT");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateSetDebugUtilsObjectNameEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateSetDebugUtilsObjectNameEXT(device, pNameInfo, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkSetDebugUtilsObjectNameEXT);
    {
        VVL_ZoneScopedN("PreCallRecord_vkSetDebugUtilsObjectNameEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordSetDebugUtilsObjectNameEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordSetDebugUtilsObjectNameEXT(device, pNameInfo, record_obj);
        }
    }
    device_dispatch->debug_report->SetUtilsObjectName(pNameInfo);
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkSetDebugUtilsObjectNameEXT");
        result = device_dispatch->SetDebugUtilsObjectNameEXT(device, pNameInfo);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkSetDebugUtilsObjectNameEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordSetDebugUtilsObjectNameEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordSetDebugUtilsObjectNameEXT(device, pNameInfo, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR VkResult VKAPI_CALL SetDebugUtilsObjectTagEXT(VkDevice device, const VkDebugUtilsObjectTagInfoEXT* pTagInfo) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkSetDebugUtilsObjectTagEXT, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkSetDebugUtilsObjectTagEXT");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateSetDebugUtilsObjectTagEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateSetDebugUtilsObjectTagEXT(device, pTagInfo, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkSetDebugUtilsObjectTagEXT);
    {
        VVL_ZoneScopedN("PreCallRecord_vkSetDebugUtilsObjectTagEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordSetDebugUtilsObjectTagEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordSetDebugUtilsObjectTagEXT(device, pTagInfo, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkSetDebugUtilsObjectTagEXT");
        result = device_dispatch->SetDebugUtilsObjectTagEXT(device, pTagInfo);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkSetDebugUtilsObjectTagEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordSetDebugUtilsObjectTagEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordSetDebugUtilsObjectTagEXT(device, pTagInfo, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR void VKAPI_CALL QueueBeginDebugUtilsLabelEXT(VkQueue queue, const VkDebugUtilsLabelEXT* pLabelInfo) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(queue);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkQueueBeginDebugUtilsLabelEXT, VulkanTypedHandle(queue, kVulkanObjectTypeQueue));
    {
        VVL_ZoneScopedN("PreCallValidate_vkQueueBeginDebugUtilsLabelEXT");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateQueueBeginDebugUtilsLabelEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateQueueBeginDebugUtilsLabelEXT(queue, pLabelInfo, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkQueueBeginDebugUtilsLabelEXT);
    {
        VVL_ZoneScopedN("PreCallRecord_vkQueueBeginDebugUtilsLabelEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordQueueBeginDebugUtilsLabelEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordQueueBeginDebugUtilsLabelEXT(queue, pLabelInfo, record_obj);
        }
    }
    device_dispatch->debug_report->BeginQueueDebugUtilsLabel(queue, pLabelInfo);
    {
        VVL_ZoneScopedN("Dispatch_vkQueueBeginDebugUtilsLabelEXT");
        device_dispatch->QueueBeginDebugUtilsLabelEXT(queue, pLabelInfo);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkQueueBeginDebugUtilsLabelEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordQueueBeginDebugUtilsLabelEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordQueueBeginDebugUtilsLabelEXT(queue, pLabelInfo, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL QueueEndDebugUtilsLabelEXT(VkQueue queue) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(queue);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkQueueEndDebugUtilsLabelEXT, VulkanTypedHandle(queue, kVulkanObjectTypeQueue));
    {
        VVL_ZoneScopedN("PreCallValidate_vkQueueEndDebugUtilsLabelEXT");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateQueueEndDebugUtilsLabelEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateQueueEndDebugUtilsLabelEXT(queue, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkQueueEndDebugUtilsLabelEXT);
    {
        VVL_ZoneScopedN("PreCallRecord_vkQueueEndDebugUtilsLabelEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordQueueEndDebugUtilsLabelEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordQueueEndDebugUtilsLabelEXT(queue, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkQueueEndDebugUtilsLabelEXT");
        device_dispatch->QueueEndDebugUtilsLabelEXT(queue);
    }
    device_dispatch->debug_report->EndQueueDebugUtilsLabel(queue);
    {
        VVL_ZoneScopedN("PostCallRecord_vkQueueEndDebugUtilsLabelEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordQueueEndDebugUtilsLabelEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordQueueEndDebugUtilsLabelEXT(queue, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL QueueInsertDebugUtilsLabelEXT(VkQueue queue, const VkDebugUtilsLabelEXT* pLabelInfo) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(queue);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkQueueInsertDebugUtilsLabelEXT, VulkanTypedHandle(queue, kVulkanObjectTypeQueue));
    {
        VVL_ZoneScopedN("PreCallValidate_vkQueueInsertDebugUtilsLabelEXT");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateQueueInsertDebugUtilsLabelEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateQueueInsertDebugUtilsLabelEXT(queue, pLabelInfo, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkQueueInsertDebugUtilsLabelEXT);
    {
        VVL_ZoneScopedN("PreCallRecord_vkQueueInsertDebugUtilsLabelEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordQueueInsertDebugUtilsLabelEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordQueueInsertDebugUtilsLabelEXT(queue, pLabelInfo, record_obj);
        }
    }
    device_dispatch->debug_report->InsertQueueDebugUtilsLabel(queue, pLabelInfo);
    {
        VVL_ZoneScopedN("Dispatch_vkQueueInsertDebugUtilsLabelEXT");
        device_dispatch->QueueInsertDebugUtilsLabelEXT(queue, pLabelInfo);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkQueueInsertDebugUtilsLabelEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordQueueInsertDebugUtilsLabelEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordQueueInsertDebugUtilsLabelEXT(queue, pLabelInfo, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdBeginDebugUtilsLabelEXT(VkCommandBuffer commandBuffer, const VkDebugUtilsLabelEXT* pLabelInfo) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdBeginDebugUtilsLabelEXT,
                          VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdBeginDebugUtilsLabelEXT");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdBeginDebugUtilsLabelEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdBeginDebugUtilsLabelEXT(commandBuffer, pLabelInfo, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdBeginDebugUtilsLabelEXT);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdBeginDebugUtilsLabelEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdBeginDebugUtilsLabelEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdBeginDebugUtilsLabelEXT(commandBuffer, pLabelInfo, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdBeginDebugUtilsLabelEXT");
        device_dispatch->CmdBeginDebugUtilsLabelEXT(commandBuffer, pLabelInfo);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdBeginDebugUtilsLabelEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdBeginDebugUtilsLabelEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdBeginDebugUtilsLabelEXT(commandBuffer, pLabelInfo, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdEndDebugUtilsLabelEXT(VkCommandBuffer commandBuffer) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdEndDebugUtilsLabelEXT, VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdEndDebugUtilsLabelEXT");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdEndDebugUtilsLabelEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdEndDebugUtilsLabelEXT(commandBuffer, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdEndDebugUtilsLabelEXT);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdEndDebugUtilsLabelEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdEndDebugUtilsLabelEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdEndDebugUtilsLabelEXT(commandBuffer, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdEndDebugUtilsLabelEXT");
        device_dispatch->CmdEndDebugUtilsLabelEXT(commandBuffer);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdEndDebugUtilsLabelEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdEndDebugUtilsLabelEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdEndDebugUtilsLabelEXT(commandBuffer, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdInsertDebugUtilsLabelEXT(VkCommandBuffer commandBuffer, const VkDebugUtilsLabelEXT* pLabelInfo) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdInsertDebugUtilsLabelEXT,
                          VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdInsertDebugUtilsLabelEXT");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdInsertDebugUtilsLabelEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdInsertDebugUtilsLabelEXT(commandBuffer, pLabelInfo, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdInsertDebugUtilsLabelEXT);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdInsertDebugUtilsLabelEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdInsertDebugUtilsLabelEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdInsertDebugUtilsLabelEXT(commandBuffer, pLabelInfo, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdInsertDebugUtilsLabelEXT");
        device_dispatch->CmdInsertDebugUtilsLabelEXT(commandBuffer, pLabelInfo);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdInsertDebugUtilsLabelEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdInsertDebugUtilsLabelEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdInsertDebugUtilsLabelEXT(commandBuffer, pLabelInfo, record_obj);
        }
    }
}

VKAPI_ATTR VkResult VKAPI_CALL CreateDebugUtilsMessengerEXT(VkInstance instance,
                                                            const VkDebugUtilsMessengerCreateInfoEXT* pCreateInfo,
                                                            const VkAllocationCallbacks* pAllocator,
                                                            VkDebugUtilsMessengerEXT* pMessenger) {
    VVL_ZoneScoped;

    auto instance_dispatch = vvl::dispatch::GetData(instance);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCreateDebugUtilsMessengerEXT, VulkanTypedHandle(instance, kVulkanObjectTypeInstance));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCreateDebugUtilsMessengerEXT");
        for (const auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            skip |= vo->PreCallValidateCreateDebugUtilsMessengerEXT(instance, pCreateInfo, pAllocator, pMessenger, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkCreateDebugUtilsMessengerEXT);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCreateDebugUtilsMessengerEXT");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PreCallRecordCreateDebugUtilsMessengerEXT(instance, pCreateInfo, pAllocator, pMessenger, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkCreateDebugUtilsMessengerEXT");
        result = instance_dispatch->CreateDebugUtilsMessengerEXT(instance, pCreateInfo, pAllocator, pMessenger);
    }
    LayerCreateMessengerCallback(instance_dispatch->debug_report, false, pCreateInfo, pMessenger);
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkCreateDebugUtilsMessengerEXT");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PostCallRecordCreateDebugUtilsMessengerEXT(instance, pCreateInfo, pAllocator, pMessenger, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR void VKAPI_CALL DestroyDebugUtilsMessengerEXT(VkInstance instance, VkDebugUtilsMessengerEXT messenger,
                                                         const VkAllocationCallbacks* pAllocator) {
    VVL_ZoneScoped;

    auto instance_dispatch = vvl::dispatch::GetData(instance);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkDestroyDebugUtilsMessengerEXT, VulkanTypedHandle(instance, kVulkanObjectTypeInstance));
    {
        VVL_ZoneScopedN("PreCallValidate_vkDestroyDebugUtilsMessengerEXT");
        for (const auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            skip |= vo->PreCallValidateDestroyDebugUtilsMessengerEXT(instance, messenger, pAllocator, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkDestroyDebugUtilsMessengerEXT);
    {
        VVL_ZoneScopedN("PreCallRecord_vkDestroyDebugUtilsMessengerEXT");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PreCallRecordDestroyDebugUtilsMessengerEXT(instance, messenger, pAllocator, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkDestroyDebugUtilsMessengerEXT");
        instance_dispatch->DestroyDebugUtilsMessengerEXT(instance, messenger, pAllocator);
    }
    LayerDestroyCallback(instance_dispatch->debug_report, messenger);
    {
        VVL_ZoneScopedN("PostCallRecord_vkDestroyDebugUtilsMessengerEXT");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PostCallRecordDestroyDebugUtilsMessengerEXT(instance, messenger, pAllocator, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL SubmitDebugUtilsMessageEXT(VkInstance instance, VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity,
                                                      VkDebugUtilsMessageTypeFlagsEXT messageTypes,
                                                      const VkDebugUtilsMessengerCallbackDataEXT* pCallbackData) {
    VVL_ZoneScoped;

    auto instance_dispatch = vvl::dispatch::GetData(instance);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkSubmitDebugUtilsMessageEXT, VulkanTypedHandle(instance, kVulkanObjectTypeInstance));
    {
        VVL_ZoneScopedN("PreCallValidate_vkSubmitDebugUtilsMessageEXT");
        for (const auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            skip |=
                vo->PreCallValidateSubmitDebugUtilsMessageEXT(instance, messageSeverity, messageTypes, pCallbackData, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkSubmitDebugUtilsMessageEXT);
    {
        VVL_ZoneScopedN("PreCallRecord_vkSubmitDebugUtilsMessageEXT");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PreCallRecordSubmitDebugUtilsMessageEXT(instance, messageSeverity, messageTypes, pCallbackData, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkSubmitDebugUtilsMessageEXT");
        instance_dispatch->SubmitDebugUtilsMessageEXT(instance, messageSeverity, messageTypes, pCallbackData);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkSubmitDebugUtilsMessageEXT");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PostCallRecordSubmitDebugUtilsMessageEXT(instance, messageSeverity, messageTypes, pCallbackData, record_obj);
        }
    }
}

#ifdef VK_USE_PLATFORM_ANDROID_KHR
VKAPI_ATTR VkResult VKAPI_CALL GetAndroidHardwareBufferPropertiesANDROID(VkDevice device, const struct AHardwareBuffer* buffer,
                                                                         VkAndroidHardwareBufferPropertiesANDROID* pProperties) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetAndroidHardwareBufferPropertiesANDROID,
                          VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetAndroidHardwareBufferPropertiesANDROID");
        for (const auto& vo :
             device_dispatch->intercept_vectors[InterceptIdPreCallValidateGetAndroidHardwareBufferPropertiesANDROID]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateGetAndroidHardwareBufferPropertiesANDROID(device, buffer, pProperties, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetAndroidHardwareBufferPropertiesANDROID);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetAndroidHardwareBufferPropertiesANDROID");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordGetAndroidHardwareBufferPropertiesANDROID]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordGetAndroidHardwareBufferPropertiesANDROID(device, buffer, pProperties, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkGetAndroidHardwareBufferPropertiesANDROID");
        result = device_dispatch->GetAndroidHardwareBufferPropertiesANDROID(device, buffer, pProperties);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetAndroidHardwareBufferPropertiesANDROID");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordGetAndroidHardwareBufferPropertiesANDROID]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordGetAndroidHardwareBufferPropertiesANDROID(device, buffer, pProperties, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR VkResult VKAPI_CALL GetMemoryAndroidHardwareBufferANDROID(VkDevice device,
                                                                     const VkMemoryGetAndroidHardwareBufferInfoANDROID* pInfo,
                                                                     struct AHardwareBuffer** pBuffer) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetMemoryAndroidHardwareBufferANDROID, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetMemoryAndroidHardwareBufferANDROID");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateGetMemoryAndroidHardwareBufferANDROID]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateGetMemoryAndroidHardwareBufferANDROID(device, pInfo, pBuffer, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetMemoryAndroidHardwareBufferANDROID);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetMemoryAndroidHardwareBufferANDROID");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordGetMemoryAndroidHardwareBufferANDROID]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordGetMemoryAndroidHardwareBufferANDROID(device, pInfo, pBuffer, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkGetMemoryAndroidHardwareBufferANDROID");
        result = device_dispatch->GetMemoryAndroidHardwareBufferANDROID(device, pInfo, pBuffer);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetMemoryAndroidHardwareBufferANDROID");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordGetMemoryAndroidHardwareBufferANDROID]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordGetMemoryAndroidHardwareBufferANDROID(device, pInfo, pBuffer, record_obj);
        }
    }
    return result;
}

#endif  // VK_USE_PLATFORM_ANDROID_KHR
#ifdef VK_ENABLE_BETA_EXTENSIONS
VKAPI_ATTR VkResult VKAPI_CALL CreateExecutionGraphPipelinesAMDX(VkDevice device, VkPipelineCache pipelineCache,
                                                                 uint32_t createInfoCount,
                                                                 const VkExecutionGraphPipelineCreateInfoAMDX* pCreateInfos,
                                                                 const VkAllocationCallbacks* pAllocator, VkPipeline* pPipelines) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCreateExecutionGraphPipelinesAMDX, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCreateExecutionGraphPipelinesAMDX");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCreateExecutionGraphPipelinesAMDX]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCreateExecutionGraphPipelinesAMDX(device, pipelineCache, createInfoCount, pCreateInfos,
                                                                         pAllocator, pPipelines, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkCreateExecutionGraphPipelinesAMDX);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCreateExecutionGraphPipelinesAMDX");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCreateExecutionGraphPipelinesAMDX]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCreateExecutionGraphPipelinesAMDX(device, pipelineCache, createInfoCount, pCreateInfos, pAllocator,
                                                               pPipelines, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkCreateExecutionGraphPipelinesAMDX");
        result = device_dispatch->CreateExecutionGraphPipelinesAMDX(device, pipelineCache, createInfoCount, pCreateInfos,
                                                                    pAllocator, pPipelines);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkCreateExecutionGraphPipelinesAMDX");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCreateExecutionGraphPipelinesAMDX]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCreateExecutionGraphPipelinesAMDX(device, pipelineCache, createInfoCount, pCreateInfos, pAllocator,
                                                                pPipelines, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR VkResult VKAPI_CALL GetExecutionGraphPipelineScratchSizeAMDX(VkDevice device, VkPipeline executionGraph,
                                                                        VkExecutionGraphPipelineScratchSizeAMDX* pSizeInfo) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetExecutionGraphPipelineScratchSizeAMDX,
                          VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetExecutionGraphPipelineScratchSizeAMDX");
        for (const auto& vo :
             device_dispatch->intercept_vectors[InterceptIdPreCallValidateGetExecutionGraphPipelineScratchSizeAMDX]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateGetExecutionGraphPipelineScratchSizeAMDX(device, executionGraph, pSizeInfo, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetExecutionGraphPipelineScratchSizeAMDX);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetExecutionGraphPipelineScratchSizeAMDX");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordGetExecutionGraphPipelineScratchSizeAMDX]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordGetExecutionGraphPipelineScratchSizeAMDX(device, executionGraph, pSizeInfo, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkGetExecutionGraphPipelineScratchSizeAMDX");
        result = device_dispatch->GetExecutionGraphPipelineScratchSizeAMDX(device, executionGraph, pSizeInfo);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetExecutionGraphPipelineScratchSizeAMDX");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordGetExecutionGraphPipelineScratchSizeAMDX]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordGetExecutionGraphPipelineScratchSizeAMDX(device, executionGraph, pSizeInfo, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR VkResult VKAPI_CALL GetExecutionGraphPipelineNodeIndexAMDX(VkDevice device, VkPipeline executionGraph,
                                                                      const VkPipelineShaderStageNodeCreateInfoAMDX* pNodeInfo,
                                                                      uint32_t* pNodeIndex) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetExecutionGraphPipelineNodeIndexAMDX, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetExecutionGraphPipelineNodeIndexAMDX");
        for (const auto& vo :
             device_dispatch->intercept_vectors[InterceptIdPreCallValidateGetExecutionGraphPipelineNodeIndexAMDX]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |=
                vo->PreCallValidateGetExecutionGraphPipelineNodeIndexAMDX(device, executionGraph, pNodeInfo, pNodeIndex, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetExecutionGraphPipelineNodeIndexAMDX);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetExecutionGraphPipelineNodeIndexAMDX");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordGetExecutionGraphPipelineNodeIndexAMDX]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordGetExecutionGraphPipelineNodeIndexAMDX(device, executionGraph, pNodeInfo, pNodeIndex, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkGetExecutionGraphPipelineNodeIndexAMDX");
        result = device_dispatch->GetExecutionGraphPipelineNodeIndexAMDX(device, executionGraph, pNodeInfo, pNodeIndex);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetExecutionGraphPipelineNodeIndexAMDX");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordGetExecutionGraphPipelineNodeIndexAMDX]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordGetExecutionGraphPipelineNodeIndexAMDX(device, executionGraph, pNodeInfo, pNodeIndex, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR void VKAPI_CALL CmdInitializeGraphScratchMemoryAMDX(VkCommandBuffer commandBuffer, VkPipeline executionGraph,
                                                               VkDeviceAddress scratch, VkDeviceSize scratchSize) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdInitializeGraphScratchMemoryAMDX,
                          VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdInitializeGraphScratchMemoryAMDX");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdInitializeGraphScratchMemoryAMDX]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdInitializeGraphScratchMemoryAMDX(commandBuffer, executionGraph, scratch, scratchSize,
                                                                           error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdInitializeGraphScratchMemoryAMDX);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdInitializeGraphScratchMemoryAMDX");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdInitializeGraphScratchMemoryAMDX]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdInitializeGraphScratchMemoryAMDX(commandBuffer, executionGraph, scratch, scratchSize, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdInitializeGraphScratchMemoryAMDX");
        device_dispatch->CmdInitializeGraphScratchMemoryAMDX(commandBuffer, executionGraph, scratch, scratchSize);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdInitializeGraphScratchMemoryAMDX");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdInitializeGraphScratchMemoryAMDX]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdInitializeGraphScratchMemoryAMDX(commandBuffer, executionGraph, scratch, scratchSize, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdDispatchGraphAMDX(VkCommandBuffer commandBuffer, VkDeviceAddress scratch, VkDeviceSize scratchSize,
                                                const VkDispatchGraphCountInfoAMDX* pCountInfo) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdDispatchGraphAMDX, VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdDispatchGraphAMDX");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdDispatchGraphAMDX]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdDispatchGraphAMDX(commandBuffer, scratch, scratchSize, pCountInfo, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdDispatchGraphAMDX);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdDispatchGraphAMDX");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdDispatchGraphAMDX]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdDispatchGraphAMDX(commandBuffer, scratch, scratchSize, pCountInfo, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdDispatchGraphAMDX");
        device_dispatch->CmdDispatchGraphAMDX(commandBuffer, scratch, scratchSize, pCountInfo);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdDispatchGraphAMDX");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdDispatchGraphAMDX]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdDispatchGraphAMDX(commandBuffer, scratch, scratchSize, pCountInfo, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdDispatchGraphIndirectAMDX(VkCommandBuffer commandBuffer, VkDeviceAddress scratch,
                                                        VkDeviceSize scratchSize, const VkDispatchGraphCountInfoAMDX* pCountInfo) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdDispatchGraphIndirectAMDX,
                          VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdDispatchGraphIndirectAMDX");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdDispatchGraphIndirectAMDX]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdDispatchGraphIndirectAMDX(commandBuffer, scratch, scratchSize, pCountInfo, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdDispatchGraphIndirectAMDX);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdDispatchGraphIndirectAMDX");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdDispatchGraphIndirectAMDX]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdDispatchGraphIndirectAMDX(commandBuffer, scratch, scratchSize, pCountInfo, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdDispatchGraphIndirectAMDX");
        device_dispatch->CmdDispatchGraphIndirectAMDX(commandBuffer, scratch, scratchSize, pCountInfo);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdDispatchGraphIndirectAMDX");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdDispatchGraphIndirectAMDX]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdDispatchGraphIndirectAMDX(commandBuffer, scratch, scratchSize, pCountInfo, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdDispatchGraphIndirectCountAMDX(VkCommandBuffer commandBuffer, VkDeviceAddress scratch,
                                                             VkDeviceSize scratchSize, VkDeviceAddress countInfo) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdDispatchGraphIndirectCountAMDX,
                          VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdDispatchGraphIndirectCountAMDX");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdDispatchGraphIndirectCountAMDX]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdDispatchGraphIndirectCountAMDX(commandBuffer, scratch, scratchSize, countInfo, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdDispatchGraphIndirectCountAMDX);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdDispatchGraphIndirectCountAMDX");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdDispatchGraphIndirectCountAMDX]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdDispatchGraphIndirectCountAMDX(commandBuffer, scratch, scratchSize, countInfo, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdDispatchGraphIndirectCountAMDX");
        device_dispatch->CmdDispatchGraphIndirectCountAMDX(commandBuffer, scratch, scratchSize, countInfo);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdDispatchGraphIndirectCountAMDX");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdDispatchGraphIndirectCountAMDX]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdDispatchGraphIndirectCountAMDX(commandBuffer, scratch, scratchSize, countInfo, record_obj);
        }
    }
}

#endif  // VK_ENABLE_BETA_EXTENSIONS
VKAPI_ATTR VkResult VKAPI_CALL WriteSamplerDescriptorsEXT(VkDevice device, uint32_t samplerCount,
                                                          const VkSamplerCreateInfo* pSamplers,
                                                          const VkHostAddressRangeEXT* pDescriptors) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkWriteSamplerDescriptorsEXT, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkWriteSamplerDescriptorsEXT");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateWriteSamplerDescriptorsEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateWriteSamplerDescriptorsEXT(device, samplerCount, pSamplers, pDescriptors, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkWriteSamplerDescriptorsEXT);
    {
        VVL_ZoneScopedN("PreCallRecord_vkWriteSamplerDescriptorsEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordWriteSamplerDescriptorsEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordWriteSamplerDescriptorsEXT(device, samplerCount, pSamplers, pDescriptors, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkWriteSamplerDescriptorsEXT");
        result = device_dispatch->WriteSamplerDescriptorsEXT(device, samplerCount, pSamplers, pDescriptors);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkWriteSamplerDescriptorsEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordWriteSamplerDescriptorsEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordWriteSamplerDescriptorsEXT(device, samplerCount, pSamplers, pDescriptors, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR VkResult VKAPI_CALL WriteResourceDescriptorsEXT(VkDevice device, uint32_t resourceCount,
                                                           const VkResourceDescriptorInfoEXT* pResources,
                                                           const VkHostAddressRangeEXT* pDescriptors) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkWriteResourceDescriptorsEXT, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkWriteResourceDescriptorsEXT");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateWriteResourceDescriptorsEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateWriteResourceDescriptorsEXT(device, resourceCount, pResources, pDescriptors, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkWriteResourceDescriptorsEXT);
    {
        VVL_ZoneScopedN("PreCallRecord_vkWriteResourceDescriptorsEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordWriteResourceDescriptorsEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordWriteResourceDescriptorsEXT(device, resourceCount, pResources, pDescriptors, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkWriteResourceDescriptorsEXT");
        result = device_dispatch->WriteResourceDescriptorsEXT(device, resourceCount, pResources, pDescriptors);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkWriteResourceDescriptorsEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordWriteResourceDescriptorsEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordWriteResourceDescriptorsEXT(device, resourceCount, pResources, pDescriptors, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR void VKAPI_CALL CmdBindSamplerHeapEXT(VkCommandBuffer commandBuffer, const VkBindHeapInfoEXT* pBindInfo) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdBindSamplerHeapEXT, VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdBindSamplerHeapEXT");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdBindSamplerHeapEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdBindSamplerHeapEXT(commandBuffer, pBindInfo, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdBindSamplerHeapEXT);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdBindSamplerHeapEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdBindSamplerHeapEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdBindSamplerHeapEXT(commandBuffer, pBindInfo, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdBindSamplerHeapEXT");
        device_dispatch->CmdBindSamplerHeapEXT(commandBuffer, pBindInfo);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdBindSamplerHeapEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdBindSamplerHeapEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdBindSamplerHeapEXT(commandBuffer, pBindInfo, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdBindResourceHeapEXT(VkCommandBuffer commandBuffer, const VkBindHeapInfoEXT* pBindInfo) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdBindResourceHeapEXT, VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdBindResourceHeapEXT");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdBindResourceHeapEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdBindResourceHeapEXT(commandBuffer, pBindInfo, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdBindResourceHeapEXT);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdBindResourceHeapEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdBindResourceHeapEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdBindResourceHeapEXT(commandBuffer, pBindInfo, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdBindResourceHeapEXT");
        device_dispatch->CmdBindResourceHeapEXT(commandBuffer, pBindInfo);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdBindResourceHeapEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdBindResourceHeapEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdBindResourceHeapEXT(commandBuffer, pBindInfo, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdPushDataEXT(VkCommandBuffer commandBuffer, const VkPushDataInfoEXT* pPushDataInfo) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdPushDataEXT, VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdPushDataEXT");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdPushDataEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdPushDataEXT(commandBuffer, pPushDataInfo, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdPushDataEXT);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdPushDataEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdPushDataEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdPushDataEXT(commandBuffer, pPushDataInfo, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdPushDataEXT");
        device_dispatch->CmdPushDataEXT(commandBuffer, pPushDataInfo);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdPushDataEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdPushDataEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdPushDataEXT(commandBuffer, pPushDataInfo, record_obj);
        }
    }
}

VKAPI_ATTR VkResult VKAPI_CALL GetImageOpaqueCaptureDataEXT(VkDevice device, uint32_t imageCount, const VkImage* pImages,
                                                            VkHostAddressRangeEXT* pDatas) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetImageOpaqueCaptureDataEXT, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetImageOpaqueCaptureDataEXT");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateGetImageOpaqueCaptureDataEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateGetImageOpaqueCaptureDataEXT(device, imageCount, pImages, pDatas, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetImageOpaqueCaptureDataEXT);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetImageOpaqueCaptureDataEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordGetImageOpaqueCaptureDataEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordGetImageOpaqueCaptureDataEXT(device, imageCount, pImages, pDatas, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkGetImageOpaqueCaptureDataEXT");
        result = device_dispatch->GetImageOpaqueCaptureDataEXT(device, imageCount, pImages, pDatas);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetImageOpaqueCaptureDataEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordGetImageOpaqueCaptureDataEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordGetImageOpaqueCaptureDataEXT(device, imageCount, pImages, pDatas, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR VkDeviceSize VKAPI_CALL GetPhysicalDeviceDescriptorSizeEXT(VkPhysicalDevice physicalDevice,
                                                                      VkDescriptorType descriptorType) {
    VVL_ZoneScoped;

    auto instance_dispatch = vvl::dispatch::GetData(physicalDevice);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetPhysicalDeviceDescriptorSizeEXT,
                          VulkanTypedHandle(physicalDevice, kVulkanObjectTypePhysicalDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetPhysicalDeviceDescriptorSizeEXT");
        for (const auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            skip |= vo->PreCallValidateGetPhysicalDeviceDescriptorSizeEXT(physicalDevice, descriptorType, error_obj);
            if (skip) return 0;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetPhysicalDeviceDescriptorSizeEXT);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetPhysicalDeviceDescriptorSizeEXT");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PreCallRecordGetPhysicalDeviceDescriptorSizeEXT(physicalDevice, descriptorType, record_obj);
        }
    }
    VkDeviceSize result;
    {
        VVL_ZoneScopedN("Dispatch_vkGetPhysicalDeviceDescriptorSizeEXT");
        result = instance_dispatch->GetPhysicalDeviceDescriptorSizeEXT(physicalDevice, descriptorType);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetPhysicalDeviceDescriptorSizeEXT");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PostCallRecordGetPhysicalDeviceDescriptorSizeEXT(physicalDevice, descriptorType, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR VkResult VKAPI_CALL RegisterCustomBorderColorEXT(VkDevice device,
                                                            const VkSamplerCustomBorderColorCreateInfoEXT* pBorderColor,
                                                            VkBool32 requestIndex, uint32_t* pIndex) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkRegisterCustomBorderColorEXT, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkRegisterCustomBorderColorEXT");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateRegisterCustomBorderColorEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateRegisterCustomBorderColorEXT(device, pBorderColor, requestIndex, pIndex, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkRegisterCustomBorderColorEXT);
    {
        VVL_ZoneScopedN("PreCallRecord_vkRegisterCustomBorderColorEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordRegisterCustomBorderColorEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordRegisterCustomBorderColorEXT(device, pBorderColor, requestIndex, pIndex, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkRegisterCustomBorderColorEXT");
        result = device_dispatch->RegisterCustomBorderColorEXT(device, pBorderColor, requestIndex, pIndex);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkRegisterCustomBorderColorEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordRegisterCustomBorderColorEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordRegisterCustomBorderColorEXT(device, pBorderColor, requestIndex, pIndex, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR void VKAPI_CALL UnregisterCustomBorderColorEXT(VkDevice device, uint32_t index) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkUnregisterCustomBorderColorEXT, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkUnregisterCustomBorderColorEXT");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateUnregisterCustomBorderColorEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateUnregisterCustomBorderColorEXT(device, index, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkUnregisterCustomBorderColorEXT);
    {
        VVL_ZoneScopedN("PreCallRecord_vkUnregisterCustomBorderColorEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordUnregisterCustomBorderColorEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordUnregisterCustomBorderColorEXT(device, index, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkUnregisterCustomBorderColorEXT");
        device_dispatch->UnregisterCustomBorderColorEXT(device, index);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkUnregisterCustomBorderColorEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordUnregisterCustomBorderColorEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordUnregisterCustomBorderColorEXT(device, index, record_obj);
        }
    }
}

VKAPI_ATTR VkResult VKAPI_CALL GetTensorOpaqueCaptureDataARM(VkDevice device, uint32_t tensorCount, const VkTensorARM* pTensors,
                                                             VkHostAddressRangeEXT* pDatas) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetTensorOpaqueCaptureDataARM, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetTensorOpaqueCaptureDataARM");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateGetTensorOpaqueCaptureDataARM]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateGetTensorOpaqueCaptureDataARM(device, tensorCount, pTensors, pDatas, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetTensorOpaqueCaptureDataARM);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetTensorOpaqueCaptureDataARM");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordGetTensorOpaqueCaptureDataARM]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordGetTensorOpaqueCaptureDataARM(device, tensorCount, pTensors, pDatas, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkGetTensorOpaqueCaptureDataARM");
        result = device_dispatch->GetTensorOpaqueCaptureDataARM(device, tensorCount, pTensors, pDatas);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetTensorOpaqueCaptureDataARM");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordGetTensorOpaqueCaptureDataARM]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordGetTensorOpaqueCaptureDataARM(device, tensorCount, pTensors, pDatas, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR void VKAPI_CALL CmdSetSampleLocationsEXT(VkCommandBuffer commandBuffer,
                                                    const VkSampleLocationsInfoEXT* pSampleLocationsInfo) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdSetSampleLocationsEXT, VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdSetSampleLocationsEXT");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdSetSampleLocationsEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdSetSampleLocationsEXT(commandBuffer, pSampleLocationsInfo, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdSetSampleLocationsEXT);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdSetSampleLocationsEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdSetSampleLocationsEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdSetSampleLocationsEXT(commandBuffer, pSampleLocationsInfo, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdSetSampleLocationsEXT");
        device_dispatch->CmdSetSampleLocationsEXT(commandBuffer, pSampleLocationsInfo);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdSetSampleLocationsEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdSetSampleLocationsEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdSetSampleLocationsEXT(commandBuffer, pSampleLocationsInfo, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL GetPhysicalDeviceMultisamplePropertiesEXT(VkPhysicalDevice physicalDevice, VkSampleCountFlagBits samples,
                                                                     VkMultisamplePropertiesEXT* pMultisampleProperties) {
    VVL_ZoneScoped;

    auto instance_dispatch = vvl::dispatch::GetData(physicalDevice);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetPhysicalDeviceMultisamplePropertiesEXT,
                          VulkanTypedHandle(physicalDevice, kVulkanObjectTypePhysicalDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetPhysicalDeviceMultisamplePropertiesEXT");
        for (const auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            skip |= vo->PreCallValidateGetPhysicalDeviceMultisamplePropertiesEXT(physicalDevice, samples, pMultisampleProperties,
                                                                                 error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetPhysicalDeviceMultisamplePropertiesEXT);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetPhysicalDeviceMultisamplePropertiesEXT");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PreCallRecordGetPhysicalDeviceMultisamplePropertiesEXT(physicalDevice, samples, pMultisampleProperties, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkGetPhysicalDeviceMultisamplePropertiesEXT");
        instance_dispatch->GetPhysicalDeviceMultisamplePropertiesEXT(physicalDevice, samples, pMultisampleProperties);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetPhysicalDeviceMultisamplePropertiesEXT");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PostCallRecordGetPhysicalDeviceMultisamplePropertiesEXT(physicalDevice, samples, pMultisampleProperties,
                                                                        record_obj);
        }
    }
}

VKAPI_ATTR VkResult VKAPI_CALL GetImageDrmFormatModifierPropertiesEXT(VkDevice device, VkImage image,
                                                                      VkImageDrmFormatModifierPropertiesEXT* pProperties) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetImageDrmFormatModifierPropertiesEXT, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetImageDrmFormatModifierPropertiesEXT");
        for (const auto& vo :
             device_dispatch->intercept_vectors[InterceptIdPreCallValidateGetImageDrmFormatModifierPropertiesEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateGetImageDrmFormatModifierPropertiesEXT(device, image, pProperties, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetImageDrmFormatModifierPropertiesEXT);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetImageDrmFormatModifierPropertiesEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordGetImageDrmFormatModifierPropertiesEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordGetImageDrmFormatModifierPropertiesEXT(device, image, pProperties, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkGetImageDrmFormatModifierPropertiesEXT");
        result = device_dispatch->GetImageDrmFormatModifierPropertiesEXT(device, image, pProperties);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetImageDrmFormatModifierPropertiesEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordGetImageDrmFormatModifierPropertiesEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordGetImageDrmFormatModifierPropertiesEXT(device, image, pProperties, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR void VKAPI_CALL CmdBindShadingRateImageNV(VkCommandBuffer commandBuffer, VkImageView imageView,
                                                     VkImageLayout imageLayout) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdBindShadingRateImageNV, VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdBindShadingRateImageNV");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdBindShadingRateImageNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdBindShadingRateImageNV(commandBuffer, imageView, imageLayout, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdBindShadingRateImageNV);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdBindShadingRateImageNV");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdBindShadingRateImageNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdBindShadingRateImageNV(commandBuffer, imageView, imageLayout, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdBindShadingRateImageNV");
        device_dispatch->CmdBindShadingRateImageNV(commandBuffer, imageView, imageLayout);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdBindShadingRateImageNV");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdBindShadingRateImageNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdBindShadingRateImageNV(commandBuffer, imageView, imageLayout, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdSetViewportShadingRatePaletteNV(VkCommandBuffer commandBuffer, uint32_t firstViewport,
                                                              uint32_t viewportCount,
                                                              const VkShadingRatePaletteNV* pShadingRatePalettes) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdSetViewportShadingRatePaletteNV,
                          VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdSetViewportShadingRatePaletteNV");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdSetViewportShadingRatePaletteNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdSetViewportShadingRatePaletteNV(commandBuffer, firstViewport, viewportCount,
                                                                          pShadingRatePalettes, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdSetViewportShadingRatePaletteNV);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdSetViewportShadingRatePaletteNV");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdSetViewportShadingRatePaletteNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdSetViewportShadingRatePaletteNV(commandBuffer, firstViewport, viewportCount, pShadingRatePalettes,
                                                                record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdSetViewportShadingRatePaletteNV");
        device_dispatch->CmdSetViewportShadingRatePaletteNV(commandBuffer, firstViewport, viewportCount, pShadingRatePalettes);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdSetViewportShadingRatePaletteNV");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdSetViewportShadingRatePaletteNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdSetViewportShadingRatePaletteNV(commandBuffer, firstViewport, viewportCount, pShadingRatePalettes,
                                                                 record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdSetCoarseSampleOrderNV(VkCommandBuffer commandBuffer, VkCoarseSampleOrderTypeNV sampleOrderType,
                                                     uint32_t customSampleOrderCount,
                                                     const VkCoarseSampleOrderCustomNV* pCustomSampleOrders) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdSetCoarseSampleOrderNV, VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdSetCoarseSampleOrderNV");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdSetCoarseSampleOrderNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdSetCoarseSampleOrderNV(commandBuffer, sampleOrderType, customSampleOrderCount,
                                                                 pCustomSampleOrders, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdSetCoarseSampleOrderNV);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdSetCoarseSampleOrderNV");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdSetCoarseSampleOrderNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdSetCoarseSampleOrderNV(commandBuffer, sampleOrderType, customSampleOrderCount, pCustomSampleOrders,
                                                       record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdSetCoarseSampleOrderNV");
        device_dispatch->CmdSetCoarseSampleOrderNV(commandBuffer, sampleOrderType, customSampleOrderCount, pCustomSampleOrders);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdSetCoarseSampleOrderNV");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdSetCoarseSampleOrderNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdSetCoarseSampleOrderNV(commandBuffer, sampleOrderType, customSampleOrderCount, pCustomSampleOrders,
                                                        record_obj);
        }
    }
}

VKAPI_ATTR VkResult VKAPI_CALL CreateAccelerationStructureNV(VkDevice device,
                                                             const VkAccelerationStructureCreateInfoNV* pCreateInfo,
                                                             const VkAllocationCallbacks* pAllocator,
                                                             VkAccelerationStructureNV* pAccelerationStructure) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCreateAccelerationStructureNV, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCreateAccelerationStructureNV");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCreateAccelerationStructureNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCreateAccelerationStructureNV(device, pCreateInfo, pAllocator, pAccelerationStructure,
                                                                     error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkCreateAccelerationStructureNV);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCreateAccelerationStructureNV");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCreateAccelerationStructureNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCreateAccelerationStructureNV(device, pCreateInfo, pAllocator, pAccelerationStructure, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkCreateAccelerationStructureNV");
        result = device_dispatch->CreateAccelerationStructureNV(device, pCreateInfo, pAllocator, pAccelerationStructure);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkCreateAccelerationStructureNV");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCreateAccelerationStructureNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCreateAccelerationStructureNV(device, pCreateInfo, pAllocator, pAccelerationStructure, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR void VKAPI_CALL DestroyAccelerationStructureNV(VkDevice device, VkAccelerationStructureNV accelerationStructure,
                                                          const VkAllocationCallbacks* pAllocator) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkDestroyAccelerationStructureNV, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkDestroyAccelerationStructureNV");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateDestroyAccelerationStructureNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateDestroyAccelerationStructureNV(device, accelerationStructure, pAllocator, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkDestroyAccelerationStructureNV);
    {
        VVL_ZoneScopedN("PreCallRecord_vkDestroyAccelerationStructureNV");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordDestroyAccelerationStructureNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordDestroyAccelerationStructureNV(device, accelerationStructure, pAllocator, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkDestroyAccelerationStructureNV");
        device_dispatch->DestroyAccelerationStructureNV(device, accelerationStructure, pAllocator);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkDestroyAccelerationStructureNV");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordDestroyAccelerationStructureNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordDestroyAccelerationStructureNV(device, accelerationStructure, pAllocator, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL GetAccelerationStructureMemoryRequirementsNV(
    VkDevice device, const VkAccelerationStructureMemoryRequirementsInfoNV* pInfo, VkMemoryRequirements2KHR* pMemoryRequirements) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetAccelerationStructureMemoryRequirementsNV,
                          VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetAccelerationStructureMemoryRequirementsNV");
        for (const auto& vo :
             device_dispatch->intercept_vectors[InterceptIdPreCallValidateGetAccelerationStructureMemoryRequirementsNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateGetAccelerationStructureMemoryRequirementsNV(device, pInfo, pMemoryRequirements, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetAccelerationStructureMemoryRequirementsNV);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetAccelerationStructureMemoryRequirementsNV");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordGetAccelerationStructureMemoryRequirementsNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordGetAccelerationStructureMemoryRequirementsNV(device, pInfo, pMemoryRequirements, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkGetAccelerationStructureMemoryRequirementsNV");
        device_dispatch->GetAccelerationStructureMemoryRequirementsNV(device, pInfo, pMemoryRequirements);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetAccelerationStructureMemoryRequirementsNV");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordGetAccelerationStructureMemoryRequirementsNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordGetAccelerationStructureMemoryRequirementsNV(device, pInfo, pMemoryRequirements, record_obj);
        }
    }
}

VKAPI_ATTR VkResult VKAPI_CALL BindAccelerationStructureMemoryNV(VkDevice device, uint32_t bindInfoCount,
                                                                 const VkBindAccelerationStructureMemoryInfoNV* pBindInfos) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkBindAccelerationStructureMemoryNV, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkBindAccelerationStructureMemoryNV");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateBindAccelerationStructureMemoryNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateBindAccelerationStructureMemoryNV(device, bindInfoCount, pBindInfos, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkBindAccelerationStructureMemoryNV);
    {
        VVL_ZoneScopedN("PreCallRecord_vkBindAccelerationStructureMemoryNV");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordBindAccelerationStructureMemoryNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordBindAccelerationStructureMemoryNV(device, bindInfoCount, pBindInfos, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkBindAccelerationStructureMemoryNV");
        result = device_dispatch->BindAccelerationStructureMemoryNV(device, bindInfoCount, pBindInfos);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkBindAccelerationStructureMemoryNV");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordBindAccelerationStructureMemoryNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordBindAccelerationStructureMemoryNV(device, bindInfoCount, pBindInfos, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR void VKAPI_CALL CmdBuildAccelerationStructureNV(VkCommandBuffer commandBuffer,
                                                           const VkAccelerationStructureInfoNV* pInfo, VkBuffer instanceData,
                                                           VkDeviceSize instanceOffset, VkBool32 update,
                                                           VkAccelerationStructureNV dst, VkAccelerationStructureNV src,
                                                           VkBuffer scratch, VkDeviceSize scratchOffset) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdBuildAccelerationStructureNV,
                          VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdBuildAccelerationStructureNV");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdBuildAccelerationStructureNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdBuildAccelerationStructureNV(commandBuffer, pInfo, instanceData, instanceOffset, update,
                                                                       dst, src, scratch, scratchOffset, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdBuildAccelerationStructureNV);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdBuildAccelerationStructureNV");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdBuildAccelerationStructureNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdBuildAccelerationStructureNV(commandBuffer, pInfo, instanceData, instanceOffset, update, dst, src,
                                                             scratch, scratchOffset, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdBuildAccelerationStructureNV");
        device_dispatch->CmdBuildAccelerationStructureNV(commandBuffer, pInfo, instanceData, instanceOffset, update, dst, src,
                                                         scratch, scratchOffset);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdBuildAccelerationStructureNV");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdBuildAccelerationStructureNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdBuildAccelerationStructureNV(commandBuffer, pInfo, instanceData, instanceOffset, update, dst, src,
                                                              scratch, scratchOffset, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdCopyAccelerationStructureNV(VkCommandBuffer commandBuffer, VkAccelerationStructureNV dst,
                                                          VkAccelerationStructureNV src, VkCopyAccelerationStructureModeKHR mode) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdCopyAccelerationStructureNV,
                          VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdCopyAccelerationStructureNV");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdCopyAccelerationStructureNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdCopyAccelerationStructureNV(commandBuffer, dst, src, mode, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdCopyAccelerationStructureNV);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdCopyAccelerationStructureNV");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdCopyAccelerationStructureNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdCopyAccelerationStructureNV(commandBuffer, dst, src, mode, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdCopyAccelerationStructureNV");
        device_dispatch->CmdCopyAccelerationStructureNV(commandBuffer, dst, src, mode);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdCopyAccelerationStructureNV");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdCopyAccelerationStructureNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdCopyAccelerationStructureNV(commandBuffer, dst, src, mode, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdTraceRaysNV(VkCommandBuffer commandBuffer, VkBuffer raygenShaderBindingTableBuffer,
                                          VkDeviceSize raygenShaderBindingOffset, VkBuffer missShaderBindingTableBuffer,
                                          VkDeviceSize missShaderBindingOffset, VkDeviceSize missShaderBindingStride,
                                          VkBuffer hitShaderBindingTableBuffer, VkDeviceSize hitShaderBindingOffset,
                                          VkDeviceSize hitShaderBindingStride, VkBuffer callableShaderBindingTableBuffer,
                                          VkDeviceSize callableShaderBindingOffset, VkDeviceSize callableShaderBindingStride,
                                          uint32_t width, uint32_t height, uint32_t depth) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdTraceRaysNV, VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdTraceRaysNV");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdTraceRaysNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdTraceRaysNV(
                commandBuffer, raygenShaderBindingTableBuffer, raygenShaderBindingOffset, missShaderBindingTableBuffer,
                missShaderBindingOffset, missShaderBindingStride, hitShaderBindingTableBuffer, hitShaderBindingOffset,
                hitShaderBindingStride, callableShaderBindingTableBuffer, callableShaderBindingOffset, callableShaderBindingStride,
                width, height, depth, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdTraceRaysNV);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdTraceRaysNV");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdTraceRaysNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdTraceRaysNV(commandBuffer, raygenShaderBindingTableBuffer, raygenShaderBindingOffset,
                                            missShaderBindingTableBuffer, missShaderBindingOffset, missShaderBindingStride,
                                            hitShaderBindingTableBuffer, hitShaderBindingOffset, hitShaderBindingStride,
                                            callableShaderBindingTableBuffer, callableShaderBindingOffset,
                                            callableShaderBindingStride, width, height, depth, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdTraceRaysNV");
        device_dispatch->CmdTraceRaysNV(commandBuffer, raygenShaderBindingTableBuffer, raygenShaderBindingOffset,
                                        missShaderBindingTableBuffer, missShaderBindingOffset, missShaderBindingStride,
                                        hitShaderBindingTableBuffer, hitShaderBindingOffset, hitShaderBindingStride,
                                        callableShaderBindingTableBuffer, callableShaderBindingOffset, callableShaderBindingStride,
                                        width, height, depth);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdTraceRaysNV");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdTraceRaysNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdTraceRaysNV(commandBuffer, raygenShaderBindingTableBuffer, raygenShaderBindingOffset,
                                             missShaderBindingTableBuffer, missShaderBindingOffset, missShaderBindingStride,
                                             hitShaderBindingTableBuffer, hitShaderBindingOffset, hitShaderBindingStride,
                                             callableShaderBindingTableBuffer, callableShaderBindingOffset,
                                             callableShaderBindingStride, width, height, depth, record_obj);
        }
    }
}

VKAPI_ATTR VkResult VKAPI_CALL GetRayTracingShaderGroupHandlesKHR(VkDevice device, VkPipeline pipeline, uint32_t firstGroup,
                                                                  uint32_t groupCount, size_t dataSize, void* pData) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetRayTracingShaderGroupHandlesKHR, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetRayTracingShaderGroupHandlesKHR");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateGetRayTracingShaderGroupHandlesKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateGetRayTracingShaderGroupHandlesKHR(device, pipeline, firstGroup, groupCount, dataSize, pData,
                                                                          error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetRayTracingShaderGroupHandlesKHR);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetRayTracingShaderGroupHandlesKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordGetRayTracingShaderGroupHandlesKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordGetRayTracingShaderGroupHandlesKHR(device, pipeline, firstGroup, groupCount, dataSize, pData,
                                                                record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkGetRayTracingShaderGroupHandlesKHR");
        result = device_dispatch->GetRayTracingShaderGroupHandlesKHR(device, pipeline, firstGroup, groupCount, dataSize, pData);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetRayTracingShaderGroupHandlesKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordGetRayTracingShaderGroupHandlesKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordGetRayTracingShaderGroupHandlesKHR(device, pipeline, firstGroup, groupCount, dataSize, pData,
                                                                 record_obj);
        }
    }
    return result;
}

VKAPI_ATTR VkResult VKAPI_CALL GetRayTracingShaderGroupHandlesNV(VkDevice device, VkPipeline pipeline, uint32_t firstGroup,
                                                                 uint32_t groupCount, size_t dataSize, void* pData) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetRayTracingShaderGroupHandlesNV, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetRayTracingShaderGroupHandlesNV");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateGetRayTracingShaderGroupHandlesNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateGetRayTracingShaderGroupHandlesNV(device, pipeline, firstGroup, groupCount, dataSize, pData,
                                                                         error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetRayTracingShaderGroupHandlesNV);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetRayTracingShaderGroupHandlesNV");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordGetRayTracingShaderGroupHandlesNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordGetRayTracingShaderGroupHandlesNV(device, pipeline, firstGroup, groupCount, dataSize, pData,
                                                               record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkGetRayTracingShaderGroupHandlesNV");
        result = device_dispatch->GetRayTracingShaderGroupHandlesNV(device, pipeline, firstGroup, groupCount, dataSize, pData);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetRayTracingShaderGroupHandlesNV");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordGetRayTracingShaderGroupHandlesNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordGetRayTracingShaderGroupHandlesNV(device, pipeline, firstGroup, groupCount, dataSize, pData,
                                                                record_obj);
        }
    }
    return result;
}

VKAPI_ATTR VkResult VKAPI_CALL GetAccelerationStructureHandleNV(VkDevice device, VkAccelerationStructureNV accelerationStructure,
                                                                size_t dataSize, void* pData) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetAccelerationStructureHandleNV, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetAccelerationStructureHandleNV");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateGetAccelerationStructureHandleNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateGetAccelerationStructureHandleNV(device, accelerationStructure, dataSize, pData, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetAccelerationStructureHandleNV);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetAccelerationStructureHandleNV");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordGetAccelerationStructureHandleNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordGetAccelerationStructureHandleNV(device, accelerationStructure, dataSize, pData, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkGetAccelerationStructureHandleNV");
        result = device_dispatch->GetAccelerationStructureHandleNV(device, accelerationStructure, dataSize, pData);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetAccelerationStructureHandleNV");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordGetAccelerationStructureHandleNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordGetAccelerationStructureHandleNV(device, accelerationStructure, dataSize, pData, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR void VKAPI_CALL CmdWriteAccelerationStructuresPropertiesNV(VkCommandBuffer commandBuffer,
                                                                      uint32_t accelerationStructureCount,
                                                                      const VkAccelerationStructureNV* pAccelerationStructures,
                                                                      VkQueryType queryType, VkQueryPool queryPool,
                                                                      uint32_t firstQuery) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdWriteAccelerationStructuresPropertiesNV,
                          VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdWriteAccelerationStructuresPropertiesNV");
        for (const auto& vo :
             device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdWriteAccelerationStructuresPropertiesNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdWriteAccelerationStructuresPropertiesNV(
                commandBuffer, accelerationStructureCount, pAccelerationStructures, queryType, queryPool, firstQuery, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdWriteAccelerationStructuresPropertiesNV);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdWriteAccelerationStructuresPropertiesNV");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdWriteAccelerationStructuresPropertiesNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdWriteAccelerationStructuresPropertiesNV(
                commandBuffer, accelerationStructureCount, pAccelerationStructures, queryType, queryPool, firstQuery, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdWriteAccelerationStructuresPropertiesNV");
        device_dispatch->CmdWriteAccelerationStructuresPropertiesNV(commandBuffer, accelerationStructureCount,
                                                                    pAccelerationStructures, queryType, queryPool, firstQuery);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdWriteAccelerationStructuresPropertiesNV");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdWriteAccelerationStructuresPropertiesNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdWriteAccelerationStructuresPropertiesNV(
                commandBuffer, accelerationStructureCount, pAccelerationStructures, queryType, queryPool, firstQuery, record_obj);
        }
    }
}

VKAPI_ATTR VkResult VKAPI_CALL CompileDeferredNV(VkDevice device, VkPipeline pipeline, uint32_t shader) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCompileDeferredNV, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCompileDeferredNV");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCompileDeferredNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCompileDeferredNV(device, pipeline, shader, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkCompileDeferredNV);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCompileDeferredNV");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCompileDeferredNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCompileDeferredNV(device, pipeline, shader, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkCompileDeferredNV");
        result = device_dispatch->CompileDeferredNV(device, pipeline, shader);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkCompileDeferredNV");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCompileDeferredNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCompileDeferredNV(device, pipeline, shader, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR VkResult VKAPI_CALL GetMemoryHostPointerPropertiesEXT(VkDevice device, VkExternalMemoryHandleTypeFlagBits handleType,
                                                                 const void* pHostPointer,
                                                                 VkMemoryHostPointerPropertiesEXT* pMemoryHostPointerProperties) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetMemoryHostPointerPropertiesEXT, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetMemoryHostPointerPropertiesEXT");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateGetMemoryHostPointerPropertiesEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateGetMemoryHostPointerPropertiesEXT(device, handleType, pHostPointer,
                                                                         pMemoryHostPointerProperties, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetMemoryHostPointerPropertiesEXT);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetMemoryHostPointerPropertiesEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordGetMemoryHostPointerPropertiesEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordGetMemoryHostPointerPropertiesEXT(device, handleType, pHostPointer, pMemoryHostPointerProperties,
                                                               record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkGetMemoryHostPointerPropertiesEXT");
        result = device_dispatch->GetMemoryHostPointerPropertiesEXT(device, handleType, pHostPointer, pMemoryHostPointerProperties);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetMemoryHostPointerPropertiesEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordGetMemoryHostPointerPropertiesEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordGetMemoryHostPointerPropertiesEXT(device, handleType, pHostPointer, pMemoryHostPointerProperties,
                                                                record_obj);
        }
    }
    return result;
}

VKAPI_ATTR void VKAPI_CALL CmdWriteBufferMarkerAMD(VkCommandBuffer commandBuffer, VkPipelineStageFlagBits pipelineStage,
                                                   VkBuffer dstBuffer, VkDeviceSize dstOffset, uint32_t marker) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdWriteBufferMarkerAMD, VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdWriteBufferMarkerAMD");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdWriteBufferMarkerAMD]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |=
                vo->PreCallValidateCmdWriteBufferMarkerAMD(commandBuffer, pipelineStage, dstBuffer, dstOffset, marker, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdWriteBufferMarkerAMD);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdWriteBufferMarkerAMD");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdWriteBufferMarkerAMD]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdWriteBufferMarkerAMD(commandBuffer, pipelineStage, dstBuffer, dstOffset, marker, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdWriteBufferMarkerAMD");
        device_dispatch->CmdWriteBufferMarkerAMD(commandBuffer, pipelineStage, dstBuffer, dstOffset, marker);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdWriteBufferMarkerAMD");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdWriteBufferMarkerAMD]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdWriteBufferMarkerAMD(commandBuffer, pipelineStage, dstBuffer, dstOffset, marker, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdWriteBufferMarker2AMD(VkCommandBuffer commandBuffer, VkPipelineStageFlags2 stage, VkBuffer dstBuffer,
                                                    VkDeviceSize dstOffset, uint32_t marker) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdWriteBufferMarker2AMD, VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdWriteBufferMarker2AMD");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdWriteBufferMarker2AMD]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdWriteBufferMarker2AMD(commandBuffer, stage, dstBuffer, dstOffset, marker, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdWriteBufferMarker2AMD);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdWriteBufferMarker2AMD");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdWriteBufferMarker2AMD]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdWriteBufferMarker2AMD(commandBuffer, stage, dstBuffer, dstOffset, marker, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdWriteBufferMarker2AMD");
        device_dispatch->CmdWriteBufferMarker2AMD(commandBuffer, stage, dstBuffer, dstOffset, marker);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdWriteBufferMarker2AMD");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdWriteBufferMarker2AMD]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdWriteBufferMarker2AMD(commandBuffer, stage, dstBuffer, dstOffset, marker, record_obj);
        }
    }
}

VKAPI_ATTR VkResult VKAPI_CALL GetPhysicalDeviceCalibrateableTimeDomainsEXT(VkPhysicalDevice physicalDevice,
                                                                            uint32_t* pTimeDomainCount,
                                                                            VkTimeDomainKHR* pTimeDomains) {
    VVL_ZoneScoped;

    auto instance_dispatch = vvl::dispatch::GetData(physicalDevice);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetPhysicalDeviceCalibrateableTimeDomainsEXT,
                          VulkanTypedHandle(physicalDevice, kVulkanObjectTypePhysicalDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetPhysicalDeviceCalibrateableTimeDomainsEXT");
        for (const auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            skip |= vo->PreCallValidateGetPhysicalDeviceCalibrateableTimeDomainsEXT(physicalDevice, pTimeDomainCount, pTimeDomains,
                                                                                    error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetPhysicalDeviceCalibrateableTimeDomainsEXT);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetPhysicalDeviceCalibrateableTimeDomainsEXT");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PreCallRecordGetPhysicalDeviceCalibrateableTimeDomainsEXT(physicalDevice, pTimeDomainCount, pTimeDomains,
                                                                          record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkGetPhysicalDeviceCalibrateableTimeDomainsEXT");
        result = instance_dispatch->GetPhysicalDeviceCalibrateableTimeDomainsEXT(physicalDevice, pTimeDomainCount, pTimeDomains);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetPhysicalDeviceCalibrateableTimeDomainsEXT");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PostCallRecordGetPhysicalDeviceCalibrateableTimeDomainsEXT(physicalDevice, pTimeDomainCount, pTimeDomains,
                                                                           record_obj);
        }
    }
    return result;
}

VKAPI_ATTR VkResult VKAPI_CALL GetCalibratedTimestampsEXT(VkDevice device, uint32_t timestampCount,
                                                          const VkCalibratedTimestampInfoKHR* pTimestampInfos,
                                                          uint64_t* pTimestamps, uint64_t* pMaxDeviation) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetCalibratedTimestampsEXT, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetCalibratedTimestampsEXT");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateGetCalibratedTimestampsEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateGetCalibratedTimestampsEXT(device, timestampCount, pTimestampInfos, pTimestamps,
                                                                  pMaxDeviation, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetCalibratedTimestampsEXT);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetCalibratedTimestampsEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordGetCalibratedTimestampsEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordGetCalibratedTimestampsEXT(device, timestampCount, pTimestampInfos, pTimestamps, pMaxDeviation,
                                                        record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkGetCalibratedTimestampsEXT");
        result = device_dispatch->GetCalibratedTimestampsEXT(device, timestampCount, pTimestampInfos, pTimestamps, pMaxDeviation);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetCalibratedTimestampsEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordGetCalibratedTimestampsEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordGetCalibratedTimestampsEXT(device, timestampCount, pTimestampInfos, pTimestamps, pMaxDeviation,
                                                         record_obj);
        }
    }
    return result;
}

VKAPI_ATTR void VKAPI_CALL CmdDrawMeshTasksNV(VkCommandBuffer commandBuffer, uint32_t taskCount, uint32_t firstTask) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdDrawMeshTasksNV, VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdDrawMeshTasksNV");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdDrawMeshTasksNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdDrawMeshTasksNV(commandBuffer, taskCount, firstTask, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdDrawMeshTasksNV);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdDrawMeshTasksNV");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdDrawMeshTasksNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdDrawMeshTasksNV(commandBuffer, taskCount, firstTask, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdDrawMeshTasksNV");
        device_dispatch->CmdDrawMeshTasksNV(commandBuffer, taskCount, firstTask);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdDrawMeshTasksNV");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdDrawMeshTasksNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdDrawMeshTasksNV(commandBuffer, taskCount, firstTask, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdDrawMeshTasksIndirectNV(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
                                                      uint32_t drawCount, uint32_t stride) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdDrawMeshTasksIndirectNV,
                          VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdDrawMeshTasksIndirectNV");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdDrawMeshTasksIndirectNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdDrawMeshTasksIndirectNV(commandBuffer, buffer, offset, drawCount, stride, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdDrawMeshTasksIndirectNV);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdDrawMeshTasksIndirectNV");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdDrawMeshTasksIndirectNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdDrawMeshTasksIndirectNV(commandBuffer, buffer, offset, drawCount, stride, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdDrawMeshTasksIndirectNV");
        device_dispatch->CmdDrawMeshTasksIndirectNV(commandBuffer, buffer, offset, drawCount, stride);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdDrawMeshTasksIndirectNV");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdDrawMeshTasksIndirectNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdDrawMeshTasksIndirectNV(commandBuffer, buffer, offset, drawCount, stride, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdDrawMeshTasksIndirectCountNV(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
                                                           VkBuffer countBuffer, VkDeviceSize countBufferOffset,
                                                           uint32_t maxDrawCount, uint32_t stride) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdDrawMeshTasksIndirectCountNV,
                          VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdDrawMeshTasksIndirectCountNV");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdDrawMeshTasksIndirectCountNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdDrawMeshTasksIndirectCountNV(commandBuffer, buffer, offset, countBuffer,
                                                                       countBufferOffset, maxDrawCount, stride, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdDrawMeshTasksIndirectCountNV);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdDrawMeshTasksIndirectCountNV");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdDrawMeshTasksIndirectCountNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdDrawMeshTasksIndirectCountNV(commandBuffer, buffer, offset, countBuffer, countBufferOffset,
                                                             maxDrawCount, stride, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdDrawMeshTasksIndirectCountNV");
        device_dispatch->CmdDrawMeshTasksIndirectCountNV(commandBuffer, buffer, offset, countBuffer, countBufferOffset,
                                                         maxDrawCount, stride);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdDrawMeshTasksIndirectCountNV");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdDrawMeshTasksIndirectCountNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdDrawMeshTasksIndirectCountNV(commandBuffer, buffer, offset, countBuffer, countBufferOffset,
                                                              maxDrawCount, stride, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdSetExclusiveScissorEnableNV(VkCommandBuffer commandBuffer, uint32_t firstExclusiveScissor,
                                                          uint32_t exclusiveScissorCount,
                                                          const VkBool32* pExclusiveScissorEnables) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdSetExclusiveScissorEnableNV,
                          VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdSetExclusiveScissorEnableNV");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdSetExclusiveScissorEnableNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdSetExclusiveScissorEnableNV(commandBuffer, firstExclusiveScissor, exclusiveScissorCount,
                                                                      pExclusiveScissorEnables, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdSetExclusiveScissorEnableNV);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdSetExclusiveScissorEnableNV");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdSetExclusiveScissorEnableNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdSetExclusiveScissorEnableNV(commandBuffer, firstExclusiveScissor, exclusiveScissorCount,
                                                            pExclusiveScissorEnables, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdSetExclusiveScissorEnableNV");
        device_dispatch->CmdSetExclusiveScissorEnableNV(commandBuffer, firstExclusiveScissor, exclusiveScissorCount,
                                                        pExclusiveScissorEnables);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdSetExclusiveScissorEnableNV");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdSetExclusiveScissorEnableNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdSetExclusiveScissorEnableNV(commandBuffer, firstExclusiveScissor, exclusiveScissorCount,
                                                             pExclusiveScissorEnables, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdSetExclusiveScissorNV(VkCommandBuffer commandBuffer, uint32_t firstExclusiveScissor,
                                                    uint32_t exclusiveScissorCount, const VkRect2D* pExclusiveScissors) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdSetExclusiveScissorNV, VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdSetExclusiveScissorNV");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdSetExclusiveScissorNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdSetExclusiveScissorNV(commandBuffer, firstExclusiveScissor, exclusiveScissorCount,
                                                                pExclusiveScissors, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdSetExclusiveScissorNV);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdSetExclusiveScissorNV");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdSetExclusiveScissorNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdSetExclusiveScissorNV(commandBuffer, firstExclusiveScissor, exclusiveScissorCount,
                                                      pExclusiveScissors, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdSetExclusiveScissorNV");
        device_dispatch->CmdSetExclusiveScissorNV(commandBuffer, firstExclusiveScissor, exclusiveScissorCount, pExclusiveScissors);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdSetExclusiveScissorNV");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdSetExclusiveScissorNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdSetExclusiveScissorNV(commandBuffer, firstExclusiveScissor, exclusiveScissorCount,
                                                       pExclusiveScissors, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdSetCheckpointNV(VkCommandBuffer commandBuffer, const void* pCheckpointMarker) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdSetCheckpointNV, VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdSetCheckpointNV");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdSetCheckpointNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdSetCheckpointNV(commandBuffer, pCheckpointMarker, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdSetCheckpointNV);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdSetCheckpointNV");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdSetCheckpointNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdSetCheckpointNV(commandBuffer, pCheckpointMarker, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdSetCheckpointNV");
        device_dispatch->CmdSetCheckpointNV(commandBuffer, pCheckpointMarker);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdSetCheckpointNV");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdSetCheckpointNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdSetCheckpointNV(commandBuffer, pCheckpointMarker, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL GetQueueCheckpointDataNV(VkQueue queue, uint32_t* pCheckpointDataCount,
                                                    VkCheckpointDataNV* pCheckpointData) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(queue);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetQueueCheckpointDataNV, VulkanTypedHandle(queue, kVulkanObjectTypeQueue));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetQueueCheckpointDataNV");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateGetQueueCheckpointDataNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateGetQueueCheckpointDataNV(queue, pCheckpointDataCount, pCheckpointData, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetQueueCheckpointDataNV);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetQueueCheckpointDataNV");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordGetQueueCheckpointDataNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordGetQueueCheckpointDataNV(queue, pCheckpointDataCount, pCheckpointData, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkGetQueueCheckpointDataNV");
        device_dispatch->GetQueueCheckpointDataNV(queue, pCheckpointDataCount, pCheckpointData);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetQueueCheckpointDataNV");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordGetQueueCheckpointDataNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordGetQueueCheckpointDataNV(queue, pCheckpointDataCount, pCheckpointData, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL GetQueueCheckpointData2NV(VkQueue queue, uint32_t* pCheckpointDataCount,
                                                     VkCheckpointData2NV* pCheckpointData) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(queue);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetQueueCheckpointData2NV, VulkanTypedHandle(queue, kVulkanObjectTypeQueue));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetQueueCheckpointData2NV");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateGetQueueCheckpointData2NV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateGetQueueCheckpointData2NV(queue, pCheckpointDataCount, pCheckpointData, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetQueueCheckpointData2NV);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetQueueCheckpointData2NV");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordGetQueueCheckpointData2NV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordGetQueueCheckpointData2NV(queue, pCheckpointDataCount, pCheckpointData, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkGetQueueCheckpointData2NV");
        device_dispatch->GetQueueCheckpointData2NV(queue, pCheckpointDataCount, pCheckpointData);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetQueueCheckpointData2NV");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordGetQueueCheckpointData2NV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordGetQueueCheckpointData2NV(queue, pCheckpointDataCount, pCheckpointData, record_obj);
        }
    }
}

VKAPI_ATTR VkResult VKAPI_CALL SetSwapchainPresentTimingQueueSizeEXT(VkDevice device, VkSwapchainKHR swapchain, uint32_t size) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkSetSwapchainPresentTimingQueueSizeEXT, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkSetSwapchainPresentTimingQueueSizeEXT");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateSetSwapchainPresentTimingQueueSizeEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateSetSwapchainPresentTimingQueueSizeEXT(device, swapchain, size, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkSetSwapchainPresentTimingQueueSizeEXT);
    {
        VVL_ZoneScopedN("PreCallRecord_vkSetSwapchainPresentTimingQueueSizeEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordSetSwapchainPresentTimingQueueSizeEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordSetSwapchainPresentTimingQueueSizeEXT(device, swapchain, size, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkSetSwapchainPresentTimingQueueSizeEXT");
        result = device_dispatch->SetSwapchainPresentTimingQueueSizeEXT(device, swapchain, size);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkSetSwapchainPresentTimingQueueSizeEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordSetSwapchainPresentTimingQueueSizeEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordSetSwapchainPresentTimingQueueSizeEXT(device, swapchain, size, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR VkResult VKAPI_CALL GetSwapchainTimingPropertiesEXT(VkDevice device, VkSwapchainKHR swapchain,
                                                               VkSwapchainTimingPropertiesEXT* pSwapchainTimingProperties,
                                                               uint64_t* pSwapchainTimingPropertiesCounter) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetSwapchainTimingPropertiesEXT, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetSwapchainTimingPropertiesEXT");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateGetSwapchainTimingPropertiesEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateGetSwapchainTimingPropertiesEXT(device, swapchain, pSwapchainTimingProperties,
                                                                       pSwapchainTimingPropertiesCounter, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetSwapchainTimingPropertiesEXT);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetSwapchainTimingPropertiesEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordGetSwapchainTimingPropertiesEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordGetSwapchainTimingPropertiesEXT(device, swapchain, pSwapchainTimingProperties,
                                                             pSwapchainTimingPropertiesCounter, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkGetSwapchainTimingPropertiesEXT");
        result = device_dispatch->GetSwapchainTimingPropertiesEXT(device, swapchain, pSwapchainTimingProperties,
                                                                  pSwapchainTimingPropertiesCounter);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetSwapchainTimingPropertiesEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordGetSwapchainTimingPropertiesEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordGetSwapchainTimingPropertiesEXT(device, swapchain, pSwapchainTimingProperties,
                                                              pSwapchainTimingPropertiesCounter, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR VkResult VKAPI_CALL GetSwapchainTimeDomainPropertiesEXT(
    VkDevice device, VkSwapchainKHR swapchain, VkSwapchainTimeDomainPropertiesEXT* pSwapchainTimeDomainProperties,
    uint64_t* pTimeDomainsCounter) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetSwapchainTimeDomainPropertiesEXT, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetSwapchainTimeDomainPropertiesEXT");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateGetSwapchainTimeDomainPropertiesEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateGetSwapchainTimeDomainPropertiesEXT(device, swapchain, pSwapchainTimeDomainProperties,
                                                                           pTimeDomainsCounter, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetSwapchainTimeDomainPropertiesEXT);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetSwapchainTimeDomainPropertiesEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordGetSwapchainTimeDomainPropertiesEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordGetSwapchainTimeDomainPropertiesEXT(device, swapchain, pSwapchainTimeDomainProperties,
                                                                 pTimeDomainsCounter, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkGetSwapchainTimeDomainPropertiesEXT");
        result = device_dispatch->GetSwapchainTimeDomainPropertiesEXT(device, swapchain, pSwapchainTimeDomainProperties,
                                                                      pTimeDomainsCounter);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetSwapchainTimeDomainPropertiesEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordGetSwapchainTimeDomainPropertiesEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordGetSwapchainTimeDomainPropertiesEXT(device, swapchain, pSwapchainTimeDomainProperties,
                                                                  pTimeDomainsCounter, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR VkResult VKAPI_CALL
GetPastPresentationTimingEXT(VkDevice device, const VkPastPresentationTimingInfoEXT* pPastPresentationTimingInfo,
                             VkPastPresentationTimingPropertiesEXT* pPastPresentationTimingProperties) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetPastPresentationTimingEXT, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetPastPresentationTimingEXT");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateGetPastPresentationTimingEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateGetPastPresentationTimingEXT(device, pPastPresentationTimingInfo,
                                                                    pPastPresentationTimingProperties, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetPastPresentationTimingEXT);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetPastPresentationTimingEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordGetPastPresentationTimingEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordGetPastPresentationTimingEXT(device, pPastPresentationTimingInfo, pPastPresentationTimingProperties,
                                                          record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkGetPastPresentationTimingEXT");
        result =
            device_dispatch->GetPastPresentationTimingEXT(device, pPastPresentationTimingInfo, pPastPresentationTimingProperties);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetPastPresentationTimingEXT");

        if (result == VK_ERROR_DEVICE_LOST) {
            for (auto& vo : device_dispatch->object_dispatch) {
                vo->is_device_lost = true;
            }
        }
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordGetPastPresentationTimingEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordGetPastPresentationTimingEXT(device, pPastPresentationTimingInfo, pPastPresentationTimingProperties,
                                                           record_obj);
        }
    }
    return result;
}

VKAPI_ATTR VkResult VKAPI_CALL InitializePerformanceApiINTEL(VkDevice device,
                                                             const VkInitializePerformanceApiInfoINTEL* pInitializeInfo) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkInitializePerformanceApiINTEL, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkInitializePerformanceApiINTEL");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateInitializePerformanceApiINTEL]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateInitializePerformanceApiINTEL(device, pInitializeInfo, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkInitializePerformanceApiINTEL);
    {
        VVL_ZoneScopedN("PreCallRecord_vkInitializePerformanceApiINTEL");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordInitializePerformanceApiINTEL]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordInitializePerformanceApiINTEL(device, pInitializeInfo, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkInitializePerformanceApiINTEL");
        result = device_dispatch->InitializePerformanceApiINTEL(device, pInitializeInfo);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkInitializePerformanceApiINTEL");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordInitializePerformanceApiINTEL]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordInitializePerformanceApiINTEL(device, pInitializeInfo, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR void VKAPI_CALL UninitializePerformanceApiINTEL(VkDevice device) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkUninitializePerformanceApiINTEL, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkUninitializePerformanceApiINTEL");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateUninitializePerformanceApiINTEL]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateUninitializePerformanceApiINTEL(device, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkUninitializePerformanceApiINTEL);
    {
        VVL_ZoneScopedN("PreCallRecord_vkUninitializePerformanceApiINTEL");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordUninitializePerformanceApiINTEL]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordUninitializePerformanceApiINTEL(device, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkUninitializePerformanceApiINTEL");
        device_dispatch->UninitializePerformanceApiINTEL(device);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkUninitializePerformanceApiINTEL");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordUninitializePerformanceApiINTEL]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordUninitializePerformanceApiINTEL(device, record_obj);
        }
    }
}

VKAPI_ATTR VkResult VKAPI_CALL CmdSetPerformanceMarkerINTEL(VkCommandBuffer commandBuffer,
                                                            const VkPerformanceMarkerInfoINTEL* pMarkerInfo) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdSetPerformanceMarkerINTEL,
                          VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdSetPerformanceMarkerINTEL");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdSetPerformanceMarkerINTEL]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdSetPerformanceMarkerINTEL(commandBuffer, pMarkerInfo, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdSetPerformanceMarkerINTEL);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdSetPerformanceMarkerINTEL");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdSetPerformanceMarkerINTEL]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdSetPerformanceMarkerINTEL(commandBuffer, pMarkerInfo, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkCmdSetPerformanceMarkerINTEL");
        result = device_dispatch->CmdSetPerformanceMarkerINTEL(commandBuffer, pMarkerInfo);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdSetPerformanceMarkerINTEL");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdSetPerformanceMarkerINTEL]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdSetPerformanceMarkerINTEL(commandBuffer, pMarkerInfo, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR VkResult VKAPI_CALL CmdSetPerformanceStreamMarkerINTEL(VkCommandBuffer commandBuffer,
                                                                  const VkPerformanceStreamMarkerInfoINTEL* pMarkerInfo) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdSetPerformanceStreamMarkerINTEL,
                          VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdSetPerformanceStreamMarkerINTEL");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdSetPerformanceStreamMarkerINTEL]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdSetPerformanceStreamMarkerINTEL(commandBuffer, pMarkerInfo, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdSetPerformanceStreamMarkerINTEL);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdSetPerformanceStreamMarkerINTEL");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdSetPerformanceStreamMarkerINTEL]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdSetPerformanceStreamMarkerINTEL(commandBuffer, pMarkerInfo, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkCmdSetPerformanceStreamMarkerINTEL");
        result = device_dispatch->CmdSetPerformanceStreamMarkerINTEL(commandBuffer, pMarkerInfo);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdSetPerformanceStreamMarkerINTEL");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdSetPerformanceStreamMarkerINTEL]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdSetPerformanceStreamMarkerINTEL(commandBuffer, pMarkerInfo, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR VkResult VKAPI_CALL CmdSetPerformanceOverrideINTEL(VkCommandBuffer commandBuffer,
                                                              const VkPerformanceOverrideInfoINTEL* pOverrideInfo) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdSetPerformanceOverrideINTEL,
                          VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdSetPerformanceOverrideINTEL");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdSetPerformanceOverrideINTEL]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdSetPerformanceOverrideINTEL(commandBuffer, pOverrideInfo, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdSetPerformanceOverrideINTEL);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdSetPerformanceOverrideINTEL");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdSetPerformanceOverrideINTEL]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdSetPerformanceOverrideINTEL(commandBuffer, pOverrideInfo, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkCmdSetPerformanceOverrideINTEL");
        result = device_dispatch->CmdSetPerformanceOverrideINTEL(commandBuffer, pOverrideInfo);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdSetPerformanceOverrideINTEL");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdSetPerformanceOverrideINTEL]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdSetPerformanceOverrideINTEL(commandBuffer, pOverrideInfo, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR VkResult VKAPI_CALL AcquirePerformanceConfigurationINTEL(VkDevice device,
                                                                    const VkPerformanceConfigurationAcquireInfoINTEL* pAcquireInfo,
                                                                    VkPerformanceConfigurationINTEL* pConfiguration) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkAcquirePerformanceConfigurationINTEL, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkAcquirePerformanceConfigurationINTEL");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateAcquirePerformanceConfigurationINTEL]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateAcquirePerformanceConfigurationINTEL(device, pAcquireInfo, pConfiguration, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkAcquirePerformanceConfigurationINTEL);
    {
        VVL_ZoneScopedN("PreCallRecord_vkAcquirePerformanceConfigurationINTEL");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordAcquirePerformanceConfigurationINTEL]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordAcquirePerformanceConfigurationINTEL(device, pAcquireInfo, pConfiguration, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkAcquirePerformanceConfigurationINTEL");
        result = device_dispatch->AcquirePerformanceConfigurationINTEL(device, pAcquireInfo, pConfiguration);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkAcquirePerformanceConfigurationINTEL");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordAcquirePerformanceConfigurationINTEL]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordAcquirePerformanceConfigurationINTEL(device, pAcquireInfo, pConfiguration, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR VkResult VKAPI_CALL ReleasePerformanceConfigurationINTEL(VkDevice device,
                                                                    VkPerformanceConfigurationINTEL configuration) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkReleasePerformanceConfigurationINTEL, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkReleasePerformanceConfigurationINTEL");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateReleasePerformanceConfigurationINTEL]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateReleasePerformanceConfigurationINTEL(device, configuration, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkReleasePerformanceConfigurationINTEL);
    {
        VVL_ZoneScopedN("PreCallRecord_vkReleasePerformanceConfigurationINTEL");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordReleasePerformanceConfigurationINTEL]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordReleasePerformanceConfigurationINTEL(device, configuration, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkReleasePerformanceConfigurationINTEL");
        result = device_dispatch->ReleasePerformanceConfigurationINTEL(device, configuration);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkReleasePerformanceConfigurationINTEL");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordReleasePerformanceConfigurationINTEL]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordReleasePerformanceConfigurationINTEL(device, configuration, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR VkResult VKAPI_CALL QueueSetPerformanceConfigurationINTEL(VkQueue queue, VkPerformanceConfigurationINTEL configuration) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(queue);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkQueueSetPerformanceConfigurationINTEL, VulkanTypedHandle(queue, kVulkanObjectTypeQueue));
    {
        VVL_ZoneScopedN("PreCallValidate_vkQueueSetPerformanceConfigurationINTEL");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateQueueSetPerformanceConfigurationINTEL]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateQueueSetPerformanceConfigurationINTEL(queue, configuration, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkQueueSetPerformanceConfigurationINTEL);
    {
        VVL_ZoneScopedN("PreCallRecord_vkQueueSetPerformanceConfigurationINTEL");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordQueueSetPerformanceConfigurationINTEL]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordQueueSetPerformanceConfigurationINTEL(queue, configuration, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkQueueSetPerformanceConfigurationINTEL");
        result = device_dispatch->QueueSetPerformanceConfigurationINTEL(queue, configuration);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkQueueSetPerformanceConfigurationINTEL");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordQueueSetPerformanceConfigurationINTEL]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordQueueSetPerformanceConfigurationINTEL(queue, configuration, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR VkResult VKAPI_CALL GetPerformanceParameterINTEL(VkDevice device, VkPerformanceParameterTypeINTEL parameter,
                                                            VkPerformanceValueINTEL* pValue) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetPerformanceParameterINTEL, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetPerformanceParameterINTEL");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateGetPerformanceParameterINTEL]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateGetPerformanceParameterINTEL(device, parameter, pValue, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetPerformanceParameterINTEL);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetPerformanceParameterINTEL");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordGetPerformanceParameterINTEL]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordGetPerformanceParameterINTEL(device, parameter, pValue, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkGetPerformanceParameterINTEL");
        result = device_dispatch->GetPerformanceParameterINTEL(device, parameter, pValue);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetPerformanceParameterINTEL");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordGetPerformanceParameterINTEL]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordGetPerformanceParameterINTEL(device, parameter, pValue, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR void VKAPI_CALL SetLocalDimmingAMD(VkDevice device, VkSwapchainKHR swapChain, VkBool32 localDimmingEnable) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkSetLocalDimmingAMD, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkSetLocalDimmingAMD");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateSetLocalDimmingAMD]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateSetLocalDimmingAMD(device, swapChain, localDimmingEnable, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkSetLocalDimmingAMD);
    {
        VVL_ZoneScopedN("PreCallRecord_vkSetLocalDimmingAMD");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordSetLocalDimmingAMD]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordSetLocalDimmingAMD(device, swapChain, localDimmingEnable, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkSetLocalDimmingAMD");
        device_dispatch->SetLocalDimmingAMD(device, swapChain, localDimmingEnable);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkSetLocalDimmingAMD");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordSetLocalDimmingAMD]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordSetLocalDimmingAMD(device, swapChain, localDimmingEnable, record_obj);
        }
    }
}

#ifdef VK_USE_PLATFORM_FUCHSIA
VKAPI_ATTR VkResult VKAPI_CALL CreateImagePipeSurfaceFUCHSIA(VkInstance instance,
                                                             const VkImagePipeSurfaceCreateInfoFUCHSIA* pCreateInfo,
                                                             const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface) {
    VVL_ZoneScoped;

    auto instance_dispatch = vvl::dispatch::GetData(instance);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCreateImagePipeSurfaceFUCHSIA, VulkanTypedHandle(instance, kVulkanObjectTypeInstance));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCreateImagePipeSurfaceFUCHSIA");
        for (const auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            skip |= vo->PreCallValidateCreateImagePipeSurfaceFUCHSIA(instance, pCreateInfo, pAllocator, pSurface, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkCreateImagePipeSurfaceFUCHSIA);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCreateImagePipeSurfaceFUCHSIA");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PreCallRecordCreateImagePipeSurfaceFUCHSIA(instance, pCreateInfo, pAllocator, pSurface, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkCreateImagePipeSurfaceFUCHSIA");
        result = instance_dispatch->CreateImagePipeSurfaceFUCHSIA(instance, pCreateInfo, pAllocator, pSurface);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkCreateImagePipeSurfaceFUCHSIA");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PostCallRecordCreateImagePipeSurfaceFUCHSIA(instance, pCreateInfo, pAllocator, pSurface, record_obj);
        }
    }
    return result;
}

#endif  // VK_USE_PLATFORM_FUCHSIA
#ifdef VK_USE_PLATFORM_METAL_EXT
VKAPI_ATTR VkResult VKAPI_CALL CreateMetalSurfaceEXT(VkInstance instance, const VkMetalSurfaceCreateInfoEXT* pCreateInfo,
                                                     const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface) {
    VVL_ZoneScoped;

    auto instance_dispatch = vvl::dispatch::GetData(instance);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCreateMetalSurfaceEXT, VulkanTypedHandle(instance, kVulkanObjectTypeInstance));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCreateMetalSurfaceEXT");
        for (const auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            skip |= vo->PreCallValidateCreateMetalSurfaceEXT(instance, pCreateInfo, pAllocator, pSurface, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkCreateMetalSurfaceEXT);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCreateMetalSurfaceEXT");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PreCallRecordCreateMetalSurfaceEXT(instance, pCreateInfo, pAllocator, pSurface, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkCreateMetalSurfaceEXT");
        result = instance_dispatch->CreateMetalSurfaceEXT(instance, pCreateInfo, pAllocator, pSurface);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkCreateMetalSurfaceEXT");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PostCallRecordCreateMetalSurfaceEXT(instance, pCreateInfo, pAllocator, pSurface, record_obj);
        }
    }
    return result;
}

#endif  // VK_USE_PLATFORM_METAL_EXT
VKAPI_ATTR VkDeviceAddress VKAPI_CALL GetBufferDeviceAddressEXT(VkDevice device, const VkBufferDeviceAddressInfo* pInfo) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetBufferDeviceAddressEXT, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetBufferDeviceAddressEXT");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateGetBufferDeviceAddressEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateGetBufferDeviceAddressEXT(device, pInfo, error_obj);
            if (skip) return 0;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetBufferDeviceAddressEXT);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetBufferDeviceAddressEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordGetBufferDeviceAddressEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordGetBufferDeviceAddressEXT(device, pInfo, record_obj);
        }
    }
    VkDeviceAddress result;
    {
        VVL_ZoneScopedN("Dispatch_vkGetBufferDeviceAddressEXT");
        result = device_dispatch->GetBufferDeviceAddressEXT(device, pInfo);
    }
    record_obj.device_address = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetBufferDeviceAddressEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordGetBufferDeviceAddressEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordGetBufferDeviceAddressEXT(device, pInfo, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR VkResult VKAPI_CALL GetPhysicalDeviceCooperativeMatrixPropertiesNV(VkPhysicalDevice physicalDevice,
                                                                              uint32_t* pPropertyCount,
                                                                              VkCooperativeMatrixPropertiesNV* pProperties) {
    VVL_ZoneScoped;

    auto instance_dispatch = vvl::dispatch::GetData(physicalDevice);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetPhysicalDeviceCooperativeMatrixPropertiesNV,
                          VulkanTypedHandle(physicalDevice, kVulkanObjectTypePhysicalDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetPhysicalDeviceCooperativeMatrixPropertiesNV");
        for (const auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            skip |= vo->PreCallValidateGetPhysicalDeviceCooperativeMatrixPropertiesNV(physicalDevice, pPropertyCount, pProperties,
                                                                                      error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetPhysicalDeviceCooperativeMatrixPropertiesNV);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetPhysicalDeviceCooperativeMatrixPropertiesNV");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PreCallRecordGetPhysicalDeviceCooperativeMatrixPropertiesNV(physicalDevice, pPropertyCount, pProperties,
                                                                            record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkGetPhysicalDeviceCooperativeMatrixPropertiesNV");
        result = instance_dispatch->GetPhysicalDeviceCooperativeMatrixPropertiesNV(physicalDevice, pPropertyCount, pProperties);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetPhysicalDeviceCooperativeMatrixPropertiesNV");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PostCallRecordGetPhysicalDeviceCooperativeMatrixPropertiesNV(physicalDevice, pPropertyCount, pProperties,
                                                                             record_obj);
        }
    }
    return result;
}

VKAPI_ATTR VkResult VKAPI_CALL GetPhysicalDeviceSupportedFramebufferMixedSamplesCombinationsNV(
    VkPhysicalDevice physicalDevice, uint32_t* pCombinationCount, VkFramebufferMixedSamplesCombinationNV* pCombinations) {
    VVL_ZoneScoped;

    auto instance_dispatch = vvl::dispatch::GetData(physicalDevice);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetPhysicalDeviceSupportedFramebufferMixedSamplesCombinationsNV,
                          VulkanTypedHandle(physicalDevice, kVulkanObjectTypePhysicalDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetPhysicalDeviceSupportedFramebufferMixedSamplesCombinationsNV");
        for (const auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            skip |= vo->PreCallValidateGetPhysicalDeviceSupportedFramebufferMixedSamplesCombinationsNV(
                physicalDevice, pCombinationCount, pCombinations, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetPhysicalDeviceSupportedFramebufferMixedSamplesCombinationsNV);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetPhysicalDeviceSupportedFramebufferMixedSamplesCombinationsNV");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PreCallRecordGetPhysicalDeviceSupportedFramebufferMixedSamplesCombinationsNV(physicalDevice, pCombinationCount,
                                                                                             pCombinations, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkGetPhysicalDeviceSupportedFramebufferMixedSamplesCombinationsNV");
        result = instance_dispatch->GetPhysicalDeviceSupportedFramebufferMixedSamplesCombinationsNV(
            physicalDevice, pCombinationCount, pCombinations);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetPhysicalDeviceSupportedFramebufferMixedSamplesCombinationsNV");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PostCallRecordGetPhysicalDeviceSupportedFramebufferMixedSamplesCombinationsNV(physicalDevice, pCombinationCount,
                                                                                              pCombinations, record_obj);
        }
    }
    return result;
}

#ifdef VK_USE_PLATFORM_WIN32_KHR
VKAPI_ATTR VkResult VKAPI_CALL GetPhysicalDeviceSurfacePresentModes2EXT(VkPhysicalDevice physicalDevice,
                                                                        const VkPhysicalDeviceSurfaceInfo2KHR* pSurfaceInfo,
                                                                        uint32_t* pPresentModeCount,
                                                                        VkPresentModeKHR* pPresentModes) {
    VVL_ZoneScoped;

    auto instance_dispatch = vvl::dispatch::GetData(physicalDevice);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetPhysicalDeviceSurfacePresentModes2EXT,
                          VulkanTypedHandle(physicalDevice, kVulkanObjectTypePhysicalDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetPhysicalDeviceSurfacePresentModes2EXT");
        for (const auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            skip |= vo->PreCallValidateGetPhysicalDeviceSurfacePresentModes2EXT(physicalDevice, pSurfaceInfo, pPresentModeCount,
                                                                                pPresentModes, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetPhysicalDeviceSurfacePresentModes2EXT);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetPhysicalDeviceSurfacePresentModes2EXT");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PreCallRecordGetPhysicalDeviceSurfacePresentModes2EXT(physicalDevice, pSurfaceInfo, pPresentModeCount,
                                                                      pPresentModes, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkGetPhysicalDeviceSurfacePresentModes2EXT");
        result = instance_dispatch->GetPhysicalDeviceSurfacePresentModes2EXT(physicalDevice, pSurfaceInfo, pPresentModeCount,
                                                                             pPresentModes);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetPhysicalDeviceSurfacePresentModes2EXT");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PostCallRecordGetPhysicalDeviceSurfacePresentModes2EXT(physicalDevice, pSurfaceInfo, pPresentModeCount,
                                                                       pPresentModes, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR VkResult VKAPI_CALL AcquireFullScreenExclusiveModeEXT(VkDevice device, VkSwapchainKHR swapchain) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkAcquireFullScreenExclusiveModeEXT, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkAcquireFullScreenExclusiveModeEXT");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateAcquireFullScreenExclusiveModeEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateAcquireFullScreenExclusiveModeEXT(device, swapchain, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkAcquireFullScreenExclusiveModeEXT);
    {
        VVL_ZoneScopedN("PreCallRecord_vkAcquireFullScreenExclusiveModeEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordAcquireFullScreenExclusiveModeEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordAcquireFullScreenExclusiveModeEXT(device, swapchain, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkAcquireFullScreenExclusiveModeEXT");
        result = device_dispatch->AcquireFullScreenExclusiveModeEXT(device, swapchain);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkAcquireFullScreenExclusiveModeEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordAcquireFullScreenExclusiveModeEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordAcquireFullScreenExclusiveModeEXT(device, swapchain, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR VkResult VKAPI_CALL ReleaseFullScreenExclusiveModeEXT(VkDevice device, VkSwapchainKHR swapchain) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkReleaseFullScreenExclusiveModeEXT, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkReleaseFullScreenExclusiveModeEXT");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateReleaseFullScreenExclusiveModeEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateReleaseFullScreenExclusiveModeEXT(device, swapchain, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkReleaseFullScreenExclusiveModeEXT);
    {
        VVL_ZoneScopedN("PreCallRecord_vkReleaseFullScreenExclusiveModeEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordReleaseFullScreenExclusiveModeEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordReleaseFullScreenExclusiveModeEXT(device, swapchain, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkReleaseFullScreenExclusiveModeEXT");
        result = device_dispatch->ReleaseFullScreenExclusiveModeEXT(device, swapchain);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkReleaseFullScreenExclusiveModeEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordReleaseFullScreenExclusiveModeEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordReleaseFullScreenExclusiveModeEXT(device, swapchain, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR VkResult VKAPI_CALL GetDeviceGroupSurfacePresentModes2EXT(VkDevice device,
                                                                     const VkPhysicalDeviceSurfaceInfo2KHR* pSurfaceInfo,
                                                                     VkDeviceGroupPresentModeFlagsKHR* pModes) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetDeviceGroupSurfacePresentModes2EXT, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetDeviceGroupSurfacePresentModes2EXT");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateGetDeviceGroupSurfacePresentModes2EXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateGetDeviceGroupSurfacePresentModes2EXT(device, pSurfaceInfo, pModes, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetDeviceGroupSurfacePresentModes2EXT);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetDeviceGroupSurfacePresentModes2EXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordGetDeviceGroupSurfacePresentModes2EXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordGetDeviceGroupSurfacePresentModes2EXT(device, pSurfaceInfo, pModes, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkGetDeviceGroupSurfacePresentModes2EXT");
        result = device_dispatch->GetDeviceGroupSurfacePresentModes2EXT(device, pSurfaceInfo, pModes);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetDeviceGroupSurfacePresentModes2EXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordGetDeviceGroupSurfacePresentModes2EXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordGetDeviceGroupSurfacePresentModes2EXT(device, pSurfaceInfo, pModes, record_obj);
        }
    }
    return result;
}

#endif  // VK_USE_PLATFORM_WIN32_KHR
VKAPI_ATTR VkResult VKAPI_CALL CreateHeadlessSurfaceEXT(VkInstance instance, const VkHeadlessSurfaceCreateInfoEXT* pCreateInfo,
                                                        const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface) {
    VVL_ZoneScoped;

    auto instance_dispatch = vvl::dispatch::GetData(instance);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCreateHeadlessSurfaceEXT, VulkanTypedHandle(instance, kVulkanObjectTypeInstance));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCreateHeadlessSurfaceEXT");
        for (const auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            skip |= vo->PreCallValidateCreateHeadlessSurfaceEXT(instance, pCreateInfo, pAllocator, pSurface, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkCreateHeadlessSurfaceEXT);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCreateHeadlessSurfaceEXT");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PreCallRecordCreateHeadlessSurfaceEXT(instance, pCreateInfo, pAllocator, pSurface, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkCreateHeadlessSurfaceEXT");
        result = instance_dispatch->CreateHeadlessSurfaceEXT(instance, pCreateInfo, pAllocator, pSurface);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkCreateHeadlessSurfaceEXT");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PostCallRecordCreateHeadlessSurfaceEXT(instance, pCreateInfo, pAllocator, pSurface, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR void VKAPI_CALL CmdSetLineStippleEXT(VkCommandBuffer commandBuffer, uint32_t lineStippleFactor,
                                                uint16_t lineStipplePattern) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdSetLineStippleEXT, VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdSetLineStippleEXT");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdSetLineStippleEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdSetLineStippleEXT(commandBuffer, lineStippleFactor, lineStipplePattern, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdSetLineStippleEXT);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdSetLineStippleEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdSetLineStippleEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdSetLineStippleEXT(commandBuffer, lineStippleFactor, lineStipplePattern, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdSetLineStippleEXT");
        device_dispatch->CmdSetLineStippleEXT(commandBuffer, lineStippleFactor, lineStipplePattern);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdSetLineStippleEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdSetLineStippleEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdSetLineStippleEXT(commandBuffer, lineStippleFactor, lineStipplePattern, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL ResetQueryPoolEXT(VkDevice device, VkQueryPool queryPool, uint32_t firstQuery, uint32_t queryCount) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkResetQueryPoolEXT, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkResetQueryPoolEXT");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateResetQueryPoolEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateResetQueryPoolEXT(device, queryPool, firstQuery, queryCount, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkResetQueryPoolEXT);
    {
        VVL_ZoneScopedN("PreCallRecord_vkResetQueryPoolEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordResetQueryPoolEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordResetQueryPoolEXT(device, queryPool, firstQuery, queryCount, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkResetQueryPoolEXT");
        device_dispatch->ResetQueryPoolEXT(device, queryPool, firstQuery, queryCount);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkResetQueryPoolEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordResetQueryPoolEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordResetQueryPoolEXT(device, queryPool, firstQuery, queryCount, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdSetCullModeEXT(VkCommandBuffer commandBuffer, VkCullModeFlags cullMode) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdSetCullModeEXT, VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdSetCullModeEXT");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdSetCullModeEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdSetCullModeEXT(commandBuffer, cullMode, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdSetCullModeEXT);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdSetCullModeEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdSetCullModeEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdSetCullModeEXT(commandBuffer, cullMode, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdSetCullModeEXT");
        device_dispatch->CmdSetCullModeEXT(commandBuffer, cullMode);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdSetCullModeEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdSetCullModeEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdSetCullModeEXT(commandBuffer, cullMode, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdSetFrontFaceEXT(VkCommandBuffer commandBuffer, VkFrontFace frontFace) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdSetFrontFaceEXT, VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdSetFrontFaceEXT");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdSetFrontFaceEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdSetFrontFaceEXT(commandBuffer, frontFace, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdSetFrontFaceEXT);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdSetFrontFaceEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdSetFrontFaceEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdSetFrontFaceEXT(commandBuffer, frontFace, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdSetFrontFaceEXT");
        device_dispatch->CmdSetFrontFaceEXT(commandBuffer, frontFace);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdSetFrontFaceEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdSetFrontFaceEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdSetFrontFaceEXT(commandBuffer, frontFace, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdSetPrimitiveTopologyEXT(VkCommandBuffer commandBuffer, VkPrimitiveTopology primitiveTopology) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdSetPrimitiveTopologyEXT,
                          VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdSetPrimitiveTopologyEXT");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdSetPrimitiveTopologyEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdSetPrimitiveTopologyEXT(commandBuffer, primitiveTopology, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdSetPrimitiveTopologyEXT);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdSetPrimitiveTopologyEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdSetPrimitiveTopologyEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdSetPrimitiveTopologyEXT(commandBuffer, primitiveTopology, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdSetPrimitiveTopologyEXT");
        device_dispatch->CmdSetPrimitiveTopologyEXT(commandBuffer, primitiveTopology);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdSetPrimitiveTopologyEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdSetPrimitiveTopologyEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdSetPrimitiveTopologyEXT(commandBuffer, primitiveTopology, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdSetViewportWithCountEXT(VkCommandBuffer commandBuffer, uint32_t viewportCount,
                                                      const VkViewport* pViewports) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdSetViewportWithCountEXT,
                          VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdSetViewportWithCountEXT");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdSetViewportWithCountEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdSetViewportWithCountEXT(commandBuffer, viewportCount, pViewports, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdSetViewportWithCountEXT);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdSetViewportWithCountEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdSetViewportWithCountEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdSetViewportWithCountEXT(commandBuffer, viewportCount, pViewports, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdSetViewportWithCountEXT");
        device_dispatch->CmdSetViewportWithCountEXT(commandBuffer, viewportCount, pViewports);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdSetViewportWithCountEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdSetViewportWithCountEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdSetViewportWithCountEXT(commandBuffer, viewportCount, pViewports, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdSetScissorWithCountEXT(VkCommandBuffer commandBuffer, uint32_t scissorCount,
                                                     const VkRect2D* pScissors) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdSetScissorWithCountEXT, VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdSetScissorWithCountEXT");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdSetScissorWithCountEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdSetScissorWithCountEXT(commandBuffer, scissorCount, pScissors, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdSetScissorWithCountEXT);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdSetScissorWithCountEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdSetScissorWithCountEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdSetScissorWithCountEXT(commandBuffer, scissorCount, pScissors, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdSetScissorWithCountEXT");
        device_dispatch->CmdSetScissorWithCountEXT(commandBuffer, scissorCount, pScissors);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdSetScissorWithCountEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdSetScissorWithCountEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdSetScissorWithCountEXT(commandBuffer, scissorCount, pScissors, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdBindVertexBuffers2EXT(VkCommandBuffer commandBuffer, uint32_t firstBinding, uint32_t bindingCount,
                                                    const VkBuffer* pBuffers, const VkDeviceSize* pOffsets,
                                                    const VkDeviceSize* pSizes, const VkDeviceSize* pStrides) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdBindVertexBuffers2EXT, VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdBindVertexBuffers2EXT");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdBindVertexBuffers2EXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdBindVertexBuffers2EXT(commandBuffer, firstBinding, bindingCount, pBuffers, pOffsets,
                                                                pSizes, pStrides, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdBindVertexBuffers2EXT);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdBindVertexBuffers2EXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdBindVertexBuffers2EXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdBindVertexBuffers2EXT(commandBuffer, firstBinding, bindingCount, pBuffers, pOffsets, pSizes,
                                                      pStrides, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdBindVertexBuffers2EXT");
        device_dispatch->CmdBindVertexBuffers2EXT(commandBuffer, firstBinding, bindingCount, pBuffers, pOffsets, pSizes, pStrides);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdBindVertexBuffers2EXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdBindVertexBuffers2EXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdBindVertexBuffers2EXT(commandBuffer, firstBinding, bindingCount, pBuffers, pOffsets, pSizes,
                                                       pStrides, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdSetDepthTestEnableEXT(VkCommandBuffer commandBuffer, VkBool32 depthTestEnable) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdSetDepthTestEnableEXT, VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdSetDepthTestEnableEXT");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdSetDepthTestEnableEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdSetDepthTestEnableEXT(commandBuffer, depthTestEnable, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdSetDepthTestEnableEXT);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdSetDepthTestEnableEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdSetDepthTestEnableEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdSetDepthTestEnableEXT(commandBuffer, depthTestEnable, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdSetDepthTestEnableEXT");
        device_dispatch->CmdSetDepthTestEnableEXT(commandBuffer, depthTestEnable);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdSetDepthTestEnableEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdSetDepthTestEnableEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdSetDepthTestEnableEXT(commandBuffer, depthTestEnable, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdSetDepthWriteEnableEXT(VkCommandBuffer commandBuffer, VkBool32 depthWriteEnable) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdSetDepthWriteEnableEXT, VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdSetDepthWriteEnableEXT");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdSetDepthWriteEnableEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdSetDepthWriteEnableEXT(commandBuffer, depthWriteEnable, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdSetDepthWriteEnableEXT);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdSetDepthWriteEnableEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdSetDepthWriteEnableEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdSetDepthWriteEnableEXT(commandBuffer, depthWriteEnable, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdSetDepthWriteEnableEXT");
        device_dispatch->CmdSetDepthWriteEnableEXT(commandBuffer, depthWriteEnable);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdSetDepthWriteEnableEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdSetDepthWriteEnableEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdSetDepthWriteEnableEXT(commandBuffer, depthWriteEnable, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdSetDepthCompareOpEXT(VkCommandBuffer commandBuffer, VkCompareOp depthCompareOp) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdSetDepthCompareOpEXT, VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdSetDepthCompareOpEXT");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdSetDepthCompareOpEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdSetDepthCompareOpEXT(commandBuffer, depthCompareOp, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdSetDepthCompareOpEXT);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdSetDepthCompareOpEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdSetDepthCompareOpEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdSetDepthCompareOpEXT(commandBuffer, depthCompareOp, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdSetDepthCompareOpEXT");
        device_dispatch->CmdSetDepthCompareOpEXT(commandBuffer, depthCompareOp);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdSetDepthCompareOpEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdSetDepthCompareOpEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdSetDepthCompareOpEXT(commandBuffer, depthCompareOp, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdSetDepthBoundsTestEnableEXT(VkCommandBuffer commandBuffer, VkBool32 depthBoundsTestEnable) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdSetDepthBoundsTestEnableEXT,
                          VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdSetDepthBoundsTestEnableEXT");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdSetDepthBoundsTestEnableEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdSetDepthBoundsTestEnableEXT(commandBuffer, depthBoundsTestEnable, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdSetDepthBoundsTestEnableEXT);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdSetDepthBoundsTestEnableEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdSetDepthBoundsTestEnableEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdSetDepthBoundsTestEnableEXT(commandBuffer, depthBoundsTestEnable, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdSetDepthBoundsTestEnableEXT");
        device_dispatch->CmdSetDepthBoundsTestEnableEXT(commandBuffer, depthBoundsTestEnable);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdSetDepthBoundsTestEnableEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdSetDepthBoundsTestEnableEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdSetDepthBoundsTestEnableEXT(commandBuffer, depthBoundsTestEnable, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdSetStencilTestEnableEXT(VkCommandBuffer commandBuffer, VkBool32 stencilTestEnable) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdSetStencilTestEnableEXT,
                          VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdSetStencilTestEnableEXT");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdSetStencilTestEnableEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdSetStencilTestEnableEXT(commandBuffer, stencilTestEnable, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdSetStencilTestEnableEXT);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdSetStencilTestEnableEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdSetStencilTestEnableEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdSetStencilTestEnableEXT(commandBuffer, stencilTestEnable, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdSetStencilTestEnableEXT");
        device_dispatch->CmdSetStencilTestEnableEXT(commandBuffer, stencilTestEnable);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdSetStencilTestEnableEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdSetStencilTestEnableEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdSetStencilTestEnableEXT(commandBuffer, stencilTestEnable, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdSetStencilOpEXT(VkCommandBuffer commandBuffer, VkStencilFaceFlags faceMask, VkStencilOp failOp,
                                              VkStencilOp passOp, VkStencilOp depthFailOp, VkCompareOp compareOp) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdSetStencilOpEXT, VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdSetStencilOpEXT");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdSetStencilOpEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |=
                vo->PreCallValidateCmdSetStencilOpEXT(commandBuffer, faceMask, failOp, passOp, depthFailOp, compareOp, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdSetStencilOpEXT);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdSetStencilOpEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdSetStencilOpEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdSetStencilOpEXT(commandBuffer, faceMask, failOp, passOp, depthFailOp, compareOp, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdSetStencilOpEXT");
        device_dispatch->CmdSetStencilOpEXT(commandBuffer, faceMask, failOp, passOp, depthFailOp, compareOp);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdSetStencilOpEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdSetStencilOpEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdSetStencilOpEXT(commandBuffer, faceMask, failOp, passOp, depthFailOp, compareOp, record_obj);
        }
    }
}

VKAPI_ATTR VkResult VKAPI_CALL CopyMemoryToImageEXT(VkDevice device, const VkCopyMemoryToImageInfo* pCopyMemoryToImageInfo) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCopyMemoryToImageEXT, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCopyMemoryToImageEXT");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCopyMemoryToImageEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCopyMemoryToImageEXT(device, pCopyMemoryToImageInfo, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkCopyMemoryToImageEXT);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCopyMemoryToImageEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCopyMemoryToImageEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCopyMemoryToImageEXT(device, pCopyMemoryToImageInfo, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkCopyMemoryToImageEXT");
        result = device_dispatch->CopyMemoryToImageEXT(device, pCopyMemoryToImageInfo);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkCopyMemoryToImageEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCopyMemoryToImageEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCopyMemoryToImageEXT(device, pCopyMemoryToImageInfo, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR VkResult VKAPI_CALL CopyImageToMemoryEXT(VkDevice device, const VkCopyImageToMemoryInfo* pCopyImageToMemoryInfo) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCopyImageToMemoryEXT, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCopyImageToMemoryEXT");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCopyImageToMemoryEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCopyImageToMemoryEXT(device, pCopyImageToMemoryInfo, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkCopyImageToMemoryEXT);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCopyImageToMemoryEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCopyImageToMemoryEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCopyImageToMemoryEXT(device, pCopyImageToMemoryInfo, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkCopyImageToMemoryEXT");
        result = device_dispatch->CopyImageToMemoryEXT(device, pCopyImageToMemoryInfo);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkCopyImageToMemoryEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCopyImageToMemoryEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCopyImageToMemoryEXT(device, pCopyImageToMemoryInfo, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR VkResult VKAPI_CALL CopyImageToImageEXT(VkDevice device, const VkCopyImageToImageInfo* pCopyImageToImageInfo) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCopyImageToImageEXT, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCopyImageToImageEXT");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCopyImageToImageEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCopyImageToImageEXT(device, pCopyImageToImageInfo, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkCopyImageToImageEXT);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCopyImageToImageEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCopyImageToImageEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCopyImageToImageEXT(device, pCopyImageToImageInfo, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkCopyImageToImageEXT");
        result = device_dispatch->CopyImageToImageEXT(device, pCopyImageToImageInfo);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkCopyImageToImageEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCopyImageToImageEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCopyImageToImageEXT(device, pCopyImageToImageInfo, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR VkResult VKAPI_CALL TransitionImageLayoutEXT(VkDevice device, uint32_t transitionCount,
                                                        const VkHostImageLayoutTransitionInfo* pTransitions) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkTransitionImageLayoutEXT, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkTransitionImageLayoutEXT");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateTransitionImageLayoutEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateTransitionImageLayoutEXT(device, transitionCount, pTransitions, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkTransitionImageLayoutEXT);
    {
        VVL_ZoneScopedN("PreCallRecord_vkTransitionImageLayoutEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordTransitionImageLayoutEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordTransitionImageLayoutEXT(device, transitionCount, pTransitions, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkTransitionImageLayoutEXT");
        result = device_dispatch->TransitionImageLayoutEXT(device, transitionCount, pTransitions);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkTransitionImageLayoutEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordTransitionImageLayoutEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordTransitionImageLayoutEXT(device, transitionCount, pTransitions, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR void VKAPI_CALL GetImageSubresourceLayout2EXT(VkDevice device, VkImage image, const VkImageSubresource2* pSubresource,
                                                         VkSubresourceLayout2* pLayout) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetImageSubresourceLayout2EXT, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetImageSubresourceLayout2EXT");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateGetImageSubresourceLayout2EXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateGetImageSubresourceLayout2EXT(device, image, pSubresource, pLayout, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetImageSubresourceLayout2EXT);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetImageSubresourceLayout2EXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordGetImageSubresourceLayout2EXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordGetImageSubresourceLayout2EXT(device, image, pSubresource, pLayout, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkGetImageSubresourceLayout2EXT");
        device_dispatch->GetImageSubresourceLayout2EXT(device, image, pSubresource, pLayout);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetImageSubresourceLayout2EXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordGetImageSubresourceLayout2EXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordGetImageSubresourceLayout2EXT(device, image, pSubresource, pLayout, record_obj);
        }
    }
}

VKAPI_ATTR VkResult VKAPI_CALL ReleaseSwapchainImagesEXT(VkDevice device, const VkReleaseSwapchainImagesInfoKHR* pReleaseInfo) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkReleaseSwapchainImagesEXT, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkReleaseSwapchainImagesEXT");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateReleaseSwapchainImagesEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateReleaseSwapchainImagesEXT(device, pReleaseInfo, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkReleaseSwapchainImagesEXT);
    {
        VVL_ZoneScopedN("PreCallRecord_vkReleaseSwapchainImagesEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordReleaseSwapchainImagesEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordReleaseSwapchainImagesEXT(device, pReleaseInfo, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkReleaseSwapchainImagesEXT");
        result = device_dispatch->ReleaseSwapchainImagesEXT(device, pReleaseInfo);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkReleaseSwapchainImagesEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordReleaseSwapchainImagesEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordReleaseSwapchainImagesEXT(device, pReleaseInfo, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR void VKAPI_CALL GetGeneratedCommandsMemoryRequirementsNV(VkDevice device,
                                                                    const VkGeneratedCommandsMemoryRequirementsInfoNV* pInfo,
                                                                    VkMemoryRequirements2* pMemoryRequirements) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetGeneratedCommandsMemoryRequirementsNV,
                          VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetGeneratedCommandsMemoryRequirementsNV");
        for (const auto& vo :
             device_dispatch->intercept_vectors[InterceptIdPreCallValidateGetGeneratedCommandsMemoryRequirementsNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateGetGeneratedCommandsMemoryRequirementsNV(device, pInfo, pMemoryRequirements, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetGeneratedCommandsMemoryRequirementsNV);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetGeneratedCommandsMemoryRequirementsNV");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordGetGeneratedCommandsMemoryRequirementsNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordGetGeneratedCommandsMemoryRequirementsNV(device, pInfo, pMemoryRequirements, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkGetGeneratedCommandsMemoryRequirementsNV");
        device_dispatch->GetGeneratedCommandsMemoryRequirementsNV(device, pInfo, pMemoryRequirements);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetGeneratedCommandsMemoryRequirementsNV");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordGetGeneratedCommandsMemoryRequirementsNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordGetGeneratedCommandsMemoryRequirementsNV(device, pInfo, pMemoryRequirements, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdPreprocessGeneratedCommandsNV(VkCommandBuffer commandBuffer,
                                                            const VkGeneratedCommandsInfoNV* pGeneratedCommandsInfo) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdPreprocessGeneratedCommandsNV,
                          VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdPreprocessGeneratedCommandsNV");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdPreprocessGeneratedCommandsNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdPreprocessGeneratedCommandsNV(commandBuffer, pGeneratedCommandsInfo, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdPreprocessGeneratedCommandsNV);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdPreprocessGeneratedCommandsNV");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdPreprocessGeneratedCommandsNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdPreprocessGeneratedCommandsNV(commandBuffer, pGeneratedCommandsInfo, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdPreprocessGeneratedCommandsNV");
        device_dispatch->CmdPreprocessGeneratedCommandsNV(commandBuffer, pGeneratedCommandsInfo);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdPreprocessGeneratedCommandsNV");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdPreprocessGeneratedCommandsNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdPreprocessGeneratedCommandsNV(commandBuffer, pGeneratedCommandsInfo, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdExecuteGeneratedCommandsNV(VkCommandBuffer commandBuffer, VkBool32 isPreprocessed,
                                                         const VkGeneratedCommandsInfoNV* pGeneratedCommandsInfo) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdExecuteGeneratedCommandsNV,
                          VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdExecuteGeneratedCommandsNV");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdExecuteGeneratedCommandsNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |=
                vo->PreCallValidateCmdExecuteGeneratedCommandsNV(commandBuffer, isPreprocessed, pGeneratedCommandsInfo, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdExecuteGeneratedCommandsNV);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdExecuteGeneratedCommandsNV");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdExecuteGeneratedCommandsNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdExecuteGeneratedCommandsNV(commandBuffer, isPreprocessed, pGeneratedCommandsInfo, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdExecuteGeneratedCommandsNV");
        device_dispatch->CmdExecuteGeneratedCommandsNV(commandBuffer, isPreprocessed, pGeneratedCommandsInfo);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdExecuteGeneratedCommandsNV");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdExecuteGeneratedCommandsNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdExecuteGeneratedCommandsNV(commandBuffer, isPreprocessed, pGeneratedCommandsInfo, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdBindPipelineShaderGroupNV(VkCommandBuffer commandBuffer, VkPipelineBindPoint pipelineBindPoint,
                                                        VkPipeline pipeline, uint32_t groupIndex) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdBindPipelineShaderGroupNV,
                          VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdBindPipelineShaderGroupNV");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdBindPipelineShaderGroupNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |=
                vo->PreCallValidateCmdBindPipelineShaderGroupNV(commandBuffer, pipelineBindPoint, pipeline, groupIndex, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdBindPipelineShaderGroupNV);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdBindPipelineShaderGroupNV");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdBindPipelineShaderGroupNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdBindPipelineShaderGroupNV(commandBuffer, pipelineBindPoint, pipeline, groupIndex, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdBindPipelineShaderGroupNV");
        device_dispatch->CmdBindPipelineShaderGroupNV(commandBuffer, pipelineBindPoint, pipeline, groupIndex);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdBindPipelineShaderGroupNV");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdBindPipelineShaderGroupNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdBindPipelineShaderGroupNV(commandBuffer, pipelineBindPoint, pipeline, groupIndex, record_obj);
        }
    }
}

VKAPI_ATTR VkResult VKAPI_CALL CreateIndirectCommandsLayoutNV(VkDevice device,
                                                              const VkIndirectCommandsLayoutCreateInfoNV* pCreateInfo,
                                                              const VkAllocationCallbacks* pAllocator,
                                                              VkIndirectCommandsLayoutNV* pIndirectCommandsLayout) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCreateIndirectCommandsLayoutNV, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCreateIndirectCommandsLayoutNV");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCreateIndirectCommandsLayoutNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCreateIndirectCommandsLayoutNV(device, pCreateInfo, pAllocator, pIndirectCommandsLayout,
                                                                      error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkCreateIndirectCommandsLayoutNV);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCreateIndirectCommandsLayoutNV");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCreateIndirectCommandsLayoutNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCreateIndirectCommandsLayoutNV(device, pCreateInfo, pAllocator, pIndirectCommandsLayout, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkCreateIndirectCommandsLayoutNV");
        result = device_dispatch->CreateIndirectCommandsLayoutNV(device, pCreateInfo, pAllocator, pIndirectCommandsLayout);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkCreateIndirectCommandsLayoutNV");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCreateIndirectCommandsLayoutNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCreateIndirectCommandsLayoutNV(device, pCreateInfo, pAllocator, pIndirectCommandsLayout, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR void VKAPI_CALL DestroyIndirectCommandsLayoutNV(VkDevice device, VkIndirectCommandsLayoutNV indirectCommandsLayout,
                                                           const VkAllocationCallbacks* pAllocator) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkDestroyIndirectCommandsLayoutNV, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkDestroyIndirectCommandsLayoutNV");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateDestroyIndirectCommandsLayoutNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateDestroyIndirectCommandsLayoutNV(device, indirectCommandsLayout, pAllocator, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkDestroyIndirectCommandsLayoutNV);
    {
        VVL_ZoneScopedN("PreCallRecord_vkDestroyIndirectCommandsLayoutNV");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordDestroyIndirectCommandsLayoutNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordDestroyIndirectCommandsLayoutNV(device, indirectCommandsLayout, pAllocator, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkDestroyIndirectCommandsLayoutNV");
        device_dispatch->DestroyIndirectCommandsLayoutNV(device, indirectCommandsLayout, pAllocator);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkDestroyIndirectCommandsLayoutNV");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordDestroyIndirectCommandsLayoutNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordDestroyIndirectCommandsLayoutNV(device, indirectCommandsLayout, pAllocator, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdSetDepthBias2EXT(VkCommandBuffer commandBuffer, const VkDepthBiasInfoEXT* pDepthBiasInfo) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdSetDepthBias2EXT, VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdSetDepthBias2EXT");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdSetDepthBias2EXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdSetDepthBias2EXT(commandBuffer, pDepthBiasInfo, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdSetDepthBias2EXT);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdSetDepthBias2EXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdSetDepthBias2EXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdSetDepthBias2EXT(commandBuffer, pDepthBiasInfo, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdSetDepthBias2EXT");
        device_dispatch->CmdSetDepthBias2EXT(commandBuffer, pDepthBiasInfo);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdSetDepthBias2EXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdSetDepthBias2EXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdSetDepthBias2EXT(commandBuffer, pDepthBiasInfo, record_obj);
        }
    }
}

VKAPI_ATTR VkResult VKAPI_CALL AcquireDrmDisplayEXT(VkPhysicalDevice physicalDevice, int32_t drmFd, VkDisplayKHR display) {
    VVL_ZoneScoped;

    auto instance_dispatch = vvl::dispatch::GetData(physicalDevice);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkAcquireDrmDisplayEXT, VulkanTypedHandle(physicalDevice, kVulkanObjectTypePhysicalDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkAcquireDrmDisplayEXT");
        for (const auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            skip |= vo->PreCallValidateAcquireDrmDisplayEXT(physicalDevice, drmFd, display, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkAcquireDrmDisplayEXT);
    {
        VVL_ZoneScopedN("PreCallRecord_vkAcquireDrmDisplayEXT");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PreCallRecordAcquireDrmDisplayEXT(physicalDevice, drmFd, display, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkAcquireDrmDisplayEXT");
        result = instance_dispatch->AcquireDrmDisplayEXT(physicalDevice, drmFd, display);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkAcquireDrmDisplayEXT");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PostCallRecordAcquireDrmDisplayEXT(physicalDevice, drmFd, display, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR VkResult VKAPI_CALL GetDrmDisplayEXT(VkPhysicalDevice physicalDevice, int32_t drmFd, uint32_t connectorId,
                                                VkDisplayKHR* display) {
    VVL_ZoneScoped;

    auto instance_dispatch = vvl::dispatch::GetData(physicalDevice);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetDrmDisplayEXT, VulkanTypedHandle(physicalDevice, kVulkanObjectTypePhysicalDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetDrmDisplayEXT");
        for (const auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            skip |= vo->PreCallValidateGetDrmDisplayEXT(physicalDevice, drmFd, connectorId, display, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetDrmDisplayEXT);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetDrmDisplayEXT");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PreCallRecordGetDrmDisplayEXT(physicalDevice, drmFd, connectorId, display, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkGetDrmDisplayEXT");
        result = instance_dispatch->GetDrmDisplayEXT(physicalDevice, drmFd, connectorId, display);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetDrmDisplayEXT");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PostCallRecordGetDrmDisplayEXT(physicalDevice, drmFd, connectorId, display, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR VkResult VKAPI_CALL CreatePrivateDataSlotEXT(VkDevice device, const VkPrivateDataSlotCreateInfo* pCreateInfo,
                                                        const VkAllocationCallbacks* pAllocator,
                                                        VkPrivateDataSlot* pPrivateDataSlot) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCreatePrivateDataSlotEXT, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCreatePrivateDataSlotEXT");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCreatePrivateDataSlotEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCreatePrivateDataSlotEXT(device, pCreateInfo, pAllocator, pPrivateDataSlot, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkCreatePrivateDataSlotEXT);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCreatePrivateDataSlotEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCreatePrivateDataSlotEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCreatePrivateDataSlotEXT(device, pCreateInfo, pAllocator, pPrivateDataSlot, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkCreatePrivateDataSlotEXT");
        result = device_dispatch->CreatePrivateDataSlotEXT(device, pCreateInfo, pAllocator, pPrivateDataSlot);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkCreatePrivateDataSlotEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCreatePrivateDataSlotEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCreatePrivateDataSlotEXT(device, pCreateInfo, pAllocator, pPrivateDataSlot, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR void VKAPI_CALL DestroyPrivateDataSlotEXT(VkDevice device, VkPrivateDataSlot privateDataSlot,
                                                     const VkAllocationCallbacks* pAllocator) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkDestroyPrivateDataSlotEXT, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkDestroyPrivateDataSlotEXT");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateDestroyPrivateDataSlotEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateDestroyPrivateDataSlotEXT(device, privateDataSlot, pAllocator, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkDestroyPrivateDataSlotEXT);
    {
        VVL_ZoneScopedN("PreCallRecord_vkDestroyPrivateDataSlotEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordDestroyPrivateDataSlotEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordDestroyPrivateDataSlotEXT(device, privateDataSlot, pAllocator, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkDestroyPrivateDataSlotEXT");
        device_dispatch->DestroyPrivateDataSlotEXT(device, privateDataSlot, pAllocator);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkDestroyPrivateDataSlotEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordDestroyPrivateDataSlotEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordDestroyPrivateDataSlotEXT(device, privateDataSlot, pAllocator, record_obj);
        }
    }
}

VKAPI_ATTR VkResult VKAPI_CALL SetPrivateDataEXT(VkDevice device, VkObjectType objectType, uint64_t objectHandle,
                                                 VkPrivateDataSlot privateDataSlot, uint64_t data) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkSetPrivateDataEXT, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkSetPrivateDataEXT");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateSetPrivateDataEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateSetPrivateDataEXT(device, objectType, objectHandle, privateDataSlot, data, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkSetPrivateDataEXT);
    {
        VVL_ZoneScopedN("PreCallRecord_vkSetPrivateDataEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordSetPrivateDataEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordSetPrivateDataEXT(device, objectType, objectHandle, privateDataSlot, data, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkSetPrivateDataEXT");
        result = device_dispatch->SetPrivateDataEXT(device, objectType, objectHandle, privateDataSlot, data);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkSetPrivateDataEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordSetPrivateDataEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordSetPrivateDataEXT(device, objectType, objectHandle, privateDataSlot, data, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR void VKAPI_CALL GetPrivateDataEXT(VkDevice device, VkObjectType objectType, uint64_t objectHandle,
                                             VkPrivateDataSlot privateDataSlot, uint64_t* pData) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetPrivateDataEXT, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetPrivateDataEXT");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateGetPrivateDataEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateGetPrivateDataEXT(device, objectType, objectHandle, privateDataSlot, pData, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetPrivateDataEXT);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetPrivateDataEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordGetPrivateDataEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordGetPrivateDataEXT(device, objectType, objectHandle, privateDataSlot, pData, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkGetPrivateDataEXT");
        device_dispatch->GetPrivateDataEXT(device, objectType, objectHandle, privateDataSlot, pData);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetPrivateDataEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordGetPrivateDataEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordGetPrivateDataEXT(device, objectType, objectHandle, privateDataSlot, pData, record_obj);
        }
    }
}

#ifdef VK_ENABLE_BETA_EXTENSIONS
VKAPI_ATTR VkResult VKAPI_CALL CreateCudaModuleNV(VkDevice device, const VkCudaModuleCreateInfoNV* pCreateInfo,
                                                  const VkAllocationCallbacks* pAllocator, VkCudaModuleNV* pModule) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCreateCudaModuleNV, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCreateCudaModuleNV");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCreateCudaModuleNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCreateCudaModuleNV(device, pCreateInfo, pAllocator, pModule, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkCreateCudaModuleNV);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCreateCudaModuleNV");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCreateCudaModuleNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCreateCudaModuleNV(device, pCreateInfo, pAllocator, pModule, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkCreateCudaModuleNV");
        result = device_dispatch->CreateCudaModuleNV(device, pCreateInfo, pAllocator, pModule);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkCreateCudaModuleNV");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCreateCudaModuleNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCreateCudaModuleNV(device, pCreateInfo, pAllocator, pModule, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR VkResult VKAPI_CALL GetCudaModuleCacheNV(VkDevice device, VkCudaModuleNV module, size_t* pCacheSize, void* pCacheData) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetCudaModuleCacheNV, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetCudaModuleCacheNV");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateGetCudaModuleCacheNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateGetCudaModuleCacheNV(device, module, pCacheSize, pCacheData, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetCudaModuleCacheNV);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetCudaModuleCacheNV");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordGetCudaModuleCacheNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordGetCudaModuleCacheNV(device, module, pCacheSize, pCacheData, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkGetCudaModuleCacheNV");
        result = device_dispatch->GetCudaModuleCacheNV(device, module, pCacheSize, pCacheData);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetCudaModuleCacheNV");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordGetCudaModuleCacheNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordGetCudaModuleCacheNV(device, module, pCacheSize, pCacheData, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR VkResult VKAPI_CALL CreateCudaFunctionNV(VkDevice device, const VkCudaFunctionCreateInfoNV* pCreateInfo,
                                                    const VkAllocationCallbacks* pAllocator, VkCudaFunctionNV* pFunction) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCreateCudaFunctionNV, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCreateCudaFunctionNV");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCreateCudaFunctionNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCreateCudaFunctionNV(device, pCreateInfo, pAllocator, pFunction, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkCreateCudaFunctionNV);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCreateCudaFunctionNV");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCreateCudaFunctionNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCreateCudaFunctionNV(device, pCreateInfo, pAllocator, pFunction, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkCreateCudaFunctionNV");
        result = device_dispatch->CreateCudaFunctionNV(device, pCreateInfo, pAllocator, pFunction);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkCreateCudaFunctionNV");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCreateCudaFunctionNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCreateCudaFunctionNV(device, pCreateInfo, pAllocator, pFunction, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR void VKAPI_CALL DestroyCudaModuleNV(VkDevice device, VkCudaModuleNV module, const VkAllocationCallbacks* pAllocator) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkDestroyCudaModuleNV, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkDestroyCudaModuleNV");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateDestroyCudaModuleNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateDestroyCudaModuleNV(device, module, pAllocator, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkDestroyCudaModuleNV);
    {
        VVL_ZoneScopedN("PreCallRecord_vkDestroyCudaModuleNV");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordDestroyCudaModuleNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordDestroyCudaModuleNV(device, module, pAllocator, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkDestroyCudaModuleNV");
        device_dispatch->DestroyCudaModuleNV(device, module, pAllocator);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkDestroyCudaModuleNV");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordDestroyCudaModuleNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordDestroyCudaModuleNV(device, module, pAllocator, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL DestroyCudaFunctionNV(VkDevice device, VkCudaFunctionNV function,
                                                 const VkAllocationCallbacks* pAllocator) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkDestroyCudaFunctionNV, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkDestroyCudaFunctionNV");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateDestroyCudaFunctionNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateDestroyCudaFunctionNV(device, function, pAllocator, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkDestroyCudaFunctionNV);
    {
        VVL_ZoneScopedN("PreCallRecord_vkDestroyCudaFunctionNV");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordDestroyCudaFunctionNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordDestroyCudaFunctionNV(device, function, pAllocator, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkDestroyCudaFunctionNV");
        device_dispatch->DestroyCudaFunctionNV(device, function, pAllocator);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkDestroyCudaFunctionNV");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordDestroyCudaFunctionNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordDestroyCudaFunctionNV(device, function, pAllocator, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdCudaLaunchKernelNV(VkCommandBuffer commandBuffer, const VkCudaLaunchInfoNV* pLaunchInfo) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdCudaLaunchKernelNV, VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdCudaLaunchKernelNV");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdCudaLaunchKernelNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdCudaLaunchKernelNV(commandBuffer, pLaunchInfo, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdCudaLaunchKernelNV);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdCudaLaunchKernelNV");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdCudaLaunchKernelNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdCudaLaunchKernelNV(commandBuffer, pLaunchInfo, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdCudaLaunchKernelNV");
        device_dispatch->CmdCudaLaunchKernelNV(commandBuffer, pLaunchInfo);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdCudaLaunchKernelNV");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdCudaLaunchKernelNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdCudaLaunchKernelNV(commandBuffer, pLaunchInfo, record_obj);
        }
    }
}

#endif  // VK_ENABLE_BETA_EXTENSIONS
VKAPI_ATTR void VKAPI_CALL CmdDispatchTileQCOM(VkCommandBuffer commandBuffer, const VkDispatchTileInfoQCOM* pDispatchTileInfo) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdDispatchTileQCOM, VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdDispatchTileQCOM");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdDispatchTileQCOM]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdDispatchTileQCOM(commandBuffer, pDispatchTileInfo, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdDispatchTileQCOM);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdDispatchTileQCOM");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdDispatchTileQCOM]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdDispatchTileQCOM(commandBuffer, pDispatchTileInfo, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdDispatchTileQCOM");
        device_dispatch->CmdDispatchTileQCOM(commandBuffer, pDispatchTileInfo);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdDispatchTileQCOM");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdDispatchTileQCOM]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdDispatchTileQCOM(commandBuffer, pDispatchTileInfo, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdBeginPerTileExecutionQCOM(VkCommandBuffer commandBuffer,
                                                        const VkPerTileBeginInfoQCOM* pPerTileBeginInfo) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdBeginPerTileExecutionQCOM,
                          VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdBeginPerTileExecutionQCOM");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdBeginPerTileExecutionQCOM]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdBeginPerTileExecutionQCOM(commandBuffer, pPerTileBeginInfo, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdBeginPerTileExecutionQCOM);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdBeginPerTileExecutionQCOM");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdBeginPerTileExecutionQCOM]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdBeginPerTileExecutionQCOM(commandBuffer, pPerTileBeginInfo, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdBeginPerTileExecutionQCOM");
        device_dispatch->CmdBeginPerTileExecutionQCOM(commandBuffer, pPerTileBeginInfo);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdBeginPerTileExecutionQCOM");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdBeginPerTileExecutionQCOM]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdBeginPerTileExecutionQCOM(commandBuffer, pPerTileBeginInfo, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdEndPerTileExecutionQCOM(VkCommandBuffer commandBuffer, const VkPerTileEndInfoQCOM* pPerTileEndInfo) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdEndPerTileExecutionQCOM,
                          VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdEndPerTileExecutionQCOM");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdEndPerTileExecutionQCOM]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdEndPerTileExecutionQCOM(commandBuffer, pPerTileEndInfo, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdEndPerTileExecutionQCOM);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdEndPerTileExecutionQCOM");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdEndPerTileExecutionQCOM]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdEndPerTileExecutionQCOM(commandBuffer, pPerTileEndInfo, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdEndPerTileExecutionQCOM");
        device_dispatch->CmdEndPerTileExecutionQCOM(commandBuffer, pPerTileEndInfo);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdEndPerTileExecutionQCOM");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdEndPerTileExecutionQCOM]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdEndPerTileExecutionQCOM(commandBuffer, pPerTileEndInfo, record_obj);
        }
    }
}

#ifdef VK_USE_PLATFORM_METAL_EXT
VKAPI_ATTR void VKAPI_CALL ExportMetalObjectsEXT(VkDevice device, VkExportMetalObjectsInfoEXT* pMetalObjectsInfo) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkExportMetalObjectsEXT, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkExportMetalObjectsEXT");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateExportMetalObjectsEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateExportMetalObjectsEXT(device, pMetalObjectsInfo, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkExportMetalObjectsEXT);
    {
        VVL_ZoneScopedN("PreCallRecord_vkExportMetalObjectsEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordExportMetalObjectsEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordExportMetalObjectsEXT(device, pMetalObjectsInfo, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkExportMetalObjectsEXT");
        device_dispatch->ExportMetalObjectsEXT(device, pMetalObjectsInfo);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkExportMetalObjectsEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordExportMetalObjectsEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordExportMetalObjectsEXT(device, pMetalObjectsInfo, record_obj);
        }
    }
}

#endif  // VK_USE_PLATFORM_METAL_EXT
VKAPI_ATTR void VKAPI_CALL GetDescriptorSetLayoutSizeEXT(VkDevice device, VkDescriptorSetLayout layout,
                                                         VkDeviceSize* pLayoutSizeInBytes) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetDescriptorSetLayoutSizeEXT, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetDescriptorSetLayoutSizeEXT");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateGetDescriptorSetLayoutSizeEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateGetDescriptorSetLayoutSizeEXT(device, layout, pLayoutSizeInBytes, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetDescriptorSetLayoutSizeEXT);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetDescriptorSetLayoutSizeEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordGetDescriptorSetLayoutSizeEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordGetDescriptorSetLayoutSizeEXT(device, layout, pLayoutSizeInBytes, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkGetDescriptorSetLayoutSizeEXT");
        device_dispatch->GetDescriptorSetLayoutSizeEXT(device, layout, pLayoutSizeInBytes);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetDescriptorSetLayoutSizeEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordGetDescriptorSetLayoutSizeEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordGetDescriptorSetLayoutSizeEXT(device, layout, pLayoutSizeInBytes, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL GetDescriptorSetLayoutBindingOffsetEXT(VkDevice device, VkDescriptorSetLayout layout, uint32_t binding,
                                                                  VkDeviceSize* pOffset) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetDescriptorSetLayoutBindingOffsetEXT, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetDescriptorSetLayoutBindingOffsetEXT");
        for (const auto& vo :
             device_dispatch->intercept_vectors[InterceptIdPreCallValidateGetDescriptorSetLayoutBindingOffsetEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateGetDescriptorSetLayoutBindingOffsetEXT(device, layout, binding, pOffset, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetDescriptorSetLayoutBindingOffsetEXT);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetDescriptorSetLayoutBindingOffsetEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordGetDescriptorSetLayoutBindingOffsetEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordGetDescriptorSetLayoutBindingOffsetEXT(device, layout, binding, pOffset, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkGetDescriptorSetLayoutBindingOffsetEXT");
        device_dispatch->GetDescriptorSetLayoutBindingOffsetEXT(device, layout, binding, pOffset);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetDescriptorSetLayoutBindingOffsetEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordGetDescriptorSetLayoutBindingOffsetEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordGetDescriptorSetLayoutBindingOffsetEXT(device, layout, binding, pOffset, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL GetDescriptorEXT(VkDevice device, const VkDescriptorGetInfoEXT* pDescriptorInfo, size_t dataSize,
                                            void* pDescriptor) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetDescriptorEXT, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetDescriptorEXT");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateGetDescriptorEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateGetDescriptorEXT(device, pDescriptorInfo, dataSize, pDescriptor, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetDescriptorEXT);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetDescriptorEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordGetDescriptorEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordGetDescriptorEXT(device, pDescriptorInfo, dataSize, pDescriptor, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkGetDescriptorEXT");
        device_dispatch->GetDescriptorEXT(device, pDescriptorInfo, dataSize, pDescriptor);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetDescriptorEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordGetDescriptorEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordGetDescriptorEXT(device, pDescriptorInfo, dataSize, pDescriptor, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdSetDescriptorBufferOffsetsEXT(VkCommandBuffer commandBuffer, VkPipelineBindPoint pipelineBindPoint,
                                                            VkPipelineLayout layout, uint32_t firstSet, uint32_t setCount,
                                                            const uint32_t* pBufferIndices, const VkDeviceSize* pOffsets) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdSetDescriptorBufferOffsetsEXT,
                          VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdSetDescriptorBufferOffsetsEXT");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdSetDescriptorBufferOffsetsEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdSetDescriptorBufferOffsetsEXT(commandBuffer, pipelineBindPoint, layout, firstSet,
                                                                        setCount, pBufferIndices, pOffsets, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdSetDescriptorBufferOffsetsEXT);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdSetDescriptorBufferOffsetsEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdSetDescriptorBufferOffsetsEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdSetDescriptorBufferOffsetsEXT(commandBuffer, pipelineBindPoint, layout, firstSet, setCount,
                                                              pBufferIndices, pOffsets, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdSetDescriptorBufferOffsetsEXT");
        device_dispatch->CmdSetDescriptorBufferOffsetsEXT(commandBuffer, pipelineBindPoint, layout, firstSet, setCount,
                                                          pBufferIndices, pOffsets);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdSetDescriptorBufferOffsetsEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdSetDescriptorBufferOffsetsEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdSetDescriptorBufferOffsetsEXT(commandBuffer, pipelineBindPoint, layout, firstSet, setCount,
                                                               pBufferIndices, pOffsets, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdBindDescriptorBufferEmbeddedSamplersEXT(VkCommandBuffer commandBuffer,
                                                                      VkPipelineBindPoint pipelineBindPoint,
                                                                      VkPipelineLayout layout, uint32_t set) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdBindDescriptorBufferEmbeddedSamplersEXT,
                          VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdBindDescriptorBufferEmbeddedSamplersEXT");
        for (const auto& vo :
             device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdBindDescriptorBufferEmbeddedSamplersEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdBindDescriptorBufferEmbeddedSamplersEXT(commandBuffer, pipelineBindPoint, layout, set,
                                                                                  error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdBindDescriptorBufferEmbeddedSamplersEXT);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdBindDescriptorBufferEmbeddedSamplersEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdBindDescriptorBufferEmbeddedSamplersEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdBindDescriptorBufferEmbeddedSamplersEXT(commandBuffer, pipelineBindPoint, layout, set, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdBindDescriptorBufferEmbeddedSamplersEXT");
        device_dispatch->CmdBindDescriptorBufferEmbeddedSamplersEXT(commandBuffer, pipelineBindPoint, layout, set);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdBindDescriptorBufferEmbeddedSamplersEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdBindDescriptorBufferEmbeddedSamplersEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdBindDescriptorBufferEmbeddedSamplersEXT(commandBuffer, pipelineBindPoint, layout, set, record_obj);
        }
    }
}

VKAPI_ATTR VkResult VKAPI_CALL GetBufferOpaqueCaptureDescriptorDataEXT(VkDevice device,
                                                                       const VkBufferCaptureDescriptorDataInfoEXT* pInfo,
                                                                       void* pData) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetBufferOpaqueCaptureDescriptorDataEXT, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetBufferOpaqueCaptureDescriptorDataEXT");
        for (const auto& vo :
             device_dispatch->intercept_vectors[InterceptIdPreCallValidateGetBufferOpaqueCaptureDescriptorDataEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateGetBufferOpaqueCaptureDescriptorDataEXT(device, pInfo, pData, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetBufferOpaqueCaptureDescriptorDataEXT);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetBufferOpaqueCaptureDescriptorDataEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordGetBufferOpaqueCaptureDescriptorDataEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordGetBufferOpaqueCaptureDescriptorDataEXT(device, pInfo, pData, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkGetBufferOpaqueCaptureDescriptorDataEXT");
        result = device_dispatch->GetBufferOpaqueCaptureDescriptorDataEXT(device, pInfo, pData);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetBufferOpaqueCaptureDescriptorDataEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordGetBufferOpaqueCaptureDescriptorDataEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordGetBufferOpaqueCaptureDescriptorDataEXT(device, pInfo, pData, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR VkResult VKAPI_CALL GetImageOpaqueCaptureDescriptorDataEXT(VkDevice device,
                                                                      const VkImageCaptureDescriptorDataInfoEXT* pInfo,
                                                                      void* pData) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetImageOpaqueCaptureDescriptorDataEXT, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetImageOpaqueCaptureDescriptorDataEXT");
        for (const auto& vo :
             device_dispatch->intercept_vectors[InterceptIdPreCallValidateGetImageOpaqueCaptureDescriptorDataEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateGetImageOpaqueCaptureDescriptorDataEXT(device, pInfo, pData, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetImageOpaqueCaptureDescriptorDataEXT);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetImageOpaqueCaptureDescriptorDataEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordGetImageOpaqueCaptureDescriptorDataEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordGetImageOpaqueCaptureDescriptorDataEXT(device, pInfo, pData, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkGetImageOpaqueCaptureDescriptorDataEXT");
        result = device_dispatch->GetImageOpaqueCaptureDescriptorDataEXT(device, pInfo, pData);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetImageOpaqueCaptureDescriptorDataEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordGetImageOpaqueCaptureDescriptorDataEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordGetImageOpaqueCaptureDescriptorDataEXT(device, pInfo, pData, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR VkResult VKAPI_CALL GetImageViewOpaqueCaptureDescriptorDataEXT(VkDevice device,
                                                                          const VkImageViewCaptureDescriptorDataInfoEXT* pInfo,
                                                                          void* pData) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetImageViewOpaqueCaptureDescriptorDataEXT,
                          VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetImageViewOpaqueCaptureDescriptorDataEXT");
        for (const auto& vo :
             device_dispatch->intercept_vectors[InterceptIdPreCallValidateGetImageViewOpaqueCaptureDescriptorDataEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateGetImageViewOpaqueCaptureDescriptorDataEXT(device, pInfo, pData, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetImageViewOpaqueCaptureDescriptorDataEXT);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetImageViewOpaqueCaptureDescriptorDataEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordGetImageViewOpaqueCaptureDescriptorDataEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordGetImageViewOpaqueCaptureDescriptorDataEXT(device, pInfo, pData, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkGetImageViewOpaqueCaptureDescriptorDataEXT");
        result = device_dispatch->GetImageViewOpaqueCaptureDescriptorDataEXT(device, pInfo, pData);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetImageViewOpaqueCaptureDescriptorDataEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordGetImageViewOpaqueCaptureDescriptorDataEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordGetImageViewOpaqueCaptureDescriptorDataEXT(device, pInfo, pData, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR VkResult VKAPI_CALL GetSamplerOpaqueCaptureDescriptorDataEXT(VkDevice device,
                                                                        const VkSamplerCaptureDescriptorDataInfoEXT* pInfo,
                                                                        void* pData) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetSamplerOpaqueCaptureDescriptorDataEXT,
                          VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetSamplerOpaqueCaptureDescriptorDataEXT");
        for (const auto& vo :
             device_dispatch->intercept_vectors[InterceptIdPreCallValidateGetSamplerOpaqueCaptureDescriptorDataEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateGetSamplerOpaqueCaptureDescriptorDataEXT(device, pInfo, pData, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetSamplerOpaqueCaptureDescriptorDataEXT);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetSamplerOpaqueCaptureDescriptorDataEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordGetSamplerOpaqueCaptureDescriptorDataEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordGetSamplerOpaqueCaptureDescriptorDataEXT(device, pInfo, pData, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkGetSamplerOpaqueCaptureDescriptorDataEXT");
        result = device_dispatch->GetSamplerOpaqueCaptureDescriptorDataEXT(device, pInfo, pData);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetSamplerOpaqueCaptureDescriptorDataEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordGetSamplerOpaqueCaptureDescriptorDataEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordGetSamplerOpaqueCaptureDescriptorDataEXT(device, pInfo, pData, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR VkResult VKAPI_CALL GetAccelerationStructureOpaqueCaptureDescriptorDataEXT(
    VkDevice device, const VkAccelerationStructureCaptureDescriptorDataInfoEXT* pInfo, void* pData) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetAccelerationStructureOpaqueCaptureDescriptorDataEXT,
                          VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetAccelerationStructureOpaqueCaptureDescriptorDataEXT");
        for (const auto& vo :
             device_dispatch->intercept_vectors[InterceptIdPreCallValidateGetAccelerationStructureOpaqueCaptureDescriptorDataEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateGetAccelerationStructureOpaqueCaptureDescriptorDataEXT(device, pInfo, pData, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetAccelerationStructureOpaqueCaptureDescriptorDataEXT);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetAccelerationStructureOpaqueCaptureDescriptorDataEXT");
        for (auto& vo :
             device_dispatch->intercept_vectors[InterceptIdPreCallRecordGetAccelerationStructureOpaqueCaptureDescriptorDataEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordGetAccelerationStructureOpaqueCaptureDescriptorDataEXT(device, pInfo, pData, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkGetAccelerationStructureOpaqueCaptureDescriptorDataEXT");
        result = device_dispatch->GetAccelerationStructureOpaqueCaptureDescriptorDataEXT(device, pInfo, pData);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetAccelerationStructureOpaqueCaptureDescriptorDataEXT");
        for (auto& vo :
             device_dispatch->intercept_vectors[InterceptIdPostCallRecordGetAccelerationStructureOpaqueCaptureDescriptorDataEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordGetAccelerationStructureOpaqueCaptureDescriptorDataEXT(device, pInfo, pData, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR void VKAPI_CALL CmdSetFragmentShadingRateEnumNV(VkCommandBuffer commandBuffer, VkFragmentShadingRateNV shadingRate,
                                                           const VkFragmentShadingRateCombinerOpKHR combinerOps[2]) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdSetFragmentShadingRateEnumNV,
                          VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdSetFragmentShadingRateEnumNV");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdSetFragmentShadingRateEnumNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdSetFragmentShadingRateEnumNV(commandBuffer, shadingRate, combinerOps, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdSetFragmentShadingRateEnumNV);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdSetFragmentShadingRateEnumNV");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdSetFragmentShadingRateEnumNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdSetFragmentShadingRateEnumNV(commandBuffer, shadingRate, combinerOps, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdSetFragmentShadingRateEnumNV");
        device_dispatch->CmdSetFragmentShadingRateEnumNV(commandBuffer, shadingRate, combinerOps);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdSetFragmentShadingRateEnumNV");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdSetFragmentShadingRateEnumNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdSetFragmentShadingRateEnumNV(commandBuffer, shadingRate, combinerOps, record_obj);
        }
    }
}

VKAPI_ATTR VkResult VKAPI_CALL GetDeviceFaultInfoEXT(VkDevice device, VkDeviceFaultCountsEXT* pFaultCounts,
                                                     VkDeviceFaultInfoEXT* pFaultInfo) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetDeviceFaultInfoEXT, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetDeviceFaultInfoEXT");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateGetDeviceFaultInfoEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateGetDeviceFaultInfoEXT(device, pFaultCounts, pFaultInfo, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetDeviceFaultInfoEXT);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetDeviceFaultInfoEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordGetDeviceFaultInfoEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordGetDeviceFaultInfoEXT(device, pFaultCounts, pFaultInfo, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkGetDeviceFaultInfoEXT");
        result = device_dispatch->GetDeviceFaultInfoEXT(device, pFaultCounts, pFaultInfo);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetDeviceFaultInfoEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordGetDeviceFaultInfoEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordGetDeviceFaultInfoEXT(device, pFaultCounts, pFaultInfo, record_obj);
        }
    }
    return result;
}

#ifdef VK_USE_PLATFORM_WIN32_KHR
VKAPI_ATTR VkResult VKAPI_CALL AcquireWinrtDisplayNV(VkPhysicalDevice physicalDevice, VkDisplayKHR display) {
    VVL_ZoneScoped;

    auto instance_dispatch = vvl::dispatch::GetData(physicalDevice);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkAcquireWinrtDisplayNV, VulkanTypedHandle(physicalDevice, kVulkanObjectTypePhysicalDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkAcquireWinrtDisplayNV");
        for (const auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            skip |= vo->PreCallValidateAcquireWinrtDisplayNV(physicalDevice, display, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkAcquireWinrtDisplayNV);
    {
        VVL_ZoneScopedN("PreCallRecord_vkAcquireWinrtDisplayNV");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PreCallRecordAcquireWinrtDisplayNV(physicalDevice, display, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkAcquireWinrtDisplayNV");
        result = instance_dispatch->AcquireWinrtDisplayNV(physicalDevice, display);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkAcquireWinrtDisplayNV");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PostCallRecordAcquireWinrtDisplayNV(physicalDevice, display, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR VkResult VKAPI_CALL GetWinrtDisplayNV(VkPhysicalDevice physicalDevice, uint32_t deviceRelativeId,
                                                 VkDisplayKHR* pDisplay) {
    VVL_ZoneScoped;

    auto instance_dispatch = vvl::dispatch::GetData(physicalDevice);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetWinrtDisplayNV, VulkanTypedHandle(physicalDevice, kVulkanObjectTypePhysicalDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetWinrtDisplayNV");
        for (const auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            skip |= vo->PreCallValidateGetWinrtDisplayNV(physicalDevice, deviceRelativeId, pDisplay, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetWinrtDisplayNV);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetWinrtDisplayNV");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PreCallRecordGetWinrtDisplayNV(physicalDevice, deviceRelativeId, pDisplay, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkGetWinrtDisplayNV");
        result = instance_dispatch->GetWinrtDisplayNV(physicalDevice, deviceRelativeId, pDisplay);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetWinrtDisplayNV");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PostCallRecordGetWinrtDisplayNV(physicalDevice, deviceRelativeId, pDisplay, record_obj);
        }
    }
    return result;
}

#endif  // VK_USE_PLATFORM_WIN32_KHR
#ifdef VK_USE_PLATFORM_DIRECTFB_EXT
VKAPI_ATTR VkResult VKAPI_CALL CreateDirectFBSurfaceEXT(VkInstance instance, const VkDirectFBSurfaceCreateInfoEXT* pCreateInfo,
                                                        const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface) {
    VVL_ZoneScoped;

    auto instance_dispatch = vvl::dispatch::GetData(instance);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCreateDirectFBSurfaceEXT, VulkanTypedHandle(instance, kVulkanObjectTypeInstance));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCreateDirectFBSurfaceEXT");
        for (const auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            skip |= vo->PreCallValidateCreateDirectFBSurfaceEXT(instance, pCreateInfo, pAllocator, pSurface, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkCreateDirectFBSurfaceEXT);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCreateDirectFBSurfaceEXT");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PreCallRecordCreateDirectFBSurfaceEXT(instance, pCreateInfo, pAllocator, pSurface, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkCreateDirectFBSurfaceEXT");
        result = instance_dispatch->CreateDirectFBSurfaceEXT(instance, pCreateInfo, pAllocator, pSurface);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkCreateDirectFBSurfaceEXT");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PostCallRecordCreateDirectFBSurfaceEXT(instance, pCreateInfo, pAllocator, pSurface, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR VkBool32 VKAPI_CALL GetPhysicalDeviceDirectFBPresentationSupportEXT(VkPhysicalDevice physicalDevice,
                                                                               uint32_t queueFamilyIndex, IDirectFB* dfb) {
    VVL_ZoneScoped;

    auto instance_dispatch = vvl::dispatch::GetData(physicalDevice);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetPhysicalDeviceDirectFBPresentationSupportEXT,
                          VulkanTypedHandle(physicalDevice, kVulkanObjectTypePhysicalDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetPhysicalDeviceDirectFBPresentationSupportEXT");
        for (const auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            skip |= vo->PreCallValidateGetPhysicalDeviceDirectFBPresentationSupportEXT(physicalDevice, queueFamilyIndex, dfb,
                                                                                       error_obj);
            if (skip) return VK_FALSE;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetPhysicalDeviceDirectFBPresentationSupportEXT);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetPhysicalDeviceDirectFBPresentationSupportEXT");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PreCallRecordGetPhysicalDeviceDirectFBPresentationSupportEXT(physicalDevice, queueFamilyIndex, dfb, record_obj);
        }
    }
    VkBool32 result;
    {
        VVL_ZoneScopedN("Dispatch_vkGetPhysicalDeviceDirectFBPresentationSupportEXT");
        result = instance_dispatch->GetPhysicalDeviceDirectFBPresentationSupportEXT(physicalDevice, queueFamilyIndex, dfb);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetPhysicalDeviceDirectFBPresentationSupportEXT");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PostCallRecordGetPhysicalDeviceDirectFBPresentationSupportEXT(physicalDevice, queueFamilyIndex, dfb, record_obj);
        }
    }
    return result;
}

#endif  // VK_USE_PLATFORM_DIRECTFB_EXT
VKAPI_ATTR void VKAPI_CALL CmdSetVertexInputEXT(VkCommandBuffer commandBuffer, uint32_t vertexBindingDescriptionCount,
                                                const VkVertexInputBindingDescription2EXT* pVertexBindingDescriptions,
                                                uint32_t vertexAttributeDescriptionCount,
                                                const VkVertexInputAttributeDescription2EXT* pVertexAttributeDescriptions) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdSetVertexInputEXT, VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdSetVertexInputEXT");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdSetVertexInputEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |=
                vo->PreCallValidateCmdSetVertexInputEXT(commandBuffer, vertexBindingDescriptionCount, pVertexBindingDescriptions,
                                                        vertexAttributeDescriptionCount, pVertexAttributeDescriptions, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdSetVertexInputEXT);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdSetVertexInputEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdSetVertexInputEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdSetVertexInputEXT(commandBuffer, vertexBindingDescriptionCount, pVertexBindingDescriptions,
                                                  vertexAttributeDescriptionCount, pVertexAttributeDescriptions, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdSetVertexInputEXT");
        device_dispatch->CmdSetVertexInputEXT(commandBuffer, vertexBindingDescriptionCount, pVertexBindingDescriptions,
                                              vertexAttributeDescriptionCount, pVertexAttributeDescriptions);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdSetVertexInputEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdSetVertexInputEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdSetVertexInputEXT(commandBuffer, vertexBindingDescriptionCount, pVertexBindingDescriptions,
                                                   vertexAttributeDescriptionCount, pVertexAttributeDescriptions, record_obj);
        }
    }
}

#ifdef VK_USE_PLATFORM_FUCHSIA
VKAPI_ATTR VkResult VKAPI_CALL GetMemoryZirconHandleFUCHSIA(VkDevice device,
                                                            const VkMemoryGetZirconHandleInfoFUCHSIA* pGetZirconHandleInfo,
                                                            zx_handle_t* pZirconHandle) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetMemoryZirconHandleFUCHSIA, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetMemoryZirconHandleFUCHSIA");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateGetMemoryZirconHandleFUCHSIA]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateGetMemoryZirconHandleFUCHSIA(device, pGetZirconHandleInfo, pZirconHandle, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetMemoryZirconHandleFUCHSIA);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetMemoryZirconHandleFUCHSIA");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordGetMemoryZirconHandleFUCHSIA]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordGetMemoryZirconHandleFUCHSIA(device, pGetZirconHandleInfo, pZirconHandle, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkGetMemoryZirconHandleFUCHSIA");
        result = device_dispatch->GetMemoryZirconHandleFUCHSIA(device, pGetZirconHandleInfo, pZirconHandle);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetMemoryZirconHandleFUCHSIA");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordGetMemoryZirconHandleFUCHSIA]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordGetMemoryZirconHandleFUCHSIA(device, pGetZirconHandleInfo, pZirconHandle, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR VkResult VKAPI_CALL
GetMemoryZirconHandlePropertiesFUCHSIA(VkDevice device, VkExternalMemoryHandleTypeFlagBits handleType, zx_handle_t zirconHandle,
                                       VkMemoryZirconHandlePropertiesFUCHSIA* pMemoryZirconHandleProperties) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetMemoryZirconHandlePropertiesFUCHSIA, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetMemoryZirconHandlePropertiesFUCHSIA");
        for (const auto& vo :
             device_dispatch->intercept_vectors[InterceptIdPreCallValidateGetMemoryZirconHandlePropertiesFUCHSIA]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateGetMemoryZirconHandlePropertiesFUCHSIA(device, handleType, zirconHandle,
                                                                              pMemoryZirconHandleProperties, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetMemoryZirconHandlePropertiesFUCHSIA);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetMemoryZirconHandlePropertiesFUCHSIA");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordGetMemoryZirconHandlePropertiesFUCHSIA]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordGetMemoryZirconHandlePropertiesFUCHSIA(device, handleType, zirconHandle, pMemoryZirconHandleProperties,
                                                                    record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkGetMemoryZirconHandlePropertiesFUCHSIA");
        result = device_dispatch->GetMemoryZirconHandlePropertiesFUCHSIA(device, handleType, zirconHandle,
                                                                         pMemoryZirconHandleProperties);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetMemoryZirconHandlePropertiesFUCHSIA");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordGetMemoryZirconHandlePropertiesFUCHSIA]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordGetMemoryZirconHandlePropertiesFUCHSIA(device, handleType, zirconHandle,
                                                                     pMemoryZirconHandleProperties, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR VkResult VKAPI_CALL ImportSemaphoreZirconHandleFUCHSIA(
    VkDevice device, const VkImportSemaphoreZirconHandleInfoFUCHSIA* pImportSemaphoreZirconHandleInfo) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkImportSemaphoreZirconHandleFUCHSIA, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkImportSemaphoreZirconHandleFUCHSIA");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateImportSemaphoreZirconHandleFUCHSIA]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateImportSemaphoreZirconHandleFUCHSIA(device, pImportSemaphoreZirconHandleInfo, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkImportSemaphoreZirconHandleFUCHSIA);
    {
        VVL_ZoneScopedN("PreCallRecord_vkImportSemaphoreZirconHandleFUCHSIA");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordImportSemaphoreZirconHandleFUCHSIA]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordImportSemaphoreZirconHandleFUCHSIA(device, pImportSemaphoreZirconHandleInfo, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkImportSemaphoreZirconHandleFUCHSIA");
        result = device_dispatch->ImportSemaphoreZirconHandleFUCHSIA(device, pImportSemaphoreZirconHandleInfo);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkImportSemaphoreZirconHandleFUCHSIA");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordImportSemaphoreZirconHandleFUCHSIA]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordImportSemaphoreZirconHandleFUCHSIA(device, pImportSemaphoreZirconHandleInfo, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR VkResult VKAPI_CALL GetSemaphoreZirconHandleFUCHSIA(VkDevice device,
                                                               const VkSemaphoreGetZirconHandleInfoFUCHSIA* pGetZirconHandleInfo,
                                                               zx_handle_t* pZirconHandle) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetSemaphoreZirconHandleFUCHSIA, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetSemaphoreZirconHandleFUCHSIA");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateGetSemaphoreZirconHandleFUCHSIA]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateGetSemaphoreZirconHandleFUCHSIA(device, pGetZirconHandleInfo, pZirconHandle, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetSemaphoreZirconHandleFUCHSIA);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetSemaphoreZirconHandleFUCHSIA");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordGetSemaphoreZirconHandleFUCHSIA]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordGetSemaphoreZirconHandleFUCHSIA(device, pGetZirconHandleInfo, pZirconHandle, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkGetSemaphoreZirconHandleFUCHSIA");
        result = device_dispatch->GetSemaphoreZirconHandleFUCHSIA(device, pGetZirconHandleInfo, pZirconHandle);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetSemaphoreZirconHandleFUCHSIA");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordGetSemaphoreZirconHandleFUCHSIA]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordGetSemaphoreZirconHandleFUCHSIA(device, pGetZirconHandleInfo, pZirconHandle, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR VkResult VKAPI_CALL CreateBufferCollectionFUCHSIA(VkDevice device,
                                                             const VkBufferCollectionCreateInfoFUCHSIA* pCreateInfo,
                                                             const VkAllocationCallbacks* pAllocator,
                                                             VkBufferCollectionFUCHSIA* pCollection) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCreateBufferCollectionFUCHSIA, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCreateBufferCollectionFUCHSIA");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCreateBufferCollectionFUCHSIA]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCreateBufferCollectionFUCHSIA(device, pCreateInfo, pAllocator, pCollection, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkCreateBufferCollectionFUCHSIA);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCreateBufferCollectionFUCHSIA");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCreateBufferCollectionFUCHSIA]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCreateBufferCollectionFUCHSIA(device, pCreateInfo, pAllocator, pCollection, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkCreateBufferCollectionFUCHSIA");
        result = device_dispatch->CreateBufferCollectionFUCHSIA(device, pCreateInfo, pAllocator, pCollection);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkCreateBufferCollectionFUCHSIA");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCreateBufferCollectionFUCHSIA]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCreateBufferCollectionFUCHSIA(device, pCreateInfo, pAllocator, pCollection, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR VkResult VKAPI_CALL SetBufferCollectionImageConstraintsFUCHSIA(
    VkDevice device, VkBufferCollectionFUCHSIA collection, const VkImageConstraintsInfoFUCHSIA* pImageConstraintsInfo) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkSetBufferCollectionImageConstraintsFUCHSIA,
                          VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkSetBufferCollectionImageConstraintsFUCHSIA");
        for (const auto& vo :
             device_dispatch->intercept_vectors[InterceptIdPreCallValidateSetBufferCollectionImageConstraintsFUCHSIA]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |=
                vo->PreCallValidateSetBufferCollectionImageConstraintsFUCHSIA(device, collection, pImageConstraintsInfo, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkSetBufferCollectionImageConstraintsFUCHSIA);
    {
        VVL_ZoneScopedN("PreCallRecord_vkSetBufferCollectionImageConstraintsFUCHSIA");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordSetBufferCollectionImageConstraintsFUCHSIA]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordSetBufferCollectionImageConstraintsFUCHSIA(device, collection, pImageConstraintsInfo, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkSetBufferCollectionImageConstraintsFUCHSIA");
        result = device_dispatch->SetBufferCollectionImageConstraintsFUCHSIA(device, collection, pImageConstraintsInfo);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkSetBufferCollectionImageConstraintsFUCHSIA");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordSetBufferCollectionImageConstraintsFUCHSIA]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordSetBufferCollectionImageConstraintsFUCHSIA(device, collection, pImageConstraintsInfo, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR VkResult VKAPI_CALL SetBufferCollectionBufferConstraintsFUCHSIA(
    VkDevice device, VkBufferCollectionFUCHSIA collection, const VkBufferConstraintsInfoFUCHSIA* pBufferConstraintsInfo) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkSetBufferCollectionBufferConstraintsFUCHSIA,
                          VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkSetBufferCollectionBufferConstraintsFUCHSIA");
        for (const auto& vo :
             device_dispatch->intercept_vectors[InterceptIdPreCallValidateSetBufferCollectionBufferConstraintsFUCHSIA]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateSetBufferCollectionBufferConstraintsFUCHSIA(device, collection, pBufferConstraintsInfo,
                                                                                   error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkSetBufferCollectionBufferConstraintsFUCHSIA);
    {
        VVL_ZoneScopedN("PreCallRecord_vkSetBufferCollectionBufferConstraintsFUCHSIA");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordSetBufferCollectionBufferConstraintsFUCHSIA]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordSetBufferCollectionBufferConstraintsFUCHSIA(device, collection, pBufferConstraintsInfo, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkSetBufferCollectionBufferConstraintsFUCHSIA");
        result = device_dispatch->SetBufferCollectionBufferConstraintsFUCHSIA(device, collection, pBufferConstraintsInfo);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkSetBufferCollectionBufferConstraintsFUCHSIA");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordSetBufferCollectionBufferConstraintsFUCHSIA]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordSetBufferCollectionBufferConstraintsFUCHSIA(device, collection, pBufferConstraintsInfo, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR void VKAPI_CALL DestroyBufferCollectionFUCHSIA(VkDevice device, VkBufferCollectionFUCHSIA collection,
                                                          const VkAllocationCallbacks* pAllocator) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkDestroyBufferCollectionFUCHSIA, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkDestroyBufferCollectionFUCHSIA");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateDestroyBufferCollectionFUCHSIA]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateDestroyBufferCollectionFUCHSIA(device, collection, pAllocator, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkDestroyBufferCollectionFUCHSIA);
    {
        VVL_ZoneScopedN("PreCallRecord_vkDestroyBufferCollectionFUCHSIA");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordDestroyBufferCollectionFUCHSIA]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordDestroyBufferCollectionFUCHSIA(device, collection, pAllocator, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkDestroyBufferCollectionFUCHSIA");
        device_dispatch->DestroyBufferCollectionFUCHSIA(device, collection, pAllocator);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkDestroyBufferCollectionFUCHSIA");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordDestroyBufferCollectionFUCHSIA]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordDestroyBufferCollectionFUCHSIA(device, collection, pAllocator, record_obj);
        }
    }
}

VKAPI_ATTR VkResult VKAPI_CALL GetBufferCollectionPropertiesFUCHSIA(VkDevice device, VkBufferCollectionFUCHSIA collection,
                                                                    VkBufferCollectionPropertiesFUCHSIA* pProperties) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetBufferCollectionPropertiesFUCHSIA, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetBufferCollectionPropertiesFUCHSIA");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateGetBufferCollectionPropertiesFUCHSIA]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateGetBufferCollectionPropertiesFUCHSIA(device, collection, pProperties, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetBufferCollectionPropertiesFUCHSIA);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetBufferCollectionPropertiesFUCHSIA");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordGetBufferCollectionPropertiesFUCHSIA]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordGetBufferCollectionPropertiesFUCHSIA(device, collection, pProperties, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkGetBufferCollectionPropertiesFUCHSIA");
        result = device_dispatch->GetBufferCollectionPropertiesFUCHSIA(device, collection, pProperties);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetBufferCollectionPropertiesFUCHSIA");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordGetBufferCollectionPropertiesFUCHSIA]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordGetBufferCollectionPropertiesFUCHSIA(device, collection, pProperties, record_obj);
        }
    }
    return result;
}

#endif  // VK_USE_PLATFORM_FUCHSIA
VKAPI_ATTR VkResult VKAPI_CALL GetDeviceSubpassShadingMaxWorkgroupSizeHUAWEI(VkDevice device, VkRenderPass renderpass,
                                                                             VkExtent2D* pMaxWorkgroupSize) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetDeviceSubpassShadingMaxWorkgroupSizeHUAWEI,
                          VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetDeviceSubpassShadingMaxWorkgroupSizeHUAWEI");
        for (const auto& vo :
             device_dispatch->intercept_vectors[InterceptIdPreCallValidateGetDeviceSubpassShadingMaxWorkgroupSizeHUAWEI]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |=
                vo->PreCallValidateGetDeviceSubpassShadingMaxWorkgroupSizeHUAWEI(device, renderpass, pMaxWorkgroupSize, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetDeviceSubpassShadingMaxWorkgroupSizeHUAWEI);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetDeviceSubpassShadingMaxWorkgroupSizeHUAWEI");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordGetDeviceSubpassShadingMaxWorkgroupSizeHUAWEI]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordGetDeviceSubpassShadingMaxWorkgroupSizeHUAWEI(device, renderpass, pMaxWorkgroupSize, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkGetDeviceSubpassShadingMaxWorkgroupSizeHUAWEI");
        result = device_dispatch->GetDeviceSubpassShadingMaxWorkgroupSizeHUAWEI(device, renderpass, pMaxWorkgroupSize);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetDeviceSubpassShadingMaxWorkgroupSizeHUAWEI");
        for (auto& vo :
             device_dispatch->intercept_vectors[InterceptIdPostCallRecordGetDeviceSubpassShadingMaxWorkgroupSizeHUAWEI]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordGetDeviceSubpassShadingMaxWorkgroupSizeHUAWEI(device, renderpass, pMaxWorkgroupSize, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR void VKAPI_CALL CmdSubpassShadingHUAWEI(VkCommandBuffer commandBuffer) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdSubpassShadingHUAWEI, VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdSubpassShadingHUAWEI");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdSubpassShadingHUAWEI]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdSubpassShadingHUAWEI(commandBuffer, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdSubpassShadingHUAWEI);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdSubpassShadingHUAWEI");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdSubpassShadingHUAWEI]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdSubpassShadingHUAWEI(commandBuffer, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdSubpassShadingHUAWEI");
        device_dispatch->CmdSubpassShadingHUAWEI(commandBuffer);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdSubpassShadingHUAWEI");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdSubpassShadingHUAWEI]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdSubpassShadingHUAWEI(commandBuffer, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdBindInvocationMaskHUAWEI(VkCommandBuffer commandBuffer, VkImageView imageView,
                                                       VkImageLayout imageLayout) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdBindInvocationMaskHUAWEI,
                          VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdBindInvocationMaskHUAWEI");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdBindInvocationMaskHUAWEI]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdBindInvocationMaskHUAWEI(commandBuffer, imageView, imageLayout, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdBindInvocationMaskHUAWEI);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdBindInvocationMaskHUAWEI");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdBindInvocationMaskHUAWEI]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdBindInvocationMaskHUAWEI(commandBuffer, imageView, imageLayout, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdBindInvocationMaskHUAWEI");
        device_dispatch->CmdBindInvocationMaskHUAWEI(commandBuffer, imageView, imageLayout);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdBindInvocationMaskHUAWEI");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdBindInvocationMaskHUAWEI]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdBindInvocationMaskHUAWEI(commandBuffer, imageView, imageLayout, record_obj);
        }
    }
}

VKAPI_ATTR VkResult VKAPI_CALL GetMemoryRemoteAddressNV(VkDevice device,
                                                        const VkMemoryGetRemoteAddressInfoNV* pMemoryGetRemoteAddressInfo,
                                                        VkRemoteAddressNV* pAddress) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetMemoryRemoteAddressNV, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetMemoryRemoteAddressNV");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateGetMemoryRemoteAddressNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateGetMemoryRemoteAddressNV(device, pMemoryGetRemoteAddressInfo, pAddress, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetMemoryRemoteAddressNV);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetMemoryRemoteAddressNV");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordGetMemoryRemoteAddressNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordGetMemoryRemoteAddressNV(device, pMemoryGetRemoteAddressInfo, pAddress, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkGetMemoryRemoteAddressNV");
        result = device_dispatch->GetMemoryRemoteAddressNV(device, pMemoryGetRemoteAddressInfo, pAddress);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetMemoryRemoteAddressNV");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordGetMemoryRemoteAddressNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordGetMemoryRemoteAddressNV(device, pMemoryGetRemoteAddressInfo, pAddress, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR VkResult VKAPI_CALL GetPipelinePropertiesEXT(VkDevice device, const VkPipelineInfoEXT* pPipelineInfo,
                                                        VkBaseOutStructure* pPipelineProperties) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetPipelinePropertiesEXT, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetPipelinePropertiesEXT");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateGetPipelinePropertiesEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateGetPipelinePropertiesEXT(device, pPipelineInfo, pPipelineProperties, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetPipelinePropertiesEXT);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetPipelinePropertiesEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordGetPipelinePropertiesEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordGetPipelinePropertiesEXT(device, pPipelineInfo, pPipelineProperties, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkGetPipelinePropertiesEXT");
        result = device_dispatch->GetPipelinePropertiesEXT(device, pPipelineInfo, pPipelineProperties);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetPipelinePropertiesEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordGetPipelinePropertiesEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordGetPipelinePropertiesEXT(device, pPipelineInfo, pPipelineProperties, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR void VKAPI_CALL CmdSetPatchControlPointsEXT(VkCommandBuffer commandBuffer, uint32_t patchControlPoints) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdSetPatchControlPointsEXT,
                          VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdSetPatchControlPointsEXT");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdSetPatchControlPointsEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdSetPatchControlPointsEXT(commandBuffer, patchControlPoints, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdSetPatchControlPointsEXT);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdSetPatchControlPointsEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdSetPatchControlPointsEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdSetPatchControlPointsEXT(commandBuffer, patchControlPoints, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdSetPatchControlPointsEXT");
        device_dispatch->CmdSetPatchControlPointsEXT(commandBuffer, patchControlPoints);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdSetPatchControlPointsEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdSetPatchControlPointsEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdSetPatchControlPointsEXT(commandBuffer, patchControlPoints, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdSetRasterizerDiscardEnableEXT(VkCommandBuffer commandBuffer, VkBool32 rasterizerDiscardEnable) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdSetRasterizerDiscardEnableEXT,
                          VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdSetRasterizerDiscardEnableEXT");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdSetRasterizerDiscardEnableEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdSetRasterizerDiscardEnableEXT(commandBuffer, rasterizerDiscardEnable, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdSetRasterizerDiscardEnableEXT);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdSetRasterizerDiscardEnableEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdSetRasterizerDiscardEnableEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdSetRasterizerDiscardEnableEXT(commandBuffer, rasterizerDiscardEnable, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdSetRasterizerDiscardEnableEXT");
        device_dispatch->CmdSetRasterizerDiscardEnableEXT(commandBuffer, rasterizerDiscardEnable);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdSetRasterizerDiscardEnableEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdSetRasterizerDiscardEnableEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdSetRasterizerDiscardEnableEXT(commandBuffer, rasterizerDiscardEnable, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdSetDepthBiasEnableEXT(VkCommandBuffer commandBuffer, VkBool32 depthBiasEnable) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdSetDepthBiasEnableEXT, VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdSetDepthBiasEnableEXT");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdSetDepthBiasEnableEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdSetDepthBiasEnableEXT(commandBuffer, depthBiasEnable, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdSetDepthBiasEnableEXT);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdSetDepthBiasEnableEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdSetDepthBiasEnableEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdSetDepthBiasEnableEXT(commandBuffer, depthBiasEnable, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdSetDepthBiasEnableEXT");
        device_dispatch->CmdSetDepthBiasEnableEXT(commandBuffer, depthBiasEnable);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdSetDepthBiasEnableEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdSetDepthBiasEnableEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdSetDepthBiasEnableEXT(commandBuffer, depthBiasEnable, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdSetLogicOpEXT(VkCommandBuffer commandBuffer, VkLogicOp logicOp) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdSetLogicOpEXT, VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdSetLogicOpEXT");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdSetLogicOpEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdSetLogicOpEXT(commandBuffer, logicOp, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdSetLogicOpEXT);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdSetLogicOpEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdSetLogicOpEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdSetLogicOpEXT(commandBuffer, logicOp, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdSetLogicOpEXT");
        device_dispatch->CmdSetLogicOpEXT(commandBuffer, logicOp);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdSetLogicOpEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdSetLogicOpEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdSetLogicOpEXT(commandBuffer, logicOp, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdSetPrimitiveRestartEnableEXT(VkCommandBuffer commandBuffer, VkBool32 primitiveRestartEnable) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdSetPrimitiveRestartEnableEXT,
                          VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdSetPrimitiveRestartEnableEXT");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdSetPrimitiveRestartEnableEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdSetPrimitiveRestartEnableEXT(commandBuffer, primitiveRestartEnable, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdSetPrimitiveRestartEnableEXT);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdSetPrimitiveRestartEnableEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdSetPrimitiveRestartEnableEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdSetPrimitiveRestartEnableEXT(commandBuffer, primitiveRestartEnable, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdSetPrimitiveRestartEnableEXT");
        device_dispatch->CmdSetPrimitiveRestartEnableEXT(commandBuffer, primitiveRestartEnable);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdSetPrimitiveRestartEnableEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdSetPrimitiveRestartEnableEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdSetPrimitiveRestartEnableEXT(commandBuffer, primitiveRestartEnable, record_obj);
        }
    }
}

#ifdef VK_USE_PLATFORM_SCREEN_QNX
VKAPI_ATTR VkResult VKAPI_CALL CreateScreenSurfaceQNX(VkInstance instance, const VkScreenSurfaceCreateInfoQNX* pCreateInfo,
                                                      const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface) {
    VVL_ZoneScoped;

    auto instance_dispatch = vvl::dispatch::GetData(instance);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCreateScreenSurfaceQNX, VulkanTypedHandle(instance, kVulkanObjectTypeInstance));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCreateScreenSurfaceQNX");
        for (const auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            skip |= vo->PreCallValidateCreateScreenSurfaceQNX(instance, pCreateInfo, pAllocator, pSurface, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkCreateScreenSurfaceQNX);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCreateScreenSurfaceQNX");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PreCallRecordCreateScreenSurfaceQNX(instance, pCreateInfo, pAllocator, pSurface, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkCreateScreenSurfaceQNX");
        result = instance_dispatch->CreateScreenSurfaceQNX(instance, pCreateInfo, pAllocator, pSurface);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkCreateScreenSurfaceQNX");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PostCallRecordCreateScreenSurfaceQNX(instance, pCreateInfo, pAllocator, pSurface, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR VkBool32 VKAPI_CALL GetPhysicalDeviceScreenPresentationSupportQNX(VkPhysicalDevice physicalDevice,
                                                                             uint32_t queueFamilyIndex,
                                                                             struct _screen_window* window) {
    VVL_ZoneScoped;

    auto instance_dispatch = vvl::dispatch::GetData(physicalDevice);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetPhysicalDeviceScreenPresentationSupportQNX,
                          VulkanTypedHandle(physicalDevice, kVulkanObjectTypePhysicalDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetPhysicalDeviceScreenPresentationSupportQNX");
        for (const auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            skip |= vo->PreCallValidateGetPhysicalDeviceScreenPresentationSupportQNX(physicalDevice, queueFamilyIndex, window,
                                                                                     error_obj);
            if (skip) return VK_FALSE;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetPhysicalDeviceScreenPresentationSupportQNX);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetPhysicalDeviceScreenPresentationSupportQNX");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PreCallRecordGetPhysicalDeviceScreenPresentationSupportQNX(physicalDevice, queueFamilyIndex, window, record_obj);
        }
    }
    VkBool32 result;
    {
        VVL_ZoneScopedN("Dispatch_vkGetPhysicalDeviceScreenPresentationSupportQNX");
        result = instance_dispatch->GetPhysicalDeviceScreenPresentationSupportQNX(physicalDevice, queueFamilyIndex, window);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetPhysicalDeviceScreenPresentationSupportQNX");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PostCallRecordGetPhysicalDeviceScreenPresentationSupportQNX(physicalDevice, queueFamilyIndex, window, record_obj);
        }
    }
    return result;
}

#endif  // VK_USE_PLATFORM_SCREEN_QNX
VKAPI_ATTR void VKAPI_CALL CmdSetColorWriteEnableEXT(VkCommandBuffer commandBuffer, uint32_t attachmentCount,
                                                     const VkBool32* pColorWriteEnables) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdSetColorWriteEnableEXT, VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdSetColorWriteEnableEXT");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdSetColorWriteEnableEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdSetColorWriteEnableEXT(commandBuffer, attachmentCount, pColorWriteEnables, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdSetColorWriteEnableEXT);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdSetColorWriteEnableEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdSetColorWriteEnableEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdSetColorWriteEnableEXT(commandBuffer, attachmentCount, pColorWriteEnables, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdSetColorWriteEnableEXT");
        device_dispatch->CmdSetColorWriteEnableEXT(commandBuffer, attachmentCount, pColorWriteEnables);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdSetColorWriteEnableEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdSetColorWriteEnableEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdSetColorWriteEnableEXT(commandBuffer, attachmentCount, pColorWriteEnables, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdDrawMultiEXT(VkCommandBuffer commandBuffer, uint32_t drawCount, const VkMultiDrawInfoEXT* pVertexInfo,
                                           uint32_t instanceCount, uint32_t firstInstance, uint32_t stride) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdDrawMultiEXT, VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdDrawMultiEXT");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdDrawMultiEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdDrawMultiEXT(commandBuffer, drawCount, pVertexInfo, instanceCount, firstInstance, stride,
                                                       error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdDrawMultiEXT);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdDrawMultiEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdDrawMultiEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdDrawMultiEXT(commandBuffer, drawCount, pVertexInfo, instanceCount, firstInstance, stride,
                                             record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdDrawMultiEXT");
        device_dispatch->CmdDrawMultiEXT(commandBuffer, drawCount, pVertexInfo, instanceCount, firstInstance, stride);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdDrawMultiEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdDrawMultiEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdDrawMultiEXT(commandBuffer, drawCount, pVertexInfo, instanceCount, firstInstance, stride,
                                              record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdDrawMultiIndexedEXT(VkCommandBuffer commandBuffer, uint32_t drawCount,
                                                  const VkMultiDrawIndexedInfoEXT* pIndexInfo, uint32_t instanceCount,
                                                  uint32_t firstInstance, uint32_t stride, const int32_t* pVertexOffset) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdDrawMultiIndexedEXT, VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdDrawMultiIndexedEXT");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdDrawMultiIndexedEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdDrawMultiIndexedEXT(commandBuffer, drawCount, pIndexInfo, instanceCount, firstInstance,
                                                              stride, pVertexOffset, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdDrawMultiIndexedEXT);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdDrawMultiIndexedEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdDrawMultiIndexedEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdDrawMultiIndexedEXT(commandBuffer, drawCount, pIndexInfo, instanceCount, firstInstance, stride,
                                                    pVertexOffset, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdDrawMultiIndexedEXT");
        device_dispatch->CmdDrawMultiIndexedEXT(commandBuffer, drawCount, pIndexInfo, instanceCount, firstInstance, stride,
                                                pVertexOffset);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdDrawMultiIndexedEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdDrawMultiIndexedEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdDrawMultiIndexedEXT(commandBuffer, drawCount, pIndexInfo, instanceCount, firstInstance, stride,
                                                     pVertexOffset, record_obj);
        }
    }
}

VKAPI_ATTR VkResult VKAPI_CALL CreateMicromapEXT(VkDevice device, const VkMicromapCreateInfoEXT* pCreateInfo,
                                                 const VkAllocationCallbacks* pAllocator, VkMicromapEXT* pMicromap) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCreateMicromapEXT, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCreateMicromapEXT");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCreateMicromapEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCreateMicromapEXT(device, pCreateInfo, pAllocator, pMicromap, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkCreateMicromapEXT);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCreateMicromapEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCreateMicromapEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCreateMicromapEXT(device, pCreateInfo, pAllocator, pMicromap, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkCreateMicromapEXT");
        result = device_dispatch->CreateMicromapEXT(device, pCreateInfo, pAllocator, pMicromap);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkCreateMicromapEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCreateMicromapEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCreateMicromapEXT(device, pCreateInfo, pAllocator, pMicromap, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR void VKAPI_CALL DestroyMicromapEXT(VkDevice device, VkMicromapEXT micromap, const VkAllocationCallbacks* pAllocator) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkDestroyMicromapEXT, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkDestroyMicromapEXT");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateDestroyMicromapEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateDestroyMicromapEXT(device, micromap, pAllocator, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkDestroyMicromapEXT);
    {
        VVL_ZoneScopedN("PreCallRecord_vkDestroyMicromapEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordDestroyMicromapEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordDestroyMicromapEXT(device, micromap, pAllocator, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkDestroyMicromapEXT");
        device_dispatch->DestroyMicromapEXT(device, micromap, pAllocator);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkDestroyMicromapEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordDestroyMicromapEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordDestroyMicromapEXT(device, micromap, pAllocator, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdBuildMicromapsEXT(VkCommandBuffer commandBuffer, uint32_t infoCount,
                                                const VkMicromapBuildInfoEXT* pInfos) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdBuildMicromapsEXT, VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdBuildMicromapsEXT");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdBuildMicromapsEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdBuildMicromapsEXT(commandBuffer, infoCount, pInfos, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdBuildMicromapsEXT);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdBuildMicromapsEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdBuildMicromapsEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdBuildMicromapsEXT(commandBuffer, infoCount, pInfos, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdBuildMicromapsEXT");
        device_dispatch->CmdBuildMicromapsEXT(commandBuffer, infoCount, pInfos);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdBuildMicromapsEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdBuildMicromapsEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdBuildMicromapsEXT(commandBuffer, infoCount, pInfos, record_obj);
        }
    }
}

VKAPI_ATTR VkResult VKAPI_CALL BuildMicromapsEXT(VkDevice device, VkDeferredOperationKHR deferredOperation, uint32_t infoCount,
                                                 const VkMicromapBuildInfoEXT* pInfos) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkBuildMicromapsEXT, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkBuildMicromapsEXT");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateBuildMicromapsEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateBuildMicromapsEXT(device, deferredOperation, infoCount, pInfos, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkBuildMicromapsEXT);
    {
        VVL_ZoneScopedN("PreCallRecord_vkBuildMicromapsEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordBuildMicromapsEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordBuildMicromapsEXT(device, deferredOperation, infoCount, pInfos, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkBuildMicromapsEXT");
        result = device_dispatch->BuildMicromapsEXT(device, deferredOperation, infoCount, pInfos);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkBuildMicromapsEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordBuildMicromapsEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordBuildMicromapsEXT(device, deferredOperation, infoCount, pInfos, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR VkResult VKAPI_CALL CopyMicromapEXT(VkDevice device, VkDeferredOperationKHR deferredOperation,
                                               const VkCopyMicromapInfoEXT* pInfo) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCopyMicromapEXT, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCopyMicromapEXT");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCopyMicromapEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCopyMicromapEXT(device, deferredOperation, pInfo, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkCopyMicromapEXT);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCopyMicromapEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCopyMicromapEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCopyMicromapEXT(device, deferredOperation, pInfo, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkCopyMicromapEXT");
        result = device_dispatch->CopyMicromapEXT(device, deferredOperation, pInfo);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkCopyMicromapEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCopyMicromapEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCopyMicromapEXT(device, deferredOperation, pInfo, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR VkResult VKAPI_CALL CopyMicromapToMemoryEXT(VkDevice device, VkDeferredOperationKHR deferredOperation,
                                                       const VkCopyMicromapToMemoryInfoEXT* pInfo) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCopyMicromapToMemoryEXT, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCopyMicromapToMemoryEXT");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCopyMicromapToMemoryEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCopyMicromapToMemoryEXT(device, deferredOperation, pInfo, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkCopyMicromapToMemoryEXT);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCopyMicromapToMemoryEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCopyMicromapToMemoryEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCopyMicromapToMemoryEXT(device, deferredOperation, pInfo, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkCopyMicromapToMemoryEXT");
        result = device_dispatch->CopyMicromapToMemoryEXT(device, deferredOperation, pInfo);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkCopyMicromapToMemoryEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCopyMicromapToMemoryEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCopyMicromapToMemoryEXT(device, deferredOperation, pInfo, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR VkResult VKAPI_CALL CopyMemoryToMicromapEXT(VkDevice device, VkDeferredOperationKHR deferredOperation,
                                                       const VkCopyMemoryToMicromapInfoEXT* pInfo) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCopyMemoryToMicromapEXT, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCopyMemoryToMicromapEXT");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCopyMemoryToMicromapEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCopyMemoryToMicromapEXT(device, deferredOperation, pInfo, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkCopyMemoryToMicromapEXT);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCopyMemoryToMicromapEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCopyMemoryToMicromapEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCopyMemoryToMicromapEXT(device, deferredOperation, pInfo, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkCopyMemoryToMicromapEXT");
        result = device_dispatch->CopyMemoryToMicromapEXT(device, deferredOperation, pInfo);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkCopyMemoryToMicromapEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCopyMemoryToMicromapEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCopyMemoryToMicromapEXT(device, deferredOperation, pInfo, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR VkResult VKAPI_CALL WriteMicromapsPropertiesEXT(VkDevice device, uint32_t micromapCount, const VkMicromapEXT* pMicromaps,
                                                           VkQueryType queryType, size_t dataSize, void* pData, size_t stride) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkWriteMicromapsPropertiesEXT, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkWriteMicromapsPropertiesEXT");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateWriteMicromapsPropertiesEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateWriteMicromapsPropertiesEXT(device, micromapCount, pMicromaps, queryType, dataSize, pData,
                                                                   stride, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkWriteMicromapsPropertiesEXT);
    {
        VVL_ZoneScopedN("PreCallRecord_vkWriteMicromapsPropertiesEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordWriteMicromapsPropertiesEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordWriteMicromapsPropertiesEXT(device, micromapCount, pMicromaps, queryType, dataSize, pData, stride,
                                                         record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkWriteMicromapsPropertiesEXT");
        result =
            device_dispatch->WriteMicromapsPropertiesEXT(device, micromapCount, pMicromaps, queryType, dataSize, pData, stride);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkWriteMicromapsPropertiesEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordWriteMicromapsPropertiesEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordWriteMicromapsPropertiesEXT(device, micromapCount, pMicromaps, queryType, dataSize, pData, stride,
                                                          record_obj);
        }
    }
    return result;
}

VKAPI_ATTR void VKAPI_CALL CmdCopyMicromapEXT(VkCommandBuffer commandBuffer, const VkCopyMicromapInfoEXT* pInfo) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdCopyMicromapEXT, VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdCopyMicromapEXT");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdCopyMicromapEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdCopyMicromapEXT(commandBuffer, pInfo, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdCopyMicromapEXT);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdCopyMicromapEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdCopyMicromapEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdCopyMicromapEXT(commandBuffer, pInfo, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdCopyMicromapEXT");
        device_dispatch->CmdCopyMicromapEXT(commandBuffer, pInfo);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdCopyMicromapEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdCopyMicromapEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdCopyMicromapEXT(commandBuffer, pInfo, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdCopyMicromapToMemoryEXT(VkCommandBuffer commandBuffer, const VkCopyMicromapToMemoryInfoEXT* pInfo) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdCopyMicromapToMemoryEXT,
                          VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdCopyMicromapToMemoryEXT");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdCopyMicromapToMemoryEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdCopyMicromapToMemoryEXT(commandBuffer, pInfo, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdCopyMicromapToMemoryEXT);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdCopyMicromapToMemoryEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdCopyMicromapToMemoryEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdCopyMicromapToMemoryEXT(commandBuffer, pInfo, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdCopyMicromapToMemoryEXT");
        device_dispatch->CmdCopyMicromapToMemoryEXT(commandBuffer, pInfo);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdCopyMicromapToMemoryEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdCopyMicromapToMemoryEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdCopyMicromapToMemoryEXT(commandBuffer, pInfo, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdCopyMemoryToMicromapEXT(VkCommandBuffer commandBuffer, const VkCopyMemoryToMicromapInfoEXT* pInfo) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdCopyMemoryToMicromapEXT,
                          VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdCopyMemoryToMicromapEXT");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdCopyMemoryToMicromapEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdCopyMemoryToMicromapEXT(commandBuffer, pInfo, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdCopyMemoryToMicromapEXT);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdCopyMemoryToMicromapEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdCopyMemoryToMicromapEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdCopyMemoryToMicromapEXT(commandBuffer, pInfo, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdCopyMemoryToMicromapEXT");
        device_dispatch->CmdCopyMemoryToMicromapEXT(commandBuffer, pInfo);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdCopyMemoryToMicromapEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdCopyMemoryToMicromapEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdCopyMemoryToMicromapEXT(commandBuffer, pInfo, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdWriteMicromapsPropertiesEXT(VkCommandBuffer commandBuffer, uint32_t micromapCount,
                                                          const VkMicromapEXT* pMicromaps, VkQueryType queryType,
                                                          VkQueryPool queryPool, uint32_t firstQuery) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdWriteMicromapsPropertiesEXT,
                          VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdWriteMicromapsPropertiesEXT");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdWriteMicromapsPropertiesEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdWriteMicromapsPropertiesEXT(commandBuffer, micromapCount, pMicromaps, queryType,
                                                                      queryPool, firstQuery, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdWriteMicromapsPropertiesEXT);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdWriteMicromapsPropertiesEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdWriteMicromapsPropertiesEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdWriteMicromapsPropertiesEXT(commandBuffer, micromapCount, pMicromaps, queryType, queryPool,
                                                            firstQuery, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdWriteMicromapsPropertiesEXT");
        device_dispatch->CmdWriteMicromapsPropertiesEXT(commandBuffer, micromapCount, pMicromaps, queryType, queryPool, firstQuery);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdWriteMicromapsPropertiesEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdWriteMicromapsPropertiesEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdWriteMicromapsPropertiesEXT(commandBuffer, micromapCount, pMicromaps, queryType, queryPool,
                                                             firstQuery, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL GetDeviceMicromapCompatibilityEXT(VkDevice device, const VkMicromapVersionInfoEXT* pVersionInfo,
                                                             VkAccelerationStructureCompatibilityKHR* pCompatibility) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetDeviceMicromapCompatibilityEXT, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetDeviceMicromapCompatibilityEXT");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateGetDeviceMicromapCompatibilityEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateGetDeviceMicromapCompatibilityEXT(device, pVersionInfo, pCompatibility, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetDeviceMicromapCompatibilityEXT);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetDeviceMicromapCompatibilityEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordGetDeviceMicromapCompatibilityEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordGetDeviceMicromapCompatibilityEXT(device, pVersionInfo, pCompatibility, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkGetDeviceMicromapCompatibilityEXT");
        device_dispatch->GetDeviceMicromapCompatibilityEXT(device, pVersionInfo, pCompatibility);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetDeviceMicromapCompatibilityEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordGetDeviceMicromapCompatibilityEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordGetDeviceMicromapCompatibilityEXT(device, pVersionInfo, pCompatibility, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL GetMicromapBuildSizesEXT(VkDevice device, VkAccelerationStructureBuildTypeKHR buildType,
                                                    const VkMicromapBuildInfoEXT* pBuildInfo,
                                                    VkMicromapBuildSizesInfoEXT* pSizeInfo) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetMicromapBuildSizesEXT, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetMicromapBuildSizesEXT");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateGetMicromapBuildSizesEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateGetMicromapBuildSizesEXT(device, buildType, pBuildInfo, pSizeInfo, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetMicromapBuildSizesEXT);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetMicromapBuildSizesEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordGetMicromapBuildSizesEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordGetMicromapBuildSizesEXT(device, buildType, pBuildInfo, pSizeInfo, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkGetMicromapBuildSizesEXT");
        device_dispatch->GetMicromapBuildSizesEXT(device, buildType, pBuildInfo, pSizeInfo);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetMicromapBuildSizesEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordGetMicromapBuildSizesEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordGetMicromapBuildSizesEXT(device, buildType, pBuildInfo, pSizeInfo, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdDrawClusterHUAWEI(VkCommandBuffer commandBuffer, uint32_t groupCountX, uint32_t groupCountY,
                                                uint32_t groupCountZ) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdDrawClusterHUAWEI, VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdDrawClusterHUAWEI");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdDrawClusterHUAWEI]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdDrawClusterHUAWEI(commandBuffer, groupCountX, groupCountY, groupCountZ, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdDrawClusterHUAWEI);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdDrawClusterHUAWEI");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdDrawClusterHUAWEI]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdDrawClusterHUAWEI(commandBuffer, groupCountX, groupCountY, groupCountZ, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdDrawClusterHUAWEI");
        device_dispatch->CmdDrawClusterHUAWEI(commandBuffer, groupCountX, groupCountY, groupCountZ);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdDrawClusterHUAWEI");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdDrawClusterHUAWEI]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdDrawClusterHUAWEI(commandBuffer, groupCountX, groupCountY, groupCountZ, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdDrawClusterIndirectHUAWEI(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdDrawClusterIndirectHUAWEI,
                          VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdDrawClusterIndirectHUAWEI");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdDrawClusterIndirectHUAWEI]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdDrawClusterIndirectHUAWEI(commandBuffer, buffer, offset, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdDrawClusterIndirectHUAWEI);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdDrawClusterIndirectHUAWEI");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdDrawClusterIndirectHUAWEI]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdDrawClusterIndirectHUAWEI(commandBuffer, buffer, offset, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdDrawClusterIndirectHUAWEI");
        device_dispatch->CmdDrawClusterIndirectHUAWEI(commandBuffer, buffer, offset);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdDrawClusterIndirectHUAWEI");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdDrawClusterIndirectHUAWEI]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdDrawClusterIndirectHUAWEI(commandBuffer, buffer, offset, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL SetDeviceMemoryPriorityEXT(VkDevice device, VkDeviceMemory memory, float priority) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkSetDeviceMemoryPriorityEXT, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkSetDeviceMemoryPriorityEXT");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateSetDeviceMemoryPriorityEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateSetDeviceMemoryPriorityEXT(device, memory, priority, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkSetDeviceMemoryPriorityEXT);
    {
        VVL_ZoneScopedN("PreCallRecord_vkSetDeviceMemoryPriorityEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordSetDeviceMemoryPriorityEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordSetDeviceMemoryPriorityEXT(device, memory, priority, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkSetDeviceMemoryPriorityEXT");
        device_dispatch->SetDeviceMemoryPriorityEXT(device, memory, priority);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkSetDeviceMemoryPriorityEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordSetDeviceMemoryPriorityEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordSetDeviceMemoryPriorityEXT(device, memory, priority, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL GetDescriptorSetLayoutHostMappingInfoVALVE(VkDevice device,
                                                                      const VkDescriptorSetBindingReferenceVALVE* pBindingReference,
                                                                      VkDescriptorSetLayoutHostMappingInfoVALVE* pHostMapping) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetDescriptorSetLayoutHostMappingInfoVALVE,
                          VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetDescriptorSetLayoutHostMappingInfoVALVE");
        for (const auto& vo :
             device_dispatch->intercept_vectors[InterceptIdPreCallValidateGetDescriptorSetLayoutHostMappingInfoVALVE]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |=
                vo->PreCallValidateGetDescriptorSetLayoutHostMappingInfoVALVE(device, pBindingReference, pHostMapping, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetDescriptorSetLayoutHostMappingInfoVALVE);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetDescriptorSetLayoutHostMappingInfoVALVE");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordGetDescriptorSetLayoutHostMappingInfoVALVE]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordGetDescriptorSetLayoutHostMappingInfoVALVE(device, pBindingReference, pHostMapping, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkGetDescriptorSetLayoutHostMappingInfoVALVE");
        device_dispatch->GetDescriptorSetLayoutHostMappingInfoVALVE(device, pBindingReference, pHostMapping);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetDescriptorSetLayoutHostMappingInfoVALVE");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordGetDescriptorSetLayoutHostMappingInfoVALVE]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordGetDescriptorSetLayoutHostMappingInfoVALVE(device, pBindingReference, pHostMapping, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL GetDescriptorSetHostMappingVALVE(VkDevice device, VkDescriptorSet descriptorSet, void** ppData) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetDescriptorSetHostMappingVALVE, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetDescriptorSetHostMappingVALVE");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateGetDescriptorSetHostMappingVALVE]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateGetDescriptorSetHostMappingVALVE(device, descriptorSet, ppData, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetDescriptorSetHostMappingVALVE);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetDescriptorSetHostMappingVALVE");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordGetDescriptorSetHostMappingVALVE]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordGetDescriptorSetHostMappingVALVE(device, descriptorSet, ppData, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkGetDescriptorSetHostMappingVALVE");
        device_dispatch->GetDescriptorSetHostMappingVALVE(device, descriptorSet, ppData);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetDescriptorSetHostMappingVALVE");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordGetDescriptorSetHostMappingVALVE]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordGetDescriptorSetHostMappingVALVE(device, descriptorSet, ppData, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdCopyMemoryIndirectNV(VkCommandBuffer commandBuffer, VkDeviceAddress copyBufferAddress,
                                                   uint32_t copyCount, uint32_t stride) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdCopyMemoryIndirectNV, VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdCopyMemoryIndirectNV");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdCopyMemoryIndirectNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdCopyMemoryIndirectNV(commandBuffer, copyBufferAddress, copyCount, stride, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdCopyMemoryIndirectNV);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdCopyMemoryIndirectNV");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdCopyMemoryIndirectNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdCopyMemoryIndirectNV(commandBuffer, copyBufferAddress, copyCount, stride, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdCopyMemoryIndirectNV");
        device_dispatch->CmdCopyMemoryIndirectNV(commandBuffer, copyBufferAddress, copyCount, stride);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdCopyMemoryIndirectNV");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdCopyMemoryIndirectNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdCopyMemoryIndirectNV(commandBuffer, copyBufferAddress, copyCount, stride, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdCopyMemoryToImageIndirectNV(VkCommandBuffer commandBuffer, VkDeviceAddress copyBufferAddress,
                                                          uint32_t copyCount, uint32_t stride, VkImage dstImage,
                                                          VkImageLayout dstImageLayout,
                                                          const VkImageSubresourceLayers* pImageSubresources) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdCopyMemoryToImageIndirectNV,
                          VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdCopyMemoryToImageIndirectNV");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdCopyMemoryToImageIndirectNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdCopyMemoryToImageIndirectNV(commandBuffer, copyBufferAddress, copyCount, stride, dstImage,
                                                                      dstImageLayout, pImageSubresources, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdCopyMemoryToImageIndirectNV);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdCopyMemoryToImageIndirectNV");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdCopyMemoryToImageIndirectNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdCopyMemoryToImageIndirectNV(commandBuffer, copyBufferAddress, copyCount, stride, dstImage,
                                                            dstImageLayout, pImageSubresources, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdCopyMemoryToImageIndirectNV");
        device_dispatch->CmdCopyMemoryToImageIndirectNV(commandBuffer, copyBufferAddress, copyCount, stride, dstImage,
                                                        dstImageLayout, pImageSubresources);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdCopyMemoryToImageIndirectNV");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdCopyMemoryToImageIndirectNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdCopyMemoryToImageIndirectNV(commandBuffer, copyBufferAddress, copyCount, stride, dstImage,
                                                             dstImageLayout, pImageSubresources, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdDecompressMemoryNV(VkCommandBuffer commandBuffer, uint32_t decompressRegionCount,
                                                 const VkDecompressMemoryRegionNV* pDecompressMemoryRegions) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdDecompressMemoryNV, VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdDecompressMemoryNV");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdDecompressMemoryNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |=
                vo->PreCallValidateCmdDecompressMemoryNV(commandBuffer, decompressRegionCount, pDecompressMemoryRegions, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdDecompressMemoryNV);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdDecompressMemoryNV");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdDecompressMemoryNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdDecompressMemoryNV(commandBuffer, decompressRegionCount, pDecompressMemoryRegions, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdDecompressMemoryNV");
        device_dispatch->CmdDecompressMemoryNV(commandBuffer, decompressRegionCount, pDecompressMemoryRegions);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdDecompressMemoryNV");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdDecompressMemoryNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdDecompressMemoryNV(commandBuffer, decompressRegionCount, pDecompressMemoryRegions, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdDecompressMemoryIndirectCountNV(VkCommandBuffer commandBuffer,
                                                              VkDeviceAddress indirectCommandsAddress,
                                                              VkDeviceAddress indirectCommandsCountAddress, uint32_t stride) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdDecompressMemoryIndirectCountNV,
                          VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdDecompressMemoryIndirectCountNV");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdDecompressMemoryIndirectCountNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdDecompressMemoryIndirectCountNV(commandBuffer, indirectCommandsAddress,
                                                                          indirectCommandsCountAddress, stride, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdDecompressMemoryIndirectCountNV);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdDecompressMemoryIndirectCountNV");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdDecompressMemoryIndirectCountNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdDecompressMemoryIndirectCountNV(commandBuffer, indirectCommandsAddress,
                                                                indirectCommandsCountAddress, stride, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdDecompressMemoryIndirectCountNV");
        device_dispatch->CmdDecompressMemoryIndirectCountNV(commandBuffer, indirectCommandsAddress, indirectCommandsCountAddress,
                                                            stride);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdDecompressMemoryIndirectCountNV");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdDecompressMemoryIndirectCountNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdDecompressMemoryIndirectCountNV(commandBuffer, indirectCommandsAddress,
                                                                 indirectCommandsCountAddress, stride, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL GetPipelineIndirectMemoryRequirementsNV(VkDevice device, const VkComputePipelineCreateInfo* pCreateInfo,
                                                                   VkMemoryRequirements2* pMemoryRequirements) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetPipelineIndirectMemoryRequirementsNV, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetPipelineIndirectMemoryRequirementsNV");
        for (const auto& vo :
             device_dispatch->intercept_vectors[InterceptIdPreCallValidateGetPipelineIndirectMemoryRequirementsNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateGetPipelineIndirectMemoryRequirementsNV(device, pCreateInfo, pMemoryRequirements, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetPipelineIndirectMemoryRequirementsNV);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetPipelineIndirectMemoryRequirementsNV");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordGetPipelineIndirectMemoryRequirementsNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordGetPipelineIndirectMemoryRequirementsNV(device, pCreateInfo, pMemoryRequirements, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkGetPipelineIndirectMemoryRequirementsNV");
        device_dispatch->GetPipelineIndirectMemoryRequirementsNV(device, pCreateInfo, pMemoryRequirements);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetPipelineIndirectMemoryRequirementsNV");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordGetPipelineIndirectMemoryRequirementsNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordGetPipelineIndirectMemoryRequirementsNV(device, pCreateInfo, pMemoryRequirements, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdUpdatePipelineIndirectBufferNV(VkCommandBuffer commandBuffer, VkPipelineBindPoint pipelineBindPoint,
                                                             VkPipeline pipeline) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdUpdatePipelineIndirectBufferNV,
                          VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdUpdatePipelineIndirectBufferNV");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdUpdatePipelineIndirectBufferNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdUpdatePipelineIndirectBufferNV(commandBuffer, pipelineBindPoint, pipeline, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdUpdatePipelineIndirectBufferNV);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdUpdatePipelineIndirectBufferNV");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdUpdatePipelineIndirectBufferNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdUpdatePipelineIndirectBufferNV(commandBuffer, pipelineBindPoint, pipeline, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdUpdatePipelineIndirectBufferNV");
        device_dispatch->CmdUpdatePipelineIndirectBufferNV(commandBuffer, pipelineBindPoint, pipeline);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdUpdatePipelineIndirectBufferNV");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdUpdatePipelineIndirectBufferNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdUpdatePipelineIndirectBufferNV(commandBuffer, pipelineBindPoint, pipeline, record_obj);
        }
    }
}

VKAPI_ATTR VkDeviceAddress VKAPI_CALL GetPipelineIndirectDeviceAddressNV(VkDevice device,
                                                                         const VkPipelineIndirectDeviceAddressInfoNV* pInfo) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetPipelineIndirectDeviceAddressNV, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetPipelineIndirectDeviceAddressNV");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateGetPipelineIndirectDeviceAddressNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateGetPipelineIndirectDeviceAddressNV(device, pInfo, error_obj);
            if (skip) return 0;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetPipelineIndirectDeviceAddressNV);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetPipelineIndirectDeviceAddressNV");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordGetPipelineIndirectDeviceAddressNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordGetPipelineIndirectDeviceAddressNV(device, pInfo, record_obj);
        }
    }
    VkDeviceAddress result;
    {
        VVL_ZoneScopedN("Dispatch_vkGetPipelineIndirectDeviceAddressNV");
        result = device_dispatch->GetPipelineIndirectDeviceAddressNV(device, pInfo);
    }
    record_obj.device_address = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetPipelineIndirectDeviceAddressNV");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordGetPipelineIndirectDeviceAddressNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordGetPipelineIndirectDeviceAddressNV(device, pInfo, record_obj);
        }
    }
    return result;
}

#ifdef VK_USE_PLATFORM_OHOS
VKAPI_ATTR VkResult VKAPI_CALL GetNativeBufferPropertiesOHOS(VkDevice device, const struct OH_NativeBuffer* buffer,
                                                             VkNativeBufferPropertiesOHOS* pProperties) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetNativeBufferPropertiesOHOS, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetNativeBufferPropertiesOHOS");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateGetNativeBufferPropertiesOHOS]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateGetNativeBufferPropertiesOHOS(device, buffer, pProperties, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetNativeBufferPropertiesOHOS);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetNativeBufferPropertiesOHOS");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordGetNativeBufferPropertiesOHOS]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordGetNativeBufferPropertiesOHOS(device, buffer, pProperties, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkGetNativeBufferPropertiesOHOS");
        result = device_dispatch->GetNativeBufferPropertiesOHOS(device, buffer, pProperties);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetNativeBufferPropertiesOHOS");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordGetNativeBufferPropertiesOHOS]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordGetNativeBufferPropertiesOHOS(device, buffer, pProperties, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR VkResult VKAPI_CALL GetMemoryNativeBufferOHOS(VkDevice device, const VkMemoryGetNativeBufferInfoOHOS* pInfo,
                                                         struct OH_NativeBuffer** pBuffer) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetMemoryNativeBufferOHOS, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetMemoryNativeBufferOHOS");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateGetMemoryNativeBufferOHOS]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateGetMemoryNativeBufferOHOS(device, pInfo, pBuffer, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetMemoryNativeBufferOHOS);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetMemoryNativeBufferOHOS");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordGetMemoryNativeBufferOHOS]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordGetMemoryNativeBufferOHOS(device, pInfo, pBuffer, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkGetMemoryNativeBufferOHOS");
        result = device_dispatch->GetMemoryNativeBufferOHOS(device, pInfo, pBuffer);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetMemoryNativeBufferOHOS");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordGetMemoryNativeBufferOHOS]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordGetMemoryNativeBufferOHOS(device, pInfo, pBuffer, record_obj);
        }
    }
    return result;
}

#endif  // VK_USE_PLATFORM_OHOS
VKAPI_ATTR void VKAPI_CALL CmdSetDepthClampEnableEXT(VkCommandBuffer commandBuffer, VkBool32 depthClampEnable) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdSetDepthClampEnableEXT, VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdSetDepthClampEnableEXT");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdSetDepthClampEnableEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdSetDepthClampEnableEXT(commandBuffer, depthClampEnable, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdSetDepthClampEnableEXT);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdSetDepthClampEnableEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdSetDepthClampEnableEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdSetDepthClampEnableEXT(commandBuffer, depthClampEnable, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdSetDepthClampEnableEXT");
        device_dispatch->CmdSetDepthClampEnableEXT(commandBuffer, depthClampEnable);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdSetDepthClampEnableEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdSetDepthClampEnableEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdSetDepthClampEnableEXT(commandBuffer, depthClampEnable, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdSetPolygonModeEXT(VkCommandBuffer commandBuffer, VkPolygonMode polygonMode) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdSetPolygonModeEXT, VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdSetPolygonModeEXT");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdSetPolygonModeEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdSetPolygonModeEXT(commandBuffer, polygonMode, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdSetPolygonModeEXT);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdSetPolygonModeEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdSetPolygonModeEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdSetPolygonModeEXT(commandBuffer, polygonMode, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdSetPolygonModeEXT");
        device_dispatch->CmdSetPolygonModeEXT(commandBuffer, polygonMode);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdSetPolygonModeEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdSetPolygonModeEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdSetPolygonModeEXT(commandBuffer, polygonMode, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdSetRasterizationSamplesEXT(VkCommandBuffer commandBuffer,
                                                         VkSampleCountFlagBits rasterizationSamples) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdSetRasterizationSamplesEXT,
                          VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdSetRasterizationSamplesEXT");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdSetRasterizationSamplesEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdSetRasterizationSamplesEXT(commandBuffer, rasterizationSamples, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdSetRasterizationSamplesEXT);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdSetRasterizationSamplesEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdSetRasterizationSamplesEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdSetRasterizationSamplesEXT(commandBuffer, rasterizationSamples, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdSetRasterizationSamplesEXT");
        device_dispatch->CmdSetRasterizationSamplesEXT(commandBuffer, rasterizationSamples);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdSetRasterizationSamplesEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdSetRasterizationSamplesEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdSetRasterizationSamplesEXT(commandBuffer, rasterizationSamples, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdSetSampleMaskEXT(VkCommandBuffer commandBuffer, VkSampleCountFlagBits samples,
                                               const VkSampleMask* pSampleMask) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdSetSampleMaskEXT, VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdSetSampleMaskEXT");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdSetSampleMaskEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdSetSampleMaskEXT(commandBuffer, samples, pSampleMask, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdSetSampleMaskEXT);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdSetSampleMaskEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdSetSampleMaskEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdSetSampleMaskEXT(commandBuffer, samples, pSampleMask, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdSetSampleMaskEXT");
        device_dispatch->CmdSetSampleMaskEXT(commandBuffer, samples, pSampleMask);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdSetSampleMaskEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdSetSampleMaskEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdSetSampleMaskEXT(commandBuffer, samples, pSampleMask, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdSetAlphaToCoverageEnableEXT(VkCommandBuffer commandBuffer, VkBool32 alphaToCoverageEnable) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdSetAlphaToCoverageEnableEXT,
                          VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdSetAlphaToCoverageEnableEXT");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdSetAlphaToCoverageEnableEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdSetAlphaToCoverageEnableEXT(commandBuffer, alphaToCoverageEnable, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdSetAlphaToCoverageEnableEXT);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdSetAlphaToCoverageEnableEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdSetAlphaToCoverageEnableEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdSetAlphaToCoverageEnableEXT(commandBuffer, alphaToCoverageEnable, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdSetAlphaToCoverageEnableEXT");
        device_dispatch->CmdSetAlphaToCoverageEnableEXT(commandBuffer, alphaToCoverageEnable);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdSetAlphaToCoverageEnableEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdSetAlphaToCoverageEnableEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdSetAlphaToCoverageEnableEXT(commandBuffer, alphaToCoverageEnable, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdSetAlphaToOneEnableEXT(VkCommandBuffer commandBuffer, VkBool32 alphaToOneEnable) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdSetAlphaToOneEnableEXT, VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdSetAlphaToOneEnableEXT");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdSetAlphaToOneEnableEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdSetAlphaToOneEnableEXT(commandBuffer, alphaToOneEnable, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdSetAlphaToOneEnableEXT);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdSetAlphaToOneEnableEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdSetAlphaToOneEnableEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdSetAlphaToOneEnableEXT(commandBuffer, alphaToOneEnable, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdSetAlphaToOneEnableEXT");
        device_dispatch->CmdSetAlphaToOneEnableEXT(commandBuffer, alphaToOneEnable);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdSetAlphaToOneEnableEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdSetAlphaToOneEnableEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdSetAlphaToOneEnableEXT(commandBuffer, alphaToOneEnable, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdSetLogicOpEnableEXT(VkCommandBuffer commandBuffer, VkBool32 logicOpEnable) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdSetLogicOpEnableEXT, VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdSetLogicOpEnableEXT");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdSetLogicOpEnableEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdSetLogicOpEnableEXT(commandBuffer, logicOpEnable, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdSetLogicOpEnableEXT);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdSetLogicOpEnableEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdSetLogicOpEnableEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdSetLogicOpEnableEXT(commandBuffer, logicOpEnable, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdSetLogicOpEnableEXT");
        device_dispatch->CmdSetLogicOpEnableEXT(commandBuffer, logicOpEnable);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdSetLogicOpEnableEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdSetLogicOpEnableEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdSetLogicOpEnableEXT(commandBuffer, logicOpEnable, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdSetColorBlendEnableEXT(VkCommandBuffer commandBuffer, uint32_t firstAttachment,
                                                     uint32_t attachmentCount, const VkBool32* pColorBlendEnables) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdSetColorBlendEnableEXT, VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdSetColorBlendEnableEXT");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdSetColorBlendEnableEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdSetColorBlendEnableEXT(commandBuffer, firstAttachment, attachmentCount,
                                                                 pColorBlendEnables, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdSetColorBlendEnableEXT);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdSetColorBlendEnableEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdSetColorBlendEnableEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdSetColorBlendEnableEXT(commandBuffer, firstAttachment, attachmentCount, pColorBlendEnables,
                                                       record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdSetColorBlendEnableEXT");
        device_dispatch->CmdSetColorBlendEnableEXT(commandBuffer, firstAttachment, attachmentCount, pColorBlendEnables);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdSetColorBlendEnableEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdSetColorBlendEnableEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdSetColorBlendEnableEXT(commandBuffer, firstAttachment, attachmentCount, pColorBlendEnables,
                                                        record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdSetColorBlendEquationEXT(VkCommandBuffer commandBuffer, uint32_t firstAttachment,
                                                       uint32_t attachmentCount,
                                                       const VkColorBlendEquationEXT* pColorBlendEquations) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdSetColorBlendEquationEXT,
                          VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdSetColorBlendEquationEXT");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdSetColorBlendEquationEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdSetColorBlendEquationEXT(commandBuffer, firstAttachment, attachmentCount,
                                                                   pColorBlendEquations, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdSetColorBlendEquationEXT);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdSetColorBlendEquationEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdSetColorBlendEquationEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdSetColorBlendEquationEXT(commandBuffer, firstAttachment, attachmentCount, pColorBlendEquations,
                                                         record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdSetColorBlendEquationEXT");
        device_dispatch->CmdSetColorBlendEquationEXT(commandBuffer, firstAttachment, attachmentCount, pColorBlendEquations);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdSetColorBlendEquationEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdSetColorBlendEquationEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdSetColorBlendEquationEXT(commandBuffer, firstAttachment, attachmentCount, pColorBlendEquations,
                                                          record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdSetColorWriteMaskEXT(VkCommandBuffer commandBuffer, uint32_t firstAttachment,
                                                   uint32_t attachmentCount, const VkColorComponentFlags* pColorWriteMasks) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdSetColorWriteMaskEXT, VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdSetColorWriteMaskEXT");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdSetColorWriteMaskEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdSetColorWriteMaskEXT(commandBuffer, firstAttachment, attachmentCount, pColorWriteMasks,
                                                               error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdSetColorWriteMaskEXT);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdSetColorWriteMaskEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdSetColorWriteMaskEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdSetColorWriteMaskEXT(commandBuffer, firstAttachment, attachmentCount, pColorWriteMasks, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdSetColorWriteMaskEXT");
        device_dispatch->CmdSetColorWriteMaskEXT(commandBuffer, firstAttachment, attachmentCount, pColorWriteMasks);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdSetColorWriteMaskEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdSetColorWriteMaskEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdSetColorWriteMaskEXT(commandBuffer, firstAttachment, attachmentCount, pColorWriteMasks,
                                                      record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdSetTessellationDomainOriginEXT(VkCommandBuffer commandBuffer,
                                                             VkTessellationDomainOrigin domainOrigin) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdSetTessellationDomainOriginEXT,
                          VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdSetTessellationDomainOriginEXT");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdSetTessellationDomainOriginEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdSetTessellationDomainOriginEXT(commandBuffer, domainOrigin, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdSetTessellationDomainOriginEXT);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdSetTessellationDomainOriginEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdSetTessellationDomainOriginEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdSetTessellationDomainOriginEXT(commandBuffer, domainOrigin, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdSetTessellationDomainOriginEXT");
        device_dispatch->CmdSetTessellationDomainOriginEXT(commandBuffer, domainOrigin);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdSetTessellationDomainOriginEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdSetTessellationDomainOriginEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdSetTessellationDomainOriginEXT(commandBuffer, domainOrigin, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdSetRasterizationStreamEXT(VkCommandBuffer commandBuffer, uint32_t rasterizationStream) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdSetRasterizationStreamEXT,
                          VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdSetRasterizationStreamEXT");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdSetRasterizationStreamEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdSetRasterizationStreamEXT(commandBuffer, rasterizationStream, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdSetRasterizationStreamEXT);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdSetRasterizationStreamEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdSetRasterizationStreamEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdSetRasterizationStreamEXT(commandBuffer, rasterizationStream, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdSetRasterizationStreamEXT");
        device_dispatch->CmdSetRasterizationStreamEXT(commandBuffer, rasterizationStream);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdSetRasterizationStreamEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdSetRasterizationStreamEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdSetRasterizationStreamEXT(commandBuffer, rasterizationStream, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdSetConservativeRasterizationModeEXT(
    VkCommandBuffer commandBuffer, VkConservativeRasterizationModeEXT conservativeRasterizationMode) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdSetConservativeRasterizationModeEXT,
                          VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdSetConservativeRasterizationModeEXT");
        for (const auto& vo :
             device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdSetConservativeRasterizationModeEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |=
                vo->PreCallValidateCmdSetConservativeRasterizationModeEXT(commandBuffer, conservativeRasterizationMode, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdSetConservativeRasterizationModeEXT);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdSetConservativeRasterizationModeEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdSetConservativeRasterizationModeEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdSetConservativeRasterizationModeEXT(commandBuffer, conservativeRasterizationMode, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdSetConservativeRasterizationModeEXT");
        device_dispatch->CmdSetConservativeRasterizationModeEXT(commandBuffer, conservativeRasterizationMode);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdSetConservativeRasterizationModeEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdSetConservativeRasterizationModeEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdSetConservativeRasterizationModeEXT(commandBuffer, conservativeRasterizationMode, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdSetExtraPrimitiveOverestimationSizeEXT(VkCommandBuffer commandBuffer,
                                                                     float extraPrimitiveOverestimationSize) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdSetExtraPrimitiveOverestimationSizeEXT,
                          VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdSetExtraPrimitiveOverestimationSizeEXT");
        for (const auto& vo :
             device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdSetExtraPrimitiveOverestimationSizeEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdSetExtraPrimitiveOverestimationSizeEXT(commandBuffer, extraPrimitiveOverestimationSize,
                                                                                 error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdSetExtraPrimitiveOverestimationSizeEXT);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdSetExtraPrimitiveOverestimationSizeEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdSetExtraPrimitiveOverestimationSizeEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdSetExtraPrimitiveOverestimationSizeEXT(commandBuffer, extraPrimitiveOverestimationSize, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdSetExtraPrimitiveOverestimationSizeEXT");
        device_dispatch->CmdSetExtraPrimitiveOverestimationSizeEXT(commandBuffer, extraPrimitiveOverestimationSize);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdSetExtraPrimitiveOverestimationSizeEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdSetExtraPrimitiveOverestimationSizeEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdSetExtraPrimitiveOverestimationSizeEXT(commandBuffer, extraPrimitiveOverestimationSize,
                                                                        record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdSetDepthClipEnableEXT(VkCommandBuffer commandBuffer, VkBool32 depthClipEnable) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdSetDepthClipEnableEXT, VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdSetDepthClipEnableEXT");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdSetDepthClipEnableEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdSetDepthClipEnableEXT(commandBuffer, depthClipEnable, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdSetDepthClipEnableEXT);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdSetDepthClipEnableEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdSetDepthClipEnableEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdSetDepthClipEnableEXT(commandBuffer, depthClipEnable, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdSetDepthClipEnableEXT");
        device_dispatch->CmdSetDepthClipEnableEXT(commandBuffer, depthClipEnable);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdSetDepthClipEnableEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdSetDepthClipEnableEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdSetDepthClipEnableEXT(commandBuffer, depthClipEnable, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdSetSampleLocationsEnableEXT(VkCommandBuffer commandBuffer, VkBool32 sampleLocationsEnable) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdSetSampleLocationsEnableEXT,
                          VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdSetSampleLocationsEnableEXT");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdSetSampleLocationsEnableEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdSetSampleLocationsEnableEXT(commandBuffer, sampleLocationsEnable, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdSetSampleLocationsEnableEXT);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdSetSampleLocationsEnableEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdSetSampleLocationsEnableEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdSetSampleLocationsEnableEXT(commandBuffer, sampleLocationsEnable, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdSetSampleLocationsEnableEXT");
        device_dispatch->CmdSetSampleLocationsEnableEXT(commandBuffer, sampleLocationsEnable);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdSetSampleLocationsEnableEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdSetSampleLocationsEnableEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdSetSampleLocationsEnableEXT(commandBuffer, sampleLocationsEnable, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdSetColorBlendAdvancedEXT(VkCommandBuffer commandBuffer, uint32_t firstAttachment,
                                                       uint32_t attachmentCount,
                                                       const VkColorBlendAdvancedEXT* pColorBlendAdvanced) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdSetColorBlendAdvancedEXT,
                          VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdSetColorBlendAdvancedEXT");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdSetColorBlendAdvancedEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdSetColorBlendAdvancedEXT(commandBuffer, firstAttachment, attachmentCount,
                                                                   pColorBlendAdvanced, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdSetColorBlendAdvancedEXT);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdSetColorBlendAdvancedEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdSetColorBlendAdvancedEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdSetColorBlendAdvancedEXT(commandBuffer, firstAttachment, attachmentCount, pColorBlendAdvanced,
                                                         record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdSetColorBlendAdvancedEXT");
        device_dispatch->CmdSetColorBlendAdvancedEXT(commandBuffer, firstAttachment, attachmentCount, pColorBlendAdvanced);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdSetColorBlendAdvancedEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdSetColorBlendAdvancedEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdSetColorBlendAdvancedEXT(commandBuffer, firstAttachment, attachmentCount, pColorBlendAdvanced,
                                                          record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdSetProvokingVertexModeEXT(VkCommandBuffer commandBuffer,
                                                        VkProvokingVertexModeEXT provokingVertexMode) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdSetProvokingVertexModeEXT,
                          VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdSetProvokingVertexModeEXT");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdSetProvokingVertexModeEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdSetProvokingVertexModeEXT(commandBuffer, provokingVertexMode, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdSetProvokingVertexModeEXT);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdSetProvokingVertexModeEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdSetProvokingVertexModeEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdSetProvokingVertexModeEXT(commandBuffer, provokingVertexMode, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdSetProvokingVertexModeEXT");
        device_dispatch->CmdSetProvokingVertexModeEXT(commandBuffer, provokingVertexMode);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdSetProvokingVertexModeEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdSetProvokingVertexModeEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdSetProvokingVertexModeEXT(commandBuffer, provokingVertexMode, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdSetLineRasterizationModeEXT(VkCommandBuffer commandBuffer,
                                                          VkLineRasterizationModeEXT lineRasterizationMode) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdSetLineRasterizationModeEXT,
                          VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdSetLineRasterizationModeEXT");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdSetLineRasterizationModeEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdSetLineRasterizationModeEXT(commandBuffer, lineRasterizationMode, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdSetLineRasterizationModeEXT);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdSetLineRasterizationModeEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdSetLineRasterizationModeEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdSetLineRasterizationModeEXT(commandBuffer, lineRasterizationMode, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdSetLineRasterizationModeEXT");
        device_dispatch->CmdSetLineRasterizationModeEXT(commandBuffer, lineRasterizationMode);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdSetLineRasterizationModeEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdSetLineRasterizationModeEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdSetLineRasterizationModeEXT(commandBuffer, lineRasterizationMode, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdSetLineStippleEnableEXT(VkCommandBuffer commandBuffer, VkBool32 stippledLineEnable) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdSetLineStippleEnableEXT,
                          VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdSetLineStippleEnableEXT");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdSetLineStippleEnableEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdSetLineStippleEnableEXT(commandBuffer, stippledLineEnable, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdSetLineStippleEnableEXT);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdSetLineStippleEnableEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdSetLineStippleEnableEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdSetLineStippleEnableEXT(commandBuffer, stippledLineEnable, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdSetLineStippleEnableEXT");
        device_dispatch->CmdSetLineStippleEnableEXT(commandBuffer, stippledLineEnable);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdSetLineStippleEnableEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdSetLineStippleEnableEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdSetLineStippleEnableEXT(commandBuffer, stippledLineEnable, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdSetDepthClipNegativeOneToOneEXT(VkCommandBuffer commandBuffer, VkBool32 negativeOneToOne) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdSetDepthClipNegativeOneToOneEXT,
                          VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdSetDepthClipNegativeOneToOneEXT");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdSetDepthClipNegativeOneToOneEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdSetDepthClipNegativeOneToOneEXT(commandBuffer, negativeOneToOne, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdSetDepthClipNegativeOneToOneEXT);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdSetDepthClipNegativeOneToOneEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdSetDepthClipNegativeOneToOneEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdSetDepthClipNegativeOneToOneEXT(commandBuffer, negativeOneToOne, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdSetDepthClipNegativeOneToOneEXT");
        device_dispatch->CmdSetDepthClipNegativeOneToOneEXT(commandBuffer, negativeOneToOne);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdSetDepthClipNegativeOneToOneEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdSetDepthClipNegativeOneToOneEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdSetDepthClipNegativeOneToOneEXT(commandBuffer, negativeOneToOne, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdSetViewportWScalingEnableNV(VkCommandBuffer commandBuffer, VkBool32 viewportWScalingEnable) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdSetViewportWScalingEnableNV,
                          VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdSetViewportWScalingEnableNV");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdSetViewportWScalingEnableNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdSetViewportWScalingEnableNV(commandBuffer, viewportWScalingEnable, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdSetViewportWScalingEnableNV);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdSetViewportWScalingEnableNV");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdSetViewportWScalingEnableNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdSetViewportWScalingEnableNV(commandBuffer, viewportWScalingEnable, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdSetViewportWScalingEnableNV");
        device_dispatch->CmdSetViewportWScalingEnableNV(commandBuffer, viewportWScalingEnable);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdSetViewportWScalingEnableNV");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdSetViewportWScalingEnableNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdSetViewportWScalingEnableNV(commandBuffer, viewportWScalingEnable, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdSetViewportSwizzleNV(VkCommandBuffer commandBuffer, uint32_t firstViewport, uint32_t viewportCount,
                                                   const VkViewportSwizzleNV* pViewportSwizzles) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdSetViewportSwizzleNV, VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdSetViewportSwizzleNV");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdSetViewportSwizzleNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdSetViewportSwizzleNV(commandBuffer, firstViewport, viewportCount, pViewportSwizzles,
                                                               error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdSetViewportSwizzleNV);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdSetViewportSwizzleNV");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdSetViewportSwizzleNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdSetViewportSwizzleNV(commandBuffer, firstViewport, viewportCount, pViewportSwizzles, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdSetViewportSwizzleNV");
        device_dispatch->CmdSetViewportSwizzleNV(commandBuffer, firstViewport, viewportCount, pViewportSwizzles);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdSetViewportSwizzleNV");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdSetViewportSwizzleNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdSetViewportSwizzleNV(commandBuffer, firstViewport, viewportCount, pViewportSwizzles, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdSetCoverageToColorEnableNV(VkCommandBuffer commandBuffer, VkBool32 coverageToColorEnable) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdSetCoverageToColorEnableNV,
                          VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdSetCoverageToColorEnableNV");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdSetCoverageToColorEnableNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdSetCoverageToColorEnableNV(commandBuffer, coverageToColorEnable, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdSetCoverageToColorEnableNV);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdSetCoverageToColorEnableNV");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdSetCoverageToColorEnableNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdSetCoverageToColorEnableNV(commandBuffer, coverageToColorEnable, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdSetCoverageToColorEnableNV");
        device_dispatch->CmdSetCoverageToColorEnableNV(commandBuffer, coverageToColorEnable);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdSetCoverageToColorEnableNV");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdSetCoverageToColorEnableNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdSetCoverageToColorEnableNV(commandBuffer, coverageToColorEnable, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdSetCoverageToColorLocationNV(VkCommandBuffer commandBuffer, uint32_t coverageToColorLocation) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdSetCoverageToColorLocationNV,
                          VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdSetCoverageToColorLocationNV");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdSetCoverageToColorLocationNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdSetCoverageToColorLocationNV(commandBuffer, coverageToColorLocation, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdSetCoverageToColorLocationNV);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdSetCoverageToColorLocationNV");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdSetCoverageToColorLocationNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdSetCoverageToColorLocationNV(commandBuffer, coverageToColorLocation, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdSetCoverageToColorLocationNV");
        device_dispatch->CmdSetCoverageToColorLocationNV(commandBuffer, coverageToColorLocation);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdSetCoverageToColorLocationNV");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdSetCoverageToColorLocationNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdSetCoverageToColorLocationNV(commandBuffer, coverageToColorLocation, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdSetCoverageModulationModeNV(VkCommandBuffer commandBuffer,
                                                          VkCoverageModulationModeNV coverageModulationMode) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdSetCoverageModulationModeNV,
                          VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdSetCoverageModulationModeNV");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdSetCoverageModulationModeNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdSetCoverageModulationModeNV(commandBuffer, coverageModulationMode, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdSetCoverageModulationModeNV);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdSetCoverageModulationModeNV");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdSetCoverageModulationModeNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdSetCoverageModulationModeNV(commandBuffer, coverageModulationMode, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdSetCoverageModulationModeNV");
        device_dispatch->CmdSetCoverageModulationModeNV(commandBuffer, coverageModulationMode);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdSetCoverageModulationModeNV");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdSetCoverageModulationModeNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdSetCoverageModulationModeNV(commandBuffer, coverageModulationMode, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdSetCoverageModulationTableEnableNV(VkCommandBuffer commandBuffer,
                                                                 VkBool32 coverageModulationTableEnable) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdSetCoverageModulationTableEnableNV,
                          VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdSetCoverageModulationTableEnableNV");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdSetCoverageModulationTableEnableNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |=
                vo->PreCallValidateCmdSetCoverageModulationTableEnableNV(commandBuffer, coverageModulationTableEnable, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdSetCoverageModulationTableEnableNV);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdSetCoverageModulationTableEnableNV");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdSetCoverageModulationTableEnableNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdSetCoverageModulationTableEnableNV(commandBuffer, coverageModulationTableEnable, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdSetCoverageModulationTableEnableNV");
        device_dispatch->CmdSetCoverageModulationTableEnableNV(commandBuffer, coverageModulationTableEnable);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdSetCoverageModulationTableEnableNV");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdSetCoverageModulationTableEnableNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdSetCoverageModulationTableEnableNV(commandBuffer, coverageModulationTableEnable, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdSetCoverageModulationTableNV(VkCommandBuffer commandBuffer, uint32_t coverageModulationTableCount,
                                                           const float* pCoverageModulationTable) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdSetCoverageModulationTableNV,
                          VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdSetCoverageModulationTableNV");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdSetCoverageModulationTableNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdSetCoverageModulationTableNV(commandBuffer, coverageModulationTableCount,
                                                                       pCoverageModulationTable, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdSetCoverageModulationTableNV);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdSetCoverageModulationTableNV");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdSetCoverageModulationTableNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdSetCoverageModulationTableNV(commandBuffer, coverageModulationTableCount, pCoverageModulationTable,
                                                             record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdSetCoverageModulationTableNV");
        device_dispatch->CmdSetCoverageModulationTableNV(commandBuffer, coverageModulationTableCount, pCoverageModulationTable);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdSetCoverageModulationTableNV");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdSetCoverageModulationTableNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdSetCoverageModulationTableNV(commandBuffer, coverageModulationTableCount, pCoverageModulationTable,
                                                              record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdSetShadingRateImageEnableNV(VkCommandBuffer commandBuffer, VkBool32 shadingRateImageEnable) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdSetShadingRateImageEnableNV,
                          VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdSetShadingRateImageEnableNV");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdSetShadingRateImageEnableNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdSetShadingRateImageEnableNV(commandBuffer, shadingRateImageEnable, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdSetShadingRateImageEnableNV);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdSetShadingRateImageEnableNV");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdSetShadingRateImageEnableNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdSetShadingRateImageEnableNV(commandBuffer, shadingRateImageEnable, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdSetShadingRateImageEnableNV");
        device_dispatch->CmdSetShadingRateImageEnableNV(commandBuffer, shadingRateImageEnable);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdSetShadingRateImageEnableNV");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdSetShadingRateImageEnableNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdSetShadingRateImageEnableNV(commandBuffer, shadingRateImageEnable, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdSetRepresentativeFragmentTestEnableNV(VkCommandBuffer commandBuffer,
                                                                    VkBool32 representativeFragmentTestEnable) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdSetRepresentativeFragmentTestEnableNV,
                          VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdSetRepresentativeFragmentTestEnableNV");
        for (const auto& vo :
             device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdSetRepresentativeFragmentTestEnableNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdSetRepresentativeFragmentTestEnableNV(commandBuffer, representativeFragmentTestEnable,
                                                                                error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdSetRepresentativeFragmentTestEnableNV);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdSetRepresentativeFragmentTestEnableNV");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdSetRepresentativeFragmentTestEnableNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdSetRepresentativeFragmentTestEnableNV(commandBuffer, representativeFragmentTestEnable, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdSetRepresentativeFragmentTestEnableNV");
        device_dispatch->CmdSetRepresentativeFragmentTestEnableNV(commandBuffer, representativeFragmentTestEnable);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdSetRepresentativeFragmentTestEnableNV");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdSetRepresentativeFragmentTestEnableNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdSetRepresentativeFragmentTestEnableNV(commandBuffer, representativeFragmentTestEnable, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdSetCoverageReductionModeNV(VkCommandBuffer commandBuffer,
                                                         VkCoverageReductionModeNV coverageReductionMode) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdSetCoverageReductionModeNV,
                          VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdSetCoverageReductionModeNV");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdSetCoverageReductionModeNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdSetCoverageReductionModeNV(commandBuffer, coverageReductionMode, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdSetCoverageReductionModeNV);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdSetCoverageReductionModeNV");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdSetCoverageReductionModeNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdSetCoverageReductionModeNV(commandBuffer, coverageReductionMode, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdSetCoverageReductionModeNV");
        device_dispatch->CmdSetCoverageReductionModeNV(commandBuffer, coverageReductionMode);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdSetCoverageReductionModeNV");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdSetCoverageReductionModeNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdSetCoverageReductionModeNV(commandBuffer, coverageReductionMode, record_obj);
        }
    }
}

VKAPI_ATTR VkResult VKAPI_CALL CreateTensorARM(VkDevice device, const VkTensorCreateInfoARM* pCreateInfo,
                                               const VkAllocationCallbacks* pAllocator, VkTensorARM* pTensor) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCreateTensorARM, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCreateTensorARM");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCreateTensorARM]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCreateTensorARM(device, pCreateInfo, pAllocator, pTensor, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkCreateTensorARM);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCreateTensorARM");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCreateTensorARM]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCreateTensorARM(device, pCreateInfo, pAllocator, pTensor, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkCreateTensorARM");
        result = device_dispatch->CreateTensorARM(device, pCreateInfo, pAllocator, pTensor);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkCreateTensorARM");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCreateTensorARM]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCreateTensorARM(device, pCreateInfo, pAllocator, pTensor, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR void VKAPI_CALL DestroyTensorARM(VkDevice device, VkTensorARM tensor, const VkAllocationCallbacks* pAllocator) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkDestroyTensorARM, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkDestroyTensorARM");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateDestroyTensorARM]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateDestroyTensorARM(device, tensor, pAllocator, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkDestroyTensorARM);
    {
        VVL_ZoneScopedN("PreCallRecord_vkDestroyTensorARM");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordDestroyTensorARM]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordDestroyTensorARM(device, tensor, pAllocator, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkDestroyTensorARM");
        device_dispatch->DestroyTensorARM(device, tensor, pAllocator);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkDestroyTensorARM");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordDestroyTensorARM]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordDestroyTensorARM(device, tensor, pAllocator, record_obj);
        }
    }
}

VKAPI_ATTR VkResult VKAPI_CALL CreateTensorViewARM(VkDevice device, const VkTensorViewCreateInfoARM* pCreateInfo,
                                                   const VkAllocationCallbacks* pAllocator, VkTensorViewARM* pView) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCreateTensorViewARM, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCreateTensorViewARM");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCreateTensorViewARM]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCreateTensorViewARM(device, pCreateInfo, pAllocator, pView, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkCreateTensorViewARM);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCreateTensorViewARM");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCreateTensorViewARM]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCreateTensorViewARM(device, pCreateInfo, pAllocator, pView, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkCreateTensorViewARM");
        result = device_dispatch->CreateTensorViewARM(device, pCreateInfo, pAllocator, pView);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkCreateTensorViewARM");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCreateTensorViewARM]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCreateTensorViewARM(device, pCreateInfo, pAllocator, pView, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR void VKAPI_CALL DestroyTensorViewARM(VkDevice device, VkTensorViewARM tensorView,
                                                const VkAllocationCallbacks* pAllocator) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkDestroyTensorViewARM, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkDestroyTensorViewARM");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateDestroyTensorViewARM]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateDestroyTensorViewARM(device, tensorView, pAllocator, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkDestroyTensorViewARM);
    {
        VVL_ZoneScopedN("PreCallRecord_vkDestroyTensorViewARM");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordDestroyTensorViewARM]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordDestroyTensorViewARM(device, tensorView, pAllocator, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkDestroyTensorViewARM");
        device_dispatch->DestroyTensorViewARM(device, tensorView, pAllocator);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkDestroyTensorViewARM");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordDestroyTensorViewARM]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordDestroyTensorViewARM(device, tensorView, pAllocator, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL GetTensorMemoryRequirementsARM(VkDevice device, const VkTensorMemoryRequirementsInfoARM* pInfo,
                                                          VkMemoryRequirements2* pMemoryRequirements) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetTensorMemoryRequirementsARM, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetTensorMemoryRequirementsARM");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateGetTensorMemoryRequirementsARM]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateGetTensorMemoryRequirementsARM(device, pInfo, pMemoryRequirements, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetTensorMemoryRequirementsARM);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetTensorMemoryRequirementsARM");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordGetTensorMemoryRequirementsARM]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordGetTensorMemoryRequirementsARM(device, pInfo, pMemoryRequirements, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkGetTensorMemoryRequirementsARM");
        device_dispatch->GetTensorMemoryRequirementsARM(device, pInfo, pMemoryRequirements);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetTensorMemoryRequirementsARM");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordGetTensorMemoryRequirementsARM]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordGetTensorMemoryRequirementsARM(device, pInfo, pMemoryRequirements, record_obj);
        }
    }
}

VKAPI_ATTR VkResult VKAPI_CALL BindTensorMemoryARM(VkDevice device, uint32_t bindInfoCount,
                                                   const VkBindTensorMemoryInfoARM* pBindInfos) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkBindTensorMemoryARM, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkBindTensorMemoryARM");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateBindTensorMemoryARM]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateBindTensorMemoryARM(device, bindInfoCount, pBindInfos, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkBindTensorMemoryARM);
    {
        VVL_ZoneScopedN("PreCallRecord_vkBindTensorMemoryARM");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordBindTensorMemoryARM]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordBindTensorMemoryARM(device, bindInfoCount, pBindInfos, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkBindTensorMemoryARM");
        result = device_dispatch->BindTensorMemoryARM(device, bindInfoCount, pBindInfos);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkBindTensorMemoryARM");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordBindTensorMemoryARM]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordBindTensorMemoryARM(device, bindInfoCount, pBindInfos, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR void VKAPI_CALL GetDeviceTensorMemoryRequirementsARM(VkDevice device, const VkDeviceTensorMemoryRequirementsARM* pInfo,
                                                                VkMemoryRequirements2* pMemoryRequirements) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetDeviceTensorMemoryRequirementsARM, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetDeviceTensorMemoryRequirementsARM");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateGetDeviceTensorMemoryRequirementsARM]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateGetDeviceTensorMemoryRequirementsARM(device, pInfo, pMemoryRequirements, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetDeviceTensorMemoryRequirementsARM);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetDeviceTensorMemoryRequirementsARM");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordGetDeviceTensorMemoryRequirementsARM]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordGetDeviceTensorMemoryRequirementsARM(device, pInfo, pMemoryRequirements, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkGetDeviceTensorMemoryRequirementsARM");
        device_dispatch->GetDeviceTensorMemoryRequirementsARM(device, pInfo, pMemoryRequirements);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetDeviceTensorMemoryRequirementsARM");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordGetDeviceTensorMemoryRequirementsARM]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordGetDeviceTensorMemoryRequirementsARM(device, pInfo, pMemoryRequirements, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdCopyTensorARM(VkCommandBuffer commandBuffer, const VkCopyTensorInfoARM* pCopyTensorInfo) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdCopyTensorARM, VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdCopyTensorARM");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdCopyTensorARM]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdCopyTensorARM(commandBuffer, pCopyTensorInfo, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdCopyTensorARM);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdCopyTensorARM");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdCopyTensorARM]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdCopyTensorARM(commandBuffer, pCopyTensorInfo, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdCopyTensorARM");
        device_dispatch->CmdCopyTensorARM(commandBuffer, pCopyTensorInfo);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdCopyTensorARM");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdCopyTensorARM]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdCopyTensorARM(commandBuffer, pCopyTensorInfo, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL GetPhysicalDeviceExternalTensorPropertiesARM(
    VkPhysicalDevice physicalDevice, const VkPhysicalDeviceExternalTensorInfoARM* pExternalTensorInfo,
    VkExternalTensorPropertiesARM* pExternalTensorProperties) {
    VVL_ZoneScoped;

    auto instance_dispatch = vvl::dispatch::GetData(physicalDevice);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetPhysicalDeviceExternalTensorPropertiesARM,
                          VulkanTypedHandle(physicalDevice, kVulkanObjectTypePhysicalDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetPhysicalDeviceExternalTensorPropertiesARM");
        for (const auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            skip |= vo->PreCallValidateGetPhysicalDeviceExternalTensorPropertiesARM(physicalDevice, pExternalTensorInfo,
                                                                                    pExternalTensorProperties, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetPhysicalDeviceExternalTensorPropertiesARM);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetPhysicalDeviceExternalTensorPropertiesARM");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PreCallRecordGetPhysicalDeviceExternalTensorPropertiesARM(physicalDevice, pExternalTensorInfo,
                                                                          pExternalTensorProperties, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkGetPhysicalDeviceExternalTensorPropertiesARM");
        instance_dispatch->GetPhysicalDeviceExternalTensorPropertiesARM(physicalDevice, pExternalTensorInfo,
                                                                        pExternalTensorProperties);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetPhysicalDeviceExternalTensorPropertiesARM");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PostCallRecordGetPhysicalDeviceExternalTensorPropertiesARM(physicalDevice, pExternalTensorInfo,
                                                                           pExternalTensorProperties, record_obj);
        }
    }
}

VKAPI_ATTR VkResult VKAPI_CALL GetTensorOpaqueCaptureDescriptorDataARM(VkDevice device,
                                                                       const VkTensorCaptureDescriptorDataInfoARM* pInfo,
                                                                       void* pData) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetTensorOpaqueCaptureDescriptorDataARM, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetTensorOpaqueCaptureDescriptorDataARM");
        for (const auto& vo :
             device_dispatch->intercept_vectors[InterceptIdPreCallValidateGetTensorOpaqueCaptureDescriptorDataARM]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateGetTensorOpaqueCaptureDescriptorDataARM(device, pInfo, pData, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetTensorOpaqueCaptureDescriptorDataARM);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetTensorOpaqueCaptureDescriptorDataARM");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordGetTensorOpaqueCaptureDescriptorDataARM]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordGetTensorOpaqueCaptureDescriptorDataARM(device, pInfo, pData, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkGetTensorOpaqueCaptureDescriptorDataARM");
        result = device_dispatch->GetTensorOpaqueCaptureDescriptorDataARM(device, pInfo, pData);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetTensorOpaqueCaptureDescriptorDataARM");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordGetTensorOpaqueCaptureDescriptorDataARM]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordGetTensorOpaqueCaptureDescriptorDataARM(device, pInfo, pData, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR VkResult VKAPI_CALL GetTensorViewOpaqueCaptureDescriptorDataARM(VkDevice device,
                                                                           const VkTensorViewCaptureDescriptorDataInfoARM* pInfo,
                                                                           void* pData) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetTensorViewOpaqueCaptureDescriptorDataARM,
                          VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetTensorViewOpaqueCaptureDescriptorDataARM");
        for (const auto& vo :
             device_dispatch->intercept_vectors[InterceptIdPreCallValidateGetTensorViewOpaqueCaptureDescriptorDataARM]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateGetTensorViewOpaqueCaptureDescriptorDataARM(device, pInfo, pData, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetTensorViewOpaqueCaptureDescriptorDataARM);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetTensorViewOpaqueCaptureDescriptorDataARM");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordGetTensorViewOpaqueCaptureDescriptorDataARM]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordGetTensorViewOpaqueCaptureDescriptorDataARM(device, pInfo, pData, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkGetTensorViewOpaqueCaptureDescriptorDataARM");
        result = device_dispatch->GetTensorViewOpaqueCaptureDescriptorDataARM(device, pInfo, pData);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetTensorViewOpaqueCaptureDescriptorDataARM");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordGetTensorViewOpaqueCaptureDescriptorDataARM]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordGetTensorViewOpaqueCaptureDescriptorDataARM(device, pInfo, pData, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR void VKAPI_CALL GetShaderModuleIdentifierEXT(VkDevice device, VkShaderModule shaderModule,
                                                        VkShaderModuleIdentifierEXT* pIdentifier) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetShaderModuleIdentifierEXT, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetShaderModuleIdentifierEXT");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateGetShaderModuleIdentifierEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateGetShaderModuleIdentifierEXT(device, shaderModule, pIdentifier, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetShaderModuleIdentifierEXT);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetShaderModuleIdentifierEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordGetShaderModuleIdentifierEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordGetShaderModuleIdentifierEXT(device, shaderModule, pIdentifier, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkGetShaderModuleIdentifierEXT");
        device_dispatch->GetShaderModuleIdentifierEXT(device, shaderModule, pIdentifier);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetShaderModuleIdentifierEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordGetShaderModuleIdentifierEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordGetShaderModuleIdentifierEXT(device, shaderModule, pIdentifier, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL GetShaderModuleCreateInfoIdentifierEXT(VkDevice device, const VkShaderModuleCreateInfo* pCreateInfo,
                                                                  VkShaderModuleIdentifierEXT* pIdentifier) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetShaderModuleCreateInfoIdentifierEXT, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetShaderModuleCreateInfoIdentifierEXT");
        for (const auto& vo :
             device_dispatch->intercept_vectors[InterceptIdPreCallValidateGetShaderModuleCreateInfoIdentifierEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateGetShaderModuleCreateInfoIdentifierEXT(device, pCreateInfo, pIdentifier, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetShaderModuleCreateInfoIdentifierEXT);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetShaderModuleCreateInfoIdentifierEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordGetShaderModuleCreateInfoIdentifierEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordGetShaderModuleCreateInfoIdentifierEXT(device, pCreateInfo, pIdentifier, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkGetShaderModuleCreateInfoIdentifierEXT");
        device_dispatch->GetShaderModuleCreateInfoIdentifierEXT(device, pCreateInfo, pIdentifier);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetShaderModuleCreateInfoIdentifierEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordGetShaderModuleCreateInfoIdentifierEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordGetShaderModuleCreateInfoIdentifierEXT(device, pCreateInfo, pIdentifier, record_obj);
        }
    }
}

VKAPI_ATTR VkResult VKAPI_CALL GetPhysicalDeviceOpticalFlowImageFormatsNV(
    VkPhysicalDevice physicalDevice, const VkOpticalFlowImageFormatInfoNV* pOpticalFlowImageFormatInfo, uint32_t* pFormatCount,
    VkOpticalFlowImageFormatPropertiesNV* pImageFormatProperties) {
    VVL_ZoneScoped;

    auto instance_dispatch = vvl::dispatch::GetData(physicalDevice);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetPhysicalDeviceOpticalFlowImageFormatsNV,
                          VulkanTypedHandle(physicalDevice, kVulkanObjectTypePhysicalDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetPhysicalDeviceOpticalFlowImageFormatsNV");
        for (const auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            skip |= vo->PreCallValidateGetPhysicalDeviceOpticalFlowImageFormatsNV(physicalDevice, pOpticalFlowImageFormatInfo,
                                                                                  pFormatCount, pImageFormatProperties, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetPhysicalDeviceOpticalFlowImageFormatsNV);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetPhysicalDeviceOpticalFlowImageFormatsNV");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PreCallRecordGetPhysicalDeviceOpticalFlowImageFormatsNV(physicalDevice, pOpticalFlowImageFormatInfo, pFormatCount,
                                                                        pImageFormatProperties, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkGetPhysicalDeviceOpticalFlowImageFormatsNV");
        result = instance_dispatch->GetPhysicalDeviceOpticalFlowImageFormatsNV(physicalDevice, pOpticalFlowImageFormatInfo,
                                                                               pFormatCount, pImageFormatProperties);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetPhysicalDeviceOpticalFlowImageFormatsNV");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PostCallRecordGetPhysicalDeviceOpticalFlowImageFormatsNV(physicalDevice, pOpticalFlowImageFormatInfo, pFormatCount,
                                                                         pImageFormatProperties, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR VkResult VKAPI_CALL CreateOpticalFlowSessionNV(VkDevice device, const VkOpticalFlowSessionCreateInfoNV* pCreateInfo,
                                                          const VkAllocationCallbacks* pAllocator,
                                                          VkOpticalFlowSessionNV* pSession) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCreateOpticalFlowSessionNV, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCreateOpticalFlowSessionNV");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCreateOpticalFlowSessionNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCreateOpticalFlowSessionNV(device, pCreateInfo, pAllocator, pSession, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkCreateOpticalFlowSessionNV);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCreateOpticalFlowSessionNV");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCreateOpticalFlowSessionNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCreateOpticalFlowSessionNV(device, pCreateInfo, pAllocator, pSession, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkCreateOpticalFlowSessionNV");
        result = device_dispatch->CreateOpticalFlowSessionNV(device, pCreateInfo, pAllocator, pSession);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkCreateOpticalFlowSessionNV");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCreateOpticalFlowSessionNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCreateOpticalFlowSessionNV(device, pCreateInfo, pAllocator, pSession, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR void VKAPI_CALL DestroyOpticalFlowSessionNV(VkDevice device, VkOpticalFlowSessionNV session,
                                                       const VkAllocationCallbacks* pAllocator) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkDestroyOpticalFlowSessionNV, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkDestroyOpticalFlowSessionNV");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateDestroyOpticalFlowSessionNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateDestroyOpticalFlowSessionNV(device, session, pAllocator, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkDestroyOpticalFlowSessionNV);
    {
        VVL_ZoneScopedN("PreCallRecord_vkDestroyOpticalFlowSessionNV");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordDestroyOpticalFlowSessionNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordDestroyOpticalFlowSessionNV(device, session, pAllocator, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkDestroyOpticalFlowSessionNV");
        device_dispatch->DestroyOpticalFlowSessionNV(device, session, pAllocator);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkDestroyOpticalFlowSessionNV");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordDestroyOpticalFlowSessionNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordDestroyOpticalFlowSessionNV(device, session, pAllocator, record_obj);
        }
    }
}

VKAPI_ATTR VkResult VKAPI_CALL BindOpticalFlowSessionImageNV(VkDevice device, VkOpticalFlowSessionNV session,
                                                             VkOpticalFlowSessionBindingPointNV bindingPoint, VkImageView view,
                                                             VkImageLayout layout) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkBindOpticalFlowSessionImageNV, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkBindOpticalFlowSessionImageNV");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateBindOpticalFlowSessionImageNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateBindOpticalFlowSessionImageNV(device, session, bindingPoint, view, layout, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkBindOpticalFlowSessionImageNV);
    {
        VVL_ZoneScopedN("PreCallRecord_vkBindOpticalFlowSessionImageNV");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordBindOpticalFlowSessionImageNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordBindOpticalFlowSessionImageNV(device, session, bindingPoint, view, layout, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkBindOpticalFlowSessionImageNV");
        result = device_dispatch->BindOpticalFlowSessionImageNV(device, session, bindingPoint, view, layout);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkBindOpticalFlowSessionImageNV");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordBindOpticalFlowSessionImageNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordBindOpticalFlowSessionImageNV(device, session, bindingPoint, view, layout, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR void VKAPI_CALL CmdOpticalFlowExecuteNV(VkCommandBuffer commandBuffer, VkOpticalFlowSessionNV session,
                                                   const VkOpticalFlowExecuteInfoNV* pExecuteInfo) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdOpticalFlowExecuteNV, VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdOpticalFlowExecuteNV");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdOpticalFlowExecuteNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdOpticalFlowExecuteNV(commandBuffer, session, pExecuteInfo, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdOpticalFlowExecuteNV);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdOpticalFlowExecuteNV");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdOpticalFlowExecuteNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdOpticalFlowExecuteNV(commandBuffer, session, pExecuteInfo, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdOpticalFlowExecuteNV");
        device_dispatch->CmdOpticalFlowExecuteNV(commandBuffer, session, pExecuteInfo);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdOpticalFlowExecuteNV");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdOpticalFlowExecuteNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdOpticalFlowExecuteNV(commandBuffer, session, pExecuteInfo, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL AntiLagUpdateAMD(VkDevice device, const VkAntiLagDataAMD* pData) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkAntiLagUpdateAMD, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkAntiLagUpdateAMD");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateAntiLagUpdateAMD]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateAntiLagUpdateAMD(device, pData, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkAntiLagUpdateAMD);
    {
        VVL_ZoneScopedN("PreCallRecord_vkAntiLagUpdateAMD");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordAntiLagUpdateAMD]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordAntiLagUpdateAMD(device, pData, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkAntiLagUpdateAMD");
        device_dispatch->AntiLagUpdateAMD(device, pData);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkAntiLagUpdateAMD");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordAntiLagUpdateAMD]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordAntiLagUpdateAMD(device, pData, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL DestroyShaderEXT(VkDevice device, VkShaderEXT shader, const VkAllocationCallbacks* pAllocator) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkDestroyShaderEXT, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkDestroyShaderEXT");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateDestroyShaderEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateDestroyShaderEXT(device, shader, pAllocator, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkDestroyShaderEXT);
    {
        VVL_ZoneScopedN("PreCallRecord_vkDestroyShaderEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordDestroyShaderEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordDestroyShaderEXT(device, shader, pAllocator, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkDestroyShaderEXT");
        device_dispatch->DestroyShaderEXT(device, shader, pAllocator);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkDestroyShaderEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordDestroyShaderEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordDestroyShaderEXT(device, shader, pAllocator, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdBindShadersEXT(VkCommandBuffer commandBuffer, uint32_t stageCount,
                                             const VkShaderStageFlagBits* pStages, const VkShaderEXT* pShaders) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdBindShadersEXT, VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdBindShadersEXT");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdBindShadersEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdBindShadersEXT(commandBuffer, stageCount, pStages, pShaders, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdBindShadersEXT);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdBindShadersEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdBindShadersEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdBindShadersEXT(commandBuffer, stageCount, pStages, pShaders, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdBindShadersEXT");
        device_dispatch->CmdBindShadersEXT(commandBuffer, stageCount, pStages, pShaders);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdBindShadersEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdBindShadersEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdBindShadersEXT(commandBuffer, stageCount, pStages, pShaders, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdSetDepthClampRangeEXT(VkCommandBuffer commandBuffer, VkDepthClampModeEXT depthClampMode,
                                                    const VkDepthClampRangeEXT* pDepthClampRange) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdSetDepthClampRangeEXT, VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdSetDepthClampRangeEXT");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdSetDepthClampRangeEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdSetDepthClampRangeEXT(commandBuffer, depthClampMode, pDepthClampRange, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdSetDepthClampRangeEXT);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdSetDepthClampRangeEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdSetDepthClampRangeEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdSetDepthClampRangeEXT(commandBuffer, depthClampMode, pDepthClampRange, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdSetDepthClampRangeEXT");
        device_dispatch->CmdSetDepthClampRangeEXT(commandBuffer, depthClampMode, pDepthClampRange);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdSetDepthClampRangeEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdSetDepthClampRangeEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdSetDepthClampRangeEXT(commandBuffer, depthClampMode, pDepthClampRange, record_obj);
        }
    }
}

VKAPI_ATTR VkResult VKAPI_CALL GetFramebufferTilePropertiesQCOM(VkDevice device, VkFramebuffer framebuffer,
                                                                uint32_t* pPropertiesCount, VkTilePropertiesQCOM* pProperties) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetFramebufferTilePropertiesQCOM, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetFramebufferTilePropertiesQCOM");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateGetFramebufferTilePropertiesQCOM]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |=
                vo->PreCallValidateGetFramebufferTilePropertiesQCOM(device, framebuffer, pPropertiesCount, pProperties, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetFramebufferTilePropertiesQCOM);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetFramebufferTilePropertiesQCOM");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordGetFramebufferTilePropertiesQCOM]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordGetFramebufferTilePropertiesQCOM(device, framebuffer, pPropertiesCount, pProperties, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkGetFramebufferTilePropertiesQCOM");
        result = device_dispatch->GetFramebufferTilePropertiesQCOM(device, framebuffer, pPropertiesCount, pProperties);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetFramebufferTilePropertiesQCOM");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordGetFramebufferTilePropertiesQCOM]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordGetFramebufferTilePropertiesQCOM(device, framebuffer, pPropertiesCount, pProperties, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR VkResult VKAPI_CALL GetDynamicRenderingTilePropertiesQCOM(VkDevice device, const VkRenderingInfo* pRenderingInfo,
                                                                     VkTilePropertiesQCOM* pProperties) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetDynamicRenderingTilePropertiesQCOM, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetDynamicRenderingTilePropertiesQCOM");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateGetDynamicRenderingTilePropertiesQCOM]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateGetDynamicRenderingTilePropertiesQCOM(device, pRenderingInfo, pProperties, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetDynamicRenderingTilePropertiesQCOM);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetDynamicRenderingTilePropertiesQCOM");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordGetDynamicRenderingTilePropertiesQCOM]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordGetDynamicRenderingTilePropertiesQCOM(device, pRenderingInfo, pProperties, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkGetDynamicRenderingTilePropertiesQCOM");
        result = device_dispatch->GetDynamicRenderingTilePropertiesQCOM(device, pRenderingInfo, pProperties);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetDynamicRenderingTilePropertiesQCOM");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordGetDynamicRenderingTilePropertiesQCOM]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordGetDynamicRenderingTilePropertiesQCOM(device, pRenderingInfo, pProperties, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR VkResult VKAPI_CALL GetPhysicalDeviceCooperativeVectorPropertiesNV(VkPhysicalDevice physicalDevice,
                                                                              uint32_t* pPropertyCount,
                                                                              VkCooperativeVectorPropertiesNV* pProperties) {
    VVL_ZoneScoped;

    auto instance_dispatch = vvl::dispatch::GetData(physicalDevice);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetPhysicalDeviceCooperativeVectorPropertiesNV,
                          VulkanTypedHandle(physicalDevice, kVulkanObjectTypePhysicalDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetPhysicalDeviceCooperativeVectorPropertiesNV");
        for (const auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            skip |= vo->PreCallValidateGetPhysicalDeviceCooperativeVectorPropertiesNV(physicalDevice, pPropertyCount, pProperties,
                                                                                      error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetPhysicalDeviceCooperativeVectorPropertiesNV);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetPhysicalDeviceCooperativeVectorPropertiesNV");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PreCallRecordGetPhysicalDeviceCooperativeVectorPropertiesNV(physicalDevice, pPropertyCount, pProperties,
                                                                            record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkGetPhysicalDeviceCooperativeVectorPropertiesNV");
        result = instance_dispatch->GetPhysicalDeviceCooperativeVectorPropertiesNV(physicalDevice, pPropertyCount, pProperties);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetPhysicalDeviceCooperativeVectorPropertiesNV");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PostCallRecordGetPhysicalDeviceCooperativeVectorPropertiesNV(physicalDevice, pPropertyCount, pProperties,
                                                                             record_obj);
        }
    }
    return result;
}

VKAPI_ATTR VkResult VKAPI_CALL ConvertCooperativeVectorMatrixNV(VkDevice device,
                                                                const VkConvertCooperativeVectorMatrixInfoNV* pInfo) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkConvertCooperativeVectorMatrixNV, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkConvertCooperativeVectorMatrixNV");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateConvertCooperativeVectorMatrixNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateConvertCooperativeVectorMatrixNV(device, pInfo, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkConvertCooperativeVectorMatrixNV);
    {
        VVL_ZoneScopedN("PreCallRecord_vkConvertCooperativeVectorMatrixNV");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordConvertCooperativeVectorMatrixNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordConvertCooperativeVectorMatrixNV(device, pInfo, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkConvertCooperativeVectorMatrixNV");
        result = device_dispatch->ConvertCooperativeVectorMatrixNV(device, pInfo);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkConvertCooperativeVectorMatrixNV");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordConvertCooperativeVectorMatrixNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordConvertCooperativeVectorMatrixNV(device, pInfo, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR void VKAPI_CALL CmdConvertCooperativeVectorMatrixNV(VkCommandBuffer commandBuffer, uint32_t infoCount,
                                                               const VkConvertCooperativeVectorMatrixInfoNV* pInfos) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdConvertCooperativeVectorMatrixNV,
                          VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdConvertCooperativeVectorMatrixNV");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdConvertCooperativeVectorMatrixNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdConvertCooperativeVectorMatrixNV(commandBuffer, infoCount, pInfos, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdConvertCooperativeVectorMatrixNV);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdConvertCooperativeVectorMatrixNV");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdConvertCooperativeVectorMatrixNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdConvertCooperativeVectorMatrixNV(commandBuffer, infoCount, pInfos, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdConvertCooperativeVectorMatrixNV");
        device_dispatch->CmdConvertCooperativeVectorMatrixNV(commandBuffer, infoCount, pInfos);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdConvertCooperativeVectorMatrixNV");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdConvertCooperativeVectorMatrixNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdConvertCooperativeVectorMatrixNV(commandBuffer, infoCount, pInfos, record_obj);
        }
    }
}

VKAPI_ATTR VkResult VKAPI_CALL SetLatencySleepModeNV(VkDevice device, VkSwapchainKHR swapchain,
                                                     const VkLatencySleepModeInfoNV* pSleepModeInfo) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkSetLatencySleepModeNV, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkSetLatencySleepModeNV");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateSetLatencySleepModeNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateSetLatencySleepModeNV(device, swapchain, pSleepModeInfo, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkSetLatencySleepModeNV);
    {
        VVL_ZoneScopedN("PreCallRecord_vkSetLatencySleepModeNV");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordSetLatencySleepModeNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordSetLatencySleepModeNV(device, swapchain, pSleepModeInfo, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkSetLatencySleepModeNV");
        result = device_dispatch->SetLatencySleepModeNV(device, swapchain, pSleepModeInfo);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkSetLatencySleepModeNV");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordSetLatencySleepModeNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordSetLatencySleepModeNV(device, swapchain, pSleepModeInfo, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR VkResult VKAPI_CALL LatencySleepNV(VkDevice device, VkSwapchainKHR swapchain, const VkLatencySleepInfoNV* pSleepInfo) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkLatencySleepNV, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkLatencySleepNV");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateLatencySleepNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateLatencySleepNV(device, swapchain, pSleepInfo, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkLatencySleepNV);
    {
        VVL_ZoneScopedN("PreCallRecord_vkLatencySleepNV");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordLatencySleepNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordLatencySleepNV(device, swapchain, pSleepInfo, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkLatencySleepNV");
        result = device_dispatch->LatencySleepNV(device, swapchain, pSleepInfo);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkLatencySleepNV");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordLatencySleepNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordLatencySleepNV(device, swapchain, pSleepInfo, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR void VKAPI_CALL SetLatencyMarkerNV(VkDevice device, VkSwapchainKHR swapchain,
                                              const VkSetLatencyMarkerInfoNV* pLatencyMarkerInfo) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkSetLatencyMarkerNV, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkSetLatencyMarkerNV");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateSetLatencyMarkerNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateSetLatencyMarkerNV(device, swapchain, pLatencyMarkerInfo, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkSetLatencyMarkerNV);
    {
        VVL_ZoneScopedN("PreCallRecord_vkSetLatencyMarkerNV");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordSetLatencyMarkerNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordSetLatencyMarkerNV(device, swapchain, pLatencyMarkerInfo, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkSetLatencyMarkerNV");
        device_dispatch->SetLatencyMarkerNV(device, swapchain, pLatencyMarkerInfo);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkSetLatencyMarkerNV");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordSetLatencyMarkerNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordSetLatencyMarkerNV(device, swapchain, pLatencyMarkerInfo, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL GetLatencyTimingsNV(VkDevice device, VkSwapchainKHR swapchain,
                                               VkGetLatencyMarkerInfoNV* pLatencyMarkerInfo) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetLatencyTimingsNV, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetLatencyTimingsNV");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateGetLatencyTimingsNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateGetLatencyTimingsNV(device, swapchain, pLatencyMarkerInfo, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetLatencyTimingsNV);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetLatencyTimingsNV");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordGetLatencyTimingsNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordGetLatencyTimingsNV(device, swapchain, pLatencyMarkerInfo, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkGetLatencyTimingsNV");
        device_dispatch->GetLatencyTimingsNV(device, swapchain, pLatencyMarkerInfo);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetLatencyTimingsNV");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordGetLatencyTimingsNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordGetLatencyTimingsNV(device, swapchain, pLatencyMarkerInfo, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL QueueNotifyOutOfBandNV(VkQueue queue, const VkOutOfBandQueueTypeInfoNV* pQueueTypeInfo) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(queue);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkQueueNotifyOutOfBandNV, VulkanTypedHandle(queue, kVulkanObjectTypeQueue));
    {
        VVL_ZoneScopedN("PreCallValidate_vkQueueNotifyOutOfBandNV");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateQueueNotifyOutOfBandNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateQueueNotifyOutOfBandNV(queue, pQueueTypeInfo, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkQueueNotifyOutOfBandNV);
    {
        VVL_ZoneScopedN("PreCallRecord_vkQueueNotifyOutOfBandNV");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordQueueNotifyOutOfBandNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordQueueNotifyOutOfBandNV(queue, pQueueTypeInfo, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkQueueNotifyOutOfBandNV");
        device_dispatch->QueueNotifyOutOfBandNV(queue, pQueueTypeInfo);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkQueueNotifyOutOfBandNV");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordQueueNotifyOutOfBandNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordQueueNotifyOutOfBandNV(queue, pQueueTypeInfo, record_obj);
        }
    }
}

VKAPI_ATTR VkResult VKAPI_CALL CreateDataGraphPipelineSessionARM(VkDevice device,
                                                                 const VkDataGraphPipelineSessionCreateInfoARM* pCreateInfo,
                                                                 const VkAllocationCallbacks* pAllocator,
                                                                 VkDataGraphPipelineSessionARM* pSession) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCreateDataGraphPipelineSessionARM, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCreateDataGraphPipelineSessionARM");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCreateDataGraphPipelineSessionARM]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCreateDataGraphPipelineSessionARM(device, pCreateInfo, pAllocator, pSession, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkCreateDataGraphPipelineSessionARM);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCreateDataGraphPipelineSessionARM");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCreateDataGraphPipelineSessionARM]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCreateDataGraphPipelineSessionARM(device, pCreateInfo, pAllocator, pSession, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkCreateDataGraphPipelineSessionARM");
        result = device_dispatch->CreateDataGraphPipelineSessionARM(device, pCreateInfo, pAllocator, pSession);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkCreateDataGraphPipelineSessionARM");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCreateDataGraphPipelineSessionARM]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCreateDataGraphPipelineSessionARM(device, pCreateInfo, pAllocator, pSession, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR VkResult VKAPI_CALL GetDataGraphPipelineSessionBindPointRequirementsARM(
    VkDevice device, const VkDataGraphPipelineSessionBindPointRequirementsInfoARM* pInfo, uint32_t* pBindPointRequirementCount,
    VkDataGraphPipelineSessionBindPointRequirementARM* pBindPointRequirements) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetDataGraphPipelineSessionBindPointRequirementsARM,
                          VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetDataGraphPipelineSessionBindPointRequirementsARM");
        for (const auto& vo :
             device_dispatch->intercept_vectors[InterceptIdPreCallValidateGetDataGraphPipelineSessionBindPointRequirementsARM]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateGetDataGraphPipelineSessionBindPointRequirementsARM(
                device, pInfo, pBindPointRequirementCount, pBindPointRequirements, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetDataGraphPipelineSessionBindPointRequirementsARM);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetDataGraphPipelineSessionBindPointRequirementsARM");
        for (auto& vo :
             device_dispatch->intercept_vectors[InterceptIdPreCallRecordGetDataGraphPipelineSessionBindPointRequirementsARM]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordGetDataGraphPipelineSessionBindPointRequirementsARM(device, pInfo, pBindPointRequirementCount,
                                                                                 pBindPointRequirements, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkGetDataGraphPipelineSessionBindPointRequirementsARM");
        result = device_dispatch->GetDataGraphPipelineSessionBindPointRequirementsARM(device, pInfo, pBindPointRequirementCount,
                                                                                      pBindPointRequirements);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetDataGraphPipelineSessionBindPointRequirementsARM");
        for (auto& vo :
             device_dispatch->intercept_vectors[InterceptIdPostCallRecordGetDataGraphPipelineSessionBindPointRequirementsARM]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordGetDataGraphPipelineSessionBindPointRequirementsARM(device, pInfo, pBindPointRequirementCount,
                                                                                  pBindPointRequirements, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR void VKAPI_CALL GetDataGraphPipelineSessionMemoryRequirementsARM(
    VkDevice device, const VkDataGraphPipelineSessionMemoryRequirementsInfoARM* pInfo, VkMemoryRequirements2* pMemoryRequirements) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetDataGraphPipelineSessionMemoryRequirementsARM,
                          VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetDataGraphPipelineSessionMemoryRequirementsARM");
        for (const auto& vo :
             device_dispatch->intercept_vectors[InterceptIdPreCallValidateGetDataGraphPipelineSessionMemoryRequirementsARM]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |=
                vo->PreCallValidateGetDataGraphPipelineSessionMemoryRequirementsARM(device, pInfo, pMemoryRequirements, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetDataGraphPipelineSessionMemoryRequirementsARM);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetDataGraphPipelineSessionMemoryRequirementsARM");
        for (auto& vo :
             device_dispatch->intercept_vectors[InterceptIdPreCallRecordGetDataGraphPipelineSessionMemoryRequirementsARM]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordGetDataGraphPipelineSessionMemoryRequirementsARM(device, pInfo, pMemoryRequirements, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkGetDataGraphPipelineSessionMemoryRequirementsARM");
        device_dispatch->GetDataGraphPipelineSessionMemoryRequirementsARM(device, pInfo, pMemoryRequirements);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetDataGraphPipelineSessionMemoryRequirementsARM");
        for (auto& vo :
             device_dispatch->intercept_vectors[InterceptIdPostCallRecordGetDataGraphPipelineSessionMemoryRequirementsARM]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordGetDataGraphPipelineSessionMemoryRequirementsARM(device, pInfo, pMemoryRequirements, record_obj);
        }
    }
}

VKAPI_ATTR VkResult VKAPI_CALL BindDataGraphPipelineSessionMemoryARM(
    VkDevice device, uint32_t bindInfoCount, const VkBindDataGraphPipelineSessionMemoryInfoARM* pBindInfos) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkBindDataGraphPipelineSessionMemoryARM, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkBindDataGraphPipelineSessionMemoryARM");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateBindDataGraphPipelineSessionMemoryARM]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateBindDataGraphPipelineSessionMemoryARM(device, bindInfoCount, pBindInfos, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkBindDataGraphPipelineSessionMemoryARM);
    {
        VVL_ZoneScopedN("PreCallRecord_vkBindDataGraphPipelineSessionMemoryARM");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordBindDataGraphPipelineSessionMemoryARM]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordBindDataGraphPipelineSessionMemoryARM(device, bindInfoCount, pBindInfos, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkBindDataGraphPipelineSessionMemoryARM");
        result = device_dispatch->BindDataGraphPipelineSessionMemoryARM(device, bindInfoCount, pBindInfos);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkBindDataGraphPipelineSessionMemoryARM");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordBindDataGraphPipelineSessionMemoryARM]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordBindDataGraphPipelineSessionMemoryARM(device, bindInfoCount, pBindInfos, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR void VKAPI_CALL DestroyDataGraphPipelineSessionARM(VkDevice device, VkDataGraphPipelineSessionARM session,
                                                              const VkAllocationCallbacks* pAllocator) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkDestroyDataGraphPipelineSessionARM, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkDestroyDataGraphPipelineSessionARM");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateDestroyDataGraphPipelineSessionARM]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateDestroyDataGraphPipelineSessionARM(device, session, pAllocator, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkDestroyDataGraphPipelineSessionARM);
    {
        VVL_ZoneScopedN("PreCallRecord_vkDestroyDataGraphPipelineSessionARM");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordDestroyDataGraphPipelineSessionARM]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordDestroyDataGraphPipelineSessionARM(device, session, pAllocator, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkDestroyDataGraphPipelineSessionARM");
        device_dispatch->DestroyDataGraphPipelineSessionARM(device, session, pAllocator);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkDestroyDataGraphPipelineSessionARM");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordDestroyDataGraphPipelineSessionARM]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordDestroyDataGraphPipelineSessionARM(device, session, pAllocator, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdDispatchDataGraphARM(VkCommandBuffer commandBuffer, VkDataGraphPipelineSessionARM session,
                                                   const VkDataGraphPipelineDispatchInfoARM* pInfo) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdDispatchDataGraphARM, VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdDispatchDataGraphARM");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdDispatchDataGraphARM]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdDispatchDataGraphARM(commandBuffer, session, pInfo, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdDispatchDataGraphARM);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdDispatchDataGraphARM");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdDispatchDataGraphARM]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdDispatchDataGraphARM(commandBuffer, session, pInfo, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdDispatchDataGraphARM");
        device_dispatch->CmdDispatchDataGraphARM(commandBuffer, session, pInfo);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdDispatchDataGraphARM");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdDispatchDataGraphARM]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdDispatchDataGraphARM(commandBuffer, session, pInfo, record_obj);
        }
    }
}

VKAPI_ATTR VkResult VKAPI_CALL GetDataGraphPipelineAvailablePropertiesARM(VkDevice device,
                                                                          const VkDataGraphPipelineInfoARM* pPipelineInfo,
                                                                          uint32_t* pPropertiesCount,
                                                                          VkDataGraphPipelinePropertyARM* pProperties) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetDataGraphPipelineAvailablePropertiesARM,
                          VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetDataGraphPipelineAvailablePropertiesARM");
        for (const auto& vo :
             device_dispatch->intercept_vectors[InterceptIdPreCallValidateGetDataGraphPipelineAvailablePropertiesARM]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateGetDataGraphPipelineAvailablePropertiesARM(device, pPipelineInfo, pPropertiesCount,
                                                                                  pProperties, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetDataGraphPipelineAvailablePropertiesARM);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetDataGraphPipelineAvailablePropertiesARM");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordGetDataGraphPipelineAvailablePropertiesARM]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordGetDataGraphPipelineAvailablePropertiesARM(device, pPipelineInfo, pPropertiesCount, pProperties,
                                                                        record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkGetDataGraphPipelineAvailablePropertiesARM");
        result = device_dispatch->GetDataGraphPipelineAvailablePropertiesARM(device, pPipelineInfo, pPropertiesCount, pProperties);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetDataGraphPipelineAvailablePropertiesARM");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordGetDataGraphPipelineAvailablePropertiesARM]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordGetDataGraphPipelineAvailablePropertiesARM(device, pPipelineInfo, pPropertiesCount, pProperties,
                                                                         record_obj);
        }
    }
    return result;
}

VKAPI_ATTR VkResult VKAPI_CALL GetDataGraphPipelinePropertiesARM(VkDevice device, const VkDataGraphPipelineInfoARM* pPipelineInfo,
                                                                 uint32_t propertiesCount,
                                                                 VkDataGraphPipelinePropertyQueryResultARM* pProperties) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetDataGraphPipelinePropertiesARM, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetDataGraphPipelinePropertiesARM");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateGetDataGraphPipelinePropertiesARM]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateGetDataGraphPipelinePropertiesARM(device, pPipelineInfo, propertiesCount, pProperties,
                                                                         error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetDataGraphPipelinePropertiesARM);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetDataGraphPipelinePropertiesARM");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordGetDataGraphPipelinePropertiesARM]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordGetDataGraphPipelinePropertiesARM(device, pPipelineInfo, propertiesCount, pProperties, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkGetDataGraphPipelinePropertiesARM");
        result = device_dispatch->GetDataGraphPipelinePropertiesARM(device, pPipelineInfo, propertiesCount, pProperties);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetDataGraphPipelinePropertiesARM");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordGetDataGraphPipelinePropertiesARM]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordGetDataGraphPipelinePropertiesARM(device, pPipelineInfo, propertiesCount, pProperties, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR VkResult VKAPI_CALL GetPhysicalDeviceQueueFamilyDataGraphPropertiesARM(
    VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex, uint32_t* pQueueFamilyDataGraphPropertyCount,
    VkQueueFamilyDataGraphPropertiesARM* pQueueFamilyDataGraphProperties) {
    VVL_ZoneScoped;

    auto instance_dispatch = vvl::dispatch::GetData(physicalDevice);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetPhysicalDeviceQueueFamilyDataGraphPropertiesARM,
                          VulkanTypedHandle(physicalDevice, kVulkanObjectTypePhysicalDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetPhysicalDeviceQueueFamilyDataGraphPropertiesARM");
        for (const auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            skip |= vo->PreCallValidateGetPhysicalDeviceQueueFamilyDataGraphPropertiesARM(
                physicalDevice, queueFamilyIndex, pQueueFamilyDataGraphPropertyCount, pQueueFamilyDataGraphProperties, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetPhysicalDeviceQueueFamilyDataGraphPropertiesARM);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetPhysicalDeviceQueueFamilyDataGraphPropertiesARM");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PreCallRecordGetPhysicalDeviceQueueFamilyDataGraphPropertiesARM(
                physicalDevice, queueFamilyIndex, pQueueFamilyDataGraphPropertyCount, pQueueFamilyDataGraphProperties, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkGetPhysicalDeviceQueueFamilyDataGraphPropertiesARM");
        result = instance_dispatch->GetPhysicalDeviceQueueFamilyDataGraphPropertiesARM(
            physicalDevice, queueFamilyIndex, pQueueFamilyDataGraphPropertyCount, pQueueFamilyDataGraphProperties);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetPhysicalDeviceQueueFamilyDataGraphPropertiesARM");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PostCallRecordGetPhysicalDeviceQueueFamilyDataGraphPropertiesARM(
                physicalDevice, queueFamilyIndex, pQueueFamilyDataGraphPropertyCount, pQueueFamilyDataGraphProperties, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR void VKAPI_CALL GetPhysicalDeviceQueueFamilyDataGraphProcessingEnginePropertiesARM(
    VkPhysicalDevice physicalDevice,
    const VkPhysicalDeviceQueueFamilyDataGraphProcessingEngineInfoARM* pQueueFamilyDataGraphProcessingEngineInfo,
    VkQueueFamilyDataGraphProcessingEnginePropertiesARM* pQueueFamilyDataGraphProcessingEngineProperties) {
    VVL_ZoneScoped;

    auto instance_dispatch = vvl::dispatch::GetData(physicalDevice);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetPhysicalDeviceQueueFamilyDataGraphProcessingEnginePropertiesARM,
                          VulkanTypedHandle(physicalDevice, kVulkanObjectTypePhysicalDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetPhysicalDeviceQueueFamilyDataGraphProcessingEnginePropertiesARM");
        for (const auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            skip |= vo->PreCallValidateGetPhysicalDeviceQueueFamilyDataGraphProcessingEnginePropertiesARM(
                physicalDevice, pQueueFamilyDataGraphProcessingEngineInfo, pQueueFamilyDataGraphProcessingEngineProperties,
                error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetPhysicalDeviceQueueFamilyDataGraphProcessingEnginePropertiesARM);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetPhysicalDeviceQueueFamilyDataGraphProcessingEnginePropertiesARM");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PreCallRecordGetPhysicalDeviceQueueFamilyDataGraphProcessingEnginePropertiesARM(
                physicalDevice, pQueueFamilyDataGraphProcessingEngineInfo, pQueueFamilyDataGraphProcessingEngineProperties,
                record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkGetPhysicalDeviceQueueFamilyDataGraphProcessingEnginePropertiesARM");
        instance_dispatch->GetPhysicalDeviceQueueFamilyDataGraphProcessingEnginePropertiesARM(
            physicalDevice, pQueueFamilyDataGraphProcessingEngineInfo, pQueueFamilyDataGraphProcessingEngineProperties);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetPhysicalDeviceQueueFamilyDataGraphProcessingEnginePropertiesARM");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PostCallRecordGetPhysicalDeviceQueueFamilyDataGraphProcessingEnginePropertiesARM(
                physicalDevice, pQueueFamilyDataGraphProcessingEngineInfo, pQueueFamilyDataGraphProcessingEngineProperties,
                record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdSetAttachmentFeedbackLoopEnableEXT(VkCommandBuffer commandBuffer, VkImageAspectFlags aspectMask) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdSetAttachmentFeedbackLoopEnableEXT,
                          VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdSetAttachmentFeedbackLoopEnableEXT");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdSetAttachmentFeedbackLoopEnableEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdSetAttachmentFeedbackLoopEnableEXT(commandBuffer, aspectMask, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdSetAttachmentFeedbackLoopEnableEXT);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdSetAttachmentFeedbackLoopEnableEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdSetAttachmentFeedbackLoopEnableEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdSetAttachmentFeedbackLoopEnableEXT(commandBuffer, aspectMask, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdSetAttachmentFeedbackLoopEnableEXT");
        device_dispatch->CmdSetAttachmentFeedbackLoopEnableEXT(commandBuffer, aspectMask);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdSetAttachmentFeedbackLoopEnableEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdSetAttachmentFeedbackLoopEnableEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdSetAttachmentFeedbackLoopEnableEXT(commandBuffer, aspectMask, record_obj);
        }
    }
}

#ifdef VK_USE_PLATFORM_SCREEN_QNX
VKAPI_ATTR VkResult VKAPI_CALL GetScreenBufferPropertiesQNX(VkDevice device, const struct _screen_buffer* buffer,
                                                            VkScreenBufferPropertiesQNX* pProperties) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetScreenBufferPropertiesQNX, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetScreenBufferPropertiesQNX");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateGetScreenBufferPropertiesQNX]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateGetScreenBufferPropertiesQNX(device, buffer, pProperties, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetScreenBufferPropertiesQNX);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetScreenBufferPropertiesQNX");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordGetScreenBufferPropertiesQNX]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordGetScreenBufferPropertiesQNX(device, buffer, pProperties, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkGetScreenBufferPropertiesQNX");
        result = device_dispatch->GetScreenBufferPropertiesQNX(device, buffer, pProperties);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetScreenBufferPropertiesQNX");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordGetScreenBufferPropertiesQNX]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordGetScreenBufferPropertiesQNX(device, buffer, pProperties, record_obj);
        }
    }
    return result;
}

#endif  // VK_USE_PLATFORM_SCREEN_QNX
VKAPI_ATTR void VKAPI_CALL CmdBindTileMemoryQCOM(VkCommandBuffer commandBuffer,
                                                 const VkTileMemoryBindInfoQCOM* pTileMemoryBindInfo) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdBindTileMemoryQCOM, VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdBindTileMemoryQCOM");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdBindTileMemoryQCOM]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdBindTileMemoryQCOM(commandBuffer, pTileMemoryBindInfo, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdBindTileMemoryQCOM);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdBindTileMemoryQCOM");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdBindTileMemoryQCOM]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdBindTileMemoryQCOM(commandBuffer, pTileMemoryBindInfo, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdBindTileMemoryQCOM");
        device_dispatch->CmdBindTileMemoryQCOM(commandBuffer, pTileMemoryBindInfo);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdBindTileMemoryQCOM");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdBindTileMemoryQCOM]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdBindTileMemoryQCOM(commandBuffer, pTileMemoryBindInfo, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdDecompressMemoryEXT(VkCommandBuffer commandBuffer,
                                                  const VkDecompressMemoryInfoEXT* pDecompressMemoryInfoEXT) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdDecompressMemoryEXT, VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdDecompressMemoryEXT");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdDecompressMemoryEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdDecompressMemoryEXT(commandBuffer, pDecompressMemoryInfoEXT, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdDecompressMemoryEXT);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdDecompressMemoryEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdDecompressMemoryEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdDecompressMemoryEXT(commandBuffer, pDecompressMemoryInfoEXT, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdDecompressMemoryEXT");
        device_dispatch->CmdDecompressMemoryEXT(commandBuffer, pDecompressMemoryInfoEXT);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdDecompressMemoryEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdDecompressMemoryEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdDecompressMemoryEXT(commandBuffer, pDecompressMemoryInfoEXT, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdDecompressMemoryIndirectCountEXT(VkCommandBuffer commandBuffer,
                                                               VkMemoryDecompressionMethodFlagsEXT decompressionMethod,
                                                               VkDeviceAddress indirectCommandsAddress,
                                                               VkDeviceAddress indirectCommandsCountAddress,
                                                               uint32_t maxDecompressionCount, uint32_t stride) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdDecompressMemoryIndirectCountEXT,
                          VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdDecompressMemoryIndirectCountEXT");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdDecompressMemoryIndirectCountEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdDecompressMemoryIndirectCountEXT(commandBuffer, decompressionMethod,
                                                                           indirectCommandsAddress, indirectCommandsCountAddress,
                                                                           maxDecompressionCount, stride, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdDecompressMemoryIndirectCountEXT);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdDecompressMemoryIndirectCountEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdDecompressMemoryIndirectCountEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdDecompressMemoryIndirectCountEXT(commandBuffer, decompressionMethod, indirectCommandsAddress,
                                                                 indirectCommandsCountAddress, maxDecompressionCount, stride,
                                                                 record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdDecompressMemoryIndirectCountEXT");
        device_dispatch->CmdDecompressMemoryIndirectCountEXT(commandBuffer, decompressionMethod, indirectCommandsAddress,
                                                             indirectCommandsCountAddress, maxDecompressionCount, stride);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdDecompressMemoryIndirectCountEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdDecompressMemoryIndirectCountEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdDecompressMemoryIndirectCountEXT(commandBuffer, decompressionMethod, indirectCommandsAddress,
                                                                  indirectCommandsCountAddress, maxDecompressionCount, stride,
                                                                  record_obj);
        }
    }
}

VKAPI_ATTR VkResult VKAPI_CALL CreateExternalComputeQueueNV(VkDevice device, const VkExternalComputeQueueCreateInfoNV* pCreateInfo,
                                                            const VkAllocationCallbacks* pAllocator,
                                                            VkExternalComputeQueueNV* pExternalQueue) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCreateExternalComputeQueueNV, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCreateExternalComputeQueueNV");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCreateExternalComputeQueueNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCreateExternalComputeQueueNV(device, pCreateInfo, pAllocator, pExternalQueue, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkCreateExternalComputeQueueNV);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCreateExternalComputeQueueNV");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCreateExternalComputeQueueNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCreateExternalComputeQueueNV(device, pCreateInfo, pAllocator, pExternalQueue, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkCreateExternalComputeQueueNV");
        result = device_dispatch->CreateExternalComputeQueueNV(device, pCreateInfo, pAllocator, pExternalQueue);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkCreateExternalComputeQueueNV");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCreateExternalComputeQueueNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCreateExternalComputeQueueNV(device, pCreateInfo, pAllocator, pExternalQueue, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR void VKAPI_CALL DestroyExternalComputeQueueNV(VkDevice device, VkExternalComputeQueueNV externalQueue,
                                                         const VkAllocationCallbacks* pAllocator) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkDestroyExternalComputeQueueNV, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkDestroyExternalComputeQueueNV");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateDestroyExternalComputeQueueNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateDestroyExternalComputeQueueNV(device, externalQueue, pAllocator, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkDestroyExternalComputeQueueNV);
    {
        VVL_ZoneScopedN("PreCallRecord_vkDestroyExternalComputeQueueNV");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordDestroyExternalComputeQueueNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordDestroyExternalComputeQueueNV(device, externalQueue, pAllocator, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkDestroyExternalComputeQueueNV");
        device_dispatch->DestroyExternalComputeQueueNV(device, externalQueue, pAllocator);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkDestroyExternalComputeQueueNV");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordDestroyExternalComputeQueueNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordDestroyExternalComputeQueueNV(device, externalQueue, pAllocator, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL GetExternalComputeQueueDataNV(VkExternalComputeQueueNV externalQueue,
                                                         VkExternalComputeQueueDataParamsNV* params, void* pData) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(externalQueue);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetExternalComputeQueueDataNV,
                          VulkanTypedHandle(externalQueue, kVulkanObjectTypeExternalComputeQueueNV));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetExternalComputeQueueDataNV");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateGetExternalComputeQueueDataNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateGetExternalComputeQueueDataNV(externalQueue, params, pData, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetExternalComputeQueueDataNV);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetExternalComputeQueueDataNV");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordGetExternalComputeQueueDataNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordGetExternalComputeQueueDataNV(externalQueue, params, pData, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkGetExternalComputeQueueDataNV");
        device_dispatch->GetExternalComputeQueueDataNV(externalQueue, params, pData);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetExternalComputeQueueDataNV");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordGetExternalComputeQueueDataNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordGetExternalComputeQueueDataNV(externalQueue, params, pData, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL GetClusterAccelerationStructureBuildSizesNV(VkDevice device,
                                                                       const VkClusterAccelerationStructureInputInfoNV* pInfo,
                                                                       VkAccelerationStructureBuildSizesInfoKHR* pSizeInfo) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetClusterAccelerationStructureBuildSizesNV,
                          VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetClusterAccelerationStructureBuildSizesNV");
        for (const auto& vo :
             device_dispatch->intercept_vectors[InterceptIdPreCallValidateGetClusterAccelerationStructureBuildSizesNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateGetClusterAccelerationStructureBuildSizesNV(device, pInfo, pSizeInfo, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetClusterAccelerationStructureBuildSizesNV);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetClusterAccelerationStructureBuildSizesNV");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordGetClusterAccelerationStructureBuildSizesNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordGetClusterAccelerationStructureBuildSizesNV(device, pInfo, pSizeInfo, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkGetClusterAccelerationStructureBuildSizesNV");
        device_dispatch->GetClusterAccelerationStructureBuildSizesNV(device, pInfo, pSizeInfo);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetClusterAccelerationStructureBuildSizesNV");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordGetClusterAccelerationStructureBuildSizesNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordGetClusterAccelerationStructureBuildSizesNV(device, pInfo, pSizeInfo, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdBuildClusterAccelerationStructureIndirectNV(
    VkCommandBuffer commandBuffer, const VkClusterAccelerationStructureCommandsInfoNV* pCommandInfos) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdBuildClusterAccelerationStructureIndirectNV,
                          VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdBuildClusterAccelerationStructureIndirectNV");
        for (const auto& vo :
             device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdBuildClusterAccelerationStructureIndirectNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdBuildClusterAccelerationStructureIndirectNV(commandBuffer, pCommandInfos, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdBuildClusterAccelerationStructureIndirectNV);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdBuildClusterAccelerationStructureIndirectNV");
        for (auto& vo :
             device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdBuildClusterAccelerationStructureIndirectNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdBuildClusterAccelerationStructureIndirectNV(commandBuffer, pCommandInfos, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdBuildClusterAccelerationStructureIndirectNV");
        device_dispatch->CmdBuildClusterAccelerationStructureIndirectNV(commandBuffer, pCommandInfos);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdBuildClusterAccelerationStructureIndirectNV");
        for (auto& vo :
             device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdBuildClusterAccelerationStructureIndirectNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdBuildClusterAccelerationStructureIndirectNV(commandBuffer, pCommandInfos, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL
GetPartitionedAccelerationStructuresBuildSizesNV(VkDevice device, const VkPartitionedAccelerationStructureInstancesInputNV* pInfo,
                                                 VkAccelerationStructureBuildSizesInfoKHR* pSizeInfo) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetPartitionedAccelerationStructuresBuildSizesNV,
                          VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetPartitionedAccelerationStructuresBuildSizesNV");
        for (const auto& vo :
             device_dispatch->intercept_vectors[InterceptIdPreCallValidateGetPartitionedAccelerationStructuresBuildSizesNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateGetPartitionedAccelerationStructuresBuildSizesNV(device, pInfo, pSizeInfo, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetPartitionedAccelerationStructuresBuildSizesNV);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetPartitionedAccelerationStructuresBuildSizesNV");
        for (auto& vo :
             device_dispatch->intercept_vectors[InterceptIdPreCallRecordGetPartitionedAccelerationStructuresBuildSizesNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordGetPartitionedAccelerationStructuresBuildSizesNV(device, pInfo, pSizeInfo, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkGetPartitionedAccelerationStructuresBuildSizesNV");
        device_dispatch->GetPartitionedAccelerationStructuresBuildSizesNV(device, pInfo, pSizeInfo);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetPartitionedAccelerationStructuresBuildSizesNV");
        for (auto& vo :
             device_dispatch->intercept_vectors[InterceptIdPostCallRecordGetPartitionedAccelerationStructuresBuildSizesNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordGetPartitionedAccelerationStructuresBuildSizesNV(device, pInfo, pSizeInfo, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdBuildPartitionedAccelerationStructuresNV(
    VkCommandBuffer commandBuffer, const VkBuildPartitionedAccelerationStructureInfoNV* pBuildInfo) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdBuildPartitionedAccelerationStructuresNV,
                          VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdBuildPartitionedAccelerationStructuresNV");
        for (const auto& vo :
             device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdBuildPartitionedAccelerationStructuresNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdBuildPartitionedAccelerationStructuresNV(commandBuffer, pBuildInfo, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdBuildPartitionedAccelerationStructuresNV);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdBuildPartitionedAccelerationStructuresNV");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdBuildPartitionedAccelerationStructuresNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdBuildPartitionedAccelerationStructuresNV(commandBuffer, pBuildInfo, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdBuildPartitionedAccelerationStructuresNV");
        device_dispatch->CmdBuildPartitionedAccelerationStructuresNV(commandBuffer, pBuildInfo);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdBuildPartitionedAccelerationStructuresNV");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdBuildPartitionedAccelerationStructuresNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdBuildPartitionedAccelerationStructuresNV(commandBuffer, pBuildInfo, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL GetGeneratedCommandsMemoryRequirementsEXT(VkDevice device,
                                                                     const VkGeneratedCommandsMemoryRequirementsInfoEXT* pInfo,
                                                                     VkMemoryRequirements2* pMemoryRequirements) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetGeneratedCommandsMemoryRequirementsEXT,
                          VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetGeneratedCommandsMemoryRequirementsEXT");
        for (const auto& vo :
             device_dispatch->intercept_vectors[InterceptIdPreCallValidateGetGeneratedCommandsMemoryRequirementsEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateGetGeneratedCommandsMemoryRequirementsEXT(device, pInfo, pMemoryRequirements, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetGeneratedCommandsMemoryRequirementsEXT);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetGeneratedCommandsMemoryRequirementsEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordGetGeneratedCommandsMemoryRequirementsEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordGetGeneratedCommandsMemoryRequirementsEXT(device, pInfo, pMemoryRequirements, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkGetGeneratedCommandsMemoryRequirementsEXT");
        device_dispatch->GetGeneratedCommandsMemoryRequirementsEXT(device, pInfo, pMemoryRequirements);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetGeneratedCommandsMemoryRequirementsEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordGetGeneratedCommandsMemoryRequirementsEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordGetGeneratedCommandsMemoryRequirementsEXT(device, pInfo, pMemoryRequirements, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdPreprocessGeneratedCommandsEXT(VkCommandBuffer commandBuffer,
                                                             const VkGeneratedCommandsInfoEXT* pGeneratedCommandsInfo,
                                                             VkCommandBuffer stateCommandBuffer) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdPreprocessGeneratedCommandsEXT,
                          VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdPreprocessGeneratedCommandsEXT");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdPreprocessGeneratedCommandsEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdPreprocessGeneratedCommandsEXT(commandBuffer, pGeneratedCommandsInfo, stateCommandBuffer,
                                                                         error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdPreprocessGeneratedCommandsEXT);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdPreprocessGeneratedCommandsEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdPreprocessGeneratedCommandsEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdPreprocessGeneratedCommandsEXT(commandBuffer, pGeneratedCommandsInfo, stateCommandBuffer,
                                                               record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdPreprocessGeneratedCommandsEXT");
        device_dispatch->CmdPreprocessGeneratedCommandsEXT(commandBuffer, pGeneratedCommandsInfo, stateCommandBuffer);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdPreprocessGeneratedCommandsEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdPreprocessGeneratedCommandsEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdPreprocessGeneratedCommandsEXT(commandBuffer, pGeneratedCommandsInfo, stateCommandBuffer,
                                                                record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdExecuteGeneratedCommandsEXT(VkCommandBuffer commandBuffer, VkBool32 isPreprocessed,
                                                          const VkGeneratedCommandsInfoEXT* pGeneratedCommandsInfo) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdExecuteGeneratedCommandsEXT,
                          VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdExecuteGeneratedCommandsEXT");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdExecuteGeneratedCommandsEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |=
                vo->PreCallValidateCmdExecuteGeneratedCommandsEXT(commandBuffer, isPreprocessed, pGeneratedCommandsInfo, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdExecuteGeneratedCommandsEXT);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdExecuteGeneratedCommandsEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdExecuteGeneratedCommandsEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdExecuteGeneratedCommandsEXT(commandBuffer, isPreprocessed, pGeneratedCommandsInfo, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdExecuteGeneratedCommandsEXT");
        device_dispatch->CmdExecuteGeneratedCommandsEXT(commandBuffer, isPreprocessed, pGeneratedCommandsInfo);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdExecuteGeneratedCommandsEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdExecuteGeneratedCommandsEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdExecuteGeneratedCommandsEXT(commandBuffer, isPreprocessed, pGeneratedCommandsInfo, record_obj);
        }
    }
}

VKAPI_ATTR VkResult VKAPI_CALL CreateIndirectCommandsLayoutEXT(VkDevice device,
                                                               const VkIndirectCommandsLayoutCreateInfoEXT* pCreateInfo,
                                                               const VkAllocationCallbacks* pAllocator,
                                                               VkIndirectCommandsLayoutEXT* pIndirectCommandsLayout) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCreateIndirectCommandsLayoutEXT, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCreateIndirectCommandsLayoutEXT");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCreateIndirectCommandsLayoutEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCreateIndirectCommandsLayoutEXT(device, pCreateInfo, pAllocator, pIndirectCommandsLayout,
                                                                       error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkCreateIndirectCommandsLayoutEXT);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCreateIndirectCommandsLayoutEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCreateIndirectCommandsLayoutEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCreateIndirectCommandsLayoutEXT(device, pCreateInfo, pAllocator, pIndirectCommandsLayout, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkCreateIndirectCommandsLayoutEXT");
        result = device_dispatch->CreateIndirectCommandsLayoutEXT(device, pCreateInfo, pAllocator, pIndirectCommandsLayout);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkCreateIndirectCommandsLayoutEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCreateIndirectCommandsLayoutEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCreateIndirectCommandsLayoutEXT(device, pCreateInfo, pAllocator, pIndirectCommandsLayout, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR void VKAPI_CALL DestroyIndirectCommandsLayoutEXT(VkDevice device, VkIndirectCommandsLayoutEXT indirectCommandsLayout,
                                                            const VkAllocationCallbacks* pAllocator) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkDestroyIndirectCommandsLayoutEXT, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkDestroyIndirectCommandsLayoutEXT");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateDestroyIndirectCommandsLayoutEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateDestroyIndirectCommandsLayoutEXT(device, indirectCommandsLayout, pAllocator, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkDestroyIndirectCommandsLayoutEXT);
    {
        VVL_ZoneScopedN("PreCallRecord_vkDestroyIndirectCommandsLayoutEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordDestroyIndirectCommandsLayoutEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordDestroyIndirectCommandsLayoutEXT(device, indirectCommandsLayout, pAllocator, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkDestroyIndirectCommandsLayoutEXT");
        device_dispatch->DestroyIndirectCommandsLayoutEXT(device, indirectCommandsLayout, pAllocator);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkDestroyIndirectCommandsLayoutEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordDestroyIndirectCommandsLayoutEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordDestroyIndirectCommandsLayoutEXT(device, indirectCommandsLayout, pAllocator, record_obj);
        }
    }
}

VKAPI_ATTR VkResult VKAPI_CALL CreateIndirectExecutionSetEXT(VkDevice device,
                                                             const VkIndirectExecutionSetCreateInfoEXT* pCreateInfo,
                                                             const VkAllocationCallbacks* pAllocator,
                                                             VkIndirectExecutionSetEXT* pIndirectExecutionSet) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCreateIndirectExecutionSetEXT, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCreateIndirectExecutionSetEXT");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCreateIndirectExecutionSetEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |=
                vo->PreCallValidateCreateIndirectExecutionSetEXT(device, pCreateInfo, pAllocator, pIndirectExecutionSet, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkCreateIndirectExecutionSetEXT);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCreateIndirectExecutionSetEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCreateIndirectExecutionSetEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCreateIndirectExecutionSetEXT(device, pCreateInfo, pAllocator, pIndirectExecutionSet, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkCreateIndirectExecutionSetEXT");
        result = device_dispatch->CreateIndirectExecutionSetEXT(device, pCreateInfo, pAllocator, pIndirectExecutionSet);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkCreateIndirectExecutionSetEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCreateIndirectExecutionSetEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCreateIndirectExecutionSetEXT(device, pCreateInfo, pAllocator, pIndirectExecutionSet, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR void VKAPI_CALL DestroyIndirectExecutionSetEXT(VkDevice device, VkIndirectExecutionSetEXT indirectExecutionSet,
                                                          const VkAllocationCallbacks* pAllocator) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkDestroyIndirectExecutionSetEXT, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkDestroyIndirectExecutionSetEXT");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateDestroyIndirectExecutionSetEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateDestroyIndirectExecutionSetEXT(device, indirectExecutionSet, pAllocator, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkDestroyIndirectExecutionSetEXT);
    {
        VVL_ZoneScopedN("PreCallRecord_vkDestroyIndirectExecutionSetEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordDestroyIndirectExecutionSetEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordDestroyIndirectExecutionSetEXT(device, indirectExecutionSet, pAllocator, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkDestroyIndirectExecutionSetEXT");
        device_dispatch->DestroyIndirectExecutionSetEXT(device, indirectExecutionSet, pAllocator);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkDestroyIndirectExecutionSetEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordDestroyIndirectExecutionSetEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordDestroyIndirectExecutionSetEXT(device, indirectExecutionSet, pAllocator, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL UpdateIndirectExecutionSetPipelineEXT(
    VkDevice device, VkIndirectExecutionSetEXT indirectExecutionSet, uint32_t executionSetWriteCount,
    const VkWriteIndirectExecutionSetPipelineEXT* pExecutionSetWrites) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkUpdateIndirectExecutionSetPipelineEXT, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkUpdateIndirectExecutionSetPipelineEXT");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateUpdateIndirectExecutionSetPipelineEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateUpdateIndirectExecutionSetPipelineEXT(device, indirectExecutionSet, executionSetWriteCount,
                                                                             pExecutionSetWrites, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkUpdateIndirectExecutionSetPipelineEXT);
    {
        VVL_ZoneScopedN("PreCallRecord_vkUpdateIndirectExecutionSetPipelineEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordUpdateIndirectExecutionSetPipelineEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordUpdateIndirectExecutionSetPipelineEXT(device, indirectExecutionSet, executionSetWriteCount,
                                                                   pExecutionSetWrites, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkUpdateIndirectExecutionSetPipelineEXT");
        device_dispatch->UpdateIndirectExecutionSetPipelineEXT(device, indirectExecutionSet, executionSetWriteCount,
                                                               pExecutionSetWrites);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkUpdateIndirectExecutionSetPipelineEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordUpdateIndirectExecutionSetPipelineEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordUpdateIndirectExecutionSetPipelineEXT(device, indirectExecutionSet, executionSetWriteCount,
                                                                    pExecutionSetWrites, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL UpdateIndirectExecutionSetShaderEXT(VkDevice device, VkIndirectExecutionSetEXT indirectExecutionSet,
                                                               uint32_t executionSetWriteCount,
                                                               const VkWriteIndirectExecutionSetShaderEXT* pExecutionSetWrites) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkUpdateIndirectExecutionSetShaderEXT, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkUpdateIndirectExecutionSetShaderEXT");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateUpdateIndirectExecutionSetShaderEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateUpdateIndirectExecutionSetShaderEXT(device, indirectExecutionSet, executionSetWriteCount,
                                                                           pExecutionSetWrites, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkUpdateIndirectExecutionSetShaderEXT);
    {
        VVL_ZoneScopedN("PreCallRecord_vkUpdateIndirectExecutionSetShaderEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordUpdateIndirectExecutionSetShaderEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordUpdateIndirectExecutionSetShaderEXT(device, indirectExecutionSet, executionSetWriteCount,
                                                                 pExecutionSetWrites, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkUpdateIndirectExecutionSetShaderEXT");
        device_dispatch->UpdateIndirectExecutionSetShaderEXT(device, indirectExecutionSet, executionSetWriteCount,
                                                             pExecutionSetWrites);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkUpdateIndirectExecutionSetShaderEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordUpdateIndirectExecutionSetShaderEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordUpdateIndirectExecutionSetShaderEXT(device, indirectExecutionSet, executionSetWriteCount,
                                                                  pExecutionSetWrites, record_obj);
        }
    }
}

#ifdef VK_USE_PLATFORM_OHOS
VKAPI_ATTR VkResult VKAPI_CALL CreateSurfaceOHOS(VkInstance instance, const VkSurfaceCreateInfoOHOS* pCreateInfo,
                                                 const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface) {
    VVL_ZoneScoped;

    auto instance_dispatch = vvl::dispatch::GetData(instance);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCreateSurfaceOHOS, VulkanTypedHandle(instance, kVulkanObjectTypeInstance));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCreateSurfaceOHOS");
        for (const auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            skip |= vo->PreCallValidateCreateSurfaceOHOS(instance, pCreateInfo, pAllocator, pSurface, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkCreateSurfaceOHOS);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCreateSurfaceOHOS");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PreCallRecordCreateSurfaceOHOS(instance, pCreateInfo, pAllocator, pSurface, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkCreateSurfaceOHOS");
        result = instance_dispatch->CreateSurfaceOHOS(instance, pCreateInfo, pAllocator, pSurface);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkCreateSurfaceOHOS");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PostCallRecordCreateSurfaceOHOS(instance, pCreateInfo, pAllocator, pSurface, record_obj);
        }
    }
    return result;
}

#endif  // VK_USE_PLATFORM_OHOS
VKAPI_ATTR VkResult VKAPI_CALL GetPhysicalDeviceCooperativeMatrixFlexibleDimensionsPropertiesNV(
    VkPhysicalDevice physicalDevice, uint32_t* pPropertyCount, VkCooperativeMatrixFlexibleDimensionsPropertiesNV* pProperties) {
    VVL_ZoneScoped;

    auto instance_dispatch = vvl::dispatch::GetData(physicalDevice);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetPhysicalDeviceCooperativeMatrixFlexibleDimensionsPropertiesNV,
                          VulkanTypedHandle(physicalDevice, kVulkanObjectTypePhysicalDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetPhysicalDeviceCooperativeMatrixFlexibleDimensionsPropertiesNV");
        for (const auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            skip |= vo->PreCallValidateGetPhysicalDeviceCooperativeMatrixFlexibleDimensionsPropertiesNV(
                physicalDevice, pPropertyCount, pProperties, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetPhysicalDeviceCooperativeMatrixFlexibleDimensionsPropertiesNV);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetPhysicalDeviceCooperativeMatrixFlexibleDimensionsPropertiesNV");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PreCallRecordGetPhysicalDeviceCooperativeMatrixFlexibleDimensionsPropertiesNV(physicalDevice, pPropertyCount,
                                                                                              pProperties, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkGetPhysicalDeviceCooperativeMatrixFlexibleDimensionsPropertiesNV");
        result = instance_dispatch->GetPhysicalDeviceCooperativeMatrixFlexibleDimensionsPropertiesNV(physicalDevice, pPropertyCount,
                                                                                                     pProperties);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetPhysicalDeviceCooperativeMatrixFlexibleDimensionsPropertiesNV");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PostCallRecordGetPhysicalDeviceCooperativeMatrixFlexibleDimensionsPropertiesNV(physicalDevice, pPropertyCount,
                                                                                               pProperties, record_obj);
        }
    }
    return result;
}

#ifdef VK_USE_PLATFORM_METAL_EXT
VKAPI_ATTR VkResult VKAPI_CALL GetMemoryMetalHandleEXT(VkDevice device, const VkMemoryGetMetalHandleInfoEXT* pGetMetalHandleInfo,
                                                       void** pHandle) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetMemoryMetalHandleEXT, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetMemoryMetalHandleEXT");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateGetMemoryMetalHandleEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateGetMemoryMetalHandleEXT(device, pGetMetalHandleInfo, pHandle, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetMemoryMetalHandleEXT);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetMemoryMetalHandleEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordGetMemoryMetalHandleEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordGetMemoryMetalHandleEXT(device, pGetMetalHandleInfo, pHandle, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkGetMemoryMetalHandleEXT");
        result = device_dispatch->GetMemoryMetalHandleEXT(device, pGetMetalHandleInfo, pHandle);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetMemoryMetalHandleEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordGetMemoryMetalHandleEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordGetMemoryMetalHandleEXT(device, pGetMetalHandleInfo, pHandle, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR VkResult VKAPI_CALL GetMemoryMetalHandlePropertiesEXT(VkDevice device, VkExternalMemoryHandleTypeFlagBits handleType,
                                                                 const void* pHandle,
                                                                 VkMemoryMetalHandlePropertiesEXT* pMemoryMetalHandleProperties) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetMemoryMetalHandlePropertiesEXT, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetMemoryMetalHandlePropertiesEXT");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateGetMemoryMetalHandlePropertiesEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateGetMemoryMetalHandlePropertiesEXT(device, handleType, pHandle, pMemoryMetalHandleProperties,
                                                                         error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetMemoryMetalHandlePropertiesEXT);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetMemoryMetalHandlePropertiesEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordGetMemoryMetalHandlePropertiesEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordGetMemoryMetalHandlePropertiesEXT(device, handleType, pHandle, pMemoryMetalHandleProperties,
                                                               record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkGetMemoryMetalHandlePropertiesEXT");
        result = device_dispatch->GetMemoryMetalHandlePropertiesEXT(device, handleType, pHandle, pMemoryMetalHandleProperties);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetMemoryMetalHandlePropertiesEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordGetMemoryMetalHandlePropertiesEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordGetMemoryMetalHandlePropertiesEXT(device, handleType, pHandle, pMemoryMetalHandleProperties,
                                                                record_obj);
        }
    }
    return result;
}

#endif  // VK_USE_PLATFORM_METAL_EXT
VKAPI_ATTR VkResult VKAPI_CALL EnumeratePhysicalDeviceQueueFamilyPerformanceCountersByRegionARM(
    VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex, uint32_t* pCounterCount, VkPerformanceCounterARM* pCounters,
    VkPerformanceCounterDescriptionARM* pCounterDescriptions) {
    VVL_ZoneScoped;

    auto instance_dispatch = vvl::dispatch::GetData(physicalDevice);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkEnumeratePhysicalDeviceQueueFamilyPerformanceCountersByRegionARM,
                          VulkanTypedHandle(physicalDevice, kVulkanObjectTypePhysicalDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkEnumeratePhysicalDeviceQueueFamilyPerformanceCountersByRegionARM");
        for (const auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            skip |= vo->PreCallValidateEnumeratePhysicalDeviceQueueFamilyPerformanceCountersByRegionARM(
                physicalDevice, queueFamilyIndex, pCounterCount, pCounters, pCounterDescriptions, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkEnumeratePhysicalDeviceQueueFamilyPerformanceCountersByRegionARM);
    {
        VVL_ZoneScopedN("PreCallRecord_vkEnumeratePhysicalDeviceQueueFamilyPerformanceCountersByRegionARM");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PreCallRecordEnumeratePhysicalDeviceQueueFamilyPerformanceCountersByRegionARM(
                physicalDevice, queueFamilyIndex, pCounterCount, pCounters, pCounterDescriptions, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkEnumeratePhysicalDeviceQueueFamilyPerformanceCountersByRegionARM");
        result = instance_dispatch->EnumeratePhysicalDeviceQueueFamilyPerformanceCountersByRegionARM(
            physicalDevice, queueFamilyIndex, pCounterCount, pCounters, pCounterDescriptions);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkEnumeratePhysicalDeviceQueueFamilyPerformanceCountersByRegionARM");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PostCallRecordEnumeratePhysicalDeviceQueueFamilyPerformanceCountersByRegionARM(
                physicalDevice, queueFamilyIndex, pCounterCount, pCounters, pCounterDescriptions, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR void VKAPI_CALL CmdEndRendering2EXT(VkCommandBuffer commandBuffer, const VkRenderingEndInfoKHR* pRenderingEndInfo) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdEndRendering2EXT, VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdEndRendering2EXT");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdEndRendering2EXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdEndRendering2EXT(commandBuffer, pRenderingEndInfo, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdEndRendering2EXT);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdEndRendering2EXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdEndRendering2EXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdEndRendering2EXT(commandBuffer, pRenderingEndInfo, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdEndRendering2EXT");
        device_dispatch->CmdEndRendering2EXT(commandBuffer, pRenderingEndInfo);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdEndRendering2EXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdEndRendering2EXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdEndRendering2EXT(commandBuffer, pRenderingEndInfo, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdBeginCustomResolveEXT(VkCommandBuffer commandBuffer,
                                                    const VkBeginCustomResolveInfoEXT* pBeginCustomResolveInfo) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdBeginCustomResolveEXT, VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdBeginCustomResolveEXT");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdBeginCustomResolveEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdBeginCustomResolveEXT(commandBuffer, pBeginCustomResolveInfo, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdBeginCustomResolveEXT);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdBeginCustomResolveEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdBeginCustomResolveEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdBeginCustomResolveEXT(commandBuffer, pBeginCustomResolveInfo, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdBeginCustomResolveEXT");
        device_dispatch->CmdBeginCustomResolveEXT(commandBuffer, pBeginCustomResolveInfo);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdBeginCustomResolveEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdBeginCustomResolveEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdBeginCustomResolveEXT(commandBuffer, pBeginCustomResolveInfo, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdSetComputeOccupancyPriorityNV(VkCommandBuffer commandBuffer,
                                                            const VkComputeOccupancyPriorityParametersNV* pParameters) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdSetComputeOccupancyPriorityNV,
                          VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdSetComputeOccupancyPriorityNV");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdSetComputeOccupancyPriorityNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdSetComputeOccupancyPriorityNV(commandBuffer, pParameters, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdSetComputeOccupancyPriorityNV);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdSetComputeOccupancyPriorityNV");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdSetComputeOccupancyPriorityNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdSetComputeOccupancyPriorityNV(commandBuffer, pParameters, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdSetComputeOccupancyPriorityNV");
        device_dispatch->CmdSetComputeOccupancyPriorityNV(commandBuffer, pParameters);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdSetComputeOccupancyPriorityNV");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdSetComputeOccupancyPriorityNV]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdSetComputeOccupancyPriorityNV(commandBuffer, pParameters, record_obj);
        }
    }
}

#ifdef VK_USE_PLATFORM_UBM_SEC
VKAPI_ATTR VkResult VKAPI_CALL CreateUbmSurfaceSEC(VkInstance instance, const VkUbmSurfaceCreateInfoSEC* pCreateInfo,
                                                   const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface) {
    VVL_ZoneScoped;

    auto instance_dispatch = vvl::dispatch::GetData(instance);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCreateUbmSurfaceSEC, VulkanTypedHandle(instance, kVulkanObjectTypeInstance));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCreateUbmSurfaceSEC");
        for (const auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            skip |= vo->PreCallValidateCreateUbmSurfaceSEC(instance, pCreateInfo, pAllocator, pSurface, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkCreateUbmSurfaceSEC);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCreateUbmSurfaceSEC");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PreCallRecordCreateUbmSurfaceSEC(instance, pCreateInfo, pAllocator, pSurface, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkCreateUbmSurfaceSEC");
        result = instance_dispatch->CreateUbmSurfaceSEC(instance, pCreateInfo, pAllocator, pSurface);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkCreateUbmSurfaceSEC");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PostCallRecordCreateUbmSurfaceSEC(instance, pCreateInfo, pAllocator, pSurface, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR VkBool32 VKAPI_CALL GetPhysicalDeviceUbmPresentationSupportSEC(VkPhysicalDevice physicalDevice,
                                                                          uint32_t queueFamilyIndex, struct ubm_device* device) {
    VVL_ZoneScoped;

    auto instance_dispatch = vvl::dispatch::GetData(physicalDevice);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetPhysicalDeviceUbmPresentationSupportSEC,
                          VulkanTypedHandle(physicalDevice, kVulkanObjectTypePhysicalDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetPhysicalDeviceUbmPresentationSupportSEC");
        for (const auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            skip |=
                vo->PreCallValidateGetPhysicalDeviceUbmPresentationSupportSEC(physicalDevice, queueFamilyIndex, device, error_obj);
            if (skip) return VK_FALSE;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetPhysicalDeviceUbmPresentationSupportSEC);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetPhysicalDeviceUbmPresentationSupportSEC");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PreCallRecordGetPhysicalDeviceUbmPresentationSupportSEC(physicalDevice, queueFamilyIndex, device, record_obj);
        }
    }
    VkBool32 result;
    {
        VVL_ZoneScopedN("Dispatch_vkGetPhysicalDeviceUbmPresentationSupportSEC");
        result = instance_dispatch->GetPhysicalDeviceUbmPresentationSupportSEC(physicalDevice, queueFamilyIndex, device);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetPhysicalDeviceUbmPresentationSupportSEC");
        for (auto& vo : instance_dispatch->object_dispatch) {
            if (!vo) {
                continue;
            }
            vo->PostCallRecordGetPhysicalDeviceUbmPresentationSupportSEC(physicalDevice, queueFamilyIndex, device, record_obj);
        }
    }
    return result;
}

#endif  // VK_USE_PLATFORM_UBM_SEC
VKAPI_ATTR VkResult VKAPI_CALL CreateAccelerationStructureKHR(VkDevice device,
                                                              const VkAccelerationStructureCreateInfoKHR* pCreateInfo,
                                                              const VkAllocationCallbacks* pAllocator,
                                                              VkAccelerationStructureKHR* pAccelerationStructure) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCreateAccelerationStructureKHR, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCreateAccelerationStructureKHR");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCreateAccelerationStructureKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCreateAccelerationStructureKHR(device, pCreateInfo, pAllocator, pAccelerationStructure,
                                                                      error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkCreateAccelerationStructureKHR);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCreateAccelerationStructureKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCreateAccelerationStructureKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCreateAccelerationStructureKHR(device, pCreateInfo, pAllocator, pAccelerationStructure, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkCreateAccelerationStructureKHR");
        result = device_dispatch->CreateAccelerationStructureKHR(device, pCreateInfo, pAllocator, pAccelerationStructure);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkCreateAccelerationStructureKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCreateAccelerationStructureKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCreateAccelerationStructureKHR(device, pCreateInfo, pAllocator, pAccelerationStructure, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR void VKAPI_CALL DestroyAccelerationStructureKHR(VkDevice device, VkAccelerationStructureKHR accelerationStructure,
                                                           const VkAllocationCallbacks* pAllocator) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkDestroyAccelerationStructureKHR, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkDestroyAccelerationStructureKHR");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateDestroyAccelerationStructureKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateDestroyAccelerationStructureKHR(device, accelerationStructure, pAllocator, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkDestroyAccelerationStructureKHR);
    {
        VVL_ZoneScopedN("PreCallRecord_vkDestroyAccelerationStructureKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordDestroyAccelerationStructureKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordDestroyAccelerationStructureKHR(device, accelerationStructure, pAllocator, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkDestroyAccelerationStructureKHR");
        device_dispatch->DestroyAccelerationStructureKHR(device, accelerationStructure, pAllocator);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkDestroyAccelerationStructureKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordDestroyAccelerationStructureKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordDestroyAccelerationStructureKHR(device, accelerationStructure, pAllocator, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdBuildAccelerationStructuresKHR(
    VkCommandBuffer commandBuffer, uint32_t infoCount, const VkAccelerationStructureBuildGeometryInfoKHR* pInfos,
    const VkAccelerationStructureBuildRangeInfoKHR* const* ppBuildRangeInfos) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdBuildAccelerationStructuresKHR,
                          VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdBuildAccelerationStructuresKHR");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdBuildAccelerationStructuresKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdBuildAccelerationStructuresKHR(commandBuffer, infoCount, pInfos, ppBuildRangeInfos,
                                                                         error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdBuildAccelerationStructuresKHR);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdBuildAccelerationStructuresKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdBuildAccelerationStructuresKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdBuildAccelerationStructuresKHR(commandBuffer, infoCount, pInfos, ppBuildRangeInfos, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdBuildAccelerationStructuresKHR");
        device_dispatch->CmdBuildAccelerationStructuresKHR(commandBuffer, infoCount, pInfos, ppBuildRangeInfos);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdBuildAccelerationStructuresKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdBuildAccelerationStructuresKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdBuildAccelerationStructuresKHR(commandBuffer, infoCount, pInfos, ppBuildRangeInfos, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdBuildAccelerationStructuresIndirectKHR(VkCommandBuffer commandBuffer, uint32_t infoCount,
                                                                     const VkAccelerationStructureBuildGeometryInfoKHR* pInfos,
                                                                     const VkDeviceAddress* pIndirectDeviceAddresses,
                                                                     const uint32_t* pIndirectStrides,
                                                                     const uint32_t* const* ppMaxPrimitiveCounts) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdBuildAccelerationStructuresIndirectKHR,
                          VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdBuildAccelerationStructuresIndirectKHR");
        for (const auto& vo :
             device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdBuildAccelerationStructuresIndirectKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdBuildAccelerationStructuresIndirectKHR(
                commandBuffer, infoCount, pInfos, pIndirectDeviceAddresses, pIndirectStrides, ppMaxPrimitiveCounts, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdBuildAccelerationStructuresIndirectKHR);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdBuildAccelerationStructuresIndirectKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdBuildAccelerationStructuresIndirectKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdBuildAccelerationStructuresIndirectKHR(commandBuffer, infoCount, pInfos, pIndirectDeviceAddresses,
                                                                       pIndirectStrides, ppMaxPrimitiveCounts, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdBuildAccelerationStructuresIndirectKHR");
        device_dispatch->CmdBuildAccelerationStructuresIndirectKHR(commandBuffer, infoCount, pInfos, pIndirectDeviceAddresses,
                                                                   pIndirectStrides, ppMaxPrimitiveCounts);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdBuildAccelerationStructuresIndirectKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdBuildAccelerationStructuresIndirectKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdBuildAccelerationStructuresIndirectKHR(commandBuffer, infoCount, pInfos, pIndirectDeviceAddresses,
                                                                        pIndirectStrides, ppMaxPrimitiveCounts, record_obj);
        }
    }
}

VKAPI_ATTR VkResult VKAPI_CALL
BuildAccelerationStructuresKHR(VkDevice device, VkDeferredOperationKHR deferredOperation, uint32_t infoCount,
                               const VkAccelerationStructureBuildGeometryInfoKHR* pInfos,
                               const VkAccelerationStructureBuildRangeInfoKHR* const* ppBuildRangeInfos) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkBuildAccelerationStructuresKHR, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkBuildAccelerationStructuresKHR");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateBuildAccelerationStructuresKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateBuildAccelerationStructuresKHR(device, deferredOperation, infoCount, pInfos,
                                                                      ppBuildRangeInfos, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkBuildAccelerationStructuresKHR);
    {
        VVL_ZoneScopedN("PreCallRecord_vkBuildAccelerationStructuresKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordBuildAccelerationStructuresKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordBuildAccelerationStructuresKHR(device, deferredOperation, infoCount, pInfos, ppBuildRangeInfos,
                                                            record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkBuildAccelerationStructuresKHR");
        result = device_dispatch->BuildAccelerationStructuresKHR(device, deferredOperation, infoCount, pInfos, ppBuildRangeInfos);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkBuildAccelerationStructuresKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordBuildAccelerationStructuresKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordBuildAccelerationStructuresKHR(device, deferredOperation, infoCount, pInfos, ppBuildRangeInfos,
                                                             record_obj);
        }
    }
    return result;
}

VKAPI_ATTR VkResult VKAPI_CALL CopyAccelerationStructureKHR(VkDevice device, VkDeferredOperationKHR deferredOperation,
                                                            const VkCopyAccelerationStructureInfoKHR* pInfo) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCopyAccelerationStructureKHR, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCopyAccelerationStructureKHR");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCopyAccelerationStructureKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCopyAccelerationStructureKHR(device, deferredOperation, pInfo, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkCopyAccelerationStructureKHR);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCopyAccelerationStructureKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCopyAccelerationStructureKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCopyAccelerationStructureKHR(device, deferredOperation, pInfo, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkCopyAccelerationStructureKHR");
        result = device_dispatch->CopyAccelerationStructureKHR(device, deferredOperation, pInfo);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkCopyAccelerationStructureKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCopyAccelerationStructureKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCopyAccelerationStructureKHR(device, deferredOperation, pInfo, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR VkResult VKAPI_CALL CopyAccelerationStructureToMemoryKHR(VkDevice device, VkDeferredOperationKHR deferredOperation,
                                                                    const VkCopyAccelerationStructureToMemoryInfoKHR* pInfo) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCopyAccelerationStructureToMemoryKHR, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCopyAccelerationStructureToMemoryKHR");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCopyAccelerationStructureToMemoryKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCopyAccelerationStructureToMemoryKHR(device, deferredOperation, pInfo, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkCopyAccelerationStructureToMemoryKHR);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCopyAccelerationStructureToMemoryKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCopyAccelerationStructureToMemoryKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCopyAccelerationStructureToMemoryKHR(device, deferredOperation, pInfo, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkCopyAccelerationStructureToMemoryKHR");
        result = device_dispatch->CopyAccelerationStructureToMemoryKHR(device, deferredOperation, pInfo);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkCopyAccelerationStructureToMemoryKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCopyAccelerationStructureToMemoryKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCopyAccelerationStructureToMemoryKHR(device, deferredOperation, pInfo, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR VkResult VKAPI_CALL CopyMemoryToAccelerationStructureKHR(VkDevice device, VkDeferredOperationKHR deferredOperation,
                                                                    const VkCopyMemoryToAccelerationStructureInfoKHR* pInfo) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCopyMemoryToAccelerationStructureKHR, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCopyMemoryToAccelerationStructureKHR");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCopyMemoryToAccelerationStructureKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCopyMemoryToAccelerationStructureKHR(device, deferredOperation, pInfo, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkCopyMemoryToAccelerationStructureKHR);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCopyMemoryToAccelerationStructureKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCopyMemoryToAccelerationStructureKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCopyMemoryToAccelerationStructureKHR(device, deferredOperation, pInfo, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkCopyMemoryToAccelerationStructureKHR");
        result = device_dispatch->CopyMemoryToAccelerationStructureKHR(device, deferredOperation, pInfo);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkCopyMemoryToAccelerationStructureKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCopyMemoryToAccelerationStructureKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCopyMemoryToAccelerationStructureKHR(device, deferredOperation, pInfo, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR VkResult VKAPI_CALL WriteAccelerationStructuresPropertiesKHR(VkDevice device, uint32_t accelerationStructureCount,
                                                                        const VkAccelerationStructureKHR* pAccelerationStructures,
                                                                        VkQueryType queryType, size_t dataSize, void* pData,
                                                                        size_t stride) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkWriteAccelerationStructuresPropertiesKHR,
                          VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkWriteAccelerationStructuresPropertiesKHR");
        for (const auto& vo :
             device_dispatch->intercept_vectors[InterceptIdPreCallValidateWriteAccelerationStructuresPropertiesKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateWriteAccelerationStructuresPropertiesKHR(
                device, accelerationStructureCount, pAccelerationStructures, queryType, dataSize, pData, stride, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkWriteAccelerationStructuresPropertiesKHR);
    {
        VVL_ZoneScopedN("PreCallRecord_vkWriteAccelerationStructuresPropertiesKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordWriteAccelerationStructuresPropertiesKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordWriteAccelerationStructuresPropertiesKHR(device, accelerationStructureCount, pAccelerationStructures,
                                                                      queryType, dataSize, pData, stride, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkWriteAccelerationStructuresPropertiesKHR");
        result = device_dispatch->WriteAccelerationStructuresPropertiesKHR(
            device, accelerationStructureCount, pAccelerationStructures, queryType, dataSize, pData, stride);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkWriteAccelerationStructuresPropertiesKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordWriteAccelerationStructuresPropertiesKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordWriteAccelerationStructuresPropertiesKHR(device, accelerationStructureCount, pAccelerationStructures,
                                                                       queryType, dataSize, pData, stride, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR void VKAPI_CALL CmdCopyAccelerationStructureKHR(VkCommandBuffer commandBuffer,
                                                           const VkCopyAccelerationStructureInfoKHR* pInfo) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdCopyAccelerationStructureKHR,
                          VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdCopyAccelerationStructureKHR");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdCopyAccelerationStructureKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdCopyAccelerationStructureKHR(commandBuffer, pInfo, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdCopyAccelerationStructureKHR);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdCopyAccelerationStructureKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdCopyAccelerationStructureKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdCopyAccelerationStructureKHR(commandBuffer, pInfo, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdCopyAccelerationStructureKHR");
        device_dispatch->CmdCopyAccelerationStructureKHR(commandBuffer, pInfo);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdCopyAccelerationStructureKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdCopyAccelerationStructureKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdCopyAccelerationStructureKHR(commandBuffer, pInfo, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdCopyAccelerationStructureToMemoryKHR(VkCommandBuffer commandBuffer,
                                                                   const VkCopyAccelerationStructureToMemoryInfoKHR* pInfo) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdCopyAccelerationStructureToMemoryKHR,
                          VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdCopyAccelerationStructureToMemoryKHR");
        for (const auto& vo :
             device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdCopyAccelerationStructureToMemoryKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdCopyAccelerationStructureToMemoryKHR(commandBuffer, pInfo, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdCopyAccelerationStructureToMemoryKHR);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdCopyAccelerationStructureToMemoryKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdCopyAccelerationStructureToMemoryKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdCopyAccelerationStructureToMemoryKHR(commandBuffer, pInfo, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdCopyAccelerationStructureToMemoryKHR");
        device_dispatch->CmdCopyAccelerationStructureToMemoryKHR(commandBuffer, pInfo);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdCopyAccelerationStructureToMemoryKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdCopyAccelerationStructureToMemoryKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdCopyAccelerationStructureToMemoryKHR(commandBuffer, pInfo, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdCopyMemoryToAccelerationStructureKHR(VkCommandBuffer commandBuffer,
                                                                   const VkCopyMemoryToAccelerationStructureInfoKHR* pInfo) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdCopyMemoryToAccelerationStructureKHR,
                          VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdCopyMemoryToAccelerationStructureKHR");
        for (const auto& vo :
             device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdCopyMemoryToAccelerationStructureKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdCopyMemoryToAccelerationStructureKHR(commandBuffer, pInfo, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdCopyMemoryToAccelerationStructureKHR);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdCopyMemoryToAccelerationStructureKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdCopyMemoryToAccelerationStructureKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdCopyMemoryToAccelerationStructureKHR(commandBuffer, pInfo, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdCopyMemoryToAccelerationStructureKHR");
        device_dispatch->CmdCopyMemoryToAccelerationStructureKHR(commandBuffer, pInfo);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdCopyMemoryToAccelerationStructureKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdCopyMemoryToAccelerationStructureKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdCopyMemoryToAccelerationStructureKHR(commandBuffer, pInfo, record_obj);
        }
    }
}

VKAPI_ATTR VkDeviceAddress VKAPI_CALL
GetAccelerationStructureDeviceAddressKHR(VkDevice device, const VkAccelerationStructureDeviceAddressInfoKHR* pInfo) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetAccelerationStructureDeviceAddressKHR,
                          VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetAccelerationStructureDeviceAddressKHR");
        for (const auto& vo :
             device_dispatch->intercept_vectors[InterceptIdPreCallValidateGetAccelerationStructureDeviceAddressKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateGetAccelerationStructureDeviceAddressKHR(device, pInfo, error_obj);
            if (skip) return 0;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetAccelerationStructureDeviceAddressKHR);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetAccelerationStructureDeviceAddressKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordGetAccelerationStructureDeviceAddressKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordGetAccelerationStructureDeviceAddressKHR(device, pInfo, record_obj);
        }
    }
    VkDeviceAddress result;
    {
        VVL_ZoneScopedN("Dispatch_vkGetAccelerationStructureDeviceAddressKHR");
        result = device_dispatch->GetAccelerationStructureDeviceAddressKHR(device, pInfo);
    }
    record_obj.device_address = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetAccelerationStructureDeviceAddressKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordGetAccelerationStructureDeviceAddressKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordGetAccelerationStructureDeviceAddressKHR(device, pInfo, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR void VKAPI_CALL CmdWriteAccelerationStructuresPropertiesKHR(VkCommandBuffer commandBuffer,
                                                                       uint32_t accelerationStructureCount,
                                                                       const VkAccelerationStructureKHR* pAccelerationStructures,
                                                                       VkQueryType queryType, VkQueryPool queryPool,
                                                                       uint32_t firstQuery) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdWriteAccelerationStructuresPropertiesKHR,
                          VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdWriteAccelerationStructuresPropertiesKHR");
        for (const auto& vo :
             device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdWriteAccelerationStructuresPropertiesKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdWriteAccelerationStructuresPropertiesKHR(
                commandBuffer, accelerationStructureCount, pAccelerationStructures, queryType, queryPool, firstQuery, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdWriteAccelerationStructuresPropertiesKHR);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdWriteAccelerationStructuresPropertiesKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdWriteAccelerationStructuresPropertiesKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdWriteAccelerationStructuresPropertiesKHR(
                commandBuffer, accelerationStructureCount, pAccelerationStructures, queryType, queryPool, firstQuery, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdWriteAccelerationStructuresPropertiesKHR");
        device_dispatch->CmdWriteAccelerationStructuresPropertiesKHR(commandBuffer, accelerationStructureCount,
                                                                     pAccelerationStructures, queryType, queryPool, firstQuery);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdWriteAccelerationStructuresPropertiesKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdWriteAccelerationStructuresPropertiesKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdWriteAccelerationStructuresPropertiesKHR(
                commandBuffer, accelerationStructureCount, pAccelerationStructures, queryType, queryPool, firstQuery, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL GetDeviceAccelerationStructureCompatibilityKHR(VkDevice device,
                                                                          const VkAccelerationStructureVersionInfoKHR* pVersionInfo,
                                                                          VkAccelerationStructureCompatibilityKHR* pCompatibility) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetDeviceAccelerationStructureCompatibilityKHR,
                          VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetDeviceAccelerationStructureCompatibilityKHR");
        for (const auto& vo :
             device_dispatch->intercept_vectors[InterceptIdPreCallValidateGetDeviceAccelerationStructureCompatibilityKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |=
                vo->PreCallValidateGetDeviceAccelerationStructureCompatibilityKHR(device, pVersionInfo, pCompatibility, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetDeviceAccelerationStructureCompatibilityKHR);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetDeviceAccelerationStructureCompatibilityKHR");
        for (auto& vo :
             device_dispatch->intercept_vectors[InterceptIdPreCallRecordGetDeviceAccelerationStructureCompatibilityKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordGetDeviceAccelerationStructureCompatibilityKHR(device, pVersionInfo, pCompatibility, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkGetDeviceAccelerationStructureCompatibilityKHR");
        device_dispatch->GetDeviceAccelerationStructureCompatibilityKHR(device, pVersionInfo, pCompatibility);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetDeviceAccelerationStructureCompatibilityKHR");
        for (auto& vo :
             device_dispatch->intercept_vectors[InterceptIdPostCallRecordGetDeviceAccelerationStructureCompatibilityKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordGetDeviceAccelerationStructureCompatibilityKHR(device, pVersionInfo, pCompatibility, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL GetAccelerationStructureBuildSizesKHR(VkDevice device, VkAccelerationStructureBuildTypeKHR buildType,
                                                                 const VkAccelerationStructureBuildGeometryInfoKHR* pBuildInfo,
                                                                 const uint32_t* pMaxPrimitiveCounts,
                                                                 VkAccelerationStructureBuildSizesInfoKHR* pSizeInfo) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetAccelerationStructureBuildSizesKHR, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetAccelerationStructureBuildSizesKHR");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateGetAccelerationStructureBuildSizesKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateGetAccelerationStructureBuildSizesKHR(device, buildType, pBuildInfo, pMaxPrimitiveCounts,
                                                                             pSizeInfo, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetAccelerationStructureBuildSizesKHR);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetAccelerationStructureBuildSizesKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordGetAccelerationStructureBuildSizesKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordGetAccelerationStructureBuildSizesKHR(device, buildType, pBuildInfo, pMaxPrimitiveCounts, pSizeInfo,
                                                                   record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkGetAccelerationStructureBuildSizesKHR");
        device_dispatch->GetAccelerationStructureBuildSizesKHR(device, buildType, pBuildInfo, pMaxPrimitiveCounts, pSizeInfo);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetAccelerationStructureBuildSizesKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordGetAccelerationStructureBuildSizesKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordGetAccelerationStructureBuildSizesKHR(device, buildType, pBuildInfo, pMaxPrimitiveCounts, pSizeInfo,
                                                                    record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdTraceRaysKHR(VkCommandBuffer commandBuffer,
                                           const VkStridedDeviceAddressRegionKHR* pRaygenShaderBindingTable,
                                           const VkStridedDeviceAddressRegionKHR* pMissShaderBindingTable,
                                           const VkStridedDeviceAddressRegionKHR* pHitShaderBindingTable,
                                           const VkStridedDeviceAddressRegionKHR* pCallableShaderBindingTable, uint32_t width,
                                           uint32_t height, uint32_t depth) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdTraceRaysKHR, VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdTraceRaysKHR");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdTraceRaysKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdTraceRaysKHR(commandBuffer, pRaygenShaderBindingTable, pMissShaderBindingTable,
                                                       pHitShaderBindingTable, pCallableShaderBindingTable, width, height, depth,
                                                       error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdTraceRaysKHR);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdTraceRaysKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdTraceRaysKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdTraceRaysKHR(commandBuffer, pRaygenShaderBindingTable, pMissShaderBindingTable,
                                             pHitShaderBindingTable, pCallableShaderBindingTable, width, height, depth, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdTraceRaysKHR");
        device_dispatch->CmdTraceRaysKHR(commandBuffer, pRaygenShaderBindingTable, pMissShaderBindingTable, pHitShaderBindingTable,
                                         pCallableShaderBindingTable, width, height, depth);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdTraceRaysKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdTraceRaysKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdTraceRaysKHR(commandBuffer, pRaygenShaderBindingTable, pMissShaderBindingTable,
                                              pHitShaderBindingTable, pCallableShaderBindingTable, width, height, depth,
                                              record_obj);
        }
    }
}

VKAPI_ATTR VkResult VKAPI_CALL GetRayTracingCaptureReplayShaderGroupHandlesKHR(VkDevice device, VkPipeline pipeline,
                                                                               uint32_t firstGroup, uint32_t groupCount,
                                                                               size_t dataSize, void* pData) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetRayTracingCaptureReplayShaderGroupHandlesKHR,
                          VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetRayTracingCaptureReplayShaderGroupHandlesKHR");
        for (const auto& vo :
             device_dispatch->intercept_vectors[InterceptIdPreCallValidateGetRayTracingCaptureReplayShaderGroupHandlesKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateGetRayTracingCaptureReplayShaderGroupHandlesKHR(device, pipeline, firstGroup, groupCount,
                                                                                       dataSize, pData, error_obj);
            if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetRayTracingCaptureReplayShaderGroupHandlesKHR);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetRayTracingCaptureReplayShaderGroupHandlesKHR");
        for (auto& vo :
             device_dispatch->intercept_vectors[InterceptIdPreCallRecordGetRayTracingCaptureReplayShaderGroupHandlesKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordGetRayTracingCaptureReplayShaderGroupHandlesKHR(device, pipeline, firstGroup, groupCount, dataSize,
                                                                             pData, record_obj);
        }
    }
    VkResult result;
    {
        VVL_ZoneScopedN("Dispatch_vkGetRayTracingCaptureReplayShaderGroupHandlesKHR");
        result = device_dispatch->GetRayTracingCaptureReplayShaderGroupHandlesKHR(device, pipeline, firstGroup, groupCount,
                                                                                  dataSize, pData);
    }
    record_obj.result = result;
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetRayTracingCaptureReplayShaderGroupHandlesKHR");
        for (auto& vo :
             device_dispatch->intercept_vectors[InterceptIdPostCallRecordGetRayTracingCaptureReplayShaderGroupHandlesKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordGetRayTracingCaptureReplayShaderGroupHandlesKHR(device, pipeline, firstGroup, groupCount, dataSize,
                                                                              pData, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR void VKAPI_CALL CmdTraceRaysIndirectKHR(VkCommandBuffer commandBuffer,
                                                   const VkStridedDeviceAddressRegionKHR* pRaygenShaderBindingTable,
                                                   const VkStridedDeviceAddressRegionKHR* pMissShaderBindingTable,
                                                   const VkStridedDeviceAddressRegionKHR* pHitShaderBindingTable,
                                                   const VkStridedDeviceAddressRegionKHR* pCallableShaderBindingTable,
                                                   VkDeviceAddress indirectDeviceAddress) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdTraceRaysIndirectKHR, VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdTraceRaysIndirectKHR");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdTraceRaysIndirectKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdTraceRaysIndirectKHR(commandBuffer, pRaygenShaderBindingTable, pMissShaderBindingTable,
                                                               pHitShaderBindingTable, pCallableShaderBindingTable,
                                                               indirectDeviceAddress, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdTraceRaysIndirectKHR);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdTraceRaysIndirectKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdTraceRaysIndirectKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdTraceRaysIndirectKHR(commandBuffer, pRaygenShaderBindingTable, pMissShaderBindingTable,
                                                     pHitShaderBindingTable, pCallableShaderBindingTable, indirectDeviceAddress,
                                                     record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdTraceRaysIndirectKHR");
        device_dispatch->CmdTraceRaysIndirectKHR(commandBuffer, pRaygenShaderBindingTable, pMissShaderBindingTable,
                                                 pHitShaderBindingTable, pCallableShaderBindingTable, indirectDeviceAddress);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdTraceRaysIndirectKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdTraceRaysIndirectKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdTraceRaysIndirectKHR(commandBuffer, pRaygenShaderBindingTable, pMissShaderBindingTable,
                                                      pHitShaderBindingTable, pCallableShaderBindingTable, indirectDeviceAddress,
                                                      record_obj);
        }
    }
}

VKAPI_ATTR VkDeviceSize VKAPI_CALL GetRayTracingShaderGroupStackSizeKHR(VkDevice device, VkPipeline pipeline, uint32_t group,
                                                                        VkShaderGroupShaderKHR groupShader) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(device);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkGetRayTracingShaderGroupStackSizeKHR, VulkanTypedHandle(device, kVulkanObjectTypeDevice));
    {
        VVL_ZoneScopedN("PreCallValidate_vkGetRayTracingShaderGroupStackSizeKHR");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateGetRayTracingShaderGroupStackSizeKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateGetRayTracingShaderGroupStackSizeKHR(device, pipeline, group, groupShader, error_obj);
            if (skip) return 0;
        }
    }
    RecordObject record_obj(vvl::Func::vkGetRayTracingShaderGroupStackSizeKHR);
    {
        VVL_ZoneScopedN("PreCallRecord_vkGetRayTracingShaderGroupStackSizeKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordGetRayTracingShaderGroupStackSizeKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordGetRayTracingShaderGroupStackSizeKHR(device, pipeline, group, groupShader, record_obj);
        }
    }
    VkDeviceSize result;
    {
        VVL_ZoneScopedN("Dispatch_vkGetRayTracingShaderGroupStackSizeKHR");
        result = device_dispatch->GetRayTracingShaderGroupStackSizeKHR(device, pipeline, group, groupShader);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkGetRayTracingShaderGroupStackSizeKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordGetRayTracingShaderGroupStackSizeKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordGetRayTracingShaderGroupStackSizeKHR(device, pipeline, group, groupShader, record_obj);
        }
    }
    return result;
}

VKAPI_ATTR void VKAPI_CALL CmdSetRayTracingPipelineStackSizeKHR(VkCommandBuffer commandBuffer, uint32_t pipelineStackSize) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdSetRayTracingPipelineStackSizeKHR,
                          VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdSetRayTracingPipelineStackSizeKHR");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdSetRayTracingPipelineStackSizeKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdSetRayTracingPipelineStackSizeKHR(commandBuffer, pipelineStackSize, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdSetRayTracingPipelineStackSizeKHR);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdSetRayTracingPipelineStackSizeKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdSetRayTracingPipelineStackSizeKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdSetRayTracingPipelineStackSizeKHR(commandBuffer, pipelineStackSize, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdSetRayTracingPipelineStackSizeKHR");
        device_dispatch->CmdSetRayTracingPipelineStackSizeKHR(commandBuffer, pipelineStackSize);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdSetRayTracingPipelineStackSizeKHR");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdSetRayTracingPipelineStackSizeKHR]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdSetRayTracingPipelineStackSizeKHR(commandBuffer, pipelineStackSize, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdDrawMeshTasksEXT(VkCommandBuffer commandBuffer, uint32_t groupCountX, uint32_t groupCountY,
                                               uint32_t groupCountZ) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdDrawMeshTasksEXT, VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdDrawMeshTasksEXT");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdDrawMeshTasksEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdDrawMeshTasksEXT(commandBuffer, groupCountX, groupCountY, groupCountZ, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdDrawMeshTasksEXT);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdDrawMeshTasksEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdDrawMeshTasksEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdDrawMeshTasksEXT(commandBuffer, groupCountX, groupCountY, groupCountZ, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdDrawMeshTasksEXT");
        device_dispatch->CmdDrawMeshTasksEXT(commandBuffer, groupCountX, groupCountY, groupCountZ);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdDrawMeshTasksEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdDrawMeshTasksEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdDrawMeshTasksEXT(commandBuffer, groupCountX, groupCountY, groupCountZ, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdDrawMeshTasksIndirectEXT(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
                                                       uint32_t drawCount, uint32_t stride) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdDrawMeshTasksIndirectEXT,
                          VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdDrawMeshTasksIndirectEXT");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdDrawMeshTasksIndirectEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdDrawMeshTasksIndirectEXT(commandBuffer, buffer, offset, drawCount, stride, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdDrawMeshTasksIndirectEXT);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdDrawMeshTasksIndirectEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdDrawMeshTasksIndirectEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdDrawMeshTasksIndirectEXT(commandBuffer, buffer, offset, drawCount, stride, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdDrawMeshTasksIndirectEXT");
        device_dispatch->CmdDrawMeshTasksIndirectEXT(commandBuffer, buffer, offset, drawCount, stride);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdDrawMeshTasksIndirectEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdDrawMeshTasksIndirectEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdDrawMeshTasksIndirectEXT(commandBuffer, buffer, offset, drawCount, stride, record_obj);
        }
    }
}

VKAPI_ATTR void VKAPI_CALL CmdDrawMeshTasksIndirectCountEXT(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
                                                            VkBuffer countBuffer, VkDeviceSize countBufferOffset,
                                                            uint32_t maxDrawCount, uint32_t stride) {
    VVL_ZoneScoped;

    auto device_dispatch = vvl::dispatch::GetData(commandBuffer);
    bool skip = false;
    ErrorObject error_obj(vvl::Func::vkCmdDrawMeshTasksIndirectCountEXT,
                          VulkanTypedHandle(commandBuffer, kVulkanObjectTypeCommandBuffer));
    {
        VVL_ZoneScopedN("PreCallValidate_vkCmdDrawMeshTasksIndirectCountEXT");
        for (const auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallValidateCmdDrawMeshTasksIndirectCountEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->ReadLock();
            skip |= vo->PreCallValidateCmdDrawMeshTasksIndirectCountEXT(commandBuffer, buffer, offset, countBuffer,
                                                                        countBufferOffset, maxDrawCount, stride, error_obj);
            if (skip) return;
        }
    }
    RecordObject record_obj(vvl::Func::vkCmdDrawMeshTasksIndirectCountEXT);
    {
        VVL_ZoneScopedN("PreCallRecord_vkCmdDrawMeshTasksIndirectCountEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPreCallRecordCmdDrawMeshTasksIndirectCountEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PreCallRecordCmdDrawMeshTasksIndirectCountEXT(commandBuffer, buffer, offset, countBuffer, countBufferOffset,
                                                              maxDrawCount, stride, record_obj);
        }
    }
    {
        VVL_ZoneScopedN("Dispatch_vkCmdDrawMeshTasksIndirectCountEXT");
        device_dispatch->CmdDrawMeshTasksIndirectCountEXT(commandBuffer, buffer, offset, countBuffer, countBufferOffset,
                                                          maxDrawCount, stride);
    }
    {
        VVL_ZoneScopedN("PostCallRecord_vkCmdDrawMeshTasksIndirectCountEXT");
        for (auto& vo : device_dispatch->intercept_vectors[InterceptIdPostCallRecordCmdDrawMeshTasksIndirectCountEXT]) {
            if (!vo) {
                continue;
            }
            auto lock = vo->WriteLock();
            vo->PostCallRecordCmdDrawMeshTasksIndirectCountEXT(commandBuffer, buffer, offset, countBuffer, countBufferOffset,
                                                               maxDrawCount, stride, record_obj);
        }
    }
}

// Map of intercepted ApiName to its associated function data
#ifdef _MSC_VER
#pragma warning(suppress : 6262)  // VS analysis: this uses more than 16 kiB, which is fine here at global scope
#endif

const vvl::unordered_map<std::string, function_data>& GetNameToFuncPtrMap() {
    static const vvl::unordered_map<std::string, function_data> name_to_func_ptr_map = {
        {"vk_layerGetPhysicalDeviceProcAddr", {kFuncTypeInst, (void*)GetPhysicalDeviceProcAddr}},
        {"vkCreateInstance", {kFuncTypeInst, (void*)CreateInstance}},
        {"vkDestroyInstance", {kFuncTypeInst, (void*)DestroyInstance}},
        {"vkEnumeratePhysicalDevices", {kFuncTypeInst, (void*)EnumeratePhysicalDevices}},
        {"vkGetPhysicalDeviceFeatures", {kFuncTypePdev, (void*)GetPhysicalDeviceFeatures}},
        {"vkGetPhysicalDeviceFormatProperties", {kFuncTypePdev, (void*)GetPhysicalDeviceFormatProperties}},
        {"vkGetPhysicalDeviceImageFormatProperties", {kFuncTypePdev, (void*)GetPhysicalDeviceImageFormatProperties}},
        {"vkGetPhysicalDeviceProperties", {kFuncTypePdev, (void*)GetPhysicalDeviceProperties}},
        {"vkGetPhysicalDeviceQueueFamilyProperties", {kFuncTypePdev, (void*)GetPhysicalDeviceQueueFamilyProperties}},
        {"vkGetPhysicalDeviceMemoryProperties", {kFuncTypePdev, (void*)GetPhysicalDeviceMemoryProperties}},
        {"vkGetInstanceProcAddr", {kFuncTypeInst, (void*)GetInstanceProcAddr}},
        {"vkGetDeviceProcAddr", {kFuncTypeDev, (void*)GetDeviceProcAddr}},
        {"vkCreateDevice", {kFuncTypePdev, (void*)CreateDevice}},
        {"vkDestroyDevice", {kFuncTypeDev, (void*)DestroyDevice}},
        {"vkEnumerateInstanceExtensionProperties", {kFuncTypeInst, (void*)EnumerateInstanceExtensionProperties}},
        {"vkEnumerateDeviceExtensionProperties", {kFuncTypePdev, (void*)EnumerateDeviceExtensionProperties}},
        {"vkEnumerateInstanceLayerProperties", {kFuncTypeInst, (void*)EnumerateInstanceLayerProperties}},
        {"vkEnumerateDeviceLayerProperties", {kFuncTypePdev, (void*)EnumerateDeviceLayerProperties}},
        {"vkGetDeviceQueue", {kFuncTypeDev, (void*)GetDeviceQueue}},
        {"vkQueueSubmit", {kFuncTypeDev, (void*)QueueSubmit}},
        {"vkQueueWaitIdle", {kFuncTypeDev, (void*)QueueWaitIdle}},
        {"vkDeviceWaitIdle", {kFuncTypeDev, (void*)DeviceWaitIdle}},
        {"vkAllocateMemory", {kFuncTypeDev, (void*)AllocateMemory}},
        {"vkFreeMemory", {kFuncTypeDev, (void*)FreeMemory}},
        {"vkMapMemory", {kFuncTypeDev, (void*)MapMemory}},
        {"vkUnmapMemory", {kFuncTypeDev, (void*)UnmapMemory}},
        {"vkFlushMappedMemoryRanges", {kFuncTypeDev, (void*)FlushMappedMemoryRanges}},
        {"vkInvalidateMappedMemoryRanges", {kFuncTypeDev, (void*)InvalidateMappedMemoryRanges}},
        {"vkGetDeviceMemoryCommitment", {kFuncTypeDev, (void*)GetDeviceMemoryCommitment}},
        {"vkBindBufferMemory", {kFuncTypeDev, (void*)BindBufferMemory}},
        {"vkBindImageMemory", {kFuncTypeDev, (void*)BindImageMemory}},
        {"vkGetBufferMemoryRequirements", {kFuncTypeDev, (void*)GetBufferMemoryRequirements}},
        {"vkGetImageMemoryRequirements", {kFuncTypeDev, (void*)GetImageMemoryRequirements}},
        {"vkGetImageSparseMemoryRequirements", {kFuncTypeDev, (void*)GetImageSparseMemoryRequirements}},
        {"vkGetPhysicalDeviceSparseImageFormatProperties", {kFuncTypePdev, (void*)GetPhysicalDeviceSparseImageFormatProperties}},
        {"vkQueueBindSparse", {kFuncTypeDev, (void*)QueueBindSparse}},
        {"vkCreateFence", {kFuncTypeDev, (void*)CreateFence}},
        {"vkDestroyFence", {kFuncTypeDev, (void*)DestroyFence}},
        {"vkResetFences", {kFuncTypeDev, (void*)ResetFences}},
        {"vkGetFenceStatus", {kFuncTypeDev, (void*)GetFenceStatus}},
        {"vkWaitForFences", {kFuncTypeDev, (void*)WaitForFences}},
        {"vkCreateSemaphore", {kFuncTypeDev, (void*)CreateSemaphore}},
        {"vkDestroySemaphore", {kFuncTypeDev, (void*)DestroySemaphore}},
        {"vkCreateQueryPool", {kFuncTypeDev, (void*)CreateQueryPool}},
        {"vkDestroyQueryPool", {kFuncTypeDev, (void*)DestroyQueryPool}},
        {"vkGetQueryPoolResults", {kFuncTypeDev, (void*)GetQueryPoolResults}},
        {"vkCreateBuffer", {kFuncTypeDev, (void*)CreateBuffer}},
        {"vkDestroyBuffer", {kFuncTypeDev, (void*)DestroyBuffer}},
        {"vkCreateImage", {kFuncTypeDev, (void*)CreateImage}},
        {"vkDestroyImage", {kFuncTypeDev, (void*)DestroyImage}},
        {"vkGetImageSubresourceLayout", {kFuncTypeDev, (void*)GetImageSubresourceLayout}},
        {"vkCreateImageView", {kFuncTypeDev, (void*)CreateImageView}},
        {"vkDestroyImageView", {kFuncTypeDev, (void*)DestroyImageView}},
        {"vkCreateCommandPool", {kFuncTypeDev, (void*)CreateCommandPool}},
        {"vkDestroyCommandPool", {kFuncTypeDev, (void*)DestroyCommandPool}},
        {"vkResetCommandPool", {kFuncTypeDev, (void*)ResetCommandPool}},
        {"vkAllocateCommandBuffers", {kFuncTypeDev, (void*)AllocateCommandBuffers}},
        {"vkFreeCommandBuffers", {kFuncTypeDev, (void*)FreeCommandBuffers}},
        {"vkBeginCommandBuffer", {kFuncTypeDev, (void*)BeginCommandBuffer}},
        {"vkEndCommandBuffer", {kFuncTypeDev, (void*)EndCommandBuffer}},
        {"vkResetCommandBuffer", {kFuncTypeDev, (void*)ResetCommandBuffer}},
        {"vkCmdCopyBuffer", {kFuncTypeDev, (void*)CmdCopyBuffer}},
        {"vkCmdCopyImage", {kFuncTypeDev, (void*)CmdCopyImage}},
        {"vkCmdCopyBufferToImage", {kFuncTypeDev, (void*)CmdCopyBufferToImage}},
        {"vkCmdCopyImageToBuffer", {kFuncTypeDev, (void*)CmdCopyImageToBuffer}},
        {"vkCmdUpdateBuffer", {kFuncTypeDev, (void*)CmdUpdateBuffer}},
        {"vkCmdFillBuffer", {kFuncTypeDev, (void*)CmdFillBuffer}},
        {"vkCmdPipelineBarrier", {kFuncTypeDev, (void*)CmdPipelineBarrier}},
        {"vkCmdBeginQuery", {kFuncTypeDev, (void*)CmdBeginQuery}},
        {"vkCmdEndQuery", {kFuncTypeDev, (void*)CmdEndQuery}},
        {"vkCmdResetQueryPool", {kFuncTypeDev, (void*)CmdResetQueryPool}},
        {"vkCmdWriteTimestamp", {kFuncTypeDev, (void*)CmdWriteTimestamp}},
        {"vkCmdCopyQueryPoolResults", {kFuncTypeDev, (void*)CmdCopyQueryPoolResults}},
        {"vkCmdExecuteCommands", {kFuncTypeDev, (void*)CmdExecuteCommands}},
        {"vkCreateEvent", {kFuncTypeDev, (void*)CreateEvent}},
        {"vkDestroyEvent", {kFuncTypeDev, (void*)DestroyEvent}},
        {"vkGetEventStatus", {kFuncTypeDev, (void*)GetEventStatus}},
        {"vkSetEvent", {kFuncTypeDev, (void*)SetEvent}},
        {"vkResetEvent", {kFuncTypeDev, (void*)ResetEvent}},
        {"vkCreateBufferView", {kFuncTypeDev, (void*)CreateBufferView}},
        {"vkDestroyBufferView", {kFuncTypeDev, (void*)DestroyBufferView}},
        {"vkCreateShaderModule", {kFuncTypeDev, (void*)CreateShaderModule}},
        {"vkDestroyShaderModule", {kFuncTypeDev, (void*)DestroyShaderModule}},
        {"vkCreatePipelineCache", {kFuncTypeDev, (void*)CreatePipelineCache}},
        {"vkDestroyPipelineCache", {kFuncTypeDev, (void*)DestroyPipelineCache}},
        {"vkGetPipelineCacheData", {kFuncTypeDev, (void*)GetPipelineCacheData}},
        {"vkMergePipelineCaches", {kFuncTypeDev, (void*)MergePipelineCaches}},
        {"vkCreateComputePipelines", {kFuncTypeDev, (void*)CreateComputePipelines}},
        {"vkDestroyPipeline", {kFuncTypeDev, (void*)DestroyPipeline}},
        {"vkCreatePipelineLayout", {kFuncTypeDev, (void*)CreatePipelineLayout}},
        {"vkDestroyPipelineLayout", {kFuncTypeDev, (void*)DestroyPipelineLayout}},
        {"vkCreateSampler", {kFuncTypeDev, (void*)CreateSampler}},
        {"vkDestroySampler", {kFuncTypeDev, (void*)DestroySampler}},
        {"vkCreateDescriptorSetLayout", {kFuncTypeDev, (void*)CreateDescriptorSetLayout}},
        {"vkDestroyDescriptorSetLayout", {kFuncTypeDev, (void*)DestroyDescriptorSetLayout}},
        {"vkCreateDescriptorPool", {kFuncTypeDev, (void*)CreateDescriptorPool}},
        {"vkDestroyDescriptorPool", {kFuncTypeDev, (void*)DestroyDescriptorPool}},
        {"vkResetDescriptorPool", {kFuncTypeDev, (void*)ResetDescriptorPool}},
        {"vkAllocateDescriptorSets", {kFuncTypeDev, (void*)AllocateDescriptorSets}},
        {"vkFreeDescriptorSets", {kFuncTypeDev, (void*)FreeDescriptorSets}},
        {"vkUpdateDescriptorSets", {kFuncTypeDev, (void*)UpdateDescriptorSets}},
        {"vkCmdBindPipeline", {kFuncTypeDev, (void*)CmdBindPipeline}},
        {"vkCmdBindDescriptorSets", {kFuncTypeDev, (void*)CmdBindDescriptorSets}},
        {"vkCmdClearColorImage", {kFuncTypeDev, (void*)CmdClearColorImage}},
        {"vkCmdDispatch", {kFuncTypeDev, (void*)CmdDispatch}},
        {"vkCmdDispatchIndirect", {kFuncTypeDev, (void*)CmdDispatchIndirect}},
        {"vkCmdSetEvent", {kFuncTypeDev, (void*)CmdSetEvent}},
        {"vkCmdResetEvent", {kFuncTypeDev, (void*)CmdResetEvent}},
        {"vkCmdWaitEvents", {kFuncTypeDev, (void*)CmdWaitEvents}},
        {"vkCmdPushConstants", {kFuncTypeDev, (void*)CmdPushConstants}},
        {"vkCreateGraphicsPipelines", {kFuncTypeDev, (void*)CreateGraphicsPipelines}},
        {"vkCreateFramebuffer", {kFuncTypeDev, (void*)CreateFramebuffer}},
        {"vkDestroyFramebuffer", {kFuncTypeDev, (void*)DestroyFramebuffer}},
        {"vkCreateRenderPass", {kFuncTypeDev, (void*)CreateRenderPass}},
        {"vkDestroyRenderPass", {kFuncTypeDev, (void*)DestroyRenderPass}},
        {"vkGetRenderAreaGranularity", {kFuncTypeDev, (void*)GetRenderAreaGranularity}},
        {"vkCmdSetViewport", {kFuncTypeDev, (void*)CmdSetViewport}},
        {"vkCmdSetScissor", {kFuncTypeDev, (void*)CmdSetScissor}},
        {"vkCmdSetLineWidth", {kFuncTypeDev, (void*)CmdSetLineWidth}},
        {"vkCmdSetDepthBias", {kFuncTypeDev, (void*)CmdSetDepthBias}},
        {"vkCmdSetBlendConstants", {kFuncTypeDev, (void*)CmdSetBlendConstants}},
        {"vkCmdSetDepthBounds", {kFuncTypeDev, (void*)CmdSetDepthBounds}},
        {"vkCmdSetStencilCompareMask", {kFuncTypeDev, (void*)CmdSetStencilCompareMask}},
        {"vkCmdSetStencilWriteMask", {kFuncTypeDev, (void*)CmdSetStencilWriteMask}},
        {"vkCmdSetStencilReference", {kFuncTypeDev, (void*)CmdSetStencilReference}},
        {"vkCmdBindIndexBuffer", {kFuncTypeDev, (void*)CmdBindIndexBuffer}},
        {"vkCmdBindVertexBuffers", {kFuncTypeDev, (void*)CmdBindVertexBuffers}},
        {"vkCmdDraw", {kFuncTypeDev, (void*)CmdDraw}},
        {"vkCmdDrawIndexed", {kFuncTypeDev, (void*)CmdDrawIndexed}},
        {"vkCmdDrawIndirect", {kFuncTypeDev, (void*)CmdDrawIndirect}},
        {"vkCmdDrawIndexedIndirect", {kFuncTypeDev, (void*)CmdDrawIndexedIndirect}},
        {"vkCmdBlitImage", {kFuncTypeDev, (void*)CmdBlitImage}},
        {"vkCmdClearDepthStencilImage", {kFuncTypeDev, (void*)CmdClearDepthStencilImage}},
        {"vkCmdClearAttachments", {kFuncTypeDev, (void*)CmdClearAttachments}},
        {"vkCmdResolveImage", {kFuncTypeDev, (void*)CmdResolveImage}},
        {"vkCmdBeginRenderPass", {kFuncTypeDev, (void*)CmdBeginRenderPass}},
        {"vkCmdNextSubpass", {kFuncTypeDev, (void*)CmdNextSubpass}},
        {"vkCmdEndRenderPass", {kFuncTypeDev, (void*)CmdEndRenderPass}},
        {"vkEnumerateInstanceVersion", {kFuncTypeInst, (void*)EnumerateInstanceVersion}},
        {"vkBindBufferMemory2", {kFuncTypeDev, (void*)BindBufferMemory2}},
        {"vkBindImageMemory2", {kFuncTypeDev, (void*)BindImageMemory2}},
        {"vkGetDeviceGroupPeerMemoryFeatures", {kFuncTypeDev, (void*)GetDeviceGroupPeerMemoryFeatures}},
        {"vkCmdSetDeviceMask", {kFuncTypeDev, (void*)CmdSetDeviceMask}},
        {"vkEnumeratePhysicalDeviceGroups", {kFuncTypeInst, (void*)EnumeratePhysicalDeviceGroups}},
        {"vkGetImageMemoryRequirements2", {kFuncTypeDev, (void*)GetImageMemoryRequirements2}},
        {"vkGetBufferMemoryRequirements2", {kFuncTypeDev, (void*)GetBufferMemoryRequirements2}},
        {"vkGetImageSparseMemoryRequirements2", {kFuncTypeDev, (void*)GetImageSparseMemoryRequirements2}},
        {"vkGetPhysicalDeviceFeatures2", {kFuncTypePdev, (void*)GetPhysicalDeviceFeatures2}},
        {"vkGetPhysicalDeviceProperties2", {kFuncTypePdev, (void*)GetPhysicalDeviceProperties2}},
        {"vkGetPhysicalDeviceFormatProperties2", {kFuncTypePdev, (void*)GetPhysicalDeviceFormatProperties2}},
        {"vkGetPhysicalDeviceImageFormatProperties2", {kFuncTypePdev, (void*)GetPhysicalDeviceImageFormatProperties2}},
        {"vkGetPhysicalDeviceQueueFamilyProperties2", {kFuncTypePdev, (void*)GetPhysicalDeviceQueueFamilyProperties2}},
        {"vkGetPhysicalDeviceMemoryProperties2", {kFuncTypePdev, (void*)GetPhysicalDeviceMemoryProperties2}},
        {"vkGetPhysicalDeviceSparseImageFormatProperties2", {kFuncTypePdev, (void*)GetPhysicalDeviceSparseImageFormatProperties2}},
        {"vkTrimCommandPool", {kFuncTypeDev, (void*)TrimCommandPool}},
        {"vkGetDeviceQueue2", {kFuncTypeDev, (void*)GetDeviceQueue2}},
        {"vkGetPhysicalDeviceExternalBufferProperties", {kFuncTypePdev, (void*)GetPhysicalDeviceExternalBufferProperties}},
        {"vkGetPhysicalDeviceExternalFenceProperties", {kFuncTypePdev, (void*)GetPhysicalDeviceExternalFenceProperties}},
        {"vkGetPhysicalDeviceExternalSemaphoreProperties", {kFuncTypePdev, (void*)GetPhysicalDeviceExternalSemaphoreProperties}},
        {"vkCmdDispatchBase", {kFuncTypeDev, (void*)CmdDispatchBase}},
        {"vkCreateDescriptorUpdateTemplate", {kFuncTypeDev, (void*)CreateDescriptorUpdateTemplate}},
        {"vkDestroyDescriptorUpdateTemplate", {kFuncTypeDev, (void*)DestroyDescriptorUpdateTemplate}},
        {"vkUpdateDescriptorSetWithTemplate", {kFuncTypeDev, (void*)UpdateDescriptorSetWithTemplate}},
        {"vkGetDescriptorSetLayoutSupport", {kFuncTypeDev, (void*)GetDescriptorSetLayoutSupport}},
        {"vkCreateSamplerYcbcrConversion", {kFuncTypeDev, (void*)CreateSamplerYcbcrConversion}},
        {"vkDestroySamplerYcbcrConversion", {kFuncTypeDev, (void*)DestroySamplerYcbcrConversion}},
        {"vkResetQueryPool", {kFuncTypeDev, (void*)ResetQueryPool}},
        {"vkGetSemaphoreCounterValue", {kFuncTypeDev, (void*)GetSemaphoreCounterValue}},
        {"vkWaitSemaphores", {kFuncTypeDev, (void*)WaitSemaphores}},
        {"vkSignalSemaphore", {kFuncTypeDev, (void*)SignalSemaphore}},
        {"vkGetBufferDeviceAddress", {kFuncTypeDev, (void*)GetBufferDeviceAddress}},
        {"vkGetBufferOpaqueCaptureAddress", {kFuncTypeDev, (void*)GetBufferOpaqueCaptureAddress}},
        {"vkGetDeviceMemoryOpaqueCaptureAddress", {kFuncTypeDev, (void*)GetDeviceMemoryOpaqueCaptureAddress}},
        {"vkCmdDrawIndirectCount", {kFuncTypeDev, (void*)CmdDrawIndirectCount}},
        {"vkCmdDrawIndexedIndirectCount", {kFuncTypeDev, (void*)CmdDrawIndexedIndirectCount}},
        {"vkCreateRenderPass2", {kFuncTypeDev, (void*)CreateRenderPass2}},
        {"vkCmdBeginRenderPass2", {kFuncTypeDev, (void*)CmdBeginRenderPass2}},
        {"vkCmdNextSubpass2", {kFuncTypeDev, (void*)CmdNextSubpass2}},
        {"vkCmdEndRenderPass2", {kFuncTypeDev, (void*)CmdEndRenderPass2}},
        {"vkGetPhysicalDeviceToolProperties", {kFuncTypePdev, (void*)GetPhysicalDeviceToolProperties}},
        {"vkCreatePrivateDataSlot", {kFuncTypeDev, (void*)CreatePrivateDataSlot}},
        {"vkDestroyPrivateDataSlot", {kFuncTypeDev, (void*)DestroyPrivateDataSlot}},
        {"vkSetPrivateData", {kFuncTypeDev, (void*)SetPrivateData}},
        {"vkGetPrivateData", {kFuncTypeDev, (void*)GetPrivateData}},
        {"vkCmdPipelineBarrier2", {kFuncTypeDev, (void*)CmdPipelineBarrier2}},
        {"vkCmdWriteTimestamp2", {kFuncTypeDev, (void*)CmdWriteTimestamp2}},
        {"vkQueueSubmit2", {kFuncTypeDev, (void*)QueueSubmit2}},
        {"vkCmdCopyBuffer2", {kFuncTypeDev, (void*)CmdCopyBuffer2}},
        {"vkCmdCopyImage2", {kFuncTypeDev, (void*)CmdCopyImage2}},
        {"vkCmdCopyBufferToImage2", {kFuncTypeDev, (void*)CmdCopyBufferToImage2}},
        {"vkCmdCopyImageToBuffer2", {kFuncTypeDev, (void*)CmdCopyImageToBuffer2}},
        {"vkGetDeviceBufferMemoryRequirements", {kFuncTypeDev, (void*)GetDeviceBufferMemoryRequirements}},
        {"vkGetDeviceImageMemoryRequirements", {kFuncTypeDev, (void*)GetDeviceImageMemoryRequirements}},
        {"vkGetDeviceImageSparseMemoryRequirements", {kFuncTypeDev, (void*)GetDeviceImageSparseMemoryRequirements}},
        {"vkCmdSetEvent2", {kFuncTypeDev, (void*)CmdSetEvent2}},
        {"vkCmdResetEvent2", {kFuncTypeDev, (void*)CmdResetEvent2}},
        {"vkCmdWaitEvents2", {kFuncTypeDev, (void*)CmdWaitEvents2}},
        {"vkCmdBlitImage2", {kFuncTypeDev, (void*)CmdBlitImage2}},
        {"vkCmdResolveImage2", {kFuncTypeDev, (void*)CmdResolveImage2}},
        {"vkCmdBeginRendering", {kFuncTypeDev, (void*)CmdBeginRendering}},
        {"vkCmdEndRendering", {kFuncTypeDev, (void*)CmdEndRendering}},
        {"vkCmdSetCullMode", {kFuncTypeDev, (void*)CmdSetCullMode}},
        {"vkCmdSetFrontFace", {kFuncTypeDev, (void*)CmdSetFrontFace}},
        {"vkCmdSetPrimitiveTopology", {kFuncTypeDev, (void*)CmdSetPrimitiveTopology}},
        {"vkCmdSetViewportWithCount", {kFuncTypeDev, (void*)CmdSetViewportWithCount}},
        {"vkCmdSetScissorWithCount", {kFuncTypeDev, (void*)CmdSetScissorWithCount}},
        {"vkCmdBindVertexBuffers2", {kFuncTypeDev, (void*)CmdBindVertexBuffers2}},
        {"vkCmdSetDepthTestEnable", {kFuncTypeDev, (void*)CmdSetDepthTestEnable}},
        {"vkCmdSetDepthWriteEnable", {kFuncTypeDev, (void*)CmdSetDepthWriteEnable}},
        {"vkCmdSetDepthCompareOp", {kFuncTypeDev, (void*)CmdSetDepthCompareOp}},
        {"vkCmdSetDepthBoundsTestEnable", {kFuncTypeDev, (void*)CmdSetDepthBoundsTestEnable}},
        {"vkCmdSetStencilTestEnable", {kFuncTypeDev, (void*)CmdSetStencilTestEnable}},
        {"vkCmdSetStencilOp", {kFuncTypeDev, (void*)CmdSetStencilOp}},
        {"vkCmdSetRasterizerDiscardEnable", {kFuncTypeDev, (void*)CmdSetRasterizerDiscardEnable}},
        {"vkCmdSetDepthBiasEnable", {kFuncTypeDev, (void*)CmdSetDepthBiasEnable}},
        {"vkCmdSetPrimitiveRestartEnable", {kFuncTypeDev, (void*)CmdSetPrimitiveRestartEnable}},
        {"vkMapMemory2", {kFuncTypeDev, (void*)MapMemory2}},
        {"vkUnmapMemory2", {kFuncTypeDev, (void*)UnmapMemory2}},
        {"vkGetDeviceImageSubresourceLayout", {kFuncTypeDev, (void*)GetDeviceImageSubresourceLayout}},
        {"vkGetImageSubresourceLayout2", {kFuncTypeDev, (void*)GetImageSubresourceLayout2}},
        {"vkCopyMemoryToImage", {kFuncTypeDev, (void*)CopyMemoryToImage}},
        {"vkCopyImageToMemory", {kFuncTypeDev, (void*)CopyImageToMemory}},
        {"vkCopyImageToImage", {kFuncTypeDev, (void*)CopyImageToImage}},
        {"vkTransitionImageLayout", {kFuncTypeDev, (void*)TransitionImageLayout}},
        {"vkCmdPushDescriptorSet", {kFuncTypeDev, (void*)CmdPushDescriptorSet}},
        {"vkCmdPushDescriptorSetWithTemplate", {kFuncTypeDev, (void*)CmdPushDescriptorSetWithTemplate}},
        {"vkCmdBindDescriptorSets2", {kFuncTypeDev, (void*)CmdBindDescriptorSets2}},
        {"vkCmdPushConstants2", {kFuncTypeDev, (void*)CmdPushConstants2}},
        {"vkCmdPushDescriptorSet2", {kFuncTypeDev, (void*)CmdPushDescriptorSet2}},
        {"vkCmdPushDescriptorSetWithTemplate2", {kFuncTypeDev, (void*)CmdPushDescriptorSetWithTemplate2}},
        {"vkCmdSetLineStipple", {kFuncTypeDev, (void*)CmdSetLineStipple}},
        {"vkCmdBindIndexBuffer2", {kFuncTypeDev, (void*)CmdBindIndexBuffer2}},
        {"vkGetRenderingAreaGranularity", {kFuncTypeDev, (void*)GetRenderingAreaGranularity}},
        {"vkCmdSetRenderingAttachmentLocations", {kFuncTypeDev, (void*)CmdSetRenderingAttachmentLocations}},
        {"vkCmdSetRenderingInputAttachmentIndices", {kFuncTypeDev, (void*)CmdSetRenderingInputAttachmentIndices}},
        {"vkDestroySurfaceKHR", {kFuncTypeInst, (void*)DestroySurfaceKHR}},
        {"vkGetPhysicalDeviceSurfaceSupportKHR", {kFuncTypePdev, (void*)GetPhysicalDeviceSurfaceSupportKHR}},
        {"vkGetPhysicalDeviceSurfaceCapabilitiesKHR", {kFuncTypePdev, (void*)GetPhysicalDeviceSurfaceCapabilitiesKHR}},
        {"vkGetPhysicalDeviceSurfaceFormatsKHR", {kFuncTypePdev, (void*)GetPhysicalDeviceSurfaceFormatsKHR}},
        {"vkGetPhysicalDeviceSurfacePresentModesKHR", {kFuncTypePdev, (void*)GetPhysicalDeviceSurfacePresentModesKHR}},
        {"vkCreateSwapchainKHR", {kFuncTypeDev, (void*)CreateSwapchainKHR}},
        {"vkDestroySwapchainKHR", {kFuncTypeDev, (void*)DestroySwapchainKHR}},
        {"vkGetSwapchainImagesKHR", {kFuncTypeDev, (void*)GetSwapchainImagesKHR}},
        {"vkAcquireNextImageKHR", {kFuncTypeDev, (void*)AcquireNextImageKHR}},
        {"vkQueuePresentKHR", {kFuncTypeDev, (void*)QueuePresentKHR}},
        {"vkGetDeviceGroupPresentCapabilitiesKHR", {kFuncTypeDev, (void*)GetDeviceGroupPresentCapabilitiesKHR}},
        {"vkGetDeviceGroupSurfacePresentModesKHR", {kFuncTypeDev, (void*)GetDeviceGroupSurfacePresentModesKHR}},
        {"vkGetPhysicalDevicePresentRectanglesKHR", {kFuncTypePdev, (void*)GetPhysicalDevicePresentRectanglesKHR}},
        {"vkAcquireNextImage2KHR", {kFuncTypeDev, (void*)AcquireNextImage2KHR}},
        {"vkGetPhysicalDeviceDisplayPropertiesKHR", {kFuncTypePdev, (void*)GetPhysicalDeviceDisplayPropertiesKHR}},
        {"vkGetPhysicalDeviceDisplayPlanePropertiesKHR", {kFuncTypePdev, (void*)GetPhysicalDeviceDisplayPlanePropertiesKHR}},
        {"vkGetDisplayPlaneSupportedDisplaysKHR", {kFuncTypePdev, (void*)GetDisplayPlaneSupportedDisplaysKHR}},
        {"vkGetDisplayModePropertiesKHR", {kFuncTypePdev, (void*)GetDisplayModePropertiesKHR}},
        {"vkCreateDisplayModeKHR", {kFuncTypePdev, (void*)CreateDisplayModeKHR}},
        {"vkGetDisplayPlaneCapabilitiesKHR", {kFuncTypePdev, (void*)GetDisplayPlaneCapabilitiesKHR}},
        {"vkCreateDisplayPlaneSurfaceKHR", {kFuncTypeInst, (void*)CreateDisplayPlaneSurfaceKHR}},
        {"vkCreateSharedSwapchainsKHR", {kFuncTypeDev, (void*)CreateSharedSwapchainsKHR}},
#ifdef VK_USE_PLATFORM_XLIB_KHR
        {"vkCreateXlibSurfaceKHR", {kFuncTypeInst, (void*)CreateXlibSurfaceKHR}},
        {"vkGetPhysicalDeviceXlibPresentationSupportKHR", {kFuncTypePdev, (void*)GetPhysicalDeviceXlibPresentationSupportKHR}},
#endif  // VK_USE_PLATFORM_XLIB_KHR
#ifdef VK_USE_PLATFORM_XCB_KHR
        {"vkCreateXcbSurfaceKHR", {kFuncTypeInst, (void*)CreateXcbSurfaceKHR}},
        {"vkGetPhysicalDeviceXcbPresentationSupportKHR", {kFuncTypePdev, (void*)GetPhysicalDeviceXcbPresentationSupportKHR}},
#endif  // VK_USE_PLATFORM_XCB_KHR
#ifdef VK_USE_PLATFORM_WAYLAND_KHR
        {"vkCreateWaylandSurfaceKHR", {kFuncTypeInst, (void*)CreateWaylandSurfaceKHR}},
        {"vkGetPhysicalDeviceWaylandPresentationSupportKHR",
         {kFuncTypePdev, (void*)GetPhysicalDeviceWaylandPresentationSupportKHR}},
#endif  // VK_USE_PLATFORM_WAYLAND_KHR
#ifdef VK_USE_PLATFORM_ANDROID_KHR
        {"vkCreateAndroidSurfaceKHR", {kFuncTypeInst, (void*)CreateAndroidSurfaceKHR}},
#endif  // VK_USE_PLATFORM_ANDROID_KHR
#ifdef VK_USE_PLATFORM_WIN32_KHR
        {"vkCreateWin32SurfaceKHR", {kFuncTypeInst, (void*)CreateWin32SurfaceKHR}},
        {"vkGetPhysicalDeviceWin32PresentationSupportKHR", {kFuncTypePdev, (void*)GetPhysicalDeviceWin32PresentationSupportKHR}},
#endif  // VK_USE_PLATFORM_WIN32_KHR
        {"vkGetPhysicalDeviceVideoCapabilitiesKHR", {kFuncTypePdev, (void*)GetPhysicalDeviceVideoCapabilitiesKHR}},
        {"vkGetPhysicalDeviceVideoFormatPropertiesKHR", {kFuncTypePdev, (void*)GetPhysicalDeviceVideoFormatPropertiesKHR}},
        {"vkCreateVideoSessionKHR", {kFuncTypeDev, (void*)CreateVideoSessionKHR}},
        {"vkDestroyVideoSessionKHR", {kFuncTypeDev, (void*)DestroyVideoSessionKHR}},
        {"vkGetVideoSessionMemoryRequirementsKHR", {kFuncTypeDev, (void*)GetVideoSessionMemoryRequirementsKHR}},
        {"vkBindVideoSessionMemoryKHR", {kFuncTypeDev, (void*)BindVideoSessionMemoryKHR}},
        {"vkCreateVideoSessionParametersKHR", {kFuncTypeDev, (void*)CreateVideoSessionParametersKHR}},
        {"vkUpdateVideoSessionParametersKHR", {kFuncTypeDev, (void*)UpdateVideoSessionParametersKHR}},
        {"vkDestroyVideoSessionParametersKHR", {kFuncTypeDev, (void*)DestroyVideoSessionParametersKHR}},
        {"vkCmdBeginVideoCodingKHR", {kFuncTypeDev, (void*)CmdBeginVideoCodingKHR}},
        {"vkCmdEndVideoCodingKHR", {kFuncTypeDev, (void*)CmdEndVideoCodingKHR}},
        {"vkCmdControlVideoCodingKHR", {kFuncTypeDev, (void*)CmdControlVideoCodingKHR}},
        {"vkCmdDecodeVideoKHR", {kFuncTypeDev, (void*)CmdDecodeVideoKHR}},
        {"vkCmdBeginRenderingKHR", {kFuncTypeDev, (void*)CmdBeginRenderingKHR}},
        {"vkCmdEndRenderingKHR", {kFuncTypeDev, (void*)CmdEndRenderingKHR}},
        {"vkGetPhysicalDeviceFeatures2KHR", {kFuncTypePdev, (void*)GetPhysicalDeviceFeatures2KHR}},
        {"vkGetPhysicalDeviceProperties2KHR", {kFuncTypePdev, (void*)GetPhysicalDeviceProperties2KHR}},
        {"vkGetPhysicalDeviceFormatProperties2KHR", {kFuncTypePdev, (void*)GetPhysicalDeviceFormatProperties2KHR}},
        {"vkGetPhysicalDeviceImageFormatProperties2KHR", {kFuncTypePdev, (void*)GetPhysicalDeviceImageFormatProperties2KHR}},
        {"vkGetPhysicalDeviceQueueFamilyProperties2KHR", {kFuncTypePdev, (void*)GetPhysicalDeviceQueueFamilyProperties2KHR}},
        {"vkGetPhysicalDeviceMemoryProperties2KHR", {kFuncTypePdev, (void*)GetPhysicalDeviceMemoryProperties2KHR}},
        {"vkGetPhysicalDeviceSparseImageFormatProperties2KHR",
         {kFuncTypePdev, (void*)GetPhysicalDeviceSparseImageFormatProperties2KHR}},
        {"vkGetDeviceGroupPeerMemoryFeaturesKHR", {kFuncTypeDev, (void*)GetDeviceGroupPeerMemoryFeaturesKHR}},
        {"vkCmdSetDeviceMaskKHR", {kFuncTypeDev, (void*)CmdSetDeviceMaskKHR}},
        {"vkCmdDispatchBaseKHR", {kFuncTypeDev, (void*)CmdDispatchBaseKHR}},
        {"vkTrimCommandPoolKHR", {kFuncTypeDev, (void*)TrimCommandPoolKHR}},
        {"vkEnumeratePhysicalDeviceGroupsKHR", {kFuncTypeInst, (void*)EnumeratePhysicalDeviceGroupsKHR}},
        {"vkGetPhysicalDeviceExternalBufferPropertiesKHR", {kFuncTypePdev, (void*)GetPhysicalDeviceExternalBufferPropertiesKHR}},
#ifdef VK_USE_PLATFORM_WIN32_KHR
        {"vkGetMemoryWin32HandleKHR", {kFuncTypeDev, (void*)GetMemoryWin32HandleKHR}},
        {"vkGetMemoryWin32HandlePropertiesKHR", {kFuncTypeDev, (void*)GetMemoryWin32HandlePropertiesKHR}},
#endif  // VK_USE_PLATFORM_WIN32_KHR
        {"vkGetMemoryFdKHR", {kFuncTypeDev, (void*)GetMemoryFdKHR}},
        {"vkGetMemoryFdPropertiesKHR", {kFuncTypeDev, (void*)GetMemoryFdPropertiesKHR}},
        {"vkGetPhysicalDeviceExternalSemaphorePropertiesKHR",
         {kFuncTypePdev, (void*)GetPhysicalDeviceExternalSemaphorePropertiesKHR}},
#ifdef VK_USE_PLATFORM_WIN32_KHR
        {"vkImportSemaphoreWin32HandleKHR", {kFuncTypeDev, (void*)ImportSemaphoreWin32HandleKHR}},
        {"vkGetSemaphoreWin32HandleKHR", {kFuncTypeDev, (void*)GetSemaphoreWin32HandleKHR}},
#endif  // VK_USE_PLATFORM_WIN32_KHR
        {"vkImportSemaphoreFdKHR", {kFuncTypeDev, (void*)ImportSemaphoreFdKHR}},
        {"vkGetSemaphoreFdKHR", {kFuncTypeDev, (void*)GetSemaphoreFdKHR}},
        {"vkCmdPushDescriptorSetKHR", {kFuncTypeDev, (void*)CmdPushDescriptorSetKHR}},
        {"vkCmdPushDescriptorSetWithTemplateKHR", {kFuncTypeDev, (void*)CmdPushDescriptorSetWithTemplateKHR}},
        {"vkCreateDescriptorUpdateTemplateKHR", {kFuncTypeDev, (void*)CreateDescriptorUpdateTemplateKHR}},
        {"vkDestroyDescriptorUpdateTemplateKHR", {kFuncTypeDev, (void*)DestroyDescriptorUpdateTemplateKHR}},
        {"vkUpdateDescriptorSetWithTemplateKHR", {kFuncTypeDev, (void*)UpdateDescriptorSetWithTemplateKHR}},
        {"vkCreateRenderPass2KHR", {kFuncTypeDev, (void*)CreateRenderPass2KHR}},
        {"vkCmdBeginRenderPass2KHR", {kFuncTypeDev, (void*)CmdBeginRenderPass2KHR}},
        {"vkCmdNextSubpass2KHR", {kFuncTypeDev, (void*)CmdNextSubpass2KHR}},
        {"vkCmdEndRenderPass2KHR", {kFuncTypeDev, (void*)CmdEndRenderPass2KHR}},
        {"vkGetSwapchainStatusKHR", {kFuncTypeDev, (void*)GetSwapchainStatusKHR}},
        {"vkGetPhysicalDeviceExternalFencePropertiesKHR", {kFuncTypePdev, (void*)GetPhysicalDeviceExternalFencePropertiesKHR}},
#ifdef VK_USE_PLATFORM_WIN32_KHR
        {"vkImportFenceWin32HandleKHR", {kFuncTypeDev, (void*)ImportFenceWin32HandleKHR}},
        {"vkGetFenceWin32HandleKHR", {kFuncTypeDev, (void*)GetFenceWin32HandleKHR}},
#endif  // VK_USE_PLATFORM_WIN32_KHR
        {"vkImportFenceFdKHR", {kFuncTypeDev, (void*)ImportFenceFdKHR}},
        {"vkGetFenceFdKHR", {kFuncTypeDev, (void*)GetFenceFdKHR}},
        {"vkEnumeratePhysicalDeviceQueueFamilyPerformanceQueryCountersKHR",
         {kFuncTypePdev, (void*)EnumeratePhysicalDeviceQueueFamilyPerformanceQueryCountersKHR}},
        {"vkGetPhysicalDeviceQueueFamilyPerformanceQueryPassesKHR",
         {kFuncTypePdev, (void*)GetPhysicalDeviceQueueFamilyPerformanceQueryPassesKHR}},
        {"vkAcquireProfilingLockKHR", {kFuncTypeDev, (void*)AcquireProfilingLockKHR}},
        {"vkReleaseProfilingLockKHR", {kFuncTypeDev, (void*)ReleaseProfilingLockKHR}},
        {"vkGetPhysicalDeviceSurfaceCapabilities2KHR", {kFuncTypePdev, (void*)GetPhysicalDeviceSurfaceCapabilities2KHR}},
        {"vkGetPhysicalDeviceSurfaceFormats2KHR", {kFuncTypePdev, (void*)GetPhysicalDeviceSurfaceFormats2KHR}},
        {"vkGetPhysicalDeviceDisplayProperties2KHR", {kFuncTypePdev, (void*)GetPhysicalDeviceDisplayProperties2KHR}},
        {"vkGetPhysicalDeviceDisplayPlaneProperties2KHR", {kFuncTypePdev, (void*)GetPhysicalDeviceDisplayPlaneProperties2KHR}},
        {"vkGetDisplayModeProperties2KHR", {kFuncTypePdev, (void*)GetDisplayModeProperties2KHR}},
        {"vkGetDisplayPlaneCapabilities2KHR", {kFuncTypePdev, (void*)GetDisplayPlaneCapabilities2KHR}},
        {"vkGetImageMemoryRequirements2KHR", {kFuncTypeDev, (void*)GetImageMemoryRequirements2KHR}},
        {"vkGetBufferMemoryRequirements2KHR", {kFuncTypeDev, (void*)GetBufferMemoryRequirements2KHR}},
        {"vkGetImageSparseMemoryRequirements2KHR", {kFuncTypeDev, (void*)GetImageSparseMemoryRequirements2KHR}},
        {"vkCreateSamplerYcbcrConversionKHR", {kFuncTypeDev, (void*)CreateSamplerYcbcrConversionKHR}},
        {"vkDestroySamplerYcbcrConversionKHR", {kFuncTypeDev, (void*)DestroySamplerYcbcrConversionKHR}},
        {"vkBindBufferMemory2KHR", {kFuncTypeDev, (void*)BindBufferMemory2KHR}},
        {"vkBindImageMemory2KHR", {kFuncTypeDev, (void*)BindImageMemory2KHR}},
        {"vkGetDescriptorSetLayoutSupportKHR", {kFuncTypeDev, (void*)GetDescriptorSetLayoutSupportKHR}},
        {"vkCmdDrawIndirectCountKHR", {kFuncTypeDev, (void*)CmdDrawIndirectCountKHR}},
        {"vkCmdDrawIndexedIndirectCountKHR", {kFuncTypeDev, (void*)CmdDrawIndexedIndirectCountKHR}},
        {"vkGetSemaphoreCounterValueKHR", {kFuncTypeDev, (void*)GetSemaphoreCounterValueKHR}},
        {"vkWaitSemaphoresKHR", {kFuncTypeDev, (void*)WaitSemaphoresKHR}},
        {"vkSignalSemaphoreKHR", {kFuncTypeDev, (void*)SignalSemaphoreKHR}},
        {"vkGetPhysicalDeviceFragmentShadingRatesKHR", {kFuncTypePdev, (void*)GetPhysicalDeviceFragmentShadingRatesKHR}},
        {"vkCmdSetFragmentShadingRateKHR", {kFuncTypeDev, (void*)CmdSetFragmentShadingRateKHR}},
        {"vkCmdSetRenderingAttachmentLocationsKHR", {kFuncTypeDev, (void*)CmdSetRenderingAttachmentLocationsKHR}},
        {"vkCmdSetRenderingInputAttachmentIndicesKHR", {kFuncTypeDev, (void*)CmdSetRenderingInputAttachmentIndicesKHR}},
        {"vkWaitForPresentKHR", {kFuncTypeDev, (void*)WaitForPresentKHR}},
        {"vkGetBufferDeviceAddressKHR", {kFuncTypeDev, (void*)GetBufferDeviceAddressKHR}},
        {"vkGetBufferOpaqueCaptureAddressKHR", {kFuncTypeDev, (void*)GetBufferOpaqueCaptureAddressKHR}},
        {"vkGetDeviceMemoryOpaqueCaptureAddressKHR", {kFuncTypeDev, (void*)GetDeviceMemoryOpaqueCaptureAddressKHR}},
        {"vkCreateDeferredOperationKHR", {kFuncTypeDev, (void*)CreateDeferredOperationKHR}},
        {"vkDestroyDeferredOperationKHR", {kFuncTypeDev, (void*)DestroyDeferredOperationKHR}},
        {"vkGetDeferredOperationMaxConcurrencyKHR", {kFuncTypeDev, (void*)GetDeferredOperationMaxConcurrencyKHR}},
        {"vkGetDeferredOperationResultKHR", {kFuncTypeDev, (void*)GetDeferredOperationResultKHR}},
        {"vkDeferredOperationJoinKHR", {kFuncTypeDev, (void*)DeferredOperationJoinKHR}},
        {"vkGetPipelineExecutablePropertiesKHR", {kFuncTypeDev, (void*)GetPipelineExecutablePropertiesKHR}},
        {"vkGetPipelineExecutableStatisticsKHR", {kFuncTypeDev, (void*)GetPipelineExecutableStatisticsKHR}},
        {"vkGetPipelineExecutableInternalRepresentationsKHR",
         {kFuncTypeDev, (void*)GetPipelineExecutableInternalRepresentationsKHR}},
        {"vkMapMemory2KHR", {kFuncTypeDev, (void*)MapMemory2KHR}},
        {"vkUnmapMemory2KHR", {kFuncTypeDev, (void*)UnmapMemory2KHR}},
        {"vkGetPhysicalDeviceVideoEncodeQualityLevelPropertiesKHR",
         {kFuncTypePdev, (void*)GetPhysicalDeviceVideoEncodeQualityLevelPropertiesKHR}},
        {"vkGetEncodedVideoSessionParametersKHR", {kFuncTypeDev, (void*)GetEncodedVideoSessionParametersKHR}},
        {"vkCmdEncodeVideoKHR", {kFuncTypeDev, (void*)CmdEncodeVideoKHR}},
        {"vkCmdSetEvent2KHR", {kFuncTypeDev, (void*)CmdSetEvent2KHR}},
        {"vkCmdResetEvent2KHR", {kFuncTypeDev, (void*)CmdResetEvent2KHR}},
        {"vkCmdWaitEvents2KHR", {kFuncTypeDev, (void*)CmdWaitEvents2KHR}},
        {"vkCmdPipelineBarrier2KHR", {kFuncTypeDev, (void*)CmdPipelineBarrier2KHR}},
        {"vkCmdWriteTimestamp2KHR", {kFuncTypeDev, (void*)CmdWriteTimestamp2KHR}},
        {"vkQueueSubmit2KHR", {kFuncTypeDev, (void*)QueueSubmit2KHR}},
        {"vkCmdCopyBuffer2KHR", {kFuncTypeDev, (void*)CmdCopyBuffer2KHR}},
        {"vkCmdCopyImage2KHR", {kFuncTypeDev, (void*)CmdCopyImage2KHR}},
        {"vkCmdCopyBufferToImage2KHR", {kFuncTypeDev, (void*)CmdCopyBufferToImage2KHR}},
        {"vkCmdCopyImageToBuffer2KHR", {kFuncTypeDev, (void*)CmdCopyImageToBuffer2KHR}},
        {"vkCmdBlitImage2KHR", {kFuncTypeDev, (void*)CmdBlitImage2KHR}},
        {"vkCmdResolveImage2KHR", {kFuncTypeDev, (void*)CmdResolveImage2KHR}},
        {"vkCmdTraceRaysIndirect2KHR", {kFuncTypeDev, (void*)CmdTraceRaysIndirect2KHR}},
        {"vkGetDeviceBufferMemoryRequirementsKHR", {kFuncTypeDev, (void*)GetDeviceBufferMemoryRequirementsKHR}},
        {"vkGetDeviceImageMemoryRequirementsKHR", {kFuncTypeDev, (void*)GetDeviceImageMemoryRequirementsKHR}},
        {"vkGetDeviceImageSparseMemoryRequirementsKHR", {kFuncTypeDev, (void*)GetDeviceImageSparseMemoryRequirementsKHR}},
        {"vkCmdBindIndexBuffer2KHR", {kFuncTypeDev, (void*)CmdBindIndexBuffer2KHR}},
        {"vkGetRenderingAreaGranularityKHR", {kFuncTypeDev, (void*)GetRenderingAreaGranularityKHR}},
        {"vkGetDeviceImageSubresourceLayoutKHR", {kFuncTypeDev, (void*)GetDeviceImageSubresourceLayoutKHR}},
        {"vkGetImageSubresourceLayout2KHR", {kFuncTypeDev, (void*)GetImageSubresourceLayout2KHR}},
        {"vkWaitForPresent2KHR", {kFuncTypeDev, (void*)WaitForPresent2KHR}},
        {"vkCreatePipelineBinariesKHR", {kFuncTypeDev, (void*)CreatePipelineBinariesKHR}},
        {"vkDestroyPipelineBinaryKHR", {kFuncTypeDev, (void*)DestroyPipelineBinaryKHR}},
        {"vkGetPipelineKeyKHR", {kFuncTypeDev, (void*)GetPipelineKeyKHR}},
        {"vkGetPipelineBinaryDataKHR", {kFuncTypeDev, (void*)GetPipelineBinaryDataKHR}},
        {"vkReleaseCapturedPipelineDataKHR", {kFuncTypeDev, (void*)ReleaseCapturedPipelineDataKHR}},
        {"vkReleaseSwapchainImagesKHR", {kFuncTypeDev, (void*)ReleaseSwapchainImagesKHR}},
        {"vkGetPhysicalDeviceCooperativeMatrixPropertiesKHR",
         {kFuncTypePdev, (void*)GetPhysicalDeviceCooperativeMatrixPropertiesKHR}},
        {"vkCmdSetLineStippleKHR", {kFuncTypeDev, (void*)CmdSetLineStippleKHR}},
        {"vkGetPhysicalDeviceCalibrateableTimeDomainsKHR", {kFuncTypePdev, (void*)GetPhysicalDeviceCalibrateableTimeDomainsKHR}},
        {"vkGetCalibratedTimestampsKHR", {kFuncTypeDev, (void*)GetCalibratedTimestampsKHR}},
        {"vkCmdBindDescriptorSets2KHR", {kFuncTypeDev, (void*)CmdBindDescriptorSets2KHR}},
        {"vkCmdPushConstants2KHR", {kFuncTypeDev, (void*)CmdPushConstants2KHR}},
        {"vkCmdPushDescriptorSet2KHR", {kFuncTypeDev, (void*)CmdPushDescriptorSet2KHR}},
        {"vkCmdPushDescriptorSetWithTemplate2KHR", {kFuncTypeDev, (void*)CmdPushDescriptorSetWithTemplate2KHR}},
        {"vkCmdSetDescriptorBufferOffsets2EXT", {kFuncTypeDev, (void*)CmdSetDescriptorBufferOffsets2EXT}},
        {"vkCmdBindDescriptorBufferEmbeddedSamplers2EXT", {kFuncTypeDev, (void*)CmdBindDescriptorBufferEmbeddedSamplers2EXT}},
        {"vkCmdCopyMemoryIndirectKHR", {kFuncTypeDev, (void*)CmdCopyMemoryIndirectKHR}},
        {"vkCmdCopyMemoryToImageIndirectKHR", {kFuncTypeDev, (void*)CmdCopyMemoryToImageIndirectKHR}},
        {"vkCmdEndRendering2KHR", {kFuncTypeDev, (void*)CmdEndRendering2KHR}},
        {"vkCreateDebugReportCallbackEXT", {kFuncTypeInst, (void*)CreateDebugReportCallbackEXT}},
        {"vkDestroyDebugReportCallbackEXT", {kFuncTypeInst, (void*)DestroyDebugReportCallbackEXT}},
        {"vkDebugReportMessageEXT", {kFuncTypeInst, (void*)DebugReportMessageEXT}},
        {"vkDebugMarkerSetObjectTagEXT", {kFuncTypeDev, (void*)DebugMarkerSetObjectTagEXT}},
        {"vkDebugMarkerSetObjectNameEXT", {kFuncTypeDev, (void*)DebugMarkerSetObjectNameEXT}},
        {"vkCmdDebugMarkerBeginEXT", {kFuncTypeDev, (void*)CmdDebugMarkerBeginEXT}},
        {"vkCmdDebugMarkerEndEXT", {kFuncTypeDev, (void*)CmdDebugMarkerEndEXT}},
        {"vkCmdDebugMarkerInsertEXT", {kFuncTypeDev, (void*)CmdDebugMarkerInsertEXT}},
        {"vkCmdBindTransformFeedbackBuffersEXT", {kFuncTypeDev, (void*)CmdBindTransformFeedbackBuffersEXT}},
        {"vkCmdBeginTransformFeedbackEXT", {kFuncTypeDev, (void*)CmdBeginTransformFeedbackEXT}},
        {"vkCmdEndTransformFeedbackEXT", {kFuncTypeDev, (void*)CmdEndTransformFeedbackEXT}},
        {"vkCmdBeginQueryIndexedEXT", {kFuncTypeDev, (void*)CmdBeginQueryIndexedEXT}},
        {"vkCmdEndQueryIndexedEXT", {kFuncTypeDev, (void*)CmdEndQueryIndexedEXT}},
        {"vkCmdDrawIndirectByteCountEXT", {kFuncTypeDev, (void*)CmdDrawIndirectByteCountEXT}},
        {"vkCreateCuModuleNVX", {kFuncTypeDev, (void*)CreateCuModuleNVX}},
        {"vkCreateCuFunctionNVX", {kFuncTypeDev, (void*)CreateCuFunctionNVX}},
        {"vkDestroyCuModuleNVX", {kFuncTypeDev, (void*)DestroyCuModuleNVX}},
        {"vkDestroyCuFunctionNVX", {kFuncTypeDev, (void*)DestroyCuFunctionNVX}},
        {"vkCmdCuLaunchKernelNVX", {kFuncTypeDev, (void*)CmdCuLaunchKernelNVX}},
        {"vkGetImageViewHandleNVX", {kFuncTypeDev, (void*)GetImageViewHandleNVX}},
        {"vkGetImageViewHandle64NVX", {kFuncTypeDev, (void*)GetImageViewHandle64NVX}},
        {"vkGetImageViewAddressNVX", {kFuncTypeDev, (void*)GetImageViewAddressNVX}},
        {"vkGetDeviceCombinedImageSamplerIndexNVX", {kFuncTypeDev, (void*)GetDeviceCombinedImageSamplerIndexNVX}},
        {"vkCmdDrawIndirectCountAMD", {kFuncTypeDev, (void*)CmdDrawIndirectCountAMD}},
        {"vkCmdDrawIndexedIndirectCountAMD", {kFuncTypeDev, (void*)CmdDrawIndexedIndirectCountAMD}},
        {"vkGetShaderInfoAMD", {kFuncTypeDev, (void*)GetShaderInfoAMD}},
#ifdef VK_USE_PLATFORM_GGP
        {"vkCreateStreamDescriptorSurfaceGGP", {kFuncTypeInst, (void*)CreateStreamDescriptorSurfaceGGP}},
#endif  // VK_USE_PLATFORM_GGP
        {"vkGetPhysicalDeviceExternalImageFormatPropertiesNV",
         {kFuncTypePdev, (void*)GetPhysicalDeviceExternalImageFormatPropertiesNV}},
#ifdef VK_USE_PLATFORM_WIN32_KHR
        {"vkGetMemoryWin32HandleNV", {kFuncTypeDev, (void*)GetMemoryWin32HandleNV}},
#endif  // VK_USE_PLATFORM_WIN32_KHR
#ifdef VK_USE_PLATFORM_VI_NN
        {"vkCreateViSurfaceNN", {kFuncTypeInst, (void*)CreateViSurfaceNN}},
#endif  // VK_USE_PLATFORM_VI_NN
        {"vkCmdBeginConditionalRenderingEXT", {kFuncTypeDev, (void*)CmdBeginConditionalRenderingEXT}},
        {"vkCmdEndConditionalRenderingEXT", {kFuncTypeDev, (void*)CmdEndConditionalRenderingEXT}},
        {"vkCmdSetViewportWScalingNV", {kFuncTypeDev, (void*)CmdSetViewportWScalingNV}},
        {"vkReleaseDisplayEXT", {kFuncTypePdev, (void*)ReleaseDisplayEXT}},
#ifdef VK_USE_PLATFORM_XLIB_XRANDR_EXT
        {"vkAcquireXlibDisplayEXT", {kFuncTypePdev, (void*)AcquireXlibDisplayEXT}},
        {"vkGetRandROutputDisplayEXT", {kFuncTypePdev, (void*)GetRandROutputDisplayEXT}},
#endif  // VK_USE_PLATFORM_XLIB_XRANDR_EXT
        {"vkGetPhysicalDeviceSurfaceCapabilities2EXT", {kFuncTypePdev, (void*)GetPhysicalDeviceSurfaceCapabilities2EXT}},
        {"vkDisplayPowerControlEXT", {kFuncTypeDev, (void*)DisplayPowerControlEXT}},
        {"vkRegisterDeviceEventEXT", {kFuncTypeDev, (void*)RegisterDeviceEventEXT}},
        {"vkRegisterDisplayEventEXT", {kFuncTypeDev, (void*)RegisterDisplayEventEXT}},
        {"vkGetSwapchainCounterEXT", {kFuncTypeDev, (void*)GetSwapchainCounterEXT}},
        {"vkGetRefreshCycleDurationGOOGLE", {kFuncTypeDev, (void*)GetRefreshCycleDurationGOOGLE}},
        {"vkGetPastPresentationTimingGOOGLE", {kFuncTypeDev, (void*)GetPastPresentationTimingGOOGLE}},
        {"vkCmdSetDiscardRectangleEXT", {kFuncTypeDev, (void*)CmdSetDiscardRectangleEXT}},
        {"vkCmdSetDiscardRectangleEnableEXT", {kFuncTypeDev, (void*)CmdSetDiscardRectangleEnableEXT}},
        {"vkCmdSetDiscardRectangleModeEXT", {kFuncTypeDev, (void*)CmdSetDiscardRectangleModeEXT}},
        {"vkSetHdrMetadataEXT", {kFuncTypeDev, (void*)SetHdrMetadataEXT}},
#ifdef VK_USE_PLATFORM_IOS_MVK
        {"vkCreateIOSSurfaceMVK", {kFuncTypeInst, (void*)CreateIOSSurfaceMVK}},
#endif  // VK_USE_PLATFORM_IOS_MVK
#ifdef VK_USE_PLATFORM_MACOS_MVK
        {"vkCreateMacOSSurfaceMVK", {kFuncTypeInst, (void*)CreateMacOSSurfaceMVK}},
#endif  // VK_USE_PLATFORM_MACOS_MVK
        {"vkSetDebugUtilsObjectNameEXT", {kFuncTypeDev, (void*)SetDebugUtilsObjectNameEXT}},
        {"vkSetDebugUtilsObjectTagEXT", {kFuncTypeDev, (void*)SetDebugUtilsObjectTagEXT}},
        {"vkQueueBeginDebugUtilsLabelEXT", {kFuncTypeDev, (void*)QueueBeginDebugUtilsLabelEXT}},
        {"vkQueueEndDebugUtilsLabelEXT", {kFuncTypeDev, (void*)QueueEndDebugUtilsLabelEXT}},
        {"vkQueueInsertDebugUtilsLabelEXT", {kFuncTypeDev, (void*)QueueInsertDebugUtilsLabelEXT}},
        {"vkCmdBeginDebugUtilsLabelEXT", {kFuncTypeDev, (void*)CmdBeginDebugUtilsLabelEXT}},
        {"vkCmdEndDebugUtilsLabelEXT", {kFuncTypeDev, (void*)CmdEndDebugUtilsLabelEXT}},
        {"vkCmdInsertDebugUtilsLabelEXT", {kFuncTypeDev, (void*)CmdInsertDebugUtilsLabelEXT}},
        {"vkCreateDebugUtilsMessengerEXT", {kFuncTypeInst, (void*)CreateDebugUtilsMessengerEXT}},
        {"vkDestroyDebugUtilsMessengerEXT", {kFuncTypeInst, (void*)DestroyDebugUtilsMessengerEXT}},
        {"vkSubmitDebugUtilsMessageEXT", {kFuncTypeInst, (void*)SubmitDebugUtilsMessageEXT}},
#ifdef VK_USE_PLATFORM_ANDROID_KHR
        {"vkGetAndroidHardwareBufferPropertiesANDROID", {kFuncTypeDev, (void*)GetAndroidHardwareBufferPropertiesANDROID}},
        {"vkGetMemoryAndroidHardwareBufferANDROID", {kFuncTypeDev, (void*)GetMemoryAndroidHardwareBufferANDROID}},
#endif  // VK_USE_PLATFORM_ANDROID_KHR
#ifdef VK_ENABLE_BETA_EXTENSIONS
        {"vkCreateExecutionGraphPipelinesAMDX", {kFuncTypeDev, (void*)CreateExecutionGraphPipelinesAMDX}},
        {"vkGetExecutionGraphPipelineScratchSizeAMDX", {kFuncTypeDev, (void*)GetExecutionGraphPipelineScratchSizeAMDX}},
        {"vkGetExecutionGraphPipelineNodeIndexAMDX", {kFuncTypeDev, (void*)GetExecutionGraphPipelineNodeIndexAMDX}},
        {"vkCmdInitializeGraphScratchMemoryAMDX", {kFuncTypeDev, (void*)CmdInitializeGraphScratchMemoryAMDX}},
        {"vkCmdDispatchGraphAMDX", {kFuncTypeDev, (void*)CmdDispatchGraphAMDX}},
        {"vkCmdDispatchGraphIndirectAMDX", {kFuncTypeDev, (void*)CmdDispatchGraphIndirectAMDX}},
        {"vkCmdDispatchGraphIndirectCountAMDX", {kFuncTypeDev, (void*)CmdDispatchGraphIndirectCountAMDX}},
#endif  // VK_ENABLE_BETA_EXTENSIONS
        {"vkWriteSamplerDescriptorsEXT", {kFuncTypeDev, (void*)WriteSamplerDescriptorsEXT}},
        {"vkWriteResourceDescriptorsEXT", {kFuncTypeDev, (void*)WriteResourceDescriptorsEXT}},
        {"vkCmdBindSamplerHeapEXT", {kFuncTypeDev, (void*)CmdBindSamplerHeapEXT}},
        {"vkCmdBindResourceHeapEXT", {kFuncTypeDev, (void*)CmdBindResourceHeapEXT}},
        {"vkCmdPushDataEXT", {kFuncTypeDev, (void*)CmdPushDataEXT}},
        {"vkGetImageOpaqueCaptureDataEXT", {kFuncTypeDev, (void*)GetImageOpaqueCaptureDataEXT}},
        {"vkGetPhysicalDeviceDescriptorSizeEXT", {kFuncTypePdev, (void*)GetPhysicalDeviceDescriptorSizeEXT}},
        {"vkRegisterCustomBorderColorEXT", {kFuncTypeDev, (void*)RegisterCustomBorderColorEXT}},
        {"vkUnregisterCustomBorderColorEXT", {kFuncTypeDev, (void*)UnregisterCustomBorderColorEXT}},
        {"vkGetTensorOpaqueCaptureDataARM", {kFuncTypeDev, (void*)GetTensorOpaqueCaptureDataARM}},
        {"vkCmdSetSampleLocationsEXT", {kFuncTypeDev, (void*)CmdSetSampleLocationsEXT}},
        {"vkGetPhysicalDeviceMultisamplePropertiesEXT", {kFuncTypePdev, (void*)GetPhysicalDeviceMultisamplePropertiesEXT}},
        {"vkGetImageDrmFormatModifierPropertiesEXT", {kFuncTypeDev, (void*)GetImageDrmFormatModifierPropertiesEXT}},
        {"vkCreateValidationCacheEXT", {kFuncTypeDev, (void*)CreateValidationCacheEXT}},
        {"vkDestroyValidationCacheEXT", {kFuncTypeDev, (void*)DestroyValidationCacheEXT}},
        {"vkMergeValidationCachesEXT", {kFuncTypeDev, (void*)MergeValidationCachesEXT}},
        {"vkGetValidationCacheDataEXT", {kFuncTypeDev, (void*)GetValidationCacheDataEXT}},
        {"vkCmdBindShadingRateImageNV", {kFuncTypeDev, (void*)CmdBindShadingRateImageNV}},
        {"vkCmdSetViewportShadingRatePaletteNV", {kFuncTypeDev, (void*)CmdSetViewportShadingRatePaletteNV}},
        {"vkCmdSetCoarseSampleOrderNV", {kFuncTypeDev, (void*)CmdSetCoarseSampleOrderNV}},
        {"vkCreateAccelerationStructureNV", {kFuncTypeDev, (void*)CreateAccelerationStructureNV}},
        {"vkDestroyAccelerationStructureNV", {kFuncTypeDev, (void*)DestroyAccelerationStructureNV}},
        {"vkGetAccelerationStructureMemoryRequirementsNV", {kFuncTypeDev, (void*)GetAccelerationStructureMemoryRequirementsNV}},
        {"vkBindAccelerationStructureMemoryNV", {kFuncTypeDev, (void*)BindAccelerationStructureMemoryNV}},
        {"vkCmdBuildAccelerationStructureNV", {kFuncTypeDev, (void*)CmdBuildAccelerationStructureNV}},
        {"vkCmdCopyAccelerationStructureNV", {kFuncTypeDev, (void*)CmdCopyAccelerationStructureNV}},
        {"vkCmdTraceRaysNV", {kFuncTypeDev, (void*)CmdTraceRaysNV}},
        {"vkCreateRayTracingPipelinesNV", {kFuncTypeDev, (void*)CreateRayTracingPipelinesNV}},
        {"vkGetRayTracingShaderGroupHandlesKHR", {kFuncTypeDev, (void*)GetRayTracingShaderGroupHandlesKHR}},
        {"vkGetRayTracingShaderGroupHandlesNV", {kFuncTypeDev, (void*)GetRayTracingShaderGroupHandlesNV}},
        {"vkGetAccelerationStructureHandleNV", {kFuncTypeDev, (void*)GetAccelerationStructureHandleNV}},
        {"vkCmdWriteAccelerationStructuresPropertiesNV", {kFuncTypeDev, (void*)CmdWriteAccelerationStructuresPropertiesNV}},
        {"vkCompileDeferredNV", {kFuncTypeDev, (void*)CompileDeferredNV}},
        {"vkGetMemoryHostPointerPropertiesEXT", {kFuncTypeDev, (void*)GetMemoryHostPointerPropertiesEXT}},
        {"vkCmdWriteBufferMarkerAMD", {kFuncTypeDev, (void*)CmdWriteBufferMarkerAMD}},
        {"vkCmdWriteBufferMarker2AMD", {kFuncTypeDev, (void*)CmdWriteBufferMarker2AMD}},
        {"vkGetPhysicalDeviceCalibrateableTimeDomainsEXT", {kFuncTypePdev, (void*)GetPhysicalDeviceCalibrateableTimeDomainsEXT}},
        {"vkGetCalibratedTimestampsEXT", {kFuncTypeDev, (void*)GetCalibratedTimestampsEXT}},
        {"vkCmdDrawMeshTasksNV", {kFuncTypeDev, (void*)CmdDrawMeshTasksNV}},
        {"vkCmdDrawMeshTasksIndirectNV", {kFuncTypeDev, (void*)CmdDrawMeshTasksIndirectNV}},
        {"vkCmdDrawMeshTasksIndirectCountNV", {kFuncTypeDev, (void*)CmdDrawMeshTasksIndirectCountNV}},
        {"vkCmdSetExclusiveScissorEnableNV", {kFuncTypeDev, (void*)CmdSetExclusiveScissorEnableNV}},
        {"vkCmdSetExclusiveScissorNV", {kFuncTypeDev, (void*)CmdSetExclusiveScissorNV}},
        {"vkCmdSetCheckpointNV", {kFuncTypeDev, (void*)CmdSetCheckpointNV}},
        {"vkGetQueueCheckpointDataNV", {kFuncTypeDev, (void*)GetQueueCheckpointDataNV}},
        {"vkGetQueueCheckpointData2NV", {kFuncTypeDev, (void*)GetQueueCheckpointData2NV}},
        {"vkSetSwapchainPresentTimingQueueSizeEXT", {kFuncTypeDev, (void*)SetSwapchainPresentTimingQueueSizeEXT}},
        {"vkGetSwapchainTimingPropertiesEXT", {kFuncTypeDev, (void*)GetSwapchainTimingPropertiesEXT}},
        {"vkGetSwapchainTimeDomainPropertiesEXT", {kFuncTypeDev, (void*)GetSwapchainTimeDomainPropertiesEXT}},
        {"vkGetPastPresentationTimingEXT", {kFuncTypeDev, (void*)GetPastPresentationTimingEXT}},
        {"vkInitializePerformanceApiINTEL", {kFuncTypeDev, (void*)InitializePerformanceApiINTEL}},
        {"vkUninitializePerformanceApiINTEL", {kFuncTypeDev, (void*)UninitializePerformanceApiINTEL}},
        {"vkCmdSetPerformanceMarkerINTEL", {kFuncTypeDev, (void*)CmdSetPerformanceMarkerINTEL}},
        {"vkCmdSetPerformanceStreamMarkerINTEL", {kFuncTypeDev, (void*)CmdSetPerformanceStreamMarkerINTEL}},
        {"vkCmdSetPerformanceOverrideINTEL", {kFuncTypeDev, (void*)CmdSetPerformanceOverrideINTEL}},
        {"vkAcquirePerformanceConfigurationINTEL", {kFuncTypeDev, (void*)AcquirePerformanceConfigurationINTEL}},
        {"vkReleasePerformanceConfigurationINTEL", {kFuncTypeDev, (void*)ReleasePerformanceConfigurationINTEL}},
        {"vkQueueSetPerformanceConfigurationINTEL", {kFuncTypeDev, (void*)QueueSetPerformanceConfigurationINTEL}},
        {"vkGetPerformanceParameterINTEL", {kFuncTypeDev, (void*)GetPerformanceParameterINTEL}},
        {"vkSetLocalDimmingAMD", {kFuncTypeDev, (void*)SetLocalDimmingAMD}},
#ifdef VK_USE_PLATFORM_FUCHSIA
        {"vkCreateImagePipeSurfaceFUCHSIA", {kFuncTypeInst, (void*)CreateImagePipeSurfaceFUCHSIA}},
#endif  // VK_USE_PLATFORM_FUCHSIA
#ifdef VK_USE_PLATFORM_METAL_EXT
        {"vkCreateMetalSurfaceEXT", {kFuncTypeInst, (void*)CreateMetalSurfaceEXT}},
#endif  // VK_USE_PLATFORM_METAL_EXT
        {"vkGetBufferDeviceAddressEXT", {kFuncTypeDev, (void*)GetBufferDeviceAddressEXT}},
        {"vkGetPhysicalDeviceToolPropertiesEXT", {kFuncTypePdev, (void*)GetPhysicalDeviceToolPropertiesEXT}},
        {"vkGetPhysicalDeviceCooperativeMatrixPropertiesNV",
         {kFuncTypePdev, (void*)GetPhysicalDeviceCooperativeMatrixPropertiesNV}},
        {"vkGetPhysicalDeviceSupportedFramebufferMixedSamplesCombinationsNV",
         {kFuncTypePdev, (void*)GetPhysicalDeviceSupportedFramebufferMixedSamplesCombinationsNV}},
#ifdef VK_USE_PLATFORM_WIN32_KHR
        {"vkGetPhysicalDeviceSurfacePresentModes2EXT", {kFuncTypePdev, (void*)GetPhysicalDeviceSurfacePresentModes2EXT}},
        {"vkAcquireFullScreenExclusiveModeEXT", {kFuncTypeDev, (void*)AcquireFullScreenExclusiveModeEXT}},
        {"vkReleaseFullScreenExclusiveModeEXT", {kFuncTypeDev, (void*)ReleaseFullScreenExclusiveModeEXT}},
        {"vkGetDeviceGroupSurfacePresentModes2EXT", {kFuncTypeDev, (void*)GetDeviceGroupSurfacePresentModes2EXT}},
#endif  // VK_USE_PLATFORM_WIN32_KHR
        {"vkCreateHeadlessSurfaceEXT", {kFuncTypeInst, (void*)CreateHeadlessSurfaceEXT}},
        {"vkCmdSetLineStippleEXT", {kFuncTypeDev, (void*)CmdSetLineStippleEXT}},
        {"vkResetQueryPoolEXT", {kFuncTypeDev, (void*)ResetQueryPoolEXT}},
        {"vkCmdSetCullModeEXT", {kFuncTypeDev, (void*)CmdSetCullModeEXT}},
        {"vkCmdSetFrontFaceEXT", {kFuncTypeDev, (void*)CmdSetFrontFaceEXT}},
        {"vkCmdSetPrimitiveTopologyEXT", {kFuncTypeDev, (void*)CmdSetPrimitiveTopologyEXT}},
        {"vkCmdSetViewportWithCountEXT", {kFuncTypeDev, (void*)CmdSetViewportWithCountEXT}},
        {"vkCmdSetScissorWithCountEXT", {kFuncTypeDev, (void*)CmdSetScissorWithCountEXT}},
        {"vkCmdBindVertexBuffers2EXT", {kFuncTypeDev, (void*)CmdBindVertexBuffers2EXT}},
        {"vkCmdSetDepthTestEnableEXT", {kFuncTypeDev, (void*)CmdSetDepthTestEnableEXT}},
        {"vkCmdSetDepthWriteEnableEXT", {kFuncTypeDev, (void*)CmdSetDepthWriteEnableEXT}},
        {"vkCmdSetDepthCompareOpEXT", {kFuncTypeDev, (void*)CmdSetDepthCompareOpEXT}},
        {"vkCmdSetDepthBoundsTestEnableEXT", {kFuncTypeDev, (void*)CmdSetDepthBoundsTestEnableEXT}},
        {"vkCmdSetStencilTestEnableEXT", {kFuncTypeDev, (void*)CmdSetStencilTestEnableEXT}},
        {"vkCmdSetStencilOpEXT", {kFuncTypeDev, (void*)CmdSetStencilOpEXT}},
        {"vkCopyMemoryToImageEXT", {kFuncTypeDev, (void*)CopyMemoryToImageEXT}},
        {"vkCopyImageToMemoryEXT", {kFuncTypeDev, (void*)CopyImageToMemoryEXT}},
        {"vkCopyImageToImageEXT", {kFuncTypeDev, (void*)CopyImageToImageEXT}},
        {"vkTransitionImageLayoutEXT", {kFuncTypeDev, (void*)TransitionImageLayoutEXT}},
        {"vkGetImageSubresourceLayout2EXT", {kFuncTypeDev, (void*)GetImageSubresourceLayout2EXT}},
        {"vkReleaseSwapchainImagesEXT", {kFuncTypeDev, (void*)ReleaseSwapchainImagesEXT}},
        {"vkGetGeneratedCommandsMemoryRequirementsNV", {kFuncTypeDev, (void*)GetGeneratedCommandsMemoryRequirementsNV}},
        {"vkCmdPreprocessGeneratedCommandsNV", {kFuncTypeDev, (void*)CmdPreprocessGeneratedCommandsNV}},
        {"vkCmdExecuteGeneratedCommandsNV", {kFuncTypeDev, (void*)CmdExecuteGeneratedCommandsNV}},
        {"vkCmdBindPipelineShaderGroupNV", {kFuncTypeDev, (void*)CmdBindPipelineShaderGroupNV}},
        {"vkCreateIndirectCommandsLayoutNV", {kFuncTypeDev, (void*)CreateIndirectCommandsLayoutNV}},
        {"vkDestroyIndirectCommandsLayoutNV", {kFuncTypeDev, (void*)DestroyIndirectCommandsLayoutNV}},
        {"vkCmdSetDepthBias2EXT", {kFuncTypeDev, (void*)CmdSetDepthBias2EXT}},
        {"vkAcquireDrmDisplayEXT", {kFuncTypePdev, (void*)AcquireDrmDisplayEXT}},
        {"vkGetDrmDisplayEXT", {kFuncTypePdev, (void*)GetDrmDisplayEXT}},
        {"vkCreatePrivateDataSlotEXT", {kFuncTypeDev, (void*)CreatePrivateDataSlotEXT}},
        {"vkDestroyPrivateDataSlotEXT", {kFuncTypeDev, (void*)DestroyPrivateDataSlotEXT}},
        {"vkSetPrivateDataEXT", {kFuncTypeDev, (void*)SetPrivateDataEXT}},
        {"vkGetPrivateDataEXT", {kFuncTypeDev, (void*)GetPrivateDataEXT}},
#ifdef VK_ENABLE_BETA_EXTENSIONS
        {"vkCreateCudaModuleNV", {kFuncTypeDev, (void*)CreateCudaModuleNV}},
        {"vkGetCudaModuleCacheNV", {kFuncTypeDev, (void*)GetCudaModuleCacheNV}},
        {"vkCreateCudaFunctionNV", {kFuncTypeDev, (void*)CreateCudaFunctionNV}},
        {"vkDestroyCudaModuleNV", {kFuncTypeDev, (void*)DestroyCudaModuleNV}},
        {"vkDestroyCudaFunctionNV", {kFuncTypeDev, (void*)DestroyCudaFunctionNV}},
        {"vkCmdCudaLaunchKernelNV", {kFuncTypeDev, (void*)CmdCudaLaunchKernelNV}},
#endif  // VK_ENABLE_BETA_EXTENSIONS
        {"vkCmdDispatchTileQCOM", {kFuncTypeDev, (void*)CmdDispatchTileQCOM}},
        {"vkCmdBeginPerTileExecutionQCOM", {kFuncTypeDev, (void*)CmdBeginPerTileExecutionQCOM}},
        {"vkCmdEndPerTileExecutionQCOM", {kFuncTypeDev, (void*)CmdEndPerTileExecutionQCOM}},
#ifdef VK_USE_PLATFORM_METAL_EXT
        {"vkExportMetalObjectsEXT", {kFuncTypeDev, (void*)ExportMetalObjectsEXT}},
#endif  // VK_USE_PLATFORM_METAL_EXT
        {"vkGetDescriptorSetLayoutSizeEXT", {kFuncTypeDev, (void*)GetDescriptorSetLayoutSizeEXT}},
        {"vkGetDescriptorSetLayoutBindingOffsetEXT", {kFuncTypeDev, (void*)GetDescriptorSetLayoutBindingOffsetEXT}},
        {"vkGetDescriptorEXT", {kFuncTypeDev, (void*)GetDescriptorEXT}},
        {"vkCmdBindDescriptorBuffersEXT", {kFuncTypeDev, (void*)CmdBindDescriptorBuffersEXT}},
        {"vkCmdSetDescriptorBufferOffsetsEXT", {kFuncTypeDev, (void*)CmdSetDescriptorBufferOffsetsEXT}},
        {"vkCmdBindDescriptorBufferEmbeddedSamplersEXT", {kFuncTypeDev, (void*)CmdBindDescriptorBufferEmbeddedSamplersEXT}},
        {"vkGetBufferOpaqueCaptureDescriptorDataEXT", {kFuncTypeDev, (void*)GetBufferOpaqueCaptureDescriptorDataEXT}},
        {"vkGetImageOpaqueCaptureDescriptorDataEXT", {kFuncTypeDev, (void*)GetImageOpaqueCaptureDescriptorDataEXT}},
        {"vkGetImageViewOpaqueCaptureDescriptorDataEXT", {kFuncTypeDev, (void*)GetImageViewOpaqueCaptureDescriptorDataEXT}},
        {"vkGetSamplerOpaqueCaptureDescriptorDataEXT", {kFuncTypeDev, (void*)GetSamplerOpaqueCaptureDescriptorDataEXT}},
        {"vkGetAccelerationStructureOpaqueCaptureDescriptorDataEXT",
         {kFuncTypeDev, (void*)GetAccelerationStructureOpaqueCaptureDescriptorDataEXT}},
        {"vkCmdSetFragmentShadingRateEnumNV", {kFuncTypeDev, (void*)CmdSetFragmentShadingRateEnumNV}},
        {"vkGetDeviceFaultInfoEXT", {kFuncTypeDev, (void*)GetDeviceFaultInfoEXT}},
#ifdef VK_USE_PLATFORM_WIN32_KHR
        {"vkAcquireWinrtDisplayNV", {kFuncTypePdev, (void*)AcquireWinrtDisplayNV}},
        {"vkGetWinrtDisplayNV", {kFuncTypePdev, (void*)GetWinrtDisplayNV}},
#endif  // VK_USE_PLATFORM_WIN32_KHR
#ifdef VK_USE_PLATFORM_DIRECTFB_EXT
        {"vkCreateDirectFBSurfaceEXT", {kFuncTypeInst, (void*)CreateDirectFBSurfaceEXT}},
        {"vkGetPhysicalDeviceDirectFBPresentationSupportEXT",
         {kFuncTypePdev, (void*)GetPhysicalDeviceDirectFBPresentationSupportEXT}},
#endif  // VK_USE_PLATFORM_DIRECTFB_EXT
        {"vkCmdSetVertexInputEXT", {kFuncTypeDev, (void*)CmdSetVertexInputEXT}},
#ifdef VK_USE_PLATFORM_FUCHSIA
        {"vkGetMemoryZirconHandleFUCHSIA", {kFuncTypeDev, (void*)GetMemoryZirconHandleFUCHSIA}},
        {"vkGetMemoryZirconHandlePropertiesFUCHSIA", {kFuncTypeDev, (void*)GetMemoryZirconHandlePropertiesFUCHSIA}},
        {"vkImportSemaphoreZirconHandleFUCHSIA", {kFuncTypeDev, (void*)ImportSemaphoreZirconHandleFUCHSIA}},
        {"vkGetSemaphoreZirconHandleFUCHSIA", {kFuncTypeDev, (void*)GetSemaphoreZirconHandleFUCHSIA}},
        {"vkCreateBufferCollectionFUCHSIA", {kFuncTypeDev, (void*)CreateBufferCollectionFUCHSIA}},
        {"vkSetBufferCollectionImageConstraintsFUCHSIA", {kFuncTypeDev, (void*)SetBufferCollectionImageConstraintsFUCHSIA}},
        {"vkSetBufferCollectionBufferConstraintsFUCHSIA", {kFuncTypeDev, (void*)SetBufferCollectionBufferConstraintsFUCHSIA}},
        {"vkDestroyBufferCollectionFUCHSIA", {kFuncTypeDev, (void*)DestroyBufferCollectionFUCHSIA}},
        {"vkGetBufferCollectionPropertiesFUCHSIA", {kFuncTypeDev, (void*)GetBufferCollectionPropertiesFUCHSIA}},
#endif  // VK_USE_PLATFORM_FUCHSIA
        {"vkGetDeviceSubpassShadingMaxWorkgroupSizeHUAWEI", {kFuncTypeDev, (void*)GetDeviceSubpassShadingMaxWorkgroupSizeHUAWEI}},
        {"vkCmdSubpassShadingHUAWEI", {kFuncTypeDev, (void*)CmdSubpassShadingHUAWEI}},
        {"vkCmdBindInvocationMaskHUAWEI", {kFuncTypeDev, (void*)CmdBindInvocationMaskHUAWEI}},
        {"vkGetMemoryRemoteAddressNV", {kFuncTypeDev, (void*)GetMemoryRemoteAddressNV}},
        {"vkGetPipelinePropertiesEXT", {kFuncTypeDev, (void*)GetPipelinePropertiesEXT}},
        {"vkCmdSetPatchControlPointsEXT", {kFuncTypeDev, (void*)CmdSetPatchControlPointsEXT}},
        {"vkCmdSetRasterizerDiscardEnableEXT", {kFuncTypeDev, (void*)CmdSetRasterizerDiscardEnableEXT}},
        {"vkCmdSetDepthBiasEnableEXT", {kFuncTypeDev, (void*)CmdSetDepthBiasEnableEXT}},
        {"vkCmdSetLogicOpEXT", {kFuncTypeDev, (void*)CmdSetLogicOpEXT}},
        {"vkCmdSetPrimitiveRestartEnableEXT", {kFuncTypeDev, (void*)CmdSetPrimitiveRestartEnableEXT}},
#ifdef VK_USE_PLATFORM_SCREEN_QNX
        {"vkCreateScreenSurfaceQNX", {kFuncTypeInst, (void*)CreateScreenSurfaceQNX}},
        {"vkGetPhysicalDeviceScreenPresentationSupportQNX", {kFuncTypePdev, (void*)GetPhysicalDeviceScreenPresentationSupportQNX}},
#endif  // VK_USE_PLATFORM_SCREEN_QNX
        {"vkCmdSetColorWriteEnableEXT", {kFuncTypeDev, (void*)CmdSetColorWriteEnableEXT}},
        {"vkCmdDrawMultiEXT", {kFuncTypeDev, (void*)CmdDrawMultiEXT}},
        {"vkCmdDrawMultiIndexedEXT", {kFuncTypeDev, (void*)CmdDrawMultiIndexedEXT}},
        {"vkCreateMicromapEXT", {kFuncTypeDev, (void*)CreateMicromapEXT}},
        {"vkDestroyMicromapEXT", {kFuncTypeDev, (void*)DestroyMicromapEXT}},
        {"vkCmdBuildMicromapsEXT", {kFuncTypeDev, (void*)CmdBuildMicromapsEXT}},
        {"vkBuildMicromapsEXT", {kFuncTypeDev, (void*)BuildMicromapsEXT}},
        {"vkCopyMicromapEXT", {kFuncTypeDev, (void*)CopyMicromapEXT}},
        {"vkCopyMicromapToMemoryEXT", {kFuncTypeDev, (void*)CopyMicromapToMemoryEXT}},
        {"vkCopyMemoryToMicromapEXT", {kFuncTypeDev, (void*)CopyMemoryToMicromapEXT}},
        {"vkWriteMicromapsPropertiesEXT", {kFuncTypeDev, (void*)WriteMicromapsPropertiesEXT}},
        {"vkCmdCopyMicromapEXT", {kFuncTypeDev, (void*)CmdCopyMicromapEXT}},
        {"vkCmdCopyMicromapToMemoryEXT", {kFuncTypeDev, (void*)CmdCopyMicromapToMemoryEXT}},
        {"vkCmdCopyMemoryToMicromapEXT", {kFuncTypeDev, (void*)CmdCopyMemoryToMicromapEXT}},
        {"vkCmdWriteMicromapsPropertiesEXT", {kFuncTypeDev, (void*)CmdWriteMicromapsPropertiesEXT}},
        {"vkGetDeviceMicromapCompatibilityEXT", {kFuncTypeDev, (void*)GetDeviceMicromapCompatibilityEXT}},
        {"vkGetMicromapBuildSizesEXT", {kFuncTypeDev, (void*)GetMicromapBuildSizesEXT}},
        {"vkCmdDrawClusterHUAWEI", {kFuncTypeDev, (void*)CmdDrawClusterHUAWEI}},
        {"vkCmdDrawClusterIndirectHUAWEI", {kFuncTypeDev, (void*)CmdDrawClusterIndirectHUAWEI}},
        {"vkSetDeviceMemoryPriorityEXT", {kFuncTypeDev, (void*)SetDeviceMemoryPriorityEXT}},
        {"vkGetDescriptorSetLayoutHostMappingInfoVALVE", {kFuncTypeDev, (void*)GetDescriptorSetLayoutHostMappingInfoVALVE}},
        {"vkGetDescriptorSetHostMappingVALVE", {kFuncTypeDev, (void*)GetDescriptorSetHostMappingVALVE}},
        {"vkCmdCopyMemoryIndirectNV", {kFuncTypeDev, (void*)CmdCopyMemoryIndirectNV}},
        {"vkCmdCopyMemoryToImageIndirectNV", {kFuncTypeDev, (void*)CmdCopyMemoryToImageIndirectNV}},
        {"vkCmdDecompressMemoryNV", {kFuncTypeDev, (void*)CmdDecompressMemoryNV}},
        {"vkCmdDecompressMemoryIndirectCountNV", {kFuncTypeDev, (void*)CmdDecompressMemoryIndirectCountNV}},
        {"vkGetPipelineIndirectMemoryRequirementsNV", {kFuncTypeDev, (void*)GetPipelineIndirectMemoryRequirementsNV}},
        {"vkCmdUpdatePipelineIndirectBufferNV", {kFuncTypeDev, (void*)CmdUpdatePipelineIndirectBufferNV}},
        {"vkGetPipelineIndirectDeviceAddressNV", {kFuncTypeDev, (void*)GetPipelineIndirectDeviceAddressNV}},
#ifdef VK_USE_PLATFORM_OHOS
        {"vkGetNativeBufferPropertiesOHOS", {kFuncTypeDev, (void*)GetNativeBufferPropertiesOHOS}},
        {"vkGetMemoryNativeBufferOHOS", {kFuncTypeDev, (void*)GetMemoryNativeBufferOHOS}},
#endif  // VK_USE_PLATFORM_OHOS
        {"vkCmdSetDepthClampEnableEXT", {kFuncTypeDev, (void*)CmdSetDepthClampEnableEXT}},
        {"vkCmdSetPolygonModeEXT", {kFuncTypeDev, (void*)CmdSetPolygonModeEXT}},
        {"vkCmdSetRasterizationSamplesEXT", {kFuncTypeDev, (void*)CmdSetRasterizationSamplesEXT}},
        {"vkCmdSetSampleMaskEXT", {kFuncTypeDev, (void*)CmdSetSampleMaskEXT}},
        {"vkCmdSetAlphaToCoverageEnableEXT", {kFuncTypeDev, (void*)CmdSetAlphaToCoverageEnableEXT}},
        {"vkCmdSetAlphaToOneEnableEXT", {kFuncTypeDev, (void*)CmdSetAlphaToOneEnableEXT}},
        {"vkCmdSetLogicOpEnableEXT", {kFuncTypeDev, (void*)CmdSetLogicOpEnableEXT}},
        {"vkCmdSetColorBlendEnableEXT", {kFuncTypeDev, (void*)CmdSetColorBlendEnableEXT}},
        {"vkCmdSetColorBlendEquationEXT", {kFuncTypeDev, (void*)CmdSetColorBlendEquationEXT}},
        {"vkCmdSetColorWriteMaskEXT", {kFuncTypeDev, (void*)CmdSetColorWriteMaskEXT}},
        {"vkCmdSetTessellationDomainOriginEXT", {kFuncTypeDev, (void*)CmdSetTessellationDomainOriginEXT}},
        {"vkCmdSetRasterizationStreamEXT", {kFuncTypeDev, (void*)CmdSetRasterizationStreamEXT}},
        {"vkCmdSetConservativeRasterizationModeEXT", {kFuncTypeDev, (void*)CmdSetConservativeRasterizationModeEXT}},
        {"vkCmdSetExtraPrimitiveOverestimationSizeEXT", {kFuncTypeDev, (void*)CmdSetExtraPrimitiveOverestimationSizeEXT}},
        {"vkCmdSetDepthClipEnableEXT", {kFuncTypeDev, (void*)CmdSetDepthClipEnableEXT}},
        {"vkCmdSetSampleLocationsEnableEXT", {kFuncTypeDev, (void*)CmdSetSampleLocationsEnableEXT}},
        {"vkCmdSetColorBlendAdvancedEXT", {kFuncTypeDev, (void*)CmdSetColorBlendAdvancedEXT}},
        {"vkCmdSetProvokingVertexModeEXT", {kFuncTypeDev, (void*)CmdSetProvokingVertexModeEXT}},
        {"vkCmdSetLineRasterizationModeEXT", {kFuncTypeDev, (void*)CmdSetLineRasterizationModeEXT}},
        {"vkCmdSetLineStippleEnableEXT", {kFuncTypeDev, (void*)CmdSetLineStippleEnableEXT}},
        {"vkCmdSetDepthClipNegativeOneToOneEXT", {kFuncTypeDev, (void*)CmdSetDepthClipNegativeOneToOneEXT}},
        {"vkCmdSetViewportWScalingEnableNV", {kFuncTypeDev, (void*)CmdSetViewportWScalingEnableNV}},
        {"vkCmdSetViewportSwizzleNV", {kFuncTypeDev, (void*)CmdSetViewportSwizzleNV}},
        {"vkCmdSetCoverageToColorEnableNV", {kFuncTypeDev, (void*)CmdSetCoverageToColorEnableNV}},
        {"vkCmdSetCoverageToColorLocationNV", {kFuncTypeDev, (void*)CmdSetCoverageToColorLocationNV}},
        {"vkCmdSetCoverageModulationModeNV", {kFuncTypeDev, (void*)CmdSetCoverageModulationModeNV}},
        {"vkCmdSetCoverageModulationTableEnableNV", {kFuncTypeDev, (void*)CmdSetCoverageModulationTableEnableNV}},
        {"vkCmdSetCoverageModulationTableNV", {kFuncTypeDev, (void*)CmdSetCoverageModulationTableNV}},
        {"vkCmdSetShadingRateImageEnableNV", {kFuncTypeDev, (void*)CmdSetShadingRateImageEnableNV}},
        {"vkCmdSetRepresentativeFragmentTestEnableNV", {kFuncTypeDev, (void*)CmdSetRepresentativeFragmentTestEnableNV}},
        {"vkCmdSetCoverageReductionModeNV", {kFuncTypeDev, (void*)CmdSetCoverageReductionModeNV}},
        {"vkCreateTensorARM", {kFuncTypeDev, (void*)CreateTensorARM}},
        {"vkDestroyTensorARM", {kFuncTypeDev, (void*)DestroyTensorARM}},
        {"vkCreateTensorViewARM", {kFuncTypeDev, (void*)CreateTensorViewARM}},
        {"vkDestroyTensorViewARM", {kFuncTypeDev, (void*)DestroyTensorViewARM}},
        {"vkGetTensorMemoryRequirementsARM", {kFuncTypeDev, (void*)GetTensorMemoryRequirementsARM}},
        {"vkBindTensorMemoryARM", {kFuncTypeDev, (void*)BindTensorMemoryARM}},
        {"vkGetDeviceTensorMemoryRequirementsARM", {kFuncTypeDev, (void*)GetDeviceTensorMemoryRequirementsARM}},
        {"vkCmdCopyTensorARM", {kFuncTypeDev, (void*)CmdCopyTensorARM}},
        {"vkGetPhysicalDeviceExternalTensorPropertiesARM", {kFuncTypePdev, (void*)GetPhysicalDeviceExternalTensorPropertiesARM}},
        {"vkGetTensorOpaqueCaptureDescriptorDataARM", {kFuncTypeDev, (void*)GetTensorOpaqueCaptureDescriptorDataARM}},
        {"vkGetTensorViewOpaqueCaptureDescriptorDataARM", {kFuncTypeDev, (void*)GetTensorViewOpaqueCaptureDescriptorDataARM}},
        {"vkGetShaderModuleIdentifierEXT", {kFuncTypeDev, (void*)GetShaderModuleIdentifierEXT}},
        {"vkGetShaderModuleCreateInfoIdentifierEXT", {kFuncTypeDev, (void*)GetShaderModuleCreateInfoIdentifierEXT}},
        {"vkGetPhysicalDeviceOpticalFlowImageFormatsNV", {kFuncTypePdev, (void*)GetPhysicalDeviceOpticalFlowImageFormatsNV}},
        {"vkCreateOpticalFlowSessionNV", {kFuncTypeDev, (void*)CreateOpticalFlowSessionNV}},
        {"vkDestroyOpticalFlowSessionNV", {kFuncTypeDev, (void*)DestroyOpticalFlowSessionNV}},
        {"vkBindOpticalFlowSessionImageNV", {kFuncTypeDev, (void*)BindOpticalFlowSessionImageNV}},
        {"vkCmdOpticalFlowExecuteNV", {kFuncTypeDev, (void*)CmdOpticalFlowExecuteNV}},
        {"vkAntiLagUpdateAMD", {kFuncTypeDev, (void*)AntiLagUpdateAMD}},
        {"vkCreateShadersEXT", {kFuncTypeDev, (void*)CreateShadersEXT}},
        {"vkDestroyShaderEXT", {kFuncTypeDev, (void*)DestroyShaderEXT}},
        {"vkGetShaderBinaryDataEXT", {kFuncTypeDev, (void*)GetShaderBinaryDataEXT}},
        {"vkCmdBindShadersEXT", {kFuncTypeDev, (void*)CmdBindShadersEXT}},
        {"vkCmdSetDepthClampRangeEXT", {kFuncTypeDev, (void*)CmdSetDepthClampRangeEXT}},
        {"vkGetFramebufferTilePropertiesQCOM", {kFuncTypeDev, (void*)GetFramebufferTilePropertiesQCOM}},
        {"vkGetDynamicRenderingTilePropertiesQCOM", {kFuncTypeDev, (void*)GetDynamicRenderingTilePropertiesQCOM}},
        {"vkGetPhysicalDeviceCooperativeVectorPropertiesNV",
         {kFuncTypePdev, (void*)GetPhysicalDeviceCooperativeVectorPropertiesNV}},
        {"vkConvertCooperativeVectorMatrixNV", {kFuncTypeDev, (void*)ConvertCooperativeVectorMatrixNV}},
        {"vkCmdConvertCooperativeVectorMatrixNV", {kFuncTypeDev, (void*)CmdConvertCooperativeVectorMatrixNV}},
        {"vkSetLatencySleepModeNV", {kFuncTypeDev, (void*)SetLatencySleepModeNV}},
        {"vkLatencySleepNV", {kFuncTypeDev, (void*)LatencySleepNV}},
        {"vkSetLatencyMarkerNV", {kFuncTypeDev, (void*)SetLatencyMarkerNV}},
        {"vkGetLatencyTimingsNV", {kFuncTypeDev, (void*)GetLatencyTimingsNV}},
        {"vkQueueNotifyOutOfBandNV", {kFuncTypeDev, (void*)QueueNotifyOutOfBandNV}},
        {"vkCreateDataGraphPipelinesARM", {kFuncTypeDev, (void*)CreateDataGraphPipelinesARM}},
        {"vkCreateDataGraphPipelineSessionARM", {kFuncTypeDev, (void*)CreateDataGraphPipelineSessionARM}},
        {"vkGetDataGraphPipelineSessionBindPointRequirementsARM",
         {kFuncTypeDev, (void*)GetDataGraphPipelineSessionBindPointRequirementsARM}},
        {"vkGetDataGraphPipelineSessionMemoryRequirementsARM",
         {kFuncTypeDev, (void*)GetDataGraphPipelineSessionMemoryRequirementsARM}},
        {"vkBindDataGraphPipelineSessionMemoryARM", {kFuncTypeDev, (void*)BindDataGraphPipelineSessionMemoryARM}},
        {"vkDestroyDataGraphPipelineSessionARM", {kFuncTypeDev, (void*)DestroyDataGraphPipelineSessionARM}},
        {"vkCmdDispatchDataGraphARM", {kFuncTypeDev, (void*)CmdDispatchDataGraphARM}},
        {"vkGetDataGraphPipelineAvailablePropertiesARM", {kFuncTypeDev, (void*)GetDataGraphPipelineAvailablePropertiesARM}},
        {"vkGetDataGraphPipelinePropertiesARM", {kFuncTypeDev, (void*)GetDataGraphPipelinePropertiesARM}},
        {"vkGetPhysicalDeviceQueueFamilyDataGraphPropertiesARM",
         {kFuncTypePdev, (void*)GetPhysicalDeviceQueueFamilyDataGraphPropertiesARM}},
        {"vkGetPhysicalDeviceQueueFamilyDataGraphProcessingEnginePropertiesARM",
         {kFuncTypePdev, (void*)GetPhysicalDeviceQueueFamilyDataGraphProcessingEnginePropertiesARM}},
        {"vkCmdSetAttachmentFeedbackLoopEnableEXT", {kFuncTypeDev, (void*)CmdSetAttachmentFeedbackLoopEnableEXT}},
#ifdef VK_USE_PLATFORM_SCREEN_QNX
        {"vkGetScreenBufferPropertiesQNX", {kFuncTypeDev, (void*)GetScreenBufferPropertiesQNX}},
#endif  // VK_USE_PLATFORM_SCREEN_QNX
        {"vkCmdBindTileMemoryQCOM", {kFuncTypeDev, (void*)CmdBindTileMemoryQCOM}},
        {"vkCmdDecompressMemoryEXT", {kFuncTypeDev, (void*)CmdDecompressMemoryEXT}},
        {"vkCmdDecompressMemoryIndirectCountEXT", {kFuncTypeDev, (void*)CmdDecompressMemoryIndirectCountEXT}},
        {"vkCreateExternalComputeQueueNV", {kFuncTypeDev, (void*)CreateExternalComputeQueueNV}},
        {"vkDestroyExternalComputeQueueNV", {kFuncTypeDev, (void*)DestroyExternalComputeQueueNV}},
        {"vkGetExternalComputeQueueDataNV", {kFuncTypeDev, (void*)GetExternalComputeQueueDataNV}},
        {"vkGetClusterAccelerationStructureBuildSizesNV", {kFuncTypeDev, (void*)GetClusterAccelerationStructureBuildSizesNV}},
        {"vkCmdBuildClusterAccelerationStructureIndirectNV", {kFuncTypeDev, (void*)CmdBuildClusterAccelerationStructureIndirectNV}},
        {"vkGetPartitionedAccelerationStructuresBuildSizesNV",
         {kFuncTypeDev, (void*)GetPartitionedAccelerationStructuresBuildSizesNV}},
        {"vkCmdBuildPartitionedAccelerationStructuresNV", {kFuncTypeDev, (void*)CmdBuildPartitionedAccelerationStructuresNV}},
        {"vkGetGeneratedCommandsMemoryRequirementsEXT", {kFuncTypeDev, (void*)GetGeneratedCommandsMemoryRequirementsEXT}},
        {"vkCmdPreprocessGeneratedCommandsEXT", {kFuncTypeDev, (void*)CmdPreprocessGeneratedCommandsEXT}},
        {"vkCmdExecuteGeneratedCommandsEXT", {kFuncTypeDev, (void*)CmdExecuteGeneratedCommandsEXT}},
        {"vkCreateIndirectCommandsLayoutEXT", {kFuncTypeDev, (void*)CreateIndirectCommandsLayoutEXT}},
        {"vkDestroyIndirectCommandsLayoutEXT", {kFuncTypeDev, (void*)DestroyIndirectCommandsLayoutEXT}},
        {"vkCreateIndirectExecutionSetEXT", {kFuncTypeDev, (void*)CreateIndirectExecutionSetEXT}},
        {"vkDestroyIndirectExecutionSetEXT", {kFuncTypeDev, (void*)DestroyIndirectExecutionSetEXT}},
        {"vkUpdateIndirectExecutionSetPipelineEXT", {kFuncTypeDev, (void*)UpdateIndirectExecutionSetPipelineEXT}},
        {"vkUpdateIndirectExecutionSetShaderEXT", {kFuncTypeDev, (void*)UpdateIndirectExecutionSetShaderEXT}},
#ifdef VK_USE_PLATFORM_OHOS
        {"vkCreateSurfaceOHOS", {kFuncTypeInst, (void*)CreateSurfaceOHOS}},
#endif  // VK_USE_PLATFORM_OHOS
        {"vkGetPhysicalDeviceCooperativeMatrixFlexibleDimensionsPropertiesNV",
         {kFuncTypePdev, (void*)GetPhysicalDeviceCooperativeMatrixFlexibleDimensionsPropertiesNV}},
#ifdef VK_USE_PLATFORM_METAL_EXT
        {"vkGetMemoryMetalHandleEXT", {kFuncTypeDev, (void*)GetMemoryMetalHandleEXT}},
        {"vkGetMemoryMetalHandlePropertiesEXT", {kFuncTypeDev, (void*)GetMemoryMetalHandlePropertiesEXT}},
#endif  // VK_USE_PLATFORM_METAL_EXT
        {"vkEnumeratePhysicalDeviceQueueFamilyPerformanceCountersByRegionARM",
         {kFuncTypePdev, (void*)EnumeratePhysicalDeviceQueueFamilyPerformanceCountersByRegionARM}},
        {"vkCmdEndRendering2EXT", {kFuncTypeDev, (void*)CmdEndRendering2EXT}},
        {"vkCmdBeginCustomResolveEXT", {kFuncTypeDev, (void*)CmdBeginCustomResolveEXT}},
        {"vkCmdSetComputeOccupancyPriorityNV", {kFuncTypeDev, (void*)CmdSetComputeOccupancyPriorityNV}},
#ifdef VK_USE_PLATFORM_UBM_SEC
        {"vkCreateUbmSurfaceSEC", {kFuncTypeInst, (void*)CreateUbmSurfaceSEC}},
        {"vkGetPhysicalDeviceUbmPresentationSupportSEC", {kFuncTypePdev, (void*)GetPhysicalDeviceUbmPresentationSupportSEC}},
#endif  // VK_USE_PLATFORM_UBM_SEC
        {"vkCreateAccelerationStructureKHR", {kFuncTypeDev, (void*)CreateAccelerationStructureKHR}},
        {"vkDestroyAccelerationStructureKHR", {kFuncTypeDev, (void*)DestroyAccelerationStructureKHR}},
        {"vkCmdBuildAccelerationStructuresKHR", {kFuncTypeDev, (void*)CmdBuildAccelerationStructuresKHR}},
        {"vkCmdBuildAccelerationStructuresIndirectKHR", {kFuncTypeDev, (void*)CmdBuildAccelerationStructuresIndirectKHR}},
        {"vkBuildAccelerationStructuresKHR", {kFuncTypeDev, (void*)BuildAccelerationStructuresKHR}},
        {"vkCopyAccelerationStructureKHR", {kFuncTypeDev, (void*)CopyAccelerationStructureKHR}},
        {"vkCopyAccelerationStructureToMemoryKHR", {kFuncTypeDev, (void*)CopyAccelerationStructureToMemoryKHR}},
        {"vkCopyMemoryToAccelerationStructureKHR", {kFuncTypeDev, (void*)CopyMemoryToAccelerationStructureKHR}},
        {"vkWriteAccelerationStructuresPropertiesKHR", {kFuncTypeDev, (void*)WriteAccelerationStructuresPropertiesKHR}},
        {"vkCmdCopyAccelerationStructureKHR", {kFuncTypeDev, (void*)CmdCopyAccelerationStructureKHR}},
        {"vkCmdCopyAccelerationStructureToMemoryKHR", {kFuncTypeDev, (void*)CmdCopyAccelerationStructureToMemoryKHR}},
        {"vkCmdCopyMemoryToAccelerationStructureKHR", {kFuncTypeDev, (void*)CmdCopyMemoryToAccelerationStructureKHR}},
        {"vkGetAccelerationStructureDeviceAddressKHR", {kFuncTypeDev, (void*)GetAccelerationStructureDeviceAddressKHR}},
        {"vkCmdWriteAccelerationStructuresPropertiesKHR", {kFuncTypeDev, (void*)CmdWriteAccelerationStructuresPropertiesKHR}},
        {"vkGetDeviceAccelerationStructureCompatibilityKHR", {kFuncTypeDev, (void*)GetDeviceAccelerationStructureCompatibilityKHR}},
        {"vkGetAccelerationStructureBuildSizesKHR", {kFuncTypeDev, (void*)GetAccelerationStructureBuildSizesKHR}},
        {"vkCmdTraceRaysKHR", {kFuncTypeDev, (void*)CmdTraceRaysKHR}},
        {"vkCreateRayTracingPipelinesKHR", {kFuncTypeDev, (void*)CreateRayTracingPipelinesKHR}},
        {"vkGetRayTracingCaptureReplayShaderGroupHandlesKHR",
         {kFuncTypeDev, (void*)GetRayTracingCaptureReplayShaderGroupHandlesKHR}},
        {"vkCmdTraceRaysIndirectKHR", {kFuncTypeDev, (void*)CmdTraceRaysIndirectKHR}},
        {"vkGetRayTracingShaderGroupStackSizeKHR", {kFuncTypeDev, (void*)GetRayTracingShaderGroupStackSizeKHR}},
        {"vkCmdSetRayTracingPipelineStackSizeKHR", {kFuncTypeDev, (void*)CmdSetRayTracingPipelineStackSizeKHR}},
        {"vkCmdDrawMeshTasksEXT", {kFuncTypeDev, (void*)CmdDrawMeshTasksEXT}},
        {"vkCmdDrawMeshTasksIndirectEXT", {kFuncTypeDev, (void*)CmdDrawMeshTasksIndirectEXT}},
        {"vkCmdDrawMeshTasksIndirectCountEXT", {kFuncTypeDev, (void*)CmdDrawMeshTasksIndirectCountEXT}},
    };
    return name_to_func_ptr_map;
}
}  // namespace vulkan_layer_chassis

VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vk_layerGetPhysicalDeviceProcAddr(VkInstance instance, const char* funcName) {
    return vulkan_layer_chassis::GetPhysicalDeviceProcAddr(instance, funcName);
}

#if defined(__GNUC__) && __GNUC__ >= 4
#define VVL_EXPORT __attribute__((visibility("default")))
#else
#define VVL_EXPORT
#endif

// The following functions need to match the `/DEF` and `--version-script` files
// for consistency across platforms that don't accept those linker options.
extern "C" {

VVL_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetInstanceProcAddr(VkInstance instance, const char* funcName) {
    return vulkan_layer_chassis::GetInstanceProcAddr(instance, funcName);
}

VVL_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetDeviceProcAddr(VkDevice dev, const char* funcName) {
    return vulkan_layer_chassis::GetDeviceProcAddr(dev, funcName);
}

VVL_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateInstanceLayerProperties(uint32_t* pCount, VkLayerProperties* pProperties) {
    return vulkan_layer_chassis::EnumerateInstanceLayerProperties(pCount, pProperties);
}

VVL_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateInstanceExtensionProperties(const char* pLayerName, uint32_t* pCount,
                                                                                 VkExtensionProperties* pProperties) {
    return vulkan_layer_chassis::EnumerateInstanceExtensionProperties(pLayerName, pCount, pProperties);
}

VVL_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkNegotiateLoaderLayerInterfaceVersion(VkNegotiateLayerInterface* pVersionStruct) {
    assert(pVersionStruct != nullptr);
    assert(pVersionStruct->sType == LAYER_NEGOTIATE_INTERFACE_STRUCT);

    // Fill in the function pointers if our version is at least capable of having the structure contain them.
    if (pVersionStruct->loaderLayerInterfaceVersion >= 2) {
        pVersionStruct->pfnGetInstanceProcAddr = vulkan_layer_chassis::GetInstanceProcAddr;
        pVersionStruct->pfnGetDeviceProcAddr = vulkan_layer_chassis::GetDeviceProcAddr;
        pVersionStruct->pfnGetPhysicalDeviceProcAddr = vulkan_layer_chassis::GetPhysicalDeviceProcAddr;
    }

    return VK_SUCCESS;
}

#if defined(VK_USE_PLATFORM_ANDROID_KHR)
VVL_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateDeviceLayerProperties(VkPhysicalDevice physicalDevice, uint32_t* pCount,
                                                                           VkLayerProperties* pProperties) {
    // the layer command handles VK_NULL_HANDLE just fine internally
    assert(physicalDevice == VK_NULL_HANDLE);
    return vulkan_layer_chassis::EnumerateDeviceLayerProperties(VK_NULL_HANDLE, pCount, pProperties);
}

VVL_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateDeviceExtensionProperties(VkPhysicalDevice physicalDevice,
                                                                               const char* pLayerName, uint32_t* pCount,
                                                                               VkExtensionProperties* pProperties) {
    // the layer command handles VK_NULL_HANDLE just fine internally
    assert(physicalDevice == VK_NULL_HANDLE);
    return vulkan_layer_chassis::EnumerateDeviceExtensionProperties(VK_NULL_HANDLE, pLayerName, pCount, pProperties);
}
#endif

}  // extern "C"

// NOLINTEND
