[PATCH] glx: add GLX_ARB_create_context_no_error support
Grigori Goronzy
greg at chown.ath.cx
Thu Aug 3 18:07:20 UTC 2017
Add the necessary bits to parse the attribute, convert the value
to DRI context flags where needed and enforce the rules outlined in
the specification.
---
glx/createcontext.c | 47 +++++++++++++++++++++++++++++++++++++++++++++++
glx/extension_string.c | 1 +
glx/extension_string.h | 1 +
glx/glxcontext.h | 5 +++++
glx/glxdri2.c | 29 +++++++++++++++++++++++++++++
glx/glxext.h | 3 +++
6 files changed, 86 insertions(+)
diff --git a/glx/createcontext.c b/glx/createcontext.c
index 068b35f..91f449e 100644
--- a/glx/createcontext.c
+++ b/glx/createcontext.c
@@ -90,6 +90,9 @@ __glXDisp_CreateContextAttribsARB(__GLXclientState * cl, GLbyte * pc)
#ifdef GLX_CONTEXT_RELEASE_BEHAVIOR_ARB
uint32_t flush = GLX_CONTEXT_RELEASE_BEHAVIOR_FLUSH_ARB;
#endif
+#ifdef __DRI2_NO_ERROR
+ uint32_t no_error = 0;
+#endif
__GLXcontext *ctx = NULL;
__GLXcontext *shareCtx = NULL;
__GLXscreen *glxScreen;
@@ -165,6 +168,20 @@ __glXDisp_CreateContextAttribsARB(__GLXclientState * cl, GLbyte * pc)
client->errorValue = shareCtx->pGlxScreen->pScreen->myNum;
return BadMatch;
}
+
+ /* The GLX_ARB_create_context_no_error spec says:
+ *
+ * "BadMatch is generated if the value of
+ * GLX_CONTEXT_OPENGL_NO_ERROR_ARB used to create <share_context>
+ * does not match the value of GLX_CONTEXT_OPENGL_NO_ERROR_ARB
+ * for the context being created."
+ */
+#ifdef __DRI2_NO_ERROR
+ if (!!shareCtx->noError != !!no_error) {
+ client->errorValue = req->shareList;
+ return BadMatch;
+ }
+#endif
}
for (i = 0; i < req->numAttribs; i++) {
@@ -206,6 +223,12 @@ __glXDisp_CreateContextAttribsARB(__GLXclientState * cl, GLbyte * pc)
break;
#endif
+#ifdef __DRI2_NO_ERROR
+ case GLX_CONTEXT_OPENGL_NO_ERROR_ARB:
+ no_error = attribs[2 * i + 1];
+ break;
+#endif
+
default:
if (!req->isDirect)
return BadValue;
@@ -213,6 +236,27 @@ __glXDisp_CreateContextAttribsARB(__GLXclientState * cl, GLbyte * pc)
}
}
+ /* The GLX_ARB_create_context_no_error spec says:
+ *
+ * "BadMatch is generated if the GLX_CONTEXT_OPENGL_NO_ERROR_ARB is
+ * TRUE at the same time as a debug or robustness context is
+ * specified."
+ */
+#ifdef __DRI2_NO_ERROR
+ if (no_error && ((flags & GLX_CONTEXT_DEBUG_BIT_ARB) ||
+ (flags & GLX_CONTEXT_ROBUST_ACCESS_BIT_ARB)))
+ return BadMatch;
+#endif
+
+ /* The KHR_no_error spec says:
+ *
+ * "Requires OpenGL ES 2.0 or OpenGL 2.0."
+ */
+#ifdef __DRI2_NO_ERROR
+ if (no_error && major_version < 2)
+ return BadMatch;
+#endif
+
/* The GLX_ARB_create_context spec says:
*
* "If attributes GLX_CONTEXT_MAJOR_VERSION_ARB and
@@ -318,6 +362,9 @@ __glXDisp_CreateContextAttribsARB(__GLXclientState * cl, GLbyte * pc)
ctx->share_id = req->shareList;
ctx->idExists = True;
ctx->isDirect = req->isDirect;
+#ifdef __DRI2_NO_ERROR
+ ctx->noError = no_error;
+#endif
ctx->renderMode = GL_RENDER;
ctx->resetNotificationStrategy = reset;
#ifdef GLX_CONTEXT_RELEASE_BEHAVIOR_ARB
diff --git a/glx/extension_string.c b/glx/extension_string.c
index d1da481..bd662e6 100644
--- a/glx/extension_string.c
+++ b/glx/extension_string.c
@@ -74,6 +74,7 @@ static const struct extension_info known_glx_extensions[] = {
/* *INDENT-OFF* */
{ GLX(ARB_context_flush_control), VER(0,0), N, },
{ GLX(ARB_create_context), VER(0,0), N, },
+ { GLX(ARB_create_context_no_error), VER(1,4), N, },
{ GLX(ARB_create_context_profile), VER(0,0), N, },
{ GLX(ARB_create_context_robustness), VER(0,0), N, },
{ GLX(ARB_fbconfig_float), VER(0,0), N, },
diff --git a/glx/extension_string.h b/glx/extension_string.h
index a10d710..5d9c52a 100644
--- a/glx/extension_string.h
+++ b/glx/extension_string.h
@@ -38,6 +38,7 @@ enum {
/* GLX_ARB_get_proc_address is implemented on the client. */
ARB_context_flush_control_bit = 0,
ARB_create_context_bit,
+ ARB_create_context_no_error_bit,
ARB_create_context_profile_bit,
ARB_create_context_robustness_bit,
ARB_fbconfig_float_bit,
diff --git a/glx/glxcontext.h b/glx/glxcontext.h
index 19d347f..165a3cb 100644
--- a/glx/glxcontext.h
+++ b/glx/glxcontext.h
@@ -90,6 +90,11 @@ struct __GLXcontext {
GLboolean isDirect;
/*
+ ** Whether this context uses no-error mode.
+ */
+ GLboolean noError;
+
+ /*
** Current rendering mode for this context.
*/
GLenum renderMode;
diff --git a/glx/glxdri2.c b/glx/glxdri2.c
index 7019442..ec46190 100644
--- a/glx/glxdri2.c
+++ b/glx/glxdri2.c
@@ -45,6 +45,7 @@
#include "glxserver.h"
#include "glxutil.h"
#include "glxdricommon.h"
+#include "glxext.h"
#include <GL/glxtokens.h>
#include "extension_string.h"
@@ -53,9 +54,16 @@ typedef struct __GLXDRIscreen __GLXDRIscreen;
typedef struct __GLXDRIcontext __GLXDRIcontext;
typedef struct __GLXDRIdrawable __GLXDRIdrawable;
+#ifdef __DRI2_NO_ERROR
+#define ALL_DRI_CTX_FLAGS (__DRI_CTX_FLAG_DEBUG \
+ | __DRI_CTX_FLAG_FORWARD_COMPATIBLE \
+ | __DRI_CTX_FLAG_ROBUST_BUFFER_ACCESS \
+ | __DRI_CTX_FLAG_NO_ERROR)
+#else
#define ALL_DRI_CTX_FLAGS (__DRI_CTX_FLAG_DEBUG \
| __DRI_CTX_FLAG_FORWARD_COMPATIBLE \
| __DRI_CTX_FLAG_ROBUST_BUFFER_ACCESS)
+#endif
struct __GLXDRIscreen {
__GLXscreen base;
@@ -342,6 +350,9 @@ dri2_convert_glx_attribs(__GLXDRIscreen *screen, unsigned num_attribs,
uint32_t *flags, int *api, int *reset, unsigned *error)
{
unsigned i;
+#ifdef __DRI2_NO_ERROR
+ int no_error = 0;
+#endif
if (num_attribs == 0)
return True;
@@ -402,6 +413,11 @@ dri2_convert_glx_attribs(__GLXDRIscreen *screen, unsigned num_attribs,
return False;
}
break;
+#ifdef __DRI2_NO_ERROR
+ case GLX_CONTEXT_OPENGL_NO_ERROR_ARB:
+ no_error = attribs[i * 2 + 1];
+ break;
+#endif
default:
/* If an unknown attribute is received, fail.
*/
@@ -410,6 +426,10 @@ dri2_convert_glx_attribs(__GLXDRIscreen *screen, unsigned num_attribs,
}
}
+ if (no_error) {
+ *flags |= __DRI_CTX_FLAG_NO_ERROR;
+ }
+
/* Unknown flag value.
*/
if ((*flags & ~ALL_DRI_CTX_FLAGS) != 0) {
@@ -894,6 +914,15 @@ initializeExtensions(__GLXscreen * screen)
"AIGLX: enabled GLX_ARB_create_context_robustness\n");
}
+#ifdef __DRI2_NO_ERROR
+ if (strcmp(extensions[i]->name, __DRI2_NO_ERROR) == 0) {
+ __glXEnableExtension(screen->glx_enable_bits,
+ "GLX_ARB_create_context_no_error");
+ LogMessage(X_INFO,
+ "AIGLX: enabled GLX_ARB_create_context_no_error\n");
+ }
+#endif
+
#ifdef __DRI2_FLUSH_CONTROL
if (strcmp(extensions[i]->name, __DRI2_FLUSH_CONTROL) == 0) {
__glXEnableExtension(screen->glx_enable_bits,
diff --git a/glx/glxext.h b/glx/glxext.h
index cde0e15..3beeddf 100644
--- a/glx/glxext.h
+++ b/glx/glxext.h
@@ -50,6 +50,9 @@
#ifndef GLX_RGBA_UNSIGNED_FLOAT_TYPE_EXT
#define GLX_RGBA_UNSIGNED_FLOAT_TYPE_EXT 0x20B1
#endif
+#ifndef GLX_CONTEXT_OPENGL_NO_ERROR_ARB
+#define GLX_CONTEXT_OPENGL_NO_ERROR_ARB 0x31B3
+#endif
extern void __glXFlushContextCache(void);
--
2.7.4
More information about the xorg-devel
mailing list