[PATCH v2 1/3] winevulkan/winex11: Add Vulkan WSI stubs (VK_KHR_surface / VK_KHR_swapchain).

Józef Kucia jkucia at codeweavers.com
Mon Mar 12 09:37:53 CDT 2018


From: Roderick Colenbrander <thunderbird2k at gmail.com>

The WSI APIs are meant for window system integration, so essentially the WGL
of Vulkan. Implementation belongs in the graphics drivers as we need to hook
into surface and swapchains.

Signed-off-by: Roderick Colenbrander <thunderbird2k at gmail.com>
Signed-off-by: Józef Kucia <jkucia at codeweavers.com>
---

Version 2:
* Fix subject.
* Use %u for unsigned integer.
* Minor coding style fixes.
* Use "static const" if possible.

---
 dlls/winevulkan/make_vulkan     | 114 +++++++++++++++++++++++++++++-
 dlls/winevulkan/vulkan.c        | 153 ++++++++++++++++++++++++++++++++++++++++
 dlls/winevulkan/vulkan_thunks.c |  12 ++++
 dlls/winevulkan/vulkan_thunks.h |  34 +++++++++
 dlls/winex11.drv/vulkan.c       | 151 ++++++++++++++++++++++++++++++++++++---
 include/wine/vulkan.h           | 130 ++++++++++++++++++++++++++++++++++
 include/wine/vulkan_driver.h    |  14 +++-
 7 files changed, 597 insertions(+), 11 deletions(-)

diff --git a/dlls/winevulkan/make_vulkan b/dlls/winevulkan/make_vulkan
index 04896daafb8f..5fff3f1511a1 100755
--- a/dlls/winevulkan/make_vulkan
+++ b/dlls/winevulkan/make_vulkan
@@ -68,10 +68,27 @@ WINE_VULKAN_DRIVER_H = "../../include/wine/vulkan_driver.h"
 WINE_VULKAN_THUNKS_C = "vulkan_thunks.c"
 WINE_VULKAN_THUNKS_H = "vulkan_thunks.h"
 
+# Extension enum values start at a certain offset (EXT_BASE).
+# Relative to the offset each extension has a block (EXT_BLOCK_SIZE)
+# of values.
+# Start for a given extension is:
+# EXT_BASE + (extension_number-1) * EXT_BLOCK_SIZE
+EXT_BASE = 1000000000
+EXT_BLOCK_SIZE = 1000
+
+# In general instance extensions can't be automatically generated
+# and need custom wrappers due to e.g. win32 / X11 specific code.
+# List of supported instance extensions.
+SUPPORTED_EXTENSIONS = [
+    "VK_KHR_surface",
+    "VK_KHR_win32_surface",
+    "VK_KHR_swapchain",
+]
+
 # Functions part of our winevulkan graphics driver interface.
 # DRIVER_VERSION should be bumped on any change to driver interface
 # in FUNCTION_OVERRIDES
-DRIVER_VERSION = 2
+DRIVER_VERSION = 3
 
 # Table of functions for which we have a special implementation.
 # This are regular device / instance functions for which we need
@@ -96,6 +113,24 @@ FUNCTION_OVERRIDES = {
     # Device functions
     "vkDestroyDevice" : {"dispatch" : True, "driver" : False, "thunk" : False},
     "vkGetDeviceProcAddr" : {"dispatch" : True, "driver" : True, "thunk" : False},
+
+    # VK_KHR_surface
+    "vkDestroySurfaceKHR" : {"dispatch" : True, "driver" : True, "thunk" : False},
+    "vkGetPhysicalDeviceSurfaceSupportKHR" : {"dispatch" : True, "driver" : True, "thunk" : False},
+    "vkGetPhysicalDeviceSurfaceCapabilitiesKHR" : {"dispatch" : True, "driver" : True, "thunk" : False},
+    "vkGetPhysicalDeviceSurfaceFormatsKHR" : {"dispatch" : True, "driver" : True, "thunk" : False},
+    "vkGetPhysicalDeviceSurfacePresentModesKHR" : {"dispatch" : True, "driver" : True, "thunk" : False},
+
+    # VK_KHR_win32_surface
+    "vkCreateWin32SurfaceKHR" : {"dispatch" : True, "driver" : True, "thunk" : False},
+    "vkGetPhysicalDeviceWin32PresentationSupportKHR" : {"dispatch" : True, "driver" : True, "thunk" : False},
+
+    # VK_KHR_swapchain
+    "vkAcquireNextImageKHR": {"dispatch" : True, "driver" : True, "thunk" : False},
+    "vkCreateSwapchainKHR" : {"dispatch" : True, "driver" : True, "thunk" : False},
+    "vkDestroySwapchainKHR" : {"dispatch" : True, "driver" : True, "thunk" : False},
+    "vkGetSwapchainImagesKHR": {"dispatch" : True, "driver" : True, "thunk" : False},
+    "vkQueuePresentKHR": {"dispatch" : True, "driver" : True, "thunk" : False},
 }
 
 
@@ -356,6 +391,11 @@ class VkFunction(object):
 
     def needs_stub(self):
         """ Temporary function to limit script hacks until more code is implemented. """
+
+        # Temporary hack to pull in VkSwapChainCreateInfoKHR.
+        if self.name == "vkCreateSwapchainKHR":
+            return False
+
         if self.params[0].type != "VkPhysicalDevice":
             return True
 
@@ -1997,6 +2037,7 @@ class VkRegistry(object):
 
         # Pull in any required types and functions.
         self._parse_features(root)
+        self._parse_extensions(root)
 
     def _mark_command_required(self, command):
         """ Helper function to mark a certain command and the datatypes it needs as required."""
@@ -2099,6 +2140,77 @@ class VkRegistry(object):
 
         self.enums = OrderedDict(sorted(enums.items()))
 
+    def _parse_extensions(self, root):
+        """ Parse extensions section and pull in any types and commands for this extensioin. """
+        extensions = []
+        exts = root.findall("./extensions/extension")
+        for ext in exts:
+            ext_name = ext.attrib["name"]
+
+            # Some extensions are not ready or have numbers reserved as a place holder.
+            if ext.attrib["supported"] == "disabled":
+                LOGGER.debug("Skipping disabled extension: {0}".format(ext_name))
+                continue
+
+            # We only support a handful of extensions for now through a whitelist.
+            if ext_name not in SUPPORTED_EXTENSIONS:
+                LOGGER.debug("Skipping blacklisted extension: {0}".format(ext_name))
+                continue
+
+            LOGGER.debug("Loading extension: {0}".format(ext_name))
+
+            # Extensions can add enum values to Core / extension enums, so add these.
+            enums = ext.findall("require/enum")
+            for enum_elem in enums:
+                if "bitpos" in enum_elem.keys():
+                    # We need to add an extra value to an existing enum type.
+                    # E.g. VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_CUBIC_BIT_IMG to VkFormatFeatureFlagBits.
+                    type_name = enum_elem.attrib["extends"]
+                    enum = self.types[type_name]["data"]
+                    enum.add(VkEnumValue(enum_elem.attrib["name"], 1 << int(enum_elem.attrib["bitpos"]), hex=True))
+                elif "offset" in enum_elem.keys():
+                    ext_number = int(ext.attrib["number"])
+                    offset = int(enum_elem.attrib["offset"])
+                    value = EXT_BASE + (ext_number - 1) * EXT_BLOCK_SIZE + offset
+
+                    # Deal with negative values.
+                    direction = enum_elem.attrib.get("dir")
+                    if direction is not None:
+                        value = -value
+
+                    type_name = enum_elem.attrib["extends"]
+                    enum = self.types[type_name]["data"]
+                    enum.add(VkEnumValue(enum_elem.attrib["name"], value))
+
+                elif "value" in enum_elem.keys():
+                    # For now skip, it mostly contains extension name and version info.
+                    continue
+                else:
+                    # This seems to be used to pull in constants e.g. VK_MAX_DEVICE_GROUP_KHX
+                    continue
+
+            # Store a list with extensions.
+            ext_type = ext.attrib["type"]
+            ext_info = {"name" : ext_name, "type" : ext_type}
+            extensions.append(ext_info)
+
+            commands = ext.findall("require/command")
+            if not commands:
+                continue
+
+            # Pull in any commands we need. We infer types to pull in from the command
+            # as well.
+            for command in commands:
+                cmd_name = command.attrib["name"]
+                self._mark_command_required(cmd_name)
+
+                # Set extension name on the function call as we were not aware of the
+                # name during initial parsing.
+                self.funcs[cmd_name].extension = ext_name
+
+        # Sort in alphabetical order.
+        self.extensions = sorted(extensions, key=lambda ext: ext["name"])
+
     def _parse_features(self, root):
         """ Parse the feature section, which describes Core commands and types needed. """
         requires = root.findall("./feature/require")
