wsi/x11: Rewrite logic for how we consider minImageCount.

MAILBOX reduced from 5 to 4 to be more inline with WL.

With xwayland_wait_ready = false now being the default,
add some extra consideration for non-FIFO present modes.
Add a lengthy rationale for why minImageCount = 3 is exposed on Xwl.

Signed-off-by: Hans-Kristian Arntzen <post@arntzen-software.no>
Reviewed-by: Bas Nieuwenhuizen <bas@basnieuwenhuizen.nl>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/27074>
This commit is contained in:
Hans-Kristian Arntzen
2024-02-08 12:28:23 +01:00
committed by Marge Bot
parent 8b4259e69b
commit bd23753991

View File

@@ -1542,6 +1542,53 @@ x11_needs_wait_for_fences(const struct wsi_device *wsi_device,
}
}
/* This matches Wayland. */
#define X11_SWAPCHAIN_MAILBOX_IMAGES 4
static bool
x11_requires_mailbox_image_count(const struct wsi_device *device,
struct wsi_x11_connection *wsi_conn,
VkPresentModeKHR present_mode)
{
/* If we're resorting to wait for fences, we're assuming a MAILBOX-like model,
* and we should allocate accordingly.
*
* One potential concern here is IMMEDIATE mode on Wayland.
* This situation could arise:
* - Fullscreen FLIP mode
* - Compositor does not support tearing protocol (we cannot know this here)
*
* With 3 images, during the window between latch and flip, there is only one image left to app,
* so peak FPS may not be reached if the window between latch and flip is large,
* but tests on contemporary compositors suggest this effect is minor.
* Frame rate in the thousands can easily be reached.
*
* There are pragmatic reasons to expose 3 images for IMMEDIATE on Xwl.
* - minImageCount is not intended as a tool to tune performance, its intent is to signal forward progress.
* Our X11 and WL implementations do so for pragmatic reasons due to sync acquire interacting poorly with 2 images.
* A jump from 3 to 4 is at best a minor improvement which only affects applications
* running at extremely high frame rates, way beyond the monitor refresh rate.
* On the other hand, lowering minImageCount to 2 would break the fundamental idea of MAILBOX
* (and IMMEDIATE without tear), since FPS > refresh rate would not be possible.
*
* - Several games developed for other platforms and other Linux WSI implementations
* do not expect that image counts arbitrarily change when changing present mode,
* and will crash when Mesa does so.
* There are several games using the strict_image_count drirc to work around this,
* and it would be good to be friendlier in the first place, so we don't have to work around more games.
* IMMEDIATE is a common presentation mode on those platforms, but MAILBOX is more Wayland-centric in nature,
* so increasing image count for that mode is more reasonable.
*
* - IMMEDIATE expects tearing, and when tearing, 3 images are more than enough.
*
* - With EXT_swapchain_maintenance1, toggling between FIFO / IMMEDIATE (used extensively by D3D layering)
* would require application to allocate >3 images which is unfortunate for memory usage,
* and potentially disastrous for latency unless KHR_present_wait is used.
*/
return x11_needs_wait_for_fences(device, wsi_conn, present_mode) ||
present_mode == VK_PRESENT_MODE_MAILBOX_KHR;
}
/**
* Send image to the X server for presentation at target_msc.
*/
@@ -2312,10 +2359,11 @@ 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;
uint32_t min_image_count = x11_get_min_image_count(wsi_device, wsi_conn->is_xwayland);
if (x11_requires_mailbox_image_count(wsi_device, wsi_conn, present_mode))
return MAX2(min_image_count, X11_SWAPCHAIN_MAILBOX_IMAGES);
else
return x11_get_min_image_count(wsi_device, wsi_conn->is_xwayland);
return min_image_count;
}
/**
@@ -2354,12 +2402,14 @@ x11_surface_create_swapchain(VkIcdSurfaceBase *icd_surface,
* - presentation mode.
*/
unsigned num_images = pCreateInfo->minImageCount;
if (wsi_device->x11.strict_imageCount)
num_images = pCreateInfo->minImageCount;
else if (x11_needs_wait_for_fences(wsi_device, wsi_conn, present_mode))
num_images = MAX2(num_images, 5);
else if (wsi_device->x11.ensure_minImageCount)
num_images = MAX2(num_images, x11_get_min_image_count(wsi_device, wsi_conn->is_xwayland));
if (!wsi_device->x11.strict_imageCount) {
if (x11_requires_mailbox_image_count(wsi_device, wsi_conn, present_mode) ||
wsi_device->x11.ensure_minImageCount) {
unsigned present_mode_images = x11_get_min_image_count_for_present_mode(
wsi_device, wsi_conn, pCreateInfo->presentMode);
num_images = MAX2(num_images, present_mode_images);
}
}
/* Check that we have a window up-front. It is an error to not have one. */
xcb_window_t window = x11_surface_get_window(icd_surface);