dri: Move API version validation into dri/common.
authorEric Anholt <eric@anholt.net>
Thu, 26 Sep 2013 19:01:56 +0000 (12:01 -0700)
committerEric Anholt <eric@anholt.net>
Thu, 10 Oct 2013 23:34:30 +0000 (16:34 -0700)
i965, i915, radeon, r200, swrast, and nouveau were mostly trying to do the
same logic, except where they failed to.  Notably, swrast had code that
appeared to try to enable GLES1/2 but forgot to set api_mask (thus
preventing any gles context from being created), and the non-intel drivers
didn't support MESA_GL_VERSION_OVERRIDE.

nouveau still relies on _mesa_compute_version(), because I don't know what
its limits actually are, and gallium drivers don't declare limits up front
at all.  I think I've heard talk about doing so, though.

v2: Compat max version should be 30 (noted by Ken)
    Drop r100's custom max version check, too (noted by Emil Velikov)

Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
16 files changed:
src/gallium/state_trackers/dri/common/dri_screen.c
src/gallium/state_trackers/dri/drm/dri2.c
src/mesa/drivers/dri/common/dri_util.c
src/mesa/drivers/dri/common/dri_util.h
src/mesa/drivers/dri/i915/intel_context.c
src/mesa/drivers/dri/i915/intel_screen.c
src/mesa/drivers/dri/i915/intel_screen.h
src/mesa/drivers/dri/i965/intel_context.c
src/mesa/drivers/dri/i965/intel_screen.c
src/mesa/drivers/dri/i965/intel_screen.h
src/mesa/drivers/dri/nouveau/nouveau_context.c
src/mesa/drivers/dri/nouveau/nouveau_screen.c
src/mesa/drivers/dri/r200/r200_context.c
src/mesa/drivers/dri/radeon/radeon_context.c
src/mesa/drivers/dri/radeon/radeon_screen.c
src/mesa/drivers/dri/swrast/swrast.c

index 779741e32e3340a6318042b3ac8482908eefec25..92cac73d5bc40534775e07fa6e7a834c748507f4 100644 (file)
@@ -438,6 +438,19 @@ dri_init_screen_helper(struct dri_screen *screen,
 
    dri_postprocessing_init(screen);
 
+   /* gallium drivers don't declare what version of GL they support, so we
+    * check the computed Mesa context version after context creation and fail
+    * out then.
+    */
+   if (screen->st_api->profile_mask & ST_PROFILE_DEFAULT_MASK)
+      screen->sPriv->max_gl_compat_version = 30;
+   if (screen->st_api->profile_mask & ST_PROFILE_OPENGL_CORE_MASK)
+      screen->sPriv->max_gl_core_version = 32;
+   if (screen->st_api->profile_mask & ST_PROFILE_OPENGL_ES1_MASK)
+      screen->sPriv->max_gl_es1_version = 11;
+   if (screen->st_api->profile_mask & ST_PROFILE_OPENGL_ES2_MASK)
+      screen->sPriv->max_gl_es2_version = 30;
+
    return dri_fill_in_modes(screen);
 }
 
index 919ba6dc2a047533383c706cdc9464b31b0bcb62..56479686366a0ce336fbc5f1a1c72e56e83115d8 100644 (file)
@@ -897,14 +897,6 @@ dri2_init_screen(__DRIscreen * sPriv)
    if (!configs)
       goto fail;
 
-   sPriv->api_mask = 0;
-   if (screen->st_api->profile_mask & ST_PROFILE_DEFAULT_MASK)
-      sPriv->api_mask |= 1 << __DRI_API_OPENGL;
-   if (screen->st_api->profile_mask & ST_PROFILE_OPENGL_ES1_MASK)
-      sPriv->api_mask |= 1 << __DRI_API_GLES;
-   if (screen->st_api->profile_mask & ST_PROFILE_OPENGL_ES2_MASK)
-      sPriv->api_mask |= 1 << __DRI_API_GLES2;
-
    screen->auto_fake_front = dri_with_format(sPriv);
    screen->broken_invalidate = !sPriv->dri2.useInvalidate;
    screen->lookup_egl_image = dri2_lookup_egl_image;
