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);
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;
{
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)
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;
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.
*
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.
*
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;