context.c revision 7e995a2e
17117f1b4Smrg/* 27117f1b4Smrg * Mesa 3-D graphics library 37117f1b4Smrg * 47117f1b4Smrg * Copyright (C) 1999-2007 Brian Paul All Rights Reserved. 5c1f859d4Smrg * Copyright (C) 2008 VMware, Inc. All Rights Reserved. 67117f1b4Smrg * 77117f1b4Smrg * Permission is hereby granted, free of charge, to any person obtaining a 87117f1b4Smrg * copy of this software and associated documentation files (the "Software"), 97117f1b4Smrg * to deal in the Software without restriction, including without limitation 107117f1b4Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 117117f1b4Smrg * and/or sell copies of the Software, and to permit persons to whom the 127117f1b4Smrg * Software is furnished to do so, subject to the following conditions: 137117f1b4Smrg * 147117f1b4Smrg * The above copyright notice and this permission notice shall be included 157117f1b4Smrg * in all copies or substantial portions of the Software. 167117f1b4Smrg * 177117f1b4Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 187117f1b4Smrg * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 197117f1b4Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 20b167d5e7Smrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 21b167d5e7Smrg * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 22b167d5e7Smrg * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 23b167d5e7Smrg * OTHER DEALINGS IN THE SOFTWARE. 247117f1b4Smrg */ 257117f1b4Smrg 26c1f859d4Smrg/** 27c1f859d4Smrg * \file context.c 28c1f859d4Smrg * Mesa context/visual/framebuffer management functions. 29c1f859d4Smrg * \author Brian Paul 30c1f859d4Smrg */ 317117f1b4Smrg 327117f1b4Smrg/** 337117f1b4Smrg * \mainpage Mesa Main Module 347117f1b4Smrg * 357117f1b4Smrg * \section MainIntroduction Introduction 367117f1b4Smrg * 377117f1b4Smrg * The Mesa Main module consists of all the files in the main/ directory. 387117f1b4Smrg * Among the features of this module are: 397117f1b4Smrg * <UL> 407117f1b4Smrg * <LI> Structures to represent most GL state </LI> 417117f1b4Smrg * <LI> State set/get functions </LI> 427117f1b4Smrg * <LI> Display lists </LI> 437117f1b4Smrg * <LI> Texture unit, object and image handling </LI> 447117f1b4Smrg * <LI> Matrix and attribute stacks </LI> 457117f1b4Smrg * </UL> 467117f1b4Smrg * 477117f1b4Smrg * Other modules are responsible for API dispatch, vertex transformation, 487117f1b4Smrg * point/line/triangle setup, rasterization, vertex array caching, 497117f1b4Smrg * vertex/fragment programs/shaders, etc. 507117f1b4Smrg * 517117f1b4Smrg * 527117f1b4Smrg * \section AboutDoxygen About Doxygen 537117f1b4Smrg * 547117f1b4Smrg * If you're viewing this information as Doxygen-generated HTML you'll 557117f1b4Smrg * see the documentation index at the top of this page. 567117f1b4Smrg * 577117f1b4Smrg * The first line lists the Mesa source code modules. 587117f1b4Smrg * The second line lists the indexes available for viewing the documentation 597117f1b4Smrg * for each module. 607117f1b4Smrg * 617117f1b4Smrg * Selecting the <b>Main page</b> link will display a summary of the module 627117f1b4Smrg * (this page). 637117f1b4Smrg * 647117f1b4Smrg * Selecting <b>Data Structures</b> will list all C structures. 657117f1b4Smrg * 667117f1b4Smrg * Selecting the <b>File List</b> link will list all the source files in 677117f1b4Smrg * the module. 687117f1b4Smrg * Selecting a filename will show a list of all functions defined in that file. 697117f1b4Smrg * 707117f1b4Smrg * Selecting the <b>Data Fields</b> link will display a list of all 717117f1b4Smrg * documented structure members. 727117f1b4Smrg * 737117f1b4Smrg * Selecting the <b>Globals</b> link will display a list 747117f1b4Smrg * of all functions, structures, global variables and macros in the module. 757117f1b4Smrg * 767117f1b4Smrg */ 777117f1b4Smrg 787117f1b4Smrg 797117f1b4Smrg#include "glheader.h" 807117f1b4Smrg#include "imports.h" 817117f1b4Smrg#include "accum.h" 82c1f859d4Smrg#include "api_exec.h" 83b167d5e7Smrg#include "api_loopback.h" 847117f1b4Smrg#include "arrayobj.h" 857117f1b4Smrg#include "attrib.h" 867e995a2eSmrg#include "bbox.h" 877117f1b4Smrg#include "blend.h" 887117f1b4Smrg#include "buffers.h" 897117f1b4Smrg#include "bufferobj.h" 907e995a2eSmrg#include "conservativeraster.h" 917117f1b4Smrg#include "context.h" 924a49301eSmrg#include "cpuinfo.h" 937117f1b4Smrg#include "debug.h" 947e995a2eSmrg#include "debug_output.h" 957117f1b4Smrg#include "depth.h" 967117f1b4Smrg#include "dlist.h" 977117f1b4Smrg#include "eval.h" 987117f1b4Smrg#include "extensions.h" 997117f1b4Smrg#include "fbobject.h" 1007117f1b4Smrg#include "feedback.h" 1017117f1b4Smrg#include "fog.h" 1023464ebd5Sriastradh#include "formats.h" 1037117f1b4Smrg#include "framebuffer.h" 1047e995a2eSmrg#include "glthread.h" 1057117f1b4Smrg#include "hint.h" 1067117f1b4Smrg#include "hash.h" 1077117f1b4Smrg#include "light.h" 1087117f1b4Smrg#include "lines.h" 1097117f1b4Smrg#include "macros.h" 1107117f1b4Smrg#include "matrix.h" 111c1f859d4Smrg#include "multisample.h" 112b167d5e7Smrg#include "performance_monitor.h" 1137e995a2eSmrg#include "performance_query.h" 114b167d5e7Smrg#include "pipelineobj.h" 1157117f1b4Smrg#include "pixel.h" 116c1f859d4Smrg#include "pixelstore.h" 1177117f1b4Smrg#include "points.h" 1187117f1b4Smrg#include "polygon.h" 1197117f1b4Smrg#include "queryobj.h" 1204a49301eSmrg#include "syncobj.h" 1217117f1b4Smrg#include "rastpos.h" 1224a49301eSmrg#include "remap.h" 123c1f859d4Smrg#include "scissor.h" 1244a49301eSmrg#include "shared.h" 1253464ebd5Sriastradh#include "shaderobj.h" 1267e995a2eSmrg#include "shaderimage.h" 1277117f1b4Smrg#include "state.h" 1287e995a2eSmrg#include "util/debug.h" 1297e995a2eSmrg#include "util/disk_cache.h" 1307e995a2eSmrg#include "util/strtod.h" 1317117f1b4Smrg#include "stencil.h" 1324a49301eSmrg#include "texcompress_s3tc.h" 1337117f1b4Smrg#include "texstate.h" 1343464ebd5Sriastradh#include "transformfeedback.h" 1357117f1b4Smrg#include "mtypes.h" 1367117f1b4Smrg#include "varray.h" 1377117f1b4Smrg#include "version.h" 1384a49301eSmrg#include "viewport.h" 1397e995a2eSmrg#include "texturebindless.h" 1403464ebd5Sriastradh#include "program/program.h" 1417117f1b4Smrg#include "math/m_matrix.h" 1423464ebd5Sriastradh#include "main/dispatch.h" /* for _gloffset_COUNT */ 1437e995a2eSmrg#include "macros.h" 1447e995a2eSmrg#include "git_sha1.h" 1457117f1b4Smrg 1467117f1b4Smrg#ifdef USE_SPARC_ASM 1477117f1b4Smrg#include "sparc/sparc.h" 1487117f1b4Smrg#endif 1497117f1b4Smrg 1507e995a2eSmrg#include "compiler/glsl_types.h" 1517e995a2eSmrg#include "compiler/glsl/glsl_parser_extras.h" 1523464ebd5Sriastradh#include <stdbool.h> 1533464ebd5Sriastradh 1543464ebd5Sriastradh 1557117f1b4Smrg#ifndef MESA_VERBOSE 1567117f1b4Smrgint MESA_VERBOSE = 0; 1577117f1b4Smrg#endif 1587117f1b4Smrg 1597117f1b4Smrg#ifndef MESA_DEBUG_FLAGS 1607117f1b4Smrgint MESA_DEBUG_FLAGS = 0; 1617117f1b4Smrg#endif 1627117f1b4Smrg 1637117f1b4Smrg 1647117f1b4Smrg/* ubyte -> float conversion */ 1657117f1b4SmrgGLfloat _mesa_ubyte_to_float_color_tab[256]; 1667117f1b4Smrg 1677117f1b4Smrg 1687117f1b4Smrg 1697117f1b4Smrg/** 1707117f1b4Smrg * Swap buffers notification callback. 1717e995a2eSmrg * 1724a49301eSmrg * \param ctx GL context. 1737117f1b4Smrg * 1747117f1b4Smrg * Called by window system just before swapping buffers. 1757117f1b4Smrg * We have to finish any pending rendering. 1767117f1b4Smrg */ 1777117f1b4Smrgvoid 1783464ebd5Sriastradh_mesa_notifySwapBuffers(struct gl_context *ctx) 1797117f1b4Smrg{ 1804a49301eSmrg if (MESA_VERBOSE & VERBOSE_SWAPBUFFERS) 1814a49301eSmrg _mesa_debug(ctx, "SwapBuffers\n"); 1824a49301eSmrg FLUSH_CURRENT( ctx, 0 ); 1834a49301eSmrg if (ctx->Driver.Flush) { 1844a49301eSmrg ctx->Driver.Flush(ctx); 1854a49301eSmrg } 1867117f1b4Smrg} 1877117f1b4Smrg 1887117f1b4Smrg 1897117f1b4Smrg/**********************************************************************/ 1907117f1b4Smrg/** \name GL Visual allocation/destruction */ 1917117f1b4Smrg/**********************************************************************/ 1927117f1b4Smrg/*@{*/ 1937117f1b4Smrg 1947117f1b4Smrg/** 1953464ebd5Sriastradh * Allocates a struct gl_config structure and initializes it via 1967117f1b4Smrg * _mesa_initialize_visual(). 1977e995a2eSmrg * 1987117f1b4Smrg * \param dbFlag double buffering 1997117f1b4Smrg * \param stereoFlag stereo buffer 2007117f1b4Smrg * \param depthBits requested bits per depth buffer value. Any value in [0, 32] 2017117f1b4Smrg * is acceptable but the actual depth type will be GLushort or GLuint as 2027117f1b4Smrg * needed. 2037117f1b4Smrg * \param stencilBits requested minimum bits per stencil buffer value 2043464ebd5Sriastradh * \param accumRedBits, accumGreenBits, accumBlueBits, accumAlphaBits number 2053464ebd5Sriastradh * of bits per color component in accum buffer. 2067117f1b4Smrg * \param indexBits number of bits per pixel if \p rgbFlag is GL_FALSE 2077117f1b4Smrg * \param redBits number of bits per color component in frame buffer for RGB(A) 2087117f1b4Smrg * mode. We always use 8 in core Mesa though. 2097117f1b4Smrg * \param greenBits same as above. 2107117f1b4Smrg * \param blueBits same as above. 2117117f1b4Smrg * \param alphaBits same as above. 2127117f1b4Smrg * \param numSamples not really used. 2137e995a2eSmrg * 2143464ebd5Sriastradh * \return pointer to new struct gl_config or NULL if requested parameters 2153464ebd5Sriastradh * can't be met. 2167117f1b4Smrg * 2177117f1b4Smrg * \note Need to add params for level and numAuxBuffers (at least) 2187117f1b4Smrg */ 2193464ebd5Sriastradhstruct gl_config * 220cdc920a0Smrg_mesa_create_visual( GLboolean dbFlag, 2217117f1b4Smrg GLboolean stereoFlag, 2227117f1b4Smrg GLint redBits, 2237117f1b4Smrg GLint greenBits, 2247117f1b4Smrg GLint blueBits, 2257117f1b4Smrg GLint alphaBits, 2267117f1b4Smrg GLint depthBits, 2277117f1b4Smrg GLint stencilBits, 2287117f1b4Smrg GLint accumRedBits, 2297117f1b4Smrg GLint accumGreenBits, 2307117f1b4Smrg GLint accumBlueBits, 2317117f1b4Smrg GLint accumAlphaBits, 2327e995a2eSmrg GLuint numSamples ) 2337117f1b4Smrg{ 2343464ebd5Sriastradh struct gl_config *vis = CALLOC_STRUCT(gl_config); 2357117f1b4Smrg if (vis) { 236cdc920a0Smrg if (!_mesa_initialize_visual(vis, dbFlag, stereoFlag, 2377117f1b4Smrg redBits, greenBits, blueBits, alphaBits, 238cdc920a0Smrg depthBits, stencilBits, 2397117f1b4Smrg accumRedBits, accumGreenBits, 2407117f1b4Smrg accumBlueBits, accumAlphaBits, 2417117f1b4Smrg numSamples)) { 242cdc920a0Smrg free(vis); 2437117f1b4Smrg return NULL; 2447117f1b4Smrg } 2457117f1b4Smrg } 2467117f1b4Smrg return vis; 2477117f1b4Smrg} 2487117f1b4Smrg 2493464ebd5Sriastradh 2507117f1b4Smrg/** 2513464ebd5Sriastradh * Makes some sanity checks and fills in the fields of the struct 2523464ebd5Sriastradh * gl_config object with the given parameters. If the caller needs to 2533464ebd5Sriastradh * set additional fields, he should just probably init the whole 2543464ebd5Sriastradh * gl_config object himself. 2553464ebd5Sriastradh * 2567117f1b4Smrg * \return GL_TRUE on success, or GL_FALSE on failure. 2577117f1b4Smrg * 2587117f1b4Smrg * \sa _mesa_create_visual() above for the parameter description. 2597117f1b4Smrg */ 2607117f1b4SmrgGLboolean 2613464ebd5Sriastradh_mesa_initialize_visual( struct gl_config *vis, 2627117f1b4Smrg GLboolean dbFlag, 2637117f1b4Smrg GLboolean stereoFlag, 2647117f1b4Smrg GLint redBits, 2657117f1b4Smrg GLint greenBits, 2667117f1b4Smrg GLint blueBits, 2677117f1b4Smrg GLint alphaBits, 2687117f1b4Smrg GLint depthBits, 2697117f1b4Smrg GLint stencilBits, 2707117f1b4Smrg GLint accumRedBits, 2717117f1b4Smrg GLint accumGreenBits, 2727117f1b4Smrg GLint accumBlueBits, 2737117f1b4Smrg GLint accumAlphaBits, 2747e995a2eSmrg GLuint numSamples ) 2757117f1b4Smrg{ 2767117f1b4Smrg assert(vis); 2777117f1b4Smrg 2787117f1b4Smrg if (depthBits < 0 || depthBits > 32) { 2797117f1b4Smrg return GL_FALSE; 2807117f1b4Smrg } 281b167d5e7Smrg if (stencilBits < 0 || stencilBits > 8) { 2827117f1b4Smrg return GL_FALSE; 2837117f1b4Smrg } 2847117f1b4Smrg assert(accumRedBits >= 0); 2857117f1b4Smrg assert(accumGreenBits >= 0); 2867117f1b4Smrg assert(accumBlueBits >= 0); 2877117f1b4Smrg assert(accumAlphaBits >= 0); 2887117f1b4Smrg 289cdc920a0Smrg vis->rgbMode = GL_TRUE; 2907117f1b4Smrg vis->doubleBufferMode = dbFlag; 2917117f1b4Smrg vis->stereoMode = stereoFlag; 2927117f1b4Smrg 2937117f1b4Smrg vis->redBits = redBits; 2947117f1b4Smrg vis->greenBits = greenBits; 2957117f1b4Smrg vis->blueBits = blueBits; 2967117f1b4Smrg vis->alphaBits = alphaBits; 2977117f1b4Smrg vis->rgbBits = redBits + greenBits + blueBits; 2987117f1b4Smrg 299cdc920a0Smrg vis->indexBits = 0; 3007117f1b4Smrg vis->depthBits = depthBits; 3017117f1b4Smrg vis->stencilBits = stencilBits; 3027117f1b4Smrg 3037117f1b4Smrg vis->accumRedBits = accumRedBits; 3047117f1b4Smrg vis->accumGreenBits = accumGreenBits; 3057117f1b4Smrg vis->accumBlueBits = accumBlueBits; 3067117f1b4Smrg vis->accumAlphaBits = accumAlphaBits; 3077117f1b4Smrg 3087117f1b4Smrg vis->haveAccumBuffer = accumRedBits > 0; 3097117f1b4Smrg vis->haveDepthBuffer = depthBits > 0; 3107117f1b4Smrg vis->haveStencilBuffer = stencilBits > 0; 3117117f1b4Smrg 3127117f1b4Smrg vis->numAuxBuffers = 0; 3137117f1b4Smrg vis->level = 0; 3147117f1b4Smrg vis->sampleBuffers = numSamples > 0 ? 1 : 0; 3157117f1b4Smrg vis->samples = numSamples; 3167117f1b4Smrg 3177117f1b4Smrg return GL_TRUE; 3187117f1b4Smrg} 3197117f1b4Smrg 3207117f1b4Smrg 3217117f1b4Smrg/** 3227117f1b4Smrg * Destroy a visual and free its memory. 3237117f1b4Smrg * 3247117f1b4Smrg * \param vis visual. 3257e995a2eSmrg * 3267117f1b4Smrg * Frees the visual structure. 3277117f1b4Smrg */ 3287117f1b4Smrgvoid 3293464ebd5Sriastradh_mesa_destroy_visual( struct gl_config *vis ) 3307117f1b4Smrg{ 331cdc920a0Smrg free(vis); 3327117f1b4Smrg} 3337117f1b4Smrg 3347117f1b4Smrg/*@}*/ 3357117f1b4Smrg 3367117f1b4Smrg 3377117f1b4Smrg/**********************************************************************/ 3387117f1b4Smrg/** \name Context allocation, initialization, destroying 3397117f1b4Smrg * 3407117f1b4Smrg * The purpose of the most initialization functions here is to provide the 3417117f1b4Smrg * default state values according to the OpenGL specification. 3427117f1b4Smrg */ 3437117f1b4Smrg/**********************************************************************/ 3447117f1b4Smrg/*@{*/ 3457117f1b4Smrg 3464a49301eSmrg 3477117f1b4Smrg/** 3487117f1b4Smrg * One-time initialization mutex lock. 3497117f1b4Smrg * 3507117f1b4Smrg * \sa Used by one_time_init(). 3517117f1b4Smrg */ 352b167d5e7Smrgmtx_t OneTimeLock = _MTX_INITIALIZER_NP; 3537117f1b4Smrg 3543464ebd5Sriastradh 3557e995a2eSmrg/** 3567e995a2eSmrg * Calls all the various one-time-fini functions in Mesa 3577e995a2eSmrg */ 3587e995a2eSmrg 3597e995a2eSmrgstatic GLbitfield api_init_mask = 0x0; 3607e995a2eSmrgstatic void __attribute__((__destructor__)) 3617e995a2eSmrgone_time_fini(void) 3627e995a2eSmrg{ 3637e995a2eSmrg if (api_init_mask) { 3647e995a2eSmrg _mesa_destroy_shader_compiler(); 3657e995a2eSmrg _mesa_locale_fini(); 3667e995a2eSmrg } 3677e995a2eSmrg} 3683464ebd5Sriastradh 3697117f1b4Smrg/** 3707117f1b4Smrg * Calls all the various one-time-init functions in Mesa. 3717117f1b4Smrg * 3727117f1b4Smrg * While holding a global mutex lock, calls several initialization functions, 3737117f1b4Smrg * and sets the glapi callbacks if the \c MESA_DEBUG environment variable is 3747117f1b4Smrg * defined. 3757117f1b4Smrg * 3767117f1b4Smrg * \sa _math_init(). 3777117f1b4Smrg */ 3787117f1b4Smrgstatic void 3793464ebd5Sriastradhone_time_init( struct gl_context *ctx ) 3807117f1b4Smrg{ 3813464ebd5Sriastradh 382b167d5e7Smrg mtx_lock(&OneTimeLock); 3833464ebd5Sriastradh 3843464ebd5Sriastradh /* truly one-time init */ 3853464ebd5Sriastradh if (!api_init_mask) { 3867117f1b4Smrg GLuint i; 3877117f1b4Smrg 3887e995a2eSmrg STATIC_ASSERT(sizeof(GLbyte) == 1); 3897e995a2eSmrg STATIC_ASSERT(sizeof(GLubyte) == 1); 3907e995a2eSmrg STATIC_ASSERT(sizeof(GLshort) == 2); 3917e995a2eSmrg STATIC_ASSERT(sizeof(GLushort) == 2); 3927e995a2eSmrg STATIC_ASSERT(sizeof(GLint) == 4); 3937e995a2eSmrg STATIC_ASSERT(sizeof(GLuint) == 4); 3947e995a2eSmrg 3957e995a2eSmrg _mesa_locale_init(); 3967117f1b4Smrg 3977e995a2eSmrg _mesa_one_time_init_extension_overrides(ctx); 3987117f1b4Smrg 399b167d5e7Smrg _mesa_get_cpu_features(); 4003464ebd5Sriastradh 4017117f1b4Smrg for (i = 0; i < 256; i++) { 4027117f1b4Smrg _mesa_ubyte_to_float_color_tab[i] = (float) i / 255.0F; 4037117f1b4Smrg } 4047117f1b4Smrg 4057e995a2eSmrg#if defined(DEBUG) 4063464ebd5Sriastradh if (MESA_VERBOSE != 0) { 4077e995a2eSmrg _mesa_debug(ctx, "Mesa " PACKAGE_VERSION " DEBUG build" MESA_GIT_SHA1 "\n"); 4083464ebd5Sriastradh } 4097117f1b4Smrg#endif 4107117f1b4Smrg } 4113464ebd5Sriastradh 4123464ebd5Sriastradh /* per-API one-time init */ 4133464ebd5Sriastradh if (!(api_init_mask & (1 << ctx->API))) { 414b167d5e7Smrg _mesa_init_remap_table(); 4153464ebd5Sriastradh } 4163464ebd5Sriastradh 4173464ebd5Sriastradh api_init_mask |= 1 << ctx->API; 4183464ebd5Sriastradh 419b167d5e7Smrg mtx_unlock(&OneTimeLock); 420eabf4f72Sriastradh} 421eabf4f72Sriastradh 4227117f1b4Smrg 4237117f1b4Smrg/** 4247117f1b4Smrg * Initialize fields of gl_current_attrib (aka ctx->Current.*) 4257117f1b4Smrg */ 4267117f1b4Smrgstatic void 4273464ebd5Sriastradh_mesa_init_current(struct gl_context *ctx) 4287117f1b4Smrg{ 4297117f1b4Smrg GLuint i; 4307117f1b4Smrg 4317117f1b4Smrg /* Init all to (0,0,0,1) */ 4327e995a2eSmrg for (i = 0; i < ARRAY_SIZE(ctx->Current.Attrib); i++) { 4337117f1b4Smrg ASSIGN_4V( ctx->Current.Attrib[i], 0.0, 0.0, 0.0, 1.0 ); 4347117f1b4Smrg } 4357117f1b4Smrg 4367117f1b4Smrg /* redo special cases: */ 4377117f1b4Smrg ASSIGN_4V( ctx->Current.Attrib[VERT_ATTRIB_NORMAL], 0.0, 0.0, 1.0, 1.0 ); 4387117f1b4Smrg ASSIGN_4V( ctx->Current.Attrib[VERT_ATTRIB_COLOR0], 1.0, 1.0, 1.0, 1.0 ); 4397117f1b4Smrg ASSIGN_4V( ctx->Current.Attrib[VERT_ATTRIB_COLOR1], 0.0, 0.0, 0.0, 1.0 ); 4407117f1b4Smrg ASSIGN_4V( ctx->Current.Attrib[VERT_ATTRIB_COLOR_INDEX], 1.0, 0.0, 0.0, 1.0 ); 4417117f1b4Smrg ASSIGN_4V( ctx->Current.Attrib[VERT_ATTRIB_EDGEFLAG], 1.0, 0.0, 0.0, 1.0 ); 4427117f1b4Smrg} 4437117f1b4Smrg 4447117f1b4Smrg 4457117f1b4Smrg/** 4463464ebd5Sriastradh * Init vertex/fragment/geometry program limits. 4474a49301eSmrg * Important: drivers should override these with actual limits. 4487117f1b4Smrg */ 4497117f1b4Smrgstatic void 450b167d5e7Smrginit_program_limits(struct gl_constants *consts, gl_shader_stage stage, 451b167d5e7Smrg struct gl_program_constants *prog) 4527117f1b4Smrg{ 4534a49301eSmrg prog->MaxInstructions = MAX_PROGRAM_INSTRUCTIONS; 4544a49301eSmrg prog->MaxAluInstructions = MAX_PROGRAM_INSTRUCTIONS; 4554a49301eSmrg prog->MaxTexInstructions = MAX_PROGRAM_INSTRUCTIONS; 4564a49301eSmrg prog->MaxTexIndirections = MAX_PROGRAM_INSTRUCTIONS; 4574a49301eSmrg prog->MaxTemps = MAX_PROGRAM_TEMPS; 4584a49301eSmrg prog->MaxEnvParams = MAX_PROGRAM_ENV_PARAMS; 4594a49301eSmrg prog->MaxLocalParams = MAX_PROGRAM_LOCAL_PARAMS; 4603464ebd5Sriastradh prog->MaxAddressOffset = MAX_PROGRAM_LOCAL_PARAMS; 4614a49301eSmrg 462b167d5e7Smrg switch (stage) { 463b167d5e7Smrg case MESA_SHADER_VERTEX: 4644a49301eSmrg prog->MaxParameters = MAX_VERTEX_PROGRAM_PARAMS; 465b167d5e7Smrg prog->MaxAttribs = MAX_VERTEX_GENERIC_ATTRIBS; 4664a49301eSmrg prog->MaxAddressRegs = MAX_VERTEX_PROGRAM_ADDRESS_REGS; 4673464ebd5Sriastradh prog->MaxUniformComponents = 4 * MAX_UNIFORMS; 468b167d5e7Smrg prog->MaxInputComponents = 0; /* value not used */ 469b167d5e7Smrg prog->MaxOutputComponents = 16 * 4; /* old limit not to break tnl and swrast */ 4703464ebd5Sriastradh break; 471b167d5e7Smrg case MESA_SHADER_FRAGMENT: 4727e995a2eSmrg prog->MaxParameters = MAX_FRAGMENT_PROGRAM_PARAMS; 4737e995a2eSmrg prog->MaxAttribs = MAX_FRAGMENT_PROGRAM_INPUTS; 4744a49301eSmrg prog->MaxAddressRegs = MAX_FRAGMENT_PROGRAM_ADDRESS_REGS; 4753464ebd5Sriastradh prog->MaxUniformComponents = 4 * MAX_UNIFORMS; 476b167d5e7Smrg prog->MaxInputComponents = 16 * 4; /* old limit not to break tnl and swrast */ 477b167d5e7Smrg prog->MaxOutputComponents = 0; /* value not used */ 4783464ebd5Sriastradh break; 4797e995a2eSmrg case MESA_SHADER_TESS_CTRL: 4807e995a2eSmrg case MESA_SHADER_TESS_EVAL: 481b167d5e7Smrg case MESA_SHADER_GEOMETRY: 482b167d5e7Smrg prog->MaxParameters = MAX_VERTEX_PROGRAM_PARAMS; 483b167d5e7Smrg prog->MaxAttribs = MAX_VERTEX_GENERIC_ATTRIBS; 4843464ebd5Sriastradh prog->MaxAddressRegs = MAX_VERTEX_PROGRAM_ADDRESS_REGS; 485b167d5e7Smrg prog->MaxUniformComponents = 4 * MAX_UNIFORMS; 486b167d5e7Smrg prog->MaxInputComponents = 16 * 4; /* old limit not to break tnl and swrast */ 487b167d5e7Smrg prog->MaxOutputComponents = 16 * 4; /* old limit not to break tnl and swrast */ 488b167d5e7Smrg break; 489b167d5e7Smrg case MESA_SHADER_COMPUTE: 490b167d5e7Smrg prog->MaxParameters = 0; /* not meaningful for compute shaders */ 491b167d5e7Smrg prog->MaxAttribs = 0; /* not meaningful for compute shaders */ 492b167d5e7Smrg prog->MaxAddressRegs = 0; /* not meaningful for compute shaders */ 493b167d5e7Smrg prog->MaxUniformComponents = 4 * MAX_UNIFORMS; 494b167d5e7Smrg prog->MaxInputComponents = 0; /* not meaningful for compute shaders */ 495b167d5e7Smrg prog->MaxOutputComponents = 0; /* not meaningful for compute shaders */ 4963464ebd5Sriastradh break; 4973464ebd5Sriastradh default: 498b167d5e7Smrg assert(0 && "Bad shader stage in init_program_limits()"); 4994a49301eSmrg } 5004a49301eSmrg 5014a49301eSmrg /* Set the native limits to zero. This implies that there is no native 5024a49301eSmrg * support for shaders. Let the drivers fill in the actual values. 5034a49301eSmrg */ 5044a49301eSmrg prog->MaxNativeInstructions = 0; 5054a49301eSmrg prog->MaxNativeAluInstructions = 0; 5064a49301eSmrg prog->MaxNativeTexInstructions = 0; 5074a49301eSmrg prog->MaxNativeTexIndirections = 0; 5084a49301eSmrg prog->MaxNativeAttribs = 0; 5094a49301eSmrg prog->MaxNativeTemps = 0; 5104a49301eSmrg prog->MaxNativeAddressRegs = 0; 5114a49301eSmrg prog->MaxNativeParameters = 0; 5123464ebd5Sriastradh 5133464ebd5Sriastradh /* Set GLSL datatype range/precision info assuming IEEE float values. 5143464ebd5Sriastradh * Drivers should override these defaults as needed. 5153464ebd5Sriastradh */ 5163464ebd5Sriastradh prog->MediumFloat.RangeMin = 127; 5173464ebd5Sriastradh prog->MediumFloat.RangeMax = 127; 5183464ebd5Sriastradh prog->MediumFloat.Precision = 23; 5193464ebd5Sriastradh prog->LowFloat = prog->HighFloat = prog->MediumFloat; 5203464ebd5Sriastradh 5213464ebd5Sriastradh /* Assume ints are stored as floats for now, since this is the least-common 5223464ebd5Sriastradh * denominator. The OpenGL ES spec implies (page 132) that the precision 5233464ebd5Sriastradh * of integer types should be 0. Practically speaking, IEEE 5243464ebd5Sriastradh * single-precision floating point values can only store integers in the 5253464ebd5Sriastradh * range [-0x01000000, 0x01000000] without loss of precision. 5263464ebd5Sriastradh */ 5273464ebd5Sriastradh prog->MediumInt.RangeMin = 24; 5283464ebd5Sriastradh prog->MediumInt.RangeMax = 24; 5293464ebd5Sriastradh prog->MediumInt.Precision = 0; 5303464ebd5Sriastradh prog->LowInt = prog->HighInt = prog->MediumInt; 531b167d5e7Smrg 532b167d5e7Smrg prog->MaxUniformBlocks = 12; 533b167d5e7Smrg prog->MaxCombinedUniformComponents = (prog->MaxUniformComponents + 534b167d5e7Smrg consts->MaxUniformBlockSize / 4 * 535b167d5e7Smrg prog->MaxUniformBlocks); 536b167d5e7Smrg 537b167d5e7Smrg prog->MaxAtomicBuffers = 0; 538b167d5e7Smrg prog->MaxAtomicCounters = 0; 5397e995a2eSmrg 5407e995a2eSmrg prog->MaxShaderStorageBlocks = 8; 5417117f1b4Smrg} 5427117f1b4Smrg 5437117f1b4Smrg 5447117f1b4Smrg/** 5457117f1b4Smrg * Initialize fields of gl_constants (aka ctx->Const.*). 5467117f1b4Smrg * Use defaults from config.h. The device drivers will often override 5477117f1b4Smrg * some of these values (such as number of texture units). 5487117f1b4Smrg */ 549b167d5e7Smrgvoid 550b167d5e7Smrg_mesa_init_constants(struct gl_constants *consts, gl_api api) 5517117f1b4Smrg{ 552b167d5e7Smrg int i; 553b167d5e7Smrg assert(consts); 5547117f1b4Smrg 5557117f1b4Smrg /* Constants, may be overriden (usually only reduced) by device drivers */ 556b167d5e7Smrg consts->MaxTextureMbytes = MAX_TEXTURE_MBYTES; 557b167d5e7Smrg consts->MaxTextureLevels = MAX_TEXTURE_LEVELS; 558b167d5e7Smrg consts->Max3DTextureLevels = MAX_3D_TEXTURE_LEVELS; 559b167d5e7Smrg consts->MaxCubeTextureLevels = MAX_CUBE_TEXTURE_LEVELS; 560b167d5e7Smrg consts->MaxTextureRectSize = MAX_TEXTURE_RECT_SIZE; 561b167d5e7Smrg consts->MaxArrayTextureLayers = MAX_ARRAY_TEXTURE_LAYERS; 562b167d5e7Smrg consts->MaxTextureCoordUnits = MAX_TEXTURE_COORD_UNITS; 563b167d5e7Smrg consts->Program[MESA_SHADER_FRAGMENT].MaxTextureImageUnits = MAX_TEXTURE_IMAGE_UNITS; 564b167d5e7Smrg consts->MaxTextureUnits = MIN2(consts->MaxTextureCoordUnits, 565b167d5e7Smrg consts->Program[MESA_SHADER_FRAGMENT].MaxTextureImageUnits); 566b167d5e7Smrg consts->MaxTextureMaxAnisotropy = MAX_TEXTURE_MAX_ANISOTROPY; 567b167d5e7Smrg consts->MaxTextureLodBias = MAX_TEXTURE_LOD_BIAS; 568b167d5e7Smrg consts->MaxTextureBufferSize = 65536; 569b167d5e7Smrg consts->TextureBufferOffsetAlignment = 1; 570b167d5e7Smrg consts->MaxArrayLockSize = MAX_ARRAY_LOCK_SIZE; 571b167d5e7Smrg consts->SubPixelBits = SUB_PIXEL_BITS; 572b167d5e7Smrg consts->MinPointSize = MIN_POINT_SIZE; 573b167d5e7Smrg consts->MaxPointSize = MAX_POINT_SIZE; 574b167d5e7Smrg consts->MinPointSizeAA = MIN_POINT_SIZE; 575b167d5e7Smrg consts->MaxPointSizeAA = MAX_POINT_SIZE; 576b167d5e7Smrg consts->PointSizeGranularity = (GLfloat) POINT_SIZE_GRANULARITY; 577b167d5e7Smrg consts->MinLineWidth = MIN_LINE_WIDTH; 578b167d5e7Smrg consts->MaxLineWidth = MAX_LINE_WIDTH; 579b167d5e7Smrg consts->MinLineWidthAA = MIN_LINE_WIDTH; 580b167d5e7Smrg consts->MaxLineWidthAA = MAX_LINE_WIDTH; 581b167d5e7Smrg consts->LineWidthGranularity = (GLfloat) LINE_WIDTH_GRANULARITY; 582b167d5e7Smrg consts->MaxClipPlanes = 6; 583b167d5e7Smrg consts->MaxLights = MAX_LIGHTS; 584b167d5e7Smrg consts->MaxShininess = 128.0; 585b167d5e7Smrg consts->MaxSpotExponent = 128.0; 5867e995a2eSmrg consts->MaxViewportWidth = 16384; 5877e995a2eSmrg consts->MaxViewportHeight = 16384; 588b167d5e7Smrg consts->MinMapBufferAlignment = 64; 589b167d5e7Smrg 590b167d5e7Smrg /* Driver must override these values if ARB_viewport_array is supported. */ 591b167d5e7Smrg consts->MaxViewports = 1; 592b167d5e7Smrg consts->ViewportSubpixelBits = 0; 593b167d5e7Smrg consts->ViewportBounds.Min = 0; 594b167d5e7Smrg consts->ViewportBounds.Max = 0; 595b167d5e7Smrg 596b167d5e7Smrg /** GL_ARB_uniform_buffer_object */ 597b167d5e7Smrg consts->MaxCombinedUniformBlocks = 36; 598b167d5e7Smrg consts->MaxUniformBufferBindings = 36; 599b167d5e7Smrg consts->MaxUniformBlockSize = 16384; 600b167d5e7Smrg consts->UniformBufferOffsetAlignment = 1; 601b167d5e7Smrg 6027e995a2eSmrg /** GL_ARB_shader_storage_buffer_object */ 6037e995a2eSmrg consts->MaxCombinedShaderStorageBlocks = 8; 6047e995a2eSmrg consts->MaxShaderStorageBufferBindings = 8; 6057e995a2eSmrg consts->MaxShaderStorageBlockSize = 128 * 1024 * 1024; /* 2^27 */ 6067e995a2eSmrg consts->ShaderStorageBufferOffsetAlignment = 256; 6077e995a2eSmrg 608b167d5e7Smrg /* GL_ARB_explicit_uniform_location, GL_MAX_UNIFORM_LOCATIONS */ 609b167d5e7Smrg consts->MaxUserAssignableUniformLocations = 610b167d5e7Smrg 4 * MESA_SHADER_STAGES * MAX_UNIFORMS; 611b167d5e7Smrg 612b167d5e7Smrg for (i = 0; i < MESA_SHADER_STAGES; i++) 613b167d5e7Smrg init_program_limits(consts, i, &consts->Program[i]); 614b167d5e7Smrg 615b167d5e7Smrg consts->MaxProgramMatrices = MAX_PROGRAM_MATRICES; 616b167d5e7Smrg consts->MaxProgramMatrixStackDepth = MAX_PROGRAM_MATRIX_STACK_DEPTH; 617b167d5e7Smrg 618b167d5e7Smrg /* Assume that if GLSL 1.30+ (or GLSL ES 3.00+) is supported that 619b167d5e7Smrg * gl_VertexID is implemented using a native hardware register with OpenGL 620b167d5e7Smrg * semantics. 621b167d5e7Smrg */ 622b167d5e7Smrg consts->VertexID_is_zero_based = false; 6237117f1b4Smrg 6247117f1b4Smrg /* GL_ARB_draw_buffers */ 625b167d5e7Smrg consts->MaxDrawBuffers = MAX_DRAW_BUFFERS; 6267117f1b4Smrg 627b167d5e7Smrg consts->MaxColorAttachments = MAX_COLOR_ATTACHMENTS; 628b167d5e7Smrg consts->MaxRenderbufferSize = MAX_RENDERBUFFER_SIZE; 6297117f1b4Smrg 630b167d5e7Smrg consts->Program[MESA_SHADER_VERTEX].MaxTextureImageUnits = MAX_TEXTURE_IMAGE_UNITS; 631b167d5e7Smrg consts->MaxCombinedTextureImageUnits = MAX_COMBINED_TEXTURE_IMAGE_UNITS; 632b167d5e7Smrg consts->MaxVarying = 16; /* old limit not to break tnl and swrast */ 633b167d5e7Smrg consts->Program[MESA_SHADER_GEOMETRY].MaxTextureImageUnits = MAX_TEXTURE_IMAGE_UNITS; 634b167d5e7Smrg consts->MaxGeometryOutputVertices = MAX_GEOMETRY_OUTPUT_VERTICES; 635b167d5e7Smrg consts->MaxGeometryTotalOutputComponents = MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS; 6367e995a2eSmrg consts->MaxGeometryShaderInvocations = MAX_GEOMETRY_SHADER_INVOCATIONS; 6373464ebd5Sriastradh 6387e995a2eSmrg#ifdef DEBUG 6397e995a2eSmrg consts->GenerateTemporaryNames = true; 6407e995a2eSmrg#else 6417e995a2eSmrg consts->GenerateTemporaryNames = false; 6427e995a2eSmrg#endif 6437117f1b4Smrg 6444a49301eSmrg /* GL_ARB_framebuffer_object */ 645b167d5e7Smrg consts->MaxSamples = 0; 6464a49301eSmrg 647b167d5e7Smrg /* GLSL default if NativeIntegers == FALSE */ 6487e995a2eSmrg consts->UniformBooleanTrue = FLOAT_AS_UNION(1.0f).u; 6494a49301eSmrg 650b167d5e7Smrg /* GL_ARB_sync */ 6517e995a2eSmrg consts->MaxServerWaitTimeout = 0x7fffffff7fffffffULL; 6524a49301eSmrg 6534a49301eSmrg /* GL_EXT_provoking_vertex */ 654b167d5e7Smrg consts->QuadsFollowProvokingVertexConvention = GL_TRUE; 6553464ebd5Sriastradh 6567e995a2eSmrg /** GL_ARB_viewport_array */ 6577e995a2eSmrg consts->LayerAndVPIndexProvokingVertex = GL_UNDEFINED_VERTEX; 6587e995a2eSmrg 6593464ebd5Sriastradh /* GL_EXT_transform_feedback */ 660b167d5e7Smrg consts->MaxTransformFeedbackBuffers = MAX_FEEDBACK_BUFFERS; 661b167d5e7Smrg consts->MaxTransformFeedbackSeparateComponents = 4 * MAX_FEEDBACK_ATTRIBS; 662b167d5e7Smrg consts->MaxTransformFeedbackInterleavedComponents = 4 * MAX_FEEDBACK_ATTRIBS; 663b167d5e7Smrg consts->MaxVertexStreams = 1; 6643464ebd5Sriastradh 665b167d5e7Smrg /* GL 3.2 */ 666b167d5e7Smrg consts->ProfileMask = api == API_OPENGL_CORE 667b167d5e7Smrg ? GL_CONTEXT_CORE_PROFILE_BIT 668b167d5e7Smrg : GL_CONTEXT_COMPATIBILITY_PROFILE_BIT; 6693464ebd5Sriastradh 6707e995a2eSmrg /* GL 4.4 */ 6717e995a2eSmrg consts->MaxVertexAttribStride = 2048; 6727e995a2eSmrg 6733464ebd5Sriastradh /** GL_EXT_gpu_shader4 */ 674b167d5e7Smrg consts->MinProgramTexelOffset = -8; 675b167d5e7Smrg consts->MaxProgramTexelOffset = 7; 676b167d5e7Smrg 677b167d5e7Smrg /* GL_ARB_texture_gather */ 678b167d5e7Smrg consts->MinProgramTextureGatherOffset = -8; 679b167d5e7Smrg consts->MaxProgramTextureGatherOffset = 7; 6803464ebd5Sriastradh 6813464ebd5Sriastradh /* GL_ARB_robustness */ 682b167d5e7Smrg consts->ResetStrategy = GL_NO_RESET_NOTIFICATION_ARB; 683b167d5e7Smrg 6847e995a2eSmrg /* GL_KHR_robustness */ 6857e995a2eSmrg consts->RobustAccess = GL_FALSE; 686b167d5e7Smrg 687b167d5e7Smrg /* ES 3.0 or ARB_ES3_compatibility */ 688b167d5e7Smrg consts->MaxElementIndex = 0xffffffffu; 689b167d5e7Smrg 690b167d5e7Smrg /* GL_ARB_texture_multisample */ 691b167d5e7Smrg consts->MaxColorTextureSamples = 1; 692b167d5e7Smrg consts->MaxDepthTextureSamples = 1; 693b167d5e7Smrg consts->MaxIntegerSamples = 1; 694b167d5e7Smrg 695b167d5e7Smrg /* GL_ARB_shader_atomic_counters */ 696b167d5e7Smrg consts->MaxAtomicBufferBindings = MAX_COMBINED_ATOMIC_BUFFERS; 697b167d5e7Smrg consts->MaxAtomicBufferSize = MAX_ATOMIC_COUNTERS * ATOMIC_COUNTER_SIZE; 698b167d5e7Smrg consts->MaxCombinedAtomicBuffers = MAX_COMBINED_ATOMIC_BUFFERS; 699b167d5e7Smrg consts->MaxCombinedAtomicCounters = MAX_ATOMIC_COUNTERS; 700b167d5e7Smrg 701b167d5e7Smrg /* GL_ARB_vertex_attrib_binding */ 702b167d5e7Smrg consts->MaxVertexAttribRelativeOffset = 2047; 703b167d5e7Smrg consts->MaxVertexAttribBindings = MAX_VERTEX_GENERIC_ATTRIBS; 704b167d5e7Smrg 705b167d5e7Smrg /* GL_ARB_compute_shader */ 706b167d5e7Smrg consts->MaxComputeWorkGroupCount[0] = 65535; 707b167d5e7Smrg consts->MaxComputeWorkGroupCount[1] = 65535; 708b167d5e7Smrg consts->MaxComputeWorkGroupCount[2] = 65535; 709b167d5e7Smrg consts->MaxComputeWorkGroupSize[0] = 1024; 710b167d5e7Smrg consts->MaxComputeWorkGroupSize[1] = 1024; 711b167d5e7Smrg consts->MaxComputeWorkGroupSize[2] = 64; 7127e995a2eSmrg /* Enables compute support for GLES 3.1 if >= 128 */ 7137e995a2eSmrg consts->MaxComputeWorkGroupInvocations = 0; 714b167d5e7Smrg 715b167d5e7Smrg /** GL_ARB_gpu_shader5 */ 716b167d5e7Smrg consts->MinFragmentInterpolationOffset = MIN_FRAGMENT_INTERPOLATION_OFFSET; 717b167d5e7Smrg consts->MaxFragmentInterpolationOffset = MAX_FRAGMENT_INTERPOLATION_OFFSET; 7187e995a2eSmrg 7197e995a2eSmrg /** GL_KHR_context_flush_control */ 7207e995a2eSmrg consts->ContextReleaseBehavior = GL_CONTEXT_RELEASE_BEHAVIOR_FLUSH; 7217e995a2eSmrg 7227e995a2eSmrg /** GL_ARB_tessellation_shader */ 7237e995a2eSmrg consts->MaxTessGenLevel = MAX_TESS_GEN_LEVEL; 7247e995a2eSmrg consts->MaxPatchVertices = MAX_PATCH_VERTICES; 7257e995a2eSmrg consts->Program[MESA_SHADER_TESS_CTRL].MaxTextureImageUnits = MAX_TEXTURE_IMAGE_UNITS; 7267e995a2eSmrg consts->Program[MESA_SHADER_TESS_EVAL].MaxTextureImageUnits = MAX_TEXTURE_IMAGE_UNITS; 7277e995a2eSmrg consts->MaxTessPatchComponents = MAX_TESS_PATCH_COMPONENTS; 7287e995a2eSmrg consts->MaxTessControlTotalOutputComponents = MAX_TESS_CONTROL_TOTAL_OUTPUT_COMPONENTS; 7297e995a2eSmrg consts->PrimitiveRestartForPatches = false; 7307e995a2eSmrg 7317e995a2eSmrg /** GL_ARB_compute_variable_group_size */ 7327e995a2eSmrg consts->MaxComputeVariableGroupSize[0] = 512; 7337e995a2eSmrg consts->MaxComputeVariableGroupSize[1] = 512; 7347e995a2eSmrg consts->MaxComputeVariableGroupSize[2] = 64; 7357e995a2eSmrg consts->MaxComputeVariableGroupInvocations = 512; 7367e995a2eSmrg 7377e995a2eSmrg /** GL_NV_conservative_raster */ 7387e995a2eSmrg consts->MaxSubpixelPrecisionBiasBits = 0; 7397e995a2eSmrg 7407e995a2eSmrg /** GL_NV_conservative_raster_dilate */ 7417e995a2eSmrg consts->ConservativeRasterDilateRange[0] = 0.0; 7427e995a2eSmrg consts->ConservativeRasterDilateRange[1] = 0.0; 7437e995a2eSmrg consts->ConservativeRasterDilateGranularity = 0.0; 7447117f1b4Smrg} 7457117f1b4Smrg 7467117f1b4Smrg 7477117f1b4Smrg/** 7487117f1b4Smrg * Do some sanity checks on the limits/constants for the given context. 7497117f1b4Smrg * Only called the first time a context is bound. 7507117f1b4Smrg */ 7517117f1b4Smrgstatic void 7523464ebd5Sriastradhcheck_context_limits(struct gl_context *ctx) 7537117f1b4Smrg{ 7547e995a2eSmrg (void) ctx; 7557e995a2eSmrg 756cdc920a0Smrg /* check that we don't exceed the size of various bitfields */ 757b167d5e7Smrg assert(VARYING_SLOT_MAX <= 7587e995a2eSmrg (8 * sizeof(ctx->VertexProgram._Current->info.outputs_written))); 759b167d5e7Smrg assert(VARYING_SLOT_MAX <= 7607e995a2eSmrg (8 * sizeof(ctx->FragmentProgram._Current->info.inputs_read))); 761cdc920a0Smrg 762cdc920a0Smrg /* shader-related checks */ 763b167d5e7Smrg assert(ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxLocalParams <= MAX_PROGRAM_LOCAL_PARAMS); 764b167d5e7Smrg assert(ctx->Const.Program[MESA_SHADER_VERTEX].MaxLocalParams <= MAX_PROGRAM_LOCAL_PARAMS); 765cdc920a0Smrg 766cdc920a0Smrg /* Texture unit checks */ 767b167d5e7Smrg assert(ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxTextureImageUnits > 0); 768b167d5e7Smrg assert(ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxTextureImageUnits <= MAX_TEXTURE_IMAGE_UNITS); 769cdc920a0Smrg assert(ctx->Const.MaxTextureCoordUnits > 0); 7707117f1b4Smrg assert(ctx->Const.MaxTextureCoordUnits <= MAX_TEXTURE_COORD_UNITS); 771cdc920a0Smrg assert(ctx->Const.MaxTextureUnits > 0); 7727117f1b4Smrg assert(ctx->Const.MaxTextureUnits <= MAX_TEXTURE_IMAGE_UNITS); 7737117f1b4Smrg assert(ctx->Const.MaxTextureUnits <= MAX_TEXTURE_COORD_UNITS); 774b167d5e7Smrg assert(ctx->Const.MaxTextureUnits == MIN2(ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxTextureImageUnits, 775cdc920a0Smrg ctx->Const.MaxTextureCoordUnits)); 776cdc920a0Smrg assert(ctx->Const.MaxCombinedTextureImageUnits > 0); 777cdc920a0Smrg assert(ctx->Const.MaxCombinedTextureImageUnits <= MAX_COMBINED_TEXTURE_IMAGE_UNITS); 778cdc920a0Smrg assert(ctx->Const.MaxTextureCoordUnits <= MAX_COMBINED_TEXTURE_IMAGE_UNITS); 779c1f859d4Smrg /* number of coord units cannot be greater than number of image units */ 780b167d5e7Smrg assert(ctx->Const.MaxTextureCoordUnits <= ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxTextureImageUnits); 781c1f859d4Smrg 782cdc920a0Smrg 783cdc920a0Smrg /* Texture size checks */ 7844a49301eSmrg assert(ctx->Const.MaxTextureLevels <= MAX_TEXTURE_LEVELS); 7854a49301eSmrg assert(ctx->Const.Max3DTextureLevels <= MAX_3D_TEXTURE_LEVELS); 7864a49301eSmrg assert(ctx->Const.MaxCubeTextureLevels <= MAX_CUBE_TEXTURE_LEVELS); 7874a49301eSmrg assert(ctx->Const.MaxTextureRectSize <= MAX_TEXTURE_RECT_SIZE); 7887117f1b4Smrg 789cdc920a0Smrg /* Texture level checks */ 790cdc920a0Smrg assert(MAX_TEXTURE_LEVELS >= MAX_3D_TEXTURE_LEVELS); 791cdc920a0Smrg assert(MAX_TEXTURE_LEVELS >= MAX_CUBE_TEXTURE_LEVELS); 792cdc920a0Smrg 793cdc920a0Smrg /* Max texture size should be <= max viewport size (render to texture) */ 794b167d5e7Smrg assert((1U << (ctx->Const.MaxTextureLevels - 1)) 795b167d5e7Smrg <= ctx->Const.MaxViewportWidth); 796b167d5e7Smrg assert((1U << (ctx->Const.MaxTextureLevels - 1)) 797b167d5e7Smrg <= ctx->Const.MaxViewportHeight); 7987117f1b4Smrg 7997117f1b4Smrg assert(ctx->Const.MaxDrawBuffers <= MAX_DRAW_BUFFERS); 8007117f1b4Smrg 8013464ebd5Sriastradh /* if this fails, add more enum values to gl_buffer_index */ 8023464ebd5Sriastradh assert(BUFFER_COLOR0 + MAX_DRAW_BUFFERS <= BUFFER_COUNT); 8033464ebd5Sriastradh 8047117f1b4Smrg /* XXX probably add more tests */ 8057117f1b4Smrg} 8067117f1b4Smrg 8077117f1b4Smrg 8087117f1b4Smrg/** 8097117f1b4Smrg * Initialize the attribute groups in a GL context. 8107117f1b4Smrg * 8117117f1b4Smrg * \param ctx GL context. 8127117f1b4Smrg * 8137117f1b4Smrg * Initializes all the attributes, calling the respective <tt>init*</tt> 8147117f1b4Smrg * functions for the more complex data structures. 8157117f1b4Smrg */ 8167117f1b4Smrgstatic GLboolean 8173464ebd5Sriastradhinit_attrib_groups(struct gl_context *ctx) 8187117f1b4Smrg{ 8197117f1b4Smrg assert(ctx); 8207117f1b4Smrg 8217117f1b4Smrg /* Constants */ 822b167d5e7Smrg _mesa_init_constants(&ctx->Const, ctx->API); 8237117f1b4Smrg 8247117f1b4Smrg /* Extensions */ 825b167d5e7Smrg _mesa_init_extensions(&ctx->Extensions); 8267117f1b4Smrg 8277117f1b4Smrg /* Attribute Groups */ 8287117f1b4Smrg _mesa_init_accum( ctx ); 8297117f1b4Smrg _mesa_init_attrib( ctx ); 8307e995a2eSmrg _mesa_init_bbox( ctx ); 8317117f1b4Smrg _mesa_init_buffer_objects( ctx ); 8327117f1b4Smrg _mesa_init_color( ctx ); 8337e995a2eSmrg _mesa_init_conservative_raster( ctx ); 8347117f1b4Smrg _mesa_init_current( ctx ); 8357117f1b4Smrg _mesa_init_depth( ctx ); 8367117f1b4Smrg _mesa_init_debug( ctx ); 8377e995a2eSmrg _mesa_init_debug_output( ctx ); 8387117f1b4Smrg _mesa_init_display_list( ctx ); 8397117f1b4Smrg _mesa_init_eval( ctx ); 840c1f859d4Smrg _mesa_init_fbobjects( ctx ); 8417117f1b4Smrg _mesa_init_feedback( ctx ); 8427117f1b4Smrg _mesa_init_fog( ctx ); 8437117f1b4Smrg _mesa_init_hint( ctx ); 8447e995a2eSmrg _mesa_init_image_units( ctx ); 8457117f1b4Smrg _mesa_init_line( ctx ); 8467117f1b4Smrg _mesa_init_lighting( ctx ); 8477117f1b4Smrg _mesa_init_matrix( ctx ); 8487117f1b4Smrg _mesa_init_multisample( ctx ); 849b167d5e7Smrg _mesa_init_performance_monitors( ctx ); 8507e995a2eSmrg _mesa_init_performance_queries( ctx ); 851b167d5e7Smrg _mesa_init_pipeline( ctx ); 8527117f1b4Smrg _mesa_init_pixel( ctx ); 853c1f859d4Smrg _mesa_init_pixelstore( ctx ); 8547117f1b4Smrg _mesa_init_point( ctx ); 8557117f1b4Smrg _mesa_init_polygon( ctx ); 8567117f1b4Smrg _mesa_init_program( ctx ); 8574a49301eSmrg _mesa_init_queryobj( ctx ); 8584a49301eSmrg _mesa_init_sync( ctx ); 8597117f1b4Smrg _mesa_init_rastpos( ctx ); 8607117f1b4Smrg _mesa_init_scissor( ctx ); 8617117f1b4Smrg _mesa_init_shader_state( ctx ); 8627117f1b4Smrg _mesa_init_stencil( ctx ); 8637117f1b4Smrg _mesa_init_transform( ctx ); 8643464ebd5Sriastradh _mesa_init_transform_feedback( ctx ); 8657117f1b4Smrg _mesa_init_varray( ctx ); 8667117f1b4Smrg _mesa_init_viewport( ctx ); 8677e995a2eSmrg _mesa_init_resident_handles( ctx ); 8687117f1b4Smrg 8697117f1b4Smrg if (!_mesa_init_texture( ctx )) 8707117f1b4Smrg return GL_FALSE; 8717117f1b4Smrg 8727117f1b4Smrg /* Miscellaneous */ 8737e995a2eSmrg ctx->TileRasterOrderIncreasingX = GL_TRUE; 8747e995a2eSmrg ctx->TileRasterOrderIncreasingY = GL_TRUE; 8757117f1b4Smrg ctx->NewState = _NEW_ALL; 876b167d5e7Smrg ctx->NewDriverState = ~0; 877b167d5e7Smrg ctx->ErrorValue = GL_NO_ERROR; 878b167d5e7Smrg ctx->ShareGroupReset = false; 879b167d5e7Smrg ctx->varying_vp_inputs = VERT_BIT_ALL; 8807117f1b4Smrg 8817117f1b4Smrg return GL_TRUE; 8827117f1b4Smrg} 8837117f1b4Smrg 8847117f1b4Smrg 885c1f859d4Smrg/** 886c1f859d4Smrg * Update default objects in a GL context with respect to shared state. 887c1f859d4Smrg * 888c1f859d4Smrg * \param ctx GL context. 889c1f859d4Smrg * 890c1f859d4Smrg * Removes references to old default objects, (texture objects, program 891c1f859d4Smrg * objects, etc.) and changes to reference those from the current shared 892c1f859d4Smrg * state. 893c1f859d4Smrg */ 894c1f859d4Smrgstatic GLboolean 8953464ebd5Sriastradhupdate_default_objects(struct gl_context *ctx) 896c1f859d4Smrg{ 897c1f859d4Smrg assert(ctx); 898c1f859d4Smrg 899c1f859d4Smrg _mesa_update_default_objects_program(ctx); 900c1f859d4Smrg _mesa_update_default_objects_texture(ctx); 901c1f859d4Smrg _mesa_update_default_objects_buffer_objects(ctx); 902c1f859d4Smrg 903c1f859d4Smrg return GL_TRUE; 904c1f859d4Smrg} 905c1f859d4Smrg 906c1f859d4Smrg 9077e995a2eSmrg/* XXX this is temporary and should be removed at some point in the 9087e995a2eSmrg * future when there's a reasonable expectation that the libGL library 9097e995a2eSmrg * contains the _glapi_new_nop_table() and _glapi_set_nop_handler() 9107e995a2eSmrg * functions which were added in Mesa 10.6. 9117e995a2eSmrg */ 9127e995a2eSmrg#if !defined(_WIN32) 9137e995a2eSmrg/* Avoid libGL / driver ABI break */ 9147e995a2eSmrg#define USE_GLAPI_NOP_FEATURES 0 9157e995a2eSmrg#else 9167e995a2eSmrg#define USE_GLAPI_NOP_FEATURES 1 9177e995a2eSmrg#endif 9187e995a2eSmrg 9197e995a2eSmrg 9207117f1b4Smrg/** 9217e995a2eSmrg * This function is called by the glapi no-op functions. For each OpenGL 9227e995a2eSmrg * function/entrypoint there's a simple no-op function. These "no-op" 9237e995a2eSmrg * functions call this function. 9247e995a2eSmrg * 9257e995a2eSmrg * If there's a current OpenGL context for the calling thread, we record a 9267e995a2eSmrg * GL_INVALID_OPERATION error. This can happen either because the app's 9277e995a2eSmrg * calling an unsupported extension function, or calling an illegal function 9287e995a2eSmrg * (such as glClear between glBegin/glEnd). 9297e995a2eSmrg * 9307e995a2eSmrg * If there's no current OpenGL context for the calling thread, we can 9317e995a2eSmrg * print a message to stderr. 9327e995a2eSmrg * 9337e995a2eSmrg * \param name the name of the OpenGL function 9347117f1b4Smrg */ 9357e995a2eSmrg#if USE_GLAPI_NOP_FEATURES 9367e995a2eSmrgstatic void 9377e995a2eSmrgnop_handler(const char *name) 9387117f1b4Smrg{ 939b167d5e7Smrg GET_CURRENT_CONTEXT(ctx); 9407e995a2eSmrg if (ctx) { 9417e995a2eSmrg _mesa_error(ctx, GL_INVALID_OPERATION, "%s(invalid call)", name); 9427e995a2eSmrg } 9437e995a2eSmrg#if defined(DEBUG) 9447e995a2eSmrg else if (getenv("MESA_DEBUG") || getenv("LIBGL_DEBUG")) { 9457e995a2eSmrg fprintf(stderr, 9467e995a2eSmrg "GL User Error: gl%s called without a rendering context\n", 9477e995a2eSmrg name); 9487e995a2eSmrg fflush(stderr); 9497e995a2eSmrg } 9507e995a2eSmrg#endif 9517117f1b4Smrg} 9527e995a2eSmrg#endif 9537117f1b4Smrg 9547117f1b4Smrg 9557117f1b4Smrg/** 956b167d5e7Smrg * Special no-op glFlush, see below. 957b167d5e7Smrg */ 958b167d5e7Smrg#if defined(_WIN32) 959b167d5e7Smrgstatic void GLAPIENTRY 960b167d5e7Smrgnop_glFlush(void) 961b167d5e7Smrg{ 9627e995a2eSmrg /* don't record an error like we do in nop_handler() */ 9637e995a2eSmrg} 9647e995a2eSmrg#endif 9657e995a2eSmrg 9667e995a2eSmrg 9677e995a2eSmrg#if !USE_GLAPI_NOP_FEATURES 9687e995a2eSmrgstatic int 9697e995a2eSmrggeneric_nop(void) 9707e995a2eSmrg{ 9717e995a2eSmrg GET_CURRENT_CONTEXT(ctx); 9727e995a2eSmrg _mesa_error(ctx, GL_INVALID_OPERATION, 9737e995a2eSmrg "unsupported function called " 9747e995a2eSmrg "(unsupported extension or deprecated function?)"); 9757e995a2eSmrg return 0; 976b167d5e7Smrg} 977b167d5e7Smrg#endif 978b167d5e7Smrg 979b167d5e7Smrg 980b167d5e7Smrg/** 9817e995a2eSmrg * Create a new API dispatch table in which all entries point to the 9827e995a2eSmrg * generic_nop() function. This will not work on Windows because of 9837e995a2eSmrg * the __stdcall convention which requires the callee to clean up the 9847e995a2eSmrg * call stack. That's impossible with one generic no-op function. 9857117f1b4Smrg */ 9863464ebd5Sriastradhstruct _glapi_table * 9877e995a2eSmrg_mesa_new_nop_table(unsigned numEntries) 9887117f1b4Smrg{ 9893464ebd5Sriastradh struct _glapi_table *table; 9903464ebd5Sriastradh 9917e995a2eSmrg#if !USE_GLAPI_NOP_FEATURES 992b167d5e7Smrg table = malloc(numEntries * sizeof(_glapi_proc)); 9937117f1b4Smrg if (table) { 9947117f1b4Smrg _glapi_proc *entry = (_glapi_proc *) table; 9957e995a2eSmrg unsigned i; 9967117f1b4Smrg for (i = 0; i < numEntries; i++) { 9977e995a2eSmrg entry[i] = (_glapi_proc) generic_nop; 9987117f1b4Smrg } 9997e995a2eSmrg } 10007e995a2eSmrg#else 10017e995a2eSmrg table = _glapi_new_nop_table(numEntries); 10027e995a2eSmrg#endif 10037e995a2eSmrg return table; 10047e995a2eSmrg} 10057e995a2eSmrg 10067e995a2eSmrg 10077e995a2eSmrg/** 10087e995a2eSmrg * Allocate and initialize a new dispatch table. The table will be 10097e995a2eSmrg * populated with pointers to "no-op" functions. In turn, the no-op 10107e995a2eSmrg * functions will call nop_handler() above. 10117e995a2eSmrg */ 10127e995a2eSmrgstruct _glapi_table * 10137e995a2eSmrg_mesa_alloc_dispatch_table(void) 10147e995a2eSmrg{ 10157e995a2eSmrg /* Find the larger of Mesa's dispatch table and libGL's dispatch table. 10167e995a2eSmrg * In practice, this'll be the same for stand-alone Mesa. But for DRI 10177e995a2eSmrg * Mesa we do this to accommodate different versions of libGL and various 10187e995a2eSmrg * DRI drivers. 10197e995a2eSmrg */ 10207e995a2eSmrg int numEntries = MAX2(_glapi_get_dispatch_table_size(), _gloffset_COUNT); 10217e995a2eSmrg 10227e995a2eSmrg struct _glapi_table *table = _mesa_new_nop_table(numEntries); 1023b167d5e7Smrg 1024b167d5e7Smrg#if defined(_WIN32) 10257e995a2eSmrg if (table) { 1026b167d5e7Smrg /* This is a special case for Windows in the event that 1027b167d5e7Smrg * wglGetProcAddress is called between glBegin/End(). 1028b167d5e7Smrg * 1029b167d5e7Smrg * The MS opengl32.dll library apparently calls glFlush from 1030b167d5e7Smrg * wglGetProcAddress(). If we're inside glBegin/End(), glFlush 1031b167d5e7Smrg * will dispatch to _mesa_generic_nop() and we'll generate a 1032b167d5e7Smrg * GL_INVALID_OPERATION error. 1033b167d5e7Smrg * 1034b167d5e7Smrg * The specific case which hits this is piglit's primitive-restart 1035b167d5e7Smrg * test which calls glPrimitiveRestartNV() inside glBegin/End. The 1036b167d5e7Smrg * first time we call glPrimitiveRestartNV() Piglit's API dispatch 1037b167d5e7Smrg * code will try to resolve the function by calling wglGetProcAddress. 1038b167d5e7Smrg * This raises GL_INVALID_OPERATION and an assert(glGetError()==0) 1039b167d5e7Smrg * will fail causing the test to fail. By suppressing the error, the 1040b167d5e7Smrg * assertion passes and the test continues. 1041b167d5e7Smrg */ 1042b167d5e7Smrg SET_Flush(table, nop_glFlush); 10437117f1b4Smrg } 10447e995a2eSmrg#endif 10457e995a2eSmrg 10467e995a2eSmrg#if USE_GLAPI_NOP_FEATURES 10477e995a2eSmrg _glapi_set_nop_handler(nop_handler); 10487e995a2eSmrg#endif 10497e995a2eSmrg 10507117f1b4Smrg return table; 10517117f1b4Smrg} 10527117f1b4Smrg 1053b167d5e7Smrg/** 1054b167d5e7Smrg * Creates a minimal dispatch table for use within glBegin()/glEnd(). 1055b167d5e7Smrg * 1056b167d5e7Smrg * This ensures that we generate GL_INVALID_OPERATION errors from most 1057b167d5e7Smrg * functions, since the set of functions that are valid within Begin/End is 1058b167d5e7Smrg * very small. 1059b167d5e7Smrg * 1060b167d5e7Smrg * From the GL 1.0 specification section 2.6.3, "GL Commands within 1061b167d5e7Smrg * Begin/End" 1062b167d5e7Smrg * 1063b167d5e7Smrg * "The only GL commands that are allowed within any Begin/End pairs are 1064b167d5e7Smrg * the commands for specifying vertex coordinates, vertex color, normal 1065b167d5e7Smrg * coordinates, and texture coordinates (Vertex, Color, Index, Normal, 1066b167d5e7Smrg * TexCoord), EvalCoord and EvalPoint commands (see section 5.1), 1067b167d5e7Smrg * commands for specifying lighting material parameters (Material 1068b167d5e7Smrg * commands see section 2.12.2), display list invocation commands 1069b167d5e7Smrg * (CallList and CallLists see section 5.4), and the EdgeFlag 1070b167d5e7Smrg * command. Executing Begin after Begin has already been executed but 1071b167d5e7Smrg * before an End is issued generates the INVALID OPERATION error, as does 1072b167d5e7Smrg * executing End without a previous corresponding Begin. Executing any 1073b167d5e7Smrg * other GL command within Begin/End results in the error INVALID 1074b167d5e7Smrg * OPERATION." 1075b167d5e7Smrg * 1076b167d5e7Smrg * The table entries for specifying vertex attributes are set up by 1077b167d5e7Smrg * install_vtxfmt() and _mesa_loopback_init_api_table(), and End() and dlists 1078b167d5e7Smrg * are set by install_vtxfmt() as well. 1079b167d5e7Smrg */ 1080b167d5e7Smrgstatic struct _glapi_table * 1081b167d5e7Smrgcreate_beginend_table(const struct gl_context *ctx) 1082b167d5e7Smrg{ 1083b167d5e7Smrg struct _glapi_table *table; 1084b167d5e7Smrg 1085b167d5e7Smrg table = _mesa_alloc_dispatch_table(); 1086b167d5e7Smrg if (!table) 1087b167d5e7Smrg return NULL; 1088b167d5e7Smrg 1089b167d5e7Smrg /* Fill in functions which return a value, since they should return some 1090b167d5e7Smrg * specific value even if they emit a GL_INVALID_OPERATION error from them 1091b167d5e7Smrg * being called within glBegin()/glEnd(). 1092b167d5e7Smrg */ 1093b167d5e7Smrg#define COPY_DISPATCH(func) SET_##func(table, GET_##func(ctx->Exec)) 1094b167d5e7Smrg 1095b167d5e7Smrg COPY_DISPATCH(GenLists); 1096b167d5e7Smrg COPY_DISPATCH(IsProgram); 1097b167d5e7Smrg COPY_DISPATCH(IsVertexArray); 1098b167d5e7Smrg COPY_DISPATCH(IsBuffer); 1099b167d5e7Smrg COPY_DISPATCH(IsEnabled); 1100b167d5e7Smrg COPY_DISPATCH(IsEnabledi); 1101b167d5e7Smrg COPY_DISPATCH(IsRenderbuffer); 1102b167d5e7Smrg COPY_DISPATCH(IsFramebuffer); 1103b167d5e7Smrg COPY_DISPATCH(CheckFramebufferStatus); 1104b167d5e7Smrg COPY_DISPATCH(RenderMode); 1105b167d5e7Smrg COPY_DISPATCH(GetString); 1106b167d5e7Smrg COPY_DISPATCH(GetStringi); 1107b167d5e7Smrg COPY_DISPATCH(GetPointerv); 1108b167d5e7Smrg COPY_DISPATCH(IsQuery); 1109b167d5e7Smrg COPY_DISPATCH(IsSampler); 1110b167d5e7Smrg COPY_DISPATCH(IsSync); 1111b167d5e7Smrg COPY_DISPATCH(IsTexture); 1112b167d5e7Smrg COPY_DISPATCH(IsTransformFeedback); 1113b167d5e7Smrg COPY_DISPATCH(DeleteQueries); 1114b167d5e7Smrg COPY_DISPATCH(AreTexturesResident); 1115b167d5e7Smrg COPY_DISPATCH(FenceSync); 1116b167d5e7Smrg COPY_DISPATCH(ClientWaitSync); 1117b167d5e7Smrg COPY_DISPATCH(MapBuffer); 1118b167d5e7Smrg COPY_DISPATCH(UnmapBuffer); 1119b167d5e7Smrg COPY_DISPATCH(MapBufferRange); 1120b167d5e7Smrg COPY_DISPATCH(ObjectPurgeableAPPLE); 1121b167d5e7Smrg COPY_DISPATCH(ObjectUnpurgeableAPPLE); 1122b167d5e7Smrg 1123b167d5e7Smrg _mesa_loopback_init_api_table(ctx, table); 1124b167d5e7Smrg 1125b167d5e7Smrg return table; 1126b167d5e7Smrg} 1127b167d5e7Smrg 1128b167d5e7Smrgvoid 1129b167d5e7Smrg_mesa_initialize_dispatch_tables(struct gl_context *ctx) 1130b167d5e7Smrg{ 1131b167d5e7Smrg /* Do the code-generated setup of the exec table in api_exec.c. */ 1132b167d5e7Smrg _mesa_initialize_exec_table(ctx); 1133b167d5e7Smrg 1134b167d5e7Smrg if (ctx->Save) 1135b167d5e7Smrg _mesa_initialize_save_table(ctx); 1136b167d5e7Smrg} 11377117f1b4Smrg 11387117f1b4Smrg/** 11393464ebd5Sriastradh * Initialize a struct gl_context struct (rendering context). 11407117f1b4Smrg * 11417117f1b4Smrg * This includes allocating all the other structs and arrays which hang off of 11427117f1b4Smrg * the context by pointers. 11437117f1b4Smrg * Note that the driver needs to pass in its dd_function_table here since 11447117f1b4Smrg * we need to at least call driverFunctions->NewTextureObject to create the 11457117f1b4Smrg * default texture objects. 11467e995a2eSmrg * 11477117f1b4Smrg * Called by _mesa_create_context(). 11487117f1b4Smrg * 11497117f1b4Smrg * Performs the imports and exports callback tables initialization, and 11507117f1b4Smrg * miscellaneous one-time initializations. If no shared context is supplied one 11517117f1b4Smrg * is allocated, and increase its reference count. Setups the GL API dispatch 11527117f1b4Smrg * tables. Initialize the TNL module. Sets the maximum Z buffer depth. 11537117f1b4Smrg * Finally queries the \c MESA_DEBUG and \c MESA_VERBOSE environment variables 11547117f1b4Smrg * for debug flags. 11557117f1b4Smrg * 11567117f1b4Smrg * \param ctx the context to initialize 11573464ebd5Sriastradh * \param api the GL API type to create the context for 1158b167d5e7Smrg * \param visual describes the visual attributes for this context or NULL to 1159b167d5e7Smrg * create a configless context 11607117f1b4Smrg * \param share_list points to context to share textures, display lists, 11617117f1b4Smrg * etc with, or NULL 11627117f1b4Smrg * \param driverFunctions table of device driver functions for this context 11637117f1b4Smrg * to use 11647117f1b4Smrg */ 11657117f1b4SmrgGLboolean 11663464ebd5Sriastradh_mesa_initialize_context(struct gl_context *ctx, 11673464ebd5Sriastradh gl_api api, 11683464ebd5Sriastradh const struct gl_config *visual, 11693464ebd5Sriastradh struct gl_context *share_list, 1170b167d5e7Smrg const struct dd_function_table *driverFunctions) 11717117f1b4Smrg{ 11724a49301eSmrg struct gl_shared_state *shared; 11733464ebd5Sriastradh int i; 11744a49301eSmrg 11757117f1b4Smrg assert(driverFunctions->NewTextureObject); 1176b167d5e7Smrg assert(driverFunctions->FreeTextureImageBuffer); 11777117f1b4Smrg 11783464ebd5Sriastradh ctx->API = api; 11797117f1b4Smrg ctx->DrawBuffer = NULL; 11807117f1b4Smrg ctx->ReadBuffer = NULL; 11817117f1b4Smrg ctx->WinSysDrawBuffer = NULL; 11827117f1b4Smrg ctx->WinSysReadBuffer = NULL; 11837117f1b4Smrg 1184b167d5e7Smrg if (visual) { 1185b167d5e7Smrg ctx->Visual = *visual; 1186b167d5e7Smrg ctx->HasConfig = GL_TRUE; 1187b167d5e7Smrg } 1188b167d5e7Smrg else { 1189b167d5e7Smrg memset(&ctx->Visual, 0, sizeof ctx->Visual); 1190b167d5e7Smrg ctx->HasConfig = GL_FALSE; 1191b167d5e7Smrg } 1192b167d5e7Smrg 11937e995a2eSmrg _mesa_override_gl_version(ctx); 1194b167d5e7Smrg 11953464ebd5Sriastradh /* misc one-time initializations */ 11963464ebd5Sriastradh one_time_init(ctx); 11973464ebd5Sriastradh 11987117f1b4Smrg /* Plug in driver functions and context pointer here. 11997117f1b4Smrg * This is important because when we call alloc_shared_state() below 12007117f1b4Smrg * we'll call ctx->Driver.NewTextureObject() to create the default 12017117f1b4Smrg * textures. 12027117f1b4Smrg */ 12037117f1b4Smrg ctx->Driver = *driverFunctions; 12047117f1b4Smrg 12057117f1b4Smrg if (share_list) { 12067117f1b4Smrg /* share state with another context */ 12074a49301eSmrg shared = share_list->Shared; 12087117f1b4Smrg } 12097117f1b4Smrg else { 12107117f1b4Smrg /* allocate new, unshared state */ 12114a49301eSmrg shared = _mesa_alloc_shared_state(ctx); 12124a49301eSmrg if (!shared) 12137117f1b4Smrg return GL_FALSE; 12147117f1b4Smrg } 12154a49301eSmrg 1216b167d5e7Smrg _mesa_reference_shared_state(ctx, &ctx->Shared, shared); 12177117f1b4Smrg 1218b167d5e7Smrg if (!init_attrib_groups( ctx )) 1219b167d5e7Smrg goto fail; 12203464ebd5Sriastradh 12217e995a2eSmrg /* KHR_no_error is likely to crash, overflow memory, etc if an application 12227e995a2eSmrg * has errors so don't enable it for setuid processes. 12237e995a2eSmrg */ 12247e995a2eSmrg if (env_var_as_boolean("MESA_NO_ERROR", false)) { 12257e995a2eSmrg#if !defined(_WIN32) 12267e995a2eSmrg if (geteuid() == getuid()) 12277e995a2eSmrg#endif 12287e995a2eSmrg ctx->Const.ContextFlags |= GL_CONTEXT_FLAG_NO_ERROR_BIT_KHR; 12297e995a2eSmrg } 12307e995a2eSmrg 1231b167d5e7Smrg /* setup the API dispatch tables with all nop functions */ 1232b167d5e7Smrg ctx->OutsideBeginEnd = _mesa_alloc_dispatch_table(); 1233b167d5e7Smrg if (!ctx->OutsideBeginEnd) 1234b167d5e7Smrg goto fail; 1235b167d5e7Smrg ctx->Exec = ctx->OutsideBeginEnd; 12367e995a2eSmrg ctx->CurrentClientDispatch = ctx->CurrentServerDispatch = ctx->OutsideBeginEnd; 12374a49301eSmrg 12387117f1b4Smrg ctx->FragmentProgram._MaintainTexEnvProgram 12397e995a2eSmrg = (getenv("MESA_TEX_PROG") != NULL); 12407117f1b4Smrg 12417117f1b4Smrg ctx->VertexProgram._MaintainTnlProgram 12427e995a2eSmrg = (getenv("MESA_TNL_PROG") != NULL); 12437117f1b4Smrg if (ctx->VertexProgram._MaintainTnlProgram) { 12447117f1b4Smrg /* this is required... */ 12457117f1b4Smrg ctx->FragmentProgram._MaintainTexEnvProgram = GL_TRUE; 12467117f1b4Smrg } 12477117f1b4Smrg 12483464ebd5Sriastradh /* Mesa core handles all the formats that mesa core knows about. 12493464ebd5Sriastradh * Drivers will want to override this list with just the formats 12503464ebd5Sriastradh * they can handle, and confirm that appropriate fallbacks exist in 12513464ebd5Sriastradh * _mesa_choose_tex_format(). 12523464ebd5Sriastradh */ 12533464ebd5Sriastradh memset(&ctx->TextureFormatSupported, GL_TRUE, 12547e995a2eSmrg sizeof(ctx->TextureFormatSupported)); 12553464ebd5Sriastradh 12563464ebd5Sriastradh switch (ctx->API) { 1257b167d5e7Smrg case API_OPENGL_COMPAT: 1258b167d5e7Smrg ctx->BeginEnd = create_beginend_table(ctx); 1259b167d5e7Smrg ctx->Save = _mesa_alloc_dispatch_table(); 1260b167d5e7Smrg if (!ctx->BeginEnd || !ctx->Save) 1261b167d5e7Smrg goto fail; 1262b167d5e7Smrg 1263b167d5e7Smrg /* fall-through */ 1264b167d5e7Smrg case API_OPENGL_CORE: 12653464ebd5Sriastradh break; 12663464ebd5Sriastradh case API_OPENGLES: 12673464ebd5Sriastradh /** 12683464ebd5Sriastradh * GL_OES_texture_cube_map says 12693464ebd5Sriastradh * "Initially all texture generation modes are set to REFLECTION_MAP_OES" 12703464ebd5Sriastradh */ 12717e995a2eSmrg for (i = 0; i < ARRAY_SIZE(ctx->Texture.FixedFuncUnit); i++) { 12727e995a2eSmrg struct gl_fixedfunc_texture_unit *texUnit = 12737e995a2eSmrg &ctx->Texture.FixedFuncUnit[i]; 12747e995a2eSmrg 12757e995a2eSmrg texUnit->GenS.Mode = GL_REFLECTION_MAP_NV; 12767e995a2eSmrg texUnit->GenT.Mode = GL_REFLECTION_MAP_NV; 12777e995a2eSmrg texUnit->GenR.Mode = GL_REFLECTION_MAP_NV; 12787e995a2eSmrg texUnit->GenS._ModeBit = TEXGEN_REFLECTION_MAP_NV; 12797e995a2eSmrg texUnit->GenT._ModeBit = TEXGEN_REFLECTION_MAP_NV; 12807e995a2eSmrg texUnit->GenR._ModeBit = TEXGEN_REFLECTION_MAP_NV; 12813464ebd5Sriastradh } 12823464ebd5Sriastradh break; 12833464ebd5Sriastradh case API_OPENGLES2: 12843464ebd5Sriastradh ctx->FragmentProgram._MaintainTexEnvProgram = GL_TRUE; 12853464ebd5Sriastradh ctx->VertexProgram._MaintainTnlProgram = GL_TRUE; 12863464ebd5Sriastradh break; 12873464ebd5Sriastradh } 1288c1f859d4Smrg 12897117f1b4Smrg ctx->FirstTimeCurrent = GL_TRUE; 12907117f1b4Smrg 12917117f1b4Smrg return GL_TRUE; 1292b167d5e7Smrg 1293b167d5e7Smrgfail: 1294b167d5e7Smrg _mesa_reference_shared_state(ctx, &ctx->Shared, NULL); 1295b167d5e7Smrg free(ctx->BeginEnd); 1296b167d5e7Smrg free(ctx->OutsideBeginEnd); 1297b167d5e7Smrg free(ctx->Save); 1298b167d5e7Smrg return GL_FALSE; 12997117f1b4Smrg} 13007117f1b4Smrg 13017117f1b4Smrg 13027117f1b4Smrg/** 13037117f1b4Smrg * Free the data associated with the given context. 13047e995a2eSmrg * 13053464ebd5Sriastradh * But doesn't free the struct gl_context struct itself. 13067117f1b4Smrg * 13077117f1b4Smrg * \sa _mesa_initialize_context() and init_attrib_groups(). 13087117f1b4Smrg */ 13097117f1b4Smrgvoid 13103464ebd5Sriastradh_mesa_free_context_data( struct gl_context *ctx ) 13117117f1b4Smrg{ 13127117f1b4Smrg if (!_mesa_get_current_context()){ 13137117f1b4Smrg /* No current context, but we may need one in order to delete 13147117f1b4Smrg * texture objs, etc. So temporarily bind the context now. 13157117f1b4Smrg */ 13167117f1b4Smrg _mesa_make_current(ctx, NULL, NULL); 13177117f1b4Smrg } 13187117f1b4Smrg 13197117f1b4Smrg /* unreference WinSysDraw/Read buffers */ 13204a49301eSmrg _mesa_reference_framebuffer(&ctx->WinSysDrawBuffer, NULL); 13214a49301eSmrg _mesa_reference_framebuffer(&ctx->WinSysReadBuffer, NULL); 13224a49301eSmrg _mesa_reference_framebuffer(&ctx->DrawBuffer, NULL); 13234a49301eSmrg _mesa_reference_framebuffer(&ctx->ReadBuffer, NULL); 13247117f1b4Smrg 13257e995a2eSmrg _mesa_reference_program(ctx, &ctx->VertexProgram.Current, NULL); 13267e995a2eSmrg _mesa_reference_program(ctx, &ctx->VertexProgram._Current, NULL); 13277e995a2eSmrg _mesa_reference_program(ctx, &ctx->VertexProgram._TnlProgram, NULL); 1328c1f859d4Smrg 13297e995a2eSmrg _mesa_reference_program(ctx, &ctx->TessCtrlProgram._Current, NULL); 13307e995a2eSmrg _mesa_reference_program(ctx, &ctx->TessEvalProgram._Current, NULL); 13317e995a2eSmrg _mesa_reference_program(ctx, &ctx->GeometryProgram._Current, NULL); 1332b167d5e7Smrg 13337e995a2eSmrg _mesa_reference_program(ctx, &ctx->FragmentProgram.Current, NULL); 13347e995a2eSmrg _mesa_reference_program(ctx, &ctx->FragmentProgram._Current, NULL); 13357e995a2eSmrg _mesa_reference_program(ctx, &ctx->FragmentProgram._TexEnvProgram, NULL); 13367e995a2eSmrg 13377e995a2eSmrg _mesa_reference_program(ctx, &ctx->ComputeProgram._Current, NULL); 1338c1f859d4Smrg 1339b167d5e7Smrg _mesa_reference_vao(ctx, &ctx->Array.VAO, NULL); 1340b167d5e7Smrg _mesa_reference_vao(ctx, &ctx->Array.DefaultVAO, NULL); 13417e995a2eSmrg _mesa_reference_vao(ctx, &ctx->Array._EmptyVAO, NULL); 13427e995a2eSmrg _mesa_reference_vao(ctx, &ctx->Array._DrawVAO, NULL); 1343b167d5e7Smrg 13447117f1b4Smrg _mesa_free_attrib_data(ctx); 13454a49301eSmrg _mesa_free_buffer_objects(ctx); 13467117f1b4Smrg _mesa_free_eval_data( ctx ); 13477117f1b4Smrg _mesa_free_texture_data( ctx ); 13487117f1b4Smrg _mesa_free_matrix_data( ctx ); 1349b167d5e7Smrg _mesa_free_pipeline_data(ctx); 13507117f1b4Smrg _mesa_free_program_data(ctx); 13517117f1b4Smrg _mesa_free_shader_state(ctx); 13524a49301eSmrg _mesa_free_queryobj_data(ctx); 13534a49301eSmrg _mesa_free_sync_data(ctx); 13544a49301eSmrg _mesa_free_varray_data(ctx); 13553464ebd5Sriastradh _mesa_free_transform_feedback(ctx); 1356b167d5e7Smrg _mesa_free_performance_monitors(ctx); 13577e995a2eSmrg _mesa_free_performance_queries(ctx); 13587e995a2eSmrg _mesa_free_resident_handles(ctx); 13594a49301eSmrg 13604a49301eSmrg _mesa_reference_buffer_object(ctx, &ctx->Pack.BufferObj, NULL); 13614a49301eSmrg _mesa_reference_buffer_object(ctx, &ctx->Unpack.BufferObj, NULL); 13624a49301eSmrg _mesa_reference_buffer_object(ctx, &ctx->DefaultPacking.BufferObj, NULL); 13634a49301eSmrg _mesa_reference_buffer_object(ctx, &ctx->Array.ArrayBufferObj, NULL); 13647117f1b4Smrg 13657117f1b4Smrg /* free dispatch tables */ 1366b167d5e7Smrg free(ctx->BeginEnd); 1367b167d5e7Smrg free(ctx->OutsideBeginEnd); 1368cdc920a0Smrg free(ctx->Save); 13697e995a2eSmrg free(ctx->ContextLost); 13707e995a2eSmrg free(ctx->MarshalExec); 13717117f1b4Smrg 13727117f1b4Smrg /* Shared context state (display lists, textures, etc) */ 1373b167d5e7Smrg _mesa_reference_shared_state(ctx, &ctx->Shared, NULL); 13744a49301eSmrg 13754a49301eSmrg /* needs to be after freeing shared state */ 13764a49301eSmrg _mesa_free_display_list_data(ctx); 13777117f1b4Smrg 1378b167d5e7Smrg _mesa_free_errors_data(ctx); 1379cdc920a0Smrg 1380b167d5e7Smrg free((void *)ctx->Extensions.String); 1381b167d5e7Smrg 1382b167d5e7Smrg free(ctx->VersionString); 13837117f1b4Smrg 13847117f1b4Smrg /* unbind the context if it's currently bound */ 13857117f1b4Smrg if (ctx == _mesa_get_current_context()) { 13867117f1b4Smrg _mesa_make_current(NULL, NULL, NULL); 13877117f1b4Smrg } 13887117f1b4Smrg} 13897117f1b4Smrg 13907117f1b4Smrg 13917117f1b4Smrg/** 13923464ebd5Sriastradh * Destroy a struct gl_context structure. 13937117f1b4Smrg * 13947117f1b4Smrg * \param ctx GL context. 13957e995a2eSmrg * 13963464ebd5Sriastradh * Calls _mesa_free_context_data() and frees the gl_context object itself. 13977117f1b4Smrg */ 13987117f1b4Smrgvoid 13993464ebd5Sriastradh_mesa_destroy_context( struct gl_context *ctx ) 14007117f1b4Smrg{ 14017117f1b4Smrg if (ctx) { 14027117f1b4Smrg _mesa_free_context_data(ctx); 1403cdc920a0Smrg free( (void *) ctx ); 14047117f1b4Smrg } 14057117f1b4Smrg} 14067117f1b4Smrg 14077117f1b4Smrg 14087117f1b4Smrg/** 14097117f1b4Smrg * Copy attribute groups from one context to another. 14107e995a2eSmrg * 14117117f1b4Smrg * \param src source context 14127117f1b4Smrg * \param dst destination context 14137117f1b4Smrg * \param mask bitwise OR of GL_*_BIT flags 14147117f1b4Smrg * 14157117f1b4Smrg * According to the bits specified in \p mask, copies the corresponding 14167117f1b4Smrg * attributes from \p src into \p dst. For many of the attributes a simple \c 14177117f1b4Smrg * memcpy is not enough due to the existence of internal pointers in their data 14187117f1b4Smrg * structures. 14197117f1b4Smrg */ 14207117f1b4Smrgvoid 14213464ebd5Sriastradh_mesa_copy_context( const struct gl_context *src, struct gl_context *dst, 14223464ebd5Sriastradh GLuint mask ) 14237117f1b4Smrg{ 14247117f1b4Smrg if (mask & GL_ACCUM_BUFFER_BIT) { 14257117f1b4Smrg /* OK to memcpy */ 14267117f1b4Smrg dst->Accum = src->Accum; 14277117f1b4Smrg } 14287117f1b4Smrg if (mask & GL_COLOR_BUFFER_BIT) { 14297117f1b4Smrg /* OK to memcpy */ 14307117f1b4Smrg dst->Color = src->Color; 14317117f1b4Smrg } 14327117f1b4Smrg if (mask & GL_CURRENT_BIT) { 14337117f1b4Smrg /* OK to memcpy */ 14347117f1b4Smrg dst->Current = src->Current; 14357117f1b4Smrg } 14367117f1b4Smrg if (mask & GL_DEPTH_BUFFER_BIT) { 14377117f1b4Smrg /* OK to memcpy */ 14387117f1b4Smrg dst->Depth = src->Depth; 14397117f1b4Smrg } 14407117f1b4Smrg if (mask & GL_ENABLE_BIT) { 14417117f1b4Smrg /* no op */ 14427117f1b4Smrg } 14437117f1b4Smrg if (mask & GL_EVAL_BIT) { 14447117f1b4Smrg /* OK to memcpy */ 14457117f1b4Smrg dst->Eval = src->Eval; 14467117f1b4Smrg } 14477117f1b4Smrg if (mask & GL_FOG_BIT) { 14487117f1b4Smrg /* OK to memcpy */ 14497117f1b4Smrg dst->Fog = src->Fog; 14507117f1b4Smrg } 14517117f1b4Smrg if (mask & GL_HINT_BIT) { 14527117f1b4Smrg /* OK to memcpy */ 14537117f1b4Smrg dst->Hint = src->Hint; 14547117f1b4Smrg } 14557117f1b4Smrg if (mask & GL_LIGHTING_BIT) { 14567e995a2eSmrg /* OK to memcpy */ 14577117f1b4Smrg dst->Light = src->Light; 14587117f1b4Smrg } 14597117f1b4Smrg if (mask & GL_LINE_BIT) { 14607117f1b4Smrg /* OK to memcpy */ 14617117f1b4Smrg dst->Line = src->Line; 14627117f1b4Smrg } 14637117f1b4Smrg if (mask & GL_LIST_BIT) { 14647117f1b4Smrg /* OK to memcpy */ 14657117f1b4Smrg dst->List = src->List; 14667117f1b4Smrg } 14677117f1b4Smrg if (mask & GL_PIXEL_MODE_BIT) { 14687117f1b4Smrg /* OK to memcpy */ 14697117f1b4Smrg dst->Pixel = src->Pixel; 14707117f1b4Smrg } 14717117f1b4Smrg if (mask & GL_POINT_BIT) { 14727117f1b4Smrg /* OK to memcpy */ 14737117f1b4Smrg dst->Point = src->Point; 14747117f1b4Smrg } 14757117f1b4Smrg if (mask & GL_POLYGON_BIT) { 14767117f1b4Smrg /* OK to memcpy */ 14777117f1b4Smrg dst->Polygon = src->Polygon; 14787117f1b4Smrg } 14797117f1b4Smrg if (mask & GL_POLYGON_STIPPLE_BIT) { 1480cdc920a0Smrg /* Use loop instead of memcpy due to problem with Portland Group's 14817117f1b4Smrg * C compiler. Reported by John Stone. 14827117f1b4Smrg */ 14837117f1b4Smrg GLuint i; 14847117f1b4Smrg for (i = 0; i < 32; i++) { 14857117f1b4Smrg dst->PolygonStipple[i] = src->PolygonStipple[i]; 14867117f1b4Smrg } 14877117f1b4Smrg } 14887117f1b4Smrg if (mask & GL_SCISSOR_BIT) { 14897117f1b4Smrg /* OK to memcpy */ 14907117f1b4Smrg dst->Scissor = src->Scissor; 14917117f1b4Smrg } 14927117f1b4Smrg if (mask & GL_STENCIL_BUFFER_BIT) { 14937117f1b4Smrg /* OK to memcpy */ 14947117f1b4Smrg dst->Stencil = src->Stencil; 14957117f1b4Smrg } 14967117f1b4Smrg if (mask & GL_TEXTURE_BIT) { 14977117f1b4Smrg /* Cannot memcpy because of pointers */ 14987117f1b4Smrg _mesa_copy_texture_state(src, dst); 14997117f1b4Smrg } 15007117f1b4Smrg if (mask & GL_TRANSFORM_BIT) { 15017117f1b4Smrg /* OK to memcpy */ 15027117f1b4Smrg dst->Transform = src->Transform; 15037117f1b4Smrg } 15047117f1b4Smrg if (mask & GL_VIEWPORT_BIT) { 1505b167d5e7Smrg unsigned i; 1506b167d5e7Smrg for (i = 0; i < src->Const.MaxViewports; i++) { 15077e995a2eSmrg /* OK to memcpy */ 15087e995a2eSmrg dst->ViewportArray[i] = src->ViewportArray[i]; 1509b167d5e7Smrg } 15107117f1b4Smrg } 15117117f1b4Smrg 15127117f1b4Smrg /* XXX FIXME: Call callbacks? 15137117f1b4Smrg */ 15147117f1b4Smrg dst->NewState = _NEW_ALL; 1515b167d5e7Smrg dst->NewDriverState = ~0; 15167117f1b4Smrg} 15177117f1b4Smrg 15187117f1b4Smrg 15197117f1b4Smrg/** 15207117f1b4Smrg * Check if the given context can render into the given framebuffer 15217117f1b4Smrg * by checking visual attributes. 15227117f1b4Smrg * 15237117f1b4Smrg * \return GL_TRUE if compatible, GL_FALSE otherwise. 15247117f1b4Smrg */ 15257e995a2eSmrgstatic GLboolean 15263464ebd5Sriastradhcheck_compatible(const struct gl_context *ctx, 15273464ebd5Sriastradh const struct gl_framebuffer *buffer) 15287117f1b4Smrg{ 15293464ebd5Sriastradh const struct gl_config *ctxvis = &ctx->Visual; 15303464ebd5Sriastradh const struct gl_config *bufvis = &buffer->Visual; 15317117f1b4Smrg 15323464ebd5Sriastradh if (buffer == _mesa_get_incomplete_framebuffer()) 15337117f1b4Smrg return GL_TRUE; 15347117f1b4Smrg 15357e995a2eSmrg#define check_component(foo) \ 15367e995a2eSmrg if (ctxvis->foo && bufvis->foo && \ 15377e995a2eSmrg ctxvis->foo != bufvis->foo) \ 15387e995a2eSmrg return GL_FALSE 15397e995a2eSmrg 15407e995a2eSmrg check_component(redMask); 15417e995a2eSmrg check_component(greenMask); 15427e995a2eSmrg check_component(blueMask); 15437e995a2eSmrg check_component(depthBits); 15447e995a2eSmrg check_component(stencilBits); 15457e995a2eSmrg 15467e995a2eSmrg#undef check_component 15477117f1b4Smrg 15487117f1b4Smrg return GL_TRUE; 15497117f1b4Smrg} 15507117f1b4Smrg 15517117f1b4Smrg 1552c7037ccdSmrg/** 1553c7037ccdSmrg * Check if the viewport/scissor size has not yet been initialized. 1554c7037ccdSmrg * Initialize the size if the given width and height are non-zero. 1555c7037ccdSmrg */ 15567e995a2eSmrgstatic void 15577e995a2eSmrgcheck_init_viewport(struct gl_context *ctx, GLuint width, GLuint height) 1558c7037ccdSmrg{ 1559c7037ccdSmrg if (!ctx->ViewportInitialized && width > 0 && height > 0) { 1560b167d5e7Smrg unsigned i; 1561b167d5e7Smrg 1562c7037ccdSmrg /* Note: set flag here, before calling _mesa_set_viewport(), to prevent 1563c7037ccdSmrg * potential infinite recursion. 1564c7037ccdSmrg */ 1565c7037ccdSmrg ctx->ViewportInitialized = GL_TRUE; 1566b167d5e7Smrg 1567b167d5e7Smrg /* Note: ctx->Const.MaxViewports may not have been set by the driver 1568b167d5e7Smrg * yet, so just initialize all of them. 1569b167d5e7Smrg */ 1570b167d5e7Smrg for (i = 0; i < MAX_VIEWPORTS; i++) { 1571b167d5e7Smrg _mesa_set_viewport(ctx, i, 0, 0, width, height); 1572b167d5e7Smrg _mesa_set_scissor(ctx, i, 0, 0, width, height); 1573b167d5e7Smrg } 1574c7037ccdSmrg } 1575c7037ccdSmrg} 1576c7037ccdSmrg 15777e995a2eSmrg 1578b167d5e7Smrgstatic void 1579b167d5e7Smrghandle_first_current(struct gl_context *ctx) 1580b167d5e7Smrg{ 15817e995a2eSmrg if (ctx->Version == 0 || !ctx->DrawBuffer) { 15827e995a2eSmrg /* probably in the process of tearing down the context */ 15837e995a2eSmrg return; 15847e995a2eSmrg } 1585b167d5e7Smrg 1586b167d5e7Smrg check_context_limits(ctx); 1587b167d5e7Smrg 15887e995a2eSmrg _mesa_update_vertex_processing_mode(ctx); 15897e995a2eSmrg 1590b167d5e7Smrg /* According to GL_MESA_configless_context the default value of 1591b167d5e7Smrg * glDrawBuffers depends on the config of the first surface it is bound to. 15927e995a2eSmrg * For GLES it is always GL_BACK which has a magic interpretation. 15937e995a2eSmrg */ 1594b167d5e7Smrg if (!ctx->HasConfig && _mesa_is_desktop_gl(ctx)) { 1595b167d5e7Smrg if (ctx->DrawBuffer != _mesa_get_incomplete_framebuffer()) { 15967e995a2eSmrg GLenum16 buffer; 15977e995a2eSmrg 1598b167d5e7Smrg if (ctx->DrawBuffer->Visual.doubleBufferMode) 1599b167d5e7Smrg buffer = GL_BACK; 1600b167d5e7Smrg else 1601b167d5e7Smrg buffer = GL_FRONT; 1602b167d5e7Smrg 16037e995a2eSmrg _mesa_drawbuffers(ctx, ctx->DrawBuffer, 1, &buffer, 16047e995a2eSmrg NULL /* destMask */); 1605b167d5e7Smrg } 1606b167d5e7Smrg 1607b167d5e7Smrg if (ctx->ReadBuffer != _mesa_get_incomplete_framebuffer()) { 16087e995a2eSmrg gl_buffer_index bufferIndex; 16097e995a2eSmrg GLenum buffer; 16107e995a2eSmrg 1611b167d5e7Smrg if (ctx->ReadBuffer->Visual.doubleBufferMode) { 1612b167d5e7Smrg buffer = GL_BACK; 1613b167d5e7Smrg bufferIndex = BUFFER_BACK_LEFT; 1614b167d5e7Smrg } 1615b167d5e7Smrg else { 1616b167d5e7Smrg buffer = GL_FRONT; 1617b167d5e7Smrg bufferIndex = BUFFER_FRONT_LEFT; 1618b167d5e7Smrg } 1619b167d5e7Smrg 16207e995a2eSmrg _mesa_readbuffer(ctx, ctx->ReadBuffer, buffer, bufferIndex); 1621b167d5e7Smrg } 1622b167d5e7Smrg } 1623b167d5e7Smrg 16247e995a2eSmrg /* Determine if generic vertex attribute 0 aliases the conventional 16257e995a2eSmrg * glVertex position. 16267e995a2eSmrg */ 16277e995a2eSmrg { 16287e995a2eSmrg const bool is_forward_compatible_context = 16297e995a2eSmrg ctx->Const.ContextFlags & GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT; 16307e995a2eSmrg 16317e995a2eSmrg /* In OpenGL 3.1 attribute 0 becomes non-magic, just like in OpenGL ES 16327e995a2eSmrg * 2.0. Note that we cannot just check for API_OPENGL_COMPAT here because 16337e995a2eSmrg * that will erroneously allow this usage in a 3.0 forward-compatible 16347e995a2eSmrg * context too. 16357e995a2eSmrg */ 16367e995a2eSmrg ctx->_AttribZeroAliasesVertex = (ctx->API == API_OPENGLES 16377e995a2eSmrg || (ctx->API == API_OPENGL_COMPAT 16387e995a2eSmrg && !is_forward_compatible_context)); 16397e995a2eSmrg } 16407e995a2eSmrg 1641b167d5e7Smrg /* We can use this to help debug user's problems. Tell them to set 1642b167d5e7Smrg * the MESA_INFO env variable before running their app. Then the 1643b167d5e7Smrg * first time each context is made current we'll print some useful 1644b167d5e7Smrg * information. 1645b167d5e7Smrg */ 16467e995a2eSmrg if (getenv("MESA_INFO")) { 1647b167d5e7Smrg _mesa_print_info(ctx); 1648b167d5e7Smrg } 1649b167d5e7Smrg} 1650c7037ccdSmrg 16517117f1b4Smrg/** 16527117f1b4Smrg * Bind the given context to the given drawBuffer and readBuffer and 16537117f1b4Smrg * make it the current context for the calling thread. 16547117f1b4Smrg * We'll render into the drawBuffer and read pixels from the 16557117f1b4Smrg * readBuffer (i.e. glRead/CopyPixels, glCopyTexImage, etc). 16567117f1b4Smrg * 16577117f1b4Smrg * We check that the context's and framebuffer's visuals are compatible 16587117f1b4Smrg * and return immediately if they're not. 16597117f1b4Smrg * 16607117f1b4Smrg * \param newCtx the new GL context. If NULL then there will be no current GL 16617117f1b4Smrg * context. 16627117f1b4Smrg * \param drawBuffer the drawing framebuffer 16637117f1b4Smrg * \param readBuffer the reading framebuffer 16647117f1b4Smrg */ 16654a49301eSmrgGLboolean 16663464ebd5Sriastradh_mesa_make_current( struct gl_context *newCtx, 16673464ebd5Sriastradh struct gl_framebuffer *drawBuffer, 16683464ebd5Sriastradh struct gl_framebuffer *readBuffer ) 16697117f1b4Smrg{ 16703464ebd5Sriastradh GET_CURRENT_CONTEXT(curCtx); 16713464ebd5Sriastradh 16727117f1b4Smrg if (MESA_VERBOSE & VERBOSE_API) 16737117f1b4Smrg _mesa_debug(newCtx, "_mesa_make_current()\n"); 16747117f1b4Smrg 16757117f1b4Smrg /* Check that the context's and framebuffer's visuals are compatible. 16767117f1b4Smrg */ 16777117f1b4Smrg if (newCtx && drawBuffer && newCtx->WinSysDrawBuffer != drawBuffer) { 16787117f1b4Smrg if (!check_compatible(newCtx, drawBuffer)) { 16797117f1b4Smrg _mesa_warning(newCtx, 16807117f1b4Smrg "MakeCurrent: incompatible visuals for context and drawbuffer"); 16814a49301eSmrg return GL_FALSE; 16827117f1b4Smrg } 16837117f1b4Smrg } 16847117f1b4Smrg if (newCtx && readBuffer && newCtx->WinSysReadBuffer != readBuffer) { 16857117f1b4Smrg if (!check_compatible(newCtx, readBuffer)) { 16867117f1b4Smrg _mesa_warning(newCtx, 16877117f1b4Smrg "MakeCurrent: incompatible visuals for context and readbuffer"); 16884a49301eSmrg return GL_FALSE; 16897117f1b4Smrg } 16907117f1b4Smrg } 16917117f1b4Smrg 16927e995a2eSmrg if (curCtx && 16937e995a2eSmrg (curCtx->WinSysDrawBuffer || curCtx->WinSysReadBuffer) && 16943464ebd5Sriastradh /* make sure this context is valid for flushing */ 16957e995a2eSmrg curCtx != newCtx && 16967e995a2eSmrg curCtx->Const.ContextReleaseBehavior == 16977e995a2eSmrg GL_CONTEXT_RELEASE_BEHAVIOR_FLUSH) { 16983464ebd5Sriastradh _mesa_flush(curCtx); 16997e995a2eSmrg } 17003464ebd5Sriastradh 17017e995a2eSmrg /* Call this periodically to detect when the user has begun using 17027e995a2eSmrg * GL rendering from multiple threads. 17037e995a2eSmrg */ 17047e995a2eSmrg _glapi_check_multithread(); 17057117f1b4Smrg 17067117f1b4Smrg if (!newCtx) { 17077117f1b4Smrg _glapi_set_dispatch(NULL); /* none current */ 17087e995a2eSmrg /* We need old ctx to correctly release Draw/ReadBuffer 17097e995a2eSmrg * and avoid a surface leak in st_renderbuffer_delete. 17107e995a2eSmrg * Therefore, first drop buffers then set new ctx to NULL. 17117e995a2eSmrg */ 17127e995a2eSmrg if (curCtx) { 17137e995a2eSmrg _mesa_reference_framebuffer(&curCtx->WinSysDrawBuffer, NULL); 17147e995a2eSmrg _mesa_reference_framebuffer(&curCtx->WinSysReadBuffer, NULL); 17157e995a2eSmrg } 17167e995a2eSmrg _glapi_set_context(NULL); 17177e995a2eSmrg assert(_mesa_get_current_context() == NULL); 17187117f1b4Smrg } 17197117f1b4Smrg else { 17207e995a2eSmrg _glapi_set_context((void *) newCtx); 17217e995a2eSmrg assert(_mesa_get_current_context() == newCtx); 17227e995a2eSmrg _glapi_set_dispatch(newCtx->CurrentClientDispatch); 17237117f1b4Smrg 17247117f1b4Smrg if (drawBuffer && readBuffer) { 17257e995a2eSmrg assert(_mesa_is_winsys_fbo(drawBuffer)); 17267e995a2eSmrg assert(_mesa_is_winsys_fbo(readBuffer)); 17277117f1b4Smrg _mesa_reference_framebuffer(&newCtx->WinSysDrawBuffer, drawBuffer); 17287117f1b4Smrg _mesa_reference_framebuffer(&newCtx->WinSysReadBuffer, readBuffer); 17297117f1b4Smrg 17307117f1b4Smrg /* 17317117f1b4Smrg * Only set the context's Draw/ReadBuffer fields if they're NULL 17327117f1b4Smrg * or not bound to a user-created FBO. 17337117f1b4Smrg */ 1734b167d5e7Smrg if (!newCtx->DrawBuffer || _mesa_is_winsys_fbo(newCtx->DrawBuffer)) { 17357117f1b4Smrg _mesa_reference_framebuffer(&newCtx->DrawBuffer, drawBuffer); 17363464ebd5Sriastradh /* Update the FBO's list of drawbuffers/renderbuffers. 17373464ebd5Sriastradh * For winsys FBOs this comes from the GL state (which may have 17383464ebd5Sriastradh * changed since the last time this FBO was bound). 17393464ebd5Sriastradh */ 17403464ebd5Sriastradh _mesa_update_draw_buffers(newCtx); 17417117f1b4Smrg } 1742b167d5e7Smrg if (!newCtx->ReadBuffer || _mesa_is_winsys_fbo(newCtx->ReadBuffer)) { 17437117f1b4Smrg _mesa_reference_framebuffer(&newCtx->ReadBuffer, readBuffer); 17447e995a2eSmrg /* In _mesa_initialize_window_framebuffer, for single-buffered 17457e995a2eSmrg * visuals, the ColorReadBuffer is set to be GL_FRONT, even with 17467e995a2eSmrg * GLES contexts. When calling read_buffer, we verify we are reading 17477e995a2eSmrg * from GL_BACK in is_legal_es3_readbuffer_enum. But the default is 17487e995a2eSmrg * incorrect, and certain dEQP tests check this. So fix it here. 17497e995a2eSmrg */ 17507e995a2eSmrg if (_mesa_is_gles(newCtx) && 17517e995a2eSmrg !newCtx->ReadBuffer->Visual.doubleBufferMode) 17527e995a2eSmrg if (newCtx->ReadBuffer->ColorReadBuffer == GL_FRONT) 17537e995a2eSmrg newCtx->ReadBuffer->ColorReadBuffer = GL_BACK; 17547117f1b4Smrg } 17557117f1b4Smrg 1756c1f859d4Smrg /* XXX only set this flag if we're really changing the draw/read 1757c1f859d4Smrg * framebuffer bindings. 1758c1f859d4Smrg */ 17597e995a2eSmrg newCtx->NewState |= _NEW_BUFFERS; 17607117f1b4Smrg 17617e995a2eSmrg check_init_viewport(newCtx, drawBuffer->Width, drawBuffer->Height); 17627117f1b4Smrg } 17637117f1b4Smrg 17647117f1b4Smrg if (newCtx->FirstTimeCurrent) { 1765b167d5e7Smrg handle_first_current(newCtx); 17667e995a2eSmrg newCtx->FirstTimeCurrent = GL_FALSE; 17677117f1b4Smrg } 17687117f1b4Smrg } 17697e995a2eSmrg 17704a49301eSmrg return GL_TRUE; 17717117f1b4Smrg} 17727117f1b4Smrg 17737117f1b4Smrg 17747117f1b4Smrg/** 17757117f1b4Smrg * Make context 'ctx' share the display lists, textures and programs 17767117f1b4Smrg * that are associated with 'ctxToShare'. 17777117f1b4Smrg * Any display lists, textures or programs associated with 'ctx' will 17787117f1b4Smrg * be deleted if nobody else is sharing them. 17797117f1b4Smrg */ 17807117f1b4SmrgGLboolean 17813464ebd5Sriastradh_mesa_share_state(struct gl_context *ctx, struct gl_context *ctxToShare) 17827117f1b4Smrg{ 17837117f1b4Smrg if (ctx && ctxToShare && ctx->Shared && ctxToShare->Shared) { 1784b167d5e7Smrg struct gl_shared_state *oldShared = NULL; 1785b167d5e7Smrg 1786b167d5e7Smrg /* save ref to old state to prevent it from being deleted immediately */ 1787b167d5e7Smrg _mesa_reference_shared_state(ctx, &oldShared, ctx->Shared); 1788c1f859d4Smrg 1789b167d5e7Smrg /* update ctx's Shared pointer */ 1790b167d5e7Smrg _mesa_reference_shared_state(ctx, &ctx->Shared, ctxToShare->Shared); 1791c1f859d4Smrg 1792c1f859d4Smrg update_default_objects(ctx); 1793c1f859d4Smrg 1794b167d5e7Smrg /* release the old shared state */ 1795b167d5e7Smrg _mesa_reference_shared_state(ctx, &oldShared, NULL); 1796c1f859d4Smrg 17977117f1b4Smrg return GL_TRUE; 17987117f1b4Smrg } 17997117f1b4Smrg else { 18007117f1b4Smrg return GL_FALSE; 18017117f1b4Smrg } 18027117f1b4Smrg} 18037117f1b4Smrg 18047117f1b4Smrg 18057117f1b4Smrg 18067117f1b4Smrg/** 18077117f1b4Smrg * \return pointer to the current GL context for this thread. 18087e995a2eSmrg * 18097117f1b4Smrg * Calls _glapi_get_context(). This isn't the fastest way to get the current 18107117f1b4Smrg * context. If you need speed, see the #GET_CURRENT_CONTEXT macro in 18117117f1b4Smrg * context.h. 18127117f1b4Smrg */ 18133464ebd5Sriastradhstruct gl_context * 18147117f1b4Smrg_mesa_get_current_context( void ) 18157117f1b4Smrg{ 18163464ebd5Sriastradh return (struct gl_context *) _glapi_get_context(); 18177117f1b4Smrg} 18187117f1b4Smrg 18197117f1b4Smrg 18207117f1b4Smrg/** 18217117f1b4Smrg * Get context's current API dispatch table. 18227117f1b4Smrg * 18237e995a2eSmrg * It'll either be the immediate-mode execute dispatcher, the display list 18247e995a2eSmrg * compile dispatcher, or the thread marshalling dispatcher. 18257e995a2eSmrg * 18267117f1b4Smrg * \param ctx GL context. 18277117f1b4Smrg * 18287117f1b4Smrg * \return pointer to dispatch_table. 18297117f1b4Smrg * 18307e995a2eSmrg * Simply returns __struct gl_contextRec::CurrentClientDispatch. 18317117f1b4Smrg */ 18327117f1b4Smrgstruct _glapi_table * 18333464ebd5Sriastradh_mesa_get_dispatch(struct gl_context *ctx) 18347117f1b4Smrg{ 18357e995a2eSmrg return ctx->CurrentClientDispatch; 18367117f1b4Smrg} 18377117f1b4Smrg 18387117f1b4Smrg/*@}*/ 18397117f1b4Smrg 18407117f1b4Smrg 18417117f1b4Smrg/**********************************************************************/ 18427117f1b4Smrg/** \name Miscellaneous functions */ 18437117f1b4Smrg/**********************************************************************/ 18447117f1b4Smrg/*@{*/ 18454a49301eSmrg/** 18464a49301eSmrg * Flush commands. 18474a49301eSmrg */ 18484a49301eSmrgvoid 18493464ebd5Sriastradh_mesa_flush(struct gl_context *ctx) 18504a49301eSmrg{ 1851b167d5e7Smrg FLUSH_VERTICES( ctx, 0 ); 18524a49301eSmrg FLUSH_CURRENT( ctx, 0 ); 18534a49301eSmrg if (ctx->Driver.Flush) { 18544a49301eSmrg ctx->Driver.Flush(ctx); 18554a49301eSmrg } 18564a49301eSmrg} 18574a49301eSmrg 18584a49301eSmrg 18594a49301eSmrg 18607117f1b4Smrg/** 18617e995a2eSmrg * Flush commands and wait for completion. 18627117f1b4Smrg * 18637117f1b4Smrg * Calls the #ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH macro and the 18647117f1b4Smrg * dd_function_table::Finish driver callback, if not NULL. 18657117f1b4Smrg */ 18667117f1b4Smrgvoid GLAPIENTRY 18677117f1b4Smrg_mesa_Finish(void) 18687117f1b4Smrg{ 18697117f1b4Smrg GET_CURRENT_CONTEXT(ctx); 1870b167d5e7Smrg ASSERT_OUTSIDE_BEGIN_END(ctx); 18717e995a2eSmrg 18727e995a2eSmrg FLUSH_VERTICES(ctx, 0); 18737e995a2eSmrg FLUSH_CURRENT(ctx, 0); 18747e995a2eSmrg 18757e995a2eSmrg if (ctx->Driver.Finish) { 18767e995a2eSmrg ctx->Driver.Finish(ctx); 18777e995a2eSmrg } 18787117f1b4Smrg} 18797117f1b4Smrg 18807117f1b4Smrg 18817117f1b4Smrg/** 18827117f1b4Smrg * Execute glFlush(). 18837117f1b4Smrg * 18847117f1b4Smrg * Calls the #ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH macro and the 18857117f1b4Smrg * dd_function_table::Flush driver callback, if not NULL. 18867117f1b4Smrg */ 18877117f1b4Smrgvoid GLAPIENTRY 18887117f1b4Smrg_mesa_Flush(void) 18897117f1b4Smrg{ 18907117f1b4Smrg GET_CURRENT_CONTEXT(ctx); 1891b167d5e7Smrg ASSERT_OUTSIDE_BEGIN_END(ctx); 18924a49301eSmrg _mesa_flush(ctx); 18934a49301eSmrg} 18944a49301eSmrg 18954a49301eSmrg 18967117f1b4Smrg/*@}*/ 1897