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>
This commit is contained in:
Ian Romanick 2012-07-04 15:21:03 -07:00 committed by Keith Packard
parent 09a8a169d5
commit cef0b808d3
2 changed files with 61 additions and 3 deletions

View File

@ -90,6 +90,17 @@ __glXDisp_CreateContextAttribsARB(__GLXclientState * cl, GLbyte * pc)
__GLXconfig *config; __GLXconfig *config;
int err; 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 /* Verify that the size of the packet matches the size inferred from the
* sizes specified for the various fields. * sizes specified for the various fields.
*/ */
@ -161,6 +172,10 @@ __glXDisp_CreateContextAttribsARB(__GLXclientState * cl, GLbyte * pc)
render_type = attribs[2 * i + 1]; render_type = attribs[2 * i + 1];
break; break;
case GLX_CONTEXT_PROFILE_MASK_ARB:
profile = attribs[2 * i + 1];
break;
default: default:
return BadValue; return BadValue;
} }
@ -202,6 +217,22 @@ __glXDisp_CreateContextAttribsARB(__GLXclientState * cl, GLbyte * pc)
if ((flags & ~ALL_VALID_FLAGS) != 0) if ((flags & ~ALL_VALID_FLAGS) != 0)
return BadValue; 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 /* Allocate memory for the new context
*/ */
if (req->isDirect) { if (req->isDirect) {

View File

@ -381,7 +381,7 @@ __glXDRIscreenDestroy(__GLXscreen * baseScreen)
static Bool static Bool
dri2_convert_glx_attribs(unsigned num_attribs, const uint32_t *attribs, dri2_convert_glx_attribs(unsigned num_attribs, const uint32_t *attribs,
unsigned *major_ver, unsigned *minor_ver, unsigned *major_ver, unsigned *minor_ver,
uint32_t *flags, unsigned *error) uint32_t *flags, int *api, unsigned *error)
{ {
unsigned i; unsigned i;
@ -409,6 +409,19 @@ dri2_convert_glx_attribs(unsigned num_attribs, const uint32_t *attribs,
break; break;
case GLX_RENDER_TYPE: case GLX_RENDER_TYPE:
break; 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: default:
/* If an unknown attribute is received, fail. /* If an unknown attribute is received, fail.
*/ */
@ -424,6 +437,16 @@ dri2_convert_glx_attribs(unsigned num_attribs, const uint32_t *attribs,
return False; 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; *error = Success;
return True; return True;
} }
@ -447,11 +470,12 @@ create_driver_context(__GLXDRIcontext * context,
unsigned major_ver; unsigned major_ver;
unsigned minor_ver; unsigned minor_ver;
uint32_t flags; uint32_t flags;
int api;
if (num_attribs != 0) { if (num_attribs != 0) {
if (!dri2_convert_glx_attribs(num_attribs, attribs, if (!dri2_convert_glx_attribs(num_attribs, attribs,
&major_ver, &minor_ver, &major_ver, &minor_ver,
&flags, (unsigned *) error)) &flags, &api, (unsigned *) error))
return NULL; return NULL;
ctx_attribs[num_ctx_attribs++] = __DRI_CTX_ATTRIB_MAJOR_VERSION; ctx_attribs[num_ctx_attribs++] = __DRI_CTX_ATTRIB_MAJOR_VERSION;
@ -471,7 +495,7 @@ create_driver_context(__GLXDRIcontext * context,
context->driContext = context->driContext =
(*screen->dri2->createContextAttribs)(screen->driScreen, (*screen->dri2->createContextAttribs)(screen->driScreen,
__DRI_API_OPENGL, api,
config->driConfig, config->driConfig,
driShare, driShare,
num_ctx_attribs / 2, num_ctx_attribs / 2,
@ -786,7 +810,10 @@ initializeExtensions(__GLXDRIscreen * screen)
if (screen->dri2->base.version >= 3) { if (screen->dri2->base.version >= 3) {
__glXEnableExtension(screen->glx_enable_bits, __glXEnableExtension(screen->glx_enable_bits,
"GLX_ARB_create_context"); "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\n");
LogMessage(X_INFO, "AIGLX: enabled GLX_ARB_create_context_profile\n");
} }
#endif #endif