dri2: Add plumbing to get context version requirements and flags to drivers
[mesa.git] / src / mesa / drivers / dri / common / drisw_util.c
index a19123f706429943e4aefeb97cd64a1002d11346..0ec124ae53762121d13a37510081cff2856fb917 100644 (file)
@@ -94,14 +94,26 @@ static const __DRIextension **driGetExtensions(__DRIscreen *psp)
  */
 
 static __DRIcontext *
-driCreateNewContextForAPI(__DRIscreen *psp, int api,
-                          const __DRIconfig *config,
-                          __DRIcontext *shared, void *data)
+driCreateContextAttribs(__DRIscreen *screen, int api,
+                       const __DRIconfig *config,
+                       __DRIcontext *shared,
+                       unsigned num_attribs,
+                       const uint32_t *attribs,
+                       unsigned *error,
+                       void *data)
 {
     __DRIcontext *pcp;
     const struct gl_config *modes = (config != NULL) ? &config->modes : NULL;
     void * const shareCtx = (shared != NULL) ? shared->driverPrivate : NULL;
     gl_api mesa_api;
+    unsigned major_version = 1;
+    unsigned minor_version = 0;
+    uint32_t flags = 0;
+
+    /* Either num_attribs is zero and attribs is NULL, or num_attribs is not
+     * zero and attribs is not NULL.
+     */
+    assert((num_attribs == 0) == (attribs == NULL));
 
     switch (api) {
     case __DRI_API_OPENGL:
@@ -113,21 +125,59 @@ driCreateNewContextForAPI(__DRIscreen *psp, int api,
     case __DRI_API_GLES2:
             mesa_api = API_OPENGLES2;
             break;
+    case __DRI_API_OPENGL_CORE:
     default:
             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.
+            */
+           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."
+     *
+     * Moreover, Mesa can't fulfill the requirements of a forward-looking
+     * context.  Return failure if a forward-looking context is requested.
+     *
+     * In Mesa, a debug context is the same as a regular context.
+     */
+    if (major_version >= 3) {
+       if ((flags & ~__DRI_CTX_FLAG_DEBUG) != 0)
+           return NULL;
+    }
+
     pcp = CALLOC_STRUCT(__DRIcontextRec);
     if (!pcp)
         return NULL;
 
     pcp->loaderPrivate = data;
 
-    pcp->driScreenPriv = psp;
+    pcp->driScreenPriv = screen;
     pcp->driDrawablePriv = NULL;
     pcp->driReadablePriv = NULL;
 
-    if (!driDriverAPI.CreateContext(mesa_api, modes, pcp, shareCtx)) {
+    if (!driDriverAPI.CreateContext(mesa_api, modes, pcp,
+                                   major_version, minor_version,
+                                   flags, error, shareCtx)) {
         FREE(pcp);
         return NULL;
     }
@@ -135,6 +185,17 @@ driCreateNewContextForAPI(__DRIscreen *psp, int api,
     return pcp;
 }
 
+static __DRIcontext *
+driCreateNewContextForAPI(__DRIscreen *psp, int api,
+                          const __DRIconfig *config,
+                          __DRIcontext *shared, void *data)
+{
+    unsigned error;
+
+    return driCreateContextAttribs(psp, api, config, shared, 0, NULL,
+                                  &error, data);
+}
+
 static __DRIcontext *
 driCreateNewContext(__DRIscreen *psp, const __DRIconfig *config,
                    __DRIcontext *shared, void *data)
@@ -288,12 +349,9 @@ const __DRIcoreExtension driCoreExtension = {
 };
 
 const __DRIswrastExtension driSWRastExtension = {
-    /* Force the version to 2 because the underlying driver don't (can't!)
-     * support the extra requirements of CreateContextAttribs.
-     */
-    { __DRI_SWRAST, 2 },
+    { __DRI_SWRAST, __DRI_SWRAST_VERSION },
     driCreateNewScreen,
     driCreateNewDrawable,
     driCreateNewContextForAPI,
-    NULL
+    driCreateContextAttribs
 };