summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdam Jackson <ajax@redhat.com>2015-05-19 11:31:25 -0400
committerAdam Jackson <ajax@redhat.com>2015-07-08 16:41:28 -0400
commit995ff11422eb49160abfe276f471e412b16cab9d (patch)
treeda46f01450af909955e88706032566620075eb31
parent2d7194334a9f84e417ec90e220b2fe476f704612 (diff)
glx: Implement GLX_ARB_context_flush_control
This extension allows clients to opt out of the implicit glFlush on context release, which is quite nice for performance for clients using multiple contexts. The server doesn't really need to be aware of the client's decision, at least for direct contexts, but it does need to not reject the context attribute out of hand. This patch won't do anything unless built against a Mesa that defines the __DRI2_FLUSH_CONTROL extension (and a new enough glxext.h, but that's been there since 10.3 at least). Reviewed-by: James Jones <jajones@nvidia.com> Signed-off-by: Adam Jackson <ajax@redhat.com>
-rw-r--r--glx/createcontext.c15
-rw-r--r--glx/extension_string.c1
-rw-r--r--glx/extension_string.h3
-rw-r--r--glx/glxcmds.c20
-rw-r--r--glx/glxcontext.h5
-rw-r--r--glx/glxdri2.c7
-rw-r--r--glx/glxdriswrast.c8
7 files changed, 57 insertions, 2 deletions
diff --git a/glx/createcontext.c b/glx/createcontext.c
index cbeddec26..d06bc1f7f 100644
--- a/glx/createcontext.c
+++ b/glx/createcontext.c
@@ -87,6 +87,9 @@ __glXDisp_CreateContextAttribsARB(__GLXclientState * cl, GLbyte * pc)
int minor_version = 0;
uint32_t flags = 0;
uint32_t render_type = GLX_RGBA_TYPE;
+#ifdef GLX_CONTEXT_RELEASE_BEHAVIOR_ARB
+ uint32_t flush = GLX_CONTEXT_RELEASE_BEHAVIOR_FLUSH_ARB;
+#endif
__GLXcontext *ctx = NULL;
__GLXcontext *shareCtx = NULL;
__GLXscreen *glxScreen;
@@ -194,6 +197,15 @@ __glXDisp_CreateContextAttribsARB(__GLXclientState * cl, GLbyte * pc)
break;
+#ifdef GLX_CONTEXT_RELEASE_BEHAVIOR_ARB
+ case GLX_CONTEXT_RELEASE_BEHAVIOR_ARB:
+ flush = attribs[2 * i + 1];
+ if (flush != GLX_CONTEXT_RELEASE_BEHAVIOR_NONE_ARB
+ && flush != GLX_CONTEXT_RELEASE_BEHAVIOR_FLUSH_ARB)
+ return BadValue;
+ break;
+#endif
+
default:
return BadValue;
}
@@ -333,6 +345,9 @@ __glXDisp_CreateContextAttribsARB(__GLXclientState * cl, GLbyte * pc)
ctx->drawPriv = NULL;
ctx->readPriv = NULL;
ctx->resetNotificationStrategy = reset;
+#ifdef GLX_CONTEXT_RELEASE_BEHAVIOR_ARB
+ ctx->releaseBehavior = flush;
+#endif
/* Add the new context to the various global tables of GLX contexts.
*/
diff --git a/glx/extension_string.c b/glx/extension_string.c
index 4bef96f0b..e881d2109 100644
--- a/glx/extension_string.c
+++ b/glx/extension_string.c
@@ -72,6 +72,7 @@ struct extension_info {
static const struct extension_info known_glx_extensions[] = {
/* GLX_ARB_get_proc_address is implemented on the client. */
/* *INDENT-OFF* */
+ { GLX(ARB_context_flush_control), VER(0,0), N, },
{ GLX(ARB_create_context), VER(0,0), N, },
{ GLX(ARB_create_context_profile), VER(0,0), N, },
{ GLX(ARB_create_context_robustness), VER(0,0), N, },
diff --git a/glx/extension_string.h b/glx/extension_string.h
index e7d393297..bac7b0624 100644
--- a/glx/extension_string.h
+++ b/glx/extension_string.h
@@ -36,7 +36,8 @@
enum {
/* GLX_ARB_get_proc_address is implemented on the client. */
- ARB_create_context_bit = 0,
+ ARB_context_flush_control_bit = 0,
+ ARB_create_context_bit,
ARB_create_context_profile_bit,
ARB_create_context_robustness_bit,
ARB_fbconfig_float_bit,
diff --git a/glx/glxcmds.c b/glx/glxcmds.c
index f5f2babb8..cbd4ede39 100644
--- a/glx/glxcmds.c
+++ b/glx/glxcmds.c
@@ -334,6 +334,19 @@ DoCreateContext(__GLXclientState * cl, GLXContextID gcId,
*/
glxc->resetNotificationStrategy = GLX_NO_RESET_NOTIFICATION_ARB;
+#ifdef GLX_CONTEXT_RELEASE_BEHAVIOR_ARB
+ /* The GLX_ARB_context_flush_control spec says:
+ *
+ * "The default value [for GLX_CONTEXT_RELEASE_BEHAVIOR] is
+ * CONTEXT_RELEASE_BEHAVIOR_FLUSH, and may in some cases be changed
+ * using platform-specific context creation extensions."
+ *
+ * Without using glXCreateContextAttribsARB, there is no way to specify a
+ * non-default release behavior.
+ */
+ glxc->releaseBehavior = GLX_CONTEXT_RELEASE_BEHAVIOR_FLUSH_ARB;
+#endif
+
/* Add the new context to the various global tables of GLX contexts.
*/
if (!__glXAddContext(glxc)) {
@@ -626,7 +639,12 @@ DoMakeCurrent(__GLXclientState * cl,
/*
** Flush the previous context if needed.
*/
- if (prevglxc->hasUnflushedCommands) {
+ Bool need_flush = GL_TRUE;
+#ifdef GLX_CONTEXT_RELEASE_BEHAVIOR_ARB
+ if (prevglxc->releaseBehavior == GLX_CONTEXT_RELEASE_BEHAVIOR_NONE_ARB)
+ need_flush = GL_FALSE;
+#endif
+ if (prevglxc->hasUnflushedCommands && need_flush) {
if (__glXForceCurrent(cl, tag, (int *) &error)) {
glFlush();
prevglxc->hasUnflushedCommands = GL_FALSE;
diff --git a/glx/glxcontext.h b/glx/glxcontext.h
index 677898a67..0733281d7 100644
--- a/glx/glxcontext.h
+++ b/glx/glxcontext.h
@@ -108,6 +108,11 @@ struct __GLXcontext {
*/
GLenum resetNotificationStrategy;
+ /**
+ * Context release behavior
+ */
+ GLenum releaseBehavior;
+
/*
** Buffers for feedback and selection.
*/
diff --git a/glx/glxdri2.c b/glx/glxdri2.c
index bcd57a4a3..6fb3d9278 100644
--- a/glx/glxdri2.c
+++ b/glx/glxdri2.c
@@ -921,6 +921,13 @@ initializeExtensions(__GLXDRIscreen * screen)
"AIGLX: enabled GLX_ARB_create_context_robustness\n");
}
+#ifdef __DRI2_FLUSH_CONTROL
+ if (strcmp(extensions[i]->name, __DRI2_FLUSH_CONTROL) == 0) {
+ __glXEnableExtension(screen->glx_enable_bits,
+ "GLX_ARB_context_flush_control\n");
+ }
+#endif
+
/* Ignore unknown extensions */
}
}
diff --git a/glx/glxdriswrast.c b/glx/glxdriswrast.c
index e25ca4768..9add2a13f 100644
--- a/glx/glxdriswrast.c
+++ b/glx/glxdriswrast.c
@@ -424,6 +424,14 @@ initializeExtensions(__GLXDRIscreen * screen)
screen->texBuffer = (const __DRItexBufferExtension *) extensions[i];
/* GLX_EXT_texture_from_pixmap is always enabled. */
}
+
+#ifdef __DRI2_FLUSH_CONTROL
+ if (strcmp(extensions[i]->name, __DRI2_FLUSH_CONTROL) == 0) {
+ __glXEnableExtension(screen->glx_enable_bits,
+ "GLX_ARB_context_flush_control\n");
+ }
+#endif
+
}
}