135c4bbdfSmrg/* 235c4bbdfSmrg * Copyright © 2011 Intel Corporation 335c4bbdfSmrg * 435c4bbdfSmrg * Permission is hereby granted, free of charge, to any person obtaining a 535c4bbdfSmrg * copy of this software and associated documentation files (the "Software"), 635c4bbdfSmrg * to deal in the Software without restriction, including without limitation 735c4bbdfSmrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 835c4bbdfSmrg * and/or sell copies of the Software, and to permit persons to whom the 935c4bbdfSmrg * Software is furnished to do so, subject to the following conditions: 1035c4bbdfSmrg * 1135c4bbdfSmrg * The above copyright notice and this permission notice (including the next 1235c4bbdfSmrg * paragraph) shall be included in all copies or substantial portions of the 1335c4bbdfSmrg * Software. 1435c4bbdfSmrg * 1535c4bbdfSmrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 1635c4bbdfSmrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 1735c4bbdfSmrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 1835c4bbdfSmrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 1935c4bbdfSmrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 2035c4bbdfSmrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 2135c4bbdfSmrg * DEALINGS IN THE SOFTWARE. 2235c4bbdfSmrg */ 2335c4bbdfSmrg#ifdef HAVE_DIX_CONFIG_H 2435c4bbdfSmrg#include <dix-config.h> 2535c4bbdfSmrg#endif 2635c4bbdfSmrg 2735c4bbdfSmrg#include <GL/glxtokens.h> 2835c4bbdfSmrg#include "glxserver.h" 2935c4bbdfSmrg#include "glxext.h" 3035c4bbdfSmrg#include "indirect_dispatch.h" 311b5d61b8Smrg#include "opaque.h" 3235c4bbdfSmrg 3335c4bbdfSmrg#define ALL_VALID_FLAGS \ 3435c4bbdfSmrg (GLX_CONTEXT_DEBUG_BIT_ARB | GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB \ 3535c4bbdfSmrg | GLX_CONTEXT_ROBUST_ACCESS_BIT_ARB) 3635c4bbdfSmrg 3735c4bbdfSmrgstatic Bool 3835c4bbdfSmrgvalidate_GL_version(int major_version, int minor_version) 3935c4bbdfSmrg{ 4035c4bbdfSmrg if (major_version <= 0 || minor_version < 0) 411b5d61b8Smrg return FALSE; 4235c4bbdfSmrg 4335c4bbdfSmrg switch (major_version) { 4435c4bbdfSmrg case 1: 4535c4bbdfSmrg if (minor_version > 5) 461b5d61b8Smrg return FALSE; 4735c4bbdfSmrg break; 4835c4bbdfSmrg 4935c4bbdfSmrg case 2: 5035c4bbdfSmrg if (minor_version > 1) 511b5d61b8Smrg return FALSE; 5235c4bbdfSmrg break; 5335c4bbdfSmrg 5435c4bbdfSmrg case 3: 5535c4bbdfSmrg if (minor_version > 3) 561b5d61b8Smrg return FALSE; 5735c4bbdfSmrg break; 5835c4bbdfSmrg 5935c4bbdfSmrg default: 6035c4bbdfSmrg break; 6135c4bbdfSmrg } 6235c4bbdfSmrg 631b5d61b8Smrg return TRUE; 6435c4bbdfSmrg} 6535c4bbdfSmrg 6635c4bbdfSmrgstatic Bool 6735c4bbdfSmrgvalidate_render_type(uint32_t render_type) 6835c4bbdfSmrg{ 6935c4bbdfSmrg switch (render_type) { 7035c4bbdfSmrg case GLX_RGBA_TYPE: 7135c4bbdfSmrg case GLX_COLOR_INDEX_TYPE: 7235c4bbdfSmrg case GLX_RGBA_FLOAT_TYPE_ARB: 7335c4bbdfSmrg case GLX_RGBA_UNSIGNED_FLOAT_TYPE_EXT: 741b5d61b8Smrg return TRUE; 7535c4bbdfSmrg default: 761b5d61b8Smrg return FALSE; 7735c4bbdfSmrg } 7835c4bbdfSmrg} 7935c4bbdfSmrg 8035c4bbdfSmrgint 8135c4bbdfSmrg__glXDisp_CreateContextAttribsARB(__GLXclientState * cl, GLbyte * pc) 8235c4bbdfSmrg{ 8335c4bbdfSmrg ClientPtr client = cl->client; 8435c4bbdfSmrg xGLXCreateContextAttribsARBReq *req = (xGLXCreateContextAttribsARBReq *) pc; 8535c4bbdfSmrg int32_t *attribs = (req->numAttribs != 0) ? (int32_t *) (req + 1) : NULL; 8635c4bbdfSmrg unsigned i; 8735c4bbdfSmrg int major_version = 1; 8835c4bbdfSmrg int minor_version = 0; 8935c4bbdfSmrg uint32_t flags = 0; 9035c4bbdfSmrg uint32_t render_type = GLX_RGBA_TYPE; 9135c4bbdfSmrg uint32_t flush = GLX_CONTEXT_RELEASE_BEHAVIOR_FLUSH_ARB; 9235c4bbdfSmrg __GLXcontext *ctx = NULL; 9335c4bbdfSmrg __GLXcontext *shareCtx = NULL; 9435c4bbdfSmrg __GLXscreen *glxScreen; 951b5d61b8Smrg __GLXconfig *config = NULL; 9635c4bbdfSmrg int err; 9735c4bbdfSmrg 9835c4bbdfSmrg /* The GLX_ARB_create_context_robustness spec says: 9935c4bbdfSmrg * 10035c4bbdfSmrg * "The default value for GLX_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB 10135c4bbdfSmrg * is GLX_NO_RESET_NOTIFICATION_ARB." 10235c4bbdfSmrg */ 10335c4bbdfSmrg int reset = GLX_NO_RESET_NOTIFICATION_ARB; 10435c4bbdfSmrg 10535c4bbdfSmrg /* The GLX_ARB_create_context_profile spec says: 10635c4bbdfSmrg * 10735c4bbdfSmrg * "The default value for GLX_CONTEXT_PROFILE_MASK_ARB is 10835c4bbdfSmrg * GLX_CONTEXT_CORE_PROFILE_BIT_ARB." 10935c4bbdfSmrg * 11035c4bbdfSmrg * The core profile only makes sense for OpenGL versions 3.2 and later. 11135c4bbdfSmrg * If the version ultimately specified is less than 3.2, the core profile 11235c4bbdfSmrg * bit is cleared (see below). 11335c4bbdfSmrg */ 11435c4bbdfSmrg int profile = GLX_CONTEXT_CORE_PROFILE_BIT_ARB; 11535c4bbdfSmrg 11635c4bbdfSmrg /* Verify that the size of the packet matches the size inferred from the 11735c4bbdfSmrg * sizes specified for the various fields. 11835c4bbdfSmrg */ 11935c4bbdfSmrg const unsigned expected_size = (sz_xGLXCreateContextAttribsARBReq 12035c4bbdfSmrg + (req->numAttribs * 8)) / 4; 12135c4bbdfSmrg 12235c4bbdfSmrg if (req->length != expected_size) 12335c4bbdfSmrg return BadLength; 12435c4bbdfSmrg 12535c4bbdfSmrg /* The GLX_ARB_create_context spec says: 12635c4bbdfSmrg * 12735c4bbdfSmrg * "* If <config> is not a valid GLXFBConfig, GLXBadFBConfig is 12835c4bbdfSmrg * generated." 12935c4bbdfSmrg * 13035c4bbdfSmrg * On the client, the screen comes from the FBConfig, so GLXBadFBConfig 13135c4bbdfSmrg * should be issued if the screen is nonsense. 13235c4bbdfSmrg */ 133ed6184dfSmrg if (!validGlxScreen(client, req->screen, &glxScreen, &err)) { 134ed6184dfSmrg client->errorValue = req->fbconfig; 13535c4bbdfSmrg return __glXError(GLXBadFBConfig); 136ed6184dfSmrg } 13735c4bbdfSmrg 1381b5d61b8Smrg if (req->fbconfig) { 139ed6184dfSmrg if (!validGlxFBConfig(client, glxScreen, req->fbconfig, &config, &err)) { 140ed6184dfSmrg client->errorValue = req->fbconfig; 1411b5d61b8Smrg return __glXError(GLXBadFBConfig); 142ed6184dfSmrg } 1431b5d61b8Smrg } 14435c4bbdfSmrg 14535c4bbdfSmrg /* Validate the context with which the new context should share resources. 14635c4bbdfSmrg */ 14735c4bbdfSmrg if (req->shareList != None) { 14835c4bbdfSmrg if (!validGlxContext(client, req->shareList, DixReadAccess, 14935c4bbdfSmrg &shareCtx, &err)) 15035c4bbdfSmrg return err; 15135c4bbdfSmrg 15235c4bbdfSmrg /* The crazy condition is because C doesn't have a logical XOR 15335c4bbdfSmrg * operator. Comparing directly for equality may fail if one is 1 and 15435c4bbdfSmrg * the other is 2 even though both are logically true. 15535c4bbdfSmrg */ 15635c4bbdfSmrg if (!!req->isDirect != !!shareCtx->isDirect) { 15735c4bbdfSmrg client->errorValue = req->shareList; 15835c4bbdfSmrg return BadMatch; 15935c4bbdfSmrg } 16035c4bbdfSmrg 16135c4bbdfSmrg /* The GLX_ARB_create_context spec says: 16235c4bbdfSmrg * 16335c4bbdfSmrg * "* If the server context state for <share_context>...was 16435c4bbdfSmrg * created on a different screen than the one referenced by 16535c4bbdfSmrg * <config>...BadMatch is generated." 16635c4bbdfSmrg */ 16735c4bbdfSmrg if (glxScreen != shareCtx->pGlxScreen) { 16835c4bbdfSmrg client->errorValue = shareCtx->pGlxScreen->pScreen->myNum; 16935c4bbdfSmrg return BadMatch; 17035c4bbdfSmrg } 17135c4bbdfSmrg } 17235c4bbdfSmrg 17335c4bbdfSmrg for (i = 0; i < req->numAttribs; i++) { 17435c4bbdfSmrg switch (attribs[i * 2]) { 17535c4bbdfSmrg case GLX_CONTEXT_MAJOR_VERSION_ARB: 17635c4bbdfSmrg major_version = attribs[2 * i + 1]; 17735c4bbdfSmrg break; 17835c4bbdfSmrg 17935c4bbdfSmrg case GLX_CONTEXT_MINOR_VERSION_ARB: 18035c4bbdfSmrg minor_version = attribs[2 * i + 1]; 18135c4bbdfSmrg break; 18235c4bbdfSmrg 18335c4bbdfSmrg case GLX_CONTEXT_FLAGS_ARB: 18435c4bbdfSmrg flags = attribs[2 * i + 1]; 18535c4bbdfSmrg break; 18635c4bbdfSmrg 18735c4bbdfSmrg case GLX_RENDER_TYPE: 1881b5d61b8Smrg /* Not valid for GLX_EXT_no_config_context */ 1891b5d61b8Smrg if (!req->fbconfig) 1901b5d61b8Smrg return BadValue; 19135c4bbdfSmrg render_type = attribs[2 * i + 1]; 19235c4bbdfSmrg break; 19335c4bbdfSmrg 19435c4bbdfSmrg case GLX_CONTEXT_PROFILE_MASK_ARB: 19535c4bbdfSmrg profile = attribs[2 * i + 1]; 19635c4bbdfSmrg break; 19735c4bbdfSmrg 19835c4bbdfSmrg case GLX_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB: 19935c4bbdfSmrg reset = attribs[2 * i + 1]; 20035c4bbdfSmrg if (reset != GLX_NO_RESET_NOTIFICATION_ARB 20135c4bbdfSmrg && reset != GLX_LOSE_CONTEXT_ON_RESET_ARB) 20235c4bbdfSmrg return BadValue; 20335c4bbdfSmrg 20435c4bbdfSmrg break; 20535c4bbdfSmrg 20635c4bbdfSmrg case GLX_CONTEXT_RELEASE_BEHAVIOR_ARB: 20735c4bbdfSmrg flush = attribs[2 * i + 1]; 20835c4bbdfSmrg if (flush != GLX_CONTEXT_RELEASE_BEHAVIOR_NONE_ARB 20935c4bbdfSmrg && flush != GLX_CONTEXT_RELEASE_BEHAVIOR_FLUSH_ARB) 21035c4bbdfSmrg return BadValue; 21135c4bbdfSmrg break; 21235c4bbdfSmrg 2131b5d61b8Smrg case GLX_SCREEN: 2141b5d61b8Smrg /* Only valid for GLX_EXT_no_config_context */ 2151b5d61b8Smrg if (req->fbconfig) 2161b5d61b8Smrg return BadValue; 2171b5d61b8Smrg /* Must match the value in the request header */ 2181b5d61b8Smrg if (attribs[2 * i + 1] != req->screen) 2191b5d61b8Smrg return BadValue; 2201b5d61b8Smrg break; 2211b5d61b8Smrg 2221b5d61b8Smrg case GLX_CONTEXT_OPENGL_NO_ERROR_ARB: 2231b5d61b8Smrg /* ignore */ 2241b5d61b8Smrg break; 2251b5d61b8Smrg 22635c4bbdfSmrg default: 2271b5d61b8Smrg if (!req->isDirect) 2281b5d61b8Smrg return BadValue; 2291b5d61b8Smrg break; 23035c4bbdfSmrg } 23135c4bbdfSmrg } 23235c4bbdfSmrg 23335c4bbdfSmrg /* The GLX_ARB_create_context spec says: 23435c4bbdfSmrg * 23535c4bbdfSmrg * "If attributes GLX_CONTEXT_MAJOR_VERSION_ARB and 23635c4bbdfSmrg * GLX_CONTEXT_MINOR_VERSION_ARB, when considered together 23735c4bbdfSmrg * with attributes GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB and 23835c4bbdfSmrg * GLX_RENDER_TYPE, specify an OpenGL version and feature set 23935c4bbdfSmrg * that are not defined, BadMatch is generated. 24035c4bbdfSmrg * 24135c4bbdfSmrg * ...Feature deprecation was introduced with OpenGL 3.0, so 24235c4bbdfSmrg * forward-compatible contexts may only be requested for 24335c4bbdfSmrg * OpenGL 3.0 and above. Thus, examples of invalid 24435c4bbdfSmrg * combinations of attributes include: 24535c4bbdfSmrg * 24635c4bbdfSmrg * - Major version < 1 or > 3 24735c4bbdfSmrg * - Major version == 1 and minor version < 0 or > 5 24835c4bbdfSmrg * - Major version == 2 and minor version < 0 or > 1 24935c4bbdfSmrg * - Major version == 3 and minor version > 2 25035c4bbdfSmrg * - Forward-compatible flag set and major version < 3 25135c4bbdfSmrg * - Color index rendering and major version >= 3" 25235c4bbdfSmrg */ 25335c4bbdfSmrg if (!validate_GL_version(major_version, minor_version)) 25435c4bbdfSmrg return BadMatch; 25535c4bbdfSmrg 25635c4bbdfSmrg if (major_version < 3 25735c4bbdfSmrg && ((flags & GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB) != 0)) 25835c4bbdfSmrg return BadMatch; 25935c4bbdfSmrg 26035c4bbdfSmrg if (major_version >= 3 && render_type == GLX_COLOR_INDEX_TYPE) 26135c4bbdfSmrg return BadMatch; 26235c4bbdfSmrg 26335c4bbdfSmrg if (!validate_render_type(render_type)) 26435c4bbdfSmrg return BadValue; 26535c4bbdfSmrg 26635c4bbdfSmrg if ((flags & ~ALL_VALID_FLAGS) != 0) 26735c4bbdfSmrg return BadValue; 26835c4bbdfSmrg 26935c4bbdfSmrg /* The GLX_ARB_create_context_profile spec says: 27035c4bbdfSmrg * 27135c4bbdfSmrg * "* If attribute GLX_CONTEXT_PROFILE_MASK_ARB has no bits set; has 27235c4bbdfSmrg * any bits set other than GLX_CONTEXT_CORE_PROFILE_BIT_ARB and 27335c4bbdfSmrg * GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB; has more than one of 27435c4bbdfSmrg * these bits set; or if the implementation does not support the 27535c4bbdfSmrg * requested profile, then GLXBadProfileARB is generated." 27635c4bbdfSmrg * 27735c4bbdfSmrg * The GLX_EXT_create_context_es2_profile spec doesn't exactly say what 27835c4bbdfSmrg * is supposed to happen if an invalid version is set, but it doesn't 27935c4bbdfSmrg * much matter as support for GLES contexts is only defined for direct 28035c4bbdfSmrg * contexts (at the moment anyway) so we can leave it up to the driver 28135c4bbdfSmrg * to validate. 28235c4bbdfSmrg */ 28335c4bbdfSmrg switch (profile) { 28435c4bbdfSmrg case GLX_CONTEXT_CORE_PROFILE_BIT_ARB: 28535c4bbdfSmrg case GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB: 28635c4bbdfSmrg case GLX_CONTEXT_ES2_PROFILE_BIT_EXT: 28735c4bbdfSmrg break; 28835c4bbdfSmrg default: 28935c4bbdfSmrg return __glXError(GLXBadProfileARB); 29035c4bbdfSmrg } 29135c4bbdfSmrg 29235c4bbdfSmrg /* The GLX_ARB_create_context_robustness spec says: 29335c4bbdfSmrg * 29435c4bbdfSmrg * "* If the reset notification behavior of <share_context> and the 29535c4bbdfSmrg * newly created context are different, BadMatch is generated." 29635c4bbdfSmrg */ 29735c4bbdfSmrg if (shareCtx != NULL && shareCtx->resetNotificationStrategy != reset) 29835c4bbdfSmrg return BadMatch; 29935c4bbdfSmrg 30035c4bbdfSmrg /* There is no GLX protocol for desktop OpenGL versions after 1.4. There 30135c4bbdfSmrg * is no GLX protocol for any version of OpenGL ES. If the application is 30235c4bbdfSmrg * requested an indirect rendering context for a version that cannot be 30335c4bbdfSmrg * satisfied, reject it. 30435c4bbdfSmrg * 30535c4bbdfSmrg * The GLX_ARB_create_context spec says: 30635c4bbdfSmrg * 30735c4bbdfSmrg * "* If <config> does not support compatible OpenGL contexts 30835c4bbdfSmrg * providing the requested API major and minor version, 30935c4bbdfSmrg * forward-compatible flag, and debug context flag, GLXBadFBConfig 31035c4bbdfSmrg * is generated." 31135c4bbdfSmrg */ 31235c4bbdfSmrg if (!req->isDirect && (major_version > 1 || minor_version > 4 31335c4bbdfSmrg || profile == GLX_CONTEXT_ES2_PROFILE_BIT_EXT)) { 314ed6184dfSmrg client->errorValue = req->fbconfig; 31535c4bbdfSmrg return __glXError(GLXBadFBConfig); 31635c4bbdfSmrg } 31735c4bbdfSmrg 31835c4bbdfSmrg /* Allocate memory for the new context 31935c4bbdfSmrg */ 32035c4bbdfSmrg if (req->isDirect) { 32135c4bbdfSmrg ctx = __glXdirectContextCreate(glxScreen, config, shareCtx); 32235c4bbdfSmrg err = BadAlloc; 32335c4bbdfSmrg } 32435c4bbdfSmrg else { 3251b5d61b8Smrg /* Only allow creating indirect GLX contexts if allowed by 3261b5d61b8Smrg * server command line. Indirect GLX is of limited use (since 3271b5d61b8Smrg * it's only GL 1.4), it's slower than direct contexts, and 3281b5d61b8Smrg * it's a massive attack surface for buffer overflow type 3291b5d61b8Smrg * errors. 3301b5d61b8Smrg */ 3311b5d61b8Smrg if (!enableIndirectGLX) { 3321b5d61b8Smrg client->errorValue = req->isDirect; 3331b5d61b8Smrg return BadValue; 3341b5d61b8Smrg } 3351b5d61b8Smrg 33635c4bbdfSmrg ctx = glxScreen->createContext(glxScreen, config, shareCtx, 33735c4bbdfSmrg req->numAttribs, (uint32_t *) attribs, 33835c4bbdfSmrg &err); 33935c4bbdfSmrg } 34035c4bbdfSmrg 34135c4bbdfSmrg if (ctx == NULL) 34235c4bbdfSmrg return err; 34335c4bbdfSmrg 34435c4bbdfSmrg ctx->pGlxScreen = glxScreen; 34535c4bbdfSmrg ctx->config = config; 34635c4bbdfSmrg ctx->id = req->context; 34735c4bbdfSmrg ctx->share_id = req->shareList; 3481b5d61b8Smrg ctx->idExists = TRUE; 34935c4bbdfSmrg ctx->isDirect = req->isDirect; 35035c4bbdfSmrg ctx->renderMode = GL_RENDER; 35135c4bbdfSmrg ctx->resetNotificationStrategy = reset; 35235c4bbdfSmrg ctx->releaseBehavior = flush; 353ed6184dfSmrg ctx->renderType = render_type; 35435c4bbdfSmrg 35535c4bbdfSmrg /* Add the new context to the various global tables of GLX contexts. 35635c4bbdfSmrg */ 35735c4bbdfSmrg if (!__glXAddContext(ctx)) { 35835c4bbdfSmrg (*ctx->destroy) (ctx); 35935c4bbdfSmrg client->errorValue = req->context; 36035c4bbdfSmrg return BadAlloc; 36135c4bbdfSmrg } 36235c4bbdfSmrg 36335c4bbdfSmrg return Success; 36435c4bbdfSmrg} 36535c4bbdfSmrg 36635c4bbdfSmrgint 36735c4bbdfSmrg__glXDispSwap_CreateContextAttribsARB(__GLXclientState * cl, GLbyte * pc) 36835c4bbdfSmrg{ 36935c4bbdfSmrg return BadRequest; 37035c4bbdfSmrg} 371