mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-28 12:30:09 +01:00
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:
parent
8ece1ade5b
commit
be0dcbdfa2
1 changed files with 82 additions and 2 deletions
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue