diff options
Diffstat (limited to 'src/mesa')
-rw-r--r-- | src/mesa/drivers/dri/common/dri_util.c | 22 | ||||
-rw-r--r-- | src/mesa/drivers/dri/common/dri_util.h | 4 | ||||
-rw-r--r-- | src/mesa/drivers/dri/common/drisw_util.c | 78 | ||||
-rw-r--r-- | src/mesa/drivers/dri/intel/intel_screen.c | 37 | ||||
-rw-r--r-- | src/mesa/drivers/dri/nouveau/nouveau_context.c | 24 | ||||
-rw-r--r-- | src/mesa/drivers/dri/nouveau/nouveau_context.h | 3 | ||||
-rw-r--r-- | src/mesa/drivers/dri/r200/r200_context.c | 25 | ||||
-rw-r--r-- | src/mesa/drivers/dri/r200/r200_context.h | 4 | ||||
-rw-r--r-- | src/mesa/drivers/dri/radeon/radeon_context.c | 26 | ||||
-rw-r--r-- | src/mesa/drivers/dri/radeon/radeon_context.h | 4 | ||||
-rw-r--r-- | src/mesa/drivers/dri/swrast/swrast.c | 24 |
11 files changed, 221 insertions, 30 deletions
diff --git a/src/mesa/drivers/dri/common/dri_util.c b/src/mesa/drivers/dri/common/dri_util.c index 77511678e85..948eb0747d9 100644 --- a/src/mesa/drivers/dri/common/dri_util.c +++ b/src/mesa/drivers/dri/common/dri_util.c @@ -194,6 +194,8 @@ dri2CreateContextAttribs(__DRIscreen *screen, int api, /* 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; } } @@ -209,9 +211,14 @@ dri2CreateContextAttribs(__DRIscreen *screen, int api, * * 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; + if ((flags & __DRI_CTX_FLAG_FORWARD_COMPATIBLE) != 0) { + *error = __DRI_CTX_ERROR_BAD_FLAG; + return NULL; + } + + if ((flags & ~__DRI_CTX_FLAG_DEBUG) != 0) { + *error = __DRI_CTX_ERROR_UNKNOWN_FLAG; + return NULL; } context = malloc(sizeof *context); @@ -226,7 +233,9 @@ dri2CreateContextAttribs(__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; } @@ -521,10 +530,7 @@ const __DRIcoreExtension driCoreExtension = { /** 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 }, + { __DRI_DRI2, __DRI_DRI2_VERSION }, dri2CreateNewScreen, dri2CreateNewDrawable, dri2CreateNewContext, diff --git a/src/mesa/drivers/dri/common/dri_util.h b/src/mesa/drivers/dri/common/dri_util.h index bebb021f615..900f04853a7 100644 --- a/src/mesa/drivers/dri/common/dri_util.h +++ b/src/mesa/drivers/dri/common/dri_util.h @@ -84,6 +84,10 @@ struct __DriverAPIRec { GLboolean (*CreateContext)(gl_api api, const struct gl_config *glVis, __DRIcontext *driContextPriv, + unsigned major_version, + unsigned minor_version, + uint32_t flags, + unsigned *error, void *sharedContextPrivate); void (*DestroyContext)(__DRIcontext *driContextPriv); diff --git a/src/mesa/drivers/dri/common/drisw_util.c b/src/mesa/drivers/dri/common/drisw_util.c index a19123f7064..0ec124ae537 100644 --- a/src/mesa/drivers/dri/common/drisw_util.c +++ b/src/mesa/drivers/dri/common/drisw_util.c @@ -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; } @@ -136,6 +186,17 @@ driCreateNewContextForAPI(__DRIscreen *psp, int api, } 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 }; diff --git a/src/mesa/drivers/dri/intel/intel_screen.c b/src/mesa/drivers/dri/intel/intel_screen.c index e4cc5b0864e..76b231b80b1 100644 --- a/src/mesa/drivers/dri/intel/intel_screen.c +++ b/src/mesa/drivers/dri/intel/intel_screen.c @@ -516,27 +516,52 @@ static GLboolean intelCreateContext(gl_api api, const struct gl_config * mesaVis, __DRIcontext * driContextPriv, + unsigned major_version, + unsigned minor_version, + uint32_t flags, + unsigned *error, void *sharedContextPrivate) { __DRIscreen *sPriv = driContextPriv->driScreenPriv; struct intel_screen *intelScreen = sPriv->driverPrivate; + bool success; #ifdef I915 if (IS_9XX(intelScreen->deviceID)) { if (!IS_965(intelScreen->deviceID)) { - return i915CreateContext(api, mesaVis, driContextPriv, - sharedContextPrivate); + success = i915CreateContext(api, mesaVis, driContextPriv, + sharedContextPrivate); } } else { intelScreen->no_vbo = true; - return i830CreateContext(mesaVis, driContextPriv, sharedContextPrivate); + success = i830CreateContext(mesaVis, driContextPriv, + sharedContextPrivate); } #else if (IS_965(intelScreen->deviceID)) - return brwCreateContext(api, mesaVis, - driContextPriv, sharedContextPrivate); + success = brwCreateContext(api, mesaVis, + driContextPriv, + sharedContextPrivate); #endif - fprintf(stderr, "Unrecognized deviceID 0x%x\n", intelScreen->deviceID); + + if (success) { + struct gl_context *ctx = + (struct gl_context *) driContextPriv->driverPrivate; + + _mesa_compute_version(ctx); + if (ctx->VersionMajor > major_version + || (ctx->VersionMajor == major_version + && ctx->VersionMinor >= minor_version)) { + *error = __DRI_CTX_ERROR_BAD_VERSION; + return true; + } + + intelDestroyContext(driContextPriv); + } else { + *error = __DRI_CTX_ERROR_NO_MEMORY; + fprintf(stderr, "Unrecognized deviceID 0x%x\n", intelScreen->deviceID); + } + return false; } diff --git a/src/mesa/drivers/dri/nouveau/nouveau_context.c b/src/mesa/drivers/dri/nouveau/nouveau_context.c index 0e3321e96f4..0cb918e4111 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_context.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_context.c @@ -34,6 +34,7 @@ #include "main/framebuffer.h" #include "main/light.h" #include "main/state.h" +#include "main/version.h" #include "drivers/common/meta.h" #include "drivers/common/driverfuncs.h" #include "swrast/swrast.h" @@ -55,6 +56,10 @@ nouveau_channel_flush_notify(struct nouveau_channel *chan) GLboolean nouveau_context_create(gl_api api, const struct gl_config *visual, __DRIcontext *dri_ctx, + unsigned major_version, + unsigned minor_version, + uint32_t flags, + unsigned *error, void *share_ctx) { __DRIscreen *dri_screen = dri_ctx->driScreenPriv; @@ -62,14 +67,31 @@ nouveau_context_create(gl_api api, struct nouveau_context *nctx; struct gl_context *ctx; + /* API and flag filtering is handled in dri2CreateContextAttribs. + */ + (void) api; + (void) flags; + ctx = screen->driver->context_create(screen, visual, share_ctx); - if (!ctx) + if (!ctx) { + *error = __DRI_CTX_ERROR_NO_MEMORY; return GL_FALSE; + } nctx = to_nouveau_context(ctx); nctx->dri_context = dri_ctx; dri_ctx->driverPrivate = ctx; + _mesa_compute_version(ctx); + if (ctx->VersionMajor < major_version + || (ctx->VersionMajor == major_version + && ctx->VersionMinor < minor_version)) { + nouveau_context_destroy(dri_ctx); + *error = __DRI_CTX_ERROR_BAD_VERSION; + return GL_FALSE; + } + + *error = __DRI_CTX_ERROR_SUCCESS; return GL_TRUE; } diff --git a/src/mesa/drivers/dri/nouveau/nouveau_context.h b/src/mesa/drivers/dri/nouveau/nouveau_context.h index 7ebc676379e..cd4a9fbc0ff 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_context.h +++ b/src/mesa/drivers/dri/nouveau/nouveau_context.h @@ -98,7 +98,8 @@ struct nouveau_context { GLboolean nouveau_context_create(gl_api api, const struct gl_config *visual, __DRIcontext *dri_ctx, - void *share_ctx); + unsigned major_version, unsigned minor_version, + uint32_t flags, unsigned *error, void *share_ctx); GLboolean nouveau_context_init(struct gl_context *ctx, struct nouveau_screen *screen, diff --git a/src/mesa/drivers/dri/r200/r200_context.c b/src/mesa/drivers/dri/r200/r200_context.c index 90cccf56119..d7a648981f6 100644 --- a/src/mesa/drivers/dri/r200/r200_context.c +++ b/src/mesa/drivers/dri/r200/r200_context.c @@ -40,6 +40,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "main/imports.h" #include "main/extensions.h" #include "main/mfeatures.h" +#include "main/version.h" #include "swrast/swrast.h" #include "swrast_setup/swrast_setup.h" @@ -196,6 +197,10 @@ static void r200_init_vtbl(radeonContextPtr radeon) GLboolean r200CreateContext( gl_api api, const struct gl_config *glVisual, __DRIcontext *driContextPriv, + unsigned major_version, + unsigned minor_version, + uint32_t flags, + unsigned *error, void *sharedContextPrivate) { __DRIscreen *sPriv = driContextPriv->driScreenPriv; @@ -206,14 +211,21 @@ GLboolean r200CreateContext( gl_api api, int i; int tcl_mode; + /* API and flag filtering is handled in dri2CreateContextAttribs. + */ + (void) api; + (void) flags; + assert(glVisual); assert(driContextPriv); assert(screen); /* Allocate the R200 context */ rmesa = (r200ContextPtr) CALLOC( sizeof(*rmesa) ); - if ( !rmesa ) + if ( !rmesa ) { + *error = __DRI_CTX_ERROR_NO_MEMORY; return GL_FALSE; + } rmesa->radeon.radeonScreen = screen; r200_init_vtbl(&rmesa->radeon); @@ -256,6 +268,7 @@ GLboolean r200CreateContext( gl_api api, glVisual, driContextPriv, sharedContextPrivate)) { FREE(rmesa); + *error = __DRI_CTX_ERROR_NO_MEMORY; return GL_FALSE; } @@ -439,6 +452,16 @@ GLboolean r200CreateContext( gl_api api, TCL_FALLBACK(rmesa->radeon.glCtx, R200_TCL_FALLBACK_TCL_DISABLE, 1); } + _mesa_compute_version(ctx); + if (ctx->VersionMajor < major_version + || (ctx->VersionMajor == major_version + && ctx->VersionMinor < minor_version)) { + r200DestroyContext(driContextPriv); + *error = __DRI_CTX_ERROR_BAD_VERSION; + return GL_FALSE; + } + + *error = __DRI_CTX_ERROR_SUCCESS; return GL_TRUE; } diff --git a/src/mesa/drivers/dri/r200/r200_context.h b/src/mesa/drivers/dri/r200/r200_context.h index 720219fc530..e0d56932a57 100644 --- a/src/mesa/drivers/dri/r200/r200_context.h +++ b/src/mesa/drivers/dri/r200/r200_context.h @@ -635,6 +635,10 @@ extern void r200DestroyContext( __DRIcontext *driContextPriv ); extern GLboolean r200CreateContext( gl_api api, const struct gl_config *glVisual, __DRIcontext *driContextPriv, + unsigned major_version, + unsigned minor_version, + uint32_t flags, + unsigned *error, void *sharedContextPrivate); extern GLboolean r200MakeCurrent( __DRIcontext *driContextPriv, __DRIdrawable *driDrawPriv, diff --git a/src/mesa/drivers/dri/radeon/radeon_context.c b/src/mesa/drivers/dri/radeon/radeon_context.c index e7d461f8d06..40fd4dcd275 100644 --- a/src/mesa/drivers/dri/radeon/radeon_context.c +++ b/src/mesa/drivers/dri/radeon/radeon_context.c @@ -42,6 +42,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "main/imports.h" #include "main/extensions.h" #include "main/mfeatures.h" +#include "main/version.h" #include "swrast/swrast.h" #include "swrast_setup/swrast_setup.h" @@ -162,6 +163,10 @@ GLboolean r100CreateContext( gl_api api, const struct gl_config *glVisual, __DRIcontext *driContextPriv, + unsigned major_version, + unsigned minor_version, + uint32_t flags, + unsigned *error, void *sharedContextPrivate) { __DRIscreen *sPriv = driContextPriv->driScreenPriv; @@ -172,14 +177,21 @@ r100CreateContext( gl_api api, int i; int tcl_mode, fthrottle_mode; + /* API and flag filtering is handled in dri2CreateContextAttribs. + */ + (void) api; + (void) flags; + assert(glVisual); assert(driContextPriv); assert(screen); /* Allocate the Radeon context */ rmesa = (r100ContextPtr) CALLOC( sizeof(*rmesa) ); - if ( !rmesa ) + if ( !rmesa ) { + *error = __DRI_CTX_ERROR_NO_MEMORY; return GL_FALSE; + } rmesa->radeon.radeonScreen = screen; r100_init_vtbl(&rmesa->radeon); @@ -218,6 +230,7 @@ r100CreateContext( gl_api api, glVisual, driContextPriv, sharedContextPrivate)) { FREE(rmesa); + *error = __DRI_CTX_ERROR_NO_MEMORY; return GL_FALSE; } @@ -386,5 +399,16 @@ r100CreateContext( gl_api api, if (rmesa->radeon.radeonScreen->chip_flags & RADEON_CHIPSET_TCL) { /* _tnl_need_dlist_norm_lengths( ctx, GL_FALSE ); */ } + + _mesa_compute_version(ctx); + if (ctx->VersionMajor < major_version + || (ctx->VersionMajor == major_version + && ctx->VersionMinor < minor_version)) { + radeonDestroyContext(driContextPriv); + *error = __DRI_CTX_ERROR_BAD_VERSION; + return GL_FALSE; + } + + *error = __DRI_CTX_ERROR_SUCCESS; return GL_TRUE; } diff --git a/src/mesa/drivers/dri/radeon/radeon_context.h b/src/mesa/drivers/dri/radeon/radeon_context.h index e7d51efca86..cb036cd6570 100644 --- a/src/mesa/drivers/dri/radeon/radeon_context.h +++ b/src/mesa/drivers/dri/radeon/radeon_context.h @@ -450,6 +450,10 @@ struct r100_context { extern GLboolean r100CreateContext( gl_api api, const struct gl_config *glVisual, __DRIcontext *driContextPriv, + unsigned major_version, + unsigned minor_version, + uint32_t flags, + unsigned *error, void *sharedContextPrivate); diff --git a/src/mesa/drivers/dri/swrast/swrast.c b/src/mesa/drivers/dri/swrast/swrast.c index ac82dc7d568..ff74cc5e290 100644 --- a/src/mesa/drivers/dri/swrast/swrast.c +++ b/src/mesa/drivers/dri/swrast/swrast.c @@ -702,7 +702,12 @@ InitExtensionsES2(struct gl_context *ctx) static GLboolean dri_create_context(gl_api api, const struct gl_config * visual, - __DRIcontext * cPriv, void *sharedContextPrivate) + __DRIcontext * cPriv, + unsigned major_version, + unsigned minor_version, + uint32_t flags, + unsigned *error, + void *sharedContextPrivate) { struct dri_context *ctx = NULL; struct dri_context *share = (struct dri_context *)sharedContextPrivate; @@ -712,9 +717,22 @@ dri_create_context(gl_api api, TRACE; + /* Flag filtering is handled in dri2CreateContextAttribs. + */ + (void) flags; + + if (api == API_OPENGL + && (major_version > 2 + || (major_version == 2 && minor_version > 1))) { + *error = __DRI_CTX_ERROR_BAD_VERSION; + goto context_fail; + } + ctx = CALLOC_STRUCT(dri_context); - if (ctx == NULL) + if (ctx == NULL) { + *error = __DRI_CTX_ERROR_NO_MEMORY; goto context_fail; + } cPriv->driverPrivate = ctx; ctx->cPriv = cPriv; @@ -731,6 +749,7 @@ dri_create_context(gl_api api, /* basic context setup */ if (!_mesa_initialize_context(mesaCtx, api, visual, sharedCtx, &functions, (void *) cPriv)) { + *error = __DRI_CTX_ERROR_NO_MEMORY; goto context_fail; } @@ -772,6 +791,7 @@ dri_create_context(gl_api api, break; } + *error = __DRI_CTX_ERROR_SUCCESS; return GL_TRUE; context_fail: |