vulkan: Implement VkSurfaceKHR and use vulkanext.h

Between header version 0.183.0 and 0.184.0, a copy of vulkan.h which
includes extensions was added to the registry, called vulkanext.h. The
vulkan.h included here is actually the registry's vulkanext.h.
(In a later upstream change, the no-extensions version was removed
from the registry, and vulkanext.h was renamed vulkan.h, matching what
we're doing here.)

The version of the extensions picked up in the header file is later
than the ones used in the previous SDK, so this change also updates
our implementation to the extension versions included in the header.
The main change is replacing the VkSurfaceDescriptionKHR structure
with a VkSurfaceKHR object.

Change-Id: I18fa5a269db0fcdbdbde3e9304167bc15e456f85
(cherry picked from commit 957a59a48a8d2e81ca3bb52aacd8d08b1b43dc74)
diff --git a/vulkan/api/platform.api b/vulkan/api/platform.api
index 23f649d..889ac2c 100644
--- a/vulkan/api/platform.api
+++ b/vulkan/api/platform.api
@@ -22,3 +22,26 @@
 // Platform types, as defined or included in vk_platform.h
 
 type u64 size_t
+
+// VK_USE_PLATFORM_X11_KHR
+@internal class Display {}
+@internal class Window {}
+
+// VK_USE_PLATFORM_XCB_KHR
+@internal class xcb_connection_t {}
+@internal type u32 xcb_window_t
+
+// VK_USE_PLATFORM_WAYLAND_KHR
+@internal class wl_display {}
+@internal class wl_surface {}
+
+// VK_USE_PLATFORM_MIR_KHR
+@internal class MirConnection {}
+@internal class MirSurface {}
+
+// VK_USE_PLATFORM_ANDROID_KHR
+@internal class ANativeWindow {}
+
+// VK_USE_PLATFORM_WIN32_KHR
+@internal type void* HINSTANCE
+@internal type void* HWND
diff --git a/vulkan/api/vulkan.api b/vulkan/api/vulkan.api
index 175e353..878cf44 100644
--- a/vulkan/api/vulkan.api
+++ b/vulkan/api/vulkan.api
@@ -45,6 +45,46 @@
 // API keyword, but needs special handling by some templates
 define NULL_HANDLE 0
 
+@extension("VK_EXT_KHR_surface") define VK_EXT_KHR_SURFACE_REVISION                     19
+@extension("VK_EXT_KHR_surface") define VK_EXT_KHR_SURFACE_EXTENSION_NUMBER             1
+@extension("VK_EXT_KHR_surface") define VK_EXT_KHR_SURFACE_EXTENSION_NAME               "VK_EXT_KHR_surface"
+
+@extension("VK_EXT_KHR_swapchain") define VK_EXT_KHR_SWAPCHAIN_REVISION                 59
+@extension("VK_EXT_KHR_swapchain") define VK_EXT_KHR_SWAPCHAIN_EXTENSION_NUMBER         2
+@extension("VK_EXT_KHR_swapchain") define VK_EXT_KHR_SWAPCHAIN_EXTENSION_NAME           "VK_EXT_KHR_swapchain"
+
+@extension("VK_EXT_KHR_display") define VK_EXT_KHR_DISPLAY_REVISION                     16
+@extension("VK_EXT_KHR_display") define VK_EXT_KHR_DISPLAY_EXTENSION_NUMBER             3
+@extension("VK_EXT_KHR_display") define VK_EXT_KHR_DISPLAY_EXTENSION_NAME               "VK_EXT_KHR_display"
+
+@extension("VK_EXT_KHR_display_swapchain") define VK_EXT_KHR_DISPLAY_REVISION           14
+@extension("VK_EXT_KHR_display_swapchain") define VK_EXT_KHR_DISPLAY_EXTENSION_NUMBER   4
+@extension("VK_EXT_KHR_display_swapchain") define VK_EXT_KHR_DISPLAY_EXTENSION_NAME     "VK_EXT_KHR_display_swapchain"
+
+@extension("VK_EXT_KHR_x11_surface") define VK_EXT_KHR_X11_SURFACE_REVISION             1
+@extension("VK_EXT_KHR_x11_surface") define VK_EXT_KHR_X11_SURFACE_NUMBER               4
+@extension("VK_EXT_KHR_x11_surface") define VK_EXT_KHR_X11_SURFACE_NAME                 "VK_EXT_KHR_x11_surface"
+
+@extension("VK_EXT_KHR_xcb_surface") define VK_EXT_KHR_XCB_SURFACE_REVISION             1
+@extension("VK_EXT_KHR_xcb_surface") define VK_EXT_KHR_XCB_SURFACE_NUMBER               6
+@extension("VK_EXT_KHR_xcb_surface") define VK_EXT_KHR_XCB_SURFACE_NAME                 "VK_EXT_KHR_xcb_surface"
+
+@extension("VK_EXT_KHR_wayland_surface") define VK_EXT_KHR_WAYLAND_SURFACE_REVISION     1
+@extension("VK_EXT_KHR_wayland_surface") define VK_EXT_KHR_WAYLAND_SURFACE_NUMBER       7
+@extension("VK_EXT_KHR_wayland_surface") define VK_EXT_KHR_WAYLAND_SURFACE_NAME         "VK_EXT_KHR_wayland_surface"
+
+@extension("VK_EXT_KHR_mir_surface") define VK_EXT_KHR_MIR_SURFACE_REVISION             1
+@extension("VK_EXT_KHR_mir_surface") define VK_EXT_KHR_MIR_SURFACE_NUMBER               8
+@extension("VK_EXT_KHR_mir_surface") define VK_EXT_KHR_MIR_SURFACE_NAME                 "VK_EXT_KHR_mir_surface"
+
+@extension("VK_EXT_KHR_android_surface") define VK_EXT_KHR_ANDROID_SURFACE_REVISION     1
+@extension("VK_EXT_KHR_android_surface") define VK_EXT_KHR_ANDROID_SURFACE_NUMBER       8
+@extension("VK_EXT_KHR_android_surface") define VK_EXT_KHR_ANDROID_SURFACE_NAME         "VK_EXT_KHR_android_surface"
+
+@extension("VK_EXT_KHR_win32_surface") define VK_EXT_KHR_WIN32_SURFACE_REVISION         1
+@extension("VK_EXT_KHR_win32_surface") define VK_EXT_KHR_WIN32_SURFACE_NUMBER           9
+@extension("VK_EXT_KHR_win32_surface") define VK_EXT_KHR_WIN32_SURFACE_NAME             "VK_EXT_KHR_win32_surface"
+
 
 /////////////
 //  Types  //
@@ -84,7 +124,13 @@
 @nonDispatchHandle type u64 VkFramebuffer
 @nonDispatchHandle type u64 VkRenderPass
 @nonDispatchHandle type u64 VkPipelineCache
-@nonDispatchHandle type u64 VkSwapchainKHR
+
+@extension("VK_EXT_KHR_surface")    @nonDispatchHandle type u64 VkSurfaceKHR
+
+@extension("VK_EXT_KHR_swapchain")  @nonDispatchHandle type u64 VkSwapchainKHR
+
+@extension("VK_EXT_KHR_display")    @nonDispatchHandle type u64 VkDisplayKHR
+@extension("VK_EXT_KHR_display")    @nonDispatchHandle type u64 VkDisplayModeKHR
 
 
 /////////////
@@ -101,6 +147,9 @@
     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
     VK_IMAGE_LAYOUT_PREINITIALIZED                          = 0x00000008,   /// Initial layout used when the data is populated by the CPU
+
+    //@extension("VK_EXT_KHR_swapchain")
+    VK_IMAGE_LAYOUT_PRESENT_SOURCE_KHR                      = 0xc0000802,
 }
 
 enum VkAttachmentLoadOp {
@@ -568,6 +617,17 @@
     VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO                  = 45,
     VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO        = 46,
     VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOC_INFO                 = 47,
+
+    //@extension("VK_EXT_KHR_swapchain")
+    VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR                 = 0xc0000801,
+
+    //@extension("VK_EXT_KHR_display")
+    VK_STRUCTURE_TYPE_DISPLAY_MODE_CREATE_INFO_KHR              = 0xc0000c00,
+    VK_STRUCTURE_TYPE_SURFACE_DESCRIPTION_DISPLAY_PLAN_KHR      = 0xc0000c01,
+
+    //@extension("VK_EXT_KHR_display_swapchain")
+    VK_STRUCTURE_TYPE_DISPLAY_SWAPCHAIN_CREATE_INFO_KHR         = 0xc0001000,
+    VK_STRUCTURE_TYPE_DISPLAY_DISPLAY_PRESENT_INFO_KHR          = 0xc0001001,
 }
 
 enum VkRenderPassContents {
@@ -586,6 +646,9 @@
     VK_EVENT_RESET                                          = 0x00000004,
     VK_INCOMPLETE                                           = 0x00000005,
 
+    //@extension("VK_EXT_KHR_swapchain")
+    VK_SUBOPTIMAL_KHR                                       = 0x40000403,
+
     // Error codes (negative values)
     VK_ERROR_OUT_OF_HOST_MEMORY                             = 0xFFFFFFFF,
     VK_ERROR_OUT_OF_DEVICE_MEMORY                           = 0xFFFFFFFE,
@@ -596,6 +659,16 @@
     VK_ERROR_EXTENSION_NOT_PRESENT                          = 0xFFFFFFF9,
     VK_ERROR_FEATURE_NOT_PRESENT                            = 0xFFFFFFF8,
     VK_ERROR_INCOMPATIBLE_DRIVER                            = 0xFFFFFFF7,
+
+    //@extension("VK_EXT_KHR_swapchain")
+    VK_ERROR_OUT_OF_DATE_KHR                                = 0xC0000804,
+
+    //@extension("VK_EXT_KHR_display_swapchain")
+    VK_ERROR_INCOMPATIBLE_DISPLAY_KHR                       = 0xC0001002,
+
+    //@extension("VK_EXT_KHR_android_surface")
+    VK_ERROR_INVALID_ANDROID_WINDOW_KHR                     = 0xC002400,
+    VK_ERROR_ANDROID_WINDOW_IN_USE_KHR                      = 0xC002401,
 }
 
 enum VkDynamicState {
@@ -610,11 +683,7 @@
     VK_DYNAMIC_STATE_STENCIL_REFERENCE                      = 0x00000008,
 }
 
-//////////////////
-//  Extensions  //
-//////////////////
-
-@extension("VK_EXT_KHR_swapchain")
+@extension("VK_EXT_KHR_surface")
 enum VkSurfaceTransformKHR {
     VK_SURFACE_TRANSFORM_NONE_KHR                           = 0x00000000,
     VK_SURFACE_TRANSFORM_ROT90_KHR                          = 0x00000001,
@@ -628,23 +697,13 @@
 }
 
 @extension("VK_EXT_KHR_swapchain")
-enum VkPlatformKHR {
-    VK_PLATFORM_WIN32_KHR                                   = 0x00000000,
-    VK_PLATFORM_X11_KHR                                     = 0x00000001,
-    VK_PLATFORM_XCB_KHR                                     = 0x00000002,
-    VK_PLATFORM_ANDROID_KHR                                 = 0x00000003,
-    VK_PLATFORM_WAYLAND_KHR                                 = 0x00000004,
-    VK_PLATFORM_MIR_KHR                                     = 0x00000005,
-}
-
-@extension("VK_EXT_KHR_device_swapchain")
 enum VkPresentModeKHR {
     VK_PRESENT_MODE_IMMEDIATE_KHR                           = 0x00000000,
     VK_PRESENT_MODE_MAILBOX_KHR                             = 0x00000001,
     VK_PRESENT_MODE_FIFO_KHR                                = 0x00000002,
 }
 
-@extension("VK_EXT_KHR_device_swapchain")
+@extension("VK_EXT_KHR_swapchain")
 enum VkColorSpaceKHR {
     VK_COLORSPACE_SRGB_NONLINEAR_KHR                        = 0x00000000,
 }
@@ -941,10 +1000,6 @@
     VK_STENCIL_FACE_BACK_BIT                                = 0x00000002,   /// Back face
 }
 
-//////////////////
-//  Extensions  //
-//////////////////
-
 @extension("VK_EXT_KHR_swapchain")
 bitfield VkSurfaceTransformFlagsKHR {
     VK_SURFACE_TRANSFORM_NONE_BIT_KHR                       = 0x00000001,
@@ -958,6 +1013,14 @@
     VK_SURFACE_TRANSFORM_INHERIT_BIT_KHR                    = 0x00000100,
 }
 
+@extension("VK_EXT_KHR_display")
+bitfield VkDisplayPlaneAlphaFlagsKHR {
+    VK_DISPLAY_PLANE_ALPHA_GLOBAL_BIT_KHR                   = 0x00000001,
+    VK_DISPLAY_PLANE_ALPHA_PER_PIXEL_BIT_KHR                = 0x00000002,
+    VK_DISPLAY_PLANE_ALPHA_PER_PIXEL_PREMULTIPLIED_BIT_KHR  = 0x00000004,
+}
+
+
 //////////////////
 //  Structures  //
 //////////////////
@@ -1995,73 +2058,136 @@
     u32                                         z
 }
 
-//////////////////
-//  Extensions  //
-//////////////////
-
-@extension("VK_EXT_KHR_device_swapchain")
+@extension("VK_EXT_KHR_swapchain")
 class VkSurfacePropertiesKHR {
-    u32                                     minImageCount
-    u32                                     maxImageCount
-    VkExtent2D                              currentExtent
-    VkExtent2D                              minImageExtent
-    VkExtent2D                              maxImageExtent
-    VkSurfaceTransformFlagsKHR              supportedTransforms
-    VkSurfaceTransformKHR                   currentTransform
-    u32                                     maxImageArraySize
-    VkImageUsageFlags                       supportedUsageFlags
+    u32                                         minImageCount
+    u32                                         maxImageCount
+    VkExtent2D                                  currentExtent
+    VkExtent2D                                  minImageExtent
+    VkExtent2D                                  maxImageExtent
+    VkSurfaceTransformFlagsKHR                  supportedTransforms
+    VkSurfaceTransformKHR                       currentTransform
+    u32                                         maxImageArraySize
+    VkImageUsageFlags                           supportedUsageFlags
 }
 
-@extension("VK_EXT_KHR_device_swapchain")
+@extension("VK_EXT_KHR_swapchain")
 class VkSurfaceFormatKHR {
-    VkFormat                                format
-    VkColorSpaceKHR                         colorSpace
+    VkFormat                                    format
+    VkColorSpaceKHR                             colorSpace
 }
 