index 424b65d7a2fc10ff48db199146bd81f46ba0a7da..70448c2df4d2845c15cd35fd48afc7b17a552900 100644 (file)
@@ -39,6 +39,7 @@
  */
 
 
+#include <stdbool.h>
 #ifndef __NOT_HAVE_DRM_H
 #include <xf86drm.h>
 #endif
@@ -46,6 +47,8 @@
 #include "utils.h"
 #include "xmlpool.h"
 #include "../glsl/glsl_parser_extras.h"
+#include "main/version.h"
+#include "main/macros.h"
 
 PUBLIC const char __dri2ConfigOptions[] =
    DRI_CONF_BEGIN
@@ -116,17 +119,35 @@ dri2CreateNewScreen(int scrn, int fd,
     psp->fd = fd;
     psp->myNum = scrn;
 
-    psp->api_mask = (1 << __DRI_API_OPENGL);
-
     *driver_configs = driDriverAPI.InitScreen(psp);
     if (*driver_configs == NULL) {
        free(psp);
        return NULL;
     }
 
+    int gl_version_override = _mesa_get_gl_version_override();
+    if (gl_version_override >= 31) {
+       psp->max_gl_core_version = MAX2(psp->max_gl_core_version,
+                                       gl_version_override);
+    } else {
+       psp->max_gl_compat_version = MAX2(psp->max_gl_compat_version,
+                                         gl_version_override);
+    }
+
+    psp->api_mask = (1 << __DRI_API_OPENGL);
+    if (psp->max_gl_core_version > 0)
+       psp->api_mask |= (1 << __DRI_API_OPENGL_CORE);
+    if (psp->max_gl_es1_version > 0)
+       psp->api_mask |= (1 << __DRI_API_GLES);
+    if (psp->max_gl_es2_version > 0)
+       psp->api_mask |= (1 << __DRI_API_GLES2);
+    if (psp->max_gl_es2_version >= 30)
+       psp->api_mask |= (1 << __DRI_API_GLES3);
+
     driParseOptionInfo(&psp->optionInfo, __dri2ConfigOptions);
     driParseConfigFiles(&psp->optionCache, &psp->optionInfo, psp->myNum, "dri2");
 
+
     return psp;
 }
 
@@ -172,6 +193,45 @@ static const __DRIextension **driGetExtensions(__DRIscreen *psp)
 /*@}*/
 
 
+static bool
+validate_context_version(__DRIscreen *screen,
+                         int mesa_api,
+                         unsigned major_version,
+                         unsigned minor_version,
+                         unsigned *dri_ctx_error)
+{
+   unsigned req_version = 10 * major_version + minor_version;
+   unsigned max_version = 0;
+
+   switch (mesa_api) {
+   case API_OPENGL_COMPAT:
+      max_version = screen->max_gl_compat_version;
+      break;
+   case API_OPENGL_CORE:
+      max_version = screen->max_gl_core_version;
+      break;
+   case API_OPENGLES:
+      max_version = screen->max_gl_es1_version;
+      break;
+   case API_OPENGLES2:
+      max_version = screen->max_gl_es2_version;
+      break;
+   default:
+      max_version = 0;
+      break;
+   }
+
+   if (max_version == 0) {
+      *dri_ctx_error = __DRI_CTX_ERROR_BAD_API;
+      return false;
+   } else if (req_version > max_version) {
+      *dri_ctx_error = __DRI_CTX_ERROR_BAD_VERSION;
+      return false;
+   }
+
+   return true;
+}
+
 /*****************************************************************/
 /** \name Context handling functions                             */
 /*****************************************************************/
@@ -293,6 +353,10 @@ dri2CreateContextAttribs(__DRIscreen *screen, int api,
        return NULL;
     }
 
