vulkan: import api from upstream

Imported from 74e25b28dc0e198a69add358d541b25291bcde82, which
corresponds to header version 0.138.0.

Change-Id: Ia9bde11a213527b1c366eb4b82aec8650ca13666
(cherry picked from commit 4e262baf54382c455c191a4c1417dec8d17e8926)
diff --git a/vulkan/api/platform.api b/vulkan/api/platform.api
new file mode 100644
index 0000000..3da6fed
--- /dev/null
+++ b/vulkan/api/platform.api
@@ -0,0 +1,30 @@
+// Copyright (c) 2015 The Khronos Group Inc.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and/or associated documentation files (the
+// "Materials"), to deal in the Materials without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Materials, and to
+// permit persons to whom the Materials are furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Materials.
+//
+// THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
+
+// Platform types, as defined or included in vk_platform.h
+
+type u64 size_t
+
+type u64 VkDeviceSize
+type u32 VkBool32
+
+type u32 VkSampleMask
+type u32 VkFlags
diff --git a/vulkan/api/templates/asciidoc.tmpl b/vulkan/api/templates/asciidoc.tmpl
new file mode 100644
index 0000000..3009e19
--- /dev/null
+++ b/vulkan/api/templates/asciidoc.tmpl
@@ -0,0 +1,151 @@
+{{Include "vulkan_common.tmpl"}}
+{{if not (Global "AsciiDocPath")}}{{Global "AsciiDocPath" "../../doc/specs/vulkan/"}}{{end}}
+{{$ | Macro "AsciiDoc.Main"}}
+
+
+{{/*
+-------------------------------------------------------------------------------
+  AsciiDoc generation main entry point.
+-------------------------------------------------------------------------------
+*/}}
+{{define "AsciiDoc.Main"}}
+  {{$docPath := Global "AsciiDocPath"}}
+
+  {{/* Generate AsciiDoc files for API enums and bitfields (flags). */}}
+  {{range $e := $.Enums}}
+    {{if not $e.IsBitfield}}
+      {{$filename := print $docPath "enums/" (Macro "EnumName" $e) ".txt"}}
+      {{Macro "AsciiDoc.Write" "Code" (Macro "AsciiDoc.Enum" $e) "File" $filename}}
+    {{else}}
+      {{$filename := print $docPath "flags/" (Macro "EnumName" $e) ".txt"}}
+      {{Macro "AsciiDoc.Write" "Code" (Macro "AsciiDoc.Flag" $e) "File" $filename}}
+    {{end}}
+  {{end}}
+
+  {{/* Generate AsciiDoc files for API commands (protos). */}}
+  {{range $f := (AllCommands $)}}
+    {{if not (GetAnnotation $f "pfn")}}
+      {{$filename := print $docPath "protos/" $f.Name ".txt"}}
+      {{Macro "AsciiDoc.Write" "Code" (Macro "AsciiDoc.Proto" $f) "File" $filename}}
+    {{end}}
+  {{end}}
+
+  {{/* Generate AsciiDoc files for API structs. */}}
+  {{range $c := $.Classes}}
+    {{if not (GetAnnotation $c "internal")}}
+      {{$filename := print $docPath "structs/" $c.Name ".txt"}}
+      {{Macro "AsciiDoc.Write" "Code" (Macro "AsciiDoc.Struct" $c) "File" $filename}}
+    {{end}}
+  {{end}}
+{{end}}
+
+
+{{/*
+-------------------------------------------------------------------------------
+  Emits the AsciiDoc contents for the specified API enum.
+-------------------------------------------------------------------------------
+*/}}
+{{define "AsciiDoc.Enum"}}
+  {{AssertType $ "Enum"}}
+
+  {{Macro "Docs" $.Docs}}
+  typedef enum {
+    {{range $i, $e := $.Entries}}
+      {{Macro "EnumEntry" $e}} = {{AsSigned $e.Value}}, {{Macro "Docs" $e.Docs}}
+    {{end}}
+  ¶
+    {{$name := Macro "EnumName" $ | TrimRight "ABCDEFGHIJKLMNOQRSTUVWXYZ" | SplitPascalCase | Upper | JoinWith "_"}}
+    {{$first := Macro "EnumFirstEntry" $}}
+    {{$last  := Macro "EnumLastEntry" $}}
+    {{$name}}_BEGIN_RANGE = {{$first}},
+    {{$name}}_END_RANGE = {{$last}},
+    {{$name}}_NUM = ({{$last}} - {{$first}} + 1),
+    {{$name}}_MAX_ENUM = 0x7FFFFFFF
+  } {{Macro "EnumName" $}};
+{{end}}
+
+
+{{/*
+-------------------------------------------------------------------------------
+  Emits the AsciiDoc contents for the specified API bitfield.
+-------------------------------------------------------------------------------
+*/}}
+{{define "AsciiDoc.Flag"}}
+  {{AssertType $ "Enum"}}
+
+  {{Macro "Docs" $.Docs}}
+  typedef VkFlags {{Macro "EnumName" $}};
+  {{if $.Entries}}
+  typedef enum {
+  {{range $e := $.Entries}}
+    {{Macro "BitfieldEntryName" $e}} = {{printf "%#.8x" $e.Value}}, {{Macro "Docs" $e.Docs}}
+  {{end}}
+  } {{Macro "EnumName" $ | TrimRight "s"}}Bits;
+  {{end}}
+{{end}}
+
+
+
+{{/*
+-------------------------------------------------------------------------------
+  Emits the AsciiDoc contents for the specified API class.
+-------------------------------------------------------------------------------
+*/}}
+{{define "AsciiDoc.Struct"}}
+  {{AssertType $ "Class"}}
+
+  {{Macro "Docs" $.Docs}}
+  typedef {{if GetAnnotation $ "union"}}union{{else}}struct{{end}} {
+    {{range $f := $.Fields}}
+      {{Node "Type" $f}} {{$f.Name}}{{Macro "ArrayPostfix" (TypeOf $f)}}; {{Macro "Docs" $f.Docs}}
+    {{end}}
+  } {{Macro "StructName" $}};
+{{end}}
+
+
+{{/*
+-------------------------------------------------------------------------------
+  Emits the AsciiDoc contents for the specified API function.
+-------------------------------------------------------------------------------
+*/}}
+{{define "AsciiDoc.Proto"}}
+  {{AssertType $ "Function"}}
+
+  {{Macro "Docs" $.Docs}}
+  {{Node "Type" $.Return}} VKAPI {{Macro "FunctionName" $}}({{Macro "Parameters" $}});
+{{end}}
+
+
+{{/*
+-------------------------------------------------------------------------------
+  Wraps the specified Code in AsciiDoc source tags then writes to the specified File.
+-------------------------------------------------------------------------------
+*/}}
+{{define "AsciiDoc.Write"}}
+  {{AssertType $.Code "string"}}
+  {{AssertType $.File "string"}}
+
+  {{$code := $.Code | Format (Global "clang-format")}}
+  {{JoinWith "\n" (Macro "AsciiDoc.Header") $code (Macro "AsciiDoc.Footer") ""| Write $.File}}
+{{end}}
+
+
+{{/*
+-------------------------------------------------------------------------------
+  Emits an AsciiDoc source header.
+-------------------------------------------------------------------------------
+*/}}
+{{define "AsciiDoc.Header"}}
+[source,{basebackend@docbook:c++:cpp}]
+------------------------------------------------------------------------------
+{{end}}
+
+
+{{/*
+-------------------------------------------------------------------------------
+  Emits an AsciiDoc source footer.
+-------------------------------------------------------------------------------
+*/}}
+{{define "AsciiDoc.Footer"}}
+------------------------------------------------------------------------------
+{{end}}
diff --git a/vulkan/api/templates/vk_xml.tmpl b/vulkan/api/templates/vk_xml.tmpl
new file mode 100644
index 0000000..c040938
--- /dev/null
+++ b/vulkan/api/templates/vk_xml.tmpl
@@ -0,0 +1,422 @@
+{{Include "vulkan_common.tmpl"}}
+{{Macro "DefineGlobals" $}}
+{{$ | Macro "vk.xml" | Reflow 4 | Write "vk.xml"}}
+
+
+{{/*
+-------------------------------------------------------------------------------
+  Entry point
+-------------------------------------------------------------------------------
+*/}}
+{{define "vk.xml"}}
+<?xml version="1.0" encoding="UTF-8"?>
+<registry>
+    »<comment>«
+Copyright (c) 2015 The Khronos Group Inc.

+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and/or associated documentation files (the
+"Materials"), to deal in the Materials without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Materials, and to
+permit persons to whom the Materials are furnished to do so, subject to
+the following conditions:

+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Materials.

+THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.

+------------------------------------------------------------------------

+This file, vk.xml, is the Vulkan API Registry.»
+    </comment>

+    <!-- SECTION: Vulkan type definitions -->
+    <types>»
+        <type name="vk_platform" category="include">#include "vk_platform.h"</type>

+        <type category="define">#define <name>VK_MAKE_VERSION</name>(major, minor, patch) \
+    «((major &lt;&lt; 22) | (minor &lt;&lt; 12) | patch)</type>»

+        <type category="define">// Vulkan API version supported by this file««
+#define <name>VK_API_VERSION</name> <type>VK_MAKE_VERSION</type>({{Global "VERSION_MAJOR"}}, {{Global "VERSION_MINOR"}}, {{Global "VERSION_PATCH"}})</type>

+        »»<type category="define">««
+#if (_MSC_VER &gt;= 1800 || __cplusplus &gt;= 201103L)
+#define <name>VK_NONDISP_HANDLE_OPERATOR_BOOL</name>() explicit operator bool() const { return handle != 0; }
+#else
+#define VK_NONDISP_HANDLE_OPERATOR_BOOL()
+«#endif
+      »»»</type>

+      <type category="define">«««
+#define <name>VK_DEFINE_HANDLE</name>(obj) typedef struct obj##_T* obj;</type>
+      »»»<type category="define">«««
+#if defined(__cplusplus)
+    »»#if (_MSC_VER &gt;= 1800 || __cplusplus &gt;= 201103L)
+        »// The bool operator only works if there are no implicit conversions from an obj to
+        // a bool-compatible type, which can then be used to unintentionally violate type safety.
+        // C++11 and above supports the "explicit" keyword on conversion operators to stop this
+        // from happening. Otherwise users of C++ below C++11 won't get direct access to evaluating
+        // the object handle as a bool in expressions like:
+        //     if (obj) vkDestroy(obj);
+        #define VK_NONDISP_HANDLE_OPERATOR_BOOL() explicit operator bool() const { return handle != 0; }
+    «#else»
+        #define VK_NONDISP_HANDLE_OPERATOR_BOOL()
+    «#endif
+    #define <name>VK_DEFINE_NONDISP_HANDLE</name>(obj) \»
+        struct obj { \
+            obj() { } \
+            obj(uint64_t x) { handle = x; } \
+            obj&amp; operator =(uint64_t x) { handle = x; return *this; } \
+            bool operator==(const obj&amp; other) const { return handle == other.handle; } \
+            bool operator!=(const obj&amp; other) const { return handle != other.handle; } \
+            bool operator!() const { return !handle; } \
+            VK_NONDISP_HANDLE_OPERATOR_BOOL() \
+            uint64_t handle; \
+        };
+««#else
+    »#define VK_DEFINE_NONDISP_HANDLE(obj) typedef struct obj##_T { uint64_t handle; } obj;«
+#endif
+        »»</type>

+        <type requires="vk_platform" name="VkDeviceSize"/>
+        <type requires="vk_platform" name="VkSampleMask"/>
+        <type requires="vk_platform" name="VkFlags"/>
+        <!-- Basic C types, pulled in via vk_platform.h -->
+        <type requires="vk_platform" name="char"/>
+        <type requires="vk_platform" name="float"/>
+        <type requires="vk_platform" name="VkBool32"/>
+        <type requires="vk_platform" name="uint8_t"/>
+        <type requires="vk_platform" name="uint32_t"/>
+        <type requires="vk_platform" name="uint64_t"/>
+        <type requires="vk_platform" name="int32_t"/>
+        <type requires="vk_platform" name="size_t"/>
+        <!-- Bitfield types -->
+        {{range $e := $.Enums}}
+          {{if $e.IsBitfield}}
+            {{$bits := print (Macro "EnumName" $e | TrimRight "s") "Bits"}}
+            <type{{if $e.Entries}} requires="{{$bits}}"{{end}} category="bitmask">typedef <type>VkFlags</type> <name>{{$e.Name}}</name>;</type>§
+            {{if $e.Entries}}{{Macro "XML.Docs" $e.Docs}}
+            {{else}}{{Macro "XML.Docs" (Strings $e.Docs "(no bits yet)")}}
+            {{end}}
+          {{end}}
+        {{end}}

+        <!-- Types which can be void pointers or class pointers, selected at compile time -->
+        {{range $i, $p := $.Pseudonyms}}
+          {{     if (GetAnnotation $p "dispatchHandle")}}
+            {{if Global "VK_DEFINE_HANDLE_TYPE_DEFINED"}}
+              <type category="handle">VK_DEFINE_HANDLE(<name>{{$p.Name}}</name>)</type>
+            {{else}}
+              {{Global "VK_DEFINE_HANDLE_TYPE_DEFINED" "YES"}}
+              <type category="handle"><type>VK_DEFINE_HANDLE</type>(<name>{{$p.Name}}</name>)</type>
+            {{end}}
+          {{else if (GetAnnotation $p "nonDispatchHandle")}}
+            {{if Global "VK_DEFINE_NONDISP_HANDLE_TYPE_DEFINED"}}
+              <type category="handle">VK_DEFINE_NONDISP_HANDLE(<name>{{$p.Name}}</name>)</type>
+            {{else}}
+              {{Global "VK_DEFINE_NONDISP_HANDLE_TYPE_DEFINED" "YES"}}
+              <type category="handle"><type>VK_DEFINE_NONDISP_HANDLE</type>(<name>{{$p.Name}}</name>)</type>
+            {{end}}
+          {{end}}
+        {{end}}

+        <!-- Types generated from corresponding <enums> tags below -->
+        {{range $e := SortBy $.Enums "EnumName"}}
+          {{if and $e.Entries (not (GetAnnotation $e "internal"))}}
+            {{if $e.IsBitfield}}
+              <type name="{{Macro "EnumName" $e | TrimRight "s"}}Bits" category="enum"/>
+            {{else}}
+              <type name="{{$e.Name}}" category="enum"/>
+            {{end}}
+          {{end}}
+        {{end}}

+        <!-- The PFN_vk*Function types are used by VkAllocCallbacks below -->
+        <type>typedef void* (VKAPI *<name>PFN_vkAllocFunction</name>)(«
+          void*                           pUserData,
+          size_t                          size,
+          size_t                          alignment,
+          <type>VkSystemAllocType</type>               allocType);</type>»
+        <type>typedef void (VKAPI *<name>PFN_vkFreeFunction</name>)(«
+          void*                           pUserData,
+          void*                           pMem);</type>»

+        <!-- The PFN_vkVoidFunction type are used by VkGet*ProcAddr below -->
+        <type>typedef void (VKAPI *<name>PFN_vkVoidFunction</name>)(void);</type>

+        <!-- Struct types -->
+        {{range $c := $.Classes}}
+          {{if not (GetAnnotation $c "internal")}}
+            {{Macro "Struct" $c}}
+          {{end}}
+        {{end}}
+    «</types>

+    <!-- SECTION: Vulkan enumerant (token) definitions. -->

+    <enums namespace="VK" comment="Misc. hardcoded constants - not an enumerated type">»
+            <!-- This is part of the header boilerplate -->
+      {{range $d := $.Definitions}}
+        {{if HasPrefix $d.Name "VK_"}}
+        <enum value="{{$d.Expression}}"        name="{{$d.Name}}"/>{{Macro "XML.Docs" $d.Docs}}
+        {{end}}
+      {{end}}
+        <enum value="MAX_FLOAT"  name="VK_LOD_CLAMP_NONE"/>
+        <enum value="UINT32_MAX" name="VK_LAST_MIP_LEVEL"/>
+        <enum value="UINT32_MAX" name="VK_LAST_ARRAY_SLICE"/>
+        <enum value="UINT64_MAX" name="VK_WHOLE_SIZE"/>
+        <enum value="UINT32_MAX" name="VK_ATTACHMENT_UNUSED"/>
+        <enum value="UINT32_MAX" name="VK_QUEUE_FAMILY_IGNORED"/>
+    «</enums>

+    <!-- Unlike OpenGL, most tokens in Vulkan are actual typed enumerants in»
+         their own numeric namespaces. The "name" attribute is the C enum
+         type name, and is pulled in from a <type> definition above
+         (slightly clunky, but retains the type / enum distinction). "type"
+         attributes of "enum" or "bitmask" indicate that these values should
+         be generated inside an appropriate definition. -->«

+    {{range $e := $.Enums}}
+      {{if not (or $e.IsBitfield (GetAnnotation $e "internal"))}}
+        {{Macro "XML.Enum" $e}}
+      {{end}}
+    {{end}}

+    <!-- Flags -->
+    {{range $e := $.Enums}}
+      {{if $e.IsBitfield}}
+        {{Macro "XML.Bitfield" $e}}
+      {{end}}
+    {{end}}

+    <!-- SECTION: Vulkan command definitions -->
+    <commands namespace="vk">»
+    {{range $f := AllCommands $}}
+      {{if not (GetAnnotation $f "pfn")}}
+        {{Macro "XML.Function" $f}}
+      {{end}}
+    {{end}}
+    «</commands>

+    <!-- SECTION: Vulkan API interface definitions -->
+    <feature api="vulkan" name="VK_VERSION_1_0" number="1.0">»
+        <require comment="Header boilerplate">»
+            <type name="vk_platform"/>
+        «</require>
+        <require comment="API version">»
+            <type name="VK_API_VERSION"/>
+        «</require>
+        <require comment="API constants">»
+            <enum name="VK_LOD_CLAMP_NONE"/>
+            <enum name="VK_LAST_MIP_LEVEL"/>
+            <enum name="VK_LAST_ARRAY_SLICE"/>
+            <enum name="VK_WHOLE_SIZE"/>
+            <enum name="VK_ATTACHMENT_UNUSED"/>
+            <enum name="VK_TRUE"/>
+            <enum name="VK_FALSE"/>
+            <enum name="VK_NULL_HANDLE"/>
+        «</require>
+        <require comment="All functions (TODO: split by type)">»
+        {{range $f := AllCommands $}}
+          {{if not (GetAnnotation $f "pfn")}}
+          <command name="{{$f.Name}}"/>
+          {{end}}
+        {{end}}
+        </require>
+        «<require comment="Types not directly used by the API">»
+            <!-- Include <type name="typename"/> here for e.g. structs that»
+                 are not parameter types of commands, but still need to be
+                 defined in the API.
+             «-->
+            <type name="VkBufferMemoryBarrier"/>
+            <type name="VkDispatchIndirectCmd"/>
+            <type name="VkDrawIndexedIndirectCmd"/>
+            <type name="VkDrawIndirectCmd"/>
+            <type name="VkImageMemoryBarrier"/>
+            <type name="VkMemoryBarrier"/>
+        «</require>
+    «</feature>

+    <!-- SECTION: Vulkan extension interface definitions (none yet) -->
+«</registry>
+{{end}}
+
+{{/*
+-------------------------------------------------------------------------------
+  Emits the C declaration for the specified bitfield.
+-------------------------------------------------------------------------------
+*/}}
+{{define "XML.Bitfield"}}
+  {{AssertType $ "Enum"}}
+
+  {{if $.Entries}}
+  <enums namespace="VK" name="{{Macro "EnumName" $ | TrimRight "s"}}Bits" type="bitmask">»
+  {{range $e := $.Entries}}
+    {{$pos := Bitpos $e.Value}}
+    <enum §
+      {{if gt $pos -1}} bitpos="{{$pos}}"    §
+      {{else}}value="{{if $e.Value}}{{printf "0x%.8X" $e.Value}}{{else}}0{{end}}"    §
+      {{end}}name="{{Macro "BitfieldEntryName" $e}}" §
+      {{if $d := $e.Docs}} comment="{{$d | JoinWith "  "}}"{{end}}/>
+  {{end}}
+  «</enums>
+  {{end}}
+
+{{end}}
+
+
+{{/*
+-------------------------------------------------------------------------------
+  Emits the C declaration for the specified enum.
+-------------------------------------------------------------------------------
+*/}}
+{{define "XML.Enum"}}
+  {{AssertType $ "Enum"}}
+
+  <enums namespace="VK" name="{{Macro "EnumName" $}}" type="enum" §
+         expand="{{Macro "EnumName" $ | SplitPascalCase | Upper | JoinWith "_"}}"{{if $.Docs}} comment="{{$.Docs | JoinWith "  "}}"{{end}}>»
+  {{range $i, $e := $.Entries}}
+    <enum value="{{AsSigned $e.Value}}"     name="{{Macro "BitfieldEntryName" $e}}"{{if $e.Docs}} comment="{{$e.Docs | JoinWith "  "}}"{{end}}/>
+  {{end}}
+  {{if $lu := GetAnnotation $ "lastUnused"}}
+    <unused start="{{index $lu.Arguments 0}}"/>
+  {{end}}
+  «</enums>
+{{end}}
+
+
+{{/*
+-------------------------------------------------------------------------------
+  Emits the C declaration for the specified class.
+-------------------------------------------------------------------------------
+*/}}
+{{define "Struct"}}
+  {{AssertType $ "Class"}}
+
+  <type category="{{Macro "StructType" $}}" name="{{Macro "StructName" $}}"{{if $.Docs}} comment="{{$.Docs | JoinWith "  "}}"{{end}}>»
+    {{range $f := $.Fields}}
+    <member>{{Node "XML.Type" $f}}        <name>{{$f.Name}}</name>{{Macro "XML.ArrayPostfix" $f}}</member>{{Macro "XML.Docs" $f.Docs}}
+    {{end}}
+  «</type>
+{{end}}
+
+
+{{/*
+-------------------------------------------------------------------------------
+  Emits either 'struct' or 'union' for the specified class.
+-------------------------------------------------------------------------------
+*/}}
+{{define "StructType"}}
+  {{AssertType $ "Class"}}
+
+  {{if GetAnnotation $ "union"}}union{{else}}struct{{end}}
+{{end}}
+
+
+{{/*
+-------------------------------------------------------------------------------
+  Emits the C function pointer typedef declaration for the specified command.
+-------------------------------------------------------------------------------
+*/}}
+{{define "XML.Function"}}
+  {{AssertType $ "Function"}}
+
+    {{$ts := GetAnnotation $ "threadSafety"}}
+    <command{{if $ts}} threadsafe="{{index $ts.Arguments 0}}"{{end}}>»
+        <proto>{{Node "XML.Type" $.Return}} <name>{{$.Name}}</name></proto>
+        {{range $p := $.CallParameters}}
+          <param>{{Node "XML.Type" $p}} <name>{{$p.Name}}{{Macro "ArrayPostfix" $p}}</name></param>
+        {{end}}
+    «</command>
+{{end}}
+
+
+{{/*
+-------------------------------------------------------------------------------
+  Emits the XML translation for the specified documentation block (string array).
+-------------------------------------------------------------------------------
+*/}}
+{{define "XML.Docs"}}
+  {{if $}} <!-- {{JoinWith "  " $ | Replace "<" "" | Replace ">" ""}} -->{{end}}
+{{end}}
+
+{{/*
+-------------------------------------------------------------------------------
+  Emits the C translation for the specified type.
+-------------------------------------------------------------------------------
+*/}}
+{{define "XML.Type.Class"      }}<type>{{Macro "StructName" $.Type}}</type>{{end}}
+{{define "XML.Type.Pseudonym"  }}<type>{{$.Type.Name}}</type>{{end}}
+{{define "XML.Type.Enum"       }}<type>{{$.Type.Name}}</type>{{end}}
+{{define "XML.Type.StaticArray"}}{{Node "XML.Type" $.Type.ValueType}}{{end}}
+{{define "XML.Type.Pointer"    }}{{if $.Type.Const}}{{Node "XML.ConstType" $.Type.To}}{{else}}{{Node "XML.Type" $.Type.To}}{{end}}*{{end}}
+{{define "XML.Type.Slice"      }}<type>{{Node "XML.Type" $.Type.To}}</type>*{{end}}
+{{define "XML.Type#s8"         }}<type>int8_t</type>{{end}}
+{{define "XML.Type#u8"         }}<type>uint8_t</type>{{end}}
+{{define "XML.Type#s16"        }}<type>int16_t</type>{{end}}
+{{define "XML.Type#u16"        }}<type>uint16_t</type>{{end}}
+{{define "XML.Type#s32"        }}<type>int32_t</type>{{end}}
+{{define "XML.Type#u32"        }}<type>uint32_t</type>{{end}}
+{{define "XML.Type#f32"        }}<type>float</type>{{end}}
+{{define "XML.Type#s64"        }}<type>int64_t</type>{{end}}
+{{define "XML.Type#u64"        }}<type>uint64_t</type>{{end}}
+{{define "XML.Type#f64"        }}<type>double</type>{{end}}
+{{define "XML.Type#char"       }}<type>char</type>{{end}}
+{{define "XML.Type#void"       }}void{{end}}
+
+{{define "XML.ConstType_Default"}}const {{Node "XML.Type" $.Type}}{{end}}
+{{define "XML.ConstType.Pointer"}}{{Node "XML.Type" $.Type}} const{{end}}
+
+
+{{/*
+-------------------------------------------------------------------------------
+  Emits a C type and name for the given parameter
+-------------------------------------------------------------------------------
+*/}}
+{{define "XML.Parameter"}}
+  {{AssertType $ "Parameter"}}
+
+  <type>{{Macro "ParameterType" $}}</type> <name>{{$.Name}}{{Macro "ArrayPostfix" $}}</name>
+{{end}}
+
+{{/*
+-------------------------------------------------------------------------------
+  Emits a comma-separated list of C type-name paired parameters for the given
+  command.
+-------------------------------------------------------------------------------
+*/}}
+{{define "XML.Parameters"}}
+  {{AssertType $ "Function"}}
+
+  {{ForEach $.CallParameters "XML.Parameter" | JoinWith ", "}}
+  {{if not $.CallParameters}}<type>void</type>{{end}}
+{{end}}
+
+
+{{/*
+-------------------------------------------------------------------------------
+  Emits the fixed-size-array postfix for pseudonym types annotated with @array
+-------------------------------------------------------------------------------
+*/}}
+{{define "XML.ArrayPostfix"}}{{Node "XML.ArrayPostfix" $}}{{end}}
+{{define "XML.ArrayPostfix.StaticArray"}}[{{Node "XML.NamedValue" $.Type.SizeExpr}}]{{end}}
+{{define "XML.ArrayPostfix_Default"}}{{end}}
+
+
+{{/*
+-------------------------------------------------------------------------------
+  Emits the value of the given constant, or the <enum> tagged name if existant.
+-------------------------------------------------------------------------------
+*/}}
+{{define "XML.NamedValue.Definition"}}<enum>{{$.Node.Name}}</enum>{{end}}
+{{define "XML.NamedValue.EnumEntry"}}<enum>{{$.Node.Name}}</enum>{{end}}
+{{define "XML.NamedValue_Default"}}{{$.Node}}{{end}}
diff --git a/vulkan/api/templates/vulkan_common.tmpl b/vulkan/api/templates/vulkan_common.tmpl
new file mode 100644
index 0000000..8c27c02
--- /dev/null
+++ b/vulkan/api/templates/vulkan_common.tmpl
@@ -0,0 +1,201 @@
+{{$clang_style := "{BasedOnStyle: Google, AccessModifierOffset: -4, ColumnLimit: 200, ContinuationIndentWidth: 8, IndentWidth: 4, AlignOperands: true, CommentPragmas: '.*'}"}}
+{{Global "clang-format" (Strings "clang-format" "-style" $clang_style)}}
+
+
+{{/*
+-------------------------------------------------------------------------------
+  Emits the C translation for the specified type.
+-------------------------------------------------------------------------------
+*/}}
+{{define "Type.Class"      }}{{if GetAnnotation $.Type "internal"}}struct {{end}}{{Macro "StructName" $.Type}}{{end}}
+{{define "Type.Pseudonym"  }}{{$.Type.Name}}{{end}}
+{{define "Type.Enum"       }}{{$.Type.Name}}{{end}}
+{{define "Type.StaticArray"}}{{Node "Type" $.Type.ValueType}}{{end}}
+{{define "Type.Pointer"    }}{{if $.Type.Const}}{{Node "ConstType" $.Type.To}}{{else}}{{Node "Type" $.Type.To}}{{end}}*{{end}}
+{{define "Type.Slice"      }}{{Log "%T %+v" $.Node $.Node}}{{Node "Type" $.Type.To}}*{{end}}
+{{define "Type#bool"       }}bool{{end}}
+{{define "Type#int"        }}int{{end}}
+{{define "Type#uint"       }}unsigned int{{end}}
+{{define "Type#s8"         }}int8_t{{end}}
+{{define "Type#u8"         }}uint8_t{{end}}
+{{define "Type#s16"        }}int16_t{{end}}
+{{define "Type#u16"        }}uint16_t{{end}}
+{{define "Type#s32"        }}int32_t{{end}}
+{{define "Type#u32"        }}uint32_t{{end}}
+{{define "Type#f32"        }}float{{end}}
+{{define "Type#s64"        }}int64_t{{end}}
+{{define "Type#u64"        }}uint64_t{{end}}
+{{define "Type#f64"        }}double{{end}}
+{{define "Type#void"       }}void{{end}}
+{{define "Type#char"       }}char{{end}}
+
+{{define "ConstType_Default"}}const {{Node "Type" $.Type}}{{end}}
+{{define "ConstType.Pointer"}}{{Node "Type" $.Type}} const{{end}}
+
+
+{{/*
+-------------------------------------------------------------------------------
+  Emits the C translation for the specified documentation block (string array).
+-------------------------------------------------------------------------------
+*/}}
+{{define "Docs"}}
+  {{if $}}// {{$ | JoinWith "\n// "}}{{end}}
+{{end}}
+
+
+{{/*
+-------------------------------------------------------------------------------
+  Emits the name of a bitfield entry.
+-------------------------------------------------------------------------------
+*/}}
+{{define "BitfieldEntryName"}}
+  {{AssertType $ "EnumEntry"}}
+
+  {{Macro "EnumEntry" $}}
+{{end}}
+
+
+{{/*
+-------------------------------------------------------------------------------
+  Emits the name of an enum type.
+-------------------------------------------------------------------------------
+*/}}
+{{define "EnumName"}}{{AssertType $ "Enum"}}{{$.Name}}{{end}}
+
+
+{{/*
+-------------------------------------------------------------------------------
+  Emits the name of an enum entry.
+-------------------------------------------------------------------------------
+*/}}
+{{define "EnumEntry"}}
+  {{AssertType $.Owner "Enum"}}
+  {{AssertType $.Name "string"}}
+
+  {{$.Name}}
+{{end}}
+
+
+{{/*
+-------------------------------------------------------------------------------
+  Emits the name of the first entry of an enum.
+-------------------------------------------------------------------------------
+*/}}
+{{define "EnumFirstEntry"}}
+  {{AssertType $ "Enum"}}
+
+  {{range $i, $e := $.Entries}}
+    {{if not $i}}{{$e.Name}}{{end}}
+  {{end}}
+{{end}}
+
+
+{{/*
+-------------------------------------------------------------------------------
+  Emits the name of the last entry of an enum.
+-------------------------------------------------------------------------------
+*/}}{{define "EnumLastEntry"}}
+  {{AssertType $ "Enum"}}
+
+  {{range $i, $e := $.Entries}}
+    {{if not (HasMore $i $.Entries)}}{{$e.Name}}{{end}}
+  {{end}}
+{{end}}
+
+
+{{/*
+-------------------------------------------------------------------------------
+  Emits the name of a struct (class) type.
+-------------------------------------------------------------------------------
+*/}}
+{{define "StructName"}}{{AssertType $ "Class"}}{{$.Name}}{{end}}
+
+
+{{/*
+-------------------------------------------------------------------------------
+  Emits the name of a function.
+-------------------------------------------------------------------------------
+*/}}
+{{define "FunctionName"}}{{AssertType $ "Function"}}{{$.Name}}{{end}}
+
+
+{{/*
+-------------------------------------------------------------------------------
+  Emits the fixed-size-array postfix for pseudonym types annotated with @array
+-------------------------------------------------------------------------------
+*/}}
+{{define "ArrayPostfix"}}{{Node "ArrayPostfix" $}}{{end}}
+{{define "ArrayPostfix.StaticArray"}}[{{$.Type.Size}}]{{end}}
+{{define "ArrayPostfix_Default"}}{{end}}
+
+
+{{/*
+-------------------------------------------------------------------------------
+  Emits a C type and name for the given parameter
+-------------------------------------------------------------------------------
+*/}}
+{{define "Parameter"}}
+  {{AssertType $ "Parameter"}}
+
+  {{Macro "ParameterType" $}} {{$.Name}}{{Macro "ArrayPostfix" $}}
+{{end}}
+
+
+{{/*
+-------------------------------------------------------------------------------
+  Emits a C name for the given parameter
+-------------------------------------------------------------------------------
+*/}}
+{{define "ParameterName"}}
+  {{AssertType $ "Parameter"}}
+
+  {{$.Name}}
+{{end}}
+
+
+{{/*
+-------------------------------------------------------------------------------
+  Emits a C type for the given parameter
+-------------------------------------------------------------------------------
+*/}}
+{{define "ParameterType"}}{{AssertType $ "Parameter"}}{{Node "Type" $}}{{end}}
+
+
+{{/*
+-------------------------------------------------------------------------------
+  Emits a comma-separated list of C type-name paired parameters for the given
+  command.
+-------------------------------------------------------------------------------
+*/}}
+{{define "Parameters"}}
+  {{AssertType $ "Function"}}
+
+  {{ForEach $.CallParameters "Parameter" | JoinWith ", "}}
+  {{if not $.CallParameters}}void{{end}}
+{{end}}
+
+
+{{/*
+-------------------------------------------------------------------------------
+  Emits the C function pointer name for the specified command.
+-------------------------------------------------------------------------------
+*/}}
+{{define "FunctionPtrName"}}
+  {{AssertType $ "Function"}}
+
+  PFN_{{$.Name}}
+{{end}}
+
+
+{{/*
+-------------------------------------------------------------------------------
+  Parses const variables as text Globals.
+-------------------------------------------------------------------------------
+*/}}
+{{define "DefineGlobals"}}
+  {{AssertType $ "API"}}
+
+  {{range $d := $.Definitions}}
+    {{Global $d.Name $d.Expression}}
+  {{end}}
+{{end}}
diff --git a/vulkan/api/templates/vulkan_h.tmpl b/vulkan/api/templates/vulkan_h.tmpl
new file mode 100644
index 0000000..df0ae6f
--- /dev/null
+++ b/vulkan/api/templates/vulkan_h.tmpl
@@ -0,0 +1,278 @@
+{{Include "vulkan_common.tmpl"}}
+{{Macro "DefineGlobals" $}}
+{{$ | Macro "vulkan.h" | Format (Global "clang-format") | Write "../include/vulkan.h"}}
+
+
+{{/*
+-------------------------------------------------------------------------------
+  Entry point
+-------------------------------------------------------------------------------
+*/}}
+{{define "vulkan.h"}}
+#ifndef __vulkan_h_
+#define __vulkan_h_ 1