-@extension("VK_EXT_KHR_device_swapchain")
+@extension("VK_EXT_KHR_swapchain")
 class VkSwapchainCreateInfoKHR {
-    VkStructureType                          sType
-    const void*                              pNext
-    const VkSurfaceDescriptionKHR*           pSurfaceDescription
-    u32                                      minImageCount
-    VkFormat                                 imageFormat
-    VkColorSpaceKHR                          imageColorSpace
-    VkExtent2D                               imageExtent
-    VkImageUsageFlags                        imageUsageFlags
-    VkSurfaceTransformKHR                    preTransform
-    u32                                      imageArraySize
-    VkSharingMode                            sharingMode
-    u32                                      queueFamilyCount
-    const u32*                               pQueueFamilyIndices
-    VkPresentModeKHR                         presentMode
-    VkSwapchainKHR                           oldSwapchain
-    VkBool32                                 clipped
+    VkStructureType                             sType
+    const void*                                 pNext
+    VkSurfaceKHR                                surface
+    u32                                         minImageCount
+    VkFormat                                    imageFormat
+    VkColorSpaceKHR                             imageColorSpace
+    VkExtent2D                                  imageExtent
+    VkImageUsageFlags                           imageUsageFlags
+    VkSurfaceTransformKHR                       preTransform
+    u32                                         imageArraySize
+    VkSharingMode                               sharingMode
+    u32                                         queueFamilyCount
+    const u32*                                  pQueueFamilyIndices
+    VkPresentModeKHR                            presentMode
+    VkSwapchainKHR                              oldSwapchain
+    VkBool32                                    clipped
 }
 
-@extension("VK_EXT_KHR_device_swapchain")
+@extension("VK_EXT_KHR_swapchain")
 class VkPresentInfoKHR {
-    VkStructureType                          sType
-    const void*                              pNext
-    u32                                      swapchainCount
-    const VkSwapchainKHR*                    swapchains
-    const u32*                               imageIndices
+    VkStructureType                             sType
+    const void*                                 pNext
+    u32                                         swapchainCount
+    const VkSwapchainKHR*                       swapchains
+    const u32*                                  imageIndices
 }
 
-@extension("VK_EXT_KHR_swapchain")
-class VkSurfaceDescriptionKHR {
-    VkStructureType                          sType
-    const void*                              pNext
+@extension("VK_EXT_KHR_display")
+class VkDisplayPropertiesKHR {
+    VkDisplayKHR                                display
+    const char*                                 displayName
+    VkExtent2D                                  physicalDimensions
+    VkExtent2D                                  physicalResolution
+    VkSurfaceTransformFlagsKHR                  supportedTransforms
+    u32                                         planeCount
+    VkBool32                                    planeReorderPossible
 }
 
-@extension("VK_EXT_KHR_swapchain")
-class VkSurfaceDescriptionWindowKHR {
-    VkStructureType                         sType
-    const void*                             pNext
-    VkPlatformKHR                           platform
-    void*                                   pPlatformHandle
-    void*                                   pPlatformWindow
+@extension("VK_EXT_KHR_display")
+class VkDisplayTimingKHR {
+    u32                                         pixelClock
+    VkExtent2D                                  visibleRegion
+    VkExtent2D                                  totalRegion
+    VkExtent2D                                  physicalDimensions
+    u32                                         hSyncStart
+    u32                                         hSyncEnd
+    u32                                         vSyncStart
+    u32                                         vSyncEnd
+    VkBool32                                    interlaced
+    VkBool32                                    doublescan
+    VkBool32                                    hSyncPos
+    VkBool32                                    vSyncPos
 }
 
+@extension("VK_EXT_KHR_display")
+class VkDisplayModePropertiesKHR {
+    VkDisplayModeKHR                            displayMode
+    VkDisplayTimingKHR                          timing
+}
+
+@extension("VK_EXT_KHR_display")
+class VkDisplayModeCreateInfoKHR {
+    VkStructureType                             sType
+    const void*                                 pNext
+    VkDisplayTimingKHR                          timing
+}
+
+@extension("VK_EXT_KHR_display")
+class VkDisplayPlanePropertiesKHR {
+    VkDisplayPlaneAlphaFlagsKHR                 supportedAlpha
+    VkOffset2D                                  minSrcPosition
+    VkOffset2D                                  maxSrcPosition
+    VkExtent2D                                  minSrcExtent
+    VkExtent2D                                  maxSrcExtent
+    VkOffset2D                                  minDstPosition
+    VkOffset2D                                  maxDstPosition
+    VkExtent2D                                  minDstExtent
+    VkExtent2D                                  maxDstExtent
+}
+
+@extension("VK_EXT_KHR_display")
+class VkSurfaceDescriptionDisplayPlaneKHR {
+    VkStructureType                             sType
+    const void*                                 pNext
+    VkDisplayModeKHR                            displayMode
+    u32                                         planeIndex
+    u32                                         planeStackIndex
+    VkSurfaceTransformKHR                       transform
+    f32                                         globalAlpha
+    VkDisplayPlaneAlphaFlagsKHR                 alphaMode
+    VkExtent2D                                  imageSize
+}
+
+@extension("VK_EXT_KHR_display_swapchain")
+class VkDisplaySwapchainCreateInfoKHR {
+    VkStructureType                             sType
+    const void*                                 pNext
+    const VkSwapchainCreateInfoKHR*             pNextSwapchainCreateInfo
+}
+
+@extension("VK_EXT_KHR_display_swapchain")
+class VkDisplayPresentInfoKHR {
+    VkStructureType                             sType
+    const void*                                 pNext
+    VkRect2D                                    srcRect
+    VkRect2D                                    dstRect
+}
+
+
 ////////////////
 //  Commands  //
 ////////////////
@@ -4296,29 +4422,34 @@
     }
 }
 
-////////////////
-// Extensions //
-////////////////
+@extension("VK_EXT_KHR_surface")
+cmd void vkDestroySurfaceKHR(
+        VkInstance                                  instance,
+        VkSurfaceKHR                                surface) {
+    instanceObject := GetInstance(instance)
+    surfaceObject := GetSurface(surface)
+    assert(surfaceObject.instance == instance)
 
-@extension("VK_EXT_KHR_swapchain")
-cmd VkResult vkGetPhysicalDeviceSurfaceSupportKHR(
-        VkPhysicalDevice                        physicalDevice,
-        u32                                     queueFamilyIndex,
-        const VkSurfaceDescriptionKHR*          pSurfaceDescription,
-        VkBool32*                               pSupported) {
-    physicalDeviceObject := GetPhysicalDevice(physicalDevice)
-
-    supported := ?
-    pSupported[0] = supported
-
-    return ?
+    State.Surfaces[surface] = null
 }
 
-@extension("VK_EXT_KHR_device_swapchain")
+@extension("VK_EXT_KHR_surface")
+cmd VkBool32 vkGetPhysicalDeviceSurfaceSupportKHR(
+        VkPhysicalDevice                            physicalDevice,
+        u32                                         queueFamilyIndex,
+        VkSurfaceKHR                                surface) {
+    physicalDeviceObject := GetPhysicalDevice(physicalDevice)
+
+    //supported := ?
+
+    return ?//supported
+}
+
+@extension("VK_EXT_KHR_swapchain")
 cmd VkResult vkGetSurfacePropertiesKHR(
-        VkDevice                                 device,
-        const VkSurfaceDescriptionKHR*           pSurfaceDescription,
-        VkSurfacePropertiesKHR*                  pSurfaceProperties) {
+        VkDevice                                    device,
+        VkSurfaceKHR                                surface,
+        VkSurfacePropertiesKHR*                     pSurfaceProperties) {
     deviceObject := GetDevice(device)
 
     surfaceProperties := ?
@@ -4327,12 +4458,12 @@
     return ?
 }
 
-@extension("VK_EXT_KHR_device_swapchain")
+@extension("VK_EXT_KHR_swapchain")
 cmd VkResult vkGetSurfaceFormatsKHR(
-        VkDevice                                 device,
-        const VkSurfaceDescriptionKHR*           pSurfaceDescription,
-        u32*                                     pCount,
-        VkSurfaceFormatKHR*                      pSurfaceFormats) {
+        VkDevice                                    device,
+        VkSurfaceKHR                                surface,
+        u32*                                        pCount,
+        VkSurfaceFormatKHR*                         pSurfaceFormats) {
     deviceObject := GetDevice(device)
 
     count := as!u32(?)
@@ -4347,12 +4478,12 @@
     return ?
 }
 
-@extension("VK_EXT_KHR_device_swapchain")
+@extension("VK_EXT_KHR_swapchain")
 cmd VkResult vkGetSurfacePresentModesKHR(
-        VkDevice                                 device,
-        const VkSurfaceDescriptionKHR*           pSurfaceDescription,
-        u32*                                     pCount,
-        VkPresentModeKHR*                        pPresentModes) {
+        VkDevice                                    device,
+        VkSurfaceKHR                                surface,
+        u32*                                        pCount,
+        VkPresentModeKHR*                           pPresentModes) {
     deviceObject := GetDevice(device)
 
     count := as!u32(?)
@@ -4367,12 +4498,12 @@
     return ?
 }
 
-@extension("VK_EXT_KHR_device_swapchain")
+@extension("VK_EXT_KHR_swapchain")
 cmd VkResult vkCreateSwapchainKHR(
         VkDevice                                 device,
         const VkSwapchainCreateInfoKHR*          pCreateInfo,
         VkSwapchainKHR*                          pSwapchain) {
-    //assert(pCreateInfo.sType == VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR)
+    assert(pCreateInfo.sType == VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR)
     deviceObject := GetDevice(device)
 
     swapchain := ?
@@ -4382,8 +4513,8 @@
     return ?
 }
 
-@extension("VK_EXT_KHR_device_swapchain")
-cmd VkResult vkDestroySwapchainKHR(
+@extension("VK_EXT_KHR_swapchain")
+cmd void vkDestroySwapchainKHR(
         VkDevice                                 device,
         VkSwapchainKHR                           swapchain) {
     deviceObject := GetDevice(device)
@@ -4391,11 +4522,9 @@
     assert(swapchainObject.device == device)
 
     State.Swapchains[swapchain] = null
-
-    return ?
 }
 
-@extension("VK_EXT_KHR_device_swapchain")
+@extension("VK_EXT_KHR_swapchain")
 cmd VkResult vkGetSwapchainImagesKHR(
         VkDevice                                 device,
         VkSwapchainKHR                           swapchain,
@@ -4410,20 +4539,19 @@
     for i in (0 .. count) {
         swapchainImage := ?
         swapchainImages[i] = swapchainImage
-        if !(swapchainImage in State.Images) {
-            State.Images[swapchainImage] = new!ImageObject(device: device)
-        }
+        State.Images[swapchainImage] = new!ImageObject(device: device)
     }
 
     return ?
 }
 
-@extension("VK_EXT_KHR_device_swapchain")
+@extension("VK_EXT_KHR_swapchain")
 cmd VkResult vkAcquireNextImageKHR(
         VkDevice                                 device,
         VkSwapchainKHR                           swapchain,
         u64                                      timeout,
         VkSemaphore                              semaphore,
+        VkFence                                  fence,
         u32*                                     pImageIndex) {
     deviceObject := GetDevice(device)
     swapchainObject := GetSwapchain(swapchain)
@@ -4434,7 +4562,7 @@
     return ?
 }
 
-@extension("VK_EXT_KHR_device_swapchain")
+@extension("VK_EXT_KHR_swapchain")
 cmd VkResult vkQueuePresentKHR(
         VkQueue                                  queue,
         VkPresentInfoKHR*                        pPresentInfo) {
@@ -4446,6 +4574,107 @@
     return ?
 }
 
+@extension("VK_EXT_KHR_display")
+cmd VkResult vkGetPhysicalDeviceDisplayPropertiesKHR(
+        VkPhysicalDevice                        physicalDevice,
+        u32*                                    count,
+        VkDisplayPropertiesKHR*                 pProperties) {
+    physicalDeviceObject := GetPhysicalDevice(physicalDevice)
+    return ?
+}
+
+@extension("VK_EXT_KHR_display")
+cmd VkResult vkGetDisplayModePropertiesKHR(
+        VkPhysicalDevice                        physicalDevice,
+        VkDisplayKHR                            display,
+        u32*                                    pCount,
+        VkDisplayModePropertiesKHR*             pModeProperties) {
+    physicalDeviceObject := GetPhysicalDevice(physicalDevice)
+    return ?
+}
+
+@extension("VK_EXT_KHR_display")
+cmd VkResult vkCreateDisplayModeKHR(
+        VkPhysicalDevice                        physicalDevice,
+        VkDisplayKHR                            display,
+        const VkDisplayModeCreateInfoKHR*       pCreateInfo,
+        VkDisplayModeKHR*                       pMode) {
+    physicalDeviceObject := GetPhysicalDevice(physicalDevice)
+    return ?
+}
+
+@extension("VK_EXT_KHR_display")
+cmd VkResult vkGetDisplayPlanePropertiesKHR(
+        VkPhysicalDevice                        physicalDevice,
+        VkDisplayKHR                            display,
+        VkDisplayModeKHR                        mode,
+        u32                                     planeIndex,
+        VkDisplayPlanePropertiesKHR*            pProperties) {
+    physicalDeviceObject := GetPhysicalDevice(physicalDevice)
+    return ?
+}
+
+@extension("VK_EXT_KHR_x11_surface")
+cmd VkResult vkCreateX11SurfaceKHR(
+        VkInstance                              instance,
+        platform.Display*                       dpy,
+        platform.Window                         root,
+        platform.Window                         window,
+        VkSurfaceKHR*                           pSurface) {
+    instanceObject := GetInstance(instance)
+    return ?
+}
+
+@extension("VK_EXT_KHR_xcb_surface")
+cmd VkResult vkCreateXCBSurfaceKHR(
+        VkInstance                              instance,
+        platform.xcb_connection_t*              connection,
+        platform.xcb_window_t                   root,
+        platform.xcb_window_t                   window,
+        VkSurfaceKHR*                           pSurface) {
+    instanceObject := GetInstance(instance)
+    return ?
+}
+
+@extension("VK_EXT_KHR_wayland_surface")
+cmd VkResult vkCreateWaylandSurfaceKHR(
+        VkInstance                              instance,
+        platform.wl_display*                    display,
+        platform.wl_surface*                    surface,
+        VkSurfaceKHR*                           pSurface) {
+    instanceObject := GetInstance(instance)
+    return ?
+}
+
+@extension("VK_EXT_KHR_mir_surface")
+cmd VkResult vkCreateMirSurfaceKHR(
+        VkInstance                              instance,
+        platform.MirConnection*                 connection,
+        platform.MirSurface*                    mirSurface,
+        VkSurfaceKHR*                           pSurface) {
+    instanceObject := GetInstance(instance)
+    return ?
+}
+
+@extension("VK_EXT_KHR_android_surface")
+cmd VkResult vkCreateAndroidSurfaceKHR(
+        VkInstance                              instance,
+        platform.ANativeWindow*                 window
+        VkSurfaceKHR*                           pSurface) {
+    instanceObject := GetInstance(instance)
+    return ?
+}
+
+@extension("VK_EXT_KHR_win32_surface")
+cmd VkResult vkCreateWin32SurfaceKHR(
+        VkInstance                              instance,
+        platform.HINSTANCE                      hinstance,
+        platform.HWND                           hwnd,
+        VkSurfaceKHR*                           pSurface) {
+    instanceObject := GetInstance(instance)
+    return ?
+}
+
 
 ////////////////
 // Validation //
@@ -4490,6 +4719,7 @@
     map!(VkRenderPass,               ref!RenderPassObject)               RenderPasses
     map!(VkPipelineCache,            ref!PipelineCacheObject)            PipelineCaches
     map!(VkCmdPool,                  ref!CmdPoolObject)                  CmdPools
+    map!(VkSurfaceKHR,               ref!SurfaceObject)                  Surfaces
     map!(VkSwapchainKHR,             ref!SwapchainObject)                Swapchains
 }
 
@@ -4609,6 +4839,10 @@
     VkDevice      device
 }
 
