+/*
+ * (C) Copyright IBM Corporation 2002, 2004
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * on the rights to use, copy, modify, merge, publish, distribute, sub
+ * license, and/or sell copies of the Software, and to permit persons to whom
+ * the Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
/**
* \file dri_util.c
* DRI utility functions.
/*@{*/
static __DRIcontext *
-dri2CreateNewContextForAPI(__DRIscreen *screen, int api,
- const __DRIconfig *config,
- __DRIcontext *shared, void *data)
+dri2CreateContextAttribs(__DRIscreen *screen, int api,
+ const __DRIconfig *config,
+ __DRIcontext *shared,
+ unsigned num_attribs,
+ const uint32_t *attribs,
+ unsigned *error,
+ void *data)
{
__DRIcontext *context;
const struct gl_config *modes = (config != NULL) ? &config->modes : NULL;
void *shareCtx = (shared != NULL) ? shared->driverPrivate : NULL;
gl_api mesa_api;
+ unsigned major_version = 1;
+ unsigned minor_version = 0;
+ uint32_t flags = 0;
+
+ assert((num_attribs == 0) || (attribs != NULL));
- if (!(screen->api_mask & (1 << api)))
+ if (!(screen->api_mask & (1 << api))) {
+ *error = __DRI_CTX_ERROR_BAD_API;
return NULL;
+ }
switch (api) {
case __DRI_API_OPENGL:
- mesa_api = API_OPENGL;
- break;
+ mesa_api = API_OPENGL_COMPAT;
+ break;
case __DRI_API_GLES:
- mesa_api = API_OPENGLES;
- break;
+ mesa_api = API_OPENGLES;
+ break;
case __DRI_API_GLES2:
- mesa_api = API_OPENGLES2;
- break;
+ case __DRI_API_GLES3:
+ mesa_api = API_OPENGLES2;
+ break;
+ case __DRI_API_OPENGL_CORE:
+ mesa_api = API_OPENGL_CORE;
+ break;
default:
+ *error = __DRI_CTX_ERROR_BAD_API;
+ return NULL;
+ }
+
+ for (unsigned i = 0; i < num_attribs; i++) {
+ switch (attribs[i * 2]) {
+ case __DRI_CTX_ATTRIB_MAJOR_VERSION:
+ major_version = attribs[i * 2 + 1];
+ break;
+ case __DRI_CTX_ATTRIB_MINOR_VERSION:
+ minor_version = attribs[i * 2 + 1];
+ break;
+ case __DRI_CTX_ATTRIB_FLAGS:
+ flags = attribs[i * 2 + 1];
+ break;
+ default:
+ /* We can't create a context that satisfies the requirements of an
+ * attribute that we don't understand. Return failure.
+ */
+ assert(!"Should not get here.");
+ *error = __DRI_CTX_ERROR_UNKNOWN_ATTRIBUTE;
return NULL;
+ }
}
- context = malloc(sizeof *context);
- if (!context)
+ /* Mesa does not support the GL_ARB_compatibilty extension or the
+ * compatibility profile. This means that we treat a API_OPENGL_COMPAT 3.1 as
+ * API_OPENGL_CORE and reject API_OPENGL_COMPAT 3.2+.
+ */
+ if (mesa_api == API_OPENGL_COMPAT && major_version == 3 && minor_version == 1)
+ mesa_api = API_OPENGL_CORE;
+
+ if (mesa_api == API_OPENGL_COMPAT
+ && ((major_version > 3)
+ || (major_version == 3 && minor_version >= 2))) {
+ *error = __DRI_CTX_ERROR_BAD_API;
+ return NULL;
+ }
+
+ /* The EGL_KHR_create_context spec says:
+ *
+ * "Flags are only defined for OpenGL context creation, and specifying
+ * a flags value other than zero for other types of contexts,
+ * including OpenGL ES contexts, will generate an error."
+ *
+ * The GLX_EXT_create_context_es2_profile specification doesn't say
+ * anything specific about this case. However, none of the known flags
+ * have any meaning in an ES context, so this seems safe.
+ */
+ if (mesa_api != API_OPENGL_COMPAT
+ && mesa_api != API_OPENGL_CORE
+ && flags != 0) {
+ *error = __DRI_CTX_ERROR_BAD_FLAG;
+ return NULL;
+ }
+
+ /* There are no forward-compatible contexts before OpenGL 3.0. The
+ * GLX_ARB_create_context spec says:
+ *
+ * "Forward-compatible contexts are defined only for OpenGL versions
+ * 3.0 and later."
+ *
+ * Forward-looking contexts are supported by silently converting the
+ * requested API to API_OPENGL_CORE.
+ *
+ * In Mesa, a debug context is the same as a regular context.
+ */
+ if ((flags & __DRI_CTX_FLAG_FORWARD_COMPATIBLE) != 0) {
+ mesa_api = API_OPENGL_CORE;
+ }
+
+ if ((flags & ~(__DRI_CTX_FLAG_DEBUG | __DRI_CTX_FLAG_FORWARD_COMPATIBLE))
+ != 0) {
+ *error = __DRI_CTX_ERROR_UNKNOWN_FLAG;
+ return NULL;
+ }
+
+ context = calloc(1, sizeof *context);
+ if (!context) {
+ *error = __DRI_CTX_ERROR_NO_MEMORY;
return NULL;
+ }
context->loaderPrivate = data;
context->driDrawablePriv = NULL;
context->driReadablePriv = NULL;
- if (!driDriverAPI.CreateContext(mesa_api, modes, context, shareCtx) ) {
+ if (!driDriverAPI.CreateContext(mesa_api, modes, context,
+ major_version, minor_version,
+ flags, error, shareCtx) ) {
free(context);
return NULL;
}
+ *error = __DRI_CTX_ERROR_SUCCESS;
return context;
}
+static __DRIcontext *
+dri2CreateNewContextForAPI(__DRIscreen *screen, int api,
+ const __DRIconfig *config,
+ __DRIcontext *shared, void *data)
+{
+ unsigned error;
+
+ return dri2CreateContextAttribs(screen, api, config, shared, 0, NULL,
+ &error, data);
+}
static __DRIcontext *
dri2CreateNewContext(__DRIscreen *screen, const __DRIconfig *config,
/** Core interface */
const __DRIcoreExtension driCoreExtension = {
- { __DRI_CORE, __DRI_CORE_VERSION },
- NULL,
- driDestroyScreen,
- driGetExtensions,
- driGetConfigAttrib,
- driIndexConfigAttrib,
- NULL,
- driDestroyDrawable,
- NULL,
- NULL,
- driCopyContext,
- driDestroyContext,
- driBindContext,
- driUnbindContext
+ .base = { __DRI_CORE, __DRI_CORE_VERSION },
+
+ .createNewScreen = NULL,
+ .destroyScreen = driDestroyScreen,
+ .getExtensions = driGetExtensions,
+ .getConfigAttrib = driGetConfigAttrib,
+ .indexConfigAttrib = driIndexConfigAttrib,
+ .createNewDrawable = NULL,
+ .destroyDrawable = driDestroyDrawable,
+ .swapBuffers = NULL,
+ .createNewContext = NULL,
+ .copyContext = driCopyContext,
+ .destroyContext = driDestroyContext,
+ .bindContext = driBindContext,
+ .unbindContext = driUnbindContext
};
/** DRI2 interface */
const __DRIdri2Extension driDRI2Extension = {
- /* Force the version to 2 because the underlying drivers don't (can't!)
- * support the extra requirements of CreateContextAttribs.
- */
- { __DRI_DRI2, 2 },
- dri2CreateNewScreen,
- dri2CreateNewDrawable,
- dri2CreateNewContext,
- dri2GetAPIMask,
- dri2CreateNewContextForAPI,
- dri2AllocateBuffer,
- dri2ReleaseBuffer,
- NULL
+ .base = { __DRI_DRI2, 3 },
+
+ .createNewScreen = dri2CreateNewScreen,
+ .createNewDrawable = dri2CreateNewDrawable,
+ .createNewContext = dri2CreateNewContext,
+ .getAPIMask = dri2GetAPIMask,
+ .createNewContextForAPI = dri2CreateNewContextForAPI,
+ .allocateBuffer = dri2AllocateBuffer,
+ .releaseBuffer = dri2ReleaseBuffer,
+ .createContextAttribs = dri2CreateContextAttribs
};
const __DRI2configQueryExtension dri2ConfigQueryExtension = {
- { __DRI2_CONFIG_QUERY, __DRI2_CONFIG_QUERY_VERSION },
- dri2ConfigQueryb,
- dri2ConfigQueryi,
- dri2ConfigQueryf,
+ .base = { __DRI2_CONFIG_QUERY, __DRI2_CONFIG_QUERY_VERSION },
+
+ .configQueryb = dri2ConfigQueryb,
+ .configQueryi = dri2ConfigQueryi,
+ .configQueryf = dri2ConfigQueryf,
};
void