+#ifdef __cplusplus
+extern "C" {
+#endif

+/*
+** Copyright (c) 2015 The Khronos Group Inc.
+**
+** Permission is hereby granted, free of charge, to any person obtaining a
+** copy of this software and/or associated documentation files (the
+** "Materials"), to deal in the Materials without restriction, including
+** without limitation the rights to use, copy, modify, merge, publish,
+** distribute, sublicense, and/or sell copies of the Materials, and to
+** permit persons to whom the Materials are furnished to do so, subject to
+** the following conditions:
+**
+** The above copyright notice and this permission notice shall be included
+** in all copies or substantial portions of the Materials.
+**
+** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
+*/

+/*
+** This header is generated from the Khronos Vulkan API Registry.
+**
+*/

+#define VK_VERSION_1_0 1
+#include "vk_platform.h"

+#define VK_MAKE_VERSION(major, minor, patch) ((major << 22) | (minor << 12) | patch)

+// Vulkan API version supported by this file
+#define VK_API_VERSION \
+    VK_MAKE_VERSION({{Global "VERSION_MAJOR"}}, {{Global "VERSION_MINOR"}}, {{Global "VERSION_PATCH"}})

+#define VK_DEFINE_HANDLE(obj) typedef struct obj##_T* obj;

+#if defined(__cplusplus)
+#if (_MSC_VER >= 1800 || __cplusplus >= 201103L)
+// The bool operator only works if there are no implicit conversions from an obj to
+// a bool-compatible type, which can then be used to unintentionally violate type safety.
+// C++11 and above supports the "explicit" keyword on conversion operators to stop this
+// from happening. Otherwise users of C++ below C++11 won't get direct access to evaluating
+// the object handle as a bool in expressions like:
+//     if (obj) vkDestroy(obj);
+#define VK_NONDISP_HANDLE_OPERATOR_BOOL() \
+    explicit operator bool() const { return handle != 0; }
+#else
+#define VK_NONDISP_HANDLE_OPERATOR_BOOL()
+#endif
+#define VK_DEFINE_NONDISP_HANDLE(obj)                                              \
+    struct obj {                                                                   \
+        obj() {}                                                                   \
+        obj(uint64_t x) { handle = x; }                                            \
+        obj& operator=(uint64_t x) {                                               \
+            handle = x;                                                            \
+            return *this;                                                          \
+        }                                                                          \
+        bool operator==(const obj& other) const { return handle == other.handle; } \
+        bool operator!=(const obj& other) const { return handle != other.handle; } \
+        bool operator!() const { return !handle; }                                 \
+        VK_NONDISP_HANDLE_OPERATOR_BOOL()                                          \
+        uint64_t handle;                                                           \
+    };
+#else
+#define VK_DEFINE_NONDISP_HANDLE(obj) \
+    typedef struct obj##_T { uint64_t handle; } obj;
+#endif

+#define VK_LOD_CLAMP_NONE       MAX_FLOAT
+#define VK_LAST_MIP_LEVEL       UINT32_MAX
+#define VK_LAST_ARRAY_SLICE     UINT32_MAX
+#define VK_WHOLE_SIZE           UINT64_MAX
+#define VK_ATTACHMENT_UNUSED    UINT32_MAX
+{{range $d := $.Definitions}}
+  {{if HasPrefix $d.Name "VK_"}}#define {{$d.Name}}  {{$d.Expression}}{{end}}
+{{end}}

+{{range $i, $p := $.Pseudonyms}}
+  {{if GetAnnotation $p "dispatchHandle"}}VK_DEFINE_HANDLE({{$p.Name}})
+  {{else if GetAnnotation $p "nonDispatchHandle"}}VK_DEFINE_NONDISP_HANDLE({{$p.Name}})
+  {{end}}
+{{end}}

+// ------------------------------------------------------------------------------------------------
+// Enumerations

+  {{range $e := $.Enums}}
+    {{if not $e.IsBitfield}}
+      {{Macro "Enum" $e}}
+    {{end}}
+  {{end}}

+// ------------------------------------------------------------------------------------------------
+// Flags

+  {{range $e := $.Enums}}
+    {{if $e.IsBitfield}}
+      {{Macro "Bitfield" $e}}
+    {{end}}
+  {{end}}

+// ------------------------------------------------------------------------------------------------
+// Vulkan structures

+  {{/* Function pointers */}}
+  {{range $f := AllCommands $}}
+    {{if GetAnnotation $f "pfn"}}
+      {{Macro "FunctionTypedef" $f}}
+    {{end}}
+  {{end}}

+  {{range $c := $.Classes}}
+    {{if not (GetAnnotation $c "internal")}}
+      {{Macro "Struct" $c}}
+    {{end}}
+  {{end}}

+// ------------------------------------------------------------------------------------------------
+// API functions

+  {{range $f := AllCommands $}}
+    {{if not (GetAnnotation $f "pfn")}}
+      {{Macro "FunctionTypedef" $f}}
+    {{end}}
+  {{end}}

+#ifdef VK_PROTOTYPES

+  {{range $f := AllCommands $}}
+    {{if not (GetAnnotation $f "pfn")}}
+      {{Macro "FunctionDecl" $f}}
+    {{end}}
+  {{end}}

+#endif

+#ifdef __cplusplus
+}
+#endif

