From: Rémi Bernon rbernon@codeweavers.com
--- dlls/win32u/vulkan.c | 467 ++++++++++++++++++++++++++++--- dlls/winevulkan/make_vulkan | 43 +-- dlls/winevulkan/vulkan.c | 441 +---------------------------- dlls/winevulkan/vulkan_private.h | 28 -- dlls/winevulkan/vulkan_thunks.c | 52 ++-- dlls/winevulkan/vulkan_thunks.h | 12 - include/wine/vulkan_driver.h | 15 +- 7 files changed, 476 insertions(+), 582 deletions(-)
diff --git a/dlls/win32u/vulkan.c b/dlls/win32u/vulkan.c index 4b46a520c63..c3b322bd4bb 100644 --- a/dlls/win32u/vulkan.c +++ b/dlls/win32u/vulkan.c @@ -38,6 +38,7 @@ #include "wine/vulkan_driver.h"
WINE_DEFAULT_DEBUG_CHANNEL(vulkan); +WINE_DECLARE_DEBUG_CHANNEL(fps);
PFN_vkGetDeviceProcAddr p_vkGetDeviceProcAddr = NULL; PFN_vkGetInstanceProcAddr p_vkGetInstanceProcAddr = NULL; @@ -49,45 +50,114 @@ static struct vulkan_funcs vulkan_funcs;
static const struct vulkan_driver_funcs *driver_funcs;
-static void (*p_vkDestroySurfaceKHR)(VkInstance, VkSurfaceKHR, const VkAllocationCallbacks *); -static VkResult (*p_vkQueuePresentKHR)(VkQueue, const VkPresentInfoKHR *); - struct surface { - struct list entry; - VkSurfaceKHR host_surface; + struct vulkan_surface obj; void *driver_private; HWND hwnd; + + struct list entry; + struct rb_entry window_entry; };
-static inline struct surface *surface_from_handle( VkSurfaceKHR handle ) +static struct surface *surface_from_handle( VkSurfaceKHR handle ) { - return (struct surface *)(uintptr_t)handle; + struct vulkan_surface *obj = vulkan_surface_from_handle( handle ); + return CONTAINING_RECORD( obj, struct surface, obj ); }
static inline VkSurfaceKHR surface_to_handle( struct surface *surface ) { - return (VkSurfaceKHR)(uintptr_t)surface; + return (VkSurfaceKHR)(uintptr_t)&surface->obj; +} + +struct swapchain +{ + struct vulkan_swapchain obj; + struct surface *surface; + VkExtent2D extents; +}; + +static struct swapchain *swapchain_from_handle( VkSwapchainKHR handle ) +{ + struct vulkan_swapchain *obj = vulkan_swapchain_from_handle( handle ); + return CONTAINING_RECORD( obj, struct swapchain, obj ); +} + +static int window_surface_compare( const void *key, const struct rb_entry *entry ) +{ + const struct surface *surface = RB_ENTRY_VALUE( entry, struct surface, window_entry ); + HWND key_hwnd = (HWND)key; + + if (key_hwnd < surface->hwnd) return -1; + if (key_hwnd > surface->hwnd) return 1; + return 0; +} + +static pthread_mutex_t window_surfaces_lock = PTHREAD_MUTEX_INITIALIZER; +static struct rb_tree window_surfaces = {.compare = window_surface_compare}; + +static void window_surfaces_insert( struct surface *surface ) +{ + struct surface *previous; + struct rb_entry *ptr; + + pthread_mutex_lock( &window_surfaces_lock ); + + if (!(ptr = rb_get( &window_surfaces, surface->hwnd ))) + rb_put( &window_surfaces, surface->hwnd, &surface->window_entry ); + else + { + previous = RB_ENTRY_VALUE( ptr, struct surface, window_entry ); + rb_replace( &window_surfaces, &previous->window_entry, &surface->window_entry ); + previous->hwnd = 0; /* make sure previous surface becomes invalid */ + } + + pthread_mutex_unlock( &window_surfaces_lock ); +} + +static void window_surfaces_remove( struct surface *surface ) +{ + pthread_mutex_lock( &window_surfaces_lock ); + if (surface->hwnd) rb_remove( &window_surfaces, &surface->window_entry ); + pthread_mutex_unlock( &window_surfaces_lock ); }
-static VkResult win32u_vkCreateWin32SurfaceKHR( VkInstance instance, const VkWin32SurfaceCreateInfoKHR *info, - const VkAllocationCallbacks *allocator, VkSurfaceKHR *handle ) +static VkResult win32u_vkCreateWin32SurfaceKHR( VkInstance client_instance, const VkWin32SurfaceCreateInfoKHR *create_info, + const VkAllocationCallbacks *allocator, VkSurfaceKHR *ret ) { + struct vulkan_instance *instance = vulkan_instance_from_handle( client_instance ); + VkSurfaceKHR host_surface; struct surface *surface; + HWND dummy = NULL; VkResult res; WND *win;
- TRACE( "instance %p, info %p, allocator %p, handle %p\n", instance, info, allocator, handle ); + TRACE( "client_instance %p, create_info %p, allocator %p, ret %p\n", client_instance, create_info, allocator, ret ); if (allocator) FIXME( "Support for allocation callbacks not implemented yet\n" );
if (!(surface = calloc( 1, sizeof(*surface) ))) return VK_ERROR_OUT_OF_HOST_MEMORY; - if ((res = driver_funcs->p_vulkan_surface_create( info->hwnd, instance, &surface->host_surface, &surface->driver_private ))) + + /* Windows allows surfaces to be created with no HWND, they return VK_ERROR_SURFACE_LOST_KHR later */ + if (!(surface->hwnd = create_info->hwnd)) + { + static const WCHAR staticW[] = {'s','t','a','t','i','c',0}; + UNICODE_STRING static_us = RTL_CONSTANT_STRING( staticW ); + dummy = NtUserCreateWindowEx( 0, &static_us, &static_us, &static_us, WS_POPUP, 0, 0, 0, 0, + NULL, NULL, NULL, NULL, 0, NULL, 0, FALSE ); + WARN( "Created dummy window %p for null surface window\n", dummy ); + surface->hwnd = dummy; + } + + if ((res = driver_funcs->p_vulkan_surface_create( surface->hwnd, instance->host.instance, + &host_surface, &surface->driver_private ))) { + if (dummy) NtUserDestroyWindow( dummy ); free( surface ); return res; }
- if (!(win = get_win_ptr( info->hwnd )) || win == WND_DESKTOP || win == WND_OTHER_PROCESS) + if (!(win = get_win_ptr( surface->hwnd )) || win == WND_DESKTOP || win == WND_OTHER_PROCESS) list_init( &surface->entry ); else { @@ -95,17 +165,28 @@ static VkResult win32u_vkCreateWin32SurfaceKHR( VkInstance instance, const VkWin release_win_ptr( win ); }
- surface->hwnd = info->hwnd; - *handle = surface_to_handle( surface ); + surface->hwnd = create_info->hwnd; + vulkan_object_init( &surface->obj.obj, host_surface ); + surface->obj.instance = instance; + instance->p_insert_object( instance, &surface->obj.obj ); + + if (dummy) NtUserDestroyWindow( dummy ); + window_surfaces_insert( surface ); + + *ret = surface->obj.client.surface; return VK_SUCCESS; }
-static void win32u_vkDestroySurfaceKHR( VkInstance instance, VkSurfaceKHR handle, const VkAllocationCallbacks *allocator ) +static void win32u_vkDestroySurfaceKHR( VkInstance client_instance, VkSurfaceKHR client_surface, + const VkAllocationCallbacks *allocator ) { - struct surface *surface = surface_from_handle( handle ); + struct vulkan_instance *instance = vulkan_instance_from_handle( client_instance ); + struct surface *surface = surface_from_handle( client_surface ); WND *win;
- TRACE( "instance %p, handle 0x%s, allocator %p\n", instance, wine_dbgstr_longlong(handle), allocator ); + if (!surface) return; + + TRACE( "instance %p, handle 0x%s, allocator %p\n", instance, wine_dbgstr_longlong( client_surface ), allocator ); if (allocator) FIXME( "Support for allocation callbacks not implemented yet\n" );
if ((win = get_win_ptr( surface->hwnd )) && win != WND_DESKTOP && win != WND_OTHER_PROCESS) @@ -114,31 +195,342 @@ static void win32u_vkDestroySurfaceKHR( VkInstance instance, VkSurfaceKHR handle release_win_ptr( win ); }
- p_vkDestroySurfaceKHR( instance, surface->host_surface, NULL /* allocator */ ); + instance->p_vkDestroySurfaceKHR( instance->host.instance, surface->obj.host.surface, NULL /* allocator */ ); driver_funcs->p_vulkan_surface_destroy( surface->hwnd, surface->driver_private ); + + instance->p_remove_object( instance, &surface->obj.obj ); + window_surfaces_remove( surface ); + free( surface ); }
-static VkBool32 win32u_vkGetPhysicalDeviceWin32PresentationSupportKHR( VkPhysicalDevice physical_device, uint32_t queue ) +static void adjust_surface_capabilities( struct vulkan_instance *instance, struct surface *surface, + VkSurfaceCapabilitiesKHR *capabilities ) +{ + RECT client_rect; + + /* Many Windows games, for example Strange Brigade, No Man's Sky, Path of Exile + * and World War Z, do not expect that maxImageCount can be set to 0. + * A value of 0 means that there is no limit on the number of images. + * Nvidia reports 8 on Windows, AMD 16. + * https://vulkan.gpuinfo.org/displayreport.php?id=9122#surface + * https://vulkan.gpuinfo.org/displayreport.php?id=9121#surface + */ + if (!capabilities->maxImageCount) capabilities->maxImageCount = max( capabilities->minImageCount, 16 ); + + /* Update the image extents to match what the Win32 WSI would provide. */ + /* FIXME: handle DPI scaling, somehow */ + NtUserGetClientRect( surface->hwnd, &client_rect, NtUserGetDpiForWindow( surface->hwnd ) ); + capabilities->minImageExtent.width = client_rect.right - client_rect.left; + capabilities->minImageExtent.height = client_rect.bottom - client_rect.top; + capabilities->maxImageExtent.width = client_rect.right - client_rect.left; + capabilities->maxImageExtent.height = client_rect.bottom - client_rect.top; + capabilities->currentExtent.width = client_rect.right - client_rect.left; + capabilities->currentExtent.height = client_rect.bottom - client_rect.top; +} + +static VkResult win32u_vkGetPhysicalDeviceSurfaceCapabilitiesKHR( VkPhysicalDevice client_physical_device, VkSurfaceKHR client_surface, + VkSurfaceCapabilitiesKHR *capabilities ) +{ + struct vulkan_physical_device *physical_device = vulkan_physical_device_from_handle( client_physical_device ); + struct surface *surface = surface_from_handle( client_surface ); + struct vulkan_instance *instance = physical_device->instance; + VkResult res; + + if (!NtUserIsWindow( surface->hwnd )) return VK_ERROR_SURFACE_LOST_KHR; + res = instance->p_vkGetPhysicalDeviceSurfaceCapabilitiesKHR( physical_device->host.physical_device, + surface->obj.host.surface, capabilities ); + if (!res) adjust_surface_capabilities( instance, surface, capabilities ); + return res; +} + +static VkResult win32u_vkGetPhysicalDeviceSurfaceCapabilities2KHR( VkPhysicalDevice client_physical_device, const VkPhysicalDeviceSurfaceInfo2KHR *surface_info, + VkSurfaceCapabilities2KHR *capabilities ) +{ + struct vulkan_physical_device *physical_device = vulkan_physical_device_from_handle( client_physical_device ); + struct surface *surface = surface_from_handle( surface_info->surface ); + VkPhysicalDeviceSurfaceInfo2KHR surface_info_host = *surface_info; + struct vulkan_instance *instance = physical_device->instance; + VkResult res; + + if (!instance->p_vkGetPhysicalDeviceSurfaceCapabilities2KHR) + { + /* Until the loader version exporting this function is common, emulate it using the older non-2 version. */ + if (surface_info->pNext || capabilities->pNext) FIXME( "Emulating vkGetPhysicalDeviceSurfaceCapabilities2KHR, ignoring pNext.\n" ); + return win32u_vkGetPhysicalDeviceSurfaceCapabilitiesKHR( client_physical_device, surface_info->surface, + &capabilities->surfaceCapabilities ); + } + + surface_info_host.surface = surface->obj.host.surface; + + if (!NtUserIsWindow( surface->hwnd )) return VK_ERROR_SURFACE_LOST_KHR; + res = instance->p_vkGetPhysicalDeviceSurfaceCapabilities2KHR( physical_device->host.physical_device, + &surface_info_host, capabilities ); + if (!res) adjust_surface_capabilities( instance, surface, &capabilities->surfaceCapabilities ); + return res; +} + +static VkResult win32u_vkGetPhysicalDevicePresentRectanglesKHR( VkPhysicalDevice client_physical_device, VkSurfaceKHR client_surface, + uint32_t *rect_count, VkRect2D *rects ) +{ + struct vulkan_physical_device *physical_device = vulkan_physical_device_from_handle( client_physical_device ); + struct surface *surface = surface_from_handle( client_surface ); + struct vulkan_instance *instance = physical_device->instance; + + if (!NtUserIsWindow( surface->hwnd )) + { + if (rects && !*rect_count) return VK_INCOMPLETE; + if (rects) memset( rects, 0, sizeof(VkRect2D) ); + *rect_count = 1; + return VK_SUCCESS; + } + + return instance->p_vkGetPhysicalDevicePresentRectanglesKHR( physical_device->host.physical_device, + surface->obj.host.surface, rect_count, rects ); +} + +static VkResult win32u_vkGetPhysicalDeviceSurfaceFormatsKHR( VkPhysicalDevice client_physical_device, VkSurfaceKHR client_surface, + uint32_t *format_count, VkSurfaceFormatKHR *formats ) +{ + struct vulkan_physical_device *physical_device = vulkan_physical_device_from_handle( client_physical_device ); + struct surface *surface = surface_from_handle( client_surface ); + struct vulkan_instance *instance = physical_device->instance; + + return instance->p_vkGetPhysicalDeviceSurfaceFormatsKHR( physical_device->host.physical_device, + surface->obj.host.surface, format_count, formats ); +} + +static VkResult win32u_vkGetPhysicalDeviceSurfaceFormats2KHR( VkPhysicalDevice client_physical_device, const VkPhysicalDeviceSurfaceInfo2KHR *surface_info, + uint32_t *format_count, VkSurfaceFormat2KHR *formats ) +{ + struct vulkan_physical_device *physical_device = vulkan_physical_device_from_handle( client_physical_device ); + struct surface *surface = surface_from_handle( surface_info->surface ); + VkPhysicalDeviceSurfaceInfo2KHR surface_info_host = *surface_info; + struct vulkan_instance *instance = physical_device->instance; + VkResult res; + + if (!instance->p_vkGetPhysicalDeviceSurfaceFormats2KHR) + { + VkSurfaceFormatKHR *surface_formats; + UINT i; + + /* Until the loader version exporting this function is common, emulate it using the older non-2 version. */ + if (surface_info->pNext) FIXME( "Emulating vkGetPhysicalDeviceSurfaceFormats2KHR, ignoring pNext.\n" ); + if (!formats) return win32u_vkGetPhysicalDeviceSurfaceFormatsKHR( client_physical_device, surface_info->surface, format_count, NULL ); + + surface_formats = calloc( *format_count, sizeof(*surface_formats) ); + if (!surface_formats) return VK_ERROR_OUT_OF_HOST_MEMORY; + + res = win32u_vkGetPhysicalDeviceSurfaceFormatsKHR( client_physical_device, surface_info->surface, format_count, surface_formats ); + if (!res || res == VK_INCOMPLETE) for (i = 0; i < *format_count; i++) formats[i].surfaceFormat = surface_formats[i]; + + free( surface_formats ); + return res; + } + + surface_info_host.surface = surface->obj.host.surface; + + return instance->p_vkGetPhysicalDeviceSurfaceFormats2KHR( physical_device->host.physical_device, + &surface_info_host, format_count, formats ); +} + +static VkBool32 win32u_vkGetPhysicalDeviceWin32PresentationSupportKHR( VkPhysicalDevice client_physical_device, uint32_t queue ) +{ + struct vulkan_physical_device *physical_device = vulkan_physical_device_from_handle( client_physical_device ); + return driver_funcs->p_vkGetPhysicalDeviceWin32PresentationSupportKHR( physical_device->host.physical_device, queue ); +} + +static VkResult win32u_vkCreateSwapchainKHR( VkDevice client_device, const VkSwapchainCreateInfoKHR *create_info, + const VkAllocationCallbacks *allocator, VkSwapchainKHR *ret ) +{ + struct swapchain *swapchain, *old_swapchain = swapchain_from_handle( create_info->oldSwapchain ); + struct surface *surface = surface_from_handle( create_info->surface ); + struct vulkan_device *device = vulkan_device_from_handle( client_device ); + struct vulkan_physical_device *physical_device = device->physical_device; + struct vulkan_instance *instance = physical_device->instance; + VkSwapchainCreateInfoKHR create_info_host = *create_info; + VkSurfaceCapabilitiesKHR capabilities; + VkSwapchainKHR host_swapchain; + VkResult res; + + if (!NtUserIsWindow( surface->hwnd )) + { + ERR( "surface %p, hwnd %p is invalid!\n", surface, surface->hwnd ); + return VK_ERROR_INITIALIZATION_FAILED; + } + + if (surface) create_info_host.surface = surface->obj.host.surface; + if (old_swapchain) create_info_host.oldSwapchain = old_swapchain->obj.host.swapchain; + + /* update the host surface to commit any pending size change */ + driver_funcs->p_vulkan_surface_update( surface->hwnd, surface->driver_private ); + + /* Windows allows client rect to be empty, but host Vulkan often doesn't, adjust extents back to the host capabilities */ + res = instance->p_vkGetPhysicalDeviceSurfaceCapabilitiesKHR( physical_device->host.physical_device, surface->obj.host.surface, &capabilities ); + if (res) return res; + + create_info_host.imageExtent.width = max( create_info_host.imageExtent.width, capabilities.minImageExtent.width ); + create_info_host.imageExtent.height = max( create_info_host.imageExtent.height, capabilities.minImageExtent.height ); + + if (!(swapchain = calloc( 1, sizeof(*swapchain) ))) return VK_ERROR_OUT_OF_HOST_MEMORY; + + if ((res = device->p_vkCreateSwapchainKHR( device->host.device, &create_info_host, NULL, &host_swapchain ))) + { + free( swapchain ); + return res; + } + + vulkan_object_init( &swapchain->obj.obj, host_swapchain ); + swapchain->surface = surface; + swapchain->extents = create_info->imageExtent; + instance->p_insert_object( instance, &swapchain->obj.obj ); + + *ret = swapchain->obj.client.swapchain; + return VK_SUCCESS; +} + +void win32u_vkDestroySwapchainKHR( VkDevice client_device, VkSwapchainKHR client_swapchain, + const VkAllocationCallbacks *allocator ) +{ + struct vulkan_device *device = vulkan_device_from_handle( client_device ); + struct vulkan_instance *instance = device->physical_device->instance; + struct swapchain *swapchain = swapchain_from_handle( client_swapchain ); + + if (allocator) FIXME( "Support for allocation callbacks not implemented yet\n" ); + if (!swapchain) return; + + device->p_vkDestroySwapchainKHR( device->host.device, swapchain->obj.host.swapchain, NULL ); + instance->p_remove_object( instance, &swapchain->obj.obj ); + + free( swapchain ); +} + +static BOOL extents_equals( const VkExtent2D *extents, const RECT *rect ) +{ + return extents->width == rect->right - rect->left && extents->height == rect->bottom - rect->top; +} + +static VkResult win32u_vkAcquireNextImage2KHR( VkDevice client_device, const VkAcquireNextImageInfoKHR *acquire_info, + uint32_t *image_index ) { - return driver_funcs->p_vkGetPhysicalDeviceWin32PresentationSupportKHR( physical_device, queue ); + struct swapchain *swapchain = swapchain_from_handle( acquire_info->swapchain ); + struct vulkan_device *device = vulkan_device_from_handle( client_device ); + VkAcquireNextImageInfoKHR acquire_info_host = *acquire_info; + struct surface *surface = swapchain->surface; + RECT client_rect; + VkResult res; + + acquire_info_host.swapchain = swapchain->obj.host.swapchain; + + res = device->p_vkAcquireNextImage2KHR( device->host.device, &acquire_info_host, image_index ); + + if (!res && NtUserGetClientRect( surface->hwnd, &client_rect, NtUserGetDpiForWindow( surface->hwnd ) ) && + !extents_equals( &swapchain->extents, &client_rect )) + { + WARN( "Swapchain size %dx%d does not match client rect %s, returning VK_SUBOPTIMAL_KHR\n", + swapchain->extents.width, swapchain->extents.height, wine_dbgstr_rect( &client_rect ) ); + return VK_SUBOPTIMAL_KHR; + } + + return res; }
-static VkResult win32u_vkQueuePresentKHR( VkQueue queue, const VkPresentInfoKHR *present_info, VkSurfaceKHR *surfaces ) +static VkResult win32u_vkAcquireNextImageKHR( VkDevice client_device, VkSwapchainKHR client_swapchain, uint64_t timeout, + VkSemaphore semaphore, VkFence fence, uint32_t *image_index ) { + struct swapchain *swapchain = swapchain_from_handle( client_swapchain ); + struct vulkan_device *device = vulkan_device_from_handle( client_device ); + struct surface *surface = swapchain->surface; + RECT client_rect; + VkResult res; + + res = device->p_vkAcquireNextImageKHR( device->host.device, swapchain->obj.host.swapchain, timeout, + semaphore, fence, image_index ); + + if (!res && NtUserGetClientRect( surface->hwnd, &client_rect, NtUserGetDpiForWindow( surface->hwnd ) ) && + !extents_equals( &swapchain->extents, &client_rect )) + { + WARN( "Swapchain size %dx%d does not match client rect %s, returning VK_SUBOPTIMAL_KHR\n", + swapchain->extents.width, swapchain->extents.height, wine_dbgstr_rect( &client_rect ) ); + return VK_SUBOPTIMAL_KHR; + } + + return res; +} + +static VkResult win32u_vkQueuePresentKHR( VkQueue client_queue, const VkPresentInfoKHR *present_info ) +{ + struct vulkan_queue *queue = vulkan_queue_from_handle( client_queue ); + VkSwapchainKHR swapchains_buffer[16], *swapchains = swapchains_buffer; + VkPresentInfoKHR present_info_host = *present_info; + struct vulkan_device *device = queue->device; VkResult res; UINT i;
TRACE( "queue %p, present_info %p\n", queue, present_info );
- res = p_vkQueuePresentKHR( queue, present_info ); + if (present_info->swapchainCount > ARRAY_SIZE(swapchains_buffer) && + !(swapchains = malloc( present_info->swapchainCount * sizeof(*swapchains) ))) + return VK_ERROR_OUT_OF_HOST_MEMORY; + + for (i = 0; i < present_info->swapchainCount; i++) + { + struct swapchain *swapchain = swapchain_from_handle( present_info->pSwapchains[i] ); + swapchains[i] = swapchain->obj.host.swapchain; + } + + present_info_host.pSwapchains = swapchains; + + res = device->p_vkQueuePresentKHR( queue->host.queue, &present_info_host );
for (i = 0; i < present_info->swapchainCount; i++) { + struct swapchain *swapchain = swapchain_from_handle( present_info->pSwapchains[i] ); VkResult swapchain_res = present_info->pResults ? present_info->pResults[i] : res; - struct surface *surface = surface_from_handle( surfaces[i] ); + struct surface *surface = swapchain->surface; + RECT client_rect;
driver_funcs->p_vulkan_surface_presented( surface->hwnd, surface->driver_private, swapchain_res ); + + if (swapchain_res < VK_SUCCESS) continue; + if (!NtUserGetClientRect( surface->hwnd, &client_rect, NtUserGetDpiForWindow( surface->hwnd ) )) + { + WARN( "Swapchain window %p is invalid, returning VK_ERROR_OUT_OF_DATE_KHR\n", surface->hwnd ); + if (present_info->pResults) present_info->pResults[i] = VK_ERROR_OUT_OF_DATE_KHR; + if (res >= VK_SUCCESS) res = VK_ERROR_OUT_OF_DATE_KHR; + } + else if (swapchain_res) + WARN( "Present returned status %d for swapchain %p\n", swapchain_res, swapchain ); + else if (!extents_equals( &swapchain->extents, &client_rect )) + { + WARN( "Swapchain size %dx%d does not match client rect %s, returning VK_SUBOPTIMAL_KHR\n", + swapchain->extents.width, swapchain->extents.height, wine_dbgstr_rect( &client_rect ) ); + if (present_info->pResults) present_info->pResults[i] = VK_SUBOPTIMAL_KHR; + if (!res) res = VK_SUBOPTIMAL_KHR; + } + } + + if (swapchains != swapchains_buffer) free( swapchains ); + + if (TRACE_ON( fps )) + { + static unsigned long frames, frames_total; + static long prev_time, start_time; + DWORD time; + + time = NtGetTickCount(); + frames++; + frames_total++; + + if (time - prev_time > 1500) + { + TRACE_(fps)( "%p @ approx %.2ffps, total %.2ffps\n", queue, 1000.0 * frames / (time - prev_time), + 1000.0 * frames_total / (time - start_time) ); + prev_time = time; + frames = 0; + + if (!start_time) start_time = time; + } }
return res; @@ -149,27 +541,22 @@ static const char *win32u_get_host_surface_extension(void) return driver_funcs->p_get_host_surface_extension(); }
-static VkSurfaceKHR win32u_wine_get_host_surface( VkSurfaceKHR handle ) -{ - struct surface *surface = surface_from_handle( handle ); - return surface->host_surface; -} - -static void win32u_vulkan_surface_update( VkSurfaceKHR handle ) -{ - struct surface *surface = surface_from_handle( handle ); - driver_funcs->p_vulkan_surface_update( surface->hwnd, surface->driver_private ); -} - static struct vulkan_funcs vulkan_funcs = { .p_vkCreateWin32SurfaceKHR = win32u_vkCreateWin32SurfaceKHR, .p_vkDestroySurfaceKHR = win32u_vkDestroySurfaceKHR, - .p_vkQueuePresentKHR = win32u_vkQueuePresentKHR, + .p_vkGetPhysicalDeviceSurfaceCapabilitiesKHR = win32u_vkGetPhysicalDeviceSurfaceCapabilitiesKHR, + .p_vkGetPhysicalDeviceSurfaceCapabilities2KHR = win32u_vkGetPhysicalDeviceSurfaceCapabilities2KHR, + .p_vkGetPhysicalDevicePresentRectanglesKHR = win32u_vkGetPhysicalDevicePresentRectanglesKHR, + .p_vkGetPhysicalDeviceSurfaceFormatsKHR = win32u_vkGetPhysicalDeviceSurfaceFormatsKHR, + .p_vkGetPhysicalDeviceSurfaceFormats2KHR = win32u_vkGetPhysicalDeviceSurfaceFormats2KHR, .p_vkGetPhysicalDeviceWin32PresentationSupportKHR = win32u_vkGetPhysicalDeviceWin32PresentationSupportKHR, + .p_vkCreateSwapchainKHR = win32u_vkCreateSwapchainKHR, + .p_vkDestroySwapchainKHR = win32u_vkDestroySwapchainKHR, + .p_vkAcquireNextImage2KHR = win32u_vkAcquireNextImage2KHR, + .p_vkAcquireNextImageKHR = win32u_vkAcquireNextImageKHR, + .p_vkQueuePresentKHR = win32u_vkQueuePresentKHR, .p_get_host_surface_extension = win32u_get_host_surface_extension, - .p_wine_get_host_surface = win32u_wine_get_host_surface, - .p_vulkan_surface_update = win32u_vulkan_surface_update, };
static VkResult nulldrv_vulkan_surface_create( HWND hwnd, VkInstance instance, VkSurfaceKHR *surface, void **private ) @@ -306,8 +693,6 @@ static void vulkan_init_once(void) return; \ }
- LOAD_FUNCPTR( vkDestroySurfaceKHR ); - LOAD_FUNCPTR( vkQueuePresentKHR ); LOAD_FUNCPTR( vkGetDeviceProcAddr ); LOAD_FUNCPTR( vkGetInstanceProcAddr ); #undef LOAD_FUNCPTR diff --git a/dlls/winevulkan/make_vulkan b/dlls/winevulkan/make_vulkan index d6d54e76dd1..95f7b31586c 100755 --- a/dlls/winevulkan/make_vulkan +++ b/dlls/winevulkan/make_vulkan @@ -194,18 +194,25 @@ FUNCTION_OVERRIDES = {
# functions for which a user driver entry must be generated USER_DRIVER_FUNCS = { + "vkAcquireNextImage2KHR", + "vkAcquireNextImageKHR", + "vkCreateSwapchainKHR", "vkCreateWin32SurfaceKHR", "vkDestroySurfaceKHR", + "vkDestroySwapchainKHR", "vkGetDeviceProcAddr", "vkGetInstanceProcAddr", + "vkGetPhysicalDevicePresentRectanglesKHR", + "vkGetPhysicalDeviceSurfaceCapabilities2KHR", + "vkGetPhysicalDeviceSurfaceCapabilitiesKHR", + "vkGetPhysicalDeviceSurfaceFormats2KHR", + "vkGetPhysicalDeviceSurfaceFormatsKHR", "vkGetPhysicalDeviceWin32PresentationSupportKHR", "vkQueuePresentKHR", }
# functions for which the unix thunk is manually implemented MANUAL_UNIX_THUNKS = { - "vkAcquireNextImage2KHR", - "vkAcquireNextImageKHR", "vkAllocateCommandBuffers", "vkAllocateMemory", "vkCreateBuffer", @@ -216,16 +223,12 @@ MANUAL_UNIX_THUNKS = { "vkCreateDevice", "vkCreateImage", "vkCreateInstance", - "vkCreateSwapchainKHR", - "vkCreateWin32SurfaceKHR", "vkDestroyCommandPool", "vkDestroyDebugReportCallbackEXT", "vkDestroyDebugUtilsMessengerEXT", "vkDestroyDeferredOperationKHR", "vkDestroyDevice", "vkDestroyInstance", - "vkDestroySurfaceKHR", - "vkDestroySwapchainKHR", "vkEnumerateDeviceExtensionProperties", "vkEnumerateDeviceLayerProperties", "vkEnumerateInstanceExtensionProperties", @@ -252,14 +255,8 @@ MANUAL_UNIX_THUNKS = { "vkGetPhysicalDeviceExternalSemaphorePropertiesKHR", "vkGetPhysicalDeviceImageFormatProperties2", "vkGetPhysicalDeviceImageFormatProperties2KHR", - "vkGetPhysicalDevicePresentRectanglesKHR", - "vkGetPhysicalDeviceSurfaceCapabilities2KHR", - "vkGetPhysicalDeviceSurfaceCapabilitiesKHR", - "vkGetPhysicalDeviceSurfaceFormats2KHR", - "vkGetPhysicalDeviceSurfaceFormatsKHR", "vkMapMemory", "vkMapMemory2KHR", - "vkQueuePresentKHR", "vkUnmapMemory", "vkUnmapMemory2KHR", } @@ -335,16 +332,12 @@ def convert_suffix(direction, win_type, unwrap, is_wrapped): return "host_to_{0}".format(win_type) if unwrap == Unwrap.NONE: return "unwrapped_host_to_{0}".format(win_type) - if unwrap == Unwrap.DRIVER: - return "driver_to_{0}".format(win_type) return "host_to_{0}".format(win_type) else: if not is_wrapped: return "{0}_to_host".format(win_type) if unwrap == Unwrap.NONE: return "{0}_to_unwrapped_host".format(win_type) - if unwrap == Unwrap.DRIVER: - return "{0}_to_driver".format(win_type) return "{0}_to_host".format(win_type)
@@ -645,10 +638,8 @@ class VkFunction(object): # and is used by the code generation. self.required = True if func_info else False
- if self.name in MANUAL_UNIX_THUNKS: + if self.name in MANUAL_UNIX_THUNKS | USER_DRIVER_FUNCS: self.unwrap = Unwrap.NONE - elif self.name in USER_DRIVER_FUNCS: - self.unwrap = Unwrap.DRIVER else: self.unwrap = Unwrap.HOST
@@ -1210,17 +1201,7 @@ class VkHandle(object): LOGGER.error("Unhandled host handle for: {0}".format(self.name)) return None
- def driver_handle(self, name): - """ Provide access to the handle that should be passed to the wine driver """ - - if self.name == "VkSurfaceKHR": - return "wine_surface_from_handle({0})->driver_surface".format(name) - - return self.host_handle(name) - def unwrap_handle(self, name, unwrap): - if unwrap == Unwrap.DRIVER: - return self.driver_handle(name) if unwrap == Unwrap.HOST: return self.host_handle(name) assert unwrap != Unwrap.NONE @@ -1590,8 +1571,6 @@ class VkMember(VkVariable): elif self.is_generic_handle(): if direction == Direction.OUTPUT: LOGGER.error("OUTPUT parameter {0}.{1} cannot be unwrapped".format(self.type, self.name)) - if unwrap == Unwrap.DRIVER and self.is_wrapped(Unwrap.DRIVER): - LOGGER.error("DRIVER unwrapping of {0}.{1} not implemented".format(self.type, self.name)) return "{0}{1} = wine_vk_unwrap_handle({2}{3}, {2}{1});\n".format(output, self.name, input, self.object_type) else: selector_part = ", {0}{1}".format(input, self.selector) if self.selector else "" @@ -1994,8 +1973,6 @@ class VkParam(VkVariable): if unwrap != Unwrap.NONE: unwrap_handle = None if self.object_type != None and self.type == "uint64_t": - if unwrap == Unwrap.DRIVER and self.is_wrapped(Unwrap.DRIVER): - LOGGER.error("DRIVER unwrapping of {0}.{1} not implemented".format(self.type, self.name)) unwrap_handle = "wine_vk_unwrap_handle({0}{1}, {0}{2})".format( params_prefix, self.object_type, self.name)
diff --git a/dlls/winevulkan/vulkan.c b/dlls/winevulkan/vulkan.c index 628bc477ff8..f6de197f720 100644 --- a/dlls/winevulkan/vulkan.c +++ b/dlls/winevulkan/vulkan.c @@ -31,7 +31,6 @@ #include "ntuser.h"
WINE_DEFAULT_DEBUG_CHANNEL(vulkan); -WINE_DECLARE_DEBUG_CHANNEL(fps);
static PFN_vkCreateInstance p_vkCreateInstance; static PFN_vkEnumerateInstanceVersion p_vkEnumerateInstanceVersion; @@ -62,45 +61,6 @@ static void vulkan_object_init_ptr( struct vulkan_object *obj, UINT64 host_handl client->unix_handle = (UINT_PTR)obj; }
-static int window_surface_compare(const void *key, const struct rb_entry *entry) -{ - const struct wine_surface *surface = RB_ENTRY_VALUE(entry, struct wine_surface, window_entry); - HWND key_hwnd = (HWND)key; - - if (key_hwnd < surface->hwnd) return -1; - if (key_hwnd > surface->hwnd) return 1; - return 0; -} - -static pthread_mutex_t window_surfaces_lock = PTHREAD_MUTEX_INITIALIZER; -static struct rb_tree window_surfaces = {.compare = window_surface_compare}; - -static void window_surfaces_insert(struct wine_surface *surface) -{ - struct wine_surface *previous; - struct rb_entry *ptr; - - pthread_mutex_lock(&window_surfaces_lock); - - if (!(ptr = rb_get(&window_surfaces, surface->hwnd))) - rb_put(&window_surfaces, surface->hwnd, &surface->window_entry); - else - { - previous = RB_ENTRY_VALUE(ptr, struct wine_surface, window_entry); - rb_replace(&window_surfaces, &previous->window_entry, &surface->window_entry); - previous->hwnd = 0; /* make sure previous surface becomes invalid */ - } - - pthread_mutex_unlock(&window_surfaces_lock); -} - -static void window_surfaces_remove(struct wine_surface *surface) -{ - pthread_mutex_lock(&window_surfaces_lock); - if (surface->hwnd) rb_remove(&window_surfaces, &surface->window_entry); - pthread_mutex_unlock(&window_surfaces_lock); -} - static BOOL is_wow64(void) { return sizeof(void *) == sizeof(UINT64) && NtCurrentTeb()->WowTebOffset; @@ -1005,6 +965,8 @@ VkResult wine_vkCreateInstance(const VkInstanceCreateInfo *create_info, }
vulkan_object_init_ptr(&instance->obj.obj, (UINT_PTR)host_instance, &client_instance->obj); + instance->obj.p_insert_object = vulkan_instance_insert_object; + instance->obj.p_remove_object = vulkan_instance_remove_object;
/* Load all instance functions we are aware of. Note the loader takes care * of any filtering for extensions which were not requested, but which the @@ -1677,269 +1639,6 @@ void wine_vkGetPhysicalDeviceExternalSemaphorePropertiesKHR(VkPhysicalDevice cli properties->externalSemaphoreFeatures = 0; }
-VkResult wine_vkCreateWin32SurfaceKHR(VkInstance client_instance, const VkWin32SurfaceCreateInfoKHR *create_info, - const VkAllocationCallbacks *allocator, VkSurfaceKHR *ret) -{ - struct vulkan_instance *instance = vulkan_instance_from_handle(client_instance); - VkWin32SurfaceCreateInfoKHR create_info_host = *create_info; - struct wine_surface *surface; - VkSurfaceKHR host_surface; - HWND dummy = NULL; - VkResult res; - - if (allocator) FIXME("Support for allocation callbacks not implemented yet\n"); - - if (!(surface = calloc(1, sizeof(*surface)))) return VK_ERROR_OUT_OF_HOST_MEMORY; - - /* Windows allows surfaces to be created with no HWND, they return VK_ERROR_SURFACE_LOST_KHR later */ - if (!(surface->hwnd = create_info->hwnd)) - { - static const WCHAR staticW[] = {'s','t','a','t','i','c',0}; - UNICODE_STRING static_us = RTL_CONSTANT_STRING(staticW); - dummy = NtUserCreateWindowEx(0, &static_us, &static_us, &static_us, WS_POPUP, - 0, 0, 0, 0, NULL, NULL, NULL, NULL, 0, NULL, 0, FALSE); - WARN("Created dummy window %p for null surface window\n", dummy); - create_info_host.hwnd = surface->hwnd = dummy; - } - - res = vk_funcs->p_vkCreateWin32SurfaceKHR(instance->host.instance, &create_info_host, - NULL /* allocator */, &surface->driver_surface); - if (res != VK_SUCCESS) - { - if (dummy) NtUserDestroyWindow(dummy); - free(surface); - return res; - } - - host_surface = vk_funcs->p_wine_get_host_surface(surface->driver_surface); - vulkan_object_init(&surface->obj.obj, host_surface); - surface->obj.instance = instance; - vulkan_instance_insert_object(instance, &surface->obj.obj); - - if (dummy) NtUserDestroyWindow(dummy); - window_surfaces_insert(surface); - - *ret = surface->obj.client.surface; - return VK_SUCCESS; -} - -void wine_vkDestroySurfaceKHR(VkInstance client_instance, VkSurfaceKHR client_surface, - const VkAllocationCallbacks *allocator) -{ - struct vulkan_instance *instance = vulkan_instance_from_handle(client_instance); - struct wine_surface *surface = wine_surface_from_handle(client_surface); - - if (!surface) - return; - - vk_funcs->p_vkDestroySurfaceKHR(instance->host.instance, surface->driver_surface, NULL); - vulkan_instance_remove_object(instance, &surface->obj.obj); - window_surfaces_remove(surface); - - free(surface); -} - -static BOOL extents_equals(const VkExtent2D *extents, const RECT *rect) -{ - return extents->width == rect->right - rect->left && - extents->height == rect->bottom - rect->top; -} - -VkResult wine_vkAcquireNextImage2KHR(VkDevice client_device, const VkAcquireNextImageInfoKHR *acquire_info, - uint32_t *image_index) -{ - struct wine_swapchain *swapchain = wine_swapchain_from_handle(acquire_info->swapchain); - struct vulkan_device *device = vulkan_device_from_handle(client_device); - VkAcquireNextImageInfoKHR acquire_info_host = *acquire_info; - struct wine_surface *surface = swapchain->surface; - RECT client_rect; - VkResult res; - - acquire_info_host.swapchain = swapchain->obj.host.swapchain; - res = device->p_vkAcquireNextImage2KHR(device->host.device, &acquire_info_host, image_index); - - if (res == VK_SUCCESS && NtUserGetClientRect(surface->hwnd, &client_rect, NtUserGetDpiForWindow(surface->hwnd)) && - !extents_equals(&swapchain->extents, &client_rect)) - { - WARN("Swapchain size %dx%d does not match client rect %s, returning VK_SUBOPTIMAL_KHR\n", - swapchain->extents.width, swapchain->extents.height, wine_dbgstr_rect(&client_rect)); - return VK_SUBOPTIMAL_KHR; - } - - return res; -} - -VkResult wine_vkAcquireNextImageKHR(VkDevice client_device, VkSwapchainKHR client_swapchain, uint64_t timeout, - VkSemaphore semaphore, VkFence fence, uint32_t *image_index) -{ - struct wine_swapchain *swapchain = wine_swapchain_from_handle(client_swapchain); - struct vulkan_device *device = vulkan_device_from_handle(client_device); - struct wine_surface *surface = swapchain->surface; - RECT client_rect; - VkResult res; - - res = device->p_vkAcquireNextImageKHR(device->host.device, swapchain->obj.host.swapchain, timeout, - semaphore, fence, image_index); - - if (res == VK_SUCCESS && NtUserGetClientRect(surface->hwnd, &client_rect, NtUserGetDpiForWindow(surface->hwnd)) && - !extents_equals(&swapchain->extents, &client_rect)) - { - WARN("Swapchain size %dx%d does not match client rect %s, returning VK_SUBOPTIMAL_KHR\n", - swapchain->extents.width, swapchain->extents.height, wine_dbgstr_rect(&client_rect)); - return VK_SUBOPTIMAL_KHR; - } - - return res; -} - -VkResult wine_vkCreateSwapchainKHR(VkDevice client_device, const VkSwapchainCreateInfoKHR *create_info, - const VkAllocationCallbacks *allocator, VkSwapchainKHR *ret) -{ - struct wine_swapchain *object, *old_swapchain = wine_swapchain_from_handle(create_info->oldSwapchain); - struct wine_surface *surface = wine_surface_from_handle(create_info->surface); - struct vulkan_device *device = vulkan_device_from_handle(client_device); - struct vulkan_physical_device *physical_device = device->physical_device; - struct vulkan_instance *instance = physical_device->instance; - VkSwapchainCreateInfoKHR create_info_host = *create_info; - VkSurfaceCapabilitiesKHR capabilities; - VkSwapchainKHR host_swapchain; - VkResult res; - - if (!NtUserIsWindow(surface->hwnd)) - { - ERR("surface %p, hwnd %p is invalid!\n", surface, surface->hwnd); - return VK_ERROR_INITIALIZATION_FAILED; - } - - if (surface) create_info_host.surface = surface->obj.host.surface; - if (old_swapchain) create_info_host.oldSwapchain = old_swapchain->obj.host.swapchain; - - /* update the host surface to commit any pending size change */ - vk_funcs->p_vulkan_surface_update( surface->driver_surface ); - - /* Windows allows client rect to be empty, but host Vulkan often doesn't, adjust extents back to the host capabilities */ - res = instance->p_vkGetPhysicalDeviceSurfaceCapabilitiesKHR(physical_device->host.physical_device, - surface->obj.host.surface, &capabilities); - if (res != VK_SUCCESS) return res; - - create_info_host.imageExtent.width = max(create_info_host.imageExtent.width, capabilities.minImageExtent.width); - create_info_host.imageExtent.height = max(create_info_host.imageExtent.height, capabilities.minImageExtent.height); - - if (!(object = calloc(1, sizeof(*object)))) return VK_ERROR_OUT_OF_HOST_MEMORY; - res = device->p_vkCreateSwapchainKHR(device->host.device, &create_info_host, NULL, &host_swapchain); - if (res != VK_SUCCESS) - { - free(object); - return res; - } - - vulkan_object_init(&object->obj.obj, host_swapchain); - object->surface = surface; - object->extents = create_info->imageExtent; - vulkan_instance_insert_object(instance, &object->obj.obj); - - *ret = object->obj.client.swapchain; - return VK_SUCCESS; -} - -void wine_vkDestroySwapchainKHR(VkDevice client_device, VkSwapchainKHR client_swapchain, - const VkAllocationCallbacks *allocator) -{ - struct vulkan_device *device = vulkan_device_from_handle(client_device); - struct vulkan_instance *instance = device->physical_device->instance; - struct wine_swapchain *swapchain = wine_swapchain_from_handle(client_swapchain); - - if (allocator) FIXME("Support for allocation callbacks not implemented yet\n"); - if (!swapchain) return; - - device->p_vkDestroySwapchainKHR(device->host.device, swapchain->obj.host.swapchain, NULL); - vulkan_instance_remove_object(instance, &swapchain->obj.obj); - - free(swapchain); -} - -VkResult wine_vkQueuePresentKHR(VkQueue client_queue, const VkPresentInfoKHR *present_info) -{ - VkSwapchainKHR swapchains_buffer[16], *swapchains = swapchains_buffer; - VkSurfaceKHR surfaces_buffer[ARRAY_SIZE(swapchains_buffer)], *surfaces = surfaces_buffer; - struct vulkan_queue *queue = vulkan_queue_from_handle(client_queue); - VkPresentInfoKHR present_info_host = *present_info; - VkResult res; - UINT i; - - if (present_info->swapchainCount > ARRAY_SIZE(swapchains_buffer) && - (!(swapchains = malloc(present_info->swapchainCount * sizeof(*swapchains))) || - !(surfaces = malloc(present_info->swapchainCount * sizeof(*surfaces))))) - { - free(swapchains); - return VK_ERROR_OUT_OF_HOST_MEMORY; - } - - for (i = 0; i < present_info->swapchainCount; i++) - { - struct wine_swapchain *swapchain = wine_swapchain_from_handle(present_info->pSwapchains[i]); - struct wine_surface *surface = swapchain->surface; - swapchains[i] = swapchain->obj.host.swapchain; - surfaces[i] = surface->driver_surface; - } - - present_info_host.pSwapchains = swapchains; - - res = vk_funcs->p_vkQueuePresentKHR(queue->host.queue, &present_info_host, surfaces); - - for (i = 0; i < present_info->swapchainCount; i++) - { - struct wine_swapchain *swapchain = wine_swapchain_from_handle(present_info->pSwapchains[i]); - VkResult swapchain_res = present_info->pResults ? present_info->pResults[i] : res; - struct wine_surface *surface = swapchain->surface; - RECT client_rect; - - if (swapchain_res < VK_SUCCESS) continue; - if (!NtUserGetClientRect(surface->hwnd, &client_rect, NtUserGetDpiForWindow(surface->hwnd))) - { - WARN("Swapchain window %p is invalid, returning VK_ERROR_OUT_OF_DATE_KHR\n", surface->hwnd); - if (present_info->pResults) present_info->pResults[i] = VK_ERROR_OUT_OF_DATE_KHR; - if (res >= VK_SUCCESS) res = VK_ERROR_OUT_OF_DATE_KHR; - } - else if (swapchain_res != VK_SUCCESS) - WARN("Present returned status %d for swapchain %p\n", swapchain_res, swapchain); - else if (!extents_equals(&swapchain->extents, &client_rect)) - { - WARN("Swapchain size %dx%d does not match client rect %s, returning VK_SUBOPTIMAL_KHR\n", - swapchain->extents.width, swapchain->extents.height, wine_dbgstr_rect(&client_rect)); - if (present_info->pResults) present_info->pResults[i] = VK_SUBOPTIMAL_KHR; - if (res == VK_SUCCESS) res = VK_SUBOPTIMAL_KHR; - } - } - - if (swapchains != swapchains_buffer) free(swapchains); - if (surfaces != surfaces_buffer) free(surfaces); - - if (TRACE_ON(fps)) - { - static unsigned long frames, frames_total; - static long prev_time, start_time; - DWORD time; - - time = NtGetTickCount(); - frames++; - frames_total++; - - if (time - prev_time > 1500) - { - TRACE_(fps)("%p @ approx %.2ffps, total %.2ffps\n", queue, - 1000.0 * frames / (time - prev_time), - 1000.0 * frames_total / (time - start_time)); - prev_time = time; - frames = 0; - - if (!start_time) start_time = time; - } - } - - return res; -} - VkResult wine_vkAllocateMemory(VkDevice client_device, const VkMemoryAllocateInfo *alloc_info, const VkAllocationCallbacks *allocator, VkDeviceMemory *ret) { @@ -2251,142 +1950,6 @@ VkResult wine_vkCreateImage(VkDevice client_device, const VkImageCreateInfo *cre return device->p_vkCreateImage(device->host.device, &info, NULL, image); }
-static void adjust_surface_capabilities(struct vulkan_instance *instance, struct wine_surface *surface, - VkSurfaceCapabilitiesKHR *capabilities) -{ - RECT client_rect; - - /* Many Windows games, for example Strange Brigade, No Man's Sky, Path of Exile - * and World War Z, do not expect that maxImageCount can be set to 0. - * A value of 0 means that there is no limit on the number of images. - * Nvidia reports 8 on Windows, AMD 16. - * https://vulkan.gpuinfo.org/displayreport.php?id=9122#surface - * https://vulkan.gpuinfo.org/displayreport.php?id=9121#surface - */ - if (!capabilities->maxImageCount) - capabilities->maxImageCount = max(capabilities->minImageCount, 16); - - /* Update the image extents to match what the Win32 WSI would provide. */ - /* FIXME: handle DPI scaling, somehow */ - NtUserGetClientRect(surface->hwnd, &client_rect, NtUserGetDpiForWindow(surface->hwnd)); - capabilities->minImageExtent.width = client_rect.right - client_rect.left; - capabilities->minImageExtent.height = client_rect.bottom - client_rect.top; - capabilities->maxImageExtent.width = client_rect.right - client_rect.left; - capabilities->maxImageExtent.height = client_rect.bottom - client_rect.top; - capabilities->currentExtent.width = client_rect.right - client_rect.left; - capabilities->currentExtent.height = client_rect.bottom - client_rect.top; -} - -VkResult wine_vkGetPhysicalDeviceSurfaceCapabilitiesKHR(VkPhysicalDevice client_physical_device, VkSurfaceKHR client_surface, - VkSurfaceCapabilitiesKHR *capabilities) -{ - struct vulkan_physical_device *physical_device = vulkan_physical_device_from_handle(client_physical_device); - struct wine_surface *surface = wine_surface_from_handle(client_surface); - struct vulkan_instance *instance = physical_device->instance; - VkResult res; - - if (!NtUserIsWindow(surface->hwnd)) return VK_ERROR_SURFACE_LOST_KHR; - res = instance->p_vkGetPhysicalDeviceSurfaceCapabilitiesKHR(physical_device->host.physical_device, - surface->obj.host.surface, capabilities); - if (res == VK_SUCCESS) adjust_surface_capabilities(instance, surface, capabilities); - return res; -} - -VkResult wine_vkGetPhysicalDeviceSurfaceCapabilities2KHR(VkPhysicalDevice client_physical_device, const VkPhysicalDeviceSurfaceInfo2KHR *surface_info, - VkSurfaceCapabilities2KHR *capabilities) -{ - struct vulkan_physical_device *physical_device = vulkan_physical_device_from_handle(client_physical_device); - struct wine_surface *surface = wine_surface_from_handle(surface_info->surface); - VkPhysicalDeviceSurfaceInfo2KHR surface_info_host = *surface_info; - struct vulkan_instance *instance = physical_device->instance; - VkResult res; - - if (!instance->p_vkGetPhysicalDeviceSurfaceCapabilities2KHR) - { - /* Until the loader version exporting this function is common, emulate it using the older non-2 version. */ - if (surface_info->pNext || capabilities->pNext) FIXME("Emulating vkGetPhysicalDeviceSurfaceCapabilities2KHR, ignoring pNext.\n"); - return wine_vkGetPhysicalDeviceSurfaceCapabilitiesKHR(client_physical_device, surface_info->surface, - &capabilities->surfaceCapabilities); - } - - surface_info_host.surface = surface->obj.host.surface; - - if (!NtUserIsWindow(surface->hwnd)) return VK_ERROR_SURFACE_LOST_KHR; - res = instance->p_vkGetPhysicalDeviceSurfaceCapabilities2KHR(physical_device->host.physical_device, - &surface_info_host, capabilities); - if (res == VK_SUCCESS) adjust_surface_capabilities(instance, surface, &capabilities->surfaceCapabilities); - return res; -} - -VkResult wine_vkGetPhysicalDevicePresentRectanglesKHR(VkPhysicalDevice client_physical_device, VkSurfaceKHR client_surface, - uint32_t *rect_count, VkRect2D *rects) -{ - struct vulkan_physical_device *physical_device = vulkan_physical_device_from_handle(client_physical_device); - struct wine_surface *surface = wine_surface_from_handle(client_surface); - struct vulkan_instance *instance = physical_device->instance; - - if (!NtUserIsWindow(surface->hwnd)) - { - if (rects && !*rect_count) return VK_INCOMPLETE; - if (rects) memset(rects, 0, sizeof(VkRect2D)); - *rect_count = 1; - return VK_SUCCESS; - } - - return instance->p_vkGetPhysicalDevicePresentRectanglesKHR(physical_device->host.physical_device, - surface->obj.host.surface, rect_count, rects); -} - -VkResult wine_vkGetPhysicalDeviceSurfaceFormatsKHR(VkPhysicalDevice client_physical_device, VkSurfaceKHR client_surface, - uint32_t *format_count, VkSurfaceFormatKHR *formats) -{ - struct vulkan_physical_device *physical_device = vulkan_physical_device_from_handle(client_physical_device); - struct wine_surface *surface = wine_surface_from_handle(client_surface); - struct vulkan_instance *instance = physical_device->instance; - - return instance->p_vkGetPhysicalDeviceSurfaceFormatsKHR(physical_device->host.physical_device, surface->obj.host.surface, - format_count, formats); -} - -VkResult wine_vkGetPhysicalDeviceSurfaceFormats2KHR(VkPhysicalDevice client_physical_device, const VkPhysicalDeviceSurfaceInfo2KHR *surface_info, - uint32_t *format_count, VkSurfaceFormat2KHR *formats) -{ - struct vulkan_physical_device *physical_device = vulkan_physical_device_from_handle(client_physical_device); - struct wine_surface *surface = wine_surface_from_handle(surface_info->surface); - VkPhysicalDeviceSurfaceInfo2KHR surface_info_host = *surface_info; - struct vulkan_instance *instance = physical_device->instance; - VkResult res; - - if (!instance->p_vkGetPhysicalDeviceSurfaceFormats2KHR) - { - VkSurfaceFormatKHR *surface_formats; - UINT i; - - /* Until the loader version exporting this function is common, emulate it using the older non-2 version. */ - if (surface_info->pNext) FIXME("Emulating vkGetPhysicalDeviceSurfaceFormats2KHR, ignoring pNext.\n"); - - if (!formats) return wine_vkGetPhysicalDeviceSurfaceFormatsKHR(client_physical_device, surface_info->surface, format_count, NULL); - - surface_formats = calloc(*format_count, sizeof(*surface_formats)); - if (!surface_formats) return VK_ERROR_OUT_OF_HOST_MEMORY; - - res = wine_vkGetPhysicalDeviceSurfaceFormatsKHR(client_physical_device, surface_info->surface, format_count, surface_formats); - if (res == VK_SUCCESS || res == VK_INCOMPLETE) - { - for (i = 0; i < *format_count; i++) - formats[i].surfaceFormat = surface_formats[i]; - } - - free(surface_formats); - return res; - } - - surface_info_host.surface = surface->obj.host.surface; - - return instance->p_vkGetPhysicalDeviceSurfaceFormats2KHR(physical_device->host.physical_device, - &surface_info_host, format_count, formats); -} - VkResult wine_vkCreateDebugUtilsMessengerEXT(VkInstance client_instance, const VkDebugUtilsMessengerCreateInfoEXT *create_info, const VkAllocationCallbacks *allocator, diff --git a/dlls/winevulkan/vulkan_private.h b/dlls/winevulkan/vulkan_private.h index 23a29bb460f..87e12c63b2b 100644 --- a/dlls/winevulkan/vulkan_private.h +++ b/dlls/winevulkan/vulkan_private.h @@ -154,34 +154,6 @@ static inline struct wine_debug_report_callback *wine_debug_report_callback_from return (struct wine_debug_report_callback *)(uintptr_t)handle; }
-struct wine_surface -{ - struct vulkan_surface obj; - VkSurfaceKHR driver_surface; - HWND hwnd; - - struct rb_entry window_entry; -}; - -static inline struct wine_surface *wine_surface_from_handle(VkSurfaceKHR handle) -{ - struct vulkan_surface *obj = vulkan_surface_from_handle(handle); - return CONTAINING_RECORD(obj, struct wine_surface, obj); -} - -struct wine_swapchain -{ - struct vulkan_swapchain obj; - struct wine_surface *surface; - VkExtent2D extents; -}; - -static inline struct wine_swapchain *wine_swapchain_from_handle(VkSwapchainKHR handle) -{ - struct vulkan_swapchain *obj = vulkan_swapchain_from_handle(handle); - return CONTAINING_RECORD(obj, struct wine_swapchain, obj); -} - BOOL wine_vk_device_extension_supported(const char *name); BOOL wine_vk_instance_extension_supported(const char *name); BOOL wine_vk_is_host_surface_extension(const char *name); diff --git a/dlls/winevulkan/vulkan_thunks.c b/dlls/winevulkan/vulkan_thunks.c index d515ad7e0e0..f3b06622208 100644 --- a/dlls/winevulkan/vulkan_thunks.c +++ b/dlls/winevulkan/vulkan_thunks.c @@ -36616,7 +36616,7 @@ static NTSTATUS thunk64_vkAcquireNextImage2KHR(void *args)
TRACE("%p, %p, %p\n", params->device, params->pAcquireInfo, params->pImageIndex);
- params->result = wine_vkAcquireNextImage2KHR(params->device, params->pAcquireInfo, params->pImageIndex); + params->result = vk_funcs->p_vkAcquireNextImage2KHR(params->device, params->pAcquireInfo, params->pImageIndex); return STATUS_SUCCESS; } #endif /* _WIN64 */ @@ -36635,7 +36635,7 @@ static NTSTATUS thunk32_vkAcquireNextImage2KHR(void *args) TRACE("%#x, %#x, %#x\n", params->device, params->pAcquireInfo, params->pImageIndex);
convert_VkAcquireNextImageInfoKHR_win32_to_unwrapped_host((const VkAcquireNextImageInfoKHR32 *)UlongToPtr(params->pAcquireInfo), &pAcquireInfo_host); - params->result = wine_vkAcquireNextImage2KHR((VkDevice)UlongToPtr(params->device), &pAcquireInfo_host, (uint32_t *)UlongToPtr(params->pImageIndex)); + params->result = vk_funcs->p_vkAcquireNextImage2KHR((VkDevice)UlongToPtr(params->device), &pAcquireInfo_host, (uint32_t *)UlongToPtr(params->pImageIndex)); return STATUS_SUCCESS; }
@@ -36646,7 +36646,7 @@ static NTSTATUS thunk64_vkAcquireNextImageKHR(void *args)
TRACE("%p, 0x%s, 0x%s, 0x%s, 0x%s, %p\n", params->device, wine_dbgstr_longlong(params->swapchain), wine_dbgstr_longlong(params->timeout), wine_dbgstr_longlong(params->semaphore), wine_dbgstr_longlong(params->fence), params->pImageIndex);
- params->result = wine_vkAcquireNextImageKHR(params->device, params->swapchain, params->timeout, params->semaphore, params->fence, params->pImageIndex); + params->result = vk_funcs->p_vkAcquireNextImageKHR(params->device, params->swapchain, params->timeout, params->semaphore, params->fence, params->pImageIndex); return STATUS_SUCCESS; } #endif /* _WIN64 */ @@ -36666,7 +36666,7 @@ static NTSTATUS thunk32_vkAcquireNextImageKHR(void *args)
TRACE("%#x, 0x%s, 0x%s, 0x%s, 0x%s, %#x\n", params->device, wine_dbgstr_longlong(params->swapchain), wine_dbgstr_longlong(params->timeout), wine_dbgstr_longlong(params->semaphore), wine_dbgstr_longlong(params->fence), params->pImageIndex);
- params->result = wine_vkAcquireNextImageKHR((VkDevice)UlongToPtr(params->device), params->swapchain, params->timeout, params->semaphore, params->fence, (uint32_t *)UlongToPtr(params->pImageIndex)); + params->result = vk_funcs->p_vkAcquireNextImageKHR((VkDevice)UlongToPtr(params->device), params->swapchain, params->timeout, params->semaphore, params->fence, (uint32_t *)UlongToPtr(params->pImageIndex)); return STATUS_SUCCESS; }
@@ -45155,7 +45155,7 @@ static NTSTATUS thunk64_vkCreateSwapchainKHR(void *args)
TRACE("%p, %p, %p, %p\n", params->device, params->pCreateInfo, params->pAllocator, params->pSwapchain);
- params->result = wine_vkCreateSwapchainKHR(params->device, params->pCreateInfo, params->pAllocator, params->pSwapchain); + params->result = vk_funcs->p_vkCreateSwapchainKHR(params->device, params->pCreateInfo, params->pAllocator, params->pSwapchain); return STATUS_SUCCESS; } #endif /* _WIN64 */ @@ -45178,7 +45178,7 @@ static NTSTATUS thunk32_vkCreateSwapchainKHR(void *args)
init_conversion_context(ctx); convert_VkSwapchainCreateInfoKHR_win32_to_unwrapped_host(ctx, (const VkSwapchainCreateInfoKHR32 *)UlongToPtr(params->pCreateInfo), &pCreateInfo_host); - params->result = wine_vkCreateSwapchainKHR((VkDevice)UlongToPtr(params->device), &pCreateInfo_host, (const VkAllocationCallbacks *)UlongToPtr(params->pAllocator), (VkSwapchainKHR *)UlongToPtr(params->pSwapchain)); + params->result = vk_funcs->p_vkCreateSwapchainKHR((VkDevice)UlongToPtr(params->device), &pCreateInfo_host, (const VkAllocationCallbacks *)UlongToPtr(params->pAllocator), (VkSwapchainKHR *)UlongToPtr(params->pSwapchain)); free_conversion_context(ctx); return STATUS_SUCCESS; } @@ -45291,7 +45291,7 @@ static NTSTATUS thunk64_vkCreateWin32SurfaceKHR(void *args)
TRACE("%p, %p, %p, %p\n", params->instance, params->pCreateInfo, params->pAllocator, params->pSurface);
- params->result = wine_vkCreateWin32SurfaceKHR(params->instance, params->pCreateInfo, params->pAllocator, params->pSurface); + params->result = vk_funcs->p_vkCreateWin32SurfaceKHR(params->instance, params->pCreateInfo, params->pAllocator, params->pSurface); return STATUS_SUCCESS; } #endif /* _WIN64 */ @@ -45311,7 +45311,7 @@ static NTSTATUS thunk32_vkCreateWin32SurfaceKHR(void *args) TRACE("%#x, %#x, %#x, %#x\n", params->instance, params->pCreateInfo, params->pAllocator, params->pSurface);
convert_VkWin32SurfaceCreateInfoKHR_win32_to_host((const VkWin32SurfaceCreateInfoKHR32 *)UlongToPtr(params->pCreateInfo), &pCreateInfo_host); - params->result = wine_vkCreateWin32SurfaceKHR((VkInstance)UlongToPtr(params->instance), &pCreateInfo_host, (const VkAllocationCallbacks *)UlongToPtr(params->pAllocator), (VkSurfaceKHR *)UlongToPtr(params->pSurface)); + params->result = vk_funcs->p_vkCreateWin32SurfaceKHR((VkInstance)UlongToPtr(params->instance), &pCreateInfo_host, (const VkAllocationCallbacks *)UlongToPtr(params->pAllocator), (VkSurfaceKHR *)UlongToPtr(params->pSurface)); return STATUS_SUCCESS; }
@@ -46587,7 +46587,7 @@ static NTSTATUS thunk64_vkDestroySurfaceKHR(void *args)
TRACE("%p, 0x%s, %p\n", params->instance, wine_dbgstr_longlong(params->surface), params->pAllocator);
- wine_vkDestroySurfaceKHR(params->instance, params->surface, params->pAllocator); + vk_funcs->p_vkDestroySurfaceKHR(params->instance, params->surface, params->pAllocator); return STATUS_SUCCESS; } #endif /* _WIN64 */ @@ -46603,7 +46603,7 @@ static NTSTATUS thunk32_vkDestroySurfaceKHR(void *args)
TRACE("%#x, 0x%s, %#x\n", params->instance, wine_dbgstr_longlong(params->surface), params->pAllocator);
- wine_vkDestroySurfaceKHR((VkInstance)UlongToPtr(params->instance), params->surface, (const VkAllocationCallbacks *)UlongToPtr(params->pAllocator)); + vk_funcs->p_vkDestroySurfaceKHR((VkInstance)UlongToPtr(params->instance), params->surface, (const VkAllocationCallbacks *)UlongToPtr(params->pAllocator)); return STATUS_SUCCESS; }
@@ -46614,7 +46614,7 @@ static NTSTATUS thunk64_vkDestroySwapchainKHR(void *args)
TRACE("%p, 0x%s, %p\n", params->device, wine_dbgstr_longlong(params->swapchain), params->pAllocator);
- wine_vkDestroySwapchainKHR(params->device, params->swapchain, params->pAllocator); + vk_funcs->p_vkDestroySwapchainKHR(params->device, params->swapchain, params->pAllocator); return STATUS_SUCCESS; } #endif /* _WIN64 */ @@ -46630,7 +46630,7 @@ static NTSTATUS thunk32_vkDestroySwapchainKHR(void *args)
TRACE("%#x, 0x%s, %#x\n", params->device, wine_dbgstr_longlong(params->swapchain), params->pAllocator);
- wine_vkDestroySwapchainKHR((VkDevice)UlongToPtr(params->device), params->swapchain, (const VkAllocationCallbacks *)UlongToPtr(params->pAllocator)); + vk_funcs->p_vkDestroySwapchainKHR((VkDevice)UlongToPtr(params->device), params->swapchain, (const VkAllocationCallbacks *)UlongToPtr(params->pAllocator)); return STATUS_SUCCESS; }
@@ -50352,7 +50352,7 @@ static NTSTATUS thunk64_vkGetPhysicalDevicePresentRectanglesKHR(void *args)
TRACE("%p, 0x%s, %p, %p\n", params->physicalDevice, wine_dbgstr_longlong(params->surface), params->pRectCount, params->pRects);
- params->result = wine_vkGetPhysicalDevicePresentRectanglesKHR(params->physicalDevice, params->surface, params->pRectCount, params->pRects); + params->result = vk_funcs->p_vkGetPhysicalDevicePresentRectanglesKHR(params->physicalDevice, params->surface, params->pRectCount, params->pRects); return STATUS_SUCCESS; } #endif /* _WIN64 */ @@ -50370,7 +50370,7 @@ static NTSTATUS thunk32_vkGetPhysicalDevicePresentRectanglesKHR(void *args)
TRACE("%#x, 0x%s, %#x, %#x\n", params->physicalDevice, wine_dbgstr_longlong(params->surface), params->pRectCount, params->pRects);
- params->result = wine_vkGetPhysicalDevicePresentRectanglesKHR((VkPhysicalDevice)UlongToPtr(params->physicalDevice), params->surface, (uint32_t *)UlongToPtr(params->pRectCount), (VkRect2D *)UlongToPtr(params->pRects)); + params->result = vk_funcs->p_vkGetPhysicalDevicePresentRectanglesKHR((VkPhysicalDevice)UlongToPtr(params->physicalDevice), params->surface, (uint32_t *)UlongToPtr(params->pRectCount), (VkRect2D *)UlongToPtr(params->pRects)); return STATUS_SUCCESS; }
@@ -50740,7 +50740,7 @@ static NTSTATUS thunk64_vkGetPhysicalDeviceSurfaceCapabilities2KHR(void *args)
TRACE("%p, %p, %p\n", params->physicalDevice, params->pSurfaceInfo, params->pSurfaceCapabilities);
- params->result = wine_vkGetPhysicalDeviceSurfaceCapabilities2KHR(params->physicalDevice, params->pSurfaceInfo, params->pSurfaceCapabilities); + params->result = vk_funcs->p_vkGetPhysicalDeviceSurfaceCapabilities2KHR(params->physicalDevice, params->pSurfaceInfo, params->pSurfaceCapabilities); return STATUS_SUCCESS; } #endif /* _WIN64 */ @@ -50764,7 +50764,7 @@ static NTSTATUS thunk32_vkGetPhysicalDeviceSurfaceCapabilities2KHR(void *args) init_conversion_context(ctx); convert_VkPhysicalDeviceSurfaceInfo2KHR_win32_to_unwrapped_host(ctx, (const VkPhysicalDeviceSurfaceInfo2KHR32 *)UlongToPtr(params->pSurfaceInfo), &pSurfaceInfo_host); convert_VkSurfaceCapabilities2KHR_win32_to_host(ctx, (VkSurfaceCapabilities2KHR32 *)UlongToPtr(params->pSurfaceCapabilities), &pSurfaceCapabilities_host); - params->result = wine_vkGetPhysicalDeviceSurfaceCapabilities2KHR((VkPhysicalDevice)UlongToPtr(params->physicalDevice), &pSurfaceInfo_host, &pSurfaceCapabilities_host); + params->result = vk_funcs->p_vkGetPhysicalDeviceSurfaceCapabilities2KHR((VkPhysicalDevice)UlongToPtr(params->physicalDevice), &pSurfaceInfo_host, &pSurfaceCapabilities_host); convert_VkSurfaceCapabilities2KHR_host_to_win32(&pSurfaceCapabilities_host, (VkSurfaceCapabilities2KHR32 *)UlongToPtr(params->pSurfaceCapabilities)); free_conversion_context(ctx); return STATUS_SUCCESS; @@ -50777,7 +50777,7 @@ static NTSTATUS thunk64_vkGetPhysicalDeviceSurfaceCapabilitiesKHR(void *args)
TRACE("%p, 0x%s, %p\n", params->physicalDevice, wine_dbgstr_longlong(params->surface), params->pSurfaceCapabilities);
- params->result = wine_vkGetPhysicalDeviceSurfaceCapabilitiesKHR(params->physicalDevice, params->surface, params->pSurfaceCapabilities); + params->result = vk_funcs->p_vkGetPhysicalDeviceSurfaceCapabilitiesKHR(params->physicalDevice, params->surface, params->pSurfaceCapabilities); return STATUS_SUCCESS; } #endif /* _WIN64 */ @@ -50794,7 +50794,7 @@ static NTSTATUS thunk32_vkGetPhysicalDeviceSurfaceCapabilitiesKHR(void *args)
TRACE("%#x, 0x%s, %#x\n", params->physicalDevice, wine_dbgstr_longlong(params->surface), params->pSurfaceCapabilities);
- params->result = wine_vkGetPhysicalDeviceSurfaceCapabilitiesKHR((VkPhysicalDevice)UlongToPtr(params->physicalDevice), params->surface, (VkSurfaceCapabilitiesKHR *)UlongToPtr(params->pSurfaceCapabilities)); + params->result = vk_funcs->p_vkGetPhysicalDeviceSurfaceCapabilitiesKHR((VkPhysicalDevice)UlongToPtr(params->physicalDevice), params->surface, (VkSurfaceCapabilitiesKHR *)UlongToPtr(params->pSurfaceCapabilities)); return STATUS_SUCCESS; }
@@ -50805,7 +50805,7 @@ static NTSTATUS thunk64_vkGetPhysicalDeviceSurfaceFormats2KHR(void *args)
TRACE("%p, %p, %p, %p\n", params->physicalDevice, params->pSurfaceInfo, params->pSurfaceFormatCount, params->pSurfaceFormats);
- params->result = wine_vkGetPhysicalDeviceSurfaceFormats2KHR(params->physicalDevice, params->pSurfaceInfo, params->pSurfaceFormatCount, params->pSurfaceFormats); + params->result = vk_funcs->p_vkGetPhysicalDeviceSurfaceFormats2KHR(params->physicalDevice, params->pSurfaceInfo, params->pSurfaceFormatCount, params->pSurfaceFormats); return STATUS_SUCCESS; } #endif /* _WIN64 */ @@ -50830,7 +50830,7 @@ static NTSTATUS thunk32_vkGetPhysicalDeviceSurfaceFormats2KHR(void *args) init_conversion_context(ctx); convert_VkPhysicalDeviceSurfaceInfo2KHR_win32_to_unwrapped_host(ctx, (const VkPhysicalDeviceSurfaceInfo2KHR32 *)UlongToPtr(params->pSurfaceInfo), &pSurfaceInfo_host); pSurfaceFormats_host = convert_VkSurfaceFormat2KHR_array_win32_to_host(ctx, (VkSurfaceFormat2KHR32 *)UlongToPtr(params->pSurfaceFormats), *(uint32_t *)UlongToPtr(params->pSurfaceFormatCount)); - params->result = wine_vkGetPhysicalDeviceSurfaceFormats2KHR((VkPhysicalDevice)UlongToPtr(params->physicalDevice), &pSurfaceInfo_host, (uint32_t *)UlongToPtr(params->pSurfaceFormatCount), pSurfaceFormats_host); + params->result = vk_funcs->p_vkGetPhysicalDeviceSurfaceFormats2KHR((VkPhysicalDevice)UlongToPtr(params->physicalDevice), &pSurfaceInfo_host, (uint32_t *)UlongToPtr(params->pSurfaceFormatCount), pSurfaceFormats_host); convert_VkSurfaceFormat2KHR_array_host_to_win32(pSurfaceFormats_host, (VkSurfaceFormat2KHR32 *)UlongToPtr(params->pSurfaceFormats), *(uint32_t *)UlongToPtr(params->pSurfaceFormatCount)); free_conversion_context(ctx); return STATUS_SUCCESS; @@ -50843,7 +50843,7 @@ static NTSTATUS thunk64_vkGetPhysicalDeviceSurfaceFormatsKHR(void *args)
TRACE("%p, 0x%s, %p, %p\n", params->physicalDevice, wine_dbgstr_longlong(params->surface), params->pSurfaceFormatCount, params->pSurfaceFormats);
- params->result = wine_vkGetPhysicalDeviceSurfaceFormatsKHR(params->physicalDevice, params->surface, params->pSurfaceFormatCount, params->pSurfaceFormats); + params->result = vk_funcs->p_vkGetPhysicalDeviceSurfaceFormatsKHR(params->physicalDevice, params->surface, params->pSurfaceFormatCount, params->pSurfaceFormats); return STATUS_SUCCESS; } #endif /* _WIN64 */ @@ -50861,7 +50861,7 @@ static NTSTATUS thunk32_vkGetPhysicalDeviceSurfaceFormatsKHR(void *args)
TRACE("%#x, 0x%s, %#x, %#x\n", params->physicalDevice, wine_dbgstr_longlong(params->surface), params->pSurfaceFormatCount, params->pSurfaceFormats);
- params->result = wine_vkGetPhysicalDeviceSurfaceFormatsKHR((VkPhysicalDevice)UlongToPtr(params->physicalDevice), params->surface, (uint32_t *)UlongToPtr(params->pSurfaceFormatCount), (VkSurfaceFormatKHR *)UlongToPtr(params->pSurfaceFormats)); + params->result = vk_funcs->p_vkGetPhysicalDeviceSurfaceFormatsKHR((VkPhysicalDevice)UlongToPtr(params->physicalDevice), params->surface, (uint32_t *)UlongToPtr(params->pSurfaceFormatCount), (VkSurfaceFormatKHR *)UlongToPtr(params->pSurfaceFormats)); return STATUS_SUCCESS; }
@@ -51112,7 +51112,7 @@ static NTSTATUS thunk64_vkGetPhysicalDeviceWin32PresentationSupportKHR(void *arg
TRACE("%p, %u\n", params->physicalDevice, params->queueFamilyIndex);
- params->result = vk_funcs->p_vkGetPhysicalDeviceWin32PresentationSupportKHR(vulkan_physical_device_from_handle(params->physicalDevice)->host.physical_device, params->queueFamilyIndex); + params->result = vk_funcs->p_vkGetPhysicalDeviceWin32PresentationSupportKHR(params->physicalDevice, params->queueFamilyIndex); return STATUS_SUCCESS; } #endif /* _WIN64 */ @@ -51128,7 +51128,7 @@ static NTSTATUS thunk32_vkGetPhysicalDeviceWin32PresentationSupportKHR(void *arg
TRACE("%#x, %u\n", params->physicalDevice, params->queueFamilyIndex);
- params->result = vk_funcs->p_vkGetPhysicalDeviceWin32PresentationSupportKHR(vulkan_physical_device_from_handle((VkPhysicalDevice)UlongToPtr(params->physicalDevice))->host.physical_device, params->queueFamilyIndex); + params->result = vk_funcs->p_vkGetPhysicalDeviceWin32PresentationSupportKHR((VkPhysicalDevice)UlongToPtr(params->physicalDevice), params->queueFamilyIndex); return STATUS_SUCCESS; }
@@ -52496,7 +52496,7 @@ static NTSTATUS thunk64_vkQueuePresentKHR(void *args)
TRACE("%p, %p\n", params->queue, params->pPresentInfo);
- params->result = wine_vkQueuePresentKHR(params->queue, params->pPresentInfo); + params->result = vk_funcs->p_vkQueuePresentKHR(params->queue, params->pPresentInfo); return STATUS_SUCCESS; } #endif /* _WIN64 */ @@ -52517,7 +52517,7 @@ static NTSTATUS thunk32_vkQueuePresentKHR(void *args)
init_conversion_context(ctx); convert_VkPresentInfoKHR_win32_to_unwrapped_host(ctx, (const VkPresentInfoKHR32 *)UlongToPtr(params->pPresentInfo), &pPresentInfo_host); - params->result = wine_vkQueuePresentKHR((VkQueue)UlongToPtr(params->queue), &pPresentInfo_host); + params->result = vk_funcs->p_vkQueuePresentKHR((VkQueue)UlongToPtr(params->queue), &pPresentInfo_host); free_conversion_context(ctx); return STATUS_SUCCESS; } diff --git a/dlls/winevulkan/vulkan_thunks.h b/dlls/winevulkan/vulkan_thunks.h index 88ce00f7a08..9fd02d744d0 100644 --- a/dlls/winevulkan/vulkan_thunks.h +++ b/dlls/winevulkan/vulkan_thunks.h @@ -21,8 +21,6 @@ #define WINE_VK_VERSION VK_API_VERSION_1_3
/* Functions for which we have custom implementations outside of the thunks. */ -VkResult wine_vkAcquireNextImage2KHR(VkDevice device, const VkAcquireNextImageInfoKHR *pAcquireInfo, uint32_t *pImageIndex); -VkResult wine_vkAcquireNextImageKHR(VkDevice device, VkSwapchainKHR swapchain, uint64_t timeout, VkSemaphore semaphore, VkFence fence, uint32_t *pImageIndex); VkResult wine_vkAllocateCommandBuffers(VkDevice device, const VkCommandBufferAllocateInfo *pAllocateInfo, VkCommandBuffer *pCommandBuffers); VkResult wine_vkAllocateMemory(VkDevice device, const VkMemoryAllocateInfo *pAllocateInfo, const VkAllocationCallbacks *pAllocator, VkDeviceMemory *pMemory); VkResult wine_vkCreateBuffer(VkDevice device, const VkBufferCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkBuffer *pBuffer); @@ -33,16 +31,12 @@ VkResult wine_vkCreateDeferredOperationKHR(VkDevice device, const VkAllocationCa VkResult wine_vkCreateDevice(VkPhysicalDevice physicalDevice, const VkDeviceCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkDevice *pDevice, void *client_ptr); VkResult wine_vkCreateImage(VkDevice device, const VkImageCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkImage *pImage); VkResult wine_vkCreateInstance(const VkInstanceCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkInstance *pInstance, void *client_ptr); -VkResult wine_vkCreateSwapchainKHR(VkDevice device, const VkSwapchainCreateInfoKHR *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkSwapchainKHR *pSwapchain); -VkResult wine_vkCreateWin32SurfaceKHR(VkInstance instance, const VkWin32SurfaceCreateInfoKHR *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface); void wine_vkDestroyCommandPool(VkDevice device, VkCommandPool commandPool, const VkAllocationCallbacks *pAllocator); void wine_vkDestroyDebugReportCallbackEXT(VkInstance instance, VkDebugReportCallbackEXT callback, const VkAllocationCallbacks *pAllocator); void wine_vkDestroyDebugUtilsMessengerEXT(VkInstance instance, VkDebugUtilsMessengerEXT messenger, const VkAllocationCallbacks *pAllocator); void wine_vkDestroyDeferredOperationKHR(VkDevice device, VkDeferredOperationKHR operation, const VkAllocationCallbacks *pAllocator); void wine_vkDestroyDevice(VkDevice device, const VkAllocationCallbacks *pAllocator); void wine_vkDestroyInstance(VkInstance instance, const VkAllocationCallbacks *pAllocator); -void wine_vkDestroySurfaceKHR(VkInstance instance, VkSurfaceKHR surface, const VkAllocationCallbacks *pAllocator); -void wine_vkDestroySwapchainKHR(VkDevice device, VkSwapchainKHR swapchain, const VkAllocationCallbacks *pAllocator); VkResult wine_vkEnumerateDeviceExtensionProperties(VkPhysicalDevice physicalDevice, const char *pLayerName, uint32_t *pPropertyCount, VkExtensionProperties *pProperties); VkResult wine_vkEnumerateDeviceLayerProperties(VkPhysicalDevice physicalDevice, uint32_t *pPropertyCount, VkLayerProperties *pProperties); VkResult wine_vkEnumerateInstanceExtensionProperties(const char *pLayerName, uint32_t *pPropertyCount, VkExtensionProperties *pProperties); @@ -66,14 +60,8 @@ void wine_vkGetPhysicalDeviceExternalSemaphoreProperties(VkPhysicalDevice physic void wine_vkGetPhysicalDeviceExternalSemaphorePropertiesKHR(VkPhysicalDevice physicalDevice, const VkPhysicalDeviceExternalSemaphoreInfo *pExternalSemaphoreInfo, VkExternalSemaphoreProperties *pExternalSemaphoreProperties); VkResult wine_vkGetPhysicalDeviceImageFormatProperties2(VkPhysicalDevice physicalDevice, const VkPhysicalDeviceImageFormatInfo2 *pImageFormatInfo, VkImageFormatProperties2 *pImageFormatProperties); VkResult wine_vkGetPhysicalDeviceImageFormatProperties2KHR(VkPhysicalDevice physicalDevice, const VkPhysicalDeviceImageFormatInfo2 *pImageFormatInfo, VkImageFormatProperties2 *pImageFormatProperties); -VkResult wine_vkGetPhysicalDevicePresentRectanglesKHR(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface, uint32_t *pRectCount, VkRect2D *pRects); -VkResult wine_vkGetPhysicalDeviceSurfaceCapabilities2KHR(VkPhysicalDevice physicalDevice, const VkPhysicalDeviceSurfaceInfo2KHR *pSurfaceInfo, VkSurfaceCapabilities2KHR *pSurfaceCapabilities); -VkResult wine_vkGetPhysicalDeviceSurfaceCapabilitiesKHR(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface, VkSurfaceCapabilitiesKHR *pSurfaceCapabilities); -VkResult wine_vkGetPhysicalDeviceSurfaceFormats2KHR(VkPhysicalDevice physicalDevice, const VkPhysicalDeviceSurfaceInfo2KHR *pSurfaceInfo, uint32_t *pSurfaceFormatCount, VkSurfaceFormat2KHR *pSurfaceFormats); -VkResult wine_vkGetPhysicalDeviceSurfaceFormatsKHR(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface, uint32_t *pSurfaceFormatCount, VkSurfaceFormatKHR *pSurfaceFormats); VkResult wine_vkMapMemory(VkDevice device, VkDeviceMemory memory, VkDeviceSize offset, VkDeviceSize size, VkMemoryMapFlags flags, void **ppData); VkResult wine_vkMapMemory2KHR(VkDevice device, const VkMemoryMapInfoKHR *pMemoryMapInfo, void **ppData); -VkResult wine_vkQueuePresentKHR(VkQueue queue, const VkPresentInfoKHR *pPresentInfo); void wine_vkUnmapMemory(VkDevice device, VkDeviceMemory memory); VkResult wine_vkUnmapMemory2KHR(VkDevice device, const VkMemoryUnmapInfoKHR *pMemoryUnmapInfo);
diff --git a/include/wine/vulkan_driver.h b/include/wine/vulkan_driver.h index 5a56bfe08f7..4bd60218943 100644 --- a/include/wine/vulkan_driver.h +++ b/include/wine/vulkan_driver.h @@ -77,6 +77,8 @@ struct vulkan_instance #define USE_VK_FUNC(x) PFN_ ## x p_ ## x; ALL_VK_INSTANCE_FUNCS #undef USE_VK_FUNC + void (*p_insert_object)( struct vulkan_instance *instance, struct vulkan_object *obj ); + void (*p_remove_object)( struct vulkan_instance *instance, struct vulkan_object *obj ); };
static inline struct vulkan_instance *vulkan_instance_from_handle( VkInstance handle ) @@ -151,17 +153,24 @@ 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. */ + PFN_vkAcquireNextImage2KHR p_vkAcquireNextImage2KHR; + PFN_vkAcquireNextImageKHR p_vkAcquireNextImageKHR; + PFN_vkCreateSwapchainKHR p_vkCreateSwapchainKHR; PFN_vkCreateWin32SurfaceKHR p_vkCreateWin32SurfaceKHR; PFN_vkDestroySurfaceKHR p_vkDestroySurfaceKHR; + PFN_vkDestroySwapchainKHR p_vkDestroySwapchainKHR; PFN_vkGetDeviceProcAddr p_vkGetDeviceProcAddr; PFN_vkGetInstanceProcAddr p_vkGetInstanceProcAddr; + PFN_vkGetPhysicalDevicePresentRectanglesKHR p_vkGetPhysicalDevicePresentRectanglesKHR; + PFN_vkGetPhysicalDeviceSurfaceCapabilities2KHR p_vkGetPhysicalDeviceSurfaceCapabilities2KHR; + PFN_vkGetPhysicalDeviceSurfaceCapabilitiesKHR p_vkGetPhysicalDeviceSurfaceCapabilitiesKHR; + PFN_vkGetPhysicalDeviceSurfaceFormats2KHR p_vkGetPhysicalDeviceSurfaceFormats2KHR; + PFN_vkGetPhysicalDeviceSurfaceFormatsKHR p_vkGetPhysicalDeviceSurfaceFormatsKHR; PFN_vkGetPhysicalDeviceWin32PresentationSupportKHR p_vkGetPhysicalDeviceWin32PresentationSupportKHR; - VkResult (*p_vkQueuePresentKHR)(VkQueue, const VkPresentInfoKHR *, VkSurfaceKHR *surfaces); + PFN_vkQueuePresentKHR p_vkQueuePresentKHR;
/* winevulkan specific functions */ const char *(*p_get_host_surface_extension)(void); - VkSurfaceKHR (*p_wine_get_host_surface)(VkSurfaceKHR); - void (*p_vulkan_surface_update)(VkSurfaceKHR); };
/* interface between win32u and the user drivers */