drirc: set always_have_depth_buffer for Topogon
[mesa.git] / src / mesa / drivers / dri / common / dri_util.c
index a153d525d9c4ea4bbfd3da34e88c84ab0d4aaa6f..9ed9df4b39b8130c3c2e9106953aa3049f8a702d 100644 (file)
@@ -1,3 +1,27 @@
+/*
+ * (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.
@@ -134,35 +158,126 @@ static const __DRIextension **driGetExtensions(__DRIscreen *psp)
 /*@{*/
 
 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;
 
@@ -170,14 +285,27 @@ dri2CreateNewContextForAPI(__DRIscreen *screen, int api,
     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,
@@ -436,43 +564,43 @@ dri2GetAPIMask(__DRIscreen *screen)
 
 /** 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