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 <kenneth@whitecape.org>
This commit is contained in:
Eric Anholt 2013-09-26 12:01:56 -07:00
parent d81632fb1e
commit 083f66fdd6
16 changed files with 125 additions and 233 deletions

View 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);
}

View 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;

View 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;

View 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;

View 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;

View 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);

View 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;

View 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;

View 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);

View 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;

View 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;

View 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;

View 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;

View 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;

View 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;
}

View 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;