Hi all,
This is a resubmit of some of my previous patches. I have added a surface_from_handle helper function to replace the macro I had.
The biggest change is initial destroy surface logic using wine_vk_surface_destroy. For now I think it is sufficient, though long-term it probably needs to be used from X11DRV_DestroyWindow as well, but that needs some more thought. Among the challenges is that vkDestroySurfaceKHR requires the 'VkInstance' the surface is tied to, which brings up other complexity (instance may have been destroyed already, locking, does VkDestroyInstance need to clean up undestroyed surfaces?). It is not even clear how Vulkan expect things to be done as Vulkan kind of assumes 'well written' software since it has very minimal error handling and validation.
Thanks, Roderick
Roderick Colenbrander (4): winex11: Add initial vkCreateWin32SurfaceKHR implementation. winex11: Implement vkGetPhysicalDeviceWin32PresentationSupportKHR. winex11: Implement vkDestroySurfaceKHR. winex11: Implement support for vkGetPhysicalDeviceSurface*KHR APIs.
dlls/winex11.drv/vulkan.c | 153 ++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 140 insertions(+), 13 deletions(-)
Implement surface creation for top-level windows. Child window rendering is not yet supported.
Signed-off-by: Roderick Colenbrander thunderbird2k@gmail.com --- dlls/winex11.drv/vulkan.c | 90 +++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 88 insertions(+), 2 deletions(-)
diff --git a/dlls/winex11.drv/vulkan.c b/dlls/winex11.drv/vulkan.c index 11d9f61b91..4b20b46e1b 100644 --- a/dlls/winex11.drv/vulkan.c +++ b/dlls/winex11.drv/vulkan.c @@ -28,6 +28,7 @@ #include "wine/debug.h" #include "wine/heap.h" #include "wine/library.h" +#include "x11drv.h"
/* We only want host compatible structures and don't need alignment. */ #define WINE_VK_ALIGN(x) @@ -43,8 +44,28 @@ WINE_DEFAULT_DEBUG_CHANNEL(vulkan); #define ARRAY_SIZE(array) (sizeof(array) / sizeof((array)[0])) #endif
+typedef VkFlags VkXlibSurfaceCreateFlagsKHR; +#define VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR 1000004000 + +struct wine_vk_surface +{ + Window window; + VkSurfaceKHR surface; /* native surface */ +}; + +typedef struct VkXlibSurfaceCreateInfoKHR +{ + VkStructureType sType; + const void *pNext; + VkXlibSurfaceCreateFlagsKHR flags; + Display *dpy; + Window window; +} VkXlibSurfaceCreateInfoKHR; + static VkResult (*pvkCreateInstance)(const VkInstanceCreateInfo *, const VkAllocationCallbacks *, VkInstance *); +static VkResult (*pvkCreateXlibSurfaceKHR)(VkInstance, const VkXlibSurfaceCreateInfoKHR *, const VkAllocationCallbacks *, VkSurfaceKHR *); static void (*pvkDestroyInstance)(VkInstance, const VkAllocationCallbacks *); +static void (*pvkDestroySurfaceKHR)(VkInstance, VkSurfaceKHR, const VkAllocationCallbacks *); static void * (*pvkGetDeviceProcAddr)(VkDevice, const char *); static void * (*pvkGetInstanceProcAddr)(VkInstance, const char *);
@@ -67,7 +88,9 @@ static BOOL wine_vk_init(void)
#define LOAD_FUNCPTR(f) if((p##f = wine_dlsym(vulkan_handle, #f, NULL, 0)) == NULL) return FALSE; LOAD_FUNCPTR(vkCreateInstance) +LOAD_FUNCPTR(vkCreateXlibSurfaceKHR) LOAD_FUNCPTR(vkDestroyInstance) +LOAD_FUNCPTR(vkDestroySurfaceKHR) LOAD_FUNCPTR(vkGetDeviceProcAddr) LOAD_FUNCPTR(vkGetInstanceProcAddr) #undef LOAD_FUNCPTR @@ -123,6 +146,20 @@ static VkResult wine_vk_instance_convert_create_info(const VkInstanceCreateInfo return VK_SUCCESS; }
+static void wine_vk_surface_destroy(VkInstance instance, struct wine_vk_surface *surface) +{ + if (!surface) + return; + + /* vkDestroySurfaceKHR must handle VK_NULL_HANDLE (0) for surface. */ + pvkDestroySurfaceKHR(instance, surface->surface, NULL /* allocator */); + + if (surface->window) + XDestroyWindow(gdi_display, surface->window); + + heap_free(surface); +} + static VkResult X11DRV_vkAcquireNextImageKHR(VkDevice device, VkSwapchainKHR swapchain, uint64_t timeout, VkSemaphore semaphore, VkFence fence, uint32_t *index) { @@ -172,8 +209,57 @@ 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; + VkResult res; + VkXlibSurfaceCreateInfoKHR create_info_host; + struct wine_vk_surface *x11_surface; + + TRACE("%p %p %p %p\n", instance, create_info, allocator, surface); + + if (allocator) + FIXME("Support for allocation callbacks not implemented yet\n"); + + /* TODO: support child window rendering. */ + if (GetAncestor(create_info->hwnd, GA_PARENT) != GetDesktopWindow()) + { + FIXME("Application requires child window rendering, which is not implemented yet!\n"); + return VK_ERROR_INCOMPATIBLE_DRIVER; + } + + x11_surface = heap_alloc_zero(sizeof(*x11_surface)); + if (!x11_surface) + return VK_ERROR_OUT_OF_HOST_MEMORY; + + x11_surface->window = create_client_window(create_info->hwnd, &default_visual); + if (!x11_surface->window) + { + ERR("Failed to allocate client window for hwnd=%p\n", create_info->hwnd); + + /* VK_KHR_win32_surface only allows out of host and device memory as errors. */ + res = VK_ERROR_OUT_OF_HOST_MEMORY; + goto err; + } + + create_info_host.sType = VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR; + create_info_host.pNext = NULL; + create_info_host.flags = 0; /* reserved */ + create_info_host.dpy = gdi_display; + create_info_host.window = x11_surface->window; + + res = pvkCreateXlibSurfaceKHR(instance, &create_info_host, NULL /* allocator */, &x11_surface->surface); + if (res != VK_SUCCESS) + { + ERR("Failed to create Xlib surface, res=%d\n", res); + goto err; + } + + *surface = (uintptr_t)x11_surface; + + TRACE("Created surface=0x%s\n", wine_dbgstr_longlong(*surface)); + return VK_SUCCESS; + +err: + wine_vk_surface_destroy(instance, x11_surface); + return res; }
static void X11DRV_vkDestroyInstance(VkInstance instance, const VkAllocationCallbacks *allocator)
Signed-off-by: Józef Kucia jkucia@codeweavers.com
On Tue, Mar 13, 2018 at 7:32 AM, Roderick Colenbrander thunderbird2k@gmail.com wrote:
Implement surface creation for top-level windows. Child window rendering is not yet supported.
Signed-off-by: Roderick Colenbrander thunderbird2k@gmail.com
dlls/winex11.drv/vulkan.c | 90 +++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 88 insertions(+), 2 deletions(-)
diff --git a/dlls/winex11.drv/vulkan.c b/dlls/winex11.drv/vulkan.c index 11d9f61b91..4b20b46e1b 100644 --- a/dlls/winex11.drv/vulkan.c +++ b/dlls/winex11.drv/vulkan.c @@ -28,6 +28,7 @@ #include "wine/debug.h" #include "wine/heap.h" #include "wine/library.h" +#include "x11drv.h"
/* We only want host compatible structures and don't need alignment. */ #define WINE_VK_ALIGN(x) @@ -43,8 +44,28 @@ WINE_DEFAULT_DEBUG_CHANNEL(vulkan); #define ARRAY_SIZE(array) (sizeof(array) / sizeof((array)[0])) #endif
+typedef VkFlags VkXlibSurfaceCreateFlagsKHR; +#define VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR 1000004000
+struct wine_vk_surface +{
- Window window;
- VkSurfaceKHR surface; /* native surface */
+};
+typedef struct VkXlibSurfaceCreateInfoKHR +{
- VkStructureType sType;
- const void *pNext;
- VkXlibSurfaceCreateFlagsKHR flags;
- Display *dpy;
- Window window;
+} VkXlibSurfaceCreateInfoKHR;
I think we should consider including VK_KHR_xlib_surface in our vulkan.h header.
static VkResult (*pvkCreateInstance)(const VkInstanceCreateInfo *, const VkAllocationCallbacks *, VkInstance *); +static VkResult (*pvkCreateXlibSurfaceKHR)(VkInstance, const VkXlibSurfaceCreateInfoKHR *, const VkAllocationCallbacks *, VkSurfaceKHR *); static void (*pvkDestroyInstance)(VkInstance, const VkAllocationCallbacks *); +static void (*pvkDestroySurfaceKHR)(VkInstance, VkSurfaceKHR, const VkAllocationCallbacks *); static void * (*pvkGetDeviceProcAddr)(VkDevice, const char *); static void * (*pvkGetInstanceProcAddr)(VkInstance, const char *);
@@ -67,7 +88,9 @@ static BOOL wine_vk_init(void)
#define LOAD_FUNCPTR(f) if((p##f = wine_dlsym(vulkan_handle, #f, NULL, 0)) == NULL) return FALSE; LOAD_FUNCPTR(vkCreateInstance) +LOAD_FUNCPTR(vkCreateXlibSurfaceKHR) LOAD_FUNCPTR(vkDestroyInstance) +LOAD_FUNCPTR(vkDestroySurfaceKHR) LOAD_FUNCPTR(vkGetDeviceProcAddr) LOAD_FUNCPTR(vkGetInstanceProcAddr) #undef LOAD_FUNCPTR @@ -123,6 +146,20 @@ static VkResult wine_vk_instance_convert_create_info(const VkInstanceCreateInfo return VK_SUCCESS; }
+static void wine_vk_surface_destroy(VkInstance instance, struct wine_vk_surface *surface) +{
- if (!surface)
return;
- /* vkDestroySurfaceKHR must handle VK_NULL_HANDLE (0) for surface. */
Personally, I think that the comment above is not very useful. Also, it should be placed above "if (!surface)".
- pvkDestroySurfaceKHR(instance, surface->surface, NULL /* allocator */);
- if (surface->window)
XDestroyWindow(gdi_display, surface->window);
- heap_free(surface);
+}
static VkResult X11DRV_vkAcquireNextImageKHR(VkDevice device, VkSwapchainKHR swapchain, uint64_t timeout, VkSemaphore semaphore, VkFence fence, uint32_t *index) { @@ -172,8 +209,57 @@ 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;
- VkResult res;
- VkXlibSurfaceCreateInfoKHR create_info_host;
- struct wine_vk_surface *x11_surface;
- TRACE("%p %p %p %p\n", instance, create_info, allocator, surface);
- if (allocator)
FIXME("Support for allocation callbacks not implemented yet\n");
- /* TODO: support child window rendering. */
- if (GetAncestor(create_info->hwnd, GA_PARENT) != GetDesktopWindow())
- {
FIXME("Application requires child window rendering, which is not implemented yet!\n");
return VK_ERROR_INCOMPATIBLE_DRIVER;
- }
- x11_surface = heap_alloc_zero(sizeof(*x11_surface));
- if (!x11_surface)
return VK_ERROR_OUT_OF_HOST_MEMORY;
- x11_surface->window = create_client_window(create_info->hwnd, &default_visual);
- if (!x11_surface->window)
- {
ERR("Failed to allocate client window for hwnd=%p\n", create_info->hwnd);
/* VK_KHR_win32_surface only allows out of host and device memory as errors. */
res = VK_ERROR_OUT_OF_HOST_MEMORY;
goto err;
goto doesn't give us much. The cleanup is a single line of code.
- }
- create_info_host.sType = VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR;
- create_info_host.pNext = NULL;
- create_info_host.flags = 0; /* reserved */
- create_info_host.dpy = gdi_display;
- create_info_host.window = x11_surface->window;
- res = pvkCreateXlibSurfaceKHR(instance, &create_info_host, NULL /* allocator */, &x11_surface->surface);
- if (res != VK_SUCCESS)
- {
ERR("Failed to create Xlib surface, res=%d\n", res);
goto err;
- }
- *surface = (uintptr_t)x11_surface;
- TRACE("Created surface=0x%s\n", wine_dbgstr_longlong(*surface));
- return VK_SUCCESS;
+err:
- wine_vk_surface_destroy(instance, x11_surface);
- return res;
}
static void X11DRV_vkDestroyInstance(VkInstance instance, const VkAllocationCallbacks *allocator)
2.14.3
Signed-off-by: Roderick Colenbrander thunderbird2k@gmail.com --- dlls/winex11.drv/vulkan.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/dlls/winex11.drv/vulkan.c b/dlls/winex11.drv/vulkan.c index 4b20b46e1b..cdcf741957 100644 --- a/dlls/winex11.drv/vulkan.c +++ b/dlls/winex11.drv/vulkan.c @@ -68,6 +68,7 @@ static void (*pvkDestroyInstance)(VkInstance, const VkAllocationCallbacks *); static void (*pvkDestroySurfaceKHR)(VkInstance, VkSurfaceKHR, const VkAllocationCallbacks *); static void * (*pvkGetDeviceProcAddr)(VkDevice, const char *); static void * (*pvkGetInstanceProcAddr)(VkInstance, const char *); +static VkBool32 (*pvkGetPhysicalDeviceXlibPresentationSupportKHR)(VkPhysicalDevice, uint32_t, Display *, VisualID);
/* TODO: dynamically generate based on host driver capabilities. */ static const struct VkExtensionProperties winex11_vk_instance_extensions[] = @@ -93,6 +94,7 @@ LOAD_FUNCPTR(vkDestroyInstance) LOAD_FUNCPTR(vkDestroySurfaceKHR) LOAD_FUNCPTR(vkGetDeviceProcAddr) LOAD_FUNCPTR(vkGetInstanceProcAddr) +LOAD_FUNCPTR(vkGetPhysicalDeviceXlibPresentationSupportKHR) #undef LOAD_FUNCPTR
return TRUE; @@ -377,8 +379,10 @@ static VkResult X11DRV_vkGetPhysicalDeviceSurfaceSupportKHR(VkPhysicalDevice phy static VkBool32 X11DRV_vkGetPhysicalDeviceWin32PresentationSupportKHR(VkPhysicalDevice phys_dev, uint32_t index) { - FIXME("stub %p %u\n", phys_dev, index); - return VK_FALSE; + TRACE("%p %u\n", phys_dev, index); + + return pvkGetPhysicalDeviceXlibPresentationSupportKHR(phys_dev, index, gdi_display, + default_visual.visual->visualid); }
static VkResult X11DRV_vkGetSwapchainImagesKHR(VkDevice device,
Signed-off-by: Józef Kucia jkucia@codeweavers.com
Signed-off-by: Roderick Colenbrander thunderbird2k@gmail.com --- dlls/winex11.drv/vulkan.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-)
diff --git a/dlls/winex11.drv/vulkan.c b/dlls/winex11.drv/vulkan.c index cdcf741957..3828f799b6 100644 --- a/dlls/winex11.drv/vulkan.c +++ b/dlls/winex11.drv/vulkan.c @@ -77,6 +77,12 @@ static const struct VkExtensionProperties winex11_vk_instance_extensions[] = { "VK_KHR_win32_surface", 1}, };
+/* Helper function to convert VkSurfaceKHR (uint64_t) to a surface pointer. */ +static inline struct wine_vk_surface * surface_from_handle(VkSurfaceKHR handle) +{ + return ((struct wine_vk_surface *)(uintptr_t)handle); +} + static BOOL wine_vk_init(void) { static BOOL init_done = FALSE; @@ -277,7 +283,14 @@ static void X11DRV_vkDestroyInstance(VkInstance instance, const VkAllocationCall static void X11DRV_vkDestroySurfaceKHR(VkInstance instance, VkSurfaceKHR surface, const VkAllocationCallbacks *allocator) { - FIXME("stub: %p 0x%s %p\n", instance, wine_dbgstr_longlong(surface), allocator); + struct wine_vk_surface *x11_surface = surface_from_handle(surface); + + TRACE("%p 0x%s %p\n", instance, wine_dbgstr_longlong(surface), allocator); + + if (allocator) + FIXME("Support for allocation callbacks not implemented yet\n"); + + wine_vk_surface_destroy(instance, x11_surface); }
static void X11DRV_vkDestroySwapchainKHR(VkDevice device, VkSwapchainKHR swapchain,
Signed-off-by: Józef Kucia jkucia@codeweavers.com
Signed-off-by: Roderick Colenbrander thunderbird2k@gmail.com --- dlls/winex11.drv/vulkan.c | 40 ++++++++++++++++++++++++++++++++-------- 1 file changed, 32 insertions(+), 8 deletions(-)
diff --git a/dlls/winex11.drv/vulkan.c b/dlls/winex11.drv/vulkan.c index 3828f799b6..3c122fbd07 100644 --- a/dlls/winex11.drv/vulkan.c +++ b/dlls/winex11.drv/vulkan.c @@ -68,6 +68,10 @@ static void (*pvkDestroyInstance)(VkInstance, const VkAllocationCallbacks *); static void (*pvkDestroySurfaceKHR)(VkInstance, VkSurfaceKHR, const VkAllocationCallbacks *); static void * (*pvkGetDeviceProcAddr)(VkDevice, const char *); static void * (*pvkGetInstanceProcAddr)(VkInstance, const char *); +static VkResult (*pvkGetPhysicalDeviceSurfaceCapabilitiesKHR)(VkPhysicalDevice, VkSurfaceKHR, VkSurfaceCapabilitiesKHR *); +static VkResult (*pvkGetPhysicalDeviceSurfaceFormatsKHR)(VkPhysicalDevice, VkSurfaceKHR, uint32_t *, VkSurfaceFormatKHR *); +static VkResult (*pvkGetPhysicalDeviceSurfacePresentModesKHR)(VkPhysicalDevice, VkSurfaceKHR, uint32_t *, VkPresentModeKHR *); +static VkResult (*pvkGetPhysicalDeviceSurfaceSupportKHR)(VkPhysicalDevice, uint32_t, VkSurfaceKHR, VkBool32 *); static VkBool32 (*pvkGetPhysicalDeviceXlibPresentationSupportKHR)(VkPhysicalDevice, uint32_t, Display *, VisualID);
/* TODO: dynamically generate based on host driver capabilities. */ @@ -100,6 +104,10 @@ LOAD_FUNCPTR(vkDestroyInstance) LOAD_FUNCPTR(vkDestroySurfaceKHR) LOAD_FUNCPTR(vkGetDeviceProcAddr) LOAD_FUNCPTR(vkGetInstanceProcAddr) +LOAD_FUNCPTR(vkGetPhysicalDeviceSurfaceCapabilitiesKHR) +LOAD_FUNCPTR(vkGetPhysicalDeviceSurfaceFormatsKHR) +LOAD_FUNCPTR(vkGetPhysicalDeviceSurfacePresentModesKHR) +LOAD_FUNCPTR(vkGetPhysicalDeviceSurfaceSupportKHR) LOAD_FUNCPTR(vkGetPhysicalDeviceXlibPresentationSupportKHR) #undef LOAD_FUNCPTR
@@ -364,29 +372,45 @@ static void * X11DRV_vkGetInstanceProcAddr(VkInstance instance, const char *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; + struct wine_vk_surface *x11_surface = surface_from_handle(surface); + + TRACE("%p, 0x%s, %p\n", phys_dev, wine_dbgstr_longlong(surface), capabilities); + + return pvkGetPhysicalDeviceSurfaceCapabilitiesKHR(phys_dev, x11_surface->surface, + capabilities); }
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; + struct wine_vk_surface *x11_surface = surface_from_handle(surface); + + TRACE("%p, 0x%s, %p, %p\n", phys_dev, wine_dbgstr_longlong(surface), count, formats); + + return pvkGetPhysicalDeviceSurfaceFormatsKHR(phys_dev, x11_surface->surface, + count, formats); }
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; + struct wine_vk_surface *x11_surface = surface_from_handle(surface); + + TRACE("%p, 0x%s, %p, %p\n", phys_dev, wine_dbgstr_longlong(surface), count, modes); + + return pvkGetPhysicalDeviceSurfacePresentModesKHR(phys_dev, x11_surface->surface, count, + modes); }
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; + struct wine_vk_surface *x11_surface = surface_from_handle(surface); + + TRACE("%p, %u, 0x%s, %p\n", phys_dev, index, wine_dbgstr_longlong(surface), supported); + + return pvkGetPhysicalDeviceSurfaceSupportKHR(phys_dev, index, x11_surface->surface, + supported); }
static VkBool32 X11DRV_vkGetPhysicalDeviceWin32PresentationSupportKHR(VkPhysicalDevice phys_dev,
Signed-off-by: Józef Kucia jkucia@codeweavers.com
On Tue, Mar 13, 2018 at 7:32 AM, Roderick Colenbrander thunderbird2k@gmail.com wrote:
Hi all,
This is a resubmit of some of my previous patches. I have added a surface_from_handle helper function to replace the macro I had.
The biggest change is initial destroy surface logic using wine_vk_surface_destroy. For now I think it is sufficient, though long-term it probably needs to be used from X11DRV_DestroyWindow as well, but that needs some more thought.
Yes, it's probably sufficient for now. In the long term, we may need to improve client window management.
Among the challenges is that vkDestroySurfaceKHR requires the 'VkInstance' the surface is tied to, which brings up other complexity (instance may have been destroyed already, locking, does VkDestroyInstance need to clean up undestroyed surfaces?). It is not even clear how Vulkan expect things to be done as Vulkan kind of assumes 'well written' software since it has very minimal error handling and validation.
I don't think we should destroy surfaces in vkDestroyInstance(). Generally, Vulkan requires all objects created from VkDevice to be destroyed before VkDevice. It also applies to VkInstances. Unfortunately, the spec doesn't mention WSI objects explicitly in the "2.3.1. Object Lifetime" section.
Thanks, Roderick
Roderick Colenbrander (4): winex11: Add initial vkCreateWin32SurfaceKHR implementation. winex11: Implement vkGetPhysicalDeviceWin32PresentationSupportKHR. winex11: Implement vkDestroySurfaceKHR. winex11: Implement support for vkGetPhysicalDeviceSurface*KHR APIs.
dlls/winex11.drv/vulkan.c | 153 ++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 140 insertions(+), 13 deletions(-)
-- 2.14.3