+@internal class SurfaceObject {
+    VkInstance    instance
+}
+
 @internal class SwapchainObject {
     VkDevice      device
 }
@@ -4743,6 +4977,11 @@
     return State.CmdPools[cmdPool]
 }
 
+macro ref!SurfaceObject GetSurface(VkSurfaceKHR surface) {
+    assert(surface in State.Surfaces)
+    return State.Surfaces[surface]
+}
+
 macro ref!SwapchainObject GetSwapchain(VkSwapchainKHR swapchain) {
     assert(swapchain in State.Swapchains)
     return State.Swapchains[swapchain]
diff --git a/vulkan/include/vulkan/vk_ext_khr_device_swapchain.h b/vulkan/include/vulkan/vk_ext_khr_device_swapchain.h
deleted file mode 100644
index 3bf73c8..0000000
--- a/vulkan/include/vulkan/vk_ext_khr_device_swapchain.h
+++ /dev/null
@@ -1,210 +0,0 @@
-//
-// File: vk_ext_khr_device_swapchain.h
-//
-/*
-** 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.
-*/
-
-#ifndef __VK_EXT_KHR_DEVICE_SWAPCHAIN_H__
-#define __VK_EXT_KHR_DEVICE_SWAPCHAIN_H__
-
-#include "vulkan.h"
-
-#define VK_EXT_KHR_DEVICE_SWAPCHAIN_REVISION         53
-#define VK_EXT_KHR_DEVICE_SWAPCHAIN_EXTENSION_NUMBER 2
-#define VK_EXT_KHR_DEVICE_SWAPCHAIN_EXTENSION_NAME   "VK_EXT_KHR_device_swapchain"
-
-#ifdef __cplusplus
-extern "C"
-{
-#endif // __cplusplus
-
-// ------------------------------------------------------------------------------------------------
-// Objects
-
-VK_DEFINE_NONDISP_HANDLE(VkSwapchainKHR);
-
-// ------------------------------------------------------------------------------------------------
-// Enumeration constants
-
-#define VK_EXT_KHR_DEVICE_SWAPCHAIN_ENUM(type,id)    ((type)((int)0xc0000000 - VK_EXT_KHR_DEVICE_SWAPCHAIN_EXTENSION_NUMBER * -1024 + (id)))
-#define VK_EXT_KHR_DEVICE_SWAPCHAIN_ENUM_POSITIVE(type,id)    ((type)((int)0x40000000 + (VK_EXT_KHR_DEVICE_SWAPCHAIN_EXTENSION_NUMBER - 1) * 1024 + (id)))
-
-// Extend VkStructureType enum with extension specific constants
-#define VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR VK_EXT_KHR_DEVICE_SWAPCHAIN_ENUM(VkStructureType, 0)
-#define VK_STRUCTURE_TYPE_PRESENT_INFO_KHR VK_EXT_KHR_DEVICE_SWAPCHAIN_ENUM(VkStructureType, 1)
-
-// Extend VkImageLayout enum with extension specific constants
-#define VK_IMAGE_LAYOUT_PRESENT_SOURCE_KHR VK_EXT_KHR_DEVICE_SWAPCHAIN_ENUM(VkImageLayout, 2)
-
-// Extend VkResult enum with extension specific constants
-//  Return codes for successful operation execution
-#define VK_SUBOPTIMAL_KHR           VK_EXT_KHR_DEVICE_SWAPCHAIN_ENUM_POSITIVE(VkResult, 3)
-//  Error codes
-#define VK_ERROR_OUT_OF_DATE_KHR    VK_EXT_KHR_DEVICE_SWAPCHAIN_ENUM(VkResult, 4)
-
-// ------------------------------------------------------------------------------------------------
-// Enumerations
-
-typedef enum {
-    VK_PRESENT_MODE_IMMEDIATE_KHR = 0,
-    VK_PRESENT_MODE_MAILBOX_KHR = 1,
-    VK_PRESENT_MODE_FIFO_KHR = 2,
-    VK_PRESENT_MODE_BEGIN_RANGE_KHR = VK_PRESENT_MODE_IMMEDIATE_KHR,
-    VK_PRESENT_MODE_END_RANGE_KHR = VK_PRESENT_MODE_FIFO_KHR,
-    VK_PRESENT_MODE_NUM = (VK_PRESENT_MODE_FIFO_KHR - VK_PRESENT_MODE_IMMEDIATE_KHR + 1),
-    VK_PRESENT_MODE_MAX_ENUM_KHR = 0x7FFFFFFF
-} VkPresentModeKHR;
-
-typedef enum {
-    VK_COLORSPACE_SRGB_NONLINEAR_KHR = 0x00000000,
-    VK_COLORSPACE_NUM = (VK_COLORSPACE_SRGB_NONLINEAR_KHR - VK_COLORSPACE_SRGB_NONLINEAR_KHR + 1),
-    VK_COLORSPACE_MAX_ENUM_KHR = 0x7FFFFFFF
-} VkColorSpaceKHR;
-
-// ------------------------------------------------------------------------------------------------
-// Flags
-
-// ------------------------------------------------------------------------------------------------
-// Structures
-
-typedef struct {
-    uint32_t                                minImageCount;      // Supported minimum number of images for the surface
-    uint32_t                                maxImageCount;      // Supported maximum number of images for the surface, 0 for unlimited
-
-    VkExtent2D                              currentExtent;      // Current image width and height for the surface, (-1, -1) if undefined
-    VkExtent2D                              minImageExtent;     // Supported minimum image width and height for the surface
-    VkExtent2D                              maxImageExtent;     // Supported maximum image width and height for the surface
-
-    VkSurfaceTransformFlagsKHR              supportedTransforms;// 1 or more bits representing the transforms supported
-    VkSurfaceTransformKHR                   currentTransform;   // The surface's current transform relative to the device's natural orientation
-
-    uint32_t                                maxImageArraySize;  // Supported maximum number of image layers for the surface
-
-    VkImageUsageFlags                       supportedUsageFlags;// Supported image usage flags for the surface
-} VkSurfacePropertiesKHR;
-
-typedef struct {
-    VkFormat                                format;             // Supported pair of rendering format
-    VkColorSpaceKHR                         colorSpace;         // and colorspace for the surface
-} VkSurfaceFormatKHR;
-
-typedef struct {
-    VkStructureType                          sType;             // Must be VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR
-    const void*                              pNext;             // Pointer to next structure
-
-    const VkSurfaceDescriptionKHR*           pSurfaceDescription;// describes the swap chain's target surface
-
-    uint32_t                                 minImageCount;     // Minimum number of presentation images the application needs
-    VkFormat                                 imageFormat;       // Format of the presentation images
-    VkColorSpaceKHR                          imageColorSpace;   // Colorspace of the presentation images
-    VkExtent2D                               imageExtent;       // Dimensions of the presentation images
-    VkImageUsageFlags                        imageUsageFlags;   // Bits indicating how the presentation images will be used
-    VkSurfaceTransformKHR                    preTransform;      // The transform, relative to the device's natural orientation, applied to the image content prior to presentation
-    uint32_t                                 imageArraySize;    // Determines the number of views for multiview/stereo presentation
-
-    VkSharingMode                            sharingMode;       // Sharing mode used for the presentation images
-    uint32_t                                 queueFamilyCount;  // Number of queue families having access to the images in case of concurrent sharing mode
-    const uint32_t*                          pQueueFamilyIndices; // Array of queue family indices having access to the images in case of concurrent sharing mode
-
-    VkPresentModeKHR                         presentMode;       // Which presentation mode to use for presents on this swap chain
-
-    VkSwapchainKHR                           oldSwapchain;      // Existing swap chain to replace, if any
-
-    VkBool32                                 clipped;           // Specifies whether presentable images may be affected by window clip regions
-} VkSwapchainCreateInfoKHR;
-
-typedef struct {
-    VkStructureType                          sType;             // Must be VK_STRUCTURE_TYPE_PRESENT_INFO_KHR
-    const void*                              pNext;             // Pointer to next structure
-    uint32_t                                 swapchainCount;    // Number of swap chains to present in this call
-    const VkSwapchainKHR*                    swapchains;        // Swap chains to present an image from
-    const uint32_t*                          imageIndices;      // Indices of which swapchain images to present
-} VkPresentInfoKHR;
-
-// ------------------------------------------------------------------------------------------------
-// Function types
-
-typedef VkResult (VKAPI *PFN_vkGetSurfacePropertiesKHR)(VkDevice device, const VkSurfaceDescriptionKHR* pSurfaceDescription, VkSurfacePropertiesKHR* pSurfaceProperties);
-typedef VkResult (VKAPI *PFN_vkGetSurfaceFormatsKHR)(VkDevice device, const VkSurfaceDescriptionKHR* pSurfaceDescription, uint32_t* pCount, VkSurfaceFormatKHR* pSurfaceFormats);
-typedef VkResult (VKAPI *PFN_vkGetSurfacePresentModesKHR)(VkDevice device, const VkSurfaceDescriptionKHR* pSurfaceDescription, uint32_t* pCount, VkPresentModeKHR* pPresentModes);
-typedef VkResult (VKAPI *PFN_vkCreateSwapchainKHR)(VkDevice device, const VkSwapchainCreateInfoKHR* pCreateInfo, VkSwapchainKHR* pSwapchain);
-typedef VkResult (VKAPI *PFN_vkDestroySwapchainKHR)(VkDevice device, VkSwapchainKHR swapchain);
-typedef VkResult (VKAPI *PFN_vkGetSwapchainImagesKHR)(VkDevice device, VkSwapchainKHR swapchain, uint32_t* pCount, VkImage* pSwapchainImages);
-typedef VkResult (VKAPI *PFN_vkAcquireNextImageKHR)(VkDevice device, VkSwapchainKHR swapchain, uint64_t timeout, VkSemaphore semaphore, uint32_t* pImageIndex);
-typedef VkResult (VKAPI *PFN_vkQueuePresentKHR)(VkQueue queue, VkPresentInfoKHR* pPresentInfo);
-
-// ------------------------------------------------------------------------------------------------
-// Function prototypes
-
-#ifdef VK_PROTOTYPES
-
-VkResult VKAPI vkGetSurfacePropertiesKHR(
-    VkDevice                                 device,
-    const VkSurfaceDescriptionKHR*           pSurfaceDescription,
-    VkSurfacePropertiesKHR*                  pSurfaceProperties);
-
-VkResult VKAPI vkGetSurfaceFormatsKHR(
-    VkDevice                                 device,
-    const VkSurfaceDescriptionKHR*           pSurfaceDescription,
-    uint32_t*                                pCount,
-    VkSurfaceFormatKHR*                      pSurfaceFormats);
-
-VkResult VKAPI vkGetSurfacePresentModesKHR(
-    VkDevice                                 device,
-    const VkSurfaceDescriptionKHR*           pSurfaceDescription,
-    uint32_t*                                pCount,
-    VkPresentModeKHR*                        pPresentModes);
-
-VkResult VKAPI vkCreateSwapchainKHR(
-    VkDevice                                 device,
-    const VkSwapchainCreateInfoKHR*          pCreateInfo,
-    VkSwapchainKHR*                          pSwapchain);
-
-VkResult VKAPI vkDestroySwapchainKHR(
-    VkDevice                                 device,
-    VkSwapchainKHR                           swapchain);
-
-VkResult VKAPI vkGetSwapchainImagesKHR(
-    VkDevice                                 device,
-    VkSwapchainKHR                           swapchain,
-    uint32_t*                                pCount,
-    VkImage*                                 pSwapchainImages);
-
-VkResult VKAPI vkAcquireNextImageKHR(
-    VkDevice                                 device,
-    VkSwapchainKHR                           swapchain,
-    uint64_t                                 timeout,
-    VkSemaphore                              semaphore,
-    uint32_t*                                pImageIndex);
-
-VkResult VKAPI vkQueuePresentKHR(
-    VkQueue                                  queue,
-    VkPresentInfoKHR*                        pPresentInfo);
-
-#endif // VK_PROTOTYPES
-
-#ifdef __cplusplus
-} // extern "C"
-#endif // __cplusplus
-
-#endif // __VK_EXT_KHR_SWAPCHAIN_H__
diff --git a/vulkan/include/vulkan/vk_ext_khr_swapchain.h b/vulkan/include/vulkan/vk_ext_khr_swapchain.h
deleted file mode 100644
index 862b4d5..0000000
--- a/vulkan/include/vulkan/vk_ext_khr_swapchain.h
+++ /dev/null
@@ -1,153 +0,0 @@
-//
-// File: vk_ext_khr_swapchain.h
-//
-/*
-** 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.
-*/
-
-#ifndef __VK_EXT_KHR_SWAPCHAIN_H__
-#define __VK_EXT_KHR_SWAPCHAIN_H__
-
-#include "vulkan.h"
-
-#define VK_EXT_KHR_SWAPCHAIN_REVISION         17
-#define VK_EXT_KHR_SWAPCHAIN_EXTENSION_NUMBER 1
-#define VK_EXT_KHR_SWAPCHAIN_EXTENSION_NAME   "VK_EXT_KHR_swapchain"
-
-#ifdef __cplusplus
-extern "C"
-{
-#endif // __cplusplus
-
-// ------------------------------------------------------------------------------------------------
-// Objects
-
-// ------------------------------------------------------------------------------------------------
-// Enumeration constants
-
-#define VK_EXT_KHR_SWAPCHAIN_ENUM(type,id)    ((type)((int)0xc0000000 - VK_EXT_KHR_SWAPCHAIN_EXTENSION_NUMBER * -1024 + (id)))
-#define VK_EXT_KHR_SWAPCHAIN_ENUM_POSITIVE(type,id)    ((type)((int)0x40000000 + (VK_EXT_KHR_SWAPCHAIN_EXTENSION_NUMBER - 1) * 1024 + (id)))
-
-// Extend VkStructureType enum with extension specific constants
-#define VK_STRUCTURE_TYPE_SURFACE_DESCRIPTION_WINDOW_KHR            VK_EXT_KHR_SWAPCHAIN_ENUM(VkStructureType, 0)
-
-// ------------------------------------------------------------------------------------------------
-// Enumerations
-
-typedef enum {
-    VK_SURFACE_TRANSFORM_NONE_KHR = 0,
-    VK_SURFACE_TRANSFORM_ROT90_KHR = 1,
-    VK_SURFACE_TRANSFORM_ROT180_KHR = 2,
-    VK_SURFACE_TRANSFORM_ROT270_KHR = 3,
-    VK_SURFACE_TRANSFORM_HMIRROR_KHR = 4,
-    VK_SURFACE_TRANSFORM_HMIRROR_ROT90_KHR = 5,
-    VK_SURFACE_TRANSFORM_HMIRROR_ROT180_KHR = 6,
-    VK_SURFACE_TRANSFORM_HMIRROR_ROT270_KHR = 7,
-    VK_SURFACE_TRANSFORM_INHERIT_KHR = 8,
-} VkSurfaceTransformKHR;
-
-typedef enum {
-    VK_SURFACE_TRANSFORM_NONE_BIT_KHR = 0x00000001,
-    VK_SURFACE_TRANSFORM_ROT90_BIT_KHR = 0x00000002,
-    VK_SURFACE_TRANSFORM_ROT180_BIT_KHR = 0x00000004,
-    VK_SURFACE_TRANSFORM_ROT270_BIT_KHR = 0x00000008,
-    VK_SURFACE_TRANSFORM_HMIRROR_BIT_KHR = 0x00000010,
-    VK_SURFACE_TRANSFORM_HMIRROR_ROT90_BIT_KHR = 0x00000020,
-    VK_SURFACE_TRANSFORM_HMIRROR_ROT180_BIT_KHR = 0x00000040,
-    VK_SURFACE_TRANSFORM_HMIRROR_ROT270_BIT_KHR = 0x00000080,
-    VK_SURFACE_TRANSFORM_INHERIT_BIT_KHR = 0x00000100,
-} VkSurfaceTransformFlagBitsKHR;
-typedef VkFlags VkSurfaceTransformFlagsKHR;
-
-typedef enum {
-    VK_PLATFORM_WIN32_KHR = 0,
-    VK_PLATFORM_X11_KHR = 1,
-    VK_PLATFORM_XCB_KHR = 2,
-    VK_PLATFORM_ANDROID_KHR = 3,
-    VK_PLATFORM_WAYLAND_KHR = 4,
-    VK_PLATFORM_MIR_KHR = 5,
-    VK_PLATFORM_BEGIN_RANGE_KHR = VK_PLATFORM_WIN32_KHR,
-    VK_PLATFORM_END_RANGE_KHR = VK_PLATFORM_MIR_KHR,
-    VK_PLATFORM_NUM_KHR = (VK_PLATFORM_MIR_KHR - VK_PLATFORM_WIN32_KHR + 1),
-    VK_PLATFORM_MAX_ENUM_KHR = 0x7FFFFFFF
-} VkPlatformKHR;
-
-// ------------------------------------------------------------------------------------------------
-// Flags
-
-// ------------------------------------------------------------------------------------------------
-// Structures
-
-// Placeholder structure header for the different types of surface description structures
-typedef struct {
-    VkStructureType                          sType;             // Can be any of the VK_STRUCTURE_TYPE_SURFACE_DESCRIPTION_XXX_KHR constants
-    const void*                              pNext;             // Pointer to next structure
-} VkSurfaceDescriptionKHR;
-
-// Surface description structure for a native platform window surface
-typedef struct {
-    VkStructureType                         sType;              // Must be VK_STRUCTURE_TYPE_SURFACE_DESCRIPTION_WINDOW_KHR
-    const void*                             pNext;              // Pointer to next structure
-    VkPlatformKHR                           platform;           // e.g. VK_PLATFORM_*_KHR
-    void*                                   pPlatformHandle;
-    void*                                   pPlatformWindow;
-} VkSurfaceDescriptionWindowKHR;
-
-// pPlatformHandle points to this struct when platform is VK_PLATFORM_X11_KHR
-#ifdef _X11_XLIB_H_
-typedef struct {
-    Display*                                 dpy;               // Display connection to an X server
-    Window                                   root;              // To identify the X screen
-} VkPlatformHandleX11KHR;
-#endif /* _X11_XLIB_H_ */
-
-// pPlatformHandle points to this struct when platform is VK_PLATFORM_XCB_KHR
-#ifdef __XCB_H__
-typedef struct {
-    xcb_connection_t*                        connection;        // XCB connection to an X server
-    xcb_window_t                             root;              // To identify the X screen
-} VkPlatformHandleXcbKHR;
-#endif /* __XCB_H__ */
-
-// ------------------------------------------------------------------------------------------------
-// Function types
-
-typedef VkResult (VKAPI *PFN_vkGetPhysicalDeviceSurfaceSupportKHR)(VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex, const VkSurfaceDescriptionKHR* pSurfaceDescription, VkBool32* pSupported);
-
-// ------------------------------------------------------------------------------------------------
-// Function prototypes
-
-#ifdef VK_PROTOTYPES
-
-VkResult VKAPI vkGetPhysicalDeviceSurfaceSupportKHR(
-    VkPhysicalDevice                        physicalDevice,
-    uint32_t                                queueFamilyIndex,
-    const VkSurfaceDescriptionKHR*          pSurfaceDescription,
-    VkBool32*                               pSupported);
-
-#endif // VK_PROTOTYPES
-
-#ifdef __cplusplus
-} // extern "C"
-#endif // __cplusplus
-
-#endif // __VK_EXT_KHR_SWAPCHAIN_H__
diff --git a/vulkan/include/vulkan/vk_platform.h b/vulkan/include/vulkan/vk_platform.h
index 969e532..14dc553 100644
--- a/vulkan/include/vulkan/vk_platform.h
+++ b/vulkan/include/vulkan/vk_platform.h
@@ -71,4 +71,32 @@
 } // extern "C"
 #endif // __cplusplus
 
