text: /*
   * Copyright (C) 2015 Google Inc.
   *
   * 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.
   *
   * THIS FILE WAS GENERATED BY apic. DO NOT EDIT.
   */
  
  // clang-format off
  #include <array>
  #include <cassert>
  #include <list>
  #include <memory>
  #include <mutex>
  #include <unordered_map>
  #include <vector>
  
  #define  API_NAME "Vulkan"
  #include "vk_dispatch_table_helper.h"
  #include "vk_layer_utils.h"
  
  #include "gfr_layer.h"
  #include "gfr_base_interceptor.h"
  
  std::mutex g_lock;
  
  // global Interceptor accessor
  intercept::BaseInterceptor *GetInterceptor();
  
  constexpr VkLayerProperties g_layer_properties = { "VK_LAYER_GOOGLE_graphics_flight_recorder", VK_LAYER_API_VERSION, 1, "Google Graphics Flight Recorder is a crash/hang debugging tool that helps determines GPU progress in a Vulkan application" };
  static constexpr std::array<VkExtensionProperties, 2> g_instance_extensions
  {
    {
      { VK_EXT_DEBUG_REPORT_EXTENSION_NAME, VK_EXT_DEBUG_REPORT_SPEC_VERSION },
      { VK_EXT_DEBUG_UTILS_EXTENSION_NAME, VK_EXT_DEBUG_UTILS_SPEC_VERSION },
    }
  };
  
  static constexpr std::array<VkExtensionProperties, 1> g_device_extensions
  {
    {
      { VK_EXT_DEBUG_MARKER_EXTENSION_NAME, VK_EXT_DEBUG_MARKER_SPEC_VERSION },
    }
  };
  
  typedef VkResult (VKAPI_PTR *PFN_vkSetInstanceLoaderData)(VkInstance instance, void* object);
  typedef VkResult (VKAPI_PTR *PFN_vkSetDeviceLoaderData)(VkDevice device, void* object);
  
  struct InstanceLayerData {
    InstanceLayerData(dispatch_key key_) : key(key_) {};
    const dispatch_key key;
    VkInstance instance = VK_NULL_HANDLE;
    VkLayerInstanceDispatchTable dispatch_table;
  
    PFN_vkSetInstanceLoaderData SetInstanceLoaderData = nullptr;
  };
  
  struct DeviceLayerData {
    DeviceLayerData(dispatch_key key_) : key(key_) {};
    const dispatch_key key;
    VkDevice device = VK_NULL_HANDLE;
    VkLayerDispatchTable dispatch_table;
    VkPhysicalDevice physical_device = VK_NULL_HANDLE;
    InstanceLayerData* instance_data = nullptr;
  
    PFN_vkSetDeviceLoaderData SetDeviceLoaderData = nullptr;
  
    // extensions implemented by our layer, don't pass them down
    std::vector<std::string> added_extensions;
  };
  
  // custom command declaration
  VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL GetDeviceProcAddr(VkDevice device, char const* pName);
  VKAPI_ATTR VkResult VKAPI_CALL CreateDevice(VkPhysicalDevice physicalDevice, VkDeviceCreateInfo const* pCreateInfo, AllocationCallbacks pAllocator, VkDevice* pDevice);
  VKAPI_ATTR void VKAPI_CALL DestroyDevice(VkDevice device, AllocationCallbacks pAllocator);
  VKAPI_ATTR VkResult VKAPI_CALL CreateInstance(VkInstanceCreateInfo const* pCreateInfo, AllocationCallbacks pAllocator, VkInstance* pInstance);
  VKAPI_ATTR void VKAPI_CALL DestroyInstance(VkInstance instance, AllocationCallbacks pAllocator);
  VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL GetInstanceProcAddr(VkInstance instance, char const* pName);
  VKAPI_ATTR VkResult VKAPI_CALL EnumerateInstanceExtensionProperties(char const* pLayerName, uint32_t* pPropertyCount, VkExtensionProperties* pProperties);
  VKAPI_ATTR VkResult VKAPI_CALL EnumerateInstanceLayerProperties(uint32_t* pPropertyCount, VkLayerProperties* pProperties);
  VKAPI_ATTR VkResult VKAPI_CALL EnumerateDeviceExtensionProperties(VkPhysicalDevice physicalDevice, char const* pLayerName, uint32_t* pPropertyCount, VkExtensionProperties* pProperties);
  VKAPI_ATTR VkResult VKAPI_CALL EnumerateDeviceLayerProperties(VkPhysicalDevice physicalDevice, uint32_t* pPropertyCount, VkLayerProperties* pProperties);
  
  namespace {
    // generally we expect to get the same device and instance, so we keep them handy
    static thread_local DeviceLayerData* last_used_device_layer_data = nullptr;
    static thread_local InstanceLayerData* last_used_instance_layer_data = nullptr;
    // but we also support multiple devices / instances
    static std::mutex device_layer_data_mutex;
    static std::vector<DeviceLayerData *> device_layer_data_list;
    static std::mutex instance_layer_data_mutex;
    static std::vector<InstanceLayerData *> instance_layer_data_list;
  }
  
  namespace intercept {
  
  struct VkStruct {
    VkStructureType sType;
    const void*     pNext;
  };
  
  VkStruct *FindOnChain(VkStruct *s, VkStructureType type) {
    VkStruct *n = (VkStruct *)s->pNext;
    while (n && n->sType != type) {
      n = (VkStruct *)n->pNext;
    }
    return n;
  }
  
  VkLayerInstanceCreateInfo *GetLoaderInstanceInfo(const VkInstanceCreateInfo *create_info, VkLayerFunction func_type) {
    VkStruct *n = (VkStruct *)create_info;
    while ((n = FindOnChain(n, VK_STRUCTURE_TYPE_LOADER_INSTANCE_CREATE_INFO))) {
      VkLayerInstanceCreateInfo *vci = (VkLayerInstanceCreateInfo *)n;
      if (vci->function == func_type) {
        return vci;
      }
    }
    return nullptr;
  }
  
  VkLayerDeviceCreateInfo *GetLoaderDeviceInfo(const VkDeviceCreateInfo *create_info, VkLayerFunction func_type) {
    VkStruct *n = (VkStruct *)create_info;
    while ((n = FindOnChain(n, VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO))) {
      VkLayerDeviceCreateInfo *vdi = (VkLayerDeviceCreateInfo *)n;
      if (vdi->function == func_type) {
        return vdi;
      }
    }
    return nullptr;
  }
  
  DeviceLayerData* GetDeviceLayerData(dispatch_key key) {
    if (!last_used_device_layer_data || last_used_device_layer_data->key != key) {
      std::lock_guard<std::mutex> lock(device_layer_data_mutex);
      auto it = std::find_if(std::begin(device_layer_data_list), std::end(device_layer_data_list),
      [&] (DeviceLayerData const* p) { return p->key == key; });
      if (it != device_layer_data_list.end()) {
        last_used_device_layer_data = *it;
        return last_used_device_layer_data;
      }
      device_layer_data_list.push_back(new DeviceLayerData(key));
      last_used_device_layer_data = device_layer_data_list.back();
    }
    return last_used_device_layer_data;
  }
  
  void FreeDeviceLayerData(dispatch_key key) {
    std::lock_guard<std::mutex> lock(device_layer_data_mutex);
    auto it = std::find_if(std::begin(device_layer_data_list), std::end(device_layer_data_list),
    [&] (DeviceLayerData const* p) { return p->key == key; });
    if (it != device_layer_data_list.end()) {
      device_layer_data_list.erase(it);
      last_used_device_layer_data = nullptr;
    }
  }
  
  InstanceLayerData* GetInstanceLayerData(dispatch_key key) {
    if (!last_used_instance_layer_data || last_used_instance_layer_data->key != key) {
      std::lock_guard<std::mutex> lock(instance_layer_data_mutex);
      auto it = std::find_if(std::begin(instance_layer_data_list), std::end(instance_layer_data_list),
      [&] (InstanceLayerData const* p) { return p->key == key; });
      if (it != instance_layer_data_list.end()) {
        last_used_instance_layer_data = *it;
        return last_used_instance_layer_data;
      }
      instance_layer_data_list.push_back(new InstanceLayerData(key));
      last_used_instance_layer_data = instance_layer_data_list.back();
    }
    return last_used_instance_layer_data;
  }
  
  void FreeInstanceLayerData(dispatch_key key) {
    std::lock_guard<std::mutex> lock(instance_layer_data_mutex);
    auto it = std::find_if(std::begin(instance_layer_data_list), std::end(instance_layer_data_list),
    [&] (InstanceLayerData const* p) { return p->key == key; });
    if (it != instance_layer_data_list.end()) {
      instance_layer_data_list.erase(it);
      last_used_instance_layer_data = nullptr;
    }
  }
  
  std::mutex &GetGlobalLayerLock() { return g_lock; }
  
  VkResult SetInstanceLoaderData(VkInstance instance, void *obj)
  {
    InstanceLayerData *instance_data = GetInstanceLayerData(get_dispatch_key(instance));
    return instance_data->SetInstanceLoaderData(instance, obj);
  }
  
  VkResult SetDeviceLoaderData(VkDevice device, void *obj)
  {
    DeviceLayerData *device_data = GetDeviceLayerData(get_dispatch_key(device));
    return device_data->SetDeviceLoaderData(device, obj);
  }
  VkResult SetDeviceLoaderData(VkDevice device, void *obj);
  
  VkLayerInstanceDispatchTable *GetInstanceDispatchTableByKey(void *key)
  {
    InstanceLayerData *instance_data = GetInstanceLayerData(get_dispatch_key(key));
    return &instance_data->dispatch_table;
  }
  
  VkLayerDispatchTable *GetDeviceDispatchTableByKey(void* key)
  {
    DeviceLayerData *device_data = GetDeviceLayerData(get_dispatch_key(key));
    return &device_data->dispatch_table;
  }
  
  
  VKAPI_ATTR VkResult VKAPI_CALL CreateBuffer(VkDevice device, VkBufferCreateInfo const* pCreateInfo, AllocationCallbacks pAllocator, VkBuffer* pBuffer)
  {
    auto &dispatch_table = *GetDeviceDispatchTable(device);
    VkResult result = VkResult::VK_SUCCESS; 
  
    if (dispatch_table.CreateBuffer) {
      result = dispatch_table.CreateBuffer(device, pCreateInfo, pAllocator, pBuffer);
    }
    return result; 
  }
  
  VKAPI_ATTR void VKAPI_CALL DestroyBuffer(VkDevice device, VkBuffer buffer, AllocationCallbacks pAllocator)
  {
    auto &dispatch_table = *GetDeviceDispatchTable(device);
  
    GetInterceptor()->PreDestroyBuffer(device, buffer, pAllocator);
  
    if (dispatch_table.DestroyBuffer) {
      dispatch_table.DestroyBuffer(device, buffer, pAllocator);
    }
  
    GetInterceptor()->PostDestroyBuffer(device, buffer, pAllocator);
  }
  
  VKAPI_ATTR VkResult VKAPI_CALL CreateBufferView(VkDevice device, VkBufferViewCreateInfo const* pCreateInfo, AllocationCallbacks pAllocator, VkBufferView* pView)
  {
    auto &dispatch_table = *GetDeviceDispatchTable(device);
    VkResult result = VkResult::VK_SUCCESS; 
  
    if (dispatch_table.CreateBufferView) {
      result = dispatch_table.CreateBufferView(device, pCreateInfo, pAllocator, pView);
    }
    return result; 
  }
  
  VKAPI_ATTR void VKAPI_CALL DestroyBufferView(VkDevice device, VkBufferView bufferView, AllocationCallbacks pAllocator)
  {
    auto &dispatch_table = *GetDeviceDispatchTable(device);
  
    if (dispatch_table.DestroyBufferView) {
      dispatch_table.DestroyBufferView(device, bufferView, pAllocator);
    }
  }
  
  VKAPI_ATTR VkResult VKAPI_CALL BindBufferMemory(VkDevice device, VkBuffer buffer, VkDeviceMemory memory, VkDeviceSize memoryOffset)
  {
    auto &dispatch_table = *GetDeviceDispatchTable(device);
    VkResult result = VkResult::VK_SUCCESS; 
  
    if (dispatch_table.BindBufferMemory) {
      result = dispatch_table.BindBufferMemory(device, buffer, memory, memoryOffset);
    }
    return result; 
  }
  
  VKAPI_ATTR VkResult VKAPI_CALL BindBufferMemory2(VkDevice device, uint32_t bindInfoCount, VkBindBufferMemoryInfo const* pBindInfos)
  {
    auto &dispatch_table = *GetDeviceDispatchTable(device);
    VkResult result = VkResult::VK_SUCCESS; 
  
    if (dispatch_table.BindBufferMemory2) {
      result = dispatch_table.BindBufferMemory2(device, bindInfoCount, pBindInfos);
    }
    return result; 
  }
  
  VKAPI_ATTR VkResult VKAPI_CALL CreateCommandPool(VkDevice device, VkCommandPoolCreateInfo const* pCreateInfo, AllocationCallbacks pAllocator, VkCommandPool* pCommandPool)
  {
    auto &dispatch_table = *GetDeviceDispatchTable(device);
    VkResult result = VkResult::VK_SUCCESS; 
  
    result = GetInterceptor()->PreCreateCommandPool(device, pCreateInfo, pAllocator, pCommandPool);
  
    if (dispatch_table.CreateCommandPool) {
      result = dispatch_table.CreateCommandPool(device, pCreateInfo, pAllocator, pCommandPool);
    }
  
    GetInterceptor()->PostCreateCommandPool(device, pCreateInfo, pAllocator, pCommandPool, result);
    return result; 
  }
  
  VKAPI_ATTR void VKAPI_CALL DestroyCommandPool(VkDevice device, VkCommandPool commandPool, AllocationCallbacks pAllocator)
  {
    auto &dispatch_table = *GetDeviceDispatchTable(device);
  
    GetInterceptor()->PreDestroyCommandPool(device, commandPool, pAllocator);
  
    if (dispatch_table.DestroyCommandPool) {
      dispatch_table.DestroyCommandPool(device, commandPool, pAllocator);
    }
  
    GetInterceptor()->PostDestroyCommandPool(device, commandPool, pAllocator);
  }
  
  VKAPI_ATTR VkResult VKAPI_CALL ResetCommandPool(VkDevice device, VkCommandPool commandPool, VkCommandPoolResetFlags flags)
  {
    auto &dispatch_table = *GetDeviceDispatchTable(device);
    VkResult result = VkResult::VK_SUCCESS; 
  
    result = GetInterceptor()->PreResetCommandPool(device, commandPool, flags);
  
    if (dispatch_table.ResetCommandPool) {
      result = dispatch_table.ResetCommandPool(device, commandPool, flags);
    }
  
    GetInterceptor()->PostResetCommandPool(device, commandPool, flags, result);
    return result; 
  }
  
  VKAPI_ATTR VkResult VKAPI_CALL AllocateCommandBuffers(VkDevice device, VkCommandBufferAllocateInfo const* pAllocateInfo, VkCommandBuffer* pCommandBuffers)
  {
    auto &dispatch_table = *GetDeviceDispatchTable(device);
    VkResult result = VkResult::VK_SUCCESS; 
  
    result = GetInterceptor()->PreAllocateCommandBuffers(device, pAllocateInfo, pCommandBuffers);
  
    if (dispatch_table.AllocateCommandBuffers) {
      result = dispatch_table.AllocateCommandBuffers(device, pAllocateInfo, pCommandBuffers);
    }
  
    GetInterceptor()->PostAllocateCommandBuffers(device, pAllocateInfo, pCommandBuffers, result);
    return result; 
  }
  VKAPI_ATTR void VKAPI_CALL FreeCommandBuffers(VkDevice device, VkCommandPool commandPool, uint32_t commandBufferCount, VkCommandBuffer const* pCommandBuffers);
  
  VKAPI_ATTR VkResult VKAPI_CALL BeginCommandBuffer(VkCommandBuffer commandBuffer, VkCommandBufferBeginInfo const* pBeginInfo)
  {
    auto &dispatch_table = *GetDeviceDispatchTable(commandBuffer);
    WrappedVkCommandBuffer *wrappedcommandBuffer = reinterpret_cast<WrappedVkCommandBuffer *>(commandBuffer);
    VkCommandBuffer unwrappedcommandBuffer = wrappedcommandBuffer->wrapped_object;
    VkResult result = VkResult::VK_SUCCESS; 
  
    result = GetInterceptor()->PreBeginCommandBuffer(wrappedcommandBuffer, pBeginInfo);
  
    if (dispatch_table.BeginCommandBuffer) {
      result = dispatch_table.BeginCommandBuffer(unwrappedcommandBuffer, pBeginInfo);
    }
  
    GetInterceptor()->PostBeginCommandBuffer(wrappedcommandBuffer, pBeginInfo, result);
    return result; 
  }
  
  VKAPI_ATTR VkResult VKAPI_CALL EndCommandBuffer(VkCommandBuffer commandBuffer)
  {
    auto &dispatch_table = *GetDeviceDispatchTable(commandBuffer);
    WrappedVkCommandBuffer *wrappedcommandBuffer = reinterpret_cast<WrappedVkCommandBuffer *>(commandBuffer);
    VkCommandBuffer unwrappedcommandBuffer = wrappedcommandBuffer->wrapped_object;
    VkResult result = VkResult::VK_SUCCESS; 
  
    result = GetInterceptor()->PreEndCommandBuffer(wrappedcommandBuffer);
  
    if (dispatch_table.EndCommandBuffer) {
      result = dispatch_table.EndCommandBuffer(unwrappedcommandBuffer);
    }
  
    GetInterceptor()->PostEndCommandBuffer(wrappedcommandBuffer, result);
    return result; 
  }
  
  VKAPI_ATTR VkResult VKAPI_CALL ResetCommandBuffer(VkCommandBuffer commandBuffer, VkCommandBufferResetFlags flags)
  {
    auto &dispatch_table = *GetDeviceDispatchTable(commandBuffer);
    WrappedVkCommandBuffer *wrappedcommandBuffer = reinterpret_cast<WrappedVkCommandBuffer *>(commandBuffer);
    VkCommandBuffer unwrappedcommandBuffer = wrappedcommandBuffer->wrapped_object;
    VkResult result = VkResult::VK_SUCCESS; 
  
    result = GetInterceptor()->PreResetCommandBuffer(wrappedcommandBuffer, flags);
  
    if (dispatch_table.ResetCommandBuffer) {
      result = dispatch_table.ResetCommandBuffer(unwrappedcommandBuffer, flags);
    }
  
    GetInterceptor()->PostResetCommandBuffer(wrappedcommandBuffer, flags, result);
    return result; 
  }
  VKAPI_ATTR void VKAPI_CALL CmdExecuteCommands(VkCommandBuffer commandBuffer, uint32_t commandBufferCount, VkCommandBuffer const* pCommandBuffers);
  
  VKAPI_ATTR void VKAPI_CALL TrimCommandPool(VkDevice device, VkCommandPool commandPool, VkCommandPoolTrimFlags flags)
  {
    auto &dispatch_table = *GetDeviceDispatchTable(device);
  
    if (dispatch_table.TrimCommandPool) {
      dispatch_table.TrimCommandPool(device, commandPool, flags);
    }
  }
  
  VKAPI_ATTR void VKAPI_CALL CmdCopyBuffer(VkCommandBuffer commandBuffer, VkBuffer srcBuffer, VkBuffer dstBuffer, uint32_t regionCount, VkBufferCopy const* pRegions)
  {
    auto &dispatch_table = *GetDeviceDispatchTable(commandBuffer);
    WrappedVkCommandBuffer *wrappedcommandBuffer = reinterpret_cast<WrappedVkCommandBuffer *>(commandBuffer);
    VkCommandBuffer unwrappedcommandBuffer = wrappedcommandBuffer->wrapped_object;
  
    GetInterceptor()->PreCmdCopyBuffer(wrappedcommandBuffer, srcBuffer, dstBuffer, regionCount, pRegions);
  
    if (dispatch_table.CmdCopyBuffer) {
      dispatch_table.CmdCopyBuffer(unwrappedcommandBuffer, srcBuffer, dstBuffer, regionCount, pRegions);
    }
  
    GetInterceptor()->PostCmdCopyBuffer(wrappedcommandBuffer, srcBuffer, dstBuffer, regionCount, pRegions);
  }
  
  VKAPI_ATTR void VKAPI_CALL CmdCopyImage(VkCommandBuffer commandBuffer, VkImage srcImage, VkImageLayout srcImageLayout, VkImage dstImage, VkImageLayout dstImageLayout, uint32_t regionCount, VkImageCopy const* pRegions)
  {
    auto &dispatch_table = *GetDeviceDispatchTable(commandBuffer);
    WrappedVkCommandBuffer *wrappedcommandBuffer = reinterpret_cast<WrappedVkCommandBuffer *>(commandBuffer);
    VkCommandBuffer unwrappedcommandBuffer = wrappedcommandBuffer->wrapped_object;
  
    GetInterceptor()->PreCmdCopyImage(wrappedcommandBuffer, srcImage, srcImageLayout, dstImage, dstImageLayout, regionCount, pRegions);
  
    if (dispatch_table.CmdCopyImage) {
      dispatch_table.CmdCopyImage(unwrappedcommandBuffer, srcImage, srcImageLayout, dstImage, dstImageLayout, regionCount, pRegions);
    }
  
    GetInterceptor()->PostCmdCopyImage(wrappedcommandBuffer, srcImage, srcImageLayout, dstImage, dstImageLayout, regionCount, pRegions);
  }
  
  VKAPI_ATTR void VKAPI_CALL CmdBlitImage(VkCommandBuffer commandBuffer, VkImage srcImage, VkImageLayout srcImageLayout, VkImage dstImage, VkImageLayout dstImageLayout, uint32_t regionCount, VkImageBlit const* pRegions, VkFilter filter)
  {
    auto &dispatch_table = *GetDeviceDispatchTable(commandBuffer);
    WrappedVkCommandBuffer *wrappedcommandBuffer = reinterpret_cast<WrappedVkCommandBuffer *>(commandBuffer);
    VkCommandBuffer unwrappedcommandBuffer = wrappedcommandBuffer->wrapped_object;
  
    GetInterceptor()->PreCmdBlitImage(wrappedcommandBuffer, srcImage, srcImageLayout, dstImage, dstImageLayout, regionCount, pRegions, filter);
  
    if (dispatch_table.CmdBlitImage) {
      dispatch_table.CmdBlitImage(unwrappedcommandBuffer, srcImage, srcImageLayout, dstImage, dstImageLayout, regionCount, pRegions, filter);
    }
  
    GetInterceptor()->PostCmdBlitImage(wrappedcommandBuffer, srcImage, srcImageLayout, dstImage, dstImageLayout, regionCount, pRegions, filter);
  }
  
  VKAPI_ATTR void VKAPI_CALL CmdCopyBufferToImage(VkCommandBuffer commandBuffer, VkBuffer srcBuffer, VkImage dstImage, VkImageLayout dstImageLayout, uint32_t regionCount, VkBufferImageCopy const* pRegions)
  {
    auto &dispatch_table = *GetDeviceDispatchTable(commandBuffer);
    WrappedVkCommandBuffer *wrappedcommandBuffer = reinterpret_cast<WrappedVkCommandBuffer *>(commandBuffer);
    VkCommandBuffer unwrappedcommandBuffer = wrappedcommandBuffer->wrapped_object;
  
    GetInterceptor()->PreCmdCopyBufferToImage(wrappedcommandBuffer, srcBuffer, dstImage, dstImageLayout, regionCount, pRegions);
  
    if (dispatch_table.CmdCopyBufferToImage) {
      dispatch_table.CmdCopyBufferToImage(unwrappedcommandBuffer, srcBuffer, dstImage, dstImageLayout, regionCount, pRegions);
    }
  
    GetInterceptor()->PostCmdCopyBufferToImage(wrappedcommandBuffer, srcBuffer, dstImage, dstImageLayout, regionCount, pRegions);
  }
  
  VKAPI_ATTR void VKAPI_CALL CmdCopyImageToBuffer(VkCommandBuffer commandBuffer, VkImage srcImage, VkImageLayout srcImageLayout, VkBuffer dstBuffer, uint32_t regionCount, VkBufferImageCopy const* pRegions)
  {
    auto &dispatch_table = *GetDeviceDispatchTable(commandBuffer);
    WrappedVkCommandBuffer *wrappedcommandBuffer = reinterpret_cast<WrappedVkCommandBuffer *>(commandBuffer);
    VkCommandBuffer unwrappedcommandBuffer = wrappedcommandBuffer->wrapped_object;
  
    GetInterceptor()->PreCmdCopyImageToBuffer(wrappedcommandBuffer, srcImage, srcImageLayout, dstBuffer, regionCount, pRegions);
  
    if (dispatch_table.CmdCopyImageToBuffer) {
      dispatch_table.CmdCopyImageToBuffer(unwrappedcommandBuffer, srcImage, srcImageLayout, dstBuffer, regionCount, pRegions);
    }
  
    GetInterceptor()->PostCmdCopyImageToBuffer(wrappedcommandBuffer, srcImage, srcImageLayout, dstBuffer, regionCount, pRegions);
  }
  
  VKAPI_ATTR void VKAPI_CALL CmdUpdateBuffer(VkCommandBuffer commandBuffer, VkBuffer dstBuffer, VkDeviceSize dstOffset, VkDeviceSize dataSize, void const* pData)
  {
    auto &dispatch_table = *GetDeviceDispatchTable(commandBuffer);
    WrappedVkCommandBuffer *wrappedcommandBuffer = reinterpret_cast<WrappedVkCommandBuffer *>(commandBuffer);
    VkCommandBuffer unwrappedcommandBuffer = wrappedcommandBuffer->wrapped_object;
  
    GetInterceptor()->PreCmdUpdateBuffer(wrappedcommandBuffer, dstBuffer, dstOffset, dataSize, pData);
  
    if (dispatch_table.CmdUpdateBuffer) {
      dispatch_table.CmdUpdateBuffer(unwrappedcommandBuffer, dstBuffer, dstOffset, dataSize, pData);
    }
  
    GetInterceptor()->PostCmdUpdateBuffer(wrappedcommandBuffer, dstBuffer, dstOffset, dataSize, pData);
  }
  
  VKAPI_ATTR void VKAPI_CALL CmdFillBuffer(VkCommandBuffer commandBuffer, VkBuffer dstBuffer, VkDeviceSize dstOffset, VkDeviceSize size, uint32_t data)
  {
    auto &dispatch_table = *GetDeviceDispatchTable(commandBuffer);
    WrappedVkCommandBuffer *wrappedcommandBuffer = reinterpret_cast<WrappedVkCommandBuffer *>(commandBuffer);
    VkCommandBuffer unwrappedcommandBuffer = wrappedcommandBuffer->wrapped_object;
  
    GetInterceptor()->PreCmdFillBuffer(wrappedcommandBuffer, dstBuffer, dstOffset, size, data);
  
    if (dispatch_table.CmdFillBuffer) {
      dispatch_table.CmdFillBuffer(unwrappedcommandBuffer, dstBuffer, dstOffset, size, data);
    }
  
    GetInterceptor()->PostCmdFillBuffer(wrappedcommandBuffer, dstBuffer, dstOffset, size, data);
  }
  
  VKAPI_ATTR void VKAPI_CALL CmdClearColorImage(VkCommandBuffer commandBuffer, VkImage image, VkImageLayout imageLayout, VkClearColorValue const* pColor, uint32_t rangeCount, VkImageSubresourceRange const* pRanges)
  {
    auto &dispatch_table = *GetDeviceDispatchTable(commandBuffer);
    WrappedVkCommandBuffer *wrappedcommandBuffer = reinterpret_cast<WrappedVkCommandBuffer *>(commandBuffer);
    VkCommandBuffer unwrappedcommandBuffer = wrappedcommandBuffer->wrapped_object;
  
    GetInterceptor()->PreCmdClearColorImage(wrappedcommandBuffer, image, imageLayout, pColor, rangeCount, pRanges);
  
    if (dispatch_table.CmdClearColorImage) {
      dispatch_table.CmdClearColorImage(unwrappedcommandBuffer, image, imageLayout, pColor, rangeCount, pRanges);
    }
  
    GetInterceptor()->PostCmdClearColorImage(wrappedcommandBuffer, image, imageLayout, pColor, rangeCount, pRanges);
  }
  
  VKAPI_ATTR void VKAPI_CALL CmdClearDepthStencilImage(VkCommandBuffer commandBuffer, VkImage image, VkImageLayout imageLayout, VkClearDepthStencilValue const* pDepthStencil, uint32_t rangeCount, VkImageSubresourceRange const* pRanges)
  {
    auto &dispatch_table = *GetDeviceDispatchTable(commandBuffer);
    WrappedVkCommandBuffer *wrappedcommandBuffer = reinterpret_cast<WrappedVkCommandBuffer *>(commandBuffer);
    VkCommandBuffer unwrappedcommandBuffer = wrappedcommandBuffer->wrapped_object;
  
    GetInterceptor()->PreCmdClearDepthStencilImage(wrappedcommandBuffer, image, imageLayout, pDepthStencil, rangeCount, pRanges);
  
    if (dispatch_table.CmdClearDepthStencilImage) {
      dispatch_table.CmdClearDepthStencilImage(unwrappedcommandBuffer, image, imageLayout, pDepthStencil, rangeCount, pRanges);
    }
  
    GetInterceptor()->PostCmdClearDepthStencilImage(wrappedcommandBuffer, image, imageLayout, pDepthStencil, rangeCount, pRanges);
  }
  
  VKAPI_ATTR void VKAPI_CALL CmdClearAttachments(VkCommandBuffer commandBuffer, uint32_t attachmentCount, VkClearAttachment const* pAttachments, uint32_t rectCount, VkClearRect const* pRects)
  {
    auto &dispatch_table = *GetDeviceDispatchTable(commandBuffer);
    WrappedVkCommandBuffer *wrappedcommandBuffer = reinterpret_cast<WrappedVkCommandBuffer *>(commandBuffer);
    VkCommandBuffer unwrappedcommandBuffer = wrappedcommandBuffer->wrapped_object;
  
    GetInterceptor()->PreCmdClearAttachments(wrappedcommandBuffer, attachmentCount, pAttachments, rectCount, pRects);
  
    if (dispatch_table.CmdClearAttachments) {
      dispatch_table.CmdClearAttachments(unwrappedcommandBuffer, attachmentCount, pAttachments, rectCount, pRects);
    }
  
    GetInterceptor()->PostCmdClearAttachments(wrappedcommandBuffer, attachmentCount, pAttachments, rectCount, pRects);
  }
  
  VKAPI_ATTR void VKAPI_CALL CmdResolveImage(VkCommandBuffer commandBuffer, VkImage srcImage, VkImageLayout srcImageLayout, VkImage dstImage, VkImageLayout dstImageLayout, uint32_t regionCount, VkImageResolve const* pRegions)
  {
    auto &dispatch_table = *GetDeviceDispatchTable(commandBuffer);
    WrappedVkCommandBuffer *wrappedcommandBuffer = reinterpret_cast<WrappedVkCommandBuffer *>(commandBuffer);
    VkCommandBuffer unwrappedcommandBuffer = wrappedcommandBuffer->wrapped_object;
  
    GetInterceptor()->PreCmdResolveImage(wrappedcommandBuffer, srcImage, srcImageLayout, dstImage, dstImageLayout, regionCount, pRegions);
  
    if (dispatch_table.CmdResolveImage) {
      dispatch_table.CmdResolveImage(unwrappedcommandBuffer, srcImage, srcImageLayout, dstImage, dstImageLayout, regionCount, pRegions);
    }
  
    GetInterceptor()->PostCmdResolveImage(wrappedcommandBuffer, srcImage, srcImageLayout, dstImage, dstImageLayout, regionCount, pRegions);
  }
  
  VKAPI_ATTR VkResult VKAPI_CALL CreateDescriptorSetLayout(VkDevice device, VkDescriptorSetLayoutCreateInfo const* pCreateInfo, AllocationCallbacks pAllocator, VkDescriptorSetLayout* pSetLayout)
  {
    auto &dispatch_table = *GetDeviceDispatchTable(device);
    VkResult result = VkResult::VK_SUCCESS; 
  
    if (dispatch_table.CreateDescriptorSetLayout) {
      result = dispatch_table.CreateDescriptorSetLayout(device, pCreateInfo, pAllocator, pSetLayout);
    }
    return result; 
  }
  
  VKAPI_ATTR void VKAPI_CALL DestroyDescriptorSetLayout(VkDevice device, VkDescriptorSetLayout descriptorSetLayout, AllocationCallbacks pAllocator)
  {
    auto &dispatch_table = *GetDeviceDispatchTable(device);
  
    if (dispatch_table.DestroyDescriptorSetLayout) {
      dispatch_table.DestroyDescriptorSetLayout(device, descriptorSetLayout, pAllocator);
    }
  }
  
  VKAPI_ATTR VkResult VKAPI_CALL CreateDescriptorPool(VkDevice device, VkDescriptorPoolCreateInfo const* pCreateInfo, AllocationCallbacks pAllocator, VkDescriptorPool* pDescriptorPool)
  {
    auto &dispatch_table = *GetDeviceDispatchTable(device);
    VkResult result = VkResult::VK_SUCCESS; 
  
    if (dispatch_table.CreateDescriptorPool) {
      result = dispatch_table.CreateDescriptorPool(device, pCreateInfo, pAllocator, pDescriptorPool);
    }
    return result; 
  }
  
  VKAPI_ATTR void VKAPI_CALL DestroyDescriptorPool(VkDevice device, VkDescriptorPool descriptorPool, AllocationCallbacks pAllocator)
  {
    auto &dispatch_table = *GetDeviceDispatchTable(device);
  
    if (dispatch_table.DestroyDescriptorPool) {
      dispatch_table.DestroyDescriptorPool(device, descriptorPool, pAllocator);
    }
  }
  
  VKAPI_ATTR VkResult VKAPI_CALL ResetDescriptorPool(VkDevice device, VkDescriptorPool descriptorPool, VkDescriptorPoolResetFlags flags)
  {
    auto &dispatch_table = *GetDeviceDispatchTable(device);
    VkResult result = VkResult::VK_SUCCESS; 
  
    if (dispatch_table.ResetDescriptorPool) {
      result = dispatch_table.ResetDescriptorPool(device, descriptorPool, flags);
    }
    return result; 
  }
  
  VKAPI_ATTR VkResult VKAPI_CALL AllocateDescriptorSets(VkDevice device, VkDescriptorSetAllocateInfo const* pAllocateInfo, VkDescriptorSet* pDescriptorSets)
  {
    auto &dispatch_table = *GetDeviceDispatchTable(device);
    VkResult result = VkResult::VK_SUCCESS; 
  
    if (dispatch_table.AllocateDescriptorSets) {
      result = dispatch_table.AllocateDescriptorSets(device, pAllocateInfo, pDescriptorSets);
    }
    return result; 
  }
  
  VKAPI_ATTR VkResult VKAPI_CALL FreeDescriptorSets(VkDevice device, VkDescriptorPool descriptorPool, uint32_t descriptorSetCount, VkDescriptorSet const* pDescriptorSets)
  {
    auto &dispatch_table = *GetDeviceDispatchTable(device);
    VkResult result = VkResult::VK_SUCCESS; 
  
    if (dispatch_table.FreeDescriptorSets) {
      result = dispatch_table.FreeDescriptorSets(device, descriptorPool, descriptorSetCount, pDescriptorSets);
    }
    return result; 
  }
  
  VKAPI_ATTR void VKAPI_CALL UpdateDescriptorSets(VkDevice device, uint32_t descriptorWriteCount, VkWriteDescriptorSet const* pDescriptorWrites, uint32_t descriptorCopyCount, VkCopyDescriptorSet const* pDescriptorCopies)
  {
    auto &dispatch_table = *GetDeviceDispatchTable(device);
  
    GetInterceptor()->PreUpdateDescriptorSets(device, descriptorWriteCount, pDescriptorWrites, descriptorCopyCount, pDescriptorCopies);
  
    if (dispatch_table.UpdateDescriptorSets) {
      dispatch_table.UpdateDescriptorSets(device, descriptorWriteCount, pDescriptorWrites, descriptorCopyCount, pDescriptorCopies);
    }
  
    GetInterceptor()->PostUpdateDescriptorSets(device, descriptorWriteCount, pDescriptorWrites, descriptorCopyCount, pDescriptorCopies);
  }
  
  VKAPI_ATTR void VKAPI_CALL CmdBindDescriptorSets(VkCommandBuffer commandBuffer, VkPipelineBindPoint pipelineBindPoint, VkPipelineLayout layout, uint32_t firstSet, uint32_t descriptorSetCount, VkDescriptorSet const* pDescriptorSets, uint32_t dynamicOffsetCount, uint32_t const* pDynamicOffsets)
  {
    auto &dispatch_table = *GetDeviceDispatchTable(commandBuffer);
    WrappedVkCommandBuffer *wrappedcommandBuffer = reinterpret_cast<WrappedVkCommandBuffer *>(commandBuffer);
    VkCommandBuffer unwrappedcommandBuffer = wrappedcommandBuffer->wrapped_object;
  
    GetInterceptor()->PreCmdBindDescriptorSets(wrappedcommandBuffer, pipelineBindPoint, layout, firstSet, descriptorSetCount, pDescriptorSets, dynamicOffsetCount, pDynamicOffsets);
  
    if (dispatch_table.CmdBindDescriptorSets) {
      dispatch_table.CmdBindDescriptorSets(unwrappedcommandBuffer, pipelineBindPoint, layout, firstSet, descriptorSetCount, pDescriptorSets, dynamicOffsetCount, pDynamicOffsets);
    }
  
    GetInterceptor()->PostCmdBindDescriptorSets(wrappedcommandBuffer, pipelineBindPoint, layout, firstSet, descriptorSetCount, pDescriptorSets, dynamicOffsetCount, pDynamicOffsets);
  }
  
  VKAPI_ATTR void VKAPI_CALL CmdPushConstants(VkCommandBuffer commandBuffer, VkPipelineLayout layout, VkShaderStageFlags stageFlags, uint32_t offset, uint32_t size, void const* pValues)
  {
    auto &dispatch_table = *GetDeviceDispatchTable(commandBuffer);
    WrappedVkCommandBuffer *wrappedcommandBuffer = reinterpret_cast<WrappedVkCommandBuffer *>(commandBuffer);
    VkCommandBuffer unwrappedcommandBuffer = wrappedcommandBuffer->wrapped_object;
  
    GetInterceptor()->PreCmdPushConstants(wrappedcommandBuffer, layout, stageFlags, offset, size, pValues);
  
    if (dispatch_table.CmdPushConstants) {
      dispatch_table.CmdPushConstants(unwrappedcommandBuffer, layout, stageFlags, offset, size, pValues);
    }
  
    GetInterceptor()->PostCmdPushConstants(wrappedcommandBuffer, layout, stageFlags, offset, size, pValues);
  }
  
  VKAPI_ATTR void VKAPI_CALL GetDescriptorSetLayoutSupport(VkDevice device, VkDescriptorSetLayoutCreateInfo const* pCreateInfo, VkDescriptorSetLayoutSupport* pSupport)
  {
    auto &dispatch_table = *GetDeviceDispatchTable(device);
  
    if (dispatch_table.GetDescriptorSetLayoutSupport) {
      dispatch_table.GetDescriptorSetLayoutSupport(device, pCreateInfo, pSupport);
    }
  }
  
  VKAPI_ATTR VkResult VKAPI_CALL DeviceWaitIdle(VkDevice device)
  {
    auto &dispatch_table = *GetDeviceDispatchTable(device);
    VkResult result = VkResult::VK_SUCCESS; 
  
    if (dispatch_table.DeviceWaitIdle) {
      result = dispatch_table.DeviceWaitIdle(device);
    }
  
    GetInterceptor()->PostDeviceWaitIdle(device, result);
    return result; 
  }
  
  VKAPI_ATTR void VKAPI_CALL CmdBindIndexBuffer(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, VkIndexType indexType)
  {
    auto &dispatch_table = *GetDeviceDispatchTable(commandBuffer);
    WrappedVkCommandBuffer *wrappedcommandBuffer = reinterpret_cast<WrappedVkCommandBuffer *>(commandBuffer);
    VkCommandBuffer unwrappedcommandBuffer = wrappedcommandBuffer->wrapped_object;
  
    GetInterceptor()->PreCmdBindIndexBuffer(wrappedcommandBuffer, buffer, offset, indexType);
  
    if (dispatch_table.CmdBindIndexBuffer) {
      dispatch_table.CmdBindIndexBuffer(unwrappedcommandBuffer, buffer, offset, indexType);
    }
  
    GetInterceptor()->PostCmdBindIndexBuffer(wrappedcommandBuffer, buffer, offset, indexType);
  }
  
  VKAPI_ATTR void VKAPI_CALL CmdBindVertexBuffers(VkCommandBuffer commandBuffer, uint32_t firstBinding, uint32_t bindingCount, VkBuffer const* pBuffers, VkDeviceSize const* pOffsets)
  {
    auto &dispatch_table = *GetDeviceDispatchTable(commandBuffer);
    WrappedVkCommandBuffer *wrappedcommandBuffer = reinterpret_cast<WrappedVkCommandBuffer *>(commandBuffer);
    VkCommandBuffer unwrappedcommandBuffer = wrappedcommandBuffer->wrapped_object;
  
    GetInterceptor()->PreCmdBindVertexBuffers(wrappedcommandBuffer, firstBinding, bindingCount, pBuffers, pOffsets);
  
    if (dispatch_table.CmdBindVertexBuffers) {
      dispatch_table.CmdBindVertexBuffers(unwrappedcommandBuffer, firstBinding, bindingCount, pBuffers, pOffsets);
    }
  
    GetInterceptor()->PostCmdBindVertexBuffers(wrappedcommandBuffer, firstBinding, bindingCount, pBuffers, pOffsets);
  }
  
  VKAPI_ATTR void VKAPI_CALL CmdDraw(VkCommandBuffer commandBuffer, uint32_t vertexCount, uint32_t instanceCount, uint32_t firstVertex, uint32_t firstInstance)
  {
    auto &dispatch_table = *GetDeviceDispatchTable(commandBuffer);
    WrappedVkCommandBuffer *wrappedcommandBuffer = reinterpret_cast<WrappedVkCommandBuffer *>(commandBuffer);
    VkCommandBuffer unwrappedcommandBuffer = wrappedcommandBuffer->wrapped_object;
  
    GetInterceptor()->PreCmdDraw(wrappedcommandBuffer, vertexCount, instanceCount, firstVertex, firstInstance);
  
    if (dispatch_table.CmdDraw) {
      dispatch_table.CmdDraw(unwrappedcommandBuffer, vertexCount, instanceCount, firstVertex, firstInstance);
    }
  
    GetInterceptor()->PostCmdDraw(wrappedcommandBuffer, vertexCount, instanceCount, firstVertex, firstInstance);
  }
  
  VKAPI_ATTR void VKAPI_CALL CmdDrawIndexed(VkCommandBuffer commandBuffer, uint32_t indexCount, uint32_t instanceCount, uint32_t firstIndex, int32_t vertexOffset, uint32_t firstInstance)
  {
    auto &dispatch_table = *GetDeviceDispatchTable(commandBuffer);
    WrappedVkCommandBuffer *wrappedcommandBuffer = reinterpret_cast<WrappedVkCommandBuffer *>(commandBuffer);
    VkCommandBuffer unwrappedcommandBuffer = wrappedcommandBuffer->wrapped_object;
  
    GetInterceptor()->PreCmdDrawIndexed(wrappedcommandBuffer, indexCount, instanceCount, firstIndex, vertexOffset, firstInstance);
  
    if (dispatch_table.CmdDrawIndexed) {
      dispatch_table.CmdDrawIndexed(unwrappedcommandBuffer, indexCount, instanceCount, firstIndex, vertexOffset, firstInstance);
    }
  
    GetInterceptor()->PostCmdDrawIndexed(wrappedcommandBuffer, indexCount, instanceCount, firstIndex, vertexOffset, firstInstance);
  }
  
  VKAPI_ATTR void VKAPI_CALL CmdDrawIndirect(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, uint32_t drawCount, uint32_t stride)
  {
    auto &dispatch_table = *GetDeviceDispatchTable(commandBuffer);
    WrappedVkCommandBuffer *wrappedcommandBuffer = reinterpret_cast<WrappedVkCommandBuffer *>(commandBuffer);
    VkCommandBuffer unwrappedcommandBuffer = wrappedcommandBuffer->wrapped_object;
  
    GetInterceptor()->PreCmdDrawIndirect(wrappedcommandBuffer, buffer, offset, drawCount, stride);
  
    if (dispatch_table.CmdDrawIndirect) {
      dispatch_table.CmdDrawIndirect(unwrappedcommandBuffer, buffer, offset, drawCount, stride);
    }
  
    GetInterceptor()->PostCmdDrawIndirect(wrappedcommandBuffer, buffer, offset, drawCount, stride);
  }
  
  VKAPI_ATTR void VKAPI_CALL CmdDrawIndexedIndirect(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, uint32_t drawCount, uint32_t stride)
  {
    auto &dispatch_table = *GetDeviceDispatchTable(commandBuffer);
    WrappedVkCommandBuffer *wrappedcommandBuffer = reinterpret_cast<WrappedVkCommandBuffer *>(commandBuffer);
    VkCommandBuffer unwrappedcommandBuffer = wrappedcommandBuffer->wrapped_object;
  
    GetInterceptor()->PreCmdDrawIndexedIndirect(wrappedcommandBuffer, buffer, offset, drawCount, stride);
  
    if (dispatch_table.CmdDrawIndexedIndirect) {
      dispatch_table.CmdDrawIndexedIndirect(unwrappedcommandBuffer, buffer, offset, drawCount, stride);
    }
  
    GetInterceptor()->PostCmdDrawIndexedIndirect(wrappedcommandBuffer, buffer, offset, drawCount, stride);
  }
  
  VKAPI_ATTR void VKAPI_CALL CmdDispatch(VkCommandBuffer commandBuffer, uint32_t groupCountX, uint32_t groupCountY, uint32_t groupCountZ)
  {
    auto &dispatch_table = *GetDeviceDispatchTable(commandBuffer);
    WrappedVkCommandBuffer *wrappedcommandBuffer = reinterpret_cast<WrappedVkCommandBuffer *>(commandBuffer);
    VkCommandBuffer unwrappedcommandBuffer = wrappedcommandBuffer->wrapped_object;
  
    GetInterceptor()->PreCmdDispatch(wrappedcommandBuffer, groupCountX, groupCountY, groupCountZ);
  
    if (dispatch_table.CmdDispatch) {
      dispatch_table.CmdDispatch(unwrappedcommandBuffer, groupCountX, groupCountY, groupCountZ);
    }
  
    GetInterceptor()->PostCmdDispatch(wrappedcommandBuffer, groupCountX, groupCountY, groupCountZ);
  }
  
  VKAPI_ATTR void VKAPI_CALL CmdDispatchIndirect(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset)
  {
    auto &dispatch_table = *GetDeviceDispatchTable(commandBuffer);
    WrappedVkCommandBuffer *wrappedcommandBuffer = reinterpret_cast<WrappedVkCommandBuffer *>(commandBuffer);
    VkCommandBuffer unwrappedcommandBuffer = wrappedcommandBuffer->wrapped_object;
  
    GetInterceptor()->PreCmdDispatchIndirect(wrappedcommandBuffer, buffer, offset);
  
    if (dispatch_table.CmdDispatchIndirect) {
      dispatch_table.CmdDispatchIndirect(unwrappedcommandBuffer, buffer, offset);
    }
  
    GetInterceptor()->PostCmdDispatchIndirect(wrappedcommandBuffer, buffer, offset);
  }
  
  VKAPI_ATTR VkResult VKAPI_CALL CreateImage(VkDevice device, VkImageCreateInfo const* pCreateInfo, AllocationCallbacks pAllocator, VkImage* pImage)
  {
    auto &dispatch_table = *GetDeviceDispatchTable(device);
    VkResult result = VkResult::VK_SUCCESS; 
  
    if (dispatch_table.CreateImage) {
      result = dispatch_table.CreateImage(device, pCreateInfo, pAllocator, pImage);
    }
    return result; 
  }
  
  VKAPI_ATTR void VKAPI_CALL DestroyImage(VkDevice device, VkImage image, AllocationCallbacks pAllocator)
  {
    auto &dispatch_table = *GetDeviceDispatchTable(device);
  
    if (dispatch_table.DestroyImage) {
      dispatch_table.DestroyImage(device, image, pAllocator);
    }
  }
  
  VKAPI_ATTR void VKAPI_CALL GetImageSubresourceLayout(VkDevice device, VkImage image, VkImageSubresource const* pSubresource, VkSubresourceLayout* pLayout)
  {
    auto &dispatch_table = *GetDeviceDispatchTable(device);
  
    if (dispatch_table.GetImageSubresourceLayout) {
      dispatch_table.GetImageSubresourceLayout(device, image, pSubresource, pLayout);
    }
  }
  
  VKAPI_ATTR VkResult VKAPI_CALL BindImageMemory(VkDevice device, VkImage image, VkDeviceMemory memory, VkDeviceSize memoryOffset)
  {
    auto &dispatch_table = *GetDeviceDispatchTable(device);
    VkResult result = VkResult::VK_SUCCESS; 
  
    if (dispatch_table.BindImageMemory) {
      result = dispatch_table.BindImageMemory(device, image, memory, memoryOffset);
    }
    return result; 
  }
  
  VKAPI_ATTR VkResult VKAPI_CALL CreateImageView(VkDevice device, VkImageViewCreateInfo const* pCreateInfo, AllocationCallbacks pAllocator, VkImageView* pView)
  {
    auto &dispatch_table = *GetDeviceDispatchTable(device);
    VkResult result = VkResult::VK_SUCCESS; 
  
    if (dispatch_table.CreateImageView) {
      result = dispatch_table.CreateImageView(device, pCreateInfo, pAllocator, pView);
    }
    return result; 
  }
  
  VKAPI_ATTR void VKAPI_CALL DestroyImageView(VkDevice device, VkImageView imageView, AllocationCallbacks pAllocator)
  {
    auto &dispatch_table = *GetDeviceDispatchTable(device);
  
    if (dispatch_table.DestroyImageView) {
      dispatch_table.DestroyImageView(device, imageView, pAllocator);
    }
  }
  
  VKAPI_ATTR VkResult VKAPI_CALL CreateSampler(VkDevice device, VkSamplerCreateInfo const* pCreateInfo, AllocationCallbacks pAllocator, VkSampler* pSampler)
  {
    auto &dispatch_table = *GetDeviceDispatchTable(device);
    VkResult result = VkResult::VK_SUCCESS; 
  
    if (dispatch_table.CreateSampler) {
      result = dispatch_table.CreateSampler(device, pCreateInfo, pAllocator, pSampler);
    }
    return result; 
  }
  
  VKAPI_ATTR void VKAPI_CALL DestroySampler(VkDevice device, VkSampler sampler, AllocationCallbacks pAllocator)
  {
    auto &dispatch_table = *GetDeviceDispatchTable(device);
  
    if (dispatch_table.DestroySampler) {
      dispatch_table.DestroySampler(device, sampler, pAllocator);
    }
  }
  
  VKAPI_ATTR VkResult VKAPI_CALL BindImageMemory2(VkDevice device, uint32_t bindInfoCount, VkBindImageMemoryInfo const* pBindInfos)
  {
    auto &dispatch_table = *GetDeviceDispatchTable(device);
    VkResult result = VkResult::VK_SUCCESS; 
  
    if (dispatch_table.BindImageMemory2) {
      result = dispatch_table.BindImageMemory2(device, bindInfoCount, pBindInfos);
    }
    return result; 
  }
  
  VKAPI_ATTR VkResult VKAPI_CALL CreateSamplerYcbcrConversion(VkDevice device, VkSamplerYcbcrConversionCreateInfo const* pCreateInfo, VkAllocationCallbacks const* pAllocator, VkSamplerYcbcrConversion* pYcbcrConversion)
  {
    auto &dispatch_table = *GetDeviceDispatchTable(device);
    VkResult result = VkResult::VK_SUCCESS; 
  
    if (dispatch_table.CreateSamplerYcbcrConversion) {
      result = dispatch_table.CreateSamplerYcbcrConversion(device, pCreateInfo, pAllocator, pYcbcrConversion);
    }
    return result; 
  }
  
  VKAPI_ATTR void VKAPI_CALL DestroySamplerYcbcrConversion(VkDevice device, VkSamplerYcbcrConversion ycbcrConversion, VkAllocationCallbacks const* pAllocator)
  {
    auto &dispatch_table = *GetDeviceDispatchTable(device);
  
    if (dispatch_table.DestroySamplerYcbcrConversion) {
      dispatch_table.DestroySamplerYcbcrConversion(device, ycbcrConversion, pAllocator);
    }
  }
  
  VKAPI_ATTR VkResult VKAPI_CALL AllocateMemory(VkDevice device, VkMemoryAllocateInfo const* pAllocateInfo, AllocationCallbacks pAllocator, VkDeviceMemory* pMemory)
  {
    auto &dispatch_table = *GetDeviceDispatchTable(device);
    VkResult result = VkResult::VK_SUCCESS; 
  
    if (dispatch_table.AllocateMemory) {
      result = dispatch_table.AllocateMemory(device, pAllocateInfo, pAllocator, pMemory);
    }
    return result; 
  }
  
  VKAPI_ATTR void VKAPI_CALL FreeMemory(VkDevice device, VkDeviceMemory memory, AllocationCallbacks pAllocator)
  {
    auto &dispatch_table = *GetDeviceDispatchTable(device);
  
    if (dispatch_table.FreeMemory) {
      dispatch_table.FreeMemory(device, memory, pAllocator);
    }
  }
  
  VKAPI_ATTR VkResult VKAPI_CALL MapMemory(VkDevice device, VkDeviceMemory memory, VkDeviceSize offset, VkDeviceSize size, VkMemoryMapFlags flags, void** ppData)
  {
    auto &dispatch_table = *GetDeviceDispatchTable(device);
    VkResult result = VkResult::VK_SUCCESS; 
  
    if (dispatch_table.MapMemory) {
      result = dispatch_table.MapMemory(device, memory, offset, size, flags, ppData);
    }
    return result; 
  }
  
  VKAPI_ATTR void VKAPI_CALL UnmapMemory(VkDevice device, VkDeviceMemory memory)
  {
    auto &dispatch_table = *GetDeviceDispatchTable(device);
  
    if (dispatch_table.UnmapMemory) {
      dispatch_table.UnmapMemory(device, memory);
    }
  }
  
  VKAPI_ATTR VkResult VKAPI_CALL FlushMappedMemoryRanges(VkDevice device, uint32_t memoryRangeCount, VkMappedMemoryRange const* pMemoryRanges)
  {
    auto &dispatch_table = *GetDeviceDispatchTable(device);
    VkResult result = VkResult::VK_SUCCESS; 
  
    if (dispatch_table.FlushMappedMemoryRanges) {
      result = dispatch_table.FlushMappedMemoryRanges(device, memoryRangeCount, pMemoryRanges);
    }
    return result; 
  }
  
  VKAPI_ATTR VkResult VKAPI_CALL InvalidateMappedMemoryRanges(VkDevice device, uint32_t memoryRangeCount, VkMappedMemoryRange const* pMemoryRanges)
  {
    auto &dispatch_table = *GetDeviceDispatchTable(device);
    VkResult result = VkResult::VK_SUCCESS; 
  
    if (dispatch_table.InvalidateMappedMemoryRanges) {
      result = dispatch_table.InvalidateMappedMemoryRanges(device, memoryRangeCount, pMemoryRanges);
    }
    return result; 
  }
  
  VKAPI_ATTR void VKAPI_CALL GetDeviceMemoryCommitment(VkDevice device, VkDeviceMemory memory, VkDeviceSize* pCommittedMemoryInBytes)
  {
    auto &dispatch_table = *GetDeviceDispatchTable(device);
  
    if (dispatch_table.GetDeviceMemoryCommitment) {
      dispatch_table.GetDeviceMemoryCommitment(device, memory, pCommittedMemoryInBytes);
    }
  }
  
  VKAPI_ATTR VkResult VKAPI_CALL EnumeratePhysicalDevices(VkInstance instance, uint32_t* pPhysicalDeviceCount, VkPhysicalDevice* pPhysicalDevices)
  {
    auto &dispatch_table = *GetInstanceDispatchTable(instance);
    VkResult result = VkResult::VK_SUCCESS; 
  
    if (dispatch_table.EnumeratePhysicalDevices) {
      result = dispatch_table.EnumeratePhysicalDevices(instance, pPhysicalDeviceCount, pPhysicalDevices);
    }
    return result; 
  }
  
  VKAPI_ATTR VkResult VKAPI_CALL CreatePipelineLayout(VkDevice device, VkPipelineLayoutCreateInfo const* pCreateInfo, AllocationCallbacks pAllocator, VkPipelineLayout* pPipelineLayout)
  {
    auto &dispatch_table = *GetDeviceDispatchTable(device);
    VkResult result = VkResult::VK_SUCCESS; 
  
    if (dispatch_table.CreatePipelineLayout) {
      result = dispatch_table.CreatePipelineLayout(device, pCreateInfo, pAllocator, pPipelineLayout);
    }
    return result; 
  }
  
  VKAPI_ATTR void VKAPI_CALL DestroyPipelineLayout(VkDevice device, VkPipelineLayout pipelineLayout, AllocationCallbacks pAllocator)
  {
    auto &dispatch_table = *GetDeviceDispatchTable(device);
  
    if (dispatch_table.DestroyPipelineLayout) {
      dispatch_table.DestroyPipelineLayout(device, pipelineLayout, pAllocator);
    }
  }
  
  VKAPI_ATTR VkResult VKAPI_CALL CreateGraphicsPipelines(VkDevice device, VkPipelineCache pipelineCache, uint32_t createInfoCount, VkGraphicsPipelineCreateInfo const* pCreateInfos, AllocationCallbacks pAllocator, VkPipeline* pPipelines)
  {
    auto &dispatch_table = *GetDeviceDispatchTable(device);
    VkResult result = VkResult::VK_SUCCESS; 
  
    result = GetInterceptor()->PreCreateGraphicsPipelines(device, pipelineCache, createInfoCount, pCreateInfos, pAllocator, pPipelines);
  
    if (dispatch_table.CreateGraphicsPipelines) {
      result = dispatch_table.CreateGraphicsPipelines(device, pipelineCache, createInfoCount, pCreateInfos, pAllocator, pPipelines);
    }
  
    GetInterceptor()->PostCreateGraphicsPipelines(device, pipelineCache, createInfoCount, pCreateInfos, pAllocator, pPipelines, result);
    return result; 
  }
  
  VKAPI_ATTR VkResult VKAPI_CALL CreateComputePipelines(VkDevice device, VkPipelineCache pipelineCache, uint32_t createInfoCount, VkComputePipelineCreateInfo const* pCreateInfos, AllocationCallbacks pAllocator, VkPipeline* pPipelines)
  {
    auto &dispatch_table = *GetDeviceDispatchTable(device);
    VkResult result = VkResult::VK_SUCCESS; 
  
    result = GetInterceptor()->PreCreateComputePipelines(device, pipelineCache, createInfoCount, pCreateInfos, pAllocator, pPipelines);
  
    if (dispatch_table.CreateComputePipelines) {
      result = dispatch_table.CreateComputePipelines(device, pipelineCache, createInfoCount, pCreateInfos, pAllocator, pPipelines);
    }
  
    GetInterceptor()->PostCreateComputePipelines(device, pipelineCache, createInfoCount, pCreateInfos, pAllocator, pPipelines, result);
    return result; 
  }
  
  VKAPI_ATTR void VKAPI_CALL DestroyPipeline(VkDevice device, VkPipeline pipeline, AllocationCallbacks pAllocator)
  {
    auto &dispatch_table = *GetDeviceDispatchTable(device);
  
    GetInterceptor()->PreDestroyPipeline(device, pipeline, pAllocator);
  
    if (dispatch_table.DestroyPipeline) {
      dispatch_table.DestroyPipeline(device, pipeline, pAllocator);
    }
  
    GetInterceptor()->PostDestroyPipeline(device, pipeline, pAllocator);
  }
  
  VKAPI_ATTR VkResult VKAPI_CALL CreateShaderModule(VkDevice device, VkShaderModuleCreateInfo const* pCreateInfo, AllocationCallbacks pAllocator, VkShaderModule* pShaderModule)
  {
    auto &dispatch_table = *GetDeviceDispatchTable(device);
    VkResult result = VkResult::VK_SUCCESS; 
  
    result = GetInterceptor()->PreCreateShaderModule(device, pCreateInfo, pAllocator, pShaderModule);
  
    if (dispatch_table.CreateShaderModule) {
      result = dispatch_table.CreateShaderModule(device, pCreateInfo, pAllocator, pShaderModule);
    }
  
    GetInterceptor()->PostCreateShaderModule(device, pCreateInfo, pAllocator, pShaderModule, result);
    return result; 
  }
  
  VKAPI_ATTR void VKAPI_CALL DestroyShaderModule(VkDevice device, VkShaderModule shaderModule, AllocationCallbacks pAllocator)
  {
    auto &dispatch_table = *GetDeviceDispatchTable(device);
  
    GetInterceptor()->PreDestroyShaderModule(device, shaderModule, pAllocator);
  
    if (dispatch_table.DestroyShaderModule) {
      dispatch_table.DestroyShaderModule(device, shaderModule, pAllocator);
    }
  
    GetInterceptor()->PostDestroyShaderModule(device, shaderModule, pAllocator);
  }
  
  VKAPI_ATTR VkResult VKAPI_CALL CreatePipelineCache(VkDevice device, VkPipelineCacheCreateInfo const* pCreateInfo, AllocationCallbacks pAllocator, VkPipelineCache* pPipelineCache)
  {
    auto &dispatch_table = *GetDeviceDispatchTable(device);
    VkResult result = VkResult::VK_SUCCESS; 
  
    if (dispatch_table.CreatePipelineCache) {
      result = dispatch_table.CreatePipelineCache(device, pCreateInfo, pAllocator, pPipelineCache);
    }
    return result; 
  }
  
  VKAPI_ATTR void VKAPI_CALL DestroyPipelineCache(VkDevice device, VkPipelineCache pipelineCache, AllocationCallbacks pAllocator)
  {
    auto &dispatch_table = *GetDeviceDispatchTable(device);
  
    if (dispatch_table.DestroyPipelineCache) {
      dispatch_table.DestroyPipelineCache(device, pipelineCache, pAllocator);
    }
  }
  
  VKAPI_ATTR VkResult VKAPI_CALL GetPipelineCacheData(VkDevice device, VkPipelineCache pipelineCache, size_val* pDataSize, void* pData)
  {
    auto &dispatch_table = *GetDeviceDispatchTable(device);
    VkResult result = VkResult::VK_SUCCESS; 
  
    if (dispatch_table.GetPipelineCacheData) {
      result = dispatch_table.GetPipelineCacheData(device, pipelineCache, pDataSize, pData);
    }
    return result; 
  }
  
  VKAPI_ATTR VkResult VKAPI_CALL MergePipelineCaches(VkDevice device, VkPipelineCache dstCache, uint32_t srcCacheCount, VkPipelineCache const* pSrcCaches)
  {
    auto &dispatch_table = *GetDeviceDispatchTable(device);
    VkResult result = VkResult::VK_SUCCESS; 
  
    if (dispatch_table.MergePipelineCaches) {
      result = dispatch_table.MergePipelineCaches(device, dstCache, srcCacheCount, pSrcCaches);
    }
    return result; 
  }
  
  VKAPI_ATTR void VKAPI_CALL CmdBindPipeline(VkCommandBuffer commandBuffer, VkPipelineBindPoint pipelineBindPoint, VkPipeline pipeline)
  {
    auto &dispatch_table = *GetDeviceDispatchTable(commandBuffer);
    WrappedVkCommandBuffer *wrappedcommandBuffer = reinterpret_cast<WrappedVkCommandBuffer *>(commandBuffer);
    VkCommandBuffer unwrappedcommandBuffer = wrappedcommandBuffer->wrapped_object;
  
    GetInterceptor()->PreCmdBindPipeline(wrappedcommandBuffer, pipelineBindPoint, pipeline);
  
    if (dispatch_table.CmdBindPipeline) {
      dispatch_table.CmdBindPipeline(unwrappedcommandBuffer, pipelineBindPoint, pipeline);
    }
  
    GetInterceptor()->PostCmdBindPipeline(wrappedcommandBuffer, pipelineBindPoint, pipeline);
  }
  
  VKAPI_ATTR void VKAPI_CALL CmdSetViewport(VkCommandBuffer commandBuffer, uint32_t firstViewport, uint32_t viewportCount, VkViewport const* pViewports)
  {
    auto &dispatch_table = *GetDeviceDispatchTable(commandBuffer);
    WrappedVkCommandBuffer *wrappedcommandBuffer = reinterpret_cast<WrappedVkCommandBuffer *>(commandBuffer);
    VkCommandBuffer unwrappedcommandBuffer = wrappedcommandBuffer->wrapped_object;
  
    GetInterceptor()->PreCmdSetViewport(wrappedcommandBuffer, firstViewport, viewportCount, pViewports);
  
    if (dispatch_table.CmdSetViewport) {
      dispatch_table.CmdSetViewport(unwrappedcommandBuffer, firstViewport, viewportCount, pViewports);
    }
  
    GetInterceptor()->PostCmdSetViewport(wrappedcommandBuffer, firstViewport, viewportCount, pViewports);
  }
  
  VKAPI_ATTR void VKAPI_CALL CmdSetScissor(VkCommandBuffer commandBuffer, uint32_t firstScissor, uint32_t scissorCount, VkRect2D const* pScissors)
  {
    auto &dispatch_table = *GetDeviceDispatchTable(commandBuffer);
    WrappedVkCommandBuffer *wrappedcommandBuffer = reinterpret_cast<WrappedVkCommandBuffer *>(commandBuffer);
    VkCommandBuffer unwrappedcommandBuffer = wrappedcommandBuffer->wrapped_object;
  
    GetInterceptor()->PreCmdSetScissor(wrappedcommandBuffer, firstScissor, scissorCount, pScissors);
  
    if (dispatch_table.CmdSetScissor) {
      dispatch_table.CmdSetScissor(unwrappedcommandBuffer, firstScissor, scissorCount, pScissors);
    }
  
    GetInterceptor()->PostCmdSetScissor(wrappedcommandBuffer, firstScissor, scissorCount, pScissors);
  }
  
  VKAPI_ATTR void VKAPI_CALL CmdSetLineWidth(VkCommandBuffer commandBuffer, float lineWidth)
  {
    auto &dispatch_table = *GetDeviceDispatchTable(commandBuffer);
    WrappedVkCommandBuffer *wrappedcommandBuffer = reinterpret_cast<WrappedVkCommandBuffer *>(commandBuffer);
    VkCommandBuffer unwrappedcommandBuffer = wrappedcommandBuffer->wrapped_object;
  
    GetInterceptor()->PreCmdSetLineWidth(wrappedcommandBuffer, lineWidth);
  
    if (dispatch_table.CmdSetLineWidth) {
      dispatch_table.CmdSetLineWidth(unwrappedcommandBuffer, lineWidth);
    }
  
    GetInterceptor()->PostCmdSetLineWidth(wrappedcommandBuffer, lineWidth);
  }
  
  VKAPI_ATTR void VKAPI_CALL CmdSetDepthBias(VkCommandBuffer commandBuffer, float depthBiasConstantFactor, float depthBiasClamp, float depthBiasSlopeFactor)
  {
    auto &dispatch_table = *GetDeviceDispatchTable(commandBuffer);
    WrappedVkCommandBuffer *wrappedcommandBuffer = reinterpret_cast<WrappedVkCommandBuffer *>(commandBuffer);
    VkCommandBuffer unwrappedcommandBuffer = wrappedcommandBuffer->wrapped_object;
  
    GetInterceptor()->PreCmdSetDepthBias(wrappedcommandBuffer, depthBiasConstantFactor, depthBiasClamp, depthBiasSlopeFactor);
  
    if (dispatch_table.CmdSetDepthBias) {
      dispatch_table.CmdSetDepthBias(unwrappedcommandBuffer, depthBiasConstantFactor, depthBiasClamp, depthBiasSlopeFactor);
    }
  
    GetInterceptor()->PostCmdSetDepthBias(wrappedcommandBuffer, depthBiasConstantFactor, depthBiasClamp, depthBiasSlopeFactor);
  }
  
  VKAPI_ATTR void VKAPI_CALL CmdSetBlendConstants(VkCommandBuffer commandBuffer, float blendConstants[4])
  {
    auto &dispatch_table = *GetDeviceDispatchTable(commandBuffer);
    WrappedVkCommandBuffer *wrappedcommandBuffer = reinterpret_cast<WrappedVkCommandBuffer *>(commandBuffer);
    VkCommandBuffer unwrappedcommandBuffer = wrappedcommandBuffer->wrapped_object;
  
    GetInterceptor()->PreCmdSetBlendConstants(wrappedcommandBuffer, blendConstants);
  
    if (dispatch_table.CmdSetBlendConstants) {
      dispatch_table.CmdSetBlendConstants(unwrappedcommandBuffer, blendConstants);
    }
  
    GetInterceptor()->PostCmdSetBlendConstants(wrappedcommandBuffer, blendConstants);
  }
  
  VKAPI_ATTR void VKAPI_CALL CmdSetDepthBounds(VkCommandBuffer commandBuffer, float minDepthBounds, float maxDepthBounds)
  {
    auto &dispatch_table = *GetDeviceDispatchTable(commandBuffer);
    WrappedVkCommandBuffer *wrappedcommandBuffer = reinterpret_cast<WrappedVkCommandBuffer *>(commandBuffer);
    VkCommandBuffer unwrappedcommandBuffer = wrappedcommandBuffer->wrapped_object;
  
    GetInterceptor()->PreCmdSetDepthBounds(wrappedcommandBuffer, minDepthBounds, maxDepthBounds);
  
    if (dispatch_table.CmdSetDepthBounds) {
      dispatch_table.CmdSetDepthBounds(unwrappedcommandBuffer, minDepthBounds, maxDepthBounds);
    }
  
    GetInterceptor()->PostCmdSetDepthBounds(wrappedcommandBuffer, minDepthBounds, maxDepthBounds);
  }
  
  VKAPI_ATTR void VKAPI_CALL CmdSetStencilCompareMask(VkCommandBuffer commandBuffer, VkStencilFaceFlags faceMask, uint32_t compareMask)
  {
    auto &dispatch_table = *GetDeviceDispatchTable(commandBuffer);
    WrappedVkCommandBuffer *wrappedcommandBuffer = reinterpret_cast<WrappedVkCommandBuffer *>(commandBuffer);
    VkCommandBuffer unwrappedcommandBuffer = wrappedcommandBuffer->wrapped_object;
  
    GetInterceptor()->PreCmdSetStencilCompareMask(wrappedcommandBuffer, faceMask, compareMask);
  
    if (dispatch_table.CmdSetStencilCompareMask) {
      dispatch_table.CmdSetStencilCompareMask(unwrappedcommandBuffer, faceMask, compareMask);
    }
  
    GetInterceptor()->PostCmdSetStencilCompareMask(wrappedcommandBuffer, faceMask, compareMask);
  }
  
  VKAPI_ATTR void VKAPI_CALL CmdSetStencilWriteMask(VkCommandBuffer commandBuffer, VkStencilFaceFlags faceMask, uint32_t writeMask)
  {
    auto &dispatch_table = *GetDeviceDispatchTable(commandBuffer);
    WrappedVkCommandBuffer *wrappedcommandBuffer = reinterpret_cast<WrappedVkCommandBuffer *>(commandBuffer);
    VkCommandBuffer unwrappedcommandBuffer = wrappedcommandBuffer->wrapped_object;
  
    GetInterceptor()->PreCmdSetStencilWriteMask(wrappedcommandBuffer, faceMask, writeMask);
  
    if (dispatch_table.CmdSetStencilWriteMask) {
      dispatch_table.CmdSetStencilWriteMask(unwrappedcommandBuffer, faceMask, writeMask);
    }
  
    GetInterceptor()->PostCmdSetStencilWriteMask(wrappedcommandBuffer, faceMask, writeMask);
  }
  
  VKAPI_ATTR void VKAPI_CALL CmdSetStencilReference(VkCommandBuffer commandBuffer, VkStencilFaceFlags faceMask, uint32_t reference)
  {
    auto &dispatch_table = *GetDeviceDispatchTable(commandBuffer);
    WrappedVkCommandBuffer *wrappedcommandBuffer = reinterpret_cast<WrappedVkCommandBuffer *>(commandBuffer);
    VkCommandBuffer unwrappedcommandBuffer = wrappedcommandBuffer->wrapped_object;
  
    GetInterceptor()->PreCmdSetStencilReference(wrappedcommandBuffer, faceMask, reference);
  
    if (dispatch_table.CmdSetStencilReference) {
      dispatch_table.CmdSetStencilReference(unwrappedcommandBuffer, faceMask, reference);
    }
  
    GetInterceptor()->PostCmdSetStencilReference(wrappedcommandBuffer, faceMask, reference);
  }
  
  VKAPI_ATTR void VKAPI_CALL GetPhysicalDeviceFeatures(VkPhysicalDevice physicalDevice, VkPhysicalDeviceFeatures* pFeatures)
  {
    auto &dispatch_table = *GetInstanceDispatchTable(physicalDevice);
  
    if (dispatch_table.GetPhysicalDeviceFeatures) {
      dispatch_table.GetPhysicalDeviceFeatures(physicalDevice, pFeatures);
    }
  }
  
  VKAPI_ATTR void VKAPI_CALL GetPhysicalDeviceFormatProperties(VkPhysicalDevice physicalDevice, VkFormat format, VkFormatProperties* pFormatProperties)
  {
    auto &dispatch_table = *GetInstanceDispatchTable(physicalDevice);
  
    if (dispatch_table.GetPhysicalDeviceFormatProperties) {
      dispatch_table.GetPhysicalDeviceFormatProperties(physicalDevice, format, pFormatProperties);
    }
  }
  
  VKAPI_ATTR VkResult VKAPI_CALL GetPhysicalDeviceImageFormatProperties(VkPhysicalDevice physicalDevice, VkFormat format, VkImageType type, VkImageTiling tiling, VkImageUsageFlags usage, VkImageCreateFlags flags, VkImageFormatProperties* pImageFormatProperties)
  {
    auto &dispatch_table = *GetInstanceDispatchTable(physicalDevice);
    VkResult result = VkResult::VK_SUCCESS; 
  
    if (dispatch_table.GetPhysicalDeviceImageFormatProperties) {
      result = dispatch_table.GetPhysicalDeviceImageFormatProperties(physicalDevice, format, type, tiling, usage, flags, pImageFormatProperties);
    }
    return result; 
  }
  
  VKAPI_ATTR void VKAPI_CALL GetPhysicalDeviceProperties(VkPhysicalDevice physicalDevice, VkPhysicalDeviceProperties* pProperties)
  {
    auto &dispatch_table = *GetInstanceDispatchTable(physicalDevice);
  
    if (dispatch_table.GetPhysicalDeviceProperties) {
      dispatch_table.GetPhysicalDeviceProperties(physicalDevice, pProperties);
    }
  }
  
  VKAPI_ATTR void VKAPI_CALL GetPhysicalDeviceQueueFamilyProperties(VkPhysicalDevice physicalDevice, uint32_t* pQueueFamilyPropertyCount, VkQueueFamilyProperties* pQueueFamilyProperties)
  {
    auto &dispatch_table = *GetInstanceDispatchTable(physicalDevice);
  
    if (dispatch_table.GetPhysicalDeviceQueueFamilyProperties) {
      dispatch_table.GetPhysicalDeviceQueueFamilyProperties(physicalDevice, pQueueFamilyPropertyCount, pQueueFamilyProperties);
    }
  }
  
  VKAPI_ATTR void VKAPI_CALL GetPhysicalDeviceMemoryProperties(VkPhysicalDevice physicalDevice, VkPhysicalDeviceMemoryProperties* pMemoryProperties)
  {
    auto &dispatch_table = *GetInstanceDispatchTable(physicalDevice);
  
    if (dispatch_table.GetPhysicalDeviceMemoryProperties) {
      dispatch_table.GetPhysicalDeviceMemoryProperties(physicalDevice, pMemoryProperties);
    }
  }
  
  VKAPI_ATTR void VKAPI_CALL GetPhysicalDeviceSparseImageFormatProperties(VkPhysicalDevice physicalDevice, VkFormat format, VkImageType type, VkSampleCountFlagBits samples, VkImageUsageFlags usage, VkImageTiling tiling, uint32_t* pPropertyCount, VkSparseImageFormatProperties* pProperties)
  {
    auto &dispatch_table = *GetInstanceDispatchTable(physicalDevice);
  
    if (dispatch_table.GetPhysicalDeviceSparseImageFormatProperties) {
      dispatch_table.GetPhysicalDeviceSparseImageFormatProperties(physicalDevice, format, type, samples, usage, tiling, pPropertyCount, pProperties);
    }
  }
  
  VKAPI_ATTR void VKAPI_CALL GetBufferMemoryRequirements(VkDevice device, VkBuffer buffer, VkMemoryRequirements* pMemoryRequirements)
  {
    auto &dispatch_table = *GetDeviceDispatchTable(device);
  
    if (dispatch_table.GetBufferMemoryRequirements) {
      dispatch_table.GetBufferMemoryRequirements(device, buffer, pMemoryRequirements);
    }
  }
  
  VKAPI_ATTR void VKAPI_CALL GetImageMemoryRequirements(VkDevice device, VkImage image, VkMemoryRequirements* pMemoryRequirements)
  {
    auto &dispatch_table = *GetDeviceDispatchTable(device);
  
    if (dispatch_table.GetImageMemoryRequirements) {
      dispatch_table.GetImageMemoryRequirements(device, image, pMemoryRequirements);
    }
  }
  
  VKAPI_ATTR void VKAPI_CALL GetImageSparseMemoryRequirements(VkDevice device, VkImage image, uint32_t* pSparseMemoryRequirementCount, VkSparseImageMemoryRequirements* pSparseMemoryRequirements)
  {
    auto &dispatch_table = *GetDeviceDispatchTable(device);
  
    if (dispatch_table.GetImageSparseMemoryRequirements) {
      dispatch_table.GetImageSparseMemoryRequirements(device, image, pSparseMemoryRequirementCount, pSparseMemoryRequirements);
    }
  }
  
  VKAPI_ATTR VkResult VKAPI_CALL EnumerateInstanceVersion(uint32_t* pApiVersion)
  {
    auto &dispatch_table = *GetInstanceDispatchTable(pApiVersion);
    VkResult result = VkResult::VK_SUCCESS; 
  
    if (dispatch_table.EnumerateInstanceVersion) {
      result = dispatch_table.EnumerateInstanceVersion(pApiVersion);
    }
    return result; 
  }
  
  VKAPI_ATTR void VKAPI_CALL GetPhysicalDeviceFeatures2(VkPhysicalDevice physicalDevice, VkPhysicalDeviceFeatures2* pFeatures)
  {
    auto &dispatch_table = *GetInstanceDispatchTable(physicalDevice);
  
    if (dispatch_table.GetPhysicalDeviceFeatures2) {
      dispatch_table.GetPhysicalDeviceFeatures2(physicalDevice, pFeatures);
    }
  }
  
  VKAPI_ATTR void VKAPI_CALL GetPhysicalDeviceFormatProperties2(VkPhysicalDevice physicalDevice, VkFormat format, VkFormatProperties2* pFormatProperties)
  {
    auto &dispatch_table = *GetInstanceDispatchTable(physicalDevice);
  
    if (dispatch_table.GetPhysicalDeviceFormatProperties2) {
      dispatch_table.GetPhysicalDeviceFormatProperties2(physicalDevice, format, pFormatProperties);
    }
  }
  
  VKAPI_ATTR VkResult VKAPI_CALL GetPhysicalDeviceImageFormatProperties2(VkPhysicalDevice physicalDevice, VkPhysicalDeviceImageFormatInfo2 const* pImageFormatInfo, VkImageFormatProperties2* pImageFormatProperties)
  {
    auto &dispatch_table = *GetInstanceDispatchTable(physicalDevice);
    VkResult result = VkResult::VK_SUCCESS; 
  
    if (dispatch_table.GetPhysicalDeviceImageFormatProperties2) {
      result = dispatch_table.GetPhysicalDeviceImageFormatProperties2(physicalDevice, pImageFormatInfo, pImageFormatProperties);
    }
    return result; 
  }
  
  VKAPI_ATTR void VKAPI_CALL GetPhysicalDeviceProperties2(VkPhysicalDevice physicalDevice, VkPhysicalDeviceProperties2* pProperties)
  {
    auto &dispatch_table = *GetInstanceDispatchTable(physicalDevice);
  
    if (dispatch_table.GetPhysicalDeviceProperties2) {
      dispatch_table.GetPhysicalDeviceProperties2(physicalDevice, pProperties);
    }
  }
  
  VKAPI_ATTR void VKAPI_CALL GetPhysicalDeviceMemoryProperties2(VkPhysicalDevice physicalDevice, VkPhysicalDeviceMemoryProperties2* pMemoryProperties)
  {
    auto &dispatch_table = *GetInstanceDispatchTable(physicalDevice);
  
    if (dispatch_table.GetPhysicalDeviceMemoryProperties2) {
      dispatch_table.GetPhysicalDeviceMemoryProperties2(physicalDevice, pMemoryProperties);
    }
  }
  
  VKAPI_ATTR void VKAPI_CALL GetPhysicalDeviceSparseImageFormatProperties2(VkPhysicalDevice physicalDevice, VkPhysicalDeviceSparseImageFormatInfo2 const* pFormatInfo, uint32_t* pPropertyCount, VkSparseImageFormatProperties2* pProperties)
  {
    auto &dispatch_table = *GetInstanceDispatchTable(physicalDevice);
  
    if (dispatch_table.GetPhysicalDeviceSparseImageFormatProperties2) {
      dispatch_table.GetPhysicalDeviceSparseImageFormatProperties2(physicalDevice, pFormatInfo, pPropertyCount, pProperties);
    }
  }
  
  VKAPI_ATTR void VKAPI_CALL GetPhysicalDeviceQueueFamilyProperties2(VkPhysicalDevice physicalDevice, uint32_t* pQueueFamilyPropertyCount, VkQueueFamilyProperties2* pQueueFamilyProperties)
  {
    auto &dispatch_table = *GetInstanceDispatchTable(physicalDevice);
  
    if (dispatch_table.GetPhysicalDeviceQueueFamilyProperties2) {
      dispatch_table.GetPhysicalDeviceQueueFamilyProperties2(physicalDevice, pQueueFamilyPropertyCount, pQueueFamilyProperties);
    }
  }
  
  VKAPI_ATTR void VKAPI_CALL GetPhysicalDeviceExternalBufferProperties(VkPhysicalDevice physicalDevice, VkPhysicalDeviceExternalBufferInfo const* pExternalBufferInfo, VkExternalBufferProperties* pExternalBufferProperties)
  {
    auto &dispatch_table = *GetInstanceDispatchTable(physicalDevice);
  
    if (dispatch_table.GetPhysicalDeviceExternalBufferProperties) {
      dispatch_table.GetPhysicalDeviceExternalBufferProperties(physicalDevice, pExternalBufferInfo, pExternalBufferProperties);
    }
  }
  
  VKAPI_ATTR void VKAPI_CALL GetPhysicalDeviceExternalSemaphoreProperties(VkPhysicalDevice physicalDevice, VkPhysicalDeviceExternalSemaphoreInfo const* pExternalSemaphoreInfo, VkExternalSemaphoreProperties* pExternalSemaphoreProperties)
  {
    auto &dispatch_table = *GetInstanceDispatchTable(physicalDevice);
  
    if (dispatch_table.GetPhysicalDeviceExternalSemaphoreProperties) {
      dispatch_table.GetPhysicalDeviceExternalSemaphoreProperties(physicalDevice, pExternalSemaphoreInfo, pExternalSemaphoreProperties);
    }
  }
  
  VKAPI_ATTR void VKAPI_CALL GetPhysicalDeviceExternalFenceProperties(VkPhysicalDevice physicalDevice, VkPhysicalDeviceExternalFenceInfo const* pExternalFenceInfo, VkExternalFenceProperties* pExternalFenceProperties)
  {
    auto &dispatch_table = *GetInstanceDispatchTable(physicalDevice);
  
    if (dispatch_table.GetPhysicalDeviceExternalFenceProperties) {
      dispatch_table.GetPhysicalDeviceExternalFenceProperties(physicalDevice, pExternalFenceInfo, pExternalFenceProperties);
    }
  }
  
  VKAPI_ATTR void VKAPI_CALL GetBufferMemoryRequirements2(VkDevice device, VkBufferMemoryRequirementsInfo2 const* pInfo, VkMemoryRequirements2* pMemoryRequirements)
  {
    auto &dispatch_table = *GetDeviceDispatchTable(device);
  
    if (dispatch_table.GetBufferMemoryRequirements2) {
      dispatch_table.GetBufferMemoryRequirements2(device, pInfo, pMemoryRequirements);
    }
  }
  
  VKAPI_ATTR void VKAPI_CALL GetImageMemoryRequirements2(VkDevice device, VkImageMemoryRequirementsInfo2 const* pInfo, VkMemoryRequirements2* pMemoryRequirements)
  {
    auto &dispatch_table = *GetDeviceDispatchTable(device);
  
    if (dispatch_table.GetImageMemoryRequirements2) {
      dispatch_table.GetImageMemoryRequirements2(device, pInfo, pMemoryRequirements);
    }
  }
  
  VKAPI_ATTR void VKAPI_CALL GetImageSparseMemoryRequirements2(VkDevice device, VkImageSparseMemoryRequirementsInfo2 const* pInfo, uint32_t* pSparseMemoryRequirementCount, VkSparseImageMemoryRequirements2* pSparseMemoryRequirements)
  {
    auto &dispatch_table = *GetDeviceDispatchTable(device);
  
    if (dispatch_table.GetImageSparseMemoryRequirements2) {
      dispatch_table.GetImageSparseMemoryRequirements2(device, pInfo, pSparseMemoryRequirementCount, pSparseMemoryRequirements);
    }
  }
  
  VKAPI_ATTR VkResult VKAPI_CALL CreateQueryPool(VkDevice device, VkQueryPoolCreateInfo const* pCreateInfo, AllocationCallbacks pAllocator, VkQueryPool* pQueryPool)
  {
    auto &dispatch_table = *GetDeviceDispatchTable(device);
    VkResult result = VkResult::VK_SUCCESS; 
  
    if (dispatch_table.CreateQueryPool) {
      result = dispatch_table.CreateQueryPool(device, pCreateInfo, pAllocator, pQueryPool);
    }
    return result; 
  }
  
  VKAPI_ATTR void VKAPI_CALL DestroyQueryPool(VkDevice device, VkQueryPool queryPool, AllocationCallbacks pAllocator)
  {
    auto &dispatch_table = *GetDeviceDispatchTable(device);
  
    if (dispatch_table.DestroyQueryPool) {
      dispatch_table.DestroyQueryPool(device, queryPool, pAllocator);
    }
  }
  
  VKAPI_ATTR VkResult VKAPI_CALL GetQueryPoolResults(VkDevice device, VkQueryPool queryPool, uint32_t firstQuery, uint32_t queryCount, size_val dataSize, void* pData, VkDeviceSize stride, VkQueryResultFlags flags)
  {
    auto &dispatch_table = *GetDeviceDispatchTable(device);
    VkResult result = VkResult::VK_SUCCESS; 
  
    if (dispatch_table.GetQueryPoolResults) {
      result = dispatch_table.GetQueryPoolResults(device, queryPool, firstQuery, queryCount, dataSize, pData, stride, flags);
    }
  
    GetInterceptor()->PostGetQueryPoolResults(device, queryPool, firstQuery, queryCount, dataSize, pData, stride, flags, result);
    return result; 
  }
  
  VKAPI_ATTR void VKAPI_CALL CmdBeginQuery(VkCommandBuffer commandBuffer, VkQueryPool queryPool, uint32_t query, VkQueryControlFlags flags)
  {
    auto &dispatch_table = *GetDeviceDispatchTable(commandBuffer);
    WrappedVkCommandBuffer *wrappedcommandBuffer = reinterpret_cast<WrappedVkCommandBuffer *>(commandBuffer);
    VkCommandBuffer unwrappedcommandBuffer = wrappedcommandBuffer->wrapped_object;
  
    GetInterceptor()->PreCmdBeginQuery(wrappedcommandBuffer, queryPool, query, flags);
  
    if (dispatch_table.CmdBeginQuery) {
      dispatch_table.CmdBeginQuery(unwrappedcommandBuffer, queryPool, query, flags);
    }
  
    GetInterceptor()->PostCmdBeginQuery(wrappedcommandBuffer, queryPool, query, flags);
  }
  
  VKAPI_ATTR void VKAPI_CALL CmdEndQuery(VkCommandBuffer commandBuffer, VkQueryPool queryPool, uint32_t query)
  {
    auto &dispatch_table = *GetDeviceDispatchTable(commandBuffer);
    WrappedVkCommandBuffer *wrappedcommandBuffer = reinterpret_cast<WrappedVkCommandBuffer *>(commandBuffer);
    VkCommandBuffer unwrappedcommandBuffer = wrappedcommandBuffer->wrapped_object;
  
    GetInterceptor()->PreCmdEndQuery(wrappedcommandBuffer, queryPool, query);
  
    if (dispatch_table.CmdEndQuery) {
      dispatch_table.CmdEndQuery(unwrappedcommandBuffer, queryPool, query);
    }
  
    GetInterceptor()->PostCmdEndQuery(wrappedcommandBuffer, queryPool, query);
  }
  
  VKAPI_ATTR void VKAPI_CALL CmdResetQueryPool(VkCommandBuffer commandBuffer, VkQueryPool queryPool, uint32_t firstQuery, uint32_t queryCount)
  {
    auto &dispatch_table = *GetDeviceDispatchTable(commandBuffer);
    WrappedVkCommandBuffer *wrappedcommandBuffer = reinterpret_cast<WrappedVkCommandBuffer *>(commandBuffer);
    VkCommandBuffer unwrappedcommandBuffer = wrappedcommandBuffer->wrapped_object;
  
    GetInterceptor()->PreCmdResetQueryPool(wrappedcommandBuffer, queryPool, firstQuery, queryCount);
  
    if (dispatch_table.CmdResetQueryPool) {
      dispatch_table.CmdResetQueryPool(unwrappedcommandBuffer, queryPool, firstQuery, queryCount);
    }
  
    GetInterceptor()->PostCmdResetQueryPool(wrappedcommandBuffer, queryPool, firstQuery, queryCount);
  }
  
  VKAPI_ATTR void VKAPI_CALL CmdWriteTimestamp(VkCommandBuffer commandBuffer, VkPipelineStageFlagBits pipelineStage, VkQueryPool queryPool, uint32_t query)
  {
    auto &dispatch_table = *GetDeviceDispatchTable(commandBuffer);
    WrappedVkCommandBuffer *wrappedcommandBuffer = reinterpret_cast<WrappedVkCommandBuffer *>(commandBuffer);
    VkCommandBuffer unwrappedcommandBuffer = wrappedcommandBuffer->wrapped_object;
  
    GetInterceptor()->PreCmdWriteTimestamp(wrappedcommandBuffer, pipelineStage, queryPool, query);
  
    if (dispatch_table.CmdWriteTimestamp) {
      dispatch_table.CmdWriteTimestamp(unwrappedcommandBuffer, pipelineStage, queryPool, query);
    }
  
    GetInterceptor()->PostCmdWriteTimestamp(wrappedcommandBuffer, pipelineStage, queryPool, query);
  }
  
  VKAPI_ATTR void VKAPI_CALL CmdCopyQueryPoolResults(VkCommandBuffer commandBuffer, VkQueryPool queryPool, uint32_t firstQuery, uint32_t queryCount, VkBuffer dstBuffer, VkDeviceSize dstOffset, VkDeviceSize stride, VkQueryResultFlags flags)
  {
    auto &dispatch_table = *GetDeviceDispatchTable(commandBuffer);
    WrappedVkCommandBuffer *wrappedcommandBuffer = reinterpret_cast<WrappedVkCommandBuffer *>(commandBuffer);
    VkCommandBuffer unwrappedcommandBuffer = wrappedcommandBuffer->wrapped_object;
  
    GetInterceptor()->PreCmdCopyQueryPoolResults(wrappedcommandBuffer, queryPool, firstQuery, queryCount, dstBuffer, dstOffset, stride, flags);
  
    if (dispatch_table.CmdCopyQueryPoolResults) {
      dispatch_table.CmdCopyQueryPoolResults(unwrappedcommandBuffer, queryPool, firstQuery, queryCount, dstBuffer, dstOffset, stride, flags);
    }
  
    GetInterceptor()->PostCmdCopyQueryPoolResults(wrappedcommandBuffer, queryPool, firstQuery, queryCount, dstBuffer, dstOffset, stride, flags);
  }
  
  VKAPI_ATTR void VKAPI_CALL GetDeviceQueue(VkDevice device, uint32_t queueFamilyIndex, uint32_t queueIndex, VkQueue* pQueue)
  {
    auto &dispatch_table = *GetDeviceDispatchTable(device);
  
    if (dispatch_table.GetDeviceQueue) {
      dispatch_table.GetDeviceQueue(device, queueFamilyIndex, queueIndex, pQueue);
    }
  
    GetInterceptor()->PostGetDeviceQueue(device, queueFamilyIndex, queueIndex, pQueue);
  }
  
  VKAPI_ATTR void VKAPI_CALL GetDeviceQueue2(VkDevice device, VkDeviceQueueInfo2 const* pQueueInfo, VkQueue* pQueue)
  {
    auto &dispatch_table = *GetDeviceDispatchTable(device);
  
    if (dispatch_table.GetDeviceQueue2) {
      dispatch_table.GetDeviceQueue2(device, pQueueInfo, pQueue);
    }
  }
  VKAPI_ATTR VkResult VKAPI_CALL QueueSubmit(VkQueue queue, uint32_t submitCount, VkSubmitInfo const* pSubmits, VkFence fence);
  
  VKAPI_ATTR VkResult VKAPI_CALL QueueWaitIdle(VkQueue queue)
  {
    auto &dispatch_table = *GetDeviceDispatchTable(queue);
    VkResult result = VkResult::VK_SUCCESS; 
  
    if (dispatch_table.QueueWaitIdle) {
      result = dispatch_table.QueueWaitIdle(queue);
    }
  
    GetInterceptor()->PostQueueWaitIdle(queue, result);
    return result; 
  }
  VKAPI_ATTR VkResult VKAPI_CALL QueueBindSparse(VkQueue queue, uint32_t bindInfoCount, VkBindSparseInfo const* pBindInfo, VkFence fence);
  
  VKAPI_ATTR VkResult VKAPI_CALL CreateFramebuffer(VkDevice device, VkFramebufferCreateInfo const* pCreateInfo, AllocationCallbacks pAllocator, VkFramebuffer* pFramebuffer)
  {
    auto &dispatch_table = *GetDeviceDispatchTable(device);
    VkResult result = VkResult::VK_SUCCESS; 
  
    if (dispatch_table.CreateFramebuffer) {
      result = dispatch_table.CreateFramebuffer(device, pCreateInfo, pAllocator, pFramebuffer);
    }
    return result; 
  }
  
  VKAPI_ATTR void VKAPI_CALL DestroyFramebuffer(VkDevice device, VkFramebuffer framebuffer, AllocationCallbacks pAllocator)
  {
    auto &dispatch_table = *GetDeviceDispatchTable(device);
  
    if (dispatch_table.DestroyFramebuffer) {
      dispatch_table.DestroyFramebuffer(device, framebuffer, pAllocator);
    }
  }
  
  VKAPI_ATTR VkResult VKAPI_CALL CreateRenderPass(VkDevice device, VkRenderPassCreateInfo const* pCreateInfo, AllocationCallbacks pAllocator, VkRenderPass* pRenderPass)
  {
    auto &dispatch_table = *GetDeviceDispatchTable(device);
    VkResult result = VkResult::VK_SUCCESS; 
  
    if (dispatch_table.CreateRenderPass) {
      result = dispatch_table.CreateRenderPass(device, pCreateInfo, pAllocator, pRenderPass);
    }
    return result; 
  }
  
  VKAPI_ATTR void VKAPI_CALL DestroyRenderPass(VkDevice device, VkRenderPass renderPass, AllocationCallbacks pAllocator)
  {
    auto &dispatch_table = *GetDeviceDispatchTable(device);
  
    if (dispatch_table.DestroyRenderPass) {
      dispatch_table.DestroyRenderPass(device, renderPass, pAllocator);
    }
  }
  
  VKAPI_ATTR void VKAPI_CALL GetRenderAreaGranularity(VkDevice device, VkRenderPass renderPass, VkExtent2D* pGranularity)
  {
    auto &dispatch_table = *GetDeviceDispatchTable(device);
  
    if (dispatch_table.GetRenderAreaGranularity) {
      dispatch_table.GetRenderAreaGranularity(device, renderPass, pGranularity);
    }
  }
  
  VKAPI_ATTR void VKAPI_CALL CmdBeginRenderPass(VkCommandBuffer commandBuffer, VkRenderPassBeginInfo const* pRenderPassBegin, VkSubpassContents contents)
  {
    auto &dispatch_table = *GetDeviceDispatchTable(commandBuffer);
    WrappedVkCommandBuffer *wrappedcommandBuffer = reinterpret_cast<WrappedVkCommandBuffer *>(commandBuffer);
    VkCommandBuffer unwrappedcommandBuffer = wrappedcommandBuffer->wrapped_object;
  
    GetInterceptor()->PreCmdBeginRenderPass(wrappedcommandBuffer, pRenderPassBegin, contents);
  
    if (dispatch_table.CmdBeginRenderPass) {
      dispatch_table.CmdBeginRenderPass(unwrappedcommandBuffer, pRenderPassBegin, contents);
    }
  
    GetInterceptor()->PostCmdBeginRenderPass(wrappedcommandBuffer, pRenderPassBegin, contents);
  }
  
  VKAPI_ATTR void VKAPI_CALL CmdNextSubpass(VkCommandBuffer commandBuffer, VkSubpassContents contents)
  {
    auto &dispatch_table = *GetDeviceDispatchTable(commandBuffer);
    WrappedVkCommandBuffer *wrappedcommandBuffer = reinterpret_cast<WrappedVkCommandBuffer *>(commandBuffer);
    VkCommandBuffer unwrappedcommandBuffer = wrappedcommandBuffer->wrapped_object;
  
    GetInterceptor()->PreCmdNextSubpass(wrappedcommandBuffer, contents);
  
    if (dispatch_table.CmdNextSubpass) {
      dispatch_table.CmdNextSubpass(unwrappedcommandBuffer, contents);
    }
  
    GetInterceptor()->PostCmdNextSubpass(wrappedcommandBuffer, contents);
  }
  
  VKAPI_ATTR void VKAPI_CALL CmdEndRenderPass(VkCommandBuffer commandBuffer)
  {
    auto &dispatch_table = *GetDeviceDispatchTable(commandBuffer);
    WrappedVkCommandBuffer *wrappedcommandBuffer = reinterpret_cast<WrappedVkCommandBuffer *>(commandBuffer);
    VkCommandBuffer unwrappedcommandBuffer = wrappedcommandBuffer->wrapped_object;
  
    GetInterceptor()->PreCmdEndRenderPass(wrappedcommandBuffer);
  
    if (dispatch_table.CmdEndRenderPass) {
      dispatch_table.CmdEndRenderPass(unwrappedcommandBuffer);
    }
  
    GetInterceptor()->PostCmdEndRenderPass(wrappedcommandBuffer);
  }
  
  VKAPI_ATTR VkResult VKAPI_CALL CreateFence(VkDevice device, VkFenceCreateInfo const* pCreateInfo, AllocationCallbacks pAllocator, VkFence* pFence)
  {
    auto &dispatch_table = *GetDeviceDispatchTable(device);
    VkResult result = VkResult::VK_SUCCESS; 
  
    if (dispatch_table.CreateFence) {
      result = dispatch_table.CreateFence(device, pCreateInfo, pAllocator, pFence);
    }
    return result; 
  }
  
  VKAPI_ATTR void VKAPI_CALL DestroyFence(VkDevice device, VkFence fence, AllocationCallbacks pAllocator)
  {
    auto &dispatch_table = *GetDeviceDispatchTable(device);
  
    if (dispatch_table.DestroyFence) {
      dispatch_table.DestroyFence(device, fence, pAllocator);
    }
  }
  
  VKAPI_ATTR VkResult VKAPI_CALL ResetFences(VkDevice device, uint32_t fenceCount, VkFence const* pFences)
  {
    auto &dispatch_table = *GetDeviceDispatchTable(device);
    VkResult result = VkResult::VK_SUCCESS; 
  
    if (dispatch_table.ResetFences) {
      result = dispatch_table.ResetFences(device, fenceCount, pFences);
    }
    return result; 
  }
  
  VKAPI_ATTR VkResult VKAPI_CALL GetFenceStatus(VkDevice device, VkFence fence)
  {
    auto &dispatch_table = *GetDeviceDispatchTable(device);
    VkResult result = VkResult::VK_SUCCESS; 
  
    if (dispatch_table.GetFenceStatus) {
      result = dispatch_table.GetFenceStatus(device, fence);
    }
  
    GetInterceptor()->PostGetFenceStatus(device, fence, result);
    return result; 
  }
  
  VKAPI_ATTR VkResult VKAPI_CALL WaitForFences(VkDevice device, uint32_t fenceCount, VkFence const* pFences, VkBool32 waitAll, uint64_t timeout)
  {
    auto &dispatch_table = *GetDeviceDispatchTable(device);
    VkResult result = VkResult::VK_SUCCESS; 
  
    if (dispatch_table.WaitForFences) {
      result = dispatch_table.WaitForFences(device, fenceCount, pFences, waitAll, timeout);
    }
  
    GetInterceptor()->PostWaitForFences(device, fenceCount, pFences, waitAll, timeout, result);
    return result; 
  }
  
  VKAPI_ATTR VkResult VKAPI_CALL CreateSemaphore(VkDevice device, VkSemaphoreCreateInfo const* pCreateInfo, AllocationCallbacks pAllocator, VkSemaphore* pSemaphore)
  {
    auto &dispatch_table = *GetDeviceDispatchTable(device);
    VkResult result = VkResult::VK_SUCCESS; 
  
    if (dispatch_table.CreateSemaphore) {
      result = dispatch_table.CreateSemaphore(device, pCreateInfo, pAllocator, pSemaphore);
    }
  
    GetInterceptor()->PostCreateSemaphore(device, pCreateInfo, pAllocator, pSemaphore, result);
    return result; 
  }
  
  VKAPI_ATTR void VKAPI_CALL DestroySemaphore(VkDevice device, VkSemaphore semaphore, AllocationCallbacks pAllocator)
  {
    auto &dispatch_table = *GetDeviceDispatchTable(device);
  
    if (dispatch_table.DestroySemaphore) {
      dispatch_table.DestroySemaphore(device, semaphore, pAllocator);
    }
  
    GetInterceptor()->PostDestroySemaphore(device, semaphore, pAllocator);
  }
  
  VKAPI_ATTR VkResult VKAPI_CALL CreateEvent(VkDevice device, VkEventCreateInfo const* pCreateInfo, AllocationCallbacks pAllocator, VkEvent* pEvent)
  {
    auto &dispatch_table = *GetDeviceDispatchTable(device);
    VkResult result = VkResult::VK_SUCCESS; 
  
    if (dispatch_table.CreateEvent) {
      result = dispatch_table.CreateEvent(device, pCreateInfo, pAllocator, pEvent);
    }
    return result; 
  }
  
  VKAPI_ATTR void VKAPI_CALL DestroyEvent(VkDevice device, VkEvent event, AllocationCallbacks pAllocator)
  {
    auto &dispatch_table = *GetDeviceDispatchTable(device);
  
    if (dispatch_table.DestroyEvent) {
      dispatch_table.DestroyEvent(device, event, pAllocator);
    }
  }
  
  VKAPI_ATTR VkResult VKAPI_CALL GetEventStatus(VkDevice device, VkEvent event)
  {
    auto &dispatch_table = *GetDeviceDispatchTable(device);
    VkResult result = VkResult::VK_SUCCESS; 
  
    if (dispatch_table.GetEventStatus) {
      result = dispatch_table.GetEventStatus(device, event);
    }
    return result; 
  }
  
  VKAPI_ATTR VkResult VKAPI_CALL SetEvent(VkDevice device, VkEvent event)
  {
    auto &dispatch_table = *GetDeviceDispatchTable(device);
    VkResult result = VkResult::VK_SUCCESS; 
  
    if (dispatch_table.SetEvent) {
      result = dispatch_table.SetEvent(device, event);
    }
    return result; 
  }
  
  VKAPI_ATTR VkResult VKAPI_CALL ResetEvent(VkDevice device, VkEvent event)
  {
    auto &dispatch_table = *GetDeviceDispatchTable(device);
    VkResult result = VkResult::VK_SUCCESS; 
  
    if (dispatch_table.ResetEvent) {
      result = dispatch_table.ResetEvent(device, event);
    }
    return result; 
  }
  
  VKAPI_ATTR void VKAPI_CALL CmdSetEvent(VkCommandBuffer commandBuffer, VkEvent event, VkPipelineStageFlags stageMask)
  {
    auto &dispatch_table = *GetDeviceDispatchTable(commandBuffer);
    WrappedVkCommandBuffer *wrappedcommandBuffer = reinterpret_cast<WrappedVkCommandBuffer *>(commandBuffer);
    VkCommandBuffer unwrappedcommandBuffer = wrappedcommandBuffer->wrapped_object;
  
    GetInterceptor()->PreCmdSetEvent(wrappedcommandBuffer, event, stageMask);
  
    if (dispatch_table.CmdSetEvent) {
      dispatch_table.CmdSetEvent(unwrappedcommandBuffer, event, stageMask);
    }
  
    GetInterceptor()->PostCmdSetEvent(wrappedcommandBuffer, event, stageMask);
  }
  
  VKAPI_ATTR void VKAPI_CALL CmdResetEvent(VkCommandBuffer commandBuffer, VkEvent event, VkPipelineStageFlags stageMask)
  {
    auto &dispatch_table = *GetDeviceDispatchTable(commandBuffer);
    WrappedVkCommandBuffer *wrappedcommandBuffer = reinterpret_cast<WrappedVkCommandBuffer *>(commandBuffer);
    VkCommandBuffer unwrappedcommandBuffer = wrappedcommandBuffer->wrapped_object;
  
    GetInterceptor()->PreCmdResetEvent(wrappedcommandBuffer, event, stageMask);
  
    if (dispatch_table.CmdResetEvent) {
      dispatch_table.CmdResetEvent(unwrappedcommandBuffer, event, stageMask);
    }
  
    GetInterceptor()->PostCmdResetEvent(wrappedcommandBuffer, event, stageMask);
  }
  
  VKAPI_ATTR void VKAPI_CALL CmdWaitEvents(VkCommandBuffer commandBuffer, uint32_t eventCount, VkEvent const* pEvents, VkPipelineStageFlags srcStageMask, VkPipelineStageFlags dstStageMask, uint32_t memoryBarrierCount, VkMemoryBarrier const* pMemoryBarriers, uint32_t bufferMemoryBarrierCount, VkBufferMemoryBarrier const* pBufferMemoryBarriers, uint32_t imageMemoryBarrierCount, VkImageMemoryBarrier const* pImageMemoryBarriers)
  {
    auto &dispatch_table = *GetDeviceDispatchTable(commandBuffer);
    WrappedVkCommandBuffer *wrappedcommandBuffer = reinterpret_cast<WrappedVkCommandBuffer *>(commandBuffer);
    VkCommandBuffer unwrappedcommandBuffer = wrappedcommandBuffer->wrapped_object;
  
    GetInterceptor()->PreCmdWaitEvents(wrappedcommandBuffer, eventCount, pEvents, srcStageMask, dstStageMask, memoryBarrierCount, pMemoryBarriers, bufferMemoryBarrierCount, pBufferMemoryBarriers, imageMemoryBarrierCount, pImageMemoryBarriers);
  
    if (dispatch_table.CmdWaitEvents) {
      dispatch_table.CmdWaitEvents(unwrappedcommandBuffer, eventCount, pEvents, srcStageMask, dstStageMask, memoryBarrierCount, pMemoryBarriers, bufferMemoryBarrierCount, pBufferMemoryBarriers, imageMemoryBarrierCount, pImageMemoryBarriers);
    }
  
    GetInterceptor()->PostCmdWaitEvents(wrappedcommandBuffer, eventCount, pEvents, srcStageMask, dstStageMask, memoryBarrierCount, pMemoryBarriers, bufferMemoryBarrierCount, pBufferMemoryBarriers, imageMemoryBarrierCount, pImageMemoryBarriers);
  }
  
  VKAPI_ATTR void VKAPI_CALL CmdPipelineBarrier(VkCommandBuffer commandBuffer, VkPipelineStageFlags srcStageMask, VkPipelineStageFlags dstStageMask, VkDependencyFlags dependencyFlags, uint32_t memoryBarrierCount, VkMemoryBarrier const* pMemoryBarriers, uint32_t bufferMemoryBarrierCount, VkBufferMemoryBarrier const* pBufferMemoryBarriers, uint32_t imageMemoryBarrierCount, VkImageMemoryBarrier const* pImageMemoryBarriers)
  {
    auto &dispatch_table = *GetDeviceDispatchTable(commandBuffer);
    WrappedVkCommandBuffer *wrappedcommandBuffer = reinterpret_cast<WrappedVkCommandBuffer *>(commandBuffer);
    VkCommandBuffer unwrappedcommandBuffer = wrappedcommandBuffer->wrapped_object;
  
    GetInterceptor()->PreCmdPipelineBarrier(wrappedcommandBuffer, srcStageMask, dstStageMask, dependencyFlags, memoryBarrierCount, pMemoryBarriers, bufferMemoryBarrierCount, pBufferMemoryBarriers, imageMemoryBarrierCount, pImageMemoryBarriers);
  
    if (dispatch_table.CmdPipelineBarrier) {
      dispatch_table.CmdPipelineBarrier(unwrappedcommandBuffer, srcStageMask, dstStageMask, dependencyFlags, memoryBarrierCount, pMemoryBarriers, bufferMemoryBarrierCount, pBufferMemoryBarriers, imageMemoryBarrierCount, pImageMemoryBarriers);
    }
  
    GetInterceptor()->PostCmdPipelineBarrier(wrappedcommandBuffer, srcStageMask, dstStageMask, dependencyFlags, memoryBarrierCount, pMemoryBarriers, bufferMemoryBarrierCount, pBufferMemoryBarriers, imageMemoryBarrierCount, pImageMemoryBarriers);
  }
  
  VKAPI_ATTR void VKAPI_CALL CmdWriteBufferMarkerAMD(VkCommandBuffer commandBuffer, VkPipelineStageFlagBits pipelineStage, VkBuffer dstBuffer, VkDeviceSize dstOffset, uint32_t marker)
  {
    auto &dispatch_table = *GetDeviceDispatchTable(commandBuffer);
    WrappedVkCommandBuffer *wrappedcommandBuffer = reinterpret_cast<WrappedVkCommandBuffer *>(commandBuffer);
    VkCommandBuffer unwrappedcommandBuffer = wrappedcommandBuffer->wrapped_object;
  
    GetInterceptor()->PreCmdWriteBufferMarkerAMD(wrappedcommandBuffer, pipelineStage, dstBuffer, dstOffset, marker);
  
    if (dispatch_table.CmdWriteBufferMarkerAMD) {
      dispatch_table.CmdWriteBufferMarkerAMD(unwrappedcommandBuffer, pipelineStage, dstBuffer, dstOffset, marker);
    }
  
    GetInterceptor()->PostCmdWriteBufferMarkerAMD(wrappedcommandBuffer, pipelineStage, dstBuffer, dstOffset, marker);
  }
  
  VKAPI_ATTR void VKAPI_CALL CmdDrawIndirectCountAMD(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, VkBuffer countBuffer, VkDeviceSize countOffset, uint32_t maxDrawCount, uint32_t stride)
  {
    auto &dispatch_table = *GetDeviceDispatchTable(commandBuffer);
    WrappedVkCommandBuffer *wrappedcommandBuffer = reinterpret_cast<WrappedVkCommandBuffer *>(commandBuffer);
    VkCommandBuffer unwrappedcommandBuffer = wrappedcommandBuffer->wrapped_object;
  
    GetInterceptor()->PreCmdDrawIndirectCountAMD(wrappedcommandBuffer, buffer, offset, countBuffer, countOffset, maxDrawCount, stride);
  
    if (dispatch_table.CmdDrawIndirectCountAMD) {
      dispatch_table.CmdDrawIndirectCountAMD(unwrappedcommandBuffer, buffer, offset, countBuffer, countOffset, maxDrawCount, stride);
    }
  
    GetInterceptor()->PostCmdDrawIndirectCountAMD(wrappedcommandBuffer, buffer, offset, countBuffer, countOffset, maxDrawCount, stride);
  }
  
  VKAPI_ATTR void VKAPI_CALL CmdDrawIndexedIndirectCountAMD(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, VkBuffer countBuffer, VkDeviceSize countOffset, uint32_t maxDrawCount, uint32_t stride)
  {
    auto &dispatch_table = *GetDeviceDispatchTable(commandBuffer);
    WrappedVkCommandBuffer *wrappedcommandBuffer = reinterpret_cast<WrappedVkCommandBuffer *>(commandBuffer);
    VkCommandBuffer unwrappedcommandBuffer = wrappedcommandBuffer->wrapped_object;
  
    GetInterceptor()->PreCmdDrawIndexedIndirectCountAMD(wrappedcommandBuffer, buffer, offset, countBuffer, countOffset, maxDrawCount, stride);
  
    if (dispatch_table.CmdDrawIndexedIndirectCountAMD) {
      dispatch_table.CmdDrawIndexedIndirectCountAMD(unwrappedcommandBuffer, buffer, offset, countBuffer, countOffset, maxDrawCount, stride);
    }
  
    GetInterceptor()->PostCmdDrawIndexedIndirectCountAMD(wrappedcommandBuffer, buffer, offset, countBuffer, countOffset, maxDrawCount, stride);
  }
  
  VKAPI_ATTR VkResult VKAPI_CALL DebugMarkerSetObjectTagEXT(VkDevice device, VkDebugMarkerObjectTagInfoEXT const* pTagInfo)
  {
    auto &dispatch_table = *GetDeviceDispatchTable(device);
    VkResult result = VkResult::VK_SUCCESS; 
  
    if (dispatch_table.DebugMarkerSetObjectTagEXT) {
      result = dispatch_table.DebugMarkerSetObjectTagEXT(device, pTagInfo);
    }
    return result; 
  }
  
  VKAPI_ATTR VkResult VKAPI_CALL DebugMarkerSetObjectNameEXT(VkDevice device, VkDebugMarkerObjectNameInfoEXT const* pNameInfo)
  {
    auto &dispatch_table = *GetDeviceDispatchTable(device);
    VkResult result = VkResult::VK_SUCCESS; 
  
    result = GetInterceptor()->PreDebugMarkerSetObjectNameEXT(device, pNameInfo);
  
    if (dispatch_table.DebugMarkerSetObjectNameEXT) {
      result = dispatch_table.DebugMarkerSetObjectNameEXT(device, pNameInfo);
    }
  
    GetInterceptor()->PostDebugMarkerSetObjectNameEXT(device, pNameInfo, result);
    return result; 
  }
  
  VKAPI_ATTR void VKAPI_CALL CmdDebugMarkerBeginEXT(VkCommandBuffer commandBuffer, VkDebugMarkerMarkerInfoEXT const* pMarkerInfo)
  {
    auto &dispatch_table = *GetDeviceDispatchTable(commandBuffer);
    WrappedVkCommandBuffer *wrappedcommandBuffer = reinterpret_cast<WrappedVkCommandBuffer *>(commandBuffer);
    VkCommandBuffer unwrappedcommandBuffer = wrappedcommandBuffer->wrapped_object;
  
    GetInterceptor()->PreCmdDebugMarkerBeginEXT(wrappedcommandBuffer, pMarkerInfo);
  
    if (dispatch_table.CmdDebugMarkerBeginEXT) {
      dispatch_table.CmdDebugMarkerBeginEXT(unwrappedcommandBuffer, pMarkerInfo);
    }
  
    GetInterceptor()->PostCmdDebugMarkerBeginEXT(wrappedcommandBuffer, pMarkerInfo);
  }
  
  VKAPI_ATTR void VKAPI_CALL CmdDebugMarkerEndEXT(VkCommandBuffer commandBuffer)
  {
    auto &dispatch_table = *GetDeviceDispatchTable(commandBuffer);
    WrappedVkCommandBuffer *wrappedcommandBuffer = reinterpret_cast<WrappedVkCommandBuffer *>(commandBuffer);
    VkCommandBuffer unwrappedcommandBuffer = wrappedcommandBuffer->wrapped_object;
  
    GetInterceptor()->PreCmdDebugMarkerEndEXT(wrappedcommandBuffer);
  
    if (dispatch_table.CmdDebugMarkerEndEXT) {
      dispatch_table.CmdDebugMarkerEndEXT(unwrappedcommandBuffer);
    }
  
    GetInterceptor()->PostCmdDebugMarkerEndEXT(wrappedcommandBuffer);
  }
  
  VKAPI_ATTR void VKAPI_CALL CmdDebugMarkerInsertEXT(VkCommandBuffer commandBuffer, VkDebugMarkerMarkerInfoEXT const* pMarkerInfo)
  {
    auto &dispatch_table = *GetDeviceDispatchTable(commandBuffer);
    WrappedVkCommandBuffer *wrappedcommandBuffer = reinterpret_cast<WrappedVkCommandBuffer *>(commandBuffer);
    VkCommandBuffer unwrappedcommandBuffer = wrappedcommandBuffer->wrapped_object;
  
    GetInterceptor()->PreCmdDebugMarkerInsertEXT(wrappedcommandBuffer, pMarkerInfo);
  
    if (dispatch_table.CmdDebugMarkerInsertEXT) {
      dispatch_table.CmdDebugMarkerInsertEXT(unwrappedcommandBuffer, pMarkerInfo);
    }
  
    GetInterceptor()->PostCmdDebugMarkerInsertEXT(wrappedcommandBuffer, pMarkerInfo);
  }
  
  VKAPI_ATTR VkResult VKAPI_CALL CreateDebugReportCallbackEXT(VkInstance instance, VkDebugReportCallbackCreateInfoEXT const* pCreateInfo, AllocationCallbacks pAllocator, VkDebugReportCallbackEXT* pCallback)
  {
    auto &dispatch_table = *GetInstanceDispatchTable(instance);
    VkResult result = VkResult::VK_SUCCESS; 
  
    if (dispatch_table.CreateDebugReportCallbackEXT) {
      result = dispatch_table.CreateDebugReportCallbackEXT(instance, pCreateInfo, pAllocator, pCallback);
    }
    return result; 
  }
  
  VKAPI_ATTR void VKAPI_CALL DestroyDebugReportCallbackEXT(VkInstance instance, VkDebugReportCallbackEXT callback, AllocationCallbacks pAllocator)
  {
    auto &dispatch_table = *GetInstanceDispatchTable(instance);
  
    if (dispatch_table.DestroyDebugReportCallbackEXT) {
      dispatch_table.DestroyDebugReportCallbackEXT(instance, callback, pAllocator);
    }
  }
  
  VKAPI_ATTR void VKAPI_CALL DebugReportMessageEXT(VkInstance instance, VkDebugReportFlagsEXT flags, VkDebugReportObjectTypeEXT objectType, uint64_t object, size_val location, int32_t messageCode, char const* pLayerPrefix, char const* pMessage)
  {
    auto &dispatch_table = *GetInstanceDispatchTable(instance);
  
    if (dispatch_table.DebugReportMessageEXT) {
      dispatch_table.DebugReportMessageEXT(instance, flags, objectType, object, location, messageCode, pLayerPrefix, pMessage);
    }
  }
  
  VKAPI_ATTR VkResult VKAPI_CALL SetDebugUtilsObjectNameEXT(VkDevice device, VkDebugUtilsObjectNameInfoEXT const* pNameInfo)
  {
    auto &dispatch_table = *GetDeviceDispatchTable(device);
    VkResult result = VkResult::VK_SUCCESS; 
  
    result = GetInterceptor()->PreSetDebugUtilsObjectNameEXT(device, pNameInfo);
  
    if (dispatch_table.SetDebugUtilsObjectNameEXT) {
      result = dispatch_table.SetDebugUtilsObjectNameEXT(device, pNameInfo);
    }
  
    GetInterceptor()->PostSetDebugUtilsObjectNameEXT(device, pNameInfo, result);
    return result; 
  }
  
  VKAPI_ATTR VkResult VKAPI_CALL SetDebugUtilsObjectTagEXT(VkDevice device, VkDebugUtilsObjectTagInfoEXT const* pTagInfo)
  {
    auto &dispatch_table = *GetDeviceDispatchTable(device);
    VkResult result = VkResult::VK_SUCCESS; 
  
    if (dispatch_table.SetDebugUtilsObjectTagEXT) {
      result = dispatch_table.SetDebugUtilsObjectTagEXT(device, pTagInfo);
    }
    return result; 
  }
  
  VKAPI_ATTR void VKAPI_CALL CmdBeginDebugUtilsLabelEXT(VkCommandBuffer commandBuffer, VkDebugUtilsLabelEXT const* pLabelInfo)
  {
    auto &dispatch_table = *GetDeviceDispatchTable(commandBuffer);
    WrappedVkCommandBuffer *wrappedcommandBuffer = reinterpret_cast<WrappedVkCommandBuffer *>(commandBuffer);
    VkCommandBuffer unwrappedcommandBuffer = wrappedcommandBuffer->wrapped_object;
  
    GetInterceptor()->PreCmdBeginDebugUtilsLabelEXT(wrappedcommandBuffer, pLabelInfo);
  
    if (dispatch_table.CmdBeginDebugUtilsLabelEXT) {
      dispatch_table.CmdBeginDebugUtilsLabelEXT(unwrappedcommandBuffer, pLabelInfo);
    }
  
    GetInterceptor()->PostCmdBeginDebugUtilsLabelEXT(wrappedcommandBuffer, pLabelInfo);
  }
  
  VKAPI_ATTR void VKAPI_CALL CmdEndDebugUtilsLabelEXT(VkCommandBuffer commandBuffer)
  {
    auto &dispatch_table = *GetDeviceDispatchTable(commandBuffer);
    WrappedVkCommandBuffer *wrappedcommandBuffer = reinterpret_cast<WrappedVkCommandBuffer *>(commandBuffer);
    VkCommandBuffer unwrappedcommandBuffer = wrappedcommandBuffer->wrapped_object;
  
    GetInterceptor()->PreCmdEndDebugUtilsLabelEXT(wrappedcommandBuffer);
  
    if (dispatch_table.CmdEndDebugUtilsLabelEXT) {
      dispatch_table.CmdEndDebugUtilsLabelEXT(unwrappedcommandBuffer);
    }
  
    GetInterceptor()->PostCmdEndDebugUtilsLabelEXT(wrappedcommandBuffer);
  }
  
  VKAPI_ATTR void VKAPI_CALL CmdInsertDebugUtilsLabelEXT(VkCommandBuffer commandBuffer, VkDebugUtilsLabelEXT const* pLabelInfo)
  {
    auto &dispatch_table = *GetDeviceDispatchTable(commandBuffer);
    WrappedVkCommandBuffer *wrappedcommandBuffer = reinterpret_cast<WrappedVkCommandBuffer *>(commandBuffer);
    VkCommandBuffer unwrappedcommandBuffer = wrappedcommandBuffer->wrapped_object;
  
    GetInterceptor()->PreCmdInsertDebugUtilsLabelEXT(wrappedcommandBuffer, pLabelInfo);
  
    if (dispatch_table.CmdInsertDebugUtilsLabelEXT) {
      dispatch_table.CmdInsertDebugUtilsLabelEXT(unwrappedcommandBuffer, pLabelInfo);
    }
  
    GetInterceptor()->PostCmdInsertDebugUtilsLabelEXT(wrappedcommandBuffer, pLabelInfo);
  }
  
  VKAPI_ATTR void VKAPI_CALL QueueBeginDebugUtilsLabelEXT(VkQueue queue, VkDebugUtilsLabelEXT const* pLabelInfo)
  {
    auto &dispatch_table = *GetDeviceDispatchTable(queue);
  
    if (dispatch_table.QueueBeginDebugUtilsLabelEXT) {
      dispatch_table.QueueBeginDebugUtilsLabelEXT(queue, pLabelInfo);
    }
  }
  
  VKAPI_ATTR void VKAPI_CALL QueueEndDebugUtilsLabelEXT(VkQueue queue)
  {
    auto &dispatch_table = *GetDeviceDispatchTable(queue);
  
    if (dispatch_table.QueueEndDebugUtilsLabelEXT) {
      dispatch_table.QueueEndDebugUtilsLabelEXT(queue);
    }
  }
  
  VKAPI_ATTR void VKAPI_CALL QueueInsertDebugUtilsLabelEXT(VkQueue queue, VkDebugUtilsLabelEXT const* pLabelInfo)
  {
    auto &dispatch_table = *GetDeviceDispatchTable(queue);
  
    if (dispatch_table.QueueInsertDebugUtilsLabelEXT) {
      dispatch_table.QueueInsertDebugUtilsLabelEXT(queue, pLabelInfo);
    }
  }
  
  VKAPI_ATTR VkResult VKAPI_CALL CreateDebugUtilsMessengerEXT(VkInstance instance, VkDebugUtilsMessengerCreateInfoEXT const* pCreateInfo, AllocationCallbacks pAllocator, VkDebugUtilsMessengerEXT* pMessenger)
  {
    auto &dispatch_table = *GetInstanceDispatchTable(instance);
    VkResult result = VkResult::VK_SUCCESS; 
  
    if (dispatch_table.CreateDebugUtilsMessengerEXT) {
      result = dispatch_table.CreateDebugUtilsMessengerEXT(instance, pCreateInfo, pAllocator, pMessenger);
    }
    return result; 
  }
  
  VKAPI_ATTR void VKAPI_CALL DestroyDebugUtilsMessengerEXT(VkInstance instance, VkDebugUtilsMessengerEXT messenger, AllocationCallbacks pAllocator)
  {
    auto &dispatch_table = *GetInstanceDispatchTable(instance);
  
    if (dispatch_table.DestroyDebugUtilsMessengerEXT) {
      dispatch_table.DestroyDebugUtilsMessengerEXT(instance, messenger, pAllocator);
    }
  }
  
  VKAPI_ATTR void VKAPI_CALL SubmitDebugUtilsMessageEXT(VkInstance instance, VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity, VkDebugUtilsMessageTypeFlagsEXT messageTypes, VkDebugUtilsMessengerCallbackDataEXT const* pCallbackData)
  {
    auto &dispatch_table = *GetInstanceDispatchTable(instance);
  
    if (dispatch_table.SubmitDebugUtilsMessageEXT) {
      dispatch_table.SubmitDebugUtilsMessageEXT(instance, messageSeverity, messageTypes, pCallbackData);
    }
  }
  
  VKAPI_ATTR void VKAPI_CALL SetHdrMetadataEXT(VkDevice device, uint32_t swapchainCount, VkSwapchainKHR const* pSwapchains, VkHdrMetadataEXT const* pMetadata)
  {
    auto &dispatch_table = *GetDeviceDispatchTable(device);
  
    if (dispatch_table.SetHdrMetadataEXT) {
      dispatch_table.SetHdrMetadataEXT(device, swapchainCount, pSwapchains, pMetadata);
    }
  }
  
  VKAPI_ATTR void VKAPI_CALL ResetQueryPoolEXT(VkDevice device, VkQueryPool queryPool, uint32_t firstQuery, uint32_t queryCount)
  {
    auto &dispatch_table = *GetDeviceDispatchTable(device);
  
    if (dispatch_table.ResetQueryPoolEXT) {
      dispatch_table.ResetQueryPoolEXT(device, queryPool, firstQuery, queryCount);
    }
  }
  
  VKAPI_ATTR VkResult VKAPI_CALL GetRefreshCycleDurationGOOGLE(VkDevice device, VkSwapchainKHR swapchain, VkRefreshCycleDurationGOOGLE* pDisplayTimingProperties)
  {
    auto &dispatch_table = *GetDeviceDispatchTable(device);
    VkResult result = VkResult::VK_SUCCESS; 
  
    if (dispatch_table.GetRefreshCycleDurationGOOGLE) {
      result = dispatch_table.GetRefreshCycleDurationGOOGLE(device, swapchain, pDisplayTimingProperties);
    }
    return result; 
  }
  
  VKAPI_ATTR VkResult VKAPI_CALL GetPastPresentationTimingGOOGLE(VkDevice device, VkSwapchainKHR swapchain, uint32_t* pPresentationTimingCount, VkPastPresentationTimingGOOGLE* pPresentationTimings)
  {
    auto &dispatch_table = *GetDeviceDispatchTable(device);
    VkResult result = VkResult::VK_SUCCESS; 
  
    if (dispatch_table.GetPastPresentationTimingGOOGLE) {
      result = dispatch_table.GetPastPresentationTimingGOOGLE(device, swapchain, pPresentationTimingCount, pPresentationTimings);
    }
    return result; 
  }
  
  VKAPI_ATTR VkResult VKAPI_CALL BindBufferMemory2KHR(VkDevice device, uint32_t bindInfoCount, VkBindBufferMemoryInfoKHR const* pBindInfos)
  {
    auto &dispatch_table = *GetDeviceDispatchTable(device);
    VkResult result = VkResult::VK_SUCCESS; 
  
    if (dispatch_table.BindBufferMemory2KHR) {
      result = dispatch_table.BindBufferMemory2KHR(device, bindInfoCount, pBindInfos);
    }
    return result; 
  }
  
  VKAPI_ATTR VkResult VKAPI_CALL BindImageMemory2KHR(VkDevice device, uint32_t bindInfoCount, VkBindImageMemoryInfoKHR const* pBindInfos)
  {
    auto &dispatch_table = *GetDeviceDispatchTable(device);
    VkResult result = VkResult::VK_SUCCESS; 
  
    if (dispatch_table.BindImageMemory2KHR) {
      result = dispatch_table.BindImageMemory2KHR(device, bindInfoCount, pBindInfos);
    }
    return result; 
  }
  
  VKAPI_ATTR VkResult VKAPI_CALL CreateDescriptorUpdateTemplateKHR(VkDevice device, VkDescriptorUpdateTemplateCreateInfo const* pCreateInfo, VkAllocationCallbacks const* pAllocator, VkDescriptorUpdateTemplate* pDescriptorUpdateTemplate)
  {
    auto &dispatch_table = *GetDeviceDispatchTable(device);
    VkResult result = VkResult::VK_SUCCESS; 
  
    if (dispatch_table.CreateDescriptorUpdateTemplateKHR) {
      result = dispatch_table.CreateDescriptorUpdateTemplateKHR(device, pCreateInfo, pAllocator, pDescriptorUpdateTemplate);
    }
    return result; 
  }
  
  VKAPI_ATTR void VKAPI_CALL DestroyDescriptorUpdateTemplateKHR(VkDevice device, VkDescriptorUpdateTemplate descriptorUpdateTemplate, VkAllocationCallbacks const* pAllocator)
  {
    auto &dispatch_table = *GetDeviceDispatchTable(device);
  
    if (dispatch_table.DestroyDescriptorUpdateTemplateKHR) {
      dispatch_table.DestroyDescriptorUpdateTemplateKHR(device, descriptorUpdateTemplate, pAllocator);
    }
  }
  
  VKAPI_ATTR void VKAPI_CALL UpdateDescriptorSetWithTemplateKHR(VkDevice device, VkDescriptorSet descriptorSet, VkDescriptorUpdateTemplate descriptorUpdateTemplate, void const* pData)
  {
    auto &dispatch_table = *GetDeviceDispatchTable(device);
  
    if (dispatch_table.UpdateDescriptorSetWithTemplateKHR) {
      dispatch_table.UpdateDescriptorSetWithTemplateKHR(device, descriptorSet, descriptorUpdateTemplate, pData);
    }
  }
  
  VKAPI_ATTR VkResult VKAPI_CALL CreateDescriptorUpdateTemplate(VkDevice device, VkDescriptorUpdateTemplateCreateInfo const* pCreateInfo, VkAllocationCallbacks const* pAllocator, VkDescriptorUpdateTemplate* pDescriptorUpdateTemplate)
  {
    auto &dispatch_table = *GetDeviceDispatchTable(device);
    VkResult result = VkResult::VK_SUCCESS; 
  
    if (dispatch_table.CreateDescriptorUpdateTemplate) {
      result = dispatch_table.CreateDescriptorUpdateTemplate(device, pCreateInfo, pAllocator, pDescriptorUpdateTemplate);
    }
    return result; 
  }
  
  VKAPI_ATTR void VKAPI_CALL DestroyDescriptorUpdateTemplate(VkDevice device, VkDescriptorUpdateTemplate descriptorUpdateTemplate, VkAllocationCallbacks const* pAllocator)
  {
    auto &dispatch_table = *GetDeviceDispatchTable(device);
  
    if (dispatch_table.DestroyDescriptorUpdateTemplate) {
      dispatch_table.DestroyDescriptorUpdateTemplate(device, descriptorUpdateTemplate, pAllocator);
    }
  }
  
  VKAPI_ATTR void VKAPI_CALL UpdateDescriptorSetWithTemplate(VkDevice device, VkDescriptorSet descriptorSet, VkDescriptorUpdateTemplate descriptorUpdateTemplate, void const* pData)
  {
    auto &dispatch_table = *GetDeviceDispatchTable(device);
  
    if (dispatch_table.UpdateDescriptorSetWithTemplate) {
      dispatch_table.UpdateDescriptorSetWithTemplate(device, descriptorSet, descriptorUpdateTemplate, pData);
    }
  }
  
  VKAPI_ATTR void VKAPI_CALL GetDeviceGroupPeerMemoryFeaturesKHR(VkDevice device, uint32_t heapIndex, uint32_t localDeviceIndex, uint32_t remoteDeviceIndex, VkPeerMemoryFeatureFlags* pPeerMemoryFeatures)
  {
    auto &dispatch_table = *GetDeviceDispatchTable(device);
  
    if (dispatch_table.GetDeviceGroupPeerMemoryFeaturesKHR) {
      dispatch_table.GetDeviceGroupPeerMemoryFeaturesKHR(device, heapIndex, localDeviceIndex, remoteDeviceIndex, pPeerMemoryFeatures);
    }
  }
  
  VKAPI_ATTR void VKAPI_CALL GetDeviceGroupPeerMemoryFeatures(VkDevice device, uint32_t heapIndex, uint32_t localDeviceIndex, uint32_t remoteDeviceIndex, VkPeerMemoryFeatureFlags* pPeerMemoryFeatures)
  {
    auto &dispatch_table = *GetDeviceDispatchTable(device);
  
    if (dispatch_table.GetDeviceGroupPeerMemoryFeatures) {
      dispatch_table.GetDeviceGroupPeerMemoryFeatures(device, heapIndex, localDeviceIndex, remoteDeviceIndex, pPeerMemoryFeatures);
    }
  }
  
  VKAPI_ATTR void VKAPI_CALL CmdSetDeviceMaskKHR(VkCommandBuffer commandBuffer, uint32_t deviceMask)
  {
    auto &dispatch_table = *GetDeviceDispatchTable(commandBuffer);
    WrappedVkCommandBuffer *wrappedcommandBuffer = reinterpret_cast<WrappedVkCommandBuffer *>(commandBuffer);
    VkCommandBuffer unwrappedcommandBuffer = wrappedcommandBuffer->wrapped_object;
  
    GetInterceptor()->PreCmdSetDeviceMaskKHR(wrappedcommandBuffer, deviceMask);
  
    if (dispatch_table.CmdSetDeviceMaskKHR) {
      dispatch_table.CmdSetDeviceMaskKHR(unwrappedcommandBuffer, deviceMask);
    }
  
    GetInterceptor()->PostCmdSetDeviceMaskKHR(wrappedcommandBuffer, deviceMask);
  }
  
  VKAPI_ATTR void VKAPI_CALL CmdSetDeviceMask(VkCommandBuffer commandBuffer, uint32_t deviceMask)
  {
    auto &dispatch_table = *GetDeviceDispatchTable(commandBuffer);
    WrappedVkCommandBuffer *wrappedcommandBuffer = reinterpret_cast<WrappedVkCommandBuffer *>(commandBuffer);
    VkCommandBuffer unwrappedcommandBuffer = wrappedcommandBuffer->wrapped_object;
  
    GetInterceptor()->PreCmdSetDeviceMask(wrappedcommandBuffer, deviceMask);
  
    if (dispatch_table.CmdSetDeviceMask) {
      dispatch_table.CmdSetDeviceMask(unwrappedcommandBuffer, deviceMask);
    }
  
    GetInterceptor()->PostCmdSetDeviceMask(wrappedcommandBuffer, deviceMask);
  }
  
  VKAPI_ATTR void VKAPI_CALL CmdDispatchBaseKHR(VkCommandBuffer commandBuffer, uint32_t baseGroupX, uint32_t baseGroupY, uint32_t baseGroupZ, uint32_t groupCountX, uint32_t groupCountY, uint32_t groupCountZ)
  {
    auto &dispatch_table = *GetDeviceDispatchTable(commandBuffer);
    WrappedVkCommandBuffer *wrappedcommandBuffer = reinterpret_cast<WrappedVkCommandBuffer *>(commandBuffer);
    VkCommandBuffer unwrappedcommandBuffer = wrappedcommandBuffer->wrapped_object;
  
    GetInterceptor()->PreCmdDispatchBaseKHR(wrappedcommandBuffer, baseGroupX, baseGroupY, baseGroupZ, groupCountX, groupCountY, groupCountZ);
  
    if (dispatch_table.CmdDispatchBaseKHR) {
      dispatch_table.CmdDispatchBaseKHR(unwrappedcommandBuffer, baseGroupX, baseGroupY, baseGroupZ, groupCountX, groupCountY, groupCountZ);
    }
  
    GetInterceptor()->PostCmdDispatchBaseKHR(wrappedcommandBuffer, baseGroupX, baseGroupY, baseGroupZ, groupCountX, groupCountY, groupCountZ);
  }
  
  VKAPI_ATTR void VKAPI_CALL CmdDispatchBase(VkCommandBuffer commandBuffer, uint32_t baseGroupX, uint32_t baseGroupY, uint32_t baseGroupZ, uint32_t groupCountX, uint32_t groupCountY, uint32_t groupCountZ)
  {
    auto &dispatch_table = *GetDeviceDispatchTable(commandBuffer);
    WrappedVkCommandBuffer *wrappedcommandBuffer = reinterpret_cast<WrappedVkCommandBuffer *>(commandBuffer);
    VkCommandBuffer unwrappedcommandBuffer = wrappedcommandBuffer->wrapped_object;
  
    GetInterceptor()->PreCmdDispatchBase(wrappedcommandBuffer, baseGroupX, baseGroupY, baseGroupZ, groupCountX, groupCountY, groupCountZ);
  
    if (dispatch_table.CmdDispatchBase) {
      dispatch_table.CmdDispatchBase(unwrappedcommandBuffer, baseGroupX, baseGroupY, baseGroupZ, groupCountX, groupCountY, groupCountZ);
    }
  
    GetInterceptor()->PostCmdDispatchBase(wrappedcommandBuffer, baseGroupX, baseGroupY, baseGroupZ, groupCountX, groupCountY, groupCountZ);
  }
  
  VKAPI_ATTR VkResult VKAPI_CALL GetDeviceGroupPresentCapabilitiesKHR(VkDevice device, VkDeviceGroupPresentCapabilitiesKHR* pDeviceGroupPresentCapabilities)
  {
    auto &dispatch_table = *GetDeviceDispatchTable(device);
    VkResult result = VkResult::VK_SUCCESS; 
  
    if (dispatch_table.GetDeviceGroupPresentCapabilitiesKHR) {
      result = dispatch_table.GetDeviceGroupPresentCapabilitiesKHR(device, pDeviceGroupPresentCapabilities);
    }
    return result; 
  }
  
  VKAPI_ATTR VkResult VKAPI_CALL GetDeviceGroupSurfacePresentModesKHR(VkDevice device, VkSurfaceKHR surface, VkDeviceGroupPresentModeFlagsKHR* pModes)
  {
    auto &dispatch_table = *GetDeviceDispatchTable(device);
    VkResult result = VkResult::VK_SUCCESS; 
  
    if (dispatch_table.GetDeviceGroupSurfacePresentModesKHR) {
      result = dispatch_table.GetDeviceGroupSurfacePresentModesKHR(device, surface, pModes);
    }
    return result; 
  }
  
  VKAPI_ATTR VkResult VKAPI_CALL GetPhysicalDevicePresentRectanglesKHR(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface, uint32_t* pRectCount, VkRect2D* pRects)
  {
    auto &dispatch_table = *GetInstanceDispatchTable(physicalDevice);
    VkResult result = VkResult::VK_SUCCESS; 
  
    if (dispatch_table.GetPhysicalDevicePresentRectanglesKHR) {
      result = dispatch_table.GetPhysicalDevicePresentRectanglesKHR(physicalDevice, surface, pRectCount, pRects);
    }
    return result; 
  }
  
  VKAPI_ATTR VkResult VKAPI_CALL AcquireNextImage2KHR(VkDevice device, VkAcquireNextImageInfoKHR const* pAcquireInfo, uint32_t* pImageIndex)
  {
    auto &dispatch_table = *GetDeviceDispatchTable(device);
    VkResult result = VkResult::VK_SUCCESS; 
  
    if (dispatch_table.AcquireNextImage2KHR) {
      result = dispatch_table.AcquireNextImage2KHR(device, pAcquireInfo, pImageIndex);
    }
    return result; 
  }
  
  VKAPI_ATTR VkResult VKAPI_CALL EnumeratePhysicalDeviceGroupsKHR(VkInstance instance, uint32_t* pPhysicalDeviceGroupCount, VkPhysicalDeviceGroupProperties* pPhysicalDeviceGroupProperties)
  {
    auto &dispatch_table = *GetInstanceDispatchTable(instance);
    VkResult result = VkResult::VK_SUCCESS; 
  
    if (dispatch_table.EnumeratePhysicalDeviceGroupsKHR) {
      result = dispatch_table.EnumeratePhysicalDeviceGroupsKHR(instance, pPhysicalDeviceGroupCount, pPhysicalDeviceGroupProperties);
    }
    return result; 
  }
  
  VKAPI_ATTR VkResult VKAPI_CALL EnumeratePhysicalDeviceGroups(VkInstance instance, uint32_t* pPhysicalDeviceGroupCount, VkPhysicalDeviceGroupProperties* pPhysicalDeviceGroupProperties)
  {
    auto &dispatch_table = *GetInstanceDispatchTable(instance);
    VkResult result = VkResult::VK_SUCCESS; 
  
    if (dispatch_table.EnumeratePhysicalDeviceGroups) {
      result = dispatch_table.EnumeratePhysicalDeviceGroups(instance, pPhysicalDeviceGroupCount, pPhysicalDeviceGroupProperties);
    }
    return result; 
  }
  
  VKAPI_ATTR VkResult VKAPI_CALL GetPhysicalDeviceDisplayPropertiesKHR(VkPhysicalDevice physicalDevice, uint32_t* pPropertyCount, VkDisplayPropertiesKHR* pProperties)
  {
    auto &dispatch_table = *GetInstanceDispatchTable(physicalDevice);
    VkResult result = VkResult::VK_SUCCESS; 
  
    if (dispatch_table.GetPhysicalDeviceDisplayPropertiesKHR) {
      result = dispatch_table.GetPhysicalDeviceDisplayPropertiesKHR(physicalDevice, pPropertyCount, pProperties);
    }
    return result; 
  }
  
  VKAPI_ATTR VkResult VKAPI_CALL GetPhysicalDeviceDisplayPlanePropertiesKHR(VkPhysicalDevice physicalDevice, uint32_t* pPropertyCount, VkDisplayPlanePropertiesKHR* pProperties)
  {
    auto &dispatch_table = *GetInstanceDispatchTable(physicalDevice);
    VkResult result = VkResult::VK_SUCCESS; 
  
    if (dispatch_table.GetPhysicalDeviceDisplayPlanePropertiesKHR) {
      result = dispatch_table.GetPhysicalDeviceDisplayPlanePropertiesKHR(physicalDevice, pPropertyCount, pProperties);
    }
    return result; 
  }
  
  VKAPI_ATTR VkResult VKAPI_CALL GetDisplayPlaneSupportedDisplaysKHR(VkPhysicalDevice physicalDevice, uint32_t planeIndex, uint32_t* pDisplayCount, VkDisplayKHR* pDisplays)
  {
    auto &dispatch_table = *GetInstanceDispatchTable(physicalDevice);
    VkResult result = VkResult::VK_SUCCESS; 
  
    if (dispatch_table.GetDisplayPlaneSupportedDisplaysKHR) {
      result = dispatch_table.GetDisplayPlaneSupportedDisplaysKHR(physicalDevice, planeIndex, pDisplayCount, pDisplays);
    }
    return result; 
  }
  
  VKAPI_ATTR VkResult VKAPI_CALL GetDisplayModePropertiesKHR(VkPhysicalDevice physicalDevice, VkDisplayKHR display, uint32_t* pPropertyCount, VkDisplayModePropertiesKHR* pProperties)
  {
    auto &dispatch_table = *GetInstanceDispatchTable(physicalDevice);
    VkResult result = VkResult::VK_SUCCESS; 
  
    if (dispatch_table.GetDisplayModePropertiesKHR) {
      result = dispatch_table.GetDisplayModePropertiesKHR(physicalDevice, display, pPropertyCount, pProperties);
    }
    return result; 
  }
  
  VKAPI_ATTR VkResult VKAPI_CALL CreateDisplayModeKHR(VkPhysicalDevice physicalDevice, VkDisplayKHR display, VkDisplayModeCreateInfoKHR const* pCreateInfo, AllocationCallbacks pAllocator, VkDisplayModeKHR* pMode)
  {
    auto &dispatch_table = *GetInstanceDispatchTable(physicalDevice);
    VkResult result = VkResult::VK_SUCCESS; 
  
    if (dispatch_table.CreateDisplayModeKHR) {
      result = dispatch_table.CreateDisplayModeKHR(physicalDevice, display, pCreateInfo, pAllocator, pMode);
    }
    return result; 
  }
  
  VKAPI_ATTR VkResult VKAPI_CALL GetDisplayPlaneCapabilitiesKHR(VkPhysicalDevice physicalDevice, VkDisplayModeKHR mode, uint32_t planeIndex, VkDisplayPlaneCapabilitiesKHR* pCapabilities)
  {
    auto &dispatch_table = *GetInstanceDispatchTable(physicalDevice);
    VkResult result = VkResult::VK_SUCCESS; 
  
    if (dispatch_table.GetDisplayPlaneCapabilitiesKHR) {
      result = dispatch_table.GetDisplayPlaneCapabilitiesKHR(physicalDevice, mode, planeIndex, pCapabilities);
    }
    return result; 
  }
  
  VKAPI_ATTR VkResult VKAPI_CALL CreateDisplayPlaneSurfaceKHR(VkInstance instance, VkDisplaySurfaceCreateInfoKHR const* pCreateInfo, AllocationCallbacks pAllocator, VkSurfaceKHR* pSurface)
  {
    auto &dispatch_table = *GetInstanceDispatchTable(instance);
    VkResult result = VkResult::VK_SUCCESS; 
  
    if (dispatch_table.CreateDisplayPlaneSurfaceKHR) {
      result = dispatch_table.CreateDisplayPlaneSurfaceKHR(instance, pCreateInfo, pAllocator, pSurface);
    }
    return result; 
  }
  
  VKAPI_ATTR VkResult VKAPI_CALL CreateSharedSwapchainsKHR(VkDevice device, uint32_t swapchainCount, VkSwapchainCreateInfoKHR const* pCreateInfos, AllocationCallbacks pAllocator, VkSwapchainKHR* pSwapchains)
  {
    auto &dispatch_table = *GetDeviceDispatchTable(device);
    VkResult result = VkResult::VK_SUCCESS; 
  
    if (dispatch_table.CreateSharedSwapchainsKHR) {
      result = dispatch_table.CreateSharedSwapchainsKHR(device, swapchainCount, pCreateInfos, pAllocator, pSwapchains);
    }
    return result; 
  }
  
  VKAPI_ATTR void VKAPI_CALL CmdDrawIndirectCountKHR(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, VkBuffer countBuffer, VkDeviceSize countOffset, uint32_t maxDrawCount, uint32_t stride)
  {
    auto &dispatch_table = *GetDeviceDispatchTable(commandBuffer);
    WrappedVkCommandBuffer *wrappedcommandBuffer = reinterpret_cast<WrappedVkCommandBuffer *>(commandBuffer);
    VkCommandBuffer unwrappedcommandBuffer = wrappedcommandBuffer->wrapped_object;
  
    GetInterceptor()->PreCmdDrawIndirectCountKHR(wrappedcommandBuffer, buffer, offset, countBuffer, countOffset, maxDrawCount, stride);
  
    if (dispatch_table.CmdDrawIndirectCountKHR) {
      dispatch_table.CmdDrawIndirectCountKHR(unwrappedcommandBuffer, buffer, offset, countBuffer, countOffset, maxDrawCount, stride);
    }
  
    GetInterceptor()->PostCmdDrawIndirectCountKHR(wrappedcommandBuffer, buffer, offset, countBuffer, countOffset, maxDrawCount, stride);
  }
  
  VKAPI_ATTR void VKAPI_CALL CmdDrawIndexedIndirectCountKHR(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, VkBuffer countBuffer, VkDeviceSize countOffset, uint32_t maxDrawCount, uint32_t stride)
  {
    auto &dispatch_table = *GetDeviceDispatchTable(commandBuffer);
    WrappedVkCommandBuffer *wrappedcommandBuffer = reinterpret_cast<WrappedVkCommandBuffer *>(commandBuffer);
    VkCommandBuffer unwrappedcommandBuffer = wrappedcommandBuffer->wrapped_object;
  
    GetInterceptor()->PreCmdDrawIndexedIndirectCountKHR(wrappedcommandBuffer, buffer, offset, countBuffer, countOffset, maxDrawCount, stride);
  
    if (dispatch_table.CmdDrawIndexedIndirectCountKHR) {
      dispatch_table.CmdDrawIndexedIndirectCountKHR(unwrappedcommandBuffer, buffer, offset, countBuffer, countOffset, maxDrawCount, stride);
    }
  
    GetInterceptor()->PostCmdDrawIndexedIndirectCountKHR(wrappedcommandBuffer, buffer, offset, countBuffer, countOffset, maxDrawCount, stride);
  }
  
  VKAPI_ATTR void VKAPI_CALL GetPhysicalDeviceExternalFencePropertiesKHR(VkPhysicalDevice physicalDevice, VkPhysicalDeviceExternalFenceInfo const* pExternalFenceInfo, VkExternalFenceProperties* pExternalFenceProperties)
  {
    auto &dispatch_table = *GetInstanceDispatchTable(physicalDevice);
  
    if (dispatch_table.GetPhysicalDeviceExternalFencePropertiesKHR) {
      dispatch_table.GetPhysicalDeviceExternalFencePropertiesKHR(physicalDevice, pExternalFenceInfo, pExternalFenceProperties);
    }
  }
  
  VKAPI_ATTR void VKAPI_CALL GetPhysicalDeviceExternalBufferPropertiesKHR(VkPhysicalDevice physicalDevice, VkPhysicalDeviceExternalBufferInfo const* pExternalBufferInfo, VkExternalBufferProperties* pExternalBufferProperties)
  {
    auto &dispatch_table = *GetInstanceDispatchTable(physicalDevice);
  
    if (dispatch_table.GetPhysicalDeviceExternalBufferPropertiesKHR) {
      dispatch_table.GetPhysicalDeviceExternalBufferPropertiesKHR(physicalDevice, pExternalBufferInfo, pExternalBufferProperties);
    }
  }
  
  VKAPI_ATTR void VKAPI_CALL GetPhysicalDeviceExternalSemaphorePropertiesKHR(VkPhysicalDevice physicalDevice, VkPhysicalDeviceExternalSemaphoreInfo const* pExternalSemaphoreInfo, VkExternalSemaphoreProperties* pExternalSemaphoreProperties)
  {
    auto &dispatch_table = *GetInstanceDispatchTable(physicalDevice);
  
    if (dispatch_table.GetPhysicalDeviceExternalSemaphorePropertiesKHR) {
      dispatch_table.GetPhysicalDeviceExternalSemaphorePropertiesKHR(physicalDevice, pExternalSemaphoreInfo, pExternalSemaphoreProperties);
    }
  }
  
  VKAPI_ATTR void VKAPI_CALL GetImageMemoryRequirements2KHR(VkDevice device, VkImageMemoryRequirementsInfo2KHR const* pInfo, VkMemoryRequirements2KHR* pMemoryRequirements)
  {
    auto &dispatch_table = *GetDeviceDispatchTable(device);
  
    if (dispatch_table.GetImageMemoryRequirements2KHR) {
      dispatch_table.GetImageMemoryRequirements2KHR(device, pInfo, pMemoryRequirements);
    }
  }
  
  VKAPI_ATTR void VKAPI_CALL GetBufferMemoryRequirements2KHR(VkDevice device, VkBufferMemoryRequirementsInfo2KHR const* pInfo, VkMemoryRequirements2KHR* pMemoryRequirements)
  {
    auto &dispatch_table = *GetDeviceDispatchTable(device);
  
    if (dispatch_table.GetBufferMemoryRequirements2KHR) {
      dispatch_table.GetBufferMemoryRequirements2KHR(device, pInfo, pMemoryRequirements);
    }
  }
  
  VKAPI_ATTR void VKAPI_CALL GetImageSparseMemoryRequirements2KHR(VkDevice device, VkImageSparseMemoryRequirementsInfo2KHR const* pInfo, uint32_t* pSparseMemoryRequirementCount, VkSparseImageMemoryRequirements2KHR* pSparseMemoryRequirements)
  {
    auto &dispatch_table = *GetDeviceDispatchTable(device);
  
    if (dispatch_table.GetImageSparseMemoryRequirements2KHR) {
      dispatch_table.GetImageSparseMemoryRequirements2KHR(device, pInfo, pSparseMemoryRequirementCount, pSparseMemoryRequirements);
    }
  }
  
  VKAPI_ATTR void VKAPI_CALL GetPhysicalDeviceFeatures2KHR(VkPhysicalDevice physicalDevice, VkPhysicalDeviceFeatures2KHR* pFeatures)
  {
    auto &dispatch_table = *GetInstanceDispatchTable(physicalDevice);
  
    if (dispatch_table.GetPhysicalDeviceFeatures2KHR) {
      dispatch_table.GetPhysicalDeviceFeatures2KHR(physicalDevice, pFeatures);
    }
  }
  
  VKAPI_ATTR void VKAPI_CALL GetPhysicalDeviceProperties2KHR(VkPhysicalDevice physicalDevice, VkPhysicalDeviceProperties2KHR* pProperties)
  {
    auto &dispatch_table = *GetInstanceDispatchTable(physicalDevice);
  
    if (dispatch_table.GetPhysicalDeviceProperties2KHR) {
      dispatch_table.GetPhysicalDeviceProperties2KHR(physicalDevice, pProperties);
    }
  }
  
  VKAPI_ATTR void VKAPI_CALL GetPhysicalDeviceFormatProperties2KHR(VkPhysicalDevice physicalDevice, VkFormat format, VkFormatProperties2KHR* pFormatProperties)
  {
    auto &dispatch_table = *GetInstanceDispatchTable(physicalDevice);
  
    if (dispatch_table.GetPhysicalDeviceFormatProperties2KHR) {
      dispatch_table.GetPhysicalDeviceFormatProperties2KHR(physicalDevice, format, pFormatProperties);
    }
  }
  
  VKAPI_ATTR VkResult VKAPI_CALL GetPhysicalDeviceImageFormatProperties2KHR(VkPhysicalDevice physicalDevice, VkPhysicalDeviceImageFormatInfo2KHR const* pImageFormatInfo, VkImageFormatProperties2KHR* pImageFormatProperties)
  {
    auto &dispatch_table = *GetInstanceDispatchTable(physicalDevice);
    VkResult result = VkResult::VK_SUCCESS; 
  
    if (dispatch_table.GetPhysicalDeviceImageFormatProperties2KHR) {
      result = dispatch_table.GetPhysicalDeviceImageFormatProperties2KHR(physicalDevice, pImageFormatInfo, pImageFormatProperties);
    }
    return result; 
  }
  
  VKAPI_ATTR void VKAPI_CALL GetPhysicalDeviceQueueFamilyProperties2KHR(VkPhysicalDevice physicalDevice, uint32_t* pQueueFamilyPropertyCount, VkQueueFamilyProperties2KHR* pQueueFamilyProperties)
  {
    auto &dispatch_table = *GetInstanceDispatchTable(physicalDevice);
  
    if (dispatch_table.GetPhysicalDeviceQueueFamilyProperties2KHR) {
      dispatch_table.GetPhysicalDeviceQueueFamilyProperties2KHR(physicalDevice, pQueueFamilyPropertyCount, pQueueFamilyProperties);
    }
  }
  
  VKAPI_ATTR void VKAPI_CALL GetPhysicalDeviceMemoryProperties2KHR(VkPhysicalDevice physicalDevice, VkPhysicalDeviceMemoryProperties2KHR* pMemoryProperties)
  {
    auto &dispatch_table = *GetInstanceDispatchTable(physicalDevice);
  
    if (dispatch_table.GetPhysicalDeviceMemoryProperties2KHR) {
      dispatch_table.GetPhysicalDeviceMemoryProperties2KHR(physicalDevice, pMemoryProperties);
    }
  }
  
  VKAPI_ATTR void VKAPI_CALL GetPhysicalDeviceSparseImageFormatProperties2KHR(VkPhysicalDevice physicalDevice, VkPhysicalDeviceSparseImageFormatInfo2KHR const* pFormatInfo, uint32_t* pPropertyCount, VkSparseImageFormatProperties2KHR* pProperties)
  {
    auto &dispatch_table = *GetInstanceDispatchTable(physicalDevice);
  
    if (dispatch_table.GetPhysicalDeviceSparseImageFormatProperties2KHR) {
      dispatch_table.GetPhysicalDeviceSparseImageFormatProperties2KHR(physicalDevice, pFormatInfo, pPropertyCount, pProperties);
    }
  }
  
  VKAPI_ATTR VkResult VKAPI_CALL GetPhysicalDeviceSurfaceCapabilities2KHR(VkPhysicalDevice physicalDevice, VkPhysicalDeviceSurfaceInfo2KHR const* pSurfaceInfo, VkSurfaceCapabilities2KHR* pSurfaceCapabilities)
  {
    auto &dispatch_table = *GetInstanceDispatchTable(physicalDevice);
    VkResult result = VkResult::VK_SUCCESS; 
  
    if (dispatch_table.GetPhysicalDeviceSurfaceCapabilities2KHR) {
      result = dispatch_table.GetPhysicalDeviceSurfaceCapabilities2KHR(physicalDevice, pSurfaceInfo, pSurfaceCapabilities);
    }
    return result; 
  }
  
  VKAPI_ATTR VkResult VKAPI_CALL GetPhysicalDeviceSurfaceFormats2KHR(VkPhysicalDevice physicalDevice, VkPhysicalDeviceSurfaceInfo2KHR const* pSurfaceInfo, uint32_t* pSurfaceFormatCount, VkSurfaceFormat2KHR* pSurfaceFormats)
  {
    auto &dispatch_table = *GetInstanceDispatchTable(physicalDevice);
    VkResult result = VkResult::VK_SUCCESS; 
  
    if (dispatch_table.GetPhysicalDeviceSurfaceFormats2KHR) {
      result = dispatch_table.GetPhysicalDeviceSurfaceFormats2KHR(physicalDevice, pSurfaceInfo, pSurfaceFormatCount, pSurfaceFormats);
    }
    return result; 
  }
  
  VKAPI_ATTR void VKAPI_CALL TrimCommandPoolKHR(VkDevice device, VkCommandPool commandPool, VkCommandPoolTrimFlags flags)
  {
    auto &dispatch_table = *GetDeviceDispatchTable(device);
  
    if (dispatch_table.TrimCommandPoolKHR) {
      dispatch_table.TrimCommandPoolKHR(device, commandPool, flags);
    }
  }
  
  VKAPI_ATTR void VKAPI_CALL GetDescriptorSetLayoutSupportKHR(VkDevice device, VkDescriptorSetLayoutCreateInfo const* pCreateInfo, VkDescriptorSetLayoutSupport* pSupport)
  {
    auto &dispatch_table = *GetDeviceDispatchTable(device);
  
    if (dispatch_table.GetDescriptorSetLayoutSupportKHR) {
      dispatch_table.GetDescriptorSetLayoutSupportKHR(device, pCreateInfo, pSupport);
    }
  }
  
  VKAPI_ATTR VkResult VKAPI_CALL CreateSamplerYcbcrConversionKHR(VkDevice device, VkSamplerYcbcrConversionCreateInfo const* pCreateInfo, VkAllocationCallbacks const* pAllocator, VkSamplerYcbcrConversion* pYcbcrConversion)
  {
    auto &dispatch_table = *GetDeviceDispatchTable(device);
    VkResult result = VkResult::VK_SUCCESS; 
  
    if (dispatch_table.CreateSamplerYcbcrConversionKHR) {
      result = dispatch_table.CreateSamplerYcbcrConversionKHR(device, pCreateInfo, pAllocator, pYcbcrConversion);
    }
    return result; 
  }
  
  VKAPI_ATTR void VKAPI_CALL DestroySamplerYcbcrConversionKHR(VkDevice device, VkSamplerYcbcrConversion ycbcrConversion, VkAllocationCallbacks const* pAllocator)
  {
    auto &dispatch_table = *GetDeviceDispatchTable(device);
  
    if (dispatch_table.DestroySamplerYcbcrConversionKHR) {
      dispatch_table.DestroySamplerYcbcrConversionKHR(device, ycbcrConversion, pAllocator);
    }
  }
  
  VKAPI_ATTR void VKAPI_CALL DestroySurfaceKHR(VkInstance instance, VkSurfaceKHR surface, AllocationCallbacks pAllocator)
  {
    auto &dispatch_table = *GetInstanceDispatchTable(instance);
  
    if (dispatch_table.DestroySurfaceKHR) {
      dispatch_table.DestroySurfaceKHR(instance, surface, pAllocator);
    }
  }
  
  VKAPI_ATTR VkResult VKAPI_CALL GetPhysicalDeviceSurfaceSupportKHR(VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex, VkSurfaceKHR surface, VkBool32* pSupported)
  {
    auto &dispatch_table = *GetInstanceDispatchTable(physicalDevice);
    VkResult result = VkResult::VK_SUCCESS; 
  
    if (dispatch_table.GetPhysicalDeviceSurfaceSupportKHR) {
      result = dispatch_table.GetPhysicalDeviceSurfaceSupportKHR(physicalDevice, queueFamilyIndex, surface, pSupported);
    }
    return result; 
  }
  
  VKAPI_ATTR VkResult VKAPI_CALL GetPhysicalDeviceSurfaceCapabilitiesKHR(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface, VkSurfaceCapabilitiesKHR* pSurfaceCapabilities)
  {
    auto &dispatch_table = *GetInstanceDispatchTable(physicalDevice);
    VkResult result = VkResult::VK_SUCCESS; 
  
    if (dispatch_table.GetPhysicalDeviceSurfaceCapabilitiesKHR) {
      result = dispatch_table.GetPhysicalDeviceSurfaceCapabilitiesKHR(physicalDevice, surface, pSurfaceCapabilities);
    }
    return result; 
  }
  
  VKAPI_ATTR VkResult VKAPI_CALL GetPhysicalDeviceSurfaceFormatsKHR(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface, uint32_t* pSurfaceFormatCount, VkSurfaceFormatKHR* pSurfaceFormats)
  {
    auto &dispatch_table = *GetInstanceDispatchTable(physicalDevice);
    VkResult result = VkResult::VK_SUCCESS; 
  
    if (dispatch_table.GetPhysicalDeviceSurfaceFormatsKHR) {
      result = dispatch_table.GetPhysicalDeviceSurfaceFormatsKHR(physicalDevice, surface, pSurfaceFormatCount, pSurfaceFormats);
    }
    return result; 
  }
  
  VKAPI_ATTR VkResult VKAPI_CALL GetPhysicalDeviceSurfacePresentModesKHR(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface, uint32_t* pPresentModeCount, VkPresentModeKHR* pPresentModes)
  {
    auto &dispatch_table = *GetInstanceDispatchTable(physicalDevice);
    VkResult result = VkResult::VK_SUCCESS; 
  
    if (dispatch_table.GetPhysicalDeviceSurfacePresentModesKHR) {
      result = dispatch_table.GetPhysicalDeviceSurfacePresentModesKHR(physicalDevice, surface, pPresentModeCount, pPresentModes);
    }
    return result; 
  }
  
  VKAPI_ATTR VkResult VKAPI_CALL CreateSwapchainKHR(VkDevice device, VkSwapchainCreateInfoKHR const* pCreateInfo, AllocationCallbacks pAllocator, VkSwapchainKHR* pSwapchain)
  {
    auto &dispatch_table = *GetDeviceDispatchTable(device);
    VkResult result = VkResult::VK_SUCCESS; 
  
    if (dispatch_table.CreateSwapchainKHR) {
      result = dispatch_table.CreateSwapchainKHR(device, pCreateInfo, pAllocator, pSwapchain);
    }
    return result; 
  }
  
  VKAPI_ATTR void VKAPI_CALL DestroySwapchainKHR(VkDevice device, VkSwapchainKHR swapchain, AllocationCallbacks pAllocator)
  {
    auto &dispatch_table = *GetDeviceDispatchTable(device);
  
    if (dispatch_table.DestroySwapchainKHR) {
      dispatch_table.DestroySwapchainKHR(device, swapchain, pAllocator);
    }
  }
  
  VKAPI_ATTR VkResult VKAPI_CALL GetSwapchainImagesKHR(VkDevice device, VkSwapchainKHR swapchain, uint32_t* pSwapchainImageCount, VkImage* pSwapchainImages)
  {
    auto &dispatch_table = *GetDeviceDispatchTable(device);
    VkResult result = VkResult::VK_SUCCESS; 
  
    if (dispatch_table.GetSwapchainImagesKHR) {
      result = dispatch_table.GetSwapchainImagesKHR(device, swapchain, pSwapchainImageCount, pSwapchainImages);
    }
    return result; 
  }
  
  VKAPI_ATTR VkResult VKAPI_CALL AcquireNextImageKHR(VkDevice device, VkSwapchainKHR swapchain, uint64_t timeout, VkSemaphore semaphore, VkFence fence, uint32_t* pImageIndex)
  {
    auto &dispatch_table = *GetDeviceDispatchTable(device);
    VkResult result = VkResult::VK_SUCCESS; 
  
    if (dispatch_table.AcquireNextImageKHR) {
      result = dispatch_table.AcquireNextImageKHR(device, swapchain, timeout, semaphore, fence, pImageIndex);
    }
  
    GetInterceptor()->PostAcquireNextImageKHR(device, swapchain, timeout, semaphore, fence, pImageIndex, result);
    return result; 
  }
  
  VKAPI_ATTR VkResult VKAPI_CALL QueuePresentKHR(VkQueue queue, VkPresentInfoKHR const* pPresentInfo)
  {
    auto &dispatch_table = *GetDeviceDispatchTable(queue);
    VkResult result = VkResult::VK_SUCCESS; 
  
    if (dispatch_table.QueuePresentKHR) {
      result = dispatch_table.QueuePresentKHR(queue, pPresentInfo);
    }
  
    GetInterceptor()->PostQueuePresentKHR(queue, pPresentInfo, result);
    return result; 
  }
  
  VKAPI_ATTR VkResult VKAPI_CALL SignalSemaphoreKHR(VkDevice device, VkSemaphoreSignalInfoKHR const* pSignalInfo)
  {
    auto &dispatch_table = *GetDeviceDispatchTable(device);
    VkResult result = VkResult::VK_SUCCESS; 
  
    if (dispatch_table.SignalSemaphoreKHR) {
      result = dispatch_table.SignalSemaphoreKHR(device, pSignalInfo);
    }
  
    GetInterceptor()->PostSignalSemaphoreKHR(device, pSignalInfo, result);
    return result; 
  }
  
  VKAPI_ATTR VkResult VKAPI_CALL WaitSemaphoresKHR(VkDevice device, VkSemaphoreWaitInfoKHR const* pWaitInfo, uint64_t timeout)
  {
    auto &dispatch_table = *GetDeviceDispatchTable(device);
    VkResult result = VkResult::VK_SUCCESS; 
  
    result = GetInterceptor()->PreWaitSemaphoresKHR(device, pWaitInfo, timeout);
  
    if (dispatch_table.WaitSemaphoresKHR) {
      result = dispatch_table.WaitSemaphoresKHR(device, pWaitInfo, timeout);
    }
  
    GetInterceptor()->PostWaitSemaphoresKHR(device, pWaitInfo, timeout, result);
    return result; 
  }
  
  VKAPI_ATTR VkResult VKAPI_CALL GetSemaphoreCounterValueKHR(VkDevice device, VkSemaphore semaphore, uint64_t* pValue)
  {
    auto &dispatch_table = *GetDeviceDispatchTable(device);
    VkResult result = VkResult::VK_SUCCESS; 
  
    if (dispatch_table.GetSemaphoreCounterValueKHR) {
      result = dispatch_table.GetSemaphoreCounterValueKHR(device, semaphore, pValue);
    }
  
    GetInterceptor()->PostGetSemaphoreCounterValueKHR(device, semaphore, pValue, result);
    return result; 
  }
  
  // Vulkan function to intercepted function table
  const std::unordered_map<std::string, void *> name_to_funcptr_map {
    {"vkGetDeviceProcAddr", (void *)GetDeviceProcAddr },
    {"vkCreateDevice", (void *)CreateDevice },
    {"vkDestroyDevice", (void *)DestroyDevice },
    {"vkCreateInstance", (void *)CreateInstance },
    {"vkDestroyInstance", (void *)DestroyInstance },
    {"vkGetInstanceProcAddr", (void *)GetInstanceProcAddr },
    {"vkEnumerateInstanceExtensionProperties", (void *)EnumerateInstanceExtensionProperties },
    {"vkEnumerateInstanceLayerProperties", (void *)EnumerateInstanceLayerProperties },
    {"vkEnumerateDeviceExtensionProperties", (void *)EnumerateDeviceExtensionProperties },
    {"vkEnumerateDeviceLayerProperties", (void *)EnumerateDeviceLayerProperties },
    {"vkCreateBuffer", (void *)CreateBuffer },
    {"vkDestroyBuffer", (void *)DestroyBuffer },
    {"vkCreateBufferView", (void *)CreateBufferView },
    {"vkDestroyBufferView", (void *)DestroyBufferView },
    {"vkBindBufferMemory", (void *)BindBufferMemory },
    {"vkBindBufferMemory2", (void *)BindBufferMemory2 },
    {"vkCreateCommandPool", (void *)CreateCommandPool },
    {"vkDestroyCommandPool", (void *)DestroyCommandPool },
    {"vkResetCommandPool", (void *)ResetCommandPool },
    {"vkAllocateCommandBuffers", (void *)AllocateCommandBuffers },
    {"vkFreeCommandBuffers", (void *)FreeCommandBuffers },
    {"vkBeginCommandBuffer", (void *)BeginCommandBuffer },
    {"vkEndCommandBuffer", (void *)EndCommandBuffer },
    {"vkResetCommandBuffer", (void *)ResetCommandBuffer },
    {"vkCmdExecuteCommands", (void *)CmdExecuteCommands },
    {"vkTrimCommandPool", (void *)TrimCommandPool },
    {"vkCmdCopyBuffer", (void *)CmdCopyBuffer },
    {"vkCmdCopyImage", (void *)CmdCopyImage },
    {"vkCmdBlitImage", (void *)CmdBlitImage },
    {"vkCmdCopyBufferToImage", (void *)CmdCopyBufferToImage },
    {"vkCmdCopyImageToBuffer", (void *)CmdCopyImageToBuffer },
    {"vkCmdUpdateBuffer", (void *)CmdUpdateBuffer },
    {"vkCmdFillBuffer", (void *)CmdFillBuffer },
    {"vkCmdClearColorImage", (void *)CmdClearColorImage },
    {"vkCmdClearDepthStencilImage", (void *)CmdClearDepthStencilImage },
    {"vkCmdClearAttachments", (void *)CmdClearAttachments },
    {"vkCmdResolveImage", (void *)CmdResolveImage },
    {"vkCreateDescriptorSetLayout", (void *)CreateDescriptorSetLayout },
    {"vkDestroyDescriptorSetLayout", (void *)DestroyDescriptorSetLayout },
    {"vkCreateDescriptorPool", (void *)CreateDescriptorPool },
    {"vkDestroyDescriptorPool", (void *)DestroyDescriptorPool },
    {"vkResetDescriptorPool", (void *)ResetDescriptorPool },
    {"vkAllocateDescriptorSets", (void *)AllocateDescriptorSets },
    {"vkFreeDescriptorSets", (void *)FreeDescriptorSets },
    {"vkUpdateDescriptorSets", (void *)UpdateDescriptorSets },
    {"vkCmdBindDescriptorSets", (void *)CmdBindDescriptorSets },
    {"vkCmdPushConstants", (void *)CmdPushConstants },
    {"vkGetDescriptorSetLayoutSupport", (void *)GetDescriptorSetLayoutSupport },
    {"vkDeviceWaitIdle", (void *)DeviceWaitIdle },
    {"vkCmdBindIndexBuffer", (void *)CmdBindIndexBuffer },
    {"vkCmdBindVertexBuffers", (void *)CmdBindVertexBuffers },
    {"vkCmdDraw", (void *)CmdDraw },
    {"vkCmdDrawIndexed", (void *)CmdDrawIndexed },
    {"vkCmdDrawIndirect", (void *)CmdDrawIndirect },
    {"vkCmdDrawIndexedIndirect", (void *)CmdDrawIndexedIndirect },
    {"vkCmdDispatch", (void *)CmdDispatch },
    {"vkCmdDispatchIndirect", (void *)CmdDispatchIndirect },
    {"vkCreateImage", (void *)CreateImage },
    {"vkDestroyImage", (void *)DestroyImage },
    {"vkGetImageSubresourceLayout", (void *)GetImageSubresourceLayout },
    {"vkBindImageMemory", (void *)BindImageMemory },
    {"vkCreateImageView", (void *)CreateImageView },
    {"vkDestroyImageView", (void *)DestroyImageView },
    {"vkCreateSampler", (void *)CreateSampler },
    {"vkDestroySampler", (void *)DestroySampler },
    {"vkBindImageMemory2", (void *)BindImageMemory2 },
    {"vkCreateSamplerYcbcrConversion", (void *)CreateSamplerYcbcrConversion },
    {"vkDestroySamplerYcbcrConversion", (void *)DestroySamplerYcbcrConversion },
    {"vkAllocateMemory", (void *)AllocateMemory },
    {"vkFreeMemory", (void *)FreeMemory },
    {"vkMapMemory", (void *)MapMemory },
    {"vkUnmapMemory", (void *)UnmapMemory },
    {"vkFlushMappedMemoryRanges", (void *)FlushMappedMemoryRanges },
    {"vkInvalidateMappedMemoryRanges", (void *)InvalidateMappedMemoryRanges },
    {"vkGetDeviceMemoryCommitment", (void *)GetDeviceMemoryCommitment },
    {"vkEnumeratePhysicalDevices", (void *)EnumeratePhysicalDevices },
    {"vkCreatePipelineLayout", (void *)CreatePipelineLayout },
    {"vkDestroyPipelineLayout", (void *)DestroyPipelineLayout },
    {"vkCreateGraphicsPipelines", (void *)CreateGraphicsPipelines },
    {"vkCreateComputePipelines", (void *)CreateComputePipelines },
    {"vkDestroyPipeline", (void *)DestroyPipeline },
    {"vkCreateShaderModule", (void *)CreateShaderModule },
    {"vkDestroyShaderModule", (void *)DestroyShaderModule },
    {"vkCreatePipelineCache", (void *)CreatePipelineCache },
    {"vkDestroyPipelineCache", (void *)DestroyPipelineCache },
    {"vkGetPipelineCacheData", (void *)GetPipelineCacheData },
    {"vkMergePipelineCaches", (void *)MergePipelineCaches },
    {"vkCmdBindPipeline", (void *)CmdBindPipeline },
    {"vkCmdSetViewport", (void *)CmdSetViewport },
    {"vkCmdSetScissor", (void *)CmdSetScissor },
    {"vkCmdSetLineWidth", (void *)CmdSetLineWidth },
    {"vkCmdSetDepthBias", (void *)CmdSetDepthBias },
    {"vkCmdSetBlendConstants", (void *)CmdSetBlendConstants },
    {"vkCmdSetDepthBounds", (void *)CmdSetDepthBounds },
    {"vkCmdSetStencilCompareMask", (void *)CmdSetStencilCompareMask },
    {"vkCmdSetStencilWriteMask", (void *)CmdSetStencilWriteMask },
    {"vkCmdSetStencilReference", (void *)CmdSetStencilReference },
    {"vkGetPhysicalDeviceFeatures", (void *)GetPhysicalDeviceFeatures },
    {"vkGetPhysicalDeviceFormatProperties", (void *)GetPhysicalDeviceFormatProperties },
    {"vkGetPhysicalDeviceImageFormatProperties", (void *)GetPhysicalDeviceImageFormatProperties },
    {"vkGetPhysicalDeviceProperties", (void *)GetPhysicalDeviceProperties },
    {"vkGetPhysicalDeviceQueueFamilyProperties", (void *)GetPhysicalDeviceQueueFamilyProperties },
    {"vkGetPhysicalDeviceMemoryProperties", (void *)GetPhysicalDeviceMemoryProperties },
    {"vkGetPhysicalDeviceSparseImageFormatProperties", (void *)GetPhysicalDeviceSparseImageFormatProperties },
    {"vkGetBufferMemoryRequirements", (void *)GetBufferMemoryRequirements },
    {"vkGetImageMemoryRequirements", (void *)GetImageMemoryRequirements },
    {"vkGetImageSparseMemoryRequirements", (void *)GetImageSparseMemoryRequirements },
    {"vkEnumerateInstanceVersion", (void *)EnumerateInstanceVersion },
    {"vkGetPhysicalDeviceFeatures2", (void *)GetPhysicalDeviceFeatures2 },
    {"vkGetPhysicalDeviceFormatProperties2", (void *)GetPhysicalDeviceFormatProperties2 },
    {"vkGetPhysicalDeviceImageFormatProperties2", (void *)GetPhysicalDeviceImageFormatProperties2 },
    {"vkGetPhysicalDeviceProperties2", (void *)GetPhysicalDeviceProperties2 },
    {"vkGetPhysicalDeviceMemoryProperties2", (void *)GetPhysicalDeviceMemoryProperties2 },
    {"vkGetPhysicalDeviceSparseImageFormatProperties2", (void *)GetPhysicalDeviceSparseImageFormatProperties2 },
    {"vkGetPhysicalDeviceQueueFamilyProperties2", (void *)GetPhysicalDeviceQueueFamilyProperties2 },
    {"vkGetPhysicalDeviceExternalBufferProperties", (void *)GetPhysicalDeviceExternalBufferProperties },
    {"vkGetPhysicalDeviceExternalSemaphoreProperties", (void *)GetPhysicalDeviceExternalSemaphoreProperties },
    {"vkGetPhysicalDeviceExternalFenceProperties", (void *)GetPhysicalDeviceExternalFenceProperties },
    {"vkGetBufferMemoryRequirements2", (void *)GetBufferMemoryRequirements2 },
    {"vkGetImageMemoryRequirements2", (void *)GetImageMemoryRequirements2 },
    {"vkGetImageSparseMemoryRequirements2", (void *)GetImageSparseMemoryRequirements2 },
    {"vkCreateQueryPool", (void *)CreateQueryPool },
    {"vkDestroyQueryPool", (void *)DestroyQueryPool },
    {"vkGetQueryPoolResults", (void *)GetQueryPoolResults },
    {"vkCmdBeginQuery", (void *)CmdBeginQuery },
    {"vkCmdEndQuery", (void *)CmdEndQuery },
    {"vkCmdResetQueryPool", (void *)CmdResetQueryPool },
    {"vkCmdWriteTimestamp", (void *)CmdWriteTimestamp },
    {"vkCmdCopyQueryPoolResults", (void *)CmdCopyQueryPoolResults },
    {"vkGetDeviceQueue", (void *)GetDeviceQueue },
    {"vkGetDeviceQueue2", (void *)GetDeviceQueue2 },
    {"vkQueueSubmit", (void *)QueueSubmit },
    {"vkQueueWaitIdle", (void *)QueueWaitIdle },
    {"vkQueueBindSparse", (void *)QueueBindSparse },
    {"vkCreateFramebuffer", (void *)CreateFramebuffer },
    {"vkDestroyFramebuffer", (void *)DestroyFramebuffer },
    {"vkCreateRenderPass", (void *)CreateRenderPass },
    {"vkDestroyRenderPass", (void *)DestroyRenderPass },
    {"vkGetRenderAreaGranularity", (void *)GetRenderAreaGranularity },
    {"vkCmdBeginRenderPass", (void *)CmdBeginRenderPass },
    {"vkCmdNextSubpass", (void *)CmdNextSubpass },
    {"vkCmdEndRenderPass", (void *)CmdEndRenderPass },
    {"vkCreateFence", (void *)CreateFence },
    {"vkDestroyFence", (void *)DestroyFence },
    {"vkResetFences", (void *)ResetFences },
    {"vkGetFenceStatus", (void *)GetFenceStatus },
    {"vkWaitForFences", (void *)WaitForFences },
    {"vkCreateSemaphore", (void *)CreateSemaphore },
    {"vkDestroySemaphore", (void *)DestroySemaphore },
    {"vkCreateEvent", (void *)CreateEvent },
    {"vkDestroyEvent", (void *)DestroyEvent },
    {"vkGetEventStatus", (void *)GetEventStatus },
    {"vkSetEvent", (void *)SetEvent },
    {"vkResetEvent", (void *)ResetEvent },
    {"vkCmdSetEvent", (void *)CmdSetEvent },
    {"vkCmdResetEvent", (void *)CmdResetEvent },
    {"vkCmdWaitEvents", (void *)CmdWaitEvents },
    {"vkCmdPipelineBarrier", (void *)CmdPipelineBarrier },
    {"vkCmdWriteBufferMarkerAMD", (void *)CmdWriteBufferMarkerAMD },
    {"vkCmdDrawIndirectCountAMD", (void *)CmdDrawIndirectCountAMD },
    {"vkCmdDrawIndexedIndirectCountAMD", (void *)CmdDrawIndexedIndirectCountAMD },
    {"vkDebugMarkerSetObjectTagEXT", (void *)DebugMarkerSetObjectTagEXT },
    {"vkDebugMarkerSetObjectNameEXT", (void *)DebugMarkerSetObjectNameEXT },
    {"vkCmdDebugMarkerBeginEXT", (void *)CmdDebugMarkerBeginEXT },
    {"vkCmdDebugMarkerEndEXT", (void *)CmdDebugMarkerEndEXT },
    {"vkCmdDebugMarkerInsertEXT", (void *)CmdDebugMarkerInsertEXT },
    {"vkCreateDebugReportCallbackEXT", (void *)CreateDebugReportCallbackEXT },
    {"vkDestroyDebugReportCallbackEXT", (void *)DestroyDebugReportCallbackEXT },
    {"vkDebugReportMessageEXT", (void *)DebugReportMessageEXT },
    {"vkSetDebugUtilsObjectNameEXT", (void *)SetDebugUtilsObjectNameEXT },
    {"vkSetDebugUtilsObjectTagEXT", (void *)SetDebugUtilsObjectTagEXT },
    {"vkCmdBeginDebugUtilsLabelEXT", (void *)CmdBeginDebugUtilsLabelEXT },
    {"vkCmdEndDebugUtilsLabelEXT", (void *)CmdEndDebugUtilsLabelEXT },
    {"vkCmdInsertDebugUtilsLabelEXT", (void *)CmdInsertDebugUtilsLabelEXT },
    {"vkQueueBeginDebugUtilsLabelEXT", (void *)QueueBeginDebugUtilsLabelEXT },
    {"vkQueueEndDebugUtilsLabelEXT", (void *)QueueEndDebugUtilsLabelEXT },
    {"vkQueueInsertDebugUtilsLabelEXT", (void *)QueueInsertDebugUtilsLabelEXT },
    {"vkCreateDebugUtilsMessengerEXT", (void *)CreateDebugUtilsMessengerEXT },
    {"vkDestroyDebugUtilsMessengerEXT", (void *)DestroyDebugUtilsMessengerEXT },
    {"vkSubmitDebugUtilsMessageEXT", (void *)SubmitDebugUtilsMessageEXT },
    {"vkSetHdrMetadataEXT", (void *)SetHdrMetadataEXT },
    {"vkResetQueryPoolEXT", (void *)ResetQueryPoolEXT },
    {"vkGetRefreshCycleDurationGOOGLE", (void *)GetRefreshCycleDurationGOOGLE },
    {"vkGetPastPresentationTimingGOOGLE", (void *)GetPastPresentationTimingGOOGLE },
    {"vkBindBufferMemory2KHR", (void *)BindBufferMemory2KHR },
    {"vkBindImageMemory2KHR", (void *)BindImageMemory2KHR },
    {"vkCreateDescriptorUpdateTemplateKHR", (void *)CreateDescriptorUpdateTemplateKHR },
    {"vkDestroyDescriptorUpdateTemplateKHR", (void *)DestroyDescriptorUpdateTemplateKHR },
    {"vkUpdateDescriptorSetWithTemplateKHR", (void *)UpdateDescriptorSetWithTemplateKHR },
    {"vkCreateDescriptorUpdateTemplate", (void *)CreateDescriptorUpdateTemplate },
    {"vkDestroyDescriptorUpdateTemplate", (void *)DestroyDescriptorUpdateTemplate },
    {"vkUpdateDescriptorSetWithTemplate", (void *)UpdateDescriptorSetWithTemplate },
    {"vkGetDeviceGroupPeerMemoryFeaturesKHR", (void *)GetDeviceGroupPeerMemoryFeaturesKHR },
    {"vkGetDeviceGroupPeerMemoryFeatures", (void *)GetDeviceGroupPeerMemoryFeatures },
    {"vkCmdSetDeviceMaskKHR", (void *)CmdSetDeviceMaskKHR },
    {"vkCmdSetDeviceMask", (void *)CmdSetDeviceMask },
    {"vkCmdDispatchBaseKHR", (void *)CmdDispatchBaseKHR },
    {"vkCmdDispatchBase", (void *)CmdDispatchBase },
    {"vkGetDeviceGroupPresentCapabilitiesKHR", (void *)GetDeviceGroupPresentCapabilitiesKHR },
    {"vkGetDeviceGroupSurfacePresentModesKHR", (void *)GetDeviceGroupSurfacePresentModesKHR },
    {"vkGetPhysicalDevicePresentRectanglesKHR", (void *)GetPhysicalDevicePresentRectanglesKHR },
    {"vkAcquireNextImage2KHR", (void *)AcquireNextImage2KHR },
    {"vkEnumeratePhysicalDeviceGroupsKHR", (void *)EnumeratePhysicalDeviceGroupsKHR },
    {"vkEnumeratePhysicalDeviceGroups", (void *)EnumeratePhysicalDeviceGroups },
    {"vkGetPhysicalDeviceDisplayPropertiesKHR", (void *)GetPhysicalDeviceDisplayPropertiesKHR },
    {"vkGetPhysicalDeviceDisplayPlanePropertiesKHR", (void *)GetPhysicalDeviceDisplayPlanePropertiesKHR },
    {"vkGetDisplayPlaneSupportedDisplaysKHR", (void *)GetDisplayPlaneSupportedDisplaysKHR },
    {"vkGetDisplayModePropertiesKHR", (void *)GetDisplayModePropertiesKHR },
    {"vkCreateDisplayModeKHR", (void *)CreateDisplayModeKHR },
    {"vkGetDisplayPlaneCapabilitiesKHR", (void *)GetDisplayPlaneCapabilitiesKHR },
    {"vkCreateDisplayPlaneSurfaceKHR", (void *)CreateDisplayPlaneSurfaceKHR },
    {"vkCreateSharedSwapchainsKHR", (void *)CreateSharedSwapchainsKHR },
    {"vkCmdDrawIndirectCountKHR", (void *)CmdDrawIndirectCountKHR },
    {"vkCmdDrawIndexedIndirectCountKHR", (void *)CmdDrawIndexedIndirectCountKHR },
    {"vkGetPhysicalDeviceExternalFencePropertiesKHR", (void *)GetPhysicalDeviceExternalFencePropertiesKHR },
    {"vkGetPhysicalDeviceExternalBufferPropertiesKHR", (void *)GetPhysicalDeviceExternalBufferPropertiesKHR },
    {"vkGetPhysicalDeviceExternalSemaphorePropertiesKHR", (void *)GetPhysicalDeviceExternalSemaphorePropertiesKHR },
    {"vkGetImageMemoryRequirements2KHR", (void *)GetImageMemoryRequirements2KHR },
    {"vkGetBufferMemoryRequirements2KHR", (void *)GetBufferMemoryRequirements2KHR },
    {"vkGetImageSparseMemoryRequirements2KHR", (void *)GetImageSparseMemoryRequirements2KHR },
    {"vkGetPhysicalDeviceFeatures2KHR", (void *)GetPhysicalDeviceFeatures2KHR },
    {"vkGetPhysicalDeviceProperties2KHR", (void *)GetPhysicalDeviceProperties2KHR },
    {"vkGetPhysicalDeviceFormatProperties2KHR", (void *)GetPhysicalDeviceFormatProperties2KHR },
    {"vkGetPhysicalDeviceImageFormatProperties2KHR", (void *)GetPhysicalDeviceImageFormatProperties2KHR },
    {"vkGetPhysicalDeviceQueueFamilyProperties2KHR", (void *)GetPhysicalDeviceQueueFamilyProperties2KHR },
    {"vkGetPhysicalDeviceMemoryProperties2KHR", (void *)GetPhysicalDeviceMemoryProperties2KHR },
    {"vkGetPhysicalDeviceSparseImageFormatProperties2KHR", (void *)GetPhysicalDeviceSparseImageFormatProperties2KHR },
    {"vkGetPhysicalDeviceSurfaceCapabilities2KHR", (void *)GetPhysicalDeviceSurfaceCapabilities2KHR },
    {"vkGetPhysicalDeviceSurfaceFormats2KHR", (void *)GetPhysicalDeviceSurfaceFormats2KHR },
    {"vkTrimCommandPoolKHR", (void *)TrimCommandPoolKHR },
    {"vkGetDescriptorSetLayoutSupportKHR", (void *)GetDescriptorSetLayoutSupportKHR },
    {"vkCreateSamplerYcbcrConversionKHR", (void *)CreateSamplerYcbcrConversionKHR },
    {"vkDestroySamplerYcbcrConversionKHR", (void *)DestroySamplerYcbcrConversionKHR },
    {"vkDestroySurfaceKHR", (void *)DestroySurfaceKHR },
    {"vkGetPhysicalDeviceSurfaceSupportKHR", (void *)GetPhysicalDeviceSurfaceSupportKHR },
    {"vkGetPhysicalDeviceSurfaceCapabilitiesKHR", (void *)GetPhysicalDeviceSurfaceCapabilitiesKHR },
    {"vkGetPhysicalDeviceSurfaceFormatsKHR", (void *)GetPhysicalDeviceSurfaceFormatsKHR },
    {"vkGetPhysicalDeviceSurfacePresentModesKHR", (void *)GetPhysicalDeviceSurfacePresentModesKHR },
    {"vkCreateSwapchainKHR", (void *)CreateSwapchainKHR },
    {"vkDestroySwapchainKHR", (void *)DestroySwapchainKHR },
    {"vkGetSwapchainImagesKHR", (void *)GetSwapchainImagesKHR },
    {"vkAcquireNextImageKHR", (void *)AcquireNextImageKHR },
    {"vkQueuePresentKHR", (void *)QueuePresentKHR },
    {"vkSignalSemaphoreKHR", (void *)SignalSemaphoreKHR },
    {"vkWaitSemaphoresKHR", (void *)WaitSemaphoresKHR },
    {"vkGetSemaphoreCounterValueKHR", (void *)GetSemaphoreCounterValueKHR },
  };
  
  // Manually written functions, generated as part of template
  
  VKAPI_ATTR VkResult VKAPI_CALL EnumerateInstanceLayerProperties(uint32_t* pPropertyCount, VkLayerProperties* pProperties)
  {
    if (nullptr == pProperties) {
      *pPropertyCount = 1;
      return VK_SUCCESS;
    }
    if (*pPropertyCount < 1) {
      return VK_INCOMPLETE;
    }
    *pProperties = g_layer_properties;
    return VK_SUCCESS;
  }
  
  VKAPI_ATTR VkResult VKAPI_CALL EnumerateInstanceExtensionProperties(char const* pLayerName, uint32_t* pPropertyCount, VkExtensionProperties* pProperties)
  {
    bool layer_requested = (nullptr == pLayerName || strcmp(pLayerName, g_layer_properties.layerName));
    if (!layer_requested) {
      return VK_ERROR_LAYER_NOT_PRESENT;
    }
    if (nullptr == pProperties) {
      *pPropertyCount += (uint32_t)g_instance_extensions.size();
      return VK_SUCCESS;
    }
    else if (*pPropertyCount > 0)
    {
      *pPropertyCount = (uint32_t)g_instance_extensions.size();
      memcpy(pProperties, g_instance_extensions.data(), g_instance_extensions.size() * sizeof(VkExtensionProperties) );
    }
    return VK_SUCCESS;
  }
  
  VKAPI_ATTR VkResult VKAPI_CALL EnumerateDeviceLayerProperties(VkPhysicalDevice physicalDevice, uint32_t* pPropertyCount, VkLayerProperties* pProperties)
  {
    if (nullptr == pProperties) {
      *pPropertyCount = 1;
      return VK_SUCCESS;
    }
    if (*pPropertyCount < 1) {
      return VK_INCOMPLETE;
    }
    *pProperties = g_layer_properties;
    return VK_SUCCESS;
  }
  
  VKAPI_ATTR VkResult VKAPI_CALL EnumerateDeviceExtensionProperties(VkPhysicalDevice physicalDevice, char const* pLayerName, uint32_t* pPropertyCount, VkExtensionProperties* pProperties)
  {
    bool layer_requested = (nullptr == pLayerName || strcmp(pLayerName, g_layer_properties.layerName));
    // not just our layer, we expose all our extensions
    uint32_t max_extensions = *pPropertyCount;
    // we want to append our extensions, removing duplicates
    InstanceLayerData* instance_data = GetInstanceLayerData(
    get_dispatch_key(physicalDevice));
    uint32_t num_other_extensions = 0;
    VkResult result =
    instance_data->dispatch_table.EnumerateDeviceExtensionProperties(
    physicalDevice, nullptr, &num_other_extensions, nullptr);
    if (result != VK_SUCCESS) {
      return result;
    }
    // call down to get other device properties
    std::vector<VkExtensionProperties> extensions(num_other_extensions);
    result = instance_data->dispatch_table.EnumerateDeviceExtensionProperties(
    physicalDevice, pLayerName, &num_other_extensions, &extensions[0]);
    // add our extensions if requested
    if (result == VK_SUCCESS && layer_requested) {
      // set and copy base extensions
      *pPropertyCount = num_other_extensions;
      if (pProperties != nullptr) {
        memcpy(pProperties, &extensions[0],
        num_other_extensions * sizeof(VkExtensionProperties));
      }
      // find our unique extensions that need to be added
      uint32_t num_additional_extensions = 0;
      auto num_device_extensions = g_device_extensions.size();
      std::vector<const VkExtensionProperties*> additional_extensions(num_device_extensions);
      for (size_t i = 0; i < num_device_extensions; ++i) {
        bool is_unique_extension = true;
        for (size_t j = 0; j < num_other_extensions; ++j) {
          if (0 == strcmp(extensions[j].extensionName,
          g_device_extensions[i].extensionName)) {
            is_unique_extension = false;
            break;
          }
        }
        if (is_unique_extension) {
          additional_extensions[num_additional_extensions++] = &g_device_extensions[i];
        }
      }
      // null properties, just count total extensions
      if (nullptr == pProperties) {
        *pPropertyCount += num_additional_extensions;
      } else {
        uint32_t numExtensions = num_other_extensions;
        for (size_t i = 0; i < num_additional_extensions && numExtensions < max_extensions; ++i) {
          pProperties[numExtensions++] = *additional_extensions[i];
        }
        *pPropertyCount = numExtensions;
        // not enough space for all extensions
        if (num_other_extensions + num_additional_extensions > max_extensions) {
          return VK_INCOMPLETE;
        }
      }
    }
    return result;
  }
  
  VKAPI_ATTR VkResult VKAPI_CALL CreateInstance(const VkInstanceCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator,
  VkInstance *pInstance) {
    VkLayerInstanceCreateInfo *chain_info = GetLoaderInstanceInfo(pCreateInfo, VK_LAYER_LINK_INFO);
  
    assert(chain_info->u.pLayerInfo);
    PFN_vkGetInstanceProcAddr fpGetInstanceProcAddr = chain_info->u.pLayerInfo->pfnNextGetInstanceProcAddr;
    PFN_vkCreateInstance fpCreateInstance = (PFN_vkCreateInstance)fpGetInstanceProcAddr(NULL, "vkCreateInstance");
    if (fpCreateInstance == NULL) return VK_ERROR_INITIALIZATION_FAILED;
    chain_info->u.pLayerInfo = chain_info->u.pLayerInfo->pNext;
  
    // Init dispatch array and call registration functions
    GetInterceptor()->PreCreateInstance(pCreateInfo, pAllocator, pInstance);
  
    const VkInstanceCreateInfo* instance_create_info = GetInterceptor()->GetModifiedInstanceCreateInfo(pCreateInfo);
    VkResult result = fpCreateInstance(instance_create_info, pAllocator, pInstance);
  
    InstanceLayerData *instance_data = GetInstanceLayerData(get_dispatch_key(*pInstance));
    instance_data->instance = *pInstance;
  
    chain_info = GetLoaderInstanceInfo(instance_create_info, VK_LOADER_DATA_CALLBACK);
    instance_data->SetInstanceLoaderData = chain_info->u.pfnSetInstanceLoaderData;
  
    layer_init_instance_dispatch_table(*pInstance, &instance_data->dispatch_table, fpGetInstanceProcAddr);
  
    GetInterceptor()->PostCreateInstance(instance_create_info, pAllocator, pInstance, result);
  
    return result;
  }
  
  VKAPI_ATTR void VKAPI_CALL DestroyInstance(VkInstance instance, const VkAllocationCallbacks *pAllocator) {
    dispatch_key key = get_dispatch_key(instance);
    InstanceLayerData *instance_data = GetInstanceLayerData(key);
  
    GetInterceptor()->PreDestroyInstance(instance, pAllocator);
  
    instance_data->dispatch_table.DestroyInstance(instance, pAllocator);
  
    std::unique_lock<std::mutex> lock(g_lock);
    GetInterceptor()->PostDestroyInstance(instance, pAllocator);
    FreeInstanceLayerData(key);
  }
  
  VKAPI_ATTR VkResult VKAPI_CALL CreateDevice(VkPhysicalDevice gpu, const VkDeviceCreateInfo *pCreateInfo,
  const VkAllocationCallbacks *pAllocator, VkDevice *pDevice) {
    InstanceLayerData *instance_data = GetInstanceLayerData(get_dispatch_key(gpu));
  
    std::unique_lock<std::mutex> lock(g_lock);
    VkLayerDeviceCreateInfo *chain_info = GetLoaderDeviceInfo(pCreateInfo, VK_LAYER_LINK_INFO);
    PFN_vkGetInstanceProcAddr fpGetInstanceProcAddr = chain_info->u.pLayerInfo->pfnNextGetInstanceProcAddr;
    PFN_vkGetDeviceProcAddr fpGetDeviceProcAddr = chain_info->u.pLayerInfo->pfnNextGetDeviceProcAddr;
    PFN_vkCreateDevice fpCreateDevice = (PFN_vkCreateDevice)fpGetInstanceProcAddr(instance_data->instance, "vkCreateDevice");
    chain_info->u.pLayerInfo = chain_info->u.pLayerInfo->pNext;
  
    GetInterceptor()->PreCreateDevice(gpu, pCreateInfo, pAllocator, pDevice);
    const VkDeviceCreateInfo* device_create_info = GetInterceptor()->GetModifiedDeviceCreateInfo(gpu, pCreateInfo);
    lock.unlock();
    // Force coherent memory
    VkDeviceCreateInfo local_create_info = *device_create_info;
  
    VkPhysicalDeviceCoherentMemoryFeaturesAMD enableDeviceCoherentMemoryFeature{};
    enableDeviceCoherentMemoryFeature.deviceCoherentMemory = true;
    enableDeviceCoherentMemoryFeature.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COHERENT_MEMORY_FEATURES_AMD;
    enableDeviceCoherentMemoryFeature.pNext = (void *)device_create_info->pNext;
    local_create_info.pNext = &enableDeviceCoherentMemoryFeature;
  
    VkResult result = fpCreateDevice(gpu, &local_create_info, pAllocator, pDevice);
  
    lock.lock();
    DeviceLayerData *device_data = GetDeviceLayerData(get_dispatch_key(*pDevice));
  
    chain_info = GetLoaderDeviceInfo(device_create_info, VK_LOADER_DATA_CALLBACK);
    device_data->SetDeviceLoaderData = chain_info->u.pfnSetDeviceLoaderData;
  
    device_data->instance_data = instance_data;
    layer_init_device_dispatch_table(*pDevice, &device_data->dispatch_table, fpGetDeviceProcAddr);
    device_data->device = *pDevice;
    device_data->physical_device = gpu;
  
    GetInterceptor()->PostCreateDevice(gpu, device_create_info, pAllocator, pDevice, result);
    lock.unlock();
  
    return result;
  }
  
  VKAPI_ATTR void VKAPI_CALL DestroyDevice(VkDevice device, const VkAllocationCallbacks *pAllocator) {
    dispatch_key key = get_dispatch_key(device);
    DeviceLayerData *device_data = GetDeviceLayerData(key);
    std::unique_lock<std::mutex> lock(g_lock);
    GetInterceptor()->PreDestroyDevice(device, pAllocator);
    lock.unlock();
    device_data->dispatch_table.DestroyDevice(device, pAllocator);
    lock.lock();
    GetInterceptor()->PostDestroyDevice(device, pAllocator);
    FreeDeviceLayerData(key);
    lock.unlock();
  }
  
  VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL GetInstanceProcAddr(VkInstance instance, const char *funcName) {
    InstanceLayerData *instance_data;
    const auto &item = name_to_funcptr_map.find(funcName);
    if (item != name_to_funcptr_map.end()) {
      return reinterpret_cast<PFN_vkVoidFunction>(item->second);
    }
    instance_data =
    GetInstanceLayerData(get_dispatch_key(instance));
    auto &table = instance_data->dispatch_table;
    if (!table.GetInstanceProcAddr) {
      return nullptr;
    }
    return table.GetInstanceProcAddr(instance, funcName);
  }
  
  VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL GetDeviceProcAddr(VkDevice device, const char *funcName) {
    assert(device);
    DeviceLayerData *device_data =
    GetDeviceLayerData(get_dispatch_key(device));
    const auto &item = name_to_funcptr_map.find(funcName);
    if (item != name_to_funcptr_map.end()) {
      return reinterpret_cast<PFN_vkVoidFunction>(item->second);
    }
    auto &table = device_data->dispatch_table;
    if (!table.GetDeviceProcAddr) {
      return nullptr;
    }
    return table.GetDeviceProcAddr(device, funcName);
  }
  
  } // namespace intercept
  
  // Main entry points, layer specific
  
  #ifdef WIN32
  #define DLL_EXPORT __declspec(dllexport)
  #else
  #define DLL_EXPORT
  #endif
  
  extern "C" DLL_EXPORT VK_LAYER_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL
  GFR_GetInstanceProcAddr(VkInstance instance, const char *funcName) {
  return intercept::GetInstanceProcAddr(instance, funcName);
  }
  
  extern "C" DLL_EXPORT VK_LAYER_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL
  GFR_GetDeviceProcAddr(VkDevice device, const char *funcName) {
  return intercept::GetDeviceProcAddr(device, funcName);
  }
  
  extern "C" DLL_EXPORT VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
  GFR_NegotiateLoaderLayerInterfaceVersion(
  VkNegotiateLayerInterface *pVersionStruct) {
  assert(pVersionStruct != NULL);
  assert(pVersionStruct->sType == LAYER_NEGOTIATE_INTERFACE_STRUCT);
  // Fill in the function pointers if our version is at least capable of having
  // the structure contain them.
  if (pVersionStruct->loaderLayerInterfaceVersion >= 2) {
    pVersionStruct->pfnGetInstanceProcAddr = &GFR_GetInstanceProcAddr;
    pVersionStruct->pfnGetDeviceProcAddr = &GFR_GetDeviceProcAddr;
    pVersionStruct->pfnGetPhysicalDeviceProcAddr = nullptr;
  }
  if (pVersionStruct->loaderLayerInterfaceVersion > CURRENT_LOADER_LAYER_INTERFACE_VERSION) {
    pVersionStruct->loaderLayerInterfaceVersion = CURRENT_LOADER_LAYER_INTERFACE_VERSION;
  }
  return VK_SUCCESS;
  }