diff --git a/include/GL/internal/dri_interface.h b/include/GL/internal/dri_interface.h index e37917eda99..29c9a116136 100644 --- a/include/GL/internal/dri_interface.h +++ b/include/GL/internal/dri_interface.h @@ -808,9 +808,27 @@ struct __DRIdri2LoaderExtensionRec { #define __DRI_CTX_ATTRIB_MINOR_VERSION 1 #define __DRI_CTX_ATTRIB_FLAGS 2 +/** + * \requires __DRI2_ROBUSTNESS. + */ +#define __DRI_CTX_ATTRIB_RESET_STRATEGY 3 + #define __DRI_CTX_FLAG_DEBUG 0x00000001 #define __DRI_CTX_FLAG_FORWARD_COMPATIBLE 0x00000002 +/** + * \requires __DRI2_ROBUSTNESS. + */ +#define __DRI_CTX_FLAG_ROBUST_BUFFER_ACCESS 0x00000004 + +/** + * \name Context reset strategies. + */ +/*@{*/ +#define __DRI_CTX_RESET_NO_NOTIFICATION 0 +#define __DRI_CTX_RESET_LOSE_CONTEXT 1 +/*@}*/ + /** * \name Reasons that __DRIdri2Extension::createContextAttribs might fail */ @@ -1000,4 +1018,21 @@ struct __DRI2configQueryExtensionRec { int (*configQueryi)(__DRIscreen *screen, const char *var, GLint *val); int (*configQueryf)(__DRIscreen *screen, const char *var, GLfloat *val); }; + +/** + * Robust context driver extension. + * + * Existence of this extension means the driver can accept the + * \c __DRI_CTX_FLAG_ROBUST_BUFFER_ACCESS flag and the + * \c __DRI_CTX_ATTRIB_RESET_STRATEGY attribute in + * \c __DRIdri2ExtensionRec::createContextAttribs. + */ +#define __DRI2_ROBUSTNESS "DRI_Robustness" +#define __DRI2_ROBUSTNESS_VERSION 1 + +typedef struct __DRIrobustnessExtensionRec __DRIrobustnessExtension; +struct __DRIrobustnessExtensionRec { + __DRIextension base; +}; + #endif diff --git a/src/glx/dri2_glx.c b/src/glx/dri2_glx.c index b6988c3ca60..79237c3c91b 100644 --- a/src/glx/dri2_glx.c +++ b/src/glx/dri2_glx.c @@ -241,7 +241,8 @@ dri2_create_context_attribs(struct glx_screen *base, uint32_t major_ver = 2; uint32_t flags = 0; unsigned api; - uint32_t ctx_attribs[2 * 4]; + int reset; + uint32_t ctx_attribs[2 * 5]; unsigned num_ctx_attribs = 0; if (psc->dri2->base.version < 3) { @@ -252,7 +253,8 @@ dri2_create_context_attribs(struct glx_screen *base, /* Remap the GLX tokens to DRI2 tokens. */ if (!dri2_convert_glx_attribs(num_attribs, attribs, - &major_ver, &minor_ver, &flags, &api, error)) + &major_ver, &minor_ver, &flags, &api, &reset, + error)) goto error_exit; if (shareList) { @@ -275,6 +277,15 @@ dri2_create_context_attribs(struct glx_screen *base, ctx_attribs[num_ctx_attribs++] = __DRI_CTX_ATTRIB_MINOR_VERSION; ctx_attribs[num_ctx_attribs++] = minor_ver; + /* Only send a value when the non-default value is requested. By doing + * this we don't have to check the driver's DRI2 version before sending the + * default value. + */ + if (reset != __DRI_CTX_RESET_NO_NOTIFICATION) { + ctx_attribs[num_ctx_attribs++] = __DRI_CTX_ATTRIB_RESET_STRATEGY; + ctx_attribs[num_ctx_attribs++] = reset; + } + if (flags != 0) { ctx_attribs[num_ctx_attribs++] = __DRI_CTX_ATTRIB_FLAGS; @@ -979,6 +990,14 @@ dri2BindExtensions(struct dri2_screen *psc, const __DRIextension **extensions) if (((strcmp(extensions[i]->name, __DRI2_THROTTLE) == 0))) psc->throttle = (__DRI2throttleExtension *) extensions[i]; + + /* DRI2 version 3 is also required because + * GLX_ARB_create_context_robustness requires GLX_ARB_create_context. + */ + if (psc->dri2->base.version >= 3 + && strcmp(extensions[i]->name, __DRI2_ROBUSTNESS) == 0) + __glXEnableDirectExtension(&psc->base, + "GLX_ARB_create_context_robustness"); } } diff --git a/src/glx/dri_common.c b/src/glx/dri_common.c index 07fd0154e1b..d170aa6f7e2 100644 --- a/src/glx/dri_common.c +++ b/src/glx/dri_common.c @@ -457,7 +457,8 @@ driReleaseDrawables(struct glx_context *gc) _X_HIDDEN bool dri2_convert_glx_attribs(unsigned num_attribs, const uint32_t *attribs, unsigned *major_ver, unsigned *minor_ver, - uint32_t *flags, unsigned *api, unsigned *error) + uint32_t *flags, unsigned *api, int *reset, + unsigned *error) { unsigned i; bool got_profile = false; @@ -478,6 +479,7 @@ dri2_convert_glx_attribs(unsigned num_attribs, const uint32_t *attribs, *major_ver = 1; *minor_ver = 0; + *reset = __DRI_CTX_RESET_NO_NOTIFICATION; for (i = 0; i < num_attribs; i++) { switch (attribs[i * 2]) { @@ -497,6 +499,19 @@ dri2_convert_glx_attribs(unsigned num_attribs, const uint32_t *attribs, case GLX_RENDER_TYPE: render_type = attribs[i * 2 + 1]; break; + case GLX_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB: + switch (attribs[i * 2 + 1]) { + case GLX_NO_RESET_NOTIFICATION_ARB: + *reset = __DRI_CTX_RESET_NO_NOTIFICATION; + break; + case GLX_LOSE_CONTEXT_ON_RESET_ARB: + *reset = __DRI_CTX_RESET_LOSE_CONTEXT; + break; + default: + *error = __DRI_CTX_ERROR_UNKNOWN_ATTRIBUTE; + return false; + } + break; default: /* If an unknown attribute is received, fail. */ @@ -536,7 +551,8 @@ dri2_convert_glx_attribs(unsigned num_attribs, const uint32_t *attribs, /* Unknown flag value. */ - if (*flags & ~(__DRI_CTX_FLAG_DEBUG | __DRI_CTX_FLAG_FORWARD_COMPATIBLE)) { + if (*flags & ~(__DRI_CTX_FLAG_DEBUG | __DRI_CTX_FLAG_FORWARD_COMPATIBLE + | __DRI_CTX_FLAG_ROBUST_BUFFER_ACCESS)) { *error = __DRI_CTX_ERROR_UNKNOWN_FLAG; return false; } diff --git a/src/glx/dri_common.h b/src/glx/dri_common.h index f5c7d456ee1..93cd744b1f2 100644 --- a/src/glx/dri_common.h +++ b/src/glx/dri_common.h @@ -72,6 +72,7 @@ extern void *driOpenDriver(const char *driverName); extern bool dri2_convert_glx_attribs(unsigned num_attribs, const uint32_t *attribs, unsigned *major_ver, unsigned *minor_ver, - uint32_t *flags, unsigned *api, unsigned *error); + uint32_t *flags, unsigned *api, int *reset, + unsigned *error); #endif /* _DRI_COMMON_H */ diff --git a/src/glx/drisw_glx.c b/src/glx/drisw_glx.c index 95d2dcc04b2..519786e5281 100644 --- a/src/glx/drisw_glx.c +++ b/src/glx/drisw_glx.c @@ -433,6 +433,7 @@ drisw_create_context_attribs(struct glx_screen *base, uint32_t major_ver = 0; uint32_t flags = 0; unsigned api; + int reset; uint32_t ctx_attribs[2 * 4]; unsigned num_ctx_attribs = 0; @@ -445,10 +446,13 @@ drisw_create_context_attribs(struct glx_screen *base, /* Remap the GLX tokens to DRI2 tokens. */ if (!dri2_convert_glx_attribs(num_attribs, attribs, - &major_ver, &minor_ver, &flags, &api, + &major_ver, &minor_ver, &flags, &api, &reset, error)) return NULL; + if (reset != __DRI_CTX_RESET_NO_NOTIFICATION) + return NULL; + if (shareList) { pcp_shared = (struct drisw_context *) shareList; shared = pcp_shared->driContext; diff --git a/src/glx/glxextensions.c b/src/glx/glxextensions.c index 86dc7d03d13..9ddc39d98ca 100644 --- a/src/glx/glxextensions.c +++ b/src/glx/glxextensions.c @@ -74,9 +74,11 @@ static const struct extension_info known_glx_extensions[] = { #ifdef HAVE_XCB_GLX_CREATE_CONTEXT { GLX(ARB_create_context), VER(0,0), Y, N, N, N }, { GLX(ARB_create_context_profile), VER(0,0), Y, N, N, N }, + { GLX(ARB_create_context_robustness), VER(0,0), Y, N, N, N }, #else { GLX(ARB_create_context), VER(0,0), N, N, N, N }, { GLX(ARB_create_context_profile), VER(0,0), N, N, N, N }, + { GLX(ARB_create_context_robustness), VER(0,0), N, N, N, N }, #endif { GLX(ARB_get_proc_address), VER(1,4), Y, N, Y, N }, { GLX(ARB_multisample), VER(1,4), Y, Y, N, N }, diff --git a/src/glx/glxextensions.h b/src/glx/glxextensions.h index cad69a82fbf..90c27a7db41 100644 --- a/src/glx/glxextensions.h +++ b/src/glx/glxextensions.h @@ -35,6 +35,7 @@ enum { ARB_create_context_bit = 0, ARB_create_context_profile_bit, + ARB_create_context_robustness_bit, ARB_get_proc_address_bit, ARB_multisample_bit, ATI_pixel_format_float_bit,