summaryrefslogtreecommitdiff
path: root/glx
diff options
context:
space:
mode:
authorIan Romanick <ian.d.romanick@intel.com>2012-07-04 15:21:03 -0700
committerKeith Packard <keithp@keithp.com>2012-07-05 11:44:13 -0700
commitcef0b808d3152a20cd98d32457dde08bd5434e7c (patch)
tree8f7ad8afe39651e9b80e360dfc55f89531c462f6 /glx
parent09a8a169d5929665778ae33e58e345fe1192b64c (diff)
glx: Implement GLX_ARB_create_context_profile
Most of the infrastructure was already in place. This just adds: * Validate values specified with the GLX_CONTEXT_PROFILE_MASK_ARB attribute. * Select a DRI2 "api" based on the setting of GLX_CONTEXT_PROFILE_MASK_ARB. * Enable GLX_ARB_create_context_profile extension. This change assumes that any DRI2 driver can handle (possibly by saying "no") seeing an API setting other than __DRI_API_OPENGL. This allows enabling this extension any time GLX_ARB_create_context is enabled. Also, the validation code in __glXDisp_CreateContextAttribsARB is structured in a very verbose manner (using a switch-statement) to ease the addition of GLX_EXT_create_context_es2_profile. Signed-off-by: Ian Romanick <ian.d.romanick@intel.com> Reviewed-by: Dave Airlie <airlied@redhat.com> Signed-off-by: Keith Packard <keithp@keithp.com>
Diffstat (limited to 'glx')
-rw-r--r--glx/createcontext.c31
-rw-r--r--glx/glxdri2.c33
2 files changed, 61 insertions, 3 deletions
diff --git a/glx/createcontext.c b/glx/createcontext.c
index 025c423fe..6f580f02b 100644
--- a/glx/createcontext.c
+++ b/glx/createcontext.c
@@ -90,6 +90,17 @@ __glXDisp_CreateContextAttribsARB(__GLXclientState * cl, GLbyte * pc)
__GLXconfig *config;
int err;
+ /* The GLX_ARB_create_context_profile spec says:
+ *
+ * "The default value for GLX_CONTEXT_PROFILE_MASK_ARB is
+ * GLX_CONTEXT_CORE_PROFILE_BIT_ARB."
+ *
+ * The core profile only makes sense for OpenGL versions 3.2 and later.
+ * If the version ultimately specified is less than 3.2, the core profile
+ * bit is cleared (see below).
+ */
+ int profile = GLX_CONTEXT_CORE_PROFILE_BIT_ARB;
+
/* Verify that the size of the packet matches the size inferred from the
* sizes specified for the various fields.
*/
@@ -161,6 +172,10 @@ __glXDisp_CreateContextAttribsARB(__GLXclientState * cl, GLbyte * pc)
render_type = attribs[2 * i + 1];
break;
+ case GLX_CONTEXT_PROFILE_MASK_ARB:
+ profile = attribs[2 * i + 1];
+ break;
+
default:
return BadValue;
}
@@ -202,6 +217,22 @@ __glXDisp_CreateContextAttribsARB(__GLXclientState * cl, GLbyte * pc)
if ((flags & ~ALL_VALID_FLAGS) != 0)
return BadValue;
+ /* The GLX_ARB_create_context_profile spec says:
+ *
+ * "* If attribute GLX_CONTEXT_PROFILE_MASK_ARB has no bits set; has
+ * any bits set other than GLX_CONTEXT_CORE_PROFILE_BIT_ARB and
+ * GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB; has more than one of
+ * these bits set; or if the implementation does not support the
+ * requested profile, then GLXBadProfileARB is generated."
+ */
+ switch (profile) {
+ case GLX_CONTEXT_CORE_PROFILE_BIT_ARB:
+ case GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB:
+ break;
+ default:
+ return __glXError(GLXBadProfileARB);
+ }
+
/* Allocate memory for the new context
*/
if (req->isDirect) {
diff --git a/glx/glxdri2.c b/glx/glxdri2.c
index 7b76c3a5f..7ec43375f 100644
--- a/glx/glxdri2.c
+++ b/glx/glxdri2.c
@@ -381,7 +381,7 @@ __glXDRIscreenDestroy(__GLXscreen * baseScreen)
static Bool
dri2_convert_glx_attribs(unsigned num_attribs, const uint32_t *attribs,
unsigned *major_ver, unsigned *minor_ver,
- uint32_t *flags, unsigned *error)
+ uint32_t *flags, int *api, unsigned *error)
{
unsigned i;
@@ -409,6 +409,19 @@ dri2_convert_glx_attribs(unsigned num_attribs, const uint32_t *attribs,
break;
case GLX_RENDER_TYPE:
break;
+ case GLX_CONTEXT_PROFILE_MASK_ARB:
+ switch (attribs[i * 2 + 1]) {
+ case GLX_CONTEXT_CORE_PROFILE_BIT_ARB:
+ *api = __DRI_API_OPENGL_CORE;
+ break;
+ case GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB:
+ *api = __DRI_API_OPENGL;
+ break;
+ default:
+ *error = __glXError(GLXBadProfileARB);
+ return False;
+ }
+ break;
default:
/* If an unknown attribute is received, fail.
*/
@@ -424,6 +437,16 @@ dri2_convert_glx_attribs(unsigned num_attribs, const uint32_t *attribs,
return False;
}
+ /* If the core profile is requested for a GL version is less than 3.2,
+ * request the non-core profile from the DRI driver. The core profile
+ * only makes sense for GL versions >= 3.2, and many DRI drivers that
+ * don't support OpenGL 3.2 may fail the request for a core profile.
+ */
+ if (*api == __DRI_API_OPENGL_CORE
+ && (*major_ver < 3 || (*major_ver < 3 && *minor_ver < 2))) {
+ *api == __DRI_API_OPENGL;
+ }
+
*error = Success;
return True;
}
@@ -447,11 +470,12 @@ create_driver_context(__GLXDRIcontext * context,
unsigned major_ver;
unsigned minor_ver;
uint32_t flags;
+ int api;
if (num_attribs != 0) {
if (!dri2_convert_glx_attribs(num_attribs, attribs,
&major_ver, &minor_ver,
- &flags, (unsigned *) error))
+ &flags, &api, (unsigned *) error))
return NULL;
ctx_attribs[num_ctx_attribs++] = __DRI_CTX_ATTRIB_MAJOR_VERSION;
@@ -471,7 +495,7 @@ create_driver_context(__GLXDRIcontext * context,
context->driContext =
(*screen->dri2->createContextAttribs)(screen->driScreen,
- __DRI_API_OPENGL,
+ api,
config->driConfig,
driShare,
num_ctx_attribs / 2,
@@ -786,7 +810,10 @@ initializeExtensions(__GLXDRIscreen * screen)
if (screen->dri2->base.version >= 3) {
__glXEnableExtension(screen->glx_enable_bits,
"GLX_ARB_create_context");
+ __glXEnableExtension(screen->glx_enable_bits,
+ "GLX_ARB_create_context_profile");
LogMessage(X_INFO, "AIGLX: enabled GLX_ARB_create_context\n");
+ LogMessage(X_INFO, "AIGLX: enabled GLX_ARB_create_context_profile\n");
}
#endif