+// Platform-specific headers required by platform window system extensions.
+// These are enabled prior to #including "vulkan.h". The same enable then
+// controls inclusion of the extension interfaces in vulkan.h.
+
+#ifdef VK_USE_PLATFORM_ANDROID_KHR
+#include <android/native_window.h>
+#endif
+
+#ifdef VK_USE_PLATFORM_MIR_KHR
+#include <mir_toolkit/client_types.h>
+#endif
+
+#ifdef VK_USE_PLATFORM_WAYLAND_KHR
+#include <wayland-client.h>
+#endif
+
+#ifdef VK_USE_PLATFORM_WIN32_KHR
+#include <windows.h>
+#endif
+
+#ifdef VK_USE_PLATFORM_X11_KHR
+#include <X11/Xlib.h>
+#endif
+
+#ifdef VK_USE_PLATFORM_XCB_KHR
+#include <xcb/xcb.h>
+#endif
+
 #endif // __VK_PLATFORM_H__
diff --git a/vulkan/include/vulkan/vulkan.h b/vulkan/include/vulkan/vulkan.h
index d6eb918..ee921bf 100644
--- a/vulkan/include/vulkan/vulkan.h
+++ b/vulkan/include/vulkan/vulkan.h
@@ -3002,6 +3002,438 @@
     const VkCmdBuffer*                          pCmdBuffers);
 #endif
 