diff --git a/dlls/winevulkan/vulkan.c b/dlls/winevulkan/vulkan.c
index 678506fbb0e5..61af8df8b848 100644
--- a/dlls/winevulkan/vulkan.c
+++ b/dlls/winevulkan/vulkan.c
@@ -162,6 +162,17 @@ static void wine_vk_instance_free(struct VkInstance_T *instance)
     heap_free(instance);
 }
 
+VkResult WINAPI wine_vkAcquireNextImageKHR(VkDevice device, VkSwapchainKHR swapchain,
+        uint64_t timeout, VkSemaphore semaphore, VkFence fence, uint32_t *image_index)
+{
+    TRACE("%p, 0x%s, 0x%s, 0x%s, 0x%s, %p\n", device, wine_dbgstr_longlong(swapchain),
+            wine_dbgstr_longlong(timeout), wine_dbgstr_longlong(semaphore),
+            wine_dbgstr_longlong(fence), image_index);
+
+    return vk_funcs->p_vkAcquireNextImageKHR(device->device, swapchain, timeout,
+            semaphore, fence, image_index);
+}
+
 VkResult WINAPI wine_vkCreateDevice(VkPhysicalDevice phys_dev,
         const VkDeviceCreateInfo *create_info,
         const VkAllocationCallbacks *allocator, VkDevice *device)
@@ -271,6 +282,72 @@ err:
     return res;
 }
 
