This is the third (and last) part of the Wayland driver Vulkan subseries:
1. Implement `vkQueuePresentKHR` and support reporting `VK_ERROR_OUT_OF_DATE_KHR` and `VK_ERROR_SURFACE_LOST_KHR`. 2. Misc. enhancements/fixes to ensure the subsurface containing the vulkan rendering is displayed properly. 3. Implement a couple of remaining Vulkan functions.
With this MR you can start enjoying some of your games with the Wayland driver (either directly with Vulkan or with a D3D->Vulkan translation). Please note, however, that we don't currently support what's needed for mouselook (you will currently get erratic view movement), so most first-person 3D games are not playable yet.
Thanks!
-- v3: winewayland.drv: Implement vkGetPhysicalDevicePresentRectanglesKHR. winewayland.drv: Implement vkGetDeviceGroupSurfacePresentModesKHR. winewayland.drv: Apply client subsurface position on creation. winewayland.drv: Ensure Vulkan parent surface is mapped with proper size. winewayland.drv: Detect and report vkQueuePresentKHR errors.
From: Alexandros Frantzis alexandros.frantzis@collabora.com
--- dlls/winewayland.drv/vulkan.c | 10 ++++++++++ dlls/winewayland.drv/wayland_surface.c | 2 ++ 2 files changed, 12 insertions(+)
diff --git a/dlls/winewayland.drv/vulkan.c b/dlls/winewayland.drv/vulkan.c index 5ecf3787656..7f73286ec5f 100644 --- a/dlls/winewayland.drv/vulkan.c +++ b/dlls/winewayland.drv/vulkan.c @@ -68,6 +68,7 @@ static VkResult (*pvkGetPhysicalDeviceSurfacePresentModesKHR)(VkPhysicalDevice, static VkResult (*pvkGetPhysicalDeviceSurfaceSupportKHR)(VkPhysicalDevice, uint32_t, VkSurfaceKHR, VkBool32 *); static VkBool32 (*pvkGetPhysicalDeviceWaylandPresentationSupportKHR)(VkPhysicalDevice, uint32_t, struct wl_display *); static VkResult (*pvkGetSwapchainImagesKHR)(VkDevice, VkSwapchainKHR, uint32_t *, VkImage *); +static VkResult (*pvkQueuePresentKHR)(VkQueue, const VkPresentInfoKHR *);
static void *vulkan_handle; static const struct vulkan_funcs vulkan_funcs; @@ -633,6 +634,13 @@ static VkResult wayland_vkGetSwapchainImagesKHR(VkDevice device, VkSwapchainKHR return pvkGetSwapchainImagesKHR(device, swapchain, count, images); }
+static VkResult wayland_vkQueuePresentKHR(VkQueue queue, const VkPresentInfoKHR *present_info) +{ + TRACE("%p, %p\n", queue, present_info); + + return pvkQueuePresentKHR(queue, present_info); +} + static VkSurfaceKHR wayland_wine_get_native_surface(VkSurfaceKHR surface) { return wine_vk_surface_from_handle(surface)->native; @@ -665,6 +673,7 @@ static void wine_vk_init(void) LOAD_FUNCPTR(vkGetPhysicalDeviceSurfaceSupportKHR); LOAD_FUNCPTR(vkGetPhysicalDeviceWaylandPresentationSupportKHR); LOAD_FUNCPTR(vkGetSwapchainImagesKHR); + LOAD_FUNCPTR(vkQueuePresentKHR); #undef LOAD_FUNCPTR #undef LOAD_OPTIONAL_FUNCPTR
@@ -694,6 +703,7 @@ static const struct vulkan_funcs vulkan_funcs = .p_vkGetPhysicalDeviceSurfaceSupportKHR = wayland_vkGetPhysicalDeviceSurfaceSupportKHR, .p_vkGetPhysicalDeviceWin32PresentationSupportKHR = wayland_vkGetPhysicalDeviceWin32PresentationSupportKHR, .p_vkGetSwapchainImagesKHR = wayland_vkGetSwapchainImagesKHR, + .p_vkQueuePresentKHR = wayland_vkQueuePresentKHR, .p_wine_get_native_surface = wayland_wine_get_native_surface, };
diff --git a/dlls/winewayland.drv/wayland_surface.c b/dlls/winewayland.drv/wayland_surface.c index 5a808b3ac96..f71e15f2f9a 100644 --- a/dlls/winewayland.drv/wayland_surface.c +++ b/dlls/winewayland.drv/wayland_surface.c @@ -803,6 +803,8 @@ struct wayland_client_surface *wayland_surface_get_client(struct wayland_surface ERR("Failed to create client wl_subsurface\n"); goto err; } + /* Present contents independently of the parent surface. */ + wl_subsurface_set_desync(surface->client->wl_subsurface);
if (process_wayland.wp_viewporter) {
From: Alexandros Frantzis alexandros.frantzis@collabora.com
If the VkSwapchainKHR extent does not match the target window client area, report VK_ERROR_OUT_OF_DATE_KHR, to notify the app that it should recreate the swapchain.
We also report VK_ERROR_OUT_OF_DATE_KHR if the HWND is no longer valid, to match win32 behavior (e.g., nvidia). The application will eventually get VK_ERROR_SURFACE_LOST_KHR during the swapchain recreation process. --- dlls/winewayland.drv/vulkan.c | 113 +++++++++++++++++++++++++++++- dlls/winewayland.drv/waylanddrv.h | 1 + 2 files changed, 113 insertions(+), 1 deletion(-)
diff --git a/dlls/winewayland.drv/vulkan.c b/dlls/winewayland.drv/vulkan.c index 7f73286ec5f..2eaec3af3c9 100644 --- a/dlls/winewayland.drv/vulkan.c +++ b/dlls/winewayland.drv/vulkan.c @@ -73,12 +73,23 @@ static VkResult (*pvkQueuePresentKHR)(VkQueue, const VkPresentInfoKHR *); static void *vulkan_handle; static const struct vulkan_funcs vulkan_funcs;
+static pthread_mutex_t wine_vk_swapchain_mutex = PTHREAD_MUTEX_INITIALIZER; +static struct list wine_vk_swapchain_list = LIST_INIT(wine_vk_swapchain_list); + struct wine_vk_surface { struct wayland_client_surface *client; VkSurfaceKHR native; };
+struct wine_vk_swapchain +{ + struct list entry; + VkSwapchainKHR native; + HWND hwnd; + VkExtent2D extent; +}; + static struct wine_vk_surface *wine_vk_surface_from_handle(VkSurfaceKHR handle) { return (struct wine_vk_surface *)(uintptr_t)handle; @@ -122,6 +133,25 @@ static BOOL wine_vk_surface_is_valid(struct wine_vk_surface *wine_vk_surface) return FALSE; }
+static struct wine_vk_swapchain *wine_vk_swapchain_from_handle(VkSwapchainKHR handle) +{ + struct wine_vk_swapchain *wine_vk_swapchain; + + pthread_mutex_lock(&wine_vk_swapchain_mutex); + LIST_FOR_EACH_ENTRY(wine_vk_swapchain, &wine_vk_swapchain_list, + struct wine_vk_swapchain, entry) + { + if (wine_vk_swapchain->native == handle) + { + pthread_mutex_unlock(&wine_vk_swapchain_mutex); + return wine_vk_swapchain; + } + } + pthread_mutex_unlock(&wine_vk_swapchain_mutex); + + return NULL; +} + /* Helper function for converting between win32 and Wayland compatible VkInstanceCreateInfo. * Caller is responsible for allocation and cleanup of 'dst'. */ static VkResult wine_vk_instance_convert_create_info(const VkInstanceCreateInfo *src, @@ -206,6 +236,58 @@ static VkResult wine_vk_surface_update_caps(struct wine_vk_surface *wine_vk_surf return VK_SUCCESS; }
+static void vk_result_update_out_of_date(VkResult *res) +{ + /* If the current result is less severe than out_of_date, which for + * now applies to all non-failure results, update it. + * TODO: Handle VK_ERROR_FULL_SCREEN_EXCLUSIVE_MODE_LOST_EXT when + * it is supported by winevulkan, since it's also considered + * less severe than out_of_date. */ + if (*res >= 0) *res = VK_ERROR_OUT_OF_DATE_KHR; +} + +static VkResult check_queue_present(const VkPresentInfoKHR *present_info, + VkResult present_res) +{ + VkResult res = present_res; + uint32_t i; + + for (i = 0; i < present_info->swapchainCount; ++i) + { + struct wine_vk_swapchain *wine_vk_swapchain = + wine_vk_swapchain_from_handle(present_info->pSwapchains[i]); + HWND hwnd = wine_vk_swapchain->hwnd; + struct wayland_surface *wayland_surface; + + if ((wayland_surface = wayland_surface_lock_hwnd(hwnd))) + { + int client_width = wayland_surface->window.client_rect.right - + wayland_surface->window.client_rect.left; + int client_height = wayland_surface->window.client_rect.bottom - + wayland_surface->window.client_rect.top; + + pthread_mutex_unlock(&wayland_surface->mutex); + + if (client_width == wine_vk_swapchain->extent.width && + client_height == wine_vk_swapchain->extent.height) + { + /* The window is still available and matches the swapchain size, + * so there is no new error to report. */ + continue; + } + } + + /* We use the out_of_date error even if the window is no longer + * available, to match win32 behavior (e.g., nvidia). The application + * will get surface_lost when it tries to recreate the swapchain. */ + if (present_info->pResults) + vk_result_update_out_of_date(&present_info->pResults[i]); + vk_result_update_out_of_date(&res); + } + + return res; +} + static VkResult wayland_vkCreateInstance(const VkInstanceCreateInfo *create_info, const VkAllocationCallbacks *allocator, VkInstance *instance) @@ -242,6 +324,7 @@ static VkResult wayland_vkCreateSwapchainKHR(VkDevice device, VkResult res; VkSwapchainCreateInfoKHR create_info_host; struct wine_vk_surface *wine_vk_surface; + struct wine_vk_swapchain *wine_vk_swapchain;
TRACE("%p %p %p %p\n", device, create_info, allocator, swapchain);
@@ -252,6 +335,13 @@ static VkResult wayland_vkCreateSwapchainKHR(VkDevice device, if (!wine_vk_surface_is_valid(wine_vk_surface)) return VK_ERROR_SURFACE_LOST_KHR;
+ wine_vk_swapchain = calloc(1, sizeof(*wine_vk_swapchain)); + if (!wine_vk_swapchain) + return VK_ERROR_OUT_OF_HOST_MEMORY; + + wine_vk_swapchain->hwnd = wine_vk_surface_get_hwnd(wine_vk_surface); + wine_vk_swapchain->extent = create_info->imageExtent; + create_info_host = *create_info; create_info_host.surface = wine_vk_surface->native;
@@ -270,9 +360,16 @@ static VkResult wayland_vkCreateSwapchainKHR(VkDevice device, if (res != VK_SUCCESS) { ERR("Failed to create vulkan wayland swapchain, res=%d\n", res); + free(wine_vk_swapchain); return res; }
+ wine_vk_swapchain->native = *swapchain; + + pthread_mutex_lock(&wine_vk_swapchain_mutex); + list_add_head(&wine_vk_swapchain_list, &wine_vk_swapchain->entry); + pthread_mutex_unlock(&wine_vk_swapchain_mutex); + TRACE("Created swapchain=0x%s\n", wine_dbgstr_longlong(*swapchain)); return res; } @@ -377,12 +474,22 @@ static void wayland_vkDestroySwapchainKHR(VkDevice device, VkSwapchainKHR swapchain, const VkAllocationCallbacks *allocator) { + struct wine_vk_swapchain *wine_vk_swapchain; + TRACE("%p, 0x%s %p\n", device, wine_dbgstr_longlong(swapchain), allocator);
if (allocator) FIXME("Support for allocation callbacks not implemented yet\n");
pvkDestroySwapchainKHR(device, swapchain, NULL /* allocator */); + + if ((wine_vk_swapchain = wine_vk_swapchain_from_handle(swapchain))) + { + pthread_mutex_lock(&wine_vk_swapchain_mutex); + list_remove(&wine_vk_swapchain->entry); + pthread_mutex_unlock(&wine_vk_swapchain_mutex); + free(wine_vk_swapchain); + } }
static VkResult wayland_vkEnumerateInstanceExtensionProperties(const char *layer_name, @@ -636,9 +743,13 @@ static VkResult wayland_vkGetSwapchainImagesKHR(VkDevice device, VkSwapchainKHR
static VkResult wayland_vkQueuePresentKHR(VkQueue queue, const VkPresentInfoKHR *present_info) { + VkResult res; + TRACE("%p, %p\n", queue, present_info);
- return pvkQueuePresentKHR(queue, present_info); + res = pvkQueuePresentKHR(queue, present_info); + + return check_queue_present(present_info, res); }
static VkSurfaceKHR wayland_wine_get_native_surface(VkSurfaceKHR surface) diff --git a/dlls/winewayland.drv/waylanddrv.h b/dlls/winewayland.drv/waylanddrv.h index 00c9112d5de..c7d730fbd3e 100644 --- a/dlls/winewayland.drv/waylanddrv.h +++ b/dlls/winewayland.drv/waylanddrv.h @@ -36,6 +36,7 @@ #include "winbase.h" #include "ntgdi.h" #include "wine/gdi_driver.h" +#include "wine/list.h" #include "wine/rbtree.h"
#include "unixlib.h"
From: Alexandros Frantzis alexandros.frantzis@collabora.com
The client area subsurface (the target of Vulkan rendering) is not going to be presented properly (or at all) by the compositor if its parent surface is not mapped or doesn't have the right size, even though the window may be visible from Wine's perspective. To avoid this issue, ensure that the parent surface has up-to-date contents in terms of size, in case these haven't been provided yet, or will never be provided (e.g., when the Vulkan rendering is fullscreen). --- dlls/winewayland.drv/vulkan.c | 2 + dlls/winewayland.drv/wayland_surface.c | 68 ++++++++++++++++++++++++++ dlls/winewayland.drv/waylanddrv.h | 3 ++ dlls/winewayland.drv/window.c | 1 + 4 files changed, 74 insertions(+)
diff --git a/dlls/winewayland.drv/vulkan.c b/dlls/winewayland.drv/vulkan.c index 2eaec3af3c9..cb945986cba 100644 --- a/dlls/winewayland.drv/vulkan.c +++ b/dlls/winewayland.drv/vulkan.c @@ -266,6 +266,8 @@ static VkResult check_queue_present(const VkPresentInfoKHR *present_info, int client_height = wayland_surface->window.client_rect.bottom - wayland_surface->window.client_rect.top;
+ wayland_surface_ensure_contents(wayland_surface); + pthread_mutex_unlock(&wayland_surface->mutex);
if (client_width == wine_vk_swapchain->extent.width && diff --git a/dlls/winewayland.drv/wayland_surface.c b/dlls/winewayland.drv/wayland_surface.c index f71e15f2f9a..57585927914 100644 --- a/dlls/winewayland.drv/wayland_surface.c +++ b/dlls/winewayland.drv/wayland_surface.c @@ -293,6 +293,9 @@ void wayland_surface_clear_role(struct wayland_surface *surface) wl_surface_attach(surface->wl_surface, NULL, 0, 0); wl_surface_commit(surface->wl_surface);
+ surface->buffer_width = 0; + surface->buffer_height = 0; + wl_display_flush(process_wayland.wl_display); }
@@ -336,6 +339,9 @@ void wayland_surface_attach_shm(struct wayland_surface *surface, } free(surface_damage); } + + surface->buffer_width = shm_buffer->width; + surface->buffer_height = shm_buffer->height; }
/********************************************************************** @@ -825,3 +831,65 @@ err: } return NULL; } + +static void dummy_buffer_release(void *data, struct wl_buffer *buffer) +{ + struct wayland_shm_buffer *shm_buffer = data; + TRACE("shm_buffer=%p\n", shm_buffer); + wayland_shm_buffer_unref(shm_buffer); +} + +static const struct wl_buffer_listener dummy_buffer_listener = +{ + dummy_buffer_release +}; + +/********************************************************************** + * wayland_surface_ensure_contents + * + * Ensure that the wayland surface has up-to-date contents, by committing + * a dummy buffer if necessary. + */ +void wayland_surface_ensure_contents(struct wayland_surface *surface) +{ + struct wayland_shm_buffer *dummy_shm_buffer; + HRGN damage; + int width, height; + BOOL needs_contents; + + width = surface->window.rect.right - surface->window.rect.left; + height = surface->window.rect.bottom - surface->window.rect.top; + needs_contents = surface->window.visible && + (surface->buffer_width != width || + surface->buffer_height != height); + + TRACE("surface=%p hwnd=%p needs_contents=%d\n", + surface, surface->hwnd, needs_contents); + + if (!needs_contents) return; + + /* Create a transparent dummy buffer. */ + dummy_shm_buffer = wayland_shm_buffer_create(width, height, WL_SHM_FORMAT_ARGB8888); + if (!dummy_shm_buffer) + { + ERR("Failed to create dummy buffer\n"); + return; + } + wl_buffer_add_listener(dummy_shm_buffer->wl_buffer, &dummy_buffer_listener, + dummy_shm_buffer); + + if (!(damage = NtGdiCreateRectRgn(0, 0, width, height))) + WARN("Failed to create damage region for dummy buffer\n"); + + if (wayland_surface_reconfigure(surface)) + { + wayland_surface_attach_shm(surface, dummy_shm_buffer, damage); + wl_surface_commit(surface->wl_surface); + } + else + { + wayland_shm_buffer_unref(dummy_shm_buffer); + } + + if (damage) NtGdiDeleteObjectApp(damage); +} diff --git a/dlls/winewayland.drv/waylanddrv.h b/dlls/winewayland.drv/waylanddrv.h index c7d730fbd3e..383c79a23fe 100644 --- a/dlls/winewayland.drv/waylanddrv.h +++ b/dlls/winewayland.drv/waylanddrv.h @@ -164,6 +164,7 @@ struct wayland_window_config enum wayland_surface_config_state state; /* The scale (i.e., normalized dpi) the window is rendering at. */ double scale; + BOOL visible; };
struct wayland_client_surface @@ -187,6 +188,7 @@ struct wayland_surface BOOL resizing; struct wayland_window_config window; struct wayland_client_surface *client; + int buffer_width, buffer_height; };
struct wayland_shm_buffer @@ -240,6 +242,7 @@ void wayland_surface_coords_to_window(struct wayland_surface *surface, int *window_x, int *window_y) DECLSPEC_HIDDEN; struct wayland_client_surface *wayland_surface_get_client(struct wayland_surface *surface) DECLSPEC_HIDDEN; BOOL wayland_client_surface_release(struct wayland_client_surface *client) DECLSPEC_HIDDEN; +void wayland_surface_ensure_contents(struct wayland_surface *surface) DECLSPEC_HIDDEN;
/********************************************************************** * Wayland SHM buffer diff --git a/dlls/winewayland.drv/window.c b/dlls/winewayland.drv/window.c index fff3749e9ad..31ecb6542c6 100644 --- a/dlls/winewayland.drv/window.c +++ b/dlls/winewayland.drv/window.c @@ -181,6 +181,7 @@ static void wayland_win_data_get_config(struct wayland_win_data *data,
conf->state = window_state; conf->scale = NtUserGetDpiForWindow(data->hwnd) / 96.0; + conf->visible = (style & WS_VISIBLE) == WS_VISIBLE; }
static void wayland_win_data_update_wayland_surface(struct wayland_win_data *data)
From: Alexandros Frantzis alexandros.frantzis@collabora.com
We cannot depend on the main surface being committed to after the client subsurface is created, so perform a commit to ensure the subsurface position takes effect on creation. --- dlls/winewayland.drv/wayland_surface.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/dlls/winewayland.drv/wayland_surface.c b/dlls/winewayland.drv/wayland_surface.c index 57585927914..285fb9a38c5 100644 --- a/dlls/winewayland.drv/wayland_surface.c +++ b/dlls/winewayland.drv/wayland_surface.c @@ -820,6 +820,8 @@ struct wayland_client_surface *wayland_surface_get_client(struct wayland_surface }
wayland_surface_reconfigure_client(surface); + /* Commit to apply subsurface positioning. */ + wl_surface_commit(surface->wl_surface);
return surface->client;
From: Alexandros Frantzis alexandros.frantzis@collabora.com
This is a simple passthrough implementation to the native Vulkan driver, with the addition of a VkSurfaceKHR invalidation check. --- dlls/winewayland.drv/vulkan.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+)
diff --git a/dlls/winewayland.drv/vulkan.c b/dlls/winewayland.drv/vulkan.c index cb945986cba..d2939f6f9d0 100644 --- a/dlls/winewayland.drv/vulkan.c +++ b/dlls/winewayland.drv/vulkan.c @@ -58,6 +58,7 @@ static void (*pvkDestroyInstance)(VkInstance, const VkAllocationCallbacks *); static void (*pvkDestroySurfaceKHR)(VkInstance, VkSurfaceKHR, const VkAllocationCallbacks *); static void (*pvkDestroySwapchainKHR)(VkDevice, VkSwapchainKHR, const VkAllocationCallbacks *); static VkResult (*pvkEnumerateInstanceExtensionProperties)(const char *, uint32_t *, VkExtensionProperties *); +static VkResult (*pvkGetDeviceGroupSurfacePresentModesKHR)(VkDevice, VkSurfaceKHR, VkDeviceGroupPresentModeFlagsKHR *); static void * (*pvkGetDeviceProcAddr)(VkDevice, const char *); static void * (*pvkGetInstanceProcAddr)(VkInstance, const char *); static VkResult (*pvkGetPhysicalDeviceSurfaceCapabilities2KHR)(VkPhysicalDevice, const VkPhysicalDeviceSurfaceInfo2KHR *, VkSurfaceCapabilities2KHR *); @@ -536,6 +537,20 @@ static VkResult wayland_vkEnumerateInstanceExtensionProperties(const char *layer return res; }
+static VkResult wayland_vkGetDeviceGroupSurfacePresentModesKHR(VkDevice device, + VkSurfaceKHR surface, + VkDeviceGroupPresentModeFlagsKHR *flags) +{ + struct wine_vk_surface *wine_vk_surface = wine_vk_surface_from_handle(surface); + + TRACE("%p, 0x%s, %p\n", device, wine_dbgstr_longlong(surface), flags); + + if (!wine_vk_surface_is_valid(wine_vk_surface)) + return VK_ERROR_SURFACE_LOST_KHR; + + return pvkGetDeviceGroupSurfacePresentModesKHR(device, wine_vk_surface->native, flags); +} + static void *wayland_vkGetDeviceProcAddr(VkDevice device, const char *name) { void *proc_addr; @@ -776,6 +791,7 @@ static void wine_vk_init(void) LOAD_FUNCPTR(vkDestroySurfaceKHR); LOAD_FUNCPTR(vkDestroySwapchainKHR); LOAD_FUNCPTR(vkEnumerateInstanceExtensionProperties); + LOAD_OPTIONAL_FUNCPTR(vkGetDeviceGroupSurfacePresentModesKHR); LOAD_FUNCPTR(vkGetDeviceProcAddr); LOAD_FUNCPTR(vkGetInstanceProcAddr); LOAD_OPTIONAL_FUNCPTR(vkGetPhysicalDeviceSurfaceCapabilities2KHR); @@ -806,6 +822,7 @@ static const struct vulkan_funcs vulkan_funcs = .p_vkDestroySurfaceKHR = wayland_vkDestroySurfaceKHR, .p_vkDestroySwapchainKHR = wayland_vkDestroySwapchainKHR, .p_vkEnumerateInstanceExtensionProperties = wayland_vkEnumerateInstanceExtensionProperties, + .p_vkGetDeviceGroupSurfacePresentModesKHR = wayland_vkGetDeviceGroupSurfacePresentModesKHR, .p_vkGetDeviceProcAddr = wayland_vkGetDeviceProcAddr, .p_vkGetInstanceProcAddr = wayland_vkGetInstanceProcAddr, .p_vkGetPhysicalDeviceSurfaceCapabilities2KHR = wayland_vkGetPhysicalDeviceSurfaceCapabilities2KHR,
From: Alexandros Frantzis alexandros.frantzis@collabora.com
This is a simple passthrough implementation to the native Vulkan driver. --- dlls/winewayland.drv/vulkan.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+)
diff --git a/dlls/winewayland.drv/vulkan.c b/dlls/winewayland.drv/vulkan.c index d2939f6f9d0..919bd7bccf7 100644 --- a/dlls/winewayland.drv/vulkan.c +++ b/dlls/winewayland.drv/vulkan.c @@ -61,6 +61,7 @@ static VkResult (*pvkEnumerateInstanceExtensionProperties)(const char *, uint32_ static VkResult (*pvkGetDeviceGroupSurfacePresentModesKHR)(VkDevice, VkSurfaceKHR, VkDeviceGroupPresentModeFlagsKHR *); static void * (*pvkGetDeviceProcAddr)(VkDevice, const char *); static void * (*pvkGetInstanceProcAddr)(VkInstance, const char *); +static VkResult (*pvkGetPhysicalDevicePresentRectanglesKHR)(VkPhysicalDevice, VkSurfaceKHR, uint32_t *, VkRect2D *); static VkResult (*pvkGetPhysicalDeviceSurfaceCapabilities2KHR)(VkPhysicalDevice, const VkPhysicalDeviceSurfaceInfo2KHR *, VkSurfaceCapabilities2KHR *); static VkResult (*pvkGetPhysicalDeviceSurfaceCapabilitiesKHR)(VkPhysicalDevice, VkSurfaceKHR, VkSurfaceCapabilitiesKHR *); static VkResult (*pvkGetPhysicalDeviceSurfaceFormats2KHR)(VkPhysicalDevice, const VkPhysicalDeviceSurfaceInfo2KHR *, uint32_t *, VkSurfaceFormat2KHR *); @@ -585,6 +586,18 @@ static void *wayland_vkGetInstanceProcAddr(VkInstance instance, const char *name return pvkGetInstanceProcAddr(instance, name); }
+static VkResult wayland_vkGetPhysicalDevicePresentRectanglesKHR(VkPhysicalDevice phys_dev, + VkSurfaceKHR surface, + uint32_t *count, VkRect2D *rects) +{ + struct wine_vk_surface *wine_vk_surface = wine_vk_surface_from_handle(surface); + + TRACE("%p, 0x%s, %p, %p\n", phys_dev, wine_dbgstr_longlong(surface), count, rects); + + return pvkGetPhysicalDevicePresentRectanglesKHR(phys_dev, wine_vk_surface->native, + count, rects); +} + static VkResult wayland_vkGetPhysicalDeviceSurfaceCapabilities2KHR(VkPhysicalDevice phys_dev, const VkPhysicalDeviceSurfaceInfo2KHR *surface_info, VkSurfaceCapabilities2KHR *capabilities) @@ -794,6 +807,7 @@ static void wine_vk_init(void) LOAD_OPTIONAL_FUNCPTR(vkGetDeviceGroupSurfacePresentModesKHR); LOAD_FUNCPTR(vkGetDeviceProcAddr); LOAD_FUNCPTR(vkGetInstanceProcAddr); + LOAD_OPTIONAL_FUNCPTR(vkGetPhysicalDevicePresentRectanglesKHR); LOAD_OPTIONAL_FUNCPTR(vkGetPhysicalDeviceSurfaceCapabilities2KHR); LOAD_FUNCPTR(vkGetPhysicalDeviceSurfaceCapabilitiesKHR); LOAD_OPTIONAL_FUNCPTR(vkGetPhysicalDeviceSurfaceFormats2KHR); @@ -825,6 +839,7 @@ static const struct vulkan_funcs vulkan_funcs = .p_vkGetDeviceGroupSurfacePresentModesKHR = wayland_vkGetDeviceGroupSurfacePresentModesKHR, .p_vkGetDeviceProcAddr = wayland_vkGetDeviceProcAddr, .p_vkGetInstanceProcAddr = wayland_vkGetInstanceProcAddr, + .p_vkGetPhysicalDevicePresentRectanglesKHR = wayland_vkGetPhysicalDevicePresentRectanglesKHR, .p_vkGetPhysicalDeviceSurfaceCapabilities2KHR = wayland_vkGetPhysicalDeviceSurfaceCapabilities2KHR, .p_vkGetPhysicalDeviceSurfaceCapabilitiesKHR = wayland_vkGetPhysicalDeviceSurfaceCapabilitiesKHR, .p_vkGetPhysicalDeviceSurfaceFormats2KHR = wayland_vkGetPhysicalDeviceSurfaceFormats2KHR,
On Tue Nov 28 14:01:13 2023 +0000, Rémi Bernon wrote:
Also btw, we don't want to implement the Vulkan spec, we want to implement Win32 behavior, as bogus as it is.
I have updated the code to return out_of_date in all cases, and applied related simplifications.
This merge request was approved by Rémi Bernon.
On Wed Nov 29 08:35:05 2023 +0000, Shmerl wrote:
Is there a lot left for the mouse input to behave correctly in games?
We need to support:
1. Cursor clipping (with the pointer-constraints protocol) 2. Either `SetCursorPos` (for which no protocol is available at the moment), or directly emit relative mouse movement (with the relative-pointer protocol, this is what the experimental branch is doing).
On Wed Nov 29 06:58:20 2023 +0000, Aida Jonikienė wrote:
@Riesi You spilled my beans 🫘
The upstream driver design has diverged enough from the experimental branch to make such a rebase a painful process. My focus is now completely on upstreaming. The big missing pieces are (in roughly the order of importance, assuming games are the primary target):
1. Mouselook support 2. Changing display resolution (emulated with scaling) 3. OpenGL 4. Positioning of popups/menus/tooltips etc
@rbernon Thanks for the review!
On Wed Nov 29 08:35:05 2023 +0000, Alexandros Frantzis wrote:
The upstream driver design has diverged enough from the experimental branch to make such a rebase a painful process. My focus is now completely on upstreaming. The big missing pieces are (in roughly the order of importance, assuming games are the primary target):
- Mouselook support
- Changing display resolution (emulated with scaling)
- OpenGL
- Positioning of popups/menus/tooltips etc
Also a basic text copy/paste buffer would be great
On Wed Nov 29 08:50:23 2023 +0000, darkblaze69 wrote:
Also a basic text copy/paste buffer would be great
Thanks for the quick answer!
Yeah if everything diverged too much it makes no sense wasting time on rebasing. Looking forward to everything getting upstream then! I hope the road will be less bumpy next year as it has been this year.
On Wed Nov 29 19:56:49 2023 +0000, Alexandros Frantzis wrote:
We need to support:
- Cursor clipping (with the pointer-constraints protocol)
- Either `SetCursorPos` (for which no protocol is available at the
moment), or directly emit relative mouse movement (with the relative-pointer protocol, this is what the experimental branch is doing).
Do you expect there to be an increased latency compared to X11 due the lack of that protocol or it won't be impacted?