+#define vk_ext_khr_surface 1
+VK_DEFINE_NONDISP_HANDLE(VkSurfaceKHR)
+
+#define VK_EXT_KHR_SURFACE_REVISION       19
+#define VK_EXT_KHR_SURFACE_EXTENSION_NUMBER 1
+#define VK_EXT_KHR_SURFACE_EXTENSION_NAME "VK_EXT_KHR_surface"
+
+typedef void (VKAPI *PFN_vkDestroySurfaceKHR)(VkInstance  instance, VkSurfaceKHR  surface);
+typedef VkBool32 (VKAPI *PFN_vkGetPhysicalDeviceSurfaceSupportKHR)(VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex, VkSurfaceKHR surface);
+
+#ifdef VK_PROTOTYPES
+void VKAPI vkDestroySurfaceKHR(
+    VkInstance                                   instance,
+    VkSurfaceKHR                                 surface);
+
+VkBool32 VKAPI vkGetPhysicalDeviceSurfaceSupportKHR(
+    VkPhysicalDevice                            physicalDevice,
+    uint32_t                                    queueFamilyIndex,
+    VkSurfaceKHR                                surface);
+#endif
+
+#define vk_ext_khr_swapchain 1
+VK_DEFINE_NONDISP_HANDLE(VkSwapchainKHR)
+
+#define VK_EXT_KHR_SWAPCHAIN_REVISION     59
+#define VK_EXT_KHR_SWAPCHAIN_EXTENSION_NUMBER 2
+#define VK_EXT_KHR_SWAPCHAIN_EXTENSION_NAME "VK_EXT_KHR_swapchain"
+#define VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR ((VkStructureType)(int)0xc0000800)
+#define VK_STRUCTURE_TYPE_PRESENT_INFO_KHR ((VkStructureType)(int)0xc0000801)
+#define VK_IMAGE_LAYOUT_PRESENT_SOURCE_KHR ((VkImageLayout)(int)0xc0000802)
+#define VK_SUBOPTIMAL_KHR                 ((VkResult)(int)0x40000403)
+#define VK_ERROR_OUT_OF_DATE_KHR          ((VkResult)(int)0xc0000804)
+
+
+typedef enum {
+    VK_SURFACE_TRANSFORM_NONE_KHR = 0,
+    VK_SURFACE_TRANSFORM_ROT90_KHR = 1,
+    VK_SURFACE_TRANSFORM_ROT180_KHR = 2,
+    VK_SURFACE_TRANSFORM_ROT270_KHR = 3,
+    VK_SURFACE_TRANSFORM_HMIRROR_KHR = 4,
+    VK_SURFACE_TRANSFORM_HMIRROR_ROT90_KHR = 5,
+    VK_SURFACE_TRANSFORM_HMIRROR_ROT180_KHR = 6,
+    VK_SURFACE_TRANSFORM_HMIRROR_ROT270_KHR = 7,
+    VK_SURFACE_TRANSFORM_INHERIT_KHR = 8,
+    VK_SURFACE_TRANSFORM_BEGIN_RANGE = VK_SURFACE_TRANSFORM_NONE_KHR,
+    VK_SURFACE_TRANSFORM_END_RANGE = VK_SURFACE_TRANSFORM_INHERIT_KHR,
+    VK_SURFACE_TRANSFORM_NUM = (VK_SURFACE_TRANSFORM_INHERIT_KHR - VK_SURFACE_TRANSFORM_NONE_KHR + 1),
+    VK_SURFACE_TRANSFORM_MAX_ENUM = 0x7FFFFFFF
+} VkSurfaceTransformKHR;
+
+typedef enum {
+    VK_COLORSPACE_SRGB_NONLINEAR_KHR = 0,
+    VK_COLORSPACE_BEGIN_RANGE = VK_COLORSPACE_SRGB_NONLINEAR_KHR,
+    VK_COLORSPACE_END_RANGE = VK_COLORSPACE_SRGB_NONLINEAR_KHR,
+    VK_COLORSPACE_NUM = (VK_COLORSPACE_SRGB_NONLINEAR_KHR - VK_COLORSPACE_SRGB_NONLINEAR_KHR + 1),
+    VK_COLORSPACE_MAX_ENUM = 0x7FFFFFFF
+} VkColorSpaceKHR;
+
+typedef enum {
+    VK_PRESENT_MODE_IMMEDIATE_KHR = 0,
+    VK_PRESENT_MODE_MAILBOX_KHR = 1,
+    VK_PRESENT_MODE_FIFO_KHR = 2,
+    VK_PRESENT_MODE_BEGIN_RANGE = VK_PRESENT_MODE_IMMEDIATE_KHR,
+    VK_PRESENT_MODE_END_RANGE = VK_PRESENT_MODE_FIFO_KHR,
+    VK_PRESENT_MODE_NUM = (VK_PRESENT_MODE_FIFO_KHR - VK_PRESENT_MODE_IMMEDIATE_KHR + 1),
+    VK_PRESENT_MODE_MAX_ENUM = 0x7FFFFFFF
+} VkPresentModeKHR;
+
+
+typedef enum {
+    VK_SURFACE_TRANSFORM_NONE_BIT_KHR = 0x00000001,
+    VK_SURFACE_TRANSFORM_ROT90_BIT_KHR = 0x00000002,
+    VK_SURFACE_TRANSFORM_ROT180_BIT_KHR = 0x00000004,
+    VK_SURFACE_TRANSFORM_ROT270_BIT_KHR = 0x00000008,
+    VK_SURFACE_TRANSFORM_HMIRROR_BIT_KHR = 0x00000010,
+    VK_SURFACE_TRANSFORM_HMIRROR_ROT90_BIT_KHR = 0x00000020,
+    VK_SURFACE_TRANSFORM_HMIRROR_ROT180_BIT_KHR = 0x00000040,
+    VK_SURFACE_TRANSFORM_HMIRROR_ROT270_BIT_KHR = 0x00000080,
+    VK_SURFACE_TRANSFORM_INHERIT_BIT_KHR = 0x00000100,
+} VkSurfaceTransformFlagBitsKHR;
+typedef VkFlags VkSurfaceTransformFlagsKHR;
+
+typedef struct {
+    uint32_t                                    minImageCount;
+    uint32_t                                    maxImageCount;
+    VkExtent2D                                  currentExtent;
+    VkExtent2D                                  minImageExtent;
+    VkExtent2D                                  maxImageExtent;
+    VkSurfaceTransformFlagsKHR                  supportedTransforms;
+    VkSurfaceTransformKHR                       currentTransform;
+    uint32_t                                    maxImageArraySize;
+    VkImageUsageFlags                           supportedUsageFlags;
+} VkSurfacePropertiesKHR;
+
+typedef struct {
+    VkFormat                                    format;
+    VkColorSpaceKHR                             colorSpace;
+} VkSurfaceFormatKHR;
+
+typedef struct {
+    VkStructureType                             sType;
+    const void*                                   pNext;
+    VkSurfaceKHR                                surface;
+    uint32_t                                    minImageCount;
+    VkFormat                                    imageFormat;
+    VkColorSpaceKHR                             imageColorSpace;
+    VkExtent2D                                  imageExtent;
+    VkImageUsageFlags                           imageUsageFlags;
+    VkSurfaceTransformKHR                       preTransform;
+    uint32_t                                    imageArraySize;
+    VkSharingMode                               sharingMode;
+    uint32_t                                    queueFamilyCount;
+    const uint32_t*                             pQueueFamilyIndices;
+    VkPresentModeKHR                            presentMode;
+    VkSwapchainKHR                              oldSwapchain;
+    VkBool32                                    clipped;
+} VkSwapchainCreateInfoKHR;
+
+typedef struct {
+    VkStructureType                             sType;
+    const void*                                   pNext;
+    uint32_t                                    swapchainCount;
+    const VkSwapchainKHR*                       swapchains;
+    const uint32_t*                             imageIndices;
+} VkPresentInfoKHR;
+
+
+typedef VkResult (VKAPI *PFN_vkGetSurfacePropertiesKHR)(VkDevice  device, VkSurfaceKHR  surface, VkSurfacePropertiesKHR*  pSurfaceProperties);
+typedef VkResult (VKAPI *PFN_vkGetSurfaceFormatsKHR)(VkDevice  device, VkSurfaceKHR  surface, uint32_t*  pCount, VkSurfaceFormatKHR*  pSurfaceFormats);
+typedef VkResult (VKAPI *PFN_vkGetSurfacePresentModesKHR)(VkDevice  device, VkSurfaceKHR  surface, uint32_t*  pCount, VkPresentModeKHR*  pPresentModes);
+typedef VkResult (VKAPI *PFN_vkCreateSwapchainKHR)(VkDevice  device, const VkSwapchainCreateInfoKHR*  pCreateInfo, VkSwapchainKHR*  pSwapchain);
+typedef void (VKAPI *PFN_vkDestroySwapchainKHR)(VkDevice  device, VkSwapchainKHR  swapchain);
+typedef VkResult (VKAPI *PFN_vkGetSwapchainImagesKHR)(VkDevice  device, VkSwapchainKHR  swapchain, uint32_t*  pCount, VkImage*  pSwapchainImages);
+typedef VkResult (VKAPI *PFN_vkAcquireNextImageKHR)(VkDevice  device, VkSwapchainKHR  swapchain, uint64_t  timeout, VkSemaphore  semaphore, VkFence  fence, uint32_t*  pImageIndex);
+typedef VkResult (VKAPI *PFN_vkQueuePresentKHR)(VkQueue  queue, VkPresentInfoKHR*  pPresentInfo);
+
+#ifdef VK_PROTOTYPES
+VkResult VKAPI vkGetSurfacePropertiesKHR(
+    VkDevice                                     device,
+    VkSurfaceKHR                                 surface,
+    VkSurfacePropertiesKHR*                      pSurfaceProperties);
+
+VkResult VKAPI vkGetSurfaceFormatsKHR(
+    VkDevice                                     device,
+    VkSurfaceKHR                                 surface,
+    uint32_t*                                    pCount,
+    VkSurfaceFormatKHR*                          pSurfaceFormats);
+
+VkResult VKAPI vkGetSurfacePresentModesKHR(
+    VkDevice                                     device,
+    VkSurfaceKHR                                 surface,
+    uint32_t*                                    pCount,
+    VkPresentModeKHR*                            pPresentModes);
+
+VkResult VKAPI vkCreateSwapchainKHR(
+    VkDevice                                     device,
+    const VkSwapchainCreateInfoKHR*              pCreateInfo,
+    VkSwapchainKHR*                              pSwapchain);
+
+void VKAPI vkDestroySwapchainKHR(
+    VkDevice                                     device,
+    VkSwapchainKHR                               swapchain);
+
+VkResult VKAPI vkGetSwapchainImagesKHR(
+    VkDevice                                     device,
+    VkSwapchainKHR                               swapchain,
+    uint32_t*                                    pCount,
+    VkImage*                                     pSwapchainImages);
+
+VkResult VKAPI vkAcquireNextImageKHR(
+    VkDevice                                     device,
+    VkSwapchainKHR                               swapchain,
+    uint64_t                                     timeout,
+    VkSemaphore                                  semaphore,
+    VkFence                                      fence,
+    uint32_t*                                    pImageIndex);
+
+VkResult VKAPI vkQueuePresentKHR(
+    VkQueue                                      queue,
+    VkPresentInfoKHR*                            pPresentInfo);
+#endif
+
+#define vk_ext_khr_display 1
+VK_DEFINE_NONDISP_HANDLE(VkDisplayKHR)
+VK_DEFINE_NONDISP_HANDLE(VkDisplayModeKHR)
+
+#define VK_EXT_KHR_DISPLAY_REVISION       16
+#define VK_EXT_KHR_DISPLAY_EXTENSION_NUMBER 3
+#define VK_EXT_KHR_DISPLAY_EXTENSION_NAME "VK_EXT_KHR_display"
+#define VK_STRUCTURE_TYPE_DISPLAY_MODE_CREATE_INFO_KHR ((VkStructureType)(int)0xc0000c00)
+#define VK_STRUCTURE_TYPE_SURFACE_DESCRIPTION_DISPLAY_PLANE_KHR ((VkStructureType)(int)0xc0000c01)
+
+
+typedef enum {
+    VK_DISPLAY_PLANE_ALPHA_GLOBAL_BIT_KHR = 0x00000001,
+    VK_DISPLAY_PLANE_ALPHA_PER_PIXEL_BIT_KHR = 0x00000002,
+    VK_DISPLAY_PLANE_ALPHA_PER_PIXEL_PREMULTIPLIED_BIT_KHR = 0x00000004,
+} VkDisplayPlaneAlphaFlagBitsKHR;
+typedef VkFlags VkDisplayPlaneAlphaFlagsKHR;
+
+typedef struct {
+    VkDisplayKHR                                display;
+    const char*                                   displayName;
+    VkExtent2D                                  physicalDimensions;
+    VkExtent2D                                  physicalResolution;
+    VkSurfaceTransformFlagsKHR                  supportedTransforms;
+    uint32_t                                    planeCount;
+    VkBool32                                    planeReorderPossible;
+} VkDisplayPropertiesKHR;
+
+typedef struct {
+    uint32_t                                    pixelClock;
+    VkExtent2D                                  visibleRegion;
+    VkExtent2D                                  totalRegion;
+    VkExtent2D                                  physicalDimensions;
+    uint32_t                                    hSyncStart;
+    uint32_t                                    hSyncEnd;
+    uint32_t                                    vSyncStart;
+    uint32_t                                    vSyncEnd;
+    VkBool32                                    interlaced;
+    VkBool32                                    doublescan;
+    VkBool32                                    hSyncPos;
+    VkBool32                                    vSyncPos;
+} VkDisplayTimingKHR;
+
+typedef struct {
+    VkDisplayModeKHR                            displayMode;
+    VkDisplayTimingKHR                          timing;
+} VkDisplayModePropertiesKHR;
+
+typedef struct {
+    VkStructureType                             sType;
+    const void*                                   pNext;
+    VkDisplayTimingKHR                          timing;
+} VkDisplayModeCreateInfoKHR;
+
+typedef struct {
+    VkDisplayPlaneAlphaFlagsKHR                 supportedAlpha;
+    VkOffset2D                                  minSrcPosition;
+    VkOffset2D                                  maxSrcPosition;
+    VkExtent2D                                  minSrcExtent;
+    VkExtent2D                                  maxSrcExtent;
+    VkOffset2D                                  minDstPosition;
+    VkOffset2D                                  maxDstPosition;
+    VkExtent2D                                  minDstExtent;
+    VkExtent2D                                  maxDstExtent;
+} VkDisplayPlanePropertiesKHR;
+
+typedef struct {
+    VkStructureType                             sType;
+    const void*                                   pNext;
+    VkDisplayModeKHR                            displayMode;
+    uint32_t                                    planeIndex;
+    uint32_t                                    planeStackIndex;
+    VkSurfaceTransformKHR                       transform;
+    float                                       globalAlpha;
+    VkDisplayPlaneAlphaFlagsKHR                 alphaMode;
+    VkExtent2D                                  imageSize;
+} VkSurfaceDescriptionDisplayPlaneKHR;
+
+
+typedef VkResult (VKAPI *PFN_vkGetPhysicalDeviceDisplayPropertiesKHR)(VkPhysicalDevice physicalDevice, uint32_t* pCount, VkDisplayPropertiesKHR* pProperties);
+typedef VkResult (VKAPI *PFN_vkGetDisplayModePropertiesKHR)(VkPhysicalDevice physicalDevice, VkDisplayKHR display, uint32_t* pCount, VkDisplayModePropertiesKHR* pModeProperties);
+typedef VkResult (VKAPI *PFN_vkCreateDisplayModeKHR)(VkPhysicalDevice physicalDevice, VkDisplayKHR display, const VkDisplayModeCreateInfoKHR*pCreateInfo, VkDisplayModeKHR* pMode);
+typedef VkResult (VKAPI *PFN_vkGetDisplayPlanePropertiesKHR)(VkPhysicalDevice physicalDevice, VkDisplayKHR display, VkDisplayModeKHR mode, uint32_t planeIndex, VkDisplayPlanePropertiesKHR* pProperties);
+
+#ifdef VK_PROTOTYPES
+VkResult VKAPI vkGetPhysicalDeviceDisplayPropertiesKHR(
+    VkPhysicalDevice                            physicalDevice,
+    uint32_t*                                   pCount,
+    VkDisplayPropertiesKHR*                     pProperties);
+
+VkResult VKAPI vkGetDisplayModePropertiesKHR(
+    VkPhysicalDevice                            physicalDevice,
+    VkDisplayKHR                                display,
+    uint32_t*                                   pCount,
+    VkDisplayModePropertiesKHR*                 pModeProperties);
+
+VkResult VKAPI vkCreateDisplayModeKHR(
+    VkPhysicalDevice                            physicalDevice,
+    VkDisplayKHR                                display,
+    const VkDisplayModeCreateInfoKHR*           pCreateInfo,
+    VkDisplayModeKHR*                           pMode);
+
+VkResult VKAPI vkGetDisplayPlanePropertiesKHR(
+    VkPhysicalDevice                            physicalDevice,
+    VkDisplayKHR                                display,
+    VkDisplayModeKHR                            mode,
+    uint32_t                                    planeIndex,
+    VkDisplayPlanePropertiesKHR*                pProperties);
+#endif
+
+#define vk_ext_khr_display_swapchain 1
+#define VK_EXT_KHR_DISPLAY_SWAPCHAIN_REVISION 4
+#define VK_EXT_KHR_DISPLAY_SWAPCHAIN_EXTENSION_NUMBER 4
+#define VK_EXT_KHR_DISPLAY_SWAPCHAIN_EXTENSION_NAME "VK_EXT_KHR_display_swapchain"
+#define VK_STRUCTURE_TYPE_DISPLAY_SWAPCHAIN_CREATE_INFO_KHR ((VkStructureType)(int)0xc0001000)
+#define VK_STRUCTURE_TYPE_DISPLAY_PRESENT_INFO_KHR ((VkStructureType)(int)0xc0001001)
+#define VK_ERROR_INCOMPATIBLE_DISPLAY_KHR ((VkResult)(int)0xc0001002)
+
+typedef struct {
+    VkStructureType                             sType;
+    const void*                                   pNext;
+    const VkSwapchainCreateInfoKHR*             pNextSwapchainCreateInfo;
+} VkDisplaySwapchainCreateInfoKHR;
+
+typedef struct {
+    VkStructureType                             sType;
+    const void*                                   pNext;
+    VkRect2D                                    srcRect;
+    VkRect2D                                    dstRect;
+} VkDisplayPresentInfoKHR;
+
+
+
+#define vk_ext_khr_x11_surface 1
+#ifdef VK_USE_PLATFORM_X11_KHR
+#include <X11/Xlib.h>
+
+#define VK_EXT_KHR_X11_SURFACE_REVISION   1
+#define VK_EXT_KHR_X11_SURFACE_EXTENSION_NUMBER 5
+#define VK_EXT_KHR_X11_SURFACE_EXTENSION_NAME "VK_EXT_KHR_x11_surface"
+
+typedef VkResult (VKAPI *PFN_vkCreateX11SurfaceKHR)(VkInstance instance, Display* dpy, Window root, Window window, VkSurfaceKHR* pSurface);
+
+#ifdef VK_PROTOTYPES
+VkResult VKAPI vkCreateX11SurfaceKHR(
+    VkInstance                                  instance,
+    Display*                                    dpy,
+    Window                                      root,
+    Window                                      window,
+    VkSurfaceKHR*                               pSurface);
+#endif
+#endif /* VK_USE_PLATFORM_X11_KHR */
+
+#define vk_ext_khr_xcb_surface 1
+#ifdef VK_USE_PLATFORM_XCB_KHR
+#include <xcb/xcb.h>
+
+#define VK_EXT_KHR_XCB_SURFACE_REVISION   1
+#define VK_EXT_KHR_XCB_SURFACE_EXTENSION_NUMBER 6
+#define VK_EXT_KHR_XCB_SURFACE_EXTENSION_NAME "VK_EXT_KHR_xcb_surface"
+
+typedef VkResult (VKAPI *PFN_vkCreateXcbSurfaceKHR)(VkInstance instance, xcb_connection_t* connection, xcb_window_t root, xcb_window_t window, VkSurfaceKHR* pSurface);
+
+#ifdef VK_PROTOTYPES
+VkResult VKAPI vkCreateXcbSurfaceKHR(
+    VkInstance                                  instance,
+    xcb_connection_t*                           connection,
+    xcb_window_t                                root,
+    xcb_window_t                                window,
+    VkSurfaceKHR*                               pSurface);
+#endif
+#endif /* VK_USE_PLATFORM_XCB_KHR */
+
+#define vk_ext_khr_wayland_surface 1
+#ifdef VK_USE_PLATFORM_WAYLAND_KHR
+#include <wayland-client.h>
+
+#define VK_EXT_KHR_WAYLAND_SURFACE_REVISION 1
+#define VK_EXT_KHR_WAYLAND_SURFACE_EXTENSION_NUMBER 7
+#define VK_EXT_KHR_WAYLAND_SURFACE_EXTENSION_NAME "VK_EXT_KHR_wayland_surface"
+
+typedef VkResult (VKAPI *PFN_vkCreateWaylandSurfaceKHR)(VkInstance instance, struct wl_display* display, struct wl_surface* surface, VkSurfaceKHR* pSurface);
+
+#ifdef VK_PROTOTYPES
+VkResult VKAPI vkCreateWaylandSurfaceKHR(
+    VkInstance                                  instance,
+    struct wl_display*                          display,
+    struct wl_surface*                          surface,
+    VkSurfaceKHR*                               pSurface);
+#endif
+#endif /* VK_USE_PLATFORM_WAYLAND_KHR */
+
+#define vk_ext_khr_mir_surface 1
+#ifdef VK_USE_PLATFORM_MIR_KHR
+#include <mir_toolkit/client_types.h>
+
+#define VK_EXT_KHR_MIR_SURFACE_REVISION   1
+#define VK_EXT_KHR_MIR_SURFACE_EXTENSION_NUMBER 8
+#define VK_EXT_KHR_MIR_SURFACE_EXTENSION_NAME "VK_EXT_KHR_mir_surface"
+
+typedef VkResult (VKAPI *PFN_vkCreateMirSurfaceKHR)(VkInstance instance, MirConnection* connection, MirSurface* mirSurface, VkSurfaceKHR* pSurface);
+
+#ifdef VK_PROTOTYPES
+VkResult VKAPI vkCreateMirSurfaceKHR(
+    VkInstance                                  instance,
+    MirConnection*                              connection,
+    MirSurface*                                 mirSurface,
+    VkSurfaceKHR*                               pSurface);
+#endif
+#endif /* VK_USE_PLATFORM_MIR_KHR */
+
+#define vk_ext_khr_android_surface 1
+#ifdef VK_USE_PLATFORM_ANDROID_KHR
+#include <android/native_window.h>
+
+#define VK_EXT_KHR_ANDROID_SURFACE_REVISION 1
+#define VK_EXT_KHR_ANDROID_SURFACE_EXTENSION_NUMBER 9
+#define VK_EXT_KHR_ANDROID_SURFACE_EXTENSION_NAME "VK_EXT_KHR_android_surface"
+#define VK_ERROR_INVALID_ANDROID_WINDOW_KHR ((VkResult)(int)0xc0002400)
+#define VK_ERROR_ANDROID_WINDOW_IN_USE_KHR ((VkResult)(int)0xc0002401)
+
+typedef VkResult (VKAPI *PFN_vkCreateAndroidSurfaceKHR)(VkInstance instance, ANativeWindow* window, VkSurfaceKHR* pSurface);
+
+#ifdef VK_PROTOTYPES
+VkResult VKAPI vkCreateAndroidSurfaceKHR(
+    VkInstance                                  instance,
+    ANativeWindow*                              window,
+    VkSurfaceKHR*                               pSurface);
+#endif
+#endif /* VK_USE_PLATFORM_ANDROID_KHR */
+
+#define vk_ext_khr_win32_surface 1
+#ifdef VK_USE_PLATFORM_WIN32_KHR
+#include <windows.h>
+
+#define VK_EXT_KHR_WIN32_SURFACE_REVISION 1
+#define VK_EXT_KHR_WIN32_SURFACE_EXTENSION_NUMBER 10
+#define VK_EXT_KHR_WIN32_SURFACE_EXTENSION_NAME "VK_EXT_KHR_win32_surface"
+
+typedef VkResult (VKAPI *PFN_vkCreateWin32SurfaceKHR)(VkInstance instance, HINSTANCE hinstance, HWND hwnd, VkSurfaceKHR* pSurface);
+
+#ifdef VK_PROTOTYPES
+VkResult VKAPI vkCreateWin32SurfaceKHR(
+    VkInstance                                  instance,
+    HINSTANCE                                   hinstance,
+    HWND                                        hwnd,
+    VkSurfaceKHR*                               pSurface);
+#endif
+#endif /* VK_USE_PLATFORM_WIN32_KHR */
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/vulkan/libvulkan/entry.cpp b/vulkan/libvulkan/entry.cpp
index 0af3bc8..339101f 100644
--- a/vulkan/libvulkan/entry.cpp
+++ b/vulkan/libvulkan/entry.cpp
@@ -762,23 +762,28 @@
 }
 
 __attribute__((visibility("default")))