+#if defined(USE_STRUCT_CONVERSION)
+static inline void convert_VkSwapchainCreateInfoKHR_win_to_host(const VkSwapchainCreateInfoKHR *in,
+        VkSwapchainCreateInfoKHR_host *out)
+{
+    if (!in) return;
+
+    out->sType = in->sType;
+    out->pNext = in->pNext;
+    out->flags = in->flags;
+    out->surface = in->surface;
+    out->minImageCount = in->minImageCount;
+    out->imageFormat = in->imageFormat;
+    out->imageColorSpace = in->imageColorSpace;
+    out->imageExtent = in->imageExtent;
+    out->imageArrayLayers = in->imageArrayLayers;
+    out->imageUsage = in->imageUsage;
+    out->imageSharingMode = in->imageSharingMode;
+    out->queueFamilyIndexCount = in->queueFamilyIndexCount;
+    out->pQueueFamilyIndices = in->pQueueFamilyIndices;
+    out->preTransform = in->preTransform;
+    out->compositeAlpha = in->compositeAlpha;
+    out->presentMode = in->presentMode;
+    out->clipped = in->clipped;
+    out->oldSwapchain = in->oldSwapchain;
+}
+#endif
+
+VkResult WINAPI wine_vkCreateSwapchainKHR(VkDevice device,
+        const VkSwapchainCreateInfoKHR *create_info,
+        const VkAllocationCallbacks *allocator, VkSwapchainKHR *swapchain)
+{
+#if defined(USE_STRUCT_CONVERSION)
+    VkSwapchainCreateInfoKHR_host create_info_host;
+    TRACE("%p %p %p %p\n", device, create_info, allocator, swapchain);
+
+    if (allocator)
+        FIXME("Support allocation allocators\n");
+
+    convert_VkSwapchainCreateInfoKHR_win_to_host(create_info, &create_info_host);
+
+    /* Wine graphics driver only uses structs in host format. */
+    return vk_funcs->p_vkCreateSwapchainKHR(device->device,
+            (VkSwapchainCreateInfoKHR *)&create_info_host, allocator, swapchain);
+#else
+    TRACE("%p %p %p %p\n", device, create_info, allocator, swapchain);
+
+    if (allocator)
+        FIXME("Support allocation allocators\n");
+
+    return vk_funcs->p_vkCreateSwapchainKHR(device->device, create_info, allocator, swapchain);
+#endif
+}
+
+VkResult WINAPI wine_vkCreateWin32SurfaceKHR(VkInstance instance,
+        const VkWin32SurfaceCreateInfoKHR *create_info,
+        const VkAllocationCallbacks* allocator, VkSurfaceKHR* surface)
+{
+    TRACE("%p %p %p %p\n", instance, create_info, allocator, surface);
+
+    if (allocator)
+        FIXME("Support allocation allocators\n");
+
+    return vk_funcs->p_vkCreateWin32SurfaceKHR(instance->instance, create_info,
+            NULL /* allocator */, surface);
+}
+
 void WINAPI wine_vkDestroyDevice(VkDevice device, const VkAllocationCallbacks *allocator)
 {
     TRACE("%p %p\n", device, allocator);
@@ -291,6 +368,28 @@ void WINAPI wine_vkDestroyInstance(VkInstance instance, const VkAllocationCallba
     wine_vk_instance_free(instance);
 }
 
+void WINAPI wine_vkDestroySurfaceKHR(VkInstance instance, VkSurfaceKHR surface,
+        const VkAllocationCallbacks *allocator)
+{
+    TRACE("%p, 0x%s, %p\n", instance, wine_dbgstr_longlong(surface), allocator);
+
+    if (allocator)
+        FIXME("Support allocation allocators\n");
+
+    vk_funcs->p_vkDestroySurfaceKHR(instance->instance, surface, NULL /* allocator */);
+}
+
+void WINAPI wine_vkDestroySwapchainKHR(VkDevice device, VkSwapchainKHR swapchain,
+        const VkAllocationCallbacks *allocator)
+{
+    TRACE("%p, 0x%s %p\n", device, wine_dbgstr_longlong(swapchain), allocator);
+
+    if (allocator)
+        FIXME("Support allocation allocators\n");
+
+    vk_funcs->p_vkDestroySwapchainKHR(device->device, swapchain, NULL /* allocator */);
+}
+
 VkResult WINAPI wine_vkEnumerateDeviceExtensionProperties(VkPhysicalDevice phys_dev,
         const char *layer_name, uint32_t *count, VkExtensionProperties *properties)
 {
@@ -418,6 +517,60 @@ static PFN_vkVoidFunction WINAPI wine_vkGetInstanceProcAddr(VkInstance instance,
     return NULL;
 }
 
+VkResult WINAPI wine_vkGetPhysicalDeviceSurfaceCapabilitiesKHR(VkPhysicalDevice phys_dev,
+        VkSurfaceKHR surface, VkSurfaceCapabilitiesKHR *capabilities)
+{
+    TRACE("%p, 0x%s, %p\n", phys_dev, wine_dbgstr_longlong(surface), capabilities);
+    return vk_funcs->p_vkGetPhysicalDeviceSurfaceCapabilitiesKHR(phys_dev->phys_dev,
+            surface, capabilities);
+}
+
+VkResult WINAPI wine_vkGetPhysicalDeviceSurfaceFormatsKHR(VkPhysicalDevice phys_dev,
+        VkSurfaceKHR surface, uint32_t *format_count, VkSurfaceFormatKHR *formats)
+{
+    TRACE("%p, 0x%s, %p, %p\n", phys_dev, wine_dbgstr_longlong(surface), format_count, formats);
+    return vk_funcs->p_vkGetPhysicalDeviceSurfaceFormatsKHR(phys_dev->phys_dev,
+            surface, format_count, formats);
+}
+
+VkResult WINAPI wine_vkGetPhysicalDeviceSurfacePresentModesKHR(VkPhysicalDevice phys_dev,
+        VkSurfaceKHR surface, uint32_t *mode_count, VkPresentModeKHR *modes)
+{
+    TRACE("%p, 0x%s, %p, %p\n", phys_dev, wine_dbgstr_longlong(surface), mode_count, modes);
+    return vk_funcs->p_vkGetPhysicalDeviceSurfacePresentModesKHR(phys_dev->phys_dev,
+            surface, mode_count, modes);
+}
+
+VkResult WINAPI wine_vkGetPhysicalDeviceSurfaceSupportKHR(VkPhysicalDevice phys_dev,
+        uint32_t queue_family_index, VkSurfaceKHR surface, VkBool32 *supported)
+{
+    TRACE("%p, %u, 0x%s, %p\n", phys_dev, queue_family_index, wine_dbgstr_longlong(surface), supported);
+    return vk_funcs->p_vkGetPhysicalDeviceSurfaceSupportKHR(phys_dev->phys_dev,
+            queue_family_index, surface, supported);
+}
+
+VkBool32 WINAPI wine_vkGetPhysicalDeviceWin32PresentationSupportKHR(VkPhysicalDevice phys_dev,
+        uint32_t queue_family_index)
+{
+    TRACE("%p %u\n", phys_dev, queue_family_index);
+    return vk_funcs->p_vkGetPhysicalDeviceWin32PresentationSupportKHR(phys_dev->phys_dev,
+            queue_family_index);
+}
+
+VkResult WINAPI wine_vkGetSwapchainImagesKHR(VkDevice device, VkSwapchainKHR swapchain,
+        uint32_t *image_count, VkImage *images)
+{
+    TRACE("%p, 0x%s %p %p\n", device, wine_dbgstr_longlong(swapchain), image_count, images);
+    return vk_funcs->p_vkGetSwapchainImagesKHR(device->device, swapchain,
+            image_count, images);
+}
+
+VkResult WINAPI wine_vkQueuePresentKHR(VkQueue queue, const VkPresentInfoKHR *present_info)
+{
+    FIXME("stub: %p, %p\n", queue, present_info);
+    return VK_ERROR_OUT_OF_HOST_MEMORY;
+}
+
 void * WINAPI wine_vk_icdGetInstanceProcAddr(VkInstance instance, const char *name)
 {
     TRACE("%p %s\n", instance, debugstr_a(name));
diff --git a/dlls/winevulkan/vulkan_thunks.c b/dlls/winevulkan/vulkan_thunks.c
index 3670926c3edf..5d9826cd6756 100644
--- a/dlls/winevulkan/vulkan_thunks.c
+++ b/dlls/winevulkan/vulkan_thunks.c
@@ -895,6 +895,7 @@ static VkResult WINAPI wine_vkWaitForFences(VkDevice device, uint32_t fenceCount
 
 static const struct vulkan_func vk_device_dispatch_table[] =
 {
+    {"vkAcquireNextImageKHR", &wine_vkAcquireNextImageKHR},
     {"vkAllocateCommandBuffers", &wine_vkAllocateCommandBuffers},
     {"vkAllocateDescriptorSets", &wine_vkAllocateDescriptorSets},
     {"vkAllocateMemory", &wine_vkAllocateMemory},
@@ -964,6 +965,7 @@ static const struct vulkan_func vk_device_dispatch_table[] =
     {"vkCreateSampler", &wine_vkCreateSampler},
     {"vkCreateSemaphore", &wine_vkCreateSemaphore},
     {"vkCreateShaderModule", &wine_vkCreateShaderModule},
+    {"vkCreateSwapchainKHR", &wine_vkCreateSwapchainKHR},
     {"vkDestroyBuffer", &wine_vkDestroyBuffer},
     {"vkDestroyBufferView", &wine_vkDestroyBufferView},
     {"vkDestroyCommandPool", &wine_vkDestroyCommandPool},
@@ -983,6 +985,7 @@ static const struct vulkan_func vk_device_dispatch_table[] =
     {"vkDestroySampler", &wine_vkDestroySampler},
     {"vkDestroySemaphore", &wine_vkDestroySemaphore},
     {"vkDestroyShaderModule", &wine_vkDestroyShaderModule},
+    {"vkDestroySwapchainKHR", &wine_vkDestroySwapchainKHR},
     {"vkDeviceWaitIdle", &wine_vkDeviceWaitIdle},
     {"vkEndCommandBuffer", &wine_vkEndCommandBuffer},
     {"vkFlushMappedMemoryRanges", &wine_vkFlushMappedMemoryRanges},
@@ -1001,10 +1004,12 @@ static const struct vulkan_func vk_device_dispatch_table[] =
     {"vkGetPipelineCacheData", &wine_vkGetPipelineCacheData},
     {"vkGetQueryPoolResults", &wine_vkGetQueryPoolResults},
     {"vkGetRenderAreaGranularity", &wine_vkGetRenderAreaGranularity},
+    {"vkGetSwapchainImagesKHR", &wine_vkGetSwapchainImagesKHR},
     {"vkInvalidateMappedMemoryRanges", &wine_vkInvalidateMappedMemoryRanges},
     {"vkMapMemory", &wine_vkMapMemory},
     {"vkMergePipelineCaches", &wine_vkMergePipelineCaches},
     {"vkQueueBindSparse", &wine_vkQueueBindSparse},
+    {"vkQueuePresentKHR", &wine_vkQueuePresentKHR},
     {"vkQueueSubmit", &wine_vkQueueSubmit},
     {"vkQueueWaitIdle", &wine_vkQueueWaitIdle},
     {"vkResetCommandBuffer", &wine_vkResetCommandBuffer},
@@ -1021,7 +1026,9 @@ static const struct vulkan_func vk_device_dispatch_table[] =
 static const struct vulkan_func vk_instance_dispatch_table[] =
 {
     {"vkCreateDevice", &wine_vkCreateDevice},
+    {"vkCreateWin32SurfaceKHR", &wine_vkCreateWin32SurfaceKHR},
     {"vkDestroyInstance", &wine_vkDestroyInstance},
+    {"vkDestroySurfaceKHR", &wine_vkDestroySurfaceKHR},
     {"vkEnumerateDeviceExtensionProperties", &wine_vkEnumerateDeviceExtensionProperties},
     {"vkEnumerateDeviceLayerProperties", &wine_vkEnumerateDeviceLayerProperties},
     {"vkEnumeratePhysicalDevices", &wine_vkEnumeratePhysicalDevices},
@@ -1032,6 +1039,11 @@ static const struct vulkan_func vk_instance_dispatch_table[] =
     {"vkGetPhysicalDeviceProperties", &wine_vkGetPhysicalDeviceProperties},
     {"vkGetPhysicalDeviceQueueFamilyProperties", &wine_vkGetPhysicalDeviceQueueFamilyProperties},
     {"vkGetPhysicalDeviceSparseImageFormatProperties", &wine_vkGetPhysicalDeviceSparseImageFormatProperties},
+    {"vkGetPhysicalDeviceSurfaceCapabilitiesKHR", &wine_vkGetPhysicalDeviceSurfaceCapabilitiesKHR},
+    {"vkGetPhysicalDeviceSurfaceFormatsKHR", &wine_vkGetPhysicalDeviceSurfaceFormatsKHR},
+    {"vkGetPhysicalDeviceSurfacePresentModesKHR", &wine_vkGetPhysicalDeviceSurfacePresentModesKHR},
+    {"vkGetPhysicalDeviceSurfaceSupportKHR", &wine_vkGetPhysicalDeviceSurfaceSupportKHR},
+    {"vkGetPhysicalDeviceWin32PresentationSupportKHR", &wine_vkGetPhysicalDeviceWin32PresentationSupportKHR},
 };
 
 void *wine_vk_get_device_proc_addr(const char *name)
diff --git a/dlls/winevulkan/vulkan_thunks.h b/dlls/winevulkan/vulkan_thunks.h
index daf679b17591..a91612e62b69 100644
--- a/dlls/winevulkan/vulkan_thunks.h
+++ b/dlls/winevulkan/vulkan_thunks.h
@@ -13,12 +13,46 @@ void *wine_vk_get_device_proc_addr(const char *name) DECLSPEC_HIDDEN;
 void *wine_vk_get_instance_proc_addr(const char *name) DECLSPEC_HIDDEN;
 
 /* Functions for which we have custom implementations outside of the thunks. */
+VkResult WINAPI wine_vkAcquireNextImageKHR(VkDevice device, VkSwapchainKHR swapchain, uint64_t timeout, VkSemaphore semaphore, VkFence fence, uint32_t *pImageIndex) DECLSPEC_HIDDEN;
 VkResult WINAPI wine_vkCreateDevice(VkPhysicalDevice physicalDevice, const VkDeviceCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkDevice *pDevice) DECLSPEC_HIDDEN;
+VkResult WINAPI wine_vkCreateSwapchainKHR(VkDevice device, const VkSwapchainCreateInfoKHR *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkSwapchainKHR *pSwapchain) DECLSPEC_HIDDEN;
+VkResult WINAPI wine_vkCreateWin32SurfaceKHR(VkInstance instance, const VkWin32SurfaceCreateInfoKHR *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface) DECLSPEC_HIDDEN;
 void WINAPI wine_vkDestroyDevice(VkDevice device, const VkAllocationCallbacks *pAllocator) DECLSPEC_HIDDEN;
 void WINAPI wine_vkDestroyInstance(VkInstance instance, const VkAllocationCallbacks *pAllocator) DECLSPEC_HIDDEN;
+void WINAPI wine_vkDestroySurfaceKHR(VkInstance instance, VkSurfaceKHR surface, const VkAllocationCallbacks *pAllocator) DECLSPEC_HIDDEN;
+void WINAPI wine_vkDestroySwapchainKHR(VkDevice device, VkSwapchainKHR swapchain, const VkAllocationCallbacks *pAllocator) DECLSPEC_HIDDEN;
 VkResult WINAPI wine_vkEnumerateDeviceExtensionProperties(VkPhysicalDevice physicalDevice, const char *pLayerName, uint32_t *pPropertyCount, VkExtensionProperties *pProperties) DECLSPEC_HIDDEN;
 VkResult WINAPI wine_vkEnumeratePhysicalDevices(VkInstance instance, uint32_t *pPhysicalDeviceCount, VkPhysicalDevice *pPhysicalDevices) DECLSPEC_HIDDEN;
 PFN_vkVoidFunction WINAPI wine_vkGetDeviceProcAddr(VkDevice device, const char *pName) DECLSPEC_HIDDEN;
+VkResult WINAPI wine_vkGetPhysicalDeviceSurfaceCapabilitiesKHR(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface, VkSurfaceCapabilitiesKHR *pSurfaceCapabilities) DECLSPEC_HIDDEN;
+VkResult WINAPI wine_vkGetPhysicalDeviceSurfaceFormatsKHR(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface, uint32_t *pSurfaceFormatCount, VkSurfaceFormatKHR *pSurfaceFormats) DECLSPEC_HIDDEN;
+VkResult WINAPI wine_vkGetPhysicalDeviceSurfacePresentModesKHR(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface, uint32_t *pPresentModeCount, VkPresentModeKHR *pPresentModes) DECLSPEC_HIDDEN;
+VkResult WINAPI wine_vkGetPhysicalDeviceSurfaceSupportKHR(VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex, VkSurfaceKHR surface, VkBool32 *pSupported) DECLSPEC_HIDDEN;
+VkBool32 WINAPI wine_vkGetPhysicalDeviceWin32PresentationSupportKHR(VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex) DECLSPEC_HIDDEN;
+VkResult WINAPI wine_vkGetSwapchainImagesKHR(VkDevice device, VkSwapchainKHR swapchain, uint32_t *pSwapchainImageCount, VkImage *pSwapchainImages) DECLSPEC_HIDDEN;
+VkResult WINAPI wine_vkQueuePresentKHR(VkQueue queue, const VkPresentInfoKHR *pPresentInfo) DECLSPEC_HIDDEN;
+
+typedef struct VkSwapchainCreateInfoKHR_host
+{
+    VkStructureType sType;
+    const void *pNext;
+    VkSwapchainCreateFlagsKHR flags;
+    VkSurfaceKHR surface;
+    uint32_t minImageCount;
+    VkFormat imageFormat;
+    VkColorSpaceKHR imageColorSpace;
+    VkExtent2D imageExtent;
+    uint32_t imageArrayLayers;
+    VkImageUsageFlags imageUsage;
+    VkSharingMode imageSharingMode;
+    uint32_t queueFamilyIndexCount;
+    const uint32_t *pQueueFamilyIndices;
+    VkSurfaceTransformFlagBitsKHR preTransform;
+    VkCompositeAlphaFlagBitsKHR compositeAlpha;
+    VkPresentModeKHR presentMode;
+    VkBool32 clipped;
+    VkSwapchainKHR oldSwapchain;
+} VkSwapchainCreateInfoKHR_host;
 
 typedef struct VkImageFormatProperties_host
 {
diff --git a/dlls/winex11.drv/vulkan.c b/dlls/winex11.drv/vulkan.c
index c99ca66168e0..fe50d666abef 100644
--- a/dlls/winex11.drv/vulkan.c
+++ b/dlls/winex11.drv/vulkan.c
@@ -27,6 +27,10 @@
 
 #include "wine/debug.h"
 #include "wine/library.h"
+
+/* We only want host compatible structures and don't need alignment. */
+#define WINE_VK_ALIGN(x)
+
 #include "wine/vulkan.h"
 #include "wine/vulkan_driver.h"
 
@@ -34,11 +38,22 @@
 
 WINE_DEFAULT_DEBUG_CHANNEL(vulkan);
 
+#ifndef ARRAY_SIZE
+#define ARRAY_SIZE(array) (sizeof(array) / sizeof((array)[0]))
+#endif
+
 static VkResult (*pvkCreateInstance)(const VkInstanceCreateInfo *, const VkAllocationCallbacks *, VkInstance *);
 static void (*pvkDestroyInstance)(VkInstance, const VkAllocationCallbacks *);
 static void * (*pvkGetDeviceProcAddr)(VkDevice, const char *);
 static void * (*pvkGetInstanceProcAddr)(VkInstance, const char *);
 
+/* TODO: dynamically generate based on host driver capabilities. */
+static const struct VkExtensionProperties winex11_vk_instance_extensions[] =
+{
+    { "VK_KHR_surface", 1 },
+    { "VK_KHR_win32_surface", 1},
+};
+
 static BOOL wine_vk_init(void)
 {
     static BOOL init_done = FALSE;
@@ -59,6 +74,16 @@ LOAD_FUNCPTR(vkGetInstanceProcAddr)
     return TRUE;
 }
 
+static VkResult X11DRV_vkAcquireNextImageKHR(VkDevice device, VkSwapchainKHR swapchain,
+        uint64_t timeout, VkSemaphore semaphore, VkFence fence, uint32_t *index)
+{
+    FIXME("stub: %p, 0x%s, 0x%s, 0x%s, 0x%s, %p\n", device,
+            wine_dbgstr_longlong(swapchain), wine_dbgstr_longlong(timeout),
+            wine_dbgstr_longlong(semaphore), wine_dbgstr_longlong(fence), index);
+
+    return VK_ERROR_OUT_OF_HOST_MEMORY;
+}
+
 static VkResult X11DRV_vkCreateInstance(const VkInstanceCreateInfo *create_info,
         const VkAllocationCallbacks *allocator, VkInstance *instance)
 {
@@ -77,6 +102,22 @@ static VkResult X11DRV_vkCreateInstance(const VkInstanceCreateInfo *create_info,
     return pvkCreateInstance(create_info, NULL /* allocator */, instance);
 }
 
+static VkResult X11DRV_vkCreateSwapchainKHR(VkDevice device,
+        const VkSwapchainCreateInfoKHR *create_info,
+        const VkAllocationCallbacks *allocator, VkSwapchainKHR *swapchain)
+{
+    FIXME("stub: %p %p %p %p\n", device, create_info, allocator, swapchain);
+    return VK_ERROR_OUT_OF_HOST_MEMORY;
+}
+
+static VkResult X11DRV_vkCreateWin32SurfaceKHR(VkInstance instance,
+        const VkWin32SurfaceCreateInfoKHR *create_info,
+        const VkAllocationCallbacks *allocator, VkSurfaceKHR *surface)
+{
+    FIXME("stub: %p %p %p %p\n", instance, create_info, allocator, surface);
+    return VK_ERROR_OUT_OF_HOST_MEMORY;
+}
+
 static void X11DRV_vkDestroyInstance(VkInstance instance, const VkAllocationCallbacks *allocator)
 {
     TRACE("%p %p\n", instance, allocator);
@@ -87,10 +128,25 @@ static void X11DRV_vkDestroyInstance(VkInstance instance, const VkAllocationCall
     pvkDestroyInstance(instance, NULL /* allocator */);
 }
 
+static void X11DRV_vkDestroySurfaceKHR(VkInstance instance, VkSurfaceKHR surface,
+        const VkAllocationCallbacks *allocator)
+{
+    FIXME("stub: %p 0x%s %p\n", instance, wine_dbgstr_longlong(surface), allocator);
+}
+
+static void X11DRV_vkDestroySwapchainKHR(VkDevice device, VkSwapchainKHR swapchain,
+         const VkAllocationCallbacks *allocator)
+{
+    FIXME("stub: %p, 0x%s %p\n", device, wine_dbgstr_longlong(swapchain), allocator);
+}
+
 static VkResult X11DRV_vkEnumerateInstanceExtensionProperties(const char *layer_name,
         uint32_t *count, VkExtensionProperties* properties)
 {
-    TRACE("layer_name %s, count %p, properties %p\n", debugstr_a(layer_name), count, properties);
+    VkResult res;
+    unsigned int i, num_copies;
+
+    TRACE("layer_name %p, count %p, properties %p\n", debugstr_a(layer_name), count, properties);
 
     /* This shouldn't get called with layer_name set, the ICD loader prevents it. */
     if (layer_name)
@@ -106,16 +162,32 @@ static VkResult X11DRV_vkEnumerateInstanceExtensionProperties(const char *layer_
          * VK_KHR_win32_surface. Long-term this needs to be an intersection
          * between what the native library supports and what thunks we have.
          */
-        *count = 0;
+        *count = ARRAY_SIZE(winex11_vk_instance_extensions);
         return VK_SUCCESS;
     }
 
-    /* When properties is not NULL, we copy the extensions over and set count
-     * to the number of copied extensions. For now we don't have much to do as
-     * we don't support any extensions yet.
-     */
-    *count = 0;
-    return VK_SUCCESS;
+    if (*count < ARRAY_SIZE(winex11_vk_instance_extensions))
+    {
+        /* Incomplete is a type of success used to signal the application
+         * that not all devices got copied.
+         */
+        num_copies = *count;
+        res = VK_INCOMPLETE;
+    }
+    else
+    {
+        num_copies = ARRAY_SIZE(winex11_vk_instance_extensions);
+        res = VK_SUCCESS;
+    }
+
+    for (i = 0; i < num_copies; i++)
+    {
+        memcpy(&properties[i], &winex11_vk_instance_extensions[i], sizeof(winex11_vk_instance_extensions[i]));
+    }
+    *count = num_copies;
+
+    TRACE("Result %d, extensions copied %u\n", res, num_copies);
+    return res;
 }
 
 static void * X11DRV_vkGetDeviceProcAddr(VkDevice device, const char *name)
@@ -130,13 +202,74 @@ static void * X11DRV_vkGetInstanceProcAddr(VkInstance instance, const char *name
     return pvkGetInstanceProcAddr(instance, name);
 }
 
+static VkResult X11DRV_vkGetPhysicalDeviceSurfaceCapabilitiesKHR(VkPhysicalDevice phys_dev,
+        VkSurfaceKHR surface, VkSurfaceCapabilitiesKHR *capabilities)
+{
+    FIXME("stub: %p, 0x%s, %p\n", phys_dev, wine_dbgstr_longlong(surface), capabilities);
+    return VK_ERROR_OUT_OF_HOST_MEMORY;
+}
+
+static VkResult X11DRV_vkGetPhysicalDeviceSurfaceFormatsKHR(VkPhysicalDevice phys_dev,
+        VkSurfaceKHR surface, uint32_t *count, VkSurfaceFormatKHR *formats)
+{
+    FIXME("stub: %p, 0x%s, %p, %p\n", phys_dev, wine_dbgstr_longlong(surface), count, formats);
+    return VK_ERROR_OUT_OF_HOST_MEMORY;
+}
+
+static VkResult X11DRV_vkGetPhysicalDeviceSurfacePresentModesKHR(VkPhysicalDevice phys_dev,
+        VkSurfaceKHR surface, uint32_t *count, VkPresentModeKHR *modes)
+{
+    FIXME("stub: %p, 0x%s, %p, %p\n", phys_dev, wine_dbgstr_longlong(surface), count, modes);
+    return VK_ERROR_OUT_OF_HOST_MEMORY;
+}
+
+static VkResult X11DRV_vkGetPhysicalDeviceSurfaceSupportKHR(VkPhysicalDevice phys_dev,
+        uint32_t index, VkSurfaceKHR surface, VkBool32 *supported)
+{
+    FIXME("stub: %p, %u, 0x%s, %p\n", phys_dev, index, wine_dbgstr_longlong(surface), supported);
+    return VK_ERROR_OUT_OF_HOST_MEMORY;
+}
+
+static VkBool32 X11DRV_vkGetPhysicalDeviceWin32PresentationSupportKHR(VkPhysicalDevice phys_dev,
+        uint32_t index)
+{
+    FIXME("stub %p %u\n", phys_dev, index);
+    return VK_FALSE;
+}
+
+static VkResult X11DRV_vkGetSwapchainImagesKHR(VkDevice device,
+        VkSwapchainKHR swapchain, uint32_t *count, VkImage *images)
+{
+    FIXME("stub: %p, 0x%s %p %p\n", device, wine_dbgstr_longlong(swapchain), count, images);
+    return VK_ERROR_OUT_OF_HOST_MEMORY;
+}
+
+static VkResult X11DRV_vkQueuePresentKHR(VkQueue queue, const VkPresentInfoKHR *present_info)
+{
+    FIXME("stub: %p, %p\n", queue, present_info);
+    return VK_ERROR_OUT_OF_HOST_MEMORY;
+}
+
+
 static const struct vulkan_funcs vulkan_funcs =
 {
+    X11DRV_vkAcquireNextImageKHR,
     X11DRV_vkCreateInstance,
+    X11DRV_vkCreateSwapchainKHR,
+    X11DRV_vkCreateWin32SurfaceKHR,
     X11DRV_vkDestroyInstance,
+    X11DRV_vkDestroySurfaceKHR,
+    X11DRV_vkDestroySwapchainKHR,
     X11DRV_vkEnumerateInstanceExtensionProperties,
     X11DRV_vkGetDeviceProcAddr,
-    X11DRV_vkGetInstanceProcAddr
+    X11DRV_vkGetInstanceProcAddr,
+    X11DRV_vkGetPhysicalDeviceSurfaceCapabilitiesKHR,
+    X11DRV_vkGetPhysicalDeviceSurfaceFormatsKHR,
+    X11DRV_vkGetPhysicalDeviceSurfacePresentModesKHR,
+    X11DRV_vkGetPhysicalDeviceSurfaceSupportKHR,
+    X11DRV_vkGetPhysicalDeviceWin32PresentationSupportKHR,
+    X11DRV_vkGetSwapchainImagesKHR,
+    X11DRV_vkQueuePresentKHR
 };
 
 const struct vulkan_funcs *get_vulkan_driver(UINT version)
diff --git a/include/wine/vulkan.h b/include/wine/vulkan.h
index fb0af61eb582..92dcb7d2b342 100644
--- a/include/wine/vulkan.h
+++ b/include/wine/vulkan.h
@@ -75,6 +75,8 @@ VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkRenderPass)
 VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkSampler)
 VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkSemaphore)
 VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkShaderModule)
+VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkSurfaceKHR)
+VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkSwapchainKHR)
 
 typedef uint32_t VkBool32;
 typedef uint64_t VkDeviceSize;
@@ -291,6 +293,12 @@ typedef enum VkColorComponentFlagBits
     VK_COLOR_COMPONENT_FLAG_BITS_MAX_ENUM = 0x7fffffff,
 } VkColorComponentFlagBits;
 
+typedef enum VkColorSpaceKHR
+{
+    VK_COLOR_SPACE_SRGB_NONLINEAR_KHR = 0,
+    VK_COLOR_SPACE_KHR_MAX_ENUM = 0x7fffffff,
+} VkColorSpaceKHR;
+
 typedef enum VkCommandBufferLevel
 {
     VK_COMMAND_BUFFER_LEVEL_PRIMARY = 0,
@@ -338,6 +346,15 @@ typedef enum VkComponentSwizzle
     VK_COMPONENT_SWIZZLE_MAX_ENUM = 0x7fffffff,
 } VkComponentSwizzle;
 
+typedef enum VkCompositeAlphaFlagBitsKHR
+{
+    VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR = 0x00000001,
+    VK_COMPOSITE_ALPHA_PRE_MULTIPLIED_BIT_KHR = 0x00000002,
+    VK_COMPOSITE_ALPHA_POST_MULTIPLIED_BIT_KHR = 0x00000004,
+    VK_COMPOSITE_ALPHA_INHERIT_BIT_KHR = 0x00000008,
+    VK_COMPOSITE_ALPHA_FLAG_BITS_KHR_MAX_ENUM = 0x7fffffff,
+} VkCompositeAlphaFlagBitsKHR;
+
 typedef enum VkCullModeFlagBits
 {
     VK_CULL_MODE_NONE = 0,
@@ -652,6 +669,7 @@ typedef enum VkImageLayout
     VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL = 6,
     VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL = 7,
     VK_IMAGE_LAYOUT_PREINITIALIZED = 8,
+    VK_IMAGE_LAYOUT_PRESENT_SRC_KHR = 1000001002,
     VK_IMAGE_LAYOUT_MAX_ENUM = 0x7fffffff,
 } VkImageLayout;
 
@@ -773,6 +791,8 @@ typedef enum VkObjectType
     VK_OBJECT_TYPE_DESCRIPTOR_SET = 23,
     VK_OBJECT_TYPE_FRAMEBUFFER = 24,
     VK_OBJECT_TYPE_COMMAND_POOL = 25,
+    VK_OBJECT_TYPE_SURFACE_KHR = 1000000000,
+    VK_OBJECT_TYPE_SWAPCHAIN_KHR = 1000001000,
     VK_OBJECT_TYPE_MAX_ENUM = 0x7fffffff,
 } VkObjectType;
 