+#endif
+{{end}}
+
+{{/*
+-------------------------------------------------------------------------------
+  Emits the C declaration for the specified bitfield.
+-------------------------------------------------------------------------------
+*/}}
+{{define "Bitfield"}}
+  {{AssertType $ "Enum"}}
+
+  {{Macro "Docs" $.Docs}}
+  typedef VkFlags {{Macro "EnumName" $}};
+  {{if $.Entries}}
+  typedef enum {
+  {{range $b := $.Entries}}
+    {{Macro "BitfieldEntryName" $b}} = {{printf "0x%.8X" $b.Value}}, {{Macro "Docs" $b.Docs}}
+  {{end}}
+  } {{Macro "EnumName" $ | TrimRight "s"}}Bits;
+  {{end}}
+  ¶
+{{end}}
+
+
+{{/*
+-------------------------------------------------------------------------------
+  Emits the C declaration for the specified enum.
+-------------------------------------------------------------------------------
+*/}}
+{{define "Enum"}}
+  {{AssertType $ "Enum"}}
+
+  {{Macro "Docs" $.Docs}}
+  typedef enum {
+    {{range $i, $e := $.Entries}}
+      {{Macro "EnumEntry" $e}} = {{printf "0x%.8X" $e.Value}}, {{Macro "Docs" $e.Docs}}
+    {{end}}
+  ¶
+    {{$name  := Macro "EnumName" $ | TrimRight "ABCDEFGHIJKLMNOQRSTUVWXYZ" | SplitPascalCase | Upper | JoinWith "_"}}
+    {{if GetAnnotation $ "enumMaxOnly"}}
+      VK_MAX_ENUM({{$name | SplitOn "VK_"}})
+    {{else}}
+      {{$first := Macro "EnumFirstEntry" $ | SplitOn $name | TrimLeft "_"}}
+      {{$last  := Macro "EnumLastEntry" $  | SplitOn $name | TrimLeft "_"}}
+      VK_ENUM_RANGE({{$name | SplitOn "VK_"}}, {{$first}}, {{$last}})
+    {{end}}
+  } {{Macro "EnumName" $}};
+  ¶
+{{end}}
+
+
+{{/*
+-------------------------------------------------------------------------------
+  Emits the C declaration for the specified class.
+-------------------------------------------------------------------------------
+*/}}
+{{define "Struct"}}
+  {{AssertType $ "Class"}}
+
+  {{Macro "Docs" $.Docs}}
+  typedef {{Macro "StructType" $}} {
+    {{ForEach $.Fields "Field" | JoinWith "\n"}}
+  } {{Macro "StructName" $}};
+  ¶
+{{end}}
+
+
+{{/*
+-------------------------------------------------------------------------------
+  Emits the C declaration for the specified class field.
+-------------------------------------------------------------------------------
+*/}}
+{{define "Field"}}
+  {{AssertType $ "Field"}}
+
+  {{Node "Type" $}} {{$.Name}}§
+  {{Macro "ArrayPostfix" (TypeOf $)}}; {{Macro "Docs" $.Docs}}
+{{end}}
+
+
+{{/*
+-------------------------------------------------------------------------------
+  Emits either 'struct' or 'union' for the specified class.
+-------------------------------------------------------------------------------
+*/}}
+{{define "StructType"}}
+  {{AssertType $ "Class"}}
+
+  {{if GetAnnotation $ "union"}}union{{else}}struct{{end}}
+{{end}}
+
+
+{{/*
+-------------------------------------------------------------------------------
+  Emits the C function pointer typedef declaration for the specified command.
+-------------------------------------------------------------------------------
+*/}}
+{{define "FunctionTypedef"}}
+  {{AssertType $ "Function"}}
+
+  typedef {{Node "Type" $.Return}} (VKAPI* {{Macro "FunctionPtrName" $}})({{Macro "Parameters" $}});
+{{end}}
+
+
+{{/*
+-------------------------------------------------------------------------------
+  Emits the C function declaration for the specified command.
+-------------------------------------------------------------------------------
+*/}}
+{{define "FunctionDecl"}}
+  {{AssertType $ "Function"}}
+
+  {{if not (GetAnnotation $ "fptr")}}
+    {{Macro "Docs" $.Docs}}
+    {{Node "Type" $.Return}} VKAPI {{Macro "FunctionName" $}}({{Macro "Parameters" $}});
+  {{end}}
+{{end}}
diff --git a/vulkan/api/vulkan.api b/vulkan/api/vulkan.api
new file mode 100644
index 0000000..8d26927
--- /dev/null
+++ b/vulkan/api/vulkan.api
@@ -0,0 +1,4704 @@
+// Copyright (c) 2015 The Khronos Group Inc.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and/or associated documentation files (the
+// "Materials"), to deal in the Materials without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Materials, and to
+// permit persons to whom the Materials are furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Materials.
+//
+// THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
+
+import platform "platform.api"
+
+///////////////
+// Constants //
+///////////////
+
+// API version (major.minor.patch)
+define VERSION_MAJOR 0
+define VERSION_MINOR 138
+define VERSION_PATCH 0
+
+// API limits
+define VK_MAX_PHYSICAL_DEVICE_NAME 256
+define VK_UUID_LENGTH              16
+define VK_MAX_EXTENSION_NAME       256
+define VK_MAX_DESCRIPTION          256
+define VK_MAX_MEMORY_TYPES         32
+define VK_MAX_MEMORY_HEAPS         16    /// The maximum number of unique memory heaps, each of which supporting 1 or more memory types.
+
+// API keywords
+define VK_TRUE        1
+define VK_FALSE       0
+define VK_NULL_HANDLE 0
+
+
+/////////////
+//  Types  //
+/////////////
+
+/// Dispatchable handle types.
+@dispatchHandle type u64 VkInstance
+@dispatchHandle type u64 VkPhysicalDevice
+@dispatchHandle type u64 VkDevice
+@dispatchHandle type u64 VkQueue
+@dispatchHandle type u64 VkCmdBuffer
+
+/// Non dispatchable handle types.
+@nonDispatchHandle type u64 VkDeviceMemory
+@nonDispatchHandle type u64 VkCmdPool
+@nonDispatchHandle type u64 VkBuffer
+@nonDispatchHandle type u64 VkBufferView
+@nonDispatchHandle type u64 VkImage
+@nonDispatchHandle type u64 VkImageView
+@nonDispatchHandle type u64 VkAttachmentView
+@nonDispatchHandle type u64 VkShaderModule
+@nonDispatchHandle type u64 VkShader
+@nonDispatchHandle type u64 VkPipeline
+@nonDispatchHandle type u64 VkPipelineLayout
+@nonDispatchHandle type u64 VkSampler
+@nonDispatchHandle type u64 VkDescriptorSet
+@nonDispatchHandle type u64 VkDescriptorSetLayout
+@nonDispatchHandle type u64 VkDescriptorPool
+@nonDispatchHandle type u64 VkDynamicViewportState
+@nonDispatchHandle type u64 VkDynamicRasterState
+@nonDispatchHandle type u64 VkDynamicColorBlendState
+@nonDispatchHandle type u64 VkDynamicDepthStencilState
+@nonDispatchHandle type u64 VkFence
+@nonDispatchHandle type u64 VkSemaphore
+@nonDispatchHandle type u64 VkEvent
+@nonDispatchHandle type u64 VkQueryPool
+@nonDispatchHandle type u64 VkFramebuffer
+@nonDispatchHandle type u64 VkRenderPass
+@nonDispatchHandle type u64 VkPipelineCache
+
+
+/////////////
+//  Enums  //
+/////////////
+
+enum VkImageLayout {
+    VK_IMAGE_LAYOUT_UNDEFINED                               = 0x00000000,   /// Implicit layout an image is when its contents are undefined due to various reasons (e.g. right after creation)
+    VK_IMAGE_LAYOUT_GENERAL                                 = 0x00000001,   /// General layout when image can be used for any kind of access
+    VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL                = 0x00000002,   /// Optimal layout when image is only used for color attachment read/write
+    VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL        = 0x00000003,   /// Optimal layout when image is only used for depth/stencil attachment read/write
+    VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL         = 0x00000004,   /// Optimal layout when image is used for read only depth/stencil attachment and shader access
+    VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL                = 0x00000005,   /// Optimal layout when image is used for read only shader access
+    VK_IMAGE_LAYOUT_TRANSFER_SOURCE_OPTIMAL                 = 0x00000006,   /// Optimal layout when image is used only as source of transfer operations
+    VK_IMAGE_LAYOUT_TRANSFER_DESTINATION_OPTIMAL            = 0x00000007,   /// Optimal layout when image is used only as destination of transfer operations
+}
+
+enum VkAttachmentLoadOp {
+    VK_ATTACHMENT_LOAD_OP_LOAD                              = 0x00000000,
+    VK_ATTACHMENT_LOAD_OP_CLEAR                             = 0x00000001,
+    VK_ATTACHMENT_LOAD_OP_DONT_CARE                         = 0x00000002,
+}
+
+enum VkAttachmentStoreOp {
+    VK_ATTACHMENT_STORE_OP_STORE                            = 0x00000000,
+    VK_ATTACHMENT_STORE_OP_DONT_CARE                        = 0x00000001,
+}
+
+enum VkImageType {
+    VK_IMAGE_TYPE_1D                                        = 0x00000000,
+    VK_IMAGE_TYPE_2D                                        = 0x00000001,
+    VK_IMAGE_TYPE_3D                                        = 0x00000002,
+}
+
+enum VkImageTiling {
+    VK_IMAGE_TILING_LINEAR                                  = 0x00000000,
+    VK_IMAGE_TILING_OPTIMAL                                 = 0x00000001,
+}
+
+enum VkImageViewType {
+    VK_IMAGE_VIEW_TYPE_1D                                   = 0x00000000,
+    VK_IMAGE_VIEW_TYPE_2D                                   = 0x00000001,
+    VK_IMAGE_VIEW_TYPE_3D                                   = 0x00000002,
+    VK_IMAGE_VIEW_TYPE_CUBE                                 = 0x00000003,
+    VK_IMAGE_VIEW_TYPE_1D_ARRAY                             = 0x00000004,
+    VK_IMAGE_VIEW_TYPE_2D_ARRAY                             = 0x00000005,
+    VK_IMAGE_VIEW_TYPE_CUBE_ARRAY                           = 0x00000006,
+}
+
+enum VkImageAspect {
+    VK_IMAGE_ASPECT_COLOR                                   = 0x00000000,
+    VK_IMAGE_ASPECT_DEPTH                                   = 0x00000001,
+    VK_IMAGE_ASPECT_STENCIL                                 = 0x00000002,
+    VK_IMAGE_ASPECT_METADATA                                = 0x00000003,
+}
+
+enum VkBufferViewType {
+    VK_BUFFER_VIEW_TYPE_RAW                                 = 0x00000000,   /// Raw buffer without special structure (UBO, SSBO)
+    VK_BUFFER_VIEW_TYPE_FORMATTED                           = 0x00000001,   /// Buffer with format (TBO, IBO)
+}
+
+enum VkCmdBufferLevel {
+    VK_CMD_BUFFER_LEVEL_PRIMARY                             = 0x00000000,
+    VK_CMD_BUFFER_LEVEL_SECONDARY                           = 0x00000001,
+}
+
+enum VkChannelSwizzle {
+    VK_CHANNEL_SWIZZLE_ZERO                                 = 0x00000000,
+    VK_CHANNEL_SWIZZLE_ONE                                  = 0x00000001,
+    VK_CHANNEL_SWIZZLE_R                                    = 0x00000002,
+    VK_CHANNEL_SWIZZLE_G                                    = 0x00000003,
+    VK_CHANNEL_SWIZZLE_B                                    = 0x00000004,
+    VK_CHANNEL_SWIZZLE_A                                    = 0x00000005,
+}
+
+enum VkDescriptorType {
+    VK_DESCRIPTOR_TYPE_SAMPLER                              = 0x00000000,
+    VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER               = 0x00000001,
+    VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE                        = 0x00000002,
+    VK_DESCRIPTOR_TYPE_STORAGE_IMAGE                        = 0x00000003,
+    VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER                 = 0x00000004,
+    VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER                 = 0x00000005,
+    VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER                       = 0x00000006,
+    VK_DESCRIPTOR_TYPE_STORAGE_BUFFER                       = 0x00000007,
+    VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC               = 0x00000008,
+    VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC               = 0x00000009,
+    VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT                     = 0x0000000a,
+}
+
+enum VkDescriptorPoolUsage {
+    VK_DESCRIPTOR_POOL_USAGE_ONE_SHOT                       = 0x00000000,
+    VK_DESCRIPTOR_POOL_USAGE_DYNAMIC                        = 0x00000001,
+}
+
+enum VkDescriptorSetUsage {
+    VK_DESCRIPTOR_SET_USAGE_ONE_SHOT                        = 0x00000000,
+    VK_DESCRIPTOR_SET_USAGE_STATIC                          = 0x00000001,
+}
+
+enum VkQueryType {
+    VK_QUERY_TYPE_OCCLUSION                                 = 0x00000000,
+    VK_QUERY_TYPE_PIPELINE_STATISTICS                       = 0x00000001, /// Optional
+}
+
+enum VkTimestampType {
+    VK_TIMESTAMP_TYPE_TOP                                   = 0x00000000,
+    VK_TIMESTAMP_TYPE_BOTTOM                                = 0x00000001,
+}
+
+enum VkBorderColor {
+    VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK                 = 0x00000000,
+    VK_BORDER_COLOR_INT_TRANSPARENT_BLACK                   = 0x00000001,
+    VK_BORDER_COLOR_FLOAT_OPAQUE_BLACK                      = 0x00000002,
+    VK_BORDER_COLOR_INT_OPAQUE_BLACK                        = 0x00000003,
+    VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE                      = 0x00000004,
+    VK_BORDER_COLOR_INT_OPAQUE_WHITE                        = 0x00000005,
+}
+
+enum VkPipelineBindPoint {
+    VK_PIPELINE_BIND_POINT_COMPUTE                          = 0x00000000,
+    VK_PIPELINE_BIND_POINT_GRAPHICS                         = 0x00000001,
+}
+
+enum VkPrimitiveTopology {
+    VK_PRIMITIVE_TOPOLOGY_POINT_LIST                        = 0x00000000,
+    VK_PRIMITIVE_TOPOLOGY_LINE_LIST                         = 0x00000001,
+    VK_PRIMITIVE_TOPOLOGY_LINE_STRIP                        = 0x00000002,
+    VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST                     = 0x00000003,
+    VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP                    = 0x00000004,
+    VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN                      = 0x00000005,
+    VK_PRIMITIVE_TOPOLOGY_LINE_LIST_ADJ                     = 0x00000006,
+    VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_ADJ                    = 0x00000007,
+    VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_ADJ                 = 0x00000008,
+    VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_ADJ                = 0x00000009,
+    VK_PRIMITIVE_TOPOLOGY_PATCH                             = 0x0000000a,
+}
+
+enum VkSharingMode {
+    VK_SHARING_MODE_EXCLUSIVE                               = 0x00000000,
+    VK_SHARING_MODE_CONCURRENT                              = 0x00000001,
+}
+
+enum VkIndexType {
+    VK_INDEX_TYPE_UINT16                                    = 0x00000000,
+    VK_INDEX_TYPE_UINT32                                    = 0x00000001,
+}
+
+enum VkTexFilter {
+    VK_TEX_FILTER_NEAREST                                   = 0x00000000,
+    VK_TEX_FILTER_LINEAR                                    = 0x00000001,
+}
+
+enum VkTexMipmapMode {
+    VK_TEX_MIPMAP_MODE_BASE                                 = 0x00000000,   /// Always choose base level
+    VK_TEX_MIPMAP_MODE_NEAREST                              = 0x00000001,   /// Choose nearest mip level
+    VK_TEX_MIPMAP_MODE_LINEAR                               = 0x00000002,   /// Linear filter between mip levels
+}
+
+enum VkTexAddress {
+    VK_TEX_ADDRESS_WRAP                                     = 0x00000000,
+    VK_TEX_ADDRESS_MIRROR                                   = 0x00000001,
+    VK_TEX_ADDRESS_CLAMP                                    = 0x00000002,
+    VK_TEX_ADDRESS_MIRROR_ONCE                              = 0x00000003,
+    VK_TEX_ADDRESS_CLAMP_BORDER                             = 0x00000004,
+}
+
+enum VkCompareOp {
+    VK_COMPARE_OP_NEVER                                     = 0x00000000,
+    VK_COMPARE_OP_LESS                                      = 0x00000001,
+    VK_COMPARE_OP_EQUAL                                     = 0x00000002,
+    VK_COMPARE_OP_LESS_EQUAL                                = 0x00000003,
+    VK_COMPARE_OP_GREATER                                   = 0x00000004,
+    VK_COMPARE_OP_NOT_EQUAL                                 = 0x00000005,
+    VK_COMPARE_OP_GREATER_EQUAL                             = 0x00000006,
+    VK_COMPARE_OP_ALWAYS                                    = 0x00000007,
+}
+
+enum VkFillMode {
+    VK_FILL_MODE_POINTS                                     = 0x00000000,
+    VK_FILL_MODE_WIREFRAME                                  = 0x00000001,
+    VK_FILL_MODE_SOLID                                      = 0x00000002,
+}
+
+enum VkCullMode {
+    VK_CULL_MODE_NONE                                       = 0x00000000,
+    VK_CULL_MODE_FRONT                                      = 0x00000001,
+    VK_CULL_MODE_BACK                                       = 0x00000002,
+    VK_CULL_MODE_FRONT_AND_BACK                             = 0x00000003,
+}
+
+enum VkFrontFace {
+    VK_FRONT_FACE_CCW                                       = 0x00000000,
+    VK_FRONT_FACE_CW                                        = 0x00000001,
+}
+
+enum VkBlend {
+    VK_BLEND_ZERO                                           = 0x00000000,
+    VK_BLEND_ONE                                            = 0x00000001,
+    VK_BLEND_SRC_COLOR                                      = 0x00000002,
+    VK_BLEND_ONE_MINUS_SRC_COLOR                            = 0x00000003,
+    VK_BLEND_DEST_COLOR                                     = 0x00000004,
+    VK_BLEND_ONE_MINUS_DEST_COLOR                           = 0x00000005,
+    VK_BLEND_SRC_ALPHA                                      = 0x00000006,
+    VK_BLEND_ONE_MINUS_SRC_ALPHA                            = 0x00000007,
+    VK_BLEND_DEST_ALPHA                                     = 0x00000008,
+    VK_BLEND_ONE_MINUS_DEST_ALPHA                           = 0x00000009,
+    VK_BLEND_CONSTANT_COLOR                                 = 0x0000000a,
+    VK_BLEND_ONE_MINUS_CONSTANT_COLOR                       = 0x0000000b,
+    VK_BLEND_CONSTANT_ALPHA                                 = 0x0000000c,
+    VK_BLEND_ONE_MINUS_CONSTANT_ALPHA                       = 0x0000000d,
+    VK_BLEND_SRC_ALPHA_SATURATE                             = 0x0000000e,
+    VK_BLEND_SRC1_COLOR                                     = 0x0000000f,
+    VK_BLEND_ONE_MINUS_SRC1_COLOR                           = 0x00000010,
+    VK_BLEND_SRC1_ALPHA                                     = 0x00000011,
+    VK_BLEND_ONE_MINUS_SRC1_ALPHA                           = 0x00000012,
+}
+
+enum VkBlendOp {
+    VK_BLEND_OP_ADD                                         = 0x00000000,
+    VK_BLEND_OP_SUBTRACT                                    = 0x00000001,
+    VK_BLEND_OP_REVERSE_SUBTRACT                            = 0x00000002,
+    VK_BLEND_OP_MIN                                         = 0x00000003,
+    VK_BLEND_OP_MAX                                         = 0x00000004,
+}
+
+enum VkStencilOp {
+    VK_STENCIL_OP_KEEP                                      = 0x00000000,
+    VK_STENCIL_OP_ZERO                                      = 0x00000001,
+    VK_STENCIL_OP_REPLACE                                   = 0x00000002,
+    VK_STENCIL_OP_INC_CLAMP                                 = 0x00000003,
+    VK_STENCIL_OP_DEC_CLAMP                                 = 0x00000004,
+    VK_STENCIL_OP_INVERT                                    = 0x00000005,
+    VK_STENCIL_OP_INC_WRAP                                  = 0x00000006,
+    VK_STENCIL_OP_DEC_WRAP                                  = 0x00000007,
+}
+
+enum VkLogicOp {
+    VK_LOGIC_OP_CLEAR                                       = 0x00000000,
+    VK_LOGIC_OP_AND                                         = 0x00000001,
+    VK_LOGIC_OP_AND_REVERSE                                 = 0x00000002,
+    VK_LOGIC_OP_COPY                                        = 0x00000003,
+    VK_LOGIC_OP_AND_INVERTED                                = 0x00000004,
+    VK_LOGIC_OP_NOOP                                        = 0x00000005,
+    VK_LOGIC_OP_XOR                                         = 0x00000006,
+    VK_LOGIC_OP_OR                                          = 0x00000007,
+    VK_LOGIC_OP_NOR                                         = 0x00000008,
+    VK_LOGIC_OP_EQUIV                                       = 0x00000009,
+    VK_LOGIC_OP_INVERT                                      = 0x0000000a,
+    VK_LOGIC_OP_OR_REVERSE                                  = 0x0000000b,
+    VK_LOGIC_OP_COPY_INVERTED                               = 0x0000000c,
+    VK_LOGIC_OP_OR_INVERTED                                 = 0x0000000d,
+    VK_LOGIC_OP_NAND                                        = 0x0000000e,
+    VK_LOGIC_OP_SET                                         = 0x0000000f,
+}
+
+enum VkSystemAllocType {
+    VK_SYSTEM_ALLOC_TYPE_API_OBJECT                         = 0x00000000,
+    VK_SYSTEM_ALLOC_TYPE_INTERNAL                           = 0x00000001,
+    VK_SYSTEM_ALLOC_TYPE_INTERNAL_TEMP                      = 0x00000002,
+    VK_SYSTEM_ALLOC_TYPE_INTERNAL_SHADER                    = 0x00000003,
+    VK_SYSTEM_ALLOC_TYPE_DEBUG                              = 0x00000004,
+}
+
+enum VkPhysicalDeviceType {
+    VK_PHYSICAL_DEVICE_TYPE_OTHER                           = 0x00000000,
+    VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU                  = 0x00000001,
+    VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU                    = 0x00000002,
+    VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU                     = 0x00000003,
+    VK_PHYSICAL_DEVICE_TYPE_CPU                             = 0x00000004,
+}
+
+enum VkVertexInputStepRate {
+    VK_VERTEX_INPUT_STEP_RATE_VERTEX                        = 0x00000000,
+    VK_VERTEX_INPUT_STEP_RATE_INSTANCE                      = 0x00000001,
+}
+
+/// Vulkan format definitions
+enum VkFormat {
+    VK_FORMAT_UNDEFINED                                     = 0x00000000,
+    VK_FORMAT_R4G4_UNORM                                    = 0x00000001,
+    VK_FORMAT_R4G4_USCALED                                  = 0x00000002,
+    VK_FORMAT_R4G4B4A4_UNORM                                = 0x00000003,
+    VK_FORMAT_R4G4B4A4_USCALED                              = 0x00000004,
+    VK_FORMAT_R5G6B5_UNORM                                  = 0x00000005,
+    VK_FORMAT_R5G6B5_USCALED                                = 0x00000006,
+    VK_FORMAT_R5G5B5A1_UNORM                                = 0x00000007,
+    VK_FORMAT_R5G5B5A1_USCALED                              = 0x00000008,
+    VK_FORMAT_R8_UNORM                                      = 0x00000009,
+    VK_FORMAT_R8_SNORM                                      = 0x0000000A,
+    VK_FORMAT_R8_USCALED                                    = 0x0000000B,
+    VK_FORMAT_R8_SSCALED                                    = 0x0000000C,
+    VK_FORMAT_R8_UINT                                       = 0x0000000D,
+    VK_FORMAT_R8_SINT                                       = 0x0000000E,
+    VK_FORMAT_R8_SRGB                                       = 0x0000000F,
+    VK_FORMAT_R8G8_UNORM                                    = 0x00000010,
+    VK_FORMAT_R8G8_SNORM                                    = 0x00000011,
+    VK_FORMAT_R8G8_USCALED                                  = 0x00000012,
+    VK_FORMAT_R8G8_SSCALED                                  = 0x00000013,
+    VK_FORMAT_R8G8_UINT                                     = 0x00000014,
+    VK_FORMAT_R8G8_SINT                                     = 0x00000015,
+    VK_FORMAT_R8G8_SRGB                                     = 0x00000016,
+    VK_FORMAT_R8G8B8_UNORM                                  = 0x00000017,
+    VK_FORMAT_R8G8B8_SNORM                                  = 0x00000018,
+    VK_FORMAT_R8G8B8_USCALED                                = 0x00000019,
+    VK_FORMAT_R8G8B8_SSCALED                                = 0x0000001A,
+    VK_FORMAT_R8G8B8_UINT                                   = 0x0000001B,
+    VK_FORMAT_R8G8B8_SINT                                   = 0x0000001C,
+    VK_FORMAT_R8G8B8_SRGB                                   = 0x0000001D,
+    VK_FORMAT_R8G8B8A8_UNORM                                = 0x0000001E,
+    VK_FORMAT_R8G8B8A8_SNORM                                = 0x0000001F,
+    VK_FORMAT_R8G8B8A8_USCALED                              = 0x00000020,
+    VK_FORMAT_R8G8B8A8_SSCALED                              = 0x00000021,
+    VK_FORMAT_R8G8B8A8_UINT                                 = 0x00000022,
+    VK_FORMAT_R8G8B8A8_SINT                                 = 0x00000023,
+    VK_FORMAT_R8G8B8A8_SRGB                                 = 0x00000024,
+    VK_FORMAT_R10G10B10A2_UNORM                             = 0x00000025,
+    VK_FORMAT_R10G10B10A2_SNORM                             = 0x00000026,
+    VK_FORMAT_R10G10B10A2_USCALED                           = 0x00000027,
+    VK_FORMAT_R10G10B10A2_SSCALED                           = 0x00000028,
+    VK_FORMAT_R10G10B10A2_UINT                              = 0x00000029,
+    VK_FORMAT_R10G10B10A2_SINT                              = 0x0000002A,
+    VK_FORMAT_R16_UNORM                                     = 0x0000002B,
+    VK_FORMAT_R16_SNORM                                     = 0x0000002C,
+    VK_FORMAT_R16_USCALED                                   = 0x0000002D,
+    VK_FORMAT_R16_SSCALED                                   = 0x0000002E,
+    VK_FORMAT_R16_UINT                                      = 0x0000002F,
+    VK_FORMAT_R16_SINT                                      = 0x00000030,
+    VK_FORMAT_R16_SFLOAT                                    = 0x00000031,
+    VK_FORMAT_R16G16_UNORM                                  = 0x00000032,
+    VK_FORMAT_R16G16_SNORM                                  = 0x00000033,
+    VK_FORMAT_R16G16_USCALED                                = 0x00000034,
+    VK_FORMAT_R16G16_SSCALED                                = 0x00000035,
+    VK_FORMAT_R16G16_UINT                                   = 0x00000036,
+    VK_FORMAT_R16G16_SINT                                   = 0x00000037,
+    VK_FORMAT_R16G16_SFLOAT                                 = 0x00000038,
+    VK_FORMAT_R16G16B16_UNORM                               = 0x00000039,
+    VK_FORMAT_R16G16B16_SNORM                               = 0x0000003A,
+    VK_FORMAT_R16G16B16_USCALED                             = 0x0000003B,
+    VK_FORMAT_R16G16B16_SSCALED                             = 0x0000003C,
+    VK_FORMAT_R16G16B16_UINT                                = 0x0000003D,
+    VK_FORMAT_R16G16B16_SINT                                = 0x0000003E,
+    VK_FORMAT_R16G16B16_SFLOAT                              = 0x0000003F,
+    VK_FORMAT_R16G16B16A16_UNORM                            = 0x00000040,
+    VK_FORMAT_R16G16B16A16_SNORM                            = 0x00000041,
+    VK_FORMAT_R16G16B16A16_USCALED                          = 0x00000042,
+    VK_FORMAT_R16G16B16A16_SSCALED                          = 0x00000043,
+    VK_FORMAT_R16G16B16A16_UINT                             = 0x00000044,
+    VK_FORMAT_R16G16B16A16_SINT                             = 0x00000045,
+    VK_FORMAT_R16G16B16A16_SFLOAT                           = 0x00000046,
+    VK_FORMAT_R32_UINT                                      = 0x00000047,
+    VK_FORMAT_R32_SINT                                      = 0x00000048,
+    VK_FORMAT_R32_SFLOAT                                    = 0x00000049,
+    VK_FORMAT_R32G32_UINT                                   = 0x0000004A,
+    VK_FORMAT_R32G32_SINT                                   = 0x0000004B,
+    VK_FORMAT_R32G32_SFLOAT                                 = 0x0000004C,
+    VK_FORMAT_R32G32B32_UINT                                = 0x0000004D,
+    VK_FORMAT_R32G32B32_SINT                                = 0x0000004E,
+    VK_FORMAT_R32G32B32_SFLOAT                              = 0x0000004F,
+    VK_FORMAT_R32G32B32A32_UINT                             = 0x00000050,
+    VK_FORMAT_R32G32B32A32_SINT                             = 0x00000051,
+    VK_FORMAT_R32G32B32A32_SFLOAT                           = 0x00000052,
+    VK_FORMAT_R64_SFLOAT                                    = 0x00000053,
+    VK_FORMAT_R64G64_SFLOAT                                 = 0x00000054,
+    VK_FORMAT_R64G64B64_SFLOAT                              = 0x00000055,
+    VK_FORMAT_R64G64B64A64_SFLOAT                           = 0x00000056,
+    VK_FORMAT_R11G11B10_UFLOAT                              = 0x00000057,
+    VK_FORMAT_R9G9B9E5_UFLOAT                               = 0x00000058,
+    VK_FORMAT_D16_UNORM                                     = 0x00000059,
+    VK_FORMAT_D24_UNORM                                     = 0x0000005A,
+    VK_FORMAT_D32_SFLOAT                                    = 0x0000005B,
+    VK_FORMAT_S8_UINT                                       = 0x0000005C,
+    VK_FORMAT_D16_UNORM_S8_UINT                             = 0x0000005D,
+    VK_FORMAT_D24_UNORM_S8_UINT                             = 0x0000005E,
+    VK_FORMAT_D32_SFLOAT_S8_UINT                            = 0x0000005F,
+    VK_FORMAT_BC1_RGB_UNORM                                 = 0x00000060,
+    VK_FORMAT_BC1_RGB_SRGB                                  = 0x00000061,
+    VK_FORMAT_BC1_RGBA_UNORM                                = 0x00000062,
+    VK_FORMAT_BC1_RGBA_SRGB                                 = 0x00000063,
+    VK_FORMAT_BC2_UNORM                                     = 0x00000064,
+    VK_FORMAT_BC2_SRGB                                      = 0x00000065,
+    VK_FORMAT_BC3_UNORM                                     = 0x00000066,
+    VK_FORMAT_BC3_SRGB                                      = 0x00000067,
+    VK_FORMAT_BC4_UNORM                                     = 0x00000068,
+    VK_FORMAT_BC4_SNORM                                     = 0x00000069,
+    VK_FORMAT_BC5_UNORM                                     = 0x0000006A,
+    VK_FORMAT_BC5_SNORM                                     = 0x0000006B,
+    VK_FORMAT_BC6H_UFLOAT                                   = 0x0000006C,
+    VK_FORMAT_BC6H_SFLOAT                                   = 0x0000006D,
+    VK_FORMAT_BC7_UNORM                                     = 0x0000006E,
+    VK_FORMAT_BC7_SRGB                                      = 0x0000006F,
+    VK_FORMAT_ETC2_R8G8B8_UNORM                             = 0x00000070,
+    VK_FORMAT_ETC2_R8G8B8_SRGB                              = 0x00000071,
+    VK_FORMAT_ETC2_R8G8B8A1_UNORM                           = 0x00000072,
+    VK_FORMAT_ETC2_R8G8B8A1_SRGB                            = 0x00000073,
+    VK_FORMAT_ETC2_R8G8B8A8_UNORM                           = 0x00000074,
+    VK_FORMAT_ETC2_R8G8B8A8_SRGB                            = 0x00000075,
+    VK_FORMAT_EAC_R11_UNORM                                 = 0x00000076,
+    VK_FORMAT_EAC_R11_SNORM                                 = 0x00000077,
+    VK_FORMAT_EAC_R11G11_UNORM                              = 0x00000078,
+    VK_FORMAT_EAC_R11G11_SNORM                              = 0x00000079,
+    VK_FORMAT_ASTC_4x4_UNORM                                = 0x0000007A,
+    VK_FORMAT_ASTC_4x4_SRGB                                 = 0x0000007B,
+    VK_FORMAT_ASTC_5x4_UNORM                                = 0x0000007C,
+    VK_FORMAT_ASTC_5x4_SRGB                                 = 0x0000007D,
+    VK_FORMAT_ASTC_5x5_UNORM                                = 0x0000007E,
+    VK_FORMAT_ASTC_5x5_SRGB                                 = 0x0000007F,
+    VK_FORMAT_ASTC_6x5_UNORM                                = 0x00000080,
+    VK_FORMAT_ASTC_6x5_SRGB                                 = 0x00000081,
+    VK_FORMAT_ASTC_6x6_UNORM                                = 0x00000082,
+    VK_FORMAT_ASTC_6x6_SRGB                                 = 0x00000083,
+    VK_FORMAT_ASTC_8x5_UNORM                                = 0x00000084,
+    VK_FORMAT_ASTC_8x5_SRGB                                 = 0x00000085,
+    VK_FORMAT_ASTC_8x6_UNORM                                = 0x00000086,
+    VK_FORMAT_ASTC_8x6_SRGB                                 = 0x00000087,
+    VK_FORMAT_ASTC_8x8_UNORM                                = 0x00000088,
+    VK_FORMAT_ASTC_8x8_SRGB                                 = 0x00000089,
+    VK_FORMAT_ASTC_10x5_UNORM                               = 0x0000008A,
+    VK_FORMAT_ASTC_10x5_SRGB                                = 0x0000008B,
+    VK_FORMAT_ASTC_10x6_UNORM                               = 0x0000008C,
+    VK_FORMAT_ASTC_10x6_SRGB                                = 0x0000008D,
+    VK_FORMAT_ASTC_10x8_UNORM                               = 0x0000008E,
+    VK_FORMAT_ASTC_10x8_SRGB                                = 0x0000008F,
+    VK_FORMAT_ASTC_10x10_UNORM                              = 0x00000090,
+    VK_FORMAT_ASTC_10x10_SRGB                               = 0x00000091,
+    VK_FORMAT_ASTC_12x10_UNORM                              = 0x00000092,
+    VK_FORMAT_ASTC_12x10_SRGB                               = 0x00000093,
+    VK_FORMAT_ASTC_12x12_UNORM                              = 0x00000094,
+    VK_FORMAT_ASTC_12x12_SRGB                               = 0x00000095,
+    VK_FORMAT_B4G4R4A4_UNORM                                = 0x00000096,
+    VK_FORMAT_B5G5R5A1_UNORM                                = 0x00000097,
+    VK_FORMAT_B5G6R5_UNORM                                  = 0x00000098,
+    VK_FORMAT_B5G6R5_USCALED                                = 0x00000099,
+    VK_FORMAT_B8G8R8_UNORM                                  = 0x0000009A,
+    VK_FORMAT_B8G8R8_SNORM                                  = 0x0000009B,
+    VK_FORMAT_B8G8R8_USCALED                                = 0x0000009C,
+    VK_FORMAT_B8G8R8_SSCALED                                = 0x0000009D,
+    VK_FORMAT_B8G8R8_UINT                                   = 0x0000009E,
+    VK_FORMAT_B8G8R8_SINT                                   = 0x0000009F,
+    VK_FORMAT_B8G8R8_SRGB                                   = 0x000000A0,
+    VK_FORMAT_B8G8R8A8_UNORM                                = 0x000000A1,
+    VK_FORMAT_B8G8R8A8_SNORM                                = 0x000000A2,
+    VK_FORMAT_B8G8R8A8_USCALED                              = 0x000000A3,
+    VK_FORMAT_B8G8R8A8_SSCALED                              = 0x000000A4,
+    VK_FORMAT_B8G8R8A8_UINT                                 = 0x000000A5,
+    VK_FORMAT_B8G8R8A8_SINT                                 = 0x000000A6,
+    VK_FORMAT_B8G8R8A8_SRGB                                 = 0x000000A7,
+    VK_FORMAT_B10G10R10A2_UNORM                             = 0x000000A8,
+    VK_FORMAT_B10G10R10A2_SNORM                             = 0x000000A9,
+    VK_FORMAT_B10G10R10A2_USCALED                           = 0x000000AA,
+    VK_FORMAT_B10G10R10A2_SSCALED                           = 0x000000AB,
+    VK_FORMAT_B10G10R10A2_UINT                              = 0x000000AC,
+    VK_FORMAT_B10G10R10A2_SINT                              = 0x000000AD,
+}
+
+/// Shader stage enumerant
+enum VkShaderStage {
+    VK_SHADER_STAGE_VERTEX                                  = 0x00000000,
+    VK_SHADER_STAGE_TESS_CONTROL                            = 0x00000001,
+    VK_SHADER_STAGE_TESS_EVALUATION                         = 0x00000002,
+    VK_SHADER_STAGE_GEOMETRY                                = 0x00000003,
+    VK_SHADER_STAGE_FRAGMENT                                = 0x00000004,
+    VK_SHADER_STAGE_COMPUTE                                 = 0x00000005,
+}
+
+/// Structure type enumerant
+enum VkStructureType {
+    VK_STRUCTURE_TYPE_APPLICATION_INFO                          = 0,
+    VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO                        = 1,
+    VK_STRUCTURE_TYPE_MEMORY_ALLOC_INFO                         = 2,
+    VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO                    = 3,
+    VK_STRUCTURE_TYPE_ATTACHMENT_VIEW_CREATE_INFO               = 4,
+    VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO                 = 5,
+    VK_STRUCTURE_TYPE_SHADER_CREATE_INFO                        = 6,
+    VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO              = 7,
+    VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO                       = 8,
+    VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO         = 9,
+    VK_STRUCTURE_TYPE_DYNAMIC_VIEWPORT_STATE_CREATE_INFO        = 10,
+    VK_STRUCTURE_TYPE_DYNAMIC_RASTER_STATE_CREATE_INFO          = 11,
+    VK_STRUCTURE_TYPE_DYNAMIC_COLOR_BLEND_STATE_CREATE_INFO     = 12,
+    VK_STRUCTURE_TYPE_DYNAMIC_DEPTH_STENCIL_STATE_CREATE_INFO   = 13,
+    VK_STRUCTURE_TYPE_CMD_BUFFER_CREATE_INFO                    = 14,
+    VK_STRUCTURE_TYPE_EVENT_CREATE_INFO                         = 15,
+    VK_STRUCTURE_TYPE_FENCE_CREATE_INFO                         = 16,
+    VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO                     = 17,
+    VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO                    = 18,
+    VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO         = 19,
+    VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO             = 20,
+    VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO   = 21,
+    VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO = 22,
+    VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO   = 23,
+    VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO       = 24,
+    VK_STRUCTURE_TYPE_PIPELINE_RASTER_STATE_CREATE_INFO         = 25,
+    VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO    = 26,
+    VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO    = 27,
+    VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO  = 28,
+    VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO                         = 29,
+    VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO                        = 30,
+    VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO                   = 31,
+    VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO                   = 32,
+    VK_STRUCTURE_TYPE_CMD_BUFFER_BEGIN_INFO                     = 33,
+    VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO                   = 34,
+    VK_STRUCTURE_TYPE_LAYER_CREATE_INFO                         = 35,
+    VK_STRUCTURE_TYPE_MEMORY_BARRIER                            = 36,
+    VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER                     = 37,
+    VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER                      = 38,
+    VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO               = 39,
+    VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET                      = 40,
+    VK_STRUCTURE_TYPE_COPY_DESCRIPTOR_SET                       = 41,
+    VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO                      = 42,
+    VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO               = 43,
+    VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE                       = 44,
+    VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO                = 45,
+    VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION                    = 46,
+    VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION                       = 47,
+    VK_STRUCTURE_TYPE_SUBPASS_DEPENDENCY                        = 48,
+    VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO                    = 49,
+    VK_STRUCTURE_TYPE_CMD_POOL_CREATE_INFO                      = 50,
+}
+
+enum VkRenderPassContents {
+    VK_RENDER_PASS_CONTENTS_INLINE                          = 0x00000000,
+    VK_RENDER_PASS_CONTENTS_SECONDARY_CMD_BUFFERS           = 0x00000001,
+}
+
+@lastUnused(-33)
+/// Error and return codes
+enum VkResult {
+    // Return codes for successful operation execution (positive values)
+    VK_SUCCESS                                              = 0x00000000,
+    VK_UNSUPPORTED                                          = 0x00000001,
+    VK_NOT_READY                                            = 0x00000002,
+    VK_TIMEOUT                                              = 0x00000003,
+    VK_EVENT_SET                                            = 0x00000004,
+    VK_EVENT_RESET                                          = 0x00000005,
+    VK_INCOMPLETE                                           = 0x00000006,
+
+    // Error codes (negative values)
+    VK_ERROR_UNKNOWN                                        = 0xFFFFFFFF,
+    VK_ERROR_UNAVAILABLE                                    = 0xFFFFFFFE,
+    VK_ERROR_INITIALIZATION_FAILED                          = 0xFFFFFFFD,
+    VK_ERROR_OUT_OF_HOST_MEMORY                             = 0xFFFFFFFC,
+    VK_ERROR_OUT_OF_DEVICE_MEMORY                           = 0xFFFFFFFB,
+    VK_ERROR_DEVICE_ALREADY_CREATED                         = 0xFFFFFFFA,
+    VK_ERROR_DEVICE_LOST                                    = 0xFFFFFFF9,
+    VK_ERROR_INVALID_POINTER                                = 0xFFFFFFF8,
+    VK_ERROR_INVALID_VALUE                                  = 0xFFFFFFF7,
+    VK_ERROR_INVALID_HANDLE                                 = 0xFFFFFFF6,
+    VK_ERROR_INVALID_ORDINAL                                = 0xFFFFFFF5,
+    VK_ERROR_INVALID_MEMORY_SIZE                            = 0xFFFFFFF4,
+    VK_ERROR_INVALID_EXTENSION                              = 0xFFFFFFF3,
+    VK_ERROR_INVALID_FLAGS                                  = 0xFFFFFFF2,
+    VK_ERROR_INVALID_ALIGNMENT                              = 0xFFFFFFF1,
+    VK_ERROR_INVALID_FORMAT                                 = 0xFFFFFFF0,
+    VK_ERROR_INVALID_IMAGE                                  = 0xFFFFFFEF,
+    VK_ERROR_INVALID_DESCRIPTOR_SET_DATA                    = 0xFFFFFFEE,
+    VK_ERROR_INVALID_QUEUE_TYPE                             = 0xFFFFFFED,
+    VK_ERROR_UNSUPPORTED_SHADER_IL_VERSION                  = 0xFFFFFFEC,
+    VK_ERROR_BAD_SHADER_CODE                                = 0xFFFFFFEB,
+    VK_ERROR_BAD_PIPELINE_DATA                              = 0xFFFFFFEA,
+    VK_ERROR_NOT_MAPPABLE                                   = 0xFFFFFFE9,
+    VK_ERROR_MEMORY_MAP_FAILED                              = 0xFFFFFFE8,
+    VK_ERROR_MEMORY_UNMAP_FAILED                            = 0xFFFFFFE7,
+    VK_ERROR_INCOMPATIBLE_DEVICE                            = 0xFFFFFFE6,
+    VK_ERROR_INCOMPATIBLE_DRIVER                            = 0xFFFFFFE5,
+    VK_ERROR_INCOMPLETE_COMMAND_BUFFER                      = 0xFFFFFFE4,
+    VK_ERROR_BUILDING_COMMAND_BUFFER                        = 0xFFFFFFE3,
+    VK_ERROR_MEMORY_NOT_BOUND                               = 0xFFFFFFE2,
+    VK_ERROR_INCOMPATIBLE_QUEUE                             = 0xFFFFFFE1,
+    VK_ERROR_INVALID_LAYER                                  = 0xFFFFFFE0,
+}
+
+
+/////////////////
+//  Bitfields  //
+/////////////////
+
+/// Device creation flags
+bitfield VkDeviceCreateFlags {
+    VK_DEVICE_CREATE_VALIDATION_BIT                         = 0x00000001,
+}
+
+/// Queue capabilities
+bitfield VkQueueFlags {
+    VK_QUEUE_GRAPHICS_BIT                                   = 0x00000001,    /// Queue supports graphics operations
+    VK_QUEUE_COMPUTE_BIT                                    = 0x00000002,    /// Queue supports compute operations
+    VK_QUEUE_DMA_BIT                                        = 0x00000004,    /// Queue supports DMA operations
+    VK_QUEUE_SPARSE_MEMMGR_BIT                              = 0x00000008,    /// Queue supports sparse resource memory management operations
+    VK_QUEUE_EXTENDED_BIT                                   = 0x40000000,    /// Extended queue
+}
+
+/// Memory properties passed into vkAllocMemory().
+bitfield VkMemoryPropertyFlags {
+    VK_MEMORY_PROPERTY_DEVICE_ONLY                          = 0x00000000,    /// If otherwise stated, then allocate memory on device
+    VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT                     = 0x00000001,    /// Memory should be mappable by host
+    VK_MEMORY_PROPERTY_HOST_NON_COHERENT_BIT                = 0x00000002,    /// Memory may not have i/o coherency so vkFlushMappedMemoryRanges and vkInvalidateMappedMemoryRanges must be used flush/invalidate host cache
+                                                                             /// vkInvalidateMappedMemoryRanges must be used flush/invalidate host cache
+    VK_MEMORY_PROPERTY_HOST_UNCACHED_BIT                    = 0x00000004,    /// Memory should not be cached by the host
+    VK_MEMORY_PROPERTY_HOST_WRITE_COMBINED_BIT              = 0x00000008,    /// Memory should support host write combining
+    VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT                 = 0x00000010,    /// Memory may be allocated by the driver when it is required
+}
+
+/// Memory heap flags
+bitfield VkMemoryHeapFlags {
+    VK_MEMORY_HEAP_HOST_LOCAL                               = 0x00000001,    /// If set, heap represents host memory
+}
+
+/// Memory output flags passed to resource transition commands
+bitfield VkMemoryOutputFlags {
+    VK_MEMORY_OUTPUT_HOST_WRITE_BIT                         = 0x00000001,    /// Controls output coherency of host writes
+    VK_MEMORY_OUTPUT_SHADER_WRITE_BIT                       = 0x00000002,    /// Controls output coherency of generic shader writes
+    VK_MEMORY_OUTPUT_COLOR_ATTACHMENT_BIT                   = 0x00000004,    /// Controls output coherency of color attachment writes
+    VK_MEMORY_OUTPUT_DEPTH_STENCIL_ATTACHMENT_BIT           = 0x00000008,    /// Controls output coherency of depth/stencil attachment writes
+    VK_MEMORY_OUTPUT_TRANSFER_BIT                           = 0x00000010,    /// Controls output coherency of transfer operations
+}
+
+/// Memory input flags passed to resource transition commands
+bitfield VkMemoryInputFlags {
+    VK_MEMORY_INPUT_HOST_READ_BIT                           = 0x00000001,    /// Controls input coherency of host reads
+    VK_MEMORY_INPUT_INDIRECT_COMMAND_BIT                    = 0x00000002,    /// Controls input coherency of indirect command reads
+    VK_MEMORY_INPUT_INDEX_FETCH_BIT                         = 0x00000004,    /// Controls input coherency of index fetches
+    VK_MEMORY_INPUT_VERTEX_ATTRIBUTE_FETCH_BIT              = 0x00000008,    /// Controls input coherency of vertex attribute fetches
+    VK_MEMORY_INPUT_UNIFORM_READ_BIT                        = 0x00000010,    /// Controls input coherency of uniform buffer reads
+    VK_MEMORY_INPUT_SHADER_READ_BIT                         = 0x00000020,    /// Controls input coherency of generic shader reads
+    VK_MEMORY_INPUT_COLOR_ATTACHMENT_BIT                    = 0x00000040,    /// Controls input coherency of color attachment reads
+    VK_MEMORY_INPUT_DEPTH_STENCIL_ATTACHMENT_BIT            = 0x00000080,    /// Controls input coherency of depth/stencil attachment reads
+    VK_MEMORY_INPUT_INPUT_ATTACHMENT_BIT                    = 0x00000100,    /// Controls input coherency of input attachment reads
+    VK_MEMORY_INPUT_TRANSFER_BIT                            = 0x00000200,    /// Controls input coherency of transfer operations
+}
+
+/// Buffer usage flags
+bitfield VkBufferUsageFlags {
+    VK_BUFFER_USAGE_GENERAL                                 = 0x00000000,    /// No special usage
+    VK_BUFFER_USAGE_TRANSFER_SOURCE_BIT                     = 0x00000001,    /// Can be used as a source of transfer operations
+    VK_BUFFER_USAGE_TRANSFER_DESTINATION_BIT                = 0x00000002,    /// Can be used as a destination of transfer operations
+    VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT                = 0x00000004,    /// Can be used as TBO
+    VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT                = 0x00000008,    /// Can be used as IBO
+    VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT                      = 0x00000010,    /// Can be used as UBO
+    VK_BUFFER_USAGE_STORAGE_BUFFER_BIT                      = 0x00000020,    /// Can be used as SSBO
+    VK_BUFFER_USAGE_INDEX_BUFFER_BIT                        = 0x00000040,    /// Can be used as source of fixed function index fetch (index buffer)
+    VK_BUFFER_USAGE_VERTEX_BUFFER_BIT                       = 0x00000080,    /// Can be used as source of fixed function vertex fetch (VBO)
+    VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT                     = 0x00000100,    /// Can be the source of indirect parameters (e.g. indirect buffer, parameter buffer)
+}
+
+/// Buffer creation flags
+bitfield VkBufferCreateFlags {
+    VK_BUFFER_CREATE_SPARSE_BIT                             = 0x00000001,    /// Buffer should support sparse backing
+    VK_BUFFER_CREATE_SPARSE_RESIDENCY_BIT                   = 0x00000002,    /// Buffer should support sparse backing with partial residency
+    VK_BUFFER_CREATE_SPARSE_ALIASED_BIT                     = 0x00000004,    /// Buffer should support constent data access to physical memory blocks mapped into multiple locations of sparse buffers
+}
+
+/// Shader stage flags
+bitfield VkShaderStageFlags {
+    VK_SHADER_STAGE_VERTEX_BIT                              = 0x00000001,
+    VK_SHADER_STAGE_TESS_CONTROL_BIT                        = 0x00000002,
+    VK_SHADER_STAGE_TESS_EVALUATION_BIT                     = 0x00000004,
+    VK_SHADER_STAGE_GEOMETRY_BIT                            = 0x00000008,
+    VK_SHADER_STAGE_FRAGMENT_BIT                            = 0x00000010,
+    VK_SHADER_STAGE_COMPUTE_BIT                             = 0x00000020,
+
+    VK_SHADER_STAGE_ALL                                     = 0x7FFFFFFF,
+}
+
+/// Image usage flags
+bitfield VkImageUsageFlags {
+    VK_IMAGE_USAGE_GENERAL                                  = 0x00000000,    /// No special usage
+    VK_IMAGE_USAGE_TRANSFER_SOURCE_BIT                      = 0x00000001,    /// Can be used as a source of transfer operations
+    VK_IMAGE_USAGE_TRANSFER_DESTINATION_BIT                 = 0x00000002,    /// Can be used as a destination of transfer operations
+    VK_IMAGE_USAGE_SAMPLED_BIT                              = 0x00000004,    /// Can be sampled from (SAMPLED_IMAGE and COMBINED_IMAGE_SAMPLER descriptor types)
+    VK_IMAGE_USAGE_STORAGE_BIT                              = 0x00000008,    /// Can be used as storage image (STORAGE_IMAGE descriptor type)
+    VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT                     = 0x00000010,    /// Can be used as framebuffer color attachment
+    VK_IMAGE_USAGE_DEPTH_STENCIL_BIT                        = 0x00000020,    /// Can be used as framebuffer depth/stencil attachment
+    VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT                 = 0x00000040,    /// Image data not needed outside of rendering
+    VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT                     = 0x00000080,    /// Can be used as framebuffer input attachment
+}
+
+/// Image creation flags
+bitfield VkImageCreateFlags {
+    VK_IMAGE_CREATE_SPARSE_BIT                              = 0x00000001,    /// Image should support sparse backing
+    VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT                    = 0x00000002,    /// Image should support sparse backing with partial residency
+    VK_IMAGE_CREATE_SPARSE_ALIASED_BIT                      = 0x00000004,    /// Image should support constent data access to physical memory blocks mapped into multiple locations of sparse images
+    VK_IMAGE_CREATE_INVARIANT_DATA_BIT                      = 0x00000008,
+    VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT                      = 0x00000010,    /// Allows image views to have different format than the base image
+    VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT                     = 0x00000020,    /// Allows creating image views with cube type from the created image
+}
+
+/// Framebuffer attachment view creation flags
+bitfield VkAttachmentViewCreateFlags {
+    VK_ATTACHMENT_VIEW_CREATE_READ_ONLY_DEPTH_BIT           = 0x00000001,
+    VK_ATTACHMENT_VIEW_CREATE_READ_ONLY_STENCIL_BIT         = 0x00000002,
+}
+
+/// Pipeline creation flags
+bitfield VkPipelineCreateFlags {
+    VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT             = 0x00000001,
+    VK_PIPELINE_CREATE_ALLOW_DERIVATIVES_BIT                = 0x00000002,
+    VK_PIPELINE_CREATE_DERIVATIVE_BIT                       = 0x00000004,
+}
+
+/// Channel flags
+bitfield VkChannelFlags {
+    VK_CHANNEL_R_BIT                                        = 0x00000001,
+    VK_CHANNEL_G_BIT                                        = 0x00000002,
+    VK_CHANNEL_B_BIT                                        = 0x00000004,
+    VK_CHANNEL_A_BIT                                        = 0x00000008,
+}
+
+/// Fence creation flags
+bitfield VkFenceCreateFlags {
+    VK_FENCE_CREATE_SIGNALED_BIT                            = 0x00000001,
+}
+
+/// Semaphore creation flags
+bitfield VkSemaphoreCreateFlags {
+}
+
+/// Format capability flags
+bitfield VkFormatFeatureFlags {
+    VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT                     = 0x00000001,    /// Format can be used for sampled images (SAMPLED_IMAGE and COMBINED_IMAGE_SAMPLER descriptor types)
+    VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT                     = 0x00000002,    /// Format can be used for storage images (STORAGE_IMAGE descriptor type)
+    VK_FORMAT_FEATURE_STORAGE_IMAGE_ATOMIC_BIT              = 0x00000004,    /// Format supports atomic operations in case it's used for storage images
+    VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT              = 0x00000008,    /// Format can be used for uniform texel buffers (TBOs)
+    VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT              = 0x00000010,    /// Format can be used for storage texel buffers (IBOs)
+    VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_ATOMIC_BIT       = 0x00000020,    /// Format supports atomic operations in case it's used for storage texel buffers
+    VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT                     = 0x00000040,    /// Format can be used for vertex buffers (VBOs)
+    VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT                  = 0x00000080,    /// Format can be used for color attachment images
+    VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT            = 0x00000100,    /// Format supports blending in case it's used for color attachment images
+    VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT          = 0x00000200,    /// Format can be used for depth/stencil attachment images
+    VK_FORMAT_FEATURE_CONVERSION_BIT                        = 0x00000400,    /// Format can be used as the source or destination of format converting blits
+}
+
+/// Query control flags
+bitfield VkQueryControlFlags {
+    VK_QUERY_CONTROL_CONSERVATIVE_BIT                       = 0x00000001,    /// Allow conservative results to be collected by the query
+}
+
+/// Query result flags
+bitfield VkQueryResultFlags {
+    VK_QUERY_RESULT_DEFAULT                                 = 0x00000000,   /// Results of the queries are immediately written to the destination buffer as 32-bit values
+    VK_QUERY_RESULT_64_BIT                                  = 0x00000001,   /// Results of the queries are written to the destination buffer as 64-bit values
+    VK_QUERY_RESULT_WAIT_BIT                                = 0x00000002,   /// Results of the queries are waited on before proceeding with the result copy
+    VK_QUERY_RESULT_WITH_AVAILABILITY_BIT                   = 0x00000004,   /// Besides the results of the query, the availability of the results is also written
+    VK_QUERY_RESULT_PARTIAL_BIT                             = 0x00000008,   /// Copy the partial results of the query even if the final results aren't available
+}
+
+/// Shader module creation flags
+bitfield VkShaderModuleCreateFlags {
+}
+
+/// Shader creation flags
+bitfield VkShaderCreateFlags {
+}
+
+/// Event creation flags
+bitfield VkEventCreateFlags {
+}
+
+/// Command buffer creation flags
+bitfield VkCmdBufferCreateFlags {
+}
+
+/// Command buffer optimization flags
+bitfield VkCmdBufferOptimizeFlags {
+    VK_CMD_BUFFER_OPTIMIZE_SMALL_BATCH_BIT                  = 0x00000001,
+    VK_CMD_BUFFER_OPTIMIZE_PIPELINE_SWITCH_BIT              = 0x00000002,
+    VK_CMD_BUFFER_OPTIMIZE_ONE_TIME_SUBMIT_BIT              = 0x00000004,
+    VK_CMD_BUFFER_OPTIMIZE_DESCRIPTOR_SET_SWITCH_BIT        = 0x00000008,
+    VK_CMD_BUFFER_OPTIMIZE_NO_SIMULTANEOUS_USE_BIT          = 0x00000010,  /// Only one call to the secondary command buffer will exist at any given time
+}
+
+/// Pipeline statistics flags
+bitfield VkQueryPipelineStatisticFlags {
+    VK_QUERY_PIPELINE_STATISTIC_IA_VERTICES_BIT             = 0x00000001,  /// Optional
+    VK_QUERY_PIPELINE_STATISTIC_IA_PRIMITIVES_BIT           = 0x00000002,  /// Optional
+    VK_QUERY_PIPELINE_STATISTIC_VS_INVOCATIONS_BIT          = 0x00000004,  /// Optional
+    VK_QUERY_PIPELINE_STATISTIC_GS_INVOCATIONS_BIT          = 0x00000008,  /// Optional
+    VK_QUERY_PIPELINE_STATISTIC_GS_PRIMITIVES_BIT           = 0x00000010,  /// Optional
+    VK_QUERY_PIPELINE_STATISTIC_C_INVOCATIONS_BIT           = 0x00000020,  /// Optional
+    VK_QUERY_PIPELINE_STATISTIC_C_PRIMITIVES_BIT            = 0x00000040,  /// Optional
+    VK_QUERY_PIPELINE_STATISTIC_FS_INVOCATIONS_BIT          = 0x00000080,  /// Optional
+    VK_QUERY_PIPELINE_STATISTIC_TCS_PATCHES_BIT             = 0x00000100,  /// Optional
+    VK_QUERY_PIPELINE_STATISTIC_TES_INVOCATIONS_BIT         = 0x00000200,  /// Optional
+    VK_QUERY_PIPELINE_STATISTIC_CS_INVOCATIONS_BIT          = 0x00000400,  /// Optional
+}
+
+/// Memory mapping flags
+bitfield VkMemoryMapFlags {
+}
+
+/// Bitfield of image aspects
+bitfield VkImageAspectFlags {
+    VK_IMAGE_ASPECT_COLOR_BIT                               = 0x00000001,
+    VK_IMAGE_ASPECT_DEPTH_BIT                               = 0x00000002,
+    VK_IMAGE_ASPECT_STENCIL_BIT                             = 0x00000004,
+    VK_IMAGE_ASPECT_METADATA_BIT                            = 0x00000008,
+}
+
+/// Sparse memory bind flags
+bitfield VkSparseMemoryBindFlags {
+    VK_SPARSE_MEMORY_BIND_REPLICATE_64KIB_BLOCK_BIT         = 0x00000001,  /// Replicate the first 64 KiB memory block to the entire bind rage
+}
+
+/// Sparse image memory requirements flags
+bitfield VkSparseImageFormatFlags {
+    VK_SPARSE_IMAGE_FMT_SINGLE_MIPTAIL_BIT                  = 0x00000001,  /// Image uses a single miptail region for all array slices
+    VK_SPARSE_IMAGE_FMT_ALIGNED_MIP_SIZE_BIT                = 0x00000002,  /// Image requires mip levels to be an exact multiple of the sparse iamge block size for non-mip-tail levels.
+    VK_SPARSE_IMAGE_FMT_NONSTD_BLOCK_SIZE_BIT               = 0x00000004,  /// Image uses a non-standard sparse block size
+}
+
+/// Pipeline stages
+bitfield VkPipelineStageFlags {
+    VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT                       = 0x00000001,  /// Before subsequent commands are processed
+    VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT                     = 0x00000002,  /// Draw/DispatchIndirect command fetch
+    VK_PIPELINE_STAGE_VERTEX_INPUT_BIT                      = 0x00000004,  /// Vertex/index fetch
+    VK_PIPELINE_STAGE_VERTEX_SHADER_BIT                     = 0x00000008,  /// Vertex shading
+    VK_PIPELINE_STAGE_TESS_CONTROL_SHADER_BIT               = 0x00000010,  /// Tessellation control shading
+    VK_PIPELINE_STAGE_TESS_EVALUATION_SHADER_BIT            = 0x00000020,  /// Tessellation evaluation shading
+    VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT                   = 0x00000040,  /// Geometry shading
+    VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT                   = 0x00000080,  /// Fragment shading
+    VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT              = 0x00000100,  /// Early fragment (depth/stencil) tests
+    VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT               = 0x00000200,  /// Late fragment (depth/stencil) tests
+    VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT           = 0x00000400,  /// Color attachment writes
+    VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT                    = 0x00000800,  /// Compute shading
+    VK_PIPELINE_STAGE_TRANSFER_BIT                          = 0x00001000,  /// Transfer/copy operations
+    VK_PIPELINE_STAGE_TRANSITION_BIT                        = 0x00002000,  /// Resource transition commands
+    VK_PIPELINE_STAGE_HOST_BIT                              = 0x00004000,  /// Indicates host (CPU) is a source/sink of the dependency
+
+    VK_PIPELINE_STAGE_ALL_GRAPHICS                          = 0x000007FF,  /// All stages of the graphics pipeline
+    VK_PIPELINE_STAGE_ALL_GPU_COMMANDS                      = 0x00003FFF,  /// All graphics, compute, copy, and transition commands
+}
+
+/// Subpass description flags
+bitfield VkSubpassDescriptionFlags {
+    VK_SUBPASS_DESCRIPTION_NO_OVERDRAW_BIT                  = 0x00000001,
+}
+
+/// Command pool creation flags
+bitfield VkCmdPoolCreateFlags {
+    VK_CMD_POOL_CREATE_TRANSIENT_BIT                        = 0x00000001,  /// Command buffers have a short lifetime
+    VK_CMD_POOL_CREATE_RESET_COMMAND_BUFFER_BIT             = 0x00000002,  /// Command buffers may release their memory individually
+}
+
+/// Command pool reset flags
+bitfield VkCmdPoolResetFlags {
+    VK_CMD_POOL_RESET_RELEASE_RESOURCES                     = 0x00000001,  /// Release resources owned by the pool
+}
+
+bitfield VkCmdBufferResetFlags {
+    VK_CMD_BUFFER_RESET_RELEASE_RESOURCES                   = 0x00000001,  /// Release resources owned by the buffer
+}
+
+
+//////////////////
+//  Structures  //
+//////////////////
+
+class VkOffset2D {
+    s32                                         x
+    s32                                         y
+}
+
+class VkOffset3D {
+    s32                                         x
+    s32                                         y
+    s32                                         z
+}
+
+class VkExtent2D {
+    s32                                         width
+    s32                                         height
+}
+
+class VkExtent3D {
+    s32                                         width
+    s32                                         height
+    s32                                         depth
+}
+
+class VkViewport {
+    f32                                         originX
+    f32                                         originY
+    f32                                         width
+    f32                                         height
+    f32                                         minDepth
+    f32                                         maxDepth
+}
+
+class VkRect2D {
+    VkOffset2D                                  offset
+    VkExtent2D                                  extent
+}
+
+class VkRect3D {
+    VkOffset3D                                  offset
+    VkExtent3D                                  extent
+}
+
+class VkChannelMapping {
+    VkChannelSwizzle                            r
+    VkChannelSwizzle                            g
+    VkChannelSwizzle                            b
+    VkChannelSwizzle                            a
+}
+
+class VkPhysicalDeviceProperties {
+    u32                                         apiVersion
+    u32                                         driverVersion
+    u32                                         vendorId
+    u32                                         deviceId
+    VkPhysicalDeviceType                        deviceType
+    char[VK_MAX_PHYSICAL_DEVICE_NAME]           deviceName
+    u8[VK_UUID_LENGTH]                          pipelineCacheUUID
+}
+
+class VkExtensionProperties {
+    char[VK_MAX_EXTENSION_NAME]                 extName            /// extension name
+    u32                                         specVersion        /// version of the extension specification implemented
+}
+
+class VkLayerProperties {
+    char[VK_MAX_EXTENSION_NAME]                 layerName          /// layer name
+    u32                                         specVersion        /// version of the layer specification implemented
+    u32                                         implVersion        /// build or release version of the layer's library
+    const char*[VK_MAX_DESCRIPTION]             description        /// Free-form description of the layer
+}
+
+class VkApplicationInfo {
+    VkStructureType                             sType              /// Type of structure. Should be VK_STRUCTURE_TYPE_APPLICATION_INFO
+    const void*                                 pNext              /// Next structure in chain
+    const char*                                 pAppName
+    u32                                         appVersion
+    const char*                                 pEngineName
+    u32                                         engineVersion
+    u32                                         apiVersion
+}
+
+class VkAllocCallbacks {
+    void*                                       pUserData
+    PFN_vkAllocFunction                         pfnAlloc
+    PFN_vkFreeFunction                          pfnFree
+}
+
+class VkDeviceQueueCreateInfo {
+    u32                                         queueFamilyIndex
+    u32                                         queueCount
+}
+
+class VkDeviceCreateInfo {
+    VkStructureType                             sType                      /// Should be VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO
+    const void*                                 pNext                      /// Pointer to next structure
+    u32                                         queueRecordCount
+    const VkDeviceQueueCreateInfo*              pRequestedQueues
+    u32                                         layerCount
+    const char* const*                          ppEnabledLayerNames        /// Ordered list of layer names to be enabled
+    u32                                         extensionCount
+    const char* const*                          ppEnabledExtensionNames
+    const VkPhysicalDeviceFeatures*             pEnabledFeatures
+    VkDeviceCreateFlags                         flags                      /// Device creation flags
+}
+
+class VkInstanceCreateInfo {
+    VkStructureType                             sType                      /// Should be VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO
+    const void*                                 pNext                      /// Pointer to next structure
+    const VkApplicationInfo*                    pAppInfo
+    const VkAllocCallbacks*                     pAllocCb
+    u32                                         layerCount
+    const char* const*                          ppEnabledLayerNames        /// Ordered list of layer names to be enabled
+    u32                                         extensionCount
+    const char* const*                          ppEnabledExtensionNames    /// Extension names to be enabled
+}
+
+class VkPhysicalDeviceQueueProperties {
+    VkQueueFlags                                queueFlags                 /// Queue flags
+    u32                                         queueCount
+    platform.VkBool32                           supportsTimestamps
+}
+
+class VkPhysicalDeviceMemoryProperties {
+    u32                                         memoryTypeCount
+    VkMemoryType[VK_MAX_MEMORY_TYPES]           memoryTypes
+    u32                                         memoryHeapCount
+    VkMemoryHeap[VK_MAX_MEMORY_HEAPS]           memoryHeaps
+}
+
+class VkMemoryAllocInfo {
+    VkStructureType                             sType                      /// Must be VK_STRUCTURE_TYPE_MEMORY_ALLOC_INFO
+    const void*                                 pNext                      /// Pointer to next structure
+    platform.VkDeviceSize                       allocationSize             /// Size of memory allocation
+    u32                                         memoryTypeIndex            /// Index of the of the memory type to allocate from
+}
+
+class VkMemoryRequirements {
+    platform.VkDeviceSize                       size                       /// Specified in bytes
+    platform.VkDeviceSize                       alignment                  /// Specified in bytes
+    u32                                         memoryTypeBits             /// Bitfield of the allowed memory type indices into memoryTypes[] for this object
+}
+
+class VkSparseImageFormatProperties {
+    VkImageAspect                               aspect
+    VkExtent3D                                  imageGranularity
+    VkSparseImageFormatFlags                    flags
+}
+
+class VkSparseImageMemoryRequirements {
+    VkSparseImageFormatProperties               formatProps
+    u32                                         imageMipTailStartLOD
+    platform.VkDeviceSize                       imageMipTailSize           /// Specified in bytes, must be a multiple of image block size / alignment
+    platform.VkDeviceSize                       imageMipTailOffset         /// Specified in bytes, must be a multiple of image block size / alignment
+    platform.VkDeviceSize                       imageMipTailStride         /// Specified in bytes, must be a multiple of image block size / alignment
+}
+
+class VkMemoryType {
+    VkMemoryPropertyFlags                       propertyFlags              /// Memory properties of this memory type
+    u32                                         heapIndex                  /// Index of the memory heap allocations of this memory type are taken from
+}
+
+class VkMemoryHeap {
+    platform.VkDeviceSize                       size                       /// Available memory in the heap
+    VkMemoryHeapFlags                           flags                      /// Flags for the heap
+}
+
+class VkMappedMemoryRange {
+    VkStructureType                             sType                      /// Must be VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE
+    const void*                                 pNext                      /// Pointer to next structure
+    VkDeviceMemory                              mem                        /// Mapped memory object
+    platform.VkDeviceSize                       offset                     /// Offset within the mapped memory the range starts from
+    platform.VkDeviceSize                       size                       /// Size of the range within the mapped memory
+}
+
+class VkFormatProperties {
+    VkFormatFeatureFlags                        linearTilingFeatures       /// Format features in case of linear tiling
+    VkFormatFeatureFlags                        optimalTilingFeatures      /// Format features in case of optimal tiling
+}
+
+class VkImageFormatProperties {
+    u64                                         maxResourceSize            /// max size (in bytes) of this resource type
+    u32                                         maxSamples                 /// max sample count for this resource type
+}
+
+class VkDescriptorInfo {
+    VkBufferView                                bufferView                 /// Buffer view to write to the descriptor (in case it's a buffer descriptor, otherwise should be VK_NULL_HANDLE)
+    VkSampler                                   sampler                    /// Sampler to write to the descriptor (in case it's a SAMPLER or COMBINED_IMAGE_SAMPLER descriptor, otherwise should be VK_NULL_HANDLE)
+    VkImageView                                 imageView                  /// Image view to write to the descriptor (in case it's a SAMPLED_IMAGE, STORAGE_IMAGE, or COMBINED_IMAGE_SAMPLER descriptor, otherwise should be VK_NULL_HANDLE)
+    VkAttachmentView                            attachmentView             /// Input attachment view to write to the descriptor (in case it's a INPUT_ATTACHMENT descriptor, otherwise should be VK_NULL_HANDLE)
+    VkImageLayout                               imageLayout                /// Layout the image is expected to be in when accessed using this descriptor (only used if imageView or attachmentView is not VK_NULL_HANDLE)
+}
+
+class VkWriteDescriptorSet {
+    VkStructureType                             sType                      /// Must be VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET
+    const void*                                 pNext                      /// Pointer to next structure
+    VkDescriptorSet                             destSet                    /// Destination descriptor set
+    u32                                         destBinding                /// Binding within the destination descriptor set to write
+    u32                                         destArrayElement           /// Array element within the destination binding to write
+    u32                                         count                      /// Number of descriptors to write (determines the size of the array pointed by <pDescriptors>)
+    VkDescriptorType                            descriptorType             /// Descriptor type to write (determines which fields of the array pointed by <pDescriptors> are going to be used)
+    const VkDescriptorInfo*                     pDescriptors               /// Array of info structures describing the descriptors to write
+}
+
+class VkCopyDescriptorSet {
+    VkStructureType                             sType                      /// Must be VK_STRUCTURE_TYPE_COPY_DESCRIPTOR_SET
+    const void*                                 pNext                      /// Pointer to next structure
+    VkDescriptorSet                             srcSet                     /// Source descriptor set
+    u32                                         srcBinding                 /// Binding within the source descriptor set to copy from
+    u32                                         srcArrayElement            /// Array element within the source binding to copy from
+    VkDescriptorSet                             destSet                    /// Destination descriptor set
+    u32                                         destBinding                /// Binding within the destination descriptor set to copy to
+    u32                                         destArrayElement           /// Array element within the destination binding to copy to
+    u32                                         count                      /// Number of descriptors to copy
+}
+
+class VkBufferCreateInfo {
+    VkStructureType                             sType                      /// Must be VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO
+    const void*                                 pNext                      /// Pointer to next structure.
+    platform.VkDeviceSize                       size                       /// Specified in bytes
+    VkBufferUsageFlags                          usage                      /// Buffer usage flags
+    VkBufferCreateFlags                         flags                      /// Buffer creation flags
+    VkSharingMode                               sharingMode
+    u32                                         queueFamilyCount
+    const u32*                                  pQueueFamilyIndices
+}
+
+class VkBufferViewCreateInfo {
+    VkStructureType                             sType                      /// Must be VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO
+    const void*                                 pNext                      /// Pointer to next structure.
+    VkBuffer                                    buffer
+    VkBufferViewType                            viewType
+    VkFormat                                    format                     /// Optionally specifies format of elements
+    platform.VkDeviceSize                       offset                     /// Specified in bytes
+    platform.VkDeviceSize                       range                      /// View size specified in bytes
+}
+
+class VkImageSubresource {
+    VkImageAspect                               aspect
+    u32                                         mipLevel
+    u32                                         arraySlice
+}
+
+class VkImageSubresourceRange {
+    VkImageAspect                               aspect
+    u32                                         baseMipLevel
+    u32                                         mipLevels
+    u32                                         baseArraySlice
+    u32                                         arraySize
+}
+
+class VkMemoryBarrier {
+    VkStructureType                             sType                      /// Must be VK_STRUCTURE_TYPE_MEMORY_BARRIER
+    const void*                                 pNext                      /// Pointer to next structure.
+    VkMemoryOutputFlags                         outputMask                 /// Outputs the barrier should sync
+    VkMemoryInputFlags                          inputMask                  /// Inputs the barrier should sync to
+}
+
+class VkBufferMemoryBarrier {
+    VkStructureType                             sType                      /// Must be VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER
+    const void*                                 pNext                      /// Pointer to next structure.
+    VkMemoryOutputFlags                         outputMask                 /// Outputs the barrier should sync
+    VkMemoryInputFlags                          inputMask                  /// Inputs the barrier should sync to
+    u32                                         srcQueueFamilyIndex        /// Queue family to transition ownership from
+    u32                                         destQueueFamilyIndex       /// Queue family to transition ownership to
+    VkBuffer                                    buffer                     /// Buffer to sync
+    platform.VkDeviceSize                       offset                     /// Offset within the buffer to sync
+    platform.VkDeviceSize                       size                       /// Amount of bytes to sync
+}
+
+class VkImageMemoryBarrier {
+    VkStructureType                             sType                      /// Must be VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER
+    const void*                                 pNext                      /// Pointer to next structure.
+    VkMemoryOutputFlags                         outputMask                 /// Outputs the barrier should sync
+    VkMemoryInputFlags                          inputMask                  /// Inputs the barrier should sync to
+    VkImageLayout                               oldLayout                  /// Current layout of the image
+    VkImageLayout                               newLayout                  /// New layout to transition the image to
+    u32                                         srcQueueFamilyIndex        /// Queue family to transition ownership from
+    u32                                         destQueueFamilyIndex       /// Queue family to transition ownership to
+    VkImage                                     image                      /// Image to sync
+    VkImageSubresourceRange                     subresourceRange           /// Subresource range to sync
+}
+
+class VkImageCreateInfo {
+    VkStructureType                             sType                      /// Must be VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO
+    const void*                                 pNext                      /// Pointer to next structure.
+    VkImageType                                 imageType
+    VkFormat                                    format
+    VkExtent3D                                  extent
+    u32                                         mipLevels
+    u32                                         arraySize
+    u32                                         samples
+    VkImageTiling                               tiling
+    VkImageUsageFlags                           usage                      /// Image usage flags
+    VkImageCreateFlags                          flags                      /// Image creation flags
+    VkSharingMode                               sharingMode                /// Cross-queue-family sharing mode
+    u32                                         queueFamilyCount           /// Number of queue families to share across
+    const u32*                                  pQueueFamilyIndices        /// Array of queue family indices to share across
+}
+
+class VkSubresourceLayout {
+    platform.VkDeviceSize                       offset                 /// Specified in bytes
+    platform.VkDeviceSize                       size                   /// Specified in bytes
+    platform.VkDeviceSize                       rowPitch               /// Specified in bytes
+    platform.VkDeviceSize                       depthPitch             /// Specified in bytes
+}
+
+class VkImageViewCreateInfo {
+    VkStructureType                             sType                  /// Must be VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO
+    const void*                                 pNext                  /// Pointer to next structure
+    VkImage                                     image
+    VkImageViewType                             viewType
+    VkFormat                                    format
+    VkChannelMapping                            channels
+    VkImageSubresourceRange                     subresourceRange
+}
+
+class VkAttachmentViewCreateInfo {
+    VkStructureType                             sType                  /// Must be VK_STRUCTURE_TYPE_ATTACHMENT_VIEW_CREATE_INFO
+    const void*                                 pNext                  /// Pointer to next structure
+    VkImage                                     image
+    VkFormat                                    format
+    u32                                         mipLevel
+    u32                                         baseArraySlice
+    u32                                         arraySize
+    VkAttachmentViewCreateFlags                 flags                  /// Framebuffer attachment view flags
+}
+
+class VkAttachmentBindInfo {
+    VkAttachmentView                            view
+    VkImageLayout                               layout
+}
+
+class VkBufferCopy {
+    platform.VkDeviceSize                       srcOffset              /// Specified in bytes
+    platform.VkDeviceSize                       destOffset             /// Specified in bytes
+    platform.VkDeviceSize                       copySize               /// Specified in bytes
+}
+
+class VkSparseMemoryBindInfo {
+    platform.VkDeviceSize                       offset                /// Specified in bytes
+    platform.VkDeviceSize                       memOffset             /// Specified in bytes
+    VkDeviceMemory                              mem
+    VkSparseMemoryBindFlags                     flags
+}
+
+class VkSparseImageMemoryBindInfo {
+    VkImageSubresource                          subresource
+    VkOffset3D                                  offset
+    VkExtent3D                                  extent
+    platform.VkDeviceSize                       memOffset             /// Specified in bytes
+    VkDeviceMemory                              mem
+    VkSparseMemoryBindFlags                     flags
+}
+
+class VkImageCopy {
+    VkImageSubresource                          srcSubresource
+    VkOffset3D                                  srcOffset             /// Specified in pixels for both compressed and uncompressed images
+    VkImageSubresource                          destSubresource
+    VkOffset3D                                  destOffset            /// Specified in pixels for both compressed and uncompressed images
+    VkExtent3D                                  extent                /// Specified in pixels for both compressed and uncompressed images
+}
+
+class VkImageBlit {
+    VkImageSubresource                          srcSubresource
+    VkOffset3D                                  srcOffset              /// Specified in pixels for both compressed and uncompressed images
+    VkExtent3D                                  srcExtent              /// Specified in pixels for both compressed and uncompressed images
+    VkImageSubresource                          destSubresource
+    VkOffset3D                                  destOffset             /// Specified in pixels for both compressed and uncompressed images
+    VkExtent3D                                  destExtent             /// Specified in pixels for both compressed and uncompressed images
+}
+
+class VkBufferImageCopy {
+    platform.VkDeviceSize                       bufferOffset           /// Specified in bytes
+    u32                                         bufferRowLength        /// Specified in texels
+    u32                                         bufferImageHeight
+    VkImageSubresource                          imageSubresource
+    VkOffset3D                                  imageOffset            /// Specified in pixels for both compressed and uncompressed images
+    VkExtent3D                                  imageExtent            /// Specified in pixels for both compressed and uncompressed images
+}
+
+class VkImageResolve {
+    VkImageSubresource                          srcSubresource
+    VkOffset3D                                  srcOffset
+    VkImageSubresource                          destSubresource
+    VkOffset3D                                  destOffset
+    VkExtent3D                                  extent
+}
+
+class VkShaderModuleCreateInfo {
+    VkStructureType                             sType                  /// Must be VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO
+    const void*                                 pNext                  /// Pointer to next structure
+    platform.size_t                             codeSize               /// Specified in bytes
+    const void*                                 pCode                  /// Binary code of size codeSize
+    VkShaderModuleCreateFlags                   flags                  /// Reserved
+}
+
+class VkShaderCreateInfo {
+    VkStructureType                             sType              /// Must be VK_STRUCTURE_TYPE_SHADER_CREATE_INFO
+    const void*                                 pNext              /// Pointer to next structure
+    VkShaderModule                              module             /// Module containing entry point
+    const char*                                 pName              /// Null-terminated entry point name
+    VkShaderCreateFlags                         flags              /// Reserved
+}
+
+class VkDescriptorSetLayoutBinding {
+    VkDescriptorType                            descriptorType     /// Type of the descriptors in this binding
+    u32                                         arraySize          /// Number of descriptors in this binding
+    VkShaderStageFlags                          stageFlags         /// Shader stages this binding is visible to
+    const VkSampler*                            pImmutableSamplers /// Immutable samplers (used if descriptor type is SAMPLER or COMBINED_IMAGE_SAMPLER, is either NULL or contains <count> number of elements)
+}
+
+class VkDescriptorSetLayoutCreateInfo {
+    VkStructureType                             sType              /// Must be VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO
+    const void*                                 pNext              /// Pointer to next structure
+    u32                                         count              /// Number of bindings in the descriptor set layout
+    const VkDescriptorSetLayoutBinding*         pBinding           /// Array of descriptor set layout bindings
+}
+
+class VkDescriptorTypeCount {
+    VkDescriptorType                            type
+    u32                                         count
+}
+
+class VkDescriptorPoolCreateInfo {
+    VkStructureType                             sType              /// Must be VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO
+    const void*                                 pNext              /// Pointer to next structure
+    u32                                         count
+    const VkDescriptorTypeCount*                pTypeCount
+}
+
+class VkSpecializationMapEntry {
+    u32                                         constantId         /// The SpecConstant ID specified in the BIL
+    platform.size_t                             size               /// Size in bytes of the SpecConstant
+    u32                                         offset             /// Offset of the value in the data block
+}
+
+class VkSpecializationInfo {
+    u32                                         mapEntryCount      /// Number of entries in the map
+    const VkSpecializationMapEntry*             pMap               /// Array of map entries
+    platform.size_t                             dataSize           /// Size in bytes of pData
+    const void*                                 pData              /// Pointer to SpecConstant data
+}
+
+class VkPipelineShaderStageCreateInfo {
+    VkStructureType                             sType              /// Must be VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO
+    const void*                                 pNext              /// Pointer to next structure
+    VkShaderStage                               stage
+    VkShader                                    shader
+    const VkSpecializationInfo*                 pSpecializationInfo
+}
+
+class VkComputePipelineCreateInfo {
+    VkStructureType                             sType              /// Must be VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO
+    const void*                                 pNext              /// Pointer to next structure
+    VkPipelineShaderStageCreateInfo             cs
+    VkPipelineCreateFlags                       flags              /// Pipeline creation flags
+    VkPipelineLayout                            layout             /// Interface layout of the pipeline
+    VkPipeline                                  basePipelineHandle /// If VK_PIPELINE_CREATE_DERIVATIVE_BIT is set and this value is nonzero, it specifies the handle of the base pipeline this is a derivative of
+    s32                                         basePipelineIndex  /// If VK_PIPELINE_CREATE_DERIVATIVE_BIT is set and this value is not -1, it specifies an index into pCreateInfos of the base pipeline this is a derivative of
+}
+
+class VkVertexInputBindingDescription {
+    u32                                         binding        /// Vertex buffer binding id
+    u32                                         strideInBytes  /// Distance between vertices in bytes (0 = no advancement)
+    VkVertexInputStepRate                       stepRate       /// Rate at which binding is incremented
+}
+
+class VkVertexInputAttributeDescription {
+    u32                                         location       /// location of the shader vertex attrib
+    u32                                         binding        /// Vertex buffer binding id
+    VkFormat                                    format         /// format of source data
+    u32                                         offsetInBytes  /// Offset of first element in bytes from base of vertex
+}
+
+class VkPipelineVertexInputStateCreateInfo {
+    VkStructureType                             sType          /// Should be VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO
+    const void*                                 pNext          /// Pointer to next structure
+    u32                                         bindingCount   /// number of bindings
+    const VkVertexInputBindingDescription*      pVertexBindingDescriptions
+    u32                                         attributeCount /// number of attributes
+    const VkVertexInputAttributeDescription*    pVertexAttributeDescriptions
+}
+
+class VkPipelineInputAssemblyStateCreateInfo {
+    VkStructureType                             sType      /// Must be VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO
+    const void*                                 pNext      /// Pointer to next structure
+    VkPrimitiveTopology                         topology
+    platform.VkBool32                           primitiveRestartEnable
+}
+
+class VkPipelineTessellationStateCreateInfo {
+    VkStructureType                             sType      /// Must be VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO
+    const void*                                 pNext      /// Pointer to next structure
+    u32                                         patchControlPoints
+}
+
+class VkPipelineViewportStateCreateInfo {
+    VkStructureType                             sType      /// Must be VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO
+    const void*                                 pNext      /// Pointer to next structure
+    u32                                         viewportCount
+}
+
+class VkPipelineRasterStateCreateInfo {
+    VkStructureType                             sType      /// Must be VK_STRUCTURE_TYPE_PIPELINE_RASTER_STATE_CREATE_INFO
+    const void*                                 pNext      /// Pointer to next structure
+    platform.VkBool32                           depthClipEnable
+    platform.VkBool32                           rasterizerDiscardEnable
+    VkFillMode                                  fillMode                   /// optional (GL45)
+    VkCullMode                                  cullMode
+    VkFrontFace                                 frontFace
+}
+
+class VkPipelineMultisampleStateCreateInfo {
+    VkStructureType                             sType      /// Must be VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO
+    const void*                                 pNext      /// Pointer to next structure
+    u32                                         rasterSamples              /// Number of samples used for rasterization
+    platform.VkBool32                           sampleShadingEnable        /// optional (GL45)
+    f32                                         minSampleShading           /// optional (GL45)
+    platform.VkSampleMask                       sampleMask
+}
+
+class VkPipelineColorBlendAttachmentState {
+    platform.VkBool32                           blendEnable
+    VkBlend                                     srcBlendColor
+    VkBlend                                     destBlendColor
+    VkBlendOp                                   blendOpColor
+    VkBlend                                     srcBlendAlpha
+    VkBlend                                     destBlendAlpha
+    VkBlendOp                                   blendOpAlpha
+    VkChannelFlags                              channelWriteMask
+}
+
+class VkPipelineColorBlendStateCreateInfo {
+    VkStructureType                             sType      /// Must be VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO
+    const void*                                 pNext      /// Pointer to next structure
+    platform.VkBool32                           alphaToCoverageEnable
+    platform.VkBool32                           logicOpEnable
+    VkLogicOp                                   logicOp
+    u32                                         attachmentCount    /// # of pAttachments
+    const VkPipelineColorBlendAttachmentState*  pAttachments
+}
+
+class VkStencilOpState {
+    VkStencilOp                                 stencilFailOp
+    VkStencilOp                                 stencilPassOp
+    VkStencilOp                                 stencilDepthFailOp
+    VkCompareOp                                 stencilCompareOp
+}
+
+class VkPipelineDepthStencilStateCreateInfo {
+    VkStructureType                             sType      /// Must be VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO
+    const void*                                 pNext      /// Pointer to next structure
+    platform.VkBool32                           depthTestEnable
+    platform.VkBool32                           depthWriteEnable
+    VkCompareOp                                 depthCompareOp
+    platform.VkBool32                           depthBoundsEnable  /// optional (depth_bounds_test)
+    platform.VkBool32                           stencilTestEnable
+    VkStencilOpState                            front
+    VkStencilOpState                            back
+}
+
+class VkGraphicsPipelineCreateInfo {
+    VkStructureType                                 sType      /// Must be VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO
+    const void*                                     pNext      /// Pointer to next structure
+    u32                                             stageCount
+    const VkPipelineShaderStageCreateInfo*          pStages    /// One entry for each active shader stage
+    const VkPipelineVertexInputStateCreateInfo*     pVertexInputState
+    const VkPipelineInputAssemblyStateCreateInfo*   pInputAssemblyState
+    const VkPipelineTessellationStateCreateInfo*    pTessellationState
+    const VkPipelineViewportStateCreateInfo*        pViewportState
+    const VkPipelineRasterStateCreateInfo*          pRasterState
+    const VkPipelineMultisampleStateCreateInfo*     pMultisampleState
+    const VkPipelineDepthStencilStateCreateInfo*    pDepthStencilState
+    const VkPipelineColorBlendStateCreateInfo*      pColorBlendState
+    VkPipelineCreateFlags                           flags              /// Pipeline creation flags
+    VkPipelineLayout                                layout             /// Interface layout of the pipeline
+    VkRenderPass                                    renderPass
+    u32                                             subpass
+    VkPipeline                                      basePipelineHandle /// If VK_PIPELINE_CREATE_DERIVATIVE_BIT is set and this value is nonzero, it specifies the handle of the base pipeline this is a derivative of
+    s32                                             basePipelineIndex  /// If VK_PIPELINE_CREATE_DERIVATIVE_BIT is set and this value is not -1, it specifies an index into pCreateInfos of the base pipeline this is a derivative of
+}
+
+class VkPipelineCacheCreateInfo {
+    VkStructureType                             sType        /// Must be VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO
+    const void*                                 pNext        /// Pointer to next structure
+    platform.size_t                             initialSize  /// Size of initial data to populate cache, in bytes
+    const void*                                 initialData  /// Initial data to populate cache
+    platform.size_t                             maxSize      /// Maximum size cache can grow to, in bytes. If zero, then the cache may grow without bound.
+}
+
+class VkPushConstantRange {
+    VkShaderStageFlags                          stageFlags   /// Which stages use the range
+    u32                                         start        /// Start of the range, in bytes
+    u32                                         length       /// Length of the range, in bytes
+}
+
+class VkPipelineLayoutCreateInfo {
+    VkStructureType                             sType                   /// Must be VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO
+    const void*                                 pNext                   /// Pointer to next structure
+    u32                                         descriptorSetCount      /// Number of descriptor sets interfaced by the pipeline
+    const VkDescriptorSetLayout*                pSetLayouts             /// Array of <setCount> number of descriptor set layout objects defining the layout of the
+    u32                                         pushConstantRangeCount  /// Number of push-constant ranges used by the pipeline
+    const VkPushConstantRange*                  pPushConstantRanges     /// Array of pushConstantRangeCount number of ranges used by various shader stages
+}
+
+class VkSamplerCreateInfo {
+    VkStructureType                             sType          /// Must be VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO
+    const void*                                 pNext          /// Pointer to next structure
+    VkTexFilter                                 magFilter      /// Filter mode for magnification
+    VkTexFilter                                 minFilter      /// Filter mode for minifiation
+    VkTexMipmapMode                             mipMode        /// Mipmap selection mode
+    VkTexAddress                                addressU
+    VkTexAddress                                addressV
+    VkTexAddress                                addressW
+    f32                                         mipLodBias
+    f32                                         maxAnisotropy
+    platform.VkBool32                           compareEnable
+    VkCompareOp                                 compareOp
+    f32                                         minLod
+    f32                                         maxLod
+    VkBorderColor                               borderColor
+}
+
+class VkDynamicViewportStateCreateInfo {
+    VkStructureType                             sType      /// Must be VK_STRUCTURE_TYPE_DYNAMIC_VIEWPORT_STATE_CREATE_INFO
+    const void*                                 pNext      /// Pointer to next structure
+    u32                                         viewportAndScissorCount  /// number of entries in pViewports and pScissors
+    const VkViewport*                           pViewports
+    const VkRect2D*                             pScissors
+}
+
+class VkDynamicRasterStateCreateInfo {
+    VkStructureType                             sType      /// Must be VK_STRUCTURE_TYPE_DYNAMIC_RASTER_STATE_CREATE_INFO
+    const void*                                 pNext      /// Pointer to next structure
+    f32                                         depthBias
+    f32                                         depthBiasClamp
+    f32                                         slopeScaledDepthBias
+    f32                                         lineWidth          /// optional (GL45) - Width of lines
+}
+
+class VkDynamicColorBlendStateCreateInfo {
+    VkStructureType                             sType      /// Must be VK_STRUCTURE_TYPE_DYNAMIC_COLOR_BLEND_STATE_CREATE_INFO
+    const void*                                 pNext      /// Pointer to next structure
+    f32[4]                                      blendConst
+}
+
+class VkDynamicDepthStencilStateCreateInfo {
+    VkStructureType                             sType      /// Must be VK_STRUCTURE_TYPE_DYNAMIC_DEPTH_STENCIL_STATE_CREATE_INFO
+    const void*                                 pNext      /// Pointer to next structure
+    f32                                         minDepthBounds         /// optional (depth_bounds_test)
+    f32                                         maxDepthBounds         /// optional (depth_bounds_test)
+    u32                                         stencilReadMask
+    u32                                         stencilWriteMask
+    u32                                         stencilFrontRef
+    u32                                         stencilBackRef
+}
+
+class VkCmdPoolCreateInfo {
+    VkStructureType                             sType            /// Must be VK_STRUCTURE_TYPE_CMD_POOL_CREATE_INFO
+    const void*                                 pNext            /// Pointer to next structure
+    u32                                         queueFamilyIndex
+    VkCmdPoolCreateFlags                        flags            /// Command pool creation flags
+}
+
+class VkCmdBufferCreateInfo {
+    VkStructureType                             sType      /// Must be VK_STRUCTURE_TYPE_CMD_BUFFER_CREATE_INFO
+    const void*                                 pNext      /// Pointer to next structure
+    VkCmdPool                                   cmdPool
+    VkCmdBufferLevel                            level
+    VkCmdBufferCreateFlags                      flags      /// Command buffer creation flags
+}
+
+class VkCmdBufferBeginInfo {
+    VkStructureType                             sType       /// Must be VK_STRUCTURE_TYPE_CMD_BUFFER_BEGIN_INFO
+    const void*                                 pNext       /// Pointer to next structure
+    VkCmdBufferOptimizeFlags                    flags       /// Command buffer optimization flags
+    VkRenderPass                                renderPass  /// Render pass for secondary command buffers
+    VkFramebuffer                               framebuffer /// Framebuffer for secondary command buffers
+}
+
+class VkRenderPassBeginInfo {
+    VkStructureType                             sType       /// Must be VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO
+    const void*                                 pNext       /// Pointer to next structure
+    VkRenderPass                                renderPass
+    VkFramebuffer                               framebuffer
+    VkRect2D                                    renderArea
+    u32                                         attachmentCount
+    const VkClearValue*                         pAttachmentClearValues
+}
+
+@union
+/// Union allowing specification of floating point, integer, or unsigned integer color data. Actual value selected is based on image/attachment being cleared.
+class VkClearColorValue {
+    f32[4]                                      f32
+    s32[4]                                      s32
+    u32[4]                                      u32
+}
+
+class VkClearDepthStencilValue {
+    f32                                         depth
+    u32                                         stencil
+}
+
+@union
+/// Union allowing specification of color, depth, and stencil color values. Actual value selected is based on attachment being cleared.
+class VkClearValue {
+    VkClearColorValue                           color
+    VkClearDepthStencilValue                    ds
+}
+
+class VkAttachmentDescription {
+    VkStructureType                             sType           /// Must be VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION
+    const void*                                 pNext           /// Pointer to next structure
+    VkFormat                                    format
+    u32                                         samples
+    VkAttachmentLoadOp                          loadOp          /// Load op for color or depth data
+    VkAttachmentStoreOp                         storeOp         /// Store op for color or depth data
+    VkAttachmentLoadOp                          stencilLoadOp   /// Load op for stencil data
+    VkAttachmentStoreOp                         stencilStoreOp  /// Store op for stencil data
+    VkImageLayout                               initialLayout
+    VkImageLayout                               finalLayout
+}
+
+class VkAttachmentReference {
+    u32                                         attachment
+    VkImageLayout                               layout
+}
+
+class VkSubpassDescription {
+    VkStructureType                             sType              /// Must be VK_STRUCTURE_SUBPASS_DESCRIPTION
+    const void*                                 pNext              /// Pointer to next structure
+    VkPipelineBindPoint                         pipelineBindPoint  /// Must be VK_PIPELINE_BIND_POINT_GRAPHICS for now
+    VkSubpassDescriptionFlags                   flags
+    u32                                         inputCount
+    const VkAttachmentReference*                inputAttachments
+    u32                                         colorCount
+    const VkAttachmentReference*                colorAttachments
+    const VkAttachmentReference*                resolveAttachments
+    VkAttachmentReference                       depthStencilAttachment
+    u32                                         preserveCount
+    const VkAttachmentReference*                preserveAttachments
+}
+
+class VkSubpassDependency {
+    VkStructureType                             sType      /// Must be VK_STRUCTURE_SUBPASS_DEPENDENCY
+    const void*                                 pNext      /// Pointer to next structure
+    u32                                         srcSubpass
+    u32                                         destSubpass
+    VkPipelineStageFlags                        srcStageMask
+    VkPipelineStageFlags                        destStageMask
+    VkMemoryOutputFlags                         outputMask
+    VkMemoryInputFlags                          inputMask
+    platform.VkBool32                           byRegion
+}
+
+class VkRenderPassCreateInfo {
+    VkStructureType                             sType      /// Must be VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO
+    const void*                                 pNext      /// Pointer to next structure
+    u32                                         attachmentCount
+    const VkAttachmentDescription*              pAttachments
+    u32                                         subpassCount
+    const VkSubpassDescription*                 pSubpasses
+    u32                                         dependencyCount
+    const VkSubpassDependency*                  pDependencies
+}
+
+class VkEventCreateInfo {
+    VkStructureType                             sType      /// Must be VK_STRUCTURE_TYPE_EVENT_CREATE_INFO
+    const void*                                 pNext      /// Pointer to next structure
+    VkEventCreateFlags                          flags      /// Event creation flags
+}
+
+class VkFenceCreateInfo {
+    VkStructureType                             sType      /// Must be VK_STRUCTURE_TYPE_FENCE_CREATE_INFO
+    const void*                                 pNext      /// Pointer to next structure
+    VkFenceCreateFlags                          flags      /// Fence creation flags
+}
+
+class VkPhysicalDeviceFeatures {
+    platform.VkBool32                           robustBufferAccess                        /// out of bounds buffer accesses are well defined
+    platform.VkBool32                           fullDrawIndexUint32                       /// full 32-bit range of indices for indexed draw calls
+    platform.VkBool32                           imageCubeArray                            /// image views which are arrays of cube maps
+    platform.VkBool32                           independentBlend                          /// blending operations are controlled per-attachment
+    platform.VkBool32                           geometryShader                            /// geometry stage
+    platform.VkBool32                           tessellationShader                        /// tessellation control and evaluation stage
+    platform.VkBool32                           sampleRateShading                         /// per-sample shading and interpolation
+    platform.VkBool32                           dualSourceBlend                           /// blend operations which take two sources
+    platform.VkBool32                           logicOp                                   /// logic operations
+    platform.VkBool32                           instancedDrawIndirect                     /// multi draw indirect
+    platform.VkBool32                           depthClip                                 /// depth clipping
+    platform.VkBool32                           depthBiasClamp                            /// depth bias clamping
+    platform.VkBool32                           fillModeNonSolid                          /// point and wireframe fill modes
+    platform.VkBool32                           depthBounds                               /// depth bounds test
+    platform.VkBool32                           wideLines                                 /// lines with width greater than 1
+    platform.VkBool32                           largePoints                               /// points with size greater than 1
+    platform.VkBool32                           textureCompressionETC2                    /// ETC texture compression formats
+    platform.VkBool32                           textureCompressionASTC_LDR                /// ASTC LDR texture compression formats
+    platform.VkBool32                           textureCompressionBC                      /// BC1-7 texture compressed formats
+    platform.VkBool32                           pipelineStatisticsQuery                   /// pipeline statistics query
+    platform.VkBool32                           vertexSideEffects                         /// storage buffers and images in vertex stage
+    platform.VkBool32                           tessellationSideEffects                   /// storage buffers and images in tessellation stage
+    platform.VkBool32                           geometrySideEffects                       /// storage buffers and images in geometry stage
+    platform.VkBool32                           fragmentSideEffects                       /// storage buffers and images in fragment stage
+    platform.VkBool32                           shaderTessellationPointSize               /// tessellation stage can export point size
+    platform.VkBool32                           shaderGeometryPointSize                   /// geometry stage can export point size
+    platform.VkBool32                           shaderTextureGatherExtended               /// texture gather with run-time values and independent offsets
+    platform.VkBool32                           shaderStorageImageExtendedFormats         /// the extended set of formats can be used for storage images
+    platform.VkBool32                           shaderStorageImageMultisample             /// multisample images can be used for storage images
+    platform.VkBool32                           shaderStorageBufferArrayConstantIndexing  /// arrays of storage buffers can be accessed with constant indices
+    platform.VkBool32                           shaderStorageImageArrayConstantIndexing   /// arrays of storage images can be accessed with constant indices
+    platform.VkBool32                           shaderUniformBufferArrayDynamicIndexing   /// arrays of uniform buffers can be accessed with dynamically uniform indices
+    platform.VkBool32                           shaderSampledImageArrayDynamicIndexing    /// arrays of sampled images can be accessed with dynamically uniform indices
+    platform.VkBool32                           shaderStorageBufferArrayDynamicIndexing   /// arrays of storage buffers can be accessed with dynamically uniform indices
+    platform.VkBool32                           shaderStorageImageArrayDynamicIndexing    /// arrays of storage images can be accessed with dynamically uniform indices
+    platform.VkBool32                           shaderClipDistance                        /// clip distance in shaders
+    platform.VkBool32                           shaderCullDistance                        /// cull distance in shaders
+    platform.VkBool32                           shaderFloat64                             /// 64-bit floats (doubles) in shaders
+    platform.VkBool32                           shaderInt64                               /// 64-bit integers in shaders
+    platform.VkBool32                           shaderFloat16                             /// 16-bit floats in shaders
+    platform.VkBool32                           shaderInt16                               /// 16-bit integers in shaders
+    platform.VkBool32                           shaderResourceResidency                   /// shader can use texture operations that return resource residency information (requires sparseNonResident support)
+    platform.VkBool32                           shaderResourceMinLOD                      /// shader can use texture operations that specify minimum resource LOD
+    platform.VkBool32                           sparse                                    /// Sparse resources support: Resource memory can be managed at opaque page level rather than object level
+    platform.VkBool32                           sparseResidencyBuffer                     /// Sparse resources support: GPU can access partially resident buffers
+    platform.VkBool32                           sparseResidencyImage2D                    /// Sparse resources support: GPU can access partially resident 2D (non-MSAA non-DepthStencil) images
+    platform.VkBool32                           sparseResidencyImage3D                    /// Sparse resources support: GPU can access partially resident 3D images
+    platform.VkBool32                           sparseResidency2Samples                   /// Sparse resources support: GPU can access partially resident MSAA 2D images with 2 samples
+    platform.VkBool32                           sparseResidency4Samples                   /// Sparse resources support: GPU can access partially resident MSAA 2D images with 4 samples
+    platform.VkBool32                           sparseResidency8Samples                   /// Sparse resources support: GPU can access partially resident MSAA 2D images with 8 samples
+    platform.VkBool32                           sparseResidency16Samples                  /// Sparse resources support: GPU can access partially resident MSAA 2D images with 16 samples
+    platform.VkBool32                           sparseResidencyStandard2DBlockShape       /// Sparse resources support: GPU will access all 2D (single sample) sparse resources using the standard block shapes (based on pixel format)
+    platform.VkBool32                           sparseResidencyStandard2DMSBlockShape     /// Sparse resources support: GPU will access all 2D (multisample) sparse resources using the standard block shapes (based on pixel format)
+    platform.VkBool32                           sparseResidencyStandard3DBlockShape       /// Sparse resources support: GPU will access all 3D sparse resources using the standard block shapes (based on pixel format)
+    platform.VkBool32                           sparseResidencyAlignedMipSize             /// Sparse resources support: Images with mip-level dimensions that are NOT a multiple of the block size will be placed in the mip tail
+    platform.VkBool32                           sparseResidencyNonResident                /// Sparse resources support: GPU can safely access non-resident regions of a resource, read values from read-write resources are undefined
+    platform.VkBool32                           sparseResidencyNonResidentStrict          /// Sparse resources support: GPU can safely access non-resident regions of a resource, all reads return as if data is 0, writes are discarded
+    platform.VkBool32                           sparseResidencyAliased                    /// Sparse resources support: GPU can correctly access data aliased into multiple locations (opt-in)
+}
+
+class VkPhysicalDeviceLimits {
+    /// resource maximum sizes
+    u32                                         maxImageDimension1D                       /// max 1D image dimension
+    u32                                         maxImageDimension2D                       /// max 2D image dimension
+    u32                                         maxImageDimension3D                       /// max 3D image dimension
+    u32                                         maxImageDimensionCube                     /// max cubemap image dimension
+    u32                                         maxImageArrayLayers                       /// max layers for image arrays
+    u32                                         maxTexelBufferSize                        /// max texel buffer size (bytes)
+    u32                                         maxUniformBufferSize                      /// max uniform buffer size (bytes)
+    u32                                         maxStorageBufferSize                      /// max storage buffer size (bytes)
+    u32                                         maxPushConstantsSize                      /// max size of the push constants pool (bytes)
+    /// memory limits
+    u32                                         maxMemoryAllocationCount                  /// max number of device memory allocations supported
+    platform.VkDeviceSize                       bufferImageGranularity                    /// Granularity (in bytes) at which buffers and images can be bound to adjacent memory for simultaneous usage
+    /// descriptor set limits
+    u32                                         maxBoundDescriptorSets                    /// max number of descriptors sets that can be bound to a pipeline
+    u32                                         maxDescriptorSets                         /// max number of allocated descriptor sets
+    u32                                         maxPerStageDescriptorSamplers             /// max num of samplers allowed per-stage in a descriptor set
+    u32                                         maxPerStageDescriptorUniformBuffers       /// max num of uniform buffers allowed per-stage in a descriptor set
+    u32                                         maxPerStageDescriptorStorageBuffers       /// max num of storage buffers allowed per-stage in a descriptor set
+    u32                                         maxPerStageDescriptorSampledImages        /// max num of sampled images allowed per-stage in a descriptor set
+    u32                                         maxPerStageDescriptorStorageImages        /// max num of storage images allowed per-stage in a descriptor set
+    u32                                         maxDescriptorSetSamplers                  /// max num of samplers allowed in all stages in a descriptor set
+    u32                                         maxDescriptorSetUniformBuffers            /// max num of uniform buffers allowed in all stages in a descriptor set
+    u32                                         maxDescriptorSetStorageBuffers            /// max num of storage buffers allowed in all stages in a descriptor set
+    u32                                         maxDescriptorSetSampledImages             /// max num of sampled images allowed in all stages in a descriptor set
+    u32                                         maxDescriptorSetStorageImages             /// max num of storage images allowed in all stages in a descriptor set
+    /// vertex stage limits
+    u32                                         maxVertexInputAttributes                  /// max num of vertex input attribute slots
+    u32                                         maxVertexInputAttributeOffset             /// max vertex input attribute offset added to vertex buffer offset
+    u32                                         maxVertexInputBindingStride               /// max vertex input binding stride
+    u32                                         maxVertexOutputComponents                 /// max num of output components written by vertex shader
+    /// tessellation control stage limits
+    u32                                         maxTessGenLevel                           /// max level supported by tess primitive generator
+    u32                                         maxTessPatchSize                          /// max patch size (vertices)
+    u32                                         maxTessControlPerVertexInputComponents    /// max num of input components per-vertex in TCS
+    u32                                         maxTessControlPerVertexOutputComponents   /// max num of output components per-vertex in TCS
+    u32                                         maxTessControlPerPatchOutputComponents    /// max num of output components per-patch in TCS
+    u32                                         maxTessControlTotalOutputComponents       /// max total num of per-vertex and per-patch output components in TCS
+    u32                                         maxTessEvaluationInputComponents          /// max num of input components per vertex in TES
+    u32                                         maxTessEvaluationOutputComponents         /// max num of output components per vertex in TES
+    /// geometry stage limits
+    u32                                         maxGeometryShaderInvocations              /// max invocation count supported in geometry shader
+    u32                                         maxGeometryInputComponents                /// max num of input components read in geometry stage
+    u32                                         maxGeometryOutputComponents               /// max num of output components written in geometry stage
+    u32                                         maxGeometryOutputVertices                 /// max num of vertices that can be emitted in geometry stage
+    u32                                         maxGeometryTotalOutputComponents          /// max total num of components (all vertices) written in geometry stage
+    /// fragment stage limits
+    u32                                         maxFragmentInputComponents                /// max num of input compontents read in fragment stage
+    u32                                         maxFragmentOutputBuffers                  /// max num of output buffers written in fragment stage
+    u32                                         maxFragmentDualSourceBuffers              /// max num of output buffers written when using dual source blending
+    u32                                         maxFragmentCombinedOutputResources        /// max total num of storage buffers, storage images and output buffers
+    /// compute stage limits
+    u32                                         maxComputeSharedMemorySize                /// max total storage size of work group local storage (bytes)
+    u32[3]                                      maxComputeWorkGroupCount                  /// max num of compute work groups that may be dispatched by a single command (x,y,z)
+    u32                                         maxComputeWorkGroupInvocations            /// max total compute invocations in a single local work group
+    u32[3]                                      maxComputeWorkGroupSize                   /// max local size of a compute work group (x,y,z)
+
+    u32                                         subPixelPrecisionBits                     /// num bits of subpixel precision in screen x and y
+    u32                                         subTexelPrecisionBits                     /// num bits of subtexel precision
+    u32                                         mipmapPrecisionBits                       /// num bits of mipmap precision
+
+    u32                                         maxDrawIndexedIndexValue                  /// max index value for indexed draw calls (for 32-bit indices)
+    u32                                         maxDrawIndirectInstanceCount              /// max instance count for indirect draw calls
+    platform.VkBool32                           primitiveRestartForPatches                /// is primitive restart supported for PATCHES
+
+    f32                                         maxSamplerLodBias                         /// max absolute sampler level of detail bias
+    f32                                         maxSamplerAnisotropy                      /// max degree of sampler anisotropy
+
+    u32                                         maxViewports                              /// max number of active viewports
+    u32                                         maxDynamicViewportStates                  /// max number of dynamic viewport state objects
+    u32[2]                                      maxViewportDimensions                     /// max viewport dimensions (x,y)
+    f32[2]                                      viewportBoundsRange                       /// viewport bounds range (min,max)
+    u32                                         viewportSubPixelBits                      /// num bits of subpixel precision for viewport
+
+    u32                                         minMemoryMapAlignment                     /// min required alignment of pointers returned by MapMemory (bytes)
+    u32                                         minTexelBufferOffsetAlignment             /// min required alignment for texel buffer offsets (bytes) 
+    u32                                         minUniformBufferOffsetAlignment           /// min required alignment for uniform buffer sizes and offsets (bytes)
+    u32                                         minStorageBufferOffsetAlignment           /// min required alignment for storage buffer offsets (bytes)
+
+    u32                                         minTexelOffset                            /// min texel offset for OpTextureSampleOffset
+    u32                                         maxTexelOffset                            /// max texel offset for OpTextureSampleOffset
+    u32                                         minTexelGatherOffset                      /// min texel offset for OpTextureGatherOffset
+    u32                                         maxTexelGatherOffset                      /// max texel offset for OpTextureGatherOffset
+    f32                                         minInterpolationOffset                    /// furthest negative offset for interpolateAtOffset
+    f32                                         maxInterpolationOffset                    /// furthest positive offset for interpolateAtOffset
+    u32                                         subPixelInterpolationOffsetBits           /// num of subpixel bits for interpolateAtOffset
+
+    u32                                         maxFramebufferWidth                       /// max width for a framebuffer
+    u32                                         maxFramebufferHeight                      /// max height for a framebuffer
+    u32                                         maxFramebufferLayers                      /// max layer count for a layered framebuffer
+    u32                                         maxFramebufferColorSamples                /// max color sample count for a framebuffer
+    u32                                         maxFramebufferDepthSamples                /// max depth sample count for a framebuffer
+    u32                                         maxFramebufferStencilSamples              /// max stencil sample count for a framebuffer
+    u32                                         maxColorAttachments                       /// max num of framebuffer color attachments
+
+    u32                                         maxSampledImageColorSamples               /// max num of color samples for a non-integer sampled image
+    u32                                         maxSampledImageDepthSamples               /// max num of depth/stencil samples for a sampled image
+    u32                                         maxSampledImageIntegerSamples             /// max num of samples supported for an integer image
+    u32                                         maxStorageImageSamples                    /// max num of samples for a storage image
+    u32                                         maxSampleMaskWords                        /// max num of sample mask words
+
+    u64                                         timestampFrequency                        /// 1/clock_tick_granularity for timestamp queries
+
+    u32                                         maxClipDistances                          /// max number of clip distances
+    u32                                         maxCullDistances                          /// max number of cull distances
+    u32                                         maxCombinedClipAndCullDistances           /// max combined number of user clipping
+
+    f32[2]                                      pointSizeRange                         /// range (min,max) of supported point sizes
+    f32[2]                                      lineWidthRange                         /// range (min,max) of supported line widths
+    f32                                         pointSizeGranularity                      /// granularity of supported point sizes
+    f32                                         lineWidthGranularity                      /// granularity of supported line widths
+}
+
+class VkSemaphoreCreateInfo {
+    VkStructureType                             sType      /// Must be VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO
+    const void*                                 pNext      /// Pointer to next structure
+    VkSemaphoreCreateFlags                      flags      /// Semaphore creation flags
+}
+
+class VkQueryPoolCreateInfo {
+    VkStructureType                             sType              /// Must be VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO
+    const void*                                 pNext              /// Pointer to next structure
+    VkQueryType                                 queryType
+    u32                                         slots
+    VkQueryPipelineStatisticFlags               pipelineStatistics /// Optional
+}
+
+class VkFramebufferCreateInfo {
+    VkStructureType                             sType  /// Must be VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO
+    const void*                                 pNext  /// Pointer to next structure
+    VkRenderPass                                renderPass
+    u32                                         attachmentCount
+    const VkAttachmentBindInfo*                 pAttachments
+    u32                                         width
+    u32                                         height
+    u32                                         layers
+}
+
+class VkDrawIndirectCmd {
+    u32                                         vertexCount
+    u32                                         instanceCount
+    u32                                         firstVertex
+    u32                                         firstInstance
+}
+
+class VkDrawIndexedIndirectCmd {
+    u32                                         indexCount
+    u32                                         instanceCount
+    u32                                         firstIndex
+    s32                                         vertexOffset
+    u32                                         firstInstance
+}
+
+class VkDispatchIndirectCmd {
+    u32                                         x
+    u32                                         y
+    u32                                         z
+}
+
+
+////////////////
+//  Commands  //
+////////////////
+
+// Function pointers. TODO: add support for function pointers.
+
+@external type void* PFN_vkVoidFunction
+@pfn cmd void vkVoidFunction() {
+}
+
+@external type void* PFN_vkAllocFunction
+@pfn cmd void* vkAllocFunction(
+        void*                                       pUserData,
+        platform.size_t                             size,
+        platform.size_t                             alignment,
+        VkSystemAllocType                           allocType) {
+    return ?
+}
+
+@external type void* PFN_vkFreeFunction
+@pfn cmd void vkFreeFunction(
+        void*                                       pUserData,
+        void*                                       pMem) {
+}
+
+
+// Global functions
+
+@threadSafety("system")
+cmd VkResult vkCreateInstance(
+        const VkInstanceCreateInfo*                 pCreateInfo,
+        VkInstance*                                 pInstance) {
+    assert(pCreateInfo.sType == VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO)
+
+    instance := ?
+    pInstance[0] = instance
+    State.Instances[instance] = new!InstanceObject()
+
+    layers := pCreateInfo.ppEnabledLayerNames[0:pCreateInfo.layerCount]
+    extensions := pCreateInfo.ppEnabledExtensionNames[0:pCreateInfo.extensionCount]
+
+    return ?
+}
+
+@threadSafety("system")
+cmd VkResult vkDestroyInstance(
+        VkInstance                                  instance) {
+    instanceObject := GetInstance(instance)
+
+    State.Instances[instance] = null
+
+    return ?
+}
+
+@threadSafety("system")
+cmd VkResult vkEnumeratePhysicalDevices(
+        VkInstance                                  instance,
+        u32*                                        pPhysicalDeviceCount,
+        VkPhysicalDevice*                           pPhysicalDevices) {
+    instanceObject := GetInstance(instance)
+
+    physicalDeviceCount := as!u32(?)
+    pPhysicalDeviceCount[0] = physicalDeviceCount
+    physicalDevices := pPhysicalDevices[0:physicalDeviceCount]
+
+    for i in (0 .. physicalDeviceCount) {
+        physicalDevice := ?
+        physicalDevices[i] = physicalDevice
+        if !(physicalDevice in State.PhysicalDevices) {
+            State.PhysicalDevices[physicalDevice] = new!PhysicalDeviceObject(instance: instance)
+        }
+    }
+
+    return ?
+}
+
+cmd PFN_vkVoidFunction vkGetDeviceProcAddr(
+        VkDevice                                    device,
+        const char*                                 pName) {
+    if device != VK_NULL_HANDLE {
+        device := GetDevice(device)
+    }
+
+    return ?
+}
+
+cmd PFN_vkVoidFunction vkGetInstanceProcAddr(
+        VkInstance                                  instance,
+        const char*                                 pName) {
+    if instance != VK_NULL_HANDLE {
+        instanceObject := GetInstance(instance)
+    }
+
+    return ?
+}
+
+cmd VkResult vkGetPhysicalDeviceProperties(
+        VkPhysicalDevice                            physicalDevice,
+        VkPhysicalDeviceProperties*                 pProperties) {
+    physicalDeviceObject := GetPhysicalDevice(physicalDevice)
+
+    properties := ?
+    pProperties[0] = properties
+
+    return ?
+}
+
+cmd VkResult vkGetPhysicalDeviceQueueCount(
+        VkPhysicalDevice                            physicalDevice,
+        u32*                                        pCount) {
+    physicalDeviceObject := GetPhysicalDevice(physicalDevice)
+
+    count := ?
+    pCount[0] = count
+
+    return ?
+}
+
+cmd VkResult vkGetPhysicalDeviceQueueProperties(
+        VkPhysicalDevice                            physicalDevice,
+        u32                                         count,
+        VkPhysicalDeviceQueueProperties*            pQueueProperties) {
+    physicalDeviceObject := GetPhysicalDevice(physicalDevice)
+    queuesProperties := pQueueProperties[0:count]
+    for i in (0 .. count) {
+        queueProperties := as!VkPhysicalDeviceQueueProperties(?)
+        queuesProperties[i] = queueProperties
+    }
+    return ?
+}
+
+cmd VkResult vkGetPhysicalDeviceMemoryProperties(
+        VkPhysicalDevice                            physicalDevice,
+        VkPhysicalDeviceMemoryProperties*           pMemoryProperties) {
+    physicalDeviceObject := GetPhysicalDevice(physicalDevice)
+
+    memoryProperties := ?
+    pMemoryProperties[0] = memoryProperties
+
+    return ?
+}
+
+cmd VkResult vkGetPhysicalDeviceFeatures(
+        VkPhysicalDevice                            physicalDevice,
+        VkPhysicalDeviceFeatures*                   pFeatures) {
+    physicalDeviceObject := GetPhysicalDevice(physicalDevice)
+
+    features := ?
+    pFeatures[0] = features
+
+    return ?
+}
+
+cmd VkResult vkGetPhysicalDeviceFormatProperties(
+        VkPhysicalDevice                            physicalDevice,
+        VkFormat                                    format,
+        VkFormatProperties*                         pFormatProperties) {
+    physicalDeviceObject := GetPhysicalDevice(physicalDevice)
+
+    formatProperties := ?
+    pFormatProperties[0] = formatProperties
+
+    return ?
+}
+
+cmd VkResult vkGetPhysicalDeviceImageFormatProperties(
+        VkPhysicalDevice                            physicalDevice,
+        VkFormat                                    format,
+        VkImageType                                 type,
+        VkImageTiling                               tiling,
+        VkImageUsageFlags                           usage,
+        VkImageFormatProperties*                    pImageFormatProperties) {
+    physicalDeviceObject := GetPhysicalDevice(physicalDevice)
+
+    imageFormatProperties := ?
+    pImageFormatProperties[0] = imageFormatProperties
+
+    return ?
+}
+
+cmd VkResult vkGetPhysicalDeviceLimits(
+        VkPhysicalDevice                            physicalDevice,
+        VkPhysicalDeviceLimits*                     pLimits) {
+    physicalDeviceObject := GetPhysicalDevice(physicalDevice)
+
+    limits := ?
+    pLimits[0] = limits
+
+    return ?
+}
+
+
+// Device functions
+
+@threadSafety("system")
+cmd VkResult vkCreateDevice(
+        VkPhysicalDevice                            physicalDevice,
+        const VkDeviceCreateInfo*                   pCreateInfo,
+        VkDevice*                                   pDevice) {
+    assert(pCreateInfo.sType == VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO)
+    physicalDeviceObject := GetPhysicalDevice(physicalDevice)
+
+    device := ?
+    pDevice[0] = device
+    State.Devices[device] = new!DeviceObject(physicalDevice: physicalDevice)
+
+    return ?
+}
+
+@threadSafety("system")
+cmd VkResult vkDestroyDevice(
+        VkDevice                                    device) {
+    deviceObject := GetDevice(device)
+
+    State.Devices[device] = null
+
+    return ?
+}
+
+
+// Extension discovery functions
+
+cmd VkResult vkGetGlobalLayerProperties(
+        u32*                                        pCount,
+        VkLayerProperties*                          pProperties) {
+    count := as!u32(?)
+    pCount[0] = count
+
+    properties := pProperties[0:count]
+    for i in (0 .. count) {
+        property := ?
+        properties[i] = property
+    }
+
+    return ?
+}
+
+cmd VkResult vkGetGlobalExtensionProperties(
+        const char*                                 pLayerName,
+        u32*                                        pCount,
+        VkExtensionProperties*                      pProperties) {
+    count := as!u32(?)
+    pCount[0] = count
+
+    properties := pProperties[0:count]
+    for i in (0 .. count) {
+        property := ?
+        properties[i] = property
+    }
+
+    return ?
+}
+
+cmd VkResult vkGetPhysicalDeviceLayerProperties(
+        VkPhysicalDevice                            physicalDevice,
+        u32*                                        pCount,
+        VkLayerProperties*                          pProperties) {
+    physicalDeviceObject := GetPhysicalDevice(physicalDevice)
+    count := as!u32(?)
+    pCount[0] = count
+
+    properties := pProperties[0:count]
+    for i in (0 .. count) {
+        property := ?
+        properties[i] = property
+    }
+
+    return ?
+}
+
+cmd VkResult vkGetPhysicalDeviceExtensionProperties(
+        VkPhysicalDevice                            physicalDevice,
+        const char*                                 pLayerName,
+        u32*                                        pCount,
+        VkExtensionProperties*                      pProperties) {
+    physicalDeviceObject := GetPhysicalDevice(physicalDevice)
+
+    count := as!u32(?)
+    pCount[0] = count
+
+    properties := pProperties[0:count]
+    for i in (0 .. count) {
+        property := ?
+        properties[i] = property
+    }
+
+    return ?
+}
+
+
+// Queue functions
+
+@threadSafety("system")
+cmd VkResult vkGetDeviceQueue(
+        VkDevice                                    device,
+        u32                                         queueFamilyIndex,
+        u32                                         queueIndex,
+        VkQueue*                                    pQueue) {
+    deviceObject := GetDevice(device)
+
+    queue := ?
+    pQueue[0] = queue
+
+    if !(queue in State.Queues) {
+        State.Queues[queue] = new!QueueObject(device: device)
+    }
+
+    return ?
+}
+
+@threadSafety("app")
+cmd VkResult vkQueueSubmit(
+        VkQueue                                     queue,
+        u32                                         cmdBufferCount,
+        const VkCmdBuffer*                          pCmdBuffers,
+        VkFence                                     fence) {
+    queueObject := GetQueue(queue)
+
+    if fence != VK_NULL_HANDLE {
+        fenceObject := GetFence(fence)
+        assert(fenceObject.device == queueObject.device)
+    }
+
+    cmdBuffers := pCmdBuffers[0:cmdBufferCount]
+    for i in (0 .. cmdBufferCount) {
+        cmdBuffer := cmdBuffers[i]
+        cmdBufferObject := GetCmdBuffer(cmdBuffer)
+        assert(cmdBufferObject.device == queueObject.device)
+
+        validate("QueueCheck", cmdBufferObject.queueFlags in queueObject.flags,
+            "vkQueueSubmit: enqueued cmdBuffer requires missing queue capabilities.")
+    }
+
+    return ?
+}
+
+@threadSafety("system")
+cmd VkResult vkQueueWaitIdle(
+        VkQueue                                     queue) {
+    queueObject := GetQueue(queue)
+
+    return ?
+}
+
+@threadSafety("system")
+cmd VkResult vkDeviceWaitIdle(
+        VkDevice                                    device) {
+    deviceObject := GetDevice(device)
+
+    return ?
+}
+
+
+// Memory functions
+
+@threadSafety("system")
+cmd VkResult vkAllocMemory(
+        VkDevice                                    device,
+        const VkMemoryAllocInfo*                    pAllocInfo,
+        VkDeviceMemory*                             pMem) {
+    assert(pAllocInfo.sType == VK_STRUCTURE_TYPE_MEMORY_ALLOC_INFO)
+    deviceObject := GetDevice(device)
+
+    mem := ?
+    pMem[0] = mem
+    State.DeviceMemories[mem] = new!DeviceMemoryObject(
+        device: device,
+        allocationSize: pAllocInfo[0].allocationSize)
+
+    return ?
+}
+
+@threadSafety("system")
+cmd VkResult vkFreeMemory(
+        VkDevice                                    device,
+        VkDeviceMemory                              mem) {
+    deviceObject := GetDevice(device)
+    memObject := GetDeviceMemory(mem)
+    assert(memObject.device == device)
+
+    // Check that no objects are still bound before freeing.
+    validate("MemoryCheck", len(memObject.boundObjects) == 0,
+        "vkFreeMemory: objects still bound")
+    validate("MemoryCheck", len(memObject.boundCommandBuffers) == 0,
+        "vkFreeMemory: cmdBuffers still bound")
+    State.DeviceMemories[mem] = null
+
+    return ?
+}
+
+@threadSafety("app")
+cmd VkResult vkMapMemory(
+        VkDevice                                    device,
+        VkDeviceMemory                              mem,
+        platform.VkDeviceSize                       offset,
+        platform.VkDeviceSize                       size,
+        VkMemoryMapFlags                            flags,
+        void**                                      ppData) {
+    deviceObject := GetDevice(device)
+    memObject := GetDeviceMemory(mem)
+    assert(memObject.device == device)
+
+    assert(flags == as!VkMemoryMapFlags(0))
+    assert((offset + size) <= memObject.allocationSize)
+
+    return ?
+}
+
+@threadSafety("app")
+cmd VkResult vkUnmapMemory(
+        VkDevice                                    device,
+        VkDeviceMemory                              mem) {
+    deviceObject := GetDevice(device)
+    memObject := GetDeviceMemory(mem)
+    assert(memObject.device == device)
+
+    return ?
+}
+
+cmd VkResult vkFlushMappedMemoryRanges(
+        VkDevice                                    device,
+        u32                                         memRangeCount
+        const VkMappedMemoryRange*                  pMemRanges) {
+    deviceObject := GetDevice(device)
+
+    memRanges := pMemRanges[0:memRangeCount]
+    for i in (0 .. memRangeCount) {
+        memRange := memRanges[i]
+        memObject := GetDeviceMemory(memRange.mem)
+        assert(memObject.device == device)
+        assert((memRange.offset + memRange.size) <= memObject.allocationSize)
+    }
+
+    return ?
+}
+
+cmd VkResult vkInvalidateMappedMemoryRanges(
+        VkDevice                                    device,
+        u32                                         memRangeCount,
+        const VkMappedMemoryRange*                  pMemRanges) {
+    deviceObject := GetDevice(device)
+
+    memRanges := pMemRanges[0:memRangeCount]
+    for i in (0 .. memRangeCount) {
+        memRange := memRanges[i]
+        memObject := GetDeviceMemory(memRange.mem)
+        assert(memObject.device == device)
+        assert((memRange.offset + memRange.size) <= memObject.allocationSize)
+    }
+
+    return ?
+}
+
+
+// Memory management API functions
+
+cmd VkResult vkGetDeviceMemoryCommitment(
+        VkDevice                                    device,
+        VkDeviceMemory                              memory,
+        platform.VkDeviceSize*                      pCommittedMemoryInBytes) {
+    deviceObject := GetDevice(device)
+
+    if memory != VK_NULL_HANDLE {
+        memoryObject := GetDeviceMemory(memory)
+        assert(memoryObject.device == device)
+    }
+
+    committedMemoryInBytes := ?
+    pCommittedMemoryInBytes[0] = committedMemoryInBytes
+
+    return ?
+}
+
+cmd VkResult vkGetBufferMemoryRequirements(
+        VkDevice                                    device,
+        VkBuffer                                    buffer,
+        VkMemoryRequirements*                       pMemoryRequirements) {
+    deviceObject := GetDevice(device)
+    bufferObject := GetBuffer(buffer)
+    assert(bufferObject.device == device)
+
+    return ?
+}
+
+cmd VkResult vkBindBufferMemory(
+        VkDevice                                    device,
+        VkBuffer                                    buffer,
+        VkDeviceMemory                              mem,
+        platform.VkDeviceSize                       memOffset) {
+    deviceObject := GetDevice(device)
+    bufferObject := GetBuffer(buffer)
+    assert(bufferObject.device == device)
+
+    // Unbind buffer from previous memory object, if not VK_NULL_HANDLE.
+    if bufferObject.mem != VK_NULL_HANDLE {
+        memObject := GetDeviceMemory(bufferObject.mem)
+        memObject.boundObjects[as!u64(buffer)] = null
+    }
+
+    // Bind buffer to given memory object, if not VK_NULL_HANDLE.
+    if mem != VK_NULL_HANDLE {
+        memObject := GetDeviceMemory(mem)
+        assert(memObject.device == device)
+        memObject.boundObjects[as!u64(buffer)] = memOffset
+    }
+    bufferObject.mem = mem
+    bufferObject.memOffset = memOffset
+
+    return ?
+}
+
+cmd VkResult vkGetImageMemoryRequirements(
+        VkDevice                                    device,
+        VkImage                                     image,
+        VkMemoryRequirements*                       pMemoryRequirements) {
+    deviceObject := GetDevice(device)
+    imageObject := GetImage(image)
+    assert(imageObject.device == device)
+
+    return ?
+}
+
+cmd VkResult vkBindImageMemory(
+        VkDevice                                    device,
+        VkImage                                     image,
+        VkDeviceMemory                              mem,
+        platform.VkDeviceSize                       memOffset) {
+    deviceObject := GetDevice(device)
+    imageObject := GetImage(image)
+    assert(imageObject.device == device)
+
+    // Unbind image from previous memory object, if not VK_NULL_HANDLE.
+    if imageObject.mem != VK_NULL_HANDLE {
+        memObject := GetDeviceMemory(imageObject.mem)
+        memObject.boundObjects[as!u64(image)] = null
+    }
+
+    // Bind image to given memory object, if not VK_NULL_HANDLE.
+    if mem != VK_NULL_HANDLE {
+        memObject := GetDeviceMemory(mem)
+        assert(memObject.device == device)
+        memObject.boundObjects[as!u64(image)] = memOffset
+    }
+    imageObject.mem = mem
+    imageObject.memOffset = memOffset
+
+    return ?
+}
+
+cmd VkResult vkGetImageSparseMemoryRequirements(
+        VkDevice                                    device,
+        VkImage                                     image,
+        u32*                                        pNumRequirements,
+        VkSparseImageMemoryRequirements*            pSparseMemoryRequirements) {
+    deviceObject := GetDevice(device)
+    imageObject := GetImage(image)
+    assert(imageObject.device == device)
+
+    return ?
+}
+
+cmd VkResult vkGetPhysicalDeviceSparseImageFormatProperties(
+        VkPhysicalDevice                            physicalDevice,
+        VkFormat                                    format,
+        VkImageType                                 type,
+        u32                                         samples,
+        VkImageUsageFlags                           usage,
+        VkImageTiling                               tiling,
+        u32*                                        pNumProperties,
+        VkSparseImageFormatProperties*              pProperties) {
+    physicalDeviceObject := GetPhysicalDevice(physicalDevice)
+
+    return ?
+}
+
+cmd VkResult vkQueueBindSparseBufferMemory(
+        VkQueue                                     queue,
+        VkBuffer                                    buffer,
+        u32                                         numBindings,
+        const VkSparseMemoryBindInfo*               pBindInfo) {
+    queueObject := GetQueue(queue)
+    bufferObject := GetBuffer(buffer)
+    assert(bufferObject.device == queueObject.device)
+
+    return ?
+}
+
+cmd VkResult vkQueueBindSparseImageOpaqueMemory(
+        VkQueue                                     queue,
+        VkImage                                     image,
+        u32                                         numBindings,
+        const VkSparseMemoryBindInfo*               pBindInfo) {
+    queueObject := GetQueue(queue)
+    imageObject := GetImage(image)
+    assert(imageObject.device == queueObject.device)
+
+    return ?
+}
+
+
+cmd VkResult vkQueueBindSparseImageMemory(
+        VkQueue                                     queue,
+        VkImage                                     image,
+        u32                                         numBindings,
+        const VkSparseImageMemoryBindInfo*          pBindInfo) {
+    queueObject := GetQueue(queue)
+    imageObject := GetImage(image)
+
+    return ?
+}
+
+
+// Fence functions
+
+@threadSafety("system")
+cmd VkResult vkCreateFence(
+        VkDevice                                    device,
+        const VkFenceCreateInfo*                    pCreateInfo,
+        VkFence*                                    pFence) {
+    assert(pCreateInfo.sType == VK_STRUCTURE_TYPE_FENCE_CREATE_INFO)
+    deviceObject := GetDevice(device)
+
+    fence := ?
+    pFence[0] = fence
+    State.Fences[fence] = new!FenceObject(
+        device: device, signaled: (pCreateInfo.flags == VK_FENCE_CREATE_SIGNALED_BIT))
+
+    return ?
+}
+
+@threadSafety("system")
+cmd VkResult vkDestroyFence(
+        VkDevice                                    device,
+        VkFence                                     fence) {
+    deviceObject := GetDevice(device)
+    fenceObject := GetFence(fence)
+    assert(fenceObject.device == device)
+
+    State.Fences[fence] = null
+
+    return ?
+}
+
+@threadSafety("system")
+cmd VkResult vkResetFences(
+        VkDevice                                    device,
+        u32                                         fenceCount,
+        const VkFence*                              pFences) {
+    deviceObject := GetDevice(device)
+
+    fences := pFences[0:fenceCount]
+    for i in (0 .. fenceCount) {
+        fence := fences[i]
+        fenceObject := GetFence(fence)
+        assert(fenceObject.device == device)
+        fenceObject.signaled = false
+    }
+
+    return ?
+}
+
+@threadSafety("system")
+cmd VkResult vkGetFenceStatus(
+        VkDevice                                    device,
+        VkFence                                     fence) {
+    deviceObject := GetDevice(device)
+    fenceObject := GetFence(fence)
+    assert(fenceObject.device == device)
+
+    return ?
+}
+
+@threadSafety("system")
+cmd VkResult vkWaitForFences(
+        VkDevice                                    device,
+        u32                                         fenceCount,
+        const VkFence*                              pFences,
+        platform.VkBool32                           waitAll,
+        u64                                         timeout) {  /// timeout in nanoseconds
+    deviceObject := GetDevice(device)
+
+    fences := pFences[0:fenceCount]
+    for i in (0 .. fenceCount) {
+        fence := fences[i]
+        fenceObject := GetFence(fence)
+        assert(fenceObject.device == device)
+    }
+
+    return ?
+}
+
+
+// Queue semaphore functions
+
+@threadSafety("system")
+cmd VkResult vkCreateSemaphore(
+        VkDevice                                    device,
+        const VkSemaphoreCreateInfo*                pCreateInfo,
+        VkSemaphore*                                pSemaphore) {
+    assert(pCreateInfo.sType == VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO)
+    deviceObject := GetDevice(device)
+
+    semaphore := ?
+    pSemaphore[0] = semaphore
+    State.Semaphores[semaphore] = new!SemaphoreObject(device: device)
+
+    return ?
+}
+
+@threadSafety("system")
+cmd VkResult vkDestroySemaphore(
+        VkDevice                                    device,
+        VkSemaphore                                 semaphore) {
+    deviceObject := GetDevice(device)
+    semaphoreObject := GetSemaphore(semaphore)
+    assert(semaphoreObject.device == device)
+
+    State.Semaphores[semaphore] = null
+
+    return ?
+}
+
+@threadSafety("app")
+cmd VkResult vkQueueSignalSemaphore(
+        VkQueue                                     queue,
+        VkSemaphore                                 semaphore) {
+    queueObject := GetQueue(queue)
+    semaphoreObject := GetSemaphore(semaphore)
+    assert(queueObject.device == semaphoreObject.device)
+
+    return ?
+}
+
+@threadSafety("system")
+cmd VkResult vkQueueWaitSemaphore(
+        VkQueue                                     queue,
+        VkSemaphore                                 semaphore) {
+    queueObject := GetQueue(queue)
+    semaphoreObject := GetSemaphore(semaphore)
+    assert(queueObject.device == semaphoreObject.device)
+
+    return ?
+}
+
+
+// Event functions
+
+@threadSafety("system")
+cmd VkResult vkCreateEvent(
+        VkDevice                                    device,
+        const VkEventCreateInfo*                    pCreateInfo,
+        VkEvent*                                    pEvent) {
+    assert(pCreateInfo.sType == VK_STRUCTURE_TYPE_EVENT_CREATE_INFO)
+    deviceObject := GetDevice(device)
+
+    event := ?
+    pEvent[0] = event
+    State.Events[event] = new!EventObject(device: device)
+
+    return ?
+}
+
+@threadSafety("system")
+cmd VkResult vkDestroyEvent(
+        VkDevice                                    device,
+        VkEvent                                     event) {
+    deviceObject := GetDevice(device)
+    eventObject := GetEvent(event)
+    assert(eventObject.device == device)
+
+    State.Events[event] = null
+
+    return ?
+}
+
+@threadSafety("system")
+cmd VkResult vkGetEventStatus(
+        VkDevice                                    device,
+        VkEvent                                     event) {
+    deviceObject := GetDevice(device)
+    eventObject := GetEvent(event)
+    assert(eventObject.device == device)
+
+    return ?
+}
+
+@threadSafety("system")
+cmd VkResult vkSetEvent(
+        VkDevice                                    device,
+        VkEvent                                     event) {
+    deviceObject := GetDevice(device)
+    eventObject := GetEvent(event)
+    assert(eventObject.device == device)
+
+    return ?
+}
+
+@threadSafety("system")
+cmd VkResult vkResetEvent(
+        VkDevice                                    device,
+        VkEvent                                     event) {
+    deviceObject := GetDevice(device)
+    eventObject := GetEvent(event)
+    assert(eventObject.device == device)
+
+    return ?
+}
+
+
+// Query functions
+
+@threadSafety("system")
+cmd VkResult vkCreateQueryPool(
+        VkDevice                                    device,
+        const VkQueryPoolCreateInfo*                pCreateInfo,
+        VkQueryPool*                                pQueryPool) {
+    assert(pCreateInfo.sType == VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO)
+    deviceObject := GetDevice(device)
+
+    queryPool := ?
+    pQueryPool[0] = queryPool
+    State.QueryPools[queryPool] = new!QueryPoolObject(device: device)
+
+    return ?
+}
+
+@threadSafety("system")
+cmd VkResult vkDestroyQueryPool(
+        VkDevice                                    device,
+        VkQueryPool                                 queryPool) {
+    deviceObject := GetDevice(device)
+    queryPoolObject := GetQueryPool(queryPool)
+    assert(queryPoolObject.device == device)
+
+    State.QueryPools[queryPool] = null
+
+    return ?
+}
+
+@threadSafety("system")
+cmd VkResult vkGetQueryPoolResults(
+        VkDevice                                    device,
+        VkQueryPool                                 queryPool,
+        u32                                         startQuery,
+        u32                                         queryCount,
+        platform.size_t*                            pDataSize,
+        void*                                       pData,
+        VkQueryResultFlags                          flags) {
+    deviceObject := GetDevice(device)
+    queryPoolObject := GetQueryPool(queryPool)
+    assert(queryPoolObject.device == device)
+
+    dataSize := ?
+    pDataSize[0] = dataSize
+    data := pData[0:dataSize]
+
+    return ?
+}
+
+// Buffer functions
+
+@threadSafety("system")
+cmd VkResult vkCreateBuffer(
+        VkDevice                                    device,
+        const VkBufferCreateInfo*                   pCreateInfo,
+        VkBuffer*                                   pBuffer) {
+    assert(pCreateInfo.sType == VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO)
+    deviceObject := GetDevice(device)
+
+    buffer := ?
+    pBuffer[0] = buffer
+    State.Buffers[buffer] = new!BufferObject(device: device)
+
+    return ?
+}
+
+@threadSafety("system")
+cmd VkResult vkDestroyBuffer(
+        VkDevice                                    device,
+        VkBuffer                                    buffer) {
+    deviceObject := GetDevice(device)
+    bufferObject := GetBuffer(buffer)
+    assert(bufferObject.device == device)
+
+    assert(bufferObject.mem == 0)
+    State.Buffers[buffer] = null
+
+    return ?
+}
+
+
+// Buffer view functions
+
+@threadSafety("system")
+cmd VkResult vkCreateBufferView(
+        VkDevice                                    device,
+        const VkBufferViewCreateInfo*               pCreateInfo,
+        VkBufferView*                               pView) {
+    assert(pCreateInfo.sType == VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO)
+    deviceObject := GetDevice(device)
+
+    bufferObject := GetBuffer(pCreateInfo.buffer)
+    assert(bufferObject.device == device)
+
+    view := ?
+    pView[0] = view
+    State.BufferViews[view] = new!BufferViewObject(device: device, buffer: pCreateInfo.buffer)
+
+    return ?
+}
+
+@threadSafety("system")
+cmd VkResult vkDestroyBufferView(
+        VkDevice                                    device,
+        VkBufferView                                bufferView) {
+    deviceObject := GetDevice(device)
+    bufferViewObject := GetBufferView(bufferView)
+    assert(bufferViewObject.device == device)
+
+    State.BufferViews[bufferView] = null
+
+    return ?
+}
+
+
+// Image functions
+
+@threadSafety("system")
+cmd VkResult vkCreateImage(
+        VkDevice                                    device,
+        const VkImageCreateInfo*                    pCreateInfo,
+        VkImage*                                    pImage) {
+    assert(pCreateInfo.sType == VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO)
+    deviceObject := GetDevice(device)
+
+    image := ?
+    pImage[0] = image
+    State.Images[image] = new!ImageObject(device: device)
+
+    return ?
+}
+
+@threadSafety("system")
+cmd VkResult vkDestroyImage(
+        VkDevice                                    device,
+        VkImage                                     image) {
+    deviceObject := GetDevice(device)
+    imageObject := GetImage(image)
+    assert(imageObject.device == device)
+
+    assert(imageObject.mem == 0)
+    State.Images[image] = null
+
+    return ?
+}
+
+cmd VkResult vkGetImageSubresourceLayout(
+        VkDevice                                    device,
+        VkImage                                     image,
+        const VkImageSubresource*                   pSubresource,
+        VkSubresourceLayout*                        pLayout) {
+    deviceObject := GetDevice(device)
+    imageObject := GetImage(image)
+    assert(imageObject.device == device)
+
+    return ?
+}
+
+
+// Image view functions
+
+@threadSafety("system")
+cmd VkResult vkCreateImageView(
+        VkDevice                                    device,
+        const VkImageViewCreateInfo*                pCreateInfo,
+        VkImageView*                                pView) {
+    assert(pCreateInfo.sType == VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO)
+    deviceObject := GetDevice(device)
+
+    imageObject := GetImage(pCreateInfo.image)
+    assert(imageObject.device == device)
+
+    view := ?
+    pView[0] = view
+    State.ImageViews[view] = new!ImageViewObject(device: device, image: pCreateInfo.image)
+
+    return ?
+}
+
+@threadSafety("system")
+cmd VkResult vkDestroyImageView(
+        VkDevice                                    device,
+        VkImageView                                 imageView) {
+    deviceObject := GetDevice(device)
+    imageViewObject := GetImageView(imageView)
+    assert(imageViewObject.device == device)
+
+    State.ImageViews[imageView] = null
+
+    return ?
+}
+
+@threadSafety("system")
+cmd VkResult vkCreateAttachmentView(
+        VkDevice                                    device,
+        const VkAttachmentViewCreateInfo*           pCreateInfo,
+        VkAttachmentView*                           pView) {
+    assert(pCreateInfo.sType == VK_STRUCTURE_TYPE_ATTACHMENT_VIEW_CREATE_INFO)
+    deviceObject := GetDevice(device)
+
+    imageObject := GetImage(pCreateInfo.image)
+    assert(imageObject.device == device)
+
+    view := ?
+    pView[0] = view
+    State.AttachmentViews[view] = new!AttachmentViewObject(device: device, image: pCreateInfo.image)
+
+    return ?
+}
+
+@threadSafety("system")
+cmd VkResult vkDestroyAttachmentView(
+        VkDevice                                    device,
+        VkAttachmentView                            attachmentView) {
+    deviceObject := GetDevice(device)
+    attachmentViewObject := GetAttachmentView(attachmentView)
+    assert(attachmentViewObject.device == device)
+
+    State.AttachmentViews[attachmentView] = null
+
+    return ?
+}
+
+
+// Shader functions
+
+cmd VkResult vkCreateShaderModule(
+        VkDevice                                    device,
+        const VkShaderModuleCreateInfo*             pCreateInfo,
+        VkShaderModule*                             pShaderModule) {
+    assert(pCreateInfo.sType == VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO)
+    deviceObject := GetDevice(device)
+
+    shaderModule := ?
+    pShaderModule[0] = shaderModule
+    State.ShaderModules[shaderModule] = new!ShaderModuleObject(device: device)
+
+    return ?
+}
+
+cmd VkResult vkDestroyShaderModule(
+        VkDevice                                    device,
+        VkShaderModule                              shaderModule) {
+    deviceObject := GetDevice(device)
+    shaderModuleObject := GetShaderModule(shaderModule)
+    assert(shaderModuleObject.device == device)
+
+    State.ShaderModules[shaderModule] = null
+
+    return ?
+}
+
+@threadSafety("system")
+cmd VkResult vkCreateShader(
+        VkDevice                                    device,
+        const VkShaderCreateInfo*                   pCreateInfo,
+        VkShader*                                   pShader) {
+    assert(pCreateInfo.sType == VK_STRUCTURE_TYPE_SHADER_CREATE_INFO)
+    deviceObject := GetDevice(device)
+
+    shader := ?
+    pShader[0] = shader
+    State.Shaders[shader] = new!ShaderObject(device: device)
+
+    return ?
+}
+
+@threadSafety("system")
+cmd VkResult vkDestroyShader(
+        VkDevice                                    device,
+        VkShader                                    shader) {
+    deviceObject := GetDevice(device)
+    shaderObject := GetShader(shader)
+    assert(shaderObject.device == device)
+
+    State.Shaders[shader] = null
+
+    return ?
+}
+
+
+// Pipeline functions
+
+cmd VkResult vkCreatePipelineCache(
+        VkDevice                                    device,
+        const VkPipelineCacheCreateInfo*            pCreateInfo,
+        VkPipelineCache*                            pPipelineCache) {
+    assert(pCreateInfo.sType == VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO)
+    deviceObject := GetDevice(device)
+
+    pipelineCache := ?
+    pPipelineCache[0] = pipelineCache
+    State.PipelineCaches[pipelineCache] = new!PipelineCacheObject(device: device)
+
+    return ?
+}
+
+cmd VkResult vkDestroyPipelineCache(
+        VkDevice                                    device,
+        VkPipelineCache                             pipelineCache) {
+    deviceObject := GetDevice(device)
+    pipelineCacheObject := GetPipelineCache(pipelineCache)
+    assert(pipelineCacheObject.device == device)
+
+    State.PipelineCaches[pipelineCache] = null
+
+    return ?
+}
+
+cmd platform.size_t vkGetPipelineCacheSize(
+        VkDevice                                    device,
+        VkPipelineCache                             pipelineCache) {
+    deviceObject := GetDevice(device)
+    pipelineCacheObject := GetPipelineCache(pipelineCache)
+    assert(pipelineCacheObject.device == device)
+
+    return ?
+}
+
+cmd VkResult vkGetPipelineCacheData(
+        VkDevice                                    device,
+        VkPipelineCache                             pipelineCache,
+        void*                                       pData) {
+    deviceObject := GetDevice(device)
+    pipelineCacheObject := GetPipelineCache(pipelineCache)
+    assert(pipelineCacheObject.device == device)
+
+    return ?
+}
+
+cmd VkResult vkMergePipelineCaches(
+        VkDevice                                    device,
+        VkPipelineCache                             destCache,
+        u32                                         srcCacheCount,
+        const VkPipelineCache*                      pSrcCaches) {
+    deviceObject := GetDevice(device)
+    destCacheObject := GetPipelineCache(destCache)
+    assert(destCacheObject.device == device)
+
+    srcCaches := pSrcCaches[0:srcCacheCount]
+    for i in (0 .. srcCacheCount) {
+        srcCache := srcCaches[i]
+        srcCacheObject := GetPipelineCache(srcCache)
+        assert(srcCacheObject.device == device)
+    }
+
+    return ?
+}
+
+cmd VkResult vkCreateGraphicsPipelines(
+        VkDevice                                    device,
+        VkPipelineCache                             pipelineCache,
+        u32                                         count,
+        const VkGraphicsPipelineCreateInfo*         pCreateInfos,
+        VkPipeline*                                 pPipelines) {
+    deviceObject := GetDevice(device)
+    if pipelineCache != VK_NULL_HANDLE {
+        pipelineCacheObject := GetPipelineCache(pipelineCache)
+        assert(pipelineCacheObject.device == device)
+    }
+
+    createInfos := pCreateInfos[0:count]
+    pipelines := pPipelines[0:count]
+    for i in (0 .. count) {
+        pipeline := ?
+        pipelines[i] = pipeline
+        State.Pipelines[pipeline] = new!PipelineObject(device: device)
+    }
+
+    return ?
+}
+
+cmd VkResult vkCreateComputePipelines(
+        VkDevice                                    device,
+        VkPipelineCache                             pipelineCache,
+        u32                                         count,
+        const VkComputePipelineCreateInfo*          pCreateInfos,
+        VkPipeline*                                 pPipelines) {
+    deviceObject := GetDevice(device)
+    if pipelineCache != VK_NULL_HANDLE {
+        pipelineCacheObject := GetPipelineCache(pipelineCache)
+        assert(pipelineCacheObject.device == device)
+    }
+
+    createInfos := pCreateInfos[0:count]
+    pipelines := pPipelines[0:count]
+    for i in (0 .. count) {
+        pipeline := ?
+        pipelines[i] = pipeline
+        State.Pipelines[pipeline] = new!PipelineObject(device: device)
+    }
+
+    return ?
+}
+
+@threadSafety("system")
+cmd VkResult vkDestroyPipeline(
+        VkDevice                                    device,
+        VkPipeline                                  pipeline) {
+    deviceObject := GetDevice(device)
+    pipelineObjects := GetPipeline(pipeline)
+    assert(pipelineObjects.device == device)
+
+    State.Pipelines[pipeline] = null
+
+    return ?
+}
+
+
+// Pipeline layout functions
+
+@threadSafety("system")
+cmd VkResult vkCreatePipelineLayout(
+        VkDevice                                    device,
+        const VkPipelineLayoutCreateInfo*           pCreateInfo,
+        VkPipelineLayout*                           pPipelineLayout) {
+    assert(pCreateInfo.sType == VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO)
+    deviceObject := GetDevice(device)
+
+    pipelineLayout := ?
+    pPipelineLayout[0] = pipelineLayout
+    State.PipelineLayouts[pipelineLayout] = new!PipelineLayoutObject(device: device)
+
+    return ?
+}
+
+@threadSafety("system")
+cmd VkResult vkDestroyPipelineLayout(
+        VkDevice                                    device,
+        VkPipelineLayout                            pipelineLayout) {
+    deviceObject := GetDevice(device)
+    pipelineLayoutObjects := GetPipelineLayout(pipelineLayout)
+    assert(pipelineLayoutObjects.device == device)
+
+    State.PipelineLayouts[pipelineLayout] = null
+
+    return ?
+}
+
+
+// Sampler functions
+
+@threadSafety("system")
+cmd VkResult vkCreateSampler(
+        VkDevice                                    device,
+        const VkSamplerCreateInfo*                  pCreateInfo,
+        VkSampler*                                  pSampler) {
+    assert(pCreateInfo.sType == VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO)
+    deviceObject := GetDevice(device)
+
+    sampler := ?
+    pSampler[0] = sampler
+    State.Samplers[sampler] = new!SamplerObject(device: device)
+
+    return ?
+}
+
+@threadSafety("system")
+cmd VkResult vkDestroySampler(
+        VkDevice                                    device,
+        VkSampler                                   sampler) {
+    deviceObject := GetDevice(device)
+    samplerObject := GetSampler(sampler)
+    assert(samplerObject.device == device)
+
+    State.Samplers[sampler] = null
+
+    return ?
+}
+
+
+// Descriptor set functions
+
+@threadSafety("system")
+cmd VkResult vkCreateDescriptorSetLayout(
+        VkDevice                                    device,
+        const VkDescriptorSetLayoutCreateInfo*      pCreateInfo,
+        VkDescriptorSetLayout*                      pSetLayout) {
+    assert(pCreateInfo.sType == VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO)
+    deviceObject := GetDevice(device)
+
+    setLayout := ?
+    pSetLayout[0] = setLayout
+    State.DescriptorSetLayouts[setLayout] = new!DescriptorSetLayoutObject(device: device)
+
+    return ?
+}
+
+@threadSafety("system")
+cmd VkResult vkDestroyDescriptorSetLayout(
+        VkDevice                                    device,
+        VkDescriptorSetLayout                       descriptorSetLayout) {
+    deviceObject := GetDevice(device)
+    descriptorSetLayoutObject := GetDescriptorSetLayout(descriptorSetLayout)
+    assert(descriptorSetLayoutObject.device == device)
+
+    State.DescriptorSetLayouts[descriptorSetLayout] = null
+
+    return ?
+}
+
+@threadSafety("system")
+cmd VkResult vkCreateDescriptorPool(
+        VkDevice                                    device,
+        VkDescriptorPoolUsage                       poolUsage,
+        u32                                         maxSets,
+        const VkDescriptorPoolCreateInfo*           pCreateInfo,
+        VkDescriptorPool*                           pDescriptorPool) {
+    assert(pCreateInfo.sType == VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO)
+    deviceObject := GetDevice(device)
+
+    descriptorPool := ?
+    pDescriptorPool[0] = descriptorPool
+    State.DescriptorPools[descriptorPool] = new!DescriptorPoolObject(device: device)
+
+    return ?
+}
+
+@threadSafety("system")
+cmd VkResult vkDestroyDescriptorPool(
+        VkDevice                                    device,
+        VkDescriptorPool                            descriptorPool) {
+    deviceObject := GetDevice(device)
+    descriptorPoolObject := GetDescriptorPool(descriptorPool)
+    assert(descriptorPoolObject.device == device)
+
+    State.DescriptorPools[descriptorPool] = null
+
+    return ?
+}
+
+@threadSafety("app")
+cmd VkResult vkResetDescriptorPool(
+        VkDevice                                    device,
+        VkDescriptorPool                            descriptorPool) {
+    deviceObject := GetDevice(device)
+    descriptorPoolObject := GetDescriptorPool(descriptorPool)
+    assert(descriptorPoolObject.device == device)
+
+    return ?
+}
+
+@threadSafety("app")
+cmd VkResult vkAllocDescriptorSets(
+        VkDevice                                    device,
+        VkDescriptorPool                            descriptorPool,
+        VkDescriptorSetUsage                        setUsage,
+        u32                                         count,
+        const VkDescriptorSetLayout*                pSetLayouts,
+        VkDescriptorSet*                            pDescriptorSets,
+        u32*                                        pCount) {
+    deviceObject := GetDevice(device)
+    descriptorPoolObject := GetDescriptorPool(descriptorPool)
+
+    setLayouts := pSetLayouts[0:count]
+    for i in (0 .. count) {
+        setLayout := setLayouts[i]
+        setLayoutObject := GetDescriptorSetLayout(setLayout)
+        assert(setLayoutObject.device == device)
+    }
+
+    setsCount := as!u32(?)
+    pCount[0] = setsCount
+    descriptorSets := pDescriptorSets[0:setsCount]
+    for i in (0 .. setsCount) {
+        descriptorSet := ?
+        descriptorSets[i] = descriptorSet
+        State.DescriptorSets[descriptorSet] = new!DescriptorSetObject(device: device)
+    }
+
+    return ?
+}
+
+cmd VkResult vkUpdateDescriptorSets(
+        VkDevice                                    device,
+        u32                                         writeCount,
+        const VkWriteDescriptorSet*                 pDescriptorWrites,
+        u32                                         copyCount,
+        const VkCopyDescriptorSet*                  pDescriptorCopies) {
+    deviceObject := GetDevice(device)
+
+    descriptorWrites := pDescriptorWrites[0:writeCount]
+    for i in (0 .. writeCount) {
+        descriptorWrite := descriptorWrites[i]
+        descriptorWriteObject := GetDescriptorSet(descriptorWrite.destSet)
+        assert(descriptorWriteObject.device == device)
+    }
+
+    descriptorCopies := pDescriptorCopies[0:copyCount]
+    for i in (0 .. copyCount) {
+        descriptorCopy := descriptorCopies[i]
+        descriptorCopyObject := GetDescriptorSet(descriptorCopy.destSet)
+        assert(descriptorCopyObject.device == device)
+    }
+
+    return ?
+}
+
+
+// State object functions
+
+@threadSafety("system")
+cmd VkResult vkCreateDynamicViewportState(
+        VkDevice                                    device,
+        const VkDynamicViewportStateCreateInfo*     pCreateInfo,
+        VkDynamicViewportState*                     pState) {
+    assert(pCreateInfo.sType == VK_STRUCTURE_TYPE_DYNAMIC_VIEWPORT_STATE_CREATE_INFO)
+    deviceObject := GetDevice(device)
+
+    state := ?
+    pState[0] = state
+    State.DynamicViewportStates[state] = new!DynamicViewportStateObject(device: device)
+
+    return ?
+}
+
+@threadSafety("system")
+cmd VkResult vkDestroyDynamicViewportState(
+        VkDevice                                    device,
+        VkDynamicViewportState                      dynamicViewportState) {
+    deviceObject := GetDevice(device)
+    dynamicViewportStateObject := GetDynamicViewportState(dynamicViewportState)
+    assert(dynamicViewportStateObject.device == device)
+
+    State.DynamicViewportStates[dynamicViewportState] = null
+
+    return ?
+}
+
+@threadSafety("system")
+cmd VkResult vkCreateDynamicRasterState(
+        VkDevice                                    device,
+        const VkDynamicRasterStateCreateInfo*       pCreateInfo,
+        VkDynamicRasterState*                       pState) {
+    assert(pCreateInfo.sType == VK_STRUCTURE_TYPE_DYNAMIC_RASTER_STATE_CREATE_INFO)
+    deviceObject := GetDevice(device)
+
+    state := ?
+    pState[0] = state
+    State.DynamicRasterStates[state] = new!DynamicRasterStateObject(device: device)
+
+    return ?
+}
+
+@threadSafety("system")
+cmd VkResult vkDestroyDynamicRasterState(
+        VkDevice                                    device,
+        VkDynamicRasterState                        dynamicRasterState) {
+    deviceObject := GetDevice(device)
+    dynamicRasterStateObject := GetDynamicRasterState(dynamicRasterState)
+    assert(dynamicRasterStateObject.device == device)
+
+    State.DynamicRasterStates[dynamicRasterState] = null
+
+    return ?
+}
+
+@threadSafety("system")
+cmd VkResult vkCreateDynamicColorBlendState(
+        VkDevice                                    device,
+        const VkDynamicColorBlendStateCreateInfo*   pCreateInfo,
+        VkDynamicColorBlendState*                   pState) {
+    assert(pCreateInfo.sType == VK_STRUCTURE_TYPE_DYNAMIC_COLOR_BLEND_STATE_CREATE_INFO)
+    deviceObject := GetDevice(device)
+
+    state := ?
+    pState[0] = state
+    State.DynamicColorBlendStates[state] = new!DynamicColorBlendStateObject(device: device)
+
+    return ?
+}
+
+@threadSafety("system")
+cmd VkResult vkDestroyDynamicColorBlendState(
+        VkDevice                                    device,
+        VkDynamicColorBlendState                    dynamicColorBlendState) {
+    deviceObject := GetDevice(device)
+    dynamicColorBlendStateObject := GetDynamicColorBlendState(dynamicColorBlendState)
+    assert(dynamicColorBlendStateObject.device == device)
+
+    State.DynamicColorBlendStates[dynamicColorBlendState] = null
+
+    return ?
+}
+
+@threadSafety("system")
+cmd VkResult vkCreateDynamicDepthStencilState(
+        VkDevice                                    device,
+        const VkDynamicDepthStencilStateCreateInfo* pCreateInfo,
+        VkDynamicDepthStencilState*                 pState) {
+    assert(pCreateInfo.sType == VK_STRUCTURE_TYPE_DYNAMIC_DEPTH_STENCIL_STATE_CREATE_INFO)
+    deviceObject := GetDevice(device)
+
+    state := ?
+    pState[0] = state
+    State.DynamicDepthStencilStates[state] = new!DynamicDepthStencilStateObject(device: device)
+
+    return ?
+}
+
+@threadSafety("system")
+cmd VkResult vkDestroyDynamicDepthStencilState(
+        VkDevice                                    device,
+        VkDynamicDepthStencilState                  dynamicDepthStencilState) {
+    deviceObject := GetDevice(device)
+    dynamicDepthStencilStateObject := GetDynamicDepthStencilState(dynamicDepthStencilState)
+    assert(dynamicDepthStencilStateObject.device == device)
+
+    State.DynamicDepthStencilStates[dynamicDepthStencilState] = null
+
+    return ?
+}
+
+
+// Framebuffer functions
+
+@threadSafety("system")
+cmd VkResult vkCreateFramebuffer(
+        VkDevice                                    device,
+        const VkFramebufferCreateInfo*              pCreateInfo,
+        VkFramebuffer*                              pFramebuffer) {
+    assert(pCreateInfo.sType == VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO)
+    deviceObject := GetDevice(device)
+
+    framebuffer := ?
+    pFramebuffer[0] = framebuffer
+    State.Framebuffers[framebuffer] = new!FramebufferObject(device: device)
+
+    return ?
+}
+
+@threadSafety("system")
+cmd VkResult vkDestroyFramebuffer(
+        VkDevice                                    device,
+        VkFramebuffer                               framebuffer) {
+    deviceObject := GetDevice(device)
+    framebufferObject := GetFramebuffer(framebuffer)
+    assert(framebufferObject.device == device)
+
+    State.Framebuffers[framebuffer] = null
+
+    return ?
+}
+
+
+// Renderpass functions
+
+@threadSafety("system")
+cmd VkResult vkCreateRenderPass(
+        VkDevice                                    device,
+        const VkRenderPassCreateInfo*               pCreateInfo,
+        VkRenderPass*                               pRenderPass) {
+    assert(pCreateInfo.sType == VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO)
+    deviceObject := GetDevice(device)
+
+    renderpass := ?
+    pRenderPass[0] = renderpass
+    State.RenderPasses[renderpass] = new!RenderPassObject(device: device)
+
+    return ?
+}
+
+@threadSafety("system")
+cmd VkResult vkDestroyRenderPass(
+        VkDevice                                    device,
+        VkRenderPass                                renderPass) {
+    deviceObject := GetDevice(device)
+    renderPassObject := GetRenderPass(renderPass)
+    assert(renderPassObject.device == device)
+
+    State.RenderPasses[renderPass] = null
+
+    return ?
+}
+
+cmd VkResult vkGetRenderAreaGranularity(
+        VkDevice                                    device,
+        VkRenderPass                                renderPass,
+        VkExtent2D*                                 pGranularity) {
+    deviceObject := GetDevice(device)
+    renderPassObject := GetRenderPass(renderPass)
+
+    granularity := ?
+    pGranularity[0] = granularity
+
+    return ?
+}
+
+// Command pool functions
+
+cmd VkResult vkCreateCommandPool(
+        VkDevice                                    device,
+        const VkCmdPoolCreateInfo*                  pCreateInfo,
+        VkCmdPool*                                  pCmdPool) {
+    assert(pCreateInfo.sType == VK_STRUCTURE_TYPE_CMD_POOL_CREATE_INFO)
+    deviceObject := GetDevice(device)
+
+    cmdPool := ?
+    pCmdPool[0] = cmdPool
+    State.CmdPools[cmdPool] = new!CmdPoolObject(device: device)
+
+    return ?
+}
+
+cmd VkResult vkDestroyCommandPool(
+        VkDevice                                    device,
+        VkCmdPool                                   cmdPool) {
+    deviceObject := GetDevice(device)
+    cmdPoolObject := GetCmdPool(cmdPool)
+    assert(cmdPoolObject.device == device)
+
+    State.CmdPools[cmdPool] = null
+
+    return ?
+}
+
+cmd VkResult vkResetCommandPool(
+        VkDevice                                    device,
+        VkCmdPool                                   cmdPool,
+        VkCmdPoolResetFlags                         flags) {
+    deviceObject := GetDevice(device)
+    cmdPoolObject := GetCmdPool(cmdPool)
+    assert(cmdPoolObject.device == device)
+
+    return ?
+}
+
+// Command buffer functions
+
+macro void bindCmdBuffer(VkCmdBuffer cmdBuffer, any obj, VkDeviceMemory mem) {
+    memoryObject := GetDeviceMemory(mem)
+    memoryObject.boundCommandBuffers[cmdBuffer] = cmdBuffer
+
+    cmdBufferObject := GetCmdBuffer(cmdBuffer)
+    cmdBufferObject.boundObjects[as!u64(obj)] = mem
+}
+
+macro void unbindCmdBuffer(VkCmdBuffer cmdBuffer, any obj, VkDeviceMemory mem) {
+    memoryObject := GetDeviceMemory(mem)
+    memoryObject.boundCommandBuffers[cmdBuffer] = null
+
+    cmdBufferObject := GetCmdBuffer(cmdBuffer)
+    cmdBufferObject.boundObjects[as!u64(obj)] = null
+}
+
+@threadSafety("system")
+cmd VkResult vkCreateCommandBuffer(
+        VkDevice                                    device,
+        const VkCmdBufferCreateInfo*                pCreateInfo,
+        VkCmdBuffer*                                pCmdBuffer) {
+    assert(pCreateInfo.sType == VK_STRUCTURE_TYPE_CMD_BUFFER_CREATE_INFO)
+
+    cmdBuffer := ?
+    pCmdBuffer[0] = cmdBuffer
+    State.CmdBuffers[cmdBuffer] = new!CmdBufferObject(device: device)
+
+    return ?
+}
+
+@threadSafety("system")
+cmd VkResult vkDestroyCommandBuffer(
+        VkDevice                                    device,
+        VkCmdBuffer                                 commandBuffer) {
+    deviceObject := GetDevice(device)
+    cmdBufferObject := GetCmdBuffer(commandBuffer)
+    assert(cmdBufferObject.device == device)
+
+    // TODO: iterate over boundObjects and clear memory bindings
+    State.CmdBuffers[commandBuffer] = null
+
+    return ?
+}
+
+@threadSafety("app")
+cmd VkResult vkBeginCommandBuffer(
+        VkCmdBuffer                                 cmdBuffer,
+        const VkCmdBufferBeginInfo*                 pBeginInfo) {
+    assert(pBeginInfo.sType == VK_STRUCTURE_TYPE_CMD_BUFFER_BEGIN_INFO)
+    cmdBufferObject := GetCmdBuffer(cmdBuffer)
+
+    // TODO: iterate over boundObjects and clear memory bindings
+
+    return ?
+}
+
+@threadSafety("app")
+cmd VkResult vkEndCommandBuffer(
+        VkCmdBuffer                                 cmdBuffer) {
+    cmdBufferObject := GetCmdBuffer(cmdBuffer)
+
+    return ?
+}
+
+@threadSafety("app")
+cmd VkResult vkResetCommandBuffer(
+        VkCmdBuffer                                 cmdBuffer,
+        VkCmdBufferResetFlags                       flags) {
+    cmdBufferObject := GetCmdBuffer(cmdBuffer)
+
+    // TODO: iterate over boundObjects and clear memory bindings
+
+    return ?
+}
+
+
+// Command buffer building functions
+
+@threadSafety("app")
+cmd void vkCmdBindPipeline(
+        VkCmdBuffer                                 cmdBuffer,
+        VkPipelineBindPoint                         pipelineBindPoint,
+        VkPipeline                                  pipeline) {
+    cmdBufferObject := GetCmdBuffer(cmdBuffer)
+    pipelineObject := GetPipeline(pipeline)
+    assert(cmdBufferObject.device == pipelineObject.device)
+
+    queueFlags := cmdBufferObject.queueFlags | switch (pipelineBindPoint) {
+        case VK_PIPELINE_BIND_POINT_COMPUTE:  VK_QUEUE_COMPUTE_BIT
+        case VK_PIPELINE_BIND_POINT_GRAPHICS: VK_QUEUE_GRAPHICS_BIT
+    }
+    cmdBufferObject.queueFlags = queueFlags
+}
+
+@threadSafety("app")
+cmd void vkCmdBindDynamicViewportState(
+        VkCmdBuffer                                 cmdBuffer,
+        VkDynamicViewportState                      dynamicViewportState) {
+    cmdBufferObject := GetCmdBuffer(cmdBuffer)
+    dynamicViewportStateObject := GetDynamicViewportState(dynamicViewportState)
+    assert(cmdBufferObject.device == dynamicViewportStateObject.device)
+
+    queueFlags := cmdBufferObject.queueFlags | VK_QUEUE_GRAPHICS_BIT
+    cmdBufferObject.queueFlags = queueFlags
+}
+
+@threadSafety("app")
+cmd void vkCmdBindDynamicRasterState(
+        VkCmdBuffer                                 cmdBuffer,
+        VkDynamicRasterState                        dynamicRasterState) {
+    cmdBufferObject := GetCmdBuffer(cmdBuffer)
+    dynamicRasterStateObject := GetDynamicRasterState(dynamicRasterState)
+    assert(cmdBufferObject.device == dynamicRasterStateObject.device)
+
+    queueFlags := cmdBufferObject.queueFlags | VK_QUEUE_GRAPHICS_BIT
+    cmdBufferObject.queueFlags = queueFlags
+}
+
+@threadSafety("app")
+cmd void vkCmdBindDynamicColorBlendState(
+        VkCmdBuffer                                 cmdBuffer,
+        VkDynamicColorBlendState                    dynamicColorBlendState) {
+    cmdBufferObject := GetCmdBuffer(cmdBuffer)
+    dynamicColorBlendStateObject := GetDynamicColorBlendState(dynamicColorBlendState)
+    assert(cmdBufferObject.device == dynamicColorBlendStateObject.device)
+
+    queueFlags := cmdBufferObject.queueFlags | VK_QUEUE_GRAPHICS_BIT
+    cmdBufferObject.queueFlags = queueFlags
+}
+
+@threadSafety("app")
+cmd void vkCmdBindDynamicDepthStencilState(
+        VkCmdBuffer                                 cmdBuffer,
+        VkDynamicDepthStencilState                  dynamicDepthStencilState) {
+    cmdBufferObject := GetCmdBuffer(cmdBuffer)
+    dynamicDepthStencilStateObject := GetDynamicDepthStencilState(dynamicDepthStencilState)
+    assert(cmdBufferObject.device == dynamicDepthStencilStateObject.device)
+
+    queueFlags := cmdBufferObject.queueFlags | VK_QUEUE_GRAPHICS_BIT
+    cmdBufferObject.queueFlags = queueFlags
+}
+
+@threadSafety("app")
+cmd void vkCmdBindDescriptorSets(
+        VkCmdBuffer                                 cmdBuffer,
+        VkPipelineBindPoint                         pipelineBindPoint,
+        VkPipelineLayout                            layout,
+        u32                                         firstSet,
+        u32                                         setCount,
+        const VkDescriptorSet*                      pDescriptorSets,
+        u32                                         dynamicOffsetCount,
+        const u32*                                  pDynamicOffsets) {
+    cmdBufferObject := GetCmdBuffer(cmdBuffer)
+
+    descriptorSets := pDescriptorSets[0:setCount]
+    for i in (0 .. setCount) {
+        descriptorSet := descriptorSets[i]
+        descriptorSetObject := GetDescriptorSet(descriptorSet)
+        assert(cmdBufferObject.device == descriptorSetObject.device)
+    }
+
+    dynamicOffsets := pDynamicOffsets[0:dynamicOffsetCount]
+    for i in (0 .. dynamicOffsetCount) {
+        dynamicOffset := dynamicOffsets[i]
+    }
+
+    queueFlags := cmdBufferObject.queueFlags | switch (pipelineBindPoint) {
+        case VK_PIPELINE_BIND_POINT_COMPUTE:  VK_QUEUE_COMPUTE_BIT
+        case VK_PIPELINE_BIND_POINT_GRAPHICS: VK_QUEUE_GRAPHICS_BIT
+    }
+    cmdBufferObject.queueFlags = queueFlags
+}
+
+@threadSafety("app")
+cmd void vkCmdBindIndexBuffer(
+        VkCmdBuffer                                 cmdBuffer,
+        VkBuffer                                    buffer,
+        platform.VkDeviceSize                       offset,
+        VkIndexType                                 indexType) {
+    cmdBufferObject := GetCmdBuffer(cmdBuffer)
+    bufferObject := GetBuffer(buffer)
+    assert(cmdBufferObject.device == bufferObject.device)
+
+    bindCmdBuffer(cmdBuffer, buffer, bufferObject.mem)
+
+    queueFlags := cmdBufferObject.queueFlags | VK_QUEUE_GRAPHICS_BIT
+    cmdBufferObject.queueFlags = queueFlags
+}
+
+@threadSafety("app")
+cmd void vkCmdBindVertexBuffers(
+        VkCmdBuffer                                 cmdBuffer,
+        u32                                         startBinding,
+        u32                                         bindingCount,
+        const VkBuffer*                             pBuffers,
+        const platform.VkDeviceSize*                pOffsets) {
+    cmdBufferObject := GetCmdBuffer(cmdBuffer)
+
+    // TODO: check if not [startBinding:startBinding+bindingCount]
+    buffers := pBuffers[0:bindingCount]
+    offsets := pOffsets[0:bindingCount]
+    for i in (0 .. bindingCount) {
+        buffer := buffers[i]
+        offset := offsets[i]
+        bufferObject := GetBuffer(buffer)
+        assert(cmdBufferObject.device == bufferObject.device)
+
+        bindCmdBuffer(cmdBuffer, buffer, bufferObject.mem)
+    }
+
+    queueFlags := cmdBufferObject.queueFlags | VK_QUEUE_GRAPHICS_BIT
+    cmdBufferObject.queueFlags = queueFlags
+}
+
+@threadSafety("app")
+cmd void vkCmdDraw(
+        VkCmdBuffer                                 cmdBuffer,
+        u32                                         firstVertex,
+        u32                                         vertexCount,
+        u32                                         firstInstance,
+        u32                                         instanceCount) {
+    cmdBufferObject := GetCmdBuffer(cmdBuffer)
+
+    queueFlags := cmdBufferObject.queueFlags | VK_QUEUE_GRAPHICS_BIT
+    cmdBufferObject.queueFlags = queueFlags
+}
+
+@threadSafety("app")
+cmd void vkCmdDrawIndexed(
+        VkCmdBuffer                                 cmdBuffer,
+        u32                                         firstIndex,
+        u32                                         indexCount,
+        s32                                         vertexOffset,
+        u32                                         firstInstance,
+        u32                                         instanceCount) {
+    cmdBufferObject := GetCmdBuffer(cmdBuffer)
+
+    queueFlags := cmdBufferObject.queueFlags | VK_QUEUE_GRAPHICS_BIT
+    cmdBufferObject.queueFlags = queueFlags
+}
+
+@threadSafety("app")
+cmd void vkCmdDrawIndirect(
+        VkCmdBuffer                                 cmdBuffer,
+        VkBuffer                                    buffer,
+        platform.VkDeviceSize                       offset,
+        u32                                         count,
+        u32                                         stride) {
+    cmdBufferObject := GetCmdBuffer(cmdBuffer)
+    bufferObject := GetBuffer(buffer)
+    assert(cmdBufferObject.device == bufferObject.device)
+
+    bindCmdBuffer(cmdBuffer, buffer, bufferObject.mem)
+
+    queueFlags := cmdBufferObject.queueFlags | VK_QUEUE_GRAPHICS_BIT
+    cmdBufferObject.queueFlags = queueFlags
+}
+
+@threadSafety("app")
+cmd void vkCmdDrawIndexedIndirect(
+        VkCmdBuffer                                 cmdBuffer,
+        VkBuffer                                    buffer,
+        platform.VkDeviceSize                       offset,
+        u32                                         count,
+        u32                                         stride) {
+    cmdBufferObject := GetCmdBuffer(cmdBuffer)
+    bufferObject := GetBuffer(buffer)
+    assert(cmdBufferObject.device == bufferObject.device)
+
+    bindCmdBuffer(cmdBuffer, buffer, bufferObject.mem)
+
+    queueFlags := cmdBufferObject.queueFlags | VK_QUEUE_GRAPHICS_BIT
+    cmdBufferObject.queueFlags = queueFlags
+}
+
+@threadSafety("app")
+cmd void vkCmdDispatch(
+        VkCmdBuffer                                 cmdBuffer,
+        u32                                         x,
+        u32                                         y,
+        u32                                         z) {
+    cmdBufferObject := GetCmdBuffer(cmdBuffer)
+
+    queueFlags := cmdBufferObject.queueFlags | VK_QUEUE_COMPUTE_BIT
+    cmdBufferObject.queueFlags = queueFlags
+}
+
+@threadSafety("app")
+cmd void vkCmdDispatchIndirect(
+        VkCmdBuffer                                 cmdBuffer,
+        VkBuffer                                    buffer,
+        platform.VkDeviceSize                       offset) {
+    cmdBufferObject := GetCmdBuffer(cmdBuffer)
+    bufferObject := GetBuffer(buffer)
+    assert(cmdBufferObject.device == bufferObject.device)
+
+    bindCmdBuffer(cmdBuffer, buffer, bufferObject.mem)
+
+    queueFlags := cmdBufferObject.queueFlags | VK_QUEUE_COMPUTE_BIT
+    cmdBufferObject.queueFlags = queueFlags
+}
+
+@threadSafety("app")
+cmd void vkCmdCopyBuffer(
+        VkCmdBuffer                                 cmdBuffer,
+        VkBuffer                                    srcBuffer,
+        VkBuffer                                    destBuffer,
+        u32                                         regionCount,
+        const VkBufferCopy*                         pRegions) {
+    cmdBufferObject := GetCmdBuffer(cmdBuffer)
+    srcBufferObject := GetBuffer(srcBuffer)
+    destBufferObject := GetBuffer(destBuffer)
+    assert(cmdBufferObject.device == srcBufferObject.device)
+    assert(cmdBufferObject.device == destBufferObject.device)
+
+    regions := pRegions[0:regionCount]
+    for i in (0 .. regionCount) {
+        region := regions[i]
+    }
+
+    bindCmdBuffer(cmdBuffer, srcBuffer, srcBufferObject.mem)
+    bindCmdBuffer(cmdBuffer, destBuffer, destBufferObject.mem)
+
+    queueFlags := cmdBufferObject.queueFlags | VK_QUEUE_DMA_BIT
+    cmdBufferObject.queueFlags = queueFlags
+}
+
+@threadSafety("app")
+cmd void vkCmdCopyImage(
+        VkCmdBuffer                                 cmdBuffer,
+        VkImage                                     srcImage,
+        VkImageLayout                               srcImageLayout,
+        VkImage                                     destImage,
+        VkImageLayout                               destImageLayout,
+        u32                                         regionCount,
+        const VkImageCopy*                          pRegions) {
+    cmdBufferObject := GetCmdBuffer(cmdBuffer)
+    srcImageObject := GetImage(srcImage)
+    destImageObject := GetImage(destImage)
+    assert(cmdBufferObject.device == srcImageObject.device)
+    assert(cmdBufferObject.device == destImageObject.device)
+
+    regions := pRegions[0:regionCount]
+    for i in (0 .. regionCount) {
+        region := regions[i]
+    }
+
+    bindCmdBuffer(cmdBuffer, srcImage, srcImageObject.mem)
+    bindCmdBuffer(cmdBuffer, destImage, destImageObject.mem)
+
+    queueFlags := cmdBufferObject.queueFlags | VK_QUEUE_DMA_BIT
+    cmdBufferObject.queueFlags = queueFlags
+}
+
+@threadSafety("app")
+cmd void vkCmdBlitImage(
+        VkCmdBuffer                                 cmdBuffer,
+        VkImage                                     srcImage,
+        VkImageLayout                               srcImageLayout,
+        VkImage                                     destImage,
+        VkImageLayout                               destImageLayout,
+        u32                                         regionCount,
+        const VkImageBlit*                          pRegions,
+        VkTexFilter                                 filter) {
+    cmdBufferObject := GetCmdBuffer(cmdBuffer)
+    srcImageObject := GetImage(srcImage)
+    destImageObject := GetImage(destImage)
+    assert(cmdBufferObject.device == srcImageObject.device)
+    assert(cmdBufferObject.device == destImageObject.device)
+
+    regions := pRegions[0:regionCount]
+    for i in (0 .. regionCount) {
+        region := regions[i]
+    }
+
+    bindCmdBuffer(cmdBuffer, srcImage, srcImageObject.mem)
+    bindCmdBuffer(cmdBuffer, destImage, destImageObject.mem)
+
+    queueFlags := cmdBufferObject.queueFlags | VK_QUEUE_GRAPHICS_BIT
+    cmdBufferObject.queueFlags = queueFlags
+}
+
+@threadSafety("app")
+cmd void vkCmdCopyBufferToImage(
+        VkCmdBuffer                                 cmdBuffer,
+        VkBuffer                                    srcBuffer,
+        VkImage                                     destImage,
+        VkImageLayout                               destImageLayout,
+        u32                                         regionCount,
+        const VkBufferImageCopy*                    pRegions) {
+    cmdBufferObject := GetCmdBuffer(cmdBuffer)
+    srcBufferObject := GetBuffer(srcBuffer)
+    destImageObject := GetImage(destImage)
+    assert(cmdBufferObject.device == srcBufferObject.device)
+    assert(cmdBufferObject.device == destImageObject.device)
+
+    regions := pRegions[0:regionCount]
+    for i in (0 .. regionCount) {
+        region := regions[i]
+    }
+
+    bindCmdBuffer(cmdBuffer, srcBuffer, srcBufferObject.mem)
+    bindCmdBuffer(cmdBuffer, destImage, destImageObject.mem)
+
+    queueFlags := cmdBufferObject.queueFlags | VK_QUEUE_DMA_BIT
+    cmdBufferObject.queueFlags = queueFlags
+}
+
+@threadSafety("app")
+cmd void vkCmdCopyImageToBuffer(
+        VkCmdBuffer                                 cmdBuffer,
+        VkImage                                     srcImage,
+        VkImageLayout                               srcImageLayout,
+        VkBuffer                                    destBuffer,
+        u32                                         regionCount,
+        const VkBufferImageCopy*                    pRegions) {
+    cmdBufferObject := GetCmdBuffer(cmdBuffer)
+    srcImageObject := GetImage(srcImage)
+    destBufferObject := GetBuffer(destBuffer)
+    assert(cmdBufferObject.device == srcImageObject.device)
+    assert(cmdBufferObject.device == destBufferObject.device)
+
+    regions := pRegions[0:regionCount]
+    for i in (0 .. regionCount) {
+        region := regions[i]
+    }
+
+    bindCmdBuffer(cmdBuffer, srcImage, srcImageObject.mem)
+    bindCmdBuffer(cmdBuffer, destBuffer, destBufferObject.mem)
+
+    queueFlags := cmdBufferObject.queueFlags | VK_QUEUE_DMA_BIT
+    cmdBufferObject.queueFlags = queueFlags
+}
+
+@threadSafety("app")
+cmd void vkCmdUpdateBuffer(
+        VkCmdBuffer                                 cmdBuffer,
+        VkBuffer                                    destBuffer,
+        platform.VkDeviceSize                       destOffset,
+        platform.VkDeviceSize                       dataSize,
+        const u32*                                  pData) {
+    cmdBufferObject := GetCmdBuffer(cmdBuffer)
+    destBufferObject := GetBuffer(destBuffer)
+    assert(cmdBufferObject.device == destBufferObject.device)
+
+    data := pData[0:dataSize]
+
+    bindCmdBuffer(cmdBuffer, destBuffer, destBufferObject.mem)
+
+    queueFlags := cmdBufferObject.queueFlags | VK_QUEUE_DMA_BIT
+    cmdBufferObject.queueFlags = queueFlags
+}
+
+@threadSafety("app")
+cmd void vkCmdFillBuffer(
+        VkCmdBuffer                                 cmdBuffer,
+        VkBuffer                                    destBuffer,
+        platform.VkDeviceSize                       destOffset,
+        platform.VkDeviceSize                       fillSize,
+        u32                                         data) {
+    cmdBufferObject := GetCmdBuffer(cmdBuffer)
+    destBufferObject := GetBuffer(destBuffer)
+    assert(cmdBufferObject.device == destBufferObject.device)
+
+    queueFlags := cmdBufferObject.queueFlags | VK_QUEUE_DMA_BIT
+    cmdBufferObject.queueFlags = queueFlags
+}
+
+@threadSafety("app")
+cmd void vkCmdClearColorImage(
+        VkCmdBuffer                                 cmdBuffer,
+        VkImage                                     image,
+        VkImageLayout                               imageLayout,
+        const VkClearColorValue*                    pColor,
+        u32                                         rangeCount,
+        const VkImageSubresourceRange*              pRanges) {
+    cmdBufferObject := GetCmdBuffer(cmdBuffer)
+    imageObject := GetImage(image)
+    assert(cmdBufferObject.device == imageObject.device)
+
+    ranges := pRanges[0:rangeCount]
+    for i in (0 .. rangeCount) {
+        range := ranges[i]
+    }
+
+    bindCmdBuffer(cmdBuffer, image, imageObject.mem)
+
+    queueFlags := cmdBufferObject.queueFlags | VK_QUEUE_GRAPHICS_BIT
+    cmdBufferObject.queueFlags = queueFlags
+}
+
+@threadSafety("app")
+cmd void vkCmdClearDepthStencilImage(
+        VkCmdBuffer                                 cmdBuffer,
+        VkImage                                     image,
+        VkImageLayout                               imageLayout,
+        f32                                         depth,
+        u32                                         stencil,
+        u32                                         rangeCount,
+        const VkImageSubresourceRange*              pRanges) {
+    cmdBufferObject := GetCmdBuffer(cmdBuffer)
+    imageObject := GetImage(image)
+    assert(cmdBufferObject.device == imageObject.device)
+
+    ranges := pRanges[0:rangeCount]
+    for i in (0 .. rangeCount) {
+        range := ranges[i]
+    }
+
+    bindCmdBuffer(cmdBuffer, image, imageObject.mem)
+
+    queueFlags := cmdBufferObject.queueFlags | VK_QUEUE_GRAPHICS_BIT
+    cmdBufferObject.queueFlags = queueFlags
+}
+
+@threadSafety("app")
+cmd void vkCmdClearColorAttachment(
+        VkCmdBuffer                                 cmdBuffer,
+        u32                                         colorAttachment,
+        VkImageLayout                               imageLayout,
+        const VkClearColorValue*                    pColor,
+        u32                                         rectCount,
+        const VkRect3D*                             pRects) {
+    cmdBufferObject := GetCmdBuffer(cmdBuffer)
+
+    rects := pRects[0:rectCount]
+    for i in (0 .. rectCount) {
+        rect := rects[i]
+    }
+
+    queueFlags := cmdBufferObject.queueFlags | VK_QUEUE_GRAPHICS_BIT
+    cmdBufferObject.queueFlags = queueFlags
+}
+
+@threadSafety("app")
+cmd void vkCmdClearDepthStencilAttachment(
+        VkCmdBuffer                                 cmdBuffer,
+        VkImageAspectFlags                          imageAspectMask,
+        VkImageLayout                               imageLayout,
+        f32                                         depth,
+        u32                                         stencil,
+        u32                                         rectCount,
+        const VkRect3D*                             pRects) {
+    cmdBufferObject := GetCmdBuffer(cmdBuffer)
+
+    rects := pRects[0:rectCount]
+    for i in (0 .. rectCount) {
+        rect := rects[i]
+    }
+
+    queueFlags := cmdBufferObject.queueFlags | VK_QUEUE_GRAPHICS_BIT
+    cmdBufferObject.queueFlags = queueFlags
+}
+
+@threadSafety("app")
+cmd void vkCmdResolveImage(
+        VkCmdBuffer                                 cmdBuffer,
+        VkImage                                     srcImage,
+        VkImageLayout                               srcImageLayout,
+        VkImage                                     destImage,
+        VkImageLayout                               destImageLayout,
+        u32                                         regionCount,
+        const VkImageResolve*                       pRegions) {
+    cmdBufferObject := GetCmdBuffer(cmdBuffer)
+    srcImageObject := GetImage(srcImage)
+    destImageObject := GetImage(destImage)
+    assert(cmdBufferObject.device == srcImageObject.device)
+    assert(cmdBufferObject.device == destImageObject.device)
+
+    regions := pRegions[0:regionCount]
+    for i in (0 .. regionCount) {
+        region := regions[i]
+    }
+
+    bindCmdBuffer(cmdBuffer, srcImage, srcImageObject.mem)
+    bindCmdBuffer(cmdBuffer, destImage, destImageObject.mem)
+
+    queueFlags := cmdBufferObject.queueFlags | VK_QUEUE_GRAPHICS_BIT
+    cmdBufferObject.queueFlags = queueFlags
+}
+
+@threadSafety("app")
+cmd void vkCmdSetEvent(
+        VkCmdBuffer                                 cmdBuffer,
+        VkEvent                                     event,
+        VkPipelineStageFlags                        stageMask) {
+    cmdBufferObject := GetCmdBuffer(cmdBuffer)
+    eventObject := GetEvent(event)
+    assert(cmdBufferObject.device == eventObject.device)
+}
+
+@threadSafety("app")
+cmd void vkCmdResetEvent(
+        VkCmdBuffer                                 cmdBuffer,
+        VkEvent                                     event,
+        VkPipelineStageFlags                        stageMask) {
+    cmdBufferObject := GetCmdBuffer(cmdBuffer)
+    eventObject := GetEvent(event)
+    assert(cmdBufferObject.device == eventObject.device)
+}
+
+@threadSafety("app")
+cmd void vkCmdWaitEvents(
+        VkCmdBuffer                                 cmdBuffer,
+        u32                                         eventCount,
+        const VkEvent*                              pEvents,
+        VkPipelineStageFlags                        srcStageMask,
+        VkPipelineStageFlags                        destStageMask,
+        u32                                         memBarrierCount,
+        const void* const*                          ppMemBarriers) {
+    cmdBufferObject := GetCmdBuffer(cmdBuffer)
+
+    events := pEvents[0:eventCount]
+    for i in (0 .. eventCount) {
+        event := events[i]
+        eventObject := GetEvent(event)
+        assert(cmdBufferObject.device == eventObject.device)
+    }
+
+    pMemBarriers := ppMemBarriers[0:memBarrierCount]
+    for i in (0 .. memBarrierCount) {
+        switch as!VkMemoryBarrier const*(pMemBarriers[i])[0].sType {
+            case VK_STRUCTURE_TYPE_MEMORY_BARRIER: {
+                memBarrier := as!VkMemoryBarrier const*(pMemBarriers[i])[0]
+            }
+            case VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER: {
+                imageMemBarrier := as!VkImageMemoryBarrier const*(pMemBarriers[i])[0]
+                imageObject := GetImage(imageMemBarrier.image)
+                assert(imageObject.device == cmdBufferObject.device)
+            }
+            case VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER: {
+                bufferMemBarrier := as!VkBufferMemoryBarrier const*(pMemBarriers[i])[0]
+                bufferObject := GetBuffer(bufferMemBarrier.buffer)
+                assert(bufferObject.device == cmdBufferObject.device)
+            }
+        }
+    }
+}
+
+@threadSafety("app")
+cmd void vkCmdPipelineBarrier(
+        VkCmdBuffer                                 cmdBuffer,
+        VkPipelineStageFlags                        srcStageMask,
+        VkPipelineStageFlags                        destStageMask,
+        platform.VkBool32                           byRegion,
+        u32                                         memBarrierCount,
+        const void* const*                          ppMemBarriers) {
+    cmdBufferObject := GetCmdBuffer(cmdBuffer)
+
+    pMemBarriers := ppMemBarriers[0:memBarrierCount]
+    for i in (0 .. memBarrierCount) {
+        switch as!VkMemoryBarrier const*(pMemBarriers[i])[0].sType {
+            case VK_STRUCTURE_TYPE_MEMORY_BARRIER: {
+                memBarrier := as!VkMemoryBarrier const*(pMemBarriers[i])[0]
+            }
+            case VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER: {
+                imageMemBarrier := as!VkImageMemoryBarrier const*(pMemBarriers[i])[0]
+                imageObject := GetImage(imageMemBarrier.image)
+                assert(imageObject.device == cmdBufferObject.device)
+            }
+            case VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER: {
+                bufferMemBarrier := as!VkBufferMemoryBarrier const*(pMemBarriers[i])[0]
+                bufferObject := GetBuffer(bufferMemBarrier.buffer)
+                assert(bufferObject.device == cmdBufferObject.device)
+            }
+        }
+    }
+}
+
+@threadSafety("app")
+cmd void vkCmdBeginQuery(
+        VkCmdBuffer                                 cmdBuffer,
+        VkQueryPool                                 queryPool,
+        u32                                         slot,
+        VkQueryControlFlags                         flags) {
+    cmdBufferObject := GetCmdBuffer(cmdBuffer)
+    queryPoolObject := GetQueryPool(queryPool)
+    assert(cmdBufferObject.device == queryPoolObject.device)
+}
+
+@threadSafety("app")
+cmd void vkCmdEndQuery(
+        VkCmdBuffer                                 cmdBuffer,
+        VkQueryPool                                 queryPool,
+        u32                                         slot) {
+    cmdBufferObject := GetCmdBuffer(cmdBuffer)
+    queryPoolObject := GetQueryPool(queryPool)
+    assert(cmdBufferObject.device == queryPoolObject.device)
+}
+
+@threadSafety("app")
+cmd void vkCmdResetQueryPool(
+        VkCmdBuffer                                 cmdBuffer,
+        VkQueryPool                                 queryPool,
+        u32                                         startQuery,
+        u32                                         queryCount) {
+    cmdBufferObject := GetCmdBuffer(cmdBuffer)
+    queryPoolObject := GetQueryPool(queryPool)
+    assert(cmdBufferObject.device == queryPoolObject.device)
+}
+
+@threadSafety("app")
+cmd void vkCmdWriteTimestamp(
+        VkCmdBuffer                                 cmdBuffer,
+        VkTimestampType                             timestampType,
+        VkBuffer                                    destBuffer,
+        platform.VkDeviceSize                       destOffset) {
+    cmdBufferObject := GetCmdBuffer(cmdBuffer)
+    destBufferObject := GetBuffer(destBuffer)
+    assert(cmdBufferObject.device == destBufferObject.device)
+}
+
+@threadSafety("app")
+cmd void vkCmdCopyQueryPoolResults(
+        VkCmdBuffer                                 cmdBuffer,
+        VkQueryPool                                 queryPool,
+        u32                                         startQuery,
+        u32                                         queryCount,
+        VkBuffer                                    destBuffer,
+        platform.VkDeviceSize                       destOffset,
+        platform.VkDeviceSize                       destStride,
+        VkQueryResultFlags                          flags) {
+    cmdBufferObject := GetCmdBuffer(cmdBuffer)
+    queryPoolObject := GetQueryPool(queryPool)
+    destBufferObject := GetBuffer(destBuffer)
+    assert(cmdBufferObject.device == queryPoolObject.device)
+    assert(cmdBufferObject.device == destBufferObject.device)
+}
+
+cmd void vkCmdPushConstants(
+        VkCmdBuffer                                 cmdBuffer,
+        VkPipelineLayout                            layout,
+        VkShaderStageFlags                          stageFlags,
+        u32                                         start,
+        u32                                         length,
+        const void*                                 values) {
+    cmdBufferObject := GetCmdBuffer(cmdBuffer)
+    layoutObject := GetPipelineLayout(layout)
+    assert(cmdBufferObject.device == layoutObject.device)
+}
+
+@threadSafety("app")
+cmd void vkCmdBeginRenderPass(
+        VkCmdBuffer                                 cmdBuffer,
+        const VkRenderPassBeginInfo*                pRenderPassBegin,
+        VkRenderPassContents                        contents) {
+    cmdBufferObject := GetCmdBuffer(cmdBuffer)
+    renderPassObject := GetRenderPass(pRenderPassBegin.renderPass)
+    framebufferObject := GetFramebuffer(pRenderPassBegin.framebuffer)
+    assert(cmdBufferObject.device == renderPassObject.device)
+    assert(cmdBufferObject.device == framebufferObject.device)
+
+    queueFlags := cmdBufferObject.queueFlags | VK_QUEUE_GRAPHICS_BIT
+    cmdBufferObject.queueFlags = queueFlags
+}
+
+cmd void vkCmdNextSubpass(
+        VkCmdBuffer                                 cmdBuffer,
+        VkRenderPassContents                        contents) {
+    cmdBufferObject := GetCmdBuffer(cmdBuffer)
+}
+
+@threadSafety("app")
+cmd void vkCmdEndRenderPass(
+        VkCmdBuffer                                 cmdBuffer) {
+    cmdBufferObject := GetCmdBuffer(cmdBuffer)
+
+    queueFlags := cmdBufferObject.queueFlags | VK_QUEUE_GRAPHICS_BIT
+    cmdBufferObject.queueFlags = queueFlags
+}
+
+cmd void vkCmdExecuteCommands(
+        VkCmdBuffer                                 cmdBuffer,
+        u32                                         cmdBuffersCount,
+        const VkCmdBuffer*                          pCmdBuffers) {
+    cmdBufferObject := GetCmdBuffer(cmdBuffer)
+
+    cmdBuffers := pCmdBuffers[0:cmdBuffersCount]
+    for i in (0 .. cmdBuffersCount) {
+        secondaryCmdBuffer := cmdBuffers[i]
+        secondaryCmdBufferObject := GetCmdBuffer(secondaryCmdBuffer)
+        assert(cmdBufferObject.device == secondaryCmdBufferObject.device)
+    }
+}
+
+
+////////////////
+// Validation //
+////////////////
+
+extern void validate(string layerName, bool condition, string message)
+
+
+/////////////////////////////
+// Internal State Tracking //
+/////////////////////////////
+
+StateObject State
+
+@internal class StateObject {
+    // Dispatchable objects.
+    map!(VkInstance,       ref!InstanceObject)       Instances
+    map!(VkPhysicalDevice, ref!PhysicalDeviceObject) PhysicalDevices
+    map!(VkDevice,         ref!DeviceObject)         Devices
+    map!(VkQueue,          ref!QueueObject)          Queues
+    map!(VkCmdBuffer,      ref!CmdBufferObject)      CmdBuffers
+
+    // Non-dispatchable objects.
+    map!(VkDeviceMemory,             ref!DeviceMemoryObject)             DeviceMemories
+    map!(VkBuffer,                   ref!BufferObject)                   Buffers
+    map!(VkBufferView,               ref!BufferViewObject)               BufferViews
+    map!(VkImage,                    ref!ImageObject)                    Images
+    map!(VkImageView,                ref!ImageViewObject)                ImageViews
+    map!(VkAttachmentView,           ref!AttachmentViewObject)           AttachmentViews
+    map!(VkShaderModule,             ref!ShaderModuleObject)             ShaderModules
+    map!(VkShader,                   ref!ShaderObject)                   Shaders
+    map!(VkPipeline,                 ref!PipelineObject)                 Pipelines
+    map!(VkPipelineLayout,           ref!PipelineLayoutObject)           PipelineLayouts
+    map!(VkSampler,                  ref!SamplerObject)                  Samplers
+    map!(VkDescriptorSet,            ref!DescriptorSetObject)            DescriptorSets
+    map!(VkDescriptorSetLayout,      ref!DescriptorSetLayoutObject)      DescriptorSetLayouts
+    map!(VkDescriptorPool,           ref!DescriptorPoolObject)           DescriptorPools
+    map!(VkDynamicViewportState,     ref!DynamicViewportStateObject)     DynamicViewportStates
+    map!(VkDynamicRasterState,       ref!DynamicRasterStateObject)       DynamicRasterStates
+    map!(VkDynamicColorBlendState,   ref!DynamicColorBlendStateObject)   DynamicColorBlendStates
+    map!(VkDynamicDepthStencilState, ref!DynamicDepthStencilStateObject) DynamicDepthStencilStates
+    map!(VkFence,                    ref!FenceObject)                    Fences
+    map!(VkSemaphore,                ref!SemaphoreObject)                Semaphores
+    map!(VkEvent,                    ref!EventObject)                    Events
+    map!(VkQueryPool,                ref!QueryPoolObject)                QueryPools
+    map!(VkFramebuffer,              ref!FramebufferObject)              Framebuffers
+    map!(VkRenderPass,               ref!RenderPassObject)               RenderPasses
+    map!(VkPipelineCache,            ref!PipelineCacheObject)            PipelineCaches
+    map!(VkCmdPool,                  ref!CmdPoolObject)                  CmdPools
+}
+
+@internal class InstanceObject {
+}
+
+@internal class PhysicalDeviceObject {
+    VkInstance instance
+}
+
+@internal class DeviceObject {
+    VkPhysicalDevice physicalDevice
+}
+
+@internal class QueueObject {
+    VkDevice      device
+    VkQueueFlags  flags
+}
+
+@internal class CmdBufferObject {
+    VkDevice                  device
+    map!(u64, VkDeviceMemory) boundObjects
+    VkQueueFlags              queueFlags
+}
+
+@internal class DeviceMemoryObject {
+    VkDevice                         device
+    platform.VkDeviceSize            allocationSize
+    map!(u64, platform.VkDeviceSize) boundObjects
+    map!(VkCmdBuffer, VkCmdBuffer)   boundCommandBuffers
+}
+
+@internal class BufferObject {
+    VkDevice              device
+    VkDeviceMemory        mem
+    platform.VkDeviceSize memOffset
+}
+
+@internal class BufferViewObject {
+    VkDevice      device
+    VkBuffer      buffer
+}
+
+@internal class ImageObject {
+    VkDevice              device
+    VkDeviceMemory        mem
+    platform.VkDeviceSize memOffset
+}
+
+@internal class ImageViewObject {
+    VkDevice      device
+    VkImage       image
+}
+
+@internal class AttachmentViewObject {
+    VkDevice      device
+    VkImage       image
+}
+
+@internal class ShaderObject {
+    VkDevice      device
+}
+
+@internal class ShaderModuleObject {
+    VkDevice      device
+}
+
+@internal class PipelineObject {
+    VkDevice      device
+}
+
+@internal class PipelineLayoutObject {
+    VkDevice      device
+}
+
+@internal class SamplerObject {
+    VkDevice      device
+}
+
+@internal class DescriptorSetObject {
+    VkDevice      device
+}
+
+@internal class DescriptorSetLayoutObject {
+    VkDevice      device
+}
+
+@internal class DescriptorPoolObject {
+    VkDevice      device
+}
+
+@internal class DynamicViewportStateObject {
+    VkDevice      device
+}
+
+@internal class DynamicRasterStateObject {
+    VkDevice      device
+}
+
+@internal class DynamicColorBlendStateObject {
+    VkDevice      device
+}
+
+@internal class DynamicDepthStencilStateObject {
+    VkDevice      device
+}
+
+@internal class FenceObject {
+    VkDevice      device
+    bool          signaled
+}
+
+@internal class SemaphoreObject {
+    VkDevice      device
+}
+
+@internal class EventObject {
+    VkDevice      device
+}
+
+@internal class QueryPoolObject {
+    VkDevice      device
+}
+
+@internal class FramebufferObject {
+    VkDevice      device
+}
+
+@internal class RenderPassObject {
+    VkDevice      device
+}
+
+@internal class PipelineCacheObject {
+    VkDevice      device
+}
+
+@internal class CmdPoolObject {
+    VkDevice      device
+}
+
+macro ref!InstanceObject GetInstance(VkInstance instance) {
+    assert(instance in State.Instances)
+    return State.Instances[instance]
+}
+
+macro ref!PhysicalDeviceObject GetPhysicalDevice(VkPhysicalDevice physicalDevice) {
+    assert(physicalDevice in State.PhysicalDevices)
+    return State.PhysicalDevices[physicalDevice]
+}
+
+macro ref!DeviceObject GetDevice(VkDevice device) {
+    assert(device in State.Devices)
+    return State.Devices[device]
+}
+
+macro ref!QueueObject GetQueue(VkQueue queue) {
+    assert(queue in State.Queues)
+    return State.Queues[queue]
+}
+
+macro ref!CmdBufferObject GetCmdBuffer(VkCmdBuffer cmdBuffer) {
+    assert(cmdBuffer in State.CmdBuffers)
+    return State.CmdBuffers[cmdBuffer]
+}
+
+macro ref!DeviceMemoryObject GetDeviceMemory(VkDeviceMemory mem) {
+    assert(mem in State.DeviceMemories)
+    return State.DeviceMemories[mem]
+}
+
+macro ref!BufferObject GetBuffer(VkBuffer buffer) {
+    assert(buffer in State.Buffers)
+    return State.Buffers[buffer]
+}
+
+macro ref!BufferViewObject GetBufferView(VkBufferView bufferView) {
+    assert(bufferView in State.BufferViews)
+    return State.BufferViews[bufferView]
+}
+
+macro ref!ImageObject GetImage(VkImage image) {
+    assert(image in State.Images)
+    return State.Images[image]
+}
+
+macro ref!ImageViewObject GetImageView(VkImageView imageView) {
+    assert(imageView in State.ImageViews)
+    return State.ImageViews[imageView]
+}
+
+macro ref!AttachmentViewObject GetAttachmentView(VkAttachmentView attachmentView) {
+    assert(attachmentView in State.AttachmentViews)
+    return State.AttachmentViews[attachmentView]
+}
+
+macro ref!ShaderObject GetShader(VkShader shader) {
+    assert(shader in State.Shaders)
+    return State.Shaders[shader]
+}
+
+macro ref!ShaderModuleObject GetShaderModule(VkShaderModule shaderModule) {
+    assert(shaderModule in State.ShaderModules)
+    return State.ShaderModules[shaderModule]
+}
+
+macro ref!PipelineObject GetPipeline(VkPipeline pipeline) {
+    assert(pipeline in State.Pipelines)
+    return State.Pipelines[pipeline]
+}
+
+macro ref!PipelineLayoutObject GetPipelineLayout(VkPipelineLayout pipelineLayout) {
+    assert(pipelineLayout in State.PipelineLayouts)
+    return State.PipelineLayouts[pipelineLayout]
+}
+
+macro ref!SamplerObject GetSampler(VkSampler sampler) {
+    assert(sampler in State.Samplers)
+    return State.Samplers[sampler]
+}
+
+macro ref!DescriptorSetObject GetDescriptorSet(VkDescriptorSet descriptorSet) {
+    assert(descriptorSet in State.DescriptorSets)
+    return State.DescriptorSets[descriptorSet]
+}
+
+macro ref!DescriptorSetLayoutObject GetDescriptorSetLayout(VkDescriptorSetLayout descriptorSetLayout) {
+    assert(descriptorSetLayout in State.DescriptorSetLayouts)
+    return State.DescriptorSetLayouts[descriptorSetLayout]
+}
+
+macro ref!DescriptorPoolObject GetDescriptorPool(VkDescriptorPool descriptorPool) {
+    assert(descriptorPool in State.DescriptorPools)
+    return State.DescriptorPools[descriptorPool]
+}
+
+macro ref!DynamicViewportStateObject GetDynamicViewportState(VkDynamicViewportState dynamicViewportState) {
+    assert(dynamicViewportState in State.DynamicViewportStates)
+    return State.DynamicViewportStates[dynamicViewportState]
+}
+
+macro ref!DynamicRasterStateObject GetDynamicRasterState(VkDynamicRasterState dynamicRasterState) {
+    assert(dynamicRasterState in State.DynamicRasterStates)
+    return State.DynamicRasterStates[dynamicRasterState]
+}
+
+macro ref!DynamicColorBlendStateObject GetDynamicColorBlendState(VkDynamicColorBlendState dynamicColorBlendState) {
+    assert(dynamicColorBlendState in State.DynamicColorBlendStates)
+    return State.DynamicColorBlendStates[dynamicColorBlendState]
+}
+
+macro ref!DynamicDepthStencilStateObject GetDynamicDepthStencilState(VkDynamicDepthStencilState dynamicDepthStencilState) {
+    assert(dynamicDepthStencilState in State.DynamicDepthStencilStates)
+    return State.DynamicDepthStencilStates[dynamicDepthStencilState]
+}
+
+macro ref!FenceObject GetFence(VkFence fence) {
+    assert(fence in State.Fences)
+    return State.Fences[fence]
+}
+
+macro ref!SemaphoreObject GetSemaphore(VkSemaphore semaphore) {
+    assert(semaphore in State.Semaphores)
+    return State.Semaphores[semaphore]
+}
+
+macro ref!EventObject GetEvent(VkEvent event) {
+    assert(event in State.Events)
+    return State.Events[event]
+}
+
+macro ref!QueryPoolObject GetQueryPool(VkQueryPool queryPool) {
+    assert(queryPool in State.QueryPools)
+    return State.QueryPools[queryPool]
+}
+
+macro ref!FramebufferObject GetFramebuffer(VkFramebuffer framebuffer) {
+    assert(framebuffer in State.Framebuffers)
+    return State.Framebuffers[framebuffer]
+}
+
+macro ref!RenderPassObject GetRenderPass(VkRenderPass renderPass) {
+    assert(renderPass in State.RenderPasses)
+    return State.RenderPasses[renderPass]
+}
+
+macro ref!PipelineCacheObject GetPipelineCache(VkPipelineCache pipelineCache) {
+    assert(pipelineCache in State.PipelineCaches)
+    return State.PipelineCaches[pipelineCache]
+}
+
+macro ref!CmdPoolObject GetCmdPool(VkCmdPool cmdPool) {
+    assert(cmdPool in State.CmdPools)
+    return State.CmdPools[cmdPool]
+}
\ No newline at end of file