egl/x11_dri3: implement EGL_KHR_swap_buffers_with_damage

Passes all of `dEQP-EGL.functional.swap_buffers_with_damage.*`:

    Passed:        36/54 (66.7%)
    Failed:        0/54 (0.0%)
    Not supported: 18/54 (33.3%)
    Warnings:      0/54 (0.0%)
    Waived:        0/54 (0.0%)

The "not supported" ones are the `preserve_buffer_*` tests, which is not
supported on X11/DRI3.

Cc: 20.2 <mesa-stable>
Closes: https://gitlab.freedesktop.org/mesa/mesa/-/issues/3030
Signed-off-by: Eric Engestrom <eric@engestrom.ch>
Reviewed-by: Michel Dänzer <mdaenzer@redhat.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/6132>
This commit is contained in:
Eric Engestrom
2020-05-23 01:45:42 +02:00
committed by Marge Bot
parent eae181e3eb
commit 326eb56718
7 changed files with 38 additions and 3 deletions

View File

@@ -1,2 +1,3 @@
GL 4.5 on llvmpipe GL 4.5 on llvmpipe
GL_NV_half_float GL_NV_half_float
EGL_KHR_swap_buffers_with_damage on X11 (DRI3)

View File

@@ -1386,6 +1386,7 @@ dri2_initialize_x11_dri3(_EGLDisplay *disp)
disp->Extensions.NOK_texture_from_pixmap = EGL_TRUE; disp->Extensions.NOK_texture_from_pixmap = EGL_TRUE;
disp->Extensions.CHROMIUM_sync_control = EGL_TRUE; disp->Extensions.CHROMIUM_sync_control = EGL_TRUE;
disp->Extensions.EXT_buffer_age = EGL_TRUE; disp->Extensions.EXT_buffer_age = EGL_TRUE;
disp->Extensions.EXT_swap_buffers_with_damage = EGL_TRUE;
dri2_set_WL_bind_wayland_display(disp); dri2_set_WL_bind_wayland_display(disp);

View File