@@ -837,6 +857,15 @@ typedef enum VkPolygonMode
     VK_POLYGON_MODE_MAX_ENUM = 0x7fffffff,
 } VkPolygonMode;
 
+typedef enum VkPresentModeKHR
+{
+    VK_PRESENT_MODE_IMMEDIATE_KHR = 0,
+    VK_PRESENT_MODE_MAILBOX_KHR = 1,
+    VK_PRESENT_MODE_FIFO_KHR = 2,
+    VK_PRESENT_MODE_FIFO_RELAXED_KHR = 3,
+    VK_PRESENT_MODE_KHR_MAX_ENUM = 0x7fffffff,
+} VkPresentModeKHR;
+
 typedef enum VkPrimitiveTopology
 {
     VK_PRIMITIVE_TOPOLOGY_POINT_LIST = 0,
@@ -894,6 +923,9 @@ typedef enum VkQueueFlagBits
 
 typedef enum VkResult
 {
+    VK_ERROR_OUT_OF_DATE_KHR = -1000001004,
+    VK_ERROR_NATIVE_WINDOW_IN_USE_KHR = -1000000001,
+    VK_ERROR_SURFACE_LOST_KHR = -1000000000,
     VK_ERROR_FRAGMENTED_POOL = -12,
     VK_ERROR_FORMAT_NOT_SUPPORTED = -11,
     VK_ERROR_TOO_MANY_OBJECTS = -10,
@@ -912,6 +944,7 @@ typedef enum VkResult
     VK_EVENT_SET = 3,
     VK_EVENT_RESET = 4,
     VK_INCOMPLETE = 5,
+    VK_SUBOPTIMAL_KHR = 1000001003,
     VK_RESULT_MAX_ENUM = 0x7fffffff,
 } VkResult;
 
@@ -1041,6 +1074,9 @@ typedef enum VkStructureType
     VK_STRUCTURE_TYPE_MEMORY_BARRIER = 46,
     VK_STRUCTURE_TYPE_LOADER_INSTANCE_CREATE_INFO = 47,
     VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO = 48,
+    VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR = 1000001000,
+    VK_STRUCTURE_TYPE_PRESENT_INFO_KHR = 1000001001,
+    VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR = 1000009000,
     VK_STRUCTURE_TYPE_MAX_ENUM = 0x7fffffff,
 } VkStructureType;
 
