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:

committed by
Marge Bot

parent
eae181e3eb
commit
326eb56718
@@ -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)
|
||||||
|
@@ -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);
|
||||||
|
|
||||||
|
@@ -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,
|
||||||
|
@@ -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
|
||||||
|
@@ -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,
|
||||||
|
@@ -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
|
||||||
|
@@ -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,
|
||||||
)
|
)
|
||||||
|
Reference in New Issue
Block a user