[PATCH v2 1/4] winex11: Add initial vkCreateWin32SurfaceKHR implementation.
Józef Kucia
joseph.kucia at gmail.com
Tue Mar 13 09:31:25 CDT 2018
On Tue, Mar 13, 2018 at 7:32 AM, Roderick Colenbrander
<thunderbird2k at gmail.com> wrote:
> Implement surface creation for top-level windows. Child window rendering
> is not yet supported.
>
> Signed-off-by: Roderick Colenbrander <thunderbird2k at 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
>
>
>
More information about the wine-devel
mailing list