/***************************************************************************
 *
 * Copyright (c) 2015-2026 The Khronos Group Inc.
 * Copyright (c) 2015-2026 Valve Corporation
 * Copyright (c) 2015-2026 LunarG, Inc.
 * Copyright (C) 2025-2026 Advanced Micro Devices, Inc. All rights reserved.
 *
 * 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.
 ****************************************************************************/

#include "chassis/dispatch_object.h"
#include <vulkan/utility/vk_safe_struct.hpp>
#include "generated/vk_extension_helper.h"
#include "state_tracker/pipeline_state.h"
#include "containers/small_vector.h"
#include "generated/dispatch_functions.h"
#include "utils/dispatch_utils.h"

#include <atomic>

#define OBJECT_LAYER_DESCRIPTION "khronos_validation"

#define DISPATCH_MAX_STACK_ALLOCATIONS 32

namespace vvl {

void MarkSupportedExtensionsAsNotEnabled(const std::vector<VkExtensionProperties> &supported_extensions,
                                         DeviceExtensions &extensions) {
    for (size_t i = 0; i < supported_extensions.size(); i++) {
        vvl::Extension extension = GetExtension(supported_extensions[i].extensionName);
        auto &info = extensions.GetInfo(extension);
        if (info.state && (extensions.*(info.state)) == kNotSupported) {
            extensions.*(info.state) = kNotEnabled;
        }
    }
}

StatelessDeviceData::StatelessDeviceData(vvl::dispatch::Instance *instance, VkPhysicalDevice physical_device,
                                         const VkDeviceCreateInfo *pCreateInfo) {
    // Get physical device limits for device
    VkPhysicalDeviceProperties device_properties = {};
    instance->instance_dispatch_table.GetPhysicalDeviceProperties(physical_device, &device_properties);

    // Setup the validation tables based on the application API version from the instance and the capabilities of the device driver
    api_version = std::min(APIVersion(device_properties.apiVersion), instance->api_version);

    extensions = DeviceExtensions(instance->extensions, api_version, pCreateInfo);
    uint32_t extension_count = 0u;
    DispatchEnumerateDeviceExtensionProperties(physical_device, nullptr, &extension_count, nullptr);
    std::vector<VkExtensionProperties> supported_extensions(extension_count);
    DispatchEnumerateDeviceExtensionProperties(physical_device, nullptr, &extension_count, supported_extensions.data());
    MarkSupportedExtensionsAsNotEnabled(supported_extensions, extensions);

    GetEnabledDeviceFeatures(pCreateInfo, &enabled_features, api_version);

    instance->GetPhysicalDeviceMemoryProperties(physical_device, &phys_dev_mem_props);
    instance->GetPhysicalDeviceProperties(physical_device, &phys_dev_props);

    // Vulkan 1.1 and later can get properties from single struct.
    // The goal is to only use the phys_dev_props_core field and funnel the properties from promoted extensions
    if (IsExtEnabled(extensions.vk_feature_version_1_2)) {
        // 1.1 struct wasn't available until 1.2
        instance->GetPhysicalDeviceExtProperties(physical_device, extensions.vk_feature_version_1_2, &phys_dev_props_core11);
        instance->GetPhysicalDeviceExtProperties(physical_device, extensions.vk_feature_version_1_2, &phys_dev_props_core12);
    } else {
        // VkPhysicalDeviceVulkan11Properties
        //
        // Can ingnore VkPhysicalDeviceIDProperties as it has no validation purpose

        if (IsExtEnabled(extensions.vk_khr_multiview)) {
            VkPhysicalDeviceMultiviewProperties multiview_props = vku::InitStructHelper();
            instance->GetPhysicalDeviceExtProperties(physical_device, extensions.vk_khr_multiview, &multiview_props);
            phys_dev_props_core11.maxMultiviewViewCount = multiview_props.maxMultiviewViewCount;
            phys_dev_props_core11.maxMultiviewInstanceIndex = multiview_props.maxMultiviewInstanceIndex;
        }

        if (IsExtEnabled(extensions.vk_khr_maintenance3)) {
            VkPhysicalDeviceMaintenance3Properties maintenance3_props = vku::InitStructHelper();
            instance->GetPhysicalDeviceExtProperties(physical_device, extensions.vk_khr_maintenance3, &maintenance3_props);
            phys_dev_props_core11.maxPerSetDescriptors = maintenance3_props.maxPerSetDescriptors;
            phys_dev_props_core11.maxMemoryAllocationSize = maintenance3_props.maxMemoryAllocationSize;
        }

        // Some 1.1 properties were added to core without previous extensions
        if (api_version >= VK_API_VERSION_1_1) {
            VkPhysicalDeviceSubgroupProperties subgroup_prop = vku::InitStructHelper();
            VkPhysicalDeviceProtectedMemoryProperties protected_memory_prop = vku::InitStructHelper(&subgroup_prop);
            VkPhysicalDeviceProperties2 prop2 = vku::InitStructHelper(&protected_memory_prop);
            instance->GetPhysicalDeviceProperties2(physical_device, &prop2);

            phys_dev_props_core11.subgroupSize = subgroup_prop.subgroupSize;
            phys_dev_props_core11.subgroupSupportedStages = subgroup_prop.supportedStages;
            phys_dev_props_core11.subgroupSupportedOperations = subgroup_prop.supportedOperations;
            phys_dev_props_core11.subgroupQuadOperationsInAllStages = subgroup_prop.quadOperationsInAllStages;

            phys_dev_props_core11.protectedNoFault = protected_memory_prop.protectedNoFault;
        }

        // VkPhysicalDeviceVulkan12Properties

        if (IsExtEnabled(extensions.vk_khr_driver_properties)) {
            VkPhysicalDeviceDriverProperties driver_properties = vku::InitStructHelper();
            instance->GetPhysicalDeviceExtProperties(physical_device, extensions.vk_khr_driver_properties, &driver_properties);
            phys_dev_props_core12.driverID = driver_properties.driverID;
            memcpy(phys_dev_props_core12.driverName, driver_properties.driverName, VK_MAX_DRIVER_NAME_SIZE);
            memcpy(phys_dev_props_core12.driverInfo, driver_properties.driverName, VK_MAX_DRIVER_INFO_SIZE);
            phys_dev_props_core12.conformanceVersion = driver_properties.conformanceVersion;
        }

        if (IsExtEnabled(extensions.vk_ext_descriptor_indexing)) {
            VkPhysicalDeviceDescriptorIndexingProperties descriptor_indexing_prop = vku::InitStructHelper();
            instance->GetPhysicalDeviceExtProperties(physical_device, extensions.vk_ext_descriptor_indexing,
                                                     &descriptor_indexing_prop);
            phys_dev_props_core12.maxUpdateAfterBindDescriptorsInAllPools =
                descriptor_indexing_prop.maxUpdateAfterBindDescriptorsInAllPools;
            phys_dev_props_core12.shaderUniformBufferArrayNonUniformIndexingNative =
                descriptor_indexing_prop.shaderUniformBufferArrayNonUniformIndexingNative;
            phys_dev_props_core12.shaderSampledImageArrayNonUniformIndexingNative =
                descriptor_indexing_prop.shaderSampledImageArrayNonUniformIndexingNative;
            phys_dev_props_core12.shaderStorageBufferArrayNonUniformIndexingNative =
                descriptor_indexing_prop.shaderStorageBufferArrayNonUniformIndexingNative;
            phys_dev_props_core12.shaderStorageImageArrayNonUniformIndexingNative =
                descriptor_indexing_prop.shaderStorageImageArrayNonUniformIndexingNative;
            phys_dev_props_core12.shaderInputAttachmentArrayNonUniformIndexingNative =
                descriptor_indexing_prop.shaderInputAttachmentArrayNonUniformIndexingNative;
            phys_dev_props_core12.robustBufferAccessUpdateAfterBind = descriptor_indexing_prop.robustBufferAccessUpdateAfterBind;
            phys_dev_props_core12.quadDivergentImplicitLod = descriptor_indexing_prop.quadDivergentImplicitLod;
            phys_dev_props_core12.maxPerStageDescriptorUpdateAfterBindSamplers =
                descriptor_indexing_prop.maxPerStageDescriptorUpdateAfterBindSamplers;
            phys_dev_props_core12.maxPerStageDescriptorUpdateAfterBindUniformBuffers =
                descriptor_indexing_prop.maxPerStageDescriptorUpdateAfterBindUniformBuffers;
            phys_dev_props_core12.maxPerStageDescriptorUpdateAfterBindStorageBuffers =
                descriptor_indexing_prop.maxPerStageDescriptorUpdateAfterBindStorageBuffers;
            phys_dev_props_core12.maxPerStageDescriptorUpdateAfterBindSampledImages =
                descriptor_indexing_prop.maxPerStageDescriptorUpdateAfterBindSampledImages;
            phys_dev_props_core12.maxPerStageDescriptorUpdateAfterBindStorageImages =
                descriptor_indexing_prop.maxPerStageDescriptorUpdateAfterBindStorageImages;
            phys_dev_props_core12.maxPerStageDescriptorUpdateAfterBindInputAttachments =
                descriptor_indexing_prop.maxPerStageDescriptorUpdateAfterBindInputAttachments;
            phys_dev_props_core12.maxPerStageUpdateAfterBindResources =
                descriptor_indexing_prop.maxPerStageUpdateAfterBindResources;
            phys_dev_props_core12.maxDescriptorSetUpdateAfterBindSamplers =
                descriptor_indexing_prop.maxDescriptorSetUpdateAfterBindSamplers;
            phys_dev_props_core12.maxDescriptorSetUpdateAfterBindUniformBuffers =
                descriptor_indexing_prop.maxDescriptorSetUpdateAfterBindUniformBuffers;
            phys_dev_props_core12.maxDescriptorSetUpdateAfterBindUniformBuffersDynamic =
                descriptor_indexing_prop.maxDescriptorSetUpdateAfterBindUniformBuffersDynamic;
            phys_dev_props_core12.maxDescriptorSetUpdateAfterBindStorageBuffers =
                descriptor_indexing_prop.maxDescriptorSetUpdateAfterBindStorageBuffers;
            phys_dev_props_core12.maxDescriptorSetUpdateAfterBindStorageBuffersDynamic =
                descriptor_indexing_prop.maxDescriptorSetUpdateAfterBindStorageBuffersDynamic;
            phys_dev_props_core12.maxDescriptorSetUpdateAfterBindSampledImages =
                descriptor_indexing_prop.maxDescriptorSetUpdateAfterBindSampledImages;
            phys_dev_props_core12.maxDescriptorSetUpdateAfterBindStorageImages =
                descriptor_indexing_prop.maxDescriptorSetUpdateAfterBindStorageImages;
            phys_dev_props_core12.maxDescriptorSetUpdateAfterBindInputAttachments =
                descriptor_indexing_prop.maxDescriptorSetUpdateAfterBindInputAttachments;
        }

        if (IsExtEnabled(extensions.vk_khr_depth_stencil_resolve)) {
            VkPhysicalDeviceDepthStencilResolveProperties depth_stencil_resolve_props = vku::InitStructHelper();
            instance->GetPhysicalDeviceExtProperties(physical_device, extensions.vk_khr_depth_stencil_resolve,
                                                     &depth_stencil_resolve_props);
            phys_dev_props_core12.supportedDepthResolveModes = depth_stencil_resolve_props.supportedDepthResolveModes;
            phys_dev_props_core12.supportedStencilResolveModes = depth_stencil_resolve_props.supportedStencilResolveModes;
            phys_dev_props_core12.independentResolveNone = depth_stencil_resolve_props.independentResolveNone;
            phys_dev_props_core12.independentResolve = depth_stencil_resolve_props.independentResolve;
        }

        if (IsExtEnabled(extensions.vk_khr_timeline_semaphore)) {
            VkPhysicalDeviceTimelineSemaphoreProperties timeline_semaphore_props = vku::InitStructHelper();
            instance->GetPhysicalDeviceExtProperties(physical_device, extensions.vk_khr_timeline_semaphore,
                                                     &timeline_semaphore_props);
            phys_dev_props_core12.maxTimelineSemaphoreValueDifference =
                timeline_semaphore_props.maxTimelineSemaphoreValueDifference;
        }

        if (IsExtEnabled(extensions.vk_ext_sampler_filter_minmax)) {
            VkPhysicalDeviceSamplerFilterMinmaxProperties sampler_filter_minmax_props = vku::InitStructHelper();
            instance->GetPhysicalDeviceExtProperties(physical_device, extensions.vk_ext_sampler_filter_minmax,
                                                     &sampler_filter_minmax_props);
            phys_dev_props_core12.filterMinmaxSingleComponentFormats =
                sampler_filter_minmax_props.filterMinmaxSingleComponentFormats;
            phys_dev_props_core12.filterMinmaxImageComponentMapping = sampler_filter_minmax_props.filterMinmaxImageComponentMapping;
        }

        if (IsExtEnabled(extensions.vk_khr_shader_float_controls)) {
            VkPhysicalDeviceFloatControlsProperties float_controls_props = vku::InitStructHelper();
            instance->GetPhysicalDeviceExtProperties(physical_device, extensions.vk_khr_shader_float_controls,
                                                     &float_controls_props);
            phys_dev_props_core12.denormBehaviorIndependence = float_controls_props.denormBehaviorIndependence;
            phys_dev_props_core12.roundingModeIndependence = float_controls_props.roundingModeIndependence;
            phys_dev_props_core12.shaderSignedZeroInfNanPreserveFloat16 =
                float_controls_props.shaderSignedZeroInfNanPreserveFloat16;
            phys_dev_props_core12.shaderSignedZeroInfNanPreserveFloat32 =
                float_controls_props.shaderSignedZeroInfNanPreserveFloat32;
            phys_dev_props_core12.shaderSignedZeroInfNanPreserveFloat64 =
                float_controls_props.shaderSignedZeroInfNanPreserveFloat64;
            phys_dev_props_core12.shaderDenormPreserveFloat16 = float_controls_props.shaderDenormPreserveFloat16;
            phys_dev_props_core12.shaderDenormPreserveFloat32 = float_controls_props.shaderDenormPreserveFloat32;
            phys_dev_props_core12.shaderDenormPreserveFloat64 = float_controls_props.shaderDenormPreserveFloat64;
            phys_dev_props_core12.shaderDenormFlushToZeroFloat16 = float_controls_props.shaderDenormFlushToZeroFloat16;
            phys_dev_props_core12.shaderDenormFlushToZeroFloat32 = float_controls_props.shaderDenormFlushToZeroFloat32;
            phys_dev_props_core12.shaderDenormFlushToZeroFloat64 = float_controls_props.shaderDenormFlushToZeroFloat64;
            phys_dev_props_core12.shaderRoundingModeRTEFloat16 = float_controls_props.shaderRoundingModeRTEFloat16;
            phys_dev_props_core12.shaderRoundingModeRTEFloat32 = float_controls_props.shaderRoundingModeRTEFloat32;
            phys_dev_props_core12.shaderRoundingModeRTEFloat64 = float_controls_props.shaderRoundingModeRTEFloat64;
            phys_dev_props_core12.shaderRoundingModeRTZFloat16 = float_controls_props.shaderRoundingModeRTZFloat16;
            phys_dev_props_core12.shaderRoundingModeRTZFloat32 = float_controls_props.shaderRoundingModeRTZFloat32;
            phys_dev_props_core12.shaderRoundingModeRTZFloat64 = float_controls_props.shaderRoundingModeRTZFloat64;
        }
    }

    // funnel promoted extensions into a VkPhysicalDeviceVulkan13Properties
    //
    // Can ingnore VkPhysicalDeviceShaderIntegerDotProductProperties as it has no validation purpose
    if (IsExtEnabled(extensions.vk_feature_version_1_3)) {
        instance->GetPhysicalDeviceExtProperties(physical_device, extensions.vk_feature_version_1_3, &phys_dev_props_core13);
    } else {
        if (IsExtEnabled(extensions.vk_ext_subgroup_size_control)) {
            VkPhysicalDeviceSubgroupSizeControlProperties subgroup_size_props = vku::InitStructHelper();
            instance->GetPhysicalDeviceExtProperties(physical_device, extensions.vk_ext_subgroup_size_control,
                                                     &subgroup_size_props);
            phys_dev_props_core13.minSubgroupSize = subgroup_size_props.minSubgroupSize;
            phys_dev_props_core13.maxSubgroupSize = subgroup_size_props.maxSubgroupSize;
            phys_dev_props_core13.maxComputeWorkgroupSubgroups = subgroup_size_props.maxComputeWorkgroupSubgroups;
            phys_dev_props_core13.requiredSubgroupSizeStages = subgroup_size_props.requiredSubgroupSizeStages;
        }

        if (IsExtEnabled(extensions.vk_ext_inline_uniform_block)) {
            VkPhysicalDeviceInlineUniformBlockProperties inline_uniform_block_props = vku::InitStructHelper();
            instance->GetPhysicalDeviceExtProperties(physical_device, extensions.vk_ext_inline_uniform_block,
                                                     &inline_uniform_block_props);
            phys_dev_props_core13.maxInlineUniformBlockSize = inline_uniform_block_props.maxInlineUniformBlockSize;
            phys_dev_props_core13.maxPerStageDescriptorInlineUniformBlocks =
                inline_uniform_block_props.maxPerStageDescriptorInlineUniformBlocks;
            phys_dev_props_core13.maxPerStageDescriptorUpdateAfterBindInlineUniformBlocks =
                inline_uniform_block_props.maxPerStageDescriptorUpdateAfterBindInlineUniformBlocks;
            phys_dev_props_core13.maxDescriptorSetInlineUniformBlocks =
                inline_uniform_block_props.maxDescriptorSetInlineUniformBlocks;
            phys_dev_props_core13.maxDescriptorSetUpdateAfterBindInlineUniformBlocks =
                inline_uniform_block_props.maxDescriptorSetUpdateAfterBindInlineUniformBlocks;
        }

        if (IsExtEnabled(extensions.vk_ext_texel_buffer_alignment)) {
            VkPhysicalDeviceTexelBufferAlignmentProperties texel_buffer_alignment_props = vku::InitStructHelper();
            instance->GetPhysicalDeviceExtProperties(physical_device, extensions.vk_ext_texel_buffer_alignment,
                                                     &texel_buffer_alignment_props);
            phys_dev_props_core13.storageTexelBufferOffsetAlignmentBytes =
                texel_buffer_alignment_props.storageTexelBufferOffsetAlignmentBytes;
            phys_dev_props_core13.storageTexelBufferOffsetSingleTexelAlignment =
                texel_buffer_alignment_props.storageTexelBufferOffsetSingleTexelAlignment;
            phys_dev_props_core13.uniformTexelBufferOffsetAlignmentBytes =
                texel_buffer_alignment_props.uniformTexelBufferOffsetAlignmentBytes;
            phys_dev_props_core13.uniformTexelBufferOffsetSingleTexelAlignment =
                texel_buffer_alignment_props.uniformTexelBufferOffsetSingleTexelAlignment;
        }

        if (IsExtEnabled(extensions.vk_khr_maintenance4)) {
            VkPhysicalDeviceMaintenance4Properties maintenance4_props = vku::InitStructHelper();
            instance->GetPhysicalDeviceExtProperties(physical_device, extensions.vk_khr_maintenance4, &maintenance4_props);
            phys_dev_props_core13.maxBufferSize = maintenance4_props.maxBufferSize;
        }
    }

    // funnel promoted extensions into a VkPhysicalDeviceVulkan14Properties
    if (IsExtEnabled(extensions.vk_feature_version_1_4)) {
        // First query to get list properties size from host image copy extension,
        // second to get actual properties
        phys_dev_props_core14.copySrcLayoutCount = 0;
        phys_dev_props_core14.pCopySrcLayouts = nullptr;
        phys_dev_props_core14.copyDstLayoutCount = 0;
        phys_dev_props_core14.pCopyDstLayouts = nullptr;
        instance->GetPhysicalDeviceExtProperties(physical_device, extensions.vk_feature_version_1_4, &phys_dev_props_core14);
        host_image_copy_props_copy_src_layouts.resize(phys_dev_props_core14.copySrcLayoutCount);
        host_image_copy_props_copy_dst_layouts.resize(phys_dev_props_core14.copyDstLayoutCount);
        phys_dev_props_core14.pCopySrcLayouts = host_image_copy_props_copy_src_layouts.data();
        phys_dev_props_core14.pCopyDstLayouts = host_image_copy_props_copy_dst_layouts.data();
        instance->GetPhysicalDeviceExtProperties<false>(physical_device, extensions.vk_feature_version_1_4, &phys_dev_props_core14);
    } else {
        if (IsExtEnabled(extensions.vk_khr_line_rasterization)) {
            VkPhysicalDeviceLineRasterizationPropertiesKHR line_rasterization_props = vku::InitStructHelper();
            instance->GetPhysicalDeviceExtProperties(physical_device, extensions.vk_khr_line_rasterization,
                                                     &line_rasterization_props);
            phys_dev_props_core14.lineSubPixelPrecisionBits = line_rasterization_props.lineSubPixelPrecisionBits;
        } else if (IsExtEnabled(extensions.vk_ext_line_rasterization)) {
            VkPhysicalDeviceLineRasterizationPropertiesEXT line_rasterization_props = vku::InitStructHelper();
            instance->GetPhysicalDeviceExtProperties(physical_device, extensions.vk_ext_line_rasterization,
                                                     &line_rasterization_props);
            phys_dev_props_core14.lineSubPixelPrecisionBits = line_rasterization_props.lineSubPixelPrecisionBits;
        }

        if (IsExtEnabled(extensions.vk_khr_vertex_attribute_divisor)) {
            VkPhysicalDeviceVertexAttributeDivisorPropertiesKHR vtx_attrib_divisor_props_khr;
            instance->GetPhysicalDeviceExtProperties(physical_device, extensions.vk_khr_vertex_attribute_divisor,
                                                     &vtx_attrib_divisor_props_khr);
            phys_dev_props_core14.maxVertexAttribDivisor = vtx_attrib_divisor_props_khr.maxVertexAttribDivisor;
            phys_dev_props_core14.supportsNonZeroFirstInstance = vtx_attrib_divisor_props_khr.supportsNonZeroFirstInstance;
        } else if (IsExtEnabled(extensions.vk_ext_vertex_attribute_divisor)) {
            VkPhysicalDeviceVertexAttributeDivisorPropertiesEXT vtx_attrib_divisor_props_ext;
            instance->GetPhysicalDeviceExtProperties(physical_device, extensions.vk_ext_vertex_attribute_divisor,
                                                     &vtx_attrib_divisor_props_ext);
            phys_dev_props_core14.maxVertexAttribDivisor = vtx_attrib_divisor_props_ext.maxVertexAttribDivisor;
        }

        if (IsExtEnabled(extensions.vk_khr_push_descriptor)) {
            VkPhysicalDevicePushDescriptorPropertiesKHR push_descriptor_props = vku::InitStructHelper();
            instance->GetPhysicalDeviceExtProperties(physical_device, extensions.vk_khr_push_descriptor, &push_descriptor_props);
            phys_dev_props_core14.maxPushDescriptors = push_descriptor_props.maxPushDescriptors;
        }

        if (IsExtEnabled(extensions.vk_khr_maintenance5)) {
            VkPhysicalDeviceMaintenance5PropertiesKHR maintenance_5_props = vku::InitStructHelper();
            instance->GetPhysicalDeviceExtProperties(physical_device, extensions.vk_khr_maintenance5, &maintenance_5_props);
            phys_dev_props_core14.earlyFragmentMultisampleCoverageAfterSampleCounting =
                maintenance_5_props.earlyFragmentMultisampleCoverageAfterSampleCounting;
            phys_dev_props_core14.earlyFragmentSampleMaskTestBeforeSampleCounting =
                maintenance_5_props.earlyFragmentSampleMaskTestBeforeSampleCounting;
            phys_dev_props_core14.depthStencilSwizzleOneSupport = maintenance_5_props.depthStencilSwizzleOneSupport;
            phys_dev_props_core14.polygonModePointSize = maintenance_5_props.polygonModePointSize;
            phys_dev_props_core14.nonStrictSinglePixelWideLinesUseParallelogram =
                maintenance_5_props.nonStrictSinglePixelWideLinesUseParallelogram;
            phys_dev_props_core14.nonStrictWideLinesUseParallelogram = maintenance_5_props.nonStrictWideLinesUseParallelogram;
        }

        if (IsExtEnabled(extensions.vk_khr_maintenance6)) {
            VkPhysicalDeviceMaintenance6PropertiesKHR maintenance_6_props = vku::InitStructHelper();
            instance->GetPhysicalDeviceExtProperties(physical_device, extensions.vk_khr_maintenance6, &maintenance_6_props);
            phys_dev_props_core14.blockTexelViewCompatibleMultipleLayers =
                maintenance_6_props.blockTexelViewCompatibleMultipleLayers;
            phys_dev_props_core14.maxCombinedImageSamplerDescriptorCount =
                maintenance_6_props.maxCombinedImageSamplerDescriptorCount;
            phys_dev_props_core14.fragmentShadingRateClampCombinerInputs =
                maintenance_6_props.fragmentShadingRateClampCombinerInputs;
        }

        if (IsExtEnabled(extensions.vk_ext_pipeline_robustness)) {
            VkPhysicalDevicePipelineRobustnessProperties pipeline_robustness_props = vku::InitStructHelper();
            instance->GetPhysicalDeviceExtProperties(physical_device, extensions.vk_ext_pipeline_robustness,
                                                     &pipeline_robustness_props);
            phys_dev_props_core14.defaultRobustnessStorageBuffers = pipeline_robustness_props.defaultRobustnessStorageBuffers;
            phys_dev_props_core14.defaultRobustnessUniformBuffers = pipeline_robustness_props.defaultRobustnessUniformBuffers;
            phys_dev_props_core14.defaultRobustnessVertexInputs = pipeline_robustness_props.defaultRobustnessVertexInputs;
            phys_dev_props_core14.defaultRobustnessImages = pipeline_robustness_props.defaultRobustnessImages;
        }

        if (IsExtEnabled(extensions.vk_ext_host_image_copy)) {
            VkPhysicalDeviceHostImageCopyPropertiesEXT host_image_copy_props = vku::InitStructHelper();
            // First call, get copySrcLayoutCount and copyDstLayoutCount
            instance->GetPhysicalDeviceExtProperties(physical_device, extensions.vk_ext_host_image_copy, &host_image_copy_props);
            host_image_copy_props_copy_src_layouts.resize(host_image_copy_props.copySrcLayoutCount);
            host_image_copy_props_copy_dst_layouts.resize(host_image_copy_props.copyDstLayoutCount);
            host_image_copy_props.pCopySrcLayouts = host_image_copy_props_copy_src_layouts.data();
            host_image_copy_props.pCopyDstLayouts = host_image_copy_props_copy_dst_layouts.data();
            instance->GetPhysicalDeviceExtProperties<false>(physical_device, extensions.vk_ext_host_image_copy,
                                                            &host_image_copy_props);

            phys_dev_props_core14.copySrcLayoutCount = host_image_copy_props.copySrcLayoutCount;
            phys_dev_props_core14.pCopySrcLayouts = host_image_copy_props_copy_src_layouts.data();
            phys_dev_props_core14.copyDstLayoutCount = host_image_copy_props.copyDstLayoutCount;
            phys_dev_props_core14.pCopyDstLayouts = host_image_copy_props_copy_dst_layouts.data();
            std::memcpy(phys_dev_props_core14.optimalTilingLayoutUUID, host_image_copy_props.optimalTilingLayoutUUID,
                        sizeof(host_image_copy_props.optimalTilingLayoutUUID));
            phys_dev_props_core14.identicalMemoryTypeRequirements = host_image_copy_props.identicalMemoryTypeRequirements;
        }
    }

    // Extensions with properties to extract to DeviceExtensionProperties
    instance->GetPhysicalDeviceExtProperties(physical_device, extensions.vk_nv_partitioned_acceleration_structure,
                                             &phys_dev_ext_props.partitioned_acceleration_structure_props);
    instance->GetPhysicalDeviceExtProperties(physical_device, extensions.vk_nv_cluster_acceleration_structure,
                                             &phys_dev_ext_props.cluster_acceleration_props);
    instance->GetPhysicalDeviceExtProperties(physical_device, extensions.vk_nv_shading_rate_image,
                                             &phys_dev_ext_props.shading_rate_image_props);
    instance->GetPhysicalDeviceExtProperties(physical_device, extensions.vk_nv_mesh_shader,
                                             &phys_dev_ext_props.mesh_shader_props_nv);
    instance->GetPhysicalDeviceExtProperties(physical_device, extensions.vk_ext_mesh_shader,
                                             &phys_dev_ext_props.mesh_shader_props_ext);
    instance->GetPhysicalDeviceExtProperties(physical_device, extensions.vk_nv_cooperative_matrix,
                                             &phys_dev_ext_props.cooperative_matrix_props);
    instance->GetPhysicalDeviceExtProperties(physical_device, extensions.vk_khr_cooperative_matrix,
                                             &phys_dev_ext_props.cooperative_matrix_props_khr);
    instance->GetPhysicalDeviceExtProperties(physical_device, extensions.vk_nv_cooperative_matrix2,
                                             &phys_dev_ext_props.cooperative_matrix_props2_nv);
    instance->GetPhysicalDeviceExtProperties(physical_device, extensions.vk_ext_transform_feedback,
                                             &phys_dev_ext_props.transform_feedback_props);
    instance->GetPhysicalDeviceExtProperties(physical_device, extensions.vk_nv_ray_tracing,
                                             &phys_dev_ext_props.ray_tracing_props_nv);
    instance->GetPhysicalDeviceExtProperties(physical_device, extensions.vk_khr_ray_tracing_pipeline,
                                             &phys_dev_ext_props.ray_tracing_props_khr);
    instance->GetPhysicalDeviceExtProperties(physical_device, extensions.vk_ext_ray_tracing_invocation_reorder,
                                             &phys_dev_ext_props.ray_tracing_invocation_reorder_props);
    instance->GetPhysicalDeviceExtProperties(physical_device, extensions.vk_khr_acceleration_structure,
                                             &phys_dev_ext_props.acc_structure_props);
    instance->GetPhysicalDeviceExtProperties(physical_device, extensions.vk_ext_fragment_density_map,
                                             &phys_dev_ext_props.fragment_density_map_props);
    instance->GetPhysicalDeviceExtProperties(physical_device, extensions.vk_ext_fragment_density_map2,
                                             &phys_dev_ext_props.fragment_density_map2_props);
    instance->GetPhysicalDeviceExtProperties(physical_device, extensions.vk_ext_fragment_density_map_offset,
                                             &phys_dev_ext_props.fragment_density_map_offset_props);
    // TODO - mgiht be more cases like this where the properties are aliased, should have a more unified way to handle these
    if (IsExtEnabled(extensions.vk_qcom_fragment_density_map_offset) &&
        !IsExtEnabled(extensions.vk_ext_fragment_density_map_offset)) {
        instance->GetPhysicalDeviceExtProperties(physical_device, extensions.vk_qcom_fragment_density_map_offset,
                                                 &phys_dev_ext_props.fragment_density_map_offset_props);
    }
    instance->GetPhysicalDeviceExtProperties(physical_device, extensions.vk_valve_fragment_density_map_layered,
                                             &phys_dev_ext_props.fragment_density_map_layered_props);
    instance->GetPhysicalDeviceExtProperties(physical_device, extensions.vk_khr_performance_query,
                                             &phys_dev_ext_props.performance_query_props);
    instance->GetPhysicalDeviceExtProperties(physical_device, extensions.vk_ext_sample_locations,
                                             &phys_dev_ext_props.sample_locations_props);
    instance->GetPhysicalDeviceExtProperties(physical_device, extensions.vk_ext_custom_border_color,
                                             &phys_dev_ext_props.custom_border_color_props);
    instance->GetPhysicalDeviceExtProperties(physical_device, extensions.vk_khr_multiview, &phys_dev_ext_props.multiview_props);
    instance->GetPhysicalDeviceExtProperties(physical_device, extensions.vk_khr_portability_subset,
                                             &phys_dev_ext_props.portability_props);
    instance->GetPhysicalDeviceExtProperties(physical_device, extensions.vk_khr_fragment_shading_rate,
                                             &phys_dev_ext_props.fragment_shading_rate_props);
    instance->GetPhysicalDeviceExtProperties(physical_device, extensions.vk_ext_provoking_vertex,
                                             &phys_dev_ext_props.provoking_vertex_props);
    instance->GetPhysicalDeviceExtProperties(physical_device, extensions.vk_ext_multi_draw, &phys_dev_ext_props.multi_draw_props);
    instance->GetPhysicalDeviceExtProperties(physical_device, extensions.vk_ext_discard_rectangles,
                                             &phys_dev_ext_props.discard_rectangle_props);
    instance->GetPhysicalDeviceExtProperties(physical_device, extensions.vk_ext_blend_operation_advanced,
                                             &phys_dev_ext_props.blend_operation_advanced_props);
    instance->GetPhysicalDeviceExtProperties(physical_device, extensions.vk_ext_conservative_rasterization,
                                             &phys_dev_ext_props.conservative_rasterization_props);
    instance->GetPhysicalDeviceExtProperties(physical_device, extensions.vk_khr_copy_memory_indirect,
                                             &phys_dev_ext_props.copy_memory_indirect_props);

    if (api_version >= VK_API_VERSION_1_1) {
        instance->GetPhysicalDeviceExtProperties(physical_device, kEnabledByCreateinfo, &phys_dev_ext_props.subgroup_props);
    }
    instance->GetPhysicalDeviceExtProperties(physical_device, extensions.vk_ext_extended_dynamic_state3,
                                             &phys_dev_ext_props.extended_dynamic_state3_props);
    instance->GetPhysicalDeviceExtProperties(physical_device, extensions.vk_qcom_image_processing,
                                             &phys_dev_ext_props.image_processing_props);
    instance->GetPhysicalDeviceExtProperties(physical_device, extensions.vk_mesa_image_alignment_control,
                                             &phys_dev_ext_props.image_alignment_control_props);
    instance->GetPhysicalDeviceExtProperties(physical_device, extensions.vk_khr_maintenance7,
                                             &phys_dev_ext_props.maintenance7_props);
    instance->GetPhysicalDeviceExtProperties(physical_device, extensions.vk_ext_nested_command_buffer,
                                             &phys_dev_ext_props.nested_command_buffer_props);
    instance->GetPhysicalDeviceExtProperties(physical_device, extensions.vk_ext_descriptor_buffer,
                                             &phys_dev_ext_props.descriptor_buffer_props);
    instance->GetPhysicalDeviceExtProperties(physical_device, extensions.vk_ext_descriptor_buffer,
                                             &phys_dev_ext_props.descriptor_buffer_density_props);
    instance->GetPhysicalDeviceExtProperties(physical_device, extensions.vk_ext_device_generated_commands,
                                             &phys_dev_ext_props.device_generated_commands_props);
    instance->GetPhysicalDeviceExtProperties(physical_device, extensions.vk_khr_pipeline_binary,
                                             &phys_dev_ext_props.pipeline_binary_props);
    instance->GetPhysicalDeviceExtProperties(physical_device, extensions.vk_ext_map_memory_placed,
                                             &phys_dev_ext_props.map_memory_placed_props);
    instance->GetPhysicalDeviceExtProperties(physical_device, extensions.vk_khr_compute_shader_derivatives,
                                             &phys_dev_ext_props.compute_shader_derivatives_props);
    instance->GetPhysicalDeviceExtProperties(physical_device, extensions.vk_nv_cooperative_vector,
                                             &phys_dev_ext_props.cooperative_vector_props_nv);
    instance->GetPhysicalDeviceExtProperties(physical_device, extensions.vk_arm_render_pass_striped,
                                             &phys_dev_ext_props.renderpass_striped_props);
    instance->GetPhysicalDeviceExtProperties(physical_device, extensions.vk_ext_external_memory_host,
                                             &phys_dev_ext_props.external_memory_host_props);
    instance->GetPhysicalDeviceExtProperties(physical_device, extensions.vk_khr_maintenance9,
                                             &phys_dev_ext_props.maintenance9_props);
    instance->GetPhysicalDeviceExtProperties(physical_device, extensions.vk_khr_maintenance10,
                                             &phys_dev_ext_props.maintenance10_props);
    instance->GetPhysicalDeviceExtProperties(physical_device, extensions.vk_arm_tensors, &phys_dev_ext_props.tensor_properties);
    instance->GetPhysicalDeviceExtProperties(physical_device, extensions.vk_ext_descriptor_heap,
                                             &phys_dev_ext_props.descriptor_heap_props);
    if (IsExtEnabled(extensions.vk_arm_tensors)) {
        instance->GetPhysicalDeviceExtProperties(physical_device, extensions.vk_ext_descriptor_heap,
                                                 &phys_dev_ext_props.descriptor_heap_tensor_props);
    }
#if defined(VK_USE_PLATFORM_ANDROID_KHR)
    instance->GetPhysicalDeviceExtProperties(physical_device, extensions.vk_android_external_format_resolve,
                                             &phys_dev_ext_props.android_format_resolve_props);
#endif
    instance->GetPhysicalDeviceExtProperties(physical_device, extensions.vk_qcom_tile_memory_heap,
                                             &phys_dev_ext_props.tile_memory_heap_props);
    instance->GetPhysicalDeviceExtProperties(physical_device, extensions.vk_ext_memory_decompression,
                                             &phys_dev_ext_props.memory_decompression_props);
    instance->GetPhysicalDeviceExtProperties(physical_device, extensions.vk_arm_performance_counters_by_region,
                                             &phys_dev_ext_props.renderpass_counter_by_region_props);
    instance->GetPhysicalDeviceExtProperties(physical_device, extensions.vk_ext_shader_long_vector,
                                             &phys_dev_ext_props.shader_long_vector_props);

    // None of these "check if supported" features are possible without first having gpdp2 first
    if (IsExtEnabled(extensions.vk_khr_get_physical_device_properties2)) {
        uint32_t n_props = 0;
        std::vector<VkExtensionProperties> props;
        DispatchEnumerateDeviceExtensionProperties(physical_device, NULL, &n_props, NULL);
        props.resize(n_props);
        DispatchEnumerateDeviceExtensionProperties(physical_device, NULL, &n_props, props.data());

        vvl::unordered_set<Extension> phys_dev_extensions;
        for (const auto &ext_prop : props) {
            phys_dev_extensions.insert(GetExtension(ext_prop.extensionName));
        }

        // promoted to 1.3
        special_supported.vk_khr_format_feature_flags2 =
            api_version >= VK_API_VERSION_1_3 ||
            phys_dev_extensions.find(Extension::_VK_KHR_format_feature_flags2) != phys_dev_extensions.end();

        // robustImageAccess is required if 1.3 or VK_EXT_image_robustness supported
        special_supported.robust_image_access =
            api_version >= VK_API_VERSION_1_3 ||
            phys_dev_extensions.find(Extension::_VK_EXT_image_robustness) != phys_dev_extensions.end();

        if (phys_dev_extensions.find(Extension::_VK_KHR_robustness2) != phys_dev_extensions.end() ||
            phys_dev_extensions.find(Extension::_VK_EXT_robustness2) != phys_dev_extensions.end()) {
            VkPhysicalDeviceRobustness2FeaturesKHR robustness_2_features = vku::InitStructHelper();
            VkPhysicalDeviceFeatures2 features2 = vku::InitStructHelper(&robustness_2_features);
            DispatchGetPhysicalDeviceFeatures2Helper(api_version, physical_device, &features2);
            special_supported.robust_image_access2 = robustness_2_features.robustImageAccess2;
            special_supported.robust_buffer_access2 = robustness_2_features.robustBufferAccess2;
        }

        if (api_version >= VK_API_VERSION_1_2) {
            VkPhysicalDeviceVulkan12Features vulkan_12_features = vku::InitStructHelper();
            VkPhysicalDeviceFeatures2 features2 = vku::InitStructHelper(&vulkan_12_features);
            DispatchGetPhysicalDeviceFeatures2Helper(api_version, physical_device, &features2);
            special_supported.descriptor_binding_sampled_image_uab =
                vulkan_12_features.descriptorBindingSampledImageUpdateAfterBind;
            special_supported.descriptor_binding_uniform_buffer_uab =
                vulkan_12_features.descriptorBindingUniformBufferUpdateAfterBind;
            special_supported.descriptor_binding_storage_buffer_uab =
                vulkan_12_features.descriptorBindingStorageBufferUpdateAfterBind;
            special_supported.descriptor_binding_storage_image_uab =
                vulkan_12_features.descriptorBindingStorageImageUpdateAfterBind;
        } else if (phys_dev_extensions.find(Extension::_VK_EXT_descriptor_indexing) != phys_dev_extensions.end()) {
            VkPhysicalDeviceDescriptorIndexingFeatures di_features = vku::InitStructHelper();
            VkPhysicalDeviceFeatures2 features2 = vku::InitStructHelper(&di_features);
            DispatchGetPhysicalDeviceFeatures2Helper(api_version, physical_device, &features2);
            special_supported.descriptor_binding_sampled_image_uab = di_features.descriptorBindingSampledImageUpdateAfterBind;
            special_supported.descriptor_binding_uniform_buffer_uab = di_features.descriptorBindingUniformBufferUpdateAfterBind;
            special_supported.descriptor_binding_storage_buffer_uab = di_features.descriptorBindingStorageBufferUpdateAfterBind;
            special_supported.descriptor_binding_storage_image_uab = di_features.descriptorBindingStorageImageUpdateAfterBind;
        }

        if (api_version >= VK_API_VERSION_1_3) {
            VkPhysicalDeviceVulkan13Features vulkan_13_features = vku::InitStructHelper();
            VkPhysicalDeviceFeatures2 features2 = vku::InitStructHelper(&vulkan_13_features);
            DispatchGetPhysicalDeviceFeatures2Helper(api_version, physical_device, &features2);
            special_supported.descriptor_binding_inline_uniform_buffer_uab =
                vulkan_13_features.descriptorBindingInlineUniformBlockUpdateAfterBind;
        } else if (phys_dev_extensions.find(Extension::_VK_EXT_inline_uniform_block) != phys_dev_extensions.end()) {
            VkPhysicalDeviceInlineUniformBlockFeatures inline_ubo_features = vku::InitStructHelper();
            VkPhysicalDeviceFeatures2 features2 = vku::InitStructHelper(&inline_ubo_features);
            DispatchGetPhysicalDeviceFeatures2Helper(api_version, physical_device, &features2);
            special_supported.descriptor_binding_inline_uniform_buffer_uab =
                inline_ubo_features.descriptorBindingInlineUniformBlockUpdateAfterBind;
        }
        if (phys_dev_extensions.find(Extension::_VK_KHR_maintenance9) != phys_dev_extensions.end()) {
            VkPhysicalDeviceMaintenance9FeaturesKHR maintenance_9_features = vku::InitStructHelper();
            VkPhysicalDeviceFeatures2 features2 = vku::InitStructHelper(&maintenance_9_features);
            DispatchGetPhysicalDeviceFeatures2Helper(api_version, physical_device, &features2);
            special_supported.has_maintenance9 = maintenance_9_features.maintenance9;
        }
    }
}

// VKU's vk_safe_struct_manual.cpp defines a local object with static storage duration
// (inside GetAccelStructGeomHostAllocMap) that serves as a cache to store AS related data.
//
// During the deinitialization sequence the AS cache may be accessed by the destructors of safe
// structures. For example, the device_data map needs the cache to be available during destruction.
// ASHostGeomCacheInitializer ensures that the AS cache is initialized before device_data, so
// that in the reverse destruction order the cache is destroyed after its clients.
//
// The ASHostGeomCacheInitializer implementation relies on vku internal details. It creates a
// temporary safe_VkAccelerationStructureGeometryKHR object, which during destruction accesses the
// AS cache. The cache is constructed upon this first request. A better API would be for VKU to
// provide an explicit function to initialize the cache (and call it from ASHostGeomCacheInitializer
// constructor).
struct ASHostGeomCacheInitializer {
    ASHostGeomCacheInitializer() { vku::safe_VkAccelerationStructureGeometryKHR cache_toucher; }
};

namespace dispatch {

static std::shared_mutex dispatch_lock;

std::atomic<uint64_t> HandleWrapper::global_unique_id{1};
vvl::concurrent_unordered_map<uint64_t, uint64_t, 4, HashedUint64> HandleWrapper::unique_id_mapping;
bool HandleWrapper::wrap_handles{true};

// Must be defined before device_data
static ASHostGeomCacheInitializer as_host_geom_cache_initializer;

// Generally we expect to get the same device and instance, so we keep them handy
static std::shared_mutex instance_mutex;
static vvl::unordered_map<void *, std::unique_ptr<Instance>> instance_data;

static std::shared_mutex device_mutex;
static vvl::unordered_map<void *, std::unique_ptr<Device>> device_data;
static std::atomic<Device *> last_used_device = nullptr;

static Instance *GetInstanceFromKey(void *key) {
    ReadLockGuard lock(instance_mutex);
    return instance_data[key].get();
}

Instance *GetData(VkInstance instance) { return GetInstanceFromKey(GetDispatchKey(instance)); }

Instance *GetData(VkPhysicalDevice pd) { return GetInstanceFromKey(GetDispatchKey(pd)); }

void SetData(VkInstance instance, std::unique_ptr<Instance> &&data) {
    void *key = GetDispatchKey(instance);
    WriteLockGuard lock(instance_mutex);
    instance_data[key] = std::move(data);
}

void FreeData(void *key, VkInstance instance) {
    WriteLockGuard lock(instance_mutex);
    instance_data.erase(key);
}

static Device *GetDeviceFromKey(void *key) {
    Device *last_device = last_used_device.load();
    if (last_device && GetDispatchKey(last_device->device) == key) {
        return last_device;
    }
    ReadLockGuard lock(device_mutex);
    last_device = device_data[key].get();
    last_used_device.store(last_device);
    if (!last_device) {
        // If this occurs from atexit() using the layer, it would be better to provide a location where this happened, but
        // everything is tore down and there is not much to do. Also this is the single location where can detect this, so having it
        // here makes sure we don't miss a spot.
        const char *error =
            "\n\nVALIDATION ERROR - The VkDevice dispatch handle was not found and Validation will crash. If you are using exit() "
            "you need to make sure to not call any Vulkan calls in your atexit() function as the layer static memory will be "
            "destroyed prior to atexit()\n\n";
        printf("%s", error);
#ifdef VK_USE_PLATFORM_WIN32_KHR
        OutputDebugString(error);
#endif
        // last_device is later dereferenced and the user **will** crash soon. We purposefully crash here to ensure that the warning
        // is printed (and a stacktrace points them here first).
        std::abort();
    }
    return last_device;
}

Device *GetData(VkDevice device) { return GetDeviceFromKey(GetDispatchKey(device)); }

Device *GetData(VkQueue queue) { return GetDeviceFromKey(GetDispatchKey(queue)); }

Device *GetData(VkCommandBuffer cb) { return GetDeviceFromKey(GetDispatchKey(cb)); }

Device *GetData(VkExternalComputeQueueNV queue) { return GetDeviceFromKey(GetDispatchKey(queue)); }

void SetData(VkDevice device, std::unique_ptr<Device> &&data) {
    void *key = GetDispatchKey(device);
    WriteLockGuard lock(device_mutex);
    device_data[key] = std::move(data);
}

void FreeData(void *key, VkDevice device) {
    last_used_device.store(nullptr);
    WriteLockGuard lock(device_mutex);
    device_data.erase(key);
}

void FreeAllData() {
    // We use to have a WriteLockGuard here, but ran into threading issues.
    // This function is solely called from the atexit() handler, there shouldn't be anything vulkan related going on any more in any
    // application threads. See https://github.com/KhronosGroup/Vulkan-ValidationLayers/issues/10659
    last_used_device.store(nullptr);
    device_data.clear();

    instance_data.clear();
}

HandleWrapper::HandleWrapper(DebugReport *dr) : Logger(dr) {}
HandleWrapper::~HandleWrapper() {}

Instance::Instance(const VkInstanceCreateInfo *pCreateInfo) : HandleWrapper(new DebugReport) {
    uint32_t specified_version = (pCreateInfo->pApplicationInfo ? pCreateInfo->pApplicationInfo->apiVersion : VK_API_VERSION_1_0);
    api_version = VK_MAKE_API_VERSION(VK_API_VERSION_VARIANT(specified_version), VK_API_VERSION_MAJOR(specified_version),
                                      VK_API_VERSION_MINOR(specified_version), 0);

    InstanceExtensions instance_extensions(specified_version, pCreateInfo);
    extensions = DeviceExtensions(instance_extensions, api_version);

    debug_report->instance_pnext_chain = vku::SafePnextCopy(pCreateInfo->pNext);
    ActivateInstanceDebugCallbacks(debug_report);

    ConfigAndEnvSettings config_and_env_settings_data{OBJECT_LAYER_DESCRIPTION,
                                                      pCreateInfo,
                                                      settings.enabled,
                                                      settings.disabled,
                                                      debug_report,
                                                      &settings.global_settings,
                                                      &settings.gpuav_settings,
                                                      &settings.syncval_settings};
    ProcessConfigAndEnvSettings(&config_and_env_settings_data);

    if (settings.disabled[handle_wrapping]) {
        wrap_handles = false;
    }

    // create all enabled validation, which is API specific
    InitValidationObjects();

    for (auto &vo : object_dispatch) {
        vo->dispatch_instance_ = this;
        vo->CopyDispatchState();
    }
}

Instance::~Instance() {
    // Destroy validation objects in reverse order so that state tracker clients
    // are destroyed before it is.
    while (!object_dispatch.empty()) {
        object_dispatch.pop_back();
    }
    vku::FreePnextChain(debug_report->instance_pnext_chain);
    delete debug_report;
}

void Instance::FindSupportedExtensions() {
    uint32_t physical_device_count = 0u;
    instance_dispatch_table.EnumeratePhysicalDevices(instance, &physical_device_count, nullptr);
    std::vector<VkPhysicalDevice> physical_devices(physical_device_count);
    instance_dispatch_table.EnumeratePhysicalDevices(instance, &physical_device_count, physical_devices.data());
    for (const auto physical_device : physical_devices) {
        uint32_t extension_count = 0u;
        instance_dispatch_table.EnumerateDeviceExtensionProperties(physical_device, nullptr, &extension_count, nullptr);
        std::vector<VkExtensionProperties> supported_extensions(extension_count);
        instance_dispatch_table.EnumerateDeviceExtensionProperties(physical_device, nullptr, &extension_count,
                                                                   supported_extensions.data());
        MarkSupportedExtensionsAsNotEnabled(supported_extensions, extensions);
    }
}

VkResult Instance::GetPhysicalDeviceDisplayPropertiesKHR(VkPhysicalDevice physicalDevice, uint32_t *pPropertyCount,
                                                         VkDisplayPropertiesKHR *pProperties) {
    VkResult result = instance_dispatch_table.GetPhysicalDeviceDisplayPropertiesKHR(physicalDevice, pPropertyCount, pProperties);
    if (!wrap_handles) return result;
    if ((result == VK_SUCCESS || result == VK_INCOMPLETE) && pProperties) {
        for (uint32_t idx0 = 0; idx0 < *pPropertyCount; ++idx0) {
            pProperties[idx0].display = MaybeWrapDisplay(pProperties[idx0].display);
        }
    }
    return result;
}

VkResult Instance::GetPhysicalDeviceDisplayProperties2KHR(VkPhysicalDevice physicalDevice, uint32_t *pPropertyCount,
                                                          VkDisplayProperties2KHR *pProperties) {
    VkResult result = instance_dispatch_table.GetPhysicalDeviceDisplayProperties2KHR(physicalDevice, pPropertyCount, pProperties);
    if (!wrap_handles) return result;
    if ((result == VK_SUCCESS || result == VK_INCOMPLETE) && pProperties) {
        for (uint32_t idx0 = 0; idx0 < *pPropertyCount; ++idx0) {
            pProperties[idx0].displayProperties.display = MaybeWrapDisplay(pProperties[idx0].displayProperties.display);
        }
    }
    return result;
}

VkResult Instance::GetPhysicalDeviceDisplayPlanePropertiesKHR(VkPhysicalDevice physicalDevice, uint32_t *pPropertyCount,
                                                              VkDisplayPlanePropertiesKHR *pProperties) {
    VkResult result =
        instance_dispatch_table.GetPhysicalDeviceDisplayPlanePropertiesKHR(physicalDevice, pPropertyCount, pProperties);
    if (!wrap_handles) return result;
    if ((result == VK_SUCCESS || result == VK_INCOMPLETE) && pProperties) {
        for (uint32_t idx0 = 0; idx0 < *pPropertyCount; ++idx0) {
            VkDisplayKHR &opt_display = pProperties[idx0].currentDisplay;
            if (opt_display) opt_display = MaybeWrapDisplay(opt_display);
        }
    }
    return result;
}

VkResult Instance::GetPhysicalDeviceDisplayPlaneProperties2KHR(VkPhysicalDevice physicalDevice, uint32_t *pPropertyCount,
                                                               VkDisplayPlaneProperties2KHR *pProperties) {
    VkResult result =
        instance_dispatch_table.GetPhysicalDeviceDisplayPlaneProperties2KHR(physicalDevice, pPropertyCount, pProperties);
    if (!wrap_handles) return result;
    if ((result == VK_SUCCESS || result == VK_INCOMPLETE) && pProperties) {
        for (uint32_t idx0 = 0; idx0 < *pPropertyCount; ++idx0) {
            VkDisplayKHR &opt_display = pProperties[idx0].displayPlaneProperties.currentDisplay;
            if (opt_display) opt_display = MaybeWrapDisplay(opt_display);
        }
    }
    return result;
}

VkResult Instance::GetDisplayPlaneSupportedDisplaysKHR(VkPhysicalDevice physicalDevice, uint32_t planeIndex,
                                                       uint32_t *pDisplayCount, VkDisplayKHR *pDisplays) {
    VkResult result =
        instance_dispatch_table.GetDisplayPlaneSupportedDisplaysKHR(physicalDevice, planeIndex, pDisplayCount, pDisplays);
    if ((result == VK_SUCCESS || result == VK_INCOMPLETE) && pDisplays) {
        if (!wrap_handles) return result;
        for (uint32_t i = 0; i < *pDisplayCount; ++i) {
            if (pDisplays[i]) pDisplays[i] = MaybeWrapDisplay(pDisplays[i]);
        }
    }
    return result;
}

VkResult Instance::GetDisplayModePropertiesKHR(VkPhysicalDevice physicalDevice, VkDisplayKHR display, uint32_t *pPropertyCount,
                                               VkDisplayModePropertiesKHR *pProperties) {
    if (!wrap_handles)
        return instance_dispatch_table.GetDisplayModePropertiesKHR(physicalDevice, display, pPropertyCount, pProperties);
    display = Unwrap(display);

    VkResult result = instance_dispatch_table.GetDisplayModePropertiesKHR(physicalDevice, display, pPropertyCount, pProperties);
    if ((result == VK_SUCCESS || result == VK_INCOMPLETE) && pProperties) {
        for (uint32_t idx0 = 0; idx0 < *pPropertyCount; ++idx0) {
            pProperties[idx0].displayMode = WrapNew(pProperties[idx0].displayMode);
        }
    }
    return result;
}

VkResult Instance::GetDisplayModeProperties2KHR(VkPhysicalDevice physicalDevice, VkDisplayKHR display, uint32_t *pPropertyCount,
                                                VkDisplayModeProperties2KHR *pProperties) {
    if (!wrap_handles)
        return instance_dispatch_table.GetDisplayModeProperties2KHR(physicalDevice, display, pPropertyCount, pProperties);
    display = Unwrap(display);

    VkResult result = instance_dispatch_table.GetDisplayModeProperties2KHR(physicalDevice, display, pPropertyCount, pProperties);
    if ((result == VK_SUCCESS || result == VK_INCOMPLETE) && pProperties) {
        for (uint32_t idx0 = 0; idx0 < *pPropertyCount; ++idx0) {
            pProperties[idx0].displayModeProperties.displayMode = WrapNew(pProperties[idx0].displayModeProperties.displayMode);
        }
    }
    return result;
}

VkResult Instance::GetPhysicalDeviceToolPropertiesEXT(VkPhysicalDevice physicalDevice, uint32_t *pToolCount,
                                                      VkPhysicalDeviceToolPropertiesEXT *pToolProperties) {
    VkResult result = VK_SUCCESS;
    if (instance_dispatch_table.GetPhysicalDeviceToolPropertiesEXT == nullptr) {
        // This layer is the terminator. Set pToolCount to zero.
        *pToolCount = 0;
    } else {
        result = instance_dispatch_table.GetPhysicalDeviceToolPropertiesEXT(physicalDevice, pToolCount, pToolProperties);
    }

    return result;
}

VkResult Instance::GetPhysicalDeviceToolProperties(VkPhysicalDevice physicalDevice, uint32_t *pToolCount,
                                                   VkPhysicalDeviceToolProperties *pToolProperties) {
    VkResult result = VK_SUCCESS;
    if (instance_dispatch_table.GetPhysicalDeviceToolProperties == nullptr) {
        // This layer is the terminator. Set pToolCount to zero.
        *pToolCount = 0;
    } else {
        result = instance_dispatch_table.GetPhysicalDeviceToolProperties(physicalDevice, pToolCount, pToolProperties);
    }

    return result;
}

base::Instance *Instance::GetValidationObject(LayerObjectTypeId object_type) const {
    for (auto &validation_object : object_dispatch) {
        if (validation_object->container_type == object_type) {
            return validation_object.get();
        }
    }
    return nullptr;
}

Device::Device(Instance *instance, VkPhysicalDevice gpu, const VkDeviceCreateInfo *pCreateInfo)
    : HandleWrapper(instance->debug_report),
      settings(instance->settings),
      dispatch_instance(instance),
      stateless_device_data(instance, gpu, pCreateInfo),
      api_version(stateless_device_data.api_version),
      extensions(stateless_device_data.extensions),
      enabled_features(stateless_device_data.enabled_features),
      phys_dev_mem_props(stateless_device_data.phys_dev_mem_props),
      phys_dev_props(stateless_device_data.phys_dev_props),
      phys_dev_props_core11(stateless_device_data.phys_dev_props_core11),
      phys_dev_props_core12(stateless_device_data.phys_dev_props_core12),
      phys_dev_props_core13(stateless_device_data.phys_dev_props_core13),
      phys_dev_props_core14(stateless_device_data.phys_dev_props_core14),
      host_image_copy_props_copy_src_layouts(stateless_device_data.host_image_copy_props_copy_src_layouts),
      host_imape_copy_props_copy_dst_layouts(stateless_device_data.host_image_copy_props_copy_dst_layouts),
      phys_dev_ext_props(stateless_device_data.phys_dev_ext_props),
      physical_device(gpu) {
    InitValidationObjects();
    InitObjectDispatchVectors();
    for (auto &vo : object_dispatch) {
        vo->dispatch_device_ = this;
        vo->CopyDispatchState();
    }
}

Device::~Device() {
    // Destroy validation objects in reverse order so that state tracker clients
    // are destroyed before it is.
    while (!aborted_object_dispatch.empty()) {
        aborted_object_dispatch.pop_back();
    }
    while (!object_dispatch.empty()) {
        object_dispatch.pop_back();
    }
}

base::Device *Device::GetValidationObject(LayerObjectTypeId object_type) const {
    for (auto &validation_object : object_dispatch) {
        if (validation_object->container_type == object_type) {
            return validation_object.get();
        }
    }
    return nullptr;
}

void Device::DestroyDevice(VkDevice device, const VkAllocationCallbacks *pAllocator) {
    device_dispatch_table.DestroyDevice(device, pAllocator);
}

// Takes the validation type and removes it from the chassis so it will not be called anymore
// Designed for things like GPU-AV to remove itself while keeping everything else alive
void Device::ReleaseValidationObject(LayerObjectTypeId type_id) const {
    for (auto object_it = object_dispatch.begin(); object_it != object_dispatch.end(); object_it++) {
        if ((*object_it)->container_type == LayerObjectTypeStateTracker) {
            auto &state_tracker = dynamic_cast<vvl::DeviceState &>(**object_it);
            state_tracker.RemoveProxy(type_id);
        }
        if ((*object_it)->container_type == type_id) {
            auto object = std::move(*object_it);

            // Do not remove the smart pointer, to not invalidate object_dispatch iterators
            // object_dispatch.erase(object_it);

            for (auto intercept_vector_it = intercept_vectors.begin(); intercept_vector_it != intercept_vectors.end();
                 intercept_vector_it++) {
                for (auto intercept_object_it = intercept_vector_it->begin(); intercept_object_it != intercept_vector_it->end();
                     intercept_object_it++) {
                    if (object.get() == *intercept_object_it) {
                        // Do not actually remove the pointer, to not invalidate intercept_vectors iterators
                        *intercept_object_it = nullptr;
                        break;
                    }
                }
            }

            // We can't destroy the object itself now as it might be unsafe (things are still being used)
            // If the rare case happens we need to release, we will cleanup later when we normally would have cleaned this up
            aborted_object_dispatch.push_back(std::move(object));
            break;
        }
    }
}

#ifdef VK_USE_PLATFORM_METAL_EXT
// The vkExportMetalObjects extension returns data from the driver -- we've created a copy of the pNext chain, so
// copy the returned data to the caller
void CopyExportMetalObjects(const void *src_chain, const void *dst_chain) {
    while (src_chain && dst_chain) {
        const VkStructureType type = reinterpret_cast<const VkBaseOutStructure *>(src_chain)->sType;
        switch (type) {
            case VK_STRUCTURE_TYPE_EXPORT_METAL_DEVICE_INFO_EXT: {
                auto *pSrc = reinterpret_cast<const VkExportMetalDeviceInfoEXT *>(src_chain);
                auto *pDstConst = reinterpret_cast<const VkExportMetalDeviceInfoEXT *>(dst_chain);
                auto *pDst = const_cast<VkExportMetalDeviceInfoEXT *>(pDstConst);
                pDst->mtlDevice = pSrc->mtlDevice;
                break;
            }
            case VK_STRUCTURE_TYPE_EXPORT_METAL_COMMAND_QUEUE_INFO_EXT: {
                const auto *pSrc = reinterpret_cast<const VkExportMetalCommandQueueInfoEXT *>(src_chain);
                auto *pDstConst = reinterpret_cast<const VkExportMetalCommandQueueInfoEXT *>(dst_chain);
                auto *pDst = const_cast<VkExportMetalCommandQueueInfoEXT *>(pDstConst);
                pDst->mtlCommandQueue = pSrc->mtlCommandQueue;
                break;
            }
            case VK_STRUCTURE_TYPE_EXPORT_METAL_BUFFER_INFO_EXT: {
                const auto *pSrc = reinterpret_cast<const VkExportMetalBufferInfoEXT *>(src_chain);
                auto *pDstConst = reinterpret_cast<const VkExportMetalBufferInfoEXT *>(dst_chain);
                auto *pDst = const_cast<VkExportMetalBufferInfoEXT *>(pDstConst);
                pDst->mtlBuffer = pSrc->mtlBuffer;
                break;
            }
            case VK_STRUCTURE_TYPE_EXPORT_METAL_TEXTURE_INFO_EXT: {
                const auto *pSrc = reinterpret_cast<const VkExportMetalTextureInfoEXT *>(src_chain);
                auto *pDstConst = reinterpret_cast<const VkExportMetalTextureInfoEXT *>(dst_chain);
                auto *pDst = const_cast<VkExportMetalTextureInfoEXT *>(pDstConst);
                pDst->mtlTexture = pSrc->mtlTexture;
                break;
            }
            case VK_STRUCTURE_TYPE_EXPORT_METAL_IO_SURFACE_INFO_EXT: {
                const auto *pSrc = reinterpret_cast<const VkExportMetalIOSurfaceInfoEXT *>(src_chain);
                auto *pDstConst = reinterpret_cast<const VkExportMetalIOSurfaceInfoEXT *>(dst_chain);
                auto *pDst = const_cast<VkExportMetalIOSurfaceInfoEXT *>(pDstConst);
                pDst->ioSurface = pSrc->ioSurface;
                break;
            }
            case VK_STRUCTURE_TYPE_EXPORT_METAL_SHARED_EVENT_INFO_EXT: {
                const auto *pSrc = reinterpret_cast<const VkExportMetalSharedEventInfoEXT *>(src_chain);
                auto *pDstConst = reinterpret_cast<const VkExportMetalSharedEventInfoEXT *>(dst_chain);
                auto *pDst = const_cast<VkExportMetalSharedEventInfoEXT *>(pDstConst);
                pDst->mtlSharedEvent = pSrc->mtlSharedEvent;
                break;
            }
            default:
                assert(false);
                break;
        }

        // Handle pNext chaining
        src_chain = reinterpret_cast<const VkBaseOutStructure *>(src_chain)->pNext;
        dst_chain = reinterpret_cast<const VkBaseOutStructure *>(dst_chain)->pNext;
    }
}

void Device::ExportMetalObjectsEXT(VkDevice device, VkExportMetalObjectsInfoEXT *pMetalObjectsInfo) {
    if (!wrap_handles) return device_dispatch_table.ExportMetalObjectsEXT(device, pMetalObjectsInfo);
    vku::safe_VkExportMetalObjectsInfoEXT local_pMetalObjectsInfo;
    {
        if (pMetalObjectsInfo) {
            local_pMetalObjectsInfo.initialize(pMetalObjectsInfo);
            UnwrapPnextChainHandles(local_pMetalObjectsInfo.pNext);
        }
    }
    device_dispatch_table.ExportMetalObjectsEXT(device, (VkExportMetalObjectsInfoEXT *)&local_pMetalObjectsInfo);
    if (pMetalObjectsInfo) {
        CopyExportMetalObjects(local_pMetalObjectsInfo.pNext, pMetalObjectsInfo->pNext);
    }
}

#endif  // VK_USE_PLATFORM_METAL_EXT

// The VK_EXT_pipeline_creation_feedback extension returns data from the driver -- we've created a copy of the pnext chain, so
// copy the returned data to the caller before freeing the copy's data.
void CopyCreatePipelineFeedbackData(const void *src_chain, const void *dst_chain) {
    auto src_feedback_struct = vku::FindStructInPNextChain<VkPipelineCreationFeedbackCreateInfo>(src_chain);
    auto dst_feedback_struct = const_cast<VkPipelineCreationFeedbackCreateInfo *>(
        vku::FindStructInPNextChain<VkPipelineCreationFeedbackCreateInfo>(dst_chain));
    if (!src_feedback_struct || !dst_feedback_struct) return;
    ASSERT_AND_RETURN(dst_feedback_struct->pPipelineCreationFeedback && src_feedback_struct->pPipelineCreationFeedback);

    *dst_feedback_struct->pPipelineCreationFeedback = *src_feedback_struct->pPipelineCreationFeedback;
    for (uint32_t i = 0; i < src_feedback_struct->pipelineStageCreationFeedbackCount; i++) {
        dst_feedback_struct->pPipelineStageCreationFeedbacks[i] = src_feedback_struct->pPipelineStageCreationFeedbacks[i];
    }
}

VkResult Device::CreateGraphicsPipelines(VkDevice device, VkPipelineCache pipelineCache, uint32_t createInfoCount,
                                         const VkGraphicsPipelineCreateInfo *pCreateInfos, const VkAllocationCallbacks *pAllocator,
                                         VkPipeline *pPipelines) {
    if (!wrap_handles)
        return device_dispatch_table.CreateGraphicsPipelines(device, pipelineCache, createInfoCount, pCreateInfos, pAllocator,
                                                             pPipelines);
    vku::safe_VkGraphicsPipelineCreateInfo *local_pCreateInfos = nullptr;
    if (pCreateInfos) {
        local_pCreateInfos = new vku::safe_VkGraphicsPipelineCreateInfo[createInfoCount];
        ReadLockGuard lock(dispatch_lock);
        for (uint32_t idx0 = 0; idx0 < createInfoCount; ++idx0) {
            bool uses_color_attachment = false;
            bool uses_depthstencil_attachment = false;
            {
                const auto subpasses_uses_it = renderpasses_states.find(Unwrap(pCreateInfos[idx0].renderPass));
                if (subpasses_uses_it != renderpasses_states.end()) {
                    const auto &subpasses_uses = subpasses_uses_it->second;
                    if (subpasses_uses.subpasses_using_color_attachment.count(pCreateInfos[idx0].subpass))
                        uses_color_attachment = true;
                    if (subpasses_uses.subpasses_using_depthstencil_attachment.count(pCreateInfos[idx0].subpass))
                        uses_depthstencil_attachment = true;
                }
            }

            // We only want to find the case where the user is possibly building non-fragment output libraries
            bool has_fragment_output_state = true;
            if (auto lib_info = vku::FindStructInPNextChain<VkGraphicsPipelineLibraryCreateInfoEXT>(pCreateInfos[idx0].pNext)) {
                has_fragment_output_state = (lib_info->flags & VK_GRAPHICS_PIPELINE_LIBRARY_FRAGMENT_OUTPUT_INTERFACE_BIT_EXT) != 0;
            }

            const VkFormat *original_color_attachment_formats = nullptr;
            const VkPipelineRenderingCreateInfo *dynamic_rendering = nullptr;
            if (pCreateInfos[idx0].renderPass == VK_NULL_HANDLE) {
                dynamic_rendering = vku::FindStructInPNextChain<VkPipelineRenderingCreateInfo>(pCreateInfos[idx0].pNext);
            }
            if (dynamic_rendering) {
                if (has_fragment_output_state) {
                    uses_color_attachment = (dynamic_rendering->colorAttachmentCount > 0);
                    uses_depthstencil_attachment = (dynamic_rendering->depthAttachmentFormat != VK_FORMAT_UNDEFINED ||
                                                    dynamic_rendering->stencilAttachmentFormat != VK_FORMAT_UNDEFINED);
                } else {
                    // https://github.com/KhronosGroup/Vulkan-ValidationLayers/issues/9527
                    // If this is not a Fragment Output library, we need to make sure this is null for the user (who is allowed to
                    // have a garbage pointer) Unlike things like uses_color_attachment we can't do this easily in VUL because
                    // safe_VkGraphicsPipelineCreateInfo calls SafePnextCopy and we have no way to pass the "ignore" info to it We
                    // will just save the value, make a "safe" Safe Struct, then restore the pointer so the user doesn't notice
                    original_color_attachment_formats = dynamic_rendering->pColorAttachmentFormats;
                    const_cast<VkPipelineRenderingCreateInfo *>(dynamic_rendering)->pColorAttachmentFormats = nullptr;
                }
            }

            local_pCreateInfos[idx0].initialize(&pCreateInfos[idx0], uses_color_attachment, uses_depthstencil_attachment);

            if (dynamic_rendering && !has_fragment_output_state) {
                const_cast<VkPipelineRenderingCreateInfo *>(dynamic_rendering)->pColorAttachmentFormats =
                    original_color_attachment_formats;
            }

            if (pCreateInfos[idx0].basePipelineHandle) {
                local_pCreateInfos[idx0].basePipelineHandle = Unwrap(pCreateInfos[idx0].basePipelineHandle);
            }
            if (pCreateInfos[idx0].layout) {
                local_pCreateInfos[idx0].layout = Unwrap(pCreateInfos[idx0].layout);
            }
            if (pCreateInfos[idx0].pStages) {
                for (uint32_t idx1 = 0; idx1 < pCreateInfos[idx0].stageCount; ++idx1) {
                    if (pCreateInfos[idx0].pStages[idx1].module) {
                        local_pCreateInfos[idx0].pStages[idx1].module = Unwrap(pCreateInfos[idx0].pStages[idx1].module);
                    }
                }
            }
            if (pCreateInfos[idx0].renderPass) {
                local_pCreateInfos[idx0].renderPass = Unwrap(pCreateInfos[idx0].renderPass);
            }

            auto *link_info = vku::FindStructInPNextChain<VkPipelineLibraryCreateInfoKHR>(local_pCreateInfos[idx0].pNext);
            if (link_info) {
                auto *unwrapped_libs = const_cast<VkPipeline *>(link_info->pLibraries);
                for (uint32_t idx1 = 0; idx1 < link_info->libraryCount; ++idx1) {
                    unwrapped_libs[idx1] = Unwrap(link_info->pLibraries[idx1]);
                }
            }

            auto device_generated_commands =
                vku::FindStructInPNextChain<VkGraphicsPipelineShaderGroupsCreateInfoNV>(local_pCreateInfos[idx0].pNext);
            if (device_generated_commands) {
                for (uint32_t idx1 = 0; idx1 < device_generated_commands->groupCount; ++idx1) {
                    for (uint32_t idx2 = 0; idx2 < device_generated_commands->pGroups[idx1].stageCount; ++idx2) {
                        auto unwrapped_stage =
                            const_cast<VkPipelineShaderStageCreateInfo *>(&device_generated_commands->pGroups[idx1].pStages[idx2]);
                        if (device_generated_commands->pGroups[idx1].pStages[idx2].module) {
                            unwrapped_stage->module = Unwrap(device_generated_commands->pGroups[idx1].pStages[idx2].module);
                        }
                    }
                }
                auto unwrapped_pipelines = const_cast<VkPipeline *>(device_generated_commands->pPipelines);
                for (uint32_t idx1 = 0; idx1 < device_generated_commands->pipelineCount; ++idx1) {
                    unwrapped_pipelines[idx1] = Unwrap(device_generated_commands->pPipelines[idx1]);
                }
            }

            auto *binary_info = vku::FindStructInPNextChain<VkPipelineBinaryInfoKHR>(local_pCreateInfos[idx0].pNext);
            if (binary_info) {
                auto *unwrapped_binaries = const_cast<VkPipelineBinaryKHR *>(binary_info->pPipelineBinaries);
                for (uint32_t idx1 = 0; idx1 < binary_info->binaryCount; ++idx1) {
                    unwrapped_binaries[idx1] = Unwrap(binary_info->pPipelineBinaries[idx1]);
                }
            }
        }
    }
    if (pipelineCache) {
        pipelineCache = Unwrap(pipelineCache);
    }

    VkResult result = device_dispatch_table.CreateGraphicsPipelines(device, pipelineCache, createInfoCount,
                                                                    local_pCreateInfos->ptr(), pAllocator, pPipelines);
    for (uint32_t i = 0; i < createInfoCount; ++i) {
        if (pCreateInfos[i].pNext != VK_NULL_HANDLE) {
            CopyCreatePipelineFeedbackData(local_pCreateInfos[i].pNext, pCreateInfos[i].pNext);
        }
    }

    delete[] local_pCreateInfos;
    {
        for (uint32_t i = 0; i < createInfoCount; ++i) {
            if (pPipelines[i] != VK_NULL_HANDLE) {
                pPipelines[i] = WrapNew(pPipelines[i]);
            }
        }
    }
    return result;
}

template <typename T>
static void UpdateCreateRenderPassState(Device *layer_data, const T *pCreateInfo, VkRenderPass renderPass) {
    auto &renderpass_state = layer_data->renderpasses_states[renderPass];

    for (uint32_t subpass = 0; subpass < pCreateInfo->subpassCount; ++subpass) {
        bool uses_color = false;
        for (uint32_t i = 0; i < pCreateInfo->pSubpasses[subpass].colorAttachmentCount && !uses_color; ++i)
            if (pCreateInfo->pSubpasses[subpass].pColorAttachments[i].attachment != VK_ATTACHMENT_UNUSED) uses_color = true;

        bool uses_depthstencil = false;
        if (pCreateInfo->pSubpasses[subpass].pDepthStencilAttachment)
            if (pCreateInfo->pSubpasses[subpass].pDepthStencilAttachment->attachment != VK_ATTACHMENT_UNUSED)
                uses_depthstencil = true;

        if (uses_color) renderpass_state.subpasses_using_color_attachment.insert(subpass);
        if (uses_depthstencil) renderpass_state.subpasses_using_depthstencil_attachment.insert(subpass);
    }
}

template <>
void UpdateCreateRenderPassState(Device *layer_data, const VkRenderPassCreateInfo2 *pCreateInfo, VkRenderPass renderPass) {
    auto &renderpass_state = layer_data->renderpasses_states[renderPass];

    for (uint32_t subpassIndex = 0; subpassIndex < pCreateInfo->subpassCount; ++subpassIndex) {
        bool uses_color = false;
        const VkSubpassDescription2 &subpass = pCreateInfo->pSubpasses[subpassIndex];
        for (uint32_t i = 0; i < subpass.colorAttachmentCount && !uses_color; ++i)
            if (subpass.pColorAttachments[i].attachment != VK_ATTACHMENT_UNUSED) uses_color = true;

#if defined(VK_USE_PLATFORM_ANDROID_KHR)
        // VK_ANDROID_external_format_resolve allows for the only color attachment to be VK_ATTACHMENT_UNUSED
        // but in this case, it will use the resolve attachment as color attachment. Which means that we do
        // actually use color attachments
        if (subpass.pResolveAttachments != nullptr) {
            for (uint32_t i = 0; i < subpass.colorAttachmentCount && !uses_color; ++i) {
                uint32_t resolveAttachmentIndex = subpass.pResolveAttachments[i].attachment;
                const void *resolveAtatchmentPNextChain = pCreateInfo->pAttachments[resolveAttachmentIndex].pNext;
                if (vku::FindStructInPNextChain<VkExternalFormatANDROID>(resolveAtatchmentPNextChain)) uses_color = true;
            }
        }
#endif

        bool uses_depthstencil = false;
        if (subpass.pDepthStencilAttachment)
            if (subpass.pDepthStencilAttachment->attachment != VK_ATTACHMENT_UNUSED) uses_depthstencil = true;

        if (uses_color) renderpass_state.subpasses_using_color_attachment.insert(subpassIndex);
        if (uses_depthstencil) renderpass_state.subpasses_using_depthstencil_attachment.insert(subpassIndex);
    }
}

VkResult Device::CreateRenderPass(VkDevice device, const VkRenderPassCreateInfo *pCreateInfo,
                                  const VkAllocationCallbacks *pAllocator, VkRenderPass *pRenderPass) {
    VkResult result = device_dispatch_table.CreateRenderPass(device, pCreateInfo, pAllocator, pRenderPass);
    if (!wrap_handles) return result;
    if (result == VK_SUCCESS) {
        WriteLockGuard lock(dispatch_lock);
        UpdateCreateRenderPassState(this, pCreateInfo, *pRenderPass);
        *pRenderPass = WrapNew(*pRenderPass);
    }
    return result;
}

VkResult Device::CreateRenderPass2KHR(VkDevice device, const VkRenderPassCreateInfo2 *pCreateInfo,
                                      const VkAllocationCallbacks *pAllocator, VkRenderPass *pRenderPass) {
    VkResult result = device_dispatch_table.CreateRenderPass2KHR(device, pCreateInfo, pAllocator, pRenderPass);
    if (!wrap_handles) return result;
    if (result == VK_SUCCESS) {
        WriteLockGuard lock(dispatch_lock);
        UpdateCreateRenderPassState(this, pCreateInfo, *pRenderPass);
        *pRenderPass = WrapNew(*pRenderPass);
    }
    return result;
}

VkResult Device::CreateRenderPass2(VkDevice device, const VkRenderPassCreateInfo2 *pCreateInfo,
                                   const VkAllocationCallbacks *pAllocator, VkRenderPass *pRenderPass) {
    VkResult result = device_dispatch_table.CreateRenderPass2(device, pCreateInfo, pAllocator, pRenderPass);
    if (!wrap_handles) return result;
    if (result == VK_SUCCESS) {
        WriteLockGuard lock(dispatch_lock);
        UpdateCreateRenderPassState(this, pCreateInfo, *pRenderPass);
        *pRenderPass = WrapNew(*pRenderPass);
    }
    return result;
}

void Device::DestroyRenderPass(VkDevice device, VkRenderPass renderPass, const VkAllocationCallbacks *pAllocator) {
    if (!wrap_handles) return device_dispatch_table.DestroyRenderPass(device, renderPass, pAllocator);
    renderPass = Erase(renderPass);

    device_dispatch_table.DestroyRenderPass(device, renderPass, pAllocator);

    WriteLockGuard lock(dispatch_lock);
    renderpasses_states.erase(renderPass);
}

VkResult Device::GetSwapchainImagesKHR(VkDevice device, VkSwapchainKHR swapchain, uint32_t *pSwapchainImageCount,
                                       VkImage *pSwapchainImages) {
    if (!wrap_handles)
        return device_dispatch_table.GetSwapchainImagesKHR(device, swapchain, pSwapchainImageCount, pSwapchainImages);
    VkSwapchainKHR wrapped_swapchain_handle = swapchain;
    if (VK_NULL_HANDLE != swapchain) {
        swapchain = Unwrap(swapchain);
    }
    VkResult result = device_dispatch_table.GetSwapchainImagesKHR(device, swapchain, pSwapchainImageCount, pSwapchainImages);
    if ((result == VK_SUCCESS) || (VK_INCOMPLETE == result)) {
        if ((*pSwapchainImageCount > 0) && pSwapchainImages) {
            WriteLockGuard lock(dispatch_lock);
            auto &wrapped_swapchain_image_handles = swapchain_wrapped_image_handle_map[wrapped_swapchain_handle];
            for (uint32_t i = static_cast<uint32_t>(wrapped_swapchain_image_handles.size()); i < *pSwapchainImageCount; i++) {
                wrapped_swapchain_image_handles.emplace_back(WrapNew(pSwapchainImages[i]));
            }
            for (uint32_t i = 0; i < *pSwapchainImageCount; i++) {
                pSwapchainImages[i] = wrapped_swapchain_image_handles[i];
            }
        }
    }
    return result;
}

void Device::DestroySwapchainKHR(VkDevice device, VkSwapchainKHR swapchain, const VkAllocationCallbacks *pAllocator) {
    if (!wrap_handles) return device_dispatch_table.DestroySwapchainKHR(device, swapchain, pAllocator);
    WriteLockGuard lock(dispatch_lock);

    auto &image_array = swapchain_wrapped_image_handle_map[swapchain];
    for (auto &image_handle : image_array) {
        Erase(image_handle);
    }
    swapchain_wrapped_image_handle_map.erase(swapchain);
    lock.unlock();

    swapchain = Erase(swapchain);
    device_dispatch_table.DestroySwapchainKHR(device, swapchain, pAllocator);
}

VkResult Device::QueuePresentKHR(VkQueue queue, const VkPresentInfoKHR *pPresentInfo) {
    if (!wrap_handles) return device_dispatch_table.QueuePresentKHR(queue, pPresentInfo);
    vku::safe_VkPresentInfoKHR *local_pPresentInfo = nullptr;
    {
        if (pPresentInfo) {
            local_pPresentInfo = new vku::safe_VkPresentInfoKHR(pPresentInfo);
            if (local_pPresentInfo->pWaitSemaphores) {
                for (uint32_t index1 = 0; index1 < local_pPresentInfo->waitSemaphoreCount; ++index1) {
                    local_pPresentInfo->pWaitSemaphores[index1] = Unwrap(pPresentInfo->pWaitSemaphores[index1]);
                }
            }
            if (local_pPresentInfo->pSwapchains) {
                for (uint32_t index1 = 0; index1 < local_pPresentInfo->swapchainCount; ++index1) {
                    local_pPresentInfo->pSwapchains[index1] = Unwrap(pPresentInfo->pSwapchains[index1]);
                }
            }
            UnwrapPnextChainHandles(local_pPresentInfo->pNext);
        }
    }
    VkResult result = device_dispatch_table.QueuePresentKHR(queue, local_pPresentInfo->ptr());

    // pResults is an output array embedded in a structure. The code generator neglects to copy back from the vku::safe *version,
    // so handle it as a special case here:
    if (pPresentInfo && pPresentInfo->pResults) {
        for (uint32_t i = 0; i < pPresentInfo->swapchainCount; i++) {
            pPresentInfo->pResults[i] = local_pPresentInfo->pResults[i];
        }
    }
    delete local_pPresentInfo;
    return result;
}

void Device::DestroyDescriptorPool(VkDevice device, VkDescriptorPool descriptorPool, const VkAllocationCallbacks *pAllocator) {
    if (!wrap_handles) return device_dispatch_table.DestroyDescriptorPool(device, descriptorPool, pAllocator);
    WriteLockGuard lock(dispatch_lock);

    // remove references to implicitly freed descriptor sets
    for (auto descriptor_set : pool_descriptor_sets_map[descriptorPool]) {
        Erase(descriptor_set);
    }
    pool_descriptor_sets_map.erase(descriptorPool);
    lock.unlock();

    descriptorPool = Erase(descriptorPool);

    device_dispatch_table.DestroyDescriptorPool(device, descriptorPool, pAllocator);
}

VkResult Device::ResetDescriptorPool(VkDevice device, VkDescriptorPool descriptorPool, VkDescriptorPoolResetFlags flags) {
    if (!wrap_handles) return device_dispatch_table.ResetDescriptorPool(device, descriptorPool, flags);
    VkDescriptorPool local_descriptor_pool = VK_NULL_HANDLE;
    { local_descriptor_pool = Unwrap(descriptorPool); }
    VkResult result = device_dispatch_table.ResetDescriptorPool(device, local_descriptor_pool, flags);
    if (result == VK_SUCCESS) {
        WriteLockGuard lock(dispatch_lock);
        // remove references to implicitly freed descriptor sets
        for (auto descriptor_set : pool_descriptor_sets_map[descriptorPool]) {
            Erase(descriptor_set);
        }
        pool_descriptor_sets_map[descriptorPool].clear();
    }

    return result;
}

VkResult Device::AllocateDescriptorSets(VkDevice device, const VkDescriptorSetAllocateInfo *pAllocateInfo,
                                        VkDescriptorSet *pDescriptorSets) {
    if (!wrap_handles) return device_dispatch_table.AllocateDescriptorSets(device, pAllocateInfo, pDescriptorSets);
    vku::safe_VkDescriptorSetAllocateInfo *local_pAllocateInfo = nullptr;
    {
        if (pAllocateInfo) {
            local_pAllocateInfo = new vku::safe_VkDescriptorSetAllocateInfo(pAllocateInfo);
            if (pAllocateInfo->descriptorPool) {
                local_pAllocateInfo->descriptorPool = Unwrap(pAllocateInfo->descriptorPool);
            }
            if (local_pAllocateInfo->pSetLayouts) {
                for (uint32_t index1 = 0; index1 < local_pAllocateInfo->descriptorSetCount; ++index1) {
                    local_pAllocateInfo->pSetLayouts[index1] = Unwrap(local_pAllocateInfo->pSetLayouts[index1]);
                }
            }
        }
    }
    VkResult result = device_dispatch_table.AllocateDescriptorSets(device, (const VkDescriptorSetAllocateInfo *)local_pAllocateInfo,
                                                                   pDescriptorSets);
    if (local_pAllocateInfo) {
        delete local_pAllocateInfo;
    }
    if (result == VK_SUCCESS) {
        WriteLockGuard lock(dispatch_lock);
        auto &pool_descriptor_sets = pool_descriptor_sets_map[pAllocateInfo->descriptorPool];
        for (uint32_t index0 = 0; index0 < pAllocateInfo->descriptorSetCount; index0++) {
            pDescriptorSets[index0] = WrapNew(pDescriptorSets[index0]);
            pool_descriptor_sets.insert(pDescriptorSets[index0]);
        }
    }
    return result;
}

VkResult Device::FreeDescriptorSets(VkDevice device, VkDescriptorPool descriptorPool, uint32_t descriptorSetCount,
                                    const VkDescriptorSet *pDescriptorSets) {
    if (!wrap_handles) return device_dispatch_table.FreeDescriptorSets(device, descriptorPool, descriptorSetCount, pDescriptorSets);
    VkDescriptorSet *local_pDescriptorSets = nullptr;
    VkDescriptorPool local_descriptor_pool = VK_NULL_HANDLE;
    {
        local_descriptor_pool = Unwrap(descriptorPool);
        if (pDescriptorSets) {
            local_pDescriptorSets = new VkDescriptorSet[descriptorSetCount];
            for (uint32_t index0 = 0; index0 < descriptorSetCount; ++index0) {
                local_pDescriptorSets[index0] = Unwrap(pDescriptorSets[index0]);
            }
        }
    }
    VkResult result = device_dispatch_table.FreeDescriptorSets(device, local_descriptor_pool, descriptorSetCount,
                                                               (const VkDescriptorSet *)local_pDescriptorSets);
    if (local_pDescriptorSets) delete[] local_pDescriptorSets;
    if ((result == VK_SUCCESS) && (pDescriptorSets)) {
        WriteLockGuard lock(dispatch_lock);
        auto &pool_descriptor_sets = pool_descriptor_sets_map[descriptorPool];
        for (uint32_t index0 = 0; index0 < descriptorSetCount; index0++) {
            VkDescriptorSet handle = pDescriptorSets[index0];
            pool_descriptor_sets.erase(handle);
            Erase(handle);
        }
    }
    return result;
}

// This is the core version of this routine.  The extension version is below.
VkResult Device::CreateDescriptorUpdateTemplate(VkDevice device, const VkDescriptorUpdateTemplateCreateInfo *pCreateInfo,
                                                const VkAllocationCallbacks *pAllocator,
                                                VkDescriptorUpdateTemplate *pDescriptorUpdateTemplate) {
    if (!wrap_handles)
        return device_dispatch_table.CreateDescriptorUpdateTemplate(device, pCreateInfo, pAllocator, pDescriptorUpdateTemplate);
    vku::safe_VkDescriptorUpdateTemplateCreateInfo var_local_pCreateInfo;
    vku::safe_VkDescriptorUpdateTemplateCreateInfo *local_pCreateInfo = nullptr;
    if (pCreateInfo) {
        local_pCreateInfo = &var_local_pCreateInfo;
        local_pCreateInfo->initialize(pCreateInfo);
        if (pCreateInfo->templateType == VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_DESCRIPTOR_SET) {
            local_pCreateInfo->descriptorSetLayout = Unwrap(pCreateInfo->descriptorSetLayout);
        }
        if (pCreateInfo->templateType == VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_PUSH_DESCRIPTORS) {
            local_pCreateInfo->pipelineLayout = Unwrap(pCreateInfo->pipelineLayout);
        }
    }
    VkResult result = device_dispatch_table.CreateDescriptorUpdateTemplate(device, local_pCreateInfo->ptr(), pAllocator,
                                                                           pDescriptorUpdateTemplate);
    if (result == VK_SUCCESS) {
        *pDescriptorUpdateTemplate = WrapNew(*pDescriptorUpdateTemplate);

        // Shadow template createInfo for later updates
        if (local_pCreateInfo) {
            WriteLockGuard lock(dispatch_lock);
            std::unique_ptr<TemplateState> template_state(new TemplateState(*pDescriptorUpdateTemplate, local_pCreateInfo));
            desc_template_createinfo_map[(uint64_t)*pDescriptorUpdateTemplate] = std::move(template_state);
        }
    }
    return result;
}

// This is the extension version of this routine.  The core version is above.
VkResult Device::CreateDescriptorUpdateTemplateKHR(VkDevice device, const VkDescriptorUpdateTemplateCreateInfo *pCreateInfo,
                                                   const VkAllocationCallbacks *pAllocator,
                                                   VkDescriptorUpdateTemplate *pDescriptorUpdateTemplate) {
    if (!wrap_handles)
        return device_dispatch_table.CreateDescriptorUpdateTemplateKHR(device, pCreateInfo, pAllocator, pDescriptorUpdateTemplate);
    vku::safe_VkDescriptorUpdateTemplateCreateInfo var_local_pCreateInfo;
    vku::safe_VkDescriptorUpdateTemplateCreateInfo *local_pCreateInfo = nullptr;
    if (pCreateInfo) {
        local_pCreateInfo = &var_local_pCreateInfo;
        local_pCreateInfo->initialize(pCreateInfo);
        if (pCreateInfo->templateType == VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_DESCRIPTOR_SET) {
            local_pCreateInfo->descriptorSetLayout = Unwrap(pCreateInfo->descriptorSetLayout);
        }
        if (pCreateInfo->templateType == VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_PUSH_DESCRIPTORS) {
            local_pCreateInfo->pipelineLayout = Unwrap(pCreateInfo->pipelineLayout);
        }
    }
    VkResult result = device_dispatch_table.CreateDescriptorUpdateTemplateKHR(device, local_pCreateInfo->ptr(), pAllocator,
                                                                              pDescriptorUpdateTemplate);

    if (result == VK_SUCCESS) {
        *pDescriptorUpdateTemplate = WrapNew(*pDescriptorUpdateTemplate);

        // Shadow template createInfo for later updates
        if (local_pCreateInfo) {
            WriteLockGuard lock(dispatch_lock);
            std::unique_ptr<TemplateState> template_state(new TemplateState(*pDescriptorUpdateTemplate, local_pCreateInfo));
            desc_template_createinfo_map[(uint64_t)*pDescriptorUpdateTemplate] = std::move(template_state);
        }
    }
    return result;
}

// This is the core version of this routine.  The extension version is below.
void Device::DestroyDescriptorUpdateTemplate(VkDevice device, VkDescriptorUpdateTemplate descriptorUpdateTemplate,
                                             const VkAllocationCallbacks *pAllocator) {
    if (!wrap_handles) return device_dispatch_table.DestroyDescriptorUpdateTemplate(device, descriptorUpdateTemplate, pAllocator);
    WriteLockGuard lock(dispatch_lock);
    uint64_t descriptor_update_template_id = CastToUint64(descriptorUpdateTemplate);
    desc_template_createinfo_map.erase(descriptor_update_template_id);
    lock.unlock();

    descriptorUpdateTemplate = Erase(descriptorUpdateTemplate);

    device_dispatch_table.DestroyDescriptorUpdateTemplate(device, descriptorUpdateTemplate, pAllocator);
}

// This is the extension version of this routine.  The core version is above.
void Device::DestroyDescriptorUpdateTemplateKHR(VkDevice device, VkDescriptorUpdateTemplate descriptorUpdateTemplate,
                                                const VkAllocationCallbacks *pAllocator) {
    if (!wrap_handles)
        return device_dispatch_table.DestroyDescriptorUpdateTemplateKHR(device, descriptorUpdateTemplate, pAllocator);
    WriteLockGuard lock(dispatch_lock);
    uint64_t descriptor_update_template_id = CastToUint64(descriptorUpdateTemplate);
    desc_template_createinfo_map.erase(descriptor_update_template_id);
    lock.unlock();

    descriptorUpdateTemplate = Erase(descriptorUpdateTemplate);

    device_dispatch_table.DestroyDescriptorUpdateTemplateKHR(device, descriptorUpdateTemplate, pAllocator);
}

void *BuildUnwrappedUpdateTemplateBuffer(Device *layer_data, uint64_t descriptorUpdateTemplate, const void *pData) {
    auto const template_map_entry = layer_data->desc_template_createinfo_map.find(descriptorUpdateTemplate);
    auto const &create_info = template_map_entry->second->create_info;
    size_t allocation_size = 0;
    std::vector<std::tuple<size_t, VulkanObjectType, uint64_t, size_t>> template_entries;

    for (uint32_t i = 0; i < create_info.descriptorUpdateEntryCount; i++) {
        for (uint32_t j = 0; j < create_info.pDescriptorUpdateEntries[i].descriptorCount; j++) {
            size_t offset = create_info.pDescriptorUpdateEntries[i].offset + j * create_info.pDescriptorUpdateEntries[i].stride;
            char *update_entry = (char *)(pData) + offset;

            switch (create_info.pDescriptorUpdateEntries[i].descriptorType) {
                case VK_DESCRIPTOR_TYPE_SAMPLER:
                case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
                case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
                case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
                case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT: {
                    auto image_entry = reinterpret_cast<VkDescriptorImageInfo *>(update_entry);
                    allocation_size = std::max(allocation_size, offset + sizeof(VkDescriptorImageInfo));

                    VkDescriptorImageInfo *wrapped_entry = new VkDescriptorImageInfo(*image_entry);
                    wrapped_entry->sampler = layer_data->Unwrap(image_entry->sampler);
                    wrapped_entry->imageView = layer_data->Unwrap(image_entry->imageView);
                    template_entries.emplace_back(offset, kVulkanObjectTypeImage, CastToUint64(wrapped_entry), 0);
                } break;

                case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
                case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
                case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
                case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC: {
                    auto buffer_entry = reinterpret_cast<VkDescriptorBufferInfo *>(update_entry);
                    allocation_size = std::max(allocation_size, offset + sizeof(VkDescriptorBufferInfo));

                    VkDescriptorBufferInfo *wrapped_entry = new VkDescriptorBufferInfo(*buffer_entry);
                    wrapped_entry->buffer = layer_data->Unwrap(buffer_entry->buffer);
                    template_entries.emplace_back(offset, kVulkanObjectTypeBuffer, CastToUint64(wrapped_entry), 0);
                } break;

                case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
                case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER: {
                    auto buffer_view_handle = reinterpret_cast<VkBufferView *>(update_entry);
                    allocation_size = std::max(allocation_size, offset + sizeof(VkBufferView));

                    VkBufferView wrapped_entry = layer_data->Unwrap(*buffer_view_handle);
                    template_entries.emplace_back(offset, kVulkanObjectTypeBufferView, CastToUint64(wrapped_entry), 0);
                } break;
                case VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK: {
                    size_t numBytes = create_info.pDescriptorUpdateEntries[i].descriptorCount;
                    allocation_size = std::max(allocation_size, offset + numBytes);
                    // nothing to unwrap, just plain data
                    template_entries.emplace_back(offset, kVulkanObjectTypeUnknown, CastToUint64(update_entry), numBytes);
                    // to break out of the loop
                    j = create_info.pDescriptorUpdateEntries[i].descriptorCount;
                } break;
                case VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_NV: {
                    auto accstruct_nv_handle = reinterpret_cast<VkAccelerationStructureNV *>(update_entry);
                    allocation_size = std::max(allocation_size, offset + sizeof(VkAccelerationStructureNV));

                    VkAccelerationStructureNV wrapped_entry = layer_data->Unwrap(*accstruct_nv_handle);
                    template_entries.emplace_back(offset, kVulkanObjectTypeAccelerationStructureNV, CastToUint64(wrapped_entry), 0);
                } break;
                case VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR: {
                    auto accstruct_khr_handle = reinterpret_cast<VkAccelerationStructureKHR *>(update_entry);
                    allocation_size = std::max(allocation_size, offset + sizeof(VkAccelerationStructureKHR));

                    VkAccelerationStructureKHR wrapped_entry = layer_data->Unwrap(*accstruct_khr_handle);
                    template_entries.emplace_back(offset, kVulkanObjectTypeAccelerationStructureKHR, CastToUint64(wrapped_entry),
                                                  0);
                } break;
                case VK_DESCRIPTOR_TYPE_PARTITIONED_ACCELERATION_STRUCTURE_NV: {
                    // PTLAS uses VkDeviceAddress directly, not an opaque handle - no unwrapping needed
                    allocation_size = std::max(allocation_size, offset + sizeof(VkDeviceAddress));
                    template_entries.emplace_back(offset, kVulkanObjectTypeUnknown, CastToUint64(update_entry),
                                                  sizeof(VkDeviceAddress));
                } break;
                default:
                    assert(false);
                    break;
            }
        }
    }
    // Allocate required buffer size and populate with source/unwrapped data
    void *unwrapped_data = malloc(allocation_size);
    for (auto &this_entry : template_entries) {
        VulkanObjectType type = std::get<1>(this_entry);
        void *destination = (char *)unwrapped_data + std::get<0>(this_entry);
        uint64_t source = std::get<2>(this_entry);
        size_t size = std::get<3>(this_entry);

        if (size != 0) {
            assert(type == kVulkanObjectTypeUnknown);
            memcpy(destination, CastFromUint64<void *>(source), size);
        } else {
            switch (type) {
                case kVulkanObjectTypeImage:
                    *(reinterpret_cast<VkDescriptorImageInfo *>(destination)) =
                        *(reinterpret_cast<VkDescriptorImageInfo *>(source));
                    delete CastFromUint64<VkDescriptorImageInfo *>(source);
                    break;
                case kVulkanObjectTypeBuffer:
                    *(reinterpret_cast<VkDescriptorBufferInfo *>(destination)) =
                        *(CastFromUint64<VkDescriptorBufferInfo *>(source));
                    delete CastFromUint64<VkDescriptorBufferInfo *>(source);
                    break;
                case kVulkanObjectTypeBufferView:
                    *(reinterpret_cast<VkBufferView *>(destination)) = CastFromUint64<VkBufferView>(source);
                    break;
                case kVulkanObjectTypeAccelerationStructureKHR:
                    *(reinterpret_cast<VkAccelerationStructureKHR *>(destination)) =
                        CastFromUint64<VkAccelerationStructureKHR>(source);
                    break;
                case kVulkanObjectTypeAccelerationStructureNV:
                    *(reinterpret_cast<VkAccelerationStructureNV *>(destination)) =
                        CastFromUint64<VkAccelerationStructureNV>(source);
                    break;
                default:
                    assert(false);
                    break;
            }
        }
    }
    return (void *)unwrapped_data;
}

void Device::UpdateDescriptorSetWithTemplate(VkDevice device, VkDescriptorSet descriptorSet,
                                             VkDescriptorUpdateTemplate descriptorUpdateTemplate, const void *pData) {
    if (!wrap_handles)
        return device_dispatch_table.UpdateDescriptorSetWithTemplate(device, descriptorSet, descriptorUpdateTemplate, pData);
    uint64_t template_handle = CastToUint64(descriptorUpdateTemplate);
    void *unwrapped_buffer = nullptr;
    {
        ReadLockGuard lock(dispatch_lock);
        descriptorSet = Unwrap(descriptorSet);
        descriptorUpdateTemplate = (VkDescriptorUpdateTemplate)Unwrap(descriptorUpdateTemplate);
        unwrapped_buffer = BuildUnwrappedUpdateTemplateBuffer(this, template_handle, pData);
    }
    device_dispatch_table.UpdateDescriptorSetWithTemplate(device, descriptorSet, descriptorUpdateTemplate, unwrapped_buffer);
    free(unwrapped_buffer);
}

void Device::UpdateDescriptorSetWithTemplateKHR(VkDevice device, VkDescriptorSet descriptorSet,
                                                VkDescriptorUpdateTemplate descriptorUpdateTemplate, const void *pData) {
    if (!wrap_handles)
        return device_dispatch_table.UpdateDescriptorSetWithTemplateKHR(device, descriptorSet, descriptorUpdateTemplate, pData);
    uint64_t template_handle = CastToUint64(descriptorUpdateTemplate);
    void *unwrapped_buffer = nullptr;
    {
        ReadLockGuard lock(dispatch_lock);
        descriptorSet = Unwrap(descriptorSet);
        descriptorUpdateTemplate = Unwrap(descriptorUpdateTemplate);
        unwrapped_buffer = BuildUnwrappedUpdateTemplateBuffer(this, template_handle, pData);
    }
    device_dispatch_table.UpdateDescriptorSetWithTemplateKHR(device, descriptorSet, descriptorUpdateTemplate, unwrapped_buffer);
    free(unwrapped_buffer);
}

void Device::CmdPushDescriptorSetWithTemplate(VkCommandBuffer commandBuffer, VkDescriptorUpdateTemplate descriptorUpdateTemplate,
                                              VkPipelineLayout layout, uint32_t set, const void *pData) {
    if (!wrap_handles)
        return device_dispatch_table.CmdPushDescriptorSetWithTemplateKHR(commandBuffer, descriptorUpdateTemplate, layout, set,
                                                                         pData);
    uint64_t template_handle = CastToUint64(descriptorUpdateTemplate);
    void *unwrapped_buffer = nullptr;
    {
        ReadLockGuard lock(dispatch_lock);
        descriptorUpdateTemplate = Unwrap(descriptorUpdateTemplate);
        layout = Unwrap(layout);
        unwrapped_buffer = BuildUnwrappedUpdateTemplateBuffer(this, template_handle, pData);
    }
    device_dispatch_table.CmdPushDescriptorSetWithTemplate(commandBuffer, descriptorUpdateTemplate, layout, set, unwrapped_buffer);
    free(unwrapped_buffer);
}

void Device::CmdPushDescriptorSetWithTemplateKHR(VkCommandBuffer commandBuffer, VkDescriptorUpdateTemplate descriptorUpdateTemplate,
                                                 VkPipelineLayout layout, uint32_t set, const void *pData) {
    if (!wrap_handles)
        return device_dispatch_table.CmdPushDescriptorSetWithTemplateKHR(commandBuffer, descriptorUpdateTemplate, layout, set,
                                                                         pData);
    uint64_t template_handle = CastToUint64(descriptorUpdateTemplate);
    void *unwrapped_buffer = nullptr;
    {
        ReadLockGuard lock(dispatch_lock);
        descriptorUpdateTemplate = Unwrap(descriptorUpdateTemplate);
        layout = Unwrap(layout);
        unwrapped_buffer = BuildUnwrappedUpdateTemplateBuffer(this, template_handle, pData);
    }
    device_dispatch_table.CmdPushDescriptorSetWithTemplateKHR(commandBuffer, descriptorUpdateTemplate, layout, set,
                                                              unwrapped_buffer);
    free(unwrapped_buffer);
}

void Device::CmdPushDescriptorSetWithTemplate2(VkCommandBuffer commandBuffer,
                                               const VkPushDescriptorSetWithTemplateInfo *pPushDescriptorSetWithTemplateInfo) {
    if (!wrap_handles)
        return device_dispatch_table.CmdPushDescriptorSetWithTemplate2KHR(commandBuffer, pPushDescriptorSetWithTemplateInfo);
    uint64_t template_handle = CastToUint64(pPushDescriptorSetWithTemplateInfo->descriptorUpdateTemplate);
    void *unwrapped_buffer = nullptr;
    {
        ReadLockGuard lock(dispatch_lock);
        const_cast<VkPushDescriptorSetWithTemplateInfo *>(pPushDescriptorSetWithTemplateInfo)->descriptorUpdateTemplate =
            Unwrap(pPushDescriptorSetWithTemplateInfo->descriptorUpdateTemplate);
        const_cast<VkPushDescriptorSetWithTemplateInfo *>(pPushDescriptorSetWithTemplateInfo)->layout =
            Unwrap(pPushDescriptorSetWithTemplateInfo->layout);
        unwrapped_buffer = BuildUnwrappedUpdateTemplateBuffer(this, template_handle, pPushDescriptorSetWithTemplateInfo->pData);
        const_cast<VkPushDescriptorSetWithTemplateInfo *>(pPushDescriptorSetWithTemplateInfo)->pData = unwrapped_buffer;
    }
    device_dispatch_table.CmdPushDescriptorSetWithTemplate2(commandBuffer, pPushDescriptorSetWithTemplateInfo);
    free(unwrapped_buffer);
}

void Device::CmdPushDescriptorSetWithTemplate2KHR(
    VkCommandBuffer commandBuffer, const VkPushDescriptorSetWithTemplateInfoKHR *pPushDescriptorSetWithTemplateInfo) {
    if (!wrap_handles)
        return device_dispatch_table.CmdPushDescriptorSetWithTemplate2KHR(commandBuffer, pPushDescriptorSetWithTemplateInfo);
    uint64_t template_handle = CastToUint64(pPushDescriptorSetWithTemplateInfo->descriptorUpdateTemplate);
    void *unwrapped_buffer = nullptr;
    {
        ReadLockGuard lock(dispatch_lock);
        const_cast<VkPushDescriptorSetWithTemplateInfoKHR *>(pPushDescriptorSetWithTemplateInfo)->descriptorUpdateTemplate =
            Unwrap(pPushDescriptorSetWithTemplateInfo->descriptorUpdateTemplate);
        const_cast<VkPushDescriptorSetWithTemplateInfoKHR *>(pPushDescriptorSetWithTemplateInfo)->layout =
            Unwrap(pPushDescriptorSetWithTemplateInfo->layout);
        unwrapped_buffer = BuildUnwrappedUpdateTemplateBuffer(this, template_handle, pPushDescriptorSetWithTemplateInfo->pData);
        const_cast<VkPushDescriptorSetWithTemplateInfoKHR *>(pPushDescriptorSetWithTemplateInfo)->pData = unwrapped_buffer;
    }
    device_dispatch_table.CmdPushDescriptorSetWithTemplate2KHR(commandBuffer, pPushDescriptorSetWithTemplateInfo);
    free(unwrapped_buffer);
}

VkResult Device::DebugMarkerSetObjectTagEXT(VkDevice device, const VkDebugMarkerObjectTagInfoEXT *pTagInfo) {
    if (!wrap_handles) return device_dispatch_table.DebugMarkerSetObjectTagEXT(device, pTagInfo);
    vku::safe_VkDebugMarkerObjectTagInfoEXT local_tag_info(pTagInfo);

    auto unwrapped = Find(local_tag_info.object);
    if (unwrapped) {
        local_tag_info.object = unwrapped;
    }

    return device_dispatch_table.DebugMarkerSetObjectTagEXT(device,
                                                            reinterpret_cast<VkDebugMarkerObjectTagInfoEXT *>(&local_tag_info));
}

VkResult Device::DebugMarkerSetObjectNameEXT(VkDevice device, const VkDebugMarkerObjectNameInfoEXT *pNameInfo) {
    if (!wrap_handles) return device_dispatch_table.DebugMarkerSetObjectNameEXT(device, pNameInfo);
    vku::safe_VkDebugMarkerObjectNameInfoEXT local_name_info(pNameInfo);

    auto unwrapped = Find(local_name_info.object);
    if (unwrapped) {
        local_name_info.object = unwrapped;
    }

    return device_dispatch_table.DebugMarkerSetObjectNameEXT(device,
                                                             reinterpret_cast<VkDebugMarkerObjectNameInfoEXT *>(&local_name_info));
}

// VK_EXT_debug_utils
VkResult Device::SetDebugUtilsObjectTagEXT(VkDevice device, const VkDebugUtilsObjectTagInfoEXT *pTagInfo) {
    if (!wrap_handles) return device_dispatch_table.SetDebugUtilsObjectTagEXT(device, pTagInfo);
    vku::safe_VkDebugUtilsObjectTagInfoEXT local_tag_info(pTagInfo);

    auto unwrapped = Find(local_tag_info.objectHandle);
    if (unwrapped) {
        local_tag_info.objectHandle = unwrapped;
    }

    return device_dispatch_table.SetDebugUtilsObjectTagEXT(device,
                                                           reinterpret_cast<const VkDebugUtilsObjectTagInfoEXT *>(&local_tag_info));
}

VkResult Device::SetDebugUtilsObjectNameEXT(VkDevice device, const VkDebugUtilsObjectNameInfoEXT *pNameInfo) {
    if (!wrap_handles) return device_dispatch_table.SetDebugUtilsObjectNameEXT(device, pNameInfo);
    vku::safe_VkDebugUtilsObjectNameInfoEXT local_name_info(pNameInfo);

    auto unwrapped = Find(local_name_info.objectHandle);
    if (unwrapped) {
        local_name_info.objectHandle = unwrapped;
    }

    return device_dispatch_table.SetDebugUtilsObjectNameEXT(
        device, reinterpret_cast<const VkDebugUtilsObjectNameInfoEXT *>(&local_name_info));
}

VkResult Device::AllocateCommandBuffers(VkDevice device, const VkCommandBufferAllocateInfo *pAllocateInfo,
                                        VkCommandBuffer *pCommandBuffers) {
    if (!wrap_handles) return device_dispatch_table.AllocateCommandBuffers(device, pAllocateInfo, pCommandBuffers);
    vku::safe_VkCommandBufferAllocateInfo local_pAllocateInfo;
    if (pAllocateInfo) {
        local_pAllocateInfo.initialize(pAllocateInfo);
        if (pAllocateInfo->commandPool) {
            local_pAllocateInfo.commandPool = Unwrap(pAllocateInfo->commandPool);
        }
    }
    VkResult result = device_dispatch_table.AllocateCommandBuffers(
        device, (const VkCommandBufferAllocateInfo *)&local_pAllocateInfo, pCommandBuffers);
    if ((result == VK_SUCCESS) && pAllocateInfo && (pAllocateInfo->level == VK_COMMAND_BUFFER_LEVEL_SECONDARY)) {
        auto lock = WriteLockGuard(secondary_cb_map_mutex);
        for (uint32_t cb_index = 0; cb_index < pAllocateInfo->commandBufferCount; cb_index++) {
            secondary_cb_map.emplace(pCommandBuffers[cb_index], pAllocateInfo->commandPool);
        }
    }
    return result;
}

void Device::FreeCommandBuffers(VkDevice device, VkCommandPool commandPool, uint32_t commandBufferCount,
                                const VkCommandBuffer *pCommandBuffers) {
    if (!wrap_handles) return device_dispatch_table.FreeCommandBuffers(device, commandPool, commandBufferCount, pCommandBuffers);
    commandPool = Unwrap(commandPool);
    device_dispatch_table.FreeCommandBuffers(device, commandPool, commandBufferCount, pCommandBuffers);

    auto lock = WriteLockGuard(secondary_cb_map_mutex);
    for (uint32_t cb_index = 0; cb_index < commandBufferCount; cb_index++) {
        secondary_cb_map.erase(pCommandBuffers[cb_index]);
    }
}

void Device::DestroyCommandPool(VkDevice device, VkCommandPool commandPool, const VkAllocationCallbacks *pAllocator) {
    if (!wrap_handles) return device_dispatch_table.DestroyCommandPool(device, commandPool, pAllocator);

    commandPool = Erase(commandPool);
    device_dispatch_table.DestroyCommandPool(device, commandPool, pAllocator);

    auto lock = WriteLockGuard(secondary_cb_map_mutex);
    for (auto item = secondary_cb_map.begin(); item != secondary_cb_map.end();) {
        if (item->second == commandPool) {
            item = secondary_cb_map.erase(item);
        } else {
            ++item;
        }
    }
}

bool Device::IsSecondary(VkCommandBuffer commandBuffer) const {
    auto lock = ReadLockGuard(secondary_cb_map_mutex);
    return secondary_cb_map.find(commandBuffer) != secondary_cb_map.end();
}

VkResult Device::BeginCommandBuffer(VkCommandBuffer commandBuffer, const VkCommandBufferBeginInfo *pBeginInfo) {
    if (!wrap_handles || !IsSecondary(commandBuffer)) return device_dispatch_table.BeginCommandBuffer(commandBuffer, pBeginInfo);
    vku::safe_VkCommandBufferBeginInfo local_pBeginInfo;
    if (pBeginInfo) {
        local_pBeginInfo.initialize(pBeginInfo);
        if (local_pBeginInfo.pInheritanceInfo) {
            if (pBeginInfo->pInheritanceInfo->renderPass) {
                local_pBeginInfo.pInheritanceInfo->renderPass = Unwrap(pBeginInfo->pInheritanceInfo->renderPass);
            }
            if (pBeginInfo->pInheritanceInfo->framebuffer) {
                local_pBeginInfo.pInheritanceInfo->framebuffer = Unwrap(pBeginInfo->pInheritanceInfo->framebuffer);
            }
        }
    }
    VkResult result = device_dispatch_table.BeginCommandBuffer(commandBuffer, (const VkCommandBufferBeginInfo *)&local_pBeginInfo);
    return result;
}

VkResult Device::CreateRayTracingPipelinesKHR(VkDevice device, VkDeferredOperationKHR deferredOperation,
                                              VkPipelineCache pipelineCache, uint32_t createInfoCount,
                                              const VkRayTracingPipelineCreateInfoKHR *pCreateInfos,
                                              const VkAllocationCallbacks *pAllocator, VkPipeline *pPipelines) {
    vku::safe_VkRayTracingPipelineCreateInfoKHR *local_pCreateInfos = (vku::safe_VkRayTracingPipelineCreateInfoKHR *)(pCreateInfos);
    if (wrap_handles) {
        deferredOperation = Unwrap(deferredOperation);
        pipelineCache = Unwrap(pipelineCache);
        if (pCreateInfos) {
            local_pCreateInfos = new vku::safe_VkRayTracingPipelineCreateInfoKHR[createInfoCount];
            for (uint32_t index0 = 0; index0 < createInfoCount; ++index0) {
                local_pCreateInfos[index0].initialize(&pCreateInfos[index0]);
                if (local_pCreateInfos[index0].pStages) {
                    for (uint32_t index1 = 0; index1 < local_pCreateInfos[index0].stageCount; ++index1) {
                        if (pCreateInfos[index0].pStages[index1].module) {
                            local_pCreateInfos[index0].pStages[index1].module = Unwrap(pCreateInfos[index0].pStages[index1].module);
                        }
                    }
                }
                if (local_pCreateInfos[index0].pLibraryInfo) {
                    if (local_pCreateInfos[index0].pLibraryInfo->pLibraries) {
                        for (uint32_t index2 = 0; index2 < local_pCreateInfos[index0].pLibraryInfo->libraryCount; ++index2) {
                            local_pCreateInfos[index0].pLibraryInfo->pLibraries[index2] =
                                Unwrap(local_pCreateInfos[index0].pLibraryInfo->pLibraries[index2]);
                        }
                    }
                }
                if (pCreateInfos[index0].layout) {
                    local_pCreateInfos[index0].layout = Unwrap(pCreateInfos[index0].layout);
                }
                if (pCreateInfos[index0].basePipelineHandle) {
                    local_pCreateInfos[index0].basePipelineHandle = Unwrap(pCreateInfos[index0].basePipelineHandle);
                }

                auto *binary_info = vku::FindStructInPNextChain<VkPipelineBinaryInfoKHR>(local_pCreateInfos[index0].pNext);
                if (binary_info) {
                    auto *unwrapped_binaries = const_cast<VkPipelineBinaryKHR *>(binary_info->pPipelineBinaries);
                    for (uint32_t idx1 = 0; idx1 < binary_info->binaryCount; ++idx1) {
                        unwrapped_binaries[idx1] = Unwrap(binary_info->pPipelineBinaries[idx1]);
                    }
                }
            }
        }
    }

    VkResult result = device_dispatch_table.CreateRayTracingPipelinesKHR(
        device, deferredOperation, pipelineCache, createInfoCount, (const VkRayTracingPipelineCreateInfoKHR *)local_pCreateInfos,
        pAllocator, pPipelines);

    if (wrap_handles && deferredOperation == VK_NULL_HANDLE) {
        for (uint32_t i = 0; i < createInfoCount; i++) {
            if (pPipelines[i] != VK_NULL_HANDLE) {
                pPipelines[i] = WrapNew(pPipelines[i]);
            }
        }

        for (uint32_t i = 0; i < createInfoCount; ++i) {
            if (pCreateInfos[i].pNext != VK_NULL_HANDLE) {
                CopyCreatePipelineFeedbackData(local_pCreateInfos[i].pNext, pCreateInfos[i].pNext);
            }
        }
    }

    // Fix check for deferred ray tracing pipeline creation
    // https://github.com/KhronosGroup/Vulkan-ValidationLayers/issues/5817
    const bool is_operation_deferred = (deferredOperation != VK_NULL_HANDLE) && (result == VK_OPERATION_DEFERRED_KHR);
    if (is_operation_deferred) {
        std::vector<std::function<void()>> post_completion_fns;
        auto completion_find = deferred_operation_post_completion.pop(deferredOperation);
        if (completion_find->first) {
            post_completion_fns = std::move(completion_find->second);
        }

        if (wrap_handles) {
            std::vector<VkPipeline> copied_wrapped_pipelines(createInfoCount);
            for (uint32_t i = 0; i < createInfoCount; ++i) {
                copied_wrapped_pipelines[i] = pPipelines[i];
            }
            auto cleanup_fn = [local_pCreateInfos, deferredOperation, this, createInfoCount, pPipelines]() {
                for (uint32_t i = 0; i < createInfoCount; i++) {
                    if (pPipelines[i] != VK_NULL_HANDLE) {
                        pPipelines[i] = WrapNew(pPipelines[i]);
                    }
                }
                if (local_pCreateInfos) {
                    delete[] local_pCreateInfos;
                }
                deferred_operation_pipelines.insert(deferredOperation,
                                                    std::pair<uint32_t, VkPipeline *>(createInfoCount, pPipelines));
            };
            post_completion_fns.emplace_back(cleanup_fn);
        } else {
            auto cleanup_fn = [deferredOperation, this, createInfoCount, pPipelines]() {
                deferred_operation_pipelines.insert(deferredOperation,
                                                    std::pair<uint32_t, VkPipeline *>(createInfoCount, pPipelines));
            };
            post_completion_fns.emplace_back(cleanup_fn);
        }
        deferred_operation_post_completion.insert(deferredOperation, std::move(post_completion_fns));
    }

    // If operation is deferred, local resources free is postponed
    if (!is_operation_deferred && wrap_handles) {
        if (local_pCreateInfos) {
            delete[] local_pCreateInfos;
        }
    }

    return result;
}

VkResult Device::DeferredOperationJoinKHR(VkDevice device, VkDeferredOperationKHR operation) {
    if (wrap_handles) {
        operation = Unwrap(operation);
    }
    VkResult result = device_dispatch_table.DeferredOperationJoinKHR(device, operation);

    // If this thread completed the operation, free any retained memory.
    if (result == VK_SUCCESS) {
        auto post_op_completion_fns = deferred_operation_post_completion.pop(operation);
        if (post_op_completion_fns != deferred_operation_post_completion.end()) {
            for (auto &post_op_completion_fn : post_op_completion_fns->second) {
                post_op_completion_fn();
            }
        }

        // Some applications never call vkGetDeferredOperationResultKHR,
        // so try to do it at join time to correctly setup state tracking
        VkResult deferred_op_result = device_dispatch_table.GetDeferredOperationResultKHR(device, operation);
        if (deferred_op_result == VK_SUCCESS) {
            auto post_check_fns = deferred_operation_post_check.pop(operation);
            auto pipelines_to_updates = deferred_operation_pipelines.pop(operation);
            if (post_check_fns->first && pipelines_to_updates->first) {
                for (auto &post_check_fn : post_check_fns->second) {
                    post_check_fn(pipelines_to_updates->second);
                }
            }
        }
    }

    return result;
}

VkResult Device::GetDeferredOperationResultKHR(VkDevice device, VkDeferredOperationKHR operation) {
    if (wrap_handles) {
        operation = Unwrap(operation);
    }
    VkResult result = device_dispatch_table.GetDeferredOperationResultKHR(device, operation);
    // Add created pipelines if successful
    if (result == VK_SUCCESS) {
        // Perfectly valid to never call vkDeferredOperationJoin before getting the result,
        // so we need to make sure functions associated to the current operation and
        // stored in deferred_operation_post_completion have been called
        auto post_op_completion_fns = deferred_operation_post_completion.pop(operation);
        if (post_op_completion_fns != deferred_operation_post_completion.end()) {
            for (auto &post_op_completion_fn : post_op_completion_fns->second) {
                post_op_completion_fn();
            }
        }

        auto post_check_fns = deferred_operation_post_check.pop(operation);
        auto pipelines_to_updates = deferred_operation_pipelines.pop(operation);
        if (post_check_fns->first && pipelines_to_updates->first) {
            for (auto &post_check_fn : post_check_fns->second) {
                post_check_fn(pipelines_to_updates->second);
            }
        }
    }

    return result;
}

void Device::CmdBuildAccelerationStructuresKHR(VkCommandBuffer commandBuffer, uint32_t infoCount,
                                               const VkAccelerationStructureBuildGeometryInfoKHR *pInfos,
                                               const VkAccelerationStructureBuildRangeInfoKHR *const *ppBuildRangeInfos) {
    if (!wrap_handles)
        return device_dispatch_table.CmdBuildAccelerationStructuresKHR(commandBuffer, infoCount, pInfos, ppBuildRangeInfos);
    vku::safe_VkAccelerationStructureBuildGeometryInfoKHR *local_pInfos = nullptr;
    {
        if (pInfos) {
            local_pInfos = new vku::safe_VkAccelerationStructureBuildGeometryInfoKHR[infoCount];
            for (uint32_t index0 = 0; index0 < infoCount; ++index0) {
                local_pInfos[index0].initialize(&pInfos[index0], false, nullptr);

                if (pInfos[index0].srcAccelerationStructure) {
                    local_pInfos[index0].srcAccelerationStructure = Unwrap(pInfos[index0].srcAccelerationStructure);
                }
                if (pInfos[index0].dstAccelerationStructure) {
                    local_pInfos[index0].dstAccelerationStructure = Unwrap(pInfos[index0].dstAccelerationStructure);
                }
                for (uint32_t geometry_index = 0; geometry_index < local_pInfos[index0].geometryCount; ++geometry_index) {
                    vku::safe_VkAccelerationStructureGeometryKHR &geometry_info =
                        local_pInfos[index0].pGeometries != nullptr ? local_pInfos[index0].pGeometries[geometry_index]
                                                                    : *(local_pInfos[index0].ppGeometries[geometry_index]);

                    if (geometry_info.geometryType == VK_GEOMETRY_TYPE_TRIANGLES_KHR) {
                        UnwrapPnextChainHandles(geometry_info.geometry.triangles.pNext);
                    }
                }
            }
        }
    }
    device_dispatch_table.CmdBuildAccelerationStructuresKHR(
        commandBuffer, infoCount, (const VkAccelerationStructureBuildGeometryInfoKHR *)local_pInfos, ppBuildRangeInfos);
    if (local_pInfos) {
        delete[] local_pInfos;
    }
}

VkResult Device::BuildAccelerationStructuresKHR(VkDevice device, VkDeferredOperationKHR deferredOperation, uint32_t infoCount,
                                                const VkAccelerationStructureBuildGeometryInfoKHR *pInfos,
                                                const VkAccelerationStructureBuildRangeInfoKHR *const *ppBuildRangeInfos) {
    if (!wrap_handles)
        return device_dispatch_table.BuildAccelerationStructuresKHR(device, deferredOperation, infoCount, pInfos,
                                                                    ppBuildRangeInfos);
    vku::safe_VkAccelerationStructureBuildGeometryInfoKHR *local_pInfos = nullptr;
    {
        deferredOperation = Unwrap(deferredOperation);
        if (pInfos) {
            local_pInfos = new vku::safe_VkAccelerationStructureBuildGeometryInfoKHR[infoCount];
            for (uint32_t index0 = 0; index0 < infoCount; ++index0) {
                local_pInfos[index0].initialize(&pInfos[index0], true, ppBuildRangeInfos[index0]);
                if (pInfos[index0].srcAccelerationStructure) {
                    local_pInfos[index0].srcAccelerationStructure = Unwrap(pInfos[index0].srcAccelerationStructure);
                }
                if (pInfos[index0].dstAccelerationStructure) {
                    local_pInfos[index0].dstAccelerationStructure = Unwrap(pInfos[index0].dstAccelerationStructure);
                }
                for (uint32_t geometry_index = 0; geometry_index < local_pInfos[index0].geometryCount; ++geometry_index) {
                    vku::safe_VkAccelerationStructureGeometryKHR &geometry_info =
                        local_pInfos[index0].pGeometries != nullptr ? local_pInfos[index0].pGeometries[geometry_index]
                                                                    : *(local_pInfos[index0].ppGeometries[geometry_index]);
                    if (geometry_info.geometryType == VK_GEOMETRY_TYPE_TRIANGLES_KHR) {
                        UnwrapPnextChainHandles(geometry_info.geometry.triangles.pNext);
                    }
                    if (geometry_info.geometryType == VK_GEOMETRY_TYPE_INSTANCES_KHR) {
                        if (geometry_info.geometry.instances.arrayOfPointers) {
                            const uint8_t *byte_ptr =
                                reinterpret_cast<const uint8_t *>(geometry_info.geometry.instances.data.hostAddress);
                            VkAccelerationStructureInstanceKHR **instances =
                                (VkAccelerationStructureInstanceKHR **)(byte_ptr +
                                                                        ppBuildRangeInfos[index0][geometry_index].primitiveOffset);
                            for (uint32_t instance_index = 0;
                                 instance_index < ppBuildRangeInfos[index0][geometry_index].primitiveCount; ++instance_index) {
                                instances[instance_index]->accelerationStructureReference =
                                    Unwrap(instances[instance_index]->accelerationStructureReference);
                            }
                        } else {
                            const uint8_t *byte_ptr =
                                reinterpret_cast<const uint8_t *>(geometry_info.geometry.instances.data.hostAddress);
                            VkAccelerationStructureInstanceKHR *instances =
                                (VkAccelerationStructureInstanceKHR *)(byte_ptr +
                                                                       ppBuildRangeInfos[index0][geometry_index].primitiveOffset);
                            for (uint32_t instance_index = 0;
                                 instance_index < ppBuildRangeInfos[index0][geometry_index].primitiveCount; ++instance_index) {
                                instances[instance_index].accelerationStructureReference =
                                    Unwrap(instances[instance_index].accelerationStructureReference);
                            }
                        }
                    }
                }
            }
        }
    }
    VkResult result = device_dispatch_table.BuildAccelerationStructuresKHR(
        device, deferredOperation, infoCount, (const VkAccelerationStructureBuildGeometryInfoKHR *)local_pInfos, ppBuildRangeInfos);
    if (local_pInfos) {
        // Fix check for deferred ray tracing pipeline creation
        // https://github.com/KhronosGroup/Vulkan-ValidationLayers/issues/5817
        const bool is_operation_deferred = (deferredOperation != VK_NULL_HANDLE) && (result == VK_OPERATION_DEFERRED_KHR);
        if (is_operation_deferred) {
            std::vector<std::function<void()>> cleanup{[local_pInfos]() { delete[] local_pInfos; }};
            deferred_operation_post_completion.insert(deferredOperation, cleanup);
        } else {
            delete[] local_pInfos;
        }
    }
    return result;
}

void Device::GetAccelerationStructureBuildSizesKHR(VkDevice device, VkAccelerationStructureBuildTypeKHR buildType,
                                                   const VkAccelerationStructureBuildGeometryInfoKHR *pBuildInfo,
                                                   const uint32_t *pMaxPrimitiveCounts,
                                                   VkAccelerationStructureBuildSizesInfoKHR *pSizeInfo) {
    if (!wrap_handles)
        return device_dispatch_table.GetAccelerationStructureBuildSizesKHR(device, buildType, pBuildInfo, pMaxPrimitiveCounts,
                                                                           pSizeInfo);
    vku::safe_VkAccelerationStructureBuildGeometryInfoKHR local_pBuildInfo;
    {
        if (pBuildInfo) {
            local_pBuildInfo.initialize(pBuildInfo, false, nullptr);
            if (pBuildInfo->srcAccelerationStructure) {
                local_pBuildInfo.srcAccelerationStructure = Unwrap(pBuildInfo->srcAccelerationStructure);
            }
            if (pBuildInfo->dstAccelerationStructure) {
                local_pBuildInfo.dstAccelerationStructure = Unwrap(pBuildInfo->dstAccelerationStructure);
            }
            for (uint32_t geometry_index = 0; geometry_index < local_pBuildInfo.geometryCount; ++geometry_index) {
                vku::safe_VkAccelerationStructureGeometryKHR &geometry_info =
                    local_pBuildInfo.pGeometries != nullptr ? local_pBuildInfo.pGeometries[geometry_index]
                                                            : *(local_pBuildInfo.ppGeometries[geometry_index]);
                if (geometry_info.geometryType == VK_GEOMETRY_TYPE_TRIANGLES_KHR) {
                    UnwrapPnextChainHandles(geometry_info.geometry.triangles.pNext);
                }
            }
        }
    }
    device_dispatch_table.GetAccelerationStructureBuildSizesKHR(
        device, buildType, (const VkAccelerationStructureBuildGeometryInfoKHR *)&local_pBuildInfo, pMaxPrimitiveCounts, pSizeInfo);
}

void Device::GetDescriptorEXT(VkDevice device, const VkDescriptorGetInfoEXT *pDescriptorInfo, size_t dataSize, void *pDescriptor) {
    if (!wrap_handles) return device_dispatch_table.GetDescriptorEXT(device, pDescriptorInfo, dataSize, pDescriptor);
    // When using a union of pointer we still need to unwrap the handles, but since it is a pointer, we can just use the pointer
    // from the incoming parameter instead of using safe structs as it is less complex doing it here
    vku::safe_VkDescriptorGetInfoEXT local_pDescriptorInfo;
    // TODO - Use safe struct once VUL is updated
    // There are no pNext for this function so nothing in short term will break
    // local_pDescriptorInfo.initialize(pDescriptorInfo);
    local_pDescriptorInfo.pNext = nullptr;
    local_pDescriptorInfo.sType = pDescriptorInfo->sType;
    local_pDescriptorInfo.type = pDescriptorInfo->type;

    // need in local scope to call down whatever we use
    VkSampler sampler;
    VkDescriptorImageInfo image_info;
    vku::safe_VkDescriptorAddressInfoEXT address_info;

    switch (pDescriptorInfo->type) {
        case VK_DESCRIPTOR_TYPE_SAMPLER: {
            // if using null descriptors can be null
            if (pDescriptorInfo->data.pSampler) {
                sampler = Unwrap(*pDescriptorInfo->data.pSampler);
                local_pDescriptorInfo.data.pSampler = &sampler;
            }
            break;
        }
        case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER: {
            if (pDescriptorInfo->data.pCombinedImageSampler) {
                image_info.sampler = Unwrap(pDescriptorInfo->data.pCombinedImageSampler->sampler);
                image_info.imageView = Unwrap(pDescriptorInfo->data.pCombinedImageSampler->imageView);
                image_info.imageLayout = pDescriptorInfo->data.pCombinedImageSampler->imageLayout;
                local_pDescriptorInfo.data.pCombinedImageSampler = &image_info;
            }
            break;
        }
        case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE: {
            if (pDescriptorInfo->data.pSampledImage) {
                image_info.sampler = Unwrap(pDescriptorInfo->data.pSampledImage->sampler);
                image_info.imageView = Unwrap(pDescriptorInfo->data.pSampledImage->imageView);
                image_info.imageLayout = pDescriptorInfo->data.pSampledImage->imageLayout;
                local_pDescriptorInfo.data.pSampledImage = &image_info;
            }
            break;
        }
        case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE: {
            if (pDescriptorInfo->data.pStorageImage) {
                image_info.sampler = Unwrap(pDescriptorInfo->data.pStorageImage->sampler);
                image_info.imageView = Unwrap(pDescriptorInfo->data.pStorageImage->imageView);
                image_info.imageLayout = pDescriptorInfo->data.pStorageImage->imageLayout;
                local_pDescriptorInfo.data.pStorageImage = &image_info;
            }
            break;
        }
        case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT: {
            if (pDescriptorInfo->data.pInputAttachmentImage) {
                image_info.sampler = Unwrap(pDescriptorInfo->data.pInputAttachmentImage->sampler);
                image_info.imageView = Unwrap(pDescriptorInfo->data.pInputAttachmentImage->imageView);
                image_info.imageLayout = pDescriptorInfo->data.pInputAttachmentImage->imageLayout;
                local_pDescriptorInfo.data.pInputAttachmentImage = &image_info;
            }
            break;
        }
        case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
            if (pDescriptorInfo->data.pUniformTexelBuffer) {
                address_info.initialize(pDescriptorInfo->data.pUniformTexelBuffer);
                local_pDescriptorInfo.data.pUniformTexelBuffer = address_info.ptr();
            }
            break;
        case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
            if (pDescriptorInfo->data.pStorageTexelBuffer) {
                address_info.initialize(pDescriptorInfo->data.pStorageTexelBuffer);
                local_pDescriptorInfo.data.pStorageTexelBuffer = address_info.ptr();
            }
            break;
        case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
            if (pDescriptorInfo->data.pUniformBuffer) {
                address_info.initialize(pDescriptorInfo->data.pUniformBuffer);
                local_pDescriptorInfo.data.pUniformBuffer = address_info.ptr();
            }
            break;
        case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
            if (pDescriptorInfo->data.pStorageBuffer) {
                address_info.initialize(pDescriptorInfo->data.pStorageBuffer);
                local_pDescriptorInfo.data.pStorageBuffer = address_info.ptr();
            }
            break;
        case VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR:
        case VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_NV:
        case VK_DESCRIPTOR_TYPE_PARTITIONED_ACCELERATION_STRUCTURE_NV:
            local_pDescriptorInfo.data.accelerationStructure = pDescriptorInfo->data.accelerationStructure;
            break;
        default:
            break;
    }

    device_dispatch_table.GetDescriptorEXT(device, (const VkDescriptorGetInfoEXT *)&local_pDescriptorInfo, dataSize, pDescriptor);
}

VkResult Device::WriteResourceDescriptorsEXT(VkDevice device, uint32_t resourceCount, const VkResourceDescriptorInfoEXT* pResources,
                                             const VkHostAddressRangeEXT* pDescriptors) {
    if (!wrap_handles || resourceCount == 0)
        return device_dispatch_table.WriteResourceDescriptorsEXT(device, resourceCount, pResources, pDescriptors);
    // When using a union of pointer we still need to unwrap the handles, but since it is a pointer, we can just use the pointer
    // from the incoming parameter instead of using safe structs as it is less complex doing it here
    std::vector<vku::safe_VkResourceDescriptorInfoEXT> local_pResources(resourceCount);
    std::vector<vku::safe_VkImageDescriptorInfoEXT> local_image;
    local_image.reserve(resourceCount);
    std::vector<vku::safe_VkTensorViewCreateInfoARM> local_tensor;
    local_tensor.reserve(resourceCount);

    for (uint32_t i = 0; i < resourceCount; i++) {
        auto& local_pResource = local_pResources[i];
        local_pResource.initialize(&pResources[i]);
        if (IsDescriptorHeapImage(local_pResource.type)) {
            if (local_pResource.data.pImage) {
                local_image.emplace_back(pResources[i].data.pImage);
                local_image.back().initialize(pResources[i].data.pImage);
                local_pResource.data.pImage = local_image.back().ptr();
                if (local_pResource.data.pImage->pView) {
                    if (pResources[i].data.pImage->pView->image) {
                        local_image.back().pView->image = Unwrap(pResources[i].data.pImage->pView->image);
                    }
                    if (pResources[i].data.pImage->pView->pNext) {
                        UnwrapPnextChainHandles(local_pResources[i].data.pImage->pView->pNext);
                    }
                }
            }
        }

        if (IsDescriptorHeapTensor(local_pResource.type)) {
            if (local_pResource.data.pTensorARM) {
                local_tensor.emplace_back(pResources[i].data.pTensorARM);
                local_tensor.back().initialize(pResources[i].data.pTensorARM);
                local_pResource.data.pTensorARM = local_tensor.back().ptr();
                if (local_pResource.data.pTensorARM) {
                    local_tensor.back().tensor = Unwrap(pResources[i].data.pTensorARM->tensor);
                    if (pResources[i].data.pTensorARM->pNext) {
                        UnwrapPnextChainHandles(local_pResources[i].data.pTensorARM->pNext);
                    }
                }
            }
        }
    }

    return device_dispatch_table.WriteResourceDescriptorsEXT(device, resourceCount, local_pResources[0].ptr(), pDescriptors);
}

VkResult Device::CreateComputePipelines(VkDevice device, VkPipelineCache pipelineCache, uint32_t createInfoCount,
                                        const VkComputePipelineCreateInfo *pCreateInfos, const VkAllocationCallbacks *pAllocator,
                                        VkPipeline *pPipelines) {
    if (!wrap_handles)
        return device_dispatch_table.CreateComputePipelines(device, pipelineCache, createInfoCount, pCreateInfos, pAllocator,
                                                            pPipelines);
    vku::safe_VkComputePipelineCreateInfo *local_pCreateInfos = nullptr;
    {
        pipelineCache = Unwrap(pipelineCache);
        if (pCreateInfos) {
            local_pCreateInfos = new vku::safe_VkComputePipelineCreateInfo[createInfoCount];
            for (uint32_t index0 = 0; index0 < createInfoCount; ++index0) {
                local_pCreateInfos[index0].initialize(&pCreateInfos[index0]);
                UnwrapPnextChainHandles(local_pCreateInfos[index0].pNext);
                if (pCreateInfos[index0].stage.module) {
                    local_pCreateInfos[index0].stage.module = Unwrap(pCreateInfos[index0].stage.module);
                }
                UnwrapPnextChainHandles(local_pCreateInfos[index0].stage.pNext);
                if (pCreateInfos[index0].layout) {
                    local_pCreateInfos[index0].layout = Unwrap(pCreateInfos[index0].layout);
                }
                if (pCreateInfos[index0].basePipelineHandle) {
                    local_pCreateInfos[index0].basePipelineHandle = Unwrap(pCreateInfos[index0].basePipelineHandle);
                }
            }
        }
    }
    VkResult result = device_dispatch_table.CreateComputePipelines(
        device, pipelineCache, createInfoCount, (const VkComputePipelineCreateInfo *)local_pCreateInfos, pAllocator, pPipelines);
    for (uint32_t i = 0; i < createInfoCount; ++i) {
        if (pCreateInfos[i].pNext != VK_NULL_HANDLE) {
            CopyCreatePipelineFeedbackData(local_pCreateInfos[i].pNext, pCreateInfos[i].pNext);
        }
    }

    if (local_pCreateInfos) {
        delete[] local_pCreateInfos;
    }
    {
        for (uint32_t index0 = 0; index0 < createInfoCount; index0++) {
            if (pPipelines[index0] != VK_NULL_HANDLE) {
                pPipelines[index0] = WrapNew(pPipelines[index0]);
            }
        }
    }
    return result;
}

VkResult Device::CreateRayTracingPipelinesNV(VkDevice device, VkPipelineCache pipelineCache, uint32_t createInfoCount,
                                             const VkRayTracingPipelineCreateInfoNV *pCreateInfos,
                                             const VkAllocationCallbacks *pAllocator, VkPipeline *pPipelines) {
    if (!wrap_handles)
        return device_dispatch_table.CreateRayTracingPipelinesNV(device, pipelineCache, createInfoCount, pCreateInfos, pAllocator,
                                                                 pPipelines);
    vku::safe_VkRayTracingPipelineCreateInfoNV *local_pCreateInfos = nullptr;
    {
        pipelineCache = Unwrap(pipelineCache);
        if (pCreateInfos) {
            local_pCreateInfos = new vku::safe_VkRayTracingPipelineCreateInfoNV[createInfoCount];
            for (uint32_t index0 = 0; index0 < createInfoCount; ++index0) {
                local_pCreateInfos[index0].initialize(&pCreateInfos[index0]);
                if (local_pCreateInfos[index0].pStages) {
                    for (uint32_t index1 = 0; index1 < local_pCreateInfos[index0].stageCount; ++index1) {
                        if (pCreateInfos[index0].pStages[index1].module) {
                            local_pCreateInfos[index0].pStages[index1].module = Unwrap(pCreateInfos[index0].pStages[index1].module);
                        }
                    }
                }
                if (pCreateInfos[index0].layout) {
                    local_pCreateInfos[index0].layout = Unwrap(pCreateInfos[index0].layout);
                }
                if (pCreateInfos[index0].basePipelineHandle) {
                    local_pCreateInfos[index0].basePipelineHandle = Unwrap(pCreateInfos[index0].basePipelineHandle);
                }

                auto *binary_info = vku::FindStructInPNextChain<VkPipelineBinaryInfoKHR>(local_pCreateInfos[index0].pNext);
                if (binary_info) {
                    auto *unwrapped_binaries = const_cast<VkPipelineBinaryKHR *>(binary_info->pPipelineBinaries);
                    for (uint32_t idx1 = 0; idx1 < binary_info->binaryCount; ++idx1) {
                        unwrapped_binaries[idx1] = Unwrap(binary_info->pPipelineBinaries[idx1]);
                    }
                }
            }
        }
    }
    VkResult result = device_dispatch_table.CreateRayTracingPipelinesNV(
        device, pipelineCache, createInfoCount, (const VkRayTracingPipelineCreateInfoNV *)local_pCreateInfos, pAllocator,
        pPipelines);
    for (uint32_t i = 0; i < createInfoCount; ++i) {
        if (pCreateInfos[i].pNext != VK_NULL_HANDLE) {
            CopyCreatePipelineFeedbackData(local_pCreateInfos[i].pNext, pCreateInfos[i].pNext);
        }
    }

    if (local_pCreateInfos) {
        delete[] local_pCreateInfos;
    }
    {
        for (uint32_t index0 = 0; index0 < createInfoCount; index0++) {
            if (pPipelines[index0] != VK_NULL_HANDLE) {
                pPipelines[index0] = WrapNew(pPipelines[index0]);
            }
        }
    }
    return result;
}

VkResult Device::ReleasePerformanceConfigurationINTEL(VkDevice device, VkPerformanceConfigurationINTEL configuration) {
    if (!wrap_handles) return device_dispatch_table.ReleasePerformanceConfigurationINTEL(device, configuration);
    { configuration = Unwrap(configuration); }
    VkResult result = device_dispatch_table.ReleasePerformanceConfigurationINTEL(device, configuration);

    return result;
}

VkResult Device::CreatePipelineBinariesKHR(VkDevice device, const VkPipelineBinaryCreateInfoKHR *pCreateInfo,
                                           const VkAllocationCallbacks *pAllocator, VkPipelineBinaryHandlesInfoKHR *pBinaries) {
    if (!wrap_handles) return device_dispatch_table.CreatePipelineBinariesKHR(device, pCreateInfo, pAllocator, pBinaries);
    vku::safe_VkPipelineBinaryCreateInfoKHR var_local_pCreateInfo;
    vku::safe_VkPipelineBinaryCreateInfoKHR *local_pCreateInfo = nullptr;
    const uint32_t array_size = pBinaries->pipelineBinaryCount;
    {
        if (pCreateInfo) {
            local_pCreateInfo = &var_local_pCreateInfo;
            local_pCreateInfo->initialize(pCreateInfo);

            if (pCreateInfo->pipeline) {
                local_pCreateInfo->pipeline = Unwrap(pCreateInfo->pipeline);
            }
            if (local_pCreateInfo->pPipelineCreateInfo) {
                UnwrapPnextChainHandles(local_pCreateInfo->pPipelineCreateInfo->pNext);
            }
        }
    }
    VkResult result = device_dispatch_table.CreatePipelineBinariesKHR(
        device, (const VkPipelineBinaryCreateInfoKHR *)local_pCreateInfo, pAllocator, (VkPipelineBinaryHandlesInfoKHR *)pBinaries);

    if (pBinaries->pPipelineBinaries) {
        for (uint32_t index0 = 0; index0 < array_size; index0++) {
            if (pBinaries->pPipelineBinaries[index0] != VK_NULL_HANDLE) {
                pBinaries->pPipelineBinaries[index0] = WrapNew(pBinaries->pPipelineBinaries[index0]);
            }
        }
    }

    return result;
}

VkResult Device::GetPipelineKeyKHR(VkDevice device, const VkPipelineCreateInfoKHR *pPipelineCreateInfo,
                                   VkPipelineBinaryKeyKHR *pPipelineKey) {
    if (!wrap_handles) return device_dispatch_table.GetPipelineKeyKHR(device, pPipelineCreateInfo, pPipelineKey);
    vku::safe_VkPipelineCreateInfoKHR var_local_pPipelineCreateInfo;
    vku::safe_VkPipelineCreateInfoKHR *local_pPipelineCreateInfo = nullptr;
    {
        if (pPipelineCreateInfo) {
            local_pPipelineCreateInfo = &var_local_pPipelineCreateInfo;
            local_pPipelineCreateInfo->initialize(pPipelineCreateInfo);
            UnwrapPnextChainHandles(local_pPipelineCreateInfo->pNext);
        }
    }
    VkResult result =
        device_dispatch_table.GetPipelineKeyKHR(device, (const VkPipelineCreateInfoKHR *)local_pPipelineCreateInfo, pPipelineKey);
    return result;
}

VkResult Device::CreateIndirectExecutionSetEXT(VkDevice device, const VkIndirectExecutionSetCreateInfoEXT *pCreateInfo,
                                               const VkAllocationCallbacks *pAllocator,
                                               VkIndirectExecutionSetEXT *pIndirectExecutionSet) {
    if (!wrap_handles)
        return device_dispatch_table.CreateIndirectExecutionSetEXT(device, pCreateInfo, pAllocator, pIndirectExecutionSet);

    // When using a union of pointer we still need to unwrap the handles, but since it is a pointer, we can just use the pointer
    // from the incoming parameter instead of using safe structs as it is less complex doing it here
    vku::safe_VkIndirectExecutionSetCreateInfoEXT local_pCreateInfo;
    local_pCreateInfo.initialize(pCreateInfo);

    // need in local scope to call down whatever we use
    vku::safe_VkIndirectExecutionSetPipelineInfoEXT pipeline_info;
    vku::safe_VkIndirectExecutionSetShaderInfoEXT shader_info;

    if (pCreateInfo) {
        local_pCreateInfo.initialize(pCreateInfo);
        switch (local_pCreateInfo.type) {
            case VK_INDIRECT_EXECUTION_SET_INFO_TYPE_PIPELINES_EXT:
                if (pCreateInfo->info.pPipelineInfo) {
                    pipeline_info.initialize(pCreateInfo->info.pPipelineInfo);
                    pipeline_info.initialPipeline = Unwrap(pCreateInfo->info.pPipelineInfo->initialPipeline);
                    local_pCreateInfo.info.pPipelineInfo = pipeline_info.ptr();
                }
                break;
            case VK_INDIRECT_EXECUTION_SET_INFO_TYPE_SHADER_OBJECTS_EXT:
                if (local_pCreateInfo.info.pShaderInfo) {
                    shader_info.initialize(pCreateInfo->info.pShaderInfo);

                    for (uint32_t index0 = 0; index0 < local_pCreateInfo.info.pShaderInfo->shaderCount; ++index0) {
                        if (local_pCreateInfo.info.pShaderInfo->pSetLayoutInfos) {
                            const auto &set_layout = local_pCreateInfo.info.pShaderInfo->pSetLayoutInfos[index0];
                            if (set_layout.pSetLayouts) {
                                for (uint32_t index1 = 0; index1 < set_layout.setLayoutCount; ++index1) {
                                    shader_info.pSetLayoutInfos[index0].pSetLayouts[index1] =
                                        Unwrap(set_layout.pSetLayouts[index1]);
                                }
                            }
                        }
                        shader_info.pInitialShaders[index0] = Unwrap(local_pCreateInfo.info.pShaderInfo->pInitialShaders[index0]);
                    }

                    local_pCreateInfo.info.pShaderInfo = shader_info.ptr();
                }
                break;
            default:
                break;
        }
    }

    VkResult result = device_dispatch_table.CreateIndirectExecutionSetEXT(
        device, (const VkIndirectExecutionSetCreateInfoEXT *)&local_pCreateInfo, pAllocator, pIndirectExecutionSet);
    if (result == VK_SUCCESS) {
        *pIndirectExecutionSet = WrapNew(*pIndirectExecutionSet);
    }
    return result;
}

VkResult Device::BindBufferMemory2(VkDevice device, uint32_t bindInfoCount, const VkBindBufferMemoryInfo *pBindInfos) {
    if (!wrap_handles) return device_dispatch_table.BindBufferMemory2(device, bindInfoCount, pBindInfos);
    small_vector<vku::safe_VkBindBufferMemoryInfo, DISPATCH_MAX_STACK_ALLOCATIONS> var_local_pBindInfos;
    vku::safe_VkBindBufferMemoryInfo *local_pBindInfos = nullptr;
    {
        if (pBindInfos) {
            var_local_pBindInfos.resize(bindInfoCount);
            local_pBindInfos = var_local_pBindInfos.data();
            for (uint32_t index0 = 0; index0 < bindInfoCount; ++index0) {
                local_pBindInfos[index0].initialize(&pBindInfos[index0]);

                if (pBindInfos[index0].buffer) {
                    local_pBindInfos[index0].buffer = Unwrap(pBindInfos[index0].buffer);
                }
                if (pBindInfos[index0].memory) {
                    local_pBindInfos[index0].memory = Unwrap(pBindInfos[index0].memory);
                }
            }
        }
    }
    VkResult result =
        device_dispatch_table.BindBufferMemory2(device, bindInfoCount, (const VkBindBufferMemoryInfo *)local_pBindInfos);

    if (pBindInfos) {
        for (uint32_t index0 = 0; index0 < bindInfoCount; ++index0) {
            auto *bind_memory_status = vku::FindStructInPNextChain<VkBindMemoryStatus>(pBindInfos[index0].pNext);
            if (bind_memory_status) {
                auto *local_bind_memory_status = vku::FindStructInPNextChain<VkBindMemoryStatus>(local_pBindInfos[index0].pNext);
                *bind_memory_status->pResult = *local_bind_memory_status->pResult;
            }
        }
    }

    return result;
}

VkResult Device::BindImageMemory2(VkDevice device, uint32_t bindInfoCount, const VkBindImageMemoryInfo *pBindInfos) {
    if (!wrap_handles) return device_dispatch_table.BindImageMemory2(device, bindInfoCount, pBindInfos);
    small_vector<vku::safe_VkBindImageMemoryInfo, DISPATCH_MAX_STACK_ALLOCATIONS> var_local_pBindInfos;
    vku::safe_VkBindImageMemoryInfo *local_pBindInfos = nullptr;
    {
        if (pBindInfos) {
            var_local_pBindInfos.resize(bindInfoCount);
            local_pBindInfos = var_local_pBindInfos.data();
            for (uint32_t index0 = 0; index0 < bindInfoCount; ++index0) {
                local_pBindInfos[index0].initialize(&pBindInfos[index0]);
                UnwrapPnextChainHandles(local_pBindInfos[index0].pNext);

                if (pBindInfos[index0].image) {
                    local_pBindInfos[index0].image = Unwrap(pBindInfos[index0].image);
                }
                if (pBindInfos[index0].memory) {
                    local_pBindInfos[index0].memory = Unwrap(pBindInfos[index0].memory);
                }
            }
        }
    }
    VkResult result =
        device_dispatch_table.BindImageMemory2(device, bindInfoCount, (const VkBindImageMemoryInfo *)local_pBindInfos);

    if (pBindInfos) {
        for (uint32_t index0 = 0; index0 < bindInfoCount; ++index0) {
            auto *bind_memory_status = vku::FindStructInPNextChain<VkBindMemoryStatus>(pBindInfos[index0].pNext);
            if (bind_memory_status) {
                auto *local_bind_memory_status = vku::FindStructInPNextChain<VkBindMemoryStatus>(local_pBindInfos[index0].pNext);
                *bind_memory_status->pResult = *local_bind_memory_status->pResult;
            }
        }
    }

    return result;
}

VkResult Device::BindBufferMemory2KHR(VkDevice device, uint32_t bindInfoCount, const VkBindBufferMemoryInfo *pBindInfos) {
    if (!wrap_handles) return device_dispatch_table.BindBufferMemory2KHR(device, bindInfoCount, pBindInfos);
    small_vector<vku::safe_VkBindBufferMemoryInfo, DISPATCH_MAX_STACK_ALLOCATIONS> var_local_pBindInfos;
    vku::safe_VkBindBufferMemoryInfo *local_pBindInfos = nullptr;
    {
        if (pBindInfos) {
            var_local_pBindInfos.resize(bindInfoCount);
            local_pBindInfos = var_local_pBindInfos.data();
            for (uint32_t index0 = 0; index0 < bindInfoCount; ++index0) {
                local_pBindInfos[index0].initialize(&pBindInfos[index0]);

                if (pBindInfos[index0].buffer) {
                    local_pBindInfos[index0].buffer = Unwrap(pBindInfos[index0].buffer);
                }
                if (pBindInfos[index0].memory) {
                    local_pBindInfos[index0].memory = Unwrap(pBindInfos[index0].memory);
                }
            }
        }
    }
    VkResult result =
        device_dispatch_table.BindBufferMemory2KHR(device, bindInfoCount, (const VkBindBufferMemoryInfo *)local_pBindInfos);

    if (pBindInfos) {
        for (uint32_t index0 = 0; index0 < bindInfoCount; ++index0) {
            auto *bind_memory_status = vku::FindStructInPNextChain<VkBindMemoryStatus>(pBindInfos[index0].pNext);
            if (bind_memory_status) {
                auto *local_bind_memory_status = vku::FindStructInPNextChain<VkBindMemoryStatus>(local_pBindInfos[index0].pNext);
                *bind_memory_status->pResult = *local_bind_memory_status->pResult;
            }
        }
    }

    return result;
}

VkResult Device::BindImageMemory2KHR(VkDevice device, uint32_t bindInfoCount, const VkBindImageMemoryInfo *pBindInfos) {
    if (!wrap_handles) return device_dispatch_table.BindImageMemory2KHR(device, bindInfoCount, pBindInfos);
    small_vector<vku::safe_VkBindImageMemoryInfo, DISPATCH_MAX_STACK_ALLOCATIONS> var_local_pBindInfos;
    vku::safe_VkBindImageMemoryInfo *local_pBindInfos = nullptr;
    {
        if (pBindInfos) {
            var_local_pBindInfos.resize(bindInfoCount);
            local_pBindInfos = var_local_pBindInfos.data();
            for (uint32_t index0 = 0; index0 < bindInfoCount; ++index0) {
                local_pBindInfos[index0].initialize(&pBindInfos[index0]);
                UnwrapPnextChainHandles(local_pBindInfos[index0].pNext);

                if (pBindInfos[index0].image) {
                    local_pBindInfos[index0].image = Unwrap(pBindInfos[index0].image);
                }
                if (pBindInfos[index0].memory) {
                    local_pBindInfos[index0].memory = Unwrap(pBindInfos[index0].memory);
                }
            }
        }
    }
    VkResult result =
        device_dispatch_table.BindImageMemory2KHR(device, bindInfoCount, (const VkBindImageMemoryInfo *)local_pBindInfos);

    if (pBindInfos) {
        for (uint32_t index0 = 0; index0 < bindInfoCount; ++index0) {
            auto *bind_memory_status = vku::FindStructInPNextChain<VkBindMemoryStatus>(pBindInfos[index0].pNext);
            if (bind_memory_status) {
                auto *local_bind_memory_status = vku::FindStructInPNextChain<VkBindMemoryStatus>(local_pBindInfos[index0].pNext);
                *bind_memory_status->pResult = *local_bind_memory_status->pResult;
            }
        }
    }

    return result;
}

VkResult Device::CreateShadersEXT(VkDevice device, uint32_t createInfoCount, const VkShaderCreateInfoEXT *pCreateInfos,
                                  const VkAllocationCallbacks *pAllocator, VkShaderEXT *pShaders) {
    if (!wrap_handles) return device_dispatch_table.CreateShadersEXT(device, createInfoCount, pCreateInfos, pAllocator, pShaders);
    small_vector<vku::safe_VkShaderCreateInfoEXT, DISPATCH_MAX_STACK_ALLOCATIONS> var_local_pCreateInfos;
    vku::safe_VkShaderCreateInfoEXT *local_pCreateInfos = nullptr;
    if (pCreateInfos) {
        var_local_pCreateInfos.resize(createInfoCount);
        local_pCreateInfos = var_local_pCreateInfos.data();
        for (uint32_t index0 = 0; index0 < createInfoCount; ++index0) {
            local_pCreateInfos[index0].initialize(&pCreateInfos[index0]);
            if (local_pCreateInfos[index0].pSetLayouts) {
                for (uint32_t index1 = 0; index1 < local_pCreateInfos[index0].setLayoutCount; ++index1) {
                    local_pCreateInfos[index0].pSetLayouts[index1] = Unwrap(local_pCreateInfos[index0].pSetLayouts[index1]);
                }
            }
        }
    }

    VkResult result = device_dispatch_table.CreateShadersEXT(
        device, createInfoCount, (const VkShaderCreateInfoEXT *)local_pCreateInfos, pAllocator, pShaders);

    // Wrap anything created which is known if handles are non-null
    for (uint32_t index0 = 0; index0 < createInfoCount; index0++) {
        if (pShaders[index0] != VK_NULL_HANDLE) {
            pShaders[index0] = WrapNew(pShaders[index0]);
        }
    }

    return result;
}

VkResult Device::CreateDataGraphPipelinesARM(VkDevice device, VkDeferredOperationKHR deferredOperation,
                                             VkPipelineCache pipelineCache, uint32_t createInfoCount,
                                             const VkDataGraphPipelineCreateInfoARM *pCreateInfos,
                                             const VkAllocationCallbacks *pAllocator, VkPipeline *pPipelines) {
    if (!wrap_handles)
        return device_dispatch_table.CreateDataGraphPipelinesARM(device, deferredOperation, pipelineCache, createInfoCount, pCreateInfos, pAllocator,
                                                            pPipelines);
    vku::safe_VkDataGraphPipelineCreateInfoARM *local_pCreateInfos = nullptr;
    {
        pipelineCache = Unwrap(pipelineCache);
        if (pCreateInfos) {
            local_pCreateInfos = new vku::safe_VkDataGraphPipelineCreateInfoARM[createInfoCount];
            for (uint32_t index0 = 0; index0 < createInfoCount; ++index0) {
                local_pCreateInfos[index0].initialize(&pCreateInfos[index0]);
                UnwrapPnextChainHandles(local_pCreateInfos[index0].pNext);
                if (pCreateInfos[index0].layout) {
                    local_pCreateInfos[index0].layout = Unwrap(pCreateInfos[index0].layout);
                }
            }
        }
    }
    VkResult result = device_dispatch_table.CreateDataGraphPipelinesARM(
        device, deferredOperation, pipelineCache, createInfoCount, (const VkDataGraphPipelineCreateInfoARM *)local_pCreateInfos,
        pAllocator, pPipelines);
    for (uint32_t i = 0; i < createInfoCount; ++i) {
        if (pCreateInfos[i].pNext != VK_NULL_HANDLE) {
            CopyCreatePipelineFeedbackData(local_pCreateInfos[i].pNext, pCreateInfos[i].pNext);
        }
    }

    if (local_pCreateInfos) {
        delete[] local_pCreateInfos;
    }
    {
        for (uint32_t index0 = 0; index0 < createInfoCount; index0++) {
            if (pPipelines[index0] != VK_NULL_HANDLE) {
                pPipelines[index0] = WrapNew(pPipelines[index0]);
            }
        }
    }
    return result;
}
}  // namespace dispatch
}  // namespace vvl