+    if (!validate_context_version(screen, mesa_api,
+                                  major_version, minor_version, error))
+       return NULL;
+
     context = calloc(1, sizeof *context);
     if (!context) {
        *error = __DRI_CTX_ERROR_NO_MEMORY;
index 900f04853a73498d6a388572429ad9ae95b86094..92edccbb02e925db18e8571712cecd0ed37f221f 100644 (file)
@@ -151,6 +151,11 @@ struct __DRIscreenRec {
 
     void *loaderPrivate;
 
+    int max_gl_core_version;
+    int max_gl_compat_version;
+    int max_gl_es1_version;
+    int max_gl_es2_version;
+
     const __DRIextension **extensions;
 
     const __DRIswrastLoaderExtension *swrast_loader;
index f27e3d084abbd47b0034a95476952393165ff714..aff51e825407a5118a8f26547730ef4e9aa0685a 100644 (file)
@@ -367,45 +367,6 @@ intelInitDriverFunctions(struct dd_function_table *functions)
    intel_init_syncobj_functions(functions);
 }
 
-static bool
-validate_context_version(struct intel_screen *screen,
-                         int mesa_api,
-                         unsigned major_version,
-                         unsigned minor_version,
-                         unsigned *dri_ctx_error)
-{
-   unsigned req_version = 10 * major_version + minor_version;
-   unsigned max_version = 0;
-
-   switch (mesa_api) {
-   case API_OPENGL_COMPAT:
-      max_version = screen->max_gl_compat_version;
-      break;
-   case API_OPENGL_CORE:
-      max_version = screen->max_gl_core_version;
-      break;
-   case API_OPENGLES:
-      max_version = screen->max_gl_es1_version;
-      break;
-   case API_OPENGLES2:
-      max_version = screen->max_gl_es2_version;
-      break;
-   default:
-      max_version = 0;
-      break;
-   }
-
-   if (max_version == 0) {
-      *dri_ctx_error = __DRI_CTX_ERROR_BAD_API;
-      return false;
-   } else if (req_version > max_version) {
-      *dri_ctx_error = __DRI_CTX_ERROR_BAD_VERSION;
-      return false;
-   }
-
-   return true;
-}
-
 bool
 intelInitContext(struct intel_context *intel,
                  int api,
@@ -430,11 +391,6 @@ intelInitContext(struct intel_context *intel,
       return false;
    }
 
-   if (!validate_context_version(intelScreen,
-                                 api, major_version, minor_version,
-                                 dri_ctx_error))
-      return false;
-
    /* Can't rely on invalidate events, fall back to glViewport hack */
    if (!driContextPriv->driScreenPriv->dri2.useInvalidate) {
       intel->saved_viewport = functions->Viewport;
index e3e6ac28bef74e021b884cc5994ea042af4f9cb5..4f8c342e8e275260b4adb380c2ea83218b6a4128 100644 (file)
@@ -1062,33 +1062,25 @@ intel_screen_make_configs(__DRIscreen *dri_screen)
 static void
 set_max_gl_versions(struct intel_screen *screen)
 {
-   int gl_version_override = _mesa_get_gl_version_override();
+   __DRIscreen *psp = screen->driScrnPriv;
 
    switch (screen->gen) {
    case 3:
-      screen->max_gl_core_version = 0;
-      screen->max_gl_es1_version = 11;
-      screen->max_gl_compat_version = 21;
-      screen->max_gl_es2_version = 20;
+      psp->max_gl_core_version = 0;
+      psp->max_gl_es1_version = 11;
+      psp->max_gl_compat_version = 21;
+      psp->max_gl_es2_version = 20;
       break;
    case 2:
-      screen->max_gl_core_version = 0;
-      screen->max_gl_compat_version = 13;
-      screen->max_gl_es1_version = 11;
-      screen->max_gl_es2_version = 0;
+      psp->max_gl_core_version = 0;
+      psp->max_gl_compat_version = 13;
+      psp->max_gl_es1_version = 11;
+      psp->max_gl_es2_version = 0;
       break;
    default:
       assert(!"unrecognized intel_screen::gen");
       break;
    }
-
-   if (gl_version_override >= 31) {
-      screen->max_gl_core_version = MAX2(screen->max_gl_core_version,
-                                         gl_version_override);
-   } else {
-      screen->max_gl_compat_version = MAX2(screen->max_gl_compat_version,
-                                           gl_version_override);
-   }
 }
 
 /**
@@ -1137,16 +1129,6 @@ __DRIconfig **intelInitScreen2(__DRIscreen *psp)
 
    set_max_gl_versions(intelScreen);
 
-   psp->api_mask = (1 << __DRI_API_OPENGL);
-   if (intelScreen->max_gl_core_version > 0)
-      psp->api_mask |= (1 << __DRI_API_OPENGL_CORE);
-   if (intelScreen->max_gl_es1_version > 0)
-      psp->api_mask |= (1 << __DRI_API_GLES);
-   if (intelScreen->max_gl_es2_version > 0)
-      psp->api_mask |= (1 << __DRI_API_GLES2);
-   if (intelScreen->max_gl_es2_version >= 30)
-      psp->api_mask |= (1 << __DRI_API_GLES3);
-
    psp->extensions = intelScreenExtensions;
 
    return (const __DRIconfig**) intel_screen_make_configs(psp);
index a0ff0e07445b26d321bcd6df84191e444fbc4a2d..331ce90f7aa275bd758e1ce8859cf8ba96e3ca28 100644 (file)
@@ -40,11 +40,6 @@ struct intel_screen
    int deviceID;
    int gen;
 
-   int max_gl_core_version;
-   int max_gl_compat_version;
-   int max_gl_es1_version;
-   int max_gl_es2_version;
-
    __DRIscreen *driScrnPriv;
 
    bool no_hw;
index 4f969898e05486b8fefe16732e897de49c8bd8bf..7526b38a26e0f33a13922abebb0a79e477323fbf 100644 (file)
@@ -394,45 +394,6 @@ intelInitDriverFunctions(struct dd_function_table *functions)
    brw_init_object_purgeable_functions(functions);
 }
 
-static bool
-validate_context_version(struct intel_screen *screen,
-                         int mesa_api,
-                         unsigned major_version,
-                         unsigned minor_version,
-                         unsigned *dri_ctx_error)
-{
-   unsigned req_version = 10 * major_version + minor_version;
-   unsigned max_version = 0;
-
-   switch (mesa_api) {
-   case API_OPENGL_COMPAT:
-      max_version = screen->max_gl_compat_version;
-      break;
-   case API_OPENGL_CORE:
-      max_version = screen->max_gl_core_version;
-      break;
-   case API_OPENGLES:
-      max_version = screen->max_gl_es1_version;
-      break;
-   case API_OPENGLES2:
-      max_version = screen->max_gl_es2_version;
-      break;
-   default:
-      max_version = 0;
-      break;
-   }
-
-   if (max_version == 0) {
-      *dri_ctx_error = __DRI_CTX_ERROR_BAD_API;
-      return false;
-   } else if (req_version > max_version) {
-      *dri_ctx_error = __DRI_CTX_ERROR_BAD_VERSION;
-      return false;
-   }
-
-   return true;
-}
-
 bool
 intelInitContext(struct brw_context *brw,
                  int api,
@@ -457,11 +418,6 @@ intelInitContext(struct brw_context *brw,
       return false;
    }
 
-   if (!validate_context_version(intelScreen,
-                                 api, major_version, minor_version,
-                                 dri_ctx_error))
-      return false;
-
    /* Can't rely on invalidate events, fall back to glViewport hack */
    if (!driContextPriv->driScreenPriv->dri2.useInvalidate) {
       brw->saved_viewport = functions->Viewport;
index cddc8e8133079cbbdeb70d94770b9fb1fe64bc40..aef3bbf7e763b4ebff4feedb9ce703821feda855 100644 (file)
@@ -1220,40 +1220,32 @@ intel_screen_make_configs(__DRIscreen *dri_screen)
 static void
 set_max_gl_versions(struct intel_screen *screen)
 {
-   int gl_version_override = _mesa_get_gl_version_override();
+   __DRIscreen *psp = screen->driScrnPriv;
 
    switch (screen->gen) {
    case 7:
-      screen->max_gl_core_version = 31;
-      screen->max_gl_compat_version = 30;
-      screen->max_gl_es1_version = 11;
-      screen->max_gl_es2_version = 30;
+      psp->max_gl_core_version = 31;
+      psp->max_gl_compat_version = 30;
+      psp->max_gl_es1_version = 11;
+      psp->max_gl_es2_version = 30;
       break;
    case 6:
-      screen->max_gl_core_version = 31;
-      screen->max_gl_compat_version = 30;
-      screen->max_gl_es1_version = 11;
-      screen->max_gl_es2_version = 30;
+      psp->max_gl_core_version = 31;
+      psp->max_gl_compat_version = 30;
+      psp->max_gl_es1_version = 11;
+      psp->max_gl_es2_version = 30;
       break;
    case 5:
    case 4:
-      screen->max_gl_core_version = 0;
-      screen->max_gl_compat_version = 21;
-      screen->max_gl_es1_version = 11;
-      screen->max_gl_es2_version = 20;
+      psp->max_gl_core_version = 0;
+      psp->max_gl_compat_version = 21;
+      psp->max_gl_es1_version = 11;
+      psp->max_gl_es2_version = 20;
       break;
    default:
       assert(!"unrecognized intel_screen::gen");
       break;
    }
-
-   if (gl_version_override >= 31) {
-      screen->max_gl_core_version = MAX2(screen->max_gl_core_version,
-                                         gl_version_override);
-   } else {
-      screen->max_gl_compat_version = MAX2(screen->max_gl_compat_version,
-                                           gl_version_override);
-   }
 }
 
 /**
@@ -1319,16 +1311,6 @@ __DRIconfig **intelInitScreen2(__DRIscreen *psp)
 
    set_max_gl_versions(intelScreen);
 
-   psp->api_mask = (1 << __DRI_API_OPENGL);
-   if (intelScreen->max_gl_core_version > 0)
-      psp->api_mask |= (1 << __DRI_API_OPENGL_CORE);
-   if (intelScreen->max_gl_es1_version > 0)
-      psp->api_mask |= (1 << __DRI_API_GLES);
-   if (intelScreen->max_gl_es2_version > 0)
-      psp->api_mask |= (1 << __DRI_API_GLES2);
-   if (intelScreen->max_gl_es2_version >= 30)
-      psp->api_mask |= (1 << __DRI_API_GLES3);
-
    psp->extensions = intelScreenExtensions;
 
    return (const __DRIconfig**) intel_screen_make_configs(psp);
index 9af42201e631d1976a78a44a80de7976bcd30e5a..fef17bcfb3c67bdfacbfe1af737dedeb4b830b86 100644 (file)
@@ -40,11 +40,6 @@ struct intel_screen
    int deviceID;
    int gen;
 
-   int max_gl_core_version;
-   int max_gl_compat_version;
-   int max_gl_es1_version;
-   int max_gl_es2_version;
-
    __DRIscreen *driScrnPriv;
 
    bool no_hw;
index eab1aa23f4712b92b17b9b60b1098626a9aeec5c..0b648acb46fdb0330541c7afa508266ea922823c 100644 (file)
@@ -61,29 +61,6 @@ nouveau_context_create(gl_api api,
        struct nouveau_context *nctx;
        struct gl_context *ctx;
 
-       switch (api) {
-       case API_OPENGL_COMPAT:
-               /* Do after-the-fact version checking (below).
-                */
-               break;
-       case API_OPENGLES:
-               /* NV10 and NV20 can support OpenGL ES 1.0 only.  Older chips
-                * cannot do even that.
-                */
-               if ((screen->device->chipset & 0xf0) == 0x00) {
-                       *error = __DRI_CTX_ERROR_BAD_API;
-                       return GL_FALSE;
-               } else if (minor_version != 0) {
-                       *error = __DRI_CTX_ERROR_BAD_VERSION;
-                       return GL_FALSE;
-               }
-               break;
-       case API_OPENGLES2:
-       case API_OPENGL_CORE:
-               *error = __DRI_CTX_ERROR_BAD_API;
-               return GL_FALSE;
-       }
-
        /* API and flag filtering is handled in dri2CreateContextAttribs.
         */
        (void) flags;
index ca39fff807a6057de699dc503ec7bb31d5b3a4cf..6816406f539ed5a82d8055396affbb8c364ec676 100644 (file)
@@ -93,6 +93,18 @@ nouveau_init_screen2(__DRIscreen *dri_screen)
        if (!screen)
                return NULL;
 
+
+        /* Compat version validation will occur at context init after
+         * _mesa_compute_version().
+         */
+        dri_screen->max_gl_compat_version = 15;
+
+        /* NV10 and NV20 can support OpenGL ES 1.0 only.  Older chips
+         * cannot do even that.
+         */
+        if ((screen->device->chipset & 0xf0) != 0x00)
+                dri_screen->max_gl_es1_version = 10;
+
        dri_screen->driverPrivate = screen;
        dri_screen->extensions = nouveau_screen_extensions;
        screen->dri_screen = dri_screen;
index b2e1f36e1878eec0c6b271f320c86e93a4e0eb8a..8da9438541eccf3261cb99306868f5060dcc2efe 100644 (file)
@@ -212,20 +212,6 @@ GLboolean r200CreateContext( gl_api api,
    int i;
    int tcl_mode;
 
-   switch (api) {
-   case API_OPENGL_COMPAT:
-      if (major_version > 1 || minor_version > 3) {
-         *error = __DRI_CTX_ERROR_BAD_VERSION;
-         return GL_FALSE;
-      }
-      break;
-   case API_OPENGLES:
-      break;
-   default:
-      *error = __DRI_CTX_ERROR_BAD_API;
-      return GL_FALSE;
-   }
-
    /* Flag filtering is handled in dri2CreateContextAttribs.
     */
    (void) flags;
index 60c39fa8532deab58e0e994208f5d49ed9241de1..592a65b68e579d3f6582bce8467b4dc2870f4d09 100644 (file)
@@ -179,20 +179,6 @@ r100CreateContext( gl_api api,
    int i;
    int tcl_mode, fthrottle_mode;
 
-   switch (api) {
-   case API_OPENGL_COMPAT:
-      if (major_version > 1 || minor_version > 3) {
-         *error = __DRI_CTX_ERROR_BAD_VERSION;
-         return GL_FALSE;
-      }
-      break;
-   case API_OPENGLES:
-      break;
-   default:
-      *error = __DRI_CTX_ERROR_BAD_API;
-      return GL_FALSE;
-   }
-
    /* Flag filtering is handled in dri2CreateContextAttribs.
     */
    (void) flags;
index dc44d4a105b71db9ee1a56dfae4ab1ce6f895842..1a8dc6c9bbbfc6b654d565ff356e7b340b64caea 100644 (file)
@@ -719,6 +719,9 @@ __DRIconfig **radeonInitScreen2(__DRIscreen *psp)
    int color;
    __DRIconfig **configs = NULL;
 
+   psp->max_gl_compat_version = 13;
+   psp->max_gl_es1_version = 11;
+
    if (!radeonInitDriver(psp)) {
        return NULL;
     }
index 332c7b72fd3f45175213b6d0f48ffa0cb4efbd42..4725a7f42dd12d6e4a28be117673b58e0f9bf4eb 100644 (file)
@@ -200,6 +200,10 @@ dri_init_screen(__DRIscreen * psp)
 
     TRACE;
 
+    psp->max_gl_compat_version = 21;
+    psp->max_gl_es1_version = 11;
+    psp->max_gl_es2_version = 20;
+
     psp->extensions = dri_screen_extensions;
 
     configs16 = swrastFillInModes(psp, 16, 16, 0, 1);
@@ -674,22 +678,6 @@ dri_create_context(gl_api api,
      */
     (void) flags;
 
-    switch (api) {
-    case API_OPENGL_COMPAT:
-        if (major_version > 2
-           || (major_version == 2 && minor_version > 1)) {
-            *error = __DRI_CTX_ERROR_BAD_VERSION;
-            return GL_FALSE;
-        }
-        break;
-    case API_OPENGLES:
-    case API_OPENGLES2:
-        break;
-    case API_OPENGL_CORE:
-        *error = __DRI_CTX_ERROR_BAD_API;
-        return GL_FALSE;
-    }
-
     ctx = CALLOC_STRUCT(dri_context);
     if (ctx == NULL) {
        *error = __DRI_CTX_ERROR_NO_MEMORY;