@@ -1056,6 +1092,25 @@ typedef enum VkSubpassDescriptionFlagBits
     VK_SUBPASS_DESCRIPTION_FLAG_BITS_MAX_ENUM = 0x7fffffff,
 } VkSubpassDescriptionFlagBits;
 
+typedef enum VkSurfaceTransformFlagBitsKHR
+{
+    VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR = 0x00000001,
+    VK_SURFACE_TRANSFORM_ROTATE_90_BIT_KHR = 0x00000002,
+    VK_SURFACE_TRANSFORM_ROTATE_180_BIT_KHR = 0x00000004,
+    VK_SURFACE_TRANSFORM_ROTATE_270_BIT_KHR = 0x00000008,
+    VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_BIT_KHR = 0x00000010,
+    VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_90_BIT_KHR = 0x00000020,
+    VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_180_BIT_KHR = 0x00000040,
+    VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_270_BIT_KHR = 0x00000080,
+    VK_SURFACE_TRANSFORM_INHERIT_BIT_KHR = 0x00000100,
+    VK_SURFACE_TRANSFORM_FLAG_BITS_KHR_MAX_ENUM = 0x7fffffff,
+} VkSurfaceTransformFlagBitsKHR;
+
+typedef enum VkSwapchainCreateFlagBitsKHR
+{
+    VK_SWAPCHAIN_CREATE_FLAG_BITS_KHR_MAX_ENUM = 0x7fffffff,
+} VkSwapchainCreateFlagBitsKHR;
+
 typedef enum VkSystemAllocationScope
 {
     VK_SYSTEM_ALLOCATION_SCOPE_COMMAND = 0,
@@ -1439,6 +1494,18 @@ typedef struct VkPipelineTessellationStateCreateInfo
     uint32_t patchControlPoints;
 } VkPipelineTessellationStateCreateInfo;
 
