context.c revision d8407755
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"
132d8407755Smaya#include "shaderimage.h"
1334a49301eSmrg#include "texcompress_s3tc.h"
1347117f1b4Smrg#include "texstate.h"
1353464ebd5Sriastradh#include "transformfeedback.h"
1367117f1b4Smrg#include "mtypes.h"
1377117f1b4Smrg#include "varray.h"
1387117f1b4Smrg#include "version.h"
1394a49301eSmrg#include "viewport.h"
1407e995a2eSmrg#include "texturebindless.h"
1413464ebd5Sriastradh#include "program/program.h"
1427117f1b4Smrg#include "math/m_matrix.h"
1433464ebd5Sriastradh#include "main/dispatch.h" /* for _gloffset_COUNT */
1447e995a2eSmrg#include "macros.h"
1457e995a2eSmrg#include "git_sha1.h"
1467117f1b4Smrg
1477117f1b4Smrg#ifdef USE_SPARC_ASM
1487117f1b4Smrg#include "sparc/sparc.h"
1497117f1b4Smrg#endif
1507117f1b4Smrg
1517e995a2eSmrg#include "compiler/glsl_types.h"
1527e995a2eSmrg#include "compiler/glsl/glsl_parser_extras.h"
1533464ebd5Sriastradh#include <stdbool.h>
1543464ebd5Sriastradh
1553464ebd5Sriastradh
1567117f1b4Smrg#ifndef MESA_VERBOSE
1577117f1b4Smrgint MESA_VERBOSE = 0;
1587117f1b4Smrg#endif
1597117f1b4Smrg
1607117f1b4Smrg#ifndef MESA_DEBUG_FLAGS
1617117f1b4Smrgint MESA_DEBUG_FLAGS = 0;
1627117f1b4Smrg#endif
1637117f1b4Smrg
1647117f1b4Smrg
1657117f1b4Smrg/* ubyte -> float conversion */
1667117f1b4SmrgGLfloat _mesa_ubyte_to_float_color_tab[256];
1677117f1b4Smrg
1687117f1b4Smrg
1697117f1b4Smrg
1707117f1b4Smrg/**
1717117f1b4Smrg * Swap buffers notification callback.
1727e995a2eSmrg *
1734a49301eSmrg * \param ctx GL context.
1747117f1b4Smrg *
1757117f1b4Smrg * Called by window system just before swapping buffers.
1767117f1b4Smrg * We have to finish any pending rendering.
1777117f1b4Smrg */
1787117f1b4Smrgvoid
1793464ebd5Sriastradh_mesa_notifySwapBuffers(struct gl_context *ctx)
1807117f1b4Smrg{
1814a49301eSmrg   if (MESA_VERBOSE & VERBOSE_SWAPBUFFERS)
1824a49301eSmrg      _mesa_debug(ctx, "SwapBuffers\n");
1834a49301eSmrg   FLUSH_CURRENT( ctx, 0 );
1844a49301eSmrg   if (ctx->Driver.Flush) {
1854a49301eSmrg      ctx->Driver.Flush(ctx);
1864a49301eSmrg   }
1877117f1b4Smrg}
1887117f1b4Smrg
1897117f1b4Smrg
1907117f1b4Smrg/**********************************************************************/
1917117f1b4Smrg/** \name GL Visual allocation/destruction                            */
1927117f1b4Smrg/**********************************************************************/
1937117f1b4Smrg/*@{*/
1947117f1b4Smrg
1957117f1b4Smrg/**
1963464ebd5Sriastradh * Allocates a struct gl_config structure and initializes it via
1977117f1b4Smrg * _mesa_initialize_visual().
1987e995a2eSmrg *
1997117f1b4Smrg * \param dbFlag double buffering
2007117f1b4Smrg * \param stereoFlag stereo buffer
2017117f1b4Smrg * \param depthBits requested bits per depth buffer value. Any value in [0, 32]
2027117f1b4Smrg * is acceptable but the actual depth type will be GLushort or GLuint as
2037117f1b4Smrg * needed.
2047117f1b4Smrg * \param stencilBits requested minimum bits per stencil buffer value
2053464ebd5Sriastradh * \param accumRedBits, accumGreenBits, accumBlueBits, accumAlphaBits number
2063464ebd5Sriastradh * of bits per color component in accum buffer.
2077117f1b4Smrg * \param indexBits number of bits per pixel if \p rgbFlag is GL_FALSE
2087117f1b4Smrg * \param redBits number of bits per color component in frame buffer for RGB(A)
2097117f1b4Smrg * mode.  We always use 8 in core Mesa though.
2107117f1b4Smrg * \param greenBits same as above.
2117117f1b4Smrg * \param blueBits same as above.
2127117f1b4Smrg * \param alphaBits same as above.
2137117f1b4Smrg * \param numSamples not really used.
2147e995a2eSmrg *
2153464ebd5Sriastradh * \return pointer to new struct gl_config or NULL if requested parameters
2163464ebd5Sriastradh * can't be met.
2177117f1b4Smrg *
2187117f1b4Smrg * \note Need to add params for level and numAuxBuffers (at least)
2197117f1b4Smrg */
2203464ebd5Sriastradhstruct gl_config *
221cdc920a0Smrg_mesa_create_visual( GLboolean dbFlag,
2227117f1b4Smrg                     GLboolean stereoFlag,
2237117f1b4Smrg                     GLint redBits,
2247117f1b4Smrg                     GLint greenBits,
2257117f1b4Smrg                     GLint blueBits,
2267117f1b4Smrg                     GLint alphaBits,
2277117f1b4Smrg                     GLint depthBits,
2287117f1b4Smrg                     GLint stencilBits,
2297117f1b4Smrg                     GLint accumRedBits,
2307117f1b4Smrg                     GLint accumGreenBits,
2317117f1b4Smrg                     GLint accumBlueBits,
2327117f1b4Smrg                     GLint accumAlphaBits,
2337e995a2eSmrg                     GLuint numSamples )
2347117f1b4Smrg{
2353464ebd5Sriastradh   struct gl_config *vis = CALLOC_STRUCT(gl_config);
2367117f1b4Smrg   if (vis) {
237cdc920a0Smrg      if (!_mesa_initialize_visual(vis, dbFlag, stereoFlag,
2387117f1b4Smrg                                   redBits, greenBits, blueBits, alphaBits,
239cdc920a0Smrg                                   depthBits, stencilBits,
2407117f1b4Smrg                                   accumRedBits, accumGreenBits,
2417117f1b4Smrg                                   accumBlueBits, accumAlphaBits,
2427117f1b4Smrg                                   numSamples)) {
243cdc920a0Smrg         free(vis);
2447117f1b4Smrg         return NULL;
2457117f1b4Smrg      }
2467117f1b4Smrg   }
2477117f1b4Smrg   return vis;
2487117f1b4Smrg}
2497117f1b4Smrg
2503464ebd5Sriastradh
2517117f1b4Smrg/**
2523464ebd5Sriastradh * Makes some sanity checks and fills in the fields of the struct
2533464ebd5Sriastradh * gl_config object with the given parameters.  If the caller needs to
2543464ebd5Sriastradh * set additional fields, he should just probably init the whole
2553464ebd5Sriastradh * gl_config object himself.
2563464ebd5Sriastradh *
2577117f1b4Smrg * \return GL_TRUE on success, or GL_FALSE on failure.
2587117f1b4Smrg *
2597117f1b4Smrg * \sa _mesa_create_visual() above for the parameter description.
2607117f1b4Smrg */
2617117f1b4SmrgGLboolean
2623464ebd5Sriastradh_mesa_initialize_visual( struct gl_config *vis,
2637117f1b4Smrg                         GLboolean dbFlag,
2647117f1b4Smrg                         GLboolean stereoFlag,
2657117f1b4Smrg                         GLint redBits,
2667117f1b4Smrg                         GLint greenBits,
2677117f1b4Smrg                         GLint blueBits,
2687117f1b4Smrg                         GLint alphaBits,
2697117f1b4Smrg                         GLint depthBits,
2707117f1b4Smrg                         GLint stencilBits,
2717117f1b4Smrg                         GLint accumRedBits,
2727117f1b4Smrg                         GLint accumGreenBits,
2737117f1b4Smrg                         GLint accumBlueBits,
2747117f1b4Smrg                         GLint accumAlphaBits,
2757e995a2eSmrg                         GLuint numSamples )
2767117f1b4Smrg{
2777117f1b4Smrg   assert(vis);
2787117f1b4Smrg
2797117f1b4Smrg   if (depthBits < 0 || depthBits > 32) {
2807117f1b4Smrg      return GL_FALSE;
2817117f1b4Smrg   }
282b167d5e7Smrg   if (stencilBits < 0 || stencilBits > 8) {
2837117f1b4Smrg      return GL_FALSE;
2847117f1b4Smrg   }
2857117f1b4Smrg   assert(accumRedBits >= 0);
2867117f1b4Smrg   assert(accumGreenBits >= 0);
2877117f1b4Smrg   assert(accumBlueBits >= 0);
2887117f1b4Smrg   assert(accumAlphaBits >= 0);
2897117f1b4Smrg
290cdc920a0Smrg   vis->rgbMode          = GL_TRUE;
2917117f1b4Smrg   vis->doubleBufferMode = dbFlag;
2927117f1b4Smrg   vis->stereoMode       = stereoFlag;
2937117f1b4Smrg
2947117f1b4Smrg   vis->redBits          = redBits;
2957117f1b4Smrg   vis->greenBits        = greenBits;
2967117f1b4Smrg   vis->blueBits         = blueBits;
2977117f1b4Smrg   vis->alphaBits        = alphaBits;
2987117f1b4Smrg   vis->rgbBits          = redBits + greenBits + blueBits;
2997117f1b4Smrg
300cdc920a0Smrg   vis->indexBits      = 0;
3017117f1b4Smrg   vis->depthBits      = depthBits;
3027117f1b4Smrg   vis->stencilBits    = stencilBits;
3037117f1b4Smrg
3047117f1b4Smrg   vis->accumRedBits   = accumRedBits;
3057117f1b4Smrg   vis->accumGreenBits = accumGreenBits;
3067117f1b4Smrg   vis->accumBlueBits  = accumBlueBits;
3077117f1b4Smrg   vis->accumAlphaBits = accumAlphaBits;
3087117f1b4Smrg
3097117f1b4Smrg   vis->haveAccumBuffer   = accumRedBits > 0;
3107117f1b4Smrg   vis->haveDepthBuffer   = depthBits > 0;
3117117f1b4Smrg   vis->haveStencilBuffer = stencilBits > 0;
3127117f1b4Smrg
3137117f1b4Smrg   vis->numAuxBuffers = 0;
3147117f1b4Smrg   vis->level = 0;
3157117f1b4Smrg   vis->sampleBuffers = numSamples > 0 ? 1 : 0;
3167117f1b4Smrg   vis->samples = numSamples;
3177117f1b4Smrg
3187117f1b4Smrg   return GL_TRUE;
3197117f1b4Smrg}
3207117f1b4Smrg
3217117f1b4Smrg
3227117f1b4Smrg/**
3237117f1b4Smrg * Destroy a visual and free its memory.
3247117f1b4Smrg *
3257117f1b4Smrg * \param vis visual.
3267e995a2eSmrg *
3277117f1b4Smrg * Frees the visual structure.
3287117f1b4Smrg */
3297117f1b4Smrgvoid
3303464ebd5Sriastradh_mesa_destroy_visual( struct gl_config *vis )
3317117f1b4Smrg{
332cdc920a0Smrg   free(vis);
3337117f1b4Smrg}
3347117f1b4Smrg
3357117f1b4Smrg/*@}*/
3367117f1b4Smrg
3377117f1b4Smrg
3387117f1b4Smrg/**********************************************************************/
3397117f1b4Smrg/** \name Context allocation, initialization, destroying
3407117f1b4Smrg *
3417117f1b4Smrg * The purpose of the most initialization functions here is to provide the
3427117f1b4Smrg * default state values according to the OpenGL specification.
3437117f1b4Smrg */
3447117f1b4Smrg/**********************************************************************/
3457117f1b4Smrg/*@{*/
3467117f1b4Smrg
3474a49301eSmrg
3487117f1b4Smrg/**
3497117f1b4Smrg * One-time initialization mutex lock.
3507117f1b4Smrg *
3517117f1b4Smrg * \sa Used by one_time_init().
3527117f1b4Smrg */
353b167d5e7Smrgmtx_t OneTimeLock = _MTX_INITIALIZER_NP;
3547117f1b4Smrg
3553464ebd5Sriastradh
3567e995a2eSmrg/**
3577e995a2eSmrg * Calls all the various one-time-fini functions in Mesa
3587e995a2eSmrg */
3597e995a2eSmrg
3607e995a2eSmrgstatic GLbitfield api_init_mask = 0x0;
3617e995a2eSmrgstatic void __attribute__((__destructor__))
3627e995a2eSmrgone_time_fini(void)
3637e995a2eSmrg{
3647e995a2eSmrg   if (api_init_mask) {
3657e995a2eSmrg      _mesa_destroy_shader_compiler();
366d8407755Smaya      _mesa_destroy_shader_compiler_types();
3677e995a2eSmrg      _mesa_locale_fini();
3687e995a2eSmrg   }
3697e995a2eSmrg}
3703464ebd5Sriastradh
3717117f1b4Smrg/**
3727117f1b4Smrg * Calls all the various one-time-init functions in Mesa.
3737117f1b4Smrg *
3747117f1b4Smrg * While holding a global mutex lock, calls several initialization functions,
3757117f1b4Smrg * and sets the glapi callbacks if the \c MESA_DEBUG environment variable is
3767117f1b4Smrg * defined.
3777117f1b4Smrg *
3787117f1b4Smrg * \sa _math_init().
3797117f1b4Smrg */
3807117f1b4Smrgstatic void
3813464ebd5Sriastradhone_time_init( struct gl_context *ctx )
3827117f1b4Smrg{
3833464ebd5Sriastradh
384b167d5e7Smrg   mtx_lock(&OneTimeLock);
3853464ebd5Sriastradh
3863464ebd5Sriastradh   /* truly one-time init */
3873464ebd5Sriastradh   if (!api_init_mask) {
3887117f1b4Smrg      GLuint i;
3897117f1b4Smrg
3907e995a2eSmrg      STATIC_ASSERT(sizeof(GLbyte) == 1);
3917e995a2eSmrg      STATIC_ASSERT(sizeof(GLubyte) == 1);
3927e995a2eSmrg      STATIC_ASSERT(sizeof(GLshort) == 2);
3937e995a2eSmrg      STATIC_ASSERT(sizeof(GLushort) == 2);
3947e995a2eSmrg      STATIC_ASSERT(sizeof(GLint) == 4);
3957e995a2eSmrg      STATIC_ASSERT(sizeof(GLuint) == 4);
3967e995a2eSmrg
3977e995a2eSmrg      _mesa_locale_init();
3987117f1b4Smrg
399d8407755Smaya      _mesa_init_shader_compiler_types();
400d8407755Smaya
4017e995a2eSmrg      _mesa_one_time_init_extension_overrides(ctx);
4027117f1b4Smrg
403b167d5e7Smrg      _mesa_get_cpu_features();
4043464ebd5Sriastradh
4057117f1b4Smrg      for (i = 0; i < 256; i++) {
4067117f1b4Smrg         _mesa_ubyte_to_float_color_tab[i] = (float) i / 255.0F;
4077117f1b4Smrg      }
4087117f1b4Smrg
4097e995a2eSmrg#if defined(DEBUG)
4103464ebd5Sriastradh      if (MESA_VERBOSE != 0) {
4117e995a2eSmrg         _mesa_debug(ctx, "Mesa " PACKAGE_VERSION " DEBUG build" MESA_GIT_SHA1 "\n");
4123464ebd5Sriastradh      }
4137117f1b4Smrg#endif
4147117f1b4Smrg   }
4153464ebd5Sriastradh
4163464ebd5Sriastradh   /* per-API one-time init */
4173464ebd5Sriastradh   if (!(api_init_mask & (1 << ctx->API))) {
418b167d5e7Smrg      _mesa_init_remap_table();
4193464ebd5Sriastradh   }
4203464ebd5Sriastradh
4213464ebd5Sriastradh   api_init_mask |= 1 << ctx->API;
4223464ebd5Sriastradh
423b167d5e7Smrg   mtx_unlock(&OneTimeLock);
424eabf4f72Sriastradh}
425eabf4f72Sriastradh
4267117f1b4Smrg
4277117f1b4Smrg/**
4287117f1b4Smrg * Initialize fields of gl_current_attrib (aka ctx->Current.*)
4297117f1b4Smrg */
4307117f1b4Smrgstatic void
4313464ebd5Sriastradh_mesa_init_current(struct gl_context *ctx)
4327117f1b4Smrg{
4337117f1b4Smrg   GLuint i;
4347117f1b4Smrg
4357117f1b4Smrg   /* Init all to (0,0,0,1) */
4367e995a2eSmrg   for (i = 0; i < ARRAY_SIZE(ctx->Current.Attrib); i++) {
4377117f1b4Smrg      ASSIGN_4V( ctx->Current.Attrib[i], 0.0, 0.0, 0.0, 1.0 );
4387117f1b4Smrg   }
4397117f1b4Smrg
4407117f1b4Smrg   /* redo special cases: */
4417117f1b4Smrg   ASSIGN_4V( ctx->Current.Attrib[VERT_ATTRIB_NORMAL], 0.0, 0.0, 1.0, 1.0 );
4427117f1b4Smrg   ASSIGN_4V( ctx->Current.Attrib[VERT_ATTRIB_COLOR0], 1.0, 1.0, 1.0, 1.0 );
4437117f1b4Smrg   ASSIGN_4V( ctx->Current.Attrib[VERT_ATTRIB_COLOR1], 0.0, 0.0, 0.0, 1.0 );
4447117f1b4Smrg   ASSIGN_4V( ctx->Current.Attrib[VERT_ATTRIB_COLOR_INDEX], 1.0, 0.0, 0.0, 1.0 );
4457117f1b4Smrg   ASSIGN_4V( ctx->Current.Attrib[VERT_ATTRIB_EDGEFLAG], 1.0, 0.0, 0.0, 1.0 );
4467117f1b4Smrg}
4477117f1b4Smrg
4487117f1b4Smrg
4497117f1b4Smrg/**
4503464ebd5Sriastradh * Init vertex/fragment/geometry program limits.
4514a49301eSmrg * Important: drivers should override these with actual limits.
4527117f1b4Smrg */
4537117f1b4Smrgstatic void
454b167d5e7Smrginit_program_limits(struct gl_constants *consts, gl_shader_stage stage,
455b167d5e7Smrg                    struct gl_program_constants *prog)
4567117f1b4Smrg{
4574a49301eSmrg   prog->MaxInstructions = MAX_PROGRAM_INSTRUCTIONS;
4584a49301eSmrg   prog->MaxAluInstructions = MAX_PROGRAM_INSTRUCTIONS;
4594a49301eSmrg   prog->MaxTexInstructions = MAX_PROGRAM_INSTRUCTIONS;
4604a49301eSmrg   prog->MaxTexIndirections = MAX_PROGRAM_INSTRUCTIONS;
4614a49301eSmrg   prog->MaxTemps = MAX_PROGRAM_TEMPS;
4624a49301eSmrg   prog->MaxEnvParams = MAX_PROGRAM_ENV_PARAMS;
4634a49301eSmrg   prog->MaxLocalParams = MAX_PROGRAM_LOCAL_PARAMS;
4643464ebd5Sriastradh   prog->MaxAddressOffset = MAX_PROGRAM_LOCAL_PARAMS;
4654a49301eSmrg
466b167d5e7Smrg   switch (stage) {
467b167d5e7Smrg   case MESA_SHADER_VERTEX:
4684a49301eSmrg      prog->MaxParameters = MAX_VERTEX_PROGRAM_PARAMS;
469b167d5e7Smrg      prog->MaxAttribs = MAX_VERTEX_GENERIC_ATTRIBS;
4704a49301eSmrg      prog->MaxAddressRegs = MAX_VERTEX_PROGRAM_ADDRESS_REGS;
4713464ebd5Sriastradh      prog->MaxUniformComponents = 4 * MAX_UNIFORMS;
472b167d5e7Smrg      prog->MaxInputComponents = 0; /* value not used */
473b167d5e7Smrg      prog->MaxOutputComponents = 16 * 4; /* old limit not to break tnl and swrast */
4743464ebd5Sriastradh      break;
475b167d5e7Smrg   case MESA_SHADER_FRAGMENT:
4767e995a2eSmrg      prog->MaxParameters = MAX_FRAGMENT_PROGRAM_PARAMS;
4777e995a2eSmrg      prog->MaxAttribs = MAX_FRAGMENT_PROGRAM_INPUTS;
4784a49301eSmrg      prog->MaxAddressRegs = MAX_FRAGMENT_PROGRAM_ADDRESS_REGS;
4793464ebd5Sriastradh      prog->MaxUniformComponents = 4 * MAX_UNIFORMS;
480b167d5e7Smrg      prog->MaxInputComponents = 16 * 4; /* old limit not to break tnl and swrast */
481b167d5e7Smrg      prog->MaxOutputComponents = 0; /* value not used */
4823464ebd5Sriastradh      break;
4837e995a2eSmrg   case MESA_SHADER_TESS_CTRL:
4847e995a2eSmrg   case MESA_SHADER_TESS_EVAL:
485b167d5e7Smrg   case MESA_SHADER_GEOMETRY:
486b167d5e7Smrg      prog->MaxParameters = MAX_VERTEX_PROGRAM_PARAMS;
487b167d5e7Smrg      prog->MaxAttribs = MAX_VERTEX_GENERIC_ATTRIBS;
4883464ebd5Sriastradh      prog->MaxAddressRegs = MAX_VERTEX_PROGRAM_ADDRESS_REGS;
489b167d5e7Smrg      prog->MaxUniformComponents = 4 * MAX_UNIFORMS;
490b167d5e7Smrg      prog->MaxInputComponents = 16 * 4; /* old limit not to break tnl and swrast */
491b167d5e7Smrg      prog->MaxOutputComponents = 16 * 4; /* old limit not to break tnl and swrast */
492b167d5e7Smrg      break;
493b167d5e7Smrg   case MESA_SHADER_COMPUTE:
494b167d5e7Smrg      prog->MaxParameters = 0; /* not meaningful for compute shaders */
495b167d5e7Smrg      prog->MaxAttribs = 0; /* not meaningful for compute shaders */
496b167d5e7Smrg      prog->MaxAddressRegs = 0; /* not meaningful for compute shaders */
497b167d5e7Smrg      prog->MaxUniformComponents = 4 * MAX_UNIFORMS;
498b167d5e7Smrg      prog->MaxInputComponents = 0; /* not meaningful for compute shaders */
499b167d5e7Smrg      prog->MaxOutputComponents = 0; /* not meaningful for compute shaders */
5003464ebd5Sriastradh      break;
5013464ebd5Sriastradh   default:
502b167d5e7Smrg      assert(0 && "Bad shader stage in init_program_limits()");
5034a49301eSmrg   }
5044a49301eSmrg
5054a49301eSmrg   /* Set the native limits to zero.  This implies that there is no native
5064a49301eSmrg    * support for shaders.  Let the drivers fill in the actual values.
5074a49301eSmrg    */
5084a49301eSmrg   prog->MaxNativeInstructions = 0;
5094a49301eSmrg   prog->MaxNativeAluInstructions = 0;
5104a49301eSmrg   prog->MaxNativeTexInstructions = 0;
5114a49301eSmrg   prog->MaxNativeTexIndirections = 0;
5124a49301eSmrg   prog->MaxNativeAttribs = 0;
5134a49301eSmrg   prog->MaxNativeTemps = 0;
5144a49301eSmrg   prog->MaxNativeAddressRegs = 0;
5154a49301eSmrg   prog->MaxNativeParameters = 0;
5163464ebd5Sriastradh
5173464ebd5Sriastradh   /* Set GLSL datatype range/precision info assuming IEEE float values.
5183464ebd5Sriastradh    * Drivers should override these defaults as needed.
5193464ebd5Sriastradh    */
5203464ebd5Sriastradh   prog->MediumFloat.RangeMin = 127;
5213464ebd5Sriastradh   prog->MediumFloat.RangeMax = 127;
5223464ebd5Sriastradh   prog->MediumFloat.Precision = 23;
5233464ebd5Sriastradh   prog->LowFloat = prog->HighFloat = prog->MediumFloat;
5243464ebd5Sriastradh
5253464ebd5Sriastradh   /* Assume ints are stored as floats for now, since this is the least-common
5263464ebd5Sriastradh    * denominator.  The OpenGL ES spec implies (page 132) that the precision
5273464ebd5Sriastradh    * of integer types should be 0.  Practically speaking, IEEE
5283464ebd5Sriastradh    * single-precision floating point values can only store integers in the
5293464ebd5Sriastradh    * range [-0x01000000, 0x01000000] without loss of precision.
5303464ebd5Sriastradh    */
5313464ebd5Sriastradh   prog->MediumInt.RangeMin = 24;
5323464ebd5Sriastradh   prog->MediumInt.RangeMax = 24;
5333464ebd5Sriastradh   prog->MediumInt.Precision = 0;
5343464ebd5Sriastradh   prog->LowInt = prog->HighInt = prog->MediumInt;
535b167d5e7Smrg
536b167d5e7Smrg   prog->MaxUniformBlocks = 12;
537b167d5e7Smrg   prog->MaxCombinedUniformComponents = (prog->MaxUniformComponents +
538b167d5e7Smrg                                         consts->MaxUniformBlockSize / 4 *
539b167d5e7Smrg                                         prog->MaxUniformBlocks);
540b167d5e7Smrg
541b167d5e7Smrg   prog->MaxAtomicBuffers = 0;
542b167d5e7Smrg   prog->MaxAtomicCounters = 0;
5437e995a2eSmrg
5447e995a2eSmrg   prog->MaxShaderStorageBlocks = 8;
5457117f1b4Smrg}
5467117f1b4Smrg
5477117f1b4Smrg
5487117f1b4Smrg/**
5497117f1b4Smrg * Initialize fields of gl_constants (aka ctx->Const.*).
5507117f1b4Smrg * Use defaults from config.h.  The device drivers will often override
5517117f1b4Smrg * some of these values (such as number of texture units).
5527117f1b4Smrg */
553b167d5e7Smrgvoid
554b167d5e7Smrg_mesa_init_constants(struct gl_constants *consts, gl_api api)
5557117f1b4Smrg{
556b167d5e7Smrg   int i;
557b167d5e7Smrg   assert(consts);
5587117f1b4Smrg
5597117f1b4Smrg   /* Constants, may be overriden (usually only reduced) by device drivers */
560b167d5e7Smrg   consts->MaxTextureMbytes = MAX_TEXTURE_MBYTES;
561b167d5e7Smrg   consts->MaxTextureLevels = MAX_TEXTURE_LEVELS;
562b167d5e7Smrg   consts->Max3DTextureLevels = MAX_3D_TEXTURE_LEVELS;
563b167d5e7Smrg   consts->MaxCubeTextureLevels = MAX_CUBE_TEXTURE_LEVELS;
564b167d5e7Smrg   consts->MaxTextureRectSize = MAX_TEXTURE_RECT_SIZE;
565b167d5e7Smrg   consts->MaxArrayTextureLayers = MAX_ARRAY_TEXTURE_LAYERS;
566b167d5e7Smrg   consts->MaxTextureCoordUnits = MAX_TEXTURE_COORD_UNITS;
567b167d5e7Smrg   consts->Program[MESA_SHADER_FRAGMENT].MaxTextureImageUnits = MAX_TEXTURE_IMAGE_UNITS;
568b167d5e7Smrg   consts->MaxTextureUnits = MIN2(consts->MaxTextureCoordUnits,
569b167d5e7Smrg                                     consts->Program[MESA_SHADER_FRAGMENT].MaxTextureImageUnits);
570b167d5e7Smrg   consts->MaxTextureMaxAnisotropy = MAX_TEXTURE_MAX_ANISOTROPY;
571b167d5e7Smrg   consts->MaxTextureLodBias = MAX_TEXTURE_LOD_BIAS;
572b167d5e7Smrg   consts->MaxTextureBufferSize = 65536;
573b167d5e7Smrg   consts->TextureBufferOffsetAlignment = 1;
574b167d5e7Smrg   consts->MaxArrayLockSize = MAX_ARRAY_LOCK_SIZE;
575b167d5e7Smrg   consts->SubPixelBits = SUB_PIXEL_BITS;
576b167d5e7Smrg   consts->MinPointSize = MIN_POINT_SIZE;
577b167d5e7Smrg   consts->MaxPointSize = MAX_POINT_SIZE;
578b167d5e7Smrg   consts->MinPointSizeAA = MIN_POINT_SIZE;
579b167d5e7Smrg   consts->MaxPointSizeAA = MAX_POINT_SIZE;
580b167d5e7Smrg   consts->PointSizeGranularity = (GLfloat) POINT_SIZE_GRANULARITY;
581b167d5e7Smrg   consts->MinLineWidth = MIN_LINE_WIDTH;
582b167d5e7Smrg   consts->MaxLineWidth = MAX_LINE_WIDTH;
583b167d5e7Smrg   consts->MinLineWidthAA = MIN_LINE_WIDTH;
584b167d5e7Smrg   consts->MaxLineWidthAA = MAX_LINE_WIDTH;
585b167d5e7Smrg   consts->LineWidthGranularity = (GLfloat) LINE_WIDTH_GRANULARITY;
586b167d5e7Smrg   consts->MaxClipPlanes = 6;
587b167d5e7Smrg   consts->MaxLights = MAX_LIGHTS;
588b167d5e7Smrg   consts->MaxShininess = 128.0;
589b167d5e7Smrg   consts->MaxSpotExponent = 128.0;
5907e995a2eSmrg   consts->MaxViewportWidth = 16384;
5917e995a2eSmrg   consts->MaxViewportHeight = 16384;
592b167d5e7Smrg   consts->MinMapBufferAlignment = 64;
593b167d5e7Smrg
594b167d5e7Smrg   /* Driver must override these values if ARB_viewport_array is supported. */
595b167d5e7Smrg   consts->MaxViewports = 1;
596b167d5e7Smrg   consts->ViewportSubpixelBits = 0;
597b167d5e7Smrg   consts->ViewportBounds.Min = 0;
598b167d5e7Smrg   consts->ViewportBounds.Max = 0;
599b167d5e7Smrg
600b167d5e7Smrg   /** GL_ARB_uniform_buffer_object */
601b167d5e7Smrg   consts->MaxCombinedUniformBlocks = 36;
602b167d5e7Smrg   consts->MaxUniformBufferBindings = 36;
603b167d5e7Smrg   consts->MaxUniformBlockSize = 16384;
604b167d5e7Smrg   consts->UniformBufferOffsetAlignment = 1;
605b167d5e7Smrg
6067e995a2eSmrg   /** GL_ARB_shader_storage_buffer_object */
6077e995a2eSmrg   consts->MaxCombinedShaderStorageBlocks = 8;
6087e995a2eSmrg   consts->MaxShaderStorageBufferBindings = 8;
6097e995a2eSmrg   consts->MaxShaderStorageBlockSize = 128 * 1024 * 1024; /* 2^27 */
6107e995a2eSmrg   consts->ShaderStorageBufferOffsetAlignment = 256;
6117e995a2eSmrg
612b167d5e7Smrg   /* GL_ARB_explicit_uniform_location, GL_MAX_UNIFORM_LOCATIONS */
613b167d5e7Smrg   consts->MaxUserAssignableUniformLocations =
614b167d5e7Smrg      4 * MESA_SHADER_STAGES * MAX_UNIFORMS;
615b167d5e7Smrg
616b167d5e7Smrg   for (i = 0; i < MESA_SHADER_STAGES; i++)
617b167d5e7Smrg      init_program_limits(consts, i, &consts->Program[i]);
618b167d5e7Smrg
619b167d5e7Smrg   consts->MaxProgramMatrices = MAX_PROGRAM_MATRICES;
620b167d5e7Smrg   consts->MaxProgramMatrixStackDepth = MAX_PROGRAM_MATRIX_STACK_DEPTH;
621b167d5e7Smrg
622d8407755Smaya   /* Set the absolute minimum possible GLSL version.  API_OPENGL_CORE can
623d8407755Smaya    * mean an OpenGL 3.0 forward-compatible context, so that implies a minimum
624d8407755Smaya    * possible version of 1.30.  Otherwise, the minimum possible version 1.20.
625d8407755Smaya    * Since Mesa unconditionally advertises GL_ARB_shading_language_100 and
626d8407755Smaya    * GL_ARB_shader_objects, every driver has GLSL 1.20... even if they don't
627d8407755Smaya    * advertise any extensions to enable any shader stages (e.g.,
628d8407755Smaya    * GL_ARB_vertex_shader).
629d8407755Smaya    */
630d8407755Smaya   consts->GLSLVersion = api == API_OPENGL_CORE ? 130 : 120;
631d8407755Smaya   consts->GLSLVersionCompat = consts->GLSLVersion;
632d8407755Smaya
633b167d5e7Smrg   /* Assume that if GLSL 1.30+ (or GLSL ES 3.00+) is supported that
634b167d5e7Smrg    * gl_VertexID is implemented using a native hardware register with OpenGL
635b167d5e7Smrg    * semantics.
636b167d5e7Smrg    */
637b167d5e7Smrg   consts->VertexID_is_zero_based = false;
6387117f1b4Smrg
6397117f1b4Smrg   /* GL_ARB_draw_buffers */
640b167d5e7Smrg   consts->MaxDrawBuffers = MAX_DRAW_BUFFERS;
6417117f1b4Smrg
642b167d5e7Smrg   consts->MaxColorAttachments = MAX_COLOR_ATTACHMENTS;
643b167d5e7Smrg   consts->MaxRenderbufferSize = MAX_RENDERBUFFER_SIZE;
6447117f1b4Smrg
645b167d5e7Smrg   consts->Program[MESA_SHADER_VERTEX].MaxTextureImageUnits = MAX_TEXTURE_IMAGE_UNITS;
646b167d5e7Smrg   consts->MaxCombinedTextureImageUnits = MAX_COMBINED_TEXTURE_IMAGE_UNITS;
647b167d5e7Smrg   consts->MaxVarying = 16; /* old limit not to break tnl and swrast */
648b167d5e7Smrg   consts->Program[MESA_SHADER_GEOMETRY].MaxTextureImageUnits = MAX_TEXTURE_IMAGE_UNITS;
649b167d5e7Smrg   consts->MaxGeometryOutputVertices = MAX_GEOMETRY_OUTPUT_VERTICES;
650b167d5e7Smrg   consts->MaxGeometryTotalOutputComponents = MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS;
6517e995a2eSmrg   consts->MaxGeometryShaderInvocations = MAX_GEOMETRY_SHADER_INVOCATIONS;
6523464ebd5Sriastradh
6537e995a2eSmrg#ifdef DEBUG
6547e995a2eSmrg   consts->GenerateTemporaryNames = true;
6557e995a2eSmrg#else
6567e995a2eSmrg   consts->GenerateTemporaryNames = false;
6577e995a2eSmrg#endif
6587117f1b4Smrg
6594a49301eSmrg   /* GL_ARB_framebuffer_object */
660b167d5e7Smrg   consts->MaxSamples = 0;
6614a49301eSmrg
662b167d5e7Smrg   /* GLSL default if NativeIntegers == FALSE */
6637e995a2eSmrg   consts->UniformBooleanTrue = FLOAT_AS_UNION(1.0f).u;
6644a49301eSmrg
665b167d5e7Smrg   /* GL_ARB_sync */
6667e995a2eSmrg   consts->MaxServerWaitTimeout = 0x7fffffff7fffffffULL;
6674a49301eSmrg
6684a49301eSmrg   /* GL_EXT_provoking_vertex */
669b167d5e7Smrg   consts->QuadsFollowProvokingVertexConvention = GL_TRUE;
6703464ebd5Sriastradh
6717e995a2eSmrg   /** GL_ARB_viewport_array */
6727e995a2eSmrg   consts->LayerAndVPIndexProvokingVertex = GL_UNDEFINED_VERTEX;
6737e995a2eSmrg
6743464ebd5Sriastradh   /* GL_EXT_transform_feedback */
675b167d5e7Smrg   consts->MaxTransformFeedbackBuffers = MAX_FEEDBACK_BUFFERS;
676b167d5e7Smrg   consts->MaxTransformFeedbackSeparateComponents = 4 * MAX_FEEDBACK_ATTRIBS;
677b167d5e7Smrg   consts->MaxTransformFeedbackInterleavedComponents = 4 * MAX_FEEDBACK_ATTRIBS;
678b167d5e7Smrg   consts->MaxVertexStreams = 1;
6793464ebd5Sriastradh
680b167d5e7Smrg   /* GL 3.2  */
681b167d5e7Smrg   consts->ProfileMask = api == API_OPENGL_CORE
682b167d5e7Smrg                          ? GL_CONTEXT_CORE_PROFILE_BIT
683b167d5e7Smrg                          : GL_CONTEXT_COMPATIBILITY_PROFILE_BIT;
6843464ebd5Sriastradh
6857e995a2eSmrg   /* GL 4.4 */
6867e995a2eSmrg   consts->MaxVertexAttribStride = 2048;
6877e995a2eSmrg
6883464ebd5Sriastradh   /** GL_EXT_gpu_shader4 */
689b167d5e7Smrg   consts->MinProgramTexelOffset = -8;
690b167d5e7Smrg   consts->MaxProgramTexelOffset = 7;
691b167d5e7Smrg
692b167d5e7Smrg   /* GL_ARB_texture_gather */
693b167d5e7Smrg   consts->MinProgramTextureGatherOffset = -8;
694b167d5e7Smrg   consts->MaxProgramTextureGatherOffset = 7;
6953464ebd5Sriastradh
6963464ebd5Sriastradh   /* GL_ARB_robustness */
697b167d5e7Smrg   consts->ResetStrategy = GL_NO_RESET_NOTIFICATION_ARB;
698b167d5e7Smrg
6997e995a2eSmrg   /* GL_KHR_robustness */
7007e995a2eSmrg   consts->RobustAccess = GL_FALSE;
701b167d5e7Smrg
702b167d5e7Smrg   /* ES 3.0 or ARB_ES3_compatibility */
703b167d5e7Smrg   consts->MaxElementIndex = 0xffffffffu;
704b167d5e7Smrg
705b167d5e7Smrg   /* GL_ARB_texture_multisample */
706b167d5e7Smrg   consts->MaxColorTextureSamples = 1;
707b167d5e7Smrg   consts->MaxDepthTextureSamples = 1;
708b167d5e7Smrg   consts->MaxIntegerSamples = 1;
709b167d5e7Smrg
710b167d5e7Smrg   /* GL_ARB_shader_atomic_counters */
711b167d5e7Smrg   consts->MaxAtomicBufferBindings = MAX_COMBINED_ATOMIC_BUFFERS;
712b167d5e7Smrg   consts->MaxAtomicBufferSize = MAX_ATOMIC_COUNTERS * ATOMIC_COUNTER_SIZE;
713b167d5e7Smrg   consts->MaxCombinedAtomicBuffers = MAX_COMBINED_ATOMIC_BUFFERS;
714b167d5e7Smrg   consts->MaxCombinedAtomicCounters = MAX_ATOMIC_COUNTERS;
715b167d5e7Smrg
716b167d5e7Smrg   /* GL_ARB_vertex_attrib_binding */
717b167d5e7Smrg   consts->MaxVertexAttribRelativeOffset = 2047;
718b167d5e7Smrg   consts->MaxVertexAttribBindings = MAX_VERTEX_GENERIC_ATTRIBS;
719b167d5e7Smrg
720b167d5e7Smrg   /* GL_ARB_compute_shader */
721b167d5e7Smrg   consts->MaxComputeWorkGroupCount[0] = 65535;
722b167d5e7Smrg   consts->MaxComputeWorkGroupCount[1] = 65535;
723b167d5e7Smrg   consts->MaxComputeWorkGroupCount[2] = 65535;
724b167d5e7Smrg   consts->MaxComputeWorkGroupSize[0] = 1024;
725b167d5e7Smrg   consts->MaxComputeWorkGroupSize[1] = 1024;
726b167d5e7Smrg   consts->MaxComputeWorkGroupSize[2] = 64;
7277e995a2eSmrg   /* Enables compute support for GLES 3.1 if >= 128 */
7287e995a2eSmrg   consts->MaxComputeWorkGroupInvocations = 0;
729b167d5e7Smrg
730b167d5e7Smrg   /** GL_ARB_gpu_shader5 */
731b167d5e7Smrg   consts->MinFragmentInterpolationOffset = MIN_FRAGMENT_INTERPOLATION_OFFSET;
732b167d5e7Smrg   consts->MaxFragmentInterpolationOffset = MAX_FRAGMENT_INTERPOLATION_OFFSET;
7337e995a2eSmrg
7347e995a2eSmrg   /** GL_KHR_context_flush_control */
7357e995a2eSmrg   consts->ContextReleaseBehavior = GL_CONTEXT_RELEASE_BEHAVIOR_FLUSH;
7367e995a2eSmrg
7377e995a2eSmrg   /** GL_ARB_tessellation_shader */
7387e995a2eSmrg   consts->MaxTessGenLevel = MAX_TESS_GEN_LEVEL;
7397e995a2eSmrg   consts->MaxPatchVertices = MAX_PATCH_VERTICES;
7407e995a2eSmrg   consts->Program[MESA_SHADER_TESS_CTRL].MaxTextureImageUnits = MAX_TEXTURE_IMAGE_UNITS;
7417e995a2eSmrg   consts->Program[MESA_SHADER_TESS_EVAL].MaxTextureImageUnits = MAX_TEXTURE_IMAGE_UNITS;
7427e995a2eSmrg   consts->MaxTessPatchComponents = MAX_TESS_PATCH_COMPONENTS;
7437e995a2eSmrg   consts->MaxTessControlTotalOutputComponents = MAX_TESS_CONTROL_TOTAL_OUTPUT_COMPONENTS;
7447e995a2eSmrg   consts->PrimitiveRestartForPatches = false;
7457e995a2eSmrg
7467e995a2eSmrg   /** GL_ARB_compute_variable_group_size */
7477e995a2eSmrg   consts->MaxComputeVariableGroupSize[0] = 512;
7487e995a2eSmrg   consts->MaxComputeVariableGroupSize[1] = 512;
7497e995a2eSmrg   consts->MaxComputeVariableGroupSize[2] = 64;
7507e995a2eSmrg   consts->MaxComputeVariableGroupInvocations = 512;
7517e995a2eSmrg
7527e995a2eSmrg   /** GL_NV_conservative_raster */
7537e995a2eSmrg   consts->MaxSubpixelPrecisionBiasBits = 0;
7547e995a2eSmrg
7557e995a2eSmrg   /** GL_NV_conservative_raster_dilate */
7567e995a2eSmrg   consts->ConservativeRasterDilateRange[0] = 0.0;
7577e995a2eSmrg   consts->ConservativeRasterDilateRange[1] = 0.0;
7587e995a2eSmrg   consts->ConservativeRasterDilateGranularity = 0.0;
7597117f1b4Smrg}
7607117f1b4Smrg
7617117f1b4Smrg
7627117f1b4Smrg/**
7637117f1b4Smrg * Do some sanity checks on the limits/constants for the given context.
7647117f1b4Smrg * Only called the first time a context is bound.
7657117f1b4Smrg */
7667117f1b4Smrgstatic void
7673464ebd5Sriastradhcheck_context_limits(struct gl_context *ctx)
7687117f1b4Smrg{
7697e995a2eSmrg   (void) ctx;
7707e995a2eSmrg
771cdc920a0Smrg   /* check that we don't exceed the size of various bitfields */
772b167d5e7Smrg   assert(VARYING_SLOT_MAX <=
7737e995a2eSmrg          (8 * sizeof(ctx->VertexProgram._Current->info.outputs_written)));
774b167d5e7Smrg   assert(VARYING_SLOT_MAX <=
7757e995a2eSmrg          (8 * sizeof(ctx->FragmentProgram._Current->info.inputs_read)));
776cdc920a0Smrg
777cdc920a0Smrg   /* shader-related checks */
778b167d5e7Smrg   assert(ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxLocalParams <= MAX_PROGRAM_LOCAL_PARAMS);
779b167d5e7Smrg   assert(ctx->Const.Program[MESA_SHADER_VERTEX].MaxLocalParams <= MAX_PROGRAM_LOCAL_PARAMS);
780cdc920a0Smrg
781cdc920a0Smrg   /* Texture unit checks */
782b167d5e7Smrg   assert(ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxTextureImageUnits > 0);
783b167d5e7Smrg   assert(ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxTextureImageUnits <= MAX_TEXTURE_IMAGE_UNITS);
784cdc920a0Smrg   assert(ctx->Const.MaxTextureCoordUnits > 0);
7857117f1b4Smrg   assert(ctx->Const.MaxTextureCoordUnits <= MAX_TEXTURE_COORD_UNITS);
786cdc920a0Smrg   assert(ctx->Const.MaxTextureUnits > 0);
7877117f1b4Smrg   assert(ctx->Const.MaxTextureUnits <= MAX_TEXTURE_IMAGE_UNITS);
7887117f1b4Smrg   assert(ctx->Const.MaxTextureUnits <= MAX_TEXTURE_COORD_UNITS);
789b167d5e7Smrg   assert(ctx->Const.MaxTextureUnits == MIN2(ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxTextureImageUnits,
790cdc920a0Smrg                                             ctx->Const.MaxTextureCoordUnits));
791cdc920a0Smrg   assert(ctx->Const.MaxCombinedTextureImageUnits > 0);
792cdc920a0Smrg   assert(ctx->Const.MaxCombinedTextureImageUnits <= MAX_COMBINED_TEXTURE_IMAGE_UNITS);
793cdc920a0Smrg   assert(ctx->Const.MaxTextureCoordUnits <= MAX_COMBINED_TEXTURE_IMAGE_UNITS);
794c1f859d4Smrg   /* number of coord units cannot be greater than number of image units */
795b167d5e7Smrg   assert(ctx->Const.MaxTextureCoordUnits <= ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxTextureImageUnits);
796c1f859d4Smrg
797cdc920a0Smrg
798cdc920a0Smrg   /* Texture size checks */
7994a49301eSmrg   assert(ctx->Const.MaxTextureLevels <= MAX_TEXTURE_LEVELS);
8004a49301eSmrg   assert(ctx->Const.Max3DTextureLevels <= MAX_3D_TEXTURE_LEVELS);
8014a49301eSmrg   assert(ctx->Const.MaxCubeTextureLevels <= MAX_CUBE_TEXTURE_LEVELS);
8024a49301eSmrg   assert(ctx->Const.MaxTextureRectSize <= MAX_TEXTURE_RECT_SIZE);
8037117f1b4Smrg
804cdc920a0Smrg   /* Texture level checks */
805cdc920a0Smrg   assert(MAX_TEXTURE_LEVELS >= MAX_3D_TEXTURE_LEVELS);
806cdc920a0Smrg   assert(MAX_TEXTURE_LEVELS >= MAX_CUBE_TEXTURE_LEVELS);
807cdc920a0Smrg
808cdc920a0Smrg   /* Max texture size should be <= max viewport size (render to texture) */
809b167d5e7Smrg   assert((1U << (ctx->Const.MaxTextureLevels - 1))
810b167d5e7Smrg          <= ctx->Const.MaxViewportWidth);
811b167d5e7Smrg   assert((1U << (ctx->Const.MaxTextureLevels - 1))
812b167d5e7Smrg          <= ctx->Const.MaxViewportHeight);
8137117f1b4Smrg
8147117f1b4Smrg   assert(ctx->Const.MaxDrawBuffers <= MAX_DRAW_BUFFERS);
8157117f1b4Smrg
8163464ebd5Sriastradh   /* if this fails, add more enum values to gl_buffer_index */
8173464ebd5Sriastradh   assert(BUFFER_COLOR0 + MAX_DRAW_BUFFERS <= BUFFER_COUNT);
8183464ebd5Sriastradh
8197117f1b4Smrg   /* XXX probably add more tests */
8207117f1b4Smrg}
8217117f1b4Smrg
8227117f1b4Smrg
8237117f1b4Smrg/**
8247117f1b4Smrg * Initialize the attribute groups in a GL context.
8257117f1b4Smrg *
8267117f1b4Smrg * \param ctx GL context.
8277117f1b4Smrg *
8287117f1b4Smrg * Initializes all the attributes, calling the respective <tt>init*</tt>
8297117f1b4Smrg * functions for the more complex data structures.
8307117f1b4Smrg */
8317117f1b4Smrgstatic GLboolean
8323464ebd5Sriastradhinit_attrib_groups(struct gl_context *ctx)
8337117f1b4Smrg{
8347117f1b4Smrg   assert(ctx);
8357117f1b4Smrg
8367117f1b4Smrg   /* Constants */
837b167d5e7Smrg   _mesa_init_constants(&ctx->Const, ctx->API);
8387117f1b4Smrg
8397117f1b4Smrg   /* Extensions */
840b167d5e7Smrg   _mesa_init_extensions(&ctx->Extensions);
8417117f1b4Smrg
8427117f1b4Smrg   /* Attribute Groups */
8437117f1b4Smrg   _mesa_init_accum( ctx );
8447117f1b4Smrg   _mesa_init_attrib( ctx );
8457e995a2eSmrg   _mesa_init_bbox( ctx );
8467117f1b4Smrg   _mesa_init_buffer_objects( ctx );
8477117f1b4Smrg   _mesa_init_color( ctx );
8487e995a2eSmrg   _mesa_init_conservative_raster( ctx );
8497117f1b4Smrg   _mesa_init_current( ctx );
8507117f1b4Smrg   _mesa_init_depth( ctx );
8517117f1b4Smrg   _mesa_init_debug( ctx );
8527e995a2eSmrg   _mesa_init_debug_output( ctx );
8537117f1b4Smrg   _mesa_init_display_list( ctx );
8547117f1b4Smrg   _mesa_init_eval( ctx );
855c1f859d4Smrg   _mesa_init_fbobjects( ctx );
8567117f1b4Smrg   _mesa_init_feedback( ctx );
8577117f1b4Smrg   _mesa_init_fog( ctx );
8587117f1b4Smrg   _mesa_init_hint( ctx );
8597e995a2eSmrg   _mesa_init_image_units( ctx );
8607117f1b4Smrg   _mesa_init_line( ctx );
8617117f1b4Smrg   _mesa_init_lighting( ctx );
8627117f1b4Smrg   _mesa_init_matrix( ctx );
8637117f1b4Smrg   _mesa_init_multisample( ctx );
864b167d5e7Smrg   _mesa_init_performance_monitors( ctx );
8657e995a2eSmrg   _mesa_init_performance_queries( ctx );
866b167d5e7Smrg   _mesa_init_pipeline( ctx );
8677117f1b4Smrg   _mesa_init_pixel( ctx );
868c1f859d4Smrg   _mesa_init_pixelstore( ctx );
8697117f1b4Smrg   _mesa_init_point( ctx );
8707117f1b4Smrg   _mesa_init_polygon( ctx );
8717117f1b4Smrg   _mesa_init_program( ctx );
8724a49301eSmrg   _mesa_init_queryobj( ctx );
8734a49301eSmrg   _mesa_init_sync( ctx );
8747117f1b4Smrg   _mesa_init_rastpos( ctx );
8757117f1b4Smrg   _mesa_init_scissor( ctx );
8767117f1b4Smrg   _mesa_init_shader_state( ctx );
8777117f1b4Smrg   _mesa_init_stencil( ctx );
8787117f1b4Smrg   _mesa_init_transform( ctx );
8793464ebd5Sriastradh   _mesa_init_transform_feedback( ctx );
8807117f1b4Smrg   _mesa_init_varray( ctx );
8817117f1b4Smrg   _mesa_init_viewport( ctx );
8827e995a2eSmrg   _mesa_init_resident_handles( ctx );
8837117f1b4Smrg
8847117f1b4Smrg   if (!_mesa_init_texture( ctx ))
8857117f1b4Smrg      return GL_FALSE;
8867117f1b4Smrg
8877117f1b4Smrg   /* Miscellaneous */
8887e995a2eSmrg   ctx->TileRasterOrderIncreasingX = GL_TRUE;
8897e995a2eSmrg   ctx->TileRasterOrderIncreasingY = GL_TRUE;
8907117f1b4Smrg   ctx->NewState = _NEW_ALL;
891b167d5e7Smrg   ctx->NewDriverState = ~0;
892b167d5e7Smrg   ctx->ErrorValue = GL_NO_ERROR;
893b167d5e7Smrg   ctx->ShareGroupReset = false;
894b167d5e7Smrg   ctx->varying_vp_inputs = VERT_BIT_ALL;
8957117f1b4Smrg
8967117f1b4Smrg   return GL_TRUE;
8977117f1b4Smrg}
8987117f1b4Smrg
8997117f1b4Smrg
900c1f859d4Smrg/**
901c1f859d4Smrg * Update default objects in a GL context with respect to shared state.
902c1f859d4Smrg *
903c1f859d4Smrg * \param ctx GL context.
904c1f859d4Smrg *
905c1f859d4Smrg * Removes references to old default objects, (texture objects, program
906c1f859d4Smrg * objects, etc.) and changes to reference those from the current shared
907c1f859d4Smrg * state.
908c1f859d4Smrg */
909c1f859d4Smrgstatic GLboolean
9103464ebd5Sriastradhupdate_default_objects(struct gl_context *ctx)
911c1f859d4Smrg{
912c1f859d4Smrg   assert(ctx);
913c1f859d4Smrg
914c1f859d4Smrg   _mesa_update_default_objects_program(ctx);
915c1f859d4Smrg   _mesa_update_default_objects_texture(ctx);
916c1f859d4Smrg   _mesa_update_default_objects_buffer_objects(ctx);
917c1f859d4Smrg
918c1f859d4Smrg   return GL_TRUE;
919c1f859d4Smrg}
920c1f859d4Smrg
921c1f859d4Smrg
9227e995a2eSmrg/* XXX this is temporary and should be removed at some point in the
9237e995a2eSmrg * future when there's a reasonable expectation that the libGL library
9247e995a2eSmrg * contains the _glapi_new_nop_table() and _glapi_set_nop_handler()
9257e995a2eSmrg * functions which were added in Mesa 10.6.
9267e995a2eSmrg */
9277e995a2eSmrg#if !defined(_WIN32)
9287e995a2eSmrg/* Avoid libGL / driver ABI break */
9297e995a2eSmrg#define USE_GLAPI_NOP_FEATURES 0
9307e995a2eSmrg#else
9317e995a2eSmrg#define USE_GLAPI_NOP_FEATURES 1
9327e995a2eSmrg#endif
9337e995a2eSmrg
9347e995a2eSmrg
9357117f1b4Smrg/**
9367e995a2eSmrg * This function is called by the glapi no-op functions.  For each OpenGL
9377e995a2eSmrg * function/entrypoint there's a simple no-op function.  These "no-op"
9387e995a2eSmrg * functions call this function.
9397e995a2eSmrg *
9407e995a2eSmrg * If there's a current OpenGL context for the calling thread, we record a
9417e995a2eSmrg * GL_INVALID_OPERATION error.  This can happen either because the app's
9427e995a2eSmrg * calling an unsupported extension function, or calling an illegal function
9437e995a2eSmrg * (such as glClear between glBegin/glEnd).
9447e995a2eSmrg *
9457e995a2eSmrg * If there's no current OpenGL context for the calling thread, we can
9467e995a2eSmrg * print a message to stderr.
9477e995a2eSmrg *
9487e995a2eSmrg * \param name  the name of the OpenGL function
9497117f1b4Smrg */
9507e995a2eSmrg#if USE_GLAPI_NOP_FEATURES
9517e995a2eSmrgstatic void
9527e995a2eSmrgnop_handler(const char *name)
9537117f1b4Smrg{
954b167d5e7Smrg   GET_CURRENT_CONTEXT(ctx);
9557e995a2eSmrg   if (ctx) {
9567e995a2eSmrg      _mesa_error(ctx, GL_INVALID_OPERATION, "%s(invalid call)", name);
9577e995a2eSmrg   }
9587e995a2eSmrg#if defined(DEBUG)
9597e995a2eSmrg   else if (getenv("MESA_DEBUG") || getenv("LIBGL_DEBUG")) {
9607e995a2eSmrg      fprintf(stderr,
9617e995a2eSmrg              "GL User Error: gl%s called without a rendering context\n",
9627e995a2eSmrg              name);
9637e995a2eSmrg      fflush(stderr);
9647e995a2eSmrg   }
9657e995a2eSmrg#endif
9667117f1b4Smrg}
9677e995a2eSmrg#endif
9687117f1b4Smrg
9697117f1b4Smrg
9707117f1b4Smrg/**
971b167d5e7Smrg * Special no-op glFlush, see below.
972b167d5e7Smrg */
973b167d5e7Smrg#if defined(_WIN32)
974b167d5e7Smrgstatic void GLAPIENTRY
975b167d5e7Smrgnop_glFlush(void)
976b167d5e7Smrg{
9777e995a2eSmrg   /* don't record an error like we do in nop_handler() */
9787e995a2eSmrg}
9797e995a2eSmrg#endif
9807e995a2eSmrg
9817e995a2eSmrg
9827e995a2eSmrg#if !USE_GLAPI_NOP_FEATURES
9837e995a2eSmrgstatic int
9847e995a2eSmrggeneric_nop(void)
9857e995a2eSmrg{
9867e995a2eSmrg   GET_CURRENT_CONTEXT(ctx);
9877e995a2eSmrg   _mesa_error(ctx, GL_INVALID_OPERATION,
9887e995a2eSmrg               "unsupported function called "
9897e995a2eSmrg               "(unsupported extension or deprecated function?)");
9907e995a2eSmrg   return 0;
991b167d5e7Smrg}
992b167d5e7Smrg#endif
993b167d5e7Smrg
994b167d5e7Smrg
995b167d5e7Smrg/**
9967e995a2eSmrg * Create a new API dispatch table in which all entries point to the
9977e995a2eSmrg * generic_nop() function.  This will not work on Windows because of
9987e995a2eSmrg * the __stdcall convention which requires the callee to clean up the
9997e995a2eSmrg * call stack.  That's impossible with one generic no-op function.
10007117f1b4Smrg */
10013464ebd5Sriastradhstruct _glapi_table *
10027e995a2eSmrg_mesa_new_nop_table(unsigned numEntries)
10037117f1b4Smrg{
10043464ebd5Sriastradh   struct _glapi_table *table;
10053464ebd5Sriastradh
10067e995a2eSmrg#if !USE_GLAPI_NOP_FEATURES
1007b167d5e7Smrg   table = malloc(numEntries * sizeof(_glapi_proc));
10087117f1b4Smrg   if (table) {
10097117f1b4Smrg      _glapi_proc *entry = (_glapi_proc *) table;
10107e995a2eSmrg      unsigned i;
10117117f1b4Smrg      for (i = 0; i < numEntries; i++) {
10127e995a2eSmrg         entry[i] = (_glapi_proc) generic_nop;
10137117f1b4Smrg      }
10147e995a2eSmrg   }
10157e995a2eSmrg#else
10167e995a2eSmrg   table = _glapi_new_nop_table(numEntries);
10177e995a2eSmrg#endif
10187e995a2eSmrg   return table;
10197e995a2eSmrg}
10207e995a2eSmrg
10217e995a2eSmrg
10227e995a2eSmrg/**
10237e995a2eSmrg * Allocate and initialize a new dispatch table.  The table will be
10247e995a2eSmrg * populated with pointers to "no-op" functions.  In turn, the no-op
10257e995a2eSmrg * functions will call nop_handler() above.
10267e995a2eSmrg */
10277e995a2eSmrgstruct _glapi_table *
10287e995a2eSmrg_mesa_alloc_dispatch_table(void)
10297e995a2eSmrg{
10307e995a2eSmrg   /* Find the larger of Mesa's dispatch table and libGL's dispatch table.
10317e995a2eSmrg    * In practice, this'll be the same for stand-alone Mesa.  But for DRI
10327e995a2eSmrg    * Mesa we do this to accommodate different versions of libGL and various
10337e995a2eSmrg    * DRI drivers.
10347e995a2eSmrg    */
10357e995a2eSmrg   int numEntries = MAX2(_glapi_get_dispatch_table_size(), _gloffset_COUNT);
10367e995a2eSmrg
10377e995a2eSmrg   struct _glapi_table *table = _mesa_new_nop_table(numEntries);
1038b167d5e7Smrg
1039b167d5e7Smrg#if defined(_WIN32)
10407e995a2eSmrg   if (table) {
1041b167d5e7Smrg      /* This is a special case for Windows in the event that
1042b167d5e7Smrg       * wglGetProcAddress is called between glBegin/End().
1043b167d5e7Smrg       *
1044b167d5e7Smrg       * The MS opengl32.dll library apparently calls glFlush from
1045b167d5e7Smrg       * wglGetProcAddress().  If we're inside glBegin/End(), glFlush
1046b167d5e7Smrg       * will dispatch to _mesa_generic_nop() and we'll generate a
1047b167d5e7Smrg       * GL_INVALID_OPERATION error.
1048b167d5e7Smrg       *
1049b167d5e7Smrg       * The specific case which hits this is piglit's primitive-restart
1050b167d5e7Smrg       * test which calls glPrimitiveRestartNV() inside glBegin/End.  The
1051b167d5e7Smrg       * first time we call glPrimitiveRestartNV() Piglit's API dispatch
1052b167d5e7Smrg       * code will try to resolve the function by calling wglGetProcAddress.
1053b167d5e7Smrg       * This raises GL_INVALID_OPERATION and an assert(glGetError()==0)
1054b167d5e7Smrg       * will fail causing the test to fail.  By suppressing the error, the
1055b167d5e7Smrg       * assertion passes and the test continues.
1056b167d5e7Smrg       */
1057b167d5e7Smrg      SET_Flush(table, nop_glFlush);
10587117f1b4Smrg   }
10597e995a2eSmrg#endif
10607e995a2eSmrg
10617e995a2eSmrg#if USE_GLAPI_NOP_FEATURES
10627e995a2eSmrg   _glapi_set_nop_handler(nop_handler);
10637e995a2eSmrg#endif
10647e995a2eSmrg
10657117f1b4Smrg   return table;
10667117f1b4Smrg}
10677117f1b4Smrg
1068b167d5e7Smrg/**
1069b167d5e7Smrg * Creates a minimal dispatch table for use within glBegin()/glEnd().
1070b167d5e7Smrg *
1071b167d5e7Smrg * This ensures that we generate GL_INVALID_OPERATION errors from most
1072b167d5e7Smrg * functions, since the set of functions that are valid within Begin/End is
1073b167d5e7Smrg * very small.
1074b167d5e7Smrg *
1075b167d5e7Smrg * From the GL 1.0 specification section 2.6.3, "GL Commands within
1076b167d5e7Smrg * Begin/End"
1077b167d5e7Smrg *
1078b167d5e7Smrg *     "The only GL commands that are allowed within any Begin/End pairs are
1079b167d5e7Smrg *      the commands for specifying vertex coordinates, vertex color, normal
1080b167d5e7Smrg *      coordinates, and texture coordinates (Vertex, Color, Index, Normal,
1081b167d5e7Smrg *      TexCoord), EvalCoord and EvalPoint commands (see section 5.1),
1082b167d5e7Smrg *      commands for specifying lighting material parameters (Material
1083b167d5e7Smrg *      commands see section 2.12.2), display list invocation commands
1084b167d5e7Smrg *      (CallList and CallLists see section 5.4), and the EdgeFlag
1085b167d5e7Smrg *      command. Executing Begin after Begin has already been executed but
1086b167d5e7Smrg *      before an End is issued generates the INVALID OPERATION error, as does
1087b167d5e7Smrg *      executing End without a previous corresponding Begin. Executing any
1088b167d5e7Smrg *      other GL command within Begin/End results in the error INVALID
1089b167d5e7Smrg *      OPERATION."
1090b167d5e7Smrg *
1091b167d5e7Smrg * The table entries for specifying vertex attributes are set up by
1092b167d5e7Smrg * install_vtxfmt() and _mesa_loopback_init_api_table(), and End() and dlists
1093b167d5e7Smrg * are set by install_vtxfmt() as well.
1094b167d5e7Smrg */
1095b167d5e7Smrgstatic struct _glapi_table *
1096b167d5e7Smrgcreate_beginend_table(const struct gl_context *ctx)
1097b167d5e7Smrg{
1098b167d5e7Smrg   struct _glapi_table *table;
1099b167d5e7Smrg
1100b167d5e7Smrg   table = _mesa_alloc_dispatch_table();
1101b167d5e7Smrg   if (!table)
1102b167d5e7Smrg      return NULL;
1103b167d5e7Smrg
1104b167d5e7Smrg   /* Fill in functions which return a value, since they should return some
1105b167d5e7Smrg    * specific value even if they emit a GL_INVALID_OPERATION error from them
1106b167d5e7Smrg    * being called within glBegin()/glEnd().
1107b167d5e7Smrg    */
1108b167d5e7Smrg#define COPY_DISPATCH(func) SET_##func(table, GET_##func(ctx->Exec))
1109b167d5e7Smrg
1110b167d5e7Smrg   COPY_DISPATCH(GenLists);
1111b167d5e7Smrg   COPY_DISPATCH(IsProgram);
1112b167d5e7Smrg   COPY_DISPATCH(IsVertexArray);
1113b167d5e7Smrg   COPY_DISPATCH(IsBuffer);
1114b167d5e7Smrg   COPY_DISPATCH(IsEnabled);
1115b167d5e7Smrg   COPY_DISPATCH(IsEnabledi);
1116b167d5e7Smrg   COPY_DISPATCH(IsRenderbuffer);
1117b167d5e7Smrg   COPY_DISPATCH(IsFramebuffer);
1118b167d5e7Smrg   COPY_DISPATCH(CheckFramebufferStatus);
1119b167d5e7Smrg   COPY_DISPATCH(RenderMode);
1120b167d5e7Smrg   COPY_DISPATCH(GetString);
1121b167d5e7Smrg   COPY_DISPATCH(GetStringi);
1122b167d5e7Smrg   COPY_DISPATCH(GetPointerv);
1123b167d5e7Smrg   COPY_DISPATCH(IsQuery);
1124b167d5e7Smrg   COPY_DISPATCH(IsSampler);
1125b167d5e7Smrg   COPY_DISPATCH(IsSync);
1126b167d5e7Smrg   COPY_DISPATCH(IsTexture);
1127b167d5e7Smrg   COPY_DISPATCH(IsTransformFeedback);
1128b167d5e7Smrg   COPY_DISPATCH(DeleteQueries);
1129b167d5e7Smrg   COPY_DISPATCH(AreTexturesResident);
1130b167d5e7Smrg   COPY_DISPATCH(FenceSync);
1131b167d5e7Smrg   COPY_DISPATCH(ClientWaitSync);
1132b167d5e7Smrg   COPY_DISPATCH(MapBuffer);
1133b167d5e7Smrg   COPY_DISPATCH(UnmapBuffer);
1134b167d5e7Smrg   COPY_DISPATCH(MapBufferRange);
1135b167d5e7Smrg   COPY_DISPATCH(ObjectPurgeableAPPLE);
1136b167d5e7Smrg   COPY_DISPATCH(ObjectUnpurgeableAPPLE);
1137b167d5e7Smrg
1138b167d5e7Smrg   _mesa_loopback_init_api_table(ctx, table);
1139b167d5e7Smrg
1140b167d5e7Smrg   return table;
1141b167d5e7Smrg}
1142b167d5e7Smrg
1143b167d5e7Smrgvoid
1144b167d5e7Smrg_mesa_initialize_dispatch_tables(struct gl_context *ctx)
1145b167d5e7Smrg{
1146b167d5e7Smrg   /* Do the code-generated setup of the exec table in api_exec.c. */
1147b167d5e7Smrg   _mesa_initialize_exec_table(ctx);
1148b167d5e7Smrg
1149b167d5e7Smrg   if (ctx->Save)
1150b167d5e7Smrg      _mesa_initialize_save_table(ctx);
1151b167d5e7Smrg}
11527117f1b4Smrg
11537117f1b4Smrg/**
11543464ebd5Sriastradh * Initialize a struct gl_context struct (rendering context).
11557117f1b4Smrg *
11567117f1b4Smrg * This includes allocating all the other structs and arrays which hang off of
11577117f1b4Smrg * the context by pointers.
11587117f1b4Smrg * Note that the driver needs to pass in its dd_function_table here since
11597117f1b4Smrg * we need to at least call driverFunctions->NewTextureObject to create the
11607117f1b4Smrg * default texture objects.
11617e995a2eSmrg *
11627117f1b4Smrg * Called by _mesa_create_context().
11637117f1b4Smrg *
11647117f1b4Smrg * Performs the imports and exports callback tables initialization, and
11657117f1b4Smrg * miscellaneous one-time initializations. If no shared context is supplied one
11667117f1b4Smrg * is allocated, and increase its reference count.  Setups the GL API dispatch
11677117f1b4Smrg * tables.  Initialize the TNL module. Sets the maximum Z buffer depth.
11687117f1b4Smrg * Finally queries the \c MESA_DEBUG and \c MESA_VERBOSE environment variables
11697117f1b4Smrg * for debug flags.
11707117f1b4Smrg *
11717117f1b4Smrg * \param ctx the context to initialize
11723464ebd5Sriastradh * \param api the GL API type to create the context for
1173b167d5e7Smrg * \param visual describes the visual attributes for this context or NULL to
1174b167d5e7Smrg *               create a configless context
11757117f1b4Smrg * \param share_list points to context to share textures, display lists,
11767117f1b4Smrg *        etc with, or NULL
11777117f1b4Smrg * \param driverFunctions table of device driver functions for this context
11787117f1b4Smrg *        to use
11797117f1b4Smrg */
11807117f1b4SmrgGLboolean
11813464ebd5Sriastradh_mesa_initialize_context(struct gl_context *ctx,
11823464ebd5Sriastradh                         gl_api api,
11833464ebd5Sriastradh                         const struct gl_config *visual,
11843464ebd5Sriastradh                         struct gl_context *share_list,
1185b167d5e7Smrg                         const struct dd_function_table *driverFunctions)
11867117f1b4Smrg{
11874a49301eSmrg   struct gl_shared_state *shared;
11883464ebd5Sriastradh   int i;
11894a49301eSmrg
11907117f1b4Smrg   assert(driverFunctions->NewTextureObject);
1191b167d5e7Smrg   assert(driverFunctions->FreeTextureImageBuffer);
11927117f1b4Smrg
11933464ebd5Sriastradh   ctx->API = api;
11947117f1b4Smrg   ctx->DrawBuffer = NULL;
11957117f1b4Smrg   ctx->ReadBuffer = NULL;
11967117f1b4Smrg   ctx->WinSysDrawBuffer = NULL;
11977117f1b4Smrg   ctx->WinSysReadBuffer = NULL;
11987117f1b4Smrg
1199b167d5e7Smrg   if (visual) {
1200b167d5e7Smrg      ctx->Visual = *visual;
1201b167d5e7Smrg      ctx->HasConfig = GL_TRUE;
1202b167d5e7Smrg   }
1203b167d5e7Smrg   else {
1204b167d5e7Smrg      memset(&ctx->Visual, 0, sizeof ctx->Visual);
1205b167d5e7Smrg      ctx->HasConfig = GL_FALSE;
1206b167d5e7Smrg   }
1207b167d5e7Smrg
12087e995a2eSmrg   _mesa_override_gl_version(ctx);
1209b167d5e7Smrg
12103464ebd5Sriastradh   /* misc one-time initializations */
12113464ebd5Sriastradh   one_time_init(ctx);
12123464ebd5Sriastradh
1213d8407755Smaya   _mesa_init_shader_compiler_types();
1214d8407755Smaya
12157117f1b4Smrg   /* Plug in driver functions and context pointer here.
12167117f1b4Smrg    * This is important because when we call alloc_shared_state() below
12177117f1b4Smrg    * we'll call ctx->Driver.NewTextureObject() to create the default
12187117f1b4Smrg    * textures.
12197117f1b4Smrg    */
12207117f1b4Smrg   ctx->Driver = *driverFunctions;
12217117f1b4Smrg
12227117f1b4Smrg   if (share_list) {
12237117f1b4Smrg      /* share state with another context */
12244a49301eSmrg      shared = share_list->Shared;
12257117f1b4Smrg   }
12267117f1b4Smrg   else {
12277117f1b4Smrg      /* allocate new, unshared state */
12284a49301eSmrg      shared = _mesa_alloc_shared_state(ctx);
12294a49301eSmrg      if (!shared)
12307117f1b4Smrg         return GL_FALSE;
12317117f1b4Smrg   }
12324a49301eSmrg
1233b167d5e7Smrg   _mesa_reference_shared_state(ctx, &ctx->Shared, shared);
12347117f1b4Smrg
1235b167d5e7Smrg   if (!init_attrib_groups( ctx ))
1236b167d5e7Smrg      goto fail;
12373464ebd5Sriastradh
12387e995a2eSmrg   /* KHR_no_error is likely to crash, overflow memory, etc if an application
12397e995a2eSmrg    * has errors so don't enable it for setuid processes.
12407e995a2eSmrg    */
12417e995a2eSmrg   if (env_var_as_boolean("MESA_NO_ERROR", false)) {
12427e995a2eSmrg#if !defined(_WIN32)
12437e995a2eSmrg      if (geteuid() == getuid())
12447e995a2eSmrg#endif
12457e995a2eSmrg         ctx->Const.ContextFlags |= GL_CONTEXT_FLAG_NO_ERROR_BIT_KHR;
12467e995a2eSmrg   }
12477e995a2eSmrg
1248b167d5e7Smrg   /* setup the API dispatch tables with all nop functions */
1249b167d5e7Smrg   ctx->OutsideBeginEnd = _mesa_alloc_dispatch_table();
1250b167d5e7Smrg   if (!ctx->OutsideBeginEnd)
1251b167d5e7Smrg      goto fail;
1252b167d5e7Smrg   ctx->Exec = ctx->OutsideBeginEnd;
12537e995a2eSmrg   ctx->CurrentClientDispatch = ctx->CurrentServerDispatch = ctx->OutsideBeginEnd;
12544a49301eSmrg
12557117f1b4Smrg   ctx->FragmentProgram._MaintainTexEnvProgram
12567e995a2eSmrg      = (getenv("MESA_TEX_PROG") != NULL);
12577117f1b4Smrg
12587117f1b4Smrg   ctx->VertexProgram._MaintainTnlProgram
12597e995a2eSmrg      = (getenv("MESA_TNL_PROG") != NULL);
12607117f1b4Smrg   if (ctx->VertexProgram._MaintainTnlProgram) {
12617117f1b4Smrg      /* this is required... */
12627117f1b4Smrg      ctx->FragmentProgram._MaintainTexEnvProgram = GL_TRUE;
12637117f1b4Smrg   }
12647117f1b4Smrg
12653464ebd5Sriastradh   /* Mesa core handles all the formats that mesa core knows about.
12663464ebd5Sriastradh    * Drivers will want to override this list with just the formats
12673464ebd5Sriastradh    * they can handle, and confirm that appropriate fallbacks exist in
12683464ebd5Sriastradh    * _mesa_choose_tex_format().
12693464ebd5Sriastradh    */
12703464ebd5Sriastradh   memset(&ctx->TextureFormatSupported, GL_TRUE,
12717e995a2eSmrg          sizeof(ctx->TextureFormatSupported));
12723464ebd5Sriastradh
12733464ebd5Sriastradh   switch (ctx->API) {
1274b167d5e7Smrg   case API_OPENGL_COMPAT:
1275b167d5e7Smrg      ctx->BeginEnd = create_beginend_table(ctx);
1276b167d5e7Smrg      ctx->Save = _mesa_alloc_dispatch_table();
1277b167d5e7Smrg      if (!ctx->BeginEnd || !ctx->Save)
1278b167d5e7Smrg         goto fail;
1279b167d5e7Smrg
1280b167d5e7Smrg      /* fall-through */
1281b167d5e7Smrg   case API_OPENGL_CORE:
12823464ebd5Sriastradh      break;
12833464ebd5Sriastradh   case API_OPENGLES:
12843464ebd5Sriastradh      /**
12853464ebd5Sriastradh       * GL_OES_texture_cube_map says
12863464ebd5Sriastradh       * "Initially all texture generation modes are set to REFLECTION_MAP_OES"
12873464ebd5Sriastradh       */
12887e995a2eSmrg      for (i = 0; i < ARRAY_SIZE(ctx->Texture.FixedFuncUnit); i++) {
12897e995a2eSmrg         struct gl_fixedfunc_texture_unit *texUnit =
12907e995a2eSmrg            &ctx->Texture.FixedFuncUnit[i];
12917e995a2eSmrg
12927e995a2eSmrg         texUnit->GenS.Mode = GL_REFLECTION_MAP_NV;
12937e995a2eSmrg         texUnit->GenT.Mode = GL_REFLECTION_MAP_NV;
12947e995a2eSmrg         texUnit->GenR.Mode = GL_REFLECTION_MAP_NV;
12957e995a2eSmrg         texUnit->GenS._ModeBit = TEXGEN_REFLECTION_MAP_NV;
12967e995a2eSmrg         texUnit->GenT._ModeBit = TEXGEN_REFLECTION_MAP_NV;
12977e995a2eSmrg         texUnit->GenR._ModeBit = TEXGEN_REFLECTION_MAP_NV;
12983464ebd5Sriastradh      }
12993464ebd5Sriastradh      break;
13003464ebd5Sriastradh   case API_OPENGLES2:
13013464ebd5Sriastradh      ctx->FragmentProgram._MaintainTexEnvProgram = GL_TRUE;
13023464ebd5Sriastradh      ctx->VertexProgram._MaintainTnlProgram = GL_TRUE;
13033464ebd5Sriastradh      break;
13043464ebd5Sriastradh   }
1305c1f859d4Smrg
13067117f1b4Smrg   ctx->FirstTimeCurrent = GL_TRUE;
13077117f1b4Smrg
13087117f1b4Smrg   return GL_TRUE;
1309b167d5e7Smrg
1310b167d5e7Smrgfail:
1311b167d5e7Smrg   _mesa_reference_shared_state(ctx, &ctx->Shared, NULL);
1312b167d5e7Smrg   free(ctx->BeginEnd);
1313b167d5e7Smrg   free(ctx->OutsideBeginEnd);
1314b167d5e7Smrg   free(ctx->Save);
1315b167d5e7Smrg   return GL_FALSE;
13167117f1b4Smrg}
13177117f1b4Smrg
13187117f1b4Smrg
13197117f1b4Smrg/**
13207117f1b4Smrg * Free the data associated with the given context.
13217e995a2eSmrg *
13223464ebd5Sriastradh * But doesn't free the struct gl_context struct itself.
13237117f1b4Smrg *
13247117f1b4Smrg * \sa _mesa_initialize_context() and init_attrib_groups().
13257117f1b4Smrg */
13267117f1b4Smrgvoid
1327d8407755Smaya_mesa_free_context_data(struct gl_context *ctx, bool destroy_compiler_types)
13287117f1b4Smrg{
13297117f1b4Smrg   if (!_mesa_get_current_context()){
13307117f1b4Smrg      /* No current context, but we may need one in order to delete
13317117f1b4Smrg       * texture objs, etc.  So temporarily bind the context now.
13327117f1b4Smrg       */
13337117f1b4Smrg      _mesa_make_current(ctx, NULL, NULL);
13347117f1b4Smrg   }
13357117f1b4Smrg
13367117f1b4Smrg   /* unreference WinSysDraw/Read buffers */
13374a49301eSmrg   _mesa_reference_framebuffer(&ctx->WinSysDrawBuffer, NULL);
13384a49301eSmrg   _mesa_reference_framebuffer(&ctx->WinSysReadBuffer, NULL);
13394a49301eSmrg   _mesa_reference_framebuffer(&ctx->DrawBuffer, NULL);
13404a49301eSmrg   _mesa_reference_framebuffer(&ctx->ReadBuffer, NULL);
13417117f1b4Smrg
13427e995a2eSmrg   _mesa_reference_program(ctx, &ctx->VertexProgram.Current, NULL);
13437e995a2eSmrg   _mesa_reference_program(ctx, &ctx->VertexProgram._Current, NULL);
13447e995a2eSmrg   _mesa_reference_program(ctx, &ctx->VertexProgram._TnlProgram, NULL);
1345c1f859d4Smrg
13467e995a2eSmrg   _mesa_reference_program(ctx, &ctx->TessCtrlProgram._Current, NULL);
13477e995a2eSmrg   _mesa_reference_program(ctx, &ctx->TessEvalProgram._Current, NULL);
13487e995a2eSmrg   _mesa_reference_program(ctx, &ctx->GeometryProgram._Current, NULL);
1349b167d5e7Smrg
13507e995a2eSmrg   _mesa_reference_program(ctx, &ctx->FragmentProgram.Current, NULL);
13517e995a2eSmrg   _mesa_reference_program(ctx, &ctx->FragmentProgram._Current, NULL);
13527e995a2eSmrg   _mesa_reference_program(ctx, &ctx->FragmentProgram._TexEnvProgram, NULL);
13537e995a2eSmrg
13547e995a2eSmrg   _mesa_reference_program(ctx, &ctx->ComputeProgram._Current, NULL);
1355c1f859d4Smrg
1356b167d5e7Smrg   _mesa_reference_vao(ctx, &ctx->Array.VAO, NULL);
1357b167d5e7Smrg   _mesa_reference_vao(ctx, &ctx->Array.DefaultVAO, NULL);
13587e995a2eSmrg   _mesa_reference_vao(ctx, &ctx->Array._EmptyVAO, NULL);
13597e995a2eSmrg   _mesa_reference_vao(ctx, &ctx->Array._DrawVAO, NULL);
1360b167d5e7Smrg
13617117f1b4Smrg   _mesa_free_attrib_data(ctx);
13624a49301eSmrg   _mesa_free_buffer_objects(ctx);
13637117f1b4Smrg   _mesa_free_eval_data( ctx );
13647117f1b4Smrg   _mesa_free_texture_data( ctx );
1365d8407755Smaya   _mesa_free_image_textures(ctx);
13667117f1b4Smrg   _mesa_free_matrix_data( ctx );
1367b167d5e7Smrg   _mesa_free_pipeline_data(ctx);
13687117f1b4Smrg   _mesa_free_program_data(ctx);
13697117f1b4Smrg   _mesa_free_shader_state(ctx);
13704a49301eSmrg   _mesa_free_queryobj_data(ctx);
13714a49301eSmrg   _mesa_free_sync_data(ctx);
13724a49301eSmrg   _mesa_free_varray_data(ctx);
13733464ebd5Sriastradh   _mesa_free_transform_feedback(ctx);
1374b167d5e7Smrg   _mesa_free_performance_monitors(ctx);
13757e995a2eSmrg   _mesa_free_performance_queries(ctx);
13767e995a2eSmrg   _mesa_free_resident_handles(ctx);
13774a49301eSmrg
13784a49301eSmrg   _mesa_reference_buffer_object(ctx, &ctx->Pack.BufferObj, NULL);
13794a49301eSmrg   _mesa_reference_buffer_object(ctx, &ctx->Unpack.BufferObj, NULL);
13804a49301eSmrg   _mesa_reference_buffer_object(ctx, &ctx->DefaultPacking.BufferObj, NULL);
13814a49301eSmrg   _mesa_reference_buffer_object(ctx, &ctx->Array.ArrayBufferObj, NULL);
13827117f1b4Smrg
13837117f1b4Smrg   /* free dispatch tables */
1384b167d5e7Smrg   free(ctx->BeginEnd);
1385b167d5e7Smrg   free(ctx->OutsideBeginEnd);
1386cdc920a0Smrg   free(ctx->Save);
13877e995a2eSmrg   free(ctx->ContextLost);
13887e995a2eSmrg   free(ctx->MarshalExec);
13897117f1b4Smrg
13907117f1b4Smrg   /* Shared context state (display lists, textures, etc) */
1391b167d5e7Smrg   _mesa_reference_shared_state(ctx, &ctx->Shared, NULL);
13924a49301eSmrg
13934a49301eSmrg   /* needs to be after freeing shared state */
13944a49301eSmrg   _mesa_free_display_list_data(ctx);
13957117f1b4Smrg
1396b167d5e7Smrg   _mesa_free_errors_data(ctx);
1397cdc920a0Smrg
1398b167d5e7Smrg   free((void *)ctx->Extensions.String);
1399b167d5e7Smrg
1400b167d5e7Smrg   free(ctx->VersionString);
14017117f1b4Smrg
1402d8407755Smaya   if (destroy_compiler_types)
1403d8407755Smaya      _mesa_destroy_shader_compiler_types();
1404d8407755Smaya
14057117f1b4Smrg   /* unbind the context if it's currently bound */
14067117f1b4Smrg   if (ctx == _mesa_get_current_context()) {
14077117f1b4Smrg      _mesa_make_current(NULL, NULL, NULL);
14087117f1b4Smrg   }
14097117f1b4Smrg}
14107117f1b4Smrg
14117117f1b4Smrg
14127117f1b4Smrg/**
14133464ebd5Sriastradh * Destroy a struct gl_context structure.
14147117f1b4Smrg *
14157117f1b4Smrg * \param ctx GL context.
14167e995a2eSmrg *
14173464ebd5Sriastradh * Calls _mesa_free_context_data() and frees the gl_context object itself.
14187117f1b4Smrg */
14197117f1b4Smrgvoid
14203464ebd5Sriastradh_mesa_destroy_context( struct gl_context *ctx )
14217117f1b4Smrg{
14227117f1b4Smrg   if (ctx) {
1423d8407755Smaya      _mesa_free_context_data(ctx, true);
1424cdc920a0Smrg      free( (void *) ctx );
14257117f1b4Smrg   }
14267117f1b4Smrg}
14277117f1b4Smrg
14287117f1b4Smrg
14297117f1b4Smrg/**
14307117f1b4Smrg * Copy attribute groups from one context to another.
14317e995a2eSmrg *
14327117f1b4Smrg * \param src source context
14337117f1b4Smrg * \param dst destination context
14347117f1b4Smrg * \param mask bitwise OR of GL_*_BIT flags
14357117f1b4Smrg *
14367117f1b4Smrg * According to the bits specified in \p mask, copies the corresponding
14377117f1b4Smrg * attributes from \p src into \p dst.  For many of the attributes a simple \c
14387117f1b4Smrg * memcpy is not enough due to the existence of internal pointers in their data
14397117f1b4Smrg * structures.
14407117f1b4Smrg */
14417117f1b4Smrgvoid
14423464ebd5Sriastradh_mesa_copy_context( const struct gl_context *src, struct gl_context *dst,
14433464ebd5Sriastradh                    GLuint mask )
14447117f1b4Smrg{
14457117f1b4Smrg   if (mask & GL_ACCUM_BUFFER_BIT) {
14467117f1b4Smrg      /* OK to memcpy */
14477117f1b4Smrg      dst->Accum = src->Accum;
14487117f1b4Smrg   }
14497117f1b4Smrg   if (mask & GL_COLOR_BUFFER_BIT) {
14507117f1b4Smrg      /* OK to memcpy */
14517117f1b4Smrg      dst->Color = src->Color;
14527117f1b4Smrg   }
14537117f1b4Smrg   if (mask & GL_CURRENT_BIT) {
14547117f1b4Smrg      /* OK to memcpy */
14557117f1b4Smrg      dst->Current = src->Current;
14567117f1b4Smrg   }
14577117f1b4Smrg   if (mask & GL_DEPTH_BUFFER_BIT) {
14587117f1b4Smrg      /* OK to memcpy */
14597117f1b4Smrg      dst->Depth = src->Depth;
14607117f1b4Smrg   }
14617117f1b4Smrg   if (mask & GL_ENABLE_BIT) {
14627117f1b4Smrg      /* no op */
14637117f1b4Smrg   }
14647117f1b4Smrg   if (mask & GL_EVAL_BIT) {
14657117f1b4Smrg      /* OK to memcpy */
14667117f1b4Smrg      dst->Eval = src->Eval;
14677117f1b4Smrg   }
14687117f1b4Smrg   if (mask & GL_FOG_BIT) {
14697117f1b4Smrg      /* OK to memcpy */
14707117f1b4Smrg      dst->Fog = src->Fog;
14717117f1b4Smrg   }
14727117f1b4Smrg   if (mask & GL_HINT_BIT) {
14737117f1b4Smrg      /* OK to memcpy */
14747117f1b4Smrg      dst->Hint = src->Hint;
14757117f1b4Smrg   }
14767117f1b4Smrg   if (mask & GL_LIGHTING_BIT) {
14777e995a2eSmrg      /* OK to memcpy */
14787117f1b4Smrg      dst->Light = src->Light;
14797117f1b4Smrg   }
14807117f1b4Smrg   if (mask & GL_LINE_BIT) {
14817117f1b4Smrg      /* OK to memcpy */
14827117f1b4Smrg      dst->Line = src->Line;
14837117f1b4Smrg   }
14847117f1b4Smrg   if (mask & GL_LIST_BIT) {
14857117f1b4Smrg      /* OK to memcpy */
14867117f1b4Smrg      dst->List = src->List;
14877117f1b4Smrg   }
14887117f1b4Smrg   if (mask & GL_PIXEL_MODE_BIT) {
14897117f1b4Smrg      /* OK to memcpy */
14907117f1b4Smrg      dst->Pixel = src->Pixel;
14917117f1b4Smrg   }
14927117f1b4Smrg   if (mask & GL_POINT_BIT) {
14937117f1b4Smrg      /* OK to memcpy */
14947117f1b4Smrg      dst->Point = src->Point;
14957117f1b4Smrg   }
14967117f1b4Smrg   if (mask & GL_POLYGON_BIT) {
14977117f1b4Smrg      /* OK to memcpy */
14987117f1b4Smrg      dst->Polygon = src->Polygon;
14997117f1b4Smrg   }
15007117f1b4Smrg   if (mask & GL_POLYGON_STIPPLE_BIT) {
1501cdc920a0Smrg      /* Use loop instead of memcpy due to problem with Portland Group's
15027117f1b4Smrg       * C compiler.  Reported by John Stone.
15037117f1b4Smrg       */
15047117f1b4Smrg      GLuint i;
15057117f1b4Smrg      for (i = 0; i < 32; i++) {
15067117f1b4Smrg         dst->PolygonStipple[i] = src->PolygonStipple[i];
15077117f1b4Smrg      }
15087117f1b4Smrg   }
15097117f1b4Smrg   if (mask & GL_SCISSOR_BIT) {
15107117f1b4Smrg      /* OK to memcpy */
15117117f1b4Smrg      dst->Scissor = src->Scissor;
15127117f1b4Smrg   }
15137117f1b4Smrg   if (mask & GL_STENCIL_BUFFER_BIT) {
15147117f1b4Smrg      /* OK to memcpy */
15157117f1b4Smrg      dst->Stencil = src->Stencil;
15167117f1b4Smrg   }
15177117f1b4Smrg   if (mask & GL_TEXTURE_BIT) {
15187117f1b4Smrg      /* Cannot memcpy because of pointers */
15197117f1b4Smrg      _mesa_copy_texture_state(src, dst);
15207117f1b4Smrg   }
15217117f1b4Smrg   if (mask & GL_TRANSFORM_BIT) {
15227117f1b4Smrg      /* OK to memcpy */
15237117f1b4Smrg      dst->Transform = src->Transform;
15247117f1b4Smrg   }
15257117f1b4Smrg   if (mask & GL_VIEWPORT_BIT) {
1526b167d5e7Smrg      unsigned i;
1527b167d5e7Smrg      for (i = 0; i < src->Const.MaxViewports; i++) {
15287e995a2eSmrg         /* OK to memcpy */
15297e995a2eSmrg         dst->ViewportArray[i] = src->ViewportArray[i];
1530b167d5e7Smrg      }
15317117f1b4Smrg   }
15327117f1b4Smrg
15337117f1b4Smrg   /* XXX FIXME:  Call callbacks?
15347117f1b4Smrg    */
15357117f1b4Smrg   dst->NewState = _NEW_ALL;
1536b167d5e7Smrg   dst->NewDriverState = ~0;
15377117f1b4Smrg}
15387117f1b4Smrg
15397117f1b4Smrg
15407117f1b4Smrg/**
15417117f1b4Smrg * Check if the given context can render into the given framebuffer
15427117f1b4Smrg * by checking visual attributes.
15437117f1b4Smrg *
15447117f1b4Smrg * \return GL_TRUE if compatible, GL_FALSE otherwise.
15457117f1b4Smrg */
15467e995a2eSmrgstatic GLboolean
15473464ebd5Sriastradhcheck_compatible(const struct gl_context *ctx,
15483464ebd5Sriastradh                 const struct gl_framebuffer *buffer)
15497117f1b4Smrg{
15503464ebd5Sriastradh   const struct gl_config *ctxvis = &ctx->Visual;
15513464ebd5Sriastradh   const struct gl_config *bufvis = &buffer->Visual;
15527117f1b4Smrg
15533464ebd5Sriastradh   if (buffer == _mesa_get_incomplete_framebuffer())
15547117f1b4Smrg      return GL_TRUE;
15557117f1b4Smrg
15567e995a2eSmrg#define check_component(foo)           \
15577e995a2eSmrg   if (ctxvis->foo && bufvis->foo &&   \
15587e995a2eSmrg       ctxvis->foo != bufvis->foo)     \
15597e995a2eSmrg      return GL_FALSE
15607e995a2eSmrg
15617e995a2eSmrg   check_component(redMask);
15627e995a2eSmrg   check_component(greenMask);
15637e995a2eSmrg   check_component(blueMask);
15647e995a2eSmrg   check_component(depthBits);
15657e995a2eSmrg   check_component(stencilBits);
15667e995a2eSmrg
15677e995a2eSmrg#undef check_component
15687117f1b4Smrg
15697117f1b4Smrg   return GL_TRUE;
15707117f1b4Smrg}
15717117f1b4Smrg
15727117f1b4Smrg
1573c7037ccdSmrg/**
1574c7037ccdSmrg * Check if the viewport/scissor size has not yet been initialized.
1575c7037ccdSmrg * Initialize the size if the given width and height are non-zero.
1576c7037ccdSmrg */
15777e995a2eSmrgstatic void
15787e995a2eSmrgcheck_init_viewport(struct gl_context *ctx, GLuint width, GLuint height)
1579c7037ccdSmrg{
1580c7037ccdSmrg   if (!ctx->ViewportInitialized && width > 0 && height > 0) {
1581b167d5e7Smrg      unsigned i;
1582b167d5e7Smrg
1583c7037ccdSmrg      /* Note: set flag here, before calling _mesa_set_viewport(), to prevent
1584c7037ccdSmrg       * potential infinite recursion.
1585c7037ccdSmrg       */
1586c7037ccdSmrg      ctx->ViewportInitialized = GL_TRUE;
1587b167d5e7Smrg
1588b167d5e7Smrg      /* Note: ctx->Const.MaxViewports may not have been set by the driver
1589b167d5e7Smrg       * yet, so just initialize all of them.
1590b167d5e7Smrg       */
1591b167d5e7Smrg      for (i = 0; i < MAX_VIEWPORTS; i++) {
1592b167d5e7Smrg         _mesa_set_viewport(ctx, i, 0, 0, width, height);
1593b167d5e7Smrg         _mesa_set_scissor(ctx, i, 0, 0, width, height);
1594b167d5e7Smrg      }
1595c7037ccdSmrg   }
1596c7037ccdSmrg}
1597c7037ccdSmrg
15987e995a2eSmrg
1599b167d5e7Smrgstatic void
1600b167d5e7Smrghandle_first_current(struct gl_context *ctx)
1601b167d5e7Smrg{
16027e995a2eSmrg   if (ctx->Version == 0 || !ctx->DrawBuffer) {
16037e995a2eSmrg      /* probably in the process of tearing down the context */
16047e995a2eSmrg      return;
16057e995a2eSmrg   }
1606b167d5e7Smrg
1607b167d5e7Smrg   check_context_limits(ctx);
1608b167d5e7Smrg
16097e995a2eSmrg   _mesa_update_vertex_processing_mode(ctx);
16107e995a2eSmrg
1611b167d5e7Smrg   /* According to GL_MESA_configless_context the default value of
1612b167d5e7Smrg    * glDrawBuffers depends on the config of the first surface it is bound to.
16137e995a2eSmrg    * For GLES it is always GL_BACK which has a magic interpretation.
16147e995a2eSmrg    */
1615b167d5e7Smrg   if (!ctx->HasConfig && _mesa_is_desktop_gl(ctx)) {
1616b167d5e7Smrg      if (ctx->DrawBuffer != _mesa_get_incomplete_framebuffer()) {
16177e995a2eSmrg         GLenum16 buffer;
16187e995a2eSmrg
1619b167d5e7Smrg         if (ctx->DrawBuffer->Visual.doubleBufferMode)
1620b167d5e7Smrg            buffer = GL_BACK;
1621b167d5e7Smrg         else
1622b167d5e7Smrg            buffer = GL_FRONT;
1623b167d5e7Smrg
16247e995a2eSmrg         _mesa_drawbuffers(ctx, ctx->DrawBuffer, 1, &buffer,
16257e995a2eSmrg                           NULL /* destMask */);
1626b167d5e7Smrg      }
1627b167d5e7Smrg
1628b167d5e7Smrg      if (ctx->ReadBuffer != _mesa_get_incomplete_framebuffer()) {
16297e995a2eSmrg         gl_buffer_index bufferIndex;
16307e995a2eSmrg         GLenum buffer;
16317e995a2eSmrg
1632b167d5e7Smrg         if (ctx->ReadBuffer->Visual.doubleBufferMode) {
1633b167d5e7Smrg            buffer = GL_BACK;
1634b167d5e7Smrg            bufferIndex = BUFFER_BACK_LEFT;
1635b167d5e7Smrg         }
1636b167d5e7Smrg         else {
1637b167d5e7Smrg            buffer = GL_FRONT;
1638b167d5e7Smrg            bufferIndex = BUFFER_FRONT_LEFT;
1639b167d5e7Smrg         }
1640b167d5e7Smrg
16417e995a2eSmrg         _mesa_readbuffer(ctx, ctx->ReadBuffer, buffer, bufferIndex);
1642b167d5e7Smrg      }
1643b167d5e7Smrg   }
1644b167d5e7Smrg
16457e995a2eSmrg   /* Determine if generic vertex attribute 0 aliases the conventional
16467e995a2eSmrg    * glVertex position.
16477e995a2eSmrg    */
16487e995a2eSmrg   {
16497e995a2eSmrg      const bool is_forward_compatible_context =
16507e995a2eSmrg         ctx->Const.ContextFlags & GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT;
16517e995a2eSmrg
16527e995a2eSmrg      /* In OpenGL 3.1 attribute 0 becomes non-magic, just like in OpenGL ES
16537e995a2eSmrg       * 2.0.  Note that we cannot just check for API_OPENGL_COMPAT here because
16547e995a2eSmrg       * that will erroneously allow this usage in a 3.0 forward-compatible
16557e995a2eSmrg       * context too.
16567e995a2eSmrg       */
16577e995a2eSmrg      ctx->_AttribZeroAliasesVertex = (ctx->API == API_OPENGLES
16587e995a2eSmrg                                       || (ctx->API == API_OPENGL_COMPAT
16597e995a2eSmrg                                           && !is_forward_compatible_context));
16607e995a2eSmrg   }
16617e995a2eSmrg
1662b167d5e7Smrg   /* We can use this to help debug user's problems.  Tell them to set
1663b167d5e7Smrg    * the MESA_INFO env variable before running their app.  Then the
1664b167d5e7Smrg    * first time each context is made current we'll print some useful
1665b167d5e7Smrg    * information.
1666b167d5e7Smrg    */
16677e995a2eSmrg   if (getenv("MESA_INFO")) {
1668b167d5e7Smrg      _mesa_print_info(ctx);
1669b167d5e7Smrg   }
1670b167d5e7Smrg}
1671c7037ccdSmrg
16727117f1b4Smrg/**
16737117f1b4Smrg * Bind the given context to the given drawBuffer and readBuffer and
16747117f1b4Smrg * make it the current context for the calling thread.
16757117f1b4Smrg * We'll render into the drawBuffer and read pixels from the
16767117f1b4Smrg * readBuffer (i.e. glRead/CopyPixels, glCopyTexImage, etc).
16777117f1b4Smrg *
16787117f1b4Smrg * We check that the context's and framebuffer's visuals are compatible
16797117f1b4Smrg * and return immediately if they're not.
16807117f1b4Smrg *
16817117f1b4Smrg * \param newCtx  the new GL context. If NULL then there will be no current GL
16827117f1b4Smrg *                context.
16837117f1b4Smrg * \param drawBuffer  the drawing framebuffer
16847117f1b4Smrg * \param readBuffer  the reading framebuffer
16857117f1b4Smrg */
16864a49301eSmrgGLboolean
16873464ebd5Sriastradh_mesa_make_current( struct gl_context *newCtx,
16883464ebd5Sriastradh                    struct gl_framebuffer *drawBuffer,
16893464ebd5Sriastradh                    struct gl_framebuffer *readBuffer )
16907117f1b4Smrg{
16913464ebd5Sriastradh   GET_CURRENT_CONTEXT(curCtx);
16923464ebd5Sriastradh
16937117f1b4Smrg   if (MESA_VERBOSE & VERBOSE_API)
16947117f1b4Smrg      _mesa_debug(newCtx, "_mesa_make_current()\n");
16957117f1b4Smrg
16967117f1b4Smrg   /* Check that the context's and framebuffer's visuals are compatible.
16977117f1b4Smrg    */
16987117f1b4Smrg   if (newCtx && drawBuffer && newCtx->WinSysDrawBuffer != drawBuffer) {
16997117f1b4Smrg      if (!check_compatible(newCtx, drawBuffer)) {
17007117f1b4Smrg         _mesa_warning(newCtx,
17017117f1b4Smrg              "MakeCurrent: incompatible visuals for context and drawbuffer");
17024a49301eSmrg         return GL_FALSE;
17037117f1b4Smrg      }
17047117f1b4Smrg   }
17057117f1b4Smrg   if (newCtx && readBuffer && newCtx->WinSysReadBuffer != readBuffer) {
17067117f1b4Smrg      if (!check_compatible(newCtx, readBuffer)) {
17077117f1b4Smrg         _mesa_warning(newCtx,
17087117f1b4Smrg              "MakeCurrent: incompatible visuals for context and readbuffer");
17094a49301eSmrg         return GL_FALSE;
17107117f1b4Smrg      }
17117117f1b4Smrg   }
17127117f1b4Smrg
17137e995a2eSmrg   if (curCtx &&
17147e995a2eSmrg       (curCtx->WinSysDrawBuffer || curCtx->WinSysReadBuffer) &&
17153464ebd5Sriastradh       /* make sure this context is valid for flushing */
17167e995a2eSmrg       curCtx != newCtx &&
17177e995a2eSmrg       curCtx->Const.ContextReleaseBehavior ==
17187e995a2eSmrg       GL_CONTEXT_RELEASE_BEHAVIOR_FLUSH) {
17193464ebd5Sriastradh      _mesa_flush(curCtx);
17207e995a2eSmrg   }
17213464ebd5Sriastradh
17227e995a2eSmrg   /* Call this periodically to detect when the user has begun using
17237e995a2eSmrg    * GL rendering from multiple threads.
17247e995a2eSmrg    */
17257e995a2eSmrg   _glapi_check_multithread();
17267117f1b4Smrg
17277117f1b4Smrg   if (!newCtx) {
17287117f1b4Smrg      _glapi_set_dispatch(NULL);  /* none current */
17297e995a2eSmrg      /* We need old ctx to correctly release Draw/ReadBuffer
17307e995a2eSmrg       * and avoid a surface leak in st_renderbuffer_delete.
17317e995a2eSmrg       * Therefore, first drop buffers then set new ctx to NULL.
17327e995a2eSmrg       */
17337e995a2eSmrg      if (curCtx) {
17347e995a2eSmrg         _mesa_reference_framebuffer(&curCtx->WinSysDrawBuffer, NULL);
17357e995a2eSmrg         _mesa_reference_framebuffer(&curCtx->WinSysReadBuffer, NULL);
17367e995a2eSmrg      }
17377e995a2eSmrg      _glapi_set_context(NULL);
17387e995a2eSmrg      assert(_mesa_get_current_context() == NULL);
17397117f1b4Smrg   }
17407117f1b4Smrg   else {
17417e995a2eSmrg      _glapi_set_context((void *) newCtx);
17427e995a2eSmrg      assert(_mesa_get_current_context() == newCtx);
17437e995a2eSmrg      _glapi_set_dispatch(newCtx->CurrentClientDispatch);
17447117f1b4Smrg
17457117f1b4Smrg      if (drawBuffer && readBuffer) {
17467e995a2eSmrg         assert(_mesa_is_winsys_fbo(drawBuffer));
17477e995a2eSmrg         assert(_mesa_is_winsys_fbo(readBuffer));
17487117f1b4Smrg         _mesa_reference_framebuffer(&newCtx->WinSysDrawBuffer, drawBuffer);
17497117f1b4Smrg         _mesa_reference_framebuffer(&newCtx->WinSysReadBuffer, readBuffer);
17507117f1b4Smrg
17517117f1b4Smrg         /*
17527117f1b4Smrg          * Only set the context's Draw/ReadBuffer fields if they're NULL
17537117f1b4Smrg          * or not bound to a user-created FBO.
17547117f1b4Smrg          */
1755b167d5e7Smrg         if (!newCtx->DrawBuffer || _mesa_is_winsys_fbo(newCtx->DrawBuffer)) {
17567117f1b4Smrg            _mesa_reference_framebuffer(&newCtx->DrawBuffer, drawBuffer);
17573464ebd5Sriastradh            /* Update the FBO's list of drawbuffers/renderbuffers.
17583464ebd5Sriastradh             * For winsys FBOs this comes from the GL state (which may have
17593464ebd5Sriastradh             * changed since the last time this FBO was bound).
17603464ebd5Sriastradh             */
17613464ebd5Sriastradh            _mesa_update_draw_buffers(newCtx);
17627117f1b4Smrg         }
1763b167d5e7Smrg         if (!newCtx->ReadBuffer || _mesa_is_winsys_fbo(newCtx->ReadBuffer)) {
17647117f1b4Smrg            _mesa_reference_framebuffer(&newCtx->ReadBuffer, readBuffer);
17657e995a2eSmrg            /* In _mesa_initialize_window_framebuffer, for single-buffered
17667e995a2eSmrg             * visuals, the ColorReadBuffer is set to be GL_FRONT, even with
17677e995a2eSmrg             * GLES contexts. When calling read_buffer, we verify we are reading
17687e995a2eSmrg             * from GL_BACK in is_legal_es3_readbuffer_enum.  But the default is
17697e995a2eSmrg             * incorrect, and certain dEQP tests check this.  So fix it here.
17707e995a2eSmrg             */
17717e995a2eSmrg            if (_mesa_is_gles(newCtx) &&
17727e995a2eSmrg               !newCtx->ReadBuffer->Visual.doubleBufferMode)
17737e995a2eSmrg               if (newCtx->ReadBuffer->ColorReadBuffer == GL_FRONT)
17747e995a2eSmrg                  newCtx->ReadBuffer->ColorReadBuffer = GL_BACK;
17757117f1b4Smrg         }
17767117f1b4Smrg
1777c1f859d4Smrg         /* XXX only set this flag if we're really changing the draw/read
1778c1f859d4Smrg          * framebuffer bindings.
1779c1f859d4Smrg          */
17807e995a2eSmrg         newCtx->NewState |= _NEW_BUFFERS;
17817117f1b4Smrg
17827e995a2eSmrg         check_init_viewport(newCtx, drawBuffer->Width, drawBuffer->Height);
17837117f1b4Smrg      }
17847117f1b4Smrg
17857117f1b4Smrg      if (newCtx->FirstTimeCurrent) {
1786b167d5e7Smrg         handle_first_current(newCtx);
17877e995a2eSmrg         newCtx->FirstTimeCurrent = GL_FALSE;
17887117f1b4Smrg      }
17897117f1b4Smrg   }
17907e995a2eSmrg
17914a49301eSmrg   return GL_TRUE;
17927117f1b4Smrg}
17937117f1b4Smrg
17947117f1b4Smrg
17957117f1b4Smrg/**
17967117f1b4Smrg * Make context 'ctx' share the display lists, textures and programs
17977117f1b4Smrg * that are associated with 'ctxToShare'.
17987117f1b4Smrg * Any display lists, textures or programs associated with 'ctx' will
17997117f1b4Smrg * be deleted if nobody else is sharing them.
18007117f1b4Smrg */
18017117f1b4SmrgGLboolean
18023464ebd5Sriastradh_mesa_share_state(struct gl_context *ctx, struct gl_context *ctxToShare)
18037117f1b4Smrg{
18047117f1b4Smrg   if (ctx && ctxToShare && ctx->Shared && ctxToShare->Shared) {
1805b167d5e7Smrg      struct gl_shared_state *oldShared = NULL;
1806b167d5e7Smrg
1807b167d5e7Smrg      /* save ref to old state to prevent it from being deleted immediately */
1808b167d5e7Smrg      _mesa_reference_shared_state(ctx, &oldShared, ctx->Shared);
1809c1f859d4Smrg
1810b167d5e7Smrg      /* update ctx's Shared pointer */
1811b167d5e7Smrg      _mesa_reference_shared_state(ctx, &ctx->Shared, ctxToShare->Shared);
1812c1f859d4Smrg
1813c1f859d4Smrg      update_default_objects(ctx);
1814c1f859d4Smrg
1815b167d5e7Smrg      /* release the old shared state */
1816b167d5e7Smrg      _mesa_reference_shared_state(ctx, &oldShared, NULL);
1817c1f859d4Smrg
18187117f1b4Smrg      return GL_TRUE;
18197117f1b4Smrg   }
18207117f1b4Smrg   else {
18217117f1b4Smrg      return GL_FALSE;
18227117f1b4Smrg   }
18237117f1b4Smrg}
18247117f1b4Smrg
18257117f1b4Smrg
18267117f1b4Smrg
18277117f1b4Smrg/**
18287117f1b4Smrg * \return pointer to the current GL context for this thread.
18297e995a2eSmrg *
18307117f1b4Smrg * Calls _glapi_get_context(). This isn't the fastest way to get the current
18317117f1b4Smrg * context.  If you need speed, see the #GET_CURRENT_CONTEXT macro in
18327117f1b4Smrg * context.h.
18337117f1b4Smrg */
18343464ebd5Sriastradhstruct gl_context *
18357117f1b4Smrg_mesa_get_current_context( void )
18367117f1b4Smrg{
18373464ebd5Sriastradh   return (struct gl_context *) _glapi_get_context();
18387117f1b4Smrg}
18397117f1b4Smrg
18407117f1b4Smrg
18417117f1b4Smrg/**
18427117f1b4Smrg * Get context's current API dispatch table.
18437117f1b4Smrg *
18447e995a2eSmrg * It'll either be the immediate-mode execute dispatcher, the display list
18457e995a2eSmrg * compile dispatcher, or the thread marshalling dispatcher.
18467e995a2eSmrg *
18477117f1b4Smrg * \param ctx GL context.
18487117f1b4Smrg *
18497117f1b4Smrg * \return pointer to dispatch_table.
18507117f1b4Smrg *
18517e995a2eSmrg * Simply returns __struct gl_contextRec::CurrentClientDispatch.
18527117f1b4Smrg */
18537117f1b4Smrgstruct _glapi_table *
18543464ebd5Sriastradh_mesa_get_dispatch(struct gl_context *ctx)
18557117f1b4Smrg{
18567e995a2eSmrg   return ctx->CurrentClientDispatch;
18577117f1b4Smrg}
18587117f1b4Smrg
18597117f1b4Smrg/*@}*/
18607117f1b4Smrg
18617117f1b4Smrg
18627117f1b4Smrg/**********************************************************************/
18637117f1b4Smrg/** \name Miscellaneous functions                                     */
18647117f1b4Smrg/**********************************************************************/
18657117f1b4Smrg/*@{*/
18664a49301eSmrg/**
18674a49301eSmrg * Flush commands.
18684a49301eSmrg */
18694a49301eSmrgvoid
18703464ebd5Sriastradh_mesa_flush(struct gl_context *ctx)
18714a49301eSmrg{
1872b167d5e7Smrg   FLUSH_VERTICES( ctx, 0 );
18734a49301eSmrg   FLUSH_CURRENT( ctx, 0 );
18744a49301eSmrg   if (ctx->Driver.Flush) {
18754a49301eSmrg      ctx->Driver.Flush(ctx);
18764a49301eSmrg   }
18774a49301eSmrg}
18784a49301eSmrg
18794a49301eSmrg
18804a49301eSmrg
18817117f1b4Smrg/**
18827e995a2eSmrg * Flush commands and wait for completion.
18837117f1b4Smrg *
18847117f1b4Smrg * Calls the #ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH macro and the
18857117f1b4Smrg * dd_function_table::Finish driver callback, if not NULL.
18867117f1b4Smrg */
18877117f1b4Smrgvoid GLAPIENTRY
18887117f1b4Smrg_mesa_Finish(void)
18897117f1b4Smrg{
18907117f1b4Smrg   GET_CURRENT_CONTEXT(ctx);
1891b167d5e7Smrg   ASSERT_OUTSIDE_BEGIN_END(ctx);
18927e995a2eSmrg
18937e995a2eSmrg   FLUSH_VERTICES(ctx, 0);
18947e995a2eSmrg   FLUSH_CURRENT(ctx, 0);
18957e995a2eSmrg
18967e995a2eSmrg   if (ctx->Driver.Finish) {
18977e995a2eSmrg      ctx->Driver.Finish(ctx);
18987e995a2eSmrg   }
18997117f1b4Smrg}
19007117f1b4Smrg
19017117f1b4Smrg
19027117f1b4Smrg/**
19037117f1b4Smrg * Execute glFlush().
19047117f1b4Smrg *
19057117f1b4Smrg * Calls the #ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH macro and the
19067117f1b4Smrg * dd_function_table::Flush driver callback, if not NULL.
19077117f1b4Smrg */
19087117f1b4Smrgvoid GLAPIENTRY
19097117f1b4Smrg_mesa_Flush(void)
19107117f1b4Smrg{
19117117f1b4Smrg   GET_CURRENT_CONTEXT(ctx);
1912b167d5e7Smrg   ASSERT_OUTSIDE_BEGIN_END(ctx);
19134a49301eSmrg   _mesa_flush(ctx);
19144a49301eSmrg}
19154a49301eSmrg
19164a49301eSmrg
19177117f1b4Smrg/*@}*/
1918