@@ -413,15 +413,23 @@ const __DRIimageLoaderExtension dri3_image_loader_extension = {
}; };
static EGLBoolean static EGLBoolean
dri3_swap_buffers(_EGLDisplay *disp, _EGLSurface *draw) dri3_swap_buffers_with_damage(_EGLDisplay *disp, _EGLSurface *draw,
const EGLint *rects, EGLint n_rects)
{ {
struct dri3_egl_surface *dri3_surf = dri3_egl_surface(draw); struct dri3_egl_surface *dri3_surf = dri3_egl_surface(draw);
return loader_dri3_swap_buffers_msc(&dri3_surf->loader_drawable, return loader_dri3_swap_buffers_msc(&dri3_surf->loader_drawable,
0, 0, 0, 0, 0, 0, 0, 0,
rects, n_rects,
draw->SwapBehavior == EGL_BUFFER_PRESERVED) != -1; draw->SwapBehavior == EGL_BUFFER_PRESERVED) != -1;
} }
static EGLBoolean
dri3_swap_buffers(_EGLDisplay *disp, _EGLSurface *draw)
{
return dri3_swap_buffers_with_damage(disp, draw, NULL, 0);
}
static EGLBoolean static EGLBoolean
dri3_copy_buffers(_EGLDisplay *disp, _EGLSurface *surf, void *native_pixmap_target) dri3_copy_buffers(_EGLDisplay *disp, _EGLSurface *surf, void *native_pixmap_target)
{ {
@@ -488,6 +496,7 @@ struct dri2_egl_display_vtbl dri3_x11_display_vtbl = {
.create_image = dri3_create_image_khr, .create_image = dri3_create_image_khr,
.swap_interval = dri3_set_swap_interval, .swap_interval = dri3_set_swap_interval,
.swap_buffers = dri3_swap_buffers, .swap_buffers = dri3_swap_buffers,
.swap_buffers_with_damage = dri3_swap_buffers_with_damage,
.copy_buffers = dri3_copy_buffers, .copy_buffers = dri3_copy_buffers,
.query_buffer_age = dri3_query_buffer_age, .query_buffer_age = dri3_query_buffer_age,
.query_surface = dri3_query_surface, .query_surface = dri3_query_surface,

View File

@@ -593,7 +593,7 @@ dri3_swap_buffers(__GLXDRIdrawable *pdraw, int64_t target_msc, int64_t divisor,
return loader_dri3_swap_buffers_msc(&priv->loader_drawable, return loader_dri3_swap_buffers_msc(&priv->loader_drawable,
target_msc, divisor, remainder, target_msc, divisor, remainder,
flags, false); flags, NULL, 0, false);
} }
static int static int

View File

@@ -30,6 +30,7 @@
#include <xcb/xcb.h> #include <xcb/xcb.h>
#include <xcb/dri3.h> #include <xcb/dri3.h>
#include <xcb/present.h> #include <xcb/present.h>
#include <xcb/xfixes.h>
#include <X11/Xlib-xcb.h> #include <X11/Xlib-xcb.h>
@@ -908,6 +909,7 @@ int64_t
loader_dri3_swap_buffers_msc(struct loader_dri3_drawable *draw, loader_dri3_swap_buffers_msc(struct loader_dri3_drawable *draw,
int64_t target_msc, int64_t divisor, int64_t target_msc, int64_t divisor,
int64_t remainder, unsigned flush_flags, int64_t remainder, unsigned flush_flags,
const int *rects, int n_rects,
bool force_copy) bool force_copy)
{ {
struct loader_dri3_buffer *back; struct loader_dri3_buffer *back;
@@ -1006,12 +1008,29 @@ loader_dri3_swap_buffers_msc(struct loader_dri3_drawable *draw,
#endif #endif
back->busy = 1; back->busy = 1;
back->last_swap = draw->send_sbc; back->last_swap = draw->send_sbc;
xcb_xfixes_region_t region = 0;
xcb_rectangle_t xcb_rects[64];
if (n_rects > 0 && n_rects <= ARRAY_SIZE(xcb_rects)) {
for (int i = 0; i < n_rects; i++) {
const int *rect = &rects[i * 4];
xcb_rects[i].x = rect[0];
xcb_rects[i].y = draw->height - rect[1] - rect[3];
xcb_rects[i].width = rect[2];
xcb_rects[i].height = rect[3];
}
region = xcb_generate_id(draw->conn);
xcb_xfixes_create_region(draw->conn, region, n_rects, xcb_rects);
}
xcb_present_pixmap(draw->conn, xcb_present_pixmap(draw->conn,
draw->drawable, draw->drawable,
back->pixmap, back->pixmap,
(uint32_t) draw->send_sbc, (uint32_t) draw->send_sbc,
0, /* valid */ 0, /* valid */
0, /* update */ region, /* update */
0, /* x_off */ 0, /* x_off */
0, /* y_off */ 0, /* y_off */
None, /* target_crtc */ None, /* target_crtc */
@@ -1023,6 +1042,9 @@ loader_dri3_swap_buffers_msc(struct loader_dri3_drawable *draw,
remainder, 0, NULL); remainder, 0, NULL);
ret = (int64_t) draw->send_sbc; ret = (int64_t) draw->send_sbc;
if (region)
xcb_xfixes_destroy_region(draw->conn, region);
/* Schedule a server-side back-preserving blit if necessary. /* Schedule a server-side back-preserving blit if necessary.
* This happens iff all conditions below are satisfied: * This happens iff all conditions below are satisfied:
* a) We have a fake front, * a) We have a fake front,

View File

@@ -205,6 +205,7 @@ int64_t
loader_dri3_swap_buffers_msc(struct loader_dri3_drawable *draw, loader_dri3_swap_buffers_msc(struct loader_dri3_drawable *draw,
int64_t target_msc, int64_t divisor, int64_t target_msc, int64_t divisor,
int64_t remainder, unsigned flush_flags, int64_t remainder, unsigned flush_flags,
const int *rects, int n_rects,
bool force_copy); bool force_copy);
int int

View File

@@ -28,6 +28,7 @@ if with_platform_x11 and with_dri3
include_directories : [inc_include, inc_src], include_directories : [inc_include, inc_src],
dependencies : [ dependencies : [
dep_libdrm, dep_xcb_dri3, dep_xcb_present, dep_xcb_sync, dep_xshmfence, dep_libdrm, dep_xcb_dri3, dep_xcb_present, dep_xcb_sync, dep_xshmfence,
dep_xcb_xfixes,
], ],
build_by_default : false, build_by_default : false,
) )