+typedef struct VkPresentInfoKHR
+{
+    VkStructureType sType;
+    const void *pNext;
+    uint32_t waitSemaphoreCount;
+    const VkSemaphore *pWaitSemaphores;
+    uint32_t swapchainCount;
+    const VkSwapchainKHR *pSwapchains;
+    const uint32_t *pImageIndices;
+    VkResult *pResults;
+} VkPresentInfoKHR;
+
 typedef struct VkQueryPoolCreateInfo
 {
     VkStructureType sType;
@@ -1745,6 +1812,12 @@ typedef struct VkSubpassDependency
     VkDependencyFlags dependencyFlags;
 } VkSubpassDependency;
 
+typedef struct VkSurfaceFormatKHR
+{
+    VkFormat format;
+    VkColorSpaceKHR colorSpace;
+} VkSurfaceFormatKHR;
+
 typedef struct VkViewport
 {
     float x;
@@ -1901,6 +1974,28 @@ typedef struct VkSubpassDescription
     const uint32_t *pPreserveAttachments;
 } VkSubpassDescription;
 
+typedef struct VkSwapchainCreateInfoKHR
+{
+    VkStructureType sType;
+    const void *pNext;
+    VkSwapchainCreateFlagsKHR flags;
+    VkSurfaceKHR WINE_VK_ALIGN(8) surface;
+    uint32_t minImageCount;
+    VkFormat imageFormat;
+    VkColorSpaceKHR imageColorSpace;
+    VkExtent2D imageExtent;
+    uint32_t imageArrayLayers;
+    VkImageUsageFlags imageUsage;
+    VkSharingMode imageSharingMode;
+    uint32_t queueFamilyIndexCount;
+    const uint32_t *pQueueFamilyIndices;
+    VkSurfaceTransformFlagBitsKHR preTransform;
+    VkCompositeAlphaFlagBitsKHR compositeAlpha;
+    VkPresentModeKHR presentMode;
+    VkBool32 clipped;
+    VkSwapchainKHR WINE_VK_ALIGN(8) oldSwapchain;
+} VkSwapchainCreateInfoKHR;
+
 typedef struct VkClearAttachment
 {
     VkImageAspectFlags aspectMask;
@@ -1987,6 +2082,29 @@ typedef struct VkRenderPassBeginInfo
     const VkClearValue *pClearValues;
 } VkRenderPassBeginInfo;
 
