[PATCH v2 0/4] winevulkan

classic Classic list List threaded Threaded
11 messages Options
Reply | Threaded
Open this post in threaded view
|

[PATCH v2 0/4] winevulkan

Roderick Colenbrander-2
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(-)

--
2.14.3



Reply | Threaded
Open this post in threaded view
|

[PATCH v2 1/4] winex11: Add initial vkCreateWin32SurfaceKHR implementation.

Roderick Colenbrander-2
Implement surface creation for top-level windows. Child window rendering
is not yet supported.

Signed-off-by: Roderick Colenbrander <[hidden email]>
---
 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)
--
2.14.3



Reply | Threaded
Open this post in threaded view
|

[PATCH v2 2/4] winex11: Implement vkGetPhysicalDeviceWin32PresentationSupportKHR.

Roderick Colenbrander-2
In reply to this post by Roderick Colenbrander-2
Signed-off-by: Roderick Colenbrander <[hidden email]>
---
 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,
--
2.14.3



Reply | Threaded
Open this post in threaded view
|

[PATCH v2 3/4] winex11: Implement vkDestroySurfaceKHR.

Roderick Colenbrander-2
In reply to this post by Roderick Colenbrander-2
Signed-off-by: Roderick Colenbrander <[hidden email]>
---
 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,
--
2.14.3



Reply | Threaded
Open this post in threaded view
|

[PATCH v2 4/4] winex11: Implement support for vkGetPhysicalDeviceSurface*KHR APIs.

Roderick Colenbrander-2
In reply to this post by Roderick Colenbrander-2
Signed-off-by: Roderick Colenbrander <[hidden email]>
---
 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,
--
2.14.3



Reply | Threaded
Open this post in threaded view
|

Re: [PATCH v2 2/4] winex11: Implement vkGetPhysicalDeviceWin32PresentationSupportKHR.

Józef Kucia-2
In reply to this post by Roderick Colenbrander-2
Signed-off-by: Józef Kucia <[hidden email]>


Reply | Threaded
Open this post in threaded view
|

Re: [PATCH v2 3/4] winex11: Implement vkDestroySurfaceKHR.

Józef Kucia-2
In reply to this post by Roderick Colenbrander-2
Signed-off-by: Józef Kucia <[hidden email]>


Reply | Threaded
Open this post in threaded view
|

Re: [PATCH v2 1/4] winex11: Add initial vkCreateWin32SurfaceKHR implementation.

Józef Kucia-2
In reply to this post by Roderick Colenbrander-2
Signed-off-by: Józef Kucia <[hidden email]>


Reply | Threaded
Open this post in threaded view
|

Re: [PATCH v2 4/4] winex11: Implement support for vkGetPhysicalDeviceSurface*KHR APIs.

Józef Kucia-2
In reply to this post by Roderick Colenbrander-2
Signed-off-by: Józef Kucia <[hidden email]>


Reply | Threaded
Open this post in threaded view
|

Re: [PATCH v2 1/4] winex11: Add initial vkCreateWin32SurfaceKHR implementation.

Józef Kucia
In reply to this post by Roderick Colenbrander-2
On Tue, Mar 13, 2018 at 7:32 AM, Roderick Colenbrander
<[hidden email]> wrote:

> Implement surface creation for top-level windows. Child window rendering
> is not yet supported.
>
> Signed-off-by: Roderick Colenbrander <[hidden email]>
> ---
>  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
>
>
>


Reply | Threaded
Open this post in threaded view
|

Re: [PATCH v2 0/4] winevulkan

Józef Kucia
In reply to this post by Roderick Colenbrander-2
On Tue, Mar 13, 2018 at 7:32 AM, Roderick Colenbrander
<[hidden email]> 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
>
>
>