wsi/x11: Implement EXT_swapchain_maintenance1.

Signed-off-by: Hans-Kristian Arntzen <post@arntzen-software.no>
Reviewed-by: Joshua Ashton <joshua@froggi.es>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/20235>
This commit is contained in:
Hans-Kristian Arntzen 2022-12-08 17:08:21 +01:00 committed by Marge Bot
parent 8ece1ade5b
commit be0dcbdfa2

View file

@ -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;