+typedef struct VkSurfaceCapabilitiesKHR
+{
+    uint32_t minImageCount;
+    uint32_t maxImageCount;
+    VkExtent2D currentExtent;
+    VkExtent2D minImageExtent;
+    VkExtent2D maxImageExtent;
+    uint32_t maxImageArrayLayers;
+    VkSurfaceTransformFlagsKHR supportedTransforms;
+    VkSurfaceTransformFlagBitsKHR currentTransform;
+    VkCompositeAlphaFlagsKHR supportedCompositeAlpha;
+    VkImageUsageFlags supportedUsageFlags;
+} VkSurfaceCapabilitiesKHR;
+
+typedef struct VkWin32SurfaceCreateInfoKHR
+{
+    VkStructureType sType;
+    const void *pNext;
+    VkWin32SurfaceCreateFlagsKHR flags;
+    HINSTANCE hinstance;
+    HWND hwnd;
+} VkWin32SurfaceCreateInfoKHR;
+
 typedef struct VkBindSparseInfo
 {
     VkStructureType sType;
@@ -2282,6 +2400,7 @@ typedef struct VkGraphicsPipelineCreateInfo
     int32_t basePipelineIndex;
 } VkGraphicsPipelineCreateInfo;
 
+VkResult VKAPI_CALL vkAcquireNextImageKHR(VkDevice device, VkSwapchainKHR swapchain, uint64_t timeout, VkSemaphore semaphore, VkFence fence, uint32_t *pImageIndex);
 VkResult VKAPI_CALL vkAllocateCommandBuffers(VkDevice device, const VkCommandBufferAllocateInfo *pAllocateInfo, VkCommandBuffer *pCommandBuffers);
 VkResult VKAPI_CALL vkAllocateDescriptorSets(VkDevice device, const VkDescriptorSetAllocateInfo *pAllocateInfo, VkDescriptorSet *pDescriptorSets);
 VkResult VKAPI_CALL vkAllocateMemory(VkDevice device, const VkMemoryAllocateInfo *pAllocateInfo, const VkAllocationCallbacks *pAllocator, VkDeviceMemory *pMemory);
