Index: NewOpenGLGame.sln
===================================================================
--- NewOpenGLGame.sln	(revision 681dbe83d28e697c52cef20ee1270155282adab1)
+++ NewOpenGLGame.sln	(revision 57d43d021f973604403220624950c82a9c67ae6e)
@@ -10,5 +10,7 @@
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "VulkanGame", "VulkanGame.vcxproj", "{3489E223-6118-49E3-98F3-8887B68AC32F}"
 EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "OpenGLGame", "OpenGLGame.vcxproj", "{569037E7-4D03-4412-8CC1-DE51435C0BBE}"
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "OpenGLGame", "OpenGLGame.vcxproj", "{7BED9D8B-405D-4051-B872-7090AA360091}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "VulkanSFMLReference", "VulkanSFMLReference.vcxproj", "{91D47623-20F5-429C-911C-96D0422927F0}"
 EndProject
 Global
@@ -44,12 +46,20 @@
 		{3489E223-6118-49E3-98F3-8887B68AC32F}.Release|x86.ActiveCfg = Release|Win32
 		{3489E223-6118-49E3-98F3-8887B68AC32F}.Release|x86.Build.0 = Release|Win32
-		{569037E7-4D03-4412-8CC1-DE51435C0BBE}.Debug|x64.ActiveCfg = Debug|x64
-		{569037E7-4D03-4412-8CC1-DE51435C0BBE}.Debug|x64.Build.0 = Debug|x64
-		{569037E7-4D03-4412-8CC1-DE51435C0BBE}.Debug|x86.ActiveCfg = Debug|Win32
-		{569037E7-4D03-4412-8CC1-DE51435C0BBE}.Debug|x86.Build.0 = Debug|Win32
-		{569037E7-4D03-4412-8CC1-DE51435C0BBE}.Release|x64.ActiveCfg = Release|x64
-		{569037E7-4D03-4412-8CC1-DE51435C0BBE}.Release|x64.Build.0 = Release|x64
-		{569037E7-4D03-4412-8CC1-DE51435C0BBE}.Release|x86.ActiveCfg = Release|Win32
-		{569037E7-4D03-4412-8CC1-DE51435C0BBE}.Release|x86.Build.0 = Release|Win32
+		{7BED9D8B-405D-4051-B872-7090AA360091}.Debug|x64.ActiveCfg = Debug|x64
+		{7BED9D8B-405D-4051-B872-7090AA360091}.Debug|x64.Build.0 = Debug|x64
+		{7BED9D8B-405D-4051-B872-7090AA360091}.Debug|x86.ActiveCfg = Debug|Win32
+		{7BED9D8B-405D-4051-B872-7090AA360091}.Debug|x86.Build.0 = Debug|Win32
+		{7BED9D8B-405D-4051-B872-7090AA360091}.Release|x64.ActiveCfg = Release|x64
+		{7BED9D8B-405D-4051-B872-7090AA360091}.Release|x64.Build.0 = Release|x64
+		{7BED9D8B-405D-4051-B872-7090AA360091}.Release|x86.ActiveCfg = Release|Win32
+		{7BED9D8B-405D-4051-B872-7090AA360091}.Release|x86.Build.0 = Release|Win32
+		{91D47623-20F5-429C-911C-96D0422927F0}.Debug|x64.ActiveCfg = Debug|x64
+		{91D47623-20F5-429C-911C-96D0422927F0}.Debug|x64.Build.0 = Debug|x64
+		{91D47623-20F5-429C-911C-96D0422927F0}.Debug|x86.ActiveCfg = Debug|Win32
+		{91D47623-20F5-429C-911C-96D0422927F0}.Debug|x86.Build.0 = Debug|Win32
+		{91D47623-20F5-429C-911C-96D0422927F0}.Release|x64.ActiveCfg = Release|x64
+		{91D47623-20F5-429C-911C-96D0422927F0}.Release|x64.Build.0 = Release|x64
+		{91D47623-20F5-429C-911C-96D0422927F0}.Release|x86.ActiveCfg = Release|Win32
+		{91D47623-20F5-429C-911C-96D0422927F0}.Release|x86.Build.0 = Release|Win32
 	EndGlobalSection
 	GlobalSection(SolutionProperties) = preSolution
Index: Vulkan.cpp
===================================================================
--- Vulkan.cpp	(revision 57d43d021f973604403220624950c82a9c67ae6e)
+++ Vulkan.cpp	(revision 57d43d021f973604403220624950c82a9c67ae6e)
@@ -0,0 +1,2557 @@
+
+////////////////////////////////////////////////////////////
+// Headers
+////////////////////////////////////////////////////////////
+#define GLAD_VULKAN_IMPLEMENTATION
+#include "vulkan.h"
+
+// Include graphics because we use sf::Image for loading images
+#include <SFML/Graphics.hpp>
+
+#include <SFML/Window.hpp>
+#include <vector>
+#include <limits>
+#include <cstring>
+#include <cmath>
+
+
+////////////////////////////////////////////////////////////
+// Helper functions
+////////////////////////////////////////////////////////////
+namespace
+{
+   typedef float Vec3[3];
+   typedef float Matrix[4][4];
+
+   // Multiply 2 matrices
+   void matrixMultiply(Matrix& result, const Matrix& left, const Matrix& right)
+   {
+      Matrix temp;
+
+      for (int i = 0; i < 4; i++)
+      {
+         for (int j = 0; j < 4; j++)
+            temp[i][j] = left[0][j] * right[i][0] + left[1][j] * right[i][1] + left[2][j] * right[i][2] + left[3][j] * right[i][3];
+      }
+
+      std::memcpy(result, temp, sizeof(Matrix));
+   }
+
+   // Rotate a matrix around the x-axis
+   void matrixRotateX(Matrix& result, float angle)
+   {
+      Matrix matrix = {
+          {1.f,   0.f,             0.f,             0.f},
+          {0.f,   std::cos(angle), std::sin(angle), 0.f},
+          {0.f,  -std::sin(angle), std::cos(angle), 0.f},
+          {0.f,   0.f,             0.f,             1.f}
+      };
+
+      matrixMultiply(result, result, matrix);
+   }
+
+   // Rotate a matrix around the y-axis
+   void matrixRotateY(Matrix& result, float angle)
+   {
+      Matrix matrix = {
+          { std::cos(angle), 0.f, std::sin(angle), 0.f},
+          { 0.f,             1.f, 0.f,             0.f},
+          {-std::sin(angle), 0.f, std::cos(angle), 0.f},
+          { 0.f,             0.f, 0.f,             1.f}
+      };
+
+      matrixMultiply(result, result, matrix);
+   }
+
+   // Rotate a matrix around the z-axis
+   void matrixRotateZ(Matrix& result, float angle)
+   {
+      Matrix matrix = {
+          { std::cos(angle), std::sin(angle), 0.f, 0.f},
+          {-std::sin(angle), std::cos(angle), 0.f, 0.f},
+          { 0.f,             0.f,             1.f, 0.f},
+          { 0.f,             0.f,             0.f, 1.f}
+      };
+
+      matrixMultiply(result, result, matrix);
+   }
+
+   // Construct a lookat view matrix
+   void matrixLookAt(Matrix& result, const Vec3& eye, const Vec3& center, const Vec3& up)
+   {
+      // Forward-looking vector
+      Vec3 forward = {
+          center[0] - eye[0],
+          center[1] - eye[1],
+          center[2] - eye[2]
+      };
+
+      // Normalize
+      float factor = 1.0f / std::sqrt(forward[0] * forward[0] + forward[1] * forward[1] + forward[2] * forward[2]);
+
+      for (int i = 0; i < 3; i++)
+         forward[i] = forward[i] * factor;
+
+      // Side vector (Forward cross product Up)
+      Vec3 side = {
+          forward[1] * up[2] - forward[2] * up[1],
+          forward[2] * up[0] - forward[0] * up[2],
+          forward[0] * up[1] - forward[1] * up[0]
+      };
+
+      // Normalize
+      factor = 1.0f / std::sqrt(side[0] * side[0] + side[1] * side[1] + side[2] * side[2]);
+
+      for (int i = 0; i < 3; i++)
+         side[i] = side[i] * factor;
+
+      result[0][0] = side[0];
+      result[0][1] = side[1] * forward[2] - side[2] * forward[1];
+      result[0][2] = -forward[0];
+      result[0][3] = 0.f;
+
+      result[1][0] = side[1];
+      result[1][1] = side[2] * forward[0] - side[0] * forward[2];
+      result[1][2] = -forward[1];
+      result[1][3] = 0.f;
+
+      result[2][0] = side[2];
+      result[2][1] = side[0] * forward[1] - side[1] * forward[0];
+      result[2][2] = -forward[2];
+      result[2][3] = 0.f;
+
+      result[3][0] = (-eye[0]) * result[0][0] + (-eye[1]) * result[1][0] + (-eye[2]) * result[2][0];
+      result[3][1] = (-eye[0]) * result[0][1] + (-eye[1]) * result[1][1] + (-eye[2]) * result[2][1];
+      result[3][2] = (-eye[0]) * result[0][2] + (-eye[1]) * result[1][2] + (-eye[2]) * result[2][2];
+      result[3][3] = (-eye[0]) * result[0][3] + (-eye[1]) * result[1][3] + (-eye[2]) * result[2][3] + 1.0f;
+   }
+
+   // Construct a perspective projection matrix
+   void matrixPerspective(Matrix& result, float fov, float aspect, float nearPlane, float farPlane)
+   {
+      const float a = 1.f / std::tan(fov / 2.f);
+
+      result[0][0] = a / aspect;
+      result[0][1] = 0.f;
+      result[0][2] = 0.f;
+      result[0][3] = 0.f;
+
+      result[1][0] = 0.f;
+      result[1][1] = -a;
+      result[1][2] = 0.f;
+      result[1][3] = 0.f;
+
+      result[2][0] = 0.f;
+      result[2][1] = 0.f;
+      result[2][2] = -((farPlane + nearPlane) / (farPlane - nearPlane));
+      result[2][3] = -1.f;
+
+      result[3][0] = 0.f;
+      result[3][1] = 0.f;
+      result[3][2] = -((2.f * farPlane * nearPlane) / (farPlane - nearPlane));
+      result[3][3] = 0.f;
+   }
+
+   // Clamp a value between low and high values
+   template<typename T>
+   T clamp(T value, T low, T high)
+   {
+      return (value <= low) ? low : ((value >= high) ? high : value);
+   }
+
+   // Helper function we pass to GLAD to load Vulkan functions via SFML
+   GLADapiproc getVulkanFunction(const char* name)
+   {
+      return reinterpret_cast<GLADapiproc>(sf::Vulkan::getFunction(name));
+   }
+
+   // Debug we pass to Vulkan to call when it detects warnings or errors
+   VKAPI_ATTR VkBool32 VKAPI_CALL debugCallback(VkDebugReportFlagsEXT, VkDebugReportObjectTypeEXT, uint64_t, size_t, int32_t, const char*, const char* pMessage, void*)
+   {
+      sf::err() << pMessage << std::endl;
+
+      return VK_FALSE;
+   }
+}
+
+
+////////////////////////////////////////////////////////////
+// VulkanExample class
+////////////////////////////////////////////////////////////
+class VulkanExample
+{
+public:
+   // Constructor
+   VulkanExample() :
+      window(sf::VideoMode(800, 600), "SFML window with Vulkan", sf::Style::Default),
+      vulkanAvailable(sf::Vulkan::isAvailable()),
+      maxFramesInFlight(2),
+      currentFrame(0),
+      swapchainOutOfDate(false),
+      instance(0),
+      debugReportCallback(0),
+      surface(0),
+      gpu(0),
+      queueFamilyIndex(-1),
+      device(0),
+      queue(0),
+      swapchainFormat(),
+      swapchainExtent(),
+      swapchain(0),
+      depthFormat(VK_FORMAT_UNDEFINED),
+      depthImage(0),
+      depthImageMemory(0),
+      depthImageView(0),
+      vertexShaderModule(0),
+      fragmentShaderModule(0),
+      descriptorSetLayout(0),
+      pipelineLayout(0),
+      renderPass(0),
+      graphicsPipeline(0),
+      commandPool(0),
+      vertexBuffer(0),
+      vertexBufferMemory(0),
+      indexBuffer(0),
+      indexBufferMemory(0),
+      textureImage(0),
+      textureImageMemory(0),
+      textureImageView(0),
+      textureSampler(0),
+      descriptorPool(0)
+   {
+      // Vulkan setup procedure
+      if (vulkanAvailable) setupInstance();
+      if (vulkanAvailable) setupDebugReportCallback();
+      if (vulkanAvailable) setupSurface();
+      if (vulkanAvailable) setupPhysicalDevice();
+      if (vulkanAvailable) setupLogicalDevice();
+      if (vulkanAvailable) setupSwapchain();
+      if (vulkanAvailable) setupSwapchainImages();
+      if (vulkanAvailable) setupShaders();
+      if (vulkanAvailable) setupRenderpass();
+      if (vulkanAvailable) setupDescriptorSetLayout();
+      if (vulkanAvailable) setupPipelineLayout();
+      if (vulkanAvailable) setupPipeline();
+      if (vulkanAvailable) setupCommandPool();
+      if (vulkanAvailable) setupVertexBuffer();
+      if (vulkanAvailable) setupIndexBuffer();
+      if (vulkanAvailable) setupUniformBuffers();
+      if (vulkanAvailable) setupDepthImage();
+      if (vulkanAvailable) setupDepthImageView();
+      if (vulkanAvailable) setupTextureImage();
+      if (vulkanAvailable) setupTextureImageView();
+      if (vulkanAvailable) setupTextureSampler();
+      if (vulkanAvailable) setupFramebuffers();
+      if (vulkanAvailable) setupDescriptorPool();
+      if (vulkanAvailable) setupDescriptorSets();
+      if (vulkanAvailable) setupCommandBuffers();
+      if (vulkanAvailable) setupDraw();
+      if (vulkanAvailable) setupSemaphores();
+      if (vulkanAvailable) setupFences();
+
+      // If something went wrong, notify the user by setting the window title
+      if (!vulkanAvailable)
+         window.setTitle("SFML window with Vulkan (Vulkan not available)");
+   }
+
+
+   // Destructor
+   ~VulkanExample()
+   {
+      // Wait until there are no pending frames
+      if (device)
+         vkDeviceWaitIdle(device);
+
+      // Teardown swapchain
+      cleanupSwapchain();
+
+      // Vulkan teardown procedure
+      for (std::size_t i = 0; i < fences.size(); i++)
+         vkDestroyFence(device, fences[i], 0);
+
+      for (std::size_t i = 0; i < renderFinishedSemaphores.size(); i++)
+         vkDestroySemaphore(device, renderFinishedSemaphores[i], 0);
+
+      for (std::size_t i = 0; i < imageAvailableSemaphores.size(); i++)
+         vkDestroySemaphore(device, imageAvailableSemaphores[i], 0);
+
+      if (descriptorPool)
+         vkDestroyDescriptorPool(device, descriptorPool, 0);
+
+      for (std::size_t i = 0; i < uniformBuffersMemory.size(); i++)
+         vkFreeMemory(device, uniformBuffersMemory[i], 0);
+
+      for (std::size_t i = 0; i < uniformBuffers.size(); i++)
+         vkDestroyBuffer(device, uniformBuffers[i], 0);
+
+      if (textureSampler)
+         vkDestroySampler(device, textureSampler, 0);
+
+      if (textureImageView)
+         vkDestroyImageView(device, textureImageView, 0);
+
+      if (textureImageMemory)
+         vkFreeMemory(device, textureImageMemory, 0);
+
+      if (textureImage)
+         vkDestroyImage(device, textureImage, 0);
+
+      if (indexBufferMemory)
+         vkFreeMemory(device, indexBufferMemory, 0);
+
+      if (indexBuffer)
+         vkDestroyBuffer(device, indexBuffer, 0);
+
+      if (vertexBufferMemory)
+         vkFreeMemory(device, vertexBufferMemory, 0);
+
+      if (vertexBuffer)
+         vkDestroyBuffer(device, vertexBuffer, 0);
+
+      if (commandPool)
+         vkDestroyCommandPool(device, commandPool, 0);
+
+      if (descriptorSetLayout)
+         vkDestroyDescriptorSetLayout(device, descriptorSetLayout, 0);
+
+      if (fragmentShaderModule)
+         vkDestroyShaderModule(device, fragmentShaderModule, 0);
+
+      if (vertexShaderModule)
+         vkDestroyShaderModule(device, vertexShaderModule, 0);
+
+      if (device)
+         vkDestroyDevice(device, 0);
+
+      if (surface)
+         vkDestroySurfaceKHR(instance, surface, 0);
+
+      if (debugReportCallback)
+         vkDestroyDebugReportCallbackEXT(instance, debugReportCallback, 0);
+
+      if (instance)
+         vkDestroyInstance(instance, 0);
+   }
+
+   // Cleanup swapchain
+   void cleanupSwapchain()
+   {
+      // Swapchain teardown procedure
+      for (std::size_t i = 0; i < fences.size(); i++)
+         vkWaitForFences(device, 1, &fences[i], VK_TRUE, std::numeric_limits<uint64_t>::max());
+
+      if (commandBuffers.size())
+         vkFreeCommandBuffers(device, commandPool, commandBuffers.size(), &commandBuffers[0]);
+
+      commandBuffers.clear();
+
+      for (std::size_t i = 0; i < swapchainFramebuffers.size(); i++)
+         vkDestroyFramebuffer(device, swapchainFramebuffers[i], 0);
+
+      swapchainFramebuffers.clear();
+
+      if (graphicsPipeline)
+         vkDestroyPipeline(device, graphicsPipeline, 0);
+
+      if (renderPass)
+         vkDestroyRenderPass(device, renderPass, 0);
+
+      if (pipelineLayout)
+         vkDestroyPipelineLayout(device, pipelineLayout, 0);
+
+      if (depthImageView)
+         vkDestroyImageView(device, depthImageView, 0);
+
+      if (depthImageMemory)
+         vkFreeMemory(device, depthImageMemory, 0);
+
+      if (depthImage)
+         vkDestroyImage(device, depthImage, 0);
+
+      for (std::size_t i = 0; i < swapchainImageViews.size(); i++)
+         vkDestroyImageView(device, swapchainImageViews[i], 0);
+
+      swapchainImageViews.clear();
+
+      if (swapchain)
+         vkDestroySwapchainKHR(device, swapchain, 0);
+   }
+
+   // Cleanup and recreate swapchain
+   void recreateSwapchain()
+   {
+      // Wait until there are no pending frames
+      vkDeviceWaitIdle(device);
+
+      // Cleanup swapchain
+      cleanupSwapchain();
+
+      // Swapchain setup procedure
+      if (vulkanAvailable) setupSwapchain();
+      if (vulkanAvailable) setupSwapchainImages();
+      if (vulkanAvailable) setupPipelineLayout();
+      if (vulkanAvailable) setupRenderpass();
+      if (vulkanAvailable) setupPipeline();
+      if (vulkanAvailable) setupDepthImage();
+      if (vulkanAvailable) setupDepthImageView();
+      if (vulkanAvailable) setupFramebuffers();
+      if (vulkanAvailable) setupCommandBuffers();
+      if (vulkanAvailable) setupDraw();
+   }
+
+   // Setup Vulkan instance
+   void setupInstance()
+   {
+      // Load bootstrap entry points
+      gladLoadVulkan(0, getVulkanFunction);
+
+      if (!vkCreateInstance)
+      {
+         vulkanAvailable = false;
+         return;
+      }
+
+      // Retrieve the available instance layers
+      uint32_t objectCount = 0;
+
+      std::vector<VkLayerProperties> layers;
+
+      if (vkEnumerateInstanceLayerProperties(&objectCount, 0) != VK_SUCCESS)
+      {
+         vulkanAvailable = false;
+         return;
+      }
+
+      layers.resize(objectCount);
+
+      if (vkEnumerateInstanceLayerProperties(&objectCount, &layers[0]) != VK_SUCCESS)
+      {
+         vulkanAvailable = false;
+         return;
+      }
+
+      // Activate the layers we are interested in
+      std::vector<const char*> validationLayers;
+
+      for (std::size_t i = 0; i < layers.size(); i++)
+      {
+         // VK_LAYER_LUNARG_standard_validation, meta-layer for the following layers:
+         // -- VK_LAYER_GOOGLE_threading
+         // -- VK_LAYER_LUNARG_parameter_validation
+         // -- VK_LAYER_LUNARG_device_limits
+         // -- VK_LAYER_LUNARG_object_tracker
+         // -- VK_LAYER_LUNARG_image
+         // -- VK_LAYER_LUNARG_core_validation
+         // -- VK_LAYER_LUNARG_swapchain
+         // -- VK_LAYER_GOOGLE_unique_objects
+         // These layers perform error checking and warn about bad or sub-optimal Vulkan API usage
+         // VK_LAYER_LUNARG_monitor appends an FPS counter to the window title
+         if (!std::strcmp(layers[i].layerName, "VK_LAYER_LUNARG_standard_validation"))
+         {
+            validationLayers.push_back("VK_LAYER_LUNARG_standard_validation");
+         }
+         else if (!std::strcmp(layers[i].layerName, "VK_LAYER_LUNARG_monitor"))
+         {
+            validationLayers.push_back("VK_LAYER_LUNARG_monitor");
+         }
+      }
+
+      // Retrieve the extensions we need to enable in order to use Vulkan with SFML
+      std::vector<const char*> requiredExtentions = sf::Vulkan::getGraphicsRequiredInstanceExtensions();
+      requiredExtentions.push_back(VK_EXT_DEBUG_REPORT_EXTENSION_NAME);
+
+      // Register our application information
+      VkApplicationInfo applicationInfo = VkApplicationInfo();
+      applicationInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
+      applicationInfo.pApplicationName = "SFML Vulkan Test";
+      applicationInfo.applicationVersion = VK_MAKE_VERSION(1, 0, 0);
+      applicationInfo.pEngineName = "SFML Vulkan Test Engine";
+      applicationInfo.engineVersion = VK_MAKE_VERSION(1, 0, 0);
+      applicationInfo.apiVersion = VK_API_VERSION_1_0;
+
+      VkInstanceCreateInfo instanceCreateInfo = VkInstanceCreateInfo();
+      instanceCreateInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
+      instanceCreateInfo.pApplicationInfo = &applicationInfo;
+      instanceCreateInfo.enabledLayerCount = validationLayers.size();
+      instanceCreateInfo.ppEnabledLayerNames = &validationLayers[0];
+      instanceCreateInfo.enabledExtensionCount = requiredExtentions.size();
+      instanceCreateInfo.ppEnabledExtensionNames = &requiredExtentions[0];
+
+      // Try to create a Vulkan instance with debug report enabled
+      VkResult result = vkCreateInstance(&instanceCreateInfo, 0, &instance);
+
+      // If an extension is missing, try disabling debug report
+      if (result == VK_ERROR_EXTENSION_NOT_PRESENT)
+      {
+         requiredExtentions.pop_back();
+
+         instanceCreateInfo.enabledExtensionCount = requiredExtentions.size();
+         instanceCreateInfo.ppEnabledExtensionNames = &requiredExtentions[0];
+
+         result = vkCreateInstance(&instanceCreateInfo, 0, &instance);
+      }
+
+      // If instance creation still fails, give up
+      if (result != VK_SUCCESS)
+      {
+         vulkanAvailable = false;
+         return;
+      }
+
+      // Load instance entry points
+      gladLoadVulkan(0, getVulkanFunction);
+   }
+
+   // Setup our debug callback function to be called by Vulkan
+   void setupDebugReportCallback()
+   {
+      // Don't try to register the callback if the extension is not available
+      if (!vkCreateDebugReportCallbackEXT)
+         return;
+
+      // Register for warnings and errors
+      VkDebugReportCallbackCreateInfoEXT debugReportCallbackCreateInfo = VkDebugReportCallbackCreateInfoEXT();
+      debugReportCallbackCreateInfo.sType = VK_STRUCTURE_TYPE_DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT;
+      debugReportCallbackCreateInfo.flags = VK_DEBUG_REPORT_WARNING_BIT_EXT | VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT | VK_DEBUG_REPORT_ERROR_BIT_EXT;
+      debugReportCallbackCreateInfo.pfnCallback = debugCallback;
+
+      // Create the debug callback
+      if (vkCreateDebugReportCallbackEXT(instance, &debugReportCallbackCreateInfo, 0, &debugReportCallback) != VK_SUCCESS)
+      {
+         vulkanAvailable = false;
+         return;
+      }
+   }
+
+   // Setup the SFML window Vulkan rendering surface
+   void setupSurface()
+   {
+      if (!window.createVulkanSurface(instance, surface))
+         vulkanAvailable = false;
+   }
+
+   // Select a GPU to use and query its capabilities
+   void setupPhysicalDevice()
+   {
+      // Last sanity check
+      if (!vkEnumeratePhysicalDevices || !vkCreateDevice || !vkGetPhysicalDeviceProperties)
+      {
+         vulkanAvailable = false;
+         return;
+      }
+
+      // Retrieve list of GPUs
+      uint32_t objectCount = 0;
+
+      std::vector<VkPhysicalDevice> devices;
+
+      if (vkEnumeratePhysicalDevices(instance, &objectCount, 0) != VK_SUCCESS)
+      {
+         vulkanAvailable = false;
+         return;
+      }
+
+      devices.resize(objectCount);
+
+      if (vkEnumeratePhysicalDevices(instance, &objectCount, &devices[0]) != VK_SUCCESS)
+      {
+         vulkanAvailable = false;
+         return;
+      }
+
+      // Look for a GPU that supports swapchains
+      for (std::size_t i = 0; i < devices.size(); i++)
+      {
+         VkPhysicalDeviceProperties deviceProperties;
+         vkGetPhysicalDeviceProperties(devices[i], &deviceProperties);
+
+         std::vector<VkExtensionProperties> extensions;
+
+         if (vkEnumerateDeviceExtensionProperties(devices[i], 0, &objectCount, 0) != VK_SUCCESS)
+         {
+            vulkanAvailable = false;
+            return;
+         }
+
+         extensions.resize(objectCount);
+
+         if (vkEnumerateDeviceExtensionProperties(devices[i], 0, &objectCount, &extensions[0]) != VK_SUCCESS)
+         {
+            vulkanAvailable = false;
+            return;
+         }
+
+         bool supportsSwapchain = false;
+
+         for (std::size_t j = 0; j < extensions.size(); j++)
+         {
+            if (!std::strcmp(extensions[j].extensionName, VK_KHR_SWAPCHAIN_EXTENSION_NAME))
+            {
+               supportsSwapchain = true;
+               break;
+            }
+         }
+
+         if (!supportsSwapchain)
+            continue;
+
+         // Prefer discrete over integrated GPUs if multiple are available
+         if (deviceProperties.deviceType == VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU)
+         {
+            gpu = devices[i];
+            break;
+         }
+         else if (deviceProperties.deviceType == VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU)
+         {
+            gpu = devices[i];
+         }
+      }
+
+      if (!gpu)
+      {
+         vulkanAvailable = false;
+         return;
+      }
+
+      // Load physical device entry points
+      gladLoadVulkan(gpu, getVulkanFunction);
+
+      // Check what depth formats are available and select one
+      VkFormatProperties formatProperties = VkFormatProperties();
+
+      vkGetPhysicalDeviceFormatProperties(gpu, VK_FORMAT_D24_UNORM_S8_UINT, &formatProperties);
+
+      if (formatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT) {
+         depthFormat = VK_FORMAT_D24_UNORM_S8_UINT;
+      }
+      else
+      {
+         vkGetPhysicalDeviceFormatProperties(gpu, VK_FORMAT_D32_SFLOAT_S8_UINT, &formatProperties);
+
+         if (formatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT) {
+            depthFormat = VK_FORMAT_D32_SFLOAT_S8_UINT;
+         }
+         else
+         {
+            vkGetPhysicalDeviceFormatProperties(gpu, VK_FORMAT_D32_SFLOAT, &formatProperties);
+
+            if (formatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT) {
+               depthFormat = VK_FORMAT_D32_SFLOAT;
+            }
+            else
+            {
+               vulkanAvailable = false;
+               return;
+            }
+         }
+      }
+   }
+
+   // Setup logical device and device queue
+   void setupLogicalDevice()
+   {
+      // Select a queue family that supports graphics operations and surface presentation
+      uint32_t objectCount = 0;
+
+      std::vector<VkQueueFamilyProperties> queueFamilyProperties;
+
+      vkGetPhysicalDeviceQueueFamilyProperties(gpu, &objectCount, 0);
+
+      queueFamilyProperties.resize(objectCount);
+
+      vkGetPhysicalDeviceQueueFamilyProperties(gpu, &objectCount, &queueFamilyProperties[0]);
+
+      for (std::size_t i = 0; i < queueFamilyProperties.size(); i++)
+      {
+         VkBool32 surfaceSupported = VK_FALSE;
+
+         vkGetPhysicalDeviceSurfaceSupportKHR(gpu, i, surface, &surfaceSupported);
+
+         if ((queueFamilyProperties[i].queueFlags & VK_QUEUE_GRAPHICS_BIT) && (surfaceSupported == VK_TRUE))
+         {
+            queueFamilyIndex = i;
+            break;
+         }
+      }
+
+      if (queueFamilyIndex < 0)
+      {
+         vulkanAvailable = false;
+         return;
+      }
+
+      float queuePriority = 1.0f;
+
+      VkDeviceQueueCreateInfo deviceQueueCreateInfo = VkDeviceQueueCreateInfo();
+      deviceQueueCreateInfo.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
+      deviceQueueCreateInfo.queueCount = 1;
+      deviceQueueCreateInfo.queueFamilyIndex = queueFamilyIndex;
+      deviceQueueCreateInfo.pQueuePriorities = &queuePriority;
+
+      // Enable the swapchain extension
+      const char* extentions[1] = { VK_KHR_SWAPCHAIN_EXTENSION_NAME };
+
+      // Enable anisotropic filtering
+      VkPhysicalDeviceFeatures physicalDeviceFeatures = VkPhysicalDeviceFeatures();
+      physicalDeviceFeatures.samplerAnisotropy = VK_TRUE;
+
+      VkDeviceCreateInfo deviceCreateInfo = VkDeviceCreateInfo();
+      deviceCreateInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
+      deviceCreateInfo.enabledExtensionCount = 1;
+      deviceCreateInfo.ppEnabledExtensionNames = extentions;
+      deviceCreateInfo.queueCreateInfoCount = 1;
+      deviceCreateInfo.pQueueCreateInfos = &deviceQueueCreateInfo;
+      deviceCreateInfo.pEnabledFeatures = &physicalDeviceFeatures;
+
+      // Create our logical device
+      if (vkCreateDevice(gpu, &deviceCreateInfo, 0, &device) != VK_SUCCESS)
+      {
+         vulkanAvailable = false;
+         return;
+      }
+
+      // Retrieve a handle to the logical device command queue
+      vkGetDeviceQueue(device, queueFamilyIndex, 0, &queue);
+   }
+
+   // Query surface formats and set up swapchain
+   void setupSwapchain()
+   {
+      // Select a surface format that supports RGBA color format
+      uint32_t objectCount = 0;
+
+      std::vector<VkSurfaceFormatKHR> surfaceFormats;
+
+      if (vkGetPhysicalDeviceSurfaceFormatsKHR(gpu, surface, &objectCount, 0) != VK_SUCCESS)
+      {
+         vulkanAvailable = false;
+         return;
+      }
+
+      surfaceFormats.resize(objectCount);
+
+      if (vkGetPhysicalDeviceSurfaceFormatsKHR(gpu, surface, &objectCount, &surfaceFormats[0]) != VK_SUCCESS)
+      {
+         vulkanAvailable = false;
+         return;
+      }
+
+      if ((surfaceFormats.size() == 1) && (surfaceFormats[0].format == VK_FORMAT_UNDEFINED))
+      {
+         swapchainFormat.format = VK_FORMAT_B8G8R8A8_UNORM;
+         swapchainFormat.colorSpace = VK_COLOR_SPACE_SRGB_NONLINEAR_KHR;
+      }
+      else if (!surfaceFormats.empty())
+      {
+         for (std::size_t i = 0; i < surfaceFormats.size(); i++)
+         {
+            if ((surfaceFormats[i].format == VK_FORMAT_B8G8R8A8_UNORM) && (surfaceFormats[i].colorSpace == VK_COLOR_SPACE_SRGB_NONLINEAR_KHR))
+            {
+               swapchainFormat.format = VK_FORMAT_B8G8R8A8_UNORM;
+               swapchainFormat.colorSpace = VK_COLOR_SPACE_SRGB_NONLINEAR_KHR;
+
+               break;
+            }
+         }
+
+         if (swapchainFormat.format == VK_FORMAT_UNDEFINED)
+            swapchainFormat = surfaceFormats[0];
+      }
+      else
+      {
+         vulkanAvailable = false;
+         return;
+      }
+
+      // Select a swapchain present mode
+      std::vector<VkPresentModeKHR> presentModes;
+
+      if (vkGetPhysicalDeviceSurfacePresentModesKHR(gpu, surface, &objectCount, 0) != VK_SUCCESS)
+      {
+         vulkanAvailable = false;
+         return;
+      }
+
+      presentModes.resize(objectCount);
+
+      if (vkGetPhysicalDeviceSurfacePresentModesKHR(gpu, surface, &objectCount, &presentModes[0]) != VK_SUCCESS)
+      {
+         vulkanAvailable = false;
+         return;
+      }
+
+      // Prefer mailbox over FIFO if it is available
+      VkPresentModeKHR presentMode = VK_PRESENT_MODE_FIFO_KHR;
+
+      for (std::size_t i = 0; i < presentModes.size(); i++)
+      {
+         if (presentModes[i] == VK_PRESENT_MODE_MAILBOX_KHR)
+         {
+            presentMode = presentModes[i];
+            break;
+         }
+      }
+
+      // Determine size and count of swapchain images
+      VkSurfaceCapabilitiesKHR surfaceCapabilities;
+
+      if (vkGetPhysicalDeviceSurfaceCapabilitiesKHR(gpu, surface, &surfaceCapabilities) != VK_SUCCESS)
+      {
+         vulkanAvailable = false;
+         return;
+      }
+
+      swapchainExtent.width = clamp<uint32_t>(window.getSize().x, surfaceCapabilities.minImageExtent.width, surfaceCapabilities.maxImageExtent.width);
+      swapchainExtent.height = clamp<uint32_t>(window.getSize().y, surfaceCapabilities.minImageExtent.height, surfaceCapabilities.maxImageExtent.height);
+
+      uint32_t imageCount = clamp<uint32_t>(2, surfaceCapabilities.minImageCount, surfaceCapabilities.maxImageCount);
+
+      VkSwapchainCreateInfoKHR swapchainCreateInfo = VkSwapchainCreateInfoKHR();
+      swapchainCreateInfo.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR;
+      swapchainCreateInfo.surface = surface;
+      swapchainCreateInfo.minImageCount = imageCount;
+      swapchainCreateInfo.imageFormat = swapchainFormat.format;
+      swapchainCreateInfo.imageColorSpace = swapchainFormat.colorSpace;
+      swapchainCreateInfo.imageExtent = swapchainExtent;
+      swapchainCreateInfo.imageArrayLayers = 1;
+      swapchainCreateInfo.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
+      swapchainCreateInfo.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE;
+      swapchainCreateInfo.preTransform = surfaceCapabilities.currentTransform;
+      swapchainCreateInfo.compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR;
+      swapchainCreateInfo.presentMode = presentMode;
+      swapchainCreateInfo.clipped = VK_TRUE;
+      swapchainCreateInfo.oldSwapchain = VK_NULL_HANDLE;
+
+      // Create the swapchain
+      if (vkCreateSwapchainKHR(device, &swapchainCreateInfo, 0, &swapchain) != VK_SUCCESS)
+      {
+         vulkanAvailable = false;
+         return;
+      }
+   }
+
+   // Retrieve the swapchain images and create image views for them
+   void setupSwapchainImages()
+   {
+      // Retrieve swapchain images
+      uint32_t objectCount = 0;
+
+      if (vkGetSwapchainImagesKHR(device, swapchain, &objectCount, 0) != VK_SUCCESS)
+      {
+         vulkanAvailable = false;
+         return;
+      }
+
+      swapchainImages.resize(objectCount);
+      swapchainImageViews.resize(objectCount);
+
+      if (vkGetSwapchainImagesKHR(device, swapchain, &objectCount, &swapchainImages[0]) != VK_SUCCESS)
+      {
+         vulkanAvailable = false;
+         return;
+      }
+
+      VkImageViewCreateInfo imageViewCreateInfo = VkImageViewCreateInfo();
+      imageViewCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
+      imageViewCreateInfo.viewType = VK_IMAGE_VIEW_TYPE_2D;
+      imageViewCreateInfo.format = swapchainFormat.format;
+      imageViewCreateInfo.components.r = VK_COMPONENT_SWIZZLE_IDENTITY;
+      imageViewCreateInfo.components.g = VK_COMPONENT_SWIZZLE_IDENTITY;
+      imageViewCreateInfo.components.b = VK_COMPONENT_SWIZZLE_IDENTITY;
+      imageViewCreateInfo.components.a = VK_COMPONENT_SWIZZLE_IDENTITY;
+      imageViewCreateInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
+      imageViewCreateInfo.subresourceRange.baseMipLevel = 0;
+      imageViewCreateInfo.subresourceRange.levelCount = 1;
+      imageViewCreateInfo.subresourceRange.baseArrayLayer = 0;
+      imageViewCreateInfo.subresourceRange.layerCount = 1;
+
+      // Create an image view for each swapchain image
+      for (std::size_t i = 0; i < swapchainImages.size(); i++)
+      {
+         imageViewCreateInfo.image = swapchainImages[i];
+
+         if (vkCreateImageView(device, &imageViewCreateInfo, 0, &swapchainImageViews[i]) != VK_SUCCESS)
+         {
+            vulkanAvailable = false;
+            return;
+         }
+      }
+   }
+
+   // Load vertex and fragment shader modules
+   void setupShaders()
+   {
+      VkShaderModuleCreateInfo shaderModuleCreateInfo = VkShaderModuleCreateInfo();
+      shaderModuleCreateInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
+
+      // Use the vertex shader SPIR-V code to create a vertex shader module
+      {
+         sf::FileInputStream file;
+
+         if (!file.open("resources/shader.vert.spv"))
+         {
+            vulkanAvailable = false;
+            return;
+         }
+
+         std::vector<char> buffer(static_cast<std::size_t>(file.getSize()));
+
+         if (file.read(&buffer[0], file.getSize()) != file.getSize())
+         {
+            vulkanAvailable = false;
+            return;
+         }
+
+         shaderModuleCreateInfo.codeSize = buffer.size();
+         shaderModuleCreateInfo.pCode = reinterpret_cast<const uint32_t*>(&buffer[0]);
+
+         if (vkCreateShaderModule(device, &shaderModuleCreateInfo, 0, &vertexShaderModule) != VK_SUCCESS)
+         {
+            vulkanAvailable = false;
+            return;
+         }
+      }
+
+      // Use the fragment shader SPIR-V code to create a fragment shader module
+      {
+         sf::FileInputStream file;
+
+         if (!file.open("resources/shader.frag.spv"))
+         {
+            vulkanAvailable = false;
+            return;
+         }
+
+         std::vector<char> buffer(static_cast<std::size_t>(file.getSize()));
+
+         if (file.read(&buffer[0], file.getSize()) != file.getSize())
+         {
+            vulkanAvailable = false;
+            return;
+         }
+
+         shaderModuleCreateInfo.codeSize = buffer.size();
+         shaderModuleCreateInfo.pCode = reinterpret_cast<const uint32_t*>(&buffer[0]);
+
+         if (vkCreateShaderModule(device, &shaderModuleCreateInfo, 0, &fragmentShaderModule) != VK_SUCCESS)
+         {
+            vulkanAvailable = false;
+            return;
+         }
+      }
+
+      // Prepare the shader stage information for later pipeline creation
+      shaderStages[0] = VkPipelineShaderStageCreateInfo();
+      shaderStages[0].sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
+      shaderStages[0].stage = VK_SHADER_STAGE_VERTEX_BIT;
+      shaderStages[0].module = vertexShaderModule;
+      shaderStages[0].pName = "main";
+
+      shaderStages[1] = VkPipelineShaderStageCreateInfo();
+      shaderStages[1].sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
+      shaderStages[1].stage = VK_SHADER_STAGE_FRAGMENT_BIT;
+      shaderStages[1].module = fragmentShaderModule;
+      shaderStages[1].pName = "main";
+   }
+
+   // Setup renderpass and its subpass dependencies
+   void setupRenderpass()
+   {
+      VkAttachmentDescription attachmentDescriptions[2];
+
+      // Color attachment
+      attachmentDescriptions[0] = VkAttachmentDescription();
+      attachmentDescriptions[0].format = swapchainFormat.format;
+      attachmentDescriptions[0].samples = VK_SAMPLE_COUNT_1_BIT;
+      attachmentDescriptions[0].loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
+      attachmentDescriptions[0].storeOp = VK_ATTACHMENT_STORE_OP_STORE;
+      attachmentDescriptions[0].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
+      attachmentDescriptions[0].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
+      attachmentDescriptions[0].initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
+      attachmentDescriptions[0].finalLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
+
+      // Depth attachment
+      attachmentDescriptions[1] = VkAttachmentDescription();
+      attachmentDescriptions[1].format = depthFormat;
+      attachmentDescriptions[1].samples = VK_SAMPLE_COUNT_1_BIT;
+      attachmentDescriptions[1].loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
+      attachmentDescriptions[1].storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
+      attachmentDescriptions[1].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
+      attachmentDescriptions[1].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
+      attachmentDescriptions[1].initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
+      attachmentDescriptions[1].finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
+
+      VkAttachmentReference attachmentReferences[2];
+
+      attachmentReferences[0] = VkAttachmentReference();
+      attachmentReferences[0].attachment = 0;
+      attachmentReferences[0].layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
+
+      attachmentReferences[1] = VkAttachmentReference();
+      attachmentReferences[1].attachment = 1;
+      attachmentReferences[1].layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
+
+      // Set up the renderpass to depend on commands that execute before the renderpass begins
+      VkSubpassDescription subpassDescription = VkSubpassDescription();
+      subpassDescription.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
+      subpassDescription.colorAttachmentCount = 1;
+      subpassDescription.pColorAttachments = &attachmentReferences[0];
+      subpassDescription.pDepthStencilAttachment = &attachmentReferences[1];
+
+      VkSubpassDependency subpassDependency = VkSubpassDependency();
+      subpassDependency.srcSubpass = VK_SUBPASS_EXTERNAL;
+      subpassDependency.srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
+      subpassDependency.srcAccessMask = 0;
+      subpassDependency.dstSubpass = 0;
+      subpassDependency.dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
+      subpassDependency.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
+
+      VkRenderPassCreateInfo renderPassCreateInfo = VkRenderPassCreateInfo();
+      renderPassCreateInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
+      renderPassCreateInfo.attachmentCount = 2;
+      renderPassCreateInfo.pAttachments = attachmentDescriptions;
+      renderPassCreateInfo.subpassCount = 1;
+      renderPassCreateInfo.pSubpasses = &subpassDescription;
+      renderPassCreateInfo.dependencyCount = 1;
+      renderPassCreateInfo.pDependencies = &subpassDependency;
+
+      // Create the renderpass
+      if (vkCreateRenderPass(device, &renderPassCreateInfo, 0, &renderPass) != VK_SUCCESS)
+      {
+         vulkanAvailable = false;
+         return;
+      }
+   }
+
+   // Set up uniform buffer and texture sampler descriptor set layouts
+   void setupDescriptorSetLayout()
+   {
+      VkDescriptorSetLayoutBinding descriptorSetLayoutBindings[2];
+
+      // Layout binding for uniform buffer
+      descriptorSetLayoutBindings[0] = VkDescriptorSetLayoutBinding();
+      descriptorSetLayoutBindings[0].binding = 0;
+      descriptorSetLayoutBindings[0].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
+      descriptorSetLayoutBindings[0].descriptorCount = 1;
+      descriptorSetLayoutBindings[0].stageFlags = VK_SHADER_STAGE_VERTEX_BIT;
+
+      // Layout binding for texture sampler
+      descriptorSetLayoutBindings[1] = VkDescriptorSetLayoutBinding();
+      descriptorSetLayoutBindings[1].binding = 1;
+      descriptorSetLayoutBindings[1].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
+      descriptorSetLayoutBindings[1].descriptorCount = 1;
+      descriptorSetLayoutBindings[1].stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
+
+      VkDescriptorSetLayoutCreateInfo descriptorSetLayoutCreateInfo = VkDescriptorSetLayoutCreateInfo();
+      descriptorSetLayoutCreateInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
+      descriptorSetLayoutCreateInfo.bindingCount = 2;
+      descriptorSetLayoutCreateInfo.pBindings = descriptorSetLayoutBindings;
+
+      // Create descriptor set layout
+      if (vkCreateDescriptorSetLayout(device, &descriptorSetLayoutCreateInfo, 0, &descriptorSetLayout) != VK_SUCCESS)
+      {
+         vulkanAvailable = false;
+         return;
+      }
+   }
+
+   // Set up pipeline layout
+   void setupPipelineLayout()
+   {
+      VkPipelineLayoutCreateInfo pipelineLayoutCreateInfo = VkPipelineLayoutCreateInfo();
+      pipelineLayoutCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
+      pipelineLayoutCreateInfo.setLayoutCount = 1;
+      pipelineLayoutCreateInfo.pSetLayouts = &descriptorSetLayout;
+
+      // Create pipeline layout
+      if (vkCreatePipelineLayout(device, &pipelineLayoutCreateInfo, 0, &pipelineLayout) != VK_SUCCESS)
+      {
+         vulkanAvailable = false;
+         return;
+      }
+   }
+
+   // Set up rendering pipeline
+   void setupPipeline()
+   {
+      // Set up how the vertex shader pulls data out of our vertex buffer
+      VkVertexInputBindingDescription vertexInputBindingDescription = VkVertexInputBindingDescription();
+      vertexInputBindingDescription.binding = 0;
+      vertexInputBindingDescription.stride = sizeof(float) * 9;
+      vertexInputBindingDescription.inputRate = VK_VERTEX_INPUT_RATE_VERTEX;
+
+      // Set up how the vertex buffer data is interpreted as attributes by the vertex shader
+      VkVertexInputAttributeDescription vertexInputAttributeDescriptions[3];
+
+      // Position attribute
+      vertexInputAttributeDescriptions[0] = VkVertexInputAttributeDescription();
+      vertexInputAttributeDescriptions[0].binding = 0;
+      vertexInputAttributeDescriptions[0].location = 0;
+      vertexInputAttributeDescriptions[0].format = VK_FORMAT_R32G32B32_SFLOAT;
+      vertexInputAttributeDescriptions[0].offset = sizeof(float) * 0;
+
+      // Color attribute
+      vertexInputAttributeDescriptions[1] = VkVertexInputAttributeDescription();
+      vertexInputAttributeDescriptions[1].binding = 0;
+      vertexInputAttributeDescriptions[1].location = 1;
+      vertexInputAttributeDescriptions[1].format = VK_FORMAT_R32G32B32A32_SFLOAT;
+      vertexInputAttributeDescriptions[1].offset = sizeof(float) * 3;
+
+      // Texture coordinate attribute
+      vertexInputAttributeDescriptions[2] = VkVertexInputAttributeDescription();
+      vertexInputAttributeDescriptions[2].binding = 0;
+      vertexInputAttributeDescriptions[2].location = 2;
+      vertexInputAttributeDescriptions[2].format = VK_FORMAT_R32G32_SFLOAT;
+      vertexInputAttributeDescriptions[2].offset = sizeof(float) * 7;
+
+      VkPipelineVertexInputStateCreateInfo vertexInputStateCreateInfo = VkPipelineVertexInputStateCreateInfo();
+      vertexInputStateCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
+      vertexInputStateCreateInfo.vertexBindingDescriptionCount = 1;
+      vertexInputStateCreateInfo.pVertexBindingDescriptions = &vertexInputBindingDescription;
+      vertexInputStateCreateInfo.vertexAttributeDescriptionCount = 3;
+      vertexInputStateCreateInfo.pVertexAttributeDescriptions = vertexInputAttributeDescriptions;
+
+      // We want to generate a triangle list with our vertex data
+      VkPipelineInputAssemblyStateCreateInfo inputAssemblyStateCreateInfo = VkPipelineInputAssemblyStateCreateInfo();
+      inputAssemblyStateCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
+      inputAssemblyStateCreateInfo.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
+      inputAssemblyStateCreateInfo.primitiveRestartEnable = VK_FALSE;
+
+      // Set up the viewport
+      VkViewport viewport = VkViewport();
+      viewport.x = 0.0f;
+      viewport.y = 0.0f;
+      viewport.width = static_cast<float>(swapchainExtent.width);
+      viewport.height = static_cast<float>(swapchainExtent.height);
+      viewport.minDepth = 0.0f;
+      viewport.maxDepth = 1.f;
+
+      // Set up the scissor region
+      VkRect2D scissor = VkRect2D();
+      scissor.offset.x = 0;
+      scissor.offset.y = 0;
+      scissor.extent = swapchainExtent;
+
+      VkPipelineViewportStateCreateInfo pipelineViewportStateCreateInfo = VkPipelineViewportStateCreateInfo();
+      pipelineViewportStateCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
+      pipelineViewportStateCreateInfo.viewportCount = 1;
+      pipelineViewportStateCreateInfo.pViewports = &viewport;
+      pipelineViewportStateCreateInfo.scissorCount = 1;
+      pipelineViewportStateCreateInfo.pScissors = &scissor;
+
+      // Set up rasterization parameters: fill polygons, no backface culling, front face is counter-clockwise
+      VkPipelineRasterizationStateCreateInfo pipelineRasterizationStateCreateInfo = VkPipelineRasterizationStateCreateInfo();
+      pipelineRasterizationStateCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
+      pipelineRasterizationStateCreateInfo.depthClampEnable = VK_FALSE;
+      pipelineRasterizationStateCreateInfo.rasterizerDiscardEnable = VK_FALSE;
+      pipelineRasterizationStateCreateInfo.polygonMode = VK_POLYGON_MODE_FILL;
+      pipelineRasterizationStateCreateInfo.lineWidth = 1.0f;
+      pipelineRasterizationStateCreateInfo.cullMode = VK_CULL_MODE_NONE;
+      pipelineRasterizationStateCreateInfo.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE;
+      pipelineRasterizationStateCreateInfo.depthBiasEnable = VK_FALSE;
+
+      // Enable depth testing and disable scissor testing
+      VkPipelineDepthStencilStateCreateInfo pipelineDepthStencilStateCreateInfo = VkPipelineDepthStencilStateCreateInfo();
+      pipelineDepthStencilStateCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO;
+      pipelineDepthStencilStateCreateInfo.depthTestEnable = VK_TRUE;
+      pipelineDepthStencilStateCreateInfo.depthWriteEnable = VK_TRUE;
+      pipelineDepthStencilStateCreateInfo.depthCompareOp = VK_COMPARE_OP_LESS;
+      pipelineDepthStencilStateCreateInfo.depthBoundsTestEnable = VK_FALSE;
+      pipelineDepthStencilStateCreateInfo.stencilTestEnable = VK_FALSE;
+
+      // Enable multi-sampling
+      VkPipelineMultisampleStateCreateInfo pipelineMultisampleStateCreateInfo = VkPipelineMultisampleStateCreateInfo();
+      pipelineMultisampleStateCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
+      pipelineMultisampleStateCreateInfo.sampleShadingEnable = VK_FALSE;
+      pipelineMultisampleStateCreateInfo.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT;
+
+      // Set up blending parameters
+      VkPipelineColorBlendAttachmentState pipelineColorBlendAttachmentState = VkPipelineColorBlendAttachmentState();
+      pipelineColorBlendAttachmentState.blendEnable = VK_TRUE;
+      pipelineColorBlendAttachmentState.srcColorBlendFactor = VK_BLEND_FACTOR_SRC_ALPHA;
+      pipelineColorBlendAttachmentState.dstColorBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
+      pipelineColorBlendAttachmentState.colorBlendOp = VK_BLEND_OP_ADD;
+      pipelineColorBlendAttachmentState.srcAlphaBlendFactor = VK_BLEND_FACTOR_ONE;
+      pipelineColorBlendAttachmentState.dstAlphaBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
+      pipelineColorBlendAttachmentState.alphaBlendOp = VK_BLEND_OP_ADD;
+      pipelineColorBlendAttachmentState.colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;
+
+      VkPipelineColorBlendStateCreateInfo pipelineColorBlendStateCreateInfo = VkPipelineColorBlendStateCreateInfo();
+      pipelineColorBlendStateCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
+      pipelineColorBlendStateCreateInfo.logicOpEnable = VK_FALSE;
+      pipelineColorBlendStateCreateInfo.attachmentCount = 1;
+      pipelineColorBlendStateCreateInfo.pAttachments = &pipelineColorBlendAttachmentState;
+
+      VkGraphicsPipelineCreateInfo graphicsPipelineCreateInfo = VkGraphicsPipelineCreateInfo();
+      graphicsPipelineCreateInfo.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
+      graphicsPipelineCreateInfo.stageCount = 2;
+      graphicsPipelineCreateInfo.pStages = shaderStages;
+      graphicsPipelineCreateInfo.pVertexInputState = &vertexInputStateCreateInfo;
+      graphicsPipelineCreateInfo.pInputAssemblyState = &inputAssemblyStateCreateInfo;
+      graphicsPipelineCreateInfo.pViewportState = &pipelineViewportStateCreateInfo;
+      graphicsPipelineCreateInfo.pRasterizationState = &pipelineRasterizationStateCreateInfo;
+      graphicsPipelineCreateInfo.pDepthStencilState = &pipelineDepthStencilStateCreateInfo;
+      graphicsPipelineCreateInfo.pMultisampleState = &pipelineMultisampleStateCreateInfo;
+      graphicsPipelineCreateInfo.pColorBlendState = &pipelineColorBlendStateCreateInfo;
+      graphicsPipelineCreateInfo.layout = pipelineLayout;
+      graphicsPipelineCreateInfo.renderPass = renderPass;
+      graphicsPipelineCreateInfo.subpass = 0;
+
+      // Create our graphics pipeline
+      if (vkCreateGraphicsPipelines(device, VK_NULL_HANDLE, 1, &graphicsPipelineCreateInfo, 0, &graphicsPipeline) != VK_SUCCESS)
+      {
+         vulkanAvailable = false;
+         return;
+      }
+   }
+
+   // Use our renderpass and swapchain images to create the corresponding framebuffers
+   void setupFramebuffers()
+   {
+      swapchainFramebuffers.resize(swapchainImageViews.size());
+
+      VkFramebufferCreateInfo framebufferCreateInfo = VkFramebufferCreateInfo();
+      framebufferCreateInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
+      framebufferCreateInfo.renderPass = renderPass;
+      framebufferCreateInfo.attachmentCount = 2;
+      framebufferCreateInfo.width = swapchainExtent.width;
+      framebufferCreateInfo.height = swapchainExtent.height;
+      framebufferCreateInfo.layers = 1;
+
+      for (std::size_t i = 0; i < swapchainFramebuffers.size(); i++)
+      {
+         // Each framebuffer consists of a corresponding swapchain image and the shared depth image
+         VkImageView attachments[] = { swapchainImageViews[i], depthImageView };
+
+         framebufferCreateInfo.pAttachments = attachments;
+
+         // Create the framebuffer
+         if (vkCreateFramebuffer(device, &framebufferCreateInfo, 0, &swapchainFramebuffers[i]) != VK_SUCCESS)
+         {
+            vulkanAvailable = false;
+            return;
+         }
+      }
+   }
+
+   // Set up our command pool
+   void setupCommandPool()
+   {
+      // We want to be able to reset command buffers after submitting them
+      VkCommandPoolCreateInfo commandPoolCreateInfo = VkCommandPoolCreateInfo();
+      commandPoolCreateInfo.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
+      commandPoolCreateInfo.queueFamilyIndex = queueFamilyIndex;
+      commandPoolCreateInfo.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
+
+      // Create our command pool
+      if (vkCreateCommandPool(device, &commandPoolCreateInfo, 0, &commandPool) != VK_SUCCESS)
+      {
+         vulkanAvailable = false;
+         return;
+      }
+   }
+
+   // Helper to create a generic buffer with the specified size, usage and memory flags
+   bool createBuffer(VkDeviceSize size, VkBufferUsageFlags usage, VkMemoryPropertyFlags properties, VkBuffer& buffer, VkDeviceMemory& memory)
+   {
+      // We only have a single queue so we can request exclusive access
+      VkBufferCreateInfo bufferCreateInfo = VkBufferCreateInfo();
+      bufferCreateInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
+      bufferCreateInfo.size = size;
+      bufferCreateInfo.usage = usage;
+      bufferCreateInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
+
+      // Create the buffer, this does not allocate any memory for it yet
+      if (vkCreateBuffer(device, &bufferCreateInfo, 0, &buffer) != VK_SUCCESS)
+         return false;
+
+      // Check what kind of memory we need to request from the GPU
+      VkMemoryRequirements memoryRequirements = VkMemoryRequirements();
+      vkGetBufferMemoryRequirements(device, buffer, &memoryRequirements);
+
+      // Check what GPU memory type is available for us to allocate out of
+      VkPhysicalDeviceMemoryProperties memoryProperties = VkPhysicalDeviceMemoryProperties();
+      vkGetPhysicalDeviceMemoryProperties(gpu, &memoryProperties);
+
+      uint32_t memoryType = 0;
+
+      for (; memoryType < memoryProperties.memoryTypeCount; memoryType++)
+      {
+         if ((memoryRequirements.memoryTypeBits & (1 << memoryType)) &&
+            ((memoryProperties.memoryTypes[memoryType].propertyFlags & properties) == properties))
+            break;
+      }
+
+      if (memoryType == memoryProperties.memoryTypeCount)
+         return false;
+
+      VkMemoryAllocateInfo memoryAllocateInfo = VkMemoryAllocateInfo();
+      memoryAllocateInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
+      memoryAllocateInfo.allocationSize = memoryRequirements.size;
+      memoryAllocateInfo.memoryTypeIndex = memoryType;
+
+      // Allocate the memory out of the GPU pool for the required memory type
+      if (vkAllocateMemory(device, &memoryAllocateInfo, 0, &memory) != VK_SUCCESS)
+         return false;
+
+      // Bind the allocated memory to our buffer object
+      if (vkBindBufferMemory(device, buffer, memory, 0) != VK_SUCCESS)
+         return false;
+
+      return true;
+   }
+
+   // Helper to copy the contents of one buffer to another buffer
+   bool copyBuffer(VkBuffer dst, VkBuffer src, VkDeviceSize size)
+   {
+      // Allocate a primary command buffer out of our command pool
+      VkCommandBufferAllocateInfo commandBufferAllocateInfo = VkCommandBufferAllocateInfo();
+      commandBufferAllocateInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
+      commandBufferAllocateInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
+      commandBufferAllocateInfo.commandPool = commandPool;
+      commandBufferAllocateInfo.commandBufferCount = 1;
+
+      VkCommandBuffer commandBuffer;
+
+      if (vkAllocateCommandBuffers(device, &commandBufferAllocateInfo, &commandBuffer) != VK_SUCCESS)
+         return false;
+
+      // Begin the command buffer
+      VkCommandBufferBeginInfo commandBufferBeginInfo = VkCommandBufferBeginInfo();
+      commandBufferBeginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
+      commandBufferBeginInfo.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
+
+      if (vkBeginCommandBuffer(commandBuffer, &commandBufferBeginInfo) != VK_SUCCESS)
+      {
+         vkFreeCommandBuffers(device, commandPool, 1, &commandBuffer);
+
+         return false;
+      }
+
+      // Add our buffer copy command
+      VkBufferCopy bufferCopy = VkBufferCopy();
+      bufferCopy.srcOffset = 0;
+      bufferCopy.dstOffset = 0;
+      bufferCopy.size = size;
+
+      vkCmdCopyBuffer(commandBuffer, src, dst, 1, &bufferCopy);
+
+      // End and submit the command buffer
+      vkEndCommandBuffer(commandBuffer);
+
+      VkSubmitInfo submitInfo = VkSubmitInfo();
+      submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
+      submitInfo.commandBufferCount = 1;
+      submitInfo.pCommandBuffers = &commandBuffer;
+
+      if (vkQueueSubmit(queue, 1, &submitInfo, VK_NULL_HANDLE) != VK_SUCCESS)
+      {
+         vkFreeCommandBuffers(device, commandPool, 1, &commandBuffer);
+
+         return false;
+      }
+
+      // Ensure the command buffer has been processed
+      if (vkQueueWaitIdle(queue) != VK_SUCCESS)
+      {
+         vkFreeCommandBuffers(device, commandPool, 1, &commandBuffer);
+
+         return false;
+      }
+
+      // Free the command buffer
+      vkFreeCommandBuffers(device, commandPool, 1, &commandBuffer);
+
+      return true;
+   }
+
+   // Create our vertex buffer and upload its data
+   void setupVertexBuffer()
+   {
+      float vertexData[] = {
+         // X      Y      Z     R     G     B     A     U     V
+         -0.5f, -0.5f,  0.5f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f,
+          0.5f, -0.5f,  0.5f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
+          0.5f,  0.5f,  0.5f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f,
+         -0.5f,  0.5f,  0.5f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f,
+
+         -0.5f, -0.5f, -0.5f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f,
+          0.5f, -0.5f, -0.5f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f,
+          0.5f,  0.5f, -0.5f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f,
+         -0.5f,  0.5f, -0.5f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f,
+
+          0.5f, -0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f,
+          0.5f,  0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f,
+          0.5f,  0.5f,  0.5f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f,
+          0.5f, -0.5f,  0.5f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f,
+
+         -0.5f, -0.5f, -0.5f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f,
+         -0.5f,  0.5f, -0.5f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f,
+         -0.5f,  0.5f,  0.5f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f,
+         -0.5f, -0.5f,  0.5f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f,
+
+         -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f,
+          0.5f, -0.5f, -0.5f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f,
+          0.5f, -0.5f,  0.5f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f,
+         -0.5f, -0.5f,  0.5f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f,
+
+         -0.5f,  0.5f, -0.5f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f,
+          0.5f,  0.5f, -0.5f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f,
+          0.5f,  0.5f,  0.5f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f,
+         -0.5f,  0.5f,  0.5f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f
+      };
+
+      // Create a staging buffer that is writable by the CPU
+      VkBuffer stagingBuffer = 0;
+      VkDeviceMemory stagingBufferMemory = 0;
+
+      if (!createBuffer(
+         sizeof(vertexData),
+         VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
+         VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
+         stagingBuffer,
+         stagingBufferMemory
+      ))
+      {
+         vulkanAvailable = false;
+         return;
+      }
+
+      void* ptr;
+
+      // Map the buffer into our address space
+      if (vkMapMemory(device, stagingBufferMemory, 0, sizeof(vertexData), 0, &ptr) != VK_SUCCESS)
+      {
+         vkFreeMemory(device, stagingBufferMemory, 0);
+         vkDestroyBuffer(device, stagingBuffer, 0);
+
+         vulkanAvailable = false;
+         return;
+      }
+
+      // Copy the vertex data into the buffer
+      std::memcpy(ptr, vertexData, sizeof(vertexData));
+
+      // Unmap the buffer
+      vkUnmapMemory(device, stagingBufferMemory);
+
+      // Create the GPU local vertex buffer
+      if (!createBuffer(
+         sizeof(vertexData),
+         VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,
+         VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
+         vertexBuffer,
+         vertexBufferMemory
+      ))
+      {
+         vkFreeMemory(device, stagingBufferMemory, 0);
+         vkDestroyBuffer(device, stagingBuffer, 0);
+
+         vulkanAvailable = false;
+         return;
+      }
+
+      // Copy the contents of the staging buffer into the GPU vertex buffer
+      vulkanAvailable = copyBuffer(vertexBuffer, stagingBuffer, sizeof(vertexData));
+
+      // Free the staging buffer and its memory
+      vkFreeMemory(device, stagingBufferMemory, 0);
+      vkDestroyBuffer(device, stagingBuffer, 0);
+   }
+
+   // Create our index buffer and upload its data
+   void setupIndexBuffer()
+   {
+      uint16_t indexData[] = {
+          0,  1,  2,
+          2,  3,  0,
+
+          4,  5,  6,
+          6,  7,  4,
+
+          8,  9,  10,
+          10, 11, 8,
+
+          12, 13, 14,
+          14, 15, 12,
+
+          16, 17, 18,
+          18, 19, 16,
+
+          20, 21, 22,
+          22, 23, 20
+      };
+
+      // Create a staging buffer that is writable by the CPU
+      VkBuffer stagingBuffer = 0;
+      VkDeviceMemory stagingBufferMemory = 0;
+
+      if (!createBuffer(
+         sizeof(indexData),
+         VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
+         VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
+         stagingBuffer,
+         stagingBufferMemory
+      ))
+      {
+         vulkanAvailable = false;
+         return;
+      }
+
+      void* ptr;
+
+      // Map the buffer into our address space
+      if (vkMapMemory(device, stagingBufferMemory, 0, sizeof(indexData), 0, &ptr) != VK_SUCCESS)
+      {
+         vkFreeMemory(device, stagingBufferMemory, 0);
+         vkDestroyBuffer(device, stagingBuffer, 0);
+
+         vulkanAvailable = false;
+         return;
+      }
+
+      // Copy the index data into the buffer
+      std::memcpy(ptr, indexData, sizeof(indexData));
+
+      // Unmap the buffer
+      vkUnmapMemory(device, stagingBufferMemory);
+
+      // Create the GPU local index buffer
+      if (!createBuffer(
+         sizeof(indexData),
+         VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_INDEX_BUFFER_BIT,
+         VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
+         indexBuffer,
+         indexBufferMemory
+      ))
+      {
+         vkFreeMemory(device, stagingBufferMemory, 0);
+         vkDestroyBuffer(device, stagingBuffer, 0);
+
+         vulkanAvailable = false;
+         return;
+      }
+
+      // Copy the contents of the staging buffer into the GPU index buffer
+      vulkanAvailable = copyBuffer(indexBuffer, stagingBuffer, sizeof(indexData));
+
+      // Free the staging buffer and its memory
+      vkFreeMemory(device, stagingBufferMemory, 0);
+      vkDestroyBuffer(device, stagingBuffer, 0);
+   }
+
+   // Create our uniform buffer but don't upload any data yet
+   void setupUniformBuffers()
+   {
+      // Create a uniform buffer for every frame that might be in flight to prevent clobbering
+      for (size_t i = 0; i < swapchainImages.size(); i++)
+      {
+         uniformBuffers.push_back(0);
+         uniformBuffersMemory.push_back(0);
+
+         // The uniform buffer will be host visible and coherent since we use it for streaming data every frame
+         if (!createBuffer(
+            sizeof(Matrix) * 3,
+            VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,
+            VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
+            uniformBuffers[i],
+            uniformBuffersMemory[i]
+         ))
+         {
+            vulkanAvailable = false;
+            return;
+         }
+      }
+   }
+
+   // Helper to create a generic image with the specified size, format, usage and memory flags
+   bool createImage(uint32_t width, uint32_t height, VkFormat format, VkImageTiling tiling, VkImageUsageFlags usage, VkMemoryPropertyFlags properties, VkImage& image, VkDeviceMemory& imageMemory)
+   {
+      // We only have a single queue so we can request exclusive access
+      VkImageCreateInfo imageCreateInfo = VkImageCreateInfo();
+      imageCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
+      imageCreateInfo.imageType = VK_IMAGE_TYPE_2D;
+      imageCreateInfo.extent.width = width;
+      imageCreateInfo.extent.height = height;
+      imageCreateInfo.extent.depth = 1;
+      imageCreateInfo.mipLevels = 1;
+      imageCreateInfo.arrayLayers = 1;
+      imageCreateInfo.format = format;
+      imageCreateInfo.tiling = tiling;
+      imageCreateInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
+      imageCreateInfo.usage = usage;
+      imageCreateInfo.samples = VK_SAMPLE_COUNT_1_BIT;
+      imageCreateInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
+
+      // Create the image, this does not allocate any memory for it yet
+      if (vkCreateImage(device, &imageCreateInfo, 0, &image) != VK_SUCCESS)
+         return false;
+
+      // Check what kind of memory we need to request from the GPU
+      VkMemoryRequirements memoryRequirements = VkMemoryRequirements();
+      vkGetImageMemoryRequirements(device, image, &memoryRequirements);
+
+      // Check what GPU memory type is available for us to allocate out of
+      VkPhysicalDeviceMemoryProperties memoryProperties = VkPhysicalDeviceMemoryProperties();
+      vkGetPhysicalDeviceMemoryProperties(gpu, &memoryProperties);
+
+      uint32_t memoryType = 0;
+
+      for (; memoryType < memoryProperties.memoryTypeCount; memoryType++)
+      {
+         if ((memoryRequirements.memoryTypeBits & (1 << memoryType)) &&
+            ((memoryProperties.memoryTypes[memoryType].propertyFlags & properties) == properties))
+            break;
+      }
+
+      if (memoryType == memoryProperties.memoryTypeCount)
+         return false;
+
+      VkMemoryAllocateInfo memoryAllocateInfo = VkMemoryAllocateInfo();
+      memoryAllocateInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
+      memoryAllocateInfo.allocationSize = memoryRequirements.size;
+      memoryAllocateInfo.memoryTypeIndex = memoryType;
+
+      // Allocate the memory out of the GPU pool for the required memory type
+      if (vkAllocateMemory(device, &memoryAllocateInfo, 0, &imageMemory) != VK_SUCCESS)
+         return false;
+
+      // Bind the allocated memory to our image object
+      if (vkBindImageMemory(device, image, imageMemory, 0) != VK_SUCCESS)
+         return false;
+
+      return true;
+   }
+
+   // Create our depth image and transition it into the proper layout
+   void setupDepthImage()
+   {
+      // Create our depth image
+      if (!createImage(
+         swapchainExtent.width,
+         swapchainExtent.height,
+         depthFormat,
+         VK_IMAGE_TILING_OPTIMAL,
+         VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT,
+         VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
+         depthImage,
+         depthImageMemory
+      ))
+      {
+         vulkanAvailable = false;
+         return;
+      }
+
+      // Allocate a command buffer
+      VkCommandBufferAllocateInfo commandBufferAllocateInfo = VkCommandBufferAllocateInfo();
+      commandBufferAllocateInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
+      commandBufferAllocateInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
+      commandBufferAllocateInfo.commandPool = commandPool;
+      commandBufferAllocateInfo.commandBufferCount = 1;
+
+      VkCommandBuffer commandBuffer;
+
+      if (vkAllocateCommandBuffers(device, &commandBufferAllocateInfo, &commandBuffer) != VK_SUCCESS)
+      {
+         vulkanAvailable = false;
+         return;
+      }
+
+      // Begin the command buffer
+      VkCommandBufferBeginInfo commandBufferBeginInfo = VkCommandBufferBeginInfo();
+      commandBufferBeginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
+      commandBufferBeginInfo.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
+
+      VkSubmitInfo submitInfo = VkSubmitInfo();
+      submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
+      submitInfo.commandBufferCount = 1;
+      submitInfo.pCommandBuffers = &commandBuffer;
+
+      if (vkBeginCommandBuffer(commandBuffer, &commandBufferBeginInfo) != VK_SUCCESS)
+      {
+         vkFreeCommandBuffers(device, commandPool, 1, &commandBuffer);
+
+         vulkanAvailable = false;
+         return;
+      }
+
+      // Submit a barrier to transition the image layout to depth stencil optimal
+      VkImageMemoryBarrier barrier = VkImageMemoryBarrier();
+      barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
+      barrier.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED;
+      barrier.newLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
+      barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
+      barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
+      barrier.image = depthImage;
+      barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT | ((depthFormat == VK_FORMAT_D32_SFLOAT) ? 0 : VK_IMAGE_ASPECT_STENCIL_BIT);
+      barrier.subresourceRange.baseMipLevel = 0;
+      barrier.subresourceRange.levelCount = 1;
+      barrier.subresourceRange.baseArrayLayer = 0;
+      barrier.subresourceRange.layerCount = 1;
+      barrier.srcAccessMask = 0;
+      barrier.dstAccessMask = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
+
+      vkCmdPipelineBarrier(commandBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT, 0, 0, 0, 0, 0, 1, &barrier);
+
+      // End and submit the command buffer
+      if (vkEndCommandBuffer(commandBuffer) != VK_SUCCESS)
+      {
+         vkFreeCommandBuffers(device, commandPool, 1, &commandBuffer);
+
+         vulkanAvailable = false;
+         return;
+      }
+
+      if (vkQueueSubmit(queue, 1, &submitInfo, VK_NULL_HANDLE) != VK_SUCCESS)
+      {
+         vkFreeCommandBuffers(device, commandPool, 1, &commandBuffer);
+
+         vulkanAvailable = false;
+         return;
+      }
+
+      // Ensure the command buffer has been processed
+      if (vkQueueWaitIdle(queue) != VK_SUCCESS)
+      {
+         vkFreeCommandBuffers(device, commandPool, 1, &commandBuffer);
+
+         vulkanAvailable = false;
+         return;
+      }
+
+      // Free the command buffer
+      vkFreeCommandBuffers(device, commandPool, 1, &commandBuffer);
+   }
+
+   // Create an image view for our depth image
+   void setupDepthImageView()
+   {
+      VkImageViewCreateInfo imageViewCreateInfo = VkImageViewCreateInfo();
+      imageViewCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
+      imageViewCreateInfo.image = depthImage;
+      imageViewCreateInfo.viewType = VK_IMAGE_VIEW_TYPE_2D;
+      imageViewCreateInfo.format = depthFormat;
+      imageViewCreateInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT | ((depthFormat == VK_FORMAT_D32_SFLOAT) ? 0 : VK_IMAGE_ASPECT_STENCIL_BIT);
+      imageViewCreateInfo.subresourceRange.baseMipLevel = 0;
+      imageViewCreateInfo.subresourceRange.levelCount = 1;
+      imageViewCreateInfo.subresourceRange.baseArrayLayer = 0;
+      imageViewCreateInfo.subresourceRange.layerCount = 1;
+
+      // Create the depth image view
+      if (vkCreateImageView(device, &imageViewCreateInfo, 0, &depthImageView) != VK_SUCCESS)
+      {
+         vulkanAvailable = false;
+         return;
+      }
+   }
+
+   // Create an image for our texture data
+   void setupTextureImage()
+   {
+      // Load the image data
+      sf::Image imageData;
+
+      if (!imageData.loadFromFile("resources/logo.png"))
+      {
+         vulkanAvailable = false;
+         return;
+      }
+
+      // Create a staging buffer to transfer the data with
+      VkDeviceSize imageSize = imageData.getSize().x * imageData.getSize().y * 4;
+
+      VkBuffer stagingBuffer;
+      VkDeviceMemory stagingBufferMemory;
+      createBuffer(imageSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, stagingBuffer, stagingBufferMemory);
+
+      void* ptr;
+
+      // Map the buffer into our address space
+      if (vkMapMemory(device, stagingBufferMemory, 0, imageSize, 0, &ptr) != VK_SUCCESS)
+      {
+         vkFreeMemory(device, stagingBufferMemory, 0);
+         vkDestroyBuffer(device, stagingBuffer, 0);
+
+         vulkanAvailable = false;
+         return;
+      }
+
+      // Copy the image data into the buffer
+      std::memcpy(ptr, imageData.getPixelsPtr(), static_cast<size_t>(imageSize));
+
+      // Unmap the buffer
+      vkUnmapMemory(device, stagingBufferMemory);
+
+      // Create a GPU local image
+      if (!createImage(
+         imageData.getSize().x,
+         imageData.getSize().y,
+         VK_FORMAT_R8G8B8A8_UNORM,
+         VK_IMAGE_TILING_OPTIMAL,
+         VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT,
+         VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
+         textureImage,
+         textureImageMemory
+      ))
+      {
+         vkFreeMemory(device, stagingBufferMemory, 0);
+         vkDestroyBuffer(device, stagingBuffer, 0);
+
+         vulkanAvailable = false;
+         return;
+      }
+
+      // Create a command buffer
+      VkCommandBufferAllocateInfo commandBufferAllocateInfo = VkCommandBufferAllocateInfo();
+      commandBufferAllocateInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
+      commandBufferAllocateInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
+      commandBufferAllocateInfo.commandPool = commandPool;
+      commandBufferAllocateInfo.commandBufferCount = 1;
+
+      VkCommandBuffer commandBuffer;
+
+      if (vkAllocateCommandBuffers(device, &commandBufferAllocateInfo, &commandBuffer) != VK_SUCCESS)
+      {
+         vkFreeMemory(device, stagingBufferMemory, 0);
+         vkDestroyBuffer(device, stagingBuffer, 0);
+
+         vulkanAvailable = false;
+         return;
+      }
+
+      // Begin the command buffer
+      VkCommandBufferBeginInfo commandBufferBeginInfo = VkCommandBufferBeginInfo();
+      commandBufferBeginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
+      commandBufferBeginInfo.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
+
+      VkSubmitInfo submitInfo = VkSubmitInfo();
+      submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
+      submitInfo.commandBufferCount = 1;
+      submitInfo.pCommandBuffers = &commandBuffer;
+
+      if (vkBeginCommandBuffer(commandBuffer, &commandBufferBeginInfo) != VK_SUCCESS)
+      {
+         vkFreeCommandBuffers(device, commandPool, 1, &commandBuffer);
+
+         vkFreeMemory(device, stagingBufferMemory, 0);
+         vkDestroyBuffer(device, stagingBuffer, 0);
+
+         vulkanAvailable = false;
+         return;
+      }
+
+      // Submit a barrier to transition the image layout to transfer destionation optimal
+      VkImageMemoryBarrier barrier = VkImageMemoryBarrier();
+      barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
+      barrier.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED;
+      barrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
+      barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
+      barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
+      barrier.image = textureImage;
+      barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
+      barrier.subresourceRange.baseMipLevel = 0;
+      barrier.subresourceRange.levelCount = 1;
+      barrier.subresourceRange.baseArrayLayer = 0;
+      barrier.subresourceRange.layerCount = 1;
+      barrier.srcAccessMask = 0;
+      barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
+
+      vkCmdPipelineBarrier(commandBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, 0, 0, 0, 1, &barrier);
+
+      if (vkEndCommandBuffer(commandBuffer) != VK_SUCCESS)
+      {
+         vkFreeCommandBuffers(device, commandPool, 1, &commandBuffer);
+
+         vkFreeMemory(device, stagingBufferMemory, 0);
+         vkDestroyBuffer(device, stagingBuffer, 0);
+
+         vulkanAvailable = false;
+         return;
+      }
+
+      if (vkQueueSubmit(queue, 1, &submitInfo, VK_NULL_HANDLE) != VK_SUCCESS)
+      {
+         vkFreeCommandBuffers(device, commandPool, 1, &commandBuffer);
+
+         vkFreeMemory(device, stagingBufferMemory, 0);
+         vkDestroyBuffer(device, stagingBuffer, 0);
+
+         vulkanAvailable = false;
+         return;
+      }
+
+      // Ensure the command buffer has been processed
+      if (vkQueueWaitIdle(queue) != VK_SUCCESS)
+      {
+         vkFreeCommandBuffers(device, commandPool, 1, &commandBuffer);
+
+         vkFreeMemory(device, stagingBufferMemory, 0);
+         vkDestroyBuffer(device, stagingBuffer, 0);
+
+         vulkanAvailable = false;
+         return;
+      }
+
+      // Begin the command buffer
+      if (vkBeginCommandBuffer(commandBuffer, &commandBufferBeginInfo) != VK_SUCCESS)
+      {
+         vkFreeCommandBuffers(device, commandPool, 1, &commandBuffer);
+
+         vkFreeMemory(device, stagingBufferMemory, 0);
+         vkDestroyBuffer(device, stagingBuffer, 0);
+
+         vulkanAvailable = false;
+         return;
+      }
+
+      // Copy the staging buffer contents into the image
+      VkBufferImageCopy bufferImageCopy = VkBufferImageCopy();
+      bufferImageCopy.bufferOffset = 0;
+      bufferImageCopy.bufferRowLength = 0;
+      bufferImageCopy.bufferImageHeight = 0;
+      bufferImageCopy.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
+      bufferImageCopy.imageSubresource.mipLevel = 0;
+      bufferImageCopy.imageSubresource.baseArrayLayer = 0;
+      bufferImageCopy.imageSubresource.layerCount = 1;
+      bufferImageCopy.imageOffset.x = 0;
+      bufferImageCopy.imageOffset.y = 0;
+      bufferImageCopy.imageOffset.z = 0;
+      bufferImageCopy.imageExtent.width = imageData.getSize().x;
+      bufferImageCopy.imageExtent.height = imageData.getSize().y;
+      bufferImageCopy.imageExtent.depth = 1;
+
+      vkCmdCopyBufferToImage(commandBuffer, stagingBuffer, textureImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &bufferImageCopy);
+
+      // End and submit the command buffer
+      if (vkEndCommandBuffer(commandBuffer) != VK_SUCCESS)
+      {
+         vkFreeCommandBuffers(device, commandPool, 1, &commandBuffer);
+
+         vkFreeMemory(device, stagingBufferMemory, 0);
+         vkDestroyBuffer(device, stagingBuffer, 0);
+
+         vulkanAvailable = false;
+         return;
+      }
+
+      if (vkQueueSubmit(queue, 1, &submitInfo, VK_NULL_HANDLE) != VK_SUCCESS)
+      {
+         vkFreeCommandBuffers(device, commandPool, 1, &commandBuffer);
+
+         vkFreeMemory(device, stagingBufferMemory, 0);
+         vkDestroyBuffer(device, stagingBuffer, 0);
+
+         vulkanAvailable = false;
+         return;
+      }
+
+      // Ensure the command buffer has been processed
+      if (vkQueueWaitIdle(queue) != VK_SUCCESS)
+      {
+         vkFreeCommandBuffers(device, commandPool, 1, &commandBuffer);
+
+         vkFreeMemory(device, stagingBufferMemory, 0);
+         vkDestroyBuffer(device, stagingBuffer, 0);
+
+         vulkanAvailable = false;
+         return;
+      }
+
+      // Begin the command buffer
+      if (vkBeginCommandBuffer(commandBuffer, &commandBufferBeginInfo) != VK_SUCCESS)
+      {
+         vkFreeCommandBuffers(device, commandPool, 1, &commandBuffer);
+
+         vkFreeMemory(device, stagingBufferMemory, 0);
+         vkDestroyBuffer(device, stagingBuffer, 0);
+
+         vulkanAvailable = false;
+         return;
+      }
+
+      // Submit a barrier to transition the image layout from transfer destionation optimal to shader read-only optimal
+      barrier.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
+      barrier.newLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
+      barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
+      barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
+
+      vkCmdPipelineBarrier(commandBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 0, 0, 0, 0, 0, 1, &barrier);
+
+      // End and submit the command buffer
+      if (vkEndCommandBuffer(commandBuffer) != VK_SUCCESS)
+      {
+         vkFreeCommandBuffers(device, commandPool, 1, &commandBuffer);
+
+         vkFreeMemory(device, stagingBufferMemory, 0);
+         vkDestroyBuffer(device, stagingBuffer, 0);
+
+         vulkanAvailable = false;
+         return;
+      }
+
+      if (vkQueueSubmit(queue, 1, &submitInfo, VK_NULL_HANDLE) != VK_SUCCESS)
+      {
+         vkFreeCommandBuffers(device, commandPool, 1, &commandBuffer);
+
+         vkFreeMemory(device, stagingBufferMemory, 0);
+         vkDestroyBuffer(device, stagingBuffer, 0);
+
+         vulkanAvailable = false;
+         return;
+      }
+
+      // Ensure the command buffer has been processed
+      if (vkQueueWaitIdle(queue) != VK_SUCCESS)
+      {
+         vkFreeCommandBuffers(device, commandPool, 1, &commandBuffer);
+
+         vkFreeMemory(device, stagingBufferMemory, 0);
+         vkDestroyBuffer(device, stagingBuffer, 0);
+
+         vulkanAvailable = false;
+         return;
+      }
+
+      // Free the command buffer
+      vkFreeCommandBuffers(device, commandPool, 1, &commandBuffer);
+
+      vkFreeMemory(device, stagingBufferMemory, 0);
+      vkDestroyBuffer(device, stagingBuffer, 0);
+   }
+
+   // Create an image view for our texture
+   void setupTextureImageView()
+   {
+      VkImageViewCreateInfo imageViewCreateInfo = VkImageViewCreateInfo();
+      imageViewCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
+      imageViewCreateInfo.image = textureImage;
+      imageViewCreateInfo.viewType = VK_IMAGE_VIEW_TYPE_2D;
+      imageViewCreateInfo.format = VK_FORMAT_R8G8B8A8_UNORM;
+      imageViewCreateInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
+      imageViewCreateInfo.subresourceRange.baseMipLevel = 0;
+      imageViewCreateInfo.subresourceRange.levelCount = 1;
+      imageViewCreateInfo.subresourceRange.baseArrayLayer = 0;
+      imageViewCreateInfo.subresourceRange.layerCount = 1;
+
+      // Create our texture image view
+      if (vkCreateImageView(device, &imageViewCreateInfo, 0, &textureImageView) != VK_SUCCESS)
+      {
+         vulkanAvailable = false;
+         return;
+      }
+   }
+
+   // Create a sampler for our texture
+   void setupTextureSampler()
+   {
+      // Sampler parameters: linear min/mag filtering, 4x anisotropic
+      VkSamplerCreateInfo samplerCreateInfo = VkSamplerCreateInfo();
+      samplerCreateInfo.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
+      samplerCreateInfo.magFilter = VK_FILTER_LINEAR;
+      samplerCreateInfo.minFilter = VK_FILTER_LINEAR;
+      samplerCreateInfo.addressModeU = VK_SAMPLER_ADDRESS_MODE_REPEAT;
+      samplerCreateInfo.addressModeV = VK_SAMPLER_ADDRESS_MODE_REPEAT;
+      samplerCreateInfo.addressModeW = VK_SAMPLER_ADDRESS_MODE_REPEAT;
+      samplerCreateInfo.anisotropyEnable = VK_TRUE;
+      samplerCreateInfo.maxAnisotropy = 4;
+      samplerCreateInfo.borderColor = VK_BORDER_COLOR_INT_OPAQUE_BLACK;
+      samplerCreateInfo.unnormalizedCoordinates = VK_FALSE;
+      samplerCreateInfo.compareEnable = VK_FALSE;
+      samplerCreateInfo.compareOp = VK_COMPARE_OP_ALWAYS;
+      samplerCreateInfo.mipmapMode = VK_SAMPLER_MIPMAP_MODE_LINEAR;
+      samplerCreateInfo.mipLodBias = 0.0f;
+      samplerCreateInfo.minLod = 0.0f;
+      samplerCreateInfo.maxLod = 0.0f;
+
+      // Create our sampler
+      if (vkCreateSampler(device, &samplerCreateInfo, 0, &textureSampler) != VK_SUCCESS)
+      {
+         vulkanAvailable = false;
+         return;
+      }
+   }
+
+   // Set up our descriptor pool
+   void setupDescriptorPool()
+   {
+      // We need to allocate as many descriptor sets as we have frames in flight
+      VkDescriptorPoolSize descriptorPoolSizes[2];
+
+      descriptorPoolSizes[0] = VkDescriptorPoolSize();
+      descriptorPoolSizes[0].type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
+      descriptorPoolSizes[0].descriptorCount = static_cast<uint32_t>(swapchainImages.size());
+
+      descriptorPoolSizes[1] = VkDescriptorPoolSize();
+      descriptorPoolSizes[1].type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
+      descriptorPoolSizes[1].descriptorCount = static_cast<uint32_t>(swapchainImages.size());
+
+      VkDescriptorPoolCreateInfo descriptorPoolCreateInfo = VkDescriptorPoolCreateInfo();
+      descriptorPoolCreateInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
+      descriptorPoolCreateInfo.poolSizeCount = 2;
+      descriptorPoolCreateInfo.pPoolSizes = descriptorPoolSizes;
+      descriptorPoolCreateInfo.maxSets = static_cast<uint32_t>(swapchainImages.size());
+
+      // Create the descriptor pool
+      if (vkCreateDescriptorPool(device, &descriptorPoolCreateInfo, 0, &descriptorPool) != VK_SUCCESS)
+      {
+         vulkanAvailable = false;
+         return;
+      }
+   }
+
+   // Set up our descriptor sets
+   void setupDescriptorSets()
+   {
+      // Allocate a descriptor set for each frame in flight
+      std::vector<VkDescriptorSetLayout> descriptorSetLayouts(swapchainImages.size(), descriptorSetLayout);
+
+      VkDescriptorSetAllocateInfo descriptorSetAllocateInfo = VkDescriptorSetAllocateInfo();
+      descriptorSetAllocateInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
+      descriptorSetAllocateInfo.descriptorPool = descriptorPool;
+      descriptorSetAllocateInfo.descriptorSetCount = static_cast<uint32_t>(swapchainImages.size());
+      descriptorSetAllocateInfo.pSetLayouts = &descriptorSetLayouts[0];
+
+      descriptorSets.resize(swapchainImages.size());
+
+      if (vkAllocateDescriptorSets(device, &descriptorSetAllocateInfo, &descriptorSets[0]) != VK_SUCCESS)
+      {
+         descriptorSets.clear();
+
+         vulkanAvailable = false;
+         return;
+      }
+
+      // For every descriptor set, set up the bindings to our uniform buffer and texture sampler
+      for (std::size_t i = 0; i < descriptorSets.size(); i++)
+      {
+         VkWriteDescriptorSet writeDescriptorSets[2];
+
+         // Uniform buffer binding information
+         VkDescriptorBufferInfo descriptorBufferInfo = VkDescriptorBufferInfo();
+         descriptorBufferInfo.buffer = uniformBuffers[i];
+         descriptorBufferInfo.offset = 0;
+         descriptorBufferInfo.range = sizeof(Matrix) * 3;
+
+         writeDescriptorSets[0] = VkWriteDescriptorSet();
+         writeDescriptorSets[0].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
+         writeDescriptorSets[0].dstSet = descriptorSets[i];
+         writeDescriptorSets[0].dstBinding = 0;
+         writeDescriptorSets[0].dstArrayElement = 0;
+         writeDescriptorSets[0].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
+         writeDescriptorSets[0].descriptorCount = 1;
+         writeDescriptorSets[0].pBufferInfo = &descriptorBufferInfo;
+
+         // Texture sampler binding information
+         VkDescriptorImageInfo descriptorImageInfo = VkDescriptorImageInfo();
+         descriptorImageInfo.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
+         descriptorImageInfo.imageView = textureImageView;
+         descriptorImageInfo.sampler = textureSampler;
+
+         writeDescriptorSets[1] = VkWriteDescriptorSet();
+         writeDescriptorSets[1].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
+         writeDescriptorSets[1].dstSet = descriptorSets[i];
+         writeDescriptorSets[1].dstBinding = 1;
+         writeDescriptorSets[1].dstArrayElement = 0;
+         writeDescriptorSets[1].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
+         writeDescriptorSets[1].descriptorCount = 1;
+         writeDescriptorSets[1].pImageInfo = &descriptorImageInfo;
+
+         // Update the desciptor set
+         vkUpdateDescriptorSets(device, 2, writeDescriptorSets, 0, 0);
+      }
+   }
+
+   // Set up the command buffers we use for drawing each frame
+   void setupCommandBuffers()
+   {
+      // We need a command buffer for every frame in flight
+      commandBuffers.resize(swapchainFramebuffers.size());
+
+      // These are primary command buffers
+      VkCommandBufferAllocateInfo commandBufferAllocateInfo = VkCommandBufferAllocateInfo();
+      commandBufferAllocateInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
+      commandBufferAllocateInfo.commandPool = commandPool;
+      commandBufferAllocateInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
+      commandBufferAllocateInfo.commandBufferCount = static_cast<uint32_t>(commandBuffers.size());
+
+      // Allocate the command buffers from our command pool
+      if (vkAllocateCommandBuffers(device, &commandBufferAllocateInfo, &commandBuffers[0]) != VK_SUCCESS)
+      {
+         commandBuffers.clear();
+         vulkanAvailable = false;
+         return;
+      }
+   }
+
+   // Set up the commands we need to issue to draw a frame
+   void setupDraw()
+   {
+      // Set up our clear colors
+      VkClearValue clearColors[2];
+
+      // Clear color buffer to opaque black
+      clearColors[0] = VkClearValue();
+      clearColors[0].color.float32[0] = 0.0f;
+      clearColors[0].color.float32[1] = 0.0f;
+      clearColors[0].color.float32[2] = 0.0f;
+      clearColors[0].color.float32[3] = 0.0f;
+
+      // Clear depth to 1.0f
+      clearColors[1] = VkClearValue();
+      clearColors[1].depthStencil.depth = 1.0f;
+      clearColors[1].depthStencil.stencil = 0;
+
+      VkRenderPassBeginInfo renderPassBeginInfo = VkRenderPassBeginInfo();
+      renderPassBeginInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
+      renderPassBeginInfo.renderPass = renderPass;
+      renderPassBeginInfo.renderArea.offset.x = 0;
+      renderPassBeginInfo.renderArea.offset.y = 0;
+      renderPassBeginInfo.renderArea.extent = swapchainExtent;
+      renderPassBeginInfo.clearValueCount = 2;
+      renderPassBeginInfo.pClearValues = clearColors;
+
+      // Simultaneous use: this command buffer can be resubmitted to a queue before a previous submission is completed
+      VkCommandBufferBeginInfo commandBufferBeginInfo = VkCommandBufferBeginInfo();
+      commandBufferBeginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
+      commandBufferBeginInfo.flags = VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT;
+
+      // Set up the command buffers for each frame in flight
+      for (std::size_t i = 0; i < commandBuffers.size(); i++)
+      {
+         // Begin the command buffer
+         if (vkBeginCommandBuffer(commandBuffers[i], &commandBufferBeginInfo) != VK_SUCCESS)
+         {
+            vulkanAvailable = false;
+            return;
+         }
+
+         // Begin the renderpass
+         renderPassBeginInfo.framebuffer = swapchainFramebuffers[i];
+
+         vkCmdBeginRenderPass(commandBuffers[i], &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
+
+         // Bind our graphics pipeline
+         vkCmdBindPipeline(commandBuffers[i], VK_PIPELINE_BIND_POINT_GRAPHICS, graphicsPipeline);
+
+         // Bind our vertex buffer
+         VkDeviceSize offset = 0;
+
+         vkCmdBindVertexBuffers(commandBuffers[i], 0, 1, &vertexBuffer, &offset);
+
+         // Bind our index buffer
+         vkCmdBindIndexBuffer(commandBuffers[i], indexBuffer, 0, VK_INDEX_TYPE_UINT16);
+
+         // Bind our descriptor sets
+         vkCmdBindDescriptorSets(commandBuffers[i], VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout, 0, 1, &descriptorSets[i], 0, 0);
+
+         // Draw our primitives
+         vkCmdDrawIndexed(commandBuffers[i], 36, 1, 0, 0, 0);
+
+         // End the renderpass
+         vkCmdEndRenderPass(commandBuffers[i]);
+
+         // End the command buffer
+         if (vkEndCommandBuffer(commandBuffers[i]) != VK_SUCCESS)
+         {
+            vulkanAvailable = false;
+            return;
+         }
+      }
+   }
+
+   // Set up the semaphores we use to synchronize frames among each other
+   void setupSemaphores()
+   {
+      VkSemaphoreCreateInfo semaphoreCreateInfo = VkSemaphoreCreateInfo();
+      semaphoreCreateInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
+
+      // Create a semaphore to track when an swapchain image is available for each frame in flight
+      for (int i = 0; i < maxFramesInFlight; i++)
+      {
+         imageAvailableSemaphores.push_back(0);
+
+         if (vkCreateSemaphore(device, &semaphoreCreateInfo, 0, &imageAvailableSemaphores[i]) != VK_SUCCESS)
+         {
+            imageAvailableSemaphores.pop_back();
+            vulkanAvailable = false;
+            return;
+         }
+      }
+
+      // Create a semaphore to track when rendering is complete for each frame in flight
+      for (int i = 0; i < maxFramesInFlight; i++)
+      {
+         renderFinishedSemaphores.push_back(0);
+
+         if (vkCreateSemaphore(device, &semaphoreCreateInfo, 0, &renderFinishedSemaphores[i]) != VK_SUCCESS)
+         {
+            renderFinishedSemaphores.pop_back();
+            vulkanAvailable = false;
+            return;
+         }
+      }
+   }
+
+   // Set up the fences we use to synchronize frames among each other
+   void setupFences()
+   {
+      // Create the fences in the signaled state
+      VkFenceCreateInfo fenceCreateInfo = VkFenceCreateInfo();
+      fenceCreateInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
+      fenceCreateInfo.flags = VK_FENCE_CREATE_SIGNALED_BIT;
+
+      // Create a fence to track when queue submission is complete for each frame in flight
+      for (int i = 0; i < maxFramesInFlight; i++)
+      {
+         fences.push_back(0);
+
+         if (vkCreateFence(device, &fenceCreateInfo, 0, &fences[i]) != VK_SUCCESS)
+         {
+            fences.pop_back();
+            vulkanAvailable = false;
+            return;
+         }
+      }
+   }
+
+   // Update the matrices in our uniform buffer every frame
+   void updateUniformBuffer(float elapsed)
+   {
+      const float pi = 3.14159265359f;
+
+      // Construct the model matrix
+      Matrix model = {
+          1.0f, 0.0f, 0.0f, 0.0f,
+          0.0f, 1.0f, 0.0f, 0.0f,
+          0.0f, 0.0f, 1.0f, 0.0f,
+          0.0f, 0.0f, 0.0f, 1.0f
+      };
+
+      matrixRotateX(model, elapsed * 59.0f * pi / 180.f);
+      matrixRotateY(model, elapsed * 83.0f * pi / 180.f);
+      matrixRotateZ(model, elapsed * 109.0f * pi / 180.f);
+
+      // Translate the model based on the mouse position
+      float x = clamp(sf::Mouse::getPosition(window).x * 2.f / window.getSize().x - 1.f, -1.0f, 1.0f) * 2.0f;
+      float y = clamp(-sf::Mouse::getPosition(window).y * 2.f / window.getSize().y + 1.f, -1.0f, 1.0f) * 1.5f;
+
+      model[3][0] -= x;
+      model[3][2] += y;
+
+      // Construct the view matrix
+      const Vec3 eye = { 0.0f, 4.0f, 0.0f };
+      const Vec3 center = { 0.0f, 0.0f, 0.0f };
+      const Vec3 up = { 0.0f, 0.0f, 1.0f };
+
+      Matrix view;
+
+      matrixLookAt(view, eye, center, up);
+
+      // Construct the projection matrix
+      const float fov = 45.0f;
+      const float aspect = static_cast<float>(swapchainExtent.width) / static_cast<float>(swapchainExtent.height);
+      const float nearPlane = 0.1f;
+      const float farPlane = 10.0f;
+
+      Matrix projection;
+
+      matrixPerspective(projection, fov * pi / 180.f, aspect, nearPlane, farPlane);
+
+      char* ptr;
+
+      // Map the current frame's uniform buffer into our address space
+      if (vkMapMemory(device, uniformBuffersMemory[currentFrame], 0, sizeof(Matrix) * 3, 0, reinterpret_cast<void**>(&ptr)) != VK_SUCCESS)
+      {
+         vulkanAvailable = false;
+         return;
+      }
+
+      // Copy the matrix data into the current frame's uniform buffer
+      std::memcpy(ptr + sizeof(Matrix) * 0, model, sizeof(Matrix));
+      std::memcpy(ptr + sizeof(Matrix) * 1, view, sizeof(Matrix));
+      std::memcpy(ptr + sizeof(Matrix) * 2, projection, sizeof(Matrix));
+
+      // Unmap the buffer
+      vkUnmapMemory(device, uniformBuffersMemory[currentFrame]);
+   }
+
+   void draw()
+   {
+      uint32_t imageIndex = 0;
+
+      // If the objects we need to submit this frame are still pending, wait here
+      vkWaitForFences(device, 1, &fences[currentFrame], VK_TRUE, std::numeric_limits<uint64_t>::max());
+
+      {
+         // Get the next image in the swapchain
+         VkResult result = vkAcquireNextImageKHR(device, swapchain, std::numeric_limits<uint64_t>::max(), imageAvailableSemaphores[currentFrame], VK_NULL_HANDLE, &imageIndex);
+
+         // Check if we need to re-create the swapchain (e.g. if the window was resized)
+         if (result == VK_ERROR_OUT_OF_DATE_KHR)
+         {
+            recreateSwapchain();
+            swapchainOutOfDate = false;
+            return;
+         }
+
+         if ((result != VK_SUCCESS) && (result != VK_TIMEOUT) && (result != VK_NOT_READY) && (result != VK_SUBOPTIMAL_KHR))
+         {
+            vulkanAvailable = false;
+            return;
+         }
+      }
+
+      // Wait for the swapchain image to be available in the color attachment stage before submitting the queue
+      VkPipelineStageFlags waitStages = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
+
+      // Signal the render finished semaphore once the queue has been processed
+      VkSubmitInfo submitInfo = VkSubmitInfo();
+      submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
+      submitInfo.waitSemaphoreCount = 1;
+      submitInfo.pWaitSemaphores = &imageAvailableSemaphores[currentFrame];
+      submitInfo.pWaitDstStageMask = &waitStages;
+      submitInfo.commandBufferCount = 1;
+      submitInfo.pCommandBuffers = &commandBuffers[imageIndex];
+      submitInfo.signalSemaphoreCount = 1;
+      submitInfo.pSignalSemaphores = &renderFinishedSemaphores[currentFrame];
+
+      vkResetFences(device, 1, &fences[currentFrame]);
+
+      if (vkQueueSubmit(queue, 1, &submitInfo, fences[currentFrame]) != VK_SUCCESS)
+      {
+         vulkanAvailable = false;
+         return;
+      }
+
+      // Wait for rendering to complete before presenting
+      VkPresentInfoKHR presentInfo = VkPresentInfoKHR();
+      presentInfo.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
+      presentInfo.waitSemaphoreCount = 1;
+      presentInfo.pWaitSemaphores = &renderFinishedSemaphores[currentFrame];
+      presentInfo.swapchainCount = 1;
+      presentInfo.pSwapchains = &swapchain;
+      presentInfo.pImageIndices = &imageIndex;
+
+      {
+         // Queue presentation
+         VkResult result = vkQueuePresentKHR(queue, &presentInfo);
+
+         // Check if we need to re-create the swapchain (e.g. if the window was resized)
+         if ((result == VK_ERROR_OUT_OF_DATE_KHR) || (result == VK_SUBOPTIMAL_KHR) || swapchainOutOfDate)
+         {
+            recreateSwapchain();
+            swapchainOutOfDate = false;
+         }
+         else if (result != VK_SUCCESS)
+         {
+            vulkanAvailable = false;
+            return;
+         }
+      }
+
+      // Make sure to use the next frame's objects next frame
+      currentFrame = (currentFrame + 1) % maxFramesInFlight;
+   }
+
+   void run()
+   {
+      sf::Clock clock;
+
+      // Start game loop
+      while (window.isOpen())
+      {
+         // Process events
+         sf::Event event;
+         while (window.pollEvent(event))
+         {
+            // Close window: exit
+            if (event.type == sf::Event::Closed)
+               window.close();
+
+            // Escape key: exit
+            if ((event.type == sf::Event::KeyPressed) && (event.key.code == sf::Keyboard::Escape))
+               window.close();
+
+            // Re-create the swapchain when the window is resized
+            if (event.type == sf::Event::Resized)
+               swapchainOutOfDate = true;
+         }
+
+         if (vulkanAvailable)
+         {
+            // Update the uniform buffer (matrices)
+            updateUniformBuffer(clock.getElapsedTime().asSeconds());
+
+            // Render the frame
+            draw();
+         }
+      }
+   }
+
+private:
+   sf::WindowBase window;
+
+   bool vulkanAvailable;
+
+   const int maxFramesInFlight;
+   int currentFrame;
+   bool swapchainOutOfDate;
+
+   VkInstance instance;
+   VkDebugReportCallbackEXT debugReportCallback;
+   VkSurfaceKHR surface;
+   VkPhysicalDevice gpu;
+   int queueFamilyIndex;
+   VkDevice device;
+   VkQueue queue;
+   VkSurfaceFormatKHR swapchainFormat;
+   VkExtent2D swapchainExtent;
+   VkSwapchainKHR swapchain;
+   std::vector<VkImage> swapchainImages;
+   std::vector<VkImageView> swapchainImageViews;
+   VkFormat depthFormat;
+   VkImage depthImage;
+   VkDeviceMemory depthImageMemory;
+   VkImageView depthImageView;
+   VkShaderModule vertexShaderModule;
+   VkShaderModule fragmentShaderModule;
+   VkPipelineShaderStageCreateInfo shaderStages[2];
+   VkDescriptorSetLayout descriptorSetLayout;
+   VkPipelineLayout pipelineLayout;
+   VkRenderPass renderPass;
+   VkPipeline graphicsPipeline;
+   std::vector<VkFramebuffer> swapchainFramebuffers;
+   VkCommandPool commandPool;
+   VkBuffer vertexBuffer;
+   VkDeviceMemory vertexBufferMemory;
+   VkBuffer indexBuffer;
+   VkDeviceMemory indexBufferMemory;
+   std::vector<VkBuffer> uniformBuffers;
+   std::vector<VkDeviceMemory> uniformBuffersMemory;
+   VkImage textureImage;
+   VkDeviceMemory textureImageMemory;
+   VkImageView textureImageView;
+   VkSampler textureSampler;
+   VkDescriptorPool descriptorPool;
+   std::vector<VkDescriptorSet> descriptorSets;
+   std::vector<VkCommandBuffer> commandBuffers;
+   std::vector<VkSemaphore> imageAvailableSemaphores;
+   std::vector<VkSemaphore> renderFinishedSemaphores;
+   std::vector<VkFence> fences;
+};
+
+
+////////////////////////////////////////////////////////////
+/// Entry point of application
+///
+/// \return Application exit code
+///
+////////////////////////////////////////////////////////////
+int main()
+{
+   VulkanExample example;
+
+   example.run();
+
+   return EXIT_SUCCESS;
+}
Index: VulkanSFMLReference.vcxproj
===================================================================
--- VulkanSFMLReference.vcxproj	(revision 57d43d021f973604403220624950c82a9c67ae6e)
+++ VulkanSFMLReference.vcxproj	(revision 57d43d021f973604403220624950c82a9c67ae6e)
@@ -0,0 +1,166 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup Label="ProjectConfigurations">
+    <ProjectConfiguration Include="Debug|Win32">
+      <Configuration>Debug</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|Win32">
+      <Configuration>Release</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug|x64">
+      <Configuration>Debug</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|x64">
+      <Configuration>Release</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="vulkan.h" />
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="Vulkan.cpp" />
+  </ItemGroup>
+  <PropertyGroup Label="Globals">
+    <VCProjectVersion>16.0</VCProjectVersion>
+    <Keyword>Win32Proj</Keyword>
+    <ProjectGuid>{91d47623-20f5-429c-911c-96d0422927f0}</ProjectGuid>
+    <RootNamespace>VulkanSFMLReference</RootNamespace>
+    <WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <PlatformToolset>v142</PlatformToolset>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>false</UseDebugLibraries>
+    <PlatformToolset>v142</PlatformToolset>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <PlatformToolset>v142</PlatformToolset>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>false</UseDebugLibraries>
+    <PlatformToolset>v142</PlatformToolset>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <ImportGroup Label="ExtensionSettings">
+  </ImportGroup>
+  <ImportGroup Label="Shared">
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <LinkIncremental>true</LinkIncremental>
+    <OutDir>$(SolutionDir)$(ProjectName).build\$(Platform)\$(Configuration)\</OutDir>
+    <IntDir>$(ProjectName).build\$(Platform)\$(Configuration)\</IntDir>
+    <IncludePath>../include;$(IncludePath)</IncludePath>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <LinkIncremental>false</LinkIncremental>
+    <OutDir>$(SolutionDir)$(ProjectName).build\$(Platform)\$(Configuration)\</OutDir>
+    <IntDir>$(ProjectName).build\$(Platform)\$(Configuration)\</IntDir>
+    <IncludePath>../include;$(IncludePath)</IncludePath>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <LinkIncremental>true</LinkIncremental>
+    <OutDir>$(SolutionDir)$(ProjectName).build\$(Platform)\$(Configuration)\</OutDir>
+    <IntDir>$(ProjectName).build\$(Platform)\$(Configuration)\</IntDir>
+    <IncludePath>../include;$(IncludePath)</IncludePath>
+    <LibraryPath>../lib;$(LibraryPath)</LibraryPath>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <LinkIncremental>false</LinkIncremental>
+    <OutDir>$(SolutionDir)$(ProjectName).build\$(Platform)\$(Configuration)\</OutDir>
+    <IntDir>$(ProjectName).build\$(Platform)\$(Configuration)\</IntDir>
+    <IncludePath>../include;$(IncludePath)</IncludePath>
+    <LibraryPath>../lib;$(LibraryPath)</LibraryPath>
+  </PropertyGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <ClCompile>
+      <WarningLevel>Level3</WarningLevel>
+      <SDLCheck>true</SDLCheck>
+      <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <ConformanceMode>true</ConformanceMode>
+    </ClCompile>
+    <Link>
+      <SubSystem>Console</SubSystem>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <ClCompile>
+      <WarningLevel>Level3</WarningLevel>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <SDLCheck>true</SDLCheck>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <ConformanceMode>true</ConformanceMode>
+    </ClCompile>
+    <Link>
+      <SubSystem>Console</SubSystem>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <OptimizeReferences>true</OptimizeReferences>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <ClCompile>
+      <WarningLevel>Level3</WarningLevel>
+      <SDLCheck>true</SDLCheck>
+      <PreprocessorDefinitions>_DEBUG;_CONSOLE;SFML_STATIC;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <ConformanceMode>true</ConformanceMode>
+    </ClCompile>
+    <Link>
+      <SubSystem>Console</SubSystem>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <AdditionalDependencies>sfml-graphics-s-d.lib;sfml-window-s-d.lib;sfml-system-s-d.lib;winmm.lib;%(AdditionalDependencies)</AdditionalDependencies>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <ClCompile>
+      <WarningLevel>Level3</WarningLevel>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <SDLCheck>true</SDLCheck>
+      <PreprocessorDefinitions>NDEBUG;_CONSOLE;SFML_STATIC;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <ConformanceMode>true</ConformanceMode>
+    </ClCompile>
+    <Link>
+      <SubSystem>Console</SubSystem>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <OptimizeReferences>true</OptimizeReferences>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <AdditionalDependencies>sfml-graphics-s.lib;sfml-window-s.lib;sfml-system-s.lib;winmm.lib;%(AdditionalDependencies)</AdditionalDependencies>
+    </Link>
+  </ItemDefinitionGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+  <ImportGroup Label="ExtensionTargets">
+  </ImportGroup>
+</Project>
Index: vulkan.h
===================================================================
--- vulkan.h	(revision 57d43d021f973604403220624950c82a9c67ae6e)
+++ vulkan.h	(revision 57d43d021f973604403220624950c82a9c67ae6e)
@@ -0,0 +1,3341 @@
+/**
+ * Loader generated by glad 2.0.0-beta on Sat Sep 15 15:51:42 2018
+ *
+ * Generator: C/C++
+ * Specification: vk
+ * Extensions: 3
+ *
+ * APIs:
+ *  - vulkan=1.0
+ *
+ * Options:
+ *  - MX_GLOBAL = False
+ *  - LOADER = False
+ *  - ALIAS = False
+ *  - HEADER_ONLY = True
+ *  - DEBUG = False
+ *  - MX = False
+ *
+ * Commandline:
+ *    --api='vulkan=1.0' --extensions='VK_EXT_debug_report,VK_KHR_surface,VK_KHR_swapchain' c --header-only
+ *
+ * Online:
+ *    http://glad.sh/#api=vulkan%3D1.0&extensions=VK_EXT_debug_report%2CVK_KHR_surface%2CVK_KHR_swapchain&generator=c&options=HEADER_ONLY
+ *
+ */
+
+#ifndef GLAD_VULKAN_H_
+#define GLAD_VULKAN_H_
+
+#ifdef VULKAN_H_
+#error  header already included (API: vulkan), remove previous include!
+#endif
+#define VULKAN_H_ 1
+
+#ifdef VULKAN_CORE_H_
+#error  header already included (API: vulkan), remove previous include!
+#endif
+#define VULKAN_CORE_H_ 1
+
+
+#define GLAD_VULKAN
+#define GLAD_OPTION_VULKAN_HEADER_ONLY
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef GLAD_PLATFORM_H_
+#define GLAD_PLATFORM_H_
+
+#if defined(_WIN32) || defined(__WIN32__) || defined(WIN32) || defined(__MINGW32__)
+#define GLAD_PLATFORM_WIN32 1
+#else
+#define GLAD_PLATFORM_WIN32 0
+#endif
+
+
+#ifndef GLAD_PLATFORM_UWP
+#if defined(_MSC_VER) && !defined(GLAD_INTERNAL_HAVE_WINAPIFAMILY)
+#ifdef __has_include
+#if __has_include(<winapifamily.h>)
+#define GLAD_INTERNAL_HAVE_WINAPIFAMILY 1
+#endif
+#elif _MSC_VER >= 1700 && !_USING_V110_SDK71_
+#define GLAD_INTERNAL_HAVE_WINAPIFAMILY 1
+#endif
+#endif
+
+#ifdef GLAD_INTERNAL_HAVE_WINAPIFAMILY
+#include <winapifamily.h>
+#if !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) && WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP)
+#define GLAD_PLATFORM_UWP 1
+#endif
+#endif
+
+#ifndef GLAD_PLATFORM_UWP
+#define GLAD_PLATFORM_UWP 0
+#endif
+#endif
+
+#ifdef __GNUC__
+#define GLAD_GNUC_EXTENSION __extension__
+#else
+#define GLAD_GNUC_EXTENSION
+#endif
+
+#ifndef GLAD_API_CALL
+#if defined(GLAD_API_CALL_EXPORT)
+#if GLAD_PLATFORM_WIN32 || defined(__CYGWIN__)
+#if defined(GLAD_API_CALL_EXPORT_BUILD)
+#if defined(__GNUC__)
+#define GLAD_API_CALL __attribute__ ((dllexport)) extern
+#else
+#define GLAD_API_CALL __declspec(dllexport) extern
+#endif
+#else
+#if defined(__GNUC__)
+#define GLAD_API_CALL __attribute__ ((dllimport)) extern
+#else
+#define GLAD_API_CALL __declspec(dllimport) extern
+#endif
+#endif
+#elif defined(__GNUC__) && defined(GLAD_API_CALL_EXPORT_BUILD)
+#define GLAD_API_CALL __attribute__ ((visibility ("default"))) extern
+#else
+#define GLAD_API_CALL extern
+#endif
+#else
+#define GLAD_API_CALL extern
+#endif
+#endif
+
+#ifdef APIENTRY
+#define GLAD_API_PTR APIENTRY
+#elif GLAD_PLATFORM_WIN32
+#define GLAD_API_PTR __stdcall
+#else
+#define GLAD_API_PTR
+#endif
+
+#ifndef GLAPI
+#define GLAPI GLAD_API_CALL
+#endif
+
+#ifndef GLAPIENTRY
+#define GLAPIENTRY GLAD_API_PTR
+#endif
+
+
+#define GLAD_MAKE_VERSION(major, minor) (major * 10000 + minor)
+#define GLAD_VERSION_MAJOR(version) (version / 10000)
+#define GLAD_VERSION_MINOR(version) (version % 10000)
+
+   typedef void (*GLADapiproc)(void);
+
+   typedef GLADapiproc(*GLADloadfunc)(const char* name);
+   typedef GLADapiproc(*GLADuserptrloadfunc)(const char* name, void* userptr);
+
+   typedef void (*GLADprecallback)(const char* name, GLADapiproc apiproc, int len_args, ...);
+   typedef void (*GLADpostcallback)(void* ret, const char* name, GLADapiproc apiproc, int len_args, ...);
+
+#endif /* GLAD_PLATFORM_H_ */
+
+#define VK_ATTACHMENT_UNUSED (~0U)
+#define VK_EXT_DEBUG_REPORT_EXTENSION_NAME "VK_EXT_debug_report"
+#define VK_EXT_DEBUG_REPORT_SPEC_VERSION 9
+#define VK_FALSE 0
+#define VK_KHR_SURFACE_EXTENSION_NAME "VK_KHR_surface"
+#define VK_KHR_SURFACE_SPEC_VERSION 25
+#define VK_KHR_SWAPCHAIN_EXTENSION_NAME "VK_KHR_swapchain"
+#define VK_KHR_SWAPCHAIN_SPEC_VERSION 70
+#define VK_LOD_CLAMP_NONE 1000.0f
+#define VK_MAX_DESCRIPTION_SIZE 256
+#define VK_MAX_DEVICE_GROUP_SIZE 32
+#define VK_MAX_EXTENSION_NAME_SIZE 256
+#define VK_MAX_MEMORY_HEAPS 16
+#define VK_MAX_MEMORY_TYPES 32
+#define VK_MAX_PHYSICAL_DEVICE_NAME_SIZE 256
+#define VK_QUEUE_FAMILY_IGNORED (~0U)
+#define VK_REMAINING_ARRAY_LAYERS (~0U)
+#define VK_REMAINING_MIP_LEVELS (~0U)
+#define VK_SUBPASS_EXTERNAL (~0U)
+#define VK_TRUE 1
+#define VK_UUID_SIZE 16
+#define VK_WHOLE_SIZE (~0ULL)
+
+
+   /* */
+   /* File: vk_platform.h */
+   /* */
+   /*
+   ** Copyright (c) 2014-2017 The Khronos Group 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.
+   */
+
+
+#ifndef VK_PLATFORM_H_
+#define VK_PLATFORM_H_
+
+#ifdef __cplusplus
+   extern "C"
+   {
+#endif /* __cplusplus */
+
+      /*
+      ***************************************************************************************************
+      *   Platform-specific directives and type declarations
+      ***************************************************************************************************
+      */
+
+      /* Platform-specific calling convention macros.
+       *
+       * Platforms should define these so that Vulkan clients call Vulkan commands
+       * with the same calling conventions that the Vulkan implementation expects.
+       *
+       * VKAPI_ATTR - Placed before the return type in function declarations.
+       *              Useful for C++11 and GCC/Clang-style function attribute syntax.
+       * VKAPI_CALL - Placed after the return type in function declarations.
+       *              Useful for MSVC-style calling convention syntax.
+       * VKAPI_PTR  - Placed between the '(' and '*' in function pointer types.
+       *
+       * Function declaration:  VKAPI_ATTR void VKAPI_CALL vkCommand(void);
+       * Function pointer type: typedef void (VKAPI_PTR *PFN_vkCommand)(void);
+       */
+#if defined(_WIN32)
+       /* On Windows, Vulkan commands use the stdcall convention */
+#define VKAPI_ATTR
+#define VKAPI_CALL __stdcall
+#define VKAPI_PTR  VKAPI_CALL
+#elif defined(__ANDROID__) && defined(__ARM_ARCH) && __ARM_ARCH < 7
+#error "Vulkan isn't supported for the 'armeabi' NDK ABI"
+#elif defined(__ANDROID__) && defined(__ARM_ARCH) && __ARM_ARCH >= 7 && defined(__ARM_32BIT_STATE)
+       /* On Android 32-bit ARM targets, Vulkan functions use the "hardfloat" */
+       /* calling convention, i.e. float parameters are passed in registers. This */
+       /* is true even if the rest of the application passes floats on the stack, */
+       /* as it does by default when compiling for the armeabi-v7a NDK ABI. */
+#define VKAPI_ATTR __attribute__((pcs("aapcs-vfp")))
+#define VKAPI_CALL
+#define VKAPI_PTR  VKAPI_ATTR
+#else
+       /* On other platforms, use the default calling convention */
+#define VKAPI_ATTR
+#define VKAPI_CALL
+#define VKAPI_PTR
+#endif
+
+#include <stddef.h>
+
+#if !defined(VK_NO_STDINT_H)
+#if defined(_MSC_VER) && (_MSC_VER < 1600)
+      typedef signed   __int8  int8_t;
+      typedef unsigned __int8  uint8_t;
+      typedef signed   __int16 int16_t;
+      typedef unsigned __int16 uint16_t;
+      typedef signed   __int32 int32_t;
+      typedef unsigned __int32 uint32_t;
+      typedef signed   __int64 int64_t;
+      typedef unsigned __int64 uint64_t;
+#else
+#include <stdint.h>
+#endif
+#endif /* !defined(VK_NO_STDINT_H) */
+
+#ifdef __cplusplus
+   } /* extern "C" */
+#endif /* __cplusplus */
+
+#endif
+#define VK_MAKE_VERSION(major, minor, patch) \
+    (((major) << 22) | ((minor) << 12) | (patch))
+#define VK_VERSION_MAJOR(version) ((uint32_t)(version) >> 22)
+#define VK_VERSION_MINOR(version) (((uint32_t)(version) >> 12) & 0x3ff)
+#define VK_VERSION_PATCH(version) ((uint32_t)(version) & 0xfff)
+/* DEPRECATED: This define has been removed. Specific version defines (e.g. VK_API_VERSION_1_0), or the VK_MAKE_VERSION macro, should be used instead. */
+/*#define VK_API_VERSION VK_MAKE_VERSION(1, 0, 0) // Patch version should always be set to 0 */
+/* Vulkan 1.0 version number */
+#define VK_API_VERSION_1_0 VK_MAKE_VERSION(1, 0, 0)/* Patch version should always be set to 0 */
+/* Version of this file */
+#define VK_HEADER_VERSION 84
+#define VK_DEFINE_HANDLE(object) typedef struct object##_T* object;
+#if !defined(VK_DEFINE_NON_DISPATCHABLE_HANDLE)
+#if defined(__LP64__) || defined(_WIN64) || (defined(__x86_64__) && !defined(__ILP32__) ) || defined(_M_X64) || defined(__ia64) || defined (_M_IA64) || defined(__aarch64__) || defined(__powerpc64__)
+#define VK_DEFINE_NON_DISPATCHABLE_HANDLE(object) typedef struct object##_T *object;
+#else
+#define VK_DEFINE_NON_DISPATCHABLE_HANDLE(object) typedef uint64_t object;
+#endif
+#endif
+#define VK_NULL_HANDLE 0
+
+
+
+
+
+
+
+
+   VK_DEFINE_HANDLE(VkInstance)
+      VK_DEFINE_HANDLE(VkPhysicalDevice)
+      VK_DEFINE_HANDLE(VkDevice)
+      VK_DEFINE_HANDLE(VkQueue)
+      VK_DEFINE_HANDLE(VkCommandBuffer)
+      VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkDeviceMemory)
+      VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkCommandPool)
+      VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkBuffer)
+      VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkBufferView)
+      VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkImage)
+      VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkImageView)
+      VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkShaderModule)
+      VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkPipeline)
+      VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkPipelineLayout)
+      VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkSampler)
+      VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkDescriptorSet)
+      VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkDescriptorSetLayout)
+      VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkDescriptorPool)
+      VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkFence)
+      VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkSemaphore)
+      VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkEvent)
+      VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkQueryPool)
+      VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkFramebuffer)
+      VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkRenderPass)
+      VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkPipelineCache)
+      VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkSurfaceKHR)
+      VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkSwapchainKHR)
+      VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkDebugReportCallbackEXT)
+      typedef enum VkAttachmentLoadOp {
+      VK_ATTACHMENT_LOAD_OP_LOAD = 0,
+      VK_ATTACHMENT_LOAD_OP_CLEAR = 1,
+      VK_ATTACHMENT_LOAD_OP_DONT_CARE = 2
+   } VkAttachmentLoadOp;
+   typedef enum VkAttachmentStoreOp {
+      VK_ATTACHMENT_STORE_OP_STORE = 0,
+      VK_ATTACHMENT_STORE_OP_DONT_CARE = 1
+   } VkAttachmentStoreOp;
+   typedef enum VkBlendFactor {
+      VK_BLEND_FACTOR_ZERO = 0,
+      VK_BLEND_FACTOR_ONE = 1,
+      VK_BLEND_FACTOR_SRC_COLOR = 2,
+      VK_BLEND_FACTOR_ONE_MINUS_SRC_COLOR = 3,
+      VK_BLEND_FACTOR_DST_COLOR = 4,
+      VK_BLEND_FACTOR_ONE_MINUS_DST_COLOR = 5,
+      VK_BLEND_FACTOR_SRC_ALPHA = 6,
+      VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA = 7,
+      VK_BLEND_FACTOR_DST_ALPHA = 8,
+      VK_BLEND_FACTOR_ONE_MINUS_DST_ALPHA = 9,
+      VK_BLEND_FACTOR_CONSTANT_COLOR = 10,
+      VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_COLOR = 11,
+      VK_BLEND_FACTOR_CONSTANT_ALPHA = 12,
+      VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_ALPHA = 13,
+      VK_BLEND_FACTOR_SRC_ALPHA_SATURATE = 14,
+      VK_BLEND_FACTOR_SRC1_COLOR = 15,
+      VK_BLEND_FACTOR_ONE_MINUS_SRC1_COLOR = 16,
+      VK_BLEND_FACTOR_SRC1_ALPHA = 17,
+      VK_BLEND_FACTOR_ONE_MINUS_SRC1_ALPHA = 18
+   } VkBlendFactor;
+   typedef enum VkBlendOp {
+      VK_BLEND_OP_ADD = 0,
+      VK_BLEND_OP_SUBTRACT = 1,
+      VK_BLEND_OP_REVERSE_SUBTRACT = 2,
+      VK_BLEND_OP_MIN = 3,
+      VK_BLEND_OP_MAX = 4
+   } VkBlendOp;
+   typedef enum VkBorderColor {
+      VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK = 0,
+      VK_BORDER_COLOR_INT_TRANSPARENT_BLACK = 1,
+      VK_BORDER_COLOR_FLOAT_OPAQUE_BLACK = 2,
+      VK_BORDER_COLOR_INT_OPAQUE_BLACK = 3,
+      VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE = 4,
+      VK_BORDER_COLOR_INT_OPAQUE_WHITE = 5
+   } VkBorderColor;
+   typedef enum VkPipelineCacheHeaderVersion {
+      VK_PIPELINE_CACHE_HEADER_VERSION_ONE = 1
+   } VkPipelineCacheHeaderVersion;
+
+
+   typedef enum VkBufferCreateFlagBits {
+      VK_BUFFER_CREATE_SPARSE_BINDING_BIT = 1,
+      VK_BUFFER_CREATE_SPARSE_RESIDENCY_BIT = 2,
+      VK_BUFFER_CREATE_SPARSE_ALIASED_BIT = 4
+   } VkBufferCreateFlagBits;
+   typedef enum VkBufferUsageFlagBits {
+      VK_BUFFER_USAGE_TRANSFER_SRC_BIT = 1,
+      VK_BUFFER_USAGE_TRANSFER_DST_BIT = 2,
+      VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT = 4,
+      VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT = 8,
+      VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT = 16,
+      VK_BUFFER_USAGE_STORAGE_BUFFER_BIT = 32,
+      VK_BUFFER_USAGE_INDEX_BUFFER_BIT = 64,
+      VK_BUFFER_USAGE_VERTEX_BUFFER_BIT = 128,
+      VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT = 256
+   } VkBufferUsageFlagBits;
+   typedef enum VkColorComponentFlagBits {
+      VK_COLOR_COMPONENT_R_BIT = 1,
+      VK_COLOR_COMPONENT_G_BIT = 2,
+      VK_COLOR_COMPONENT_B_BIT = 4,
+      VK_COLOR_COMPONENT_A_BIT = 8
+   } VkColorComponentFlagBits;
+   typedef enum VkComponentSwizzle {
+      VK_COMPONENT_SWIZZLE_IDENTITY = 0,
+      VK_COMPONENT_SWIZZLE_ZERO = 1,
+      VK_COMPONENT_SWIZZLE_ONE = 2,
+      VK_COMPONENT_SWIZZLE_R = 3,
+      VK_COMPONENT_SWIZZLE_G = 4,
+      VK_COMPONENT_SWIZZLE_B = 5,
+      VK_COMPONENT_SWIZZLE_A = 6
+   } VkComponentSwizzle;
+   typedef enum VkCommandPoolCreateFlagBits {
+      VK_COMMAND_POOL_CREATE_TRANSIENT_BIT = 1,
+      VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT = 2
+   } VkCommandPoolCreateFlagBits;
+   typedef enum VkCommandPoolResetFlagBits {
+      VK_COMMAND_POOL_RESET_RELEASE_RESOURCES_BIT = 1
+   } VkCommandPoolResetFlagBits;
+   typedef enum VkCommandBufferResetFlagBits {
+      VK_COMMAND_BUFFER_RESET_RELEASE_RESOURCES_BIT = 1
+   } VkCommandBufferResetFlagBits;
+   typedef enum VkCommandBufferLevel {
+      VK_COMMAND_BUFFER_LEVEL_PRIMARY = 0,
+      VK_COMMAND_BUFFER_LEVEL_SECONDARY = 1
+   } VkCommandBufferLevel;
+   typedef enum VkCommandBufferUsageFlagBits {
+      VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT = 1,
+      VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT = 2,
+      VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT = 4
+   } VkCommandBufferUsageFlagBits;
+   typedef enum VkCompareOp {
+      VK_COMPARE_OP_NEVER = 0,
+      VK_COMPARE_OP_LESS = 1,
+      VK_COMPARE_OP_EQUAL = 2,
+      VK_COMPARE_OP_LESS_OR_EQUAL = 3,
+      VK_COMPARE_OP_GREATER = 4,
+      VK_COMPARE_OP_NOT_EQUAL = 5,
+      VK_COMPARE_OP_GREATER_OR_EQUAL = 6,
+      VK_COMPARE_OP_ALWAYS = 7
+   } VkCompareOp;
+   typedef enum VkCullModeFlagBits {
+      VK_CULL_MODE_NONE = 0,
+      VK_CULL_MODE_FRONT_BIT = 1,
+      VK_CULL_MODE_BACK_BIT = 2,
+      VK_CULL_MODE_FRONT_AND_BACK = 0x00000003
+   } VkCullModeFlagBits;
+   typedef enum VkDescriptorType {
+      VK_DESCRIPTOR_TYPE_SAMPLER = 0,
+      VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER = 1,
+      VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE = 2,
+      VK_DESCRIPTOR_TYPE_STORAGE_IMAGE = 3,
+      VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER = 4,
+      VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER = 5,
+      VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER = 6,
+      VK_DESCRIPTOR_TYPE_STORAGE_BUFFER = 7,
+      VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC = 8,
+      VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC = 9,
+      VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT = 10
+   } VkDescriptorType;
+   typedef enum VkDynamicState {
+      VK_DYNAMIC_STATE_VIEWPORT = 0,
+      VK_DYNAMIC_STATE_SCISSOR = 1,
+      VK_DYNAMIC_STATE_LINE_WIDTH = 2,
+      VK_DYNAMIC_STATE_DEPTH_BIAS = 3,
+      VK_DYNAMIC_STATE_BLEND_CONSTANTS = 4,
+      VK_DYNAMIC_STATE_DEPTH_BOUNDS = 5,
+      VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK = 6,
+      VK_DYNAMIC_STATE_STENCIL_WRITE_MASK = 7,
+      VK_DYNAMIC_STATE_STENCIL_REFERENCE = 8
+   } VkDynamicState;
+   typedef enum VkFenceCreateFlagBits {
+      VK_FENCE_CREATE_SIGNALED_BIT = 1
+   } VkFenceCreateFlagBits;
+   typedef enum VkPolygonMode {
+      VK_POLYGON_MODE_FILL = 0,
+      VK_POLYGON_MODE_LINE = 1,
+      VK_POLYGON_MODE_POINT = 2
+   } VkPolygonMode;
+   typedef enum VkFormat {
+      VK_FORMAT_UNDEFINED = 0,
+      VK_FORMAT_R4G4_UNORM_PACK8 = 1,
+      VK_FORMAT_R4G4B4A4_UNORM_PACK16 = 2,
+      VK_FORMAT_B4G4R4A4_UNORM_PACK16 = 3,
+      VK_FORMAT_R5G6B5_UNORM_PACK16 = 4,
+      VK_FORMAT_B5G6R5_UNORM_PACK16 = 5,
+      VK_FORMAT_R5G5B5A1_UNORM_PACK16 = 6,
+      VK_FORMAT_B5G5R5A1_UNORM_PACK16 = 7,
+      VK_FORMAT_A1R5G5B5_UNORM_PACK16 = 8,
+      VK_FORMAT_R8_UNORM = 9,
+      VK_FORMAT_R8_SNORM = 10,
+      VK_FORMAT_R8_USCALED = 11,
+      VK_FORMAT_R8_SSCALED = 12,
+      VK_FORMAT_R8_UINT = 13,
+      VK_FORMAT_R8_SINT = 14,
+      VK_FORMAT_R8_SRGB = 15,
+      VK_FORMAT_R8G8_UNORM = 16,
+      VK_FORMAT_R8G8_SNORM = 17,
+      VK_FORMAT_R8G8_USCALED = 18,
+      VK_FORMAT_R8G8_SSCALED = 19,
+      VK_FORMAT_R8G8_UINT = 20,
+      VK_FORMAT_R8G8_SINT = 21,
+      VK_FORMAT_R8G8_SRGB = 22,
+      VK_FORMAT_R8G8B8_UNORM = 23,
+      VK_FORMAT_R8G8B8_SNORM = 24,
+      VK_FORMAT_R8G8B8_USCALED = 25,
+      VK_FORMAT_R8G8B8_SSCALED = 26,
+      VK_FORMAT_R8G8B8_UINT = 27,
+      VK_FORMAT_R8G8B8_SINT = 28,
+      VK_FORMAT_R8G8B8_SRGB = 29,
+      VK_FORMAT_B8G8R8_UNORM = 30,
+      VK_FORMAT_B8G8R8_SNORM = 31,
+      VK_FORMAT_B8G8R8_USCALED = 32,
+      VK_FORMAT_B8G8R8_SSCALED = 33,
+      VK_FORMAT_B8G8R8_UINT = 34,
+      VK_FORMAT_B8G8R8_SINT = 35,
+      VK_FORMAT_B8G8R8_SRGB = 36,
+      VK_FORMAT_R8G8B8A8_UNORM = 37,
+      VK_FORMAT_R8G8B8A8_SNORM = 38,
+      VK_FORMAT_R8G8B8A8_USCALED = 39,
+      VK_FORMAT_R8G8B8A8_SSCALED = 40,
+      VK_FORMAT_R8G8B8A8_UINT = 41,
+      VK_FORMAT_R8G8B8A8_SINT = 42,
+      VK_FORMAT_R8G8B8A8_SRGB = 43,
+      VK_FORMAT_B8G8R8A8_UNORM = 44,
+      VK_FORMAT_B8G8R8A8_SNORM = 45,
+      VK_FORMAT_B8G8R8A8_USCALED = 46,
+      VK_FORMAT_B8G8R8A8_SSCALED = 47,
+      VK_FORMAT_B8G8R8A8_UINT = 48,
+      VK_FORMAT_B8G8R8A8_SINT = 49,
+      VK_FORMAT_B8G8R8A8_SRGB = 50,
+      VK_FORMAT_A8B8G8R8_UNORM_PACK32 = 51,
+      VK_FORMAT_A8B8G8R8_SNORM_PACK32 = 52,
+      VK_FORMAT_A8B8G8R8_USCALED_PACK32 = 53,
+      VK_FORMAT_A8B8G8R8_SSCALED_PACK32 = 54,
+      VK_FORMAT_A8B8G8R8_UINT_PACK32 = 55,
+      VK_FORMAT_A8B8G8R8_SINT_PACK32 = 56,
+      VK_FORMAT_A8B8G8R8_SRGB_PACK32 = 57,
+      VK_FORMAT_A2R10G10B10_UNORM_PACK32 = 58,
+      VK_FORMAT_A2R10G10B10_SNORM_PACK32 = 59,
+      VK_FORMAT_A2R10G10B10_USCALED_PACK32 = 60,
+      VK_FORMAT_A2R10G10B10_SSCALED_PACK32 = 61,
+      VK_FORMAT_A2R10G10B10_UINT_PACK32 = 62,
+      VK_FORMAT_A2R10G10B10_SINT_PACK32 = 63,
+      VK_FORMAT_A2B10G10R10_UNORM_PACK32 = 64,
+      VK_FORMAT_A2B10G10R10_SNORM_PACK32 = 65,
+      VK_FORMAT_A2B10G10R10_USCALED_PACK32 = 66,
+      VK_FORMAT_A2B10G10R10_SSCALED_PACK32 = 67,
+      VK_FORMAT_A2B10G10R10_UINT_PACK32 = 68,
+      VK_FORMAT_A2B10G10R10_SINT_PACK32 = 69,
+      VK_FORMAT_R16_UNORM = 70,
+      VK_FORMAT_R16_SNORM = 71,
+      VK_FORMAT_R16_USCALED = 72,
+      VK_FORMAT_R16_SSCALED = 73,
+      VK_FORMAT_R16_UINT = 74,
+      VK_FORMAT_R16_SINT = 75,
+      VK_FORMAT_R16_SFLOAT = 76,
+      VK_FORMAT_R16G16_UNORM = 77,
+      VK_FORMAT_R16G16_SNORM = 78,
+      VK_FORMAT_R16G16_USCALED = 79,
+      VK_FORMAT_R16G16_SSCALED = 80,
+      VK_FORMAT_R16G16_UINT = 81,
+      VK_FORMAT_R16G16_SINT = 82,
+      VK_FORMAT_R16G16_SFLOAT = 83,
+      VK_FORMAT_R16G16B16_UNORM = 84,
+      VK_FORMAT_R16G16B16_SNORM = 85,
+      VK_FORMAT_R16G16B16_USCALED = 86,
+      VK_FORMAT_R16G16B16_SSCALED = 87,
+      VK_FORMAT_R16G16B16_UINT = 88,
+      VK_FORMAT_R16G16B16_SINT = 89,
+      VK_FORMAT_R16G16B16_SFLOAT = 90,
+      VK_FORMAT_R16G16B16A16_UNORM = 91,
+      VK_FORMAT_R16G16B16A16_SNORM = 92,
+      VK_FORMAT_R16G16B16A16_USCALED = 93,
+      VK_FORMAT_R16G16B16A16_SSCALED = 94,
+      VK_FORMAT_R16G16B16A16_UINT = 95,
+      VK_FORMAT_R16G16B16A16_SINT = 96,
+      VK_FORMAT_R16G16B16A16_SFLOAT = 97,
+      VK_FORMAT_R32_UINT = 98,
+      VK_FORMAT_R32_SINT = 99,
+      VK_FORMAT_R32_SFLOAT = 100,
+      VK_FORMAT_R32G32_UINT = 101,
+      VK_FORMAT_R32G32_SINT = 102,
+      VK_FORMAT_R32G32_SFLOAT = 103,
+      VK_FORMAT_R32G32B32_UINT = 104,
+      VK_FORMAT_R32G32B32_SINT = 105,
+      VK_FORMAT_R32G32B32_SFLOAT = 106,
+      VK_FORMAT_R32G32B32A32_UINT = 107,
+      VK_FORMAT_R32G32B32A32_SINT = 108,
+      VK_FORMAT_R32G32B32A32_SFLOAT = 109,
+      VK_FORMAT_R64_UINT = 110,
+      VK_FORMAT_R64_SINT = 111,
+      VK_FORMAT_R64_SFLOAT = 112,
+      VK_FORMAT_R64G64_UINT = 113,
+      VK_FORMAT_R64G64_SINT = 114,
+      VK_FORMAT_R64G64_SFLOAT = 115,
+      VK_FORMAT_R64G64B64_UINT = 116,
+      VK_FORMAT_R64G64B64_SINT = 117,
+      VK_FORMAT_R64G64B64_SFLOAT = 118,
+      VK_FORMAT_R64G64B64A64_UINT = 119,
+      VK_FORMAT_R64G64B64A64_SINT = 120,
+      VK_FORMAT_R64G64B64A64_SFLOAT = 121,
+      VK_FORMAT_B10G11R11_UFLOAT_PACK32 = 122,
+      VK_FORMAT_E5B9G9R9_UFLOAT_PACK32 = 123,
+      VK_FORMAT_D16_UNORM = 124,
+      VK_FORMAT_X8_D24_UNORM_PACK32 = 125,
+      VK_FORMAT_D32_SFLOAT = 126,
+      VK_FORMAT_S8_UINT = 127,
+      VK_FORMAT_D16_UNORM_S8_UINT = 128,
+      VK_FORMAT_D24_UNORM_S8_UINT = 129,
+      VK_FORMAT_D32_SFLOAT_S8_UINT = 130,
+      VK_FORMAT_BC1_RGB_UNORM_BLOCK = 131,
+      VK_FORMAT_BC1_RGB_SRGB_BLOCK = 132,
+      VK_FORMAT_BC1_RGBA_UNORM_BLOCK = 133,
+      VK_FORMAT_BC1_RGBA_SRGB_BLOCK = 134,
+      VK_FORMAT_BC2_UNORM_BLOCK = 135,
+      VK_FORMAT_BC2_SRGB_BLOCK = 136,
+      VK_FORMAT_BC3_UNORM_BLOCK = 137,
+      VK_FORMAT_BC3_SRGB_BLOCK = 138,
+      VK_FORMAT_BC4_UNORM_BLOCK = 139,
+      VK_FORMAT_BC4_SNORM_BLOCK = 140,
+      VK_FORMAT_BC5_UNORM_BLOCK = 141,
+      VK_FORMAT_BC5_SNORM_BLOCK = 142,
+      VK_FORMAT_BC6H_UFLOAT_BLOCK = 143,
+      VK_FORMAT_BC6H_SFLOAT_BLOCK = 144,
+      VK_FORMAT_BC7_UNORM_BLOCK = 145,
+      VK_FORMAT_BC7_SRGB_BLOCK = 146,
+      VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK = 147,
+      VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK = 148,
+      VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK = 149,
+      VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK = 150,
+      VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK = 151,
+      VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK = 152,
+      VK_FORMAT_EAC_R11_UNORM_BLOCK = 153,
+      VK_FORMAT_EAC_R11_SNORM_BLOCK = 154,
+      VK_FORMAT_EAC_R11G11_UNORM_BLOCK = 155,
+      VK_FORMAT_EAC_R11G11_SNORM_BLOCK = 156,
+      VK_FORMAT_ASTC_4x4_UNORM_BLOCK = 157,
+      VK_FORMAT_ASTC_4x4_SRGB_BLOCK = 158,
+      VK_FORMAT_ASTC_5x4_UNORM_BLOCK = 159,
+      VK_FORMAT_ASTC_5x4_SRGB_BLOCK = 160,
+      VK_FORMAT_ASTC_5x5_UNORM_BLOCK = 161,
+      VK_FORMAT_ASTC_5x5_SRGB_BLOCK = 162,
+      VK_FORMAT_ASTC_6x5_UNORM_BLOCK = 163,
+      VK_FORMAT_ASTC_6x5_SRGB_BLOCK = 164,
+      VK_FORMAT_ASTC_6x6_UNORM_BLOCK = 165,
+      VK_FORMAT_ASTC_6x6_SRGB_BLOCK = 166,
+      VK_FORMAT_ASTC_8x5_UNORM_BLOCK = 167,
+      VK_FORMAT_ASTC_8x5_SRGB_BLOCK = 168,
+      VK_FORMAT_ASTC_8x6_UNORM_BLOCK = 169,
+      VK_FORMAT_ASTC_8x6_SRGB_BLOCK = 170,
+      VK_FORMAT_ASTC_8x8_UNORM_BLOCK = 171,
+      VK_FORMAT_ASTC_8x8_SRGB_BLOCK = 172,
+      VK_FORMAT_ASTC_10x5_UNORM_BLOCK = 173,
+      VK_FORMAT_ASTC_10x5_SRGB_BLOCK = 174,
+      VK_FORMAT_ASTC_10x6_UNORM_BLOCK = 175,
+      VK_FORMAT_ASTC_10x6_SRGB_BLOCK = 176,
+      VK_FORMAT_ASTC_10x8_UNORM_BLOCK = 177,
+      VK_FORMAT_ASTC_10x8_SRGB_BLOCK = 178,
+      VK_FORMAT_ASTC_10x10_UNORM_BLOCK = 179,
+      VK_FORMAT_ASTC_10x10_SRGB_BLOCK = 180,
+      VK_FORMAT_ASTC_12x10_UNORM_BLOCK = 181,
+      VK_FORMAT_ASTC_12x10_SRGB_BLOCK = 182,
+      VK_FORMAT_ASTC_12x12_UNORM_BLOCK = 183,
+      VK_FORMAT_ASTC_12x12_SRGB_BLOCK = 184
+   } VkFormat;
+   typedef enum VkFormatFeatureFlagBits {
+      VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT = 1,
+      VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT = 2,
+      VK_FORMAT_FEATURE_STORAGE_IMAGE_ATOMIC_BIT = 4,
+      VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT = 8,
+      VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT = 16,
+      VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_ATOMIC_BIT = 32,
+      VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT = 64,
+      VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT = 128,
+      VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT = 256,
+      VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT = 512,
+      VK_FORMAT_FEATURE_BLIT_SRC_BIT = 1024,
+      VK_FORMAT_FEATURE_BLIT_DST_BIT = 2048,
+      VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT = 4096
+   } VkFormatFeatureFlagBits;
+   typedef enum VkFrontFace {
+      VK_FRONT_FACE_COUNTER_CLOCKWISE = 0,
+      VK_FRONT_FACE_CLOCKWISE = 1
+   } VkFrontFace;
+   typedef enum VkImageAspectFlagBits {
+      VK_IMAGE_ASPECT_COLOR_BIT = 1,
+      VK_IMAGE_ASPECT_DEPTH_BIT = 2,
+      VK_IMAGE_ASPECT_STENCIL_BIT = 4,
+      VK_IMAGE_ASPECT_METADATA_BIT = 8
+   } VkImageAspectFlagBits;
+   typedef enum VkImageCreateFlagBits {
+      VK_IMAGE_CREATE_SPARSE_BINDING_BIT = 1,
+      VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT = 2,
+      VK_IMAGE_CREATE_SPARSE_ALIASED_BIT = 4,
+      VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT = 8,
+      VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT = 16
+   } VkImageCreateFlagBits;
+   typedef enum VkImageLayout {
+      VK_IMAGE_LAYOUT_UNDEFINED = 0,
+      VK_IMAGE_LAYOUT_GENERAL = 1,
+      VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL = 2,
+      VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL = 3,
+      VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL = 4,
+      VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL = 5,
+      VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL = 6,
+      VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL = 7,
+      VK_IMAGE_LAYOUT_PREINITIALIZED = 8,
+      VK_IMAGE_LAYOUT_PRESENT_SRC_KHR = 1000001002
+   } VkImageLayout;
+   typedef enum VkImageTiling {
+      VK_IMAGE_TILING_OPTIMAL = 0,
+      VK_IMAGE_TILING_LINEAR = 1
+   } VkImageTiling;
+   typedef enum VkImageType {
+      VK_IMAGE_TYPE_1D = 0,
+      VK_IMAGE_TYPE_2D = 1,
+      VK_IMAGE_TYPE_3D = 2
+   } VkImageType;
+   typedef enum VkImageUsageFlagBits {
+      VK_IMAGE_USAGE_TRANSFER_SRC_BIT = 1,
+      VK_IMAGE_USAGE_TRANSFER_DST_BIT = 2,
+      VK_IMAGE_USAGE_SAMPLED_BIT = 4,
+      VK_IMAGE_USAGE_STORAGE_BIT = 8,
+      VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT = 16,
+      VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT = 32,
+      VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT = 64,
+      VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT = 128
+   } VkImageUsageFlagBits;
+   typedef enum VkImageViewType {
+      VK_IMAGE_VIEW_TYPE_1D = 0,
+      VK_IMAGE_VIEW_TYPE_2D = 1,
+      VK_IMAGE_VIEW_TYPE_3D = 2,
+      VK_IMAGE_VIEW_TYPE_CUBE = 3,
+      VK_IMAGE_VIEW_TYPE_1D_ARRAY = 4,
+      VK_IMAGE_VIEW_TYPE_2D_ARRAY = 5,
+      VK_IMAGE_VIEW_TYPE_CUBE_ARRAY = 6
+   } VkImageViewType;
+   typedef enum VkSharingMode {
+      VK_SHARING_MODE_EXCLUSIVE = 0,
+      VK_SHARING_MODE_CONCURRENT = 1
+   } VkSharingMode;
+   typedef enum VkIndexType {
+      VK_INDEX_TYPE_UINT16 = 0,
+      VK_INDEX_TYPE_UINT32 = 1
+   } VkIndexType;
+   typedef enum VkLogicOp {
+      VK_LOGIC_OP_CLEAR = 0,
+      VK_LOGIC_OP_AND = 1,
+      VK_LOGIC_OP_AND_REVERSE = 2,
+      VK_LOGIC_OP_COPY = 3,
+      VK_LOGIC_OP_AND_INVERTED = 4,
+      VK_LOGIC_OP_NO_OP = 5,
+      VK_LOGIC_OP_XOR = 6,
+      VK_LOGIC_OP_OR = 7,
+      VK_LOGIC_OP_NOR = 8,
+      VK_LOGIC_OP_EQUIVALENT = 9,
+      VK_LOGIC_OP_INVERT = 10,
+      VK_LOGIC_OP_OR_REVERSE = 11,
+      VK_LOGIC_OP_COPY_INVERTED = 12,
+      VK_LOGIC_OP_OR_INVERTED = 13,
+      VK_LOGIC_OP_NAND = 14,
+      VK_LOGIC_OP_SET = 15
+   } VkLogicOp;
+   typedef enum VkMemoryHeapFlagBits {
+      VK_MEMORY_HEAP_DEVICE_LOCAL_BIT = 1
+   } VkMemoryHeapFlagBits;
+   typedef enum VkAccessFlagBits {
+      VK_ACCESS_INDIRECT_COMMAND_READ_BIT = 1,
+      VK_ACCESS_INDEX_READ_BIT = 2,
+      VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT = 4,
+      VK_ACCESS_UNIFORM_READ_BIT = 8,
+      VK_ACCESS_INPUT_ATTACHMENT_READ_BIT = 16,
+      VK_ACCESS_SHADER_READ_BIT = 32,
+      VK_ACCESS_SHADER_WRITE_BIT = 64,
+      VK_ACCESS_COLOR_ATTACHMENT_READ_BIT = 128,
+      VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT = 256,
+      VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT = 512,
+      VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT = 1024,
+      VK_ACCESS_TRANSFER_READ_BIT = 2048,
+      VK_ACCESS_TRANSFER_WRITE_BIT = 4096,
+      VK_ACCESS_HOST_READ_BIT = 8192,
+      VK_ACCESS_HOST_WRITE_BIT = 16384,
+      VK_ACCESS_MEMORY_READ_BIT = 32768,
+      VK_ACCESS_MEMORY_WRITE_BIT = 65536
+   } VkAccessFlagBits;
+   typedef enum VkMemoryPropertyFlagBits {
+      VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT = 1,
+      VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT = 2,
+      VK_MEMORY_PROPERTY_HOST_COHERENT_BIT = 4,
+      VK_MEMORY_PROPERTY_HOST_CACHED_BIT = 8,
+      VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT = 16
+   } VkMemoryPropertyFlagBits;
+   typedef enum VkPhysicalDeviceType {
+      VK_PHYSICAL_DEVICE_TYPE_OTHER = 0,
+      VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU = 1,
+      VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU = 2,
+      VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU = 3,
+      VK_PHYSICAL_DEVICE_TYPE_CPU = 4
+   } VkPhysicalDeviceType;
+   typedef enum VkPipelineBindPoint {
+      VK_PIPELINE_BIND_POINT_GRAPHICS = 0,
+      VK_PIPELINE_BIND_POINT_COMPUTE = 1
+   } VkPipelineBindPoint;
+   typedef enum VkPipelineCreateFlagBits {
+      VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT = 1,
+      VK_PIPELINE_CREATE_ALLOW_DERIVATIVES_BIT = 2,
+      VK_PIPELINE_CREATE_DERIVATIVE_BIT = 4
+   } VkPipelineCreateFlagBits;
+   typedef enum VkPrimitiveTopology {
+      VK_PRIMITIVE_TOPOLOGY_POINT_LIST = 0,
+      VK_PRIMITIVE_TOPOLOGY_LINE_LIST = 1,
+      VK_PRIMITIVE_TOPOLOGY_LINE_STRIP = 2,
+      VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST = 3,
+      VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP = 4,
+      VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN = 5,
+      VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY = 6,
+      VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY = 7,
+      VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY = 8,
+      VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY = 9,
+      VK_PRIMITIVE_TOPOLOGY_PATCH_LIST = 10
+   } VkPrimitiveTopology;
+   typedef enum VkQueryControlFlagBits {
+      VK_QUERY_CONTROL_PRECISE_BIT = 1
+   } VkQueryControlFlagBits;
+   typedef enum VkQueryPipelineStatisticFlagBits {
+      VK_QUERY_PIPELINE_STATISTIC_INPUT_ASSEMBLY_VERTICES_BIT = 1,
+      VK_QUERY_PIPELINE_STATISTIC_INPUT_ASSEMBLY_PRIMITIVES_BIT = 2,
+      VK_QUERY_PIPELINE_STATISTIC_VERTEX_SHADER_INVOCATIONS_BIT = 4,
+      VK_QUERY_PIPELINE_STATISTIC_GEOMETRY_SHADER_INVOCATIONS_BIT = 8,
+      VK_QUERY_PIPELINE_STATISTIC_GEOMETRY_SHADER_PRIMITIVES_BIT = 16,
+      VK_QUERY_PIPELINE_STATISTIC_CLIPPING_INVOCATIONS_BIT = 32,
+      VK_QUERY_PIPELINE_STATISTIC_CLIPPING_PRIMITIVES_BIT = 64,
+      VK_QUERY_PIPELINE_STATISTIC_FRAGMENT_SHADER_INVOCATIONS_BIT = 128,
+      VK_QUERY_PIPELINE_STATISTIC_TESSELLATION_CONTROL_SHADER_PATCHES_BIT = 256,
+      VK_QUERY_PIPELINE_STATISTIC_TESSELLATION_EVALUATION_SHADER_INVOCATIONS_BIT = 512,
+      VK_QUERY_PIPELINE_STATISTIC_COMPUTE_SHADER_INVOCATIONS_BIT = 1024
+   } VkQueryPipelineStatisticFlagBits;
+   typedef enum VkQueryResultFlagBits {
+      VK_QUERY_RESULT_64_BIT = 1,
+      VK_QUERY_RESULT_WAIT_BIT = 2,
+      VK_QUERY_RESULT_WITH_AVAILABILITY_BIT = 4,
+      VK_QUERY_RESULT_PARTIAL_BIT = 8
+   } VkQueryResultFlagBits;
+   typedef enum VkQueryType {
+      VK_QUERY_TYPE_OCCLUSION = 0,
+      VK_QUERY_TYPE_PIPELINE_STATISTICS = 1,
+      VK_QUERY_TYPE_TIMESTAMP = 2
+   } VkQueryType;
+   typedef enum VkQueueFlagBits {
+      VK_QUEUE_GRAPHICS_BIT = 1,
+      VK_QUEUE_COMPUTE_BIT = 2,
+      VK_QUEUE_TRANSFER_BIT = 4,
+      VK_QUEUE_SPARSE_BINDING_BIT = 8
+   } VkQueueFlagBits;
+   typedef enum VkSubpassContents {
+      VK_SUBPASS_CONTENTS_INLINE = 0,
+      VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS = 1
+   } VkSubpassContents;
+   typedef enum VkResult {
+      VK_SUCCESS = 0,
+      VK_NOT_READY = 1,
+      VK_TIMEOUT = 2,
+      VK_EVENT_SET = 3,
+      VK_EVENT_RESET = 4,
+      VK_INCOMPLETE = 5,
+      VK_ERROR_OUT_OF_HOST_MEMORY = -1,
+      VK_ERROR_OUT_OF_DEVICE_MEMORY = -2,
+      VK_ERROR_INITIALIZATION_FAILED = -3,
+      VK_ERROR_DEVICE_LOST = -4,
+      VK_ERROR_MEMORY_MAP_FAILED = -5,
+      VK_ERROR_LAYER_NOT_PRESENT = -6,
+      VK_ERROR_EXTENSION_NOT_PRESENT = -7,
+      VK_ERROR_FEATURE_NOT_PRESENT = -8,
+      VK_ERROR_INCOMPATIBLE_DRIVER = -9,
+      VK_ERROR_TOO_MANY_OBJECTS = -10,
+      VK_ERROR_FORMAT_NOT_SUPPORTED = -11,
+      VK_ERROR_FRAGMENTED_POOL = -12,
+      VK_ERROR_SURFACE_LOST_KHR = -1000000000,
+      VK_ERROR_NATIVE_WINDOW_IN_USE_KHR = -1000000001,
+      VK_SUBOPTIMAL_KHR = 1000001003,
+      VK_ERROR_OUT_OF_DATE_KHR = -1000001004,
+      VK_ERROR_VALIDATION_FAILED_EXT = -1000011001
+   } VkResult;
+   typedef enum VkShaderStageFlagBits {
+      VK_SHADER_STAGE_VERTEX_BIT = 1,
+      VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT = 2,
+      VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT = 4,
+      VK_SHADER_STAGE_GEOMETRY_BIT = 8,
+      VK_SHADER_STAGE_FRAGMENT_BIT = 16,
+      VK_SHADER_STAGE_COMPUTE_BIT = 32,
+      VK_SHADER_STAGE_ALL_GRAPHICS = 0x0000001F,
+      VK_SHADER_STAGE_ALL = 0x7FFFFFFF
+   } VkShaderStageFlagBits;
+   typedef enum VkSparseMemoryBindFlagBits {
+      VK_SPARSE_MEMORY_BIND_METADATA_BIT = 1
+   } VkSparseMemoryBindFlagBits;
+   typedef enum VkStencilFaceFlagBits {
+      VK_STENCIL_FACE_FRONT_BIT = 1,
+      VK_STENCIL_FACE_BACK_BIT = 2,
+      VK_STENCIL_FRONT_AND_BACK = 0x00000003
+   } VkStencilFaceFlagBits;
+   typedef enum VkStencilOp {
+      VK_STENCIL_OP_KEEP = 0,
+      VK_STENCIL_OP_ZERO = 1,
+      VK_STENCIL_OP_REPLACE = 2,
+      VK_STENCIL_OP_INCREMENT_AND_CLAMP = 3,
+      VK_STENCIL_OP_DECREMENT_AND_CLAMP = 4,
+      VK_STENCIL_OP_INVERT = 5,
+      VK_STENCIL_OP_INCREMENT_AND_WRAP = 6,
+      VK_STENCIL_OP_DECREMENT_AND_WRAP = 7
+   } VkStencilOp;
+   typedef enum VkStructureType {
+      VK_STRUCTURE_TYPE_APPLICATION_INFO = 0,
+      VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO = 1,
+      VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO = 2,
+      VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO = 3,
+      VK_STRUCTURE_TYPE_SUBMIT_INFO = 4,
+      VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO = 5,
+      VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE = 6,
+      VK_STRUCTURE_TYPE_BIND_SPARSE_INFO = 7,
+      VK_STRUCTURE_TYPE_FENCE_CREATE_INFO = 8,
+      VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO = 9,
+      VK_STRUCTURE_TYPE_EVENT_CREATE_INFO = 10,
+      VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO = 11,
+      VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO = 12,
+      VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO = 13,
+      VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO = 14,
+      VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO = 15,
+      VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO = 16,
+      VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO = 17,
+      VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO = 18,
+      VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO = 19,
+      VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO = 20,
+      VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO = 21,
+      VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO = 22,
+      VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO = 23,
+      VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO = 24,
+      VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO = 25,
+      VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO = 26,
+      VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO = 27,
+      VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO = 28,
+      VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO = 29,
+      VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO = 30,
+      VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO = 31,
+      VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO = 32,
+      VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO = 33,
+      VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO = 34,
+      VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET = 35,
+      VK_STRUCTURE_TYPE_COPY_DESCRIPTOR_SET = 36,
+      VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO = 37,
+      VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO = 38,
+      VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO = 39,
+      VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO = 40,
+      VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO = 41,
+      VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO = 42,
+      VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO = 43,
+      VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER = 44,
+      VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER = 45,
+      VK_STRUCTURE_TYPE_MEMORY_BARRIER = 46,
+      VK_STRUCTURE_TYPE_LOADER_INSTANCE_CREATE_INFO = 47,
+      VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO = 48,
+      VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR = 1000001000,
+      VK_STRUCTURE_TYPE_PRESENT_INFO_KHR = 1000001001,
+      VK_STRUCTURE_TYPE_DEVICE_GROUP_PRESENT_CAPABILITIES_KHR = 1000060007,
+      VK_STRUCTURE_TYPE_IMAGE_SWAPCHAIN_CREATE_INFO_KHR = 1000060008,
+      VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_SWAPCHAIN_INFO_KHR = 1000060009,
+      VK_STRUCTURE_TYPE_ACQUIRE_NEXT_IMAGE_INFO_KHR = 1000060010,
+      VK_STRUCTURE_TYPE_DEVICE_GROUP_PRESENT_INFO_KHR = 1000060011,
+      VK_STRUCTURE_TYPE_DEVICE_GROUP_SWAPCHAIN_CREATE_INFO_KHR = 1000060012,
+      VK_STRUCTURE_TYPE_DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT = 1000011000,
+      VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT = VK_STRUCTURE_TYPE_DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT
+   } VkStructureType;
+   typedef enum VkSystemAllocationScope {
+      VK_SYSTEM_ALLOCATION_SCOPE_COMMAND = 0,
+      VK_SYSTEM_ALLOCATION_SCOPE_OBJECT = 1,
+      VK_SYSTEM_ALLOCATION_SCOPE_CACHE = 2,
+      VK_SYSTEM_ALLOCATION_SCOPE_DEVICE = 3,
+      VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE = 4
+   } VkSystemAllocationScope;
+   typedef enum VkInternalAllocationType {
+      VK_INTERNAL_ALLOCATION_TYPE_EXECUTABLE = 0
+   } VkInternalAllocationType;
+   typedef enum VkSamplerAddressMode {
+      VK_SAMPLER_ADDRESS_MODE_REPEAT = 0,
+      VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT = 1,
+      VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE = 2,
+      VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER = 3
+   } VkSamplerAddressMode;
+   typedef enum VkFilter {
+      VK_FILTER_NEAREST = 0,
+      VK_FILTER_LINEAR = 1
+   } VkFilter;
+   typedef enum VkSamplerMipmapMode {
+      VK_SAMPLER_MIPMAP_MODE_NEAREST = 0,
+      VK_SAMPLER_MIPMAP_MODE_LINEAR = 1
+   } VkSamplerMipmapMode;
+   typedef enum VkVertexInputRate {
+      VK_VERTEX_INPUT_RATE_VERTEX = 0,
+      VK_VERTEX_INPUT_RATE_INSTANCE = 1
+   } VkVertexInputRate;
+   typedef enum VkPipelineStageFlagBits {
+      VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT = 1,
+      VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT = 2,
+      VK_PIPELINE_STAGE_VERTEX_INPUT_BIT = 4,
+      VK_PIPELINE_STAGE_VERTEX_SHADER_BIT = 8,
+      VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT = 16,
+      VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT = 32,
+      VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT = 64,
+      VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT = 128,
+      VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT = 256,
+      VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT = 512,
+      VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT = 1024,
+      VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT = 2048,
+      VK_PIPELINE_STAGE_TRANSFER_BIT = 4096,
+      VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT = 8192,
+      VK_PIPELINE_STAGE_HOST_BIT = 16384,
+      VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT = 32768,
+      VK_PIPELINE_STAGE_ALL_COMMANDS_BIT = 65536
+   } VkPipelineStageFlagBits;
+   typedef enum VkSparseImageFormatFlagBits {
+      VK_SPARSE_IMAGE_FORMAT_SINGLE_MIPTAIL_BIT = 1,
+      VK_SPARSE_IMAGE_FORMAT_ALIGNED_MIP_SIZE_BIT = 2,
+      VK_SPARSE_IMAGE_FORMAT_NONSTANDARD_BLOCK_SIZE_BIT = 4
+   } VkSparseImageFormatFlagBits;
+   typedef enum VkSampleCountFlagBits {
+      VK_SAMPLE_COUNT_1_BIT = 1,
+      VK_SAMPLE_COUNT_2_BIT = 2,
+      VK_SAMPLE_COUNT_4_BIT = 4,
+      VK_SAMPLE_COUNT_8_BIT = 8,
+      VK_SAMPLE_COUNT_16_BIT = 16,
+      VK_SAMPLE_COUNT_32_BIT = 32,
+      VK_SAMPLE_COUNT_64_BIT = 64
+   } VkSampleCountFlagBits;
+   typedef enum VkAttachmentDescriptionFlagBits {
+      VK_ATTACHMENT_DESCRIPTION_MAY_ALIAS_BIT = 1
+   } VkAttachmentDescriptionFlagBits;
+   typedef enum VkDescriptorPoolCreateFlagBits {
+      VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT = 1
+   } VkDescriptorPoolCreateFlagBits;
+   typedef enum VkDependencyFlagBits {
+      VK_DEPENDENCY_BY_REGION_BIT = 1
+   } VkDependencyFlagBits;
+   typedef enum VkObjectType {
+      VK_OBJECT_TYPE_UNKNOWN = 0,
+      VK_OBJECT_TYPE_INSTANCE = 1,
+      VK_OBJECT_TYPE_PHYSICAL_DEVICE = 2,
+      VK_OBJECT_TYPE_DEVICE = 3,
+      VK_OBJECT_TYPE_QUEUE = 4,
+      VK_OBJECT_TYPE_SEMAPHORE = 5,
+      VK_OBJECT_TYPE_COMMAND_BUFFER = 6,
+      VK_OBJECT_TYPE_FENCE = 7,
+      VK_OBJECT_TYPE_DEVICE_MEMORY = 8,
+      VK_OBJECT_TYPE_BUFFER = 9,
+      VK_OBJECT_TYPE_IMAGE = 10,
+      VK_OBJECT_TYPE_EVENT = 11,
+      VK_OBJECT_TYPE_QUERY_POOL = 12,
+      VK_OBJECT_TYPE_BUFFER_VIEW = 13,
+      VK_OBJECT_TYPE_IMAGE_VIEW = 14,
+      VK_OBJECT_TYPE_SHADER_MODULE = 15,
+      VK_OBJECT_TYPE_PIPELINE_CACHE = 16,
+      VK_OBJECT_TYPE_PIPELINE_LAYOUT = 17,
+      VK_OBJECT_TYPE_RENDER_PASS = 18,
+      VK_OBJECT_TYPE_PIPELINE = 19,
+      VK_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT = 20,
+      VK_OBJECT_TYPE_SAMPLER = 21,
+      VK_OBJECT_TYPE_DESCRIPTOR_POOL = 22,
+      VK_OBJECT_TYPE_DESCRIPTOR_SET = 23,
+      VK_OBJECT_TYPE_FRAMEBUFFER = 24,
+      VK_OBJECT_TYPE_COMMAND_POOL = 25,
+      VK_OBJECT_TYPE_SURFACE_KHR = 1000000000,
+      VK_OBJECT_TYPE_SWAPCHAIN_KHR = 1000001000,
+      VK_OBJECT_TYPE_DEBUG_REPORT_CALLBACK_EXT = 1000011000
+   } VkObjectType;
+
+   typedef enum VkColorSpaceKHR {
+      VK_COLOR_SPACE_SRGB_NONLINEAR_KHR = 0,
+      VK_COLORSPACE_SRGB_NONLINEAR_KHR = VK_COLOR_SPACE_SRGB_NONLINEAR_KHR
+   } VkColorSpaceKHR;
+   typedef enum VkCompositeAlphaFlagBitsKHR {
+      VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR = 1,
+      VK_COMPOSITE_ALPHA_PRE_MULTIPLIED_BIT_KHR = 2,
+      VK_COMPOSITE_ALPHA_POST_MULTIPLIED_BIT_KHR = 4,
+      VK_COMPOSITE_ALPHA_INHERIT_BIT_KHR = 8
+   } VkCompositeAlphaFlagBitsKHR;
+   typedef enum VkPresentModeKHR {
+      VK_PRESENT_MODE_IMMEDIATE_KHR = 0,
+      VK_PRESENT_MODE_MAILBOX_KHR = 1,
+      VK_PRESENT_MODE_FIFO_KHR = 2,
+      VK_PRESENT_MODE_FIFO_RELAXED_KHR = 3
+   } VkPresentModeKHR;
+   typedef enum VkSurfaceTransformFlagBitsKHR {
+      VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR = 1,
+      VK_SURFACE_TRANSFORM_ROTATE_90_BIT_KHR = 2,
+      VK_SURFACE_TRANSFORM_ROTATE_180_BIT_KHR = 4,
+      VK_SURFACE_TRANSFORM_ROTATE_270_BIT_KHR = 8,
+      VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_BIT_KHR = 16,
+      VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_90_BIT_KHR = 32,
+      VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_180_BIT_KHR = 64,
+      VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_270_BIT_KHR = 128,
+      VK_SURFACE_TRANSFORM_INHERIT_BIT_KHR = 256
+   } VkSurfaceTransformFlagBitsKHR;
+   typedef enum VkDebugReportFlagBitsEXT {
+      VK_DEBUG_REPORT_INFORMATION_BIT_EXT = 1,
+      VK_DEBUG_REPORT_WARNING_BIT_EXT = 2,
+      VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT = 4,
+      VK_DEBUG_REPORT_ERROR_BIT_EXT = 8,
+      VK_DEBUG_REPORT_DEBUG_BIT_EXT = 16
+   } VkDebugReportFlagBitsEXT;
+   typedef enum VkDebugReportObjectTypeEXT {
+      VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT = 0,
+      VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT = 1,
+      VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT = 2,
+      VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT = 3,
+      VK_DEBUG_REPORT_OBJECT_TYPE_QUEUE_EXT = 4,
+      VK_DEBUG_REPORT_OBJECT_TYPE_SEMAPHORE_EXT = 5,
+      VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT = 6,
+      VK_DEBUG_REPORT_OBJECT_TYPE_FENCE_EXT = 7,
+      VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT = 8,
+      VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT = 9,
+      VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT = 10,
+      VK_DEBUG_REPORT_OBJECT_TYPE_EVENT_EXT = 11,
+      VK_DEBUG_REPORT_OBJECT_TYPE_QUERY_POOL_EXT = 12,
+      VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_VIEW_EXT = 13,
+      VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_VIEW_EXT = 14,
+      VK_DEBUG_REPORT_OBJECT_TYPE_SHADER_MODULE_EXT = 15,
+      VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_CACHE_EXT = 16,
+      VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_LAYOUT_EXT = 17,
+      VK_DEBUG_REPORT_OBJECT_TYPE_RENDER_PASS_EXT = 18,
+      VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT = 19,
+      VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT_EXT = 20,
+      VK_DEBUG_REPORT_OBJECT_TYPE_SAMPLER_EXT = 21,
+      VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_POOL_EXT = 22,
+      VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT = 23,
+      VK_DEBUG_REPORT_OBJECT_TYPE_FRAMEBUFFER_EXT = 24,
+      VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_POOL_EXT = 25,
+      VK_DEBUG_REPORT_OBJECT_TYPE_SURFACE_KHR_EXT = 26,
+      VK_DEBUG_REPORT_OBJECT_TYPE_SWAPCHAIN_KHR_EXT = 27,
+      VK_DEBUG_REPORT_OBJECT_TYPE_DEBUG_REPORT_CALLBACK_EXT_EXT = 28,
+      VK_DEBUG_REPORT_OBJECT_TYPE_DEBUG_REPORT_EXT = VK_DEBUG_REPORT_OBJECT_TYPE_DEBUG_REPORT_CALLBACK_EXT_EXT,
+      VK_DEBUG_REPORT_OBJECT_TYPE_DISPLAY_KHR_EXT = 29,
+      VK_DEBUG_REPORT_OBJECT_TYPE_DISPLAY_MODE_KHR_EXT = 30,
+      VK_DEBUG_REPORT_OBJECT_TYPE_OBJECT_TABLE_NVX_EXT = 31,
+      VK_DEBUG_REPORT_OBJECT_TYPE_INDIRECT_COMMANDS_LAYOUT_NVX_EXT = 32,
+      VK_DEBUG_REPORT_OBJECT_TYPE_VALIDATION_CACHE_EXT_EXT = 33,
+      VK_DEBUG_REPORT_OBJECT_TYPE_VALIDATION_CACHE_EXT = VK_DEBUG_REPORT_OBJECT_TYPE_VALIDATION_CACHE_EXT_EXT,
+      VK_DEBUG_REPORT_OBJECT_TYPE_SAMPLER_YCBCR_CONVERSION_EXT = 1000156000,
+      VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_EXT = 1000085000
+   } VkDebugReportObjectTypeEXT;
+   typedef enum VkDeviceGroupPresentModeFlagBitsKHR {
+      VK_DEVICE_GROUP_PRESENT_MODE_LOCAL_BIT_KHR = 1,
+      VK_DEVICE_GROUP_PRESENT_MODE_REMOTE_BIT_KHR = 2,
+      VK_DEVICE_GROUP_PRESENT_MODE_SUM_BIT_KHR = 4,
+      VK_DEVICE_GROUP_PRESENT_MODE_LOCAL_MULTI_DEVICE_BIT_KHR = 8
+   } VkDeviceGroupPresentModeFlagBitsKHR;
+   typedef enum VkSwapchainCreateFlagBitsKHR {
+      VK_SWAPCHAIN_CREATE_SPLIT_INSTANCE_BIND_REGIONS_BIT_KHR = 1,
+      VK_SWAPCHAIN_CREATE_PROTECTED_BIT_KHR = 2
+   } VkSwapchainCreateFlagBitsKHR;
+   typedef enum VkVendorId {
+      VK_VENDOR_ID_VIV = 0x10001,
+      VK_VENDOR_ID_VSI = 0x10002,
+      VK_VENDOR_ID_KAZAN = 0x10003
+   } VkVendorId;
+   typedef void (VKAPI_PTR* PFN_vkInternalAllocationNotification)(
+      void* pUserData,
+      size_t                                      size,
+      VkInternalAllocationType                    allocationType,
+      VkSystemAllocationScope                     allocationScope);
+   typedef void (VKAPI_PTR* PFN_vkInternalFreeNotification)(
+      void* pUserData,
+      size_t                                      size,
+      VkInternalAllocationType                    allocationType,
+      VkSystemAllocationScope                     allocationScope);
+   typedef void* (VKAPI_PTR* PFN_vkReallocationFunction)(
+      void* pUserData,
+      void* pOriginal,
+      size_t                                      size,
+      size_t                                      alignment,
+      VkSystemAllocationScope                     allocationScope);
+   typedef void* (VKAPI_PTR* PFN_vkAllocationFunction)(
+      void* pUserData,
+      size_t                                      size,
+      size_t                                      alignment,
+      VkSystemAllocationScope                     allocationScope);
+   typedef void (VKAPI_PTR* PFN_vkFreeFunction)(
+      void* pUserData,
+      void* pMemory);
+   typedef void (VKAPI_PTR* PFN_vkVoidFunction)(void);
+   typedef struct VkBaseOutStructure {
+      VkStructureType   sType;
+      struct  VkBaseOutStructure* pNext;
+   } VkBaseOutStructure;
+   typedef struct VkBaseInStructure {
+      VkStructureType   sType;
+      const struct  VkBaseInStructure* pNext;
+   } VkBaseInStructure;
+   typedef struct VkOffset2D {
+      int32_t          x;
+      int32_t          y;
+   } VkOffset2D;
+   typedef struct VkOffset3D {
+      int32_t          x;
+      int32_t          y;
+      int32_t          z;
+   } VkOffset3D;
+   typedef struct VkExtent2D {
+      uint32_t          width;
+      uint32_t          height;
+   } VkExtent2D;
+   typedef struct VkExtent3D {
+      uint32_t          width;
+      uint32_t          height;
+      uint32_t          depth;
+   } VkExtent3D;
+   typedef struct VkViewport {
+      float   x;
+      float   y;
+      float   width;
+      float   height;
+      float                         minDepth;
+      float                         maxDepth;
+   } VkViewport;
+   typedef struct VkRect2D {
+      VkOffset2D       offset;
+      VkExtent2D       extent;
+   } VkRect2D;
+   typedef struct VkClearRect {
+      VkRect2D         rect;
+      uint32_t         baseArrayLayer;
+      uint32_t         layerCount;
+   } VkClearRect;
+   typedef struct VkComponentMapping {
+      VkComponentSwizzle   r;
+      VkComponentSwizzle   g;
+      VkComponentSwizzle   b;
+      VkComponentSwizzle   a;
+   } VkComponentMapping;
+   typedef struct VkExtensionProperties {
+      char              extensionName[VK_MAX_EXTENSION_NAME_SIZE];
+      uint32_t          specVersion;
+   } VkExtensionProperties;
+   typedef struct VkLayerProperties {
+      char              layerName[VK_MAX_EXTENSION_NAME_SIZE];
+      uint32_t          specVersion;
+      uint32_t          implementationVersion;
+      char              description[VK_MAX_DESCRIPTION_SIZE];
+   } VkLayerProperties;
+   typedef struct VkApplicationInfo {
+      VkStructureType   sType;
+      const  void* pNext;
+      const  char* pApplicationName;
+      uint32_t          applicationVersion;
+      const  char* pEngineName;
+      uint32_t          engineVersion;
+      uint32_t          apiVersion;
+   } VkApplicationInfo;
+   typedef struct VkAllocationCallbacks {
+      void* pUserData;
+      PFN_vkAllocationFunction     pfnAllocation;
+      PFN_vkReallocationFunction   pfnReallocation;
+      PFN_vkFreeFunction      pfnFree;
+      PFN_vkInternalAllocationNotification   pfnInternalAllocation;
+      PFN_vkInternalFreeNotification   pfnInternalFree;
+   } VkAllocationCallbacks;
+   typedef struct VkDescriptorImageInfo {
+      VkSampler         sampler;
+      VkImageView       imageView;
+      VkImageLayout     imageLayout;
+   } VkDescriptorImageInfo;
+   typedef struct VkCopyDescriptorSet {
+      VkStructureType   sType;
+      const  void* pNext;
+      VkDescriptorSet          srcSet;
+      uint32_t                 srcBinding;
+      uint32_t                 srcArrayElement;
+      VkDescriptorSet          dstSet;
+      uint32_t                 dstBinding;
+      uint32_t                 dstArrayElement;
+      uint32_t                 descriptorCount;
+   } VkCopyDescriptorSet;
+   typedef struct VkDescriptorPoolSize {
+      VkDescriptorType         type;
+      uint32_t                 descriptorCount;
+   } VkDescriptorPoolSize;
+   typedef struct VkDescriptorSetAllocateInfo {
+      VkStructureType   sType;
+      const  void* pNext;
+      VkDescriptorPool         descriptorPool;
+      uint32_t                 descriptorSetCount;
+      const  VkDescriptorSetLayout* pSetLayouts;
+   } VkDescriptorSetAllocateInfo;
+   typedef struct VkSpecializationMapEntry {
+      uint32_t                       constantID;
+      uint32_t                       offset;
+      size_t   size;
+   } VkSpecializationMapEntry;
+   typedef struct VkSpecializationInfo {
+      uint32_t                 mapEntryCount;
+      const  VkSpecializationMapEntry* pMapEntries;
+      size_t                   dataSize;
+      const  void* pData;
+   } VkSpecializationInfo;
+   typedef struct VkVertexInputBindingDescription {
+      uint32_t                 binding;
+      uint32_t                 stride;
+      VkVertexInputRate        inputRate;
+   } VkVertexInputBindingDescription;
+   typedef struct VkVertexInputAttributeDescription {
+      uint32_t                 location;
+      uint32_t                 binding;
+      VkFormat                 format;
+      uint32_t                 offset;
+   } VkVertexInputAttributeDescription;
+   typedef struct VkStencilOpState {
+      VkStencilOp              failOp;
+      VkStencilOp              passOp;
+      VkStencilOp              depthFailOp;
+      VkCompareOp              compareOp;
+      uint32_t                 compareMask;
+      uint32_t                 writeMask;
+      uint32_t                 reference;
+   } VkStencilOpState;
+   typedef struct VkCommandBufferAllocateInfo {
+      VkStructureType   sType;
+      const  void* pNext;
+      VkCommandPool            commandPool;
+      VkCommandBufferLevel     level;
+      uint32_t                 commandBufferCount;
+   } VkCommandBufferAllocateInfo;
+   typedef union VkClearColorValue {
+      float                    float32[4];
+      int32_t                  int32[4];
+      uint32_t                 uint32[4];
+   } VkClearColorValue;
+   typedef struct VkClearDepthStencilValue {
+      float                    depth;
+      uint32_t                 stencil;
+   } VkClearDepthStencilValue;
+   typedef union VkClearValue {
+      VkClearColorValue        color;
+      VkClearDepthStencilValue   depthStencil;
+   } VkClearValue;
+   typedef struct VkAttachmentReference {
+      uint32_t                 attachment;
+      VkImageLayout            layout;
+   } VkAttachmentReference;
+   typedef struct VkDrawIndirectCommand {
+      uint32_t                         vertexCount;
+      uint32_t                         instanceCount;
+      uint32_t                         firstVertex;
+      uint32_t   firstInstance;
+   } VkDrawIndirectCommand;
+   typedef struct VkDrawIndexedIndirectCommand {
+      uint32_t                         indexCount;
+      uint32_t                         instanceCount;
+      uint32_t                         firstIndex;
+      int32_t                          vertexOffset;
+      uint32_t   firstInstance;
+   } VkDrawIndexedIndirectCommand;
+   typedef struct VkDispatchIndirectCommand {
+      uint32_t   x;
+      uint32_t   y;
+      uint32_t   z;
+   } VkDispatchIndirectCommand;
+   typedef struct VkSurfaceFormatKHR {
+      VkFormat                           format;
+      VkColorSpaceKHR                    colorSpace;
+   } VkSurfaceFormatKHR;
+   typedef struct VkPresentInfoKHR {
+      VkStructureType   sType;
+      const  void* pNext;
+      uint32_t           waitSemaphoreCount;
+      const  VkSemaphore* pWaitSemaphores;
+      uint32_t                           swapchainCount;
+      const  VkSwapchainKHR* pSwapchains;
+      const  uint32_t* pImageIndices;
+      VkResult* pResults;
+   } VkPresentInfoKHR;
+   typedef struct VkImageSwapchainCreateInfoKHR {
+      VkStructureType   sType;
+      const  void* pNext;
+      VkSwapchainKHR     swapchain;
+   } VkImageSwapchainCreateInfoKHR;
+   typedef struct VkBindImageMemorySwapchainInfoKHR {
+      VkStructureType   sType;
+      const  void* pNext;
+      VkSwapchainKHR   swapchain;
+      uint32_t                           imageIndex;
+   } VkBindImageMemorySwapchainInfoKHR;
+   typedef struct VkAcquireNextImageInfoKHR {
+      VkStructureType   sType;
+      const  void* pNext;
+      VkSwapchainKHR   swapchain;
+      uint64_t                           timeout;
+      VkSemaphore   semaphore;
+      VkFence   fence;
+      uint32_t                           deviceMask;
+   } VkAcquireNextImageInfoKHR;
+   typedef struct VkDeviceGroupPresentInfoKHR {
+      VkStructureType   sType;
+      const  void* pNext;
+      uint32_t           swapchainCount;
+      const  uint32_t* pDeviceMasks;
+      VkDeviceGroupPresentModeFlagBitsKHR   mode;
+   } VkDeviceGroupPresentInfoKHR;
+   typedef uint32_t VkSampleMask;
+   typedef uint32_t VkBool32;
+   typedef uint32_t VkFlags;
+   typedef uint64_t VkDeviceSize;
+   typedef VkFlags VkFramebufferCreateFlags;
+   typedef VkFlags VkQueryPoolCreateFlags;
+   typedef VkFlags VkRenderPassCreateFlags;
+   typedef VkFlags VkSamplerCreateFlags;
+   typedef VkFlags VkPipelineLayoutCreateFlags;
+   typedef VkFlags VkPipelineCacheCreateFlags;
+   typedef VkFlags VkPipelineDepthStencilStateCreateFlags;
+   typedef VkFlags VkPipelineDynamicStateCreateFlags;
+   typedef VkFlags VkPipelineColorBlendStateCreateFlags;
+   typedef VkFlags VkPipelineMultisampleStateCreateFlags;
+   typedef VkFlags VkPipelineRasterizationStateCreateFlags;
+   typedef VkFlags VkPipelineViewportStateCreateFlags;
+   typedef VkFlags VkPipelineTessellationStateCreateFlags;
+   typedef VkFlags VkPipelineInputAssemblyStateCreateFlags;
+   typedef VkFlags VkPipelineVertexInputStateCreateFlags;
+   typedef VkFlags VkPipelineShaderStageCreateFlags;
+   typedef VkFlags VkDescriptorSetLayoutCreateFlags;
+   typedef VkFlags VkBufferViewCreateFlags;
+   typedef VkFlags VkInstanceCreateFlags;
+   typedef VkFlags VkDeviceCreateFlags;
+   typedef VkFlags VkDeviceQueueCreateFlags;
+   typedef VkFlags VkQueueFlags;
+   typedef VkFlags VkMemoryPropertyFlags;
+   typedef VkFlags VkMemoryHeapFlags;
+   typedef VkFlags VkAccessFlags;
+   typedef VkFlags VkBufferUsageFlags;
+   typedef VkFlags VkBufferCreateFlags;
+   typedef VkFlags VkShaderStageFlags;
+   typedef VkFlags VkImageUsageFlags;
+   typedef VkFlags VkImageCreateFlags;
+   typedef VkFlags VkImageViewCreateFlags;
+   typedef VkFlags VkPipelineCreateFlags;
+   typedef VkFlags VkColorComponentFlags;
+   typedef VkFlags VkFenceCreateFlags;
+   typedef VkFlags VkSemaphoreCreateFlags;
+   typedef VkFlags VkFormatFeatureFlags;
+   typedef VkFlags VkQueryControlFlags;
+   typedef VkFlags VkQueryResultFlags;
+   typedef VkFlags VkShaderModuleCreateFlags;
+   typedef VkFlags VkEventCreateFlags;
+   typedef VkFlags VkCommandPoolCreateFlags;
+   typedef VkFlags VkCommandPoolResetFlags;
+   typedef VkFlags VkCommandBufferResetFlags;
+   typedef VkFlags VkCommandBufferUsageFlags;
+   typedef VkFlags VkQueryPipelineStatisticFlags;
+   typedef VkFlags VkMemoryMapFlags;
+   typedef VkFlags VkImageAspectFlags;
+   typedef VkFlags VkSparseMemoryBindFlags;
+   typedef VkFlags VkSparseImageFormatFlags;
+   typedef VkFlags VkSubpassDescriptionFlags;
+   typedef VkFlags VkPipelineStageFlags;
+   typedef VkFlags VkSampleCountFlags;
+   typedef VkFlags VkAttachmentDescriptionFlags;
+   typedef VkFlags VkStencilFaceFlags;
+   typedef VkFlags VkCullModeFlags;
+   typedef VkFlags VkDescriptorPoolCreateFlags;
+   typedef VkFlags VkDescriptorPoolResetFlags;
+   typedef VkFlags VkDependencyFlags;
+   typedef VkFlags VkCompositeAlphaFlagsKHR;
+   typedef VkFlags VkSurfaceTransformFlagsKHR;
+   typedef VkFlags VkSwapchainCreateFlagsKHR;
+   typedef VkFlags VkDeviceGroupPresentModeFlagsKHR;
+   typedef VkFlags VkDebugReportFlagsEXT;
+   typedef VkBool32(VKAPI_PTR* PFN_vkDebugReportCallbackEXT)(
+      VkDebugReportFlagsEXT                       flags,
+      VkDebugReportObjectTypeEXT                  objectType,
+      uint64_t                                    object,
+      size_t                                      location,
+      int32_t                                     messageCode,
+      const char* pLayerPrefix,
+      const char* pMessage,
+      void* pUserData);
+   typedef struct VkDeviceQueueCreateInfo {
+      VkStructureType   sType;
+      const  void* pNext;
+      VkDeviceQueueCreateFlags      flags;
+      uint32_t          queueFamilyIndex;
+      uint32_t          queueCount;
+      const  float* pQueuePriorities;
+   } VkDeviceQueueCreateInfo;
+   typedef struct VkInstanceCreateInfo {
+      VkStructureType   sType;
+      const  void* pNext;
+      VkInstanceCreateFlags    flags;
+      const  VkApplicationInfo* pApplicationInfo;
+      uint32_t                 enabledLayerCount;
+      const  char* const* ppEnabledLayerNames;
+      uint32_t                 enabledExtensionCount;
+      const  char* const* ppEnabledExtensionNames;
+   } VkInstanceCreateInfo;
+   typedef struct VkQueueFamilyProperties {
+      VkQueueFlags             queueFlags;
+      uint32_t                 queueCount;
+      uint32_t                 timestampValidBits;
+      VkExtent3D               minImageTransferGranularity;
+   } VkQueueFamilyProperties;
+   typedef struct VkMemoryAllocateInfo {
+      VkStructureType   sType;
+      const  void* pNext;
+      VkDeviceSize             allocationSize;
+      uint32_t                 memoryTypeIndex;
+   } VkMemoryAllocateInfo;
+   typedef struct VkMemoryRequirements {
+      VkDeviceSize             size;
+      VkDeviceSize             alignment;
+      uint32_t                 memoryTypeBits;
+   } VkMemoryRequirements;
+   typedef struct VkSparseImageFormatProperties {
+      VkImageAspectFlags       aspectMask;
+      VkExtent3D               imageGranularity;
+      VkSparseImageFormatFlags   flags;
+   } VkSparseImageFormatProperties;
+   typedef struct VkSparseImageMemoryRequirements {
+      VkSparseImageFormatProperties   formatProperties;
+      uint32_t                 imageMipTailFirstLod;
+      VkDeviceSize             imageMipTailSize;
+      VkDeviceSize             imageMipTailOffset;
+      VkDeviceSize             imageMipTailStride;
+   } VkSparseImageMemoryRequirements;
+   typedef struct VkMemoryType {
+      VkMemoryPropertyFlags    propertyFlags;
+      uint32_t                 heapIndex;
+   } VkMemoryType;
+   typedef struct VkMemoryHeap {
+      VkDeviceSize             size;
+      VkMemoryHeapFlags        flags;
+   } VkMemoryHeap;
+   typedef struct VkMappedMemoryRange {
+      VkStructureType   sType;
+      const  void* pNext;
+      VkDeviceMemory           memory;
+      VkDeviceSize             offset;
+      VkDeviceSize             size;
+   } VkMappedMemoryRange;
+   typedef struct VkFormatProperties {
+      VkFormatFeatureFlags     linearTilingFeatures;
+      VkFormatFeatureFlags     optimalTilingFeatures;
+      VkFormatFeatureFlags     bufferFeatures;
+   } VkFormatProperties;
+   typedef struct VkImageFormatProperties {
+      VkExtent3D               maxExtent;
+      uint32_t                 maxMipLevels;
+      uint32_t                 maxArrayLayers;
+      VkSampleCountFlags       sampleCounts;
+      VkDeviceSize             maxResourceSize;
+   } VkImageFormatProperties;
+   typedef struct VkDescriptorBufferInfo {
+      VkBuffer                 buffer;
+      VkDeviceSize             offset;
+      VkDeviceSize             range;
+   } VkDescriptorBufferInfo;
+   typedef struct VkWriteDescriptorSet {
+      VkStructureType   sType;
+      const  void* pNext;
+      VkDescriptorSet          dstSet;
+      uint32_t                 dstBinding;
+      uint32_t                 dstArrayElement;
+      uint32_t                 descriptorCount;
+      VkDescriptorType         descriptorType;
+      const  VkDescriptorImageInfo* pImageInfo;
+      const  VkDescriptorBufferInfo* pBufferInfo;
+      const  VkBufferView* pTexelBufferView;
+   } VkWriteDescriptorSet;
+   typedef struct VkBufferCreateInfo {
+      VkStructureType   sType;
+      const  void* pNext;
+      VkBufferCreateFlags      flags;
+      VkDeviceSize             size;
+      VkBufferUsageFlags       usage;
+      VkSharingMode            sharingMode;
+      uint32_t                 queueFamilyIndexCount;
+      const  uint32_t* pQueueFamilyIndices;
+   } VkBufferCreateInfo;
+   typedef struct VkBufferViewCreateInfo {
+      VkStructureType   sType;
+      const  void* pNext;
+      VkBufferViewCreateFlags flags;
+      VkBuffer                 buffer;
+      VkFormat                 format;
+      VkDeviceSize             offset;
+      VkDeviceSize             range;
+   } VkBufferViewCreateInfo;
+   typedef struct VkImageSubresource {
+      VkImageAspectFlags       aspectMask;
+      uint32_t                 mipLevel;
+      uint32_t                 arrayLayer;
+   } VkImageSubresource;
+   typedef struct VkImageSubresourceLayers {
+      VkImageAspectFlags       aspectMask;
+      uint32_t                 mipLevel;
+      uint32_t                 baseArrayLayer;
+      uint32_t                 layerCount;
+   } VkImageSubresourceLayers;
+   typedef struct VkImageSubresourceRange {
+      VkImageAspectFlags       aspectMask;
+      uint32_t                 baseMipLevel;
+      uint32_t                 levelCount;
+      uint32_t                 baseArrayLayer;
+      uint32_t                 layerCount;
+   } VkImageSubresourceRange;
+   typedef struct VkMemoryBarrier {
+      VkStructureType   sType;
+      const  void* pNext;
+      VkAccessFlags            srcAccessMask;
+      VkAccessFlags            dstAccessMask;
+   } VkMemoryBarrier;
+   typedef struct VkBufferMemoryBarrier {
+      VkStructureType   sType;
+      const  void* pNext;
+      VkAccessFlags            srcAccessMask;
+      VkAccessFlags            dstAccessMask;
+      uint32_t                 srcQueueFamilyIndex;
+      uint32_t                 dstQueueFamilyIndex;
+      VkBuffer                 buffer;
+      VkDeviceSize             offset;
+      VkDeviceSize             size;
+   } VkBufferMemoryBarrier;
+   typedef struct VkImageMemoryBarrier {
+      VkStructureType   sType;
+      const  void* pNext;
+      VkAccessFlags            srcAccessMask;
+      VkAccessFlags            dstAccessMask;
+      VkImageLayout            oldLayout;
+      VkImageLayout            newLayout;
+      uint32_t                 srcQueueFamilyIndex;
+      uint32_t                 dstQueueFamilyIndex;
+      VkImage                  image;
+      VkImageSubresourceRange   subresourceRange;
+   } VkImageMemoryBarrier;
+   typedef struct VkImageCreateInfo {
+      VkStructureType   sType;
+      const  void* pNext;
+      VkImageCreateFlags       flags;
+      VkImageType              imageType;
+      VkFormat                 format;
+      VkExtent3D               extent;
+      uint32_t                 mipLevels;
+      uint32_t                 arrayLayers;
+      VkSampleCountFlagBits    samples;
+      VkImageTiling            tiling;
+      VkImageUsageFlags        usage;
+      VkSharingMode            sharingMode;
+      uint32_t                 queueFamilyIndexCount;
+      const  uint32_t* pQueueFamilyIndices;
+      VkImageLayout            initialLayout;
+   } VkImageCreateInfo;
+   typedef struct VkSubresourceLayout {
+      VkDeviceSize             offset;
+      VkDeviceSize             size;
+      VkDeviceSize             rowPitch;
+      VkDeviceSize             arrayPitch;
+      VkDeviceSize             depthPitch;
+   } VkSubresourceLayout;
+   typedef struct VkImageViewCreateInfo {
+      VkStructureType   sType;
+      const  void* pNext;
+      VkImageViewCreateFlags   flags;
+      VkImage                  image;
+      VkImageViewType          viewType;
+      VkFormat                 format;
+      VkComponentMapping       components;
+      VkImageSubresourceRange   subresourceRange;
+   } VkImageViewCreateInfo;
+   typedef struct VkBufferCopy {
+      VkDeviceSize                         srcOffset;
+      VkDeviceSize                         dstOffset;
+      VkDeviceSize   size;
+   } VkBufferCopy;
+   typedef struct VkSparseMemoryBind {
+      VkDeviceSize             resourceOffset;
+      VkDeviceSize             size;
+      VkDeviceMemory           memory;
+      VkDeviceSize             memoryOffset;
+      VkSparseMemoryBindFlags flags;
+   } VkSparseMemoryBind;
+   typedef struct VkSparseImageMemoryBind {
+      VkImageSubresource       subresource;
+      VkOffset3D               offset;
+      VkExtent3D               extent;
+      VkDeviceMemory           memory;
+      VkDeviceSize             memoryOffset;
+      VkSparseMemoryBindFlags flags;
+   } VkSparseImageMemoryBind;
+   typedef struct VkSparseBufferMemoryBindInfo {
+      VkBuffer   buffer;
+      uint32_t                 bindCount;
+      const  VkSparseMemoryBind* pBinds;
+   } VkSparseBufferMemoryBindInfo;
+   typedef struct VkSparseImageOpaqueMemoryBindInfo {
+      VkImage   image;
+      uint32_t                 bindCount;
+      const  VkSparseMemoryBind* pBinds;
+   } VkSparseImageOpaqueMemoryBindInfo;
+   typedef struct VkSparseImageMemoryBindInfo {
+      VkImage   image;
+      uint32_t                 bindCount;
+      const  VkSparseImageMemoryBind* pBinds;
+   } VkSparseImageMemoryBindInfo;
+   typedef struct VkBindSparseInfo {
+      VkStructureType   sType;
+      const  void* pNext;
+      uint32_t                 waitSemaphoreCount;
+      const  VkSemaphore* pWaitSemaphores;
+      uint32_t                 bufferBindCount;
+      const  VkSparseBufferMemoryBindInfo* pBufferBinds;
+      uint32_t                 imageOpaqueBindCount;
+      const  VkSparseImageOpaqueMemoryBindInfo* pImageOpaqueBinds;
+      uint32_t                 imageBindCount;
+      const  VkSparseImageMemoryBindInfo* pImageBinds;
+      uint32_t                 signalSemaphoreCount;
+      const  VkSemaphore* pSignalSemaphores;
+   } VkBindSparseInfo;
+   typedef struct VkImageCopy {
+      VkImageSubresourceLayers   srcSubresource;
+      VkOffset3D               srcOffset;
+      VkImageSubresourceLayers   dstSubresource;
+      VkOffset3D               dstOffset;
+      VkExtent3D               extent;
+   } VkImageCopy;
+   typedef struct VkImageBlit {
+      VkImageSubresourceLayers   srcSubresource;
+      VkOffset3D               srcOffsets[2];
+      VkImageSubresourceLayers   dstSubresource;
+      VkOffset3D               dstOffsets[2];
+   } VkImageBlit;
+   typedef struct VkBufferImageCopy {
+      VkDeviceSize             bufferOffset;
+      uint32_t                 bufferRowLength;
+      uint32_t                 bufferImageHeight;
+      VkImageSubresourceLayers   imageSubresource;
+      VkOffset3D               imageOffset;
+      VkExtent3D               imageExtent;
+   } VkBufferImageCopy;
+   typedef struct VkImageResolve {
+      VkImageSubresourceLayers   srcSubresource;
+      VkOffset3D               srcOffset;
+      VkImageSubresourceLayers   dstSubresource;
+      VkOffset3D               dstOffset;
+      VkExtent3D               extent;
+   } VkImageResolve;
+   typedef struct VkShaderModuleCreateInfo {
+      VkStructureType   sType;
+      const  void* pNext;
+      VkShaderModuleCreateFlags   flags;
+      size_t                   codeSize;
+      const  uint32_t* pCode;
+   } VkShaderModuleCreateInfo;
+   typedef struct VkDescriptorSetLayoutBinding {
+      uint32_t                 binding;
+      VkDescriptorType         descriptorType;
+      uint32_t   descriptorCount;
+      VkShaderStageFlags       stageFlags;
+      const  VkSampler* pImmutableSamplers;
+   } VkDescriptorSetLayoutBinding;
+   typedef struct VkDescriptorSetLayoutCreateInfo {
+      VkStructureType   sType;
+      const  void* pNext;
+      VkDescriptorSetLayoutCreateFlags      flags;
+      uint32_t                 bindingCount;
+      const  VkDescriptorSetLayoutBinding* pBindings;
+   } VkDescriptorSetLayoutCreateInfo;
+   typedef struct VkDescriptorPoolCreateInfo {
+      VkStructureType   sType;
+      const  void* pNext;
+      VkDescriptorPoolCreateFlags    flags;
+      uint32_t                 maxSets;
+      uint32_t                 poolSizeCount;
+      const  VkDescriptorPoolSize* pPoolSizes;
+   } VkDescriptorPoolCreateInfo;
+   typedef struct VkPipelineShaderStageCreateInfo {
+      VkStructureType   sType;
+      const  void* pNext;
+      VkPipelineShaderStageCreateFlags      flags;
+      VkShaderStageFlagBits    stage;
+      VkShaderModule           module;
+      const  char* pName;
+      const  VkSpecializationInfo* pSpecializationInfo;
+   } VkPipelineShaderStageCreateInfo;
+   typedef struct VkComputePipelineCreateInfo {
+      VkStructureType   sType;
+      const  void* pNext;
+      VkPipelineCreateFlags    flags;
+      VkPipelineShaderStageCreateInfo   stage;
+      VkPipelineLayout         layout;
+      VkPipeline        basePipelineHandle;
+      int32_t                  basePipelineIndex;
+   } VkComputePipelineCreateInfo;
+   typedef struct VkPipelineVertexInputStateCreateInfo {
+      VkStructureType   sType;
+      const  void* pNext;
+      VkPipelineVertexInputStateCreateFlags      flags;
+      uint32_t                 vertexBindingDescriptionCount;
+      const  VkVertexInputBindingDescription* pVertexBindingDescriptions;
+      uint32_t                 vertexAttributeDescriptionCount;
+      const  VkVertexInputAttributeDescription* pVertexAttributeDescriptions;
+   } VkPipelineVertexInputStateCreateInfo;
+   typedef struct VkPipelineInputAssemblyStateCreateInfo {
+      VkStructureType   sType;
+      const  void* pNext;
+      VkPipelineInputAssemblyStateCreateFlags      flags;
+      VkPrimitiveTopology      topology;
+      VkBool32                 primitiveRestartEnable;
+   } VkPipelineInputAssemblyStateCreateInfo;
+   typedef struct VkPipelineTessellationStateCreateInfo {
+      VkStructureType   sType;
+      const  void* pNext;
+      VkPipelineTessellationStateCreateFlags      flags;
+      uint32_t                 patchControlPoints;
+   } VkPipelineTessellationStateCreateInfo;
+   typedef struct VkPipelineViewportStateCreateInfo {
+      VkStructureType   sType;
+      const  void* pNext;
+      VkPipelineViewportStateCreateFlags      flags;
+      uint32_t                 viewportCount;
+      const  VkViewport* pViewports;
+      uint32_t                 scissorCount;
+      const  VkRect2D* pScissors;
+   } VkPipelineViewportStateCreateInfo;
+   typedef struct VkPipelineRasterizationStateCreateInfo {
+      VkStructureType   sType;
+      const  void* pNext;
+      VkPipelineRasterizationStateCreateFlags      flags;
+      VkBool32                 depthClampEnable;
+      VkBool32                 rasterizerDiscardEnable;
+      VkPolygonMode            polygonMode;
+      VkCullModeFlags          cullMode;
+      VkFrontFace              frontFace;
+      VkBool32                 depthBiasEnable;
+      float                    depthBiasConstantFactor;
+      float                    depthBiasClamp;
+      float                    depthBiasSlopeFactor;
+      float                    lineWidth;
+   } VkPipelineRasterizationStateCreateInfo;
+   typedef struct VkPipelineMultisampleStateCreateInfo {
+      VkStructureType   sType;
+      const  void* pNext;
+      VkPipelineMultisampleStateCreateFlags      flags;
+      VkSampleCountFlagBits    rasterizationSamples;
+      VkBool32                 sampleShadingEnable;
+      float                    minSampleShading;
+      const  VkSampleMask* pSampleMask;
+      VkBool32                 alphaToCoverageEnable;
+      VkBool32                 alphaToOneEnable;
+   } VkPipelineMultisampleStateCreateInfo;
+   typedef struct VkPipelineColorBlendAttachmentState {
+      VkBool32                 blendEnable;
+      VkBlendFactor            srcColorBlendFactor;
+      VkBlendFactor            dstColorBlendFactor;
+      VkBlendOp                colorBlendOp;
+      VkBlendFactor            srcAlphaBlendFactor;
+      VkBlendFactor            dstAlphaBlendFactor;
+      VkBlendOp                alphaBlendOp;
+      VkColorComponentFlags    colorWriteMask;
+   } VkPipelineColorBlendAttachmentState;
+   typedef struct VkPipelineColorBlendStateCreateInfo {
+      VkStructureType   sType;
+      const  void* pNext;
+      VkPipelineColorBlendStateCreateFlags      flags;
+      VkBool32                 logicOpEnable;
+      VkLogicOp                logicOp;
+      uint32_t                 attachmentCount;
+      const  VkPipelineColorBlendAttachmentState* pAttachments;
+      float                    blendConstants[4];
+   } VkPipelineColorBlendStateCreateInfo;
+   typedef struct VkPipelineDynamicStateCreateInfo {
+      VkStructureType   sType;
+      const  void* pNext;
+      VkPipelineDynamicStateCreateFlags      flags;
+      uint32_t                 dynamicStateCount;
+      const  VkDynamicState* pDynamicStates;
+   } VkPipelineDynamicStateCreateInfo;
+   typedef struct VkPipelineDepthStencilStateCreateInfo {
+      VkStructureType   sType;
+      const  void* pNext;
+      VkPipelineDepthStencilStateCreateFlags      flags;
+      VkBool32                 depthTestEnable;
+      VkBool32                 depthWriteEnable;
+      VkCompareOp              depthCompareOp;
+      VkBool32                 depthBoundsTestEnable;
+      VkBool32                 stencilTestEnable;
+      VkStencilOpState         front;
+      VkStencilOpState         back;
+      float                    minDepthBounds;
+      float                    maxDepthBounds;
+   } VkPipelineDepthStencilStateCreateInfo;
+   typedef struct VkGraphicsPipelineCreateInfo {
+      VkStructureType   sType;
+      const  void* pNext;
+      VkPipelineCreateFlags    flags;
+      uint32_t                 stageCount;
+      const  VkPipelineShaderStageCreateInfo* pStages;
+      const  VkPipelineVertexInputStateCreateInfo* pVertexInputState;
+      const  VkPipelineInputAssemblyStateCreateInfo* pInputAssemblyState;
+      const  VkPipelineTessellationStateCreateInfo* pTessellationState;
+      const  VkPipelineViewportStateCreateInfo* pViewportState;
+      const  VkPipelineRasterizationStateCreateInfo* pRasterizationState;
+      const  VkPipelineMultisampleStateCreateInfo* pMultisampleState;
+      const  VkPipelineDepthStencilStateCreateInfo* pDepthStencilState;
+      const  VkPipelineColorBlendStateCreateInfo* pColorBlendState;
+      const  VkPipelineDynamicStateCreateInfo* pDynamicState;
+      VkPipelineLayout         layout;
+      VkRenderPass             renderPass;
+      uint32_t                 subpass;
+      VkPipeline        basePipelineHandle;
+      int32_t                  basePipelineIndex;
+   } VkGraphicsPipelineCreateInfo;
+   typedef struct VkPipelineCacheCreateInfo {
+      VkStructureType   sType;
+      const  void* pNext;
+      VkPipelineCacheCreateFlags      flags;
+      size_t                   initialDataSize;
+      const  void* pInitialData;
+   } VkPipelineCacheCreateInfo;
+   typedef struct VkPushConstantRange {
+      VkShaderStageFlags       stageFlags;
+      uint32_t                 offset;
+      uint32_t                 size;
+   } VkPushConstantRange;
+   typedef struct VkPipelineLayoutCreateInfo {
+      VkStructureType   sType;
+      const  void* pNext;
+      VkPipelineLayoutCreateFlags      flags;
+      uint32_t                 setLayoutCount;
+      const  VkDescriptorSetLayout* pSetLayouts;
+      uint32_t                 pushConstantRangeCount;
+      const  VkPushConstantRange* pPushConstantRanges;
+   } VkPipelineLayoutCreateInfo;
+   typedef struct VkSamplerCreateInfo {
+      VkStructureType   sType;
+      const  void* pNext;
+      VkSamplerCreateFlags     flags;
+      VkFilter                 magFilter;
+      VkFilter                 minFilter;
+      VkSamplerMipmapMode      mipmapMode;
+      VkSamplerAddressMode     addressModeU;
+      VkSamplerAddressMode     addressModeV;
+      VkSamplerAddressMode     addressModeW;
+      float                    mipLodBias;
+      VkBool32                 anisotropyEnable;
+      float                    maxAnisotropy;
+      VkBool32                 compareEnable;
+      VkCompareOp              compareOp;
+      float                    minLod;
+      float                    maxLod;
+      VkBorderColor            borderColor;
+      VkBool32                 unnormalizedCoordinates;
+   } VkSamplerCreateInfo;
+   typedef struct VkCommandPoolCreateInfo {
+      VkStructureType   sType;
+      const  void* pNext;
+      VkCommandPoolCreateFlags     flags;
+      uint32_t                 queueFamilyIndex;
+   } VkCommandPoolCreateInfo;
+   typedef struct VkCommandBufferInheritanceInfo {
+      VkStructureType   sType;
+      const  void* pNext;
+      VkRenderPass      renderPass;
+      uint32_t                 subpass;
+      VkFramebuffer     framebuffer;
+      VkBool32                 occlusionQueryEnable;
+      VkQueryControlFlags      queryFlags;
+      VkQueryPipelineStatisticFlags   pipelineStatistics;
+   } VkCommandBufferInheritanceInfo;
+   typedef struct VkCommandBufferBeginInfo {
+      VkStructureType   sType;
+      const  void* pNext;
+      VkCommandBufferUsageFlags    flags;
+      const  VkCommandBufferInheritanceInfo* pInheritanceInfo;
+   } VkCommandBufferBeginInfo;
+   typedef struct VkRenderPassBeginInfo {
+      VkStructureType   sType;
+      const  void* pNext;
+      VkRenderPass             renderPass;
+      VkFramebuffer            framebuffer;
+      VkRect2D                 renderArea;
+      uint32_t                 clearValueCount;
+      const  VkClearValue* pClearValues;
+   } VkRenderPassBeginInfo;
+   typedef struct VkClearAttachment {
+      VkImageAspectFlags       aspectMask;
+      uint32_t                 colorAttachment;
+      VkClearValue             clearValue;
+   } VkClearAttachment;
+   typedef struct VkAttachmentDescription {
+      VkAttachmentDescriptionFlags   flags;
+      VkFormat                 format;
+      VkSampleCountFlagBits    samples;
+      VkAttachmentLoadOp       loadOp;
+      VkAttachmentStoreOp      storeOp;
+      VkAttachmentLoadOp       stencilLoadOp;
+      VkAttachmentStoreOp      stencilStoreOp;
+      VkImageLayout            initialLayout;
+      VkImageLayout            finalLayout;
+   } VkAttachmentDescription;
+   typedef struct VkSubpassDescription {
+      VkSubpassDescriptionFlags   flags;
+      VkPipelineBindPoint      pipelineBindPoint;
+      uint32_t                 inputAttachmentCount;
+      const  VkAttachmentReference* pInputAttachments;
+      uint32_t                 colorAttachmentCount;
+      const  VkAttachmentReference* pColorAttachments;
+      const  VkAttachmentReference* pResolveAttachments;
+      const  VkAttachmentReference* pDepthStencilAttachment;
+      uint32_t                 preserveAttachmentCount;
+      const  uint32_t* pPreserveAttachments;
+   } VkSubpassDescription;
+   typedef struct VkSubpassDependency {
+      uint32_t                 srcSubpass;
+      uint32_t                 dstSubpass;
+      VkPipelineStageFlags     srcStageMask;
+      VkPipelineStageFlags     dstStageMask;
+      VkAccessFlags            srcAccessMask;
+      VkAccessFlags            dstAccessMask;
+      VkDependencyFlags        dependencyFlags;
+   } VkSubpassDependency;
+   typedef struct VkRenderPassCreateInfo {
+      VkStructureType   sType;
+      const  void* pNext;
+      VkRenderPassCreateFlags      flags;
+      uint32_t     attachmentCount;
+      const  VkAttachmentDescription* pAttachments;
+      uint32_t                 subpassCount;
+      const  VkSubpassDescription* pSubpasses;
+      uint32_t         dependencyCount;
+      const  VkSubpassDependency* pDependencies;
+   } VkRenderPassCreateInfo;
+   typedef struct VkEventCreateInfo {
+      VkStructureType   sType;
+      const  void* pNext;
+      VkEventCreateFlags       flags;
+   } VkEventCreateInfo;
+   typedef struct VkFenceCreateInfo {
+      VkStructureType   sType;
+      const  void* pNext;
+      VkFenceCreateFlags       flags;
+   } VkFenceCreateInfo;
+   typedef struct VkPhysicalDeviceFeatures {
+      VkBool32                 robustBufferAccess;
+      VkBool32                 fullDrawIndexUint32;
+      VkBool32                 imageCubeArray;
+      VkBool32                 independentBlend;
+      VkBool32                 geometryShader;
+      VkBool32                 tessellationShader;
+      VkBool32                 sampleRateShading;
+      VkBool32                 dualSrcBlend;
+      VkBool32                 logicOp;
+      VkBool32                 multiDrawIndirect;
+      VkBool32                 drawIndirectFirstInstance;
+      VkBool32                 depthClamp;
+      VkBool32                 depthBiasClamp;
+      VkBool32                 fillModeNonSolid;
+      VkBool32                 depthBounds;
+      VkBool32                 wideLines;
+      VkBool32                 largePoints;
+      VkBool32                 alphaToOne;
+      VkBool32                 multiViewport;
+      VkBool32                 samplerAnisotropy;
+      VkBool32                 textureCompressionETC2;
+      VkBool32                 textureCompressionASTC_LDR;
+      VkBool32                 textureCompressionBC;
+      VkBool32                 occlusionQueryPrecise;
+      VkBool32                 pipelineStatisticsQuery;
+      VkBool32                 vertexPipelineStoresAndAtomics;
+      VkBool32                 fragmentStoresAndAtomics;
+      VkBool32                 shaderTessellationAndGeometryPointSize;
+      VkBool32                 shaderImageGatherExtended;
+      VkBool32                 shaderStorageImageExtendedFormats;
+      VkBool32                 shaderStorageImageMultisample;
+      VkBool32                 shaderStorageImageReadWithoutFormat;
+      VkBool32                 shaderStorageImageWriteWithoutFormat;
+      VkBool32                 shaderUniformBufferArrayDynamicIndexing;
+      VkBool32                 shaderSampledImageArrayDynamicIndexing;
+      VkBool32                 shaderStorageBufferArrayDynamicIndexing;
+      VkBool32                 shaderStorageImageArrayDynamicIndexing;
+      VkBool32                 shaderClipDistance;
+      VkBool32                 shaderCullDistance;
+      VkBool32                 shaderFloat64;
+      VkBool32                 shaderInt64;
+      VkBool32                 shaderInt16;
+      VkBool32                 shaderResourceResidency;
+      VkBool32                 shaderResourceMinLod;
+      VkBool32                 sparseBinding;
+      VkBool32                 sparseResidencyBuffer;
+      VkBool32                 sparseResidencyImage2D;
+      VkBool32                 sparseResidencyImage3D;
+      VkBool32                 sparseResidency2Samples;
+      VkBool32                 sparseResidency4Samples;
+      VkBool32                 sparseResidency8Samples;
+      VkBool32                 sparseResidency16Samples;
+      VkBool32                 sparseResidencyAliased;
+      VkBool32                 variableMultisampleRate;
+      VkBool32                 inheritedQueries;
+   } VkPhysicalDeviceFeatures;
+   typedef struct VkPhysicalDeviceSparseProperties {
+      VkBool32                 residencyStandard2DBlockShape;
+      VkBool32                 residencyStandard2DMultisampleBlockShape;
+      VkBool32                 residencyStandard3DBlockShape;
+      VkBool32                 residencyAlignedMipSize;
+      VkBool32                 residencyNonResidentStrict;
+   } VkPhysicalDeviceSparseProperties;
+   typedef struct VkPhysicalDeviceLimits {
+      uint32_t                 maxImageDimension1D;
+      uint32_t                 maxImageDimension2D;
+      uint32_t                 maxImageDimension3D;
+      uint32_t                 maxImageDimensionCube;
+      uint32_t                 maxImageArrayLayers;
+      uint32_t                 maxTexelBufferElements;
+      uint32_t                 maxUniformBufferRange;
+      uint32_t                 maxStorageBufferRange;
+      uint32_t                 maxPushConstantsSize;
+      uint32_t                 maxMemoryAllocationCount;
+      uint32_t                 maxSamplerAllocationCount;
+      VkDeviceSize             bufferImageGranularity;
+      VkDeviceSize             sparseAddressSpaceSize;
+      uint32_t                 maxBoundDescriptorSets;
+      uint32_t                 maxPerStageDescriptorSamplers;
+      uint32_t                 maxPerStageDescriptorUniformBuffers;
+      uint32_t                 maxPerStageDescriptorStorageBuffers;
+      uint32_t                 maxPerStageDescriptorSampledImages;
+      uint32_t                 maxPerStageDescriptorStorageImages;
+      uint32_t                 maxPerStageDescriptorInputAttachments;
+      uint32_t                 maxPerStageResources;
+      uint32_t                 maxDescriptorSetSamplers;
+      uint32_t                 maxDescriptorSetUniformBuffers;
+      uint32_t                 maxDescriptorSetUniformBuffersDynamic;
+      uint32_t                 maxDescriptorSetStorageBuffers;
+      uint32_t                 maxDescriptorSetStorageBuffersDynamic;
+      uint32_t                 maxDescriptorSetSampledImages;
+      uint32_t                 maxDescriptorSetStorageImages;
+      uint32_t                 maxDescriptorSetInputAttachments;
+      uint32_t                 maxVertexInputAttributes;
+      uint32_t                 maxVertexInputBindings;
+      uint32_t                 maxVertexInputAttributeOffset;
+      uint32_t                 maxVertexInputBindingStride;
+      uint32_t                 maxVertexOutputComponents;
+      uint32_t                 maxTessellationGenerationLevel;
+      uint32_t                 maxTessellationPatchSize;
+      uint32_t                 maxTessellationControlPerVertexInputComponents;
+      uint32_t                 maxTessellationControlPerVertexOutputComponents;
+      uint32_t                 maxTessellationControlPerPatchOutputComponents;
+      uint32_t                 maxTessellationControlTotalOutputComponents;
+      uint32_t                 maxTessellationEvaluationInputComponents;
+      uint32_t                 maxTessellationEvaluationOutputComponents;
+      uint32_t                 maxGeometryShaderInvocations;
+      uint32_t                 maxGeometryInputComponents;
+      uint32_t                 maxGeometryOutputComponents;
+      uint32_t                 maxGeometryOutputVertices;
+      uint32_t                 maxGeometryTotalOutputComponents;
+      uint32_t                 maxFragmentInputComponents;
+      uint32_t                 maxFragmentOutputAttachments;
+      uint32_t                 maxFragmentDualSrcAttachments;
+      uint32_t                 maxFragmentCombinedOutputResources;
+      uint32_t                 maxComputeSharedMemorySize;
+      uint32_t                 maxComputeWorkGroupCount[3];
+      uint32_t                 maxComputeWorkGroupInvocations;
+      uint32_t                 maxComputeWorkGroupSize[3];
+      uint32_t                 subPixelPrecisionBits;
+      uint32_t                 subTexelPrecisionBits;
+      uint32_t                 mipmapPrecisionBits;
+      uint32_t                 maxDrawIndexedIndexValue;
+      uint32_t                 maxDrawIndirectCount;
+      float                    maxSamplerLodBias;
+      float                    maxSamplerAnisotropy;
+      uint32_t                 maxViewports;
+      uint32_t                 maxViewportDimensions[2];
+      float                    viewportBoundsRange[2];
+      uint32_t                 viewportSubPixelBits;
+      size_t                   minMemoryMapAlignment;
+      VkDeviceSize             minTexelBufferOffsetAlignment;
+      VkDeviceSize             minUniformBufferOffsetAlignment;
+      VkDeviceSize             minStorageBufferOffsetAlignment;
+      int32_t                  minTexelOffset;
+      uint32_t                 maxTexelOffset;
+      int32_t                  minTexelGatherOffset;
+      uint32_t                 maxTexelGatherOffset;
+      float                    minInterpolationOffset;
+      float                    maxInterpolationOffset;
+      uint32_t                 subPixelInterpolationOffsetBits;
+      uint32_t                 maxFramebufferWidth;
+      uint32_t                 maxFramebufferHeight;
+      uint32_t                 maxFramebufferLayers;
+      VkSampleCountFlags       framebufferColorSampleCounts;
+      VkSampleCountFlags       framebufferDepthSampleCounts;
+      VkSampleCountFlags       framebufferStencilSampleCounts;
+      VkSampleCountFlags       framebufferNoAttachmentsSampleCounts;
+      uint32_t                 maxColorAttachments;
+      VkSampleCountFlags       sampledImageColorSampleCounts;
+      VkSampleCountFlags       sampledImageIntegerSampleCounts;
+      VkSampleCountFlags       sampledImageDepthSampleCounts;
+      VkSampleCountFlags       sampledImageStencilSampleCounts;
+      VkSampleCountFlags       storageImageSampleCounts;
+      uint32_t                 maxSampleMaskWords;
+      VkBool32                 timestampComputeAndGraphics;
+      float                    timestampPeriod;
+      uint32_t                 maxClipDistances;
+      uint32_t                 maxCullDistances;
+      uint32_t                 maxCombinedClipAndCullDistances;
+      uint32_t                 discreteQueuePriorities;
+      float                    pointSizeRange[2];
+      float                    lineWidthRange[2];
+      float                    pointSizeGranularity;
+      float                    lineWidthGranularity;
+      VkBool32                 strictLines;
+      VkBool32                 standardSampleLocations;
+      VkDeviceSize             optimalBufferCopyOffsetAlignment;
+      VkDeviceSize             optimalBufferCopyRowPitchAlignment;
+      VkDeviceSize             nonCoherentAtomSize;
+   } VkPhysicalDeviceLimits;
+   typedef struct VkSemaphoreCreateInfo {
+      VkStructureType   sType;
+      const  void* pNext;
+      VkSemaphoreCreateFlags   flags;
+   } VkSemaphoreCreateInfo;
+   typedef struct VkQueryPoolCreateInfo {
+      VkStructureType   sType;
+      const  void* pNext;
+      VkQueryPoolCreateFlags   flags;
+      VkQueryType              queryType;
+      uint32_t                 queryCount;
+      VkQueryPipelineStatisticFlags   pipelineStatistics;
+   } VkQueryPoolCreateInfo;
+   typedef struct VkFramebufferCreateInfo {
+      VkStructureType   sType;
+      const  void* pNext;
+      VkFramebufferCreateFlags      flags;
+      VkRenderPass             renderPass;
+      uint32_t                 attachmentCount;
+      const  VkImageView* pAttachments;
+      uint32_t                 width;
+      uint32_t                 height;
+      uint32_t                 layers;
+   } VkFramebufferCreateInfo;
+   typedef struct VkSubmitInfo {
+      VkStructureType   sType;
+      const  void* pNext;
+      uint32_t         waitSemaphoreCount;
+      const  VkSemaphore* pWaitSemaphores;
+      const  VkPipelineStageFlags* pWaitDstStageMask;
+      uint32_t         commandBufferCount;
+      const  VkCommandBuffer* pCommandBuffers;
+      uint32_t         signalSemaphoreCount;
+      const  VkSemaphore* pSignalSemaphores;
+   } VkSubmitInfo;
+   typedef struct VkSurfaceCapabilitiesKHR {
+      uint32_t                           minImageCount;
+      uint32_t                           maxImageCount;
+      VkExtent2D                         currentExtent;
+      VkExtent2D                         minImageExtent;
+      VkExtent2D                         maxImageExtent;
+      uint32_t                           maxImageArrayLayers;
+      VkSurfaceTransformFlagsKHR         supportedTransforms;
+      VkSurfaceTransformFlagBitsKHR      currentTransform;
+      VkCompositeAlphaFlagsKHR           supportedCompositeAlpha;
+      VkImageUsageFlags                  supportedUsageFlags;
+   } VkSurfaceCapabilitiesKHR;
+   typedef struct VkSwapchainCreateInfoKHR {
+      VkStructureType   sType;
+      const  void* pNext;
+      VkSwapchainCreateFlagsKHR          flags;
+      VkSurfaceKHR                       surface;
+      uint32_t                           minImageCount;
+      VkFormat                           imageFormat;
+      VkColorSpaceKHR                    imageColorSpace;
+      VkExtent2D                         imageExtent;
+      uint32_t                           imageArrayLayers;
+      VkImageUsageFlags                  imageUsage;
+      VkSharingMode                      imageSharingMode;
+      uint32_t           queueFamilyIndexCount;
+      const  uint32_t* pQueueFamilyIndices;
+      VkSurfaceTransformFlagBitsKHR      preTransform;
+      VkCompositeAlphaFlagBitsKHR        compositeAlpha;
+      VkPresentModeKHR                   presentMode;
+      VkBool32                           clipped;
+      VkSwapchainKHR     oldSwapchain;
+   } VkSwapchainCreateInfoKHR;
+   typedef struct VkDebugReportCallbackCreateInfoEXT {
+      VkStructureType   sType;
+      const  void* pNext;
+      VkDebugReportFlagsEXT              flags;
+      PFN_vkDebugReportCallbackEXT       pfnCallback;
+      void* pUserData;
+   } VkDebugReportCallbackCreateInfoEXT;
+   typedef struct VkDeviceGroupPresentCapabilitiesKHR {
+      VkStructureType   sType;
+      const  void* pNext;
+      uint32_t                           presentMask[VK_MAX_DEVICE_GROUP_SIZE];
+      VkDeviceGroupPresentModeFlagsKHR   modes;
+   } VkDeviceGroupPresentCapabilitiesKHR;
+   typedef struct VkDeviceGroupSwapchainCreateInfoKHR {
+      VkStructureType   sType;
+      const  void* pNext;
+      VkDeviceGroupPresentModeFlagsKHR                           modes;
+   } VkDeviceGroupSwapchainCreateInfoKHR;
+   typedef struct VkPhysicalDeviceProperties {
+      uint32_t         apiVersion;
+      uint32_t         driverVersion;
+      uint32_t         vendorID;
+      uint32_t         deviceID;
+      VkPhysicalDeviceType   deviceType;
+      char             deviceName[VK_MAX_PHYSICAL_DEVICE_NAME_SIZE];
+      uint8_t          pipelineCacheUUID[VK_UUID_SIZE];
+      VkPhysicalDeviceLimits   limits;
+      VkPhysicalDeviceSparseProperties   sparseProperties;
+   } VkPhysicalDeviceProperties;
+   typedef struct VkDeviceCreateInfo {
+      VkStructureType   sType;
+      const  void* pNext;
+      VkDeviceCreateFlags      flags;
+      uint32_t          queueCreateInfoCount;
+      const  VkDeviceQueueCreateInfo* pQueueCreateInfos;
+      uint32_t                 enabledLayerCount;
+      const  char* const* ppEnabledLayerNames;
+      uint32_t                 enabledExtensionCount;
+      const  char* const* ppEnabledExtensionNames;
+      const  VkPhysicalDeviceFeatures* pEnabledFeatures;
+   } VkDeviceCreateInfo;
+   typedef struct VkPhysicalDeviceMemoryProperties {
+      uint32_t                 memoryTypeCount;
+      VkMemoryType             memoryTypes[VK_MAX_MEMORY_TYPES];
+      uint32_t                 memoryHeapCount;
+      VkMemoryHeap             memoryHeaps[VK_MAX_MEMORY_HEAPS];
+   } VkPhysicalDeviceMemoryProperties;
+
+
+#define VK_VERSION_1_0 1
+   GLAD_API_CALL int GLAD_VK_VERSION_1_0;
+#define VK_EXT_debug_report 1
+   GLAD_API_CALL int GLAD_VK_EXT_debug_report;
+#define VK_KHR_surface 1
+   GLAD_API_CALL int GLAD_VK_KHR_surface;
+#define VK_KHR_swapchain 1
+   GLAD_API_CALL int GLAD_VK_KHR_swapchain;
+
+
+   typedef VkResult(GLAD_API_PTR* PFN_vkAcquireNextImage2KHR)(VkDevice   device, const  VkAcquireNextImageInfoKHR* pAcquireInfo, uint32_t* pImageIndex);
+   typedef VkResult(GLAD_API_PTR* PFN_vkAcquireNextImageKHR)(VkDevice   device, VkSwapchainKHR   swapchain, uint64_t   timeout, VkSemaphore   semaphore, VkFence   fence, uint32_t* pImageIndex);
+   typedef VkResult(GLAD_API_PTR* PFN_vkAllocateCommandBuffers)(VkDevice   device, const  VkCommandBufferAllocateInfo* pAllocateInfo, VkCommandBuffer* pCommandBuffers);
+   typedef VkResult(GLAD_API_PTR* PFN_vkAllocateDescriptorSets)(VkDevice   device, const  VkDescriptorSetAllocateInfo* pAllocateInfo, VkDescriptorSet* pDescriptorSets);
+   typedef VkResult(GLAD_API_PTR* PFN_vkAllocateMemory)(VkDevice   device, const  VkMemoryAllocateInfo* pAllocateInfo, const  VkAllocationCallbacks* pAllocator, VkDeviceMemory* pMemory);
+   typedef VkResult(GLAD_API_PTR* PFN_vkBeginCommandBuffer)(VkCommandBuffer   commandBuffer, const  VkCommandBufferBeginInfo* pBeginInfo);
+   typedef VkResult(GLAD_API_PTR* PFN_vkBindBufferMemory)(VkDevice   device, VkBuffer   buffer, VkDeviceMemory   memory, VkDeviceSize   memoryOffset);
+   typedef VkResult(GLAD_API_PTR* PFN_vkBindImageMemory)(VkDevice   device, VkImage   image, VkDeviceMemory   memory, VkDeviceSize   memoryOffset);
+   typedef void (GLAD_API_PTR* PFN_vkCmdBeginQuery)(VkCommandBuffer   commandBuffer, VkQueryPool   queryPool, uint32_t   query, VkQueryControlFlags   flags);
+   typedef void (GLAD_API_PTR* PFN_vkCmdBeginRenderPass)(VkCommandBuffer   commandBuffer, const  VkRenderPassBeginInfo* pRenderPassBegin, VkSubpassContents   contents);
+   typedef void (GLAD_API_PTR* PFN_vkCmdBindDescriptorSets)(VkCommandBuffer   commandBuffer, VkPipelineBindPoint   pipelineBindPoint, VkPipelineLayout   layout, uint32_t   firstSet, uint32_t   descriptorSetCount, const  VkDescriptorSet* pDescriptorSets, uint32_t   dynamicOffsetCount, const  uint32_t* pDynamicOffsets);
+   typedef void (GLAD_API_PTR* PFN_vkCmdBindIndexBuffer)(VkCommandBuffer   commandBuffer, VkBuffer   buffer, VkDeviceSize   offset, VkIndexType   indexType);
+   typedef void (GLAD_API_PTR* PFN_vkCmdBindPipeline)(VkCommandBuffer   commandBuffer, VkPipelineBindPoint   pipelineBindPoint, VkPipeline   pipeline);
+   typedef void (GLAD_API_PTR* PFN_vkCmdBindVertexBuffers)(VkCommandBuffer   commandBuffer, uint32_t   firstBinding, uint32_t   bindingCount, const  VkBuffer* pBuffers, const  VkDeviceSize* pOffsets);
+   typedef void (GLAD_API_PTR* PFN_vkCmdBlitImage)(VkCommandBuffer   commandBuffer, VkImage   srcImage, VkImageLayout   srcImageLayout, VkImage   dstImage, VkImageLayout   dstImageLayout, uint32_t   regionCount, const  VkImageBlit* pRegions, VkFilter   filter);
+   typedef void (GLAD_API_PTR* PFN_vkCmdClearAttachments)(VkCommandBuffer   commandBuffer, uint32_t   attachmentCount, const  VkClearAttachment* pAttachments, uint32_t   rectCount, const  VkClearRect* pRects);
+   typedef void (GLAD_API_PTR* PFN_vkCmdClearColorImage)(VkCommandBuffer   commandBuffer, VkImage   image, VkImageLayout   imageLayout, const  VkClearColorValue* pColor, uint32_t   rangeCount, const  VkImageSubresourceRange* pRanges);
+   typedef void (GLAD_API_PTR* PFN_vkCmdClearDepthStencilImage)(VkCommandBuffer   commandBuffer, VkImage   image, VkImageLayout   imageLayout, const  VkClearDepthStencilValue* pDepthStencil, uint32_t   rangeCount, const  VkImageSubresourceRange* pRanges);
+   typedef void (GLAD_API_PTR* PFN_vkCmdCopyBuffer)(VkCommandBuffer   commandBuffer, VkBuffer   srcBuffer, VkBuffer   dstBuffer, uint32_t   regionCount, const  VkBufferCopy* pRegions);
+   typedef void (GLAD_API_PTR* PFN_vkCmdCopyBufferToImage)(VkCommandBuffer   commandBuffer, VkBuffer   srcBuffer, VkImage   dstImage, VkImageLayout   dstImageLayout, uint32_t   regionCount, const  VkBufferImageCopy* pRegions);
+   typedef void (GLAD_API_PTR* PFN_vkCmdCopyImage)(VkCommandBuffer   commandBuffer, VkImage   srcImage, VkImageLayout   srcImageLayout, VkImage   dstImage, VkImageLayout   dstImageLayout, uint32_t   regionCount, const  VkImageCopy* pRegions);
+   typedef void (GLAD_API_PTR* PFN_vkCmdCopyImageToBuffer)(VkCommandBuffer   commandBuffer, VkImage   srcImage, VkImageLayout   srcImageLayout, VkBuffer   dstBuffer, uint32_t   regionCount, const  VkBufferImageCopy* pRegions);
+   typedef void (GLAD_API_PTR* PFN_vkCmdCopyQueryPoolResults)(VkCommandBuffer   commandBuffer, VkQueryPool   queryPool, uint32_t   firstQuery, uint32_t   queryCount, VkBuffer   dstBuffer, VkDeviceSize   dstOffset, VkDeviceSize   stride, VkQueryResultFlags   flags);
+   typedef void (GLAD_API_PTR* PFN_vkCmdDispatch)(VkCommandBuffer   commandBuffer, uint32_t   groupCountX, uint32_t   groupCountY, uint32_t   groupCountZ);
+   typedef void (GLAD_API_PTR* PFN_vkCmdDispatchIndirect)(VkCommandBuffer   commandBuffer, VkBuffer   buffer, VkDeviceSize   offset);
+   typedef void (GLAD_API_PTR* PFN_vkCmdDraw)(VkCommandBuffer   commandBuffer, uint32_t   vertexCount, uint32_t   instanceCount, uint32_t   firstVertex, uint32_t   firstInstance);
+   typedef void (GLAD_API_PTR* PFN_vkCmdDrawIndexed)(VkCommandBuffer   commandBuffer, uint32_t   indexCount, uint32_t   instanceCount, uint32_t   firstIndex, int32_t   vertexOffset, uint32_t   firstInstance);
+   typedef void (GLAD_API_PTR* PFN_vkCmdDrawIndexedIndirect)(VkCommandBuffer   commandBuffer, VkBuffer   buffer, VkDeviceSize   offset, uint32_t   drawCount, uint32_t   stride);
+   typedef void (GLAD_API_PTR* PFN_vkCmdDrawIndirect)(VkCommandBuffer   commandBuffer, VkBuffer   buffer, VkDeviceSize   offset, uint32_t   drawCount, uint32_t   stride);
+   typedef void (GLAD_API_PTR* PFN_vkCmdEndQuery)(VkCommandBuffer   commandBuffer, VkQueryPool   queryPool, uint32_t   query);
+   typedef void (GLAD_API_PTR* PFN_vkCmdEndRenderPass)(VkCommandBuffer   commandBuffer);
+   typedef void (GLAD_API_PTR* PFN_vkCmdExecuteCommands)(VkCommandBuffer   commandBuffer, uint32_t   commandBufferCount, const  VkCommandBuffer* pCommandBuffers);
+   typedef void (GLAD_API_PTR* PFN_vkCmdFillBuffer)(VkCommandBuffer   commandBuffer, VkBuffer   dstBuffer, VkDeviceSize   dstOffset, VkDeviceSize   size, uint32_t   data);
+   typedef void (GLAD_API_PTR* PFN_vkCmdNextSubpass)(VkCommandBuffer   commandBuffer, VkSubpassContents   contents);
+   typedef void (GLAD_API_PTR* PFN_vkCmdPipelineBarrier)(VkCommandBuffer   commandBuffer, VkPipelineStageFlags   srcStageMask, VkPipelineStageFlags   dstStageMask, VkDependencyFlags   dependencyFlags, uint32_t   memoryBarrierCount, const  VkMemoryBarrier* pMemoryBarriers, uint32_t   bufferMemoryBarrierCount, const  VkBufferMemoryBarrier* pBufferMemoryBarriers, uint32_t   imageMemoryBarrierCount, const  VkImageMemoryBarrier* pImageMemoryBarriers);
+   typedef void (GLAD_API_PTR* PFN_vkCmdPushConstants)(VkCommandBuffer   commandBuffer, VkPipelineLayout   layout, VkShaderStageFlags   stageFlags, uint32_t   offset, uint32_t   size, const  void* pValues);
+   typedef void (GLAD_API_PTR* PFN_vkCmdResetEvent)(VkCommandBuffer   commandBuffer, VkEvent   event, VkPipelineStageFlags   stageMask);
+   typedef void (GLAD_API_PTR* PFN_vkCmdResetQueryPool)(VkCommandBuffer   commandBuffer, VkQueryPool   queryPool, uint32_t   firstQuery, uint32_t   queryCount);
+   typedef void (GLAD_API_PTR* PFN_vkCmdResolveImage)(VkCommandBuffer   commandBuffer, VkImage   srcImage, VkImageLayout   srcImageLayout, VkImage   dstImage, VkImageLayout   dstImageLayout, uint32_t   regionCount, const  VkImageResolve* pRegions);
+   typedef void (GLAD_API_PTR* PFN_vkCmdSetBlendConstants)(VkCommandBuffer   commandBuffer, const  float   blendConstants[4]);
+   typedef void (GLAD_API_PTR* PFN_vkCmdSetDepthBias)(VkCommandBuffer   commandBuffer, float   depthBiasConstantFactor, float   depthBiasClamp, float   depthBiasSlopeFactor);
+   typedef void (GLAD_API_PTR* PFN_vkCmdSetDepthBounds)(VkCommandBuffer   commandBuffer, float   minDepthBounds, float   maxDepthBounds);
+   typedef void (GLAD_API_PTR* PFN_vkCmdSetEvent)(VkCommandBuffer   commandBuffer, VkEvent   event, VkPipelineStageFlags   stageMask);
+   typedef void (GLAD_API_PTR* PFN_vkCmdSetLineWidth)(VkCommandBuffer   commandBuffer, float   lineWidth);
+   typedef void (GLAD_API_PTR* PFN_vkCmdSetScissor)(VkCommandBuffer   commandBuffer, uint32_t   firstScissor, uint32_t   scissorCount, const  VkRect2D* pScissors);
+   typedef void (GLAD_API_PTR* PFN_vkCmdSetStencilCompareMask)(VkCommandBuffer   commandBuffer, VkStencilFaceFlags   faceMask, uint32_t   compareMask);
+   typedef void (GLAD_API_PTR* PFN_vkCmdSetStencilReference)(VkCommandBuffer   commandBuffer, VkStencilFaceFlags   faceMask, uint32_t   reference);
+   typedef void (GLAD_API_PTR* PFN_vkCmdSetStencilWriteMask)(VkCommandBuffer   commandBuffer, VkStencilFaceFlags   faceMask, uint32_t   writeMask);
+   typedef void (GLAD_API_PTR* PFN_vkCmdSetViewport)(VkCommandBuffer   commandBuffer, uint32_t   firstViewport, uint32_t   viewportCount, const  VkViewport* pViewports);
+   typedef void (GLAD_API_PTR* PFN_vkCmdUpdateBuffer)(VkCommandBuffer   commandBuffer, VkBuffer   dstBuffer, VkDeviceSize   dstOffset, VkDeviceSize   dataSize, const  void* pData);
+   typedef void (GLAD_API_PTR* PFN_vkCmdWaitEvents)(VkCommandBuffer   commandBuffer, uint32_t   eventCount, const  VkEvent* pEvents, VkPipelineStageFlags   srcStageMask, VkPipelineStageFlags   dstStageMask, uint32_t   memoryBarrierCount, const  VkMemoryBarrier* pMemoryBarriers, uint32_t   bufferMemoryBarrierCount, const  VkBufferMemoryBarrier* pBufferMemoryBarriers, uint32_t   imageMemoryBarrierCount, const  VkImageMemoryBarrier* pImageMemoryBarriers);
+   typedef void (GLAD_API_PTR* PFN_vkCmdWriteTimestamp)(VkCommandBuffer   commandBuffer, VkPipelineStageFlagBits   pipelineStage, VkQueryPool   queryPool, uint32_t   query);
+   typedef VkResult(GLAD_API_PTR* PFN_vkCreateBuffer)(VkDevice   device, const  VkBufferCreateInfo* pCreateInfo, const  VkAllocationCallbacks* pAllocator, VkBuffer* pBuffer);
+   typedef VkResult(GLAD_API_PTR* PFN_vkCreateBufferView)(VkDevice   device, const  VkBufferViewCreateInfo* pCreateInfo, const  VkAllocationCallbacks* pAllocator, VkBufferView* pView);
+   typedef VkResult(GLAD_API_PTR* PFN_vkCreateCommandPool)(VkDevice   device, const  VkCommandPoolCreateInfo* pCreateInfo, const  VkAllocationCallbacks* pAllocator, VkCommandPool* pCommandPool);
+   typedef VkResult(GLAD_API_PTR* PFN_vkCreateComputePipelines)(VkDevice   device, VkPipelineCache   pipelineCache, uint32_t   createInfoCount, const  VkComputePipelineCreateInfo* pCreateInfos, const  VkAllocationCallbacks* pAllocator, VkPipeline* pPipelines);
+   typedef VkResult(GLAD_API_PTR* PFN_vkCreateDebugReportCallbackEXT)(VkInstance   instance, const  VkDebugReportCallbackCreateInfoEXT* pCreateInfo, const  VkAllocationCallbacks* pAllocator, VkDebugReportCallbackEXT* pCallback);
+   typedef VkResult(GLAD_API_PTR* PFN_vkCreateDescriptorPool)(VkDevice   device, const  VkDescriptorPoolCreateInfo* pCreateInfo, const  VkAllocationCallbacks* pAllocator, VkDescriptorPool* pDescriptorPool);
+   typedef VkResult(GLAD_API_PTR* PFN_vkCreateDescriptorSetLayout)(VkDevice   device, const  VkDescriptorSetLayoutCreateInfo* pCreateInfo, const  VkAllocationCallbacks* pAllocator, VkDescriptorSetLayout* pSetLayout);
+   typedef VkResult(GLAD_API_PTR* PFN_vkCreateDevice)(VkPhysicalDevice   physicalDevice, const  VkDeviceCreateInfo* pCreateInfo, const  VkAllocationCallbacks* pAllocator, VkDevice* pDevice);
+   typedef VkResult(GLAD_API_PTR* PFN_vkCreateEvent)(VkDevice   device, const  VkEventCreateInfo* pCreateInfo, const  VkAllocationCallbacks* pAllocator, VkEvent* pEvent);
+   typedef VkResult(GLAD_API_PTR* PFN_vkCreateFence)(VkDevice   device, const  VkFenceCreateInfo* pCreateInfo, const  VkAllocationCallbacks* pAllocator, VkFence* pFence);
+   typedef VkResult(GLAD_API_PTR* PFN_vkCreateFramebuffer)(VkDevice   device, const  VkFramebufferCreateInfo* pCreateInfo, const  VkAllocationCallbacks* pAllocator, VkFramebuffer* pFramebuffer);
+   typedef VkResult(GLAD_API_PTR* PFN_vkCreateGraphicsPipelines)(VkDevice   device, VkPipelineCache   pipelineCache, uint32_t   createInfoCount, const  VkGraphicsPipelineCreateInfo* pCreateInfos, const  VkAllocationCallbacks* pAllocator, VkPipeline* pPipelines);
+   typedef VkResult(GLAD_API_PTR* PFN_vkCreateImage)(VkDevice   device, const  VkImageCreateInfo* pCreateInfo, const  VkAllocationCallbacks* pAllocator, VkImage* pImage);
+   typedef VkResult(GLAD_API_PTR* PFN_vkCreateImageView)(VkDevice   device, const  VkImageViewCreateInfo* pCreateInfo, const  VkAllocationCallbacks* pAllocator, VkImageView* pView);
+   typedef VkResult(GLAD_API_PTR* PFN_vkCreateInstance)(const  VkInstanceCreateInfo* pCreateInfo, const  VkAllocationCallbacks* pAllocator, VkInstance* pInstance);
+   typedef VkResult(GLAD_API_PTR* PFN_vkCreatePipelineCache)(VkDevice   device, const  VkPipelineCacheCreateInfo* pCreateInfo, const  VkAllocationCallbacks* pAllocator, VkPipelineCache* pPipelineCache);
+   typedef VkResult(GLAD_API_PTR* PFN_vkCreatePipelineLayout)(VkDevice   device, const  VkPipelineLayoutCreateInfo* pCreateInfo, const  VkAllocationCallbacks* pAllocator, VkPipelineLayout* pPipelineLayout);
+   typedef VkResult(GLAD_API_PTR* PFN_vkCreateQueryPool)(VkDevice   device, const  VkQueryPoolCreateInfo* pCreateInfo, const  VkAllocationCallbacks* pAllocator, VkQueryPool* pQueryPool);
+   typedef VkResult(GLAD_API_PTR* PFN_vkCreateRenderPass)(VkDevice   device, const  VkRenderPassCreateInfo* pCreateInfo, const  VkAllocationCallbacks* pAllocator, VkRenderPass* pRenderPass);
+   typedef VkResult(GLAD_API_PTR* PFN_vkCreateSampler)(VkDevice   device, const  VkSamplerCreateInfo* pCreateInfo, const  VkAllocationCallbacks* pAllocator, VkSampler* pSampler);
+   typedef VkResult(GLAD_API_PTR* PFN_vkCreateSemaphore)(VkDevice   device, const  VkSemaphoreCreateInfo* pCreateInfo, const  VkAllocationCallbacks* pAllocator, VkSemaphore* pSemaphore);
+   typedef VkResult(GLAD_API_PTR* PFN_vkCreateShaderModule)(VkDevice   device, const  VkShaderModuleCreateInfo* pCreateInfo, const  VkAllocationCallbacks* pAllocator, VkShaderModule* pShaderModule);
+   typedef VkResult(GLAD_API_PTR* PFN_vkCreateSwapchainKHR)(VkDevice   device, const  VkSwapchainCreateInfoKHR* pCreateInfo, const  VkAllocationCallbacks* pAllocator, VkSwapchainKHR* pSwapchain);
+   typedef void (GLAD_API_PTR* PFN_vkDebugReportMessageEXT)(VkInstance   instance, VkDebugReportFlagsEXT   flags, VkDebugReportObjectTypeEXT   objectType, uint64_t   object, size_t   location, int32_t   messageCode, const  char* pLayerPrefix, const  char* pMessage);
+   typedef void (GLAD_API_PTR* PFN_vkDestroyBuffer)(VkDevice   device, VkBuffer   buffer, const  VkAllocationCallbacks* pAllocator);
+   typedef void (GLAD_API_PTR* PFN_vkDestroyBufferView)(VkDevice   device, VkBufferView   bufferView, const  VkAllocationCallbacks* pAllocator);
+   typedef void (GLAD_API_PTR* PFN_vkDestroyCommandPool)(VkDevice   device, VkCommandPool   commandPool, const  VkAllocationCallbacks* pAllocator);
+   typedef void (GLAD_API_PTR* PFN_vkDestroyDebugReportCallbackEXT)(VkInstance   instance, VkDebugReportCallbackEXT   callback, const  VkAllocationCallbacks* pAllocator);
+   typedef void (GLAD_API_PTR* PFN_vkDestroyDescriptorPool)(VkDevice   device, VkDescriptorPool   descriptorPool, const  VkAllocationCallbacks* pAllocator);
+   typedef void (GLAD_API_PTR* PFN_vkDestroyDescriptorSetLayout)(VkDevice   device, VkDescriptorSetLayout   descriptorSetLayout, const  VkAllocationCallbacks* pAllocator);
+   typedef void (GLAD_API_PTR* PFN_vkDestroyDevice)(VkDevice   device, const  VkAllocationCallbacks* pAllocator);
+   typedef void (GLAD_API_PTR* PFN_vkDestroyEvent)(VkDevice   device, VkEvent   event, const  VkAllocationCallbacks* pAllocator);
+   typedef void (GLAD_API_PTR* PFN_vkDestroyFence)(VkDevice   device, VkFence   fence, const  VkAllocationCallbacks* pAllocator);
+   typedef void (GLAD_API_PTR* PFN_vkDestroyFramebuffer)(VkDevice   device, VkFramebuffer   framebuffer, const  VkAllocationCallbacks* pAllocator);
+   typedef void (GLAD_API_PTR* PFN_vkDestroyImage)(VkDevice   device, VkImage   image, const  VkAllocationCallbacks* pAllocator);
+   typedef void (GLAD_API_PTR* PFN_vkDestroyImageView)(VkDevice   device, VkImageView   imageView, const  VkAllocationCallbacks* pAllocator);
+   typedef void (GLAD_API_PTR* PFN_vkDestroyInstance)(VkInstance   instance, const  VkAllocationCallbacks* pAllocator);
+   typedef void (GLAD_API_PTR* PFN_vkDestroyPipeline)(VkDevice   device, VkPipeline   pipeline, const  VkAllocationCallbacks* pAllocator);
+   typedef void (GLAD_API_PTR* PFN_vkDestroyPipelineCache)(VkDevice   device, VkPipelineCache   pipelineCache, const  VkAllocationCallbacks* pAllocator);
+   typedef void (GLAD_API_PTR* PFN_vkDestroyPipelineLayout)(VkDevice   device, VkPipelineLayout   pipelineLayout, const  VkAllocationCallbacks* pAllocator);
+   typedef void (GLAD_API_PTR* PFN_vkDestroyQueryPool)(VkDevice   device, VkQueryPool   queryPool, const  VkAllocationCallbacks* pAllocator);
+   typedef void (GLAD_API_PTR* PFN_vkDestroyRenderPass)(VkDevice   device, VkRenderPass   renderPass, const  VkAllocationCallbacks* pAllocator);
+   typedef void (GLAD_API_PTR* PFN_vkDestroySampler)(VkDevice   device, VkSampler   sampler, const  VkAllocationCallbacks* pAllocator);
+   typedef void (GLAD_API_PTR* PFN_vkDestroySemaphore)(VkDevice   device, VkSemaphore   semaphore, const  VkAllocationCallbacks* pAllocator);
+   typedef void (GLAD_API_PTR* PFN_vkDestroyShaderModule)(VkDevice   device, VkShaderModule   shaderModule, const  VkAllocationCallbacks* pAllocator);
+   typedef void (GLAD_API_PTR* PFN_vkDestroySurfaceKHR)(VkInstance   instance, VkSurfaceKHR   surface, const  VkAllocationCallbacks* pAllocator);
+   typedef void (GLAD_API_PTR* PFN_vkDestroySwapchainKHR)(VkDevice   device, VkSwapchainKHR   swapchain, const  VkAllocationCallbacks* pAllocator);
+   typedef VkResult(GLAD_API_PTR* PFN_vkDeviceWaitIdle)(VkDevice   device);
+   typedef VkResult(GLAD_API_PTR* PFN_vkEndCommandBuffer)(VkCommandBuffer   commandBuffer);
+   typedef VkResult(GLAD_API_PTR* PFN_vkEnumerateDeviceExtensionProperties)(VkPhysicalDevice   physicalDevice, const  char* pLayerName, uint32_t* pPropertyCount, VkExtensionProperties* pProperties);
+   typedef VkResult(GLAD_API_PTR* PFN_vkEnumerateDeviceLayerProperties)(VkPhysicalDevice   physicalDevice, uint32_t* pPropertyCount, VkLayerProperties* pProperties);
+   typedef VkResult(GLAD_API_PTR* PFN_vkEnumerateInstanceExtensionProperties)(const  char* pLayerName, uint32_t* pPropertyCount, VkExtensionProperties* pProperties);
+   typedef VkResult(GLAD_API_PTR* PFN_vkEnumerateInstanceLayerProperties)(uint32_t* pPropertyCount, VkLayerProperties* pProperties);
+   typedef VkResult(GLAD_API_PTR* PFN_vkEnumeratePhysicalDevices)(VkInstance   instance, uint32_t* pPhysicalDeviceCount, VkPhysicalDevice* pPhysicalDevices);
+   typedef VkResult(GLAD_API_PTR* PFN_vkFlushMappedMemoryRanges)(VkDevice   device, uint32_t   memoryRangeCount, const  VkMappedMemoryRange* pMemoryRanges);
+   typedef void (GLAD_API_PTR* PFN_vkFreeCommandBuffers)(VkDevice   device, VkCommandPool   commandPool, uint32_t   commandBufferCount, const  VkCommandBuffer* pCommandBuffers);
+   typedef VkResult(GLAD_API_PTR* PFN_vkFreeDescriptorSets)(VkDevice   device, VkDescriptorPool   descriptorPool, uint32_t   descriptorSetCount, const  VkDescriptorSet* pDescriptorSets);
+   typedef void (GLAD_API_PTR* PFN_vkFreeMemory)(VkDevice   device, VkDeviceMemory   memory, const  VkAllocationCallbacks* pAllocator);
+   typedef void (GLAD_API_PTR* PFN_vkGetBufferMemoryRequirements)(VkDevice   device, VkBuffer   buffer, VkMemoryRequirements* pMemoryRequirements);
+   typedef VkResult(GLAD_API_PTR* PFN_vkGetDeviceGroupPresentCapabilitiesKHR)(VkDevice   device, VkDeviceGroupPresentCapabilitiesKHR* pDeviceGroupPresentCapabilities);
+   typedef VkResult(GLAD_API_PTR* PFN_vkGetDeviceGroupSurfacePresentModesKHR)(VkDevice   device, VkSurfaceKHR   surface, VkDeviceGroupPresentModeFlagsKHR* pModes);
+   typedef void (GLAD_API_PTR* PFN_vkGetDeviceMemoryCommitment)(VkDevice   device, VkDeviceMemory   memory, VkDeviceSize* pCommittedMemoryInBytes);
+   typedef PFN_vkVoidFunction(GLAD_API_PTR* PFN_vkGetDeviceProcAddr)(VkDevice   device, const  char* pName);
+   typedef void (GLAD_API_PTR* PFN_vkGetDeviceQueue)(VkDevice   device, uint32_t   queueFamilyIndex, uint32_t   queueIndex, VkQueue* pQueue);
+   typedef VkResult(GLAD_API_PTR* PFN_vkGetEventStatus)(VkDevice   device, VkEvent   event);
+   typedef VkResult(GLAD_API_PTR* PFN_vkGetFenceStatus)(VkDevice   device, VkFence   fence);
+   typedef void (GLAD_API_PTR* PFN_vkGetImageMemoryRequirements)(VkDevice   device, VkImage   image, VkMemoryRequirements* pMemoryRequirements);
+   typedef void (GLAD_API_PTR* PFN_vkGetImageSparseMemoryRequirements)(VkDevice   device, VkImage   image, uint32_t* pSparseMemoryRequirementCount, VkSparseImageMemoryRequirements* pSparseMemoryRequirements);
+   typedef void (GLAD_API_PTR* PFN_vkGetImageSubresourceLayout)(VkDevice   device, VkImage   image, const  VkImageSubresource* pSubresource, VkSubresourceLayout* pLayout);
+   typedef PFN_vkVoidFunction(GLAD_API_PTR* PFN_vkGetInstanceProcAddr)(VkInstance   instance, const  char* pName);
+   typedef void (GLAD_API_PTR* PFN_vkGetPhysicalDeviceFeatures)(VkPhysicalDevice   physicalDevice, VkPhysicalDeviceFeatures* pFeatures);
+   typedef void (GLAD_API_PTR* PFN_vkGetPhysicalDeviceFormatProperties)(VkPhysicalDevice   physicalDevice, VkFormat   format, VkFormatProperties* pFormatProperties);
+   typedef VkResult(GLAD_API_PTR* PFN_vkGetPhysicalDeviceImageFormatProperties)(VkPhysicalDevice   physicalDevice, VkFormat   format, VkImageType   type, VkImageTiling   tiling, VkImageUsageFlags   usage, VkImageCreateFlags   flags, VkImageFormatProperties* pImageFormatProperties);
+   typedef void (GLAD_API_PTR* PFN_vkGetPhysicalDeviceMemoryProperties)(VkPhysicalDevice   physicalDevice, VkPhysicalDeviceMemoryProperties* pMemoryProperties);
+   typedef VkResult(GLAD_API_PTR* PFN_vkGetPhysicalDevicePresentRectanglesKHR)(VkPhysicalDevice   physicalDevice, VkSurfaceKHR   surface, uint32_t* pRectCount, VkRect2D* pRects);
+   typedef void (GLAD_API_PTR* PFN_vkGetPhysicalDeviceProperties)(VkPhysicalDevice   physicalDevice, VkPhysicalDeviceProperties* pProperties);
+   typedef void (GLAD_API_PTR* PFN_vkGetPhysicalDeviceQueueFamilyProperties)(VkPhysicalDevice   physicalDevice, uint32_t* pQueueFamilyPropertyCount, VkQueueFamilyProperties* pQueueFamilyProperties);
+   typedef void (GLAD_API_PTR* PFN_vkGetPhysicalDeviceSparseImageFormatProperties)(VkPhysicalDevice   physicalDevice, VkFormat   format, VkImageType   type, VkSampleCountFlagBits   samples, VkImageUsageFlags   usage, VkImageTiling   tiling, uint32_t* pPropertyCount, VkSparseImageFormatProperties* pProperties);
+   typedef VkResult(GLAD_API_PTR* PFN_vkGetPhysicalDeviceSurfaceCapabilitiesKHR)(VkPhysicalDevice   physicalDevice, VkSurfaceKHR   surface, VkSurfaceCapabilitiesKHR* pSurfaceCapabilities);
+   typedef VkResult(GLAD_API_PTR* PFN_vkGetPhysicalDeviceSurfaceFormatsKHR)(VkPhysicalDevice   physicalDevice, VkSurfaceKHR   surface, uint32_t* pSurfaceFormatCount, VkSurfaceFormatKHR* pSurfaceFormats);
+   typedef VkResult(GLAD_API_PTR* PFN_vkGetPhysicalDeviceSurfacePresentModesKHR)(VkPhysicalDevice   physicalDevice, VkSurfaceKHR   surface, uint32_t* pPresentModeCount, VkPresentModeKHR* pPresentModes);
+   typedef VkResult(GLAD_API_PTR* PFN_vkGetPhysicalDeviceSurfaceSupportKHR)(VkPhysicalDevice   physicalDevice, uint32_t   queueFamilyIndex, VkSurfaceKHR   surface, VkBool32* pSupported);
+   typedef VkResult(GLAD_API_PTR* PFN_vkGetPipelineCacheData)(VkDevice   device, VkPipelineCache   pipelineCache, size_t* pDataSize, void* pData);
+   typedef VkResult(GLAD_API_PTR* PFN_vkGetQueryPoolResults)(VkDevice   device, VkQueryPool   queryPool, uint32_t   firstQuery, uint32_t   queryCount, size_t   dataSize, void* pData, VkDeviceSize   stride, VkQueryResultFlags   flags);
+   typedef void (GLAD_API_PTR* PFN_vkGetRenderAreaGranularity)(VkDevice   device, VkRenderPass   renderPass, VkExtent2D* pGranularity);
+   typedef VkResult(GLAD_API_PTR* PFN_vkGetSwapchainImagesKHR)(VkDevice   device, VkSwapchainKHR   swapchain, uint32_t* pSwapchainImageCount, VkImage* pSwapchainImages);
+   typedef VkResult(GLAD_API_PTR* PFN_vkInvalidateMappedMemoryRanges)(VkDevice   device, uint32_t   memoryRangeCount, const  VkMappedMemoryRange* pMemoryRanges);
+   typedef VkResult(GLAD_API_PTR* PFN_vkMapMemory)(VkDevice   device, VkDeviceMemory   memory, VkDeviceSize   offset, VkDeviceSize   size, VkMemoryMapFlags   flags, void** ppData);
+   typedef VkResult(GLAD_API_PTR* PFN_vkMergePipelineCaches)(VkDevice   device, VkPipelineCache   dstCache, uint32_t   srcCacheCount, const  VkPipelineCache* pSrcCaches);
+   typedef VkResult(GLAD_API_PTR* PFN_vkQueueBindSparse)(VkQueue   queue, uint32_t   bindInfoCount, const  VkBindSparseInfo* pBindInfo, VkFence   fence);
+   typedef VkResult(GLAD_API_PTR* PFN_vkQueuePresentKHR)(VkQueue   queue, const  VkPresentInfoKHR* pPresentInfo);
+   typedef VkResult(GLAD_API_PTR* PFN_vkQueueSubmit)(VkQueue   queue, uint32_t   submitCount, const  VkSubmitInfo* pSubmits, VkFence   fence);
+   typedef VkResult(GLAD_API_PTR* PFN_vkQueueWaitIdle)(VkQueue   queue);
+   typedef VkResult(GLAD_API_PTR* PFN_vkResetCommandBuffer)(VkCommandBuffer   commandBuffer, VkCommandBufferResetFlags   flags);
+   typedef VkResult(GLAD_API_PTR* PFN_vkResetCommandPool)(VkDevice   device, VkCommandPool   commandPool, VkCommandPoolResetFlags   flags);
+   typedef VkResult(GLAD_API_PTR* PFN_vkResetDescriptorPool)(VkDevice   device, VkDescriptorPool   descriptorPool, VkDescriptorPoolResetFlags   flags);
+   typedef VkResult(GLAD_API_PTR* PFN_vkResetEvent)(VkDevice   device, VkEvent   event);
+   typedef VkResult(GLAD_API_PTR* PFN_vkResetFences)(VkDevice   device, uint32_t   fenceCount, const  VkFence* pFences);
+   typedef VkResult(GLAD_API_PTR* PFN_vkSetEvent)(VkDevice   device, VkEvent   event);
+   typedef void (GLAD_API_PTR* PFN_vkUnmapMemory)(VkDevice   device, VkDeviceMemory   memory);
+   typedef void (GLAD_API_PTR* PFN_vkUpdateDescriptorSets)(VkDevice   device, uint32_t   descriptorWriteCount, const  VkWriteDescriptorSet* pDescriptorWrites, uint32_t   descriptorCopyCount, const  VkCopyDescriptorSet* pDescriptorCopies);
+   typedef VkResult(GLAD_API_PTR* PFN_vkWaitForFences)(VkDevice   device, uint32_t   fenceCount, const  VkFence* pFences, VkBool32   waitAll, uint64_t   timeout);
+
+   GLAD_API_CALL PFN_vkAcquireNextImage2KHR glad_vkAcquireNextImage2KHR;
+#define vkAcquireNextImage2KHR glad_vkAcquireNextImage2KHR
+   GLAD_API_CALL PFN_vkAcquireNextImageKHR glad_vkAcquireNextImageKHR;
+#define vkAcquireNextImageKHR glad_vkAcquireNextImageKHR
+   GLAD_API_CALL PFN_vkAllocateCommandBuffers glad_vkAllocateCommandBuffers;
+#define vkAllocateCommandBuffers glad_vkAllocateCommandBuffers
+   GLAD_API_CALL PFN_vkAllocateDescriptorSets glad_vkAllocateDescriptorSets;
+#define vkAllocateDescriptorSets glad_vkAllocateDescriptorSets
+   GLAD_API_CALL PFN_vkAllocateMemory glad_vkAllocateMemory;
+#define vkAllocateMemory glad_vkAllocateMemory
+   GLAD_API_CALL PFN_vkBeginCommandBuffer glad_vkBeginCommandBuffer;
+#define vkBeginCommandBuffer glad_vkBeginCommandBuffer
+   GLAD_API_CALL PFN_vkBindBufferMemory glad_vkBindBufferMemory;
+#define vkBindBufferMemory glad_vkBindBufferMemory
+   GLAD_API_CALL PFN_vkBindImageMemory glad_vkBindImageMemory;
+#define vkBindImageMemory glad_vkBindImageMemory
+   GLAD_API_CALL PFN_vkCmdBeginQuery glad_vkCmdBeginQuery;
+#define vkCmdBeginQuery glad_vkCmdBeginQuery
+   GLAD_API_CALL PFN_vkCmdBeginRenderPass glad_vkCmdBeginRenderPass;
+#define vkCmdBeginRenderPass glad_vkCmdBeginRenderPass
+   GLAD_API_CALL PFN_vkCmdBindDescriptorSets glad_vkCmdBindDescriptorSets;
+#define vkCmdBindDescriptorSets glad_vkCmdBindDescriptorSets
+   GLAD_API_CALL PFN_vkCmdBindIndexBuffer glad_vkCmdBindIndexBuffer;
+#define vkCmdBindIndexBuffer glad_vkCmdBindIndexBuffer
+   GLAD_API_CALL PFN_vkCmdBindPipeline glad_vkCmdBindPipeline;
+#define vkCmdBindPipeline glad_vkCmdBindPipeline
+   GLAD_API_CALL PFN_vkCmdBindVertexBuffers glad_vkCmdBindVertexBuffers;
+#define vkCmdBindVertexBuffers glad_vkCmdBindVertexBuffers
+   GLAD_API_CALL PFN_vkCmdBlitImage glad_vkCmdBlitImage;
+#define vkCmdBlitImage glad_vkCmdBlitImage
+   GLAD_API_CALL PFN_vkCmdClearAttachments glad_vkCmdClearAttachments;
+#define vkCmdClearAttachments glad_vkCmdClearAttachments
+   GLAD_API_CALL PFN_vkCmdClearColorImage glad_vkCmdClearColorImage;
+#define vkCmdClearColorImage glad_vkCmdClearColorImage
+   GLAD_API_CALL PFN_vkCmdClearDepthStencilImage glad_vkCmdClearDepthStencilImage;
+#define vkCmdClearDepthStencilImage glad_vkCmdClearDepthStencilImage
+   GLAD_API_CALL PFN_vkCmdCopyBuffer glad_vkCmdCopyBuffer;
+#define vkCmdCopyBuffer glad_vkCmdCopyBuffer
+   GLAD_API_CALL PFN_vkCmdCopyBufferToImage glad_vkCmdCopyBufferToImage;
+#define vkCmdCopyBufferToImage glad_vkCmdCopyBufferToImage
+   GLAD_API_CALL PFN_vkCmdCopyImage glad_vkCmdCopyImage;
+#define vkCmdCopyImage glad_vkCmdCopyImage
+   GLAD_API_CALL PFN_vkCmdCopyImageToBuffer glad_vkCmdCopyImageToBuffer;
+#define vkCmdCopyImageToBuffer glad_vkCmdCopyImageToBuffer
+   GLAD_API_CALL PFN_vkCmdCopyQueryPoolResults glad_vkCmdCopyQueryPoolResults;
+#define vkCmdCopyQueryPoolResults glad_vkCmdCopyQueryPoolResults
+   GLAD_API_CALL PFN_vkCmdDispatch glad_vkCmdDispatch;
+#define vkCmdDispatch glad_vkCmdDispatch
+   GLAD_API_CALL PFN_vkCmdDispatchIndirect glad_vkCmdDispatchIndirect;
+#define vkCmdDispatchIndirect glad_vkCmdDispatchIndirect
+   GLAD_API_CALL PFN_vkCmdDraw glad_vkCmdDraw;
+#define vkCmdDraw glad_vkCmdDraw
+   GLAD_API_CALL PFN_vkCmdDrawIndexed glad_vkCmdDrawIndexed;
+#define vkCmdDrawIndexed glad_vkCmdDrawIndexed
+   GLAD_API_CALL PFN_vkCmdDrawIndexedIndirect glad_vkCmdDrawIndexedIndirect;
+#define vkCmdDrawIndexedIndirect glad_vkCmdDrawIndexedIndirect
+   GLAD_API_CALL PFN_vkCmdDrawIndirect glad_vkCmdDrawIndirect;
+#define vkCmdDrawIndirect glad_vkCmdDrawIndirect
+   GLAD_API_CALL PFN_vkCmdEndQuery glad_vkCmdEndQuery;
+#define vkCmdEndQuery glad_vkCmdEndQuery
+   GLAD_API_CALL PFN_vkCmdEndRenderPass glad_vkCmdEndRenderPass;
+#define vkCmdEndRenderPass glad_vkCmdEndRenderPass
+   GLAD_API_CALL PFN_vkCmdExecuteCommands glad_vkCmdExecuteCommands;
+#define vkCmdExecuteCommands glad_vkCmdExecuteCommands
+   GLAD_API_CALL PFN_vkCmdFillBuffer glad_vkCmdFillBuffer;
+#define vkCmdFillBuffer glad_vkCmdFillBuffer
+   GLAD_API_CALL PFN_vkCmdNextSubpass glad_vkCmdNextSubpass;
+#define vkCmdNextSubpass glad_vkCmdNextSubpass
+   GLAD_API_CALL PFN_vkCmdPipelineBarrier glad_vkCmdPipelineBarrier;
+#define vkCmdPipelineBarrier glad_vkCmdPipelineBarrier
+   GLAD_API_CALL PFN_vkCmdPushConstants glad_vkCmdPushConstants;
+#define vkCmdPushConstants glad_vkCmdPushConstants
+   GLAD_API_CALL PFN_vkCmdResetEvent glad_vkCmdResetEvent;
+#define vkCmdResetEvent glad_vkCmdResetEvent
+   GLAD_API_CALL PFN_vkCmdResetQueryPool glad_vkCmdResetQueryPool;
+#define vkCmdResetQueryPool glad_vkCmdResetQueryPool
+   GLAD_API_CALL PFN_vkCmdResolveImage glad_vkCmdResolveImage;
+#define vkCmdResolveImage glad_vkCmdResolveImage
+   GLAD_API_CALL PFN_vkCmdSetBlendConstants glad_vkCmdSetBlendConstants;
+#define vkCmdSetBlendConstants glad_vkCmdSetBlendConstants
+   GLAD_API_CALL PFN_vkCmdSetDepthBias glad_vkCmdSetDepthBias;
+#define vkCmdSetDepthBias glad_vkCmdSetDepthBias
+   GLAD_API_CALL PFN_vkCmdSetDepthBounds glad_vkCmdSetDepthBounds;
+#define vkCmdSetDepthBounds glad_vkCmdSetDepthBounds
+   GLAD_API_CALL PFN_vkCmdSetEvent glad_vkCmdSetEvent;
+#define vkCmdSetEvent glad_vkCmdSetEvent
+   GLAD_API_CALL PFN_vkCmdSetLineWidth glad_vkCmdSetLineWidth;
+#define vkCmdSetLineWidth glad_vkCmdSetLineWidth
+   GLAD_API_CALL PFN_vkCmdSetScissor glad_vkCmdSetScissor;
+#define vkCmdSetScissor glad_vkCmdSetScissor
+   GLAD_API_CALL PFN_vkCmdSetStencilCompareMask glad_vkCmdSetStencilCompareMask;
+#define vkCmdSetStencilCompareMask glad_vkCmdSetStencilCompareMask
+   GLAD_API_CALL PFN_vkCmdSetStencilReference glad_vkCmdSetStencilReference;
+#define vkCmdSetStencilReference glad_vkCmdSetStencilReference
+   GLAD_API_CALL PFN_vkCmdSetStencilWriteMask glad_vkCmdSetStencilWriteMask;
+#define vkCmdSetStencilWriteMask glad_vkCmdSetStencilWriteMask
+   GLAD_API_CALL PFN_vkCmdSetViewport glad_vkCmdSetViewport;
+#define vkCmdSetViewport glad_vkCmdSetViewport
+   GLAD_API_CALL PFN_vkCmdUpdateBuffer glad_vkCmdUpdateBuffer;
+#define vkCmdUpdateBuffer glad_vkCmdUpdateBuffer
+   GLAD_API_CALL PFN_vkCmdWaitEvents glad_vkCmdWaitEvents;
+#define vkCmdWaitEvents glad_vkCmdWaitEvents
+   GLAD_API_CALL PFN_vkCmdWriteTimestamp glad_vkCmdWriteTimestamp;
+#define vkCmdWriteTimestamp glad_vkCmdWriteTimestamp
+   GLAD_API_CALL PFN_vkCreateBuffer glad_vkCreateBuffer;
+#define vkCreateBuffer glad_vkCreateBuffer
+   GLAD_API_CALL PFN_vkCreateBufferView glad_vkCreateBufferView;
+#define vkCreateBufferView glad_vkCreateBufferView
+   GLAD_API_CALL PFN_vkCreateCommandPool glad_vkCreateCommandPool;
+#define vkCreateCommandPool glad_vkCreateCommandPool
+   GLAD_API_CALL PFN_vkCreateComputePipelines glad_vkCreateComputePipelines;
+#define vkCreateComputePipelines glad_vkCreateComputePipelines
+   GLAD_API_CALL PFN_vkCreateDebugReportCallbackEXT glad_vkCreateDebugReportCallbackEXT;
+#define vkCreateDebugReportCallbackEXT glad_vkCreateDebugReportCallbackEXT
+   GLAD_API_CALL PFN_vkCreateDescriptorPool glad_vkCreateDescriptorPool;
+#define vkCreateDescriptorPool glad_vkCreateDescriptorPool
+   GLAD_API_CALL PFN_vkCreateDescriptorSetLayout glad_vkCreateDescriptorSetLayout;
+#define vkCreateDescriptorSetLayout glad_vkCreateDescriptorSetLayout
+   GLAD_API_CALL PFN_vkCreateDevice glad_vkCreateDevice;
+#define vkCreateDevice glad_vkCreateDevice
+   GLAD_API_CALL PFN_vkCreateEvent glad_vkCreateEvent;
+#define vkCreateEvent glad_vkCreateEvent
+   GLAD_API_CALL PFN_vkCreateFence glad_vkCreateFence;
+#define vkCreateFence glad_vkCreateFence
+   GLAD_API_CALL PFN_vkCreateFramebuffer glad_vkCreateFramebuffer;
+#define vkCreateFramebuffer glad_vkCreateFramebuffer
+   GLAD_API_CALL PFN_vkCreateGraphicsPipelines glad_vkCreateGraphicsPipelines;
+#define vkCreateGraphicsPipelines glad_vkCreateGraphicsPipelines
+   GLAD_API_CALL PFN_vkCreateImage glad_vkCreateImage;
+#define vkCreateImage glad_vkCreateImage
+   GLAD_API_CALL PFN_vkCreateImageView glad_vkCreateImageView;
+#define vkCreateImageView glad_vkCreateImageView
+   GLAD_API_CALL PFN_vkCreateInstance glad_vkCreateInstance;
+#define vkCreateInstance glad_vkCreateInstance
+   GLAD_API_CALL PFN_vkCreatePipelineCache glad_vkCreatePipelineCache;
+#define vkCreatePipelineCache glad_vkCreatePipelineCache
+   GLAD_API_CALL PFN_vkCreatePipelineLayout glad_vkCreatePipelineLayout;
+#define vkCreatePipelineLayout glad_vkCreatePipelineLayout
+   GLAD_API_CALL PFN_vkCreateQueryPool glad_vkCreateQueryPool;
+#define vkCreateQueryPool glad_vkCreateQueryPool
+   GLAD_API_CALL PFN_vkCreateRenderPass glad_vkCreateRenderPass;
+#define vkCreateRenderPass glad_vkCreateRenderPass
+   GLAD_API_CALL PFN_vkCreateSampler glad_vkCreateSampler;
+#define vkCreateSampler glad_vkCreateSampler
+   GLAD_API_CALL PFN_vkCreateSemaphore glad_vkCreateSemaphore;
+#define vkCreateSemaphore glad_vkCreateSemaphore
+   GLAD_API_CALL PFN_vkCreateShaderModule glad_vkCreateShaderModule;
+#define vkCreateShaderModule glad_vkCreateShaderModule
+   GLAD_API_CALL PFN_vkCreateSwapchainKHR glad_vkCreateSwapchainKHR;
+#define vkCreateSwapchainKHR glad_vkCreateSwapchainKHR
+   GLAD_API_CALL PFN_vkDebugReportMessageEXT glad_vkDebugReportMessageEXT;
+#define vkDebugReportMessageEXT glad_vkDebugReportMessageEXT
+   GLAD_API_CALL PFN_vkDestroyBuffer glad_vkDestroyBuffer;
+#define vkDestroyBuffer glad_vkDestroyBuffer
+   GLAD_API_CALL PFN_vkDestroyBufferView glad_vkDestroyBufferView;
+#define vkDestroyBufferView glad_vkDestroyBufferView
+   GLAD_API_CALL PFN_vkDestroyCommandPool glad_vkDestroyCommandPool;
+#define vkDestroyCommandPool glad_vkDestroyCommandPool
+   GLAD_API_CALL PFN_vkDestroyDebugReportCallbackEXT glad_vkDestroyDebugReportCallbackEXT;
+#define vkDestroyDebugReportCallbackEXT glad_vkDestroyDebugReportCallbackEXT
+   GLAD_API_CALL PFN_vkDestroyDescriptorPool glad_vkDestroyDescriptorPool;
+#define vkDestroyDescriptorPool glad_vkDestroyDescriptorPool
+   GLAD_API_CALL PFN_vkDestroyDescriptorSetLayout glad_vkDestroyDescriptorSetLayout;
+#define vkDestroyDescriptorSetLayout glad_vkDestroyDescriptorSetLayout
+   GLAD_API_CALL PFN_vkDestroyDevice glad_vkDestroyDevice;
+#define vkDestroyDevice glad_vkDestroyDevice
+   GLAD_API_CALL PFN_vkDestroyEvent glad_vkDestroyEvent;
+#define vkDestroyEvent glad_vkDestroyEvent
+   GLAD_API_CALL PFN_vkDestroyFence glad_vkDestroyFence;
+#define vkDestroyFence glad_vkDestroyFence
+   GLAD_API_CALL PFN_vkDestroyFramebuffer glad_vkDestroyFramebuffer;
+#define vkDestroyFramebuffer glad_vkDestroyFramebuffer
+   GLAD_API_CALL PFN_vkDestroyImage glad_vkDestroyImage;
+#define vkDestroyImage glad_vkDestroyImage
+   GLAD_API_CALL PFN_vkDestroyImageView glad_vkDestroyImageView;
+#define vkDestroyImageView glad_vkDestroyImageView
+   GLAD_API_CALL PFN_vkDestroyInstance glad_vkDestroyInstance;
+#define vkDestroyInstance glad_vkDestroyInstance
+   GLAD_API_CALL PFN_vkDestroyPipeline glad_vkDestroyPipeline;
+#define vkDestroyPipeline glad_vkDestroyPipeline
+   GLAD_API_CALL PFN_vkDestroyPipelineCache glad_vkDestroyPipelineCache;
+#define vkDestroyPipelineCache glad_vkDestroyPipelineCache
+   GLAD_API_CALL PFN_vkDestroyPipelineLayout glad_vkDestroyPipelineLayout;
+#define vkDestroyPipelineLayout glad_vkDestroyPipelineLayout
+   GLAD_API_CALL PFN_vkDestroyQueryPool glad_vkDestroyQueryPool;
+#define vkDestroyQueryPool glad_vkDestroyQueryPool
+   GLAD_API_CALL PFN_vkDestroyRenderPass glad_vkDestroyRenderPass;
+#define vkDestroyRenderPass glad_vkDestroyRenderPass
+   GLAD_API_CALL PFN_vkDestroySampler glad_vkDestroySampler;
+#define vkDestroySampler glad_vkDestroySampler
+   GLAD_API_CALL PFN_vkDestroySemaphore glad_vkDestroySemaphore;
+#define vkDestroySemaphore glad_vkDestroySemaphore
+   GLAD_API_CALL PFN_vkDestroyShaderModule glad_vkDestroyShaderModule;
+#define vkDestroyShaderModule glad_vkDestroyShaderModule
+   GLAD_API_CALL PFN_vkDestroySurfaceKHR glad_vkDestroySurfaceKHR;
+#define vkDestroySurfaceKHR glad_vkDestroySurfaceKHR
+   GLAD_API_CALL PFN_vkDestroySwapchainKHR glad_vkDestroySwapchainKHR;
+#define vkDestroySwapchainKHR glad_vkDestroySwapchainKHR
+   GLAD_API_CALL PFN_vkDeviceWaitIdle glad_vkDeviceWaitIdle;
+#define vkDeviceWaitIdle glad_vkDeviceWaitIdle
+   GLAD_API_CALL PFN_vkEndCommandBuffer glad_vkEndCommandBuffer;
+#define vkEndCommandBuffer glad_vkEndCommandBuffer
+   GLAD_API_CALL PFN_vkEnumerateDeviceExtensionProperties glad_vkEnumerateDeviceExtensionProperties;
+#define vkEnumerateDeviceExtensionProperties glad_vkEnumerateDeviceExtensionProperties
+   GLAD_API_CALL PFN_vkEnumerateDeviceLayerProperties glad_vkEnumerateDeviceLayerProperties;
+#define vkEnumerateDeviceLayerProperties glad_vkEnumerateDeviceLayerProperties
+   GLAD_API_CALL PFN_vkEnumerateInstanceExtensionProperties glad_vkEnumerateInstanceExtensionProperties;
+#define vkEnumerateInstanceExtensionProperties glad_vkEnumerateInstanceExtensionProperties
+   GLAD_API_CALL PFN_vkEnumerateInstanceLayerProperties glad_vkEnumerateInstanceLayerProperties;
+#define vkEnumerateInstanceLayerProperties glad_vkEnumerateInstanceLayerProperties
+   GLAD_API_CALL PFN_vkEnumeratePhysicalDevices glad_vkEnumeratePhysicalDevices;
+#define vkEnumeratePhysicalDevices glad_vkEnumeratePhysicalDevices
+   GLAD_API_CALL PFN_vkFlushMappedMemoryRanges glad_vkFlushMappedMemoryRanges;
+#define vkFlushMappedMemoryRanges glad_vkFlushMappedMemoryRanges
+   GLAD_API_CALL PFN_vkFreeCommandBuffers glad_vkFreeCommandBuffers;
+#define vkFreeCommandBuffers glad_vkFreeCommandBuffers
+   GLAD_API_CALL PFN_vkFreeDescriptorSets glad_vkFreeDescriptorSets;
+#define vkFreeDescriptorSets glad_vkFreeDescriptorSets
+   GLAD_API_CALL PFN_vkFreeMemory glad_vkFreeMemory;
+#define vkFreeMemory glad_vkFreeMemory
+   GLAD_API_CALL PFN_vkGetBufferMemoryRequirements glad_vkGetBufferMemoryRequirements;
+#define vkGetBufferMemoryRequirements glad_vkGetBufferMemoryRequirements
+   GLAD_API_CALL PFN_vkGetDeviceGroupPresentCapabilitiesKHR glad_vkGetDeviceGroupPresentCapabilitiesKHR;
+#define vkGetDeviceGroupPresentCapabilitiesKHR glad_vkGetDeviceGroupPresentCapabilitiesKHR
+   GLAD_API_CALL PFN_vkGetDeviceGroupSurfacePresentModesKHR glad_vkGetDeviceGroupSurfacePresentModesKHR;
+#define vkGetDeviceGroupSurfacePresentModesKHR glad_vkGetDeviceGroupSurfacePresentModesKHR
+   GLAD_API_CALL PFN_vkGetDeviceMemoryCommitment glad_vkGetDeviceMemoryCommitment;
+#define vkGetDeviceMemoryCommitment glad_vkGetDeviceMemoryCommitment
+   GLAD_API_CALL PFN_vkGetDeviceProcAddr glad_vkGetDeviceProcAddr;
+#define vkGetDeviceProcAddr glad_vkGetDeviceProcAddr
+   GLAD_API_CALL PFN_vkGetDeviceQueue glad_vkGetDeviceQueue;
+#define vkGetDeviceQueue glad_vkGetDeviceQueue
+   GLAD_API_CALL PFN_vkGetEventStatus glad_vkGetEventStatus;
+#define vkGetEventStatus glad_vkGetEventStatus
+   GLAD_API_CALL PFN_vkGetFenceStatus glad_vkGetFenceStatus;
+#define vkGetFenceStatus glad_vkGetFenceStatus
+   GLAD_API_CALL PFN_vkGetImageMemoryRequirements glad_vkGetImageMemoryRequirements;
+#define vkGetImageMemoryRequirements glad_vkGetImageMemoryRequirements
+   GLAD_API_CALL PFN_vkGetImageSparseMemoryRequirements glad_vkGetImageSparseMemoryRequirements;
+#define vkGetImageSparseMemoryRequirements glad_vkGetImageSparseMemoryRequirements
+   GLAD_API_CALL PFN_vkGetImageSubresourceLayout glad_vkGetImageSubresourceLayout;
+#define vkGetImageSubresourceLayout glad_vkGetImageSubresourceLayout
+   GLAD_API_CALL PFN_vkGetInstanceProcAddr glad_vkGetInstanceProcAddr;
+#define vkGetInstanceProcAddr glad_vkGetInstanceProcAddr
+   GLAD_API_CALL PFN_vkGetPhysicalDeviceFeatures glad_vkGetPhysicalDeviceFeatures;
+#define vkGetPhysicalDeviceFeatures glad_vkGetPhysicalDeviceFeatures
+   GLAD_API_CALL PFN_vkGetPhysicalDeviceFormatProperties glad_vkGetPhysicalDeviceFormatProperties;
+#define vkGetPhysicalDeviceFormatProperties glad_vkGetPhysicalDeviceFormatProperties
+   GLAD_API_CALL PFN_vkGetPhysicalDeviceImageFormatProperties glad_vkGetPhysicalDeviceImageFormatProperties;
+#define vkGetPhysicalDeviceImageFormatProperties glad_vkGetPhysicalDeviceImageFormatProperties
+   GLAD_API_CALL PFN_vkGetPhysicalDeviceMemoryProperties glad_vkGetPhysicalDeviceMemoryProperties;
+#define vkGetPhysicalDeviceMemoryProperties glad_vkGetPhysicalDeviceMemoryProperties
+   GLAD_API_CALL PFN_vkGetPhysicalDevicePresentRectanglesKHR glad_vkGetPhysicalDevicePresentRectanglesKHR;
+#define vkGetPhysicalDevicePresentRectanglesKHR glad_vkGetPhysicalDevicePresentRectanglesKHR
+   GLAD_API_CALL PFN_vkGetPhysicalDeviceProperties glad_vkGetPhysicalDeviceProperties;
+#define vkGetPhysicalDeviceProperties glad_vkGetPhysicalDeviceProperties
+   GLAD_API_CALL PFN_vkGetPhysicalDeviceQueueFamilyProperties glad_vkGetPhysicalDeviceQueueFamilyProperties;
+#define vkGetPhysicalDeviceQueueFamilyProperties glad_vkGetPhysicalDeviceQueueFamilyProperties
+   GLAD_API_CALL PFN_vkGetPhysicalDeviceSparseImageFormatProperties glad_vkGetPhysicalDeviceSparseImageFormatProperties;
+#define vkGetPhysicalDeviceSparseImageFormatProperties glad_vkGetPhysicalDeviceSparseImageFormatProperties
+   GLAD_API_CALL PFN_vkGetPhysicalDeviceSurfaceCapabilitiesKHR glad_vkGetPhysicalDeviceSurfaceCapabilitiesKHR;
+#define vkGetPhysicalDeviceSurfaceCapabilitiesKHR glad_vkGetPhysicalDeviceSurfaceCapabilitiesKHR
+   GLAD_API_CALL PFN_vkGetPhysicalDeviceSurfaceFormatsKHR glad_vkGetPhysicalDeviceSurfaceFormatsKHR;
+#define vkGetPhysicalDeviceSurfaceFormatsKHR glad_vkGetPhysicalDeviceSurfaceFormatsKHR
+   GLAD_API_CALL PFN_vkGetPhysicalDeviceSurfacePresentModesKHR glad_vkGetPhysicalDeviceSurfacePresentModesKHR;
+#define vkGetPhysicalDeviceSurfacePresentModesKHR glad_vkGetPhysicalDeviceSurfacePresentModesKHR
+   GLAD_API_CALL PFN_vkGetPhysicalDeviceSurfaceSupportKHR glad_vkGetPhysicalDeviceSurfaceSupportKHR;
+#define vkGetPhysicalDeviceSurfaceSupportKHR glad_vkGetPhysicalDeviceSurfaceSupportKHR
+   GLAD_API_CALL PFN_vkGetPipelineCacheData glad_vkGetPipelineCacheData;
+#define vkGetPipelineCacheData glad_vkGetPipelineCacheData
+   GLAD_API_CALL PFN_vkGetQueryPoolResults glad_vkGetQueryPoolResults;
+#define vkGetQueryPoolResults glad_vkGetQueryPoolResults
+   GLAD_API_CALL PFN_vkGetRenderAreaGranularity glad_vkGetRenderAreaGranularity;
+#define vkGetRenderAreaGranularity glad_vkGetRenderAreaGranularity
+   GLAD_API_CALL PFN_vkGetSwapchainImagesKHR glad_vkGetSwapchainImagesKHR;
+#define vkGetSwapchainImagesKHR glad_vkGetSwapchainImagesKHR
+   GLAD_API_CALL PFN_vkInvalidateMappedMemoryRanges glad_vkInvalidateMappedMemoryRanges;
+#define vkInvalidateMappedMemoryRanges glad_vkInvalidateMappedMemoryRanges
+   GLAD_API_CALL PFN_vkMapMemory glad_vkMapMemory;
+#define vkMapMemory glad_vkMapMemory
+   GLAD_API_CALL PFN_vkMergePipelineCaches glad_vkMergePipelineCaches;
+#define vkMergePipelineCaches glad_vkMergePipelineCaches
+   GLAD_API_CALL PFN_vkQueueBindSparse glad_vkQueueBindSparse;
+#define vkQueueBindSparse glad_vkQueueBindSparse
+   GLAD_API_CALL PFN_vkQueuePresentKHR glad_vkQueuePresentKHR;
+#define vkQueuePresentKHR glad_vkQueuePresentKHR
+   GLAD_API_CALL PFN_vkQueueSubmit glad_vkQueueSubmit;
+#define vkQueueSubmit glad_vkQueueSubmit
+   GLAD_API_CALL PFN_vkQueueWaitIdle glad_vkQueueWaitIdle;
+#define vkQueueWaitIdle glad_vkQueueWaitIdle
+   GLAD_API_CALL PFN_vkResetCommandBuffer glad_vkResetCommandBuffer;
+#define vkResetCommandBuffer glad_vkResetCommandBuffer
+   GLAD_API_CALL PFN_vkResetCommandPool glad_vkResetCommandPool;
+#define vkResetCommandPool glad_vkResetCommandPool
+   GLAD_API_CALL PFN_vkResetDescriptorPool glad_vkResetDescriptorPool;
+#define vkResetDescriptorPool glad_vkResetDescriptorPool
+   GLAD_API_CALL PFN_vkResetEvent glad_vkResetEvent;
+#define vkResetEvent glad_vkResetEvent
+   GLAD_API_CALL PFN_vkResetFences glad_vkResetFences;
+#define vkResetFences glad_vkResetFences
+   GLAD_API_CALL PFN_vkSetEvent glad_vkSetEvent;
+#define vkSetEvent glad_vkSetEvent
+   GLAD_API_CALL PFN_vkUnmapMemory glad_vkUnmapMemory;
+#define vkUnmapMemory glad_vkUnmapMemory
+   GLAD_API_CALL PFN_vkUpdateDescriptorSets glad_vkUpdateDescriptorSets;
+#define vkUpdateDescriptorSets glad_vkUpdateDescriptorSets
+   GLAD_API_CALL PFN_vkWaitForFences glad_vkWaitForFences;
+#define vkWaitForFences glad_vkWaitForFences
+
+
+   GLAD_API_CALL int gladLoadVulkanUserPtr(VkPhysicalDevice physical_device, GLADuserptrloadfunc load, void* userptr);
+   GLAD_API_CALL int gladLoadVulkan(VkPhysicalDevice physical_device, GLADloadfunc load);
+
+
+
+
+
+
+#ifdef __cplusplus
+}
+#endif
+#endif
+
+/* Source */
+#ifdef GLAD_VULKAN_IMPLEMENTATION
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#ifndef GLAD_IMPL_UTIL_C_
+#define GLAD_IMPL_UTIL_C_
+
+#ifdef _MSC_VER
+#define GLAD_IMPL_UTIL_SSCANF sscanf_s
+#else
+#define GLAD_IMPL_UTIL_SSCANF sscanf
+#endif
+
+#endif /* GLAD_IMPL_UTIL_C_ */
+
+
+int GLAD_VK_VERSION_1_0 = 0;
+int GLAD_VK_EXT_debug_report = 0;
+int GLAD_VK_KHR_surface = 0;
+int GLAD_VK_KHR_swapchain = 0;
+
+
+
+PFN_vkAcquireNextImage2KHR glad_vkAcquireNextImage2KHR = NULL;
+PFN_vkAcquireNextImageKHR glad_vkAcquireNextImageKHR = NULL;
+PFN_vkAllocateCommandBuffers glad_vkAllocateCommandBuffers = NULL;
+PFN_vkAllocateDescriptorSets glad_vkAllocateDescriptorSets = NULL;
+PFN_vkAllocateMemory glad_vkAllocateMemory = NULL;
+PFN_vkBeginCommandBuffer glad_vkBeginCommandBuffer = NULL;
+PFN_vkBindBufferMemory glad_vkBindBufferMemory = NULL;
+PFN_vkBindImageMemory glad_vkBindImageMemory = NULL;
+PFN_vkCmdBeginQuery glad_vkCmdBeginQuery = NULL;
+PFN_vkCmdBeginRenderPass glad_vkCmdBeginRenderPass = NULL;
+PFN_vkCmdBindDescriptorSets glad_vkCmdBindDescriptorSets = NULL;
+PFN_vkCmdBindIndexBuffer glad_vkCmdBindIndexBuffer = NULL;
+PFN_vkCmdBindPipeline glad_vkCmdBindPipeline = NULL;
+PFN_vkCmdBindVertexBuffers glad_vkCmdBindVertexBuffers = NULL;
+PFN_vkCmdBlitImage glad_vkCmdBlitImage = NULL;
+PFN_vkCmdClearAttachments glad_vkCmdClearAttachments = NULL;
+PFN_vkCmdClearColorImage glad_vkCmdClearColorImage = NULL;
+PFN_vkCmdClearDepthStencilImage glad_vkCmdClearDepthStencilImage = NULL;
+PFN_vkCmdCopyBuffer glad_vkCmdCopyBuffer = NULL;
+PFN_vkCmdCopyBufferToImage glad_vkCmdCopyBufferToImage = NULL;
+PFN_vkCmdCopyImage glad_vkCmdCopyImage = NULL;
+PFN_vkCmdCopyImageToBuffer glad_vkCmdCopyImageToBuffer = NULL;
+PFN_vkCmdCopyQueryPoolResults glad_vkCmdCopyQueryPoolResults = NULL;
+PFN_vkCmdDispatch glad_vkCmdDispatch = NULL;
+PFN_vkCmdDispatchIndirect glad_vkCmdDispatchIndirect = NULL;
+PFN_vkCmdDraw glad_vkCmdDraw = NULL;
+PFN_vkCmdDrawIndexed glad_vkCmdDrawIndexed = NULL;
+PFN_vkCmdDrawIndexedIndirect glad_vkCmdDrawIndexedIndirect = NULL;
+PFN_vkCmdDrawIndirect glad_vkCmdDrawIndirect = NULL;
+PFN_vkCmdEndQuery glad_vkCmdEndQuery = NULL;
+PFN_vkCmdEndRenderPass glad_vkCmdEndRenderPass = NULL;
+PFN_vkCmdExecuteCommands glad_vkCmdExecuteCommands = NULL;
+PFN_vkCmdFillBuffer glad_vkCmdFillBuffer = NULL;
+PFN_vkCmdNextSubpass glad_vkCmdNextSubpass = NULL;
+PFN_vkCmdPipelineBarrier glad_vkCmdPipelineBarrier = NULL;
+PFN_vkCmdPushConstants glad_vkCmdPushConstants = NULL;
+PFN_vkCmdResetEvent glad_vkCmdResetEvent = NULL;
+PFN_vkCmdResetQueryPool glad_vkCmdResetQueryPool = NULL;
+PFN_vkCmdResolveImage glad_vkCmdResolveImage = NULL;
+PFN_vkCmdSetBlendConstants glad_vkCmdSetBlendConstants = NULL;
+PFN_vkCmdSetDepthBias glad_vkCmdSetDepthBias = NULL;
+PFN_vkCmdSetDepthBounds glad_vkCmdSetDepthBounds = NULL;
+PFN_vkCmdSetEvent glad_vkCmdSetEvent = NULL;
+PFN_vkCmdSetLineWidth glad_vkCmdSetLineWidth = NULL;
+PFN_vkCmdSetScissor glad_vkCmdSetScissor = NULL;
+PFN_vkCmdSetStencilCompareMask glad_vkCmdSetStencilCompareMask = NULL;
+PFN_vkCmdSetStencilReference glad_vkCmdSetStencilReference = NULL;
+PFN_vkCmdSetStencilWriteMask glad_vkCmdSetStencilWriteMask = NULL;
+PFN_vkCmdSetViewport glad_vkCmdSetViewport = NULL;
+PFN_vkCmdUpdateBuffer glad_vkCmdUpdateBuffer = NULL;
+PFN_vkCmdWaitEvents glad_vkCmdWaitEvents = NULL;
+PFN_vkCmdWriteTimestamp glad_vkCmdWriteTimestamp = NULL;
+PFN_vkCreateBuffer glad_vkCreateBuffer = NULL;
+PFN_vkCreateBufferView glad_vkCreateBufferView = NULL;
+PFN_vkCreateCommandPool glad_vkCreateCommandPool = NULL;
+PFN_vkCreateComputePipelines glad_vkCreateComputePipelines = NULL;
+PFN_vkCreateDebugReportCallbackEXT glad_vkCreateDebugReportCallbackEXT = NULL;
+PFN_vkCreateDescriptorPool glad_vkCreateDescriptorPool = NULL;
+PFN_vkCreateDescriptorSetLayout glad_vkCreateDescriptorSetLayout = NULL;
+PFN_vkCreateDevice glad_vkCreateDevice = NULL;
+PFN_vkCreateEvent glad_vkCreateEvent = NULL;
+PFN_vkCreateFence glad_vkCreateFence = NULL;
+PFN_vkCreateFramebuffer glad_vkCreateFramebuffer = NULL;
+PFN_vkCreateGraphicsPipelines glad_vkCreateGraphicsPipelines = NULL;
+PFN_vkCreateImage glad_vkCreateImage = NULL;
+PFN_vkCreateImageView glad_vkCreateImageView = NULL;
+PFN_vkCreateInstance glad_vkCreateInstance = NULL;
+PFN_vkCreatePipelineCache glad_vkCreatePipelineCache = NULL;
+PFN_vkCreatePipelineLayout glad_vkCreatePipelineLayout = NULL;
+PFN_vkCreateQueryPool glad_vkCreateQueryPool = NULL;
+PFN_vkCreateRenderPass glad_vkCreateRenderPass = NULL;
+PFN_vkCreateSampler glad_vkCreateSampler = NULL;
+PFN_vkCreateSemaphore glad_vkCreateSemaphore = NULL;
+PFN_vkCreateShaderModule glad_vkCreateShaderModule = NULL;
+PFN_vkCreateSwapchainKHR glad_vkCreateSwapchainKHR = NULL;
+PFN_vkDebugReportMessageEXT glad_vkDebugReportMessageEXT = NULL;
+PFN_vkDestroyBuffer glad_vkDestroyBuffer = NULL;
+PFN_vkDestroyBufferView glad_vkDestroyBufferView = NULL;
+PFN_vkDestroyCommandPool glad_vkDestroyCommandPool = NULL;
+PFN_vkDestroyDebugReportCallbackEXT glad_vkDestroyDebugReportCallbackEXT = NULL;
+PFN_vkDestroyDescriptorPool glad_vkDestroyDescriptorPool = NULL;
+PFN_vkDestroyDescriptorSetLayout glad_vkDestroyDescriptorSetLayout = NULL;
+PFN_vkDestroyDevice glad_vkDestroyDevice = NULL;
+PFN_vkDestroyEvent glad_vkDestroyEvent = NULL;
+PFN_vkDestroyFence glad_vkDestroyFence = NULL;
+PFN_vkDestroyFramebuffer glad_vkDestroyFramebuffer = NULL;
+PFN_vkDestroyImage glad_vkDestroyImage = NULL;
+PFN_vkDestroyImageView glad_vkDestroyImageView = NULL;
+PFN_vkDestroyInstance glad_vkDestroyInstance = NULL;
+PFN_vkDestroyPipeline glad_vkDestroyPipeline = NULL;
+PFN_vkDestroyPipelineCache glad_vkDestroyPipelineCache = NULL;
+PFN_vkDestroyPipelineLayout glad_vkDestroyPipelineLayout = NULL;
+PFN_vkDestroyQueryPool glad_vkDestroyQueryPool = NULL;
+PFN_vkDestroyRenderPass glad_vkDestroyRenderPass = NULL;
+PFN_vkDestroySampler glad_vkDestroySampler = NULL;
+PFN_vkDestroySemaphore glad_vkDestroySemaphore = NULL;
+PFN_vkDestroyShaderModule glad_vkDestroyShaderModule = NULL;
+PFN_vkDestroySurfaceKHR glad_vkDestroySurfaceKHR = NULL;
+PFN_vkDestroySwapchainKHR glad_vkDestroySwapchainKHR = NULL;
+PFN_vkDeviceWaitIdle glad_vkDeviceWaitIdle = NULL;
+PFN_vkEndCommandBuffer glad_vkEndCommandBuffer = NULL;
+PFN_vkEnumerateDeviceExtensionProperties glad_vkEnumerateDeviceExtensionProperties = NULL;
+PFN_vkEnumerateDeviceLayerProperties glad_vkEnumerateDeviceLayerProperties = NULL;
+PFN_vkEnumerateInstanceExtensionProperties glad_vkEnumerateInstanceExtensionProperties = NULL;
+PFN_vkEnumerateInstanceLayerProperties glad_vkEnumerateInstanceLayerProperties = NULL;
+PFN_vkEnumeratePhysicalDevices glad_vkEnumeratePhysicalDevices = NULL;
+PFN_vkFlushMappedMemoryRanges glad_vkFlushMappedMemoryRanges = NULL;
+PFN_vkFreeCommandBuffers glad_vkFreeCommandBuffers = NULL;
+PFN_vkFreeDescriptorSets glad_vkFreeDescriptorSets = NULL;
+PFN_vkFreeMemory glad_vkFreeMemory = NULL;
+PFN_vkGetBufferMemoryRequirements glad_vkGetBufferMemoryRequirements = NULL;
+PFN_vkGetDeviceGroupPresentCapabilitiesKHR glad_vkGetDeviceGroupPresentCapabilitiesKHR = NULL;
+PFN_vkGetDeviceGroupSurfacePresentModesKHR glad_vkGetDeviceGroupSurfacePresentModesKHR = NULL;
+PFN_vkGetDeviceMemoryCommitment glad_vkGetDeviceMemoryCommitment = NULL;
+PFN_vkGetDeviceProcAddr glad_vkGetDeviceProcAddr = NULL;
+PFN_vkGetDeviceQueue glad_vkGetDeviceQueue = NULL;
+PFN_vkGetEventStatus glad_vkGetEventStatus = NULL;
+PFN_vkGetFenceStatus glad_vkGetFenceStatus = NULL;
+PFN_vkGetImageMemoryRequirements glad_vkGetImageMemoryRequirements = NULL;
+PFN_vkGetImageSparseMemoryRequirements glad_vkGetImageSparseMemoryRequirements = NULL;
+PFN_vkGetImageSubresourceLayout glad_vkGetImageSubresourceLayout = NULL;
+PFN_vkGetInstanceProcAddr glad_vkGetInstanceProcAddr = NULL;
+PFN_vkGetPhysicalDeviceFeatures glad_vkGetPhysicalDeviceFeatures = NULL;
+PFN_vkGetPhysicalDeviceFormatProperties glad_vkGetPhysicalDeviceFormatProperties = NULL;
+PFN_vkGetPhysicalDeviceImageFormatProperties glad_vkGetPhysicalDeviceImageFormatProperties = NULL;
+PFN_vkGetPhysicalDeviceMemoryProperties glad_vkGetPhysicalDeviceMemoryProperties = NULL;
+PFN_vkGetPhysicalDevicePresentRectanglesKHR glad_vkGetPhysicalDevicePresentRectanglesKHR = NULL;
+PFN_vkGetPhysicalDeviceProperties glad_vkGetPhysicalDeviceProperties = NULL;
+PFN_vkGetPhysicalDeviceQueueFamilyProperties glad_vkGetPhysicalDeviceQueueFamilyProperties = NULL;
+PFN_vkGetPhysicalDeviceSparseImageFormatProperties glad_vkGetPhysicalDeviceSparseImageFormatProperties = NULL;
+PFN_vkGetPhysicalDeviceSurfaceCapabilitiesKHR glad_vkGetPhysicalDeviceSurfaceCapabilitiesKHR = NULL;
+PFN_vkGetPhysicalDeviceSurfaceFormatsKHR glad_vkGetPhysicalDeviceSurfaceFormatsKHR = NULL;
+PFN_vkGetPhysicalDeviceSurfacePresentModesKHR glad_vkGetPhysicalDeviceSurfacePresentModesKHR = NULL;
+PFN_vkGetPhysicalDeviceSurfaceSupportKHR glad_vkGetPhysicalDeviceSurfaceSupportKHR = NULL;
+PFN_vkGetPipelineCacheData glad_vkGetPipelineCacheData = NULL;
+PFN_vkGetQueryPoolResults glad_vkGetQueryPoolResults = NULL;
+PFN_vkGetRenderAreaGranularity glad_vkGetRenderAreaGranularity = NULL;
+PFN_vkGetSwapchainImagesKHR glad_vkGetSwapchainImagesKHR = NULL;
+PFN_vkInvalidateMappedMemoryRanges glad_vkInvalidateMappedMemoryRanges = NULL;
+PFN_vkMapMemory glad_vkMapMemory = NULL;
+PFN_vkMergePipelineCaches glad_vkMergePipelineCaches = NULL;
+PFN_vkQueueBindSparse glad_vkQueueBindSparse = NULL;
+PFN_vkQueuePresentKHR glad_vkQueuePresentKHR = NULL;
+PFN_vkQueueSubmit glad_vkQueueSubmit = NULL;
+PFN_vkQueueWaitIdle glad_vkQueueWaitIdle = NULL;
+PFN_vkResetCommandBuffer glad_vkResetCommandBuffer = NULL;
+PFN_vkResetCommandPool glad_vkResetCommandPool = NULL;
+PFN_vkResetDescriptorPool glad_vkResetDescriptorPool = NULL;
+PFN_vkResetEvent glad_vkResetEvent = NULL;
+PFN_vkResetFences glad_vkResetFences = NULL;
+PFN_vkSetEvent glad_vkSetEvent = NULL;
+PFN_vkUnmapMemory glad_vkUnmapMemory = NULL;
+PFN_vkUpdateDescriptorSets glad_vkUpdateDescriptorSets = NULL;
+PFN_vkWaitForFences glad_vkWaitForFences = NULL;
+
+
+static void glad_vk_load_VK_VERSION_1_0(GLADuserptrloadfunc load, void* userptr) {
+   if (!GLAD_VK_VERSION_1_0) return;
+   vkAllocateCommandBuffers = (PFN_vkAllocateCommandBuffers)load("vkAllocateCommandBuffers", userptr);
+   vkAllocateDescriptorSets = (PFN_vkAllocateDescriptorSets)load("vkAllocateDescriptorSets", userptr);
+   vkAllocateMemory = (PFN_vkAllocateMemory)load("vkAllocateMemory", userptr);
+   vkBeginCommandBuffer = (PFN_vkBeginCommandBuffer)load("vkBeginCommandBuffer", userptr);
+   vkBindBufferMemory = (PFN_vkBindBufferMemory)load("vkBindBufferMemory", userptr);
+   vkBindImageMemory = (PFN_vkBindImageMemory)load("vkBindImageMemory", userptr);
+   vkCmdBeginQuery = (PFN_vkCmdBeginQuery)load("vkCmdBeginQuery", userptr);
+   vkCmdBeginRenderPass = (PFN_vkCmdBeginRenderPass)load("vkCmdBeginRenderPass", userptr);
+   vkCmdBindDescriptorSets = (PFN_vkCmdBindDescriptorSets)load("vkCmdBindDescriptorSets", userptr);
+   vkCmdBindIndexBuffer = (PFN_vkCmdBindIndexBuffer)load("vkCmdBindIndexBuffer", userptr);
+   vkCmdBindPipeline = (PFN_vkCmdBindPipeline)load("vkCmdBindPipeline", userptr);
+   vkCmdBindVertexBuffers = (PFN_vkCmdBindVertexBuffers)load("vkCmdBindVertexBuffers", userptr);
+   vkCmdBlitImage = (PFN_vkCmdBlitImage)load("vkCmdBlitImage", userptr);
+   vkCmdClearAttachments = (PFN_vkCmdClearAttachments)load("vkCmdClearAttachments", userptr);
+   vkCmdClearColorImage = (PFN_vkCmdClearColorImage)load("vkCmdClearColorImage", userptr);
+   vkCmdClearDepthStencilImage = (PFN_vkCmdClearDepthStencilImage)load("vkCmdClearDepthStencilImage", userptr);
+   vkCmdCopyBuffer = (PFN_vkCmdCopyBuffer)load("vkCmdCopyBuffer", userptr);
+   vkCmdCopyBufferToImage = (PFN_vkCmdCopyBufferToImage)load("vkCmdCopyBufferToImage", userptr);
+   vkCmdCopyImage = (PFN_vkCmdCopyImage)load("vkCmdCopyImage", userptr);
+   vkCmdCopyImageToBuffer = (PFN_vkCmdCopyImageToBuffer)load("vkCmdCopyImageToBuffer", userptr);
+   vkCmdCopyQueryPoolResults = (PFN_vkCmdCopyQueryPoolResults)load("vkCmdCopyQueryPoolResults", userptr);
+   vkCmdDispatch = (PFN_vkCmdDispatch)load("vkCmdDispatch", userptr);
+   vkCmdDispatchIndirect = (PFN_vkCmdDispatchIndirect)load("vkCmdDispatchIndirect", userptr);
+   vkCmdDraw = (PFN_vkCmdDraw)load("vkCmdDraw", userptr);
+   vkCmdDrawIndexed = (PFN_vkCmdDrawIndexed)load("vkCmdDrawIndexed", userptr);
+   vkCmdDrawIndexedIndirect = (PFN_vkCmdDrawIndexedIndirect)load("vkCmdDrawIndexedIndirect", userptr);
+   vkCmdDrawIndirect = (PFN_vkCmdDrawIndirect)load("vkCmdDrawIndirect", userptr);
+   vkCmdEndQuery = (PFN_vkCmdEndQuery)load("vkCmdEndQuery", userptr);
+   vkCmdEndRenderPass = (PFN_vkCmdEndRenderPass)load("vkCmdEndRenderPass", userptr);
+   vkCmdExecuteCommands = (PFN_vkCmdExecuteCommands)load("vkCmdExecuteCommands", userptr);
+   vkCmdFillBuffer = (PFN_vkCmdFillBuffer)load("vkCmdFillBuffer", userptr);
+   vkCmdNextSubpass = (PFN_vkCmdNextSubpass)load("vkCmdNextSubpass", userptr);
+   vkCmdPipelineBarrier = (PFN_vkCmdPipelineBarrier)load("vkCmdPipelineBarrier", userptr);
+   vkCmdPushConstants = (PFN_vkCmdPushConstants)load("vkCmdPushConstants", userptr);
+   vkCmdResetEvent = (PFN_vkCmdResetEvent)load("vkCmdResetEvent", userptr);
+   vkCmdResetQueryPool = (PFN_vkCmdResetQueryPool)load("vkCmdResetQueryPool", userptr);
+   vkCmdResolveImage = (PFN_vkCmdResolveImage)load("vkCmdResolveImage", userptr);
+   vkCmdSetBlendConstants = (PFN_vkCmdSetBlendConstants)load("vkCmdSetBlendConstants", userptr);
+   vkCmdSetDepthBias = (PFN_vkCmdSetDepthBias)load("vkCmdSetDepthBias", userptr);
+   vkCmdSetDepthBounds = (PFN_vkCmdSetDepthBounds)load("vkCmdSetDepthBounds", userptr);
+   vkCmdSetEvent = (PFN_vkCmdSetEvent)load("vkCmdSetEvent", userptr);
+   vkCmdSetLineWidth = (PFN_vkCmdSetLineWidth)load("vkCmdSetLineWidth", userptr);
+   vkCmdSetScissor = (PFN_vkCmdSetScissor)load("vkCmdSetScissor", userptr);
+   vkCmdSetStencilCompareMask = (PFN_vkCmdSetStencilCompareMask)load("vkCmdSetStencilCompareMask", userptr);
+   vkCmdSetStencilReference = (PFN_vkCmdSetStencilReference)load("vkCmdSetStencilReference", userptr);
+   vkCmdSetStencilWriteMask = (PFN_vkCmdSetStencilWriteMask)load("vkCmdSetStencilWriteMask", userptr);
+   vkCmdSetViewport = (PFN_vkCmdSetViewport)load("vkCmdSetViewport", userptr);
+   vkCmdUpdateBuffer = (PFN_vkCmdUpdateBuffer)load("vkCmdUpdateBuffer", userptr);
+   vkCmdWaitEvents = (PFN_vkCmdWaitEvents)load("vkCmdWaitEvents", userptr);
+   vkCmdWriteTimestamp = (PFN_vkCmdWriteTimestamp)load("vkCmdWriteTimestamp", userptr);
+   vkCreateBuffer = (PFN_vkCreateBuffer)load("vkCreateBuffer", userptr);
+   vkCreateBufferView = (PFN_vkCreateBufferView)load("vkCreateBufferView", userptr);
+   vkCreateCommandPool = (PFN_vkCreateCommandPool)load("vkCreateCommandPool", userptr);
+   vkCreateComputePipelines = (PFN_vkCreateComputePipelines)load("vkCreateComputePipelines", userptr);
+   vkCreateDescriptorPool = (PFN_vkCreateDescriptorPool)load("vkCreateDescriptorPool", userptr);
+   vkCreateDescriptorSetLayout = (PFN_vkCreateDescriptorSetLayout)load("vkCreateDescriptorSetLayout", userptr);
+   vkCreateDevice = (PFN_vkCreateDevice)load("vkCreateDevice", userptr);
+   vkCreateEvent = (PFN_vkCreateEvent)load("vkCreateEvent", userptr);
+   vkCreateFence = (PFN_vkCreateFence)load("vkCreateFence", userptr);
+   vkCreateFramebuffer = (PFN_vkCreateFramebuffer)load("vkCreateFramebuffer", userptr);
+   vkCreateGraphicsPipelines = (PFN_vkCreateGraphicsPipelines)load("vkCreateGraphicsPipelines", userptr);
+   vkCreateImage = (PFN_vkCreateImage)load("vkCreateImage", userptr);
+   vkCreateImageView = (PFN_vkCreateImageView)load("vkCreateImageView", userptr);
+   vkCreateInstance = (PFN_vkCreateInstance)load("vkCreateInstance", userptr);
+   vkCreatePipelineCache = (PFN_vkCreatePipelineCache)load("vkCreatePipelineCache", userptr);
+   vkCreatePipelineLayout = (PFN_vkCreatePipelineLayout)load("vkCreatePipelineLayout", userptr);
+   vkCreateQueryPool = (PFN_vkCreateQueryPool)load("vkCreateQueryPool", userptr);
+   vkCreateRenderPass = (PFN_vkCreateRenderPass)load("vkCreateRenderPass", userptr);
+   vkCreateSampler = (PFN_vkCreateSampler)load("vkCreateSampler", userptr);
+   vkCreateSemaphore = (PFN_vkCreateSemaphore)load("vkCreateSemaphore", userptr);
+   vkCreateShaderModule = (PFN_vkCreateShaderModule)load("vkCreateShaderModule", userptr);
+   vkDestroyBuffer = (PFN_vkDestroyBuffer)load("vkDestroyBuffer", userptr);
+   vkDestroyBufferView = (PFN_vkDestroyBufferView)load("vkDestroyBufferView", userptr);
+   vkDestroyCommandPool = (PFN_vkDestroyCommandPool)load("vkDestroyCommandPool", userptr);
+   vkDestroyDescriptorPool = (PFN_vkDestroyDescriptorPool)load("vkDestroyDescriptorPool", userptr);
+   vkDestroyDescriptorSetLayout = (PFN_vkDestroyDescriptorSetLayout)load("vkDestroyDescriptorSetLayout", userptr);
+   vkDestroyDevice = (PFN_vkDestroyDevice)load("vkDestroyDevice", userptr);
+   vkDestroyEvent = (PFN_vkDestroyEvent)load("vkDestroyEvent", userptr);
+   vkDestroyFence = (PFN_vkDestroyFence)load("vkDestroyFence", userptr);
+   vkDestroyFramebuffer = (PFN_vkDestroyFramebuffer)load("vkDestroyFramebuffer", userptr);
+   vkDestroyImage = (PFN_vkDestroyImage)load("vkDestroyImage", userptr);
+   vkDestroyImageView = (PFN_vkDestroyImageView)load("vkDestroyImageView", userptr);
+   vkDestroyInstance = (PFN_vkDestroyInstance)load("vkDestroyInstance", userptr);
+   vkDestroyPipeline = (PFN_vkDestroyPipeline)load("vkDestroyPipeline", userptr);
+   vkDestroyPipelineCache = (PFN_vkDestroyPipelineCache)load("vkDestroyPipelineCache", userptr);
+   vkDestroyPipelineLayout = (PFN_vkDestroyPipelineLayout)load("vkDestroyPipelineLayout", userptr);
+   vkDestroyQueryPool = (PFN_vkDestroyQueryPool)load("vkDestroyQueryPool", userptr);
+   vkDestroyRenderPass = (PFN_vkDestroyRenderPass)load("vkDestroyRenderPass", userptr);
+   vkDestroySampler = (PFN_vkDestroySampler)load("vkDestroySampler", userptr);
+   vkDestroySemaphore = (PFN_vkDestroySemaphore)load("vkDestroySemaphore", userptr);
+   vkDestroyShaderModule = (PFN_vkDestroyShaderModule)load("vkDestroyShaderModule", userptr);
+   vkDeviceWaitIdle = (PFN_vkDeviceWaitIdle)load("vkDeviceWaitIdle", userptr);
+   vkEndCommandBuffer = (PFN_vkEndCommandBuffer)load("vkEndCommandBuffer", userptr);
+   vkEnumerateDeviceExtensionProperties = (PFN_vkEnumerateDeviceExtensionProperties)load("vkEnumerateDeviceExtensionProperties", userptr);
+   vkEnumerateDeviceLayerProperties = (PFN_vkEnumerateDeviceLayerProperties)load("vkEnumerateDeviceLayerProperties", userptr);
+   vkEnumerateInstanceExtensionProperties = (PFN_vkEnumerateInstanceExtensionProperties)load("vkEnumerateInstanceExtensionProperties", userptr);
+   vkEnumerateInstanceLayerProperties = (PFN_vkEnumerateInstanceLayerProperties)load("vkEnumerateInstanceLayerProperties", userptr);
+   vkEnumeratePhysicalDevices = (PFN_vkEnumeratePhysicalDevices)load("vkEnumeratePhysicalDevices", userptr);
+   vkFlushMappedMemoryRanges = (PFN_vkFlushMappedMemoryRanges)load("vkFlushMappedMemoryRanges", userptr);
+   vkFreeCommandBuffers = (PFN_vkFreeCommandBuffers)load("vkFreeCommandBuffers", userptr);
+   vkFreeDescriptorSets = (PFN_vkFreeDescriptorSets)load("vkFreeDescriptorSets", userptr);
+   vkFreeMemory = (PFN_vkFreeMemory)load("vkFreeMemory", userptr);
+   vkGetBufferMemoryRequirements = (PFN_vkGetBufferMemoryRequirements)load("vkGetBufferMemoryRequirements", userptr);
+   vkGetDeviceMemoryCommitment = (PFN_vkGetDeviceMemoryCommitment)load("vkGetDeviceMemoryCommitment", userptr);
+   vkGetDeviceProcAddr = (PFN_vkGetDeviceProcAddr)load("vkGetDeviceProcAddr", userptr);
+   vkGetDeviceQueue = (PFN_vkGetDeviceQueue)load("vkGetDeviceQueue", userptr);
+   vkGetEventStatus = (PFN_vkGetEventStatus)load("vkGetEventStatus", userptr);
+   vkGetFenceStatus = (PFN_vkGetFenceStatus)load("vkGetFenceStatus", userptr);
+   vkGetImageMemoryRequirements = (PFN_vkGetImageMemoryRequirements)load("vkGetImageMemoryRequirements", userptr);
+   vkGetImageSparseMemoryRequirements = (PFN_vkGetImageSparseMemoryRequirements)load("vkGetImageSparseMemoryRequirements", userptr);
+   vkGetImageSubresourceLayout = (PFN_vkGetImageSubresourceLayout)load("vkGetImageSubresourceLayout", userptr);
+   vkGetInstanceProcAddr = (PFN_vkGetInstanceProcAddr)load("vkGetInstanceProcAddr", userptr);
+   vkGetPhysicalDeviceFeatures = (PFN_vkGetPhysicalDeviceFeatures)load("vkGetPhysicalDeviceFeatures", userptr);
+   vkGetPhysicalDeviceFormatProperties = (PFN_vkGetPhysicalDeviceFormatProperties)load("vkGetPhysicalDeviceFormatProperties", userptr);
+   vkGetPhysicalDeviceImageFormatProperties = (PFN_vkGetPhysicalDeviceImageFormatProperties)load("vkGetPhysicalDeviceImageFormatProperties", userptr);
+   vkGetPhysicalDeviceMemoryProperties = (PFN_vkGetPhysicalDeviceMemoryProperties)load("vkGetPhysicalDeviceMemoryProperties", userptr);
+   vkGetPhysicalDeviceProperties = (PFN_vkGetPhysicalDeviceProperties)load("vkGetPhysicalDeviceProperties", userptr);
+   vkGetPhysicalDeviceQueueFamilyProperties = (PFN_vkGetPhysicalDeviceQueueFamilyProperties)load("vkGetPhysicalDeviceQueueFamilyProperties", userptr);
+   vkGetPhysicalDeviceSparseImageFormatProperties = (PFN_vkGetPhysicalDeviceSparseImageFormatProperties)load("vkGetPhysicalDeviceSparseImageFormatProperties", userptr);
+   vkGetPipelineCacheData = (PFN_vkGetPipelineCacheData)load("vkGetPipelineCacheData", userptr);
+   vkGetQueryPoolResults = (PFN_vkGetQueryPoolResults)load("vkGetQueryPoolResults", userptr);
+   vkGetRenderAreaGranularity = (PFN_vkGetRenderAreaGranularity)load("vkGetRenderAreaGranularity", userptr);
+   vkInvalidateMappedMemoryRanges = (PFN_vkInvalidateMappedMemoryRanges)load("vkInvalidateMappedMemoryRanges", userptr);
+   vkMapMemory = (PFN_vkMapMemory)load("vkMapMemory", userptr);
+   vkMergePipelineCaches = (PFN_vkMergePipelineCaches)load("vkMergePipelineCaches", userptr);
+   vkQueueBindSparse = (PFN_vkQueueBindSparse)load("vkQueueBindSparse", userptr);
+   vkQueueSubmit = (PFN_vkQueueSubmit)load("vkQueueSubmit", userptr);
+   vkQueueWaitIdle = (PFN_vkQueueWaitIdle)load("vkQueueWaitIdle", userptr);
+   vkResetCommandBuffer = (PFN_vkResetCommandBuffer)load("vkResetCommandBuffer", userptr);
+   vkResetCommandPool = (PFN_vkResetCommandPool)load("vkResetCommandPool", userptr);
+   vkResetDescriptorPool = (PFN_vkResetDescriptorPool)load("vkResetDescriptorPool", userptr);
+   vkResetEvent = (PFN_vkResetEvent)load("vkResetEvent", userptr);
+   vkResetFences = (PFN_vkResetFences)load("vkResetFences", userptr);
+   vkSetEvent = (PFN_vkSetEvent)load("vkSetEvent", userptr);
+   vkUnmapMemory = (PFN_vkUnmapMemory)load("vkUnmapMemory", userptr);
+   vkUpdateDescriptorSets = (PFN_vkUpdateDescriptorSets)load("vkUpdateDescriptorSets", userptr);
+   vkWaitForFences = (PFN_vkWaitForFences)load("vkWaitForFences", userptr);
+}
+static void glad_vk_load_VK_EXT_debug_report(GLADuserptrloadfunc load, void* userptr) {
+   if (!GLAD_VK_EXT_debug_report) return;
+   vkCreateDebugReportCallbackEXT = (PFN_vkCreateDebugReportCallbackEXT)load("vkCreateDebugReportCallbackEXT", userptr);
+   vkDebugReportMessageEXT = (PFN_vkDebugReportMessageEXT)load("vkDebugReportMessageEXT", userptr);
+   vkDestroyDebugReportCallbackEXT = (PFN_vkDestroyDebugReportCallbackEXT)load("vkDestroyDebugReportCallbackEXT", userptr);
+}
+static void glad_vk_load_VK_KHR_surface(GLADuserptrloadfunc load, void* userptr) {
+   if (!GLAD_VK_KHR_surface) return;
+   vkDestroySurfaceKHR = (PFN_vkDestroySurfaceKHR)load("vkDestroySurfaceKHR", userptr);
+   vkGetPhysicalDeviceSurfaceCapabilitiesKHR = (PFN_vkGetPhysicalDeviceSurfaceCapabilitiesKHR)load("vkGetPhysicalDeviceSurfaceCapabilitiesKHR", userptr);
+   vkGetPhysicalDeviceSurfaceFormatsKHR = (PFN_vkGetPhysicalDeviceSurfaceFormatsKHR)load("vkGetPhysicalDeviceSurfaceFormatsKHR", userptr);
+   vkGetPhysicalDeviceSurfacePresentModesKHR = (PFN_vkGetPhysicalDeviceSurfacePresentModesKHR)load("vkGetPhysicalDeviceSurfacePresentModesKHR", userptr);
+   vkGetPhysicalDeviceSurfaceSupportKHR = (PFN_vkGetPhysicalDeviceSurfaceSupportKHR)load("vkGetPhysicalDeviceSurfaceSupportKHR", userptr);
+}
+static void glad_vk_load_VK_KHR_swapchain(GLADuserptrloadfunc load, void* userptr) {
+   if (!GLAD_VK_KHR_swapchain) return;
+   vkAcquireNextImage2KHR = (PFN_vkAcquireNextImage2KHR)load("vkAcquireNextImage2KHR", userptr);
+   vkAcquireNextImageKHR = (PFN_vkAcquireNextImageKHR)load("vkAcquireNextImageKHR", userptr);
+   vkCreateSwapchainKHR = (PFN_vkCreateSwapchainKHR)load("vkCreateSwapchainKHR", userptr);
+   vkDestroySwapchainKHR = (PFN_vkDestroySwapchainKHR)load("vkDestroySwapchainKHR", userptr);
+   vkGetDeviceGroupPresentCapabilitiesKHR = (PFN_vkGetDeviceGroupPresentCapabilitiesKHR)load("vkGetDeviceGroupPresentCapabilitiesKHR", userptr);
+   vkGetDeviceGroupSurfacePresentModesKHR = (PFN_vkGetDeviceGroupSurfacePresentModesKHR)load("vkGetDeviceGroupSurfacePresentModesKHR", userptr);
+   vkGetPhysicalDevicePresentRectanglesKHR = (PFN_vkGetPhysicalDevicePresentRectanglesKHR)load("vkGetPhysicalDevicePresentRectanglesKHR", userptr);
+   vkGetSwapchainImagesKHR = (PFN_vkGetSwapchainImagesKHR)load("vkGetSwapchainImagesKHR", userptr);
+   vkQueuePresentKHR = (PFN_vkQueuePresentKHR)load("vkQueuePresentKHR", userptr);
+}
+
+
+
+static int glad_vk_get_extensions(VkPhysicalDevice physical_device, uint32_t* out_extension_count, char*** out_extensions) {
+   uint32_t i;
+   uint32_t instance_extension_count = 0;
+   uint32_t device_extension_count = 0;
+   uint32_t max_extension_count;
+   uint32_t total_extension_count;
+   char** extensions;
+   VkExtensionProperties* ext_properties;
+   VkResult result;
+
+   if (vkEnumerateInstanceExtensionProperties == NULL || (physical_device != NULL && vkEnumerateDeviceExtensionProperties == NULL)) {
+      return 0;
+   }
+
+   result = vkEnumerateInstanceExtensionProperties(NULL, &instance_extension_count, NULL);
+   if (result != VK_SUCCESS) {
+      return 0;
+   }
+
+   if (physical_device != NULL) {
+      result = vkEnumerateDeviceExtensionProperties(physical_device, NULL, &device_extension_count, NULL);
+      if (result != VK_SUCCESS) {
+         return 0;
+      }
+   }
+
+   total_extension_count = instance_extension_count + device_extension_count;
+   max_extension_count = instance_extension_count > device_extension_count
+      ? instance_extension_count : device_extension_count;
+
+   ext_properties = (VkExtensionProperties*)malloc(max_extension_count * sizeof(VkExtensionProperties));
+   if (ext_properties == NULL) {
+      return 0;
+   }
+
+   result = vkEnumerateInstanceExtensionProperties(NULL, &instance_extension_count, ext_properties);
+   if (result != VK_SUCCESS) {
+      free((void*)ext_properties);
+      return 0;
+   }
+
+   extensions = (char**)calloc(total_extension_count, sizeof(char*));
+   if (extensions == NULL) {
+      free((void*)ext_properties);
+      return 0;
+   }
+
+   for (i = 0; i < instance_extension_count; ++i) {
+      VkExtensionProperties ext = ext_properties[i];
+
+      size_t extension_name_length = strlen(ext.extensionName) + 1;
+      extensions[i] = (char*)malloc(extension_name_length * sizeof(char));
+      memcpy(extensions[i], ext.extensionName, extension_name_length * sizeof(char));
+   }
+
+   if (physical_device != NULL) {
+      result = vkEnumerateDeviceExtensionProperties(physical_device, NULL, &device_extension_count, ext_properties);
+      if (result != VK_SUCCESS) {
+         for (i = 0; i < instance_extension_count; ++i) {
+            free((void*)extensions[i]);
+         }
+         free(extensions);
+         return 0;
+      }
+
+      for (i = 0; i < device_extension_count; ++i) {
+         VkExtensionProperties ext = ext_properties[i];
+
+         size_t extension_name_length = strlen(ext.extensionName) + 1;
+         extensions[instance_extension_count + i] = (char*)malloc(extension_name_length * sizeof(char));
+         memcpy(extensions[instance_extension_count + i], ext.extensionName, extension_name_length * sizeof(char));
+      }
+   }
+
+   free((void*)ext_properties);
+
+   *out_extension_count = total_extension_count;
+   *out_extensions = extensions;
+
+   return 1;
+}
+
+static void glad_vk_free_extensions(uint32_t extension_count, char** extensions) {
+   uint32_t i;
+
+   for (i = 0; i < extension_count; ++i) {
+      free((void*)(extensions[i]));
+   }
+
+   free((void*)extensions);
+}
+
+static int glad_vk_has_extension(const char* name, uint32_t extension_count, char** extensions) {
+   uint32_t i;
+
+   for (i = 0; i < extension_count; ++i) {
+      if (strcmp(name, extensions[i]) == 0) {
+         return 1;
+      }
+   }
+
+   return 0;
+}
+
+static GLADapiproc glad_vk_get_proc_from_userptr(const char* name, void* userptr) {
+   return (GLAD_GNUC_EXTENSION(GLADapiproc(*)(const char* name)) userptr)(name);
+}
+
+static int glad_vk_find_extensions_vulkan(VkPhysicalDevice physical_device) {
+   uint32_t extension_count = 0;
+   char** extensions = NULL;
+   if (!glad_vk_get_extensions(physical_device, &extension_count, &extensions)) return 0;
+
+   GLAD_VK_EXT_debug_report = glad_vk_has_extension("VK_EXT_debug_report", extension_count, extensions);
+   GLAD_VK_KHR_surface = glad_vk_has_extension("VK_KHR_surface", extension_count, extensions);
+   GLAD_VK_KHR_swapchain = glad_vk_has_extension("VK_KHR_swapchain", extension_count, extensions);
+
+   glad_vk_free_extensions(extension_count, extensions);
+
+   return 1;
+}
+
+static int glad_vk_find_core_vulkan(VkPhysicalDevice physical_device) {
+   int major = 1;
+   int minor = 0;
+
+#ifdef VK_VERSION_1_1
+   if (vkEnumerateInstanceVersion != NULL) {
+      uint32_t version;
+      VkResult result;
+
+      result = vkEnumerateInstanceVersion(&version);
+      if (result == VK_SUCCESS) {
+         major = (int)VK_VERSION_MAJOR(version);
+         minor = (int)VK_VERSION_MINOR(version);
+      }
+   }
+#endif
+
+   if (physical_device != NULL && vkGetPhysicalDeviceProperties != NULL) {
+      VkPhysicalDeviceProperties properties;
+      vkGetPhysicalDeviceProperties(physical_device, &properties);
+
+      major = (int)VK_VERSION_MAJOR(properties.apiVersion);
+      minor = (int)VK_VERSION_MINOR(properties.apiVersion);
+   }
+
+   GLAD_VK_VERSION_1_0 = (major == 1 && minor >= 0) || major > 1;
+
+   return GLAD_MAKE_VERSION(major, minor);
+}
+
+int gladLoadVulkanUserPtr(VkPhysicalDevice physical_device, GLADuserptrloadfunc load, void* userptr) {
+   int version;
+
+#ifdef VK_VERSION_1_1
+   vkEnumerateInstanceVersion = (PFN_vkEnumerateInstanceVersion)load("vkEnumerateInstanceVersion", userptr);
+#endif
+   version = glad_vk_find_core_vulkan(physical_device);
+   if (!version) {
+      return 0;
+   }
+
+   glad_vk_load_VK_VERSION_1_0(load, userptr);
+
+   if (!glad_vk_find_extensions_vulkan(physical_device)) return 0;
+   glad_vk_load_VK_EXT_debug_report(load, userptr);
+   glad_vk_load_VK_KHR_surface(load, userptr);
+   glad_vk_load_VK_KHR_swapchain(load, userptr);
+
+
+   return version;
+}
+
+
+int gladLoadVulkan(VkPhysicalDevice physical_device, GLADloadfunc load) {
+   return gladLoadVulkanUserPtr(physical_device, glad_vk_get_proc_from_userptr, GLAD_GNUC_EXTENSION(void*) load);
+}
+
+
+
+
+
+#endif /* GLAD_VULKAN_IMPLEMENTATION */
+
