Hi, On pe, 2014-10-24 at 17:37 +0000, Emil Velikov wrote: > Hi Joonas, > > On 22/10/14 18:17, Joonas Lahtinen wrote: > > Hi, > > > > This patch introduced DRI3 support to the EGL backend. > > > > Patch is on top of current master. With the patch you can observe > > reduced CPU stress when many glViewport calls are made. > > > > Notice that the DRI3 extension is only exposed if the DRI3 interface is > > found working too instead of just existing. So you need to enable DRI3 > > from all three; Mesa, X driver and X server, to get the benefit. > > > It seems that you introduce yet another dri extension > (DRIdri3Extension) which afaict should not be needed ? > > Am I missing something here or did you get carried away by looking at > __DRIcoreExtension, __DRIdri2Extension and __DRIswrastExtension :P >
The DRI3 (just like the USE_INVALIDATE extension) extension is needed for the drivers to know that they do not need to invalidate buffers on each glViewport call. One could use USE_INVALIDATE extension for same functionality, but I see it would not be very good idea as the naming vs. context would be confusing. DRI3 is exposed dynamically depending on if DRI3 is usable or not. The USE_INVALIDATE is exposed as long as GLX is used. So that also makes them bit different (in logic too, not just naming). Regards, Joonas > Thanks > Emil > > > Regards, Joonas > > > > PS. Will be traveling over the weekend, so will react to comments on > > Monday. > > > > From c945e777e0aaf77a5ec450cdec1cf4db89ef0c8d Mon Sep 17 00:00:00 2001 > > From: Joonas Lahtinen <joonas.lahti...@linux.intel.com> > > Date: Wed, 22 Oct 2014 21:05:31 +0300 > > Subject: [PATCH] egl: Add DRI3 support to the EGL backend. > > > > DRI3 support is needed to avoid excess buffer invalidations, because > > the XCB interface doesn't supply that information through DRI2. > > > > Signed-off-by: Daniel van der Wath <danielx.j.van.der.w...@intel.com> > > Signed-off-by: Joonas Lahtinen <joonas.lahti...@linux.intel.com> > > --- > > configure.ac | 4 + > > include/GL/internal/dri_interface.h | 8 + > > src/egl/drivers/dri2/egl_dri2.c | 9 + > > src/egl/drivers/dri2/egl_dri2.h | 39 +++- > > src/egl/drivers/dri2/platform_x11.c | 340 > > ++++++++++++++++++++++++++++++- > > src/egl/main/Makefile.am | 4 + > > src/mesa/drivers/dri/common/dri_util.c | 2 + > > src/mesa/drivers/dri/common/dri_util.h | 1 + > > src/mesa/drivers/dri/i965/brw_context.c | 12 +- > > 9 files changed, 406 insertions(+), 13 deletions(-) > > > > diff --git a/configure.ac b/configure.ac > > index 0ed9325..308fddf 100644 > > --- a/configure.ac > > +++ b/configure.ac > > @@ -43,6 +43,7 @@ VDPAU_REQUIRED=0.4.1 > > WAYLAND_REQUIRED=1.2.0 > > XCB_REQUIRED=1.9.3 > > XCBDRI2_REQUIRED=1.8 > > +XCBDRI3_REQUIRED=1.8 > > XCBGLX_REQUIRED=1.8.1 > > XSHMFENCE_REQUIRED=1.1 > > XVMC_REQUIRED=1.0.6 > > @@ -1557,6 +1558,9 @@ for plat in $egl_platforms; do > > > > x11) > > PKG_CHECK_MODULES([XCB_DRI2], [x11-xcb xcb xcb-dri2 >= > > $XCBDRI2_REQUIRED xcb-xfixes]) > > + if test x"$enable_dri3" = "xyes"; then > > + PKG_CHECK_MODULES([XCB_DRI3], [xcb-dri3 >= > > $XCBDRI3_REQUIRED xcb-present]) > > + fi > > ;; > > > > drm) > > diff --git a/include/GL/internal/dri_interface.h > > b/include/GL/internal/dri_interface.h > > index 8c5ceb9..3bd9d18 100644 > > --- a/include/GL/internal/dri_interface.h > > +++ b/include/GL/internal/dri_interface.h > > @@ -83,6 +83,7 @@ typedef struct __DRIswrastExtensionRec > > __DRIswrastExtension; > > typedef struct __DRIbufferRec __DRIbuffer; > > typedef struct __DRIdri2ExtensionRec __DRIdri2Extension; > > typedef struct __DRIdri2LoaderExtensionRec __DRIdri2LoaderExtension; > > +typedef struct __DRIdri3ExtensionRec __DRIdri3Extension; > > typedef struct __DRI2flushExtensionRec __DRI2flushExtension; > > typedef struct __DRI2throttleExtensionRec __DRI2throttleExtension; > > > > @@ -999,6 +1000,13 @@ struct __DRIdri2ExtensionRec { > > __DRIcreateNewScreen2Func createNewScreen2; > > }; > > > > +#define __DRI_DRI3 "DRI_DRI3" > > +#define __DRI_DRI3_VERSION 1 > > + > > +struct __DRIdri3ExtensionRec { > > + __DRIextension base; > > +}; > > + > > > > /** > > * This extension provides functionality to enable various EGLImage > > diff --git a/src/egl/drivers/dri2/egl_dri2.c > > b/src/egl/drivers/dri2/egl_dri2.c > > index 20a7243..6024cb3 100644 > > --- a/src/egl/drivers/dri2/egl_dri2.c > > +++ b/src/egl/drivers/dri2/egl_dri2.c > > @@ -55,6 +55,12 @@ const __DRIuseInvalidateExtension use_invalidate = { > > .base = { __DRI_USE_INVALIDATE, 1 } > > }; > > > > +#ifdef HAVE_DRI3 > > +const __DRIdri3Extension dri3_extension = { > > + .base = { __DRI_DRI3, 1 } > > +}; > > +#endif > > + > > EGLint dri2_to_egl_attribute_map[] = { > > 0, > > EGL_BUFFER_SIZE, /* __DRI_ATTRIB_BUFFER_SIZE */ > > @@ -600,6 +606,9 @@ dri2_create_screen(_EGLDisplay *disp) > > if (strcmp(extensions[i]->name, __DRI2_CONFIG_QUERY) == 0) { > > dri2_dpy->config = (__DRI2configQueryExtension *) extensions[i]; > > } > > + if (strcmp(extensions[i]->name, __DRI_DRI3) == 0) { > > + dri2_dpy->dri3 = (__DRIdri3Extension *) extensions[i]; > > + } > > } > > } else { > > assert(dri2_dpy->swrast); > > diff --git a/src/egl/drivers/dri2/egl_dri2.h > > b/src/egl/drivers/dri2/egl_dri2.h > > index 52f05fb..d8713df 100644 > > --- a/src/egl/drivers/dri2/egl_dri2.h > > +++ b/src/egl/drivers/dri2/egl_dri2.h > > @@ -35,6 +35,11 @@ > > #include <X11/Xlib-xcb.h> > > #endif > > > > +#ifdef HAVE_DRI3 > > +#include <xcb/dri3.h> > > +#include <xcb/present.h> > > +#endif > > + > > #ifdef HAVE_WAYLAND_PLATFORM > > #include <wayland-client.h> > > #include "wayland-egl-priv.h" > > @@ -74,6 +79,7 @@ > > #include "eglimage.h" > > > > #define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0])) > > +#define DRI2_EGL_SURFACE_NUM_BUFFERS 5 > > > > struct wl_buffer; > > > > @@ -150,12 +156,17 @@ struct dri2_egl_display > > > > int dri2_major; > > int dri2_minor; > > +#ifdef HAVE_DRI3 > > + int dri3_major; > > + int dri3_minor; > > +#endif > > __DRIscreen *dri_screen; > > int own_dri_screen; > > const __DRIconfig **driver_configs; > > void *driver; > > const __DRIcoreExtension *core; > > const __DRIdri2Extension *dri2; > > + const __DRIdri3Extension *dri3; > > const __DRIswrastExtension *swrast; > > const __DRI2flushExtension *flush; > > const __DRItexBufferExtension *tex_buffer; > > @@ -163,6 +174,7 @@ struct dri2_egl_display > > const __DRIrobustnessExtension *robustness; > > const __DRI2configQueryExtension *config; > > int fd; > > + int dri3_present_and_working; > > > > int own_device; > > int swap_available; > > @@ -218,7 +230,7 @@ struct dri2_egl_surface > > { > > _EGLSurface base; > > __DRIdrawable *dri_drawable; > > - __DRIbuffer buffers[5]; > > + __DRIbuffer buffers[DRI2_EGL_SURFACE_NUM_BUFFERS]; > > int buffer_count; > > int have_fake_front; > > > > @@ -229,6 +241,28 @@ struct dri2_egl_surface > > int bytes_per_pixel; > > xcb_gcontext_t gc; > > xcb_gcontext_t swapgc; > > +#ifdef HAVE_DRI3 > > + xcb_special_event_t *special_event; > > + xcb_present_event_t eid; > > + uint32_t *stamp; > > + uint8_t is_pixmap; > > + uint8_t flipping; > > + > > + /* SBC numbers are tracked by using the serial numbers > > + * in the present request and complete events > > + */ > > + uint64_t send_sbc; > > + uint64_t recv_sbc; > > + > > + /* Last received UST/MSC values */ > > + uint64_t ust, msc; > > + > > + int num_back; > > + > > + /* Serial numbers for tracking wait_for_msc events */ > > + uint32_t send_msc_serial; > > + uint32_t recv_msc_serial; > > +#endif > > #endif > > > > #ifdef HAVE_WAYLAND_PLATFORM > > @@ -293,6 +327,9 @@ _EGL_DRIVER_TYPECAST(dri2_egl_image, _EGLImage, obj) > > > > extern const __DRIimageLookupExtension image_lookup_extension; > > extern const __DRIuseInvalidateExtension use_invalidate; > > +#ifdef HAVE_DRI3 > > +extern const __DRIdri3Extension dri3_extension; > > +#endif > > > > EGLBoolean > > dri2_load_driver(_EGLDisplay *disp); > > diff --git a/src/egl/drivers/dri2/platform_x11.c > > b/src/egl/drivers/dri2/platform_x11.c > > index f8c4b70..3bf0c96 100644 > > --- a/src/egl/drivers/dri2/platform_x11.c > > +++ b/src/egl/drivers/dri2/platform_x11.c > > @@ -188,6 +188,240 @@ get_xcb_screen(xcb_screen_iterator_t iter, int screen) > > return NULL; > > } > > > > +#ifdef HAVE_DRI3 > > +/** dri3_open > > + * > > + * Wrapper around xcb_dri3_open > > + */ > > +static int > > +dri3_open(struct dri2_egl_display *dri2_dpy, > > + Window root, > > + uint32_t provider) > > +{ > > + xcb_dri3_open_cookie_t cookie; > > + xcb_dri3_open_reply_t *reply; > > + xcb_connection_t *c = dri2_dpy->conn; > > + int fd; > > + > > + cookie = xcb_dri3_open(c, > > + root, > > + provider); > > + > > + reply = xcb_dri3_open_reply(c, cookie, NULL); > > + if (!reply) > > + return -1; > > + > > + if (reply->nfd != 1) { > > + free(reply); > > + return -1; > > + } > > + > > + fd = xcb_dri3_open_reply_fds(c, reply)[0]; > > + > > + fcntl(fd, F_SETFD, FD_CLOEXEC); > > + return fd; > > +} > > + > > +/* from glx. Called by the XCB_PRESENT_COMPLETE_NOTIFY case. > > + */ > > +static void > > +dri3_update_num_back(struct dri2_egl_surface *priv) > > +{ > > + priv->num_back = 1; > > + if (priv->flipping) > > + priv->num_back++; > > + if (priv->base.SwapInterval == 0) > > + priv->num_back++; > > +} > > + > > +/** dri3_free_render_buffer > > + * > > + * In the glx version there's some more clean up, but here we can just > > call releaseBuffer(). > > + */ > > +static void > > +dri3_free_render_buffer(struct dri2_egl_surface *pdraw, __DRIbuffer > > *buffer) > > +{ > > + struct dri2_egl_display *dri2_dpy = > > dri2_egl_display(pdraw->base.Resource.Display); > > + > > + (*dri2_dpy->dri2->releaseBuffer)(dri2_dpy->dri_screen, buffer); > > +} > > + > > +/* > > + * Process one Present event > > + */ > > +static void > > +dri3_handle_present_event(struct dri2_egl_surface *priv, > > xcb_present_generic_event_t *ge) > > +{ > > + switch (ge->evtype) { > > + case XCB_PRESENT_CONFIGURE_NOTIFY: { > > + xcb_present_configure_notify_event_t *ce = (void *) ge; > > + > > + priv->base.Width = ce->width; > > + priv->base.Height = ce->height; > > + break; > > + } > > + case XCB_PRESENT_COMPLETE_NOTIFY: { > > + xcb_present_complete_notify_event_t *ce = (void *) ge; > > + > > + /* Compute the processed SBC number from the received 32-bit serial > > number merged > > + * with the upper 32-bits of the sent 64-bit serial number while > > checking for > > + * wrap > > + */ > > + if (ce->kind == XCB_PRESENT_COMPLETE_KIND_PIXMAP) { > > + priv->recv_sbc = (priv->send_sbc & 0xffffffff00000000LL) | > > ce->serial; > > + if (priv->recv_sbc > priv->send_sbc) > > + priv->recv_sbc -= 0x100000000; > > + switch (ce->mode) { > > + case XCB_PRESENT_COMPLETE_MODE_FLIP: > > + priv->flipping = true; > > + break; > > + case XCB_PRESENT_COMPLETE_MODE_COPY: > > + priv->flipping = false; > > + break; > > + } > > + dri3_update_num_back(priv); > > + } else { > > + priv->recv_msc_serial = ce->serial; > > + } > > + priv->ust = ce->ust; > > + priv->msc = ce->msc; > > + break; > > + } > > + case XCB_PRESENT_EVENT_IDLE_NOTIFY: { > > + xcb_present_idle_notify_event_t *ie = (void *) ge; > > + int b; > > + > > + for (b = 0; b < sizeof (priv->buffers) / sizeof (priv->buffers[0]); > > b++) { > > + __DRIbuffer *buf = &priv->buffers[b]; > > + > > + if (buf && buf->name == ie->pixmap) { > > + /* busy is used in the glx version (in dri3_find_back()) but > > isn't required here */ > > + //buf->busy = 0; > > + > > + /* slight change from glx, these buffers are not dynamically > > allocated so don't > > + * need to be NULL'd. > > + */ > > + if (priv->num_back <= b && b < DRI2_EGL_SURFACE_NUM_BUFFERS) { > > + dri3_free_render_buffer(priv, buf); > > + } > > + break; > > + } > > + } > > + break; > > + } > > + default: > > + break; > > + } > > + free(ge); > > +} > > + > > +/** dri3_flush_present_events > > + * > > + * Process any present events that have been received from the X server > > + * > > + * From glx, we additionally invalidate the drawable here if there has a > > been a special event. > > + */ > > +static void > > +dri3_flush_present_events(struct dri2_egl_display *dri2_dpy, struct > > dri2_egl_surface *priv) > > +{ > > + xcb_connection_t *c = dri2_dpy->conn; > > + > > + /* Check to see if any configuration changes have occurred > > + * since we were last invoked > > + */ > > + if (priv->special_event) { > > + xcb_generic_event_t *ev; > > + > > + while ((ev = xcb_poll_for_special_event(c, priv->special_event)) != > > NULL) { > > + xcb_present_generic_event_t *ge = (void *) ev; > > + dri3_handle_present_event(priv, ge); > > + _eglLog(_EGL_INFO, "DRI3: Invalidating buffer 0x%x\n", > > priv->dri_drawable); > > + (*dri2_dpy->flush->invalidate)(priv->dri_drawable); > > + } > > + } > > +} > > + > > +/** dri3_update_drawable > > + * > > + * from glx > > + * Called the first time we use the drawable and then > > + * after we receive present configure notify events to > > + * track the geometry of the drawable > > + */ > > +static int > > +dri3_update_drawable(struct dri2_egl_display *dri2_dpy, __DRIdrawable > > *driDrawable, void *loaderPrivate) > > +{ > > + struct dri2_egl_surface *priv = loaderPrivate; > > + xcb_connection_t *c = dri2_dpy->conn; > > + > > + /* First time through, go get the current drawable geometry > > + */ > > + if (priv->base.Width == 0 || priv->base.Height == 0 || priv->depth == > > 0) { > > + xcb_get_geometry_cookie_t geom_cookie; > > + xcb_get_geometry_reply_t *geom_reply; > > + xcb_void_cookie_t cookie; > > + xcb_generic_error_t *error; > > + > > + /* Try to select for input on the window. > > + * > > + * If the drawable is a window, this will get our events > > + * delivered. > > + * > > + * Otherwise, we'll get a BadWindow error back from this request > > which > > + * will let us know that the drawable is a pixmap instead. > > + */ > > + > > + > > + cookie = xcb_present_select_input_checked(c, > > + (priv->eid = > > xcb_generate_id(c)), > > + priv->drawable, > > + > > XCB_PRESENT_EVENT_MASK_CONFIGURE_NOTIFY| > > + > > XCB_PRESENT_EVENT_MASK_COMPLETE_NOTIFY| > > + > > XCB_PRESENT_EVENT_MASK_IDLE_NOTIFY); > > + > > + /* Create an XCB event queue to hold present events outside of the > > usual > > + * application event queue > > + */ > > + priv->special_event = xcb_register_for_special_xge(c, > > + &xcb_present_id, > > + priv->eid, > > + priv->stamp); > > + > > + geom_cookie = xcb_get_geometry(c, priv->drawable); > > + > > + geom_reply = xcb_get_geometry_reply(c, geom_cookie, NULL); > > + > > + if (!geom_reply) > > + return false; > > + > > + priv->base.Width = geom_reply->width; > > + priv->base.Height = geom_reply->height; > > + priv->depth = geom_reply->depth; > > + priv->is_pixmap = false; > > + > > + free(geom_reply); > > + > > + /* Check to see if our select input call failed. If it failed with a > > + * BadWindow error, then assume the drawable is a pixmap. Destroy the > > + * special event queue created above and mark the drawable as a > > pixmap > > + */ > > + > > + error = xcb_request_check(c, cookie); > > + > > + if (error) { > > + if (error->error_code != BadWindow) { > > + free(error); > > + return false; > > + } > > + priv->is_pixmap = true; > > + xcb_unregister_for_special_event(c, priv->special_event); > > + priv->special_event = NULL; > > + } > > + } > > + dri3_flush_present_events(dri2_dpy, priv); > > + return true; > > +} > > +#endif > > > > /** > > * Called via eglCreateWindowSurface(), drv->API.CreateWindowSurface(). > > @@ -212,7 +446,10 @@ dri2_x11_create_surface(_EGLDriver *drv, _EGLDisplay > > *disp, EGLint type, > > > > (void) drv; > > > > - dri2_surf = malloc(sizeof *dri2_surf); > > + /* dri2_surf->special_event needs to be initialised as NULL > > + * so calloc makes sense here > > + */ > > + dri2_surf = calloc(1, sizeof *dri2_surf); > > if (!dri2_surf) { > > _eglError(EGL_BAD_ALLOC, "dri2_create_surface"); > > return NULL; > > @@ -360,6 +597,17 @@ dri2_x11_destroy_surface(_EGLDriver *drv, _EGLDisplay > > *disp, _EGLSurface *surf) > > if (surf->Type == EGL_PBUFFER_BIT) > > xcb_free_pixmap (dri2_dpy->conn, dri2_surf->drawable); > > > > +#ifdef HAVE_DRI3 > > + /* from glx: dri3_destroy_drawable(). dri2_surf is not necessarily being > > + * destroyed so we need to NULL special_event after unregistering it > > + */ > > + if (dri2_dpy->dri3_present_and_working && dri2_surf->special_event) > > + { > > + xcb_unregister_for_special_event(dri2_dpy->conn, > > dri2_surf->special_event); > > + dri2_surf->special_event = NULL; > > + } > > +#endif > > + > > free(surf); > > > > return EGL_TRUE; > > @@ -427,6 +675,11 @@ dri2_x11_get_buffers(__DRIdrawable * driDrawable, > > > > (void) driDrawable; > > > > +#ifdef HAVE_DRI3 > > + if (dri2_dpy->dri3_present_and_working && > > !dri3_update_drawable(dri2_dpy, driDrawable, loaderPrivate)) > > + return false; > > +#endif > > + > > cookie = xcb_dri2_get_buffers_unchecked (dri2_dpy->conn, > > dri2_surf->drawable, > > count, count, attachments); > > @@ -461,6 +714,11 @@ dri2_x11_get_buffers_with_format(__DRIdrawable * > > driDrawable, > > > > (void) driDrawable; > > > > +#ifdef HAVE_DRI3 > > + if (dri2_dpy->dri3_present_and_working && > > !dri3_update_drawable(dri2_dpy, driDrawable, loaderPrivate)) > > + return false; > > +#endif > > + > > format_attachments = (xcb_dri2_attach_format_t *) attachments; > > cookie = xcb_dri2_get_buffers_with_format_unchecked (dri2_dpy->conn, > > dri2_surf->drawable, > > @@ -500,12 +758,16 @@ dri2_x11_flush_front_buffer(__DRIdrawable * > > driDrawable, void *loaderPrivate) > > } > > > > static EGLBoolean > > -dri2_x11_connect(struct dri2_egl_display *dri2_dpy) > > +dri2_x11_connect(struct dri2_egl_display *dri2_dpy, _EGLDisplay *disp) > > { > > xcb_xfixes_query_version_reply_t *xfixes_query; > > xcb_xfixes_query_version_cookie_t xfixes_query_cookie; > > xcb_dri2_query_version_reply_t *dri2_query; > > xcb_dri2_query_version_cookie_t dri2_query_cookie; > > +#ifdef HAVE_DRI3 > > + xcb_dri3_query_version_reply_t *dri3_query; > > + xcb_dri3_query_version_cookie_t dri3_query_cookie; > > +#endif > > xcb_dri2_connect_reply_t *connect; > > xcb_dri2_connect_cookie_t connect_cookie; > > xcb_generic_error_t *error; > > @@ -525,6 +787,44 @@ dri2_x11_connect(struct dri2_egl_display *dri2_dpy) > > if (!(extension && extension->present)) > > return EGL_FALSE; > > > > +#ifdef HAVE_DRI3 > > + xcb_prefetch_extension_data (dri2_dpy->conn, &xcb_dri3_id); > > + extension = xcb_get_extension_data (dri2_dpy->conn, &xcb_dri3_id); > > + if (extension && extension->present) { > > + dri3_query_cookie = xcb_dri3_query_version (dri2_dpy->conn, > > + XCB_DRI3_MAJOR_VERSION, > > + XCB_DRI3_MINOR_VERSION); > > + dri3_query = > > + xcb_dri3_query_version_reply (dri2_dpy->conn, dri3_query_cookie, > > &error); > > + if (dri3_query == NULL || error != NULL) { > > + _eglLog(_EGL_WARNING, "DRI2: failed to query DRI3 version"); > > + free(error); > > + dri2_dpy->dri3_present_and_working = 0; > > + } else { > > + dri2_dpy->dri3_major = dri3_query->major_version; > > + dri2_dpy->dri3_minor = dri3_query->minor_version; > > + free(dri3_query); > > + > > + dri2_dpy->fd = dri3_open(dri2_dpy, > > RootWindow(disp->PlatformDisplay, DefaultScreen(disp->PlatformDisplay)), > > None); > > + if(dri2_dpy->fd < 0) > > + { > > + dri2_dpy->dri3_present_and_working = 0; > > + _eglLog(_EGL_INFO, "DRI2: DRI3 extension not working\n"); > > + } else { > > + dri2_dpy->dri3_present_and_working = 1; > > + _eglLog(_EGL_INFO, "DRI2: DRI3 present and working\n"); > > + close(dri2_dpy->fd); > > + dri2_dpy->fd = -1; > > + } > > + } > > + } else { > > + dri2_dpy->dri3_present_and_working = 0; > > + _eglLog(_EGL_INFO, "DRI2: DRI3 extension not present\n"); > > + } > > +#else > > + dri2_dpy->dri3_present_and_working = 0; > > +#endif > > + > > xfixes_query_cookie = xcb_xfixes_query_version(dri2_dpy->conn, > > XCB_XFIXES_MAJOR_VERSION, > > XCB_XFIXES_MINOR_VERSION); > > @@ -774,6 +1074,13 @@ dri2_x11_swap_buffers_msc(_EGLDriver *drv, > > _EGLDisplay *disp, _EGLSurface *draw, > > if (dri2_dpy->flush) > > (*dri2_dpy->flush->flush)(dri2_surf->dri_drawable); > > > > +#ifdef HAVE_DRI3 > > + /* Poll for special events and invalidate the surface if needed. > > + */ > > + if(dri2_dpy->dri3_present_and_working) > > + dri3_flush_present_events(dri2_dpy, dri2_surf); > > +#endif > > + > > cookie = xcb_dri2_swap_buffers_unchecked(dri2_dpy->conn, > > dri2_surf->drawable, > > msc_hi, msc_lo, divisor_hi, divisor_lo, remainder_hi, > > remainder_lo); > > > > @@ -794,10 +1101,15 @@ dri2_x11_swap_buffers_msc(_EGLDriver *drv, > > _EGLDisplay *disp, _EGLSurface *draw, > > * happened. The driver should still be using the viewport hack to > > catch > > * window resizes. > > */ > > - if (dri2_dpy->flush && > > - dri2_dpy->flush->base.version >= 3 && dri2_dpy->flush->invalidate) > > + /* With DRI3 we ARE watching for the server's invalidate events like > > we're > > + * supposed to. They're handled in dri3_flush_present_events(), so if > > we've > > + * got DRI3 then we don't need to invalidate here. > > + */ > > + if (!dri2_dpy->dri3_present_and_working && dri2_dpy->flush && > > + dri2_dpy->flush->base.version >= 3 && dri2_dpy->flush->invalidate) { > > + _eglLog(_EGL_INFO, "DRI: Invalidating buffer 0x%x\n", > > dri2_surf->dri_drawable); > > (*dri2_dpy->flush->invalidate)(dri2_surf->dri_drawable); > > - > > + } > > return swap_count; > > } > > > > @@ -807,6 +1119,14 @@ dri2_x11_swap_buffers(_EGLDriver *drv, _EGLDisplay > > *disp, _EGLSurface *draw) > > struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); > > struct dri2_egl_surface *dri2_surf = dri2_egl_surface(draw); > > > > +#ifdef HAVE_DRI3 > > + /* from glx: dri3_swap_buffers(). Polls for special events and > > invalidates > > + * the surface if needed. > > + */ > > + if(dri2_dpy->dri3_present_and_working) > > + dri3_flush_present_events(dri2_dpy, dri2_surf); > > +#endif > > + > > if (dri2_dpy->dri2) { > > return dri2_x11_swap_buffers_msc(drv, disp, draw, 0, 0, 0) != -1; > > } else { > > @@ -1234,7 +1554,7 @@ dri2_initialize_x11_dri2(_EGLDriver *drv, _EGLDisplay > > *disp) > > } > > > > if (dri2_dpy->conn) { > > - if (!dri2_x11_connect(dri2_dpy)) > > + if (!dri2_x11_connect(dri2_dpy, disp)) > > goto cleanup_conn; > > } > > > > @@ -1277,10 +1597,16 @@ dri2_initialize_x11_dri2(_EGLDriver *drv, > > _EGLDisplay *disp) > > dri2_dpy->dri2_loader_extension.flushFrontBuffer = > > dri2_x11_flush_front_buffer; > > dri2_dpy->dri2_loader_extension.getBuffersWithFormat = NULL; > > } > > - > > + > > dri2_dpy->extensions[0] = &dri2_dpy->dri2_loader_extension.base; > > dri2_dpy->extensions[1] = &image_lookup_extension.base; > > dri2_dpy->extensions[2] = NULL; > > +#ifdef HAVE_DRI3 > > + if (dri2_dpy->dri3_present_and_working) { > > + dri2_dpy->extensions[2] = &dri3_extension.base; > > + dri2_dpy->extensions[3] = NULL; > > + } > > +#endif > > > > dri2_dpy->swap_available = (dri2_dpy->dri2_minor >= 2); > > dri2_dpy->invalidate_available = (dri2_dpy->dri2_minor >= 3); > > diff --git a/src/egl/main/Makefile.am b/src/egl/main/Makefile.am > > index df8bf28..490930f 100644 > > --- a/src/egl/main/Makefile.am > > +++ b/src/egl/main/Makefile.am > > @@ -79,6 +79,10 @@ libEGL_la_LIBADD += ../drivers/dri2/libegl_dri2.la > > libEGL_la_LIBADD += $(DLOPEN_LIBS) $(LIBDRM_LIBS) > > endif > > > > +if HAVE_DRI3 > > +libEGL_la_LIBADD += $(XCB_DRI3_LIBS) > > +endif > > + > > include $(top_srcdir)/install-lib-links.mk > > > > pkgconfigdir = $(libdir)/pkgconfig > > diff --git a/src/mesa/drivers/dri/common/dri_util.c > > b/src/mesa/drivers/dri/common/dri_util.c > > index 6c78928..068d209 100644 > > --- a/src/mesa/drivers/dri/common/dri_util.c > > +++ b/src/mesa/drivers/dri/common/dri_util.c > > @@ -73,6 +73,8 @@ setupLoaderExtensions(__DRIscreen *psp, > > for (i = 0; extensions[i]; i++) { > > if (strcmp(extensions[i]->name, __DRI_DRI2_LOADER) == 0) > > psp->dri2.loader = (__DRIdri2LoaderExtension *) extensions[i]; > > + if (strcmp(extensions[i]->name, __DRI_DRI3) == 0) > > + psp->dri2.dri3 = (__DRIdri3Extension *) extensions[i]; > > if (strcmp(extensions[i]->name, __DRI_IMAGE_LOOKUP) == 0) > > psp->dri2.image = (__DRIimageLookupExtension *) extensions[i]; > > if (strcmp(extensions[i]->name, __DRI_USE_INVALIDATE) == 0) > > diff --git a/src/mesa/drivers/dri/common/dri_util.h > > b/src/mesa/drivers/dri/common/dri_util.h > > index 1138bf1..e64a049 100644 > > --- a/src/mesa/drivers/dri/common/dri_util.h > > +++ b/src/mesa/drivers/dri/common/dri_util.h > > @@ -175,6 +175,7 @@ struct __DRIscreenRec { > > /* Flag to indicate that this is a DRI2 screen. Many of the above > > * fields will not be valid or initializaed in that case. */ > > const __DRIdri2LoaderExtension *loader; > > + const __DRIdri3Extension *dri3; > > const __DRIimageLookupExtension *image; > > const __DRIuseInvalidateExtension *useInvalidate; > > } dri2; > > diff --git a/src/mesa/drivers/dri/i965/brw_context.c > > b/src/mesa/drivers/dri/i965/brw_context.c > > index 8b3f45b..0b25dc8 100644 > > --- a/src/mesa/drivers/dri/i965/brw_context.c > > +++ b/src/mesa/drivers/dri/i965/brw_context.c > > @@ -148,6 +148,9 @@ intel_viewport(struct gl_context *ctx) > > __DRIcontext *driContext = brw->driContext; > > > > if (_mesa_is_winsys_fbo(ctx->DrawBuffer)) { > > + if (unlikely(INTEL_DEBUG & DEBUG_DRI)) > > + fprintf(stderr, "invalidating drawables\n"); > > + > > dri2InvalidateDrawable(driContext->driDrawablePriv); > > dri2InvalidateDrawable(driContext->driReadablePriv); > > } > > @@ -252,13 +255,12 @@ brw_init_driver_functions(struct brw_context *brw, > > _mesa_init_driver_functions(functions); > > > > /* GLX uses DRI2 invalidate events to handle window resizing. > > - * Unfortunately, EGL does not - libEGL is written in XCB (not Xlib), > > - * which doesn't provide a mechanism for snooping the event queues. > > + * EGL backend can only receive the events when DRI3 is present. > > * > > - * So EGL still relies on viewport hacks to handle window resizing. > > - * This should go away with DRI3000. > > + * So DRI2 relies on viewport hacks to handle window resizing. > > */ > > - if (!brw->driContext->driScreenPriv->dri2.useInvalidate) > > + if (!brw->driContext->driScreenPriv->dri2.useInvalidate && > > + !brw->driContext->driScreenPriv->dri2.dri3) > > functions->Viewport = intel_viewport; > > > > functions->Flush = intel_glFlush; > > > _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev