From: Rémi Bernon rbernon@codeweavers.com
--- dlls/vulkan-1/tests/vulkan.c | 2 -- dlls/winevulkan/vulkan.c | 33 +++++++++++++++++++++++++++------ 2 files changed, 27 insertions(+), 8 deletions(-)
diff --git a/dlls/vulkan-1/tests/vulkan.c b/dlls/vulkan-1/tests/vulkan.c index 5417585e00c..e2ab609925b 100644 --- a/dlls/vulkan-1/tests/vulkan.c +++ b/dlls/vulkan-1/tests/vulkan.c @@ -595,10 +595,8 @@ static void test_win32_surface_hwnd(VkInstance vk_instance, VkPhysicalDevice vk_ ok(surf_caps.maxImageCount > 2, "Got minImageCount %u\n", surf_caps.maxImageCount); ok(surf_caps.minImageCount <= surf_caps.maxImageCount, "Got maxImageCount %u\n", surf_caps.maxImageCount);
- todo_wine_if(IsRectEmpty(&client_rect)) ok(surf_caps.currentExtent.width == client_rect.right - client_rect.left, "Got currentExtent.width %d\n", surf_caps.currentExtent.width); - todo_wine_if(IsRectEmpty(&client_rect)) ok(surf_caps.currentExtent.height == client_rect.bottom - client_rect.top, "Got currentExtent.height %d\n", surf_caps.currentExtent.height);
diff --git a/dlls/winevulkan/vulkan.c b/dlls/winevulkan/vulkan.c index 25d78f02347..59f34e882ae 100644 --- a/dlls/winevulkan/vulkan.c +++ b/dlls/winevulkan/vulkan.c @@ -1499,12 +1499,23 @@ VkResult wine_vkCreateSwapchainKHR(VkDevice device_handle, const VkSwapchainCrea 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 wine_device *device = wine_device_from_handle(device_handle); + struct wine_phys_dev *physical_device = device->phys_dev; + struct wine_instance *instance = physical_device->instance; VkSwapchainCreateInfoKHR create_info_host = *create_info; + VkSurfaceCapabilitiesKHR capabilities; VkResult res;
if (surface) create_info_host.surface = surface->driver_surface; if (old_swapchain) create_info_host.oldSwapchain = old_swapchain->host_swapchain;
+ /* Windows allows client rect to be empty, but host Vulkan often doesn't, adjust extents back to the host capabilities */ + res = instance->funcs.p_vkGetPhysicalDeviceSurfaceCapabilitiesKHR(physical_device->host_physical_device, + surface->driver_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->funcs.p_vkCreateSwapchainKHR(device->host_device, &create_info_host, NULL, &object->host_swapchain); if (res != VK_SUCCESS) @@ -1772,8 +1783,11 @@ VkResult wine_vkCreateImage(VkDevice handle, const VkImageCreateInfo *create_inf return device->funcs.p_vkCreateImage(device->host_device, &info, NULL, image); }
-static inline void adjust_max_image_count(struct wine_phys_dev *phys_dev, VkSurfaceCapabilitiesKHR* capabilities) +static void adjust_surface_capabilities(struct wine_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. @@ -1781,10 +1795,17 @@ static inline void adjust_max_image_count(struct wine_phys_dev *phys_dev, VkSurf * https://vulkan.gpuinfo.org/displayreport.php?id=9122#surface * https://vulkan.gpuinfo.org/displayreport.php?id=9121#surface */ - if ((phys_dev->instance->quirks & WINEVULKAN_QUIRK_ADJUST_MAX_IMAGE_COUNT) && !capabilities->maxImageCount) - { + if ((instance->quirks & WINEVULKAN_QUIRK_ADJUST_MAX_IMAGE_COUNT) && !capabilities->maxImageCount) capabilities->maxImageCount = max(capabilities->minImageCount, 16); - } + + /* Update the image extents to match what the Win32 WSI would provide. */ + NtUserGetClientRect(surface->hwnd, &client_rect); + 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 device_handle, VkSurfaceKHR surface_handle, @@ -1798,7 +1819,7 @@ VkResult wine_vkGetPhysicalDeviceSurfaceCapabilitiesKHR(VkPhysicalDevice device_ if (!NtUserIsWindow(surface->hwnd)) return VK_ERROR_SURFACE_LOST_KHR; res = instance->funcs.p_vkGetPhysicalDeviceSurfaceCapabilitiesKHR(physical_device->host_physical_device, surface->driver_surface, capabilities); - if (res == VK_SUCCESS) adjust_max_image_count(physical_device, capabilities); + if (res == VK_SUCCESS) adjust_surface_capabilities(instance, surface, capabilities); return res; }
@@ -1816,7 +1837,7 @@ VkResult wine_vkGetPhysicalDeviceSurfaceCapabilities2KHR(VkPhysicalDevice device if (!NtUserIsWindow(surface->hwnd)) return VK_ERROR_SURFACE_LOST_KHR; res = instance->funcs.p_vkGetPhysicalDeviceSurfaceCapabilities2KHR(physical_device->host_physical_device, &surface_info_host, capabilities); - if (res == VK_SUCCESS) adjust_max_image_count(physical_device, &capabilities->surfaceCapabilities); + if (res == VK_SUCCESS) adjust_surface_capabilities(instance, surface, &capabilities->surfaceCapabilities); return res; }