return (struct dri3_drawable *)(((void*) draw) - offset);
}
-static int
-glx_dri3_get_swap_interval(struct loader_dri3_drawable *draw)
-{
- struct dri3_drawable *priv = loader_drawable_to_dri3_drawable(draw);
-
- return priv->swap_interval;
-}
-
-static int
-glx_dri3_clamp_swap_interval(struct loader_dri3_drawable *draw, int interval)
-{
- return interval;
-}
-
-static void
-glx_dri3_set_swap_interval(struct loader_dri3_drawable *draw, int interval)
-{
- struct dri3_drawable *priv = loader_drawable_to_dri3_drawable(draw);
-
- priv->swap_interval = interval;
-}
-
static void
glx_dri3_set_drawable_size(struct loader_dri3_drawable *draw,
int width, int height)
}
static __DRIscreen *
-glx_dri3_get_dri_screen(struct loader_dri3_drawable *draw)
+glx_dri3_get_dri_screen(void)
{
struct glx_context *gc = __glXGetCurrentContext();
struct dri3_context *pcp = (struct dri3_context *) gc;
}
static const struct loader_dri3_vtable glx_dri3_vtable = {
- .get_swap_interval = glx_dri3_get_swap_interval,
- .clamp_swap_interval = glx_dri3_clamp_swap_interval,
- .set_swap_interval = glx_dri3_set_swap_interval,
.set_drawable_size = glx_dri3_set_drawable_size,
.in_current_context = glx_dri3_in_current_context,
.get_dri_context = glx_dri3_get_dri_context,
return GLXBadContext;
if (dri_draw)
- (*psc->f->invalidate)(dri_draw);
+ psc->f->invalidate(dri_draw);
if (dri_read && dri_read != dri_draw)
- (*psc->f->invalidate)(dri_read);
+ psc->f->invalidate(dri_read);
return Success;
}
uint32_t flags = 0;
unsigned api;
int reset = __DRI_CTX_RESET_NO_NOTIFICATION;
- uint32_t ctx_attribs[2 * 5];
+ int release = __DRI_CTX_RELEASE_BEHAVIOR_FLUSH;
+ uint32_t ctx_attribs[2 * 6];
unsigned num_ctx_attribs = 0;
uint32_t render_type;
if (!dri2_convert_glx_attribs(num_attribs, attribs,
&major_ver, &minor_ver,
&render_type, &flags, &api,
- &reset, error))
+ &reset, &release, error))
+ goto error_exit;
+
+ if (!dri2_check_no_error(flags, shareList, major_ver, error)) {
goto error_exit;
+ }
/* Check the renderType value */
if (!validate_renderType_against_config(config_base, render_type))
goto error_exit;
}
- if (!glx_context_init(&pcp->base, &psc->base, &config->base))
+ if (!glx_context_init(&pcp->base, &psc->base, config_base))
goto error_exit;
ctx_attribs[num_ctx_attribs++] = __DRI_CTX_ATTRIB_MAJOR_VERSION;
ctx_attribs[num_ctx_attribs++] = reset;
}
+ if (release != __DRI_CTX_RELEASE_BEHAVIOR_FLUSH) {
+ ctx_attribs[num_ctx_attribs++] = __DRI_CTX_ATTRIB_RELEASE_BEHAVIOR;
+ ctx_attribs[num_ctx_attribs++] = release;
+ }
+
if (flags != 0) {
ctx_attribs[num_ctx_attribs++] = __DRI_CTX_ATTRIB_FLAGS;
* GLX_CONTEXT_*_BIT values.
*/
ctx_attribs[num_ctx_attribs++] = flags;
+
+ if (flags & __DRI_CTX_FLAG_NO_ERROR)
+ pcp->base.noError = GL_TRUE;
}
pcp->driContext =
(*psc->image_driver->createContextAttribs) (psc->driScreen,
api,
- config->driConfig,
+ config ? config->driConfig
+ : NULL,
shared,
num_ctx_attribs / 2,
ctx_attribs,
struct glx_context *shareList, int renderType)
{
unsigned int error;
+ uint32_t attribs[2] = { GLX_RENDER_TYPE, renderType };
return dri3_create_context_attribs(base, config_base, shareList,
- 0, NULL, &error);
+ 1, attribs, &error);
}
static void
struct dri3_drawable *pdraw;
struct dri3_screen *psc = (struct dri3_screen *) base;
__GLXDRIconfigPrivate *config = (__GLXDRIconfigPrivate *) config_base;
+ bool has_multibuffer = false;
+#ifdef HAVE_DRI3_MODIFIERS
+ const struct dri3_display *const pdp = (struct dri3_display *)
+ base->display->dri3Display;
+#endif
pdraw = calloc(1, sizeof(*pdraw));
if (!pdraw)
pdraw->base.drawable = drawable;
pdraw->base.psc = &psc->base;
+#ifdef HAVE_DRI3_MODIFIERS
+ if ((psc->image && psc->image->base.version >= 15) &&
+ (pdp->dri3Major > 1 || (pdp->dri3Major == 1 && pdp->dri3Minor >= 2)) &&
+ (pdp->presentMajor > 1 ||
+ (pdp->presentMajor == 1 && pdp->presentMinor >= 2)))
+ has_multibuffer = true;
+#endif
+
(void) __glXInitialize(psc->base.dpy);
if (loader_dri3_drawable_init(XGetXCBConnection(base->dpy),
xDrawable, psc->driScreen,
- psc->is_different_gpu, config->driConfig,
+ psc->is_different_gpu, has_multibuffer,
+ config->driConfig,
&psc->loader_dri3_ext, &glx_dri3_vtable,
&pdraw->loader_drawable)) {
free(pdraw);
loader_dri3_flush(draw, __DRI2_FLUSH_DRAWABLE, __DRI2_THROTTLE_FLUSHFRONT);
- (*psc->f->invalidate)(driDrawable);
+ psc->f->invalidate(driDrawable);
loader_dri3_wait_gl(draw);
}
+/**
+ * Make sure all pending swapbuffers have been submitted to hardware
+ *
+ * \param driDrawable[in] Pointer to the dri drawable whose swaps we are
+ * flushing.
+ * \param loaderPrivate[in] Pointer to the corresponding struct
+ * loader_dri_drawable.
+ */
+static void
+dri3_flush_swap_buffers(__DRIdrawable *driDrawable, void *loaderPrivate)
+{
+ struct loader_dri3_drawable *draw = loaderPrivate;
+ struct dri3_drawable *pdraw = loader_drawable_to_dri3_drawable(draw);
+ struct dri3_screen *psc;
+
+ if (!pdraw)
+ return;
+
+ if (!pdraw->base.psc)
+ return;
+
+ psc = (struct dri3_screen *) pdraw->base.psc;
+
+ (void) __glXInitialize(psc->base.dpy);
+ loader_dri3_swapbuffer_barrier(draw);
+}
+
static void
dri_set_background_context(void *loaderPrivate)
{
/* The image loader extension record for DRI3
*/
static const __DRIimageLoaderExtension imageLoaderExtension = {
- .base = { __DRI_IMAGE_LOADER, 1 },
+ .base = { __DRI_IMAGE_LOADER, 3 },
.getBuffers = loader_dri3_get_buffers,
.flushFrontBuffer = dri3_flush_front_buffer,
+ .flushSwapBuffers = dri3_flush_swap_buffers,
};
const __DRIuseInvalidateExtension dri3UseInvalidate = {
struct dri3_screen *psc = (struct dri3_screen *) base;
/* Free the direct rendering per screen data */
+ loader_dri3_close_screen(psc->driScreen);
(*psc->core->destroyScreen) (psc->driScreen);
driDestroyConfigs(psc->driver_configs);
close(psc->fd);
struct dri3_drawable *priv = (struct dri3_drawable *) pdraw;
- return priv->swap_interval;
+ return priv->loader_drawable.swap_interval;
}
static void
if (pdraw != NULL) {
psc = (struct dri3_screen *) base->psc;
- (*psc->f->invalidate)(pdraw->loader_drawable.dri_drawable);
+ psc->f->invalidate(pdraw->loader_drawable.dri_drawable);
XSync(dpy, false);
extensions = psc->core->getExtensions(psc->driScreen);
- __glXEnableDirectExtension(&psc->base, "GLX_SGI_video_sync");
__glXEnableDirectExtension(&psc->base, "GLX_SGI_swap_control");
__glXEnableDirectExtension(&psc->base, "GLX_MESA_swap_control");
__glXEnableDirectExtension(&psc->base, "GLX_SGI_make_current_read");
__glXEnableDirectExtension(&psc->base,
"GLX_ARB_create_context_robustness");
+ if (strcmp(extensions[i]->name, __DRI2_NO_ERROR) == 0)
+ __glXEnableDirectExtension(&psc->base,
+ "GLX_ARB_create_context_no_error");
+
if (strcmp(extensions[i]->name, __DRI2_RENDERER_QUERY) == 0) {
psc->rendererQuery = (__DRI2rendererQueryExtension *) extensions[i];
__glXEnableDirectExtension(&psc->base, "GLX_MESA_query_renderer");
if (strcmp(extensions[i]->name, __DRI2_INTEROP) == 0)
psc->interop = (__DRI2interopExtension*)extensions[i];
+
+ if (strcmp(extensions[i]->name, __DRI2_FLUSH_CONTROL) == 0)
+ __glXEnableDirectExtension(&psc->base,
+ "GLX_ARB_context_flush_control");
}
}
struct dri3_screen *psc;
__GLXDRIscreen *psp;
struct glx_config *configs = NULL, *visuals = NULL;
- char *driverName, *deviceName, *tmp;
+ char *driverName, *tmp;
int i;
unsigned char disable;
}
psc->fd = loader_get_user_preferred_fd(psc->fd, &psc->is_different_gpu);
- deviceName = NULL;
driverName = loader_get_driver_for_fd(psc->fd);
if (!driverName) {
goto handle_error;
}
- psc->driver = driOpenDriver(driverName);
- if (psc->driver == NULL) {
- ErrorMessageF("driver pointer missing\n");
- goto handle_error;
- }
-
- extensions = driGetDriverExtensions(psc->driver, driverName);
+ extensions = driOpenDriver(driverName, &psc->driver);
if (extensions == NULL)
goto handle_error;
&disable) || !disable)
__glXEnableDirectExtension(&psc->base, "GLX_OML_sync_control");
+ if (psc->config->configQueryb(psc->driScreen,
+ "glx_disable_sgi_video_sync",
+ &disable) || !disable)
+ __glXEnableDirectExtension(&psc->base, "GLX_SGI_video_sync");
+
psp->copySubBuffer = dri3_copy_sub_buffer;
__glXEnableDirectExtension(&psc->base, "GLX_MESA_copy_sub_buffer");
__glXEnableDirectExtension(&psc->base, "GLX_EXT_buffer_age");
free(driverName);
- free(deviceName);
tmp = getenv("LIBGL_SHOW_FPS");
psc->show_fps_interval = tmp ? atoi(tmp) : 0;
return &psc->base;
handle_error:
- CriticalErrorMessageF("failed to load driver: %s\n", driverName);
+ CriticalErrorMessageF("failed to load driver: %s\n", driverName ? driverName : "(null)");
if (configs)
glx_config_destroy_list(configs);
dlclose(psc->driver);
free(driverName);
- free(deviceName);
glx_screen_cleanup(&psc->base);
free(psc);
free(dpy);
}
+/* Only request versions of these protocols which we actually support. */
+#define DRI3_SUPPORTED_MAJOR 1
+#define PRESENT_SUPPORTED_MAJOR 1
+
+#ifdef HAVE_DRI3_MODIFIERS
+#define DRI3_SUPPORTED_MINOR 2
+#define PRESENT_SUPPORTED_MINOR 2
+#else
+#define PRESENT_SUPPORTED_MINOR 0
+#define DRI3_SUPPORTED_MINOR 0
+#endif
+
/** dri3_create_display
*
* Allocate, initialize and return a __DRIdisplayPrivate object.
return NULL;
dri3_cookie = xcb_dri3_query_version(c,
- XCB_DRI3_MAJOR_VERSION,
- XCB_DRI3_MINOR_VERSION);
-
-
+ DRI3_SUPPORTED_MAJOR,
+ DRI3_SUPPORTED_MINOR);
present_cookie = xcb_present_query_version(c,
- XCB_PRESENT_MAJOR_VERSION,
- XCB_PRESENT_MINOR_VERSION);
+ PRESENT_SUPPORTED_MAJOR,
+ PRESENT_SUPPORTED_MINOR);
pdp = malloc(sizeof *pdp);
if (pdp == NULL)