-VkResult vkGetPhysicalDeviceSurfaceSupportKHR(VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex, const VkSurfaceDescriptionKHR* pSurfaceDescription, VkBool32* pSupported) {
-    return GetVtbl(physicalDevice).GetPhysicalDeviceSurfaceSupportKHR(physicalDevice, queueFamilyIndex, pSurfaceDescription, pSupported);
+void vkDestroySurfaceKHR(VkInstance instance, VkSurfaceKHR surface) {
+    GetVtbl(instance).DestroySurfaceKHR(instance, surface);
 }
 
 __attribute__((visibility("default")))
-VkResult vkGetSurfacePropertiesKHR(VkDevice device, const VkSurfaceDescriptionKHR* pSurfaceDescription, VkSurfacePropertiesKHR* pSurfaceProperties) {
-    return GetVtbl(device).GetSurfacePropertiesKHR(device, pSurfaceDescription, pSurfaceProperties);
+VkBool32 vkGetPhysicalDeviceSurfaceSupportKHR(VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex, VkSurfaceKHR surface) {
+    return GetVtbl(physicalDevice).GetPhysicalDeviceSurfaceSupportKHR(physicalDevice, queueFamilyIndex, surface);
 }
 
 __attribute__((visibility("default")))
-VkResult vkGetSurfaceFormatsKHR(VkDevice device, const VkSurfaceDescriptionKHR* pSurfaceDescription, uint32_t* pCount, VkSurfaceFormatKHR* pSurfaceFormats) {
-    return GetVtbl(device).GetSurfaceFormatsKHR(device, pSurfaceDescription, pCount, pSurfaceFormats);
+VkResult vkGetSurfacePropertiesKHR(VkDevice device, VkSurfaceKHR surface, VkSurfacePropertiesKHR* pSurfaceProperties) {
+    return GetVtbl(device).GetSurfacePropertiesKHR(device, surface, pSurfaceProperties);
 }
 
 __attribute__((visibility("default")))
-VkResult vkGetSurfacePresentModesKHR(VkDevice device, const VkSurfaceDescriptionKHR* pSurfaceDescription, uint32_t* pCount, VkPresentModeKHR* pPresentModes) {
-    return GetVtbl(device).GetSurfacePresentModesKHR(device, pSurfaceDescription, pCount, pPresentModes);
+VkResult vkGetSurfaceFormatsKHR(VkDevice device, VkSurfaceKHR surface, uint32_t* pCount, VkSurfaceFormatKHR* pSurfaceFormats) {
+    return GetVtbl(device).GetSurfaceFormatsKHR(device, surface, pCount, pSurfaceFormats);
+}
+
+__attribute__((visibility("default")))
+VkResult vkGetSurfacePresentModesKHR(VkDevice device, VkSurfaceKHR surface, uint32_t* pCount, VkPresentModeKHR* pPresentModes) {
+    return GetVtbl(device).GetSurfacePresentModesKHR(device, surface, pCount, pPresentModes);
 }
 
 __attribute__((visibility("default")))
@@ -787,8 +792,8 @@
 }
 
 __attribute__((visibility("default")))
-VkResult vkDestroySwapchainKHR(VkDevice device, VkSwapchainKHR swapchain) {
-    return GetVtbl(device).DestroySwapchainKHR(device, swapchain);
+void vkDestroySwapchainKHR(VkDevice device, VkSwapchainKHR swapchain) {
+    GetVtbl(device).DestroySwapchainKHR(device, swapchain);
 }
 
 __attribute__((visibility("default")))
@@ -797,11 +802,16 @@
 }
 
 __attribute__((visibility("default")))
-VkResult vkAcquireNextImageKHR(VkDevice device, VkSwapchainKHR swapchain, uint64_t timeout, VkSemaphore semaphore, uint32_t* pImageIndex) {
-    return GetVtbl(device).AcquireNextImageKHR(device, swapchain, timeout, semaphore, pImageIndex);
+VkResult vkAcquireNextImageKHR(VkDevice device, VkSwapchainKHR swapchain, uint64_t timeout, VkSemaphore semaphore, VkFence fence, uint32_t* pImageIndex) {
+    return GetVtbl(device).AcquireNextImageKHR(device, swapchain, timeout, semaphore, fence, pImageIndex);
 }
 
 __attribute__((visibility("default")))
 VkResult vkQueuePresentKHR(VkQueue queue, VkPresentInfoKHR* pPresentInfo) {
     return GetVtbl(queue).QueuePresentKHR(queue, pPresentInfo);
 }
+
+__attribute__((visibility("default")))
+VkResult vkCreateAndroidSurfaceKHR(VkInstance instance, struct ANativeWindow* window, VkSurfaceKHR* pSurface) {
+    return GetVtbl(instance).CreateAndroidSurfaceKHR(instance, window, pSurface);
+}
diff --git a/vulkan/libvulkan/entry.cpp.tmpl b/vulkan/libvulkan/entry.cpp.tmpl
index 72185e7..d0e665f 100644
--- a/vulkan/libvulkan/entry.cpp.tmpl
+++ b/vulkan/libvulkan/entry.cpp.tmpl
@@ -69,7 +69,7 @@
 } // namespace

   {{range $f := AllCommands $}}
-    {{if not (GetAnnotation $f "pfn")}}
+    {{if and (not (GetAnnotation $f "pfn")) (Macro "IsExportedEntry" $f)}}
       __attribute__((visibility("default")))
       {{if eq (Macro "IsSpecialEntry" $f.Name) "true"}}
         {{Macro "EmitSpecialEntry" $f}}
@@ -84,6 +84,25 @@
 
 {{/*
 -------------------------------------------------------------------------------
+  Decides whether an entrypoint should be exported from the Android Vulkan
+  library. Entrypoints in the core API and in mandatory extensions are
+  exported.
+-------------------------------------------------------------------------------
+*/}}
+{{define "IsExportedEntry"}}
+  {{AssertType $ "Function"}}
+  {{$ext := GetAnnotation $ "extension"}}
+  {{if $ext}}
+    {{$extval := index $ext.Arguments 0}}
+    {{if      eq $extval "VK_EXT_KHR_surface"}}true
+    {{else if eq $extval "VK_EXT_KHR_swapchain"}}true
+    {{else if eq $extval "VK_EXT_KHR_android_surface"}}true{{end}}
+  {{else}}true{{end}}
+{{end}}
+
+
+{{/*
+-------------------------------------------------------------------------------
   Decides whether an entrypoint needs special-case handling. Emits the string
   "true" if so, nothing otherwise.
 -------------------------------------------------------------------------------
@@ -95,6 +114,7 @@
   {{end}}
 {{end}}
 
+
 {{/*
 -------------------------------------------------------------------------------
   Emits the entrypoint definition for the specified command, which always
diff --git a/vulkan/libvulkan/get_proc_addr.cpp b/vulkan/libvulkan/get_proc_addr.cpp
index b9bd689..f1ad5f3 100644
--- a/vulkan/libvulkan/get_proc_addr.cpp
+++ b/vulkan/libvulkan/get_proc_addr.cpp
@@ -49,8 +49,10 @@
 
 const NameProcEntry kInstanceProcTbl[] = {
     // clang-format off
+    {"vkCreateAndroidSurfaceKHR", reinterpret_cast<PFN_vkVoidFunction>(vkCreateAndroidSurfaceKHR)},
     {"vkCreateDevice", reinterpret_cast<PFN_vkVoidFunction>(vkCreateDevice)},
     {"vkDestroyInstance", reinterpret_cast<PFN_vkVoidFunction>(vkDestroyInstance)},
+    {"vkDestroySurfaceKHR", reinterpret_cast<PFN_vkVoidFunction>(vkDestroySurfaceKHR)},
     {"vkEnumerateDeviceExtensionProperties", reinterpret_cast<PFN_vkVoidFunction>(vkEnumerateDeviceExtensionProperties)},
     {"vkEnumerateDeviceLayerProperties", reinterpret_cast<PFN_vkVoidFunction>(vkEnumerateDeviceLayerProperties)},
     {"vkEnumeratePhysicalDevices", reinterpret_cast<PFN_vkVoidFunction>(vkEnumeratePhysicalDevices)},
@@ -209,8 +211,10 @@
 
 const NameOffsetEntry kInstanceOffsetTbl[] = {
     // clang-format off
+    {"vkCreateAndroidSurfaceKHR", offsetof(InstanceVtbl, CreateAndroidSurfaceKHR)},
     {"vkCreateDevice", offsetof(InstanceVtbl, CreateDevice)},
     {"vkDestroyInstance", offsetof(InstanceVtbl, DestroyInstance)},
+    {"vkDestroySurfaceKHR", offsetof(InstanceVtbl, DestroySurfaceKHR)},
     {"vkEnumerateDeviceExtensionProperties", offsetof(InstanceVtbl, EnumerateDeviceExtensionProperties)},
     {"vkEnumerateDeviceLayerProperties", offsetof(InstanceVtbl, EnumerateDeviceLayerProperties)},
     {"vkEnumeratePhysicalDevices", offsetof(InstanceVtbl, EnumeratePhysicalDevices)},
@@ -490,7 +494,9 @@
         ALOGE("missing instance proc: %s", "vkGetPhysicalDeviceSparseImageFormatProperties");
         success = false;
     }
+    vtbl.DestroySurfaceKHR = reinterpret_cast<PFN_vkDestroySurfaceKHR>(get_proc_addr(instance, "vkDestroySurfaceKHR"));
     vtbl.GetPhysicalDeviceSurfaceSupportKHR = reinterpret_cast<PFN_vkGetPhysicalDeviceSurfaceSupportKHR>(get_proc_addr(instance, "vkGetPhysicalDeviceSurfaceSupportKHR"));
+    vtbl.CreateAndroidSurfaceKHR = reinterpret_cast<PFN_vkCreateAndroidSurfaceKHR>(get_proc_addr(instance, "vkCreateAndroidSurfaceKHR"));
     // clang-format on
     return success;
 }
diff --git a/vulkan/libvulkan/get_proc_addr.cpp.tmpl b/vulkan/libvulkan/get_proc_addr.cpp.tmpl
index 6d5f618..c6ec0d1 100644
--- a/vulkan/libvulkan/get_proc_addr.cpp.tmpl
+++ b/vulkan/libvulkan/get_proc_addr.cpp.tmpl
@@ -78,7 +78,7 @@
 const NameProcEntry kInstanceProcTbl[] = {«
   // clang-format off
   {{range $f := SortBy (AllCommands $) "FunctionName"}}
-    {{if eq (Macro "Vtbl" $f) "Instance"}}
+    {{if and (Macro "IsDispatched" $f) (eq (Macro "Vtbl" $f) "Instance")}}
       {"{{Macro "FunctionName" $f}}", reinterpret_cast<PFN_vkVoidFunction>({{Macro "FunctionName" $f}})},
     {{end}}
   {{end}}
@@ -88,7 +88,7 @@
 const NameProcEntry kDeviceProcTbl[] = {«
   // clang-format off
   {{range $f := SortBy (AllCommands $) "FunctionName"}}
-    {{if eq (Macro "Vtbl" $f) "Device"}}
+    {{if and (Macro "IsDispatched" $f) (eq (Macro "Vtbl" $f) "Device")}}
       {"{{Macro "FunctionName" $f}}", reinterpret_cast<PFN_vkVoidFunction>({{Macro "FunctionName" $f}})},
     {{end}}
   {{end}}
@@ -98,7 +98,7 @@
 const NameOffsetEntry kInstanceOffsetTbl[] = {«
   // clang-format off
   {{range $f := SortBy (AllCommands $) "FunctionName"}}
-    {{if eq (Macro "Vtbl" $f) "Instance"}}
+    {{if and (Macro "IsDispatched" $f) (eq (Macro "Vtbl" $f) "Instance")}}
       {"{{Macro "FunctionName" $f}}", offsetof(InstanceVtbl, {{TrimPrefix "vk" (Macro "FunctionName" $f)}})},
     {{end}}
   {{end}}
@@ -108,7 +108,7 @@
 const NameOffsetEntry kDeviceOffsetTbl[] = {«
   // clang-format off
   {{range $f := SortBy (AllCommands $) "FunctionName"}}
-    {{if eq (Macro "Vtbl" $f) "Device"}}
+    {{if and (Macro "IsDispatched" $f) (eq (Macro "Vtbl" $f) "Device")}}
       {"{{Macro "FunctionName" $f}}", offsetof(DeviceVtbl, {{TrimPrefix "vk" (Macro "FunctionName" $f)}})},
     {{end}}
   {{end}}
@@ -194,7 +194,7 @@
     {{end}}
     {{range $f := AllCommands $}}
       {{if eq (Macro "Vtbl" $f) "Instance"}}
-        {{if (GetAnnotation $f "extension")}}
+        {{if and (GetAnnotation $f "extension") (Macro "IsDispatched" $f)}}
     vtbl.{{TrimPrefix "vk" (Macro "FunctionName" $f)}} = §
         reinterpret_cast<{{Macro "FunctionPtrName" $f}}>(§
             get_proc_addr(instance, "{{Macro "FunctionName" $f}}"));
@@ -265,3 +265,32 @@
 } // namespace vulkan

 {{end}}
+
+
+{{/*
+-------------------------------------------------------------------------------
+  This function emits nil for extension entrypoints that should not be
+  included in dispatch tables, "true" otherwise. Extensions that are ony used
+  directly between the loader and driver, or that aren't supported on Android
+  at all, should be excluded from dispatch.
+-------------------------------------------------------------------------------
+*/}}
+{{define "IsUnsupportedExtension"}}
+  {{$ext := index $.Arguments 0}}
+  {{     if eq $ext "VK_EXT_KHR_display"}}true
+  {{else if eq $ext "VK_EXT_KHR_display_swapchain"}}true
+  {{else if eq $ext "VK_EXT_KHR_x11_surface"}}true
+  {{else if eq $ext "VK_EXT_KHR_xcb_surface"}}true
+  {{else if eq $ext "VK_EXT_KHR_wayland_surface"}}true
+  {{else if eq $ext "VK_EXT_KHR_mir_surface"}}true
+  {{else if eq $ext "VK_EXT_KHR_win32_surface"}}true
+  {{end}}
+{{end}}
+
+{{define "IsDispatched"}}
+  {{AssertType $ "Function"}}
+  {{$ext := GetAnnotation $ "extension"}}
+  {{if not $ext}}true
+  {{else if not (Macro "IsUnsupportedExtension" $ext)}}true
+  {{end}}
+{{end}}
diff --git a/vulkan/libvulkan/loader.cpp b/vulkan/libvulkan/loader.cpp
index c427918..a44026f 100644
--- a/vulkan/libvulkan/loader.cpp
+++ b/vulkan/libvulkan/loader.cpp
@@ -1102,16 +1102,29 @@
     return VK_SUCCESS;
 }
 
-void* AllocDeviceMem(VkDevice device,
-                     size_t size,
-                     size_t align,
-                     VkSystemAllocType type) {
+void* AllocMem(VkInstance instance,
+               size_t size,
+               size_t align,
+               VkSystemAllocType type) {
+    const VkAllocCallbacks* alloc_cb = instance->alloc;
+    return alloc_cb->pfnAlloc(alloc_cb->pUserData, size, align, type);
+}
+
+void FreeMem(VkInstance instance, void* ptr) {
+    const VkAllocCallbacks* alloc_cb = instance->alloc;
+    alloc_cb->pfnFree(alloc_cb->pUserData, ptr);
+}
+
+void* AllocMem(VkDevice device,
+               size_t size,
+               size_t align,
+               VkSystemAllocType type) {
     const VkAllocCallbacks* alloc_cb =
         static_cast<Device*>(GetVtbl(device)->device)->instance->alloc;
     return alloc_cb->pfnAlloc(alloc_cb->pUserData, size, align, type);
 }
 
-void FreeDeviceMem(VkDevice device, void* ptr) {
+void FreeMem(VkDevice device, void* ptr) {
     const VkAllocCallbacks* alloc_cb =
         static_cast<Device*>(GetVtbl(device)->device)->instance->alloc;
     alloc_cb->pfnFree(alloc_cb->pUserData, ptr);
diff --git a/vulkan/libvulkan/loader.h b/vulkan/libvulkan/loader.h
index 5e0a6c9..3e34e75 100644
--- a/vulkan/libvulkan/loader.h
+++ b/vulkan/libvulkan/loader.h
@@ -18,9 +18,8 @@
 #define LIBVULKAN_LOADER_H 1
 
 #define VK_PROTOTYPES
+#define VK_USE_PLATFORM_ANDROID_KHR
 #include <vulkan/vulkan.h>
-#include <vulkan/vk_ext_khr_swapchain.h>
-#include <vulkan/vk_ext_khr_device_swapchain.h>
 #include <vulkan/vk_ext_android_native_buffer.h>
 
 namespace vulkan {
@@ -52,6 +51,8 @@
     PFN_vkGetPhysicalDeviceSparseImageFormatProperties GetPhysicalDeviceSparseImageFormatProperties;
 
     // Layers and loader only, not implemented by drivers
+    PFN_vkCreateAndroidSurfaceKHR CreateAndroidSurfaceKHR;
+    PFN_vkDestroySurfaceKHR DestroySurfaceKHR;
     PFN_vkGetPhysicalDeviceSurfaceSupportKHR GetPhysicalDeviceSurfaceSupportKHR;
     // clang-format on
 };
@@ -230,11 +231,16 @@
                              VkCmdBuffer* cmdbuffers);
 VkResult DestroyDevice(VkDevice drv_device);
 
-void* AllocDeviceMem(VkDevice device,
-                     size_t size,
-                     size_t align,
-                     VkSystemAllocType type);
-void FreeDeviceMem(VkDevice device, void* ptr);
+void* AllocMem(VkInstance instance,
+               size_t size,
+               size_t align,
+               VkSystemAllocType type);
+void FreeMem(VkInstance instance, void* ptr);
+void* AllocMem(VkDevice device,
+               size_t size,
+               size_t align,
+               VkSystemAllocType type);
+void FreeMem(VkDevice device, void* ptr);
 const DeviceVtbl& GetDriverVtbl(VkDevice device);
 const DeviceVtbl& GetDriverVtbl(VkQueue queue);
 
@@ -260,20 +266,22 @@
 // -----------------------------------------------------------------------------
 // swapchain.cpp
 
-VkResult GetPhysicalDeviceSurfaceSupportKHR(
-    VkPhysicalDevice pdev,
-    uint32_t queue_family,
-    const VkSurfaceDescriptionKHR* surface_desc,
-    VkBool32* supported);
+VkResult CreateAndroidSurfaceKHR(VkInstance instance,
+                                 ANativeWindow* window,
+                                 VkSurfaceKHR* surface);
+void DestroySurfaceKHR(VkInstance instance, VkSurfaceKHR surface);
+VkBool32 GetPhysicalDeviceSurfaceSupportKHR(VkPhysicalDevice pdev,
+                                            uint32_t queue_family,
+                                            VkSurfaceKHR surface);
 VkResult GetSurfacePropertiesKHR(VkDevice device,
-                                 const VkSurfaceDescriptionKHR* surface_desc,
+                                 VkSurfaceKHR surface,
                                  VkSurfacePropertiesKHR* properties);
 VkResult GetSurfaceFormatsKHR(VkDevice device,
-                              const VkSurfaceDescriptionKHR* surface_desc,
+                              VkSurfaceKHR surface,
                               uint32_t* count,
                               VkSurfaceFormatKHR* formats);
 VkResult GetSurfacePresentModesKHR(VkDevice device,
-                                   const VkSurfaceDescriptionKHR* surface_desc,
+                                   VkSurfaceKHR surface,
                                    uint32_t* count,
                                    VkPresentModeKHR* modes);
 VkResult CreateSwapchainKHR(VkDevice device,
diff --git a/vulkan/libvulkan/swapchain.cpp b/vulkan/libvulkan/swapchain.cpp
index 70c0e33..6813680 100644
--- a/vulkan/libvulkan/swapchain.cpp
+++ b/vulkan/libvulkan/swapchain.cpp
@@ -49,43 +49,55 @@
     void operator()(T* obj) { obj->common.decRef(&obj->common); }
 };
 
-template <typename T>
+template <typename T, typename Host>
 class VulkanAllocator {
    public:
     typedef T value_type;
 
-    explicit VulkanAllocator(VkDevice device) : device_(device) {}
+    explicit VulkanAllocator(Host host) : host_(host) {}
 
     template <typename U>
-    explicit VulkanAllocator(const VulkanAllocator<U>& other)
-        : device_(other.device_) {}
+    explicit VulkanAllocator(const VulkanAllocator<U, Host>& other)
+        : host_(other.host_) {}
 
     T* allocate(size_t n) const {
-        return static_cast<T*>(AllocDeviceMem(
-            device_, n * sizeof(T), alignof(T), VK_SYSTEM_ALLOC_TYPE_INTERNAL));
+        return static_cast<T*>(AllocMem(host_, n * sizeof(T), alignof(T),
+                                        VK_SYSTEM_ALLOC_TYPE_INTERNAL));
     }
-    void deallocate(T* p, size_t) const { return FreeDeviceMem(device_, p); }
+    void deallocate(T* p, size_t) const { return FreeMem(host_, p); }
 
    private:
-    template <typename U>
+    template <typename U, typename H>
     friend class VulkanAllocator;
-    VkDevice device_;
+    Host host_;
 };
 
-template <typename T>
-std::shared_ptr<T> InitSharedPtr(VkDevice device, T* obj) {
+template <typename T, typename Host>
+std::shared_ptr<T> InitSharedPtr(Host host, T* obj) {
     obj->common.incRef(&obj->common);
     return std::shared_ptr<T>(obj, NativeBaseDeleter<T>(),
-                              VulkanAllocator<T>(device));
+                              VulkanAllocator<T, Host>(host));
 }
 
 // ----------------------------------------------------------------------------
 
-struct Swapchain {
-    Swapchain(std::shared_ptr<ANativeWindow> window_, uint32_t num_images_)
-        : window(window_), num_images(num_images_) {}
-
+struct Surface {
     std::shared_ptr<ANativeWindow> window;
+};
+
+VkSurfaceKHR HandleFromSurface(Surface* surface) {
+    return VkSurfaceKHR(reinterpret_cast<uint64_t>(surface));
+}
+
+Surface* SurfaceFromHandle(VkSurfaceKHR handle) {
+    return reinterpret_cast<Surface*>(handle.handle);
+}
+
+struct Swapchain {
+    Swapchain(Surface& surface_, uint32_t num_images_)
+        : surface(surface_), num_images(num_images_) {}
+
+    Surface& surface;
     uint32_t num_images;
 
     struct Image {
@@ -113,95 +125,69 @@
 
 namespace vulkan {
 
-VkResult GetPhysicalDeviceSurfaceSupportKHR(
-    VkPhysicalDevice /*pdev*/,
-    uint32_t /*queue_family*/,
-    const VkSurfaceDescriptionKHR* surface_desc,
-    VkBool32* supported) {
-// TODO(jessehall): Fix the header, preferrably upstream, so values added to
-// existing enums don't trigger warnings like this.
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wold-style-cast"
-#pragma clang diagnostic ignored "-Wsign-conversion"
-    ALOGE_IF(
-        surface_desc->sType != VK_STRUCTURE_TYPE_SURFACE_DESCRIPTION_WINDOW_KHR,
-        "vkGetPhysicalDeviceSurfaceSupportKHR: pSurfaceDescription->sType=%#x "
-        "not supported",
-        surface_desc->sType);
-#pragma clang diagnostic pop
+VkResult CreateAndroidSurfaceKHR(VkInstance instance,
+                                 ANativeWindow* window,
+                                 VkSurfaceKHR* out_surface) {
+    void* mem = AllocMem(instance, sizeof(Surface), alignof(Surface),
+                         VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
+    if (!mem)
+        return VK_ERROR_OUT_OF_HOST_MEMORY;
+    Surface* surface = new (mem) Surface;
 
-    const VkSurfaceDescriptionWindowKHR* window_desc =
-        reinterpret_cast<const VkSurfaceDescriptionWindowKHR*>(surface_desc);
+    surface->window = InitSharedPtr(instance, window);
 
-    // TODO(jessehall): Also check whether the physical device exports the
-    // VK_EXT_ANDROID_native_buffer extension. For now, assume it does.
-    *supported = (window_desc->platform == VK_PLATFORM_ANDROID_KHR &&
-                  !window_desc->pPlatformHandle &&
-                  static_cast<ANativeWindow*>(window_desc->pPlatformWindow)
-                          ->common.magic == ANDROID_NATIVE_WINDOW_MAGIC);
+    // TODO(jessehall): Create and use NATIVE_WINDOW_API_VULKAN.
+    int err =
+        native_window_api_connect(surface->window.get(), NATIVE_WINDOW_API_EGL);
+    if (err != 0) {
+        // TODO(jessehall): Improve error reporting. Can we enumerate possible
+        // errors and translate them to valid Vulkan result codes?
+        ALOGE("native_window_api_connect() failed: %s (%d)", strerror(-err),
+              err);
+        surface->~Surface();
+        FreeMem(instance, surface);
+        return VK_ERROR_INITIALIZATION_FAILED;
+    }
 
+    *out_surface = HandleFromSurface(surface);
     return VK_SUCCESS;
 }
 
+void DestroySurfaceKHR(VkInstance instance, VkSurfaceKHR surface_handle) {
+    Surface* surface = SurfaceFromHandle(surface_handle);
+    if (!surface)
+        return;
+    native_window_api_disconnect(surface->window.get(), NATIVE_WINDOW_API_EGL);
+    surface->~Surface();
+    FreeMem(instance, surface);
+}
+
+VkBool32 GetPhysicalDeviceSurfaceSupportKHR(VkPhysicalDevice /*pdev*/,
+                                            uint32_t /*queue_family*/,
+                                            VkSurfaceKHR /*surface*/) {
+    return VK_TRUE;
+}
+
 VkResult GetSurfacePropertiesKHR(VkDevice /*device*/,
-                                 const VkSurfaceDescriptionKHR* surface_desc,
+                                 VkSurfaceKHR surface,
                                  VkSurfacePropertiesKHR* properties) {
-    const VkSurfaceDescriptionWindowKHR* window_desc =
-        reinterpret_cast<const VkSurfaceDescriptionWindowKHR*>(surface_desc);
-    ANativeWindow* window =
-        static_cast<ANativeWindow*>(window_desc->pPlatformWindow);
-
     int err;
-
-    // TODO(jessehall): Currently the window must be connected for several
-    // queries -- including default dimensions -- to work, since Surface caches
-    // the queried values at connect() and queueBuffer(), and query() returns
-    // those cached values.
-    //
-    // The proposed refactoring to create a VkSurface object (bug 14596) will
-    // give us a place to connect once per window. If that doesn't end up
-    // happening, we'll probably need to maintain an internal list of windows
-    // that have swapchains created for them, search that list here, and
-    // only temporarily connect if the window doesn't have a swapchain.
-
-    bool disconnect = true;
-    err = native_window_api_connect(window, NATIVE_WINDOW_API_EGL);
-    if (err == -EINVAL) {
-        // This is returned if the window is already connected, among other
-        // things. We'll just assume we're already connected and charge ahead.
-        // See TODO above, this is not cool.
-        ALOGW(
-            "vkGetSurfacePropertiesKHR: native_window_api_connect returned "
-            "-EINVAL, assuming already connected");
-        err = 0;
-        disconnect = false;
-    } else if (err != 0) {
-        // TODO(jessehall): Improve error reporting. Can we enumerate possible
-        // errors and translate them to valid Vulkan result codes?
-        return VK_ERROR_INITIALIZATION_FAILED;
-    }
+    ANativeWindow* window = SurfaceFromHandle(surface)->window.get();
 
     int width, height;
     err = window->query(window, NATIVE_WINDOW_DEFAULT_WIDTH, &width);
     if (err != 0) {
         ALOGE("NATIVE_WINDOW_DEFAULT_WIDTH query failed: %s (%d)",
               strerror(-err), err);
-        if (disconnect)
-            native_window_api_disconnect(window, NATIVE_WINDOW_API_EGL);
         return VK_ERROR_INITIALIZATION_FAILED;
     }
     err = window->query(window, NATIVE_WINDOW_DEFAULT_HEIGHT, &height);
     if (err != 0) {
         ALOGE("NATIVE_WINDOW_DEFAULT_WIDTH query failed: %s (%d)",
               strerror(-err), err);
-        if (disconnect)
-            native_window_api_disconnect(window, NATIVE_WINDOW_API_EGL);
         return VK_ERROR_INITIALIZATION_FAILED;
     }
 
-    if (disconnect)
-        native_window_api_disconnect(window, NATIVE_WINDOW_API_EGL);
-
     properties->currentExtent = VkExtent2D{width, height};
 
     // TODO(jessehall): Figure out what the min/max values should be.
@@ -238,13 +224,14 @@
 }
 
 VkResult GetSurfaceFormatsKHR(VkDevice /*device*/,
-                              const VkSurfaceDescriptionKHR* /*surface_desc*/,
+                              VkSurfaceKHR /*surface*/,
                               uint32_t* count,
                               VkSurfaceFormatKHR* formats) {
-    // TODO(jessehall): Fill out the set of supported formats. Open question
-    // whether we should query the driver for support -- how does it know what
-    // the consumer can support? Should we support formats that don't
-    // correspond to gralloc formats?
+    // TODO(jessehall): Fill out the set of supported formats. Longer term, add
+    // a new gralloc method to query whether a (format, usage) pair is
+    // supported, and check that for each gralloc format that corresponds to a
+    // Vulkan format. Shorter term, just add a few more formats to the ones
+    // hardcoded below.
 
     const VkSurfaceFormatKHR kFormats[] = {
         {VK_FORMAT_R8G8B8A8_UNORM, VK_COLORSPACE_SRGB_NONLINEAR_KHR},
@@ -262,11 +249,10 @@
     return result;
 }
 
-VkResult GetSurfacePresentModesKHR(
-    VkDevice /*device*/,
-    const VkSurfaceDescriptionKHR* /*surface_desc*/,
-    uint32_t* count,
-    VkPresentModeKHR* modes) {
+VkResult GetSurfacePresentModesKHR(VkDevice /*device*/,
+                                   VkSurfaceKHR /*surface*/,
+                                   uint32_t* count,
+                                   VkPresentModeKHR* modes) {
     const VkPresentModeKHR kModes[] = {
         VK_PRESENT_MODE_MAILBOX_KHR, VK_PRESENT_MODE_FIFO_KHR,
     };
@@ -304,26 +290,11 @@
              "present modes other than FIFO are not yet implemented");
 
     // -- Configure the native window --
-    // Failure paths from here on need to disconnect the window.
 
+    Surface& surface = *SurfaceFromHandle(create_info->surface);
     const DeviceVtbl& driver_vtbl = GetDriverVtbl(device);
 
-    std::shared_ptr<ANativeWindow> window = InitSharedPtr(
-        device, static_cast<ANativeWindow*>(
-                    reinterpret_cast<const VkSurfaceDescriptionWindowKHR*>(
-                        create_info->pSurfaceDescription)->pPlatformWindow));
-
-    // TODO(jessehall): Create and use NATIVE_WINDOW_API_VULKAN.
-    err = native_window_api_connect(window.get(), NATIVE_WINDOW_API_EGL);
-    if (err != 0) {
-        // TODO(jessehall): Improve error reporting. Can we enumerate possible
-        // errors and translate them to valid Vulkan result codes?
-        ALOGE("native_window_api_connect() failed: %s (%d)", strerror(-err),
-              err);
-        return VK_ERROR_INITIALIZATION_FAILED;
-    }
-
-    err = native_window_set_buffers_dimensions(window.get(),
+    err = native_window_set_buffers_dimensions(surface.window.get(),
                                                create_info->imageExtent.width,
                                                create_info->imageExtent.height);
     if (err != 0) {
@@ -332,40 +303,37 @@
         ALOGE("native_window_set_buffers_dimensions(%d,%d) failed: %s (%d)",
               create_info->imageExtent.width, create_info->imageExtent.height,
               strerror(-err), err);
-        native_window_api_disconnect(window.get(), NATIVE_WINDOW_API_EGL);
         return VK_ERROR_INITIALIZATION_FAILED;
     }
 
     err = native_window_set_scaling_mode(
-        window.get(), NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
+        surface.window.get(), NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
     if (err != 0) {
         // TODO(jessehall): Improve error reporting. Can we enumerate possible
         // errors and translate them to valid Vulkan result codes?
         ALOGE("native_window_set_scaling_mode(SCALE_TO_WINDOW) failed: %s (%d)",
               strerror(-err), err);
-        native_window_api_disconnect(window.get(), NATIVE_WINDOW_API_EGL);
         return VK_ERROR_INITIALIZATION_FAILED;
     }
 
     uint32_t min_undequeued_buffers;
-    err = window->query(window.get(), NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS,
-                        reinterpret_cast<int*>(&min_undequeued_buffers));
+    err = surface.window->query(
+        surface.window.get(), NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS,
+        reinterpret_cast<int*>(&min_undequeued_buffers));
     if (err != 0) {
         // TODO(jessehall): Improve error reporting. Can we enumerate possible
         // errors and translate them to valid Vulkan result codes?
         ALOGE("window->query failed: %s (%d)", strerror(-err), err);
-        native_window_api_disconnect(window.get(), NATIVE_WINDOW_API_EGL);
         return VK_ERROR_INITIALIZATION_FAILED;
     }
     uint32_t num_images =
         (create_info->minImageCount - 1) + min_undequeued_buffers;
-    err = native_window_set_buffer_count(window.get(), num_images);
+    err = native_window_set_buffer_count(surface.window.get(), num_images);
     if (err != 0) {
         // TODO(jessehall): Improve error reporting. Can we enumerate possible
         // errors and translate them to valid Vulkan result codes?
         ALOGE("native_window_set_buffer_count failed: %s (%d)", strerror(-err),
               err);
-        native_window_api_disconnect(window.get(), NATIVE_WINDOW_API_EGL);
         return VK_ERROR_INITIALIZATION_FAILED;
     }
 
@@ -377,31 +345,27 @@
             &gralloc_usage);
         if (result != VK_SUCCESS) {
             ALOGE("vkGetSwapchainGrallocUsageANDROID failed: %d", result);
-            native_window_api_disconnect(window.get(), NATIVE_WINDOW_API_EGL);
             return VK_ERROR_INITIALIZATION_FAILED;
         }
     } else {
         gralloc_usage = GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_HW_TEXTURE;
     }
-    err = native_window_set_usage(window.get(), gralloc_usage);
+    err = native_window_set_usage(surface.window.get(), gralloc_usage);
     if (err != 0) {
         // TODO(jessehall): Improve error reporting. Can we enumerate possible
         // errors and translate them to valid Vulkan result codes?
         ALOGE("native_window_set_usage failed: %s (%d)", strerror(-err), err);
-        native_window_api_disconnect(window.get(), NATIVE_WINDOW_API_EGL);
         return VK_ERROR_INITIALIZATION_FAILED;
     }
 
     // -- Allocate our Swapchain object --
     // After this point, we must deallocate the swapchain on error.
 
-    void* mem = AllocDeviceMem(device, sizeof(Swapchain), alignof(Swapchain),
-                               VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
-    if (!mem) {
-        native_window_api_disconnect(window.get(), NATIVE_WINDOW_API_EGL);
+    void* mem = AllocMem(device, sizeof(Swapchain), alignof(Swapchain),
+                         VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
+    if (!mem)
         return VK_ERROR_OUT_OF_HOST_MEMORY;
-    }
-    Swapchain* swapchain = new (mem) Swapchain(window, num_images);
+    Swapchain* swapchain = new (mem) Swapchain(surface, num_images);
 
     // -- Dequeue all buffers and create a VkImage for each --
     // Any failures during or after this must cancel the dequeued buffers.
@@ -435,7 +399,8 @@
         Swapchain::Image& img = swapchain->images[i];
 
         ANativeWindowBuffer* buffer;
-        err = window->dequeueBuffer(window.get(), &buffer, &img.dequeue_fence);
+        err = surface.window->dequeueBuffer(surface.window.get(), &buffer,
+                                            &img.dequeue_fence);
         if (err != 0) {
             // TODO(jessehall): Improve error reporting. Can we enumerate
             // possible errors and translate them to valid Vulkan result codes?
@@ -469,8 +434,8 @@
     for (uint32_t i = 0; i < num_images; i++) {
         Swapchain::Image& img = swapchain->images[i];
         if (img.dequeued) {
-            window->cancelBuffer(window.get(), img.buffer.get(),
-                                 img.dequeue_fence);
+            surface.window->cancelBuffer(surface.window.get(), img.buffer.get(),
+                                         img.dequeue_fence);
             img.dequeue_fence = -1;
             img.dequeued = false;
         }
@@ -481,9 +446,8 @@
     }
 
     if (result != VK_SUCCESS) {
-        native_window_api_disconnect(window.get(), NATIVE_WINDOW_API_EGL);
         swapchain->~Swapchain();
-        FreeDeviceMem(device, swapchain);
+        FreeMem(device, swapchain);
         return result;
     }
 
@@ -494,7 +458,7 @@
 VkResult DestroySwapchainKHR(VkDevice device, VkSwapchainKHR swapchain_handle) {
     const DeviceVtbl& driver_vtbl = GetDriverVtbl(device);
     Swapchain* swapchain = SwapchainFromHandle(swapchain_handle);
-    const std::shared_ptr<ANativeWindow>& window = swapchain->window;
+    const std::shared_ptr<ANativeWindow>& window = swapchain->surface.window;
 
     for (uint32_t i = 0; i < swapchain->num_images; i++) {
         Swapchain::Image& img = swapchain->images[i];
@@ -509,9 +473,8 @@
         }
     }
 
-    native_window_api_disconnect(window.get(), NATIVE_WINDOW_API_EGL);
     swapchain->~Swapchain();
-    FreeDeviceMem(device, swapchain);
+    FreeMem(device, swapchain);
 
     return VK_SUCCESS;
 }
@@ -541,6 +504,7 @@
                              VkSemaphore semaphore,
                              uint32_t* image_index) {
     Swapchain& swapchain = *SwapchainFromHandle(swapchain_handle);
+    ANativeWindow* window = swapchain.surface.window.get();
     VkResult result;
     int err;
 
@@ -550,8 +514,7 @@
 
     ANativeWindowBuffer* buffer;
     int fence;
-    err = swapchain.window->dequeueBuffer(swapchain.window.get(), &buffer,
-                                          &fence);
+    err = window->dequeueBuffer(window, &buffer, &fence);
     if (err != 0) {
         // TODO(jessehall): Improve error reporting. Can we enumerate possible
         // errors and translate them to valid Vulkan result codes?
@@ -569,7 +532,7 @@
     }
     if (idx == swapchain.num_images) {
         ALOGE("dequeueBuffer returned unrecognized buffer");
-        swapchain.window->cancelBuffer(swapchain.window.get(), buffer, fence);
+        window->cancelBuffer(window, buffer, fence);
 #pragma clang diagnostic push
 #pragma clang diagnostic ignored "-Wold-style-cast"
         return VK_ERROR_OUT_OF_DATE_KHR;
@@ -605,7 +568,7 @@
         // number between the time the driver closes it and the time we close
         // it. We must assume one of: the driver *always* closes it even on
         // failure, or *never* closes it on failure.
-        swapchain.window->cancelBuffer(swapchain.window.get(), buffer, fence);
+        window->cancelBuffer(window, buffer, fence);
         swapchain.images[idx].dequeued = false;
         swapchain.images[idx].dequeue_fence = -1;
         return result;
@@ -630,6 +593,7 @@
     for (uint32_t sc = 0; sc < present_info->swapchainCount; sc++) {
         Swapchain& swapchain =
             *SwapchainFromHandle(present_info->swapchains[sc]);
+        ANativeWindow* window = swapchain.surface.window.get();
         uint32_t image_idx = present_info->imageIndices[sc];
         Swapchain::Image& img = swapchain.images[image_idx];
         VkResult result;
@@ -656,8 +620,7 @@
             continue;
         }
 
-        err = swapchain.window->queueBuffer(swapchain.window.get(),
-                                            img.buffer.get(), fence);
+        err = window->queueBuffer(window, img.buffer.get(), fence);
         if (err != 0) {
             // TODO(jessehall): What now? We should probably cancel the buffer,
             // I guess?