@@ -2353,6 +2472,8 @@ VkResult VKAPI_CALL vkCreateRenderPass(VkDevice device, const VkRenderPassCreate
 VkResult VKAPI_CALL vkCreateSampler(VkDevice device, const VkSamplerCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkSampler *pSampler);
 VkResult VKAPI_CALL vkCreateSemaphore(VkDevice device, const VkSemaphoreCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkSemaphore *pSemaphore);
 VkResult VKAPI_CALL vkCreateShaderModule(VkDevice device, const VkShaderModuleCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkShaderModule *pShaderModule);
+VkResult VKAPI_CALL vkCreateSwapchainKHR(VkDevice device, const VkSwapchainCreateInfoKHR *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkSwapchainKHR *pSwapchain);
+VkResult VKAPI_CALL vkCreateWin32SurfaceKHR(VkInstance instance, const VkWin32SurfaceCreateInfoKHR *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface);
 void VKAPI_CALL vkDestroyBuffer(VkDevice device, VkBuffer buffer, const VkAllocationCallbacks *pAllocator);
 void VKAPI_CALL vkDestroyBufferView(VkDevice device, VkBufferView bufferView, const VkAllocationCallbacks *pAllocator);
 void VKAPI_CALL vkDestroyCommandPool(VkDevice device, VkCommandPool commandPool, const VkAllocationCallbacks *pAllocator);
@@ -2373,6 +2494,8 @@ void VKAPI_CALL vkDestroyRenderPass(VkDevice device, VkRenderPass renderPass, co
 void VKAPI_CALL vkDestroySampler(VkDevice device, VkSampler sampler, const VkAllocationCallbacks *pAllocator);
 void VKAPI_CALL vkDestroySemaphore(VkDevice device, VkSemaphore semaphore, const VkAllocationCallbacks *pAllocator);
 void VKAPI_CALL vkDestroyShaderModule(VkDevice device, VkShaderModule shaderModule, const VkAllocationCallbacks *pAllocator);
+void VKAPI_CALL vkDestroySurfaceKHR(VkInstance instance, VkSurfaceKHR surface, const VkAllocationCallbacks *pAllocator);
+void VKAPI_CALL vkDestroySwapchainKHR(VkDevice device, VkSwapchainKHR swapchain, const VkAllocationCallbacks *pAllocator);
 VkResult VKAPI_CALL vkDeviceWaitIdle(VkDevice device);
 VkResult VKAPI_CALL vkEndCommandBuffer(VkCommandBuffer commandBuffer);
 VkResult VKAPI_CALL vkEnumerateDeviceExtensionProperties(VkPhysicalDevice physicalDevice, const char *pLayerName, uint32_t *pPropertyCount, VkExtensionProperties *pProperties);
@@ -2401,13 +2524,20 @@ void VKAPI_CALL vkGetPhysicalDeviceMemoryProperties(VkPhysicalDevice physicalDev
 void VKAPI_CALL vkGetPhysicalDeviceProperties(VkPhysicalDevice physicalDevice, VkPhysicalDeviceProperties *pProperties);
 void VKAPI_CALL vkGetPhysicalDeviceQueueFamilyProperties(VkPhysicalDevice physicalDevice, uint32_t *pQueueFamilyPropertyCount, VkQueueFamilyProperties *pQueueFamilyProperties);
 void VKAPI_CALL vkGetPhysicalDeviceSparseImageFormatProperties(VkPhysicalDevice physicalDevice, VkFormat format, VkImageType type, VkSampleCountFlagBits samples, VkImageUsageFlags usage, VkImageTiling tiling, uint32_t *pPropertyCount, VkSparseImageFormatProperties *pProperties);
+VkResult VKAPI_CALL vkGetPhysicalDeviceSurfaceCapabilitiesKHR(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface, VkSurfaceCapabilitiesKHR *pSurfaceCapabilities);
+VkResult VKAPI_CALL vkGetPhysicalDeviceSurfaceFormatsKHR(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface, uint32_t *pSurfaceFormatCount, VkSurfaceFormatKHR *pSurfaceFormats);
+VkResult VKAPI_CALL vkGetPhysicalDeviceSurfacePresentModesKHR(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface, uint32_t *pPresentModeCount, VkPresentModeKHR *pPresentModes);
+VkResult VKAPI_CALL vkGetPhysicalDeviceSurfaceSupportKHR(VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex, VkSurfaceKHR surface, VkBool32 *pSupported);
+VkBool32 VKAPI_CALL vkGetPhysicalDeviceWin32PresentationSupportKHR(VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex);
 VkResult VKAPI_CALL vkGetPipelineCacheData(VkDevice device, VkPipelineCache pipelineCache, size_t *pDataSize, void *pData);
 VkResult VKAPI_CALL vkGetQueryPoolResults(VkDevice device, VkQueryPool queryPool, uint32_t firstQuery, uint32_t queryCount, size_t dataSize, void *pData, VkDeviceSize stride, VkQueryResultFlags flags);
 void VKAPI_CALL vkGetRenderAreaGranularity(VkDevice device, VkRenderPass renderPass, VkExtent2D *pGranularity);
+VkResult VKAPI_CALL vkGetSwapchainImagesKHR(VkDevice device, VkSwapchainKHR swapchain, uint32_t *pSwapchainImageCount, VkImage *pSwapchainImages);
 VkResult VKAPI_CALL vkInvalidateMappedMemoryRanges(VkDevice device, uint32_t memoryRangeCount, const VkMappedMemoryRange *pMemoryRanges);
 VkResult VKAPI_CALL vkMapMemory(VkDevice device, VkDeviceMemory memory, VkDeviceSize offset, VkDeviceSize size, VkMemoryMapFlags flags, void **ppData);
 VkResult VKAPI_CALL vkMergePipelineCaches(VkDevice device, VkPipelineCache dstCache, uint32_t srcCacheCount, const VkPipelineCache *pSrcCaches);
 VkResult VKAPI_CALL vkQueueBindSparse(VkQueue queue, uint32_t bindInfoCount, const VkBindSparseInfo *pBindInfo, VkFence fence);
+VkResult VKAPI_CALL vkQueuePresentKHR(VkQueue queue, const VkPresentInfoKHR *pPresentInfo);
 VkResult VKAPI_CALL vkQueueSubmit(VkQueue queue, uint32_t submitCount, const VkSubmitInfo *pSubmits, VkFence fence);
 VkResult VKAPI_CALL vkQueueWaitIdle(VkQueue queue);
 VkResult VKAPI_CALL vkResetCommandBuffer(VkCommandBuffer commandBuffer, VkCommandBufferResetFlags flags);
diff --git a/include/wine/vulkan_driver.h b/include/wine/vulkan_driver.h
index 8d69222e03c4..60d16dd52a24 100644
--- a/include/wine/vulkan_driver.h
+++ b/include/wine/vulkan_driver.h
@@ -4,7 +4,7 @@
 #define __WINE_VULKAN_DRIVER_H
 
 /* Wine internal vulkan driver version, needs to be bumped upon vulkan_funcs changes. */
-#define WINE_VULKAN_DRIVER_VERSION 2
+#define WINE_VULKAN_DRIVER_VERSION 3
 
 struct vulkan_funcs
 {
@@ -12,11 +12,23 @@ struct vulkan_funcs
      * needs to provide. Other function calls will be provided indirectly by dispatch
      * tables part of dispatchable Vulkan objects such as VkInstance or vkDevice.
      */
+    VkResult (*p_vkAcquireNextImageKHR)(VkDevice, VkSwapchainKHR, uint64_t, VkSemaphore, VkFence, uint32_t *);
     VkResult (*p_vkCreateInstance)(const VkInstanceCreateInfo *, const VkAllocationCallbacks *, VkInstance *);
+    VkResult (*p_vkCreateSwapchainKHR)(VkDevice, const VkSwapchainCreateInfoKHR *, const VkAllocationCallbacks *, VkSwapchainKHR *);
+    VkResult (*p_vkCreateWin32SurfaceKHR)(VkInstance, const VkWin32SurfaceCreateInfoKHR *, const VkAllocationCallbacks *, VkSurfaceKHR *);
     void (*p_vkDestroyInstance)(VkInstance, const VkAllocationCallbacks *);
+    void (*p_vkDestroySurfaceKHR)(VkInstance, VkSurfaceKHR, const VkAllocationCallbacks *);
+    void (*p_vkDestroySwapchainKHR)(VkDevice, VkSwapchainKHR, const VkAllocationCallbacks *);
     VkResult (*p_vkEnumerateInstanceExtensionProperties)(const char *, uint32_t *, VkExtensionProperties *);
     void * (*p_vkGetDeviceProcAddr)(VkDevice, const char *);
     void * (*p_vkGetInstanceProcAddr)(VkInstance, const char *);
+    VkResult (*p_vkGetPhysicalDeviceSurfaceCapabilitiesKHR)(VkPhysicalDevice, VkSurfaceKHR, VkSurfaceCapabilitiesKHR *);
+    VkResult (*p_vkGetPhysicalDeviceSurfaceFormatsKHR)(VkPhysicalDevice, VkSurfaceKHR, uint32_t *, VkSurfaceFormatKHR *);
+    VkResult (*p_vkGetPhysicalDeviceSurfacePresentModesKHR)(VkPhysicalDevice, VkSurfaceKHR, uint32_t *, VkPresentModeKHR *);
+    VkResult (*p_vkGetPhysicalDeviceSurfaceSupportKHR)(VkPhysicalDevice, uint32_t, VkSurfaceKHR, VkBool32 *);
+    VkBool32 (*p_vkGetPhysicalDeviceWin32PresentationSupportKHR)(VkPhysicalDevice, uint32_t);
+    VkResult (*p_vkGetSwapchainImagesKHR)(VkDevice, VkSwapchainKHR, uint32_t *, VkImage *);
+    VkResult (*p_vkQueuePresentKHR)(VkQueue, const VkPresentInfoKHR *);
 };
 
 extern const struct vulkan_funcs * CDECL __wine_get_vulkan_driver(HDC hdc, UINT version);
-- 
2.16.1




More information about the wine-devel mailing list