From 083f66fdd6451648fe355b64b02b29a6a4389f0d Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Thu, 26 Sep 2013 12:01:56 -0700 Subject: [PATCH] dri: Move API version validation into dri/common. 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 --- .../state_trackers/dri/common/dri_screen.c | 13 ++++ src/gallium/state_trackers/dri/drm/dri2.c | 8 --- src/mesa/drivers/dri/common/dri_util.c | 68 ++++++++++++++++++- src/mesa/drivers/dri/common/dri_util.h | 5 ++ src/mesa/drivers/dri/i915/intel_context.c | 44 ------------ src/mesa/drivers/dri/i915/intel_screen.c | 36 +++------- src/mesa/drivers/dri/i915/intel_screen.h | 5 -- src/mesa/drivers/dri/i965/intel_context.c | 44 ------------ src/mesa/drivers/dri/i965/intel_screen.c | 44 ++++-------- src/mesa/drivers/dri/i965/intel_screen.h | 5 -- .../drivers/dri/nouveau/nouveau_context.c | 23 ------- src/mesa/drivers/dri/nouveau/nouveau_screen.c | 12 ++++ src/mesa/drivers/dri/r200/r200_context.c | 14 ---- src/mesa/drivers/dri/radeon/radeon_context.c | 14 ---- src/mesa/drivers/dri/radeon/radeon_screen.c | 3 + src/mesa/drivers/dri/swrast/swrast.c | 20 ++---- 16 files changed, 125 insertions(+), 233 deletions(-) diff --git a/src/gallium/state_trackers/dri/common/dri_screen.c b/src/gallium/state_trackers/dri/common/dri_screen.c index 779741e32e3..92cac73d5bc 100644 --- a/src/gallium/state_trackers/dri/common/dri_screen.c +++ b/src/gallium/state_trackers/dri/common/dri_screen.c @@ -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); } diff --git a/src/gallium/state_trackers/dri/drm/dri2.c b/src/gallium/state_trackers/dri/drm/dri2.c index 919ba6dc2a0..56479686366 100644 --- a/src/gallium/state_trackers/dri/drm/dri2.c +++ b/src/gallium/state_trackers/dri/drm/dri2.c @@ -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; diff --git a/src/mesa/drivers/dri/common/dri_util.c b/src/mesa/drivers/dri/common/dri_util.c index 424b65d7a2f..70448c2df4d 100644 --- a/src/mesa/drivers/dri/common/dri_util.c +++ b/src/mesa/drivers/dri/common/dri_util.c @@ -39,6 +39,7 @@ */ +#include #ifndef __NOT_HAVE_DRM_H #include #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; diff --git a/src/mesa/drivers/dri/common/dri_util.h b/src/mesa/drivers/dri/common/dri_util.h index 900f04853a7..92edccbb02e 100644 --- a/src/mesa/drivers/dri/common/dri_util.h +++ b/src/mesa/drivers/dri/common/dri_util.h @@ -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; diff --git a/src/mesa/drivers/dri/i915/intel_context.c b/src/mesa/drivers/dri/i915/intel_context.c index f27e3d084ab..aff51e82540 100644 --- a/src/mesa/drivers/dri/i915/intel_context.c +++ b/src/mesa/drivers/dri/i915/intel_context.c @@ -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; diff --git a/src/mesa/drivers/dri/i915/intel_screen.c b/src/mesa/drivers/dri/i915/intel_screen.c index e3e6ac28bef..4f8c342e8e2 100644 --- a/src/mesa/drivers/dri/i915/intel_screen.c +++ b/src/mesa/drivers/dri/i915/intel_screen.c @@ -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); diff --git a/src/mesa/drivers/dri/i915/intel_screen.h b/src/mesa/drivers/dri/i915/intel_screen.h index a0ff0e07445..331ce90f7aa 100644 --- a/src/mesa/drivers/dri/i915/intel_screen.h +++ b/src/mesa/drivers/dri/i915/intel_screen.h @@ -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; diff --git a/src/mesa/drivers/dri/i965/intel_context.c b/src/mesa/drivers/dri/i965/intel_context.c index 4f969898e05..7526b38a26e 100644 --- a/src/mesa/drivers/dri/i965/intel_context.c +++ b/src/mesa/drivers/dri/i965/intel_context.c @@ -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; diff --git a/src/mesa/drivers/dri/i965/intel_screen.c b/src/mesa/drivers/dri/i965/intel_screen.c index cddc8e81330..aef3bbf7e76 100644 --- a/src/mesa/drivers/dri/i965/intel_screen.c +++ b/src/mesa/drivers/dri/i965/intel_screen.c @@ -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); diff --git a/src/mesa/drivers/dri/i965/intel_screen.h b/src/mesa/drivers/dri/i965/intel_screen.h index 9af42201e63..fef17bcfb3c 100644 --- a/src/mesa/drivers/dri/i965/intel_screen.h +++ b/src/mesa/drivers/dri/i965/intel_screen.h @@ -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; diff --git a/src/mesa/drivers/dri/nouveau/nouveau_context.c b/src/mesa/drivers/dri/nouveau/nouveau_context.c index eab1aa23f47..0b648acb46f 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_context.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_context.c @@ -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; diff --git a/src/mesa/drivers/dri/nouveau/nouveau_screen.c b/src/mesa/drivers/dri/nouveau/nouveau_screen.c index ca39fff807a..6816406f539 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_screen.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_screen.c @@ -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; diff --git a/src/mesa/drivers/dri/r200/r200_context.c b/src/mesa/drivers/dri/r200/r200_context.c index b2e1f36e187..8da9438541e 100644 --- a/src/mesa/drivers/dri/r200/r200_context.c +++ b/src/mesa/drivers/dri/r200/r200_context.c @@ -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; diff --git a/src/mesa/drivers/dri/radeon/radeon_context.c b/src/mesa/drivers/dri/radeon/radeon_context.c index 60c39fa8532..592a65b68e5 100644 --- a/src/mesa/drivers/dri/radeon/radeon_context.c +++ b/src/mesa/drivers/dri/radeon/radeon_context.c @@ -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; diff --git a/src/mesa/drivers/dri/radeon/radeon_screen.c b/src/mesa/drivers/dri/radeon/radeon_screen.c index dc44d4a105b..1a8dc6c9bbb 100644 --- a/src/mesa/drivers/dri/radeon/radeon_screen.c +++ b/src/mesa/drivers/dri/radeon/radeon_screen.c @@ -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; } diff --git a/src/mesa/drivers/dri/swrast/swrast.c b/src/mesa/drivers/dri/swrast/swrast.c index 332c7b72fd3..4725a7f42dd 100644 --- a/src/mesa/drivers/dri/swrast/swrast.c +++ b/src/mesa/drivers/dri/swrast/swrast.c @@ -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; -- 2.30.2