text: " ""VK API description"""
  
  # Copyright (c) 2015-2016 The Khronos Group Inc.
  # Copyright (c) 2015-2016 Valve Corporation
  # Copyright (c) 2015-2016 LunarG, Inc.
  # Copyright (c) 2015-2016 Google Inc.
  #
  # Licensed under the Apache License, Version 2.0 (the "License");
  # you may not use this file except in compliance with the License.
  # You may obtain a copy of the License at
  #
  #     http://www.apache.org/licenses/LICENSE-2.0
  #
  # Unless required by applicable law or agreed to in writing, software
  # distributed under the License is distributed on an "AS IS" BASIS,
  # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  # See the License for the specific language governing permissions and
  # limitations under the License.
  #
  # Author: Chia-I Wu <olv@lunarg.com>
  # Author: Jon Ashburn <jon@lunarg.com>
  # Author: Courtney Goeltzenleuchter <courtney@LunarG.com>
  # Author: Tobin Ehlis <tobin@lunarg.com>
  # Author: Tony Barbour <tony@LunarG.com>
  # Author: Gwan-gyeong Mun <kk.moon@samsung.com>
  
  class Param(object):
      """A function parameter."""
  
      def __init__(self, ty, name):
          self.ty = ty
          self.name = name
  
      def c(self):
          """Return the parameter in C."""
          idx = self.ty.find("[")
  
          # arrays have a different syntax
          if idx >= 0:
              return "%s %s%s" % (self.ty[:idx], self.name, self.ty[idx:])
          else:
              return "%s %s" % (self.ty, self.name)
  
      def indirection_level(self):
          """Return the level of indirection."""
          return self.ty.count("*") + self.ty.count("[")
  
      def dereferenced_type(self, level=0):
          """Return the type after dereferencing."""
          if not level:
              level = self.indirection_level()
  
          deref = self.ty if level else ""
          while level > 0:
              idx = deref.rfind("[")
              if idx < 0:
                  idx = deref.rfind("*")
              if idx < 0:
                  deref = ""
                  break
              deref = deref[:idx]
              level -= 1;
  
          return deref.rstrip()
  
      def __repr__(self):
          return "Param(\"%s\", \"%s\")" % (self.ty, self.name)
  
  class Proto(object):
      """A function prototype."""
  
      def __init__(self, ret, name, params=[]):
          # the proto has only a param
          if not isinstance(params, list):
              params = [params]
  
          self.ret = ret
          self.name = name
          self.params = params
  
      def c_params(self, need_type=True, need_name=True):
          """Return the parameter list in C."""
          if self.params and (need_type or need_name):
              if need_type and need_name:
                  return ", ".join([param.c() for param in self.params])
              elif need_type:
                  return ", ".join([param.ty for param in self.params])
              else:
                  return ", ".join([param.name for param in self.params])
          else:
              return "void" if need_type else ""
  
      def c_decl(self, name, attr="", typed=False, need_param_names=True):
          """Return a named declaration in C."""
          if typed:
              return "%s (%s*%s)(%s)" % (
                  self.ret,
                  attr + "_PTR " if attr else "",
                  name,
                  self.c_params(need_name=need_param_names))
          else:
              return "%s%s %s%s(%s)" % (
                  attr + "_ATTR " if attr else "",
                  self.ret,
                  attr + "_CALL " if attr else "",
                  name,
                  self.c_params(need_name=need_param_names))
  
      def c_pretty_decl(self, name, attr=""):
          """Return a named declaration in C, with vulkan.h formatting."""
          plist = []
          for param in self.params:
              idx = param.ty.find("[")
              if idx < 0:
                  idx = len(param.ty)
  
              pad = 44 - idx
              if pad <= 0:
                  pad = 1
  
              plist.append("    %s%s%s%s" % (param.ty[:idx],
                  " " * pad, param.name, param.ty[idx:]))
  
          return "%s%s %s%s(\n%s)" % (
                  attr + "_ATTR " if attr else "",
                  self.ret,
                  attr + "_CALL " if attr else "",
                  name,
                  ",\n".join(plist))
  
      def c_typedef(self, suffix="", attr=""):
          """Return the typedef for the prototype in C."""
          return self.c_decl(self.name + suffix, attr=attr, typed=True)
  
      def c_func(self, prefix="", attr=""):
          """Return the prototype in C."""
          return self.c_decl(prefix + self.name, attr=attr, typed=False)
  
      def c_call(self):
          """Return a call to the prototype in C."""
          return "%s(%s)" % (self.name, self.c_params(need_type=False))
  
      def object_in_params(self):
          """Return the params that are simple VK objects and are inputs."""
          return [param for param in self.params if param.ty in objects]
  
      def object_out_params(self):
          """Return the params that are simple VK objects and are outputs."""
          return [param for param in self.params
                  if param.dereferenced_type() in objects]
  
      def __repr__(self):
          param_strs = []
          for param in self.params:
              param_strs.append(str(param))
          param_str = "    [%s]" % (",\n     ".join(param_strs))
  
          return "Proto(\"%s\", \"%s\",\n%s)" % \
                  (self.ret, self.name, param_str)
  
  class Extension(object):
      def __init__(self, name, headers, objects, protos, ifdef = None):
          self.name = name
          self.headers = headers
          self.objects = objects
          self.protos = protos
          self.ifdef = ifdef
  
      def __repr__(self):
          lines = []
          lines.append("Extension(")
          lines.append("    name=\"%s\"," % self.name)
          lines.append("    headers=[\"%s\"]," %
                  "\", \"".join(self.headers))
  
          lines.append("    objects=[")
          for obj in self.objects:
              lines.append("        \"%s\"," % obj)
          lines.append("    ],")
  
          lines.append("    protos=[")
          for proto in self.protos:
              param_lines = str(proto).splitlines()
              param_lines[-1] += ",\n" if proto != self.protos[-1] else ","
              for p in param_lines:
                  lines.append("        " + p)
          lines.append("    ],")
          lines.append(")")
  
          return "\n".join(lines)
  
  # VK core API
  core = Extension(
      name="VK_CORE",
      headers=["vulkan/vulkan.h"],
      objects=[
          "VkInstance",
          "VkPhysicalDevice",
          "VkDevice",
          "VkQueue",
          "VkSemaphore",
          "VkCommandBuffer",
          "VkFence",
          "VkDeviceMemory",
          "VkBuffer",
          "VkImage",
          "VkEvent",
          "VkQueryPool",
          "VkBufferView",
          "VkImageView",
          "VkShaderModule",
          "VkPipelineCache",
          "VkPipelineLayout",
          "VkRenderPass",
          "VkPipeline",
          "VkDescriptorSetLayout",
          "VkSampler",
          "VkDescriptorPool",
          "VkDescriptorSet",
          "VkFramebuffer",
          "VkCommandPool",
      ],
      protos=[
          Proto("VkResult", "CreateInstance",
              [Param("const VkInstanceCreateInfo*", "pCreateInfo"),
               Param("const VkAllocationCallbacks*", "pAllocator"),
               Param("VkInstance*", "pInstance")]),
  
          Proto("void", "DestroyInstance",
              [Param("VkInstance", "instance"),
               Param("const VkAllocationCallbacks*", "pAllocator")]),
  
          Proto("VkResult", "EnumeratePhysicalDevices",
              [Param("VkInstance", "instance"),
               Param("uint32_t*", "pPhysicalDeviceCount"),
               Param("VkPhysicalDevice*", "pPhysicalDevices")]),
  
          Proto("void", "GetPhysicalDeviceFeatures",
              [Param("VkPhysicalDevice", "physicalDevice"),
               Param("VkPhysicalDeviceFeatures*", "pFeatures")]),
  
          Proto("void", "GetPhysicalDeviceFormatProperties",
              [Param("VkPhysicalDevice", "physicalDevice"),
               Param("VkFormat", "format"),
               Param("VkFormatProperties*", "pFormatProperties")]),
  
          Proto("VkResult", "GetPhysicalDeviceImageFormatProperties",
              [Param("VkPhysicalDevice", "physicalDevice"),
               Param("VkFormat", "format"),
               Param("VkImageType", "type"),
               Param("VkImageTiling", "tiling"),
               Param("VkImageUsageFlags", "usage"),
               Param("VkImageCreateFlags", "flags"),
               Param("VkImageFormatProperties*", "pImageFormatProperties")]),
  
          Proto("void", "GetPhysicalDeviceProperties",
              [Param("VkPhysicalDevice", "physicalDevice"),
               Param("VkPhysicalDeviceProperties*", "pProperties")]),
  
          Proto("void", "GetPhysicalDeviceQueueFamilyProperties",
              [Param("VkPhysicalDevice", "physicalDevice"),
               Param("uint32_t*", "pQueueFamilyPropertyCount"),
               Param("VkQueueFamilyProperties*", "pQueueFamilyProperties")]),
  
          Proto("void", "GetPhysicalDeviceMemoryProperties",
              [Param("VkPhysicalDevice", "physicalDevice"),
               Param("VkPhysicalDeviceMemoryProperties*", "pMemoryProperties")]),
  
          Proto("PFN_vkVoidFunction", "GetInstanceProcAddr",
              [Param("VkInstance", "instance"),
               Param("const char*", "pName")]),
  
          Proto("PFN_vkVoidFunction", "GetDeviceProcAddr",
              [Param("VkDevice", "device"),
               Param("const char*", "pName")]),
  
          Proto("VkResult", "CreateDevice",
              [Param("VkPhysicalDevice", "physicalDevice"),
               Param("const VkDeviceCreateInfo*", "pCreateInfo"),
               Param("const VkAllocationCallbacks*", "pAllocator"),
               Param("VkDevice*", "pDevice")]),
  
          Proto("void", "DestroyDevice",
              [Param("VkDevice", "device"),
               Param("const VkAllocationCallbacks*", "pAllocator")]),
  
          Proto("VkResult", "EnumerateInstanceExtensionProperties",
              [Param("const char*", "pLayerName"),
               Param("uint32_t*", "pPropertyCount"),
               Param("VkExtensionProperties*", "pProperties")]),
  
          Proto("VkResult", "EnumerateDeviceExtensionProperties",
              [Param("VkPhysicalDevice", "physicalDevice"),
               Param("const char*", "pLayerName"),
               Param("uint32_t*", "pPropertyCount"),
               Param("VkExtensionProperties*", "pProperties")]),
  
          Proto("VkResult", "EnumerateInstanceLayerProperties",
              [Param("uint32_t*", "pPropertyCount"),
               Param("VkLayerProperties*", "pProperties")]),
  
          Proto("VkResult", "EnumerateDeviceLayerProperties",
              [Param("VkPhysicalDevice", "physicalDevice"),
               Param("uint32_t*", "pPropertyCount"),
               Param("VkLayerProperties*", "pProperties")]),
  
          Proto("void", "GetDeviceQueue",
              [Param("VkDevice", "device"),
               Param("uint32_t", "queueFamilyIndex"),
               Param("uint32_t", "queueIndex"),
               Param("VkQueue*", "pQueue")]),
  
          Proto("VkResult", "QueueSubmit",
              [Param("VkQueue", "queue"),
               Param("uint32_t", "submitCount"),
               Param("const VkSubmitInfo*", "pSubmits"),
               Param("VkFence", "fence")]),
  
          Proto("VkResult", "QueueWaitIdle",
              [Param("VkQueue", "queue")]),
  
          Proto("VkResult", "DeviceWaitIdle",
              [Param("VkDevice", "device")]),
  
          Proto("VkResult", "AllocateMemory",
              [Param("VkDevice", "device"),
               Param("const VkMemoryAllocateInfo*", "pAllocateInfo"),
               Param("const VkAllocationCallbacks*", "pAllocator"),
               Param("VkDeviceMemory*", "pMemory")]),
  
          Proto("void", "FreeMemory",
              [Param("VkDevice", "device"),
               Param("VkDeviceMemory", "memory"),
               Param("const VkAllocationCallbacks*", "pAllocator")]),
  
          Proto("VkResult", "MapMemory",
              [Param("VkDevice", "device"),
               Param("VkDeviceMemory", "memory"),
               Param("VkDeviceSize", "offset"),
               Param("VkDeviceSize", "size"),
               Param("VkMemoryMapFlags", "flags"),
               Param("void**", "ppData")]),
  
          Proto("void", "UnmapMemory",
              [Param("VkDevice", "device"),
               Param("VkDeviceMemory", "memory")]),
  
          Proto("VkResult", "FlushMappedMemoryRanges",
              [Param("VkDevice", "device"),
               Param("uint32_t", "memoryRangeCount"),
               Param("const VkMappedMemoryRange*", "pMemoryRanges")]),
  
          Proto("VkResult", "InvalidateMappedMemoryRanges",
              [Param("VkDevice", "device"),
               Param("uint32_t", "memoryRangeCount"),
               Param("const VkMappedMemoryRange*", "pMemoryRanges")]),
  
          Proto("void", "GetDeviceMemoryCommitment",
              [Param("VkDevice", "device"),
               Param("VkDeviceMemory", "memory"),
               Param("VkDeviceSize*", "pCommittedMemoryInBytes")]),
  
          Proto("VkResult", "BindBufferMemory",
              [Param("VkDevice", "device"),
               Param("VkBuffer", "buffer"),
               Param("VkDeviceMemory", "memory"),
               Param("VkDeviceSize", "memoryOffset")]),
  
          Proto("VkResult", "BindImageMemory",
              [Param("VkDevice", "device"),
               Param("VkImage", "image"),
               Param("VkDeviceMemory", "memory"),
               Param("VkDeviceSize", "memoryOffset")]),
  
          Proto("void", "GetBufferMemoryRequirements",
              [Param("VkDevice", "device"),
               Param("VkBuffer", "buffer"),
               Param("VkMemoryRequirements*", "pMemoryRequirements")]),
  
          Proto("void", "GetImageMemoryRequirements",
              [Param("VkDevice", "device"),
               Param("VkImage", "image"),
               Param("VkMemoryRequirements*", "pMemoryRequirements")]),
  
          Proto("void", "GetImageSparseMemoryRequirements",
              [Param("VkDevice", "device"),
               Param("VkImage", "image"),
               Param("uint32_t*", "pSparseMemoryRequirementCount"),
               Param("VkSparseImageMemoryRequirements*", "pSparseMemoryRequirements")]),
  
          Proto("void", "GetPhysicalDeviceSparseImageFormatProperties",
              [Param("VkPhysicalDevice", "physicalDevice"),
               Param("VkFormat", "format"),
               Param("VkImageType", "type"),
               Param("VkSampleCountFlagBits", "samples"),
               Param("VkImageUsageFlags", "usage"),
               Param("VkImageTiling", "tiling"),
               Param("uint32_t*", "pPropertyCount"),
               Param("VkSparseImageFormatProperties*", "pProperties")]),
  
          Proto("VkResult", "QueueBindSparse",
              [Param("VkQueue", "queue"),
               Param("uint32_t", "bindInfoCount"),
               Param("const VkBindSparseInfo*", "pBindInfo"),
               Param("VkFence", "fence")]),
  
          Proto("VkResult", "CreateFence",
              [Param("VkDevice", "device"),
               Param("const VkFenceCreateInfo*", "pCreateInfo"),
               Param("const VkAllocationCallbacks*", "pAllocator"),
               Param("VkFence*", "pFence")]),
  
          Proto("void", "DestroyFence",
              [Param("VkDevice", "device"),
               Param("VkFence", "fence"),
               Param("const VkAllocationCallbacks*", "pAllocator")]),
  
          Proto("VkResult", "ResetFences",
              [Param("VkDevice", "device"),
               Param("uint32_t", "fenceCount"),
               Param("const VkFence*", "pFences")]),
  
          Proto("VkResult", "GetFenceStatus",
              [Param("VkDevice", "device"),
               Param("VkFence", "fence")]),
  
          Proto("VkResult", "WaitForFences",
              [Param("VkDevice", "device"),
               Param("uint32_t", "fenceCount"),
               Param("const VkFence*", "pFences"),
               Param("VkBool32", "waitAll"),
               Param("uint64_t", "timeout")]),
  
          Proto("VkResult", "CreateSemaphore",
              [Param("VkDevice", "device"),
               Param("const VkSemaphoreCreateInfo*", "pCreateInfo"),
               Param("const VkAllocationCallbacks*", "pAllocator"),
               Param("VkSemaphore*", "pSemaphore")]),
  
          Proto("void", "DestroySemaphore",
              [Param("VkDevice", "device"),
               Param("VkSemaphore", "semaphore"),
               Param("const VkAllocationCallbacks*", "pAllocator")]),
  
          Proto("VkResult", "CreateEvent",
              [Param("VkDevice", "device"),
               Param("const VkEventCreateInfo*", "pCreateInfo"),
               Param("const VkAllocationCallbacks*", "pAllocator"),
               Param("VkEvent*", "pEvent")]),
  
          Proto("void", "DestroyEvent",
              [Param("VkDevice", "device"),
               Param("VkEvent", "event"),
               Param("const VkAllocationCallbacks*", "pAllocator")]),
  
          Proto("VkResult", "GetEventStatus",
              [Param("VkDevice", "device"),
               Param("VkEvent", "event")]),
  
          Proto("VkResult", "SetEvent",
              [Param("VkDevice", "device"),
               Param("VkEvent", "event")]),
  
          Proto("VkResult", "ResetEvent",
              [Param("VkDevice", "device"),
               Param("VkEvent", "event")]),
  
          Proto("VkResult", "CreateQueryPool",
              [Param("VkDevice", "device"),
               Param("const VkQueryPoolCreateInfo*", "pCreateInfo"),
               Param("const VkAllocationCallbacks*", "pAllocator"),
               Param("VkQueryPool*", "pQueryPool")]),
  
          Proto("void", "DestroyQueryPool",
              [Param("VkDevice", "device"),
               Param("VkQueryPool", "queryPool"),
               Param("const VkAllocationCallbacks*", "pAllocator")]),
  
          Proto("VkResult", "GetQueryPoolResults",
              [Param("VkDevice", "device"),
               Param("VkQueryPool", "queryPool"),
               Param("uint32_t", "firstQuery"),
               Param("uint32_t", "queryCount"),
               Param("size_t", "dataSize"),
               Param("void*", "pData"),
               Param("VkDeviceSize", "stride"),
               Param("VkQueryResultFlags", "flags")]),
  
          Proto("VkResult", "CreateBuffer",
              [Param("VkDevice", "device"),
               Param("const VkBufferCreateInfo*", "pCreateInfo"),
               Param("const VkAllocationCallbacks*", "pAllocator"),
               Param("VkBuffer*", "pBuffer")]),
  
          Proto("void", "DestroyBuffer",
              [Param("VkDevice", "device"),
               Param("VkBuffer", "buffer"),
               Param("const VkAllocationCallbacks*", "pAllocator")]),
  
          Proto("VkResult", "CreateBufferView",
              [Param("VkDevice", "device"),
               Param("const VkBufferViewCreateInfo*", "pCreateInfo"),
               Param("const VkAllocationCallbacks*", "pAllocator"),
               Param("VkBufferView*", "pView")]),
  
          Proto("void", "DestroyBufferView",
              [Param("VkDevice", "device"),
               Param("VkBufferView", "bufferView"),
               Param("const VkAllocationCallbacks*", "pAllocator")]),
  
          Proto("VkResult", "CreateImage",
              [Param("VkDevice", "device"),
               Param("const VkImageCreateInfo*", "pCreateInfo"),
               Param("const VkAllocationCallbacks*", "pAllocator"),
               Param("VkImage*", "pImage")]),
  
          Proto("void", "DestroyImage",
              [Param("VkDevice", "device"),
               Param("VkImage", "image"),
               Param("const VkAllocationCallbacks*", "pAllocator")]),
  
          Proto("void", "GetImageSubresourceLayout",
              [Param("VkDevice", "device"),
               Param("VkImage", "image"),
               Param("const VkImageSubresource*", "pSubresource"),
               Param("VkSubresourceLayout*", "pLayout")]),
  
          Proto("VkResult", "CreateImageView",
              [Param("VkDevice", "device"),
               Param("const VkImageViewCreateInfo*", "pCreateInfo"),
               Param("const VkAllocationCallbacks*", "pAllocator"),
               Param("VkImageView*", "pView")]),
  
          Proto("void", "DestroyImageView",
              [Param("VkDevice", "device"),
               Param("VkImageView", "imageView"),
               Param("const VkAllocationCallbacks*", "pAllocator")]),
  
          Proto("VkResult", "CreateShaderModule",
              [Param("VkDevice", "device"),
               Param("const VkShaderModuleCreateInfo*", "pCreateInfo"),
               Param("const VkAllocationCallbacks*", "pAllocator"),
               Param("VkShaderModule*", "pShaderModule")]),
  
          Proto("void", "DestroyShaderModule",
              [Param("VkDevice", "device"),
               Param("VkShaderModule", "shaderModule"),
               Param("const VkAllocationCallbacks*", "pAllocator")]),
  
          Proto("VkResult", "CreatePipelineCache",
              [Param("VkDevice", "device"),
               Param("const VkPipelineCacheCreateInfo*", "pCreateInfo"),
               Param("const VkAllocationCallbacks*", "pAllocator"),
               Param("VkPipelineCache*", "pPipelineCache")]),
  
          Proto("void", "DestroyPipelineCache",
              [Param("VkDevice", "device"),
               Param("VkPipelineCache", "pipelineCache"),
               Param("const VkAllocationCallbacks*", "pAllocator")]),
  
          Proto("VkResult", "GetPipelineCacheData",
              [Param("VkDevice", "device"),
               Param("VkPipelineCache", "pipelineCache"),
               Param("size_t*", "pDataSize"),
               Param("void*", "pData")]),
  
          Proto("VkResult", "MergePipelineCaches",
              [Param("VkDevice", "device"),
               Param("VkPipelineCache", "dstCache"),
               Param("uint32_t", "srcCacheCount"),
               Param("const VkPipelineCache*", "pSrcCaches")]),
  
          Proto("VkResult", "CreateGraphicsPipelines",
              [Param("VkDevice", "device"),
               Param("VkPipelineCache", "pipelineCache"),
               Param("uint32_t", "createInfoCount"),
               Param("const VkGraphicsPipelineCreateInfo*", "pCreateInfos"),
               Param("const VkAllocationCallbacks*", "pAllocator"),
               Param("VkPipeline*", "pPipelines")]),
  
          Proto("VkResult", "CreateComputePipelines",
              [Param("VkDevice", "device"),
               Param("VkPipelineCache", "pipelineCache"),
               Param("uint32_t", "createInfoCount"),
               Param("const VkComputePipelineCreateInfo*", "pCreateInfos"),
               Param("const VkAllocationCallbacks*", "pAllocator"),
               Param("VkPipeline*", "pPipelines")]),
  
          Proto("void", "DestroyPipeline",
              [Param("VkDevice", "device"),
               Param("VkPipeline", "pipeline"),
               Param("const VkAllocationCallbacks*", "pAllocator")]),
  
          Proto("VkResult", "CreatePipelineLayout",
              [Param("VkDevice", "device"),
               Param("const VkPipelineLayoutCreateInfo*", "pCreateInfo"),
               Param("const VkAllocationCallbacks*", "pAllocator"),
               Param("VkPipelineLayout*", "pPipelineLayout")]),
  
          Proto("void", "DestroyPipelineLayout",
              [Param("VkDevice", "device"),
               Param("VkPipelineLayout", "pipelineLayout"),
               Param("const VkAllocationCallbacks*", "pAllocator")]),
  
          Proto("VkResult", "CreateSampler",
              [Param("VkDevice", "device"),
               Param("const VkSamplerCreateInfo*", "pCreateInfo"),
               Param("const VkAllocationCallbacks*", "pAllocator"),
               Param("VkSampler*", "pSampler")]),
  
          Proto("void", "DestroySampler",
              [Param("VkDevice", "device"),
               Param("VkSampler", "sampler"),
               Param("const VkAllocationCallbacks*", "pAllocator")]),
  
          Proto("VkResult", "CreateDescriptorSetLayout",
              [Param("VkDevice", "device"),
               Param("const VkDescriptorSetLayoutCreateInfo*", "pCreateInfo"),
               Param("const VkAllocationCallbacks*", "pAllocator"),
               Param("VkDescriptorSetLayout*", "pSetLayout")]),
  
          Proto("void", "DestroyDescriptorSetLayout",
              [Param("VkDevice", "device"),
               Param("VkDescriptorSetLayout", "descriptorSetLayout"),
               Param("const VkAllocationCallbacks*", "pAllocator")]),
  
          Proto("VkResult", "CreateDescriptorPool",
              [Param("VkDevice", "device"),
               Param("const VkDescriptorPoolCreateInfo*", "pCreateInfo"),
               Param("const VkAllocationCallbacks*", "pAllocator"),
               Param("VkDescriptorPool*", "pDescriptorPool")]),
  
          Proto("void", "DestroyDescriptorPool",
              [Param("VkDevice", "device"),
               Param("VkDescriptorPool", "descriptorPool"),
               Param("const VkAllocationCallbacks*", "pAllocator")]),
  
          Proto("VkResult", "ResetDescriptorPool",
              [Param("VkDevice", "device"),
               Param("VkDescriptorPool", "descriptorPool"),
               Param("VkDescriptorPoolResetFlags", "flags")]),
  
          Proto("VkResult", "AllocateDescriptorSets",
              [Param("VkDevice", "device"),
               Param("const VkDescriptorSetAllocateInfo*", "pAllocateInfo"),
               Param("VkDescriptorSet*", "pDescriptorSets")]),
  
          Proto("VkResult", "FreeDescriptorSets",
              [Param("VkDevice", "device"),
               Param("VkDescriptorPool", "descriptorPool"),
               Param("uint32_t", "descriptorSetCount"),
               Param("const VkDescriptorSet*", "pDescriptorSets")]),
  
          Proto("void", "UpdateDescriptorSets",
              [Param("VkDevice", "device"),
               Param("uint32_t", "descriptorWriteCount"),
               Param("const VkWriteDescriptorSet*", "pDescriptorWrites"),
               Param("uint32_t", "descriptorCopyCount"),
               Param("const VkCopyDescriptorSet*", "pDescriptorCopies")]),
  
          Proto("VkResult", "CreateFramebuffer",
              [Param("VkDevice", "device"),
               Param("const VkFramebufferCreateInfo*", "pCreateInfo"),
               Param("const VkAllocationCallbacks*", "pAllocator"),
               Param("VkFramebuffer*", "pFramebuffer")]),
  
          Proto("void", "DestroyFramebuffer",
              [Param("VkDevice", "device"),
               Param("VkFramebuffer", "framebuffer"),
               Param("const VkAllocationCallbacks*", "pAllocator")]),
  
          Proto("VkResult", "CreateRenderPass",
              [Param("VkDevice", "device"),
               Param("const VkRenderPassCreateInfo*", "pCreateInfo"),
               Param("const VkAllocationCallbacks*", "pAllocator"),
               Param("VkRenderPass*", "pRenderPass")]),
  
          Proto("void", "DestroyRenderPass",
              [Param("VkDevice", "device"),
               Param("VkRenderPass", "renderPass"),
               Param("const VkAllocationCallbacks*", "pAllocator")]),
  
          Proto("void", "GetRenderAreaGranularity",
              [Param("VkDevice", "device"),
               Param("VkRenderPass", "renderPass"),
               Param("VkExtent2D*", "pGranularity")]),
  
          Proto("VkResult", "CreateCommandPool",
              [Param("VkDevice", "device"),
               Param("const VkCommandPoolCreateInfo*", "pCreateInfo"),
               Param("const VkAllocationCallbacks*", "pAllocator"),
               Param("VkCommandPool*", "pCommandPool")]),
  
          Proto("void", "DestroyCommandPool",
              [Param("VkDevice", "device"),
               Param("VkCommandPool", "commandPool"),
               Param("const VkAllocationCallbacks*", "pAllocator")]),
  
          Proto("VkResult", "ResetCommandPool",
              [Param("VkDevice", "device"),
               Param("VkCommandPool", "commandPool"),
               Param("VkCommandPoolResetFlags", "flags")]),
  
          Proto("VkResult", "AllocateCommandBuffers",
              [Param("VkDevice", "device"),
               Param("const VkCommandBufferAllocateInfo*", "pAllocateInfo"),
               Param("VkCommandBuffer*", "pCommandBuffers")]),
  
          Proto("void", "FreeCommandBuffers",
              [Param("VkDevice", "device"),
               Param("VkCommandPool", "commandPool"),
               Param("uint32_t", "commandBufferCount"),
               Param("const VkCommandBuffer*", "pCommandBuffers")]),
  
          Proto("VkResult", "BeginCommandBuffer",
              [Param("VkCommandBuffer", "commandBuffer"),
               Param("const VkCommandBufferBeginInfo*", "pBeginInfo")]),
  
          Proto("VkResult", "EndCommandBuffer",
              [Param("VkCommandBuffer", "commandBuffer")]),
  
          Proto("VkResult", "ResetCommandBuffer",
              [Param("VkCommandBuffer", "commandBuffer"),
               Param("VkCommandBufferResetFlags", "flags")]),
  
          Proto("void", "CmdBindPipeline",
              [Param("VkCommandBuffer", "commandBuffer"),
               Param("VkPipelineBindPoint", "pipelineBindPoint"),
               Param("VkPipeline", "pipeline")]),
  
          Proto("void", "CmdSetViewport",
              [Param("VkCommandBuffer", "commandBuffer"),
               Param("uint32_t", "firstViewport"),
               Param("uint32_t", "viewportCount"),
               Param("const VkViewport*", "pViewports")]),
  
          Proto("void", "CmdSetScissor",
              [Param("VkCommandBuffer", "commandBuffer"),
               Param("uint32_t", "firstScissor"),
               Param("uint32_t", "scissorCount"),
               Param("const VkRect2D*", "pScissors")]),
  
          Proto("void", "CmdSetLineWidth",
              [Param("VkCommandBuffer", "commandBuffer"),
               Param("float", "lineWidth")]),
  
          Proto("void", "CmdSetDepthBias",
              [Param("VkCommandBuffer", "commandBuffer"),
               Param("float", "depthBiasConstantFactor"),
               Param("float", "depthBiasClamp"),
               Param("float", "depthBiasSlopeFactor")]),
  
          Proto("void", "CmdSetBlendConstants",
              [Param("VkCommandBuffer", "commandBuffer"),
               Param("const float[4]", "blendConstants")]),
  
          Proto("void", "CmdSetDepthBounds",
              [Param("VkCommandBuffer", "commandBuffer"),
               Param("float", "minDepthBounds"),
               Param("float", "maxDepthBounds")]),
  
          Proto("void", "CmdSetStencilCompareMask",
              [Param("VkCommandBuffer", "commandBuffer"),
               Param("VkStencilFaceFlags", "faceMask"),
               Param("uint32_t", "compareMask")]),
  
          Proto("void", "CmdSetStencilWriteMask",
              [Param("VkCommandBuffer", "commandBuffer"),
               Param("VkStencilFaceFlags", "faceMask"),
               Param("uint32_t", "writeMask")]),
  
          Proto("void", "CmdSetStencilReference",
              [Param("VkCommandBuffer", "commandBuffer"),
               Param("VkStencilFaceFlags", "faceMask"),
               Param("uint32_t", "reference")]),
  
          Proto("void", "CmdBindDescriptorSets",
              [Param("VkCommandBuffer", "commandBuffer"),
               Param("VkPipelineBindPoint", "pipelineBindPoint"),
               Param("VkPipelineLayout", "layout"),
               Param("uint32_t", "firstSet"),
               Param("uint32_t", "descriptorSetCount"),
               Param("const VkDescriptorSet*", "pDescriptorSets"),
               Param("uint32_t", "dynamicOffsetCount"),
               Param("const uint32_t*", "pDynamicOffsets")]),
  
          Proto("void", "CmdBindIndexBuffer",
              [Param("VkCommandBuffer", "commandBuffer"),
               Param("VkBuffer", "buffer"),
               Param("VkDeviceSize", "offset"),
               Param("VkIndexType", "indexType")]),
  
          Proto("void", "CmdBindVertexBuffers",
              [Param("VkCommandBuffer", "commandBuffer"),
               Param("uint32_t", "firstBinding"),
               Param("uint32_t", "bindingCount"),
               Param("const VkBuffer*", "pBuffers"),
               Param("const VkDeviceSize*", "pOffsets")]),
  
          Proto("void", "CmdDraw",
              [Param("VkCommandBuffer", "commandBuffer"),
               Param("uint32_t", "vertexCount"),
               Param("uint32_t", "instanceCount"),
               Param("uint32_t", "firstVertex"),
               Param("uint32_t", "firstInstance")]),
  
          Proto("void", "CmdDrawIndexed",
              [Param("VkCommandBuffer", "commandBuffer"),
               Param("uint32_t", "indexCount"),
               Param("uint32_t", "instanceCount"),
               Param("uint32_t", "firstIndex"),
               Param("int32_t", "vertexOffset"),
               Param("uint32_t", "firstInstance")]),
  
          Proto("void", "CmdDrawIndirect",
              [Param("VkCommandBuffer", "commandBuffer"),
               Param("VkBuffer", "buffer"),
               Param("VkDeviceSize", "offset"),
               Param("uint32_t", "drawCount"),
               Param("uint32_t", "stride")]),
  
          Proto("void", "CmdDrawIndexedIndirect",
              [Param("VkCommandBuffer", "commandBuffer"),
               Param("VkBuffer", "buffer"),
               Param("VkDeviceSize", "offset"),
               Param("uint32_t", "drawCount"),
               Param("uint32_t", "stride")]),
  
          Proto("void", "CmdDispatch",
              [Param("VkCommandBuffer", "commandBuffer"),
               Param("uint32_t", "x"),
               Param("uint32_t", "y"),
               Param("uint32_t", "z")]),
  
          Proto("void", "CmdDispatchIndirect",
              [Param("VkCommandBuffer", "commandBuffer"),
               Param("VkBuffer", "buffer"),
               Param("VkDeviceSize", "offset")]),
  
          Proto("void", "CmdCopyBuffer",
              [Param("VkCommandBuffer", "commandBuffer"),
               Param("VkBuffer", "srcBuffer"),
               Param("VkBuffer", "dstBuffer"),
               Param("uint32_t", "regionCount"),
               Param("const VkBufferCopy*", "pRegions")]),
  
          Proto("void", "CmdCopyImage",
              [Param("VkCommandBuffer", "commandBuffer"),
               Param("VkImage", "srcImage"),
               Param("VkImageLayout", "srcImageLayout"),
               Param("VkImage", "dstImage"),
               Param("VkImageLayout", "dstImageLayout"),
               Param("uint32_t", "regionCount"),
               Param("const VkImageCopy*", "pRegions")]),
  
          Proto("void", "CmdBlitImage",
              [Param("VkCommandBuffer", "commandBuffer"),
               Param("VkImage", "srcImage"),
               Param("VkImageLayout", "srcImageLayout"),
               Param("VkImage", "dstImage"),
               Param("VkImageLayout", "dstImageLayout"),
               Param("uint32_t", "regionCount"),
               Param("const VkImageBlit*", "pRegions"),
               Param("VkFilter", "filter")]),
  
          Proto("void", "CmdCopyBufferToImage",
              [Param("VkCommandBuffer", "commandBuffer"),
               Param("VkBuffer", "srcBuffer"),
               Param("VkImage", "dstImage"),
               Param("VkImageLayout", "dstImageLayout"),
               Param("uint32_t", "regionCount"),
               Param("const VkBufferImageCopy*", "pRegions")]),
  
          Proto("void", "CmdCopyImageToBuffer",
              [Param("VkCommandBuffer", "commandBuffer"),
               Param("VkImage", "srcImage"),
               Param("VkImageLayout", "srcImageLayout"),
               Param("VkBuffer", "dstBuffer"),
               Param("uint32_t", "regionCount"),
               Param("const VkBufferImageCopy*", "pRegions")]),
  
          Proto("void", "CmdUpdateBuffer",
              [Param("VkCommandBuffer", "commandBuffer"),
               Param("VkBuffer", "dstBuffer"),
               Param("VkDeviceSize", "dstOffset"),
               Param("VkDeviceSize", "dataSize"),
               Param("const void*", "pData")]),
  
          Proto("void", "CmdFillBuffer",
              [Param("VkCommandBuffer", "commandBuffer"),
               Param("VkBuffer", "dstBuffer"),
               Param("VkDeviceSize", "dstOffset"),
               Param("VkDeviceSize", "size"),
               Param("uint32_t", "data")]),
  
          Proto("void", "CmdClearColorImage",
              [Param("VkCommandBuffer", "commandBuffer"),
               Param("VkImage", "image"),
               Param("VkImageLayout", "imageLayout"),
               Param("const VkClearColorValue*", "pColor"),
               Param("uint32_t", "rangeCount"),
               Param("const VkImageSubresourceRange*", "pRanges")]),
  
          Proto("void", "CmdClearDepthStencilImage",
              [Param("VkCommandBuffer", "commandBuffer"),
               Param("VkImage", "image"),
               Param("VkImageLayout", "imageLayout"),
               Param("const VkClearDepthStencilValue*", "pDepthStencil"),
               Param("uint32_t", "rangeCount"),
               Param("const VkImageSubresourceRange*", "pRanges")]),
  
          Proto("void", "CmdClearAttachments",
              [Param("VkCommandBuffer", "commandBuffer"),
               Param("uint32_t", "attachmentCount"),
               Param("const VkClearAttachment*", "pAttachments"),
               Param("uint32_t", "rectCount"),
               Param("const VkClearRect*", "pRects")]),
  
          Proto("void", "CmdResolveImage",
              [Param("VkCommandBuffer", "commandBuffer"),
               Param("VkImage", "srcImage"),
               Param("VkImageLayout", "srcImageLayout"),
               Param("VkImage", "dstImage"),
               Param("VkImageLayout", "dstImageLayout"),
               Param("uint32_t", "regionCount"),
               Param("const VkImageResolve*", "pRegions")]),
  
          Proto("void", "CmdSetEvent",
              [Param("VkCommandBuffer", "commandBuffer"),
               Param("VkEvent", "event"),
               Param("VkPipelineStageFlags", "stageMask")]),
  
          Proto("void", "CmdResetEvent",
              [Param("VkCommandBuffer", "commandBuffer"),
               Param("VkEvent", "event"),
               Param("VkPipelineStageFlags", "stageMask")]),
  
          Proto("void", "CmdWaitEvents",
              [Param("VkCommandBuffer", "commandBuffer"),
               Param("uint32_t", "eventCount"),
               Param("const VkEvent*", "pEvents"),
               Param("VkPipelineStageFlags", "srcStageMask"),
               Param("VkPipelineStageFlags", "dstStageMask"),
               Param("uint32_t", "memoryBarrierCount"),
               Param("const VkMemoryBarrier*", "pMemoryBarriers"),
               Param("uint32_t", "bufferMemoryBarrierCount"),
               Param("const VkBufferMemoryBarrier*", "pBufferMemoryBarriers"),
               Param("uint32_t", "imageMemoryBarrierCount"),
               Param("const VkImageMemoryBarrier*", "pImageMemoryBarriers")]),
  
          Proto("void", "CmdPipelineBarrier",
              [Param("VkCommandBuffer", "commandBuffer"),
               Param("VkPipelineStageFlags", "srcStageMask"),
               Param("VkPipelineStageFlags", "dstStageMask"),
               Param("VkDependencyFlags", "dependencyFlags"),
               Param("uint32_t", "memoryBarrierCount"),
               Param("const VkMemoryBarrier*", "pMemoryBarriers"),
               Param("uint32_t", "bufferMemoryBarrierCount"),
               Param("const VkBufferMemoryBarrier*", "pBufferMemoryBarriers"),
               Param("uint32_t", "imageMemoryBarrierCount"),
               Param("const VkImageMemoryBarrier*", "pImageMemoryBarriers")]),
  
          Proto("void", "CmdBeginQuery",
              [Param("VkCommandBuffer", "commandBuffer"),
               Param("VkQueryPool", "queryPool"),
               Param("uint32_t", "query"),
               Param("VkQueryControlFlags", "flags")]),
  
          Proto("void", "CmdEndQuery",
              [Param("VkCommandBuffer", "commandBuffer"),
               Param("VkQueryPool", "queryPool"),
               Param("uint32_t", "query")]),
  
          Proto("void", "CmdResetQueryPool",
              [Param("VkCommandBuffer", "commandBuffer"),
               Param("VkQueryPool", "queryPool"),
               Param("uint32_t", "firstQuery"),
               Param("uint32_t", "queryCount")]),
  
          Proto("void", "CmdWriteTimestamp",
              [Param("VkCommandBuffer", "commandBuffer"),
               Param("VkPipelineStageFlagBits", "pipelineStage"),
               Param("VkQueryPool", "queryPool"),
               Param("uint32_t", "query")]),
  
          Proto("void", "CmdCopyQueryPoolResults",
              [Param("VkCommandBuffer", "commandBuffer"),
               Param("VkQueryPool", "queryPool"),
               Param("uint32_t", "firstQuery"),
               Param("uint32_t", "queryCount"),
               Param("VkBuffer", "dstBuffer"),
               Param("VkDeviceSize", "dstOffset"),
               Param("VkDeviceSize", "stride"),
               Param("VkQueryResultFlags", "flags")]),
  
          Proto("void", "CmdPushConstants",
              [Param("VkCommandBuffer", "commandBuffer"),
               Param("VkPipelineLayout", "layout"),
               Param("VkShaderStageFlags", "stageFlags"),
               Param("uint32_t", "offset"),
               Param("uint32_t", "size"),
               Param("const void*", "pValues")]),
  
          Proto("void", "CmdBeginRenderPass",
              [Param("VkCommandBuffer", "commandBuffer"),
               Param("const VkRenderPassBeginInfo*", "pRenderPassBegin"),
               Param("VkSubpassContents", "contents")]),
  
          Proto("void", "CmdNextSubpass",
              [Param("VkCommandBuffer", "commandBuffer"),
               Param("VkSubpassContents", "contents")]),
  
          Proto("void", "CmdEndRenderPass",
              [Param("VkCommandBuffer", "commandBuffer")]),
  
          Proto("void", "CmdExecuteCommands",
              [Param("VkCommandBuffer", "commandBuffer"),
               Param("uint32_t", "commandBufferCount"),
               Param("const VkCommandBuffer*", "pCommandBuffers")]),
      ],
  )
  
  ext_amd_extension_draw_indirect_count = Extension(
      name="VK_AMD_draw_indirect_count",
      headers=["vulkan/vulkan.h"],
      objects=[],
      protos=[
          Proto("void", "CmdDrawIndirectCountAMD",
              [Param("VkCommandBuffer", "commandBuffer"),
               Param("VkBuffer", "buffer"),
               Param("VkDeviceSize", "offset"),
               Param("VkBuffer", "countBuffer"),
               Param("VkDeviceSize", "countBufferOffset"),
               Param("uint32_t", "maxDrawCount"),
               Param("uint32_t", "stride")]),
  
          Proto("void", "CmdDrawIndexedIndirectCountAMD",
              [Param("VkCommandBuffer", "commandBuffer"),
               Param("VkBuffer", "buffer"),
               Param("VkDeviceSize", "offset"),
               Param("VkBuffer", "countBuffer"),
               Param("VkDeviceSize", "countBufferOffset"),
               Param("uint32_t", "maxDrawCount"),
               Param("uint32_t", "stride")]),
      ],
  )
  
  ext_nv_external_memory_capabilities = Extension(
      name="VK_NV_external_memory_capabilities",
      headers=["vulkan/vulkan.h"],
      objects=[],
      protos=[
          Proto("VkResult", "GetPhysicalDeviceExternalImageFormatPropertiesNV",
              [Param("VkPhysicalDevice", "physicalDevice"),
               Param("VkFormat", "format"),
               Param("VkImageType", "type"),
               Param("VkImageTiling", "tiling"),
               Param("VkImageUsageFlags", "usage"),
               Param("VkImageCreateFlags", "flags"),
               Param("VkExternalMemoryHandleTypeFlagsNV", "externalHandleType"),
               Param("VkExternalImageFormatPropertiesNV*", "pExternalImageFormatProperties")]),
      ],
  )
  
  ext_nv_external_memory_win32 = Extension(
      name="VK_NV_external_memory_win32",
      headers=["vulkan/vulkan.h"],
      objects=[],
      ifdef="VK_USE_PLATFORM_WIN32_KHR",
      protos=[
          Proto("VkResult", "GetMemoryWin32HandleNV",
              [Param("VkDevice", "device"),
               Param("VkDeviceMemory", "memory"),
               Param("VkExternalMemoryHandleTypeFlagsNV", "handleType"),
               Param("HANDLE*", "pHandle")]),
      ],
  )
  
  ext_khr_surface = Extension(
      name="VK_KHR_surface",
      headers=["vulkan/vulkan.h"],
      objects=["vkSurfaceKHR"],
      protos=[
          Proto("void", "DestroySurfaceKHR",
              [Param("VkInstance", "instance"),
               Param("VkSurfaceKHR", "surface"),
               Param("const VkAllocationCallbacks*", "pAllocator")]),
  
          Proto("VkResult", "GetPhysicalDeviceSurfaceSupportKHR",
              [Param("VkPhysicalDevice", "physicalDevice"),
               Param("uint32_t", "queueFamilyIndex"),
               Param("VkSurfaceKHR", "surface"),
               Param("VkBool32*", "pSupported")]),
  
          Proto("VkResult", "GetPhysicalDeviceSurfaceCapabilitiesKHR",
              [Param("VkPhysicalDevice", "physicalDevice"),
               Param("VkSurfaceKHR", "surface"),
               Param("VkSurfaceCapabilitiesKHR*", "pSurfaceCapabilities")]),
  
          Proto("VkResult", "GetPhysicalDeviceSurfaceFormatsKHR",
              [Param("VkPhysicalDevice", "physicalDevice"),
               Param("VkSurfaceKHR", "surface"),
               Param("uint32_t*", "pSurfaceFormatCount"),
               Param("VkSurfaceFormatKHR*", "pSurfaceFormats")]),
  
          Proto("VkResult", "GetPhysicalDeviceSurfacePresentModesKHR",
              [Param("VkPhysicalDevice", "physicalDevice"),
               Param("VkSurfaceKHR", "surface"),
               Param("uint32_t*", "pPresentModeCount"),
               Param("VkPresentModeKHR*", "pPresentModes")]),
      ],
  )
  
  ext_khr_display = Extension(
      name="VK_KHR_display",
      headers=["vulkan/vulkan.h"],
      objects=['VkSurfaceKHR', 'VkDisplayModeKHR'],
      protos=[
          Proto("VkResult", "GetPhysicalDeviceDisplayPropertiesKHR",
              [Param("VkPhysicalDevice", "physicalDevice"),
               Param("uint32_t*", "pPropertyCount"),
               Param("VkDisplayPropertiesKHR*", "pProperties")]),
  
          Proto("VkResult", "GetPhysicalDeviceDisplayPlanePropertiesKHR",
              [Param("VkPhysicalDevice", "physicalDevice"),
               Param("uint32_t*", "pPropertyCount"),
               Param("VkDisplayPlanePropertiesKHR*", "pProperties")]),
  
          Proto("VkResult", "GetDisplayPlaneSupportedDisplaysKHR",
              [Param("VkPhysicalDevice", "physicalDevice"),
               Param("uint32_t", "planeIndex"),
               Param("uint32_t*", "pDisplayCount"),
               Param("VkDisplayKHR*", "pDisplays")]),
  
          Proto("VkResult", "GetDisplayModePropertiesKHR",
              [Param("VkPhysicalDevice", "physicalDevice"),
               Param("VkDisplayKHR", "display"),
               Param("uint32_t*", "pPropertyCount"),
               Param("VkDisplayModePropertiesKHR*", "pProperties")]),
  
          Proto("VkResult", "CreateDisplayModeKHR",
              [Param("VkPhysicalDevice", "physicalDevice"),
               Param("VkDisplayKHR", "display"),
               Param("const VkDisplayModeCreateInfoKHR*", "pCreateInfo"),
               Param("const VkAllocationCallbacks*", "pAllocator"),
               Param("VkDisplayModeKHR*", "pMode")]),
  
          Proto("VkResult", "GetDisplayPlaneCapabilitiesKHR",
              [Param("VkPhysicalDevice", "physicalDevice"),
               Param("VkDisplayModeKHR", "mode"),
               Param("uint32_t", "planeIndex"),
               Param("VkDisplayPlaneCapabilitiesKHR*", "pCapabilities")]),
  
          Proto("VkResult", "CreateDisplayPlaneSurfaceKHR",
              [Param("VkInstance", "instance"),
               Param("const VkDisplaySurfaceCreateInfoKHR*", "pCreateInfo"),
               Param("const VkAllocationCallbacks*", "pAllocator"),
               Param("VkSurfaceKHR*", "pSurface")]),
      ],
  )
  
  ext_khr_device_swapchain = Extension(
      name="VK_KHR_swapchain",
      headers=["vulkan/vulkan.h"],
      objects=["VkSwapchainKHR"],
      protos=[
          Proto("VkResult", "CreateSwapchainKHR",
              [Param("VkDevice", "device"),
               Param("const VkSwapchainCreateInfoKHR*", "pCreateInfo"),
               Param("const VkAllocationCallbacks*", "pAllocator"),
               Param("VkSwapchainKHR*", "pSwapchain")]),
  
          Proto("void", "DestroySwapchainKHR",
              [Param("VkDevice", "device"),
               Param("VkSwapchainKHR", "swapchain"),
               Param("const VkAllocationCallbacks*", "pAllocator")]),
  
          Proto("VkResult", "GetSwapchainImagesKHR",
              [Param("VkDevice", "device"),
           Param("VkSwapchainKHR", "swapchain"),
           Param("uint32_t*", "pSwapchainImageCount"),
               Param("VkImage*", "pSwapchainImages")]),
  
          Proto("VkResult", "AcquireNextImageKHR",
              [Param("VkDevice", "device"),
               Param("VkSwapchainKHR", "swapchain"),
               Param("uint64_t", "timeout"),
               Param("VkSemaphore", "semaphore"),
               Param("VkFence", "fence"),
               Param("uint32_t*", "pImageIndex")]),
  
          Proto("VkResult", "QueuePresentKHR",
              [Param("VkQueue", "queue"),
               Param("const VkPresentInfoKHR*", "pPresentInfo")]),
      ],
  )
  
  ext_khr_display_swapchain = Extension(
      name="VK_KHR_display_swapchain",
      headers=["vulkan/vulkan.h"],
      objects=["VkDisplayPresentInfoKHR"],
      protos=[
          Proto("VkResult", "CreateSharedSwapchainsKHR",
              [Param("VkDevice", "device"),
               Param("uint32_t", "swapchainCount"),
               Param("const VkSwapchainCreateInfoKHR*", "pCreateInfos"),
               Param("const VkAllocationCallbacks*", "pAllocator"),
               Param("VkSwapchainKHR*", "pSwapchains")]),
      ],
  )
  
  ext_khr_xcb_surface = Extension(
      name="VK_KHR_xcb_surface",
      headers=["vulkan/vulkan.h"],
      objects=[],
      protos=[
          Proto("VkResult", "CreateXcbSurfaceKHR",
              [Param("VkInstance", "instance"),
               Param("const VkXcbSurfaceCreateInfoKHR*", "pCreateInfo"),
               Param("const VkAllocationCallbacks*", "pAllocator"),
               Param("VkSurfaceKHR*", "pSurface")]),
  
          Proto("VkBool32", "GetPhysicalDeviceXcbPresentationSupportKHR",
              [Param("VkPhysicalDevice", "physicalDevice"),
               Param("uint32_t", "queueFamilyIndex"),
               Param("xcb_connection_t*", "connection"),
               Param("xcb_visualid_t", "visual_id")]),
      ],
  )
  ext_khr_xlib_surface = Extension(
      name="VK_KHR_xlib_surface",
      headers=["vulkan/vulkan.h"],
      objects=[],
      ifdef="VK_USE_PLATFORM_XLIB_KHR",
      protos=[
          Proto("VkResult", "CreateXlibSurfaceKHR",
              [Param("VkInstance", "instance"),
               Param("const VkXlibSurfaceCreateInfoKHR*", "pCreateInfo"),
               Param("const VkAllocationCallbacks*", "pAllocator"),
               Param("VkSurfaceKHR*", "pSurface")]),
  
          Proto("VkBool32", "GetPhysicalDeviceXlibPresentationSupportKHR",
              [Param("VkPhysicalDevice", "physicalDevice"),
               Param("uint32_t", "queueFamilyIndex"),
               Param("Display*", "dpy"),
               Param("VisualID", "visualID")]),
      ],
  )
  ext_khr_wayland_surface = Extension(
      name="VK_KHR_wayland_surface",
      headers=["vulkan/vulkan.h"],
      objects=[],
      protos=[
          Proto("VkResult", "CreateWaylandSurfaceKHR",
              [Param("VkInstance", "instance"),
               Param("const VkWaylandSurfaceCreateInfoKHR*", "pCreateInfo"),
               Param("const VkAllocationCallbacks*", "pAllocator"),
               Param("VkSurfaceKHR*", "pSurface")]),
  
          Proto("VkBool32", "GetPhysicalDeviceWaylandPresentationSupportKHR",
              [Param("VkPhysicalDevice", "physicalDevice"),
               Param("uint32_t", "queueFamilyIndex"),
               Param("struct wl_display*", "display")]),
      ],
  )
  ext_khr_mir_surface = Extension(
      name="VK_KHR_mir_surface",
      headers=["vulkan/vulkan.h"],
      objects=[],
      protos=[
          Proto("VkResult", "CreateMirSurfaceKHR",
              [Param("VkInstance", "instance"),
               Param("const VkMirSurfaceCreateInfoKHR*", "pCreateInfo"),
               Param("const VkAllocationCallbacks*", "pAllocator"),
               Param("VkSurfaceKHR*", "pSurface")]),
  
          Proto("VkBool32", "GetPhysicalDeviceMirPresentationSupportKHR",
              [Param("VkPhysicalDevice", "physicalDevice"),
               Param("uint32_t", "queueFamilyIndex"),
               Param("MirConnection*", "connection")]),
      ],
  )
  ext_khr_android_surface = Extension(
      name="VK_KHR_android_surface",
      headers=["vulkan/vulkan.h"],
      objects=[],
      protos=[
          Proto("VkResult", "CreateAndroidSurfaceKHR",
              [Param("VkInstance", "instance"),
               Param("const VkAndroidSurfaceCreateInfoKHR*", "pCreateInfo"),
               Param("const VkAllocationCallbacks*", "pAllocator"),
               Param("VkSurfaceKHR*", "pSurface")]),
      ],
  )
  ext_khr_win32_surface = Extension(
      name="VK_KHR_win32_surface",
      headers=["vulkan/vulkan.h"],
      objects=[],
      protos=[
          Proto("VkResult", "CreateWin32SurfaceKHR",
              [Param("VkInstance", "instance"),
               Param("const VkWin32SurfaceCreateInfoKHR*", "pCreateInfo"),
               Param("const VkAllocationCallbacks*", "pAllocator"),
               Param("VkSurfaceKHR*", "pSurface")]),
  
          Proto("VkBool32", "GetPhysicalDeviceWin32PresentationSupportKHR",
              [Param("VkPhysicalDevice", "physicalDevice"),
               Param("uint32_t", "queueFamilyIndex")]),
      ],
  )
  ext_debug_report = Extension(
      name="VK_EXT_debug_report",
      headers=["vulkan/vulkan.h"],
      objects=[
          "VkDebugReportCallbackEXT",
      ],
      protos=[
          Proto("VkResult", "CreateDebugReportCallbackEXT",
              [Param("VkInstance", "instance"),
               Param("const VkDebugReportCallbackCreateInfoEXT*", "pCreateInfo"),
               Param("const VkAllocationCallbacks*", "pAllocator"),
               Param("VkDebugReportCallbackEXT*", "pCallback")]),
  
          Proto("void", "DestroyDebugReportCallbackEXT",
              [Param("VkInstance", "instance"),
               Param("VkDebugReportCallbackEXT", "callback"),
               Param("const VkAllocationCallbacks*", "pAllocator")]),
  
          Proto("void", "DebugReportMessageEXT",
              [Param("VkInstance", "instance"),
               Param("VkDebugReportFlagsEXT", "flags"),
               Param("VkDebugReportObjectTypeEXT", "objType"),
               Param("uint64_t", "object"),
               Param("size_t", "location"),
               Param("int32_t", "msgCode"),
               Param("const char *", "pLayerPrefix"),
               Param("const char *", "pMsg")]),
      ],
  )
  ext_debug_marker = Extension(
      name="VK_EXT_debug_marker",
      headers=["vulkan/vulkan.h"],
      objects=[
          "VkDebugMarkerObjectNameInfoEXT",
          "VkDebugMarkerObjectTagInfoEXT",
          "VkDebugMarkerMarkerInfoEXT"
      ],
      protos=[
          Proto("VkResult", "DebugMarkerSetObjectTagEXT",
              [Param("VkDevice", "device"),
               Param("VkDebugMarkerObjectTagInfoEXT*", "pTagInfo")]),
  
          Proto("VkResult", "DebugMarkerSetObjectNameEXT",
              [Param("VkDevice", "device"),
               Param("VkDebugMarkerObjectNameInfoEXT*", "pNameInfo")]),
  
          Proto("void", "CmdDebugMarkerBeginEXT",
              [Param("VkCommandBuffer", "commandBuffer"),
               Param("VkDebugMarkerMarkerInfoEXT*", "pMarkerInfo")]),
  
          Proto("void", "CmdDebugMarkerEndEXT",
              [Param("VkCommandBuffer", "commandBuffer")]),
  
          Proto("void", "CmdDebugMarkerInsertEXT",
              [Param("VkCommandBuffer", "commandBuffer"),
               Param("VkDebugMarkerMarkerInfoEXT*", "pMarkerInfo")]),
      ],
  )
  
  import sys
  
  if sys.argv[1] == 'AllPlatforms':
      extensions = [core, ext_khr_surface, ext_khr_device_swapchain, ext_khr_win32_surface, ext_khr_xcb_surface,
                           ext_khr_xlib_surface, ext_khr_wayland_surface, ext_khr_mir_surface, ext_khr_display,
                           ext_khr_android_surface, ext_khr_display_swapchain]
      extensions_all = [core, ext_khr_surface, ext_khr_device_swapchain, ext_khr_win32_surface,
                               ext_khr_xcb_surface, ext_khr_xlib_surface, ext_khr_wayland_surface, ext_khr_mir_surface,
                               ext_khr_display, ext_khr_android_surface, ext_amd_extension_draw_indirect_count,
                               ext_nv_external_memory_capabilities, ext_nv_external_memory_win32,
                               ext_khr_display_swapchain, ext_debug_report, ext_debug_marker]
  else :
      if len(sys.argv) > 3:
          if (sys.platform.startswith('win32') or sys.platform.startswith('msys')) and sys.argv[1] != 'Android':
              extensions = [core, ext_khr_surface, ext_khr_device_swapchain, ext_khr_win32_surface,
                                   ext_khr_display, ext_khr_display_swapchain]
              extensions_all = [core, ext_khr_surface, ext_khr_device_swapchain, ext_khr_win32_surface,
                                        ext_khr_display, ext_amd_extension_draw_indirect_count,
                                        ext_nv_external_memory_capabilities, ext_nv_external_memory_win32,
                                        ext_khr_display_swapchain, ext_debug_report, ext_debug_marker]
          elif sys.platform.startswith('linux') and sys.argv[1] != 'Android':
              extensions = [core, ext_khr_surface, ext_khr_device_swapchain, ext_khr_xcb_surface,
                                   ext_khr_xlib_surface, ext_khr_wayland_surface, ext_khr_mir_surface, ext_khr_display,
                                   ext_khr_display_swapchain]
              extensions_all = [core, ext_khr_surface, ext_khr_device_swapchain, ext_khr_xcb_surface,
                                        ext_khr_xlib_surface, ext_khr_wayland_surface, ext_khr_mir_surface,
                                        ext_khr_display, ext_amd_extension_draw_indirect_count,
                                        ext_nv_external_memory_capabilities, ext_khr_display_swapchain,
                                        ext_debug_report, ext_debug_marker]
          else: # android
              extensions = [core, ext_khr_surface, ext_khr_device_swapchain, ext_khr_android_surface,
                                   ext_khr_display_swapchain]
              extensions_all = [core, ext_khr_surface, ext_khr_device_swapchain, ext_khr_android_surface,
                                        ext_amd_extension_draw_indirect_count, ext_nv_external_memory_capabilities,
                                        ext_khr_display_swapchain, ext_debug_report, ext_debug_marker]
      else :
          if sys.argv[1] == 'Win32' or sys.argv[1] == 'msys':
              extensions = [core, ext_khr_surface, ext_khr_device_swapchain, ext_khr_win32_surface,
                                   ext_khr_display, ext_khr_display_swapchain]
              extensions_all = [core, ext_khr_surface, ext_khr_device_swapchain, ext_khr_win32_surface,
                                        ext_khr_display, ext_amd_extension_draw_indirect_count,
                                        ext_nv_external_memory_capabilities, ext_nv_external_memory_win32,
                                        ext_khr_display_swapchain, ext_debug_report, ext_debug_marker]
          elif sys.argv[1] == 'Android':
              extensions = [core, ext_khr_surface, ext_khr_device_swapchain, ext_khr_android_surface,
                                   ext_khr_display_swapchain]
              extensions_all = [core, ext_khr_surface, ext_khr_device_swapchain, ext_khr_android_surface,
                                        ext_amd_extension_draw_indirect_count, ext_nv_external_memory_capabilities,
                                        ext_khr_display_swapchain, ext_debug_report, ext_debug_marker]
          elif sys.argv[1] == 'Xcb' or sys.argv[1] == 'Xlib' or sys.argv[1] == 'Wayland' or sys.argv[1] == 'Mir' or sys.argv[1] == 'Display':
              extensions = [core, ext_khr_surface, ext_khr_device_swapchain, ext_khr_xcb_surface,
                                   ext_khr_xlib_surface, ext_khr_wayland_surface, ext_khr_mir_surface,
                                   ext_khr_display, ext_khr_display_swapchain]
              extensions_all = [core, ext_khr_surface, ext_khr_device_swapchain, ext_khr_xcb_surface,
                                        ext_khr_xlib_surface, ext_khr_wayland_surface, ext_khr_mir_surface,
                                        ext_khr_display, ext_amd_extension_draw_indirect_count,
                                        ext_nv_external_memory_capabilities, ext_khr_display_swapchain,
                                        ext_debug_report, ext_debug_marker]
          else:
              print('Error: Undefined DisplayServer')
              extensions = []
              extensions_all = []
  
  object_dispatch_list = [
      "VkInstance",
      "VkPhysicalDevice",
      "VkDevice",
      "VkQueue",
      "VkCommandBuffer",
  ]
  
  object_non_dispatch_list = [
      "VkCommandPool",
      "VkFence",
      "VkDeviceMemory",
      "VkBuffer",
      "VkImage",
      "VkSemaphore",
      "VkEvent",
      "VkQueryPool",
      "VkBufferView",
      "VkImageView",
      "VkShaderModule",
      "VkPipelineCache",
      "VkPipelineLayout",
      "VkPipeline",
      "VkDescriptorSetLayout",
      "VkSampler",
      "VkDescriptorPool",
      "VkDescriptorSet",
      "VkRenderPass",
      "VkFramebuffer",
      "VkSwapchainKHR",
      "VkSurfaceKHR",
      "VkDebugReportCallbackEXT",
      "VkDisplayKHR",
      "VkDisplayModeKHR",
  ]
  
  object_type_list = object_dispatch_list + object_non_dispatch_list
  
  headers = []
  objects = []
  protos = []
  for ext in extensions:
      headers.extend(ext.headers)
      objects.extend(ext.objects)
      protos.extend(ext.protos)
  
  proto_names = [proto.name for proto in protos]
  
  headers_all = []
  objects_all = []
  protos_all = []
  for ext in extensions_all:
      headers_all.extend(ext.headers)
      objects_all.extend(ext.objects)
      protos_all.extend(ext.protos)
  
  proto_all_names = [proto.name for proto in protos_all]
  
  def parse_vk_h(filename):
      # read object and protoype typedefs
      object_lines = []
      proto_lines = []
      with open(filename, "r") as fp:
          for line in fp:
              line = line.strip()
              if line.startswith("VK_DEFINE"):
                  begin = line.find("(") + 1
                  end = line.find(",")
                  # extract the object type
                  object_lines.append(line[begin:end])
              if line.startswith("typedef") and line.endswith(");"):
                  if "*PFN_vkVoidFunction" in line:
                      continue
  
                  # drop leading "typedef " and trailing ");"
                  proto_lines.append(line[8:-2])
  
      # parse proto_lines to protos
      protos = []
      for line in proto_lines:
          first, rest = line.split(" (VKAPI_PTR *PFN_vk")
          second, third = rest.split(")(")
  
          # get the return type, no space before "*"
          proto_ret = "*".join([t.rstrip() for t in first.split("*")])
  
          # get the name
          proto_name = second.strip()
  
          # get the list of params
          param_strs = third.split(", ")
          params = []
          for s in param_strs:
              ty, name = s.rsplit(" ", 1)
  
              # no space before "*"
              ty = "*".join([t.rstrip() for t in ty.split("*")])
              # attach [] to ty
              idx = name.rfind("[")
              if idx >= 0:
                  ty += name[idx:]
                  name = name[:idx]
  
              params.append(Param(ty, name))
  
          protos.append(Proto(proto_ret, proto_name, params))
  
      # make them an extension and print
      ext = Extension("VK_CORE",
              headers=["vulkan/vulkan.h"],
              objects=object_lines,
              protos=protos)
      print("core =", str(ext))
  
      print("")
      print("typedef struct VkLayerDispatchTable_")
      print("{")
      for proto in ext.protos:
          print("    PFN_vk%s %s;" % (proto.name, proto.name))
      print("} VkLayerDispatchTable;")
  
  if __name__ == "__main__":
      parse_vk_h("include/vulkan/vulkan.h")
  