+ __GLXDRIdrawable *pdraw =
+ dri2GetGlxDrawableFromXDrawableId(dpy, drawable);
+ struct dri2_screen *psc;
+ struct dri2_drawable *pdp = (struct dri2_drawable *) pdraw;
+
+ if (!pdraw)
+ return;
+
+ psc = (struct dri2_screen *) pdraw->psc;
+
+ if (pdraw && psc->f && psc->f->base.version >= 3 && psc->f->invalidate)
+ psc->f->invalidate(pdp->driDrawable);
+}
+
+static void
+dri2_bind_tex_image(Display * dpy,
+ GLXDrawable drawable,
+ int buffer, const int *attrib_list)
+{
+ struct glx_context *gc = __glXGetCurrentContext();
+ struct dri2_context *pcp = (struct dri2_context *) gc;
+ __GLXDRIdrawable *base = GetGLXDRIDrawable(dpy, drawable);
+ struct glx_display *dpyPriv = __glXInitialize(dpy);
+ struct dri2_drawable *pdraw = (struct dri2_drawable *) base;
+ struct dri2_display *pdp;
+ struct dri2_screen *psc;
+
+ if (dpyPriv == NULL)
+ return;
+
+ pdp = (struct dri2_display *) dpyPriv->dri2Display;
+
+ if (pdraw != NULL) {
+ psc = (struct dri2_screen *) base->psc;
+
+ if (!pdp->invalidateAvailable && psc->f &&
+ psc->f->base.version >= 3 && psc->f->invalidate)
+ psc->f->invalidate(pdraw->driDrawable);
+
+ if (psc->texBuffer->base.version >= 2 &&
+ psc->texBuffer->setTexBuffer2 != NULL) {
+ (*psc->texBuffer->setTexBuffer2) (pcp->driContext,
+ pdraw->base.textureTarget,
+ pdraw->base.textureFormat,
+ pdraw->driDrawable);
+ }
+ else {
+ (*psc->texBuffer->setTexBuffer) (pcp->driContext,
+ pdraw->base.textureTarget,
+ pdraw->driDrawable);
+ }
+ }
+}
+
+static void
+dri2_release_tex_image(Display * dpy, GLXDrawable drawable, int buffer)
+{
+ struct glx_context *gc = __glXGetCurrentContext();
+ struct dri2_context *pcp = (struct dri2_context *) gc;
+ __GLXDRIdrawable *base = GetGLXDRIDrawable(dpy, drawable);
+ struct glx_display *dpyPriv = __glXInitialize(dpy);
+ struct dri2_drawable *pdraw = (struct dri2_drawable *) base;
+ struct dri2_screen *psc;
+
+ if (dpyPriv != NULL && pdraw != NULL) {
+ psc = (struct dri2_screen *) base->psc;
+
+ if (psc->texBuffer->base.version >= 3 &&
+ psc->texBuffer->releaseTexBuffer != NULL) {
+ (*psc->texBuffer->releaseTexBuffer) (pcp->driContext,
+ pdraw->base.textureTarget,
+ pdraw->driDrawable);
+ }
+ }
+}
+
+static const struct glx_context_vtable dri2_context_vtable = {
+ .destroy = dri2_destroy_context,
+ .bind = dri2_bind_context,
+ .unbind = dri2_unbind_context,
+ .wait_gl = dri2_wait_gl,
+ .wait_x = dri2_wait_x,
+ .use_x_font = DRI_glXUseXFont,
+ .bind_tex_image = dri2_bind_tex_image,
+ .release_tex_image = dri2_release_tex_image,
+ .get_proc_address = NULL,
+ .interop_query_device_info = dri2_interop_query_device_info,
+ .interop_export_object = dri2_interop_export_object
+};
+
+static void
+dri2BindExtensions(struct dri2_screen *psc, struct glx_display * priv,
+ const char *driverName)
+{
+ const struct dri2_display *const pdp = (struct dri2_display *)
+ priv->dri2Display;
+ const __DRIextension **extensions;
+ int i;
+
+ extensions = psc->core->getExtensions(psc->driScreen);
+
+ __glXEnableDirectExtension(&psc->base, "GLX_SGI_swap_control");
+ __glXEnableDirectExtension(&psc->base, "GLX_MESA_swap_control");
+ __glXEnableDirectExtension(&psc->base, "GLX_SGI_make_current_read");
+
+ /*
+ * GLX_INTEL_swap_event is broken on the server side, where it's
+ * currently unconditionally enabled. This completely breaks
+ * systems running on drivers which don't support that extension.
+ * There's no way to test for its presence on this side, so instead
+ * of disabling it unconditionally, just disable it for drivers
+ * which are known to not support it, or for DDX drivers supporting
+ * only an older (pre-ScheduleSwap) version of DRI2.
+ *
+ * This is a hack which is required until:
+ * http://lists.x.org/archives/xorg-devel/2013-February/035449.html
+ * is merged and updated xserver makes it's way into distros:
+ */
+ if (pdp->swapAvailable && strcmp(driverName, "vmwgfx") != 0) {
+ __glXEnableDirectExtension(&psc->base, "GLX_INTEL_swap_event");
+ }