From be0dcbdfa228b2a47633bc79278a91e90e59cdae Mon Sep 17 00:00:00 2001 From: Hans-Kristian Arntzen Date: Thu, 8 Dec 2022 17:08:21 +0100 Subject: [PATCH] wsi/x11: Implement EXT_swapchain_maintenance1. Signed-off-by: Hans-Kristian Arntzen Reviewed-by: Joshua Ashton Part-of: --- src/vulkan/wsi/wsi_common_x11.c | 84 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 82 insertions(+), 2 deletions(-) diff --git a/src/vulkan/wsi/wsi_common_x11.c b/src/vulkan/wsi/wsi_common_x11.c index 3c620be..1b3d5ae 100644 --- a/src/vulkan/wsi/wsi_common_x11.c +++ b/src/vulkan/wsi/wsi_common_x11.c @@ -658,9 +658,15 @@ x11_get_min_image_count(const struct wsi_device *wsi_device, bool is_xwayland) return is_xwayland && wsi_device->x11.extra_xwayland_image ? 4 : 3; } +static unsigned +x11_get_min_image_count_for_present_mode(struct wsi_device *wsi_device, + struct wsi_x11_connection *wsi_conn, + VkPresentModeKHR present_mode); + static VkResult x11_surface_get_capabilities(VkIcdSurfaceBase *icd_surface, struct wsi_device *wsi_device, + const VkSurfacePresentModeEXT *present_mode, VkSurfaceCapabilitiesKHR *caps) { xcb_connection_t *conn = x11_surface_get_connection(icd_surface); @@ -703,7 +709,12 @@ x11_surface_get_capabilities(VkIcdSurfaceBase *icd_surface, VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR; } - caps->minImageCount = x11_get_min_image_count(wsi_device, wsi_conn->is_xwayland); + if (present_mode) { + caps->minImageCount = x11_get_min_image_count_for_present_mode(wsi_device, wsi_conn, present_mode->presentMode); + } else { + caps->minImageCount = x11_get_min_image_count(wsi_device, wsi_conn->is_xwayland); + } + /* There is no real maximum */ caps->maxImageCount = 0; @@ -729,8 +740,10 @@ x11_surface_get_capabilities2(VkIcdSurfaceBase *icd_surface, { assert(caps->sType == VK_STRUCTURE_TYPE_SURFACE_CAPABILITIES_2_KHR); + const VkSurfacePresentModeEXT *present_mode = vk_find_struct_const(info_next, SURFACE_PRESENT_MODE_EXT); + VkResult result = - x11_surface_get_capabilities(icd_surface, wsi_device, + x11_surface_get_capabilities(icd_surface, wsi_device, present_mode, &caps->surfaceCapabilities); if (result != VK_SUCCESS) @@ -744,6 +757,33 @@ x11_surface_get_capabilities2(VkIcdSurfaceBase *icd_surface, break; } + case VK_STRUCTURE_TYPE_SURFACE_PRESENT_SCALING_CAPABILITIES_EXT: { + /* Unsupported. */ + VkSurfacePresentScalingCapabilitiesEXT *scaling = (void *)ext; + scaling->supportedPresentScaling = 0; + scaling->supportedPresentGravityX = 0; + scaling->supportedPresentGravityY = 0; + scaling->minScaledImageExtent = caps->surfaceCapabilities.minImageExtent; + scaling->maxScaledImageExtent = caps->surfaceCapabilities.maxImageExtent; + break; + } + + case VK_STRUCTURE_TYPE_SURFACE_PRESENT_MODE_COMPATIBILITY_EXT: { + /* To be able to toggle between FIFO and non-FIFO, we would need a rewrite to always use FIFO thread + * mechanism. For now, only return the input, making this effectively unsupported. */ + assert(present_mode); + VkSurfacePresentModeCompatibilityEXT *compat = (void *)ext; + if (compat->pPresentModes) { + if (compat->presentModeCount) { + compat->pPresentModes[0] = present_mode->presentMode; + compat->presentModeCount = 1; + } + } else { + compat->presentModeCount = 1; + } + break; + } + default: /* Ignored */ break; @@ -1645,6 +1685,34 @@ x11_present_to_x11(struct x11_swapchain *chain, uint32_t image_index, return result; } +static VkResult +x11_release_images(struct wsi_swapchain *wsi_chain, + uint32_t count, const uint32_t *indices) +{ + struct x11_swapchain *chain = (struct x11_swapchain *)wsi_chain; + if (chain->status == VK_ERROR_SURFACE_LOST_KHR) + return chain->status; + + for (uint32_t i = 0; i < count; i++) { + uint32_t index = indices[i]; + assert(index < chain->base.image_count); + + if (chain->has_acquire_queue) { + wsi_queue_push(&chain->acquire_queue, index); + } else { + assert(chain->images[index].busy); + chain->images[index].busy = false; + } + } + + if (!chain->has_acquire_queue) { + assert(chain->present_poll_acquire_count >= count); + chain->present_poll_acquire_count -= count; + } + + return VK_SUCCESS; +} + /** * Acquire a ready-to-use image from the swapchain. * @@ -2441,6 +2509,17 @@ static VkResult x11_wait_for_present(struct wsi_swapchain *wsi_chain, return result; } +static unsigned +x11_get_min_image_count_for_present_mode(struct wsi_device *wsi_device, + struct wsi_x11_connection *wsi_conn, + VkPresentModeKHR present_mode) +{ + if (x11_needs_wait_for_fences(wsi_device, wsi_conn, present_mode)) + return 5; + else + return x11_get_min_image_count(wsi_device, wsi_conn->is_xwayland); +} + /** * Create the swapchain. * @@ -2569,6 +2648,7 @@ x11_surface_create_swapchain(VkIcdSurfaceBase *icd_surface, chain->base.acquire_next_image = x11_acquire_next_image; chain->base.queue_present = x11_queue_present; chain->base.wait_for_present = x11_wait_for_present; + chain->base.release_images = x11_release_images; chain->base.present_mode = present_mode; chain->base.image_count = num_images; chain->conn = conn; -- 2.7.4