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"
801463c08dSmrg
817117f1b4Smrg#include "accum.h"
82c1f859d4Smrg#include "api_exec.h"
837117f1b4Smrg#include "arrayobj.h"
847117f1b4Smrg#include "attrib.h"
857e995a2eSmrg#include "bbox.h"
867117f1b4Smrg#include "blend.h"
877117f1b4Smrg#include "buffers.h"
887117f1b4Smrg#include "bufferobj.h"
897e995a2eSmrg#include "conservativeraster.h"
907117f1b4Smrg#include "context.h"
914a49301eSmrg#include "cpuinfo.h"
927117f1b4Smrg#include "debug.h"
937e995a2eSmrg#include "debug_output.h"
947117f1b4Smrg#include "depth.h"
957117f1b4Smrg#include "dlist.h"
961463c08dSmrg#include "draw_validate.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"
1521463c08dSmrg#include "compiler/glsl/builtin_functions.h"
1537e995a2eSmrg#include "compiler/glsl/glsl_parser_extras.h"
1543464ebd5Sriastradh#include <stdbool.h>
1551463c08dSmrg#include "util/u_memory.h"
1563464ebd5Sriastradh
1573464ebd5Sriastradh
1587117f1b4Smrg#ifndef MESA_VERBOSE
1597117f1b4Smrgint MESA_VERBOSE = 0;
1607117f1b4Smrg#endif
1617117f1b4Smrg
1627117f1b4Smrg#ifndef MESA_DEBUG_FLAGS
1637117f1b4Smrgint MESA_DEBUG_FLAGS = 0;
1647117f1b4Smrg#endif
1657117f1b4Smrg
1667117f1b4Smrg
1677117f1b4Smrg/* ubyte -> float conversion */
1687117f1b4SmrgGLfloat _mesa_ubyte_to_float_color_tab[256];
1697117f1b4Smrg
1707117f1b4Smrg
1717117f1b4Smrg/**********************************************************************/
1721463c08dSmrg/** \name GL Visual initialization                                    */
1737117f1b4Smrg/**********************************************************************/
1747117f1b4Smrg/*@{*/
1757117f1b4Smrg
1761463c08dSmrg
1777117f1b4Smrg/**
1781463c08dSmrg * Makes some sanity checks and fills in the fields of the struct
1791463c08dSmrg * gl_config object with the given parameters.  If the caller needs to
1801463c08dSmrg * set additional fields, he should just probably init the whole
1811463c08dSmrg * gl_config object himself.
1827e995a2eSmrg *
1837117f1b4Smrg * \param dbFlag double buffering
1847117f1b4Smrg * \param stereoFlag stereo buffer
1857117f1b4Smrg * \param depthBits requested bits per depth buffer value. Any value in [0, 32]
1867117f1b4Smrg * is acceptable but the actual depth type will be GLushort or GLuint as
1877117f1b4Smrg * needed.
1887117f1b4Smrg * \param stencilBits requested minimum bits per stencil buffer value
1893464ebd5Sriastradh * \param accumRedBits, accumGreenBits, accumBlueBits, accumAlphaBits number
1903464ebd5Sriastradh * of bits per color component in accum buffer.
1917117f1b4Smrg * \param redBits number of bits per color component in frame buffer for RGB(A)
1927117f1b4Smrg * mode.  We always use 8 in core Mesa though.
1937117f1b4Smrg * \param greenBits same as above.
1947117f1b4Smrg * \param blueBits same as above.
1957117f1b4Smrg * \param alphaBits same as above.
1961463c08dSmrg * \param numSamples number of samples per pixel.
1977e995a2eSmrg *
1983464ebd5Sriastradh * \return pointer to new struct gl_config or NULL if requested parameters
1993464ebd5Sriastradh * can't be met.
2007117f1b4Smrg *
2017117f1b4Smrg * \return GL_TRUE on success, or GL_FALSE on failure.
2027117f1b4Smrg */
2031463c08dSmrgvoid
2043464ebd5Sriastradh_mesa_initialize_visual( struct gl_config *vis,
2057117f1b4Smrg                         GLboolean dbFlag,
2067117f1b4Smrg                         GLboolean stereoFlag,
2077117f1b4Smrg                         GLint redBits,
2087117f1b4Smrg                         GLint greenBits,
2097117f1b4Smrg                         GLint blueBits,
2107117f1b4Smrg                         GLint alphaBits,
2117117f1b4Smrg                         GLint depthBits,
2127117f1b4Smrg                         GLint stencilBits,
2137117f1b4Smrg                         GLint accumRedBits,
2147117f1b4Smrg                         GLint accumGreenBits,
2157117f1b4Smrg                         GLint accumBlueBits,
2167117f1b4Smrg                         GLint accumAlphaBits,
2177e995a2eSmrg                         GLuint numSamples )
2187117f1b4Smrg{
2197117f1b4Smrg   assert(vis);
2207117f1b4Smrg
2217117f1b4Smrg   vis->doubleBufferMode = dbFlag;
2227117f1b4Smrg   vis->stereoMode       = stereoFlag;
2237117f1b4Smrg
2247117f1b4Smrg   vis->redBits          = redBits;
2257117f1b4Smrg   vis->greenBits        = greenBits;
2267117f1b4Smrg   vis->blueBits         = blueBits;
2277117f1b4Smrg   vis->alphaBits        = alphaBits;
2281463c08dSmrg   vis->rgbBits          = redBits + greenBits + blueBits + alphaBits;
2297117f1b4Smrg
2307117f1b4Smrg   vis->depthBits      = depthBits;
2317117f1b4Smrg   vis->stencilBits    = stencilBits;
2327117f1b4Smrg
2337117f1b4Smrg   vis->accumRedBits   = accumRedBits;
2347117f1b4Smrg   vis->accumGreenBits = accumGreenBits;
2357117f1b4Smrg   vis->accumBlueBits  = accumBlueBits;
2367117f1b4Smrg   vis->accumAlphaBits = accumAlphaBits;
2377117f1b4Smrg
2387117f1b4Smrg   vis->samples = numSamples;
2397117f1b4Smrg}
2407117f1b4Smrg
2417117f1b4Smrg
2427117f1b4Smrg/*@}*/
2437117f1b4Smrg
2447117f1b4Smrg
2457117f1b4Smrg/**********************************************************************/
2467117f1b4Smrg/** \name Context allocation, initialization, destroying
2477117f1b4Smrg *
2487117f1b4Smrg * The purpose of the most initialization functions here is to provide the
2497117f1b4Smrg * default state values according to the OpenGL specification.
2507117f1b4Smrg */
2517117f1b4Smrg/**********************************************************************/
2527117f1b4Smrg/*@{*/
2537117f1b4Smrg
2544a49301eSmrg
2557e995a2eSmrg/**
2567e995a2eSmrg * Calls all the various one-time-fini functions in Mesa
2577e995a2eSmrg */
2587e995a2eSmrg
2597e995a2eSmrgstatic GLbitfield api_init_mask = 0x0;
2607e995a2eSmrgstatic void __attribute__((__destructor__))
2617e995a2eSmrgone_time_fini(void)
2627e995a2eSmrg{
2637e995a2eSmrg   if (api_init_mask) {
2641463c08dSmrg      glsl_type_singleton_decref();
2657e995a2eSmrg      _mesa_locale_fini();
2667e995a2eSmrg   }
2677e995a2eSmrg}
2683464ebd5Sriastradh
2697117f1b4Smrg/**
2701463c08dSmrg * Calls all the various one-time-init functions in Mesa
2717117f1b4Smrg */
2721463c08dSmrg
2737117f1b4Smrgstatic void
2741463c08dSmrgone_time_init(void)
2757117f1b4Smrg{
2761463c08dSmrg   GLuint i;
2773464ebd5Sriastradh
2781463c08dSmrg   STATIC_ASSERT(sizeof(GLbyte) == 1);
2791463c08dSmrg   STATIC_ASSERT(sizeof(GLubyte) == 1);
2801463c08dSmrg   STATIC_ASSERT(sizeof(GLshort) == 2);
2811463c08dSmrg   STATIC_ASSERT(sizeof(GLushort) == 2);
2821463c08dSmrg   STATIC_ASSERT(sizeof(GLint) == 4);
2831463c08dSmrg   STATIC_ASSERT(sizeof(GLuint) == 4);
2847e995a2eSmrg
2851463c08dSmrg   _mesa_locale_init();
2867117f1b4Smrg
2871463c08dSmrg   _mesa_one_time_init_extension_overrides();
288d8407755Smaya
2891463c08dSmrg   _mesa_get_cpu_features();
2907117f1b4Smrg
2911463c08dSmrg   for (i = 0; i < 256; i++) {
2921463c08dSmrg      _mesa_ubyte_to_float_color_tab[i] = (float) i / 255.0F;
2931463c08dSmrg   }
2943464ebd5Sriastradh
2951463c08dSmrg   atexit(one_time_fini);
2967117f1b4Smrg
2977e995a2eSmrg#if defined(DEBUG)
2981463c08dSmrg   if (MESA_VERBOSE != 0) {
2991463c08dSmrg      _mesa_debug(NULL, "Mesa " PACKAGE_VERSION " DEBUG build" MESA_GIT_SHA1 "\n");
3007117f1b4Smrg   }
3011463c08dSmrg#endif
3023464ebd5Sriastradh
3031463c08dSmrg   /* Take a glsl type reference for the duration of libGL's life to avoid
3041463c08dSmrg    * unecessary creation/destruction of glsl types.
3051463c08dSmrg    */
3061463c08dSmrg   glsl_type_singleton_init_or_ref();
3071463c08dSmrg
3081463c08dSmrg   _mesa_init_remap_table();
3091463c08dSmrg}
3101463c08dSmrg
3111463c08dSmrg/**
3121463c08dSmrg * One-time initialization flag
3131463c08dSmrg *
3141463c08dSmrg * \sa Used by _mesa_initialize().
3151463c08dSmrg */
3161463c08dSmrgstatic once_flag init_once = ONCE_FLAG_INIT;
3173464ebd5Sriastradh
3183464ebd5Sriastradh
3191463c08dSmrg/**
3201463c08dSmrg * Calls all the various one-time-init functions in Mesa.
3211463c08dSmrg *
3221463c08dSmrg * While holding a global mutex lock, calls several initialization functions,
3231463c08dSmrg * and sets the glapi callbacks if the \c MESA_DEBUG environment variable is
3241463c08dSmrg * defined.
3251463c08dSmrg *
3261463c08dSmrg * \sa _math_init().
3271463c08dSmrg */
3281463c08dSmrgvoid
3291463c08dSmrg_mesa_initialize(void)
3301463c08dSmrg{
3311463c08dSmrg   call_once(&init_once, one_time_init);
332eabf4f72Sriastradh}
333eabf4f72Sriastradh
3347117f1b4Smrg
3357117f1b4Smrg/**
3367117f1b4Smrg * Initialize fields of gl_current_attrib (aka ctx->Current.*)
3377117f1b4Smrg */
3387117f1b4Smrgstatic void
3393464ebd5Sriastradh_mesa_init_current(struct gl_context *ctx)
3407117f1b4Smrg{
3417117f1b4Smrg   GLuint i;
3427117f1b4Smrg
3437117f1b4Smrg   /* Init all to (0,0,0,1) */
3447e995a2eSmrg   for (i = 0; i < ARRAY_SIZE(ctx->Current.Attrib); i++) {
3457117f1b4Smrg      ASSIGN_4V( ctx->Current.Attrib[i], 0.0, 0.0, 0.0, 1.0 );
3467117f1b4Smrg   }
3477117f1b4Smrg
3487117f1b4Smrg   /* redo special cases: */
3497117f1b4Smrg   ASSIGN_4V( ctx->Current.Attrib[VERT_ATTRIB_NORMAL], 0.0, 0.0, 1.0, 1.0 );
3507117f1b4Smrg   ASSIGN_4V( ctx->Current.Attrib[VERT_ATTRIB_COLOR0], 1.0, 1.0, 1.0, 1.0 );
3517117f1b4Smrg   ASSIGN_4V( ctx->Current.Attrib[VERT_ATTRIB_COLOR1], 0.0, 0.0, 0.0, 1.0 );
3527117f1b4Smrg   ASSIGN_4V( ctx->Current.Attrib[VERT_ATTRIB_COLOR_INDEX], 1.0, 0.0, 0.0, 1.0 );
3537117f1b4Smrg   ASSIGN_4V( ctx->Current.Attrib[VERT_ATTRIB_EDGEFLAG], 1.0, 0.0, 0.0, 1.0 );
3547117f1b4Smrg}
3557117f1b4Smrg
3567117f1b4Smrg
3577117f1b4Smrg/**
3583464ebd5Sriastradh * Init vertex/fragment/geometry program limits.
3594a49301eSmrg * Important: drivers should override these with actual limits.
3607117f1b4Smrg */
3617117f1b4Smrgstatic void
362b167d5e7Smrginit_program_limits(struct gl_constants *consts, gl_shader_stage stage,
363b167d5e7Smrg                    struct gl_program_constants *prog)
3647117f1b4Smrg{
3654a49301eSmrg   prog->MaxInstructions = MAX_PROGRAM_INSTRUCTIONS;
3664a49301eSmrg   prog->MaxAluInstructions = MAX_PROGRAM_INSTRUCTIONS;
3674a49301eSmrg   prog->MaxTexInstructions = MAX_PROGRAM_INSTRUCTIONS;
3684a49301eSmrg   prog->MaxTexIndirections = MAX_PROGRAM_INSTRUCTIONS;
3694a49301eSmrg   prog->MaxTemps = MAX_PROGRAM_TEMPS;
3704a49301eSmrg   prog->MaxEnvParams = MAX_PROGRAM_ENV_PARAMS;
3714a49301eSmrg   prog->MaxLocalParams = MAX_PROGRAM_LOCAL_PARAMS;
3723464ebd5Sriastradh   prog->MaxAddressOffset = MAX_PROGRAM_LOCAL_PARAMS;
3734a49301eSmrg
374b167d5e7Smrg   switch (stage) {
375b167d5e7Smrg   case MESA_SHADER_VERTEX:
3764a49301eSmrg      prog->MaxParameters = MAX_VERTEX_PROGRAM_PARAMS;
377b167d5e7Smrg      prog->MaxAttribs = MAX_VERTEX_GENERIC_ATTRIBS;
3784a49301eSmrg      prog->MaxAddressRegs = MAX_VERTEX_PROGRAM_ADDRESS_REGS;
3793464ebd5Sriastradh      prog->MaxUniformComponents = 4 * MAX_UNIFORMS;
380b167d5e7Smrg      prog->MaxInputComponents = 0; /* value not used */
381b167d5e7Smrg      prog->MaxOutputComponents = 16 * 4; /* old limit not to break tnl and swrast */
3823464ebd5Sriastradh      break;
383b167d5e7Smrg   case MESA_SHADER_FRAGMENT:
3847e995a2eSmrg      prog->MaxParameters = MAX_FRAGMENT_PROGRAM_PARAMS;
3857e995a2eSmrg      prog->MaxAttribs = MAX_FRAGMENT_PROGRAM_INPUTS;
3864a49301eSmrg      prog->MaxAddressRegs = MAX_FRAGMENT_PROGRAM_ADDRESS_REGS;
3873464ebd5Sriastradh      prog->MaxUniformComponents = 4 * MAX_UNIFORMS;
388b167d5e7Smrg      prog->MaxInputComponents = 16 * 4; /* old limit not to break tnl and swrast */
389b167d5e7Smrg      prog->MaxOutputComponents = 0; /* value not used */
3903464ebd5Sriastradh      break;
3917e995a2eSmrg   case MESA_SHADER_TESS_CTRL:
3927e995a2eSmrg   case MESA_SHADER_TESS_EVAL:
393b167d5e7Smrg   case MESA_SHADER_GEOMETRY:
394b167d5e7Smrg      prog->MaxParameters = MAX_VERTEX_PROGRAM_PARAMS;
395b167d5e7Smrg      prog->MaxAttribs = MAX_VERTEX_GENERIC_ATTRIBS;
3963464ebd5Sriastradh      prog->MaxAddressRegs = MAX_VERTEX_PROGRAM_ADDRESS_REGS;
397b167d5e7Smrg      prog->MaxUniformComponents = 4 * MAX_UNIFORMS;
398b167d5e7Smrg      prog->MaxInputComponents = 16 * 4; /* old limit not to break tnl and swrast */
399b167d5e7Smrg      prog->MaxOutputComponents = 16 * 4; /* old limit not to break tnl and swrast */
400b167d5e7Smrg      break;
401b167d5e7Smrg   case MESA_SHADER_COMPUTE:
402b167d5e7Smrg      prog->MaxParameters = 0; /* not meaningful for compute shaders */
403b167d5e7Smrg      prog->MaxAttribs = 0; /* not meaningful for compute shaders */
404b167d5e7Smrg      prog->MaxAddressRegs = 0; /* not meaningful for compute shaders */
405b167d5e7Smrg      prog->MaxUniformComponents = 4 * MAX_UNIFORMS;
406b167d5e7Smrg      prog->MaxInputComponents = 0; /* not meaningful for compute shaders */
407b167d5e7Smrg      prog->MaxOutputComponents = 0; /* not meaningful for compute shaders */
4083464ebd5Sriastradh      break;
4093464ebd5Sriastradh   default:
410b167d5e7Smrg      assert(0 && "Bad shader stage in init_program_limits()");
4114a49301eSmrg   }
4124a49301eSmrg
4134a49301eSmrg   /* Set the native limits to zero.  This implies that there is no native
4144a49301eSmrg    * support for shaders.  Let the drivers fill in the actual values.
4154a49301eSmrg    */
4164a49301eSmrg   prog->MaxNativeInstructions = 0;
4174a49301eSmrg   prog->MaxNativeAluInstructions = 0;
4184a49301eSmrg   prog->MaxNativeTexInstructions = 0;
4194a49301eSmrg   prog->MaxNativeTexIndirections = 0;
4204a49301eSmrg   prog->MaxNativeAttribs = 0;
4214a49301eSmrg   prog->MaxNativeTemps = 0;
4224a49301eSmrg   prog->MaxNativeAddressRegs = 0;
4234a49301eSmrg   prog->MaxNativeParameters = 0;
4243464ebd5Sriastradh
4253464ebd5Sriastradh   /* Set GLSL datatype range/precision info assuming IEEE float values.
4263464ebd5Sriastradh    * Drivers should override these defaults as needed.
4273464ebd5Sriastradh    */
4283464ebd5Sriastradh   prog->MediumFloat.RangeMin = 127;
4293464ebd5Sriastradh   prog->MediumFloat.RangeMax = 127;
4303464ebd5Sriastradh   prog->MediumFloat.Precision = 23;
4313464ebd5Sriastradh   prog->LowFloat = prog->HighFloat = prog->MediumFloat;
4323464ebd5Sriastradh
4333464ebd5Sriastradh   /* Assume ints are stored as floats for now, since this is the least-common
4343464ebd5Sriastradh    * denominator.  The OpenGL ES spec implies (page 132) that the precision
4353464ebd5Sriastradh    * of integer types should be 0.  Practically speaking, IEEE
4363464ebd5Sriastradh    * single-precision floating point values can only store integers in the
4373464ebd5Sriastradh    * range [-0x01000000, 0x01000000] without loss of precision.
4383464ebd5Sriastradh    */
4393464ebd5Sriastradh   prog->MediumInt.RangeMin = 24;
4403464ebd5Sriastradh   prog->MediumInt.RangeMax = 24;
4413464ebd5Sriastradh   prog->MediumInt.Precision = 0;
4423464ebd5Sriastradh   prog->LowInt = prog->HighInt = prog->MediumInt;
443b167d5e7Smrg
444b167d5e7Smrg   prog->MaxUniformBlocks = 12;
445b167d5e7Smrg   prog->MaxCombinedUniformComponents = (prog->MaxUniformComponents +
446b167d5e7Smrg                                         consts->MaxUniformBlockSize / 4 *
447b167d5e7Smrg                                         prog->MaxUniformBlocks);
448b167d5e7Smrg
449b167d5e7Smrg   prog->MaxAtomicBuffers = 0;
450b167d5e7Smrg   prog->MaxAtomicCounters = 0;
4517e995a2eSmrg
4527e995a2eSmrg   prog->MaxShaderStorageBlocks = 8;
4537117f1b4Smrg}
4547117f1b4Smrg
4557117f1b4Smrg
4567117f1b4Smrg/**
4577117f1b4Smrg * Initialize fields of gl_constants (aka ctx->Const.*).
4587117f1b4Smrg * Use defaults from config.h.  The device drivers will often override
4597117f1b4Smrg * some of these values (such as number of texture units).
4607117f1b4Smrg */
461b167d5e7Smrgvoid
462b167d5e7Smrg_mesa_init_constants(struct gl_constants *consts, gl_api api)
4637117f1b4Smrg{
464b167d5e7Smrg   int i;
465b167d5e7Smrg   assert(consts);
4667117f1b4Smrg
4677117f1b4Smrg   /* Constants, may be overriden (usually only reduced) by device drivers */
468b167d5e7Smrg   consts->MaxTextureMbytes = MAX_TEXTURE_MBYTES;
4691463c08dSmrg   consts->MaxTextureSize = 1 << (MAX_TEXTURE_LEVELS - 1);
4701463c08dSmrg   consts->Max3DTextureLevels = MAX_TEXTURE_LEVELS;
4711463c08dSmrg   consts->MaxCubeTextureLevels = MAX_TEXTURE_LEVELS;
472b167d5e7Smrg   consts->MaxTextureRectSize = MAX_TEXTURE_RECT_SIZE;
473b167d5e7Smrg   consts->MaxArrayTextureLayers = MAX_ARRAY_TEXTURE_LAYERS;
474b167d5e7Smrg   consts->MaxTextureCoordUnits = MAX_TEXTURE_COORD_UNITS;
475b167d5e7Smrg   consts->Program[MESA_SHADER_FRAGMENT].MaxTextureImageUnits = MAX_TEXTURE_IMAGE_UNITS;
476b167d5e7Smrg   consts->MaxTextureUnits = MIN2(consts->MaxTextureCoordUnits,
477b167d5e7Smrg                                     consts->Program[MESA_SHADER_FRAGMENT].MaxTextureImageUnits);
478b167d5e7Smrg   consts->MaxTextureMaxAnisotropy = MAX_TEXTURE_MAX_ANISOTROPY;
479b167d5e7Smrg   consts->MaxTextureLodBias = MAX_TEXTURE_LOD_BIAS;
480b167d5e7Smrg   consts->MaxTextureBufferSize = 65536;
481b167d5e7Smrg   consts->TextureBufferOffsetAlignment = 1;
482b167d5e7Smrg   consts->MaxArrayLockSize = MAX_ARRAY_LOCK_SIZE;
483b167d5e7Smrg   consts->SubPixelBits = SUB_PIXEL_BITS;
484b167d5e7Smrg   consts->MinPointSize = MIN_POINT_SIZE;
485b167d5e7Smrg   consts->MaxPointSize = MAX_POINT_SIZE;
486b167d5e7Smrg   consts->MinPointSizeAA = MIN_POINT_SIZE;
487b167d5e7Smrg   consts->MaxPointSizeAA = MAX_POINT_SIZE;
488b167d5e7Smrg   consts->PointSizeGranularity = (GLfloat) POINT_SIZE_GRANULARITY;
489b167d5e7Smrg   consts->MinLineWidth = MIN_LINE_WIDTH;
490b167d5e7Smrg   consts->MaxLineWidth = MAX_LINE_WIDTH;
491b167d5e7Smrg   consts->MinLineWidthAA = MIN_LINE_WIDTH;
492b167d5e7Smrg   consts->MaxLineWidthAA = MAX_LINE_WIDTH;
493b167d5e7Smrg   consts->LineWidthGranularity = (GLfloat) LINE_WIDTH_GRANULARITY;
494b167d5e7Smrg   consts->MaxClipPlanes = 6;
495b167d5e7Smrg   consts->MaxLights = MAX_LIGHTS;
496b167d5e7Smrg   consts->MaxShininess = 128.0;
497b167d5e7Smrg   consts->MaxSpotExponent = 128.0;
4987e995a2eSmrg   consts->MaxViewportWidth = 16384;
4997e995a2eSmrg   consts->MaxViewportHeight = 16384;
500b167d5e7Smrg   consts->MinMapBufferAlignment = 64;
501b167d5e7Smrg
502b167d5e7Smrg   /* Driver must override these values if ARB_viewport_array is supported. */
503b167d5e7Smrg   consts->MaxViewports = 1;
504b167d5e7Smrg   consts->ViewportSubpixelBits = 0;
505b167d5e7Smrg   consts->ViewportBounds.Min = 0;
506b167d5e7Smrg   consts->ViewportBounds.Max = 0;
507b167d5e7Smrg
508b167d5e7Smrg   /** GL_ARB_uniform_buffer_object */
509b167d5e7Smrg   consts->MaxCombinedUniformBlocks = 36;
510b167d5e7Smrg   consts->MaxUniformBufferBindings = 36;
511b167d5e7Smrg   consts->MaxUniformBlockSize = 16384;
512b167d5e7Smrg   consts->UniformBufferOffsetAlignment = 1;
513b167d5e7Smrg
5147e995a2eSmrg   /** GL_ARB_shader_storage_buffer_object */
5157e995a2eSmrg   consts->MaxCombinedShaderStorageBlocks = 8;
5167e995a2eSmrg   consts->MaxShaderStorageBufferBindings = 8;
5177e995a2eSmrg   consts->MaxShaderStorageBlockSize = 128 * 1024 * 1024; /* 2^27 */
5187e995a2eSmrg   consts->ShaderStorageBufferOffsetAlignment = 256;
5197e995a2eSmrg
520b167d5e7Smrg   /* GL_ARB_explicit_uniform_location, GL_MAX_UNIFORM_LOCATIONS */
521b167d5e7Smrg   consts->MaxUserAssignableUniformLocations =
522b167d5e7Smrg      4 * MESA_SHADER_STAGES * MAX_UNIFORMS;
523b167d5e7Smrg
524b167d5e7Smrg   for (i = 0; i < MESA_SHADER_STAGES; i++)
525b167d5e7Smrg      init_program_limits(consts, i, &consts->Program[i]);
526b167d5e7Smrg
527b167d5e7Smrg   consts->MaxProgramMatrices = MAX_PROGRAM_MATRICES;
528b167d5e7Smrg   consts->MaxProgramMatrixStackDepth = MAX_PROGRAM_MATRIX_STACK_DEPTH;
529b167d5e7Smrg
530d8407755Smaya   /* Set the absolute minimum possible GLSL version.  API_OPENGL_CORE can
531d8407755Smaya    * mean an OpenGL 3.0 forward-compatible context, so that implies a minimum
532d8407755Smaya    * possible version of 1.30.  Otherwise, the minimum possible version 1.20.
533d8407755Smaya    * Since Mesa unconditionally advertises GL_ARB_shading_language_100 and
534d8407755Smaya    * GL_ARB_shader_objects, every driver has GLSL 1.20... even if they don't
535d8407755Smaya    * advertise any extensions to enable any shader stages (e.g.,
536d8407755Smaya    * GL_ARB_vertex_shader).
537d8407755Smaya    */
538d8407755Smaya   consts->GLSLVersion = api == API_OPENGL_CORE ? 130 : 120;
539d8407755Smaya   consts->GLSLVersionCompat = consts->GLSLVersion;
540d8407755Smaya
5411463c08dSmrg   consts->GLSLLowerConstArrays = true;
5421463c08dSmrg
543b167d5e7Smrg   /* Assume that if GLSL 1.30+ (or GLSL ES 3.00+) is supported that
544b167d5e7Smrg    * gl_VertexID is implemented using a native hardware register with OpenGL
545b167d5e7Smrg    * semantics.
546b167d5e7Smrg    */
547b167d5e7Smrg   consts->VertexID_is_zero_based = false;
5487117f1b4Smrg
5497117f1b4Smrg   /* GL_ARB_draw_buffers */
550b167d5e7Smrg   consts->MaxDrawBuffers = MAX_DRAW_BUFFERS;
5517117f1b4Smrg
552b167d5e7Smrg   consts->MaxColorAttachments = MAX_COLOR_ATTACHMENTS;
553b167d5e7Smrg   consts->MaxRenderbufferSize = MAX_RENDERBUFFER_SIZE;
5547117f1b4Smrg
555b167d5e7Smrg   consts->Program[MESA_SHADER_VERTEX].MaxTextureImageUnits = MAX_TEXTURE_IMAGE_UNITS;
556b167d5e7Smrg   consts->MaxCombinedTextureImageUnits = MAX_COMBINED_TEXTURE_IMAGE_UNITS;
557b167d5e7Smrg   consts->MaxVarying = 16; /* old limit not to break tnl and swrast */
558b167d5e7Smrg   consts->Program[MESA_SHADER_GEOMETRY].MaxTextureImageUnits = MAX_TEXTURE_IMAGE_UNITS;
559b167d5e7Smrg   consts->MaxGeometryOutputVertices = MAX_GEOMETRY_OUTPUT_VERTICES;
560b167d5e7Smrg   consts->MaxGeometryTotalOutputComponents = MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS;
5617e995a2eSmrg   consts->MaxGeometryShaderInvocations = MAX_GEOMETRY_SHADER_INVOCATIONS;
5623464ebd5Sriastradh
5637e995a2eSmrg#ifdef DEBUG
5647e995a2eSmrg   consts->GenerateTemporaryNames = true;
5657e995a2eSmrg#else
5667e995a2eSmrg   consts->GenerateTemporaryNames = false;
5677e995a2eSmrg#endif
5687117f1b4Smrg
5694a49301eSmrg   /* GL_ARB_framebuffer_object */
570b167d5e7Smrg   consts->MaxSamples = 0;
5714a49301eSmrg
572b167d5e7Smrg   /* GLSL default if NativeIntegers == FALSE */
5737e995a2eSmrg   consts->UniformBooleanTrue = FLOAT_AS_UNION(1.0f).u;
5744a49301eSmrg
575b167d5e7Smrg   /* GL_ARB_sync */
5767e995a2eSmrg   consts->MaxServerWaitTimeout = 0x7fffffff7fffffffULL;
5774a49301eSmrg
5784a49301eSmrg   /* GL_EXT_provoking_vertex */
579b167d5e7Smrg   consts->QuadsFollowProvokingVertexConvention = GL_TRUE;
5803464ebd5Sriastradh
5817e995a2eSmrg   /** GL_ARB_viewport_array */
5827e995a2eSmrg   consts->LayerAndVPIndexProvokingVertex = GL_UNDEFINED_VERTEX;
5837e995a2eSmrg
5843464ebd5Sriastradh   /* GL_EXT_transform_feedback */
585b167d5e7Smrg   consts->MaxTransformFeedbackBuffers = MAX_FEEDBACK_BUFFERS;
586b167d5e7Smrg   consts->MaxTransformFeedbackSeparateComponents = 4 * MAX_FEEDBACK_ATTRIBS;
587b167d5e7Smrg   consts->MaxTransformFeedbackInterleavedComponents = 4 * MAX_FEEDBACK_ATTRIBS;
588b167d5e7Smrg   consts->MaxVertexStreams = 1;
5893464ebd5Sriastradh
590b167d5e7Smrg   /* GL 3.2  */
591b167d5e7Smrg   consts->ProfileMask = api == API_OPENGL_CORE
592b167d5e7Smrg                          ? GL_CONTEXT_CORE_PROFILE_BIT
593b167d5e7Smrg                          : GL_CONTEXT_COMPATIBILITY_PROFILE_BIT;
5943464ebd5Sriastradh
5957e995a2eSmrg   /* GL 4.4 */
5967e995a2eSmrg   consts->MaxVertexAttribStride = 2048;
5977e995a2eSmrg
5983464ebd5Sriastradh   /** GL_EXT_gpu_shader4 */
599b167d5e7Smrg   consts->MinProgramTexelOffset = -8;
600b167d5e7Smrg   consts->MaxProgramTexelOffset = 7;
601b167d5e7Smrg
602b167d5e7Smrg   /* GL_ARB_texture_gather */
603b167d5e7Smrg   consts->MinProgramTextureGatherOffset = -8;
604b167d5e7Smrg   consts->MaxProgramTextureGatherOffset = 7;
6053464ebd5Sriastradh
6063464ebd5Sriastradh   /* GL_ARB_robustness */
607b167d5e7Smrg   consts->ResetStrategy = GL_NO_RESET_NOTIFICATION_ARB;
608b167d5e7Smrg
6097e995a2eSmrg   /* GL_KHR_robustness */
6107e995a2eSmrg   consts->RobustAccess = GL_FALSE;
611b167d5e7Smrg
612b167d5e7Smrg   /* ES 3.0 or ARB_ES3_compatibility */
613b167d5e7Smrg   consts->MaxElementIndex = 0xffffffffu;
614b167d5e7Smrg
615b167d5e7Smrg   /* GL_ARB_texture_multisample */
616b167d5e7Smrg   consts->MaxColorTextureSamples = 1;
617b167d5e7Smrg   consts->MaxDepthTextureSamples = 1;
618b167d5e7Smrg   consts->MaxIntegerSamples = 1;
619b167d5e7Smrg
620b167d5e7Smrg   /* GL_ARB_shader_atomic_counters */
621b167d5e7Smrg   consts->MaxAtomicBufferBindings = MAX_COMBINED_ATOMIC_BUFFERS;
622b167d5e7Smrg   consts->MaxAtomicBufferSize = MAX_ATOMIC_COUNTERS * ATOMIC_COUNTER_SIZE;
623b167d5e7Smrg   consts->MaxCombinedAtomicBuffers = MAX_COMBINED_ATOMIC_BUFFERS;
624b167d5e7Smrg   consts->MaxCombinedAtomicCounters = MAX_ATOMIC_COUNTERS;
625b167d5e7Smrg
626b167d5e7Smrg   /* GL_ARB_vertex_attrib_binding */
627b167d5e7Smrg   consts->MaxVertexAttribRelativeOffset = 2047;
628b167d5e7Smrg   consts->MaxVertexAttribBindings = MAX_VERTEX_GENERIC_ATTRIBS;
629b167d5e7Smrg
630b167d5e7Smrg   /* GL_ARB_compute_shader */
631b167d5e7Smrg   consts->MaxComputeWorkGroupCount[0] = 65535;
632b167d5e7Smrg   consts->MaxComputeWorkGroupCount[1] = 65535;
633b167d5e7Smrg   consts->MaxComputeWorkGroupCount[2] = 65535;
634b167d5e7Smrg   consts->MaxComputeWorkGroupSize[0] = 1024;
635b167d5e7Smrg   consts->MaxComputeWorkGroupSize[1] = 1024;
636b167d5e7Smrg   consts->MaxComputeWorkGroupSize[2] = 64;
6377e995a2eSmrg   /* Enables compute support for GLES 3.1 if >= 128 */
6387e995a2eSmrg   consts->MaxComputeWorkGroupInvocations = 0;
639b167d5e7Smrg
640b167d5e7Smrg   /** GL_ARB_gpu_shader5 */
641b167d5e7Smrg   consts->MinFragmentInterpolationOffset = MIN_FRAGMENT_INTERPOLATION_OFFSET;
642b167d5e7Smrg   consts->MaxFragmentInterpolationOffset = MAX_FRAGMENT_INTERPOLATION_OFFSET;
6437e995a2eSmrg
6447e995a2eSmrg   /** GL_KHR_context_flush_control */
6457e995a2eSmrg   consts->ContextReleaseBehavior = GL_CONTEXT_RELEASE_BEHAVIOR_FLUSH;
6467e995a2eSmrg
6477e995a2eSmrg   /** GL_ARB_tessellation_shader */
6487e995a2eSmrg   consts->MaxTessGenLevel = MAX_TESS_GEN_LEVEL;
6497e995a2eSmrg   consts->MaxPatchVertices = MAX_PATCH_VERTICES;
6507e995a2eSmrg   consts->Program[MESA_SHADER_TESS_CTRL].MaxTextureImageUnits = MAX_TEXTURE_IMAGE_UNITS;
6517e995a2eSmrg   consts->Program[MESA_SHADER_TESS_EVAL].MaxTextureImageUnits = MAX_TEXTURE_IMAGE_UNITS;
6527e995a2eSmrg   consts->MaxTessPatchComponents = MAX_TESS_PATCH_COMPONENTS;
6537e995a2eSmrg   consts->MaxTessControlTotalOutputComponents = MAX_TESS_CONTROL_TOTAL_OUTPUT_COMPONENTS;
6547e995a2eSmrg   consts->PrimitiveRestartForPatches = false;
6557e995a2eSmrg
6567e995a2eSmrg   /** GL_ARB_compute_variable_group_size */
6577e995a2eSmrg   consts->MaxComputeVariableGroupSize[0] = 512;
6587e995a2eSmrg   consts->MaxComputeVariableGroupSize[1] = 512;
6597e995a2eSmrg   consts->MaxComputeVariableGroupSize[2] = 64;
6607e995a2eSmrg   consts->MaxComputeVariableGroupInvocations = 512;
6617e995a2eSmrg
6627e995a2eSmrg   /** GL_NV_conservative_raster */
6637e995a2eSmrg   consts->MaxSubpixelPrecisionBiasBits = 0;
6647e995a2eSmrg
6657e995a2eSmrg   /** GL_NV_conservative_raster_dilate */
6667e995a2eSmrg   consts->ConservativeRasterDilateRange[0] = 0.0;
6677e995a2eSmrg   consts->ConservativeRasterDilateRange[1] = 0.0;
6687e995a2eSmrg   consts->ConservativeRasterDilateGranularity = 0.0;
6691463c08dSmrg
6701463c08dSmrg   consts->glBeginEndBufferSize = 512 * 1024;
6717117f1b4Smrg}
6727117f1b4Smrg
6737117f1b4Smrg
6747117f1b4Smrg/**
6757117f1b4Smrg * Do some sanity checks on the limits/constants for the given context.
6767117f1b4Smrg * Only called the first time a context is bound.
6777117f1b4Smrg */
6787117f1b4Smrgstatic void
6793464ebd5Sriastradhcheck_context_limits(struct gl_context *ctx)
6807117f1b4Smrg{
6817e995a2eSmrg   (void) ctx;
6827e995a2eSmrg
683cdc920a0Smrg   /* check that we don't exceed the size of various bitfields */
684b167d5e7Smrg   assert(VARYING_SLOT_MAX <=
6857e995a2eSmrg          (8 * sizeof(ctx->VertexProgram._Current->info.outputs_written)));
686b167d5e7Smrg   assert(VARYING_SLOT_MAX <=
6877e995a2eSmrg          (8 * sizeof(ctx->FragmentProgram._Current->info.inputs_read)));
688cdc920a0Smrg
689cdc920a0Smrg   /* shader-related checks */
690b167d5e7Smrg   assert(ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxLocalParams <= MAX_PROGRAM_LOCAL_PARAMS);
691b167d5e7Smrg   assert(ctx->Const.Program[MESA_SHADER_VERTEX].MaxLocalParams <= MAX_PROGRAM_LOCAL_PARAMS);
692cdc920a0Smrg
693cdc920a0Smrg   /* Texture unit checks */
694b167d5e7Smrg   assert(ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxTextureImageUnits > 0);
695b167d5e7Smrg   assert(ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxTextureImageUnits <= MAX_TEXTURE_IMAGE_UNITS);
696cdc920a0Smrg   assert(ctx->Const.MaxTextureCoordUnits > 0);
6977117f1b4Smrg   assert(ctx->Const.MaxTextureCoordUnits <= MAX_TEXTURE_COORD_UNITS);
698cdc920a0Smrg   assert(ctx->Const.MaxTextureUnits > 0);
6997117f1b4Smrg   assert(ctx->Const.MaxTextureUnits <= MAX_TEXTURE_IMAGE_UNITS);
7007117f1b4Smrg   assert(ctx->Const.MaxTextureUnits <= MAX_TEXTURE_COORD_UNITS);
701b167d5e7Smrg   assert(ctx->Const.MaxTextureUnits == MIN2(ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxTextureImageUnits,
702cdc920a0Smrg                                             ctx->Const.MaxTextureCoordUnits));
703cdc920a0Smrg   assert(ctx->Const.MaxCombinedTextureImageUnits > 0);
704cdc920a0Smrg   assert(ctx->Const.MaxCombinedTextureImageUnits <= MAX_COMBINED_TEXTURE_IMAGE_UNITS);
705cdc920a0Smrg   assert(ctx->Const.MaxTextureCoordUnits <= MAX_COMBINED_TEXTURE_IMAGE_UNITS);
706c1f859d4Smrg   /* number of coord units cannot be greater than number of image units */
707b167d5e7Smrg   assert(ctx->Const.MaxTextureCoordUnits <= ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxTextureImageUnits);
708c1f859d4Smrg
709cdc920a0Smrg
710cdc920a0Smrg   /* Texture size checks */
7111463c08dSmrg   assert(ctx->Const.MaxTextureSize <= (1 << (MAX_TEXTURE_LEVELS - 1)));
7121463c08dSmrg   assert(ctx->Const.Max3DTextureLevels <= MAX_TEXTURE_LEVELS);
7131463c08dSmrg   assert(ctx->Const.MaxCubeTextureLevels <= MAX_TEXTURE_LEVELS);
7144a49301eSmrg   assert(ctx->Const.MaxTextureRectSize <= MAX_TEXTURE_RECT_SIZE);
7157117f1b4Smrg
716cdc920a0Smrg   /* Max texture size should be <= max viewport size (render to texture) */
7171463c08dSmrg   assert(ctx->Const.MaxTextureSize <= ctx->Const.MaxViewportWidth);
7181463c08dSmrg   assert(ctx->Const.MaxTextureSize <= ctx->Const.MaxViewportHeight);
7197117f1b4Smrg
7207117f1b4Smrg   assert(ctx->Const.MaxDrawBuffers <= MAX_DRAW_BUFFERS);
7217117f1b4Smrg
7223464ebd5Sriastradh   /* if this fails, add more enum values to gl_buffer_index */
7233464ebd5Sriastradh   assert(BUFFER_COLOR0 + MAX_DRAW_BUFFERS <= BUFFER_COUNT);
7243464ebd5Sriastradh
7257117f1b4Smrg   /* XXX probably add more tests */
7267117f1b4Smrg}
7277117f1b4Smrg
7287117f1b4Smrg
7297117f1b4Smrg/**
7307117f1b4Smrg * Initialize the attribute groups in a GL context.
7317117f1b4Smrg *
7327117f1b4Smrg * \param ctx GL context.
7337117f1b4Smrg *
7347117f1b4Smrg * Initializes all the attributes, calling the respective <tt>init*</tt>
7357117f1b4Smrg * functions for the more complex data structures.
7367117f1b4Smrg */
7377117f1b4Smrgstatic GLboolean
7383464ebd5Sriastradhinit_attrib_groups(struct gl_context *ctx)
7397117f1b4Smrg{
7407117f1b4Smrg   assert(ctx);
7417117f1b4Smrg
7427117f1b4Smrg   /* Constants */
743b167d5e7Smrg   _mesa_init_constants(&ctx->Const, ctx->API);
7447117f1b4Smrg
7457117f1b4Smrg   /* Extensions */
746b167d5e7Smrg   _mesa_init_extensions(&ctx->Extensions);
7477117f1b4Smrg
7487117f1b4Smrg   /* Attribute Groups */
7497117f1b4Smrg   _mesa_init_accum( ctx );
7507117f1b4Smrg   _mesa_init_attrib( ctx );
7517e995a2eSmrg   _mesa_init_bbox( ctx );
7527117f1b4Smrg   _mesa_init_buffer_objects( ctx );
7537117f1b4Smrg   _mesa_init_color( ctx );
7547e995a2eSmrg   _mesa_init_conservative_raster( ctx );
7557117f1b4Smrg   _mesa_init_current( ctx );
7567117f1b4Smrg   _mesa_init_depth( ctx );
7577117f1b4Smrg   _mesa_init_debug( ctx );
7587e995a2eSmrg   _mesa_init_debug_output( ctx );
7597117f1b4Smrg   _mesa_init_display_list( ctx );
7607117f1b4Smrg   _mesa_init_eval( ctx );
7617117f1b4Smrg   _mesa_init_feedback( ctx );
7627117f1b4Smrg   _mesa_init_fog( ctx );
7637117f1b4Smrg   _mesa_init_hint( ctx );
7647e995a2eSmrg   _mesa_init_image_units( ctx );
7657117f1b4Smrg   _mesa_init_line( ctx );
7667117f1b4Smrg   _mesa_init_lighting( ctx );
7677117f1b4Smrg   _mesa_init_matrix( ctx );
7687117f1b4Smrg   _mesa_init_multisample( ctx );
769b167d5e7Smrg   _mesa_init_performance_monitors( ctx );
7707e995a2eSmrg   _mesa_init_performance_queries( ctx );
771b167d5e7Smrg   _mesa_init_pipeline( ctx );
7727117f1b4Smrg   _mesa_init_pixel( ctx );
773c1f859d4Smrg   _mesa_init_pixelstore( ctx );
7747117f1b4Smrg   _mesa_init_point( ctx );
7757117f1b4Smrg   _mesa_init_polygon( ctx );
7767117f1b4Smrg   _mesa_init_program( ctx );
7774a49301eSmrg   _mesa_init_queryobj( ctx );
7784a49301eSmrg   _mesa_init_sync( ctx );
7797117f1b4Smrg   _mesa_init_rastpos( ctx );
7807117f1b4Smrg   _mesa_init_scissor( ctx );
7817117f1b4Smrg   _mesa_init_shader_state( ctx );
7827117f1b4Smrg   _mesa_init_stencil( ctx );
7837117f1b4Smrg   _mesa_init_transform( ctx );
7843464ebd5Sriastradh   _mesa_init_transform_feedback( ctx );
7857117f1b4Smrg   _mesa_init_varray( ctx );
7867117f1b4Smrg   _mesa_init_viewport( ctx );
7877e995a2eSmrg   _mesa_init_resident_handles( ctx );
7887117f1b4Smrg
7897117f1b4Smrg   if (!_mesa_init_texture( ctx ))
7907117f1b4Smrg      return GL_FALSE;
7917117f1b4Smrg
7927117f1b4Smrg   /* Miscellaneous */
7937e995a2eSmrg   ctx->TileRasterOrderIncreasingX = GL_TRUE;
7947e995a2eSmrg   ctx->TileRasterOrderIncreasingY = GL_TRUE;
7957117f1b4Smrg   ctx->NewState = _NEW_ALL;
796b167d5e7Smrg   ctx->NewDriverState = ~0;
797b167d5e7Smrg   ctx->ErrorValue = GL_NO_ERROR;
798b167d5e7Smrg   ctx->ShareGroupReset = false;
7991463c08dSmrg   ctx->VertexProgram._VaryingInputs = VERT_BIT_ALL;
8001463c08dSmrg   ctx->IntelBlackholeRender = env_var_as_boolean("INTEL_BLACKHOLE_DEFAULT", false);
8017117f1b4Smrg
8027117f1b4Smrg   return GL_TRUE;
8037117f1b4Smrg}
8047117f1b4Smrg
8057117f1b4Smrg
806c1f859d4Smrg/**
807c1f859d4Smrg * Update default objects in a GL context with respect to shared state.
808c1f859d4Smrg *
809c1f859d4Smrg * \param ctx GL context.
810c1f859d4Smrg *
811c1f859d4Smrg * Removes references to old default objects, (texture objects, program
812c1f859d4Smrg * objects, etc.) and changes to reference those from the current shared
813c1f859d4Smrg * state.
814c1f859d4Smrg */
815c1f859d4Smrgstatic GLboolean
8163464ebd5Sriastradhupdate_default_objects(struct gl_context *ctx)
817c1f859d4Smrg{
818c1f859d4Smrg   assert(ctx);
819c1f859d4Smrg
820c1f859d4Smrg   _mesa_update_default_objects_program(ctx);
821c1f859d4Smrg   _mesa_update_default_objects_texture(ctx);
822c1f859d4Smrg   _mesa_update_default_objects_buffer_objects(ctx);
823c1f859d4Smrg
824c1f859d4Smrg   return GL_TRUE;
825c1f859d4Smrg}
826c1f859d4Smrg
827c1f859d4Smrg
8287e995a2eSmrg/* XXX this is temporary and should be removed at some point in the
8297e995a2eSmrg * future when there's a reasonable expectation that the libGL library
8307e995a2eSmrg * contains the _glapi_new_nop_table() and _glapi_set_nop_handler()
8317e995a2eSmrg * functions which were added in Mesa 10.6.
8327e995a2eSmrg */
8337e995a2eSmrg#if !defined(_WIN32)
8347e995a2eSmrg/* Avoid libGL / driver ABI break */
8357e995a2eSmrg#define USE_GLAPI_NOP_FEATURES 0
8367e995a2eSmrg#else
8377e995a2eSmrg#define USE_GLAPI_NOP_FEATURES 1
8387e995a2eSmrg#endif
8397e995a2eSmrg
8407e995a2eSmrg
8417117f1b4Smrg/**
8427e995a2eSmrg * This function is called by the glapi no-op functions.  For each OpenGL
8437e995a2eSmrg * function/entrypoint there's a simple no-op function.  These "no-op"
8447e995a2eSmrg * functions call this function.
8457e995a2eSmrg *
8467e995a2eSmrg * If there's a current OpenGL context for the calling thread, we record a
8477e995a2eSmrg * GL_INVALID_OPERATION error.  This can happen either because the app's
8487e995a2eSmrg * calling an unsupported extension function, or calling an illegal function
8497e995a2eSmrg * (such as glClear between glBegin/glEnd).
8507e995a2eSmrg *
8517e995a2eSmrg * If there's no current OpenGL context for the calling thread, we can
8527e995a2eSmrg * print a message to stderr.
8537e995a2eSmrg *
8547e995a2eSmrg * \param name  the name of the OpenGL function
8557117f1b4Smrg */
8567e995a2eSmrg#if USE_GLAPI_NOP_FEATURES
8577e995a2eSmrgstatic void
8587e995a2eSmrgnop_handler(const char *name)
8597117f1b4Smrg{
860b167d5e7Smrg   GET_CURRENT_CONTEXT(ctx);
8617e995a2eSmrg   if (ctx) {
8627e995a2eSmrg      _mesa_error(ctx, GL_INVALID_OPERATION, "%s(invalid call)", name);
8637e995a2eSmrg   }
8641463c08dSmrg#ifndef NDEBUG
8657e995a2eSmrg   else if (getenv("MESA_DEBUG") || getenv("LIBGL_DEBUG")) {
8667e995a2eSmrg      fprintf(stderr,
8677e995a2eSmrg              "GL User Error: gl%s called without a rendering context\n",
8687e995a2eSmrg              name);
8697e995a2eSmrg      fflush(stderr);
8707e995a2eSmrg   }
8717e995a2eSmrg#endif
8727117f1b4Smrg}
8737e995a2eSmrg#endif
8747117f1b4Smrg
8757117f1b4Smrg
8767117f1b4Smrg/**
877b167d5e7Smrg * Special no-op glFlush, see below.
878b167d5e7Smrg */
879b167d5e7Smrg#if defined(_WIN32)
880b167d5e7Smrgstatic void GLAPIENTRY
881b167d5e7Smrgnop_glFlush(void)
882b167d5e7Smrg{
8837e995a2eSmrg   /* don't record an error like we do in nop_handler() */
8847e995a2eSmrg}
8857e995a2eSmrg#endif
8867e995a2eSmrg
8877e995a2eSmrg
8887e995a2eSmrg#if !USE_GLAPI_NOP_FEATURES
8897e995a2eSmrgstatic int
8907e995a2eSmrggeneric_nop(void)
8917e995a2eSmrg{
8927e995a2eSmrg   GET_CURRENT_CONTEXT(ctx);
8937e995a2eSmrg   _mesa_error(ctx, GL_INVALID_OPERATION,
8947e995a2eSmrg               "unsupported function called "
8957e995a2eSmrg               "(unsupported extension or deprecated function?)");
8967e995a2eSmrg   return 0;
897b167d5e7Smrg}
898b167d5e7Smrg#endif
899b167d5e7Smrg
900b167d5e7Smrg
901b167d5e7Smrg/**
9027e995a2eSmrg * Create a new API dispatch table in which all entries point to the
9037e995a2eSmrg * generic_nop() function.  This will not work on Windows because of
9047e995a2eSmrg * the __stdcall convention which requires the callee to clean up the
9057e995a2eSmrg * call stack.  That's impossible with one generic no-op function.
9067117f1b4Smrg */
9073464ebd5Sriastradhstruct _glapi_table *
9087e995a2eSmrg_mesa_new_nop_table(unsigned numEntries)
9097117f1b4Smrg{
9103464ebd5Sriastradh   struct _glapi_table *table;
9113464ebd5Sriastradh
9127e995a2eSmrg#if !USE_GLAPI_NOP_FEATURES
913b167d5e7Smrg   table = malloc(numEntries * sizeof(_glapi_proc));
9147117f1b4Smrg   if (table) {
9157117f1b4Smrg      _glapi_proc *entry = (_glapi_proc *) table;
9167e995a2eSmrg      unsigned i;
9177117f1b4Smrg      for (i = 0; i < numEntries; i++) {
9187e995a2eSmrg         entry[i] = (_glapi_proc) generic_nop;
9197117f1b4Smrg      }
9207e995a2eSmrg   }
9217e995a2eSmrg#else
9227e995a2eSmrg   table = _glapi_new_nop_table(numEntries);
9237e995a2eSmrg#endif
9247e995a2eSmrg   return table;
9257e995a2eSmrg}
9267e995a2eSmrg
9277e995a2eSmrg
9287e995a2eSmrg/**
9297e995a2eSmrg * Allocate and initialize a new dispatch table.  The table will be
9307e995a2eSmrg * populated with pointers to "no-op" functions.  In turn, the no-op
9317e995a2eSmrg * functions will call nop_handler() above.
9327e995a2eSmrg */
9337e995a2eSmrgstruct _glapi_table *
9347e995a2eSmrg_mesa_alloc_dispatch_table(void)
9357e995a2eSmrg{
9367e995a2eSmrg   /* Find the larger of Mesa's dispatch table and libGL's dispatch table.
9377e995a2eSmrg    * In practice, this'll be the same for stand-alone Mesa.  But for DRI
9387e995a2eSmrg    * Mesa we do this to accommodate different versions of libGL and various
9397e995a2eSmrg    * DRI drivers.
9407e995a2eSmrg    */
9417e995a2eSmrg   int numEntries = MAX2(_glapi_get_dispatch_table_size(), _gloffset_COUNT);
9427e995a2eSmrg
9437e995a2eSmrg   struct _glapi_table *table = _mesa_new_nop_table(numEntries);
944b167d5e7Smrg
945b167d5e7Smrg#if defined(_WIN32)
9467e995a2eSmrg   if (table) {
947b167d5e7Smrg      /* This is a special case for Windows in the event that
948b167d5e7Smrg       * wglGetProcAddress is called between glBegin/End().
949b167d5e7Smrg       *
950b167d5e7Smrg       * The MS opengl32.dll library apparently calls glFlush from
951b167d5e7Smrg       * wglGetProcAddress().  If we're inside glBegin/End(), glFlush
952b167d5e7Smrg       * will dispatch to _mesa_generic_nop() and we'll generate a
953b167d5e7Smrg       * GL_INVALID_OPERATION error.
954b167d5e7Smrg       *
955b167d5e7Smrg       * The specific case which hits this is piglit's primitive-restart
956b167d5e7Smrg       * test which calls glPrimitiveRestartNV() inside glBegin/End.  The
957b167d5e7Smrg       * first time we call glPrimitiveRestartNV() Piglit's API dispatch
958b167d5e7Smrg       * code will try to resolve the function by calling wglGetProcAddress.
959b167d5e7Smrg       * This raises GL_INVALID_OPERATION and an assert(glGetError()==0)
960b167d5e7Smrg       * will fail causing the test to fail.  By suppressing the error, the
961b167d5e7Smrg       * assertion passes and the test continues.
962b167d5e7Smrg       */
963b167d5e7Smrg      SET_Flush(table, nop_glFlush);
9647117f1b4Smrg   }
9657e995a2eSmrg#endif
9667e995a2eSmrg
9677e995a2eSmrg#if USE_GLAPI_NOP_FEATURES
9687e995a2eSmrg   _glapi_set_nop_handler(nop_handler);
9697e995a2eSmrg#endif
9707e995a2eSmrg
9717117f1b4Smrg   return table;
9727117f1b4Smrg}
9737117f1b4Smrg
974b167d5e7Smrg/**
975b167d5e7Smrg * Creates a minimal dispatch table for use within glBegin()/glEnd().
976b167d5e7Smrg *
977b167d5e7Smrg * This ensures that we generate GL_INVALID_OPERATION errors from most
978b167d5e7Smrg * functions, since the set of functions that are valid within Begin/End is
979b167d5e7Smrg * very small.
980b167d5e7Smrg *
981b167d5e7Smrg * From the GL 1.0 specification section 2.6.3, "GL Commands within
982b167d5e7Smrg * Begin/End"
983b167d5e7Smrg *
984b167d5e7Smrg *     "The only GL commands that are allowed within any Begin/End pairs are
985b167d5e7Smrg *      the commands for specifying vertex coordinates, vertex color, normal
986b167d5e7Smrg *      coordinates, and texture coordinates (Vertex, Color, Index, Normal,
987b167d5e7Smrg *      TexCoord), EvalCoord and EvalPoint commands (see section 5.1),
988b167d5e7Smrg *      commands for specifying lighting material parameters (Material
989b167d5e7Smrg *      commands see section 2.12.2), display list invocation commands
990b167d5e7Smrg *      (CallList and CallLists see section 5.4), and the EdgeFlag
991b167d5e7Smrg *      command. Executing Begin after Begin has already been executed but
992b167d5e7Smrg *      before an End is issued generates the INVALID OPERATION error, as does
993b167d5e7Smrg *      executing End without a previous corresponding Begin. Executing any
994b167d5e7Smrg *      other GL command within Begin/End results in the error INVALID
995b167d5e7Smrg *      OPERATION."
996b167d5e7Smrg *
997b167d5e7Smrg * The table entries for specifying vertex attributes are set up by
9981463c08dSmrg * install_vtxfmt(), and End() and dlists
999b167d5e7Smrg * are set by install_vtxfmt() as well.
1000b167d5e7Smrg */
1001b167d5e7Smrgstatic struct _glapi_table *
1002b167d5e7Smrgcreate_beginend_table(const struct gl_context *ctx)
1003b167d5e7Smrg{
1004b167d5e7Smrg   struct _glapi_table *table;
1005b167d5e7Smrg
1006b167d5e7Smrg   table = _mesa_alloc_dispatch_table();
1007b167d5e7Smrg   if (!table)
1008b167d5e7Smrg      return NULL;
1009b167d5e7Smrg
1010b167d5e7Smrg   /* Fill in functions which return a value, since they should return some
1011b167d5e7Smrg    * specific value even if they emit a GL_INVALID_OPERATION error from them
1012b167d5e7Smrg    * being called within glBegin()/glEnd().
1013b167d5e7Smrg    */
1014b167d5e7Smrg#define COPY_DISPATCH(func) SET_##func(table, GET_##func(ctx->Exec))
1015b167d5e7Smrg
1016b167d5e7Smrg   COPY_DISPATCH(GenLists);
1017b167d5e7Smrg   COPY_DISPATCH(IsProgram);
1018b167d5e7Smrg   COPY_DISPATCH(IsVertexArray);
1019b167d5e7Smrg   COPY_DISPATCH(IsBuffer);
1020b167d5e7Smrg   COPY_DISPATCH(IsEnabled);
1021b167d5e7Smrg   COPY_DISPATCH(IsEnabledi);
1022b167d5e7Smrg   COPY_DISPATCH(IsRenderbuffer);
1023b167d5e7Smrg   COPY_DISPATCH(IsFramebuffer);
1024b167d5e7Smrg   COPY_DISPATCH(CheckFramebufferStatus);
1025b167d5e7Smrg   COPY_DISPATCH(RenderMode);
1026b167d5e7Smrg   COPY_DISPATCH(GetString);
1027b167d5e7Smrg   COPY_DISPATCH(GetStringi);
1028b167d5e7Smrg   COPY_DISPATCH(GetPointerv);
1029b167d5e7Smrg   COPY_DISPATCH(IsQuery);
1030b167d5e7Smrg   COPY_DISPATCH(IsSampler);
1031b167d5e7Smrg   COPY_DISPATCH(IsSync);
1032b167d5e7Smrg   COPY_DISPATCH(IsTexture);
1033b167d5e7Smrg   COPY_DISPATCH(IsTransformFeedback);
1034b167d5e7Smrg   COPY_DISPATCH(DeleteQueries);
1035b167d5e7Smrg   COPY_DISPATCH(AreTexturesResident);
1036b167d5e7Smrg   COPY_DISPATCH(FenceSync);
1037b167d5e7Smrg   COPY_DISPATCH(ClientWaitSync);
1038b167d5e7Smrg   COPY_DISPATCH(MapBuffer);
1039b167d5e7Smrg   COPY_DISPATCH(UnmapBuffer);
1040b167d5e7Smrg   COPY_DISPATCH(MapBufferRange);
1041b167d5e7Smrg   COPY_DISPATCH(ObjectPurgeableAPPLE);
1042b167d5e7Smrg   COPY_DISPATCH(ObjectUnpurgeableAPPLE);
1043b167d5e7Smrg
1044b167d5e7Smrg   return table;
1045b167d5e7Smrg}
1046b167d5e7Smrg
1047b167d5e7Smrgvoid
1048b167d5e7Smrg_mesa_initialize_dispatch_tables(struct gl_context *ctx)
1049b167d5e7Smrg{
1050b167d5e7Smrg   /* Do the code-generated setup of the exec table in api_exec.c. */
1051b167d5e7Smrg   _mesa_initialize_exec_table(ctx);
1052b167d5e7Smrg
1053b167d5e7Smrg   if (ctx->Save)
1054b167d5e7Smrg      _mesa_initialize_save_table(ctx);
1055b167d5e7Smrg}
10567117f1b4Smrg
10577117f1b4Smrg/**
10583464ebd5Sriastradh * Initialize a struct gl_context struct (rendering context).
10597117f1b4Smrg *
10607117f1b4Smrg * This includes allocating all the other structs and arrays which hang off of
10617117f1b4Smrg * the context by pointers.
10627117f1b4Smrg * Note that the driver needs to pass in its dd_function_table here since
10637117f1b4Smrg * we need to at least call driverFunctions->NewTextureObject to create the
10647117f1b4Smrg * default texture objects.
10657e995a2eSmrg *
10667117f1b4Smrg * Called by _mesa_create_context().
10677117f1b4Smrg *
10687117f1b4Smrg * Performs the imports and exports callback tables initialization, and
10697117f1b4Smrg * miscellaneous one-time initializations. If no shared context is supplied one
10707117f1b4Smrg * is allocated, and increase its reference count.  Setups the GL API dispatch
10717117f1b4Smrg * tables.  Initialize the TNL module. Sets the maximum Z buffer depth.
10727117f1b4Smrg * Finally queries the \c MESA_DEBUG and \c MESA_VERBOSE environment variables
10737117f1b4Smrg * for debug flags.
10747117f1b4Smrg *
10757117f1b4Smrg * \param ctx the context to initialize
10763464ebd5Sriastradh * \param api the GL API type to create the context for
1077b167d5e7Smrg * \param visual describes the visual attributes for this context or NULL to
1078b167d5e7Smrg *               create a configless context
10797117f1b4Smrg * \param share_list points to context to share textures, display lists,
10807117f1b4Smrg *        etc with, or NULL
10817117f1b4Smrg * \param driverFunctions table of device driver functions for this context
10827117f1b4Smrg *        to use
10837117f1b4Smrg */
10847117f1b4SmrgGLboolean
10853464ebd5Sriastradh_mesa_initialize_context(struct gl_context *ctx,
10863464ebd5Sriastradh                         gl_api api,
10873464ebd5Sriastradh                         const struct gl_config *visual,
10883464ebd5Sriastradh                         struct gl_context *share_list,
1089b167d5e7Smrg                         const struct dd_function_table *driverFunctions)
10907117f1b4Smrg{
10914a49301eSmrg   struct gl_shared_state *shared;
10923464ebd5Sriastradh   int i;
10934a49301eSmrg
10947117f1b4Smrg   assert(driverFunctions->NewTextureObject);
1095b167d5e7Smrg   assert(driverFunctions->FreeTextureImageBuffer);
10967117f1b4Smrg
10973464ebd5Sriastradh   ctx->API = api;
10987117f1b4Smrg   ctx->DrawBuffer = NULL;
10997117f1b4Smrg   ctx->ReadBuffer = NULL;
11007117f1b4Smrg   ctx->WinSysDrawBuffer = NULL;
11017117f1b4Smrg   ctx->WinSysReadBuffer = NULL;
11027117f1b4Smrg
1103b167d5e7Smrg   if (visual) {
1104b167d5e7Smrg      ctx->Visual = *visual;
1105b167d5e7Smrg      ctx->HasConfig = GL_TRUE;
1106b167d5e7Smrg   }
1107b167d5e7Smrg   else {
1108b167d5e7Smrg      memset(&ctx->Visual, 0, sizeof ctx->Visual);
1109b167d5e7Smrg      ctx->HasConfig = GL_FALSE;
1110b167d5e7Smrg   }
1111b167d5e7Smrg
11127e995a2eSmrg   _mesa_override_gl_version(ctx);
1113b167d5e7Smrg
11143464ebd5Sriastradh   /* misc one-time initializations */
11151463c08dSmrg   _mesa_initialize();
1116d8407755Smaya
11177117f1b4Smrg   /* Plug in driver functions and context pointer here.
11187117f1b4Smrg    * This is important because when we call alloc_shared_state() below
11197117f1b4Smrg    * we'll call ctx->Driver.NewTextureObject() to create the default
11207117f1b4Smrg    * textures.
11217117f1b4Smrg    */
11227117f1b4Smrg   ctx->Driver = *driverFunctions;
11237117f1b4Smrg
11247117f1b4Smrg   if (share_list) {
11257117f1b4Smrg      /* share state with another context */
11264a49301eSmrg      shared = share_list->Shared;
11277117f1b4Smrg   }
11287117f1b4Smrg   else {
11297117f1b4Smrg      /* allocate new, unshared state */
11304a49301eSmrg      shared = _mesa_alloc_shared_state(ctx);
11314a49301eSmrg      if (!shared)
11327117f1b4Smrg         return GL_FALSE;
11337117f1b4Smrg   }
11344a49301eSmrg
1135b167d5e7Smrg   _mesa_reference_shared_state(ctx, &ctx->Shared, shared);
11367117f1b4Smrg
1137b167d5e7Smrg   if (!init_attrib_groups( ctx ))
1138b167d5e7Smrg      goto fail;
11393464ebd5Sriastradh
11407e995a2eSmrg   /* KHR_no_error is likely to crash, overflow memory, etc if an application
11417e995a2eSmrg    * has errors so don't enable it for setuid processes.
11427e995a2eSmrg    */
11437e995a2eSmrg   if (env_var_as_boolean("MESA_NO_ERROR", false)) {
11447e995a2eSmrg#if !defined(_WIN32)
1145757f638fSmaya      if (!issetugid())
11467e995a2eSmrg#endif
11477e995a2eSmrg         ctx->Const.ContextFlags |= GL_CONTEXT_FLAG_NO_ERROR_BIT_KHR;
11487e995a2eSmrg   }
11497e995a2eSmrg
1150b167d5e7Smrg   /* setup the API dispatch tables with all nop functions */
1151b167d5e7Smrg   ctx->OutsideBeginEnd = _mesa_alloc_dispatch_table();
1152b167d5e7Smrg   if (!ctx->OutsideBeginEnd)
1153b167d5e7Smrg      goto fail;
1154b167d5e7Smrg   ctx->Exec = ctx->OutsideBeginEnd;
11557e995a2eSmrg   ctx->CurrentClientDispatch = ctx->CurrentServerDispatch = ctx->OutsideBeginEnd;
11564a49301eSmrg
11577117f1b4Smrg   ctx->FragmentProgram._MaintainTexEnvProgram
11587e995a2eSmrg      = (getenv("MESA_TEX_PROG") != NULL);
11597117f1b4Smrg
11607117f1b4Smrg   ctx->VertexProgram._MaintainTnlProgram
11617e995a2eSmrg      = (getenv("MESA_TNL_PROG") != NULL);
11627117f1b4Smrg   if (ctx->VertexProgram._MaintainTnlProgram) {
11637117f1b4Smrg      /* this is required... */
11647117f1b4Smrg      ctx->FragmentProgram._MaintainTexEnvProgram = GL_TRUE;
11651463c08dSmrg      _mesa_reset_vertex_processing_mode(ctx);
11667117f1b4Smrg   }
11677117f1b4Smrg
11683464ebd5Sriastradh   /* Mesa core handles all the formats that mesa core knows about.
11693464ebd5Sriastradh    * Drivers will want to override this list with just the formats
11703464ebd5Sriastradh    * they can handle, and confirm that appropriate fallbacks exist in
11713464ebd5Sriastradh    * _mesa_choose_tex_format().
11723464ebd5Sriastradh    */
11733464ebd5Sriastradh   memset(&ctx->TextureFormatSupported, GL_TRUE,
11747e995a2eSmrg          sizeof(ctx->TextureFormatSupported));
11753464ebd5Sriastradh
11763464ebd5Sriastradh   switch (ctx->API) {
1177b167d5e7Smrg   case API_OPENGL_COMPAT:
1178b167d5e7Smrg      ctx->BeginEnd = create_beginend_table(ctx);
1179b167d5e7Smrg      ctx->Save = _mesa_alloc_dispatch_table();
1180b167d5e7Smrg      if (!ctx->BeginEnd || !ctx->Save)
1181b167d5e7Smrg         goto fail;
1182b167d5e7Smrg
11831463c08dSmrg      FALLTHROUGH;
1184b167d5e7Smrg   case API_OPENGL_CORE:
11853464ebd5Sriastradh      break;
11863464ebd5Sriastradh   case API_OPENGLES:
11873464ebd5Sriastradh      /**
11883464ebd5Sriastradh       * GL_OES_texture_cube_map says
11893464ebd5Sriastradh       * "Initially all texture generation modes are set to REFLECTION_MAP_OES"
11903464ebd5Sriastradh       */
11917e995a2eSmrg      for (i = 0; i < ARRAY_SIZE(ctx->Texture.FixedFuncUnit); i++) {
11927e995a2eSmrg         struct gl_fixedfunc_texture_unit *texUnit =
11937e995a2eSmrg            &ctx->Texture.FixedFuncUnit[i];
11947e995a2eSmrg
11957e995a2eSmrg         texUnit->GenS.Mode = GL_REFLECTION_MAP_NV;
11967e995a2eSmrg         texUnit->GenT.Mode = GL_REFLECTION_MAP_NV;
11977e995a2eSmrg         texUnit->GenR.Mode = GL_REFLECTION_MAP_NV;
11987e995a2eSmrg         texUnit->GenS._ModeBit = TEXGEN_REFLECTION_MAP_NV;
11997e995a2eSmrg         texUnit->GenT._ModeBit = TEXGEN_REFLECTION_MAP_NV;
12007e995a2eSmrg         texUnit->GenR._ModeBit = TEXGEN_REFLECTION_MAP_NV;
12013464ebd5Sriastradh      }
12023464ebd5Sriastradh      break;
12033464ebd5Sriastradh   case API_OPENGLES2:
12043464ebd5Sriastradh      ctx->FragmentProgram._MaintainTexEnvProgram = GL_TRUE;
12053464ebd5Sriastradh      ctx->VertexProgram._MaintainTnlProgram = GL_TRUE;
12061463c08dSmrg      _mesa_reset_vertex_processing_mode(ctx);
12073464ebd5Sriastradh      break;
12083464ebd5Sriastradh   }
1209c1f859d4Smrg
12107117f1b4Smrg   ctx->FirstTimeCurrent = GL_TRUE;
12117117f1b4Smrg
12127117f1b4Smrg   return GL_TRUE;
1213b167d5e7Smrg
1214b167d5e7Smrgfail:
1215b167d5e7Smrg   _mesa_reference_shared_state(ctx, &ctx->Shared, NULL);
1216b167d5e7Smrg   free(ctx->BeginEnd);
1217b167d5e7Smrg   free(ctx->OutsideBeginEnd);
1218b167d5e7Smrg   free(ctx->Save);
1219b167d5e7Smrg   return GL_FALSE;
12207117f1b4Smrg}
12217117f1b4Smrg
12227117f1b4Smrg
12237117f1b4Smrg/**
12247117f1b4Smrg * Free the data associated with the given context.
12257e995a2eSmrg *
12263464ebd5Sriastradh * But doesn't free the struct gl_context struct itself.
12277117f1b4Smrg *
12287117f1b4Smrg * \sa _mesa_initialize_context() and init_attrib_groups().
12297117f1b4Smrg */
12307117f1b4Smrgvoid
12311463c08dSmrg_mesa_free_context_data(struct gl_context *ctx, bool destroy_debug_output)
12327117f1b4Smrg{
12337117f1b4Smrg   if (!_mesa_get_current_context()){
12347117f1b4Smrg      /* No current context, but we may need one in order to delete
12357117f1b4Smrg       * texture objs, etc.  So temporarily bind the context now.
12367117f1b4Smrg       */
12377117f1b4Smrg      _mesa_make_current(ctx, NULL, NULL);
12387117f1b4Smrg   }
12397117f1b4Smrg
12407117f1b4Smrg   /* unreference WinSysDraw/Read buffers */
12414a49301eSmrg   _mesa_reference_framebuffer(&ctx->WinSysDrawBuffer, NULL);
12424a49301eSmrg   _mesa_reference_framebuffer(&ctx->WinSysReadBuffer, NULL);
12434a49301eSmrg   _mesa_reference_framebuffer(&ctx->DrawBuffer, NULL);
12444a49301eSmrg   _mesa_reference_framebuffer(&ctx->ReadBuffer, NULL);
12457117f1b4Smrg
12467e995a2eSmrg   _mesa_reference_program(ctx, &ctx->VertexProgram.Current, NULL);
12477e995a2eSmrg   _mesa_reference_program(ctx, &ctx->VertexProgram._Current, NULL);
12487e995a2eSmrg   _mesa_reference_program(ctx, &ctx->VertexProgram._TnlProgram, NULL);
1249c1f859d4Smrg
12507e995a2eSmrg   _mesa_reference_program(ctx, &ctx->TessCtrlProgram._Current, NULL);
12517e995a2eSmrg   _mesa_reference_program(ctx, &ctx->TessEvalProgram._Current, NULL);
12527e995a2eSmrg   _mesa_reference_program(ctx, &ctx->GeometryProgram._Current, NULL);
1253b167d5e7Smrg
12547e995a2eSmrg   _mesa_reference_program(ctx, &ctx->FragmentProgram.Current, NULL);
12557e995a2eSmrg   _mesa_reference_program(ctx, &ctx->FragmentProgram._Current, NULL);
12567e995a2eSmrg   _mesa_reference_program(ctx, &ctx->FragmentProgram._TexEnvProgram, NULL);
12577e995a2eSmrg
12587e995a2eSmrg   _mesa_reference_program(ctx, &ctx->ComputeProgram._Current, NULL);
1259c1f859d4Smrg
1260b167d5e7Smrg   _mesa_reference_vao(ctx, &ctx->Array.VAO, NULL);
1261b167d5e7Smrg   _mesa_reference_vao(ctx, &ctx->Array.DefaultVAO, NULL);
12627e995a2eSmrg   _mesa_reference_vao(ctx, &ctx->Array._EmptyVAO, NULL);
12637e995a2eSmrg   _mesa_reference_vao(ctx, &ctx->Array._DrawVAO, NULL);
1264b167d5e7Smrg
12657117f1b4Smrg   _mesa_free_attrib_data(ctx);
12667117f1b4Smrg   _mesa_free_eval_data( ctx );
12677117f1b4Smrg   _mesa_free_texture_data( ctx );
1268d8407755Smaya   _mesa_free_image_textures(ctx);
12697117f1b4Smrg   _mesa_free_matrix_data( ctx );
1270b167d5e7Smrg   _mesa_free_pipeline_data(ctx);
12717117f1b4Smrg   _mesa_free_program_data(ctx);
12727117f1b4Smrg   _mesa_free_shader_state(ctx);
12734a49301eSmrg   _mesa_free_queryobj_data(ctx);
12744a49301eSmrg   _mesa_free_sync_data(ctx);
12754a49301eSmrg   _mesa_free_varray_data(ctx);
12763464ebd5Sriastradh   _mesa_free_transform_feedback(ctx);
1277b167d5e7Smrg   _mesa_free_performance_monitors(ctx);
12787e995a2eSmrg   _mesa_free_performance_queries(ctx);
12797e995a2eSmrg   _mesa_free_resident_handles(ctx);
12804a49301eSmrg
12814a49301eSmrg   _mesa_reference_buffer_object(ctx, &ctx->Pack.BufferObj, NULL);
12824a49301eSmrg   _mesa_reference_buffer_object(ctx, &ctx->Unpack.BufferObj, NULL);
12834a49301eSmrg   _mesa_reference_buffer_object(ctx, &ctx->DefaultPacking.BufferObj, NULL);
12844a49301eSmrg   _mesa_reference_buffer_object(ctx, &ctx->Array.ArrayBufferObj, NULL);
12857117f1b4Smrg
12861463c08dSmrg   /* This must be called after all buffers are unbound because global buffer
12871463c08dSmrg    * references that this context holds will be removed.
12881463c08dSmrg    */
12891463c08dSmrg   _mesa_free_buffer_objects(ctx);
12901463c08dSmrg
12917117f1b4Smrg   /* free dispatch tables */
1292b167d5e7Smrg   free(ctx->BeginEnd);
1293b167d5e7Smrg   free(ctx->OutsideBeginEnd);
1294cdc920a0Smrg   free(ctx->Save);
12957e995a2eSmrg   free(ctx->ContextLost);
12967e995a2eSmrg   free(ctx->MarshalExec);
12977117f1b4Smrg
12987117f1b4Smrg   /* Shared context state (display lists, textures, etc) */
1299b167d5e7Smrg   _mesa_reference_shared_state(ctx, &ctx->Shared, NULL);
13004a49301eSmrg
13011463c08dSmrg   if (destroy_debug_output)
13021463c08dSmrg      _mesa_destroy_debug_output(ctx);
1303cdc920a0Smrg
1304b167d5e7Smrg   free((void *)ctx->Extensions.String);
1305b167d5e7Smrg
1306b167d5e7Smrg   free(ctx->VersionString);
13077117f1b4Smrg
13081463c08dSmrg   ralloc_free(ctx->SoftFP64);
1309d8407755Smaya
13107117f1b4Smrg   /* unbind the context if it's currently bound */
13117117f1b4Smrg   if (ctx == _mesa_get_current_context()) {
13127117f1b4Smrg      _mesa_make_current(NULL, NULL, NULL);
13137117f1b4Smrg   }
13147117f1b4Smrg
13151463c08dSmrg   /* Do this after unbinding context to ensure any thread is finished. */
13161463c08dSmrg   if (ctx->shader_builtin_ref) {
13171463c08dSmrg      _mesa_glsl_builtin_functions_decref();
13181463c08dSmrg      ctx->shader_builtin_ref = false;
13197117f1b4Smrg   }
13201463c08dSmrg
13211463c08dSmrg   free(ctx->Const.SpirVExtensions);
13227117f1b4Smrg}
13237117f1b4Smrg
13247117f1b4Smrg
13257117f1b4Smrg/**
13267117f1b4Smrg * Copy attribute groups from one context to another.
13277e995a2eSmrg *
13287117f1b4Smrg * \param src source context
13297117f1b4Smrg * \param dst destination context
13307117f1b4Smrg * \param mask bitwise OR of GL_*_BIT flags
13317117f1b4Smrg *
13327117f1b4Smrg * According to the bits specified in \p mask, copies the corresponding
13337117f1b4Smrg * attributes from \p src into \p dst.  For many of the attributes a simple \c
13347117f1b4Smrg * memcpy is not enough due to the existence of internal pointers in their data
13357117f1b4Smrg * structures.
13367117f1b4Smrg */
13377117f1b4Smrgvoid
13383464ebd5Sriastradh_mesa_copy_context( const struct gl_context *src, struct gl_context *dst,
13393464ebd5Sriastradh                    GLuint mask )
13407117f1b4Smrg{
13417117f1b4Smrg   if (mask & GL_ACCUM_BUFFER_BIT) {
13427117f1b4Smrg      /* OK to memcpy */
13437117f1b4Smrg      dst->Accum = src->Accum;
13447117f1b4Smrg   }
13457117f1b4Smrg   if (mask & GL_COLOR_BUFFER_BIT) {
13467117f1b4Smrg      /* OK to memcpy */
13477117f1b4Smrg      dst->Color = src->Color;
13487117f1b4Smrg   }
13497117f1b4Smrg   if (mask & GL_CURRENT_BIT) {
13507117f1b4Smrg      /* OK to memcpy */
13517117f1b4Smrg      dst->Current = src->Current;
13527117f1b4Smrg   }
13537117f1b4Smrg   if (mask & GL_DEPTH_BUFFER_BIT) {
13547117f1b4Smrg      /* OK to memcpy */
13557117f1b4Smrg      dst->Depth = src->Depth;
13567117f1b4Smrg   }
13577117f1b4Smrg   if (mask & GL_ENABLE_BIT) {
13587117f1b4Smrg      /* no op */
13597117f1b4Smrg   }
13607117f1b4Smrg   if (mask & GL_EVAL_BIT) {
13617117f1b4Smrg      /* OK to memcpy */
13627117f1b4Smrg      dst->Eval = src->Eval;
13637117f1b4Smrg   }
13647117f1b4Smrg   if (mask & GL_FOG_BIT) {
13657117f1b4Smrg      /* OK to memcpy */
13667117f1b4Smrg      dst->Fog = src->Fog;
13677117f1b4Smrg   }
13687117f1b4Smrg   if (mask & GL_HINT_BIT) {
13697117f1b4Smrg      /* OK to memcpy */
13707117f1b4Smrg      dst->Hint = src->Hint;
13717117f1b4Smrg   }
13727117f1b4Smrg   if (mask & GL_LIGHTING_BIT) {
13737e995a2eSmrg      /* OK to memcpy */
13747117f1b4Smrg      dst->Light = src->Light;
13757117f1b4Smrg   }
13767117f1b4Smrg   if (mask & GL_LINE_BIT) {
13777117f1b4Smrg      /* OK to memcpy */
13787117f1b4Smrg      dst->Line = src->Line;
13797117f1b4Smrg   }
13807117f1b4Smrg   if (mask & GL_LIST_BIT) {
13817117f1b4Smrg      /* OK to memcpy */
13827117f1b4Smrg      dst->List = src->List;
13837117f1b4Smrg   }
13847117f1b4Smrg   if (mask & GL_PIXEL_MODE_BIT) {
13857117f1b4Smrg      /* OK to memcpy */
13867117f1b4Smrg      dst->Pixel = src->Pixel;
13877117f1b4Smrg   }
13887117f1b4Smrg   if (mask & GL_POINT_BIT) {
13897117f1b4Smrg      /* OK to memcpy */
13907117f1b4Smrg      dst->Point = src->Point;
13917117f1b4Smrg   }
13927117f1b4Smrg   if (mask & GL_POLYGON_BIT) {
13937117f1b4Smrg      /* OK to memcpy */
13947117f1b4Smrg      dst->Polygon = src->Polygon;
13957117f1b4Smrg   }
13967117f1b4Smrg   if (mask & GL_POLYGON_STIPPLE_BIT) {
1397cdc920a0Smrg      /* Use loop instead of memcpy due to problem with Portland Group's
13987117f1b4Smrg       * C compiler.  Reported by John Stone.
13997117f1b4Smrg       */
14007117f1b4Smrg      GLuint i;
14017117f1b4Smrg      for (i = 0; i < 32; i++) {
14027117f1b4Smrg         dst->PolygonStipple[i] = src->PolygonStipple[i];
14037117f1b4Smrg      }
14047117f1b4Smrg   }
14057117f1b4Smrg   if (mask & GL_SCISSOR_BIT) {
14067117f1b4Smrg      /* OK to memcpy */
14077117f1b4Smrg      dst->Scissor = src->Scissor;
14087117f1b4Smrg   }
14097117f1b4Smrg   if (mask & GL_STENCIL_BUFFER_BIT) {
14107117f1b4Smrg      /* OK to memcpy */
14117117f1b4Smrg      dst->Stencil = src->Stencil;
14127117f1b4Smrg   }
14137117f1b4Smrg   if (mask & GL_TEXTURE_BIT) {
14147117f1b4Smrg      /* Cannot memcpy because of pointers */
14157117f1b4Smrg      _mesa_copy_texture_state(src, dst);
14167117f1b4Smrg   }
14177117f1b4Smrg   if (mask & GL_TRANSFORM_BIT) {
14187117f1b4Smrg      /* OK to memcpy */
14197117f1b4Smrg      dst->Transform = src->Transform;
14207117f1b4Smrg   }
14217117f1b4Smrg   if (mask & GL_VIEWPORT_BIT) {
1422b167d5e7Smrg      unsigned i;
1423b167d5e7Smrg      for (i = 0; i < src->Const.MaxViewports; i++) {
14247e995a2eSmrg         /* OK to memcpy */
14257e995a2eSmrg         dst->ViewportArray[i] = src->ViewportArray[i];
1426b167d5e7Smrg      }
14277117f1b4Smrg   }
14287117f1b4Smrg
14297117f1b4Smrg   /* XXX FIXME:  Call callbacks?
14307117f1b4Smrg    */
14317117f1b4Smrg   dst->NewState = _NEW_ALL;
1432b167d5e7Smrg   dst->NewDriverState = ~0;
14337117f1b4Smrg}
14347117f1b4Smrg
14357117f1b4Smrg
14367117f1b4Smrg/**
14377117f1b4Smrg * Check if the given context can render into the given framebuffer
14387117f1b4Smrg * by checking visual attributes.
14397117f1b4Smrg *
14407117f1b4Smrg * \return GL_TRUE if compatible, GL_FALSE otherwise.
14417117f1b4Smrg */
14427e995a2eSmrgstatic GLboolean
14433464ebd5Sriastradhcheck_compatible(const struct gl_context *ctx,
14443464ebd5Sriastradh                 const struct gl_framebuffer *buffer)
14457117f1b4Smrg{
14463464ebd5Sriastradh   const struct gl_config *ctxvis = &ctx->Visual;
14473464ebd5Sriastradh   const struct gl_config *bufvis = &buffer->Visual;
14487117f1b4Smrg
14493464ebd5Sriastradh   if (buffer == _mesa_get_incomplete_framebuffer())
14507117f1b4Smrg      return GL_TRUE;
14517117f1b4Smrg
14527e995a2eSmrg#define check_component(foo)           \
14537e995a2eSmrg   if (ctxvis->foo && bufvis->foo &&   \
14547e995a2eSmrg       ctxvis->foo != bufvis->foo)     \
14557e995a2eSmrg      return GL_FALSE
14567e995a2eSmrg
14571463c08dSmrg   check_component(redShift);
14581463c08dSmrg   check_component(greenShift);
14591463c08dSmrg   check_component(blueShift);
14601463c08dSmrg   check_component(redBits);
14611463c08dSmrg   check_component(greenBits);
14621463c08dSmrg   check_component(blueBits);
14637e995a2eSmrg   check_component(depthBits);
14647e995a2eSmrg   check_component(stencilBits);
14657e995a2eSmrg
14667e995a2eSmrg#undef check_component
14677117f1b4Smrg
14687117f1b4Smrg   return GL_TRUE;
14697117f1b4Smrg}
14707117f1b4Smrg
14717117f1b4Smrg
1472c7037ccdSmrg/**
1473c7037ccdSmrg * Check if the viewport/scissor size has not yet been initialized.
1474c7037ccdSmrg * Initialize the size if the given width and height are non-zero.
1475c7037ccdSmrg */
14767e995a2eSmrgstatic void
14777e995a2eSmrgcheck_init_viewport(struct gl_context *ctx, GLuint width, GLuint height)
1478c7037ccdSmrg{
1479c7037ccdSmrg   if (!ctx->ViewportInitialized && width > 0 && height > 0) {
1480b167d5e7Smrg      unsigned i;
1481b167d5e7Smrg
1482c7037ccdSmrg      /* Note: set flag here, before calling _mesa_set_viewport(), to prevent
1483c7037ccdSmrg       * potential infinite recursion.
1484c7037ccdSmrg       */
1485c7037ccdSmrg      ctx->ViewportInitialized = GL_TRUE;
1486b167d5e7Smrg
1487b167d5e7Smrg      /* Note: ctx->Const.MaxViewports may not have been set by the driver
1488b167d5e7Smrg       * yet, so just initialize all of them.
1489b167d5e7Smrg       */
1490b167d5e7Smrg      for (i = 0; i < MAX_VIEWPORTS; i++) {
1491b167d5e7Smrg         _mesa_set_viewport(ctx, i, 0, 0, width, height);
1492b167d5e7Smrg         _mesa_set_scissor(ctx, i, 0, 0, width, height);
1493b167d5e7Smrg      }
1494c7037ccdSmrg   }
1495c7037ccdSmrg}
1496c7037ccdSmrg
14977e995a2eSmrg
1498b167d5e7Smrgstatic void
1499b167d5e7Smrghandle_first_current(struct gl_context *ctx)
1500b167d5e7Smrg{
15017e995a2eSmrg   if (ctx->Version == 0 || !ctx->DrawBuffer) {
15027e995a2eSmrg      /* probably in the process of tearing down the context */
15037e995a2eSmrg      return;
15047e995a2eSmrg   }
1505b167d5e7Smrg
1506b167d5e7Smrg   check_context_limits(ctx);
1507b167d5e7Smrg
15087e995a2eSmrg   _mesa_update_vertex_processing_mode(ctx);
15097e995a2eSmrg
1510b167d5e7Smrg   /* According to GL_MESA_configless_context the default value of
1511b167d5e7Smrg    * glDrawBuffers depends on the config of the first surface it is bound to.
15127e995a2eSmrg    * For GLES it is always GL_BACK which has a magic interpretation.
15137e995a2eSmrg    */
1514b167d5e7Smrg   if (!ctx->HasConfig && _mesa_is_desktop_gl(ctx)) {
1515b167d5e7Smrg      if (ctx->DrawBuffer != _mesa_get_incomplete_framebuffer()) {
15167e995a2eSmrg         GLenum16 buffer;
15177e995a2eSmrg
1518b167d5e7Smrg         if (ctx->DrawBuffer->Visual.doubleBufferMode)
1519b167d5e7Smrg            buffer = GL_BACK;
1520b167d5e7Smrg         else
1521b167d5e7Smrg            buffer = GL_FRONT;
1522b167d5e7Smrg
15237e995a2eSmrg         _mesa_drawbuffers(ctx, ctx->DrawBuffer, 1, &buffer,
15247e995a2eSmrg                           NULL /* destMask */);
1525b167d5e7Smrg      }
1526b167d5e7Smrg
1527b167d5e7Smrg      if (ctx->ReadBuffer != _mesa_get_incomplete_framebuffer()) {
15287e995a2eSmrg         gl_buffer_index bufferIndex;
15297e995a2eSmrg         GLenum buffer;
15307e995a2eSmrg
1531b167d5e7Smrg         if (ctx->ReadBuffer->Visual.doubleBufferMode) {
1532b167d5e7Smrg            buffer = GL_BACK;
1533b167d5e7Smrg            bufferIndex = BUFFER_BACK_LEFT;
1534b167d5e7Smrg         }
1535b167d5e7Smrg         else {
1536b167d5e7Smrg            buffer = GL_FRONT;
1537b167d5e7Smrg            bufferIndex = BUFFER_FRONT_LEFT;
1538b167d5e7Smrg         }
1539b167d5e7Smrg
15407e995a2eSmrg         _mesa_readbuffer(ctx, ctx->ReadBuffer, buffer, bufferIndex);
1541b167d5e7Smrg      }
1542b167d5e7Smrg   }
1543b167d5e7Smrg
15447e995a2eSmrg   /* Determine if generic vertex attribute 0 aliases the conventional
15457e995a2eSmrg    * glVertex position.
15467e995a2eSmrg    */
15477e995a2eSmrg   {
15487e995a2eSmrg      const bool is_forward_compatible_context =
15497e995a2eSmrg         ctx->Const.ContextFlags & GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT;
15507e995a2eSmrg
15517e995a2eSmrg      /* In OpenGL 3.1 attribute 0 becomes non-magic, just like in OpenGL ES
15527e995a2eSmrg       * 2.0.  Note that we cannot just check for API_OPENGL_COMPAT here because
15537e995a2eSmrg       * that will erroneously allow this usage in a 3.0 forward-compatible
15547e995a2eSmrg       * context too.
15557e995a2eSmrg       */
15567e995a2eSmrg      ctx->_AttribZeroAliasesVertex = (ctx->API == API_OPENGLES
15577e995a2eSmrg                                       || (ctx->API == API_OPENGL_COMPAT
15587e995a2eSmrg                                           && !is_forward_compatible_context));
15597e995a2eSmrg   }
15607e995a2eSmrg
1561b167d5e7Smrg   /* We can use this to help debug user's problems.  Tell them to set
1562b167d5e7Smrg    * the MESA_INFO env variable before running their app.  Then the
1563b167d5e7Smrg    * first time each context is made current we'll print some useful
1564b167d5e7Smrg    * information.
1565b167d5e7Smrg    */
15667e995a2eSmrg   if (getenv("MESA_INFO")) {
1567b167d5e7Smrg      _mesa_print_info(ctx);
1568b167d5e7Smrg   }
1569b167d5e7Smrg}
1570c7037ccdSmrg
15717117f1b4Smrg/**
15727117f1b4Smrg * Bind the given context to the given drawBuffer and readBuffer and
15737117f1b4Smrg * make it the current context for the calling thread.
15747117f1b4Smrg * We'll render into the drawBuffer and read pixels from the
15757117f1b4Smrg * readBuffer (i.e. glRead/CopyPixels, glCopyTexImage, etc).
15767117f1b4Smrg *
15777117f1b4Smrg * We check that the context's and framebuffer's visuals are compatible
15787117f1b4Smrg * and return immediately if they're not.
15797117f1b4Smrg *
15807117f1b4Smrg * \param newCtx  the new GL context. If NULL then there will be no current GL
15817117f1b4Smrg *                context.
15827117f1b4Smrg * \param drawBuffer  the drawing framebuffer
15837117f1b4Smrg * \param readBuffer  the reading framebuffer
15847117f1b4Smrg */
15854a49301eSmrgGLboolean
15863464ebd5Sriastradh_mesa_make_current( struct gl_context *newCtx,
15873464ebd5Sriastradh                    struct gl_framebuffer *drawBuffer,
15883464ebd5Sriastradh                    struct gl_framebuffer *readBuffer )
15897117f1b4Smrg{
15903464ebd5Sriastradh   GET_CURRENT_CONTEXT(curCtx);
15913464ebd5Sriastradh
15927117f1b4Smrg   if (MESA_VERBOSE & VERBOSE_API)
15937117f1b4Smrg      _mesa_debug(newCtx, "_mesa_make_current()\n");
15947117f1b4Smrg
15957117f1b4Smrg   /* Check that the context's and framebuffer's visuals are compatible.
15967117f1b4Smrg    */
15977117f1b4Smrg   if (newCtx && drawBuffer && newCtx->WinSysDrawBuffer != drawBuffer) {
15987117f1b4Smrg      if (!check_compatible(newCtx, drawBuffer)) {
15997117f1b4Smrg         _mesa_warning(newCtx,
16007117f1b4Smrg              "MakeCurrent: incompatible visuals for context and drawbuffer");
16014a49301eSmrg         return GL_FALSE;
16027117f1b4Smrg      }
16037117f1b4Smrg   }
16047117f1b4Smrg   if (newCtx && readBuffer && newCtx->WinSysReadBuffer != readBuffer) {
16057117f1b4Smrg      if (!check_compatible(newCtx, readBuffer)) {
16067117f1b4Smrg         _mesa_warning(newCtx,
16077117f1b4Smrg              "MakeCurrent: incompatible visuals for context and readbuffer");
16084a49301eSmrg         return GL_FALSE;
16097117f1b4Smrg      }
16107117f1b4Smrg   }
16117117f1b4Smrg
16127e995a2eSmrg   if (curCtx &&
16133464ebd5Sriastradh       /* make sure this context is valid for flushing */
16147e995a2eSmrg       curCtx != newCtx &&
16157e995a2eSmrg       curCtx->Const.ContextReleaseBehavior ==
16167e995a2eSmrg       GL_CONTEXT_RELEASE_BEHAVIOR_FLUSH) {
16171463c08dSmrg      FLUSH_VERTICES(curCtx, 0, 0);
16181463c08dSmrg      if (curCtx->Driver.Flush)
16191463c08dSmrg         curCtx->Driver.Flush(curCtx, 0);
16207e995a2eSmrg   }
16213464ebd5Sriastradh
16227e995a2eSmrg   /* Call this periodically to detect when the user has begun using
16237e995a2eSmrg    * GL rendering from multiple threads.
16247e995a2eSmrg    */
16257e995a2eSmrg   _glapi_check_multithread();
16267117f1b4Smrg
16277117f1b4Smrg   if (!newCtx) {
16287117f1b4Smrg      _glapi_set_dispatch(NULL);  /* none current */
16297e995a2eSmrg      /* We need old ctx to correctly release Draw/ReadBuffer
16307e995a2eSmrg       * and avoid a surface leak in st_renderbuffer_delete.
16317e995a2eSmrg       * Therefore, first drop buffers then set new ctx to NULL.
16327e995a2eSmrg       */
16337e995a2eSmrg      if (curCtx) {
16347e995a2eSmrg         _mesa_reference_framebuffer(&curCtx->WinSysDrawBuffer, NULL);
16357e995a2eSmrg         _mesa_reference_framebuffer(&curCtx->WinSysReadBuffer, NULL);
16367e995a2eSmrg      }
16377e995a2eSmrg      _glapi_set_context(NULL);
16387e995a2eSmrg      assert(_mesa_get_current_context() == NULL);
16397117f1b4Smrg   }
16407117f1b4Smrg   else {
16417e995a2eSmrg      _glapi_set_context((void *) newCtx);
16427e995a2eSmrg      assert(_mesa_get_current_context() == newCtx);
16437e995a2eSmrg      _glapi_set_dispatch(newCtx->CurrentClientDispatch);
16447117f1b4Smrg
16457117f1b4Smrg      if (drawBuffer && readBuffer) {
16467e995a2eSmrg         assert(_mesa_is_winsys_fbo(drawBuffer));
16477e995a2eSmrg         assert(_mesa_is_winsys_fbo(readBuffer));
16487117f1b4Smrg         _mesa_reference_framebuffer(&newCtx->WinSysDrawBuffer, drawBuffer);
16497117f1b4Smrg         _mesa_reference_framebuffer(&newCtx->WinSysReadBuffer, readBuffer);
16507117f1b4Smrg
16517117f1b4Smrg         /*
16527117f1b4Smrg          * Only set the context's Draw/ReadBuffer fields if they're NULL
16537117f1b4Smrg          * or not bound to a user-created FBO.
16547117f1b4Smrg          */
1655b167d5e7Smrg         if (!newCtx->DrawBuffer || _mesa_is_winsys_fbo(newCtx->DrawBuffer)) {
16567117f1b4Smrg            _mesa_reference_framebuffer(&newCtx->DrawBuffer, drawBuffer);
16573464ebd5Sriastradh            /* Update the FBO's list of drawbuffers/renderbuffers.
16583464ebd5Sriastradh             * For winsys FBOs this comes from the GL state (which may have
16593464ebd5Sriastradh             * changed since the last time this FBO was bound).
16603464ebd5Sriastradh             */
16613464ebd5Sriastradh            _mesa_update_draw_buffers(newCtx);
16621463c08dSmrg            _mesa_update_allow_draw_out_of_order(newCtx);
16631463c08dSmrg            _mesa_update_valid_to_render_state(newCtx);
16647117f1b4Smrg         }
1665b167d5e7Smrg         if (!newCtx->ReadBuffer || _mesa_is_winsys_fbo(newCtx->ReadBuffer)) {
16667117f1b4Smrg            _mesa_reference_framebuffer(&newCtx->ReadBuffer, readBuffer);
16677e995a2eSmrg            /* In _mesa_initialize_window_framebuffer, for single-buffered
16687e995a2eSmrg             * visuals, the ColorReadBuffer is set to be GL_FRONT, even with
16697e995a2eSmrg             * GLES contexts. When calling read_buffer, we verify we are reading
16707e995a2eSmrg             * from GL_BACK in is_legal_es3_readbuffer_enum.  But the default is
16717e995a2eSmrg             * incorrect, and certain dEQP tests check this.  So fix it here.
16727e995a2eSmrg             */
16737e995a2eSmrg            if (_mesa_is_gles(newCtx) &&
16747e995a2eSmrg               !newCtx->ReadBuffer->Visual.doubleBufferMode)
16757e995a2eSmrg               if (newCtx->ReadBuffer->ColorReadBuffer == GL_FRONT)
16767e995a2eSmrg                  newCtx->ReadBuffer->ColorReadBuffer = GL_BACK;
16777117f1b4Smrg         }
16787117f1b4Smrg
1679c1f859d4Smrg         /* XXX only set this flag if we're really changing the draw/read
1680c1f859d4Smrg          * framebuffer bindings.
1681c1f859d4Smrg          */
16827e995a2eSmrg         newCtx->NewState |= _NEW_BUFFERS;
16837117f1b4Smrg
16847e995a2eSmrg         check_init_viewport(newCtx, drawBuffer->Width, drawBuffer->Height);
16857117f1b4Smrg      }
16867117f1b4Smrg
16877117f1b4Smrg      if (newCtx->FirstTimeCurrent) {
1688b167d5e7Smrg         handle_first_current(newCtx);
16897e995a2eSmrg         newCtx->FirstTimeCurrent = GL_FALSE;
16907117f1b4Smrg      }
16917117f1b4Smrg   }
16927e995a2eSmrg
16934a49301eSmrg   return GL_TRUE;
16947117f1b4Smrg}
16957117f1b4Smrg
16967117f1b4Smrg
16977117f1b4Smrg/**
16987117f1b4Smrg * Make context 'ctx' share the display lists, textures and programs
16997117f1b4Smrg * that are associated with 'ctxToShare'.
17007117f1b4Smrg * Any display lists, textures or programs associated with 'ctx' will
17017117f1b4Smrg * be deleted if nobody else is sharing them.
17027117f1b4Smrg */
17037117f1b4SmrgGLboolean
17043464ebd5Sriastradh_mesa_share_state(struct gl_context *ctx, struct gl_context *ctxToShare)
17057117f1b4Smrg{
17067117f1b4Smrg   if (ctx && ctxToShare && ctx->Shared && ctxToShare->Shared) {
1707b167d5e7Smrg      struct gl_shared_state *oldShared = NULL;
1708b167d5e7Smrg
1709b167d5e7Smrg      /* save ref to old state to prevent it from being deleted immediately */
1710b167d5e7Smrg      _mesa_reference_shared_state(ctx, &oldShared, ctx->Shared);
1711c1f859d4Smrg
1712b167d5e7Smrg      /* update ctx's Shared pointer */
1713b167d5e7Smrg      _mesa_reference_shared_state(ctx, &ctx->Shared, ctxToShare->Shared);
1714c1f859d4Smrg
1715c1f859d4Smrg      update_default_objects(ctx);
1716c1f859d4Smrg
1717b167d5e7Smrg      /* release the old shared state */
1718b167d5e7Smrg      _mesa_reference_shared_state(ctx, &oldShared, NULL);
1719c1f859d4Smrg
17207117f1b4Smrg      return GL_TRUE;
17217117f1b4Smrg   }
17227117f1b4Smrg   else {
17237117f1b4Smrg      return GL_FALSE;
17247117f1b4Smrg   }
17257117f1b4Smrg}
17267117f1b4Smrg
17277117f1b4Smrg
17287117f1b4Smrg
17297117f1b4Smrg/**
17307117f1b4Smrg * \return pointer to the current GL context for this thread.
17317e995a2eSmrg *
17327117f1b4Smrg * Calls _glapi_get_context(). This isn't the fastest way to get the current
17337117f1b4Smrg * context.  If you need speed, see the #GET_CURRENT_CONTEXT macro in
17347117f1b4Smrg * context.h.
17357117f1b4Smrg */
17363464ebd5Sriastradhstruct gl_context *
17377117f1b4Smrg_mesa_get_current_context( void )
17387117f1b4Smrg{
17393464ebd5Sriastradh   return (struct gl_context *) _glapi_get_context();
17407117f1b4Smrg}
17417117f1b4Smrg
17427117f1b4Smrg
17437117f1b4Smrg/**
17447117f1b4Smrg * Get context's current API dispatch table.
17457117f1b4Smrg *
17467e995a2eSmrg * It'll either be the immediate-mode execute dispatcher, the display list
17477e995a2eSmrg * compile dispatcher, or the thread marshalling dispatcher.
17487e995a2eSmrg *
17497117f1b4Smrg * \param ctx GL context.
17507117f1b4Smrg *
17517117f1b4Smrg * \return pointer to dispatch_table.
17527117f1b4Smrg *
17537e995a2eSmrg * Simply returns __struct gl_contextRec::CurrentClientDispatch.
17547117f1b4Smrg */
17557117f1b4Smrgstruct _glapi_table *
17563464ebd5Sriastradh_mesa_get_dispatch(struct gl_context *ctx)
17577117f1b4Smrg{
17587e995a2eSmrg   return ctx->CurrentClientDispatch;
17597117f1b4Smrg}
17607117f1b4Smrg
17617117f1b4Smrg/*@}*/
17627117f1b4Smrg
17637117f1b4Smrg
17647117f1b4Smrg/**********************************************************************/
17657117f1b4Smrg/** \name Miscellaneous functions                                     */
17667117f1b4Smrg/**********************************************************************/
17677117f1b4Smrg/*@{*/
17684a49301eSmrg/**
17694a49301eSmrg * Flush commands.
17704a49301eSmrg */
17714a49301eSmrgvoid
17723464ebd5Sriastradh_mesa_flush(struct gl_context *ctx)
17734a49301eSmrg{
17741463c08dSmrg   FLUSH_VERTICES(ctx, 0, 0);
17754a49301eSmrg   if (ctx->Driver.Flush) {
17761463c08dSmrg      bool async = !ctx->Shared->HasExternallySharedImages;
17771463c08dSmrg
17781463c08dSmrg      ctx->Driver.Flush(ctx, async ? PIPE_FLUSH_ASYNC : 0);
17794a49301eSmrg   }
17804a49301eSmrg}
17814a49301eSmrg
17824a49301eSmrg
17834a49301eSmrg
17847117f1b4Smrg/**
17857e995a2eSmrg * Flush commands and wait for completion.
17867117f1b4Smrg *
17877117f1b4Smrg * Calls the #ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH macro and the
17887117f1b4Smrg * dd_function_table::Finish driver callback, if not NULL.
17897117f1b4Smrg */
17907117f1b4Smrgvoid GLAPIENTRY
17917117f1b4Smrg_mesa_Finish(void)
17927117f1b4Smrg{
17937117f1b4Smrg   GET_CURRENT_CONTEXT(ctx);
1794b167d5e7Smrg   ASSERT_OUTSIDE_BEGIN_END(ctx);
17957e995a2eSmrg
17961463c08dSmrg   FLUSH_VERTICES(ctx, 0, 0);
17977e995a2eSmrg
17987e995a2eSmrg   if (ctx->Driver.Finish) {
17997e995a2eSmrg      ctx->Driver.Finish(ctx);
18007e995a2eSmrg   }
18017117f1b4Smrg}
18027117f1b4Smrg
18037117f1b4Smrg
18047117f1b4Smrg/**
18057117f1b4Smrg * Execute glFlush().
18067117f1b4Smrg *
18077117f1b4Smrg * Calls the #ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH macro and the
18087117f1b4Smrg * dd_function_table::Flush driver callback, if not NULL.
18097117f1b4Smrg */
18107117f1b4Smrgvoid GLAPIENTRY
18117117f1b4Smrg_mesa_Flush(void)
18127117f1b4Smrg{
18137117f1b4Smrg   GET_CURRENT_CONTEXT(ctx);
1814b167d5e7Smrg   ASSERT_OUTSIDE_BEGIN_END(ctx);
18154a49301eSmrg   _mesa_flush(ctx);
18164a49301eSmrg}
18174a49301eSmrg
18184a49301eSmrg
18197117f1b4Smrg/*@}*/
1820