context.c revision c7037ccd
17117f1b4Smrg/* 27117f1b4Smrg * Mesa 3-D graphics library 3c1f859d4Smrg * Version: 7.3 47117f1b4Smrg * 57117f1b4Smrg * Copyright (C) 1999-2007 Brian Paul All Rights Reserved. 6c1f859d4Smrg * Copyright (C) 2008 VMware, Inc. All Rights Reserved. 77117f1b4Smrg * 87117f1b4Smrg * Permission is hereby granted, free of charge, to any person obtaining a 97117f1b4Smrg * copy of this software and associated documentation files (the "Software"), 107117f1b4Smrg * to deal in the Software without restriction, including without limitation 117117f1b4Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 127117f1b4Smrg * and/or sell copies of the Software, and to permit persons to whom the 137117f1b4Smrg * Software is furnished to do so, subject to the following conditions: 147117f1b4Smrg * 157117f1b4Smrg * The above copyright notice and this permission notice shall be included 167117f1b4Smrg * in all copies or substantial portions of the Software. 177117f1b4Smrg * 187117f1b4Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 197117f1b4Smrg * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 207117f1b4Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 217117f1b4Smrg * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 227117f1b4Smrg * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 237117f1b4Smrg * CONNECTION WITH THE SOFTWARE OR THE USE OR 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" 81c1f859d4Smrg#if FEATURE_accum 827117f1b4Smrg#include "accum.h" 83c1f859d4Smrg#endif 84c1f859d4Smrg#include "api_exec.h" 857117f1b4Smrg#include "arrayobj.h" 86c1f859d4Smrg#if FEATURE_attrib_stack 877117f1b4Smrg#include "attrib.h" 88c1f859d4Smrg#endif 897117f1b4Smrg#include "blend.h" 907117f1b4Smrg#include "buffers.h" 917117f1b4Smrg#include "bufferobj.h" 92c1f859d4Smrg#if FEATURE_colortable 937117f1b4Smrg#include "colortab.h" 94c1f859d4Smrg#endif 957117f1b4Smrg#include "context.h" 967117f1b4Smrg#include "debug.h" 977117f1b4Smrg#include "depth.h" 98c1f859d4Smrg#if FEATURE_dlist 997117f1b4Smrg#include "dlist.h" 100c1f859d4Smrg#endif 101c1f859d4Smrg#if FEATURE_evaluators 1027117f1b4Smrg#include "eval.h" 103c1f859d4Smrg#endif 1047117f1b4Smrg#include "enums.h" 1057117f1b4Smrg#include "extensions.h" 1067117f1b4Smrg#include "fbobject.h" 107c1f859d4Smrg#if FEATURE_feedback 1087117f1b4Smrg#include "feedback.h" 109c1f859d4Smrg#endif 1107117f1b4Smrg#include "fog.h" 1117117f1b4Smrg#include "framebuffer.h" 1127117f1b4Smrg#include "get.h" 113c1f859d4Smrg#if FEATURE_histogram 1147117f1b4Smrg#include "histogram.h" 115c1f859d4Smrg#endif 1167117f1b4Smrg#include "hint.h" 1177117f1b4Smrg#include "hash.h" 1187117f1b4Smrg#include "light.h" 1197117f1b4Smrg#include "lines.h" 1207117f1b4Smrg#include "macros.h" 1217117f1b4Smrg#include "matrix.h" 122c1f859d4Smrg#include "multisample.h" 1237117f1b4Smrg#include "pixel.h" 124c1f859d4Smrg#include "pixelstore.h" 1257117f1b4Smrg#include "points.h" 1267117f1b4Smrg#include "polygon.h" 127c1f859d4Smrg#if FEATURE_ARB_occlusion_query 1287117f1b4Smrg#include "queryobj.h" 129c1f859d4Smrg#endif 130c1f859d4Smrg#if FEATURE_drawpix 1317117f1b4Smrg#include "rastpos.h" 132c1f859d4Smrg#endif 133c1f859d4Smrg#include "scissor.h" 1347117f1b4Smrg#include "simple_list.h" 1357117f1b4Smrg#include "state.h" 1367117f1b4Smrg#include "stencil.h" 1377117f1b4Smrg#include "texcompress.h" 1387117f1b4Smrg#include "teximage.h" 1397117f1b4Smrg#include "texobj.h" 1407117f1b4Smrg#include "texstate.h" 1417117f1b4Smrg#include "mtypes.h" 1427117f1b4Smrg#include "varray.h" 1437117f1b4Smrg#include "version.h" 1447117f1b4Smrg#include "vtxfmt.h" 145c1f859d4Smrg#include "glapi/glthread.h" 146c1f859d4Smrg#include "glapi/glapioffsets.h" 147c1f859d4Smrg#include "glapi/glapitable.h" 148c1f859d4Smrg#if FEATURE_NV_vertex_program || FEATURE_NV_fragment_program 149c1f859d4Smrg#include "shader/program.h" 150c1f859d4Smrg#endif 151c1f859d4Smrg#include "shader/shader_api.h" 152c1f859d4Smrg#if FEATURE_ATI_fragment_shader 153c1f859d4Smrg#include "shader/atifragshader.h" 154c1f859d4Smrg#endif 1557117f1b4Smrg#if _HAVE_FULL_GL 1567117f1b4Smrg#include "math/m_translate.h" 1577117f1b4Smrg#include "math/m_matrix.h" 1587117f1b4Smrg#include "math/m_xform.h" 1597117f1b4Smrg#include "math/mathmod.h" 1607117f1b4Smrg#endif 1617117f1b4Smrg 1627117f1b4Smrg#ifdef USE_SPARC_ASM 1637117f1b4Smrg#include "sparc/sparc.h" 1647117f1b4Smrg#endif 1657117f1b4Smrg 1667117f1b4Smrg#ifndef MESA_VERBOSE 1677117f1b4Smrgint MESA_VERBOSE = 0; 1687117f1b4Smrg#endif 1697117f1b4Smrg 1707117f1b4Smrg#ifndef MESA_DEBUG_FLAGS 1717117f1b4Smrgint MESA_DEBUG_FLAGS = 0; 1727117f1b4Smrg#endif 1737117f1b4Smrg 1747117f1b4Smrg 1757117f1b4Smrg/* ubyte -> float conversion */ 1767117f1b4SmrgGLfloat _mesa_ubyte_to_float_color_tab[256]; 1777117f1b4Smrg 1787117f1b4Smrg 1797117f1b4Smrg 1807117f1b4Smrg/** 1817117f1b4Smrg * Swap buffers notification callback. 1827117f1b4Smrg * 1837117f1b4Smrg * \param gc GL context. 1847117f1b4Smrg * 1857117f1b4Smrg * Called by window system just before swapping buffers. 1867117f1b4Smrg * We have to finish any pending rendering. 1877117f1b4Smrg */ 1887117f1b4Smrgvoid 1897117f1b4Smrg_mesa_notifySwapBuffers(__GLcontext *gc) 1907117f1b4Smrg{ 1917117f1b4Smrg FLUSH_VERTICES( gc, 0 ); 1927117f1b4Smrg} 1937117f1b4Smrg 1947117f1b4Smrg 1957117f1b4Smrg/**********************************************************************/ 1967117f1b4Smrg/** \name GL Visual allocation/destruction */ 1977117f1b4Smrg/**********************************************************************/ 1987117f1b4Smrg/*@{*/ 1997117f1b4Smrg 2007117f1b4Smrg/** 2017117f1b4Smrg * Allocates a GLvisual structure and initializes it via 2027117f1b4Smrg * _mesa_initialize_visual(). 2037117f1b4Smrg * 2047117f1b4Smrg * \param rgbFlag GL_TRUE for RGB(A) mode, GL_FALSE for Color Index mode. 2057117f1b4Smrg * \param dbFlag double buffering 2067117f1b4Smrg * \param stereoFlag stereo buffer 2077117f1b4Smrg * \param depthBits requested bits per depth buffer value. Any value in [0, 32] 2087117f1b4Smrg * is acceptable but the actual depth type will be GLushort or GLuint as 2097117f1b4Smrg * needed. 2107117f1b4Smrg * \param stencilBits requested minimum bits per stencil buffer value 2117117f1b4Smrg * \param accumRedBits, accumGreenBits, accumBlueBits, accumAlphaBits number of bits per color component in accum buffer. 2127117f1b4Smrg * \param indexBits number of bits per pixel if \p rgbFlag is GL_FALSE 2137117f1b4Smrg * \param redBits number of bits per color component in frame buffer for RGB(A) 2147117f1b4Smrg * mode. We always use 8 in core Mesa though. 2157117f1b4Smrg * \param greenBits same as above. 2167117f1b4Smrg * \param blueBits same as above. 2177117f1b4Smrg * \param alphaBits same as above. 2187117f1b4Smrg * \param numSamples not really used. 2197117f1b4Smrg * 2207117f1b4Smrg * \return pointer to new GLvisual or NULL if requested parameters can't be 2217117f1b4Smrg * met. 2227117f1b4Smrg * 2237117f1b4Smrg * \note Need to add params for level and numAuxBuffers (at least) 2247117f1b4Smrg */ 2257117f1b4SmrgGLvisual * 2267117f1b4Smrg_mesa_create_visual( GLboolean rgbFlag, 2277117f1b4Smrg GLboolean dbFlag, 2287117f1b4Smrg GLboolean stereoFlag, 2297117f1b4Smrg GLint redBits, 2307117f1b4Smrg GLint greenBits, 2317117f1b4Smrg GLint blueBits, 2327117f1b4Smrg GLint alphaBits, 2337117f1b4Smrg GLint indexBits, 2347117f1b4Smrg GLint depthBits, 2357117f1b4Smrg GLint stencilBits, 2367117f1b4Smrg GLint accumRedBits, 2377117f1b4Smrg GLint accumGreenBits, 2387117f1b4Smrg GLint accumBlueBits, 2397117f1b4Smrg GLint accumAlphaBits, 2407117f1b4Smrg GLint numSamples ) 2417117f1b4Smrg{ 2427117f1b4Smrg GLvisual *vis = (GLvisual *) _mesa_calloc(sizeof(GLvisual)); 2437117f1b4Smrg if (vis) { 2447117f1b4Smrg if (!_mesa_initialize_visual(vis, rgbFlag, dbFlag, stereoFlag, 2457117f1b4Smrg redBits, greenBits, blueBits, alphaBits, 2467117f1b4Smrg indexBits, depthBits, stencilBits, 2477117f1b4Smrg accumRedBits, accumGreenBits, 2487117f1b4Smrg accumBlueBits, accumAlphaBits, 2497117f1b4Smrg numSamples)) { 2507117f1b4Smrg _mesa_free(vis); 2517117f1b4Smrg return NULL; 2527117f1b4Smrg } 2537117f1b4Smrg } 2547117f1b4Smrg return vis; 2557117f1b4Smrg} 2567117f1b4Smrg 2577117f1b4Smrg/** 2587117f1b4Smrg * Makes some sanity checks and fills in the fields of the 2597117f1b4Smrg * GLvisual object with the given parameters. If the caller needs 2607117f1b4Smrg * to set additional fields, he should just probably init the whole GLvisual 2617117f1b4Smrg * object himself. 2627117f1b4Smrg * \return GL_TRUE on success, or GL_FALSE on failure. 2637117f1b4Smrg * 2647117f1b4Smrg * \sa _mesa_create_visual() above for the parameter description. 2657117f1b4Smrg */ 2667117f1b4SmrgGLboolean 2677117f1b4Smrg_mesa_initialize_visual( GLvisual *vis, 2687117f1b4Smrg GLboolean rgbFlag, 2697117f1b4Smrg GLboolean dbFlag, 2707117f1b4Smrg GLboolean stereoFlag, 2717117f1b4Smrg GLint redBits, 2727117f1b4Smrg GLint greenBits, 2737117f1b4Smrg GLint blueBits, 2747117f1b4Smrg GLint alphaBits, 2757117f1b4Smrg GLint indexBits, 2767117f1b4Smrg GLint depthBits, 2777117f1b4Smrg GLint stencilBits, 2787117f1b4Smrg GLint accumRedBits, 2797117f1b4Smrg GLint accumGreenBits, 2807117f1b4Smrg GLint accumBlueBits, 2817117f1b4Smrg GLint accumAlphaBits, 2827117f1b4Smrg GLint numSamples ) 2837117f1b4Smrg{ 2847117f1b4Smrg assert(vis); 2857117f1b4Smrg 2867117f1b4Smrg if (depthBits < 0 || depthBits > 32) { 2877117f1b4Smrg return GL_FALSE; 2887117f1b4Smrg } 2897117f1b4Smrg if (stencilBits < 0 || stencilBits > STENCIL_BITS) { 2907117f1b4Smrg return GL_FALSE; 2917117f1b4Smrg } 2927117f1b4Smrg assert(accumRedBits >= 0); 2937117f1b4Smrg assert(accumGreenBits >= 0); 2947117f1b4Smrg assert(accumBlueBits >= 0); 2957117f1b4Smrg assert(accumAlphaBits >= 0); 2967117f1b4Smrg 2977117f1b4Smrg vis->rgbMode = rgbFlag; 2987117f1b4Smrg vis->doubleBufferMode = dbFlag; 2997117f1b4Smrg vis->stereoMode = stereoFlag; 3007117f1b4Smrg 3017117f1b4Smrg vis->redBits = redBits; 3027117f1b4Smrg vis->greenBits = greenBits; 3037117f1b4Smrg vis->blueBits = blueBits; 3047117f1b4Smrg vis->alphaBits = alphaBits; 3057117f1b4Smrg vis->rgbBits = redBits + greenBits + blueBits; 3067117f1b4Smrg 3077117f1b4Smrg vis->indexBits = indexBits; 3087117f1b4Smrg vis->depthBits = depthBits; 3097117f1b4Smrg vis->stencilBits = stencilBits; 3107117f1b4Smrg 3117117f1b4Smrg vis->accumRedBits = accumRedBits; 3127117f1b4Smrg vis->accumGreenBits = accumGreenBits; 3137117f1b4Smrg vis->accumBlueBits = accumBlueBits; 3147117f1b4Smrg vis->accumAlphaBits = accumAlphaBits; 3157117f1b4Smrg 3167117f1b4Smrg vis->haveAccumBuffer = accumRedBits > 0; 3177117f1b4Smrg vis->haveDepthBuffer = depthBits > 0; 3187117f1b4Smrg vis->haveStencilBuffer = stencilBits > 0; 3197117f1b4Smrg 3207117f1b4Smrg vis->numAuxBuffers = 0; 3217117f1b4Smrg vis->level = 0; 3227117f1b4Smrg vis->pixmapMode = 0; 3237117f1b4Smrg vis->sampleBuffers = numSamples > 0 ? 1 : 0; 3247117f1b4Smrg vis->samples = numSamples; 3257117f1b4Smrg 3267117f1b4Smrg return GL_TRUE; 3277117f1b4Smrg} 3287117f1b4Smrg 3297117f1b4Smrg 3307117f1b4Smrg/** 3317117f1b4Smrg * Destroy a visual and free its memory. 3327117f1b4Smrg * 3337117f1b4Smrg * \param vis visual. 3347117f1b4Smrg * 3357117f1b4Smrg * Frees the visual structure. 3367117f1b4Smrg */ 3377117f1b4Smrgvoid 3387117f1b4Smrg_mesa_destroy_visual( GLvisual *vis ) 3397117f1b4Smrg{ 3407117f1b4Smrg _mesa_free(vis); 3417117f1b4Smrg} 3427117f1b4Smrg 3437117f1b4Smrg/*@}*/ 3447117f1b4Smrg 3457117f1b4Smrg 3467117f1b4Smrg/**********************************************************************/ 3477117f1b4Smrg/** \name Context allocation, initialization, destroying 3487117f1b4Smrg * 3497117f1b4Smrg * The purpose of the most initialization functions here is to provide the 3507117f1b4Smrg * default state values according to the OpenGL specification. 3517117f1b4Smrg */ 3527117f1b4Smrg/**********************************************************************/ 3537117f1b4Smrg/*@{*/ 3547117f1b4Smrg 3557117f1b4Smrg/** 3567117f1b4Smrg * One-time initialization mutex lock. 3577117f1b4Smrg * 3587117f1b4Smrg * \sa Used by one_time_init(). 3597117f1b4Smrg */ 3607117f1b4Smrg_glthread_DECLARE_STATIC_MUTEX(OneTimeLock); 3617117f1b4Smrg 3627117f1b4Smrg/** 3637117f1b4Smrg * Calls all the various one-time-init functions in Mesa. 3647117f1b4Smrg * 3657117f1b4Smrg * While holding a global mutex lock, calls several initialization functions, 3667117f1b4Smrg * and sets the glapi callbacks if the \c MESA_DEBUG environment variable is 3677117f1b4Smrg * defined. 3687117f1b4Smrg * 3697117f1b4Smrg * \sa _math_init(). 3707117f1b4Smrg */ 3717117f1b4Smrgstatic void 3727117f1b4Smrgone_time_init( GLcontext *ctx ) 3737117f1b4Smrg{ 3747117f1b4Smrg static GLboolean alreadyCalled = GL_FALSE; 3757117f1b4Smrg (void) ctx; 3767117f1b4Smrg _glthread_LOCK_MUTEX(OneTimeLock); 3777117f1b4Smrg if (!alreadyCalled) { 3787117f1b4Smrg GLuint i; 3797117f1b4Smrg 3807117f1b4Smrg /* do some implementation tests */ 3817117f1b4Smrg assert( sizeof(GLbyte) == 1 ); 3827117f1b4Smrg assert( sizeof(GLubyte) == 1 ); 3837117f1b4Smrg assert( sizeof(GLshort) == 2 ); 3847117f1b4Smrg assert( sizeof(GLushort) == 2 ); 3857117f1b4Smrg assert( sizeof(GLint) == 4 ); 3867117f1b4Smrg assert( sizeof(GLuint) == 4 ); 3877117f1b4Smrg 3887117f1b4Smrg _mesa_init_sqrt_table(); 3897117f1b4Smrg 3907117f1b4Smrg#if _HAVE_FULL_GL 3917117f1b4Smrg _math_init(); 3927117f1b4Smrg 3937117f1b4Smrg for (i = 0; i < 256; i++) { 3947117f1b4Smrg _mesa_ubyte_to_float_color_tab[i] = (float) i / 255.0F; 3957117f1b4Smrg } 3967117f1b4Smrg#endif 3977117f1b4Smrg 3987117f1b4Smrg#ifdef USE_SPARC_ASM 3997117f1b4Smrg _mesa_init_sparc_glapi_relocs(); 4007117f1b4Smrg#endif 4017117f1b4Smrg if (_mesa_getenv("MESA_DEBUG")) { 4027117f1b4Smrg _glapi_noop_enable_warnings(GL_TRUE); 4037117f1b4Smrg _glapi_set_warning_func( (_glapi_warning_func) _mesa_warning ); 4047117f1b4Smrg } 4057117f1b4Smrg else { 4067117f1b4Smrg _glapi_noop_enable_warnings(GL_FALSE); 4077117f1b4Smrg } 4087117f1b4Smrg 4097117f1b4Smrg#if defined(DEBUG) && defined(__DATE__) && defined(__TIME__) 4107117f1b4Smrg _mesa_debug(ctx, "Mesa %s DEBUG build %s %s\n", 4117117f1b4Smrg MESA_VERSION_STRING, __DATE__, __TIME__); 4127117f1b4Smrg#endif 4137117f1b4Smrg 4147117f1b4Smrg alreadyCalled = GL_TRUE; 4157117f1b4Smrg } 4167117f1b4Smrg _glthread_UNLOCK_MUTEX(OneTimeLock); 4177117f1b4Smrg} 4187117f1b4Smrg 4197117f1b4Smrg 4207117f1b4Smrg/** 4217117f1b4Smrg * Allocate and initialize a shared context state structure. 4227117f1b4Smrg * Initializes the display list, texture objects and vertex programs hash 4237117f1b4Smrg * tables, allocates the texture objects. If it runs out of memory, frees 4247117f1b4Smrg * everything already allocated before returning NULL. 4257117f1b4Smrg * 4267117f1b4Smrg * \return pointer to a gl_shared_state structure on success, or NULL on 4277117f1b4Smrg * failure. 4287117f1b4Smrg */ 4297117f1b4Smrgstatic GLboolean 4307117f1b4Smrgalloc_shared_state( GLcontext *ctx ) 4317117f1b4Smrg{ 432c1f859d4Smrg GLuint i; 4337117f1b4Smrg struct gl_shared_state *ss = CALLOC_STRUCT(gl_shared_state); 4347117f1b4Smrg if (!ss) 4357117f1b4Smrg return GL_FALSE; 4367117f1b4Smrg 4377117f1b4Smrg ctx->Shared = ss; 4387117f1b4Smrg 4397117f1b4Smrg _glthread_INIT_MUTEX(ss->Mutex); 4407117f1b4Smrg 4417117f1b4Smrg ss->DisplayList = _mesa_NewHashTable(); 4427117f1b4Smrg ss->TexObjects = _mesa_NewHashTable(); 4437117f1b4Smrg ss->Programs = _mesa_NewHashTable(); 4447117f1b4Smrg 4457117f1b4Smrg#if FEATURE_ARB_vertex_program 446c1f859d4Smrg ss->DefaultVertexProgram = (struct gl_vertex_program *) 447c1f859d4Smrg ctx->Driver.NewProgram(ctx, GL_VERTEX_PROGRAM_ARB, 0); 4487117f1b4Smrg if (!ss->DefaultVertexProgram) 4497117f1b4Smrg goto cleanup; 4507117f1b4Smrg#endif 4517117f1b4Smrg#if FEATURE_ARB_fragment_program 452c1f859d4Smrg ss->DefaultFragmentProgram = (struct gl_fragment_program *) 453c1f859d4Smrg ctx->Driver.NewProgram(ctx, GL_FRAGMENT_PROGRAM_ARB, 0); 4547117f1b4Smrg if (!ss->DefaultFragmentProgram) 4557117f1b4Smrg goto cleanup; 4567117f1b4Smrg#endif 4577117f1b4Smrg#if FEATURE_ATI_fragment_shader 4587117f1b4Smrg ss->ATIShaders = _mesa_NewHashTable(); 4597117f1b4Smrg ss->DefaultFragmentShader = _mesa_new_ati_fragment_shader(ctx, 0); 4607117f1b4Smrg if (!ss->DefaultFragmentShader) 4617117f1b4Smrg goto cleanup; 4627117f1b4Smrg#endif 4637117f1b4Smrg 4647117f1b4Smrg#if FEATURE_ARB_vertex_buffer_object || FEATURE_ARB_pixel_buffer_object 4657117f1b4Smrg ss->BufferObjects = _mesa_NewHashTable(); 4667117f1b4Smrg#endif 4677117f1b4Smrg 4687117f1b4Smrg ss->ArrayObjects = _mesa_NewHashTable(); 4697117f1b4Smrg 4707117f1b4Smrg#if FEATURE_ARB_shader_objects 4717117f1b4Smrg ss->ShaderObjects = _mesa_NewHashTable(); 4727117f1b4Smrg#endif 4737117f1b4Smrg 474c1f859d4Smrg /* Create default texture objects */ 475c1f859d4Smrg for (i = 0; i < NUM_TEXTURE_TARGETS; i++) { 476c1f859d4Smrg static const GLenum targets[NUM_TEXTURE_TARGETS] = { 477c1f859d4Smrg GL_TEXTURE_1D, 478c1f859d4Smrg GL_TEXTURE_2D, 479c1f859d4Smrg GL_TEXTURE_3D, 480c1f859d4Smrg GL_TEXTURE_CUBE_MAP, 481c1f859d4Smrg GL_TEXTURE_RECTANGLE_NV, 482c1f859d4Smrg GL_TEXTURE_1D_ARRAY_EXT, 483c1f859d4Smrg GL_TEXTURE_2D_ARRAY_EXT 484c1f859d4Smrg }; 485c1f859d4Smrg ss->DefaultTex[i] = ctx->Driver.NewTextureObject(ctx, 0, targets[i]); 486c1f859d4Smrg if (!ss->DefaultTex[i]) 487c1f859d4Smrg goto cleanup; 488c1f859d4Smrg } 4897117f1b4Smrg 4907117f1b4Smrg /* sanity check */ 491c1f859d4Smrg assert(ss->DefaultTex[TEXTURE_1D_INDEX]->RefCount == 1); 4927117f1b4Smrg 4937117f1b4Smrg _glthread_INIT_MUTEX(ss->TexMutex); 4947117f1b4Smrg ss->TextureStateStamp = 0; 4957117f1b4Smrg 4967117f1b4Smrg#if FEATURE_EXT_framebuffer_object 4977117f1b4Smrg ss->FrameBuffers = _mesa_NewHashTable(); 4987117f1b4Smrg if (!ss->FrameBuffers) 4997117f1b4Smrg goto cleanup; 5007117f1b4Smrg ss->RenderBuffers = _mesa_NewHashTable(); 5017117f1b4Smrg if (!ss->RenderBuffers) 5027117f1b4Smrg goto cleanup; 5037117f1b4Smrg#endif 5047117f1b4Smrg 5057117f1b4Smrg return GL_TRUE; 5067117f1b4Smrg 5077117f1b4Smrgcleanup: 5087117f1b4Smrg /* Ran out of memory at some point. Free everything and return NULL */ 5097117f1b4Smrg if (ss->DisplayList) 5107117f1b4Smrg _mesa_DeleteHashTable(ss->DisplayList); 5117117f1b4Smrg if (ss->TexObjects) 5127117f1b4Smrg _mesa_DeleteHashTable(ss->TexObjects); 5137117f1b4Smrg if (ss->Programs) 5147117f1b4Smrg _mesa_DeleteHashTable(ss->Programs); 5157117f1b4Smrg#if FEATURE_ARB_vertex_program 516c1f859d4Smrg _mesa_reference_vertprog(ctx, &ss->DefaultVertexProgram, NULL); 5177117f1b4Smrg#endif 5187117f1b4Smrg#if FEATURE_ARB_fragment_program 519c1f859d4Smrg _mesa_reference_fragprog(ctx, &ss->DefaultFragmentProgram, NULL); 5207117f1b4Smrg#endif 5217117f1b4Smrg#if FEATURE_ATI_fragment_shader 5227117f1b4Smrg if (ss->DefaultFragmentShader) 5237117f1b4Smrg _mesa_delete_ati_fragment_shader(ctx, ss->DefaultFragmentShader); 5247117f1b4Smrg#endif 5257117f1b4Smrg#if FEATURE_ARB_vertex_buffer_object || FEATURE_ARB_pixel_buffer_object 5267117f1b4Smrg if (ss->BufferObjects) 5277117f1b4Smrg _mesa_DeleteHashTable(ss->BufferObjects); 5287117f1b4Smrg#endif 5297117f1b4Smrg 5307117f1b4Smrg if (ss->ArrayObjects) 5317117f1b4Smrg _mesa_DeleteHashTable (ss->ArrayObjects); 5327117f1b4Smrg 5337117f1b4Smrg#if FEATURE_ARB_shader_objects 5347117f1b4Smrg if (ss->ShaderObjects) 5357117f1b4Smrg _mesa_DeleteHashTable (ss->ShaderObjects); 5367117f1b4Smrg#endif 5377117f1b4Smrg 5387117f1b4Smrg#if FEATURE_EXT_framebuffer_object 5397117f1b4Smrg if (ss->FrameBuffers) 5407117f1b4Smrg _mesa_DeleteHashTable(ss->FrameBuffers); 5417117f1b4Smrg if (ss->RenderBuffers) 5427117f1b4Smrg _mesa_DeleteHashTable(ss->RenderBuffers); 5437117f1b4Smrg#endif 5447117f1b4Smrg 545c1f859d4Smrg for (i = 0; i < NUM_TEXTURE_TARGETS; i++) { 546c1f859d4Smrg if (ss->DefaultTex[i]) 547c1f859d4Smrg ctx->Driver.DeleteTexture(ctx, ss->DefaultTex[i]); 548c1f859d4Smrg } 549c1f859d4Smrg 550c1f859d4Smrg _mesa_free(ss); 551c1f859d4Smrg 5527117f1b4Smrg return GL_FALSE; 5537117f1b4Smrg} 5547117f1b4Smrg 5557117f1b4Smrg 5567117f1b4Smrg/** 5577117f1b4Smrg * Callback for deleting a display list. Called by _mesa_HashDeleteAll(). 5587117f1b4Smrg */ 5597117f1b4Smrgstatic void 5607117f1b4Smrgdelete_displaylist_cb(GLuint id, void *data, void *userData) 5617117f1b4Smrg{ 562c1f859d4Smrg#if FEATURE_dlist 5637117f1b4Smrg struct mesa_display_list *list = (struct mesa_display_list *) data; 5647117f1b4Smrg GLcontext *ctx = (GLcontext *) userData; 5657117f1b4Smrg _mesa_delete_list(ctx, list); 566c1f859d4Smrg#endif 5677117f1b4Smrg} 5687117f1b4Smrg 5697117f1b4Smrg/** 5707117f1b4Smrg * Callback for deleting a texture object. Called by _mesa_HashDeleteAll(). 5717117f1b4Smrg */ 5727117f1b4Smrgstatic void 5737117f1b4Smrgdelete_texture_cb(GLuint id, void *data, void *userData) 5747117f1b4Smrg{ 5757117f1b4Smrg struct gl_texture_object *texObj = (struct gl_texture_object *) data; 5767117f1b4Smrg GLcontext *ctx = (GLcontext *) userData; 5777117f1b4Smrg ctx->Driver.DeleteTexture(ctx, texObj); 5787117f1b4Smrg} 5797117f1b4Smrg 5807117f1b4Smrg/** 5817117f1b4Smrg * Callback for deleting a program object. Called by _mesa_HashDeleteAll(). 5827117f1b4Smrg */ 5837117f1b4Smrgstatic void 5847117f1b4Smrgdelete_program_cb(GLuint id, void *data, void *userData) 5857117f1b4Smrg{ 5867117f1b4Smrg struct gl_program *prog = (struct gl_program *) data; 5877117f1b4Smrg GLcontext *ctx = (GLcontext *) userData; 588c1f859d4Smrg ASSERT(prog->RefCount == 1); /* should only be referenced by hash table */ 589c1f859d4Smrg prog->RefCount = 0; /* now going away */ 5907117f1b4Smrg ctx->Driver.DeleteProgram(ctx, prog); 5917117f1b4Smrg} 5927117f1b4Smrg 5937117f1b4Smrg/** 5947117f1b4Smrg * Callback for deleting an ATI fragment shader object. 5957117f1b4Smrg * Called by _mesa_HashDeleteAll(). 5967117f1b4Smrg */ 5977117f1b4Smrgstatic void 5987117f1b4Smrgdelete_fragshader_cb(GLuint id, void *data, void *userData) 5997117f1b4Smrg{ 6007117f1b4Smrg struct ati_fragment_shader *shader = (struct ati_fragment_shader *) data; 6017117f1b4Smrg GLcontext *ctx = (GLcontext *) userData; 6027117f1b4Smrg _mesa_delete_ati_fragment_shader(ctx, shader); 6037117f1b4Smrg} 6047117f1b4Smrg 6057117f1b4Smrg/** 6067117f1b4Smrg * Callback for deleting a buffer object. Called by _mesa_HashDeleteAll(). 6077117f1b4Smrg */ 6087117f1b4Smrgstatic void 6097117f1b4Smrgdelete_bufferobj_cb(GLuint id, void *data, void *userData) 6107117f1b4Smrg{ 6117117f1b4Smrg struct gl_buffer_object *bufObj = (struct gl_buffer_object *) data; 6127117f1b4Smrg GLcontext *ctx = (GLcontext *) userData; 6137117f1b4Smrg ctx->Driver.DeleteBuffer(ctx, bufObj); 6147117f1b4Smrg} 6157117f1b4Smrg 6167117f1b4Smrg/** 6177117f1b4Smrg * Callback for deleting an array object. Called by _mesa_HashDeleteAll(). 6187117f1b4Smrg */ 6197117f1b4Smrgstatic void 6207117f1b4Smrgdelete_arrayobj_cb(GLuint id, void *data, void *userData) 6217117f1b4Smrg{ 6227117f1b4Smrg struct gl_array_object *arrayObj = (struct gl_array_object *) data; 6237117f1b4Smrg GLcontext *ctx = (GLcontext *) userData; 6247117f1b4Smrg _mesa_delete_array_object(ctx, arrayObj); 6257117f1b4Smrg} 6267117f1b4Smrg 627c1f859d4Smrg/** 628c1f859d4Smrg * Callback for freeing shader program data. Call it before delete_shader_cb 629c1f859d4Smrg * to avoid memory access error. 630c1f859d4Smrg */ 631c1f859d4Smrgstatic void 632c1f859d4Smrgfree_shader_program_data_cb(GLuint id, void *data, void *userData) 633c1f859d4Smrg{ 634c1f859d4Smrg GLcontext *ctx = (GLcontext *) userData; 635c1f859d4Smrg struct gl_shader_program *shProg = (struct gl_shader_program *) data; 636c1f859d4Smrg 637c1f859d4Smrg if (shProg->Type == GL_SHADER_PROGRAM_MESA) { 638c1f859d4Smrg _mesa_free_shader_program_data(ctx, shProg); 639c1f859d4Smrg } 640c1f859d4Smrg} 641c1f859d4Smrg 6427117f1b4Smrg/** 6437117f1b4Smrg * Callback for deleting shader and shader programs objects. 6447117f1b4Smrg * Called by _mesa_HashDeleteAll(). 6457117f1b4Smrg */ 6467117f1b4Smrgstatic void 6477117f1b4Smrgdelete_shader_cb(GLuint id, void *data, void *userData) 6487117f1b4Smrg{ 6497117f1b4Smrg GLcontext *ctx = (GLcontext *) userData; 6507117f1b4Smrg struct gl_shader *sh = (struct gl_shader *) data; 6517117f1b4Smrg if (sh->Type == GL_FRAGMENT_SHADER || sh->Type == GL_VERTEX_SHADER) { 6527117f1b4Smrg _mesa_free_shader(ctx, sh); 6537117f1b4Smrg } 6547117f1b4Smrg else { 6557117f1b4Smrg struct gl_shader_program *shProg = (struct gl_shader_program *) data; 6567117f1b4Smrg ASSERT(shProg->Type == GL_SHADER_PROGRAM_MESA); 6577117f1b4Smrg _mesa_free_shader_program(ctx, shProg); 6587117f1b4Smrg } 6597117f1b4Smrg} 6607117f1b4Smrg 6617117f1b4Smrg/** 6627117f1b4Smrg * Callback for deleting a framebuffer object. Called by _mesa_HashDeleteAll() 6637117f1b4Smrg */ 6647117f1b4Smrgstatic void 6657117f1b4Smrgdelete_framebuffer_cb(GLuint id, void *data, void *userData) 6667117f1b4Smrg{ 6677117f1b4Smrg struct gl_framebuffer *fb = (struct gl_framebuffer *) data; 6687117f1b4Smrg /* The fact that the framebuffer is in the hashtable means its refcount 6697117f1b4Smrg * is one, but we're removing from the hashtable now. So clear refcount. 6707117f1b4Smrg */ 6717117f1b4Smrg /*assert(fb->RefCount == 1);*/ 6727117f1b4Smrg fb->RefCount = 0; 6737117f1b4Smrg 6747117f1b4Smrg /* NOTE: Delete should always be defined but there are two reports 6757117f1b4Smrg * of it being NULL (bugs 13507, 14293). Work-around for now. 6767117f1b4Smrg */ 6777117f1b4Smrg if (fb->Delete) 6787117f1b4Smrg fb->Delete(fb); 6797117f1b4Smrg} 6807117f1b4Smrg 6817117f1b4Smrg/** 6827117f1b4Smrg * Callback for deleting a renderbuffer object. Called by _mesa_HashDeleteAll() 6837117f1b4Smrg */ 6847117f1b4Smrgstatic void 6857117f1b4Smrgdelete_renderbuffer_cb(GLuint id, void *data, void *userData) 6867117f1b4Smrg{ 6877117f1b4Smrg struct gl_renderbuffer *rb = (struct gl_renderbuffer *) data; 6887117f1b4Smrg rb->RefCount = 0; /* see comment for FBOs above */ 689c1f859d4Smrg if (rb->Delete) 690c1f859d4Smrg rb->Delete(rb); 6917117f1b4Smrg} 6927117f1b4Smrg 6937117f1b4Smrg 6947117f1b4Smrg 6957117f1b4Smrg/** 6967117f1b4Smrg * Deallocate a shared state object and all children structures. 6977117f1b4Smrg * 6987117f1b4Smrg * \param ctx GL context. 6997117f1b4Smrg * \param ss shared state pointer. 7007117f1b4Smrg * 7017117f1b4Smrg * Frees the display lists, the texture objects (calling the driver texture 7027117f1b4Smrg * deletion callback to free its private data) and the vertex programs, as well 7037117f1b4Smrg * as their hash tables. 7047117f1b4Smrg * 7057117f1b4Smrg * \sa alloc_shared_state(). 7067117f1b4Smrg */ 7077117f1b4Smrgstatic void 7087117f1b4Smrgfree_shared_state( GLcontext *ctx, struct gl_shared_state *ss ) 7097117f1b4Smrg{ 710c1f859d4Smrg GLuint i; 711c1f859d4Smrg 7127117f1b4Smrg /* 7137117f1b4Smrg * Free display lists 7147117f1b4Smrg */ 7157117f1b4Smrg _mesa_HashDeleteAll(ss->DisplayList, delete_displaylist_cb, ctx); 7167117f1b4Smrg _mesa_DeleteHashTable(ss->DisplayList); 7177117f1b4Smrg 718c1f859d4Smrg#if FEATURE_ARB_shader_objects 719c1f859d4Smrg _mesa_HashWalk(ss->ShaderObjects, free_shader_program_data_cb, ctx); 720c1f859d4Smrg _mesa_HashDeleteAll(ss->ShaderObjects, delete_shader_cb, ctx); 721c1f859d4Smrg _mesa_DeleteHashTable(ss->ShaderObjects); 722c1f859d4Smrg#endif 723c1f859d4Smrg 7247117f1b4Smrg _mesa_HashDeleteAll(ss->Programs, delete_program_cb, ctx); 7257117f1b4Smrg _mesa_DeleteHashTable(ss->Programs); 726c1f859d4Smrg 7277117f1b4Smrg#if FEATURE_ARB_vertex_program 728c1f859d4Smrg _mesa_reference_vertprog(ctx, &ss->DefaultVertexProgram, NULL); 7297117f1b4Smrg#endif 7307117f1b4Smrg#if FEATURE_ARB_fragment_program 731c1f859d4Smrg _mesa_reference_fragprog(ctx, &ss->DefaultFragmentProgram, NULL); 7327117f1b4Smrg#endif 7337117f1b4Smrg 7347117f1b4Smrg#if FEATURE_ATI_fragment_shader 7357117f1b4Smrg _mesa_HashDeleteAll(ss->ATIShaders, delete_fragshader_cb, ctx); 7367117f1b4Smrg _mesa_DeleteHashTable(ss->ATIShaders); 7377117f1b4Smrg _mesa_delete_ati_fragment_shader(ctx, ss->DefaultFragmentShader); 7387117f1b4Smrg#endif 7397117f1b4Smrg 7407117f1b4Smrg#if FEATURE_ARB_vertex_buffer_object || FEATURE_ARB_pixel_buffer_object 7417117f1b4Smrg _mesa_HashDeleteAll(ss->BufferObjects, delete_bufferobj_cb, ctx); 7427117f1b4Smrg _mesa_DeleteHashTable(ss->BufferObjects); 7437117f1b4Smrg#endif 7447117f1b4Smrg 7457117f1b4Smrg _mesa_HashDeleteAll(ss->ArrayObjects, delete_arrayobj_cb, ctx); 7467117f1b4Smrg _mesa_DeleteHashTable(ss->ArrayObjects); 7477117f1b4Smrg 7487117f1b4Smrg#if FEATURE_EXT_framebuffer_object 7497117f1b4Smrg _mesa_HashDeleteAll(ss->FrameBuffers, delete_framebuffer_cb, ctx); 7507117f1b4Smrg _mesa_DeleteHashTable(ss->FrameBuffers); 7517117f1b4Smrg _mesa_HashDeleteAll(ss->RenderBuffers, delete_renderbuffer_cb, ctx); 7527117f1b4Smrg _mesa_DeleteHashTable(ss->RenderBuffers); 7537117f1b4Smrg#endif 7547117f1b4Smrg 7557117f1b4Smrg /* 7567117f1b4Smrg * Free texture objects (after FBOs since some textures might have 7577117f1b4Smrg * been bound to FBOs). 7587117f1b4Smrg */ 7597117f1b4Smrg ASSERT(ctx->Driver.DeleteTexture); 7607117f1b4Smrg /* the default textures */ 761c1f859d4Smrg for (i = 0; i < NUM_TEXTURE_TARGETS; i++) { 762c1f859d4Smrg ctx->Driver.DeleteTexture(ctx, ss->DefaultTex[i]); 763c1f859d4Smrg } 7647117f1b4Smrg /* all other textures */ 7657117f1b4Smrg _mesa_HashDeleteAll(ss->TexObjects, delete_texture_cb, ctx); 7667117f1b4Smrg _mesa_DeleteHashTable(ss->TexObjects); 7677117f1b4Smrg 7687117f1b4Smrg _glthread_DESTROY_MUTEX(ss->Mutex); 7697117f1b4Smrg 7707117f1b4Smrg _mesa_free(ss); 7717117f1b4Smrg} 7727117f1b4Smrg 7737117f1b4Smrg 7747117f1b4Smrg/** 7757117f1b4Smrg * Initialize fields of gl_current_attrib (aka ctx->Current.*) 7767117f1b4Smrg */ 7777117f1b4Smrgstatic void 7787117f1b4Smrg_mesa_init_current(GLcontext *ctx) 7797117f1b4Smrg{ 7807117f1b4Smrg GLuint i; 7817117f1b4Smrg 7827117f1b4Smrg /* Init all to (0,0,0,1) */ 7837117f1b4Smrg for (i = 0; i < VERT_ATTRIB_MAX; i++) { 7847117f1b4Smrg ASSIGN_4V( ctx->Current.Attrib[i], 0.0, 0.0, 0.0, 1.0 ); 7857117f1b4Smrg } 7867117f1b4Smrg 7877117f1b4Smrg /* redo special cases: */ 7887117f1b4Smrg ASSIGN_4V( ctx->Current.Attrib[VERT_ATTRIB_WEIGHT], 1.0, 0.0, 0.0, 0.0 ); 7897117f1b4Smrg ASSIGN_4V( ctx->Current.Attrib[VERT_ATTRIB_NORMAL], 0.0, 0.0, 1.0, 1.0 ); 7907117f1b4Smrg ASSIGN_4V( ctx->Current.Attrib[VERT_ATTRIB_COLOR0], 1.0, 1.0, 1.0, 1.0 ); 7917117f1b4Smrg ASSIGN_4V( ctx->Current.Attrib[VERT_ATTRIB_COLOR1], 0.0, 0.0, 0.0, 1.0 ); 7927117f1b4Smrg ASSIGN_4V( ctx->Current.Attrib[VERT_ATTRIB_COLOR_INDEX], 1.0, 0.0, 0.0, 1.0 ); 7937117f1b4Smrg ASSIGN_4V( ctx->Current.Attrib[VERT_ATTRIB_EDGEFLAG], 1.0, 0.0, 0.0, 1.0 ); 7947117f1b4Smrg} 7957117f1b4Smrg 7967117f1b4Smrg 7977117f1b4Smrg/** 7987117f1b4Smrg * Init vertex/fragment program native limits from logical limits. 7997117f1b4Smrg */ 8007117f1b4Smrgstatic void 8017117f1b4Smrginit_natives(struct gl_program_constants *prog) 8027117f1b4Smrg{ 8037117f1b4Smrg prog->MaxNativeInstructions = prog->MaxInstructions; 8047117f1b4Smrg prog->MaxNativeAluInstructions = prog->MaxAluInstructions; 8057117f1b4Smrg prog->MaxNativeTexInstructions = prog->MaxTexInstructions; 8067117f1b4Smrg prog->MaxNativeTexIndirections = prog->MaxTexIndirections; 8077117f1b4Smrg prog->MaxNativeAttribs = prog->MaxAttribs; 8087117f1b4Smrg prog->MaxNativeTemps = prog->MaxTemps; 8097117f1b4Smrg prog->MaxNativeAddressRegs = prog->MaxAddressRegs; 8107117f1b4Smrg prog->MaxNativeParameters = prog->MaxParameters; 8117117f1b4Smrg} 8127117f1b4Smrg 8137117f1b4Smrg 8147117f1b4Smrg/** 8157117f1b4Smrg * Initialize fields of gl_constants (aka ctx->Const.*). 8167117f1b4Smrg * Use defaults from config.h. The device drivers will often override 8177117f1b4Smrg * some of these values (such as number of texture units). 8187117f1b4Smrg */ 8197117f1b4Smrgstatic void 8207117f1b4Smrg_mesa_init_constants(GLcontext *ctx) 8217117f1b4Smrg{ 8227117f1b4Smrg assert(ctx); 8237117f1b4Smrg 8247117f1b4Smrg assert(MAX_TEXTURE_LEVELS >= MAX_3D_TEXTURE_LEVELS); 8257117f1b4Smrg assert(MAX_TEXTURE_LEVELS >= MAX_CUBE_TEXTURE_LEVELS); 8267117f1b4Smrg 8277117f1b4Smrg /* Constants, may be overriden (usually only reduced) by device drivers */ 8287117f1b4Smrg ctx->Const.MaxTextureLevels = MAX_TEXTURE_LEVELS; 8297117f1b4Smrg ctx->Const.Max3DTextureLevels = MAX_3D_TEXTURE_LEVELS; 8307117f1b4Smrg ctx->Const.MaxCubeTextureLevels = MAX_CUBE_TEXTURE_LEVELS; 8317117f1b4Smrg ctx->Const.MaxTextureRectSize = MAX_TEXTURE_RECT_SIZE; 832c1f859d4Smrg ctx->Const.MaxArrayTextureLayers = MAX_ARRAY_TEXTURE_LAYERS; 8337117f1b4Smrg ctx->Const.MaxTextureCoordUnits = MAX_TEXTURE_COORD_UNITS; 8347117f1b4Smrg ctx->Const.MaxTextureImageUnits = MAX_TEXTURE_IMAGE_UNITS; 8357117f1b4Smrg ctx->Const.MaxTextureUnits = MIN2(ctx->Const.MaxTextureCoordUnits, 8367117f1b4Smrg ctx->Const.MaxTextureImageUnits); 8377117f1b4Smrg ctx->Const.MaxTextureMaxAnisotropy = MAX_TEXTURE_MAX_ANISOTROPY; 8387117f1b4Smrg ctx->Const.MaxTextureLodBias = MAX_TEXTURE_LOD_BIAS; 8397117f1b4Smrg ctx->Const.MaxArrayLockSize = MAX_ARRAY_LOCK_SIZE; 8407117f1b4Smrg ctx->Const.SubPixelBits = SUB_PIXEL_BITS; 8417117f1b4Smrg ctx->Const.MinPointSize = MIN_POINT_SIZE; 8427117f1b4Smrg ctx->Const.MaxPointSize = MAX_POINT_SIZE; 8437117f1b4Smrg ctx->Const.MinPointSizeAA = MIN_POINT_SIZE; 8447117f1b4Smrg ctx->Const.MaxPointSizeAA = MAX_POINT_SIZE; 8457117f1b4Smrg ctx->Const.PointSizeGranularity = (GLfloat) POINT_SIZE_GRANULARITY; 8467117f1b4Smrg ctx->Const.MinLineWidth = MIN_LINE_WIDTH; 8477117f1b4Smrg ctx->Const.MaxLineWidth = MAX_LINE_WIDTH; 8487117f1b4Smrg ctx->Const.MinLineWidthAA = MIN_LINE_WIDTH; 8497117f1b4Smrg ctx->Const.MaxLineWidthAA = MAX_LINE_WIDTH; 8507117f1b4Smrg ctx->Const.LineWidthGranularity = (GLfloat) LINE_WIDTH_GRANULARITY; 8517117f1b4Smrg ctx->Const.MaxColorTableSize = MAX_COLOR_TABLE_SIZE; 8527117f1b4Smrg ctx->Const.MaxConvolutionWidth = MAX_CONVOLUTION_WIDTH; 8537117f1b4Smrg ctx->Const.MaxConvolutionHeight = MAX_CONVOLUTION_HEIGHT; 8547117f1b4Smrg ctx->Const.MaxClipPlanes = MAX_CLIP_PLANES; 8557117f1b4Smrg ctx->Const.MaxLights = MAX_LIGHTS; 8567117f1b4Smrg ctx->Const.MaxShininess = 128.0; 8577117f1b4Smrg ctx->Const.MaxSpotExponent = 128.0; 8587117f1b4Smrg ctx->Const.MaxViewportWidth = MAX_WIDTH; 8597117f1b4Smrg ctx->Const.MaxViewportHeight = MAX_HEIGHT; 8607117f1b4Smrg#if FEATURE_ARB_vertex_program 8617117f1b4Smrg ctx->Const.VertexProgram.MaxInstructions = MAX_NV_VERTEX_PROGRAM_INSTRUCTIONS; 8627117f1b4Smrg ctx->Const.VertexProgram.MaxAluInstructions = 0; 8637117f1b4Smrg ctx->Const.VertexProgram.MaxTexInstructions = 0; 8647117f1b4Smrg ctx->Const.VertexProgram.MaxTexIndirections = 0; 8657117f1b4Smrg ctx->Const.VertexProgram.MaxAttribs = MAX_NV_VERTEX_PROGRAM_INPUTS; 8667117f1b4Smrg ctx->Const.VertexProgram.MaxTemps = MAX_PROGRAM_TEMPS; 8677117f1b4Smrg ctx->Const.VertexProgram.MaxParameters = MAX_NV_VERTEX_PROGRAM_PARAMS; 8687117f1b4Smrg ctx->Const.VertexProgram.MaxLocalParams = MAX_PROGRAM_LOCAL_PARAMS; 8697117f1b4Smrg ctx->Const.VertexProgram.MaxEnvParams = MAX_PROGRAM_ENV_PARAMS; 8707117f1b4Smrg ctx->Const.VertexProgram.MaxAddressRegs = MAX_VERTEX_PROGRAM_ADDRESS_REGS; 8717117f1b4Smrg ctx->Const.VertexProgram.MaxUniformComponents = 4 * MAX_UNIFORMS; 8727117f1b4Smrg init_natives(&ctx->Const.VertexProgram); 8737117f1b4Smrg#endif 8747117f1b4Smrg 8757117f1b4Smrg#if FEATURE_ARB_fragment_program 8767117f1b4Smrg ctx->Const.FragmentProgram.MaxInstructions = MAX_NV_FRAGMENT_PROGRAM_INSTRUCTIONS; 8777117f1b4Smrg ctx->Const.FragmentProgram.MaxAluInstructions = MAX_FRAGMENT_PROGRAM_ALU_INSTRUCTIONS; 8787117f1b4Smrg ctx->Const.FragmentProgram.MaxTexInstructions = MAX_FRAGMENT_PROGRAM_TEX_INSTRUCTIONS; 8797117f1b4Smrg ctx->Const.FragmentProgram.MaxTexIndirections = MAX_FRAGMENT_PROGRAM_TEX_INDIRECTIONS; 8807117f1b4Smrg ctx->Const.FragmentProgram.MaxAttribs = MAX_NV_FRAGMENT_PROGRAM_INPUTS; 8817117f1b4Smrg ctx->Const.FragmentProgram.MaxTemps = MAX_PROGRAM_TEMPS; 8827117f1b4Smrg ctx->Const.FragmentProgram.MaxParameters = MAX_NV_FRAGMENT_PROGRAM_PARAMS; 8837117f1b4Smrg ctx->Const.FragmentProgram.MaxLocalParams = MAX_PROGRAM_LOCAL_PARAMS; 8847117f1b4Smrg ctx->Const.FragmentProgram.MaxEnvParams = MAX_PROGRAM_ENV_PARAMS; 8857117f1b4Smrg ctx->Const.FragmentProgram.MaxAddressRegs = MAX_FRAGMENT_PROGRAM_ADDRESS_REGS; 8867117f1b4Smrg ctx->Const.FragmentProgram.MaxUniformComponents = 4 * MAX_UNIFORMS; 8877117f1b4Smrg init_natives(&ctx->Const.FragmentProgram); 8887117f1b4Smrg#endif 8897117f1b4Smrg ctx->Const.MaxProgramMatrices = MAX_PROGRAM_MATRICES; 8907117f1b4Smrg ctx->Const.MaxProgramMatrixStackDepth = MAX_PROGRAM_MATRIX_STACK_DEPTH; 8917117f1b4Smrg 8927117f1b4Smrg /* CheckArrayBounds is overriden by drivers/x11 for X server */ 8937117f1b4Smrg ctx->Const.CheckArrayBounds = GL_FALSE; 8947117f1b4Smrg 8957117f1b4Smrg /* GL_ARB_draw_buffers */ 8967117f1b4Smrg ctx->Const.MaxDrawBuffers = MAX_DRAW_BUFFERS; 8977117f1b4Smrg 8987117f1b4Smrg /* GL_OES_read_format */ 8997117f1b4Smrg ctx->Const.ColorReadFormat = GL_RGBA; 9007117f1b4Smrg ctx->Const.ColorReadType = GL_UNSIGNED_BYTE; 9017117f1b4Smrg 9027117f1b4Smrg#if FEATURE_EXT_framebuffer_object 9037117f1b4Smrg ctx->Const.MaxColorAttachments = MAX_COLOR_ATTACHMENTS; 9047117f1b4Smrg ctx->Const.MaxRenderbufferSize = MAX_WIDTH; 9057117f1b4Smrg#endif 9067117f1b4Smrg 9077117f1b4Smrg#if FEATURE_ARB_vertex_shader 9087117f1b4Smrg ctx->Const.MaxVertexTextureImageUnits = MAX_VERTEX_TEXTURE_IMAGE_UNITS; 9097117f1b4Smrg ctx->Const.MaxVarying = MAX_VARYING; 9107117f1b4Smrg#endif 9117117f1b4Smrg 9127117f1b4Smrg /* sanity checks */ 9137117f1b4Smrg ASSERT(ctx->Const.MaxTextureUnits == MIN2(ctx->Const.MaxTextureImageUnits, 9147117f1b4Smrg ctx->Const.MaxTextureCoordUnits)); 9157117f1b4Smrg ASSERT(ctx->Const.FragmentProgram.MaxLocalParams <= MAX_PROGRAM_LOCAL_PARAMS); 9167117f1b4Smrg ASSERT(ctx->Const.VertexProgram.MaxLocalParams <= MAX_PROGRAM_LOCAL_PARAMS); 9177117f1b4Smrg 9187117f1b4Smrg ASSERT(MAX_NV_FRAGMENT_PROGRAM_TEMPS <= MAX_PROGRAM_TEMPS); 9197117f1b4Smrg ASSERT(MAX_NV_VERTEX_PROGRAM_TEMPS <= MAX_PROGRAM_TEMPS); 9207117f1b4Smrg ASSERT(MAX_NV_VERTEX_PROGRAM_INPUTS <= VERT_ATTRIB_MAX); 9217117f1b4Smrg ASSERT(MAX_NV_VERTEX_PROGRAM_OUTPUTS <= VERT_RESULT_MAX); 9227117f1b4Smrg} 9237117f1b4Smrg 9247117f1b4Smrg 9257117f1b4Smrg/** 9267117f1b4Smrg * Do some sanity checks on the limits/constants for the given context. 9277117f1b4Smrg * Only called the first time a context is bound. 9287117f1b4Smrg */ 9297117f1b4Smrgstatic void 9307117f1b4Smrgcheck_context_limits(GLcontext *ctx) 9317117f1b4Smrg{ 9327117f1b4Smrg /* Many context limits/constants are limited by the size of 9337117f1b4Smrg * internal arrays. 9347117f1b4Smrg */ 9357117f1b4Smrg assert(ctx->Const.MaxTextureImageUnits <= MAX_TEXTURE_IMAGE_UNITS); 9367117f1b4Smrg assert(ctx->Const.MaxTextureCoordUnits <= MAX_TEXTURE_COORD_UNITS); 9377117f1b4Smrg assert(ctx->Const.MaxTextureUnits <= MAX_TEXTURE_IMAGE_UNITS); 9387117f1b4Smrg assert(ctx->Const.MaxTextureUnits <= MAX_TEXTURE_COORD_UNITS); 9397117f1b4Smrg 940c1f859d4Smrg /* number of coord units cannot be greater than number of image units */ 941c1f859d4Smrg assert(ctx->Const.MaxTextureCoordUnits <= ctx->Const.MaxTextureImageUnits); 942c1f859d4Smrg 9437117f1b4Smrg assert(ctx->Const.MaxViewportWidth <= MAX_WIDTH); 9447117f1b4Smrg assert(ctx->Const.MaxViewportHeight <= MAX_WIDTH); 9457117f1b4Smrg 9467117f1b4Smrg /* make sure largest texture image is <= MAX_WIDTH in size */ 9477117f1b4Smrg assert((1 << (ctx->Const.MaxTextureLevels -1 )) <= MAX_WIDTH); 9487117f1b4Smrg assert((1 << (ctx->Const.MaxCubeTextureLevels -1 )) <= MAX_WIDTH); 9497117f1b4Smrg assert((1 << (ctx->Const.Max3DTextureLevels -1 )) <= MAX_WIDTH); 9507117f1b4Smrg 9517117f1b4Smrg assert(ctx->Const.MaxDrawBuffers <= MAX_DRAW_BUFFERS); 9527117f1b4Smrg 9537117f1b4Smrg /* XXX probably add more tests */ 9547117f1b4Smrg} 9557117f1b4Smrg 9567117f1b4Smrg 9577117f1b4Smrg/** 9587117f1b4Smrg * Initialize the attribute groups in a GL context. 9597117f1b4Smrg * 9607117f1b4Smrg * \param ctx GL context. 9617117f1b4Smrg * 9627117f1b4Smrg * Initializes all the attributes, calling the respective <tt>init*</tt> 9637117f1b4Smrg * functions for the more complex data structures. 9647117f1b4Smrg */ 9657117f1b4Smrgstatic GLboolean 9667117f1b4Smrginit_attrib_groups(GLcontext *ctx) 9677117f1b4Smrg{ 9687117f1b4Smrg assert(ctx); 9697117f1b4Smrg 9707117f1b4Smrg /* Constants */ 9717117f1b4Smrg _mesa_init_constants( ctx ); 9727117f1b4Smrg 9737117f1b4Smrg /* Extensions */ 9747117f1b4Smrg _mesa_init_extensions( ctx ); 9757117f1b4Smrg 9767117f1b4Smrg /* Attribute Groups */ 977c1f859d4Smrg#if FEATURE_accum 9787117f1b4Smrg _mesa_init_accum( ctx ); 979c1f859d4Smrg#endif 980c1f859d4Smrg#if FEATURE_attrib_stack 9817117f1b4Smrg _mesa_init_attrib( ctx ); 982c1f859d4Smrg#endif 9837117f1b4Smrg _mesa_init_buffer_objects( ctx ); 9847117f1b4Smrg _mesa_init_color( ctx ); 985c1f859d4Smrg#if FEATURE_colortable 9867117f1b4Smrg _mesa_init_colortables( ctx ); 987c1f859d4Smrg#endif 9887117f1b4Smrg _mesa_init_current( ctx ); 9897117f1b4Smrg _mesa_init_depth( ctx ); 9907117f1b4Smrg _mesa_init_debug( ctx ); 991c1f859d4Smrg#if FEATURE_dlist 9927117f1b4Smrg _mesa_init_display_list( ctx ); 993c1f859d4Smrg#endif 994c1f859d4Smrg#if FEATURE_evaluators 9957117f1b4Smrg _mesa_init_eval( ctx ); 996c1f859d4Smrg#endif 997c1f859d4Smrg _mesa_init_fbobjects( ctx ); 998c1f859d4Smrg#if FEATURE_feedback 9997117f1b4Smrg _mesa_init_feedback( ctx ); 1000c1f859d4Smrg#else 1001c1f859d4Smrg ctx->RenderMode = GL_RENDER; 1002c1f859d4Smrg#endif 10037117f1b4Smrg _mesa_init_fog( ctx ); 1004c1f859d4Smrg#if FEATURE_histogram 10057117f1b4Smrg _mesa_init_histogram( ctx ); 1006c1f859d4Smrg#endif 10077117f1b4Smrg _mesa_init_hint( ctx ); 10087117f1b4Smrg _mesa_init_line( ctx ); 10097117f1b4Smrg _mesa_init_lighting( ctx ); 10107117f1b4Smrg _mesa_init_matrix( ctx ); 10117117f1b4Smrg _mesa_init_multisample( ctx ); 10127117f1b4Smrg _mesa_init_pixel( ctx ); 1013c1f859d4Smrg _mesa_init_pixelstore( ctx ); 10147117f1b4Smrg _mesa_init_point( ctx ); 10157117f1b4Smrg _mesa_init_polygon( ctx ); 10167117f1b4Smrg _mesa_init_program( ctx ); 1017c1f859d4Smrg#if FEATURE_ARB_occlusion_query 10187117f1b4Smrg _mesa_init_query( ctx ); 1019c1f859d4Smrg#endif 1020c1f859d4Smrg#if FEATURE_drawpix 10217117f1b4Smrg _mesa_init_rastpos( ctx ); 1022c1f859d4Smrg#endif 10237117f1b4Smrg _mesa_init_scissor( ctx ); 10247117f1b4Smrg _mesa_init_shader_state( ctx ); 10257117f1b4Smrg _mesa_init_stencil( ctx ); 10267117f1b4Smrg _mesa_init_transform( ctx ); 10277117f1b4Smrg _mesa_init_varray( ctx ); 10287117f1b4Smrg _mesa_init_viewport( ctx ); 10297117f1b4Smrg 10307117f1b4Smrg if (!_mesa_init_texture( ctx )) 10317117f1b4Smrg return GL_FALSE; 10327117f1b4Smrg 1033c1f859d4Smrg#if FEATURE_texture_s3tc 10347117f1b4Smrg _mesa_init_texture_s3tc( ctx ); 1035c1f859d4Smrg#endif 1036c1f859d4Smrg#if FEATURE_texture_fxt1 10377117f1b4Smrg _mesa_init_texture_fxt1( ctx ); 1038c1f859d4Smrg#endif 10397117f1b4Smrg 10407117f1b4Smrg /* Miscellaneous */ 10417117f1b4Smrg ctx->NewState = _NEW_ALL; 10427117f1b4Smrg ctx->ErrorValue = (GLenum) GL_NO_ERROR; 10437117f1b4Smrg 10447117f1b4Smrg return GL_TRUE; 10457117f1b4Smrg} 10467117f1b4Smrg 10477117f1b4Smrg 1048c1f859d4Smrg/** 1049c1f859d4Smrg * Update default objects in a GL context with respect to shared state. 1050c1f859d4Smrg * 1051c1f859d4Smrg * \param ctx GL context. 1052c1f859d4Smrg * 1053c1f859d4Smrg * Removes references to old default objects, (texture objects, program 1054c1f859d4Smrg * objects, etc.) and changes to reference those from the current shared 1055c1f859d4Smrg * state. 1056c1f859d4Smrg */ 1057c1f859d4Smrgstatic GLboolean 1058c1f859d4Smrgupdate_default_objects(GLcontext *ctx) 1059c1f859d4Smrg{ 1060c1f859d4Smrg assert(ctx); 1061c1f859d4Smrg 1062c1f859d4Smrg _mesa_update_default_objects_program(ctx); 1063c1f859d4Smrg _mesa_update_default_objects_texture(ctx); 1064c1f859d4Smrg _mesa_update_default_objects_buffer_objects(ctx); 1065c1f859d4Smrg 1066c1f859d4Smrg return GL_TRUE; 1067c1f859d4Smrg} 1068c1f859d4Smrg 1069c1f859d4Smrg 10707117f1b4Smrg/** 10717117f1b4Smrg * This is the default function we plug into all dispatch table slots 10727117f1b4Smrg * This helps prevents a segfault when someone calls a GL function without 10737117f1b4Smrg * first checking if the extension's supported. 10747117f1b4Smrg */ 10757117f1b4Smrgstatic int 10767117f1b4Smrggeneric_nop(void) 10777117f1b4Smrg{ 1078c1f859d4Smrg _mesa_warning(NULL, "User called no-op dispatch function (an unsupported extension function?)"); 10797117f1b4Smrg return 0; 10807117f1b4Smrg} 10817117f1b4Smrg 10827117f1b4Smrg 10837117f1b4Smrg/** 10847117f1b4Smrg * Allocate and initialize a new dispatch table. 10857117f1b4Smrg */ 10867117f1b4Smrgstatic struct _glapi_table * 10877117f1b4Smrgalloc_dispatch_table(void) 10887117f1b4Smrg{ 10897117f1b4Smrg /* Find the larger of Mesa's dispatch table and libGL's dispatch table. 10907117f1b4Smrg * In practice, this'll be the same for stand-alone Mesa. But for DRI 10917117f1b4Smrg * Mesa we do this to accomodate different versions of libGL and various 10927117f1b4Smrg * DRI drivers. 10937117f1b4Smrg */ 10947117f1b4Smrg GLint numEntries = MAX2(_glapi_get_dispatch_table_size(), 10957117f1b4Smrg sizeof(struct _glapi_table) / sizeof(_glapi_proc)); 10967117f1b4Smrg struct _glapi_table *table = 10977117f1b4Smrg (struct _glapi_table *) _mesa_malloc(numEntries * sizeof(_glapi_proc)); 10987117f1b4Smrg if (table) { 10997117f1b4Smrg _glapi_proc *entry = (_glapi_proc *) table; 11007117f1b4Smrg GLint i; 11017117f1b4Smrg for (i = 0; i < numEntries; i++) { 11027117f1b4Smrg entry[i] = (_glapi_proc) generic_nop; 11037117f1b4Smrg } 11047117f1b4Smrg } 11057117f1b4Smrg return table; 11067117f1b4Smrg} 11077117f1b4Smrg 11087117f1b4Smrg 11097117f1b4Smrg/** 11107117f1b4Smrg * Initialize a GLcontext struct (rendering context). 11117117f1b4Smrg * 11127117f1b4Smrg * This includes allocating all the other structs and arrays which hang off of 11137117f1b4Smrg * the context by pointers. 11147117f1b4Smrg * Note that the driver needs to pass in its dd_function_table here since 11157117f1b4Smrg * we need to at least call driverFunctions->NewTextureObject to create the 11167117f1b4Smrg * default texture objects. 11177117f1b4Smrg * 11187117f1b4Smrg * Called by _mesa_create_context(). 11197117f1b4Smrg * 11207117f1b4Smrg * Performs the imports and exports callback tables initialization, and 11217117f1b4Smrg * miscellaneous one-time initializations. If no shared context is supplied one 11227117f1b4Smrg * is allocated, and increase its reference count. Setups the GL API dispatch 11237117f1b4Smrg * tables. Initialize the TNL module. Sets the maximum Z buffer depth. 11247117f1b4Smrg * Finally queries the \c MESA_DEBUG and \c MESA_VERBOSE environment variables 11257117f1b4Smrg * for debug flags. 11267117f1b4Smrg * 11277117f1b4Smrg * \param ctx the context to initialize 11287117f1b4Smrg * \param visual describes the visual attributes for this context 11297117f1b4Smrg * \param share_list points to context to share textures, display lists, 11307117f1b4Smrg * etc with, or NULL 11317117f1b4Smrg * \param driverFunctions table of device driver functions for this context 11327117f1b4Smrg * to use 11337117f1b4Smrg * \param driverContext pointer to driver-specific context data 11347117f1b4Smrg */ 11357117f1b4SmrgGLboolean 11367117f1b4Smrg_mesa_initialize_context(GLcontext *ctx, 11377117f1b4Smrg const GLvisual *visual, 11387117f1b4Smrg GLcontext *share_list, 11397117f1b4Smrg const struct dd_function_table *driverFunctions, 11407117f1b4Smrg void *driverContext) 11417117f1b4Smrg{ 11427117f1b4Smrg ASSERT(driverContext); 11437117f1b4Smrg assert(driverFunctions->NewTextureObject); 11447117f1b4Smrg assert(driverFunctions->FreeTexImageData); 11457117f1b4Smrg 11467117f1b4Smrg /* misc one-time initializations */ 11477117f1b4Smrg one_time_init(ctx); 11487117f1b4Smrg 11497117f1b4Smrg ctx->Visual = *visual; 11507117f1b4Smrg ctx->DrawBuffer = NULL; 11517117f1b4Smrg ctx->ReadBuffer = NULL; 11527117f1b4Smrg ctx->WinSysDrawBuffer = NULL; 11537117f1b4Smrg ctx->WinSysReadBuffer = NULL; 11547117f1b4Smrg 11557117f1b4Smrg /* Plug in driver functions and context pointer here. 11567117f1b4Smrg * This is important because when we call alloc_shared_state() below 11577117f1b4Smrg * we'll call ctx->Driver.NewTextureObject() to create the default 11587117f1b4Smrg * textures. 11597117f1b4Smrg */ 11607117f1b4Smrg ctx->Driver = *driverFunctions; 11617117f1b4Smrg ctx->DriverCtx = driverContext; 11627117f1b4Smrg 11637117f1b4Smrg if (share_list) { 11647117f1b4Smrg /* share state with another context */ 11657117f1b4Smrg ctx->Shared = share_list->Shared; 11667117f1b4Smrg } 11677117f1b4Smrg else { 11687117f1b4Smrg /* allocate new, unshared state */ 11697117f1b4Smrg if (!alloc_shared_state( ctx )) { 11707117f1b4Smrg return GL_FALSE; 11717117f1b4Smrg } 11727117f1b4Smrg } 11737117f1b4Smrg _glthread_LOCK_MUTEX(ctx->Shared->Mutex); 11747117f1b4Smrg ctx->Shared->RefCount++; 11757117f1b4Smrg _glthread_UNLOCK_MUTEX(ctx->Shared->Mutex); 11767117f1b4Smrg 11777117f1b4Smrg if (!init_attrib_groups( ctx )) { 11787117f1b4Smrg free_shared_state(ctx, ctx->Shared); 11797117f1b4Smrg return GL_FALSE; 11807117f1b4Smrg } 11817117f1b4Smrg 11827117f1b4Smrg /* setup the API dispatch tables */ 11837117f1b4Smrg ctx->Exec = alloc_dispatch_table(); 11847117f1b4Smrg ctx->Save = alloc_dispatch_table(); 11857117f1b4Smrg if (!ctx->Exec || !ctx->Save) { 11867117f1b4Smrg free_shared_state(ctx, ctx->Shared); 11877117f1b4Smrg if (ctx->Exec) 11887117f1b4Smrg _mesa_free(ctx->Exec); 11897117f1b4Smrg } 1190c1f859d4Smrg#if FEATURE_dispatch 11917117f1b4Smrg _mesa_init_exec_table(ctx->Exec); 1192c1f859d4Smrg#endif 11937117f1b4Smrg ctx->CurrentDispatch = ctx->Exec; 1194c1f859d4Smrg#if FEATURE_dlist 11957117f1b4Smrg _mesa_init_dlist_table(ctx->Save); 11967117f1b4Smrg _mesa_install_save_vtxfmt( ctx, &ctx->ListState.ListVtxfmt ); 1197c1f859d4Smrg#endif 11987117f1b4Smrg /* Neutral tnl module stuff */ 11997117f1b4Smrg _mesa_init_exec_vtxfmt( ctx ); 12007117f1b4Smrg ctx->TnlModule.Current = NULL; 12017117f1b4Smrg ctx->TnlModule.SwapCount = 0; 12027117f1b4Smrg 12037117f1b4Smrg ctx->FragmentProgram._MaintainTexEnvProgram 12047117f1b4Smrg = (_mesa_getenv("MESA_TEX_PROG") != NULL); 12057117f1b4Smrg 12067117f1b4Smrg ctx->VertexProgram._MaintainTnlProgram 12077117f1b4Smrg = (_mesa_getenv("MESA_TNL_PROG") != NULL); 12087117f1b4Smrg if (ctx->VertexProgram._MaintainTnlProgram) { 12097117f1b4Smrg /* this is required... */ 12107117f1b4Smrg ctx->FragmentProgram._MaintainTexEnvProgram = GL_TRUE; 12117117f1b4Smrg } 12127117f1b4Smrg 1213c1f859d4Smrg#ifdef FEATURE_extra_context_init 1214c1f859d4Smrg _mesa_initialize_context_extra(ctx); 1215c1f859d4Smrg#endif 1216c1f859d4Smrg 12177117f1b4Smrg ctx->FirstTimeCurrent = GL_TRUE; 12187117f1b4Smrg 12197117f1b4Smrg return GL_TRUE; 12207117f1b4Smrg} 12217117f1b4Smrg 12227117f1b4Smrg 12237117f1b4Smrg/** 12247117f1b4Smrg * Allocate and initialize a GLcontext structure. 12257117f1b4Smrg * Note that the driver needs to pass in its dd_function_table here since 12267117f1b4Smrg * we need to at least call driverFunctions->NewTextureObject to initialize 12277117f1b4Smrg * the rendering context. 12287117f1b4Smrg * 12297117f1b4Smrg * \param visual a GLvisual pointer (we copy the struct contents) 12307117f1b4Smrg * \param share_list another context to share display lists with or NULL 12317117f1b4Smrg * \param driverFunctions points to the dd_function_table into which the 12327117f1b4Smrg * driver has plugged in all its special functions. 12337117f1b4Smrg * \param driverCtx points to the device driver's private context state 12347117f1b4Smrg * 12357117f1b4Smrg * \return pointer to a new __GLcontextRec or NULL if error. 12367117f1b4Smrg */ 12377117f1b4SmrgGLcontext * 12387117f1b4Smrg_mesa_create_context(const GLvisual *visual, 12397117f1b4Smrg GLcontext *share_list, 12407117f1b4Smrg const struct dd_function_table *driverFunctions, 12417117f1b4Smrg void *driverContext) 12427117f1b4Smrg{ 12437117f1b4Smrg GLcontext *ctx; 12447117f1b4Smrg 12457117f1b4Smrg ASSERT(visual); 12467117f1b4Smrg ASSERT(driverContext); 12477117f1b4Smrg 12487117f1b4Smrg ctx = (GLcontext *) _mesa_calloc(sizeof(GLcontext)); 12497117f1b4Smrg if (!ctx) 12507117f1b4Smrg return NULL; 12517117f1b4Smrg 12527117f1b4Smrg if (_mesa_initialize_context(ctx, visual, share_list, 12537117f1b4Smrg driverFunctions, driverContext)) { 12547117f1b4Smrg return ctx; 12557117f1b4Smrg } 12567117f1b4Smrg else { 12577117f1b4Smrg _mesa_free(ctx); 12587117f1b4Smrg return NULL; 12597117f1b4Smrg } 12607117f1b4Smrg} 12617117f1b4Smrg 12627117f1b4Smrg 12637117f1b4Smrg/** 12647117f1b4Smrg * Free the data associated with the given context. 12657117f1b4Smrg * 12667117f1b4Smrg * But doesn't free the GLcontext struct itself. 12677117f1b4Smrg * 12687117f1b4Smrg * \sa _mesa_initialize_context() and init_attrib_groups(). 12697117f1b4Smrg */ 12707117f1b4Smrgvoid 12717117f1b4Smrg_mesa_free_context_data( GLcontext *ctx ) 12727117f1b4Smrg{ 1273c1f859d4Smrg GLint RefCount; 1274c1f859d4Smrg 12757117f1b4Smrg if (!_mesa_get_current_context()){ 12767117f1b4Smrg /* No current context, but we may need one in order to delete 12777117f1b4Smrg * texture objs, etc. So temporarily bind the context now. 12787117f1b4Smrg */ 12797117f1b4Smrg _mesa_make_current(ctx, NULL, NULL); 12807117f1b4Smrg } 12817117f1b4Smrg 12827117f1b4Smrg /* unreference WinSysDraw/Read buffers */ 12837117f1b4Smrg _mesa_unreference_framebuffer(&ctx->WinSysDrawBuffer); 12847117f1b4Smrg _mesa_unreference_framebuffer(&ctx->WinSysReadBuffer); 12857117f1b4Smrg _mesa_unreference_framebuffer(&ctx->DrawBuffer); 12867117f1b4Smrg _mesa_unreference_framebuffer(&ctx->ReadBuffer); 12877117f1b4Smrg 1288c1f859d4Smrg _mesa_reference_vertprog(ctx, &ctx->VertexProgram.Current, NULL); 1289c1f859d4Smrg _mesa_reference_vertprog(ctx, &ctx->VertexProgram._Current, NULL); 1290c1f859d4Smrg _mesa_reference_vertprog(ctx, &ctx->VertexProgram._TnlProgram, NULL); 1291c1f859d4Smrg 1292c1f859d4Smrg _mesa_reference_fragprog(ctx, &ctx->FragmentProgram.Current, NULL); 1293c1f859d4Smrg _mesa_reference_fragprog(ctx, &ctx->FragmentProgram._Current, NULL); 1294c1f859d4Smrg _mesa_reference_fragprog(ctx, &ctx->FragmentProgram._TexEnvProgram, NULL); 1295c1f859d4Smrg 12967117f1b4Smrg _mesa_free_attrib_data(ctx); 12977117f1b4Smrg _mesa_free_lighting_data( ctx ); 1298c1f859d4Smrg#if FEATURE_evaluators 12997117f1b4Smrg _mesa_free_eval_data( ctx ); 1300c1f859d4Smrg#endif 13017117f1b4Smrg _mesa_free_texture_data( ctx ); 13027117f1b4Smrg _mesa_free_matrix_data( ctx ); 13037117f1b4Smrg _mesa_free_viewport_data( ctx ); 1304c1f859d4Smrg#if FEATURE_colortable 13057117f1b4Smrg _mesa_free_colortables_data( ctx ); 1306c1f859d4Smrg#endif 13077117f1b4Smrg _mesa_free_program_data(ctx); 13087117f1b4Smrg _mesa_free_shader_state(ctx); 1309c1f859d4Smrg#if FEATURE_ARB_occlusion_query 13107117f1b4Smrg _mesa_free_query_data(ctx); 1311c1f859d4Smrg#endif 13127117f1b4Smrg 13137117f1b4Smrg#if FEATURE_ARB_vertex_buffer_object 13147117f1b4Smrg _mesa_delete_buffer_object(ctx, ctx->Array.NullBufferObj); 13157117f1b4Smrg#endif 13167117f1b4Smrg _mesa_delete_array_object(ctx, ctx->Array.DefaultArrayObj); 13177117f1b4Smrg 13187117f1b4Smrg /* free dispatch tables */ 13197117f1b4Smrg _mesa_free(ctx->Exec); 13207117f1b4Smrg _mesa_free(ctx->Save); 13217117f1b4Smrg 13227117f1b4Smrg /* Shared context state (display lists, textures, etc) */ 13237117f1b4Smrg _glthread_LOCK_MUTEX(ctx->Shared->Mutex); 1324c1f859d4Smrg RefCount = --ctx->Shared->RefCount; 13257117f1b4Smrg _glthread_UNLOCK_MUTEX(ctx->Shared->Mutex); 1326c1f859d4Smrg assert(RefCount >= 0); 1327c1f859d4Smrg if (RefCount == 0) { 13287117f1b4Smrg /* free shared state */ 13297117f1b4Smrg free_shared_state( ctx, ctx->Shared ); 13307117f1b4Smrg } 13317117f1b4Smrg 13327117f1b4Smrg if (ctx->Extensions.String) 13337117f1b4Smrg _mesa_free((void *) ctx->Extensions.String); 13347117f1b4Smrg 13357117f1b4Smrg /* unbind the context if it's currently bound */ 13367117f1b4Smrg if (ctx == _mesa_get_current_context()) { 13377117f1b4Smrg _mesa_make_current(NULL, NULL, NULL); 13387117f1b4Smrg } 13397117f1b4Smrg} 13407117f1b4Smrg 13417117f1b4Smrg 13427117f1b4Smrg/** 13437117f1b4Smrg * Destroy a GLcontext structure. 13447117f1b4Smrg * 13457117f1b4Smrg * \param ctx GL context. 13467117f1b4Smrg * 13477117f1b4Smrg * Calls _mesa_free_context_data() and frees the GLcontext structure itself. 13487117f1b4Smrg */ 13497117f1b4Smrgvoid 13507117f1b4Smrg_mesa_destroy_context( GLcontext *ctx ) 13517117f1b4Smrg{ 13527117f1b4Smrg if (ctx) { 13537117f1b4Smrg _mesa_free_context_data(ctx); 13547117f1b4Smrg _mesa_free( (void *) ctx ); 13557117f1b4Smrg } 13567117f1b4Smrg} 13577117f1b4Smrg 13587117f1b4Smrg 13597117f1b4Smrg#if _HAVE_FULL_GL 13607117f1b4Smrg/** 13617117f1b4Smrg * Copy attribute groups from one context to another. 13627117f1b4Smrg * 13637117f1b4Smrg * \param src source context 13647117f1b4Smrg * \param dst destination context 13657117f1b4Smrg * \param mask bitwise OR of GL_*_BIT flags 13667117f1b4Smrg * 13677117f1b4Smrg * According to the bits specified in \p mask, copies the corresponding 13687117f1b4Smrg * attributes from \p src into \p dst. For many of the attributes a simple \c 13697117f1b4Smrg * memcpy is not enough due to the existence of internal pointers in their data 13707117f1b4Smrg * structures. 13717117f1b4Smrg */ 13727117f1b4Smrgvoid 13737117f1b4Smrg_mesa_copy_context( const GLcontext *src, GLcontext *dst, GLuint mask ) 13747117f1b4Smrg{ 13757117f1b4Smrg if (mask & GL_ACCUM_BUFFER_BIT) { 13767117f1b4Smrg /* OK to memcpy */ 13777117f1b4Smrg dst->Accum = src->Accum; 13787117f1b4Smrg } 13797117f1b4Smrg if (mask & GL_COLOR_BUFFER_BIT) { 13807117f1b4Smrg /* OK to memcpy */ 13817117f1b4Smrg dst->Color = src->Color; 13827117f1b4Smrg } 13837117f1b4Smrg if (mask & GL_CURRENT_BIT) { 13847117f1b4Smrg /* OK to memcpy */ 13857117f1b4Smrg dst->Current = src->Current; 13867117f1b4Smrg } 13877117f1b4Smrg if (mask & GL_DEPTH_BUFFER_BIT) { 13887117f1b4Smrg /* OK to memcpy */ 13897117f1b4Smrg dst->Depth = src->Depth; 13907117f1b4Smrg } 13917117f1b4Smrg if (mask & GL_ENABLE_BIT) { 13927117f1b4Smrg /* no op */ 13937117f1b4Smrg } 13947117f1b4Smrg if (mask & GL_EVAL_BIT) { 13957117f1b4Smrg /* OK to memcpy */ 13967117f1b4Smrg dst->Eval = src->Eval; 13977117f1b4Smrg } 13987117f1b4Smrg if (mask & GL_FOG_BIT) { 13997117f1b4Smrg /* OK to memcpy */ 14007117f1b4Smrg dst->Fog = src->Fog; 14017117f1b4Smrg } 14027117f1b4Smrg if (mask & GL_HINT_BIT) { 14037117f1b4Smrg /* OK to memcpy */ 14047117f1b4Smrg dst->Hint = src->Hint; 14057117f1b4Smrg } 14067117f1b4Smrg if (mask & GL_LIGHTING_BIT) { 14077117f1b4Smrg GLuint i; 14087117f1b4Smrg /* begin with memcpy */ 14097117f1b4Smrg dst->Light = src->Light; 14107117f1b4Smrg /* fixup linked lists to prevent pointer insanity */ 14117117f1b4Smrg make_empty_list( &(dst->Light.EnabledList) ); 14127117f1b4Smrg for (i = 0; i < MAX_LIGHTS; i++) { 14137117f1b4Smrg if (dst->Light.Light[i].Enabled) { 14147117f1b4Smrg insert_at_tail(&(dst->Light.EnabledList), &(dst->Light.Light[i])); 14157117f1b4Smrg } 14167117f1b4Smrg } 14177117f1b4Smrg } 14187117f1b4Smrg if (mask & GL_LINE_BIT) { 14197117f1b4Smrg /* OK to memcpy */ 14207117f1b4Smrg dst->Line = src->Line; 14217117f1b4Smrg } 14227117f1b4Smrg if (mask & GL_LIST_BIT) { 14237117f1b4Smrg /* OK to memcpy */ 14247117f1b4Smrg dst->List = src->List; 14257117f1b4Smrg } 14267117f1b4Smrg if (mask & GL_PIXEL_MODE_BIT) { 14277117f1b4Smrg /* OK to memcpy */ 14287117f1b4Smrg dst->Pixel = src->Pixel; 14297117f1b4Smrg } 14307117f1b4Smrg if (mask & GL_POINT_BIT) { 14317117f1b4Smrg /* OK to memcpy */ 14327117f1b4Smrg dst->Point = src->Point; 14337117f1b4Smrg } 14347117f1b4Smrg if (mask & GL_POLYGON_BIT) { 14357117f1b4Smrg /* OK to memcpy */ 14367117f1b4Smrg dst->Polygon = src->Polygon; 14377117f1b4Smrg } 14387117f1b4Smrg if (mask & GL_POLYGON_STIPPLE_BIT) { 14397117f1b4Smrg /* Use loop instead of MEMCPY due to problem with Portland Group's 14407117f1b4Smrg * C compiler. Reported by John Stone. 14417117f1b4Smrg */ 14427117f1b4Smrg GLuint i; 14437117f1b4Smrg for (i = 0; i < 32; i++) { 14447117f1b4Smrg dst->PolygonStipple[i] = src->PolygonStipple[i]; 14457117f1b4Smrg } 14467117f1b4Smrg } 14477117f1b4Smrg if (mask & GL_SCISSOR_BIT) { 14487117f1b4Smrg /* OK to memcpy */ 14497117f1b4Smrg dst->Scissor = src->Scissor; 14507117f1b4Smrg } 14517117f1b4Smrg if (mask & GL_STENCIL_BUFFER_BIT) { 14527117f1b4Smrg /* OK to memcpy */ 14537117f1b4Smrg dst->Stencil = src->Stencil; 14547117f1b4Smrg } 14557117f1b4Smrg if (mask & GL_TEXTURE_BIT) { 14567117f1b4Smrg /* Cannot memcpy because of pointers */ 14577117f1b4Smrg _mesa_copy_texture_state(src, dst); 14587117f1b4Smrg } 14597117f1b4Smrg if (mask & GL_TRANSFORM_BIT) { 14607117f1b4Smrg /* OK to memcpy */ 14617117f1b4Smrg dst->Transform = src->Transform; 14627117f1b4Smrg } 14637117f1b4Smrg if (mask & GL_VIEWPORT_BIT) { 14647117f1b4Smrg /* Cannot use memcpy, because of pointers in GLmatrix _WindowMap */ 14657117f1b4Smrg dst->Viewport.X = src->Viewport.X; 14667117f1b4Smrg dst->Viewport.Y = src->Viewport.Y; 14677117f1b4Smrg dst->Viewport.Width = src->Viewport.Width; 14687117f1b4Smrg dst->Viewport.Height = src->Viewport.Height; 14697117f1b4Smrg dst->Viewport.Near = src->Viewport.Near; 14707117f1b4Smrg dst->Viewport.Far = src->Viewport.Far; 14717117f1b4Smrg _math_matrix_copy(&dst->Viewport._WindowMap, &src->Viewport._WindowMap); 14727117f1b4Smrg } 14737117f1b4Smrg 14747117f1b4Smrg /* XXX FIXME: Call callbacks? 14757117f1b4Smrg */ 14767117f1b4Smrg dst->NewState = _NEW_ALL; 14777117f1b4Smrg} 14787117f1b4Smrg#endif 14797117f1b4Smrg 14807117f1b4Smrg 14817117f1b4Smrg/** 14827117f1b4Smrg * Check if the given context can render into the given framebuffer 14837117f1b4Smrg * by checking visual attributes. 14847117f1b4Smrg * 1485c1f859d4Smrg * Most of these tests could go away because Mesa is now pretty flexible 1486c1f859d4Smrg * in terms of mixing rendering contexts with framebuffers. As long 1487c1f859d4Smrg * as RGB vs. CI mode agree, we're probably good. 14887117f1b4Smrg * 14897117f1b4Smrg * \return GL_TRUE if compatible, GL_FALSE otherwise. 14907117f1b4Smrg */ 14917117f1b4Smrgstatic GLboolean 14927117f1b4Smrgcheck_compatible(const GLcontext *ctx, const GLframebuffer *buffer) 14937117f1b4Smrg{ 14947117f1b4Smrg const GLvisual *ctxvis = &ctx->Visual; 14957117f1b4Smrg const GLvisual *bufvis = &buffer->Visual; 14967117f1b4Smrg 14977117f1b4Smrg if (ctxvis == bufvis) 14987117f1b4Smrg return GL_TRUE; 14997117f1b4Smrg 15007117f1b4Smrg if (ctxvis->rgbMode != bufvis->rgbMode) 15017117f1b4Smrg return GL_FALSE; 15027117f1b4Smrg#if 0 15037117f1b4Smrg /* disabling this fixes the fgl_glxgears pbuffer demo */ 15047117f1b4Smrg if (ctxvis->doubleBufferMode && !bufvis->doubleBufferMode) 15057117f1b4Smrg return GL_FALSE; 15067117f1b4Smrg#endif 15077117f1b4Smrg if (ctxvis->stereoMode && !bufvis->stereoMode) 15087117f1b4Smrg return GL_FALSE; 15097117f1b4Smrg if (ctxvis->haveAccumBuffer && !bufvis->haveAccumBuffer) 15107117f1b4Smrg return GL_FALSE; 15117117f1b4Smrg if (ctxvis->haveDepthBuffer && !bufvis->haveDepthBuffer) 15127117f1b4Smrg return GL_FALSE; 15137117f1b4Smrg if (ctxvis->haveStencilBuffer && !bufvis->haveStencilBuffer) 15147117f1b4Smrg return GL_FALSE; 15157117f1b4Smrg if (ctxvis->redMask && ctxvis->redMask != bufvis->redMask) 15167117f1b4Smrg return GL_FALSE; 15177117f1b4Smrg if (ctxvis->greenMask && ctxvis->greenMask != bufvis->greenMask) 15187117f1b4Smrg return GL_FALSE; 15197117f1b4Smrg if (ctxvis->blueMask && ctxvis->blueMask != bufvis->blueMask) 15207117f1b4Smrg return GL_FALSE; 15217117f1b4Smrg#if 0 15227117f1b4Smrg /* disabled (see bug 11161) */ 15237117f1b4Smrg if (ctxvis->depthBits && ctxvis->depthBits != bufvis->depthBits) 15247117f1b4Smrg return GL_FALSE; 15257117f1b4Smrg#endif 15267117f1b4Smrg if (ctxvis->stencilBits && ctxvis->stencilBits != bufvis->stencilBits) 15277117f1b4Smrg return GL_FALSE; 15287117f1b4Smrg 15297117f1b4Smrg return GL_TRUE; 15307117f1b4Smrg} 15317117f1b4Smrg 15327117f1b4Smrg 15337117f1b4Smrg/** 15347117f1b4Smrg * Do one-time initialization for the given framebuffer. Specifically, 15357117f1b4Smrg * ask the driver for the window's current size and update the framebuffer 15367117f1b4Smrg * object to match. 15377117f1b4Smrg * Really, the device driver should totally take care of this. 15387117f1b4Smrg */ 15397117f1b4Smrgstatic void 15407117f1b4Smrginitialize_framebuffer_size(GLcontext *ctx, GLframebuffer *fb) 15417117f1b4Smrg{ 15427117f1b4Smrg GLuint width, height; 15437117f1b4Smrg if (ctx->Driver.GetBufferSize) { 15447117f1b4Smrg ctx->Driver.GetBufferSize(fb, &width, &height); 15457117f1b4Smrg if (ctx->Driver.ResizeBuffers) 15467117f1b4Smrg ctx->Driver.ResizeBuffers(ctx, fb, width, height); 15477117f1b4Smrg fb->Initialized = GL_TRUE; 15487117f1b4Smrg } 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 */ 1556c7037ccdSmrgvoid 1557c7037ccdSmrg_mesa_check_init_viewport(GLcontext *ctx, GLuint width, GLuint height) 1558c7037ccdSmrg{ 1559c7037ccdSmrg if (!ctx->ViewportInitialized && width > 0 && height > 0) { 1560c7037ccdSmrg /* Note: set flag here, before calling _mesa_set_viewport(), to prevent 1561c7037ccdSmrg * potential infinite recursion. 1562c7037ccdSmrg */ 1563c7037ccdSmrg ctx->ViewportInitialized = GL_TRUE; 1564c7037ccdSmrg _mesa_set_viewport(ctx, 0, 0, width, height); 1565c7037ccdSmrg _mesa_set_scissor(ctx, 0, 0, width, height); 1566c7037ccdSmrg } 1567c7037ccdSmrg} 1568c7037ccdSmrg 1569c7037ccdSmrg 15707117f1b4Smrg/** 15717117f1b4Smrg * Bind the given context to the given drawBuffer and readBuffer and 15727117f1b4Smrg * make it the current context for the calling thread. 15737117f1b4Smrg * We'll render into the drawBuffer and read pixels from the 15747117f1b4Smrg * readBuffer (i.e. glRead/CopyPixels, glCopyTexImage, etc). 15757117f1b4Smrg * 15767117f1b4Smrg * We check that the context's and framebuffer's visuals are compatible 15777117f1b4Smrg * and return immediately if they're not. 15787117f1b4Smrg * 15797117f1b4Smrg * \param newCtx the new GL context. If NULL then there will be no current GL 15807117f1b4Smrg * context. 15817117f1b4Smrg * \param drawBuffer the drawing framebuffer 15827117f1b4Smrg * \param readBuffer the reading framebuffer 15837117f1b4Smrg */ 15847117f1b4Smrgvoid 15857117f1b4Smrg_mesa_make_current( GLcontext *newCtx, GLframebuffer *drawBuffer, 15867117f1b4Smrg GLframebuffer *readBuffer ) 15877117f1b4Smrg{ 15887117f1b4Smrg if (MESA_VERBOSE & VERBOSE_API) 15897117f1b4Smrg _mesa_debug(newCtx, "_mesa_make_current()\n"); 15907117f1b4Smrg 15917117f1b4Smrg /* Check that the context's and framebuffer's visuals are compatible. 15927117f1b4Smrg */ 15937117f1b4Smrg if (newCtx && drawBuffer && newCtx->WinSysDrawBuffer != drawBuffer) { 15947117f1b4Smrg if (!check_compatible(newCtx, drawBuffer)) { 15957117f1b4Smrg _mesa_warning(newCtx, 15967117f1b4Smrg "MakeCurrent: incompatible visuals for context and drawbuffer"); 15977117f1b4Smrg return; 15987117f1b4Smrg } 15997117f1b4Smrg } 16007117f1b4Smrg if (newCtx && readBuffer && newCtx->WinSysReadBuffer != readBuffer) { 16017117f1b4Smrg if (!check_compatible(newCtx, readBuffer)) { 16027117f1b4Smrg _mesa_warning(newCtx, 16037117f1b4Smrg "MakeCurrent: incompatible visuals for context and readbuffer"); 16047117f1b4Smrg return; 16057117f1b4Smrg } 16067117f1b4Smrg } 16077117f1b4Smrg 16087117f1b4Smrg /* We used to call _glapi_check_multithread() here. Now do it in drivers */ 16097117f1b4Smrg _glapi_set_context((void *) newCtx); 16107117f1b4Smrg ASSERT(_mesa_get_current_context() == newCtx); 16117117f1b4Smrg 16127117f1b4Smrg if (!newCtx) { 16137117f1b4Smrg _glapi_set_dispatch(NULL); /* none current */ 16147117f1b4Smrg } 16157117f1b4Smrg else { 16167117f1b4Smrg _glapi_set_dispatch(newCtx->CurrentDispatch); 16177117f1b4Smrg 16187117f1b4Smrg if (drawBuffer && readBuffer) { 16197117f1b4Smrg /* TODO: check if newCtx and buffer's visual match??? */ 16207117f1b4Smrg 16217117f1b4Smrg ASSERT(drawBuffer->Name == 0); 16227117f1b4Smrg ASSERT(readBuffer->Name == 0); 16237117f1b4Smrg _mesa_reference_framebuffer(&newCtx->WinSysDrawBuffer, drawBuffer); 16247117f1b4Smrg _mesa_reference_framebuffer(&newCtx->WinSysReadBuffer, readBuffer); 16257117f1b4Smrg 16267117f1b4Smrg /* 16277117f1b4Smrg * Only set the context's Draw/ReadBuffer fields if they're NULL 16287117f1b4Smrg * or not bound to a user-created FBO. 16297117f1b4Smrg */ 16307117f1b4Smrg if (!newCtx->DrawBuffer || newCtx->DrawBuffer->Name == 0) { 16317117f1b4Smrg _mesa_reference_framebuffer(&newCtx->DrawBuffer, drawBuffer); 16327117f1b4Smrg } 16337117f1b4Smrg if (!newCtx->ReadBuffer || newCtx->ReadBuffer->Name == 0) { 16347117f1b4Smrg _mesa_reference_framebuffer(&newCtx->ReadBuffer, readBuffer); 16357117f1b4Smrg } 16367117f1b4Smrg 1637c1f859d4Smrg /* XXX only set this flag if we're really changing the draw/read 1638c1f859d4Smrg * framebuffer bindings. 1639c1f859d4Smrg */ 16407117f1b4Smrg newCtx->NewState |= _NEW_BUFFERS; 16417117f1b4Smrg 16427117f1b4Smrg#if 1 16437117f1b4Smrg /* We want to get rid of these lines: */ 16447117f1b4Smrg 16457117f1b4Smrg#if _HAVE_FULL_GL 16467117f1b4Smrg if (!drawBuffer->Initialized) { 16477117f1b4Smrg initialize_framebuffer_size(newCtx, drawBuffer); 16487117f1b4Smrg } 16497117f1b4Smrg if (readBuffer != drawBuffer && !readBuffer->Initialized) { 16507117f1b4Smrg initialize_framebuffer_size(newCtx, readBuffer); 16517117f1b4Smrg } 16527117f1b4Smrg 16537117f1b4Smrg _mesa_resizebuffers(newCtx); 16547117f1b4Smrg#endif 16557117f1b4Smrg 16567117f1b4Smrg#else 16577117f1b4Smrg /* We want the drawBuffer and readBuffer to be initialized by 16587117f1b4Smrg * the driver. 16597117f1b4Smrg * This generally means the Width and Height match the actual 16607117f1b4Smrg * window size and the renderbuffers (both hardware and software 16617117f1b4Smrg * based) are allocated to match. The later can generally be 16627117f1b4Smrg * done with a call to _mesa_resize_framebuffer(). 16637117f1b4Smrg * 16647117f1b4Smrg * It's theoretically possible for a buffer to have zero width 16657117f1b4Smrg * or height, but for now, assert check that the driver did what's 16667117f1b4Smrg * expected of it. 16677117f1b4Smrg */ 16687117f1b4Smrg ASSERT(drawBuffer->Width > 0); 16697117f1b4Smrg ASSERT(drawBuffer->Height > 0); 16707117f1b4Smrg#endif 16717117f1b4Smrg 1672c7037ccdSmrg if (drawBuffer) { 1673c7037ccdSmrg _mesa_check_init_viewport(newCtx, 1674c7037ccdSmrg drawBuffer->Width, drawBuffer->Height); 16757117f1b4Smrg } 16767117f1b4Smrg } 16777117f1b4Smrg 16787117f1b4Smrg if (newCtx->FirstTimeCurrent) { 1679c7037ccdSmrg check_context_limits(newCtx); 1680c7037ccdSmrg 1681c7037ccdSmrg /* We can use this to help debug user's problems. Tell them to set 1682c7037ccdSmrg * the MESA_INFO env variable before running their app. Then the 1683c7037ccdSmrg * first time each context is made current we'll print some useful 1684c7037ccdSmrg * information. 1685c7037ccdSmrg */ 16867117f1b4Smrg if (_mesa_getenv("MESA_INFO")) { 16877117f1b4Smrg _mesa_print_info(); 16887117f1b4Smrg } 1689c7037ccdSmrg 16907117f1b4Smrg newCtx->FirstTimeCurrent = GL_FALSE; 16917117f1b4Smrg } 16927117f1b4Smrg } 16937117f1b4Smrg} 16947117f1b4Smrg 16957117f1b4Smrg 16967117f1b4Smrg/** 16977117f1b4Smrg * Make context 'ctx' share the display lists, textures and programs 16987117f1b4Smrg * that are associated with 'ctxToShare'. 16997117f1b4Smrg * Any display lists, textures or programs associated with 'ctx' will 17007117f1b4Smrg * be deleted if nobody else is sharing them. 17017117f1b4Smrg */ 17027117f1b4SmrgGLboolean 17037117f1b4Smrg_mesa_share_state(GLcontext *ctx, GLcontext *ctxToShare) 17047117f1b4Smrg{ 17057117f1b4Smrg if (ctx && ctxToShare && ctx->Shared && ctxToShare->Shared) { 1706c1f859d4Smrg struct gl_shared_state *oldSharedState = ctx->Shared; 1707c1f859d4Smrg 17087117f1b4Smrg ctx->Shared = ctxToShare->Shared; 17097117f1b4Smrg ctx->Shared->RefCount++; 1710c1f859d4Smrg 1711c1f859d4Smrg update_default_objects(ctx); 1712c1f859d4Smrg 1713c1f859d4Smrg oldSharedState->RefCount--; 1714c1f859d4Smrg if (oldSharedState->RefCount == 0) { 1715c1f859d4Smrg free_shared_state(ctx, oldSharedState); 1716c1f859d4Smrg } 1717c1f859d4Smrg 17187117f1b4Smrg return GL_TRUE; 17197117f1b4Smrg } 17207117f1b4Smrg else { 17217117f1b4Smrg return GL_FALSE; 17227117f1b4Smrg } 17237117f1b4Smrg} 17247117f1b4Smrg 17257117f1b4Smrg 17267117f1b4Smrg 17277117f1b4Smrg/** 17287117f1b4Smrg * \return pointer to the current GL context for this thread. 17297117f1b4Smrg * 17307117f1b4Smrg * Calls _glapi_get_context(). This isn't the fastest way to get the current 17317117f1b4Smrg * context. If you need speed, see the #GET_CURRENT_CONTEXT macro in 17327117f1b4Smrg * context.h. 17337117f1b4Smrg */ 17347117f1b4SmrgGLcontext * 17357117f1b4Smrg_mesa_get_current_context( void ) 17367117f1b4Smrg{ 17377117f1b4Smrg return (GLcontext *) _glapi_get_context(); 17387117f1b4Smrg} 17397117f1b4Smrg 17407117f1b4Smrg 17417117f1b4Smrg/** 17427117f1b4Smrg * Get context's current API dispatch table. 17437117f1b4Smrg * 17447117f1b4Smrg * It'll either be the immediate-mode execute dispatcher or the display list 17457117f1b4Smrg * compile dispatcher. 17467117f1b4Smrg * 17477117f1b4Smrg * \param ctx GL context. 17487117f1b4Smrg * 17497117f1b4Smrg * \return pointer to dispatch_table. 17507117f1b4Smrg * 17517117f1b4Smrg * Simply returns __GLcontextRec::CurrentDispatch. 17527117f1b4Smrg */ 17537117f1b4Smrgstruct _glapi_table * 17547117f1b4Smrg_mesa_get_dispatch(GLcontext *ctx) 17557117f1b4Smrg{ 17567117f1b4Smrg return ctx->CurrentDispatch; 17577117f1b4Smrg} 17587117f1b4Smrg 17597117f1b4Smrg/*@}*/ 17607117f1b4Smrg 17617117f1b4Smrg 17627117f1b4Smrg/**********************************************************************/ 17637117f1b4Smrg/** \name Miscellaneous functions */ 17647117f1b4Smrg/**********************************************************************/ 17657117f1b4Smrg/*@{*/ 17667117f1b4Smrg 17677117f1b4Smrg/** 17687117f1b4Smrg * Record an error. 17697117f1b4Smrg * 17707117f1b4Smrg * \param ctx GL context. 17717117f1b4Smrg * \param error error code. 17727117f1b4Smrg * 17737117f1b4Smrg * Records the given error code and call the driver's dd_function_table::Error 17747117f1b4Smrg * function if defined. 17757117f1b4Smrg * 17767117f1b4Smrg * \sa 17777117f1b4Smrg * This is called via _mesa_error(). 17787117f1b4Smrg */ 17797117f1b4Smrgvoid 17807117f1b4Smrg_mesa_record_error(GLcontext *ctx, GLenum error) 17817117f1b4Smrg{ 17827117f1b4Smrg if (!ctx) 17837117f1b4Smrg return; 17847117f1b4Smrg 17857117f1b4Smrg if (ctx->ErrorValue == GL_NO_ERROR) { 17867117f1b4Smrg ctx->ErrorValue = error; 17877117f1b4Smrg } 17887117f1b4Smrg 17897117f1b4Smrg /* Call device driver's error handler, if any. This is used on the Mac. */ 17907117f1b4Smrg if (ctx->Driver.Error) { 17917117f1b4Smrg ctx->Driver.Error(ctx); 17927117f1b4Smrg } 17937117f1b4Smrg} 17947117f1b4Smrg 17957117f1b4Smrg 17967117f1b4Smrg/** 17977117f1b4Smrg * Execute glFinish(). 17987117f1b4Smrg * 17997117f1b4Smrg * Calls the #ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH macro and the 18007117f1b4Smrg * dd_function_table::Finish driver callback, if not NULL. 18017117f1b4Smrg */ 18027117f1b4Smrgvoid GLAPIENTRY 18037117f1b4Smrg_mesa_Finish(void) 18047117f1b4Smrg{ 18057117f1b4Smrg GET_CURRENT_CONTEXT(ctx); 18067117f1b4Smrg ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); 18077117f1b4Smrg if (ctx->Driver.Finish) { 18087117f1b4Smrg ctx->Driver.Finish(ctx); 18097117f1b4Smrg } 18107117f1b4Smrg} 18117117f1b4Smrg 18127117f1b4Smrg 18137117f1b4Smrg/** 18147117f1b4Smrg * Execute glFlush(). 18157117f1b4Smrg * 18167117f1b4Smrg * Calls the #ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH macro and the 18177117f1b4Smrg * dd_function_table::Flush driver callback, if not NULL. 18187117f1b4Smrg */ 18197117f1b4Smrgvoid GLAPIENTRY 18207117f1b4Smrg_mesa_Flush(void) 18217117f1b4Smrg{ 18227117f1b4Smrg GET_CURRENT_CONTEXT(ctx); 18237117f1b4Smrg ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); 18247117f1b4Smrg if (ctx->Driver.Flush) { 18257117f1b4Smrg ctx->Driver.Flush(ctx); 18267117f1b4Smrg } 18277117f1b4Smrg} 18287117f1b4Smrg 18297117f1b4Smrg 18307117f1b4Smrg/*@}*/ 1831