egl/kopper: Update the EGLSurface size after kopperSwapBuffers()
Some checks are pending
macOS-CI / macOS-CI (dri) (push) Waiting to run
macOS-CI / macOS-CI (xlib) (push) Waiting to run

Otherwise, the size of the EGLSurface and the drawable may get out of
sync if kopper needs to re-create the swapchain at a different size.
This can cause problems with things like eglSetDamageRegionKHR() where
the core EGL code clamps them to the size in the EGLSurface.

With Wayland, it's up to the client to choose a size and resize by
creating a new EGLSurface with a different size.  Only on X11 can we
get a resize side-band like this.

Normally, without kopper, this goes the other direction where the X11
EGL code will detect a surface size change in dri2_x11_query_surface()
and it invalidates the drawable if they've changed, forcing
re-allocation.  Kopper, however, works more like the DRI2 path where we
just get handed buffers at some size decided by X11 and have to deal
with them.  In the DRI2 path, the size is unconditionally updated by
dri2_x11_get_buffers().  This is roughly equivalent, updating the size
right after every call to kopperSwapBuffers().

Fixes: 8ade5588e3 ("zink: add kopper api")
Closes: https://gitlab.freedesktop.org/mesa/mesa/-/issues/12797
Reviewed-By: Mike Blumenkrantz <michael.blumenkrantz@gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/34015>
This commit is contained in:
Faith Ekstrand 2025-03-11 21:51:31 -05:00 committed by Marge Bot
parent dc8714c568
commit ad90dbabe4
4 changed files with 33 additions and 0 deletions

View file

@ -1108,6 +1108,15 @@ dri2_x11_swap_buffers(_EGLDisplay *disp, _EGLSurface *draw)
*/
kopperSwapBuffers(dri2_surf->dri_drawable,
__DRI2_FLUSH_INVALIDATE_ANCILLARY);
/* If the X11 window has been resized, vkQueuePresentKHR() or
* vkAcquireNextImageKHR() may return VK_ERROR_SURFACE_LOST or
* VK_SUBOPTIMAL_KHR, causing kopper to re-create the swapchain with
* a different size. We need to resize the EGLSurface in that case.
*/
kopperQuerySurfaceSize(dri2_surf->dri_drawable,
&dri2_surf->base.Width,
&dri2_surf->base.Height);
return EGL_TRUE;
} else if (dri2_dpy->swrast) {
/* aka the swrast path, which does the swap in the gallium driver. */
@ -1137,6 +1146,15 @@ dri2_x11_kopper_swap_buffers_with_damage(_EGLDisplay *disp, _EGLSurface *draw,
kopperSwapBuffersWithDamage(dri2_surf->dri_drawable, __DRI2_FLUSH_INVALIDATE_ANCILLARY, numRects, rects);
else
kopperSwapBuffers(dri2_surf->dri_drawable, __DRI2_FLUSH_INVALIDATE_ANCILLARY);
/* If the X11 window has been resized, vkQueuePresentKHR() or
* vkAcquireNextImageKHR() may return VK_ERROR_SURFACE_LOST or
* VK_SUBOPTIMAL_KHR, causing kopper to re-create the swapchain with
* a different size. We need to resize the EGLSurface in that case.
*/
kopperQuerySurfaceSize(dri2_surf->dri_drawable,
&dri2_surf->base.Width,
&dri2_surf->base.Height);
} else {
if (numRects)
driSwapBuffersWithDamage(dri2_surf->dri_drawable, numRects, rects);

View file

@ -163,6 +163,8 @@ PUBLIC void
kopperSetSwapInterval(struct dri_drawable *drawable, int interval);
PUBLIC int
kopperQueryBufferAge(struct dri_drawable *drawable);
PUBLIC void
kopperQuerySurfaceSize(struct dri_drawable *drawable, int *width, int *height);
PUBLIC void
driswCopySubBuffer(struct dri_drawable *drawable, int x, int y, int w, int h);

View file

@ -663,6 +663,13 @@ kopperQueryBufferAge(struct dri_drawable *drawable)
return zink_kopper_query_buffer_age(ctx->st->pipe, ptex);
}
void
kopperQuerySurfaceSize(struct dri_drawable *drawable, int *width, int *height)
{
*width = drawable->w;
*height = drawable->h;
}
int
kopperGetSyncValues(struct dri_drawable *drawable, int64_t target_msc, int64_t divisor,
int64_t remainder, int64_t *ust, int64_t *msc, int64_t *sbc)

View file

@ -26,6 +26,12 @@ kopperQueryBufferAge(struct dri_drawable *dPriv)
return 0;
}
void
kopperQuerySurfaceSize(struct dri_drawable *drawable, int *width, int *height)
{
*width = *height = 1;
}
int
kopperGetSyncValues(struct dri_drawable *drawable, int64_t target_msc, int64_t divisor,
int64_t remainder, int64_t *ust, int64_t *msc, int64_t *sbc)