context.c revision b167d5e7
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"
867117f1b4Smrg#include "blend.h"
877117f1b4Smrg#include "buffers.h"
887117f1b4Smrg#include "bufferobj.h"
897117f1b4Smrg#include "context.h"
904a49301eSmrg#include "cpuinfo.h"
917117f1b4Smrg#include "debug.h"
927117f1b4Smrg#include "depth.h"
937117f1b4Smrg#include "dlist.h"
947117f1b4Smrg#include "eval.h"
957117f1b4Smrg#include "extensions.h"
967117f1b4Smrg#include "fbobject.h"
977117f1b4Smrg#include "feedback.h"
987117f1b4Smrg#include "fog.h"
993464ebd5Sriastradh#include "formats.h"
1007117f1b4Smrg#include "framebuffer.h"
1017117f1b4Smrg#include "hint.h"
1027117f1b4Smrg#include "hash.h"
1037117f1b4Smrg#include "light.h"
1047117f1b4Smrg#include "lines.h"
1057117f1b4Smrg#include "macros.h"
1067117f1b4Smrg#include "matrix.h"
107c1f859d4Smrg#include "multisample.h"
108b167d5e7Smrg#include "performance_monitor.h"
109b167d5e7Smrg#include "pipelineobj.h"
1107117f1b4Smrg#include "pixel.h"
111c1f859d4Smrg#include "pixelstore.h"
1127117f1b4Smrg#include "points.h"
1137117f1b4Smrg#include "polygon.h"
1147117f1b4Smrg#include "queryobj.h"
1154a49301eSmrg#include "syncobj.h"
1167117f1b4Smrg#include "rastpos.h"
1174a49301eSmrg#include "remap.h"
118c1f859d4Smrg#include "scissor.h"
1194a49301eSmrg#include "shared.h"
1203464ebd5Sriastradh#include "shaderobj.h"
1217117f1b4Smrg#include "simple_list.h"
1227117f1b4Smrg#include "state.h"
1237117f1b4Smrg#include "stencil.h"
1244a49301eSmrg#include "texcompress_s3tc.h"
1257117f1b4Smrg#include "texstate.h"
1263464ebd5Sriastradh#include "transformfeedback.h"
1277117f1b4Smrg#include "mtypes.h"
1287117f1b4Smrg#include "varray.h"
1297117f1b4Smrg#include "version.h"
1304a49301eSmrg#include "viewport.h"
1317117f1b4Smrg#include "vtxfmt.h"
1323464ebd5Sriastradh#include "program/program.h"
1333464ebd5Sriastradh#include "program/prog_print.h"
1347117f1b4Smrg#include "math/m_matrix.h"
1353464ebd5Sriastradh#include "main/dispatch.h" /* for _gloffset_COUNT */
1367117f1b4Smrg
1377117f1b4Smrg#ifdef USE_SPARC_ASM
1387117f1b4Smrg#include "sparc/sparc.h"
1397117f1b4Smrg#endif
1407117f1b4Smrg
1413464ebd5Sriastradh#include "glsl_parser_extras.h"
1423464ebd5Sriastradh#include <stdbool.h>
1433464ebd5Sriastradh
1443464ebd5Sriastradh
1457117f1b4Smrg#ifndef MESA_VERBOSE
1467117f1b4Smrgint MESA_VERBOSE = 0;
1477117f1b4Smrg#endif
1487117f1b4Smrg
1497117f1b4Smrg#ifndef MESA_DEBUG_FLAGS
1507117f1b4Smrgint MESA_DEBUG_FLAGS = 0;
1517117f1b4Smrg#endif
1527117f1b4Smrg
1537117f1b4Smrg
1547117f1b4Smrg/* ubyte -> float conversion */
1557117f1b4SmrgGLfloat _mesa_ubyte_to_float_color_tab[256];
1567117f1b4Smrg
1577117f1b4Smrg
1587117f1b4Smrg
1597117f1b4Smrg/**
1607117f1b4Smrg * Swap buffers notification callback.
1617117f1b4Smrg *
1624a49301eSmrg * \param ctx GL context.
1637117f1b4Smrg *
1647117f1b4Smrg * Called by window system just before swapping buffers.
1657117f1b4Smrg * We have to finish any pending rendering.
1667117f1b4Smrg */
1677117f1b4Smrgvoid
1683464ebd5Sriastradh_mesa_notifySwapBuffers(struct gl_context *ctx)
1697117f1b4Smrg{
1704a49301eSmrg   if (MESA_VERBOSE & VERBOSE_SWAPBUFFERS)
1714a49301eSmrg      _mesa_debug(ctx, "SwapBuffers\n");
1724a49301eSmrg   FLUSH_CURRENT( ctx, 0 );
1734a49301eSmrg   if (ctx->Driver.Flush) {
1744a49301eSmrg      ctx->Driver.Flush(ctx);
1754a49301eSmrg   }
1767117f1b4Smrg}
1777117f1b4Smrg
1787117f1b4Smrg
1797117f1b4Smrg/**********************************************************************/
1807117f1b4Smrg/** \name GL Visual allocation/destruction                            */
1817117f1b4Smrg/**********************************************************************/
1827117f1b4Smrg/*@{*/
1837117f1b4Smrg
1847117f1b4Smrg/**
1853464ebd5Sriastradh * Allocates a struct gl_config structure and initializes it via
1867117f1b4Smrg * _mesa_initialize_visual().
1877117f1b4Smrg *
1887117f1b4Smrg * \param dbFlag double buffering
1897117f1b4Smrg * \param stereoFlag stereo buffer
1907117f1b4Smrg * \param depthBits requested bits per depth buffer value. Any value in [0, 32]
1917117f1b4Smrg * is acceptable but the actual depth type will be GLushort or GLuint as
1927117f1b4Smrg * needed.
1937117f1b4Smrg * \param stencilBits requested minimum bits per stencil buffer value
1943464ebd5Sriastradh * \param accumRedBits, accumGreenBits, accumBlueBits, accumAlphaBits number
1953464ebd5Sriastradh * of bits per color component in accum buffer.
1967117f1b4Smrg * \param indexBits number of bits per pixel if \p rgbFlag is GL_FALSE
1977117f1b4Smrg * \param redBits number of bits per color component in frame buffer for RGB(A)
1987117f1b4Smrg * mode.  We always use 8 in core Mesa though.
1997117f1b4Smrg * \param greenBits same as above.
2007117f1b4Smrg * \param blueBits same as above.
2017117f1b4Smrg * \param alphaBits same as above.
2027117f1b4Smrg * \param numSamples not really used.
2037117f1b4Smrg *
2043464ebd5Sriastradh * \return pointer to new struct gl_config or NULL if requested parameters
2053464ebd5Sriastradh * can't be met.
2067117f1b4Smrg *
2077117f1b4Smrg * \note Need to add params for level and numAuxBuffers (at least)
2087117f1b4Smrg */
2093464ebd5Sriastradhstruct gl_config *
210cdc920a0Smrg_mesa_create_visual( GLboolean dbFlag,
2117117f1b4Smrg                     GLboolean stereoFlag,
2127117f1b4Smrg                     GLint redBits,
2137117f1b4Smrg                     GLint greenBits,
2147117f1b4Smrg                     GLint blueBits,
2157117f1b4Smrg                     GLint alphaBits,
2167117f1b4Smrg                     GLint depthBits,
2177117f1b4Smrg                     GLint stencilBits,
2187117f1b4Smrg                     GLint accumRedBits,
2197117f1b4Smrg                     GLint accumGreenBits,
2207117f1b4Smrg                     GLint accumBlueBits,
2217117f1b4Smrg                     GLint accumAlphaBits,
2227117f1b4Smrg                     GLint numSamples )
2237117f1b4Smrg{
2243464ebd5Sriastradh   struct gl_config *vis = CALLOC_STRUCT(gl_config);
2257117f1b4Smrg   if (vis) {
226cdc920a0Smrg      if (!_mesa_initialize_visual(vis, dbFlag, stereoFlag,
2277117f1b4Smrg                                   redBits, greenBits, blueBits, alphaBits,
228cdc920a0Smrg                                   depthBits, stencilBits,
2297117f1b4Smrg                                   accumRedBits, accumGreenBits,
2307117f1b4Smrg                                   accumBlueBits, accumAlphaBits,
2317117f1b4Smrg                                   numSamples)) {
232cdc920a0Smrg         free(vis);
2337117f1b4Smrg         return NULL;
2347117f1b4Smrg      }
2357117f1b4Smrg   }
2367117f1b4Smrg   return vis;
2377117f1b4Smrg}
2387117f1b4Smrg
2393464ebd5Sriastradh
2407117f1b4Smrg/**
2413464ebd5Sriastradh * Makes some sanity checks and fills in the fields of the struct
2423464ebd5Sriastradh * gl_config object with the given parameters.  If the caller needs to
2433464ebd5Sriastradh * set additional fields, he should just probably init the whole
2443464ebd5Sriastradh * gl_config object himself.
2453464ebd5Sriastradh *
2467117f1b4Smrg * \return GL_TRUE on success, or GL_FALSE on failure.
2477117f1b4Smrg *
2487117f1b4Smrg * \sa _mesa_create_visual() above for the parameter description.
2497117f1b4Smrg */
2507117f1b4SmrgGLboolean
2513464ebd5Sriastradh_mesa_initialize_visual( struct gl_config *vis,
2527117f1b4Smrg                         GLboolean dbFlag,
2537117f1b4Smrg                         GLboolean stereoFlag,
2547117f1b4Smrg                         GLint redBits,
2557117f1b4Smrg                         GLint greenBits,
2567117f1b4Smrg                         GLint blueBits,
2577117f1b4Smrg                         GLint alphaBits,
2587117f1b4Smrg                         GLint depthBits,
2597117f1b4Smrg                         GLint stencilBits,
2607117f1b4Smrg                         GLint accumRedBits,
2617117f1b4Smrg                         GLint accumGreenBits,
2627117f1b4Smrg                         GLint accumBlueBits,
2637117f1b4Smrg                         GLint accumAlphaBits,
2647117f1b4Smrg                         GLint numSamples )
2657117f1b4Smrg{
2667117f1b4Smrg   assert(vis);
2677117f1b4Smrg
2687117f1b4Smrg   if (depthBits < 0 || depthBits > 32) {
2697117f1b4Smrg      return GL_FALSE;
2707117f1b4Smrg   }
271b167d5e7Smrg   if (stencilBits < 0 || stencilBits > 8) {
2727117f1b4Smrg      return GL_FALSE;
2737117f1b4Smrg   }
2747117f1b4Smrg   assert(accumRedBits >= 0);
2757117f1b4Smrg   assert(accumGreenBits >= 0);
2767117f1b4Smrg   assert(accumBlueBits >= 0);
2777117f1b4Smrg   assert(accumAlphaBits >= 0);
2787117f1b4Smrg
279cdc920a0Smrg   vis->rgbMode          = GL_TRUE;
2807117f1b4Smrg   vis->doubleBufferMode = dbFlag;
2817117f1b4Smrg   vis->stereoMode       = stereoFlag;
2827117f1b4Smrg
2837117f1b4Smrg   vis->redBits          = redBits;
2847117f1b4Smrg   vis->greenBits        = greenBits;
2857117f1b4Smrg   vis->blueBits         = blueBits;
2867117f1b4Smrg   vis->alphaBits        = alphaBits;
2877117f1b4Smrg   vis->rgbBits          = redBits + greenBits + blueBits;
2887117f1b4Smrg
289cdc920a0Smrg   vis->indexBits      = 0;
2907117f1b4Smrg   vis->depthBits      = depthBits;
2917117f1b4Smrg   vis->stencilBits    = stencilBits;
2927117f1b4Smrg
2937117f1b4Smrg   vis->accumRedBits   = accumRedBits;
2947117f1b4Smrg   vis->accumGreenBits = accumGreenBits;
2957117f1b4Smrg   vis->accumBlueBits  = accumBlueBits;
2967117f1b4Smrg   vis->accumAlphaBits = accumAlphaBits;
2977117f1b4Smrg
2987117f1b4Smrg   vis->haveAccumBuffer   = accumRedBits > 0;
2997117f1b4Smrg   vis->haveDepthBuffer   = depthBits > 0;
3007117f1b4Smrg   vis->haveStencilBuffer = stencilBits > 0;
3017117f1b4Smrg
3027117f1b4Smrg   vis->numAuxBuffers = 0;
3037117f1b4Smrg   vis->level = 0;
3047117f1b4Smrg   vis->sampleBuffers = numSamples > 0 ? 1 : 0;
3057117f1b4Smrg   vis->samples = numSamples;
3067117f1b4Smrg
3077117f1b4Smrg   return GL_TRUE;
3087117f1b4Smrg}
3097117f1b4Smrg
3107117f1b4Smrg
3117117f1b4Smrg/**
3127117f1b4Smrg * Destroy a visual and free its memory.
3137117f1b4Smrg *
3147117f1b4Smrg * \param vis visual.
3157117f1b4Smrg *
3167117f1b4Smrg * Frees the visual structure.
3177117f1b4Smrg */
3187117f1b4Smrgvoid
3193464ebd5Sriastradh_mesa_destroy_visual( struct gl_config *vis )
3207117f1b4Smrg{
321cdc920a0Smrg   free(vis);
3227117f1b4Smrg}
3237117f1b4Smrg
3247117f1b4Smrg/*@}*/
3257117f1b4Smrg
3267117f1b4Smrg
3277117f1b4Smrg/**********************************************************************/
3287117f1b4Smrg/** \name Context allocation, initialization, destroying
3297117f1b4Smrg *
3307117f1b4Smrg * The purpose of the most initialization functions here is to provide the
3317117f1b4Smrg * default state values according to the OpenGL specification.
3327117f1b4Smrg */
3337117f1b4Smrg/**********************************************************************/
3347117f1b4Smrg/*@{*/
3357117f1b4Smrg
3364a49301eSmrg
3374a49301eSmrg/**
3384a49301eSmrg * This is lame.  gdb only seems to recognize enum types that are
3394a49301eSmrg * actually used somewhere.  We want to be able to print/use enum
3404a49301eSmrg * values such as TEXTURE_2D_INDEX in gdb.  But we don't actually use
3414a49301eSmrg * the gl_texture_index type anywhere.  Thus, this lame function.
3424a49301eSmrg */
3434a49301eSmrgstatic void
3444a49301eSmrgdummy_enum_func(void)
3454a49301eSmrg{
3463464ebd5Sriastradh   gl_buffer_index bi = BUFFER_FRONT_LEFT;
3473464ebd5Sriastradh   gl_face_index fi = FACE_POS_X;
3483464ebd5Sriastradh   gl_frag_result fr = FRAG_RESULT_DEPTH;
3493464ebd5Sriastradh   gl_texture_index ti = TEXTURE_2D_ARRAY_INDEX;
3503464ebd5Sriastradh   gl_vert_attrib va = VERT_ATTRIB_POS;
351b167d5e7Smrg   gl_varying_slot vs = VARYING_SLOT_POS;
3524a49301eSmrg
3534a49301eSmrg   (void) bi;
3544a49301eSmrg   (void) fi;
3554a49301eSmrg   (void) fr;
3564a49301eSmrg   (void) ti;
3574a49301eSmrg   (void) va;
358b167d5e7Smrg   (void) vs;
3594a49301eSmrg}
3604a49301eSmrg
3614a49301eSmrg
3627117f1b4Smrg/**
3637117f1b4Smrg * One-time initialization mutex lock.
3647117f1b4Smrg *
3657117f1b4Smrg * \sa Used by one_time_init().
3667117f1b4Smrg */
367b167d5e7Smrgmtx_t OneTimeLock = _MTX_INITIALIZER_NP;
3687117f1b4Smrg
3693464ebd5Sriastradh
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 */
380eabf4f72Sriastradhstatic GLbitfield api_init_mask = 0x0;
3817117f1b4Smrgstatic void
3823464ebd5Sriastradhone_time_init( struct gl_context *ctx )
3837117f1b4Smrg{
3843464ebd5Sriastradh
385b167d5e7Smrg   mtx_lock(&OneTimeLock);
3863464ebd5Sriastradh
3873464ebd5Sriastradh   /* truly one-time init */
3883464ebd5Sriastradh   if (!api_init_mask) {
3897117f1b4Smrg      GLuint i;
3907117f1b4Smrg
3917117f1b4Smrg      /* do some implementation tests */
3927117f1b4Smrg      assert( sizeof(GLbyte) == 1 );
3937117f1b4Smrg      assert( sizeof(GLubyte) == 1 );
3947117f1b4Smrg      assert( sizeof(GLshort) == 2 );
3957117f1b4Smrg      assert( sizeof(GLushort) == 2 );
3967117f1b4Smrg      assert( sizeof(GLint) == 4 );
3977117f1b4Smrg      assert( sizeof(GLuint) == 4 );
3987117f1b4Smrg
399b167d5e7Smrg      _mesa_one_time_init_extension_overrides();
4007117f1b4Smrg
401b167d5e7Smrg      _mesa_get_cpu_features();
4023464ebd5Sriastradh
4037117f1b4Smrg      for (i = 0; i < 256; i++) {
4047117f1b4Smrg         _mesa_ubyte_to_float_color_tab[i] = (float) i / 255.0F;
4057117f1b4Smrg      }
4067117f1b4Smrg
4077117f1b4Smrg#if defined(DEBUG) && defined(__DATE__) && defined(__TIME__)
4083464ebd5Sriastradh      if (MESA_VERBOSE != 0) {
4093464ebd5Sriastradh	 _mesa_debug(ctx, "Mesa %s DEBUG build %s %s\n",
410b167d5e7Smrg		     PACKAGE_VERSION, __DATE__, __TIME__);
4113464ebd5Sriastradh      }
4127117f1b4Smrg#endif
4137117f1b4Smrg
4143464ebd5Sriastradh#ifdef DEBUG
4153464ebd5Sriastradh      _mesa_test_formats();
4163464ebd5Sriastradh#endif
4177117f1b4Smrg   }
4183464ebd5Sriastradh
4193464ebd5Sriastradh   /* per-API one-time init */
4203464ebd5Sriastradh   if (!(api_init_mask & (1 << ctx->API))) {
421b167d5e7Smrg      _mesa_init_get_hash(ctx);
422b167d5e7Smrg
423b167d5e7Smrg      _mesa_init_remap_table();
4243464ebd5Sriastradh   }
4253464ebd5Sriastradh
4263464ebd5Sriastradh   api_init_mask |= 1 << ctx->API;
4273464ebd5Sriastradh
428b167d5e7Smrg   mtx_unlock(&OneTimeLock);
4297117f1b4Smrg
4304a49301eSmrg   dummy_enum_func();
4317117f1b4Smrg}
4327117f1b4Smrg
433eabf4f72Sriastradhstatic void __attribute__((__destructor__))
434eabf4f72Sriastradhone_time_fini(void)
435eabf4f72Sriastradh{
436eabf4f72Sriastradh  if (api_init_mask)
437eabf4f72Sriastradh    _mesa_destroy_shader_compiler();
438eabf4f72Sriastradh}
439eabf4f72Sriastradh
4407117f1b4Smrg
4417117f1b4Smrg/**
4427117f1b4Smrg * Initialize fields of gl_current_attrib (aka ctx->Current.*)
4437117f1b4Smrg */
4447117f1b4Smrgstatic void
4453464ebd5Sriastradh_mesa_init_current(struct gl_context *ctx)
4467117f1b4Smrg{
4477117f1b4Smrg   GLuint i;
4487117f1b4Smrg
4497117f1b4Smrg   /* Init all to (0,0,0,1) */
4504a49301eSmrg   for (i = 0; i < Elements(ctx->Current.Attrib); i++) {
4517117f1b4Smrg      ASSIGN_4V( ctx->Current.Attrib[i], 0.0, 0.0, 0.0, 1.0 );
4527117f1b4Smrg   }
4537117f1b4Smrg
4547117f1b4Smrg   /* redo special cases: */
4557117f1b4Smrg   ASSIGN_4V( ctx->Current.Attrib[VERT_ATTRIB_WEIGHT], 1.0, 0.0, 0.0, 0.0 );
4567117f1b4Smrg   ASSIGN_4V( ctx->Current.Attrib[VERT_ATTRIB_NORMAL], 0.0, 0.0, 1.0, 1.0 );
4577117f1b4Smrg   ASSIGN_4V( ctx->Current.Attrib[VERT_ATTRIB_COLOR0], 1.0, 1.0, 1.0, 1.0 );
4587117f1b4Smrg   ASSIGN_4V( ctx->Current.Attrib[VERT_ATTRIB_COLOR1], 0.0, 0.0, 0.0, 1.0 );
4597117f1b4Smrg   ASSIGN_4V( ctx->Current.Attrib[VERT_ATTRIB_COLOR_INDEX], 1.0, 0.0, 0.0, 1.0 );
4607117f1b4Smrg   ASSIGN_4V( ctx->Current.Attrib[VERT_ATTRIB_EDGEFLAG], 1.0, 0.0, 0.0, 1.0 );
4617117f1b4Smrg}
4627117f1b4Smrg
4637117f1b4Smrg
4647117f1b4Smrg/**
4653464ebd5Sriastradh * Init vertex/fragment/geometry program limits.
4664a49301eSmrg * Important: drivers should override these with actual limits.
4677117f1b4Smrg */
4687117f1b4Smrgstatic void
469b167d5e7Smrginit_program_limits(struct gl_constants *consts, gl_shader_stage stage,
470b167d5e7Smrg                    struct gl_program_constants *prog)
4717117f1b4Smrg{
4724a49301eSmrg   prog->MaxInstructions = MAX_PROGRAM_INSTRUCTIONS;
4734a49301eSmrg   prog->MaxAluInstructions = MAX_PROGRAM_INSTRUCTIONS;
4744a49301eSmrg   prog->MaxTexInstructions = MAX_PROGRAM_INSTRUCTIONS;
4754a49301eSmrg   prog->MaxTexIndirections = MAX_PROGRAM_INSTRUCTIONS;
4764a49301eSmrg   prog->MaxTemps = MAX_PROGRAM_TEMPS;
4774a49301eSmrg   prog->MaxEnvParams = MAX_PROGRAM_ENV_PARAMS;
4784a49301eSmrg   prog->MaxLocalParams = MAX_PROGRAM_LOCAL_PARAMS;
4793464ebd5Sriastradh   prog->MaxAddressOffset = MAX_PROGRAM_LOCAL_PARAMS;
4804a49301eSmrg
481b167d5e7Smrg   switch (stage) {
482b167d5e7Smrg   case MESA_SHADER_VERTEX:
4834a49301eSmrg      prog->MaxParameters = MAX_VERTEX_PROGRAM_PARAMS;
484b167d5e7Smrg      prog->MaxAttribs = MAX_VERTEX_GENERIC_ATTRIBS;
4854a49301eSmrg      prog->MaxAddressRegs = MAX_VERTEX_PROGRAM_ADDRESS_REGS;
4863464ebd5Sriastradh      prog->MaxUniformComponents = 4 * MAX_UNIFORMS;
487b167d5e7Smrg      prog->MaxInputComponents = 0; /* value not used */
488b167d5e7Smrg      prog->MaxOutputComponents = 16 * 4; /* old limit not to break tnl and swrast */
4893464ebd5Sriastradh      break;
490b167d5e7Smrg   case MESA_SHADER_FRAGMENT:
4914a49301eSmrg      prog->MaxParameters = MAX_NV_FRAGMENT_PROGRAM_PARAMS;
4924a49301eSmrg      prog->MaxAttribs = MAX_NV_FRAGMENT_PROGRAM_INPUTS;
4934a49301eSmrg      prog->MaxAddressRegs = MAX_FRAGMENT_PROGRAM_ADDRESS_REGS;
4943464ebd5Sriastradh      prog->MaxUniformComponents = 4 * MAX_UNIFORMS;
495b167d5e7Smrg      prog->MaxInputComponents = 16 * 4; /* old limit not to break tnl and swrast */
496b167d5e7Smrg      prog->MaxOutputComponents = 0; /* value not used */
4973464ebd5Sriastradh      break;
498b167d5e7Smrg   case MESA_SHADER_GEOMETRY:
499b167d5e7Smrg      prog->MaxParameters = MAX_VERTEX_PROGRAM_PARAMS;
500b167d5e7Smrg      prog->MaxAttribs = MAX_VERTEX_GENERIC_ATTRIBS;
5013464ebd5Sriastradh      prog->MaxAddressRegs = MAX_VERTEX_PROGRAM_ADDRESS_REGS;
502b167d5e7Smrg      prog->MaxUniformComponents = 4 * MAX_UNIFORMS;
503b167d5e7Smrg      prog->MaxInputComponents = 16 * 4; /* old limit not to break tnl and swrast */
504b167d5e7Smrg      prog->MaxOutputComponents = 16 * 4; /* old limit not to break tnl and swrast */
505b167d5e7Smrg      break;
506b167d5e7Smrg   case MESA_SHADER_COMPUTE:
507b167d5e7Smrg      prog->MaxParameters = 0; /* not meaningful for compute shaders */
508b167d5e7Smrg      prog->MaxAttribs = 0; /* not meaningful for compute shaders */
509b167d5e7Smrg      prog->MaxAddressRegs = 0; /* not meaningful for compute shaders */
510b167d5e7Smrg      prog->MaxUniformComponents = 4 * MAX_UNIFORMS;
511b167d5e7Smrg      prog->MaxInputComponents = 0; /* not meaningful for compute shaders */
512b167d5e7Smrg      prog->MaxOutputComponents = 0; /* not meaningful for compute shaders */
5133464ebd5Sriastradh      break;
5143464ebd5Sriastradh   default:
515b167d5e7Smrg      assert(0 && "Bad shader stage in init_program_limits()");
5164a49301eSmrg   }
5174a49301eSmrg
5184a49301eSmrg   /* Set the native limits to zero.  This implies that there is no native
5194a49301eSmrg    * support for shaders.  Let the drivers fill in the actual values.
5204a49301eSmrg    */
5214a49301eSmrg   prog->MaxNativeInstructions = 0;
5224a49301eSmrg   prog->MaxNativeAluInstructions = 0;
5234a49301eSmrg   prog->MaxNativeTexInstructions = 0;
5244a49301eSmrg   prog->MaxNativeTexIndirections = 0;
5254a49301eSmrg   prog->MaxNativeAttribs = 0;
5264a49301eSmrg   prog->MaxNativeTemps = 0;
5274a49301eSmrg   prog->MaxNativeAddressRegs = 0;
5284a49301eSmrg   prog->MaxNativeParameters = 0;
5293464ebd5Sriastradh
5303464ebd5Sriastradh   /* Set GLSL datatype range/precision info assuming IEEE float values.
5313464ebd5Sriastradh    * Drivers should override these defaults as needed.
5323464ebd5Sriastradh    */
5333464ebd5Sriastradh   prog->MediumFloat.RangeMin = 127;
5343464ebd5Sriastradh   prog->MediumFloat.RangeMax = 127;
5353464ebd5Sriastradh   prog->MediumFloat.Precision = 23;
5363464ebd5Sriastradh   prog->LowFloat = prog->HighFloat = prog->MediumFloat;
5373464ebd5Sriastradh
5383464ebd5Sriastradh   /* Assume ints are stored as floats for now, since this is the least-common
5393464ebd5Sriastradh    * denominator.  The OpenGL ES spec implies (page 132) that the precision
5403464ebd5Sriastradh    * of integer types should be 0.  Practically speaking, IEEE
5413464ebd5Sriastradh    * single-precision floating point values can only store integers in the
5423464ebd5Sriastradh    * range [-0x01000000, 0x01000000] without loss of precision.
5433464ebd5Sriastradh    */
5443464ebd5Sriastradh   prog->MediumInt.RangeMin = 24;
5453464ebd5Sriastradh   prog->MediumInt.RangeMax = 24;
5463464ebd5Sriastradh   prog->MediumInt.Precision = 0;
5473464ebd5Sriastradh   prog->LowInt = prog->HighInt = prog->MediumInt;
548b167d5e7Smrg
549b167d5e7Smrg   prog->MaxUniformBlocks = 12;
550b167d5e7Smrg   prog->MaxCombinedUniformComponents = (prog->MaxUniformComponents +
551b167d5e7Smrg                                         consts->MaxUniformBlockSize / 4 *
552b167d5e7Smrg                                         prog->MaxUniformBlocks);
553b167d5e7Smrg
554b167d5e7Smrg   prog->MaxAtomicBuffers = 0;
555b167d5e7Smrg   prog->MaxAtomicCounters = 0;
5567117f1b4Smrg}
5577117f1b4Smrg
5587117f1b4Smrg
5597117f1b4Smrg/**
5607117f1b4Smrg * Initialize fields of gl_constants (aka ctx->Const.*).
5617117f1b4Smrg * Use defaults from config.h.  The device drivers will often override
5627117f1b4Smrg * some of these values (such as number of texture units).
5637117f1b4Smrg */
564b167d5e7Smrgvoid
565b167d5e7Smrg_mesa_init_constants(struct gl_constants *consts, gl_api api)
5667117f1b4Smrg{
567b167d5e7Smrg   int i;
568b167d5e7Smrg   assert(consts);
5697117f1b4Smrg
5707117f1b4Smrg   /* Constants, may be overriden (usually only reduced) by device drivers */
571b167d5e7Smrg   consts->MaxTextureMbytes = MAX_TEXTURE_MBYTES;
572b167d5e7Smrg   consts->MaxTextureLevels = MAX_TEXTURE_LEVELS;
573b167d5e7Smrg   consts->Max3DTextureLevels = MAX_3D_TEXTURE_LEVELS;
574b167d5e7Smrg   consts->MaxCubeTextureLevels = MAX_CUBE_TEXTURE_LEVELS;
575b167d5e7Smrg   consts->MaxTextureRectSize = MAX_TEXTURE_RECT_SIZE;
576b167d5e7Smrg   consts->MaxArrayTextureLayers = MAX_ARRAY_TEXTURE_LAYERS;
577b167d5e7Smrg   consts->MaxTextureCoordUnits = MAX_TEXTURE_COORD_UNITS;
578b167d5e7Smrg   consts->Program[MESA_SHADER_FRAGMENT].MaxTextureImageUnits = MAX_TEXTURE_IMAGE_UNITS;
579b167d5e7Smrg   consts->MaxTextureUnits = MIN2(consts->MaxTextureCoordUnits,
580b167d5e7Smrg                                     consts->Program[MESA_SHADER_FRAGMENT].MaxTextureImageUnits);
581b167d5e7Smrg   consts->MaxTextureMaxAnisotropy = MAX_TEXTURE_MAX_ANISOTROPY;
582b167d5e7Smrg   consts->MaxTextureLodBias = MAX_TEXTURE_LOD_BIAS;
583b167d5e7Smrg   consts->MaxTextureBufferSize = 65536;
584b167d5e7Smrg   consts->TextureBufferOffsetAlignment = 1;
585b167d5e7Smrg   consts->MaxArrayLockSize = MAX_ARRAY_LOCK_SIZE;
586b167d5e7Smrg   consts->SubPixelBits = SUB_PIXEL_BITS;
587b167d5e7Smrg   consts->MinPointSize = MIN_POINT_SIZE;
588b167d5e7Smrg   consts->MaxPointSize = MAX_POINT_SIZE;
589b167d5e7Smrg   consts->MinPointSizeAA = MIN_POINT_SIZE;
590b167d5e7Smrg   consts->MaxPointSizeAA = MAX_POINT_SIZE;
591b167d5e7Smrg   consts->PointSizeGranularity = (GLfloat) POINT_SIZE_GRANULARITY;
592b167d5e7Smrg   consts->MinLineWidth = MIN_LINE_WIDTH;
593b167d5e7Smrg   consts->MaxLineWidth = MAX_LINE_WIDTH;
594b167d5e7Smrg   consts->MinLineWidthAA = MIN_LINE_WIDTH;
595b167d5e7Smrg   consts->MaxLineWidthAA = MAX_LINE_WIDTH;
596b167d5e7Smrg   consts->LineWidthGranularity = (GLfloat) LINE_WIDTH_GRANULARITY;
597b167d5e7Smrg   consts->MaxClipPlanes = 6;
598b167d5e7Smrg   consts->MaxLights = MAX_LIGHTS;
599b167d5e7Smrg   consts->MaxShininess = 128.0;
600b167d5e7Smrg   consts->MaxSpotExponent = 128.0;
601b167d5e7Smrg   consts->MaxViewportWidth = MAX_VIEWPORT_WIDTH;
602b167d5e7Smrg   consts->MaxViewportHeight = MAX_VIEWPORT_HEIGHT;
603b167d5e7Smrg   consts->MinMapBufferAlignment = 64;
604b167d5e7Smrg
605b167d5e7Smrg   /* Driver must override these values if ARB_viewport_array is supported. */
606b167d5e7Smrg   consts->MaxViewports = 1;
607b167d5e7Smrg   consts->ViewportSubpixelBits = 0;
608b167d5e7Smrg   consts->ViewportBounds.Min = 0;
609b167d5e7Smrg   consts->ViewportBounds.Max = 0;
610b167d5e7Smrg
611b167d5e7Smrg   /** GL_ARB_uniform_buffer_object */
612b167d5e7Smrg   consts->MaxCombinedUniformBlocks = 36;
613b167d5e7Smrg   consts->MaxUniformBufferBindings = 36;
614b167d5e7Smrg   consts->MaxUniformBlockSize = 16384;
615b167d5e7Smrg   consts->UniformBufferOffsetAlignment = 1;
616b167d5e7Smrg
617b167d5e7Smrg   /* GL_ARB_explicit_uniform_location, GL_MAX_UNIFORM_LOCATIONS */
618b167d5e7Smrg   consts->MaxUserAssignableUniformLocations =
619b167d5e7Smrg      4 * MESA_SHADER_STAGES * MAX_UNIFORMS;
620b167d5e7Smrg
621b167d5e7Smrg   for (i = 0; i < MESA_SHADER_STAGES; i++)
622b167d5e7Smrg      init_program_limits(consts, i, &consts->Program[i]);
623b167d5e7Smrg
624b167d5e7Smrg   consts->MaxProgramMatrices = MAX_PROGRAM_MATRICES;
625b167d5e7Smrg   consts->MaxProgramMatrixStackDepth = MAX_PROGRAM_MATRIX_STACK_DEPTH;
626b167d5e7Smrg
627b167d5e7Smrg   /* Assume that if GLSL 1.30+ (or GLSL ES 3.00+) is supported that
628b167d5e7Smrg    * gl_VertexID is implemented using a native hardware register with OpenGL
629b167d5e7Smrg    * semantics.
630b167d5e7Smrg    */
631b167d5e7Smrg   consts->VertexID_is_zero_based = false;
6327117f1b4Smrg
6337117f1b4Smrg   /* CheckArrayBounds is overriden by drivers/x11 for X server */
634b167d5e7Smrg   consts->CheckArrayBounds = GL_FALSE;
6357117f1b4Smrg
6367117f1b4Smrg   /* GL_ARB_draw_buffers */
637b167d5e7Smrg   consts->MaxDrawBuffers = MAX_DRAW_BUFFERS;
6387117f1b4Smrg
639b167d5e7Smrg   consts->MaxColorAttachments = MAX_COLOR_ATTACHMENTS;
640b167d5e7Smrg   consts->MaxRenderbufferSize = MAX_RENDERBUFFER_SIZE;
6417117f1b4Smrg
642b167d5e7Smrg   consts->Program[MESA_SHADER_VERTEX].MaxTextureImageUnits = MAX_TEXTURE_IMAGE_UNITS;
643b167d5e7Smrg   consts->MaxCombinedTextureImageUnits = MAX_COMBINED_TEXTURE_IMAGE_UNITS;
644b167d5e7Smrg   consts->MaxVarying = 16; /* old limit not to break tnl and swrast */
645b167d5e7Smrg   consts->Program[MESA_SHADER_GEOMETRY].MaxTextureImageUnits = MAX_TEXTURE_IMAGE_UNITS;
646b167d5e7Smrg   consts->MaxGeometryOutputVertices = MAX_GEOMETRY_OUTPUT_VERTICES;
647b167d5e7Smrg   consts->MaxGeometryTotalOutputComponents = MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS;
6483464ebd5Sriastradh
6493464ebd5Sriastradh   /* Shading language version */
650b167d5e7Smrg   if (api == API_OPENGL_COMPAT || api == API_OPENGL_CORE) {
651b167d5e7Smrg      consts->GLSLVersion = 120;
652b167d5e7Smrg      _mesa_override_glsl_version(consts);
6533464ebd5Sriastradh   }
654b167d5e7Smrg   else if (api == API_OPENGLES2) {
655b167d5e7Smrg      consts->GLSLVersion = 100;
6563464ebd5Sriastradh   }
657b167d5e7Smrg   else if (api == API_OPENGLES) {
658b167d5e7Smrg      consts->GLSLVersion = 0; /* GLSL not supported */
6593464ebd5Sriastradh   }
6607117f1b4Smrg
6614a49301eSmrg   /* GL_ARB_framebuffer_object */
662b167d5e7Smrg   consts->MaxSamples = 0;
6634a49301eSmrg
664b167d5e7Smrg   /* GLSL default if NativeIntegers == FALSE */
665b167d5e7Smrg   consts->UniformBooleanTrue = FLT_AS_UINT(1.0f);
6664a49301eSmrg
667b167d5e7Smrg   /* GL_ARB_sync */
668b167d5e7Smrg   consts->MaxServerWaitTimeout = 0x1fff7fffffffULL;
6694a49301eSmrg
6704a49301eSmrg   /* GL_EXT_provoking_vertex */
671b167d5e7Smrg   consts->QuadsFollowProvokingVertexConvention = GL_TRUE;
6723464ebd5Sriastradh
6733464ebd5Sriastradh   /* GL_EXT_transform_feedback */
674b167d5e7Smrg   consts->MaxTransformFeedbackBuffers = MAX_FEEDBACK_BUFFERS;
675b167d5e7Smrg   consts->MaxTransformFeedbackSeparateComponents = 4 * MAX_FEEDBACK_ATTRIBS;
676b167d5e7Smrg   consts->MaxTransformFeedbackInterleavedComponents = 4 * MAX_FEEDBACK_ATTRIBS;
677b167d5e7Smrg   consts->MaxVertexStreams = 1;
6783464ebd5Sriastradh
679b167d5e7Smrg   /* GL 3.2  */
680b167d5e7Smrg   consts->ProfileMask = api == API_OPENGL_CORE
681b167d5e7Smrg                          ? GL_CONTEXT_CORE_PROFILE_BIT
682b167d5e7Smrg                          : GL_CONTEXT_COMPATIBILITY_PROFILE_BIT;
6833464ebd5Sriastradh
6843464ebd5Sriastradh   /** GL_EXT_gpu_shader4 */
685b167d5e7Smrg   consts->MinProgramTexelOffset = -8;
686b167d5e7Smrg   consts->MaxProgramTexelOffset = 7;
687b167d5e7Smrg
688b167d5e7Smrg   /* GL_ARB_texture_gather */
689b167d5e7Smrg   consts->MinProgramTextureGatherOffset = -8;
690b167d5e7Smrg   consts->MaxProgramTextureGatherOffset = 7;
6913464ebd5Sriastradh
6923464ebd5Sriastradh   /* GL_ARB_robustness */
693b167d5e7Smrg   consts->ResetStrategy = GL_NO_RESET_NOTIFICATION_ARB;
694b167d5e7Smrg
695b167d5e7Smrg   /* PrimitiveRestart */
696b167d5e7Smrg   consts->PrimitiveRestartInSoftware = GL_FALSE;
697b167d5e7Smrg
698b167d5e7Smrg   /* ES 3.0 or ARB_ES3_compatibility */
699b167d5e7Smrg   consts->MaxElementIndex = 0xffffffffu;
700b167d5e7Smrg
701b167d5e7Smrg   /* GL_ARB_texture_multisample */
702b167d5e7Smrg   consts->MaxColorTextureSamples = 1;
703b167d5e7Smrg   consts->MaxDepthTextureSamples = 1;
704b167d5e7Smrg   consts->MaxIntegerSamples = 1;
705b167d5e7Smrg
706b167d5e7Smrg   /* GL_ARB_shader_atomic_counters */
707b167d5e7Smrg   consts->MaxAtomicBufferBindings = MAX_COMBINED_ATOMIC_BUFFERS;
708b167d5e7Smrg   consts->MaxAtomicBufferSize = MAX_ATOMIC_COUNTERS * ATOMIC_COUNTER_SIZE;
709b167d5e7Smrg   consts->MaxCombinedAtomicBuffers = MAX_COMBINED_ATOMIC_BUFFERS;
710b167d5e7Smrg   consts->MaxCombinedAtomicCounters = MAX_ATOMIC_COUNTERS;
711b167d5e7Smrg
712b167d5e7Smrg   /* GL_ARB_vertex_attrib_binding */
713b167d5e7Smrg   consts->MaxVertexAttribRelativeOffset = 2047;
714b167d5e7Smrg   consts->MaxVertexAttribBindings = MAX_VERTEX_GENERIC_ATTRIBS;
715b167d5e7Smrg
716b167d5e7Smrg   /* GL_ARB_compute_shader */
717b167d5e7Smrg   consts->MaxComputeWorkGroupCount[0] = 65535;
718b167d5e7Smrg   consts->MaxComputeWorkGroupCount[1] = 65535;
719b167d5e7Smrg   consts->MaxComputeWorkGroupCount[2] = 65535;
720b167d5e7Smrg   consts->MaxComputeWorkGroupSize[0] = 1024;
721b167d5e7Smrg   consts->MaxComputeWorkGroupSize[1] = 1024;
722b167d5e7Smrg   consts->MaxComputeWorkGroupSize[2] = 64;
723b167d5e7Smrg   consts->MaxComputeWorkGroupInvocations = 1024;
724b167d5e7Smrg
725b167d5e7Smrg   /** GL_ARB_gpu_shader5 */
726b167d5e7Smrg   consts->MinFragmentInterpolationOffset = MIN_FRAGMENT_INTERPOLATION_OFFSET;
727b167d5e7Smrg   consts->MaxFragmentInterpolationOffset = MAX_FRAGMENT_INTERPOLATION_OFFSET;
7287117f1b4Smrg}
7297117f1b4Smrg
7307117f1b4Smrg
7317117f1b4Smrg/**
7327117f1b4Smrg * Do some sanity checks on the limits/constants for the given context.
7337117f1b4Smrg * Only called the first time a context is bound.
7347117f1b4Smrg */
7357117f1b4Smrgstatic void
7363464ebd5Sriastradhcheck_context_limits(struct gl_context *ctx)
7377117f1b4Smrg{
738cdc920a0Smrg   /* check that we don't exceed the size of various bitfields */
739b167d5e7Smrg   assert(VARYING_SLOT_MAX <=
740cdc920a0Smrg	  (8 * sizeof(ctx->VertexProgram._Current->Base.OutputsWritten)));
741b167d5e7Smrg   assert(VARYING_SLOT_MAX <=
742cdc920a0Smrg	  (8 * sizeof(ctx->FragmentProgram._Current->Base.InputsRead)));
743cdc920a0Smrg
744cdc920a0Smrg   /* shader-related checks */
745b167d5e7Smrg   assert(ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxLocalParams <= MAX_PROGRAM_LOCAL_PARAMS);
746b167d5e7Smrg   assert(ctx->Const.Program[MESA_SHADER_VERTEX].MaxLocalParams <= MAX_PROGRAM_LOCAL_PARAMS);
747cdc920a0Smrg
748cdc920a0Smrg   /* Texture unit checks */
749b167d5e7Smrg   assert(ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxTextureImageUnits > 0);
750b167d5e7Smrg   assert(ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxTextureImageUnits <= MAX_TEXTURE_IMAGE_UNITS);
751cdc920a0Smrg   assert(ctx->Const.MaxTextureCoordUnits > 0);
7527117f1b4Smrg   assert(ctx->Const.MaxTextureCoordUnits <= MAX_TEXTURE_COORD_UNITS);
753cdc920a0Smrg   assert(ctx->Const.MaxTextureUnits > 0);
7547117f1b4Smrg   assert(ctx->Const.MaxTextureUnits <= MAX_TEXTURE_IMAGE_UNITS);
7557117f1b4Smrg   assert(ctx->Const.MaxTextureUnits <= MAX_TEXTURE_COORD_UNITS);
756b167d5e7Smrg   assert(ctx->Const.MaxTextureUnits == MIN2(ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxTextureImageUnits,
757cdc920a0Smrg                                             ctx->Const.MaxTextureCoordUnits));
758cdc920a0Smrg   assert(ctx->Const.MaxCombinedTextureImageUnits > 0);
759cdc920a0Smrg   assert(ctx->Const.MaxCombinedTextureImageUnits <= MAX_COMBINED_TEXTURE_IMAGE_UNITS);
760cdc920a0Smrg   assert(ctx->Const.MaxTextureCoordUnits <= MAX_COMBINED_TEXTURE_IMAGE_UNITS);
761c1f859d4Smrg   /* number of coord units cannot be greater than number of image units */
762b167d5e7Smrg   assert(ctx->Const.MaxTextureCoordUnits <= ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxTextureImageUnits);
763c1f859d4Smrg
764cdc920a0Smrg
765cdc920a0Smrg   /* Texture size checks */
7664a49301eSmrg   assert(ctx->Const.MaxTextureLevels <= MAX_TEXTURE_LEVELS);
7674a49301eSmrg   assert(ctx->Const.Max3DTextureLevels <= MAX_3D_TEXTURE_LEVELS);
7684a49301eSmrg   assert(ctx->Const.MaxCubeTextureLevels <= MAX_CUBE_TEXTURE_LEVELS);
7694a49301eSmrg   assert(ctx->Const.MaxTextureRectSize <= MAX_TEXTURE_RECT_SIZE);
7707117f1b4Smrg
771cdc920a0Smrg   /* Texture level checks */
772cdc920a0Smrg   assert(MAX_TEXTURE_LEVELS >= MAX_3D_TEXTURE_LEVELS);
773cdc920a0Smrg   assert(MAX_TEXTURE_LEVELS >= MAX_CUBE_TEXTURE_LEVELS);
774cdc920a0Smrg
775cdc920a0Smrg   /* Max texture size should be <= max viewport size (render to texture) */
776b167d5e7Smrg   assert((1U << (ctx->Const.MaxTextureLevels - 1))
777b167d5e7Smrg          <= ctx->Const.MaxViewportWidth);
778b167d5e7Smrg   assert((1U << (ctx->Const.MaxTextureLevels - 1))
779b167d5e7Smrg          <= ctx->Const.MaxViewportHeight);
7807117f1b4Smrg
7817117f1b4Smrg   assert(ctx->Const.MaxDrawBuffers <= MAX_DRAW_BUFFERS);
7827117f1b4Smrg
7833464ebd5Sriastradh   /* if this fails, add more enum values to gl_buffer_index */
7843464ebd5Sriastradh   assert(BUFFER_COLOR0 + MAX_DRAW_BUFFERS <= BUFFER_COUNT);
7853464ebd5Sriastradh
7867117f1b4Smrg   /* XXX probably add more tests */
7877117f1b4Smrg}
7887117f1b4Smrg
7897117f1b4Smrg
7907117f1b4Smrg/**
7917117f1b4Smrg * Initialize the attribute groups in a GL context.
7927117f1b4Smrg *
7937117f1b4Smrg * \param ctx GL context.
7947117f1b4Smrg *
7957117f1b4Smrg * Initializes all the attributes, calling the respective <tt>init*</tt>
7967117f1b4Smrg * functions for the more complex data structures.
7977117f1b4Smrg */
7987117f1b4Smrgstatic GLboolean
7993464ebd5Sriastradhinit_attrib_groups(struct gl_context *ctx)
8007117f1b4Smrg{
8017117f1b4Smrg   assert(ctx);
8027117f1b4Smrg
8037117f1b4Smrg   /* Constants */
804b167d5e7Smrg   _mesa_init_constants(&ctx->Const, ctx->API);
8057117f1b4Smrg
8067117f1b4Smrg   /* Extensions */
807b167d5e7Smrg   _mesa_init_extensions(&ctx->Extensions);
8087117f1b4Smrg
8097117f1b4Smrg   /* Attribute Groups */
8107117f1b4Smrg   _mesa_init_accum( ctx );
8117117f1b4Smrg   _mesa_init_attrib( ctx );
8127117f1b4Smrg   _mesa_init_buffer_objects( ctx );
8137117f1b4Smrg   _mesa_init_color( ctx );
8147117f1b4Smrg   _mesa_init_current( ctx );
8157117f1b4Smrg   _mesa_init_depth( ctx );
8167117f1b4Smrg   _mesa_init_debug( ctx );
8177117f1b4Smrg   _mesa_init_display_list( ctx );
818b167d5e7Smrg   _mesa_init_errors( ctx );
8197117f1b4Smrg   _mesa_init_eval( ctx );
820c1f859d4Smrg   _mesa_init_fbobjects( ctx );
8217117f1b4Smrg   _mesa_init_feedback( ctx );
8227117f1b4Smrg   _mesa_init_fog( ctx );
8237117f1b4Smrg   _mesa_init_hint( ctx );
8247117f1b4Smrg   _mesa_init_line( ctx );
8257117f1b4Smrg   _mesa_init_lighting( ctx );
8267117f1b4Smrg   _mesa_init_matrix( ctx );
8277117f1b4Smrg   _mesa_init_multisample( ctx );
828b167d5e7Smrg   _mesa_init_performance_monitors( ctx );
829b167d5e7Smrg   _mesa_init_pipeline( ctx );
8307117f1b4Smrg   _mesa_init_pixel( ctx );
831c1f859d4Smrg   _mesa_init_pixelstore( ctx );
8327117f1b4Smrg   _mesa_init_point( ctx );
8337117f1b4Smrg   _mesa_init_polygon( ctx );
8347117f1b4Smrg   _mesa_init_program( ctx );
8354a49301eSmrg   _mesa_init_queryobj( ctx );
8364a49301eSmrg   _mesa_init_sync( ctx );
8377117f1b4Smrg   _mesa_init_rastpos( ctx );
8387117f1b4Smrg   _mesa_init_scissor( ctx );
8397117f1b4Smrg   _mesa_init_shader_state( ctx );
8407117f1b4Smrg   _mesa_init_stencil( ctx );
8417117f1b4Smrg   _mesa_init_transform( ctx );
8423464ebd5Sriastradh   _mesa_init_transform_feedback( ctx );
8437117f1b4Smrg   _mesa_init_varray( ctx );
8447117f1b4Smrg   _mesa_init_viewport( ctx );
8457117f1b4Smrg
8467117f1b4Smrg   if (!_mesa_init_texture( ctx ))
8477117f1b4Smrg      return GL_FALSE;
8487117f1b4Smrg
8497117f1b4Smrg   _mesa_init_texture_s3tc( ctx );
8507117f1b4Smrg
8517117f1b4Smrg   /* Miscellaneous */
8527117f1b4Smrg   ctx->NewState = _NEW_ALL;
853b167d5e7Smrg   ctx->NewDriverState = ~0;
854b167d5e7Smrg   ctx->ErrorValue = GL_NO_ERROR;
855b167d5e7Smrg   ctx->ShareGroupReset = false;
856b167d5e7Smrg   ctx->varying_vp_inputs = VERT_BIT_ALL;
8577117f1b4Smrg
8587117f1b4Smrg   return GL_TRUE;
8597117f1b4Smrg}
8607117f1b4Smrg
8617117f1b4Smrg
862c1f859d4Smrg/**
863c1f859d4Smrg * Update default objects in a GL context with respect to shared state.
864c1f859d4Smrg *
865c1f859d4Smrg * \param ctx GL context.
866c1f859d4Smrg *
867c1f859d4Smrg * Removes references to old default objects, (texture objects, program
868c1f859d4Smrg * objects, etc.) and changes to reference those from the current shared
869c1f859d4Smrg * state.
870c1f859d4Smrg */
871c1f859d4Smrgstatic GLboolean
8723464ebd5Sriastradhupdate_default_objects(struct gl_context *ctx)
873c1f859d4Smrg{
874c1f859d4Smrg   assert(ctx);
875c1f859d4Smrg
876c1f859d4Smrg   _mesa_update_default_objects_program(ctx);
877c1f859d4Smrg   _mesa_update_default_objects_texture(ctx);
878c1f859d4Smrg   _mesa_update_default_objects_buffer_objects(ctx);
879c1f859d4Smrg
880c1f859d4Smrg   return GL_TRUE;
881c1f859d4Smrg}
882c1f859d4Smrg
883c1f859d4Smrg
8847117f1b4Smrg/**
8857117f1b4Smrg * This is the default function we plug into all dispatch table slots
8867117f1b4Smrg * This helps prevents a segfault when someone calls a GL function without
8877117f1b4Smrg * first checking if the extension's supported.
8887117f1b4Smrg */
889b167d5e7Smrgint
890b167d5e7Smrg_mesa_generic_nop(void)
8917117f1b4Smrg{
892b167d5e7Smrg   GET_CURRENT_CONTEXT(ctx);
893b167d5e7Smrg   _mesa_error(ctx, GL_INVALID_OPERATION,
894b167d5e7Smrg               "unsupported function called "
895b167d5e7Smrg               "(unsupported extension or deprecated function?)");
8967117f1b4Smrg   return 0;
8977117f1b4Smrg}
8987117f1b4Smrg
8997117f1b4Smrg
9007117f1b4Smrg/**
901b167d5e7Smrg * Special no-op glFlush, see below.
902b167d5e7Smrg */
903b167d5e7Smrg#if defined(_WIN32)
904b167d5e7Smrgstatic void GLAPIENTRY
905b167d5e7Smrgnop_glFlush(void)
906b167d5e7Smrg{
907b167d5e7Smrg   /* don't record an error like we do in _mesa_generic_nop() */
908b167d5e7Smrg}
909b167d5e7Smrg#endif
910b167d5e7Smrg
911b167d5e7Smrg
912b167d5e7Smrg/**
913b167d5e7Smrg * Allocate and initialize a new dispatch table.  All the dispatch
914b167d5e7Smrg * function pointers will point at the _mesa_generic_nop() function
915b167d5e7Smrg * which raises GL_INVALID_OPERATION.
9167117f1b4Smrg */
9173464ebd5Sriastradhstruct _glapi_table *
918b167d5e7Smrg_mesa_alloc_dispatch_table()
9197117f1b4Smrg{
9207117f1b4Smrg   /* Find the larger of Mesa's dispatch table and libGL's dispatch table.
9217117f1b4Smrg    * In practice, this'll be the same for stand-alone Mesa.  But for DRI
9227117f1b4Smrg    * Mesa we do this to accomodate different versions of libGL and various
9237117f1b4Smrg    * DRI drivers.
9247117f1b4Smrg    */
9253464ebd5Sriastradh   GLint numEntries = MAX2(_glapi_get_dispatch_table_size(), _gloffset_COUNT);
9263464ebd5Sriastradh   struct _glapi_table *table;
9273464ebd5Sriastradh
928b167d5e7Smrg   table = malloc(numEntries * sizeof(_glapi_proc));
9297117f1b4Smrg   if (table) {
9307117f1b4Smrg      _glapi_proc *entry = (_glapi_proc *) table;
9317117f1b4Smrg      GLint i;
9327117f1b4Smrg      for (i = 0; i < numEntries; i++) {
933b167d5e7Smrg         entry[i] = (_glapi_proc) _mesa_generic_nop;
9347117f1b4Smrg      }
935b167d5e7Smrg
936b167d5e7Smrg#if defined(_WIN32)
937b167d5e7Smrg      /* This is a special case for Windows in the event that
938b167d5e7Smrg       * wglGetProcAddress is called between glBegin/End().
939b167d5e7Smrg       *
940b167d5e7Smrg       * The MS opengl32.dll library apparently calls glFlush from
941b167d5e7Smrg       * wglGetProcAddress().  If we're inside glBegin/End(), glFlush
942b167d5e7Smrg       * will dispatch to _mesa_generic_nop() and we'll generate a
943b167d5e7Smrg       * GL_INVALID_OPERATION error.
944b167d5e7Smrg       *
945b167d5e7Smrg       * The specific case which hits this is piglit's primitive-restart
946b167d5e7Smrg       * test which calls glPrimitiveRestartNV() inside glBegin/End.  The
947b167d5e7Smrg       * first time we call glPrimitiveRestartNV() Piglit's API dispatch
948b167d5e7Smrg       * code will try to resolve the function by calling wglGetProcAddress.
949b167d5e7Smrg       * This raises GL_INVALID_OPERATION and an assert(glGetError()==0)
950b167d5e7Smrg       * will fail causing the test to fail.  By suppressing the error, the
951b167d5e7Smrg       * assertion passes and the test continues.
952b167d5e7Smrg       */
953b167d5e7Smrg      SET_Flush(table, nop_glFlush);
954b167d5e7Smrg#endif
9557117f1b4Smrg   }
9567117f1b4Smrg   return table;
9577117f1b4Smrg}
9587117f1b4Smrg
959b167d5e7Smrg/**
960b167d5e7Smrg * Creates a minimal dispatch table for use within glBegin()/glEnd().
961b167d5e7Smrg *
962b167d5e7Smrg * This ensures that we generate GL_INVALID_OPERATION errors from most
963b167d5e7Smrg * functions, since the set of functions that are valid within Begin/End is
964b167d5e7Smrg * very small.
965b167d5e7Smrg *
966b167d5e7Smrg * From the GL 1.0 specification section 2.6.3, "GL Commands within
967b167d5e7Smrg * Begin/End"
968b167d5e7Smrg *
969b167d5e7Smrg *     "The only GL commands that are allowed within any Begin/End pairs are
970b167d5e7Smrg *      the commands for specifying vertex coordinates, vertex color, normal
971b167d5e7Smrg *      coordinates, and texture coordinates (Vertex, Color, Index, Normal,
972b167d5e7Smrg *      TexCoord), EvalCoord and EvalPoint commands (see section 5.1),
973b167d5e7Smrg *      commands for specifying lighting material parameters (Material
974b167d5e7Smrg *      commands see section 2.12.2), display list invocation commands
975b167d5e7Smrg *      (CallList and CallLists see section 5.4), and the EdgeFlag
976b167d5e7Smrg *      command. Executing Begin after Begin has already been executed but
977b167d5e7Smrg *      before an End is issued generates the INVALID OPERATION error, as does
978b167d5e7Smrg *      executing End without a previous corresponding Begin. Executing any
979b167d5e7Smrg *      other GL command within Begin/End results in the error INVALID
980b167d5e7Smrg *      OPERATION."
981b167d5e7Smrg *
982b167d5e7Smrg * The table entries for specifying vertex attributes are set up by
983b167d5e7Smrg * install_vtxfmt() and _mesa_loopback_init_api_table(), and End() and dlists
984b167d5e7Smrg * are set by install_vtxfmt() as well.
985b167d5e7Smrg */
986b167d5e7Smrgstatic struct _glapi_table *
987b167d5e7Smrgcreate_beginend_table(const struct gl_context *ctx)
988b167d5e7Smrg{
989b167d5e7Smrg   struct _glapi_table *table;
990b167d5e7Smrg
991b167d5e7Smrg   table = _mesa_alloc_dispatch_table();
992b167d5e7Smrg   if (!table)
993b167d5e7Smrg      return NULL;
994b167d5e7Smrg
995b167d5e7Smrg   /* Fill in functions which return a value, since they should return some
996b167d5e7Smrg    * specific value even if they emit a GL_INVALID_OPERATION error from them
997b167d5e7Smrg    * being called within glBegin()/glEnd().
998b167d5e7Smrg    */
999b167d5e7Smrg#define COPY_DISPATCH(func) SET_##func(table, GET_##func(ctx->Exec))
1000b167d5e7Smrg
1001b167d5e7Smrg   COPY_DISPATCH(GenLists);
1002b167d5e7Smrg   COPY_DISPATCH(IsProgram);
1003b167d5e7Smrg   COPY_DISPATCH(IsVertexArray);
1004b167d5e7Smrg   COPY_DISPATCH(IsBuffer);
1005b167d5e7Smrg   COPY_DISPATCH(IsEnabled);
1006b167d5e7Smrg   COPY_DISPATCH(IsEnabledi);
1007b167d5e7Smrg   COPY_DISPATCH(IsRenderbuffer);
1008b167d5e7Smrg   COPY_DISPATCH(IsFramebuffer);
1009b167d5e7Smrg   COPY_DISPATCH(CheckFramebufferStatus);
1010b167d5e7Smrg   COPY_DISPATCH(RenderMode);
1011b167d5e7Smrg   COPY_DISPATCH(GetString);
1012b167d5e7Smrg   COPY_DISPATCH(GetStringi);
1013b167d5e7Smrg   COPY_DISPATCH(GetPointerv);
1014b167d5e7Smrg   COPY_DISPATCH(IsQuery);
1015b167d5e7Smrg   COPY_DISPATCH(IsSampler);
1016b167d5e7Smrg   COPY_DISPATCH(IsSync);
1017b167d5e7Smrg   COPY_DISPATCH(IsTexture);
1018b167d5e7Smrg   COPY_DISPATCH(IsTransformFeedback);
1019b167d5e7Smrg   COPY_DISPATCH(DeleteQueries);
1020b167d5e7Smrg   COPY_DISPATCH(AreTexturesResident);
1021b167d5e7Smrg   COPY_DISPATCH(FenceSync);
1022b167d5e7Smrg   COPY_DISPATCH(ClientWaitSync);
1023b167d5e7Smrg   COPY_DISPATCH(MapBuffer);
1024b167d5e7Smrg   COPY_DISPATCH(UnmapBuffer);
1025b167d5e7Smrg   COPY_DISPATCH(MapBufferRange);
1026b167d5e7Smrg   COPY_DISPATCH(ObjectPurgeableAPPLE);
1027b167d5e7Smrg   COPY_DISPATCH(ObjectUnpurgeableAPPLE);
1028b167d5e7Smrg
1029b167d5e7Smrg   _mesa_loopback_init_api_table(ctx, table);
1030b167d5e7Smrg
1031b167d5e7Smrg   return table;
1032b167d5e7Smrg}
1033b167d5e7Smrg
1034b167d5e7Smrgvoid
1035b167d5e7Smrg_mesa_initialize_dispatch_tables(struct gl_context *ctx)
1036b167d5e7Smrg{
1037b167d5e7Smrg   /* Do the code-generated setup of the exec table in api_exec.c. */
1038b167d5e7Smrg   _mesa_initialize_exec_table(ctx);
1039b167d5e7Smrg
1040b167d5e7Smrg   if (ctx->Save)
1041b167d5e7Smrg      _mesa_initialize_save_table(ctx);
1042b167d5e7Smrg}
10437117f1b4Smrg
10447117f1b4Smrg/**
10453464ebd5Sriastradh * Initialize a struct gl_context struct (rendering context).
10467117f1b4Smrg *
10477117f1b4Smrg * This includes allocating all the other structs and arrays which hang off of
10487117f1b4Smrg * the context by pointers.
10497117f1b4Smrg * Note that the driver needs to pass in its dd_function_table here since
10507117f1b4Smrg * we need to at least call driverFunctions->NewTextureObject to create the
10517117f1b4Smrg * default texture objects.
10527117f1b4Smrg *
10537117f1b4Smrg * Called by _mesa_create_context().
10547117f1b4Smrg *
10557117f1b4Smrg * Performs the imports and exports callback tables initialization, and
10567117f1b4Smrg * miscellaneous one-time initializations. If no shared context is supplied one
10577117f1b4Smrg * is allocated, and increase its reference count.  Setups the GL API dispatch
10587117f1b4Smrg * tables.  Initialize the TNL module. Sets the maximum Z buffer depth.
10597117f1b4Smrg * Finally queries the \c MESA_DEBUG and \c MESA_VERBOSE environment variables
10607117f1b4Smrg * for debug flags.
10617117f1b4Smrg *
10627117f1b4Smrg * \param ctx the context to initialize
10633464ebd5Sriastradh * \param api the GL API type to create the context for
1064b167d5e7Smrg * \param visual describes the visual attributes for this context or NULL to
1065b167d5e7Smrg *               create a configless context
10667117f1b4Smrg * \param share_list points to context to share textures, display lists,
10677117f1b4Smrg *        etc with, or NULL
10687117f1b4Smrg * \param driverFunctions table of device driver functions for this context
10697117f1b4Smrg *        to use
10707117f1b4Smrg */
10717117f1b4SmrgGLboolean
10723464ebd5Sriastradh_mesa_initialize_context(struct gl_context *ctx,
10733464ebd5Sriastradh                         gl_api api,
10743464ebd5Sriastradh                         const struct gl_config *visual,
10753464ebd5Sriastradh                         struct gl_context *share_list,
1076b167d5e7Smrg                         const struct dd_function_table *driverFunctions)
10777117f1b4Smrg{
10784a49301eSmrg   struct gl_shared_state *shared;
10793464ebd5Sriastradh   int i;
10804a49301eSmrg
10817117f1b4Smrg   assert(driverFunctions->NewTextureObject);
1082b167d5e7Smrg   assert(driverFunctions->FreeTextureImageBuffer);
10837117f1b4Smrg
10843464ebd5Sriastradh   ctx->API = api;
10857117f1b4Smrg   ctx->DrawBuffer = NULL;
10867117f1b4Smrg   ctx->ReadBuffer = NULL;
10877117f1b4Smrg   ctx->WinSysDrawBuffer = NULL;
10887117f1b4Smrg   ctx->WinSysReadBuffer = NULL;
10897117f1b4Smrg
1090b167d5e7Smrg   if (visual) {
1091b167d5e7Smrg      ctx->Visual = *visual;
1092b167d5e7Smrg      ctx->HasConfig = GL_TRUE;
1093b167d5e7Smrg   }
1094b167d5e7Smrg   else {
1095b167d5e7Smrg      memset(&ctx->Visual, 0, sizeof ctx->Visual);
1096b167d5e7Smrg      ctx->HasConfig = GL_FALSE;
1097b167d5e7Smrg   }
1098b167d5e7Smrg
1099b167d5e7Smrg   if (_mesa_is_desktop_gl(ctx)) {
1100b167d5e7Smrg      _mesa_override_gl_version(ctx);
1101b167d5e7Smrg   }
1102b167d5e7Smrg
11033464ebd5Sriastradh   /* misc one-time initializations */
11043464ebd5Sriastradh   one_time_init(ctx);
11053464ebd5Sriastradh
11067117f1b4Smrg   /* Plug in driver functions and context pointer here.
11077117f1b4Smrg    * This is important because when we call alloc_shared_state() below
11087117f1b4Smrg    * we'll call ctx->Driver.NewTextureObject() to create the default
11097117f1b4Smrg    * textures.
11107117f1b4Smrg    */
11117117f1b4Smrg   ctx->Driver = *driverFunctions;
11127117f1b4Smrg
11137117f1b4Smrg   if (share_list) {
11147117f1b4Smrg      /* share state with another context */
11154a49301eSmrg      shared = share_list->Shared;
11167117f1b4Smrg   }
11177117f1b4Smrg   else {
11187117f1b4Smrg      /* allocate new, unshared state */
11194a49301eSmrg      shared = _mesa_alloc_shared_state(ctx);
11204a49301eSmrg      if (!shared)
11217117f1b4Smrg         return GL_FALSE;
11227117f1b4Smrg   }
11234a49301eSmrg
1124b167d5e7Smrg   _mesa_reference_shared_state(ctx, &ctx->Shared, shared);
11257117f1b4Smrg
1126b167d5e7Smrg   if (!init_attrib_groups( ctx ))
1127b167d5e7Smrg      goto fail;
11283464ebd5Sriastradh
1129b167d5e7Smrg   /* setup the API dispatch tables with all nop functions */
1130b167d5e7Smrg   ctx->OutsideBeginEnd = _mesa_alloc_dispatch_table();
1131b167d5e7Smrg   if (!ctx->OutsideBeginEnd)
1132b167d5e7Smrg      goto fail;
1133b167d5e7Smrg   ctx->Exec = ctx->OutsideBeginEnd;
1134b167d5e7Smrg   ctx->CurrentDispatch = ctx->OutsideBeginEnd;
11354a49301eSmrg
11367117f1b4Smrg   ctx->FragmentProgram._MaintainTexEnvProgram
11377117f1b4Smrg      = (_mesa_getenv("MESA_TEX_PROG") != NULL);
11387117f1b4Smrg
11397117f1b4Smrg   ctx->VertexProgram._MaintainTnlProgram
11407117f1b4Smrg      = (_mesa_getenv("MESA_TNL_PROG") != NULL);
11417117f1b4Smrg   if (ctx->VertexProgram._MaintainTnlProgram) {
11427117f1b4Smrg      /* this is required... */
11437117f1b4Smrg      ctx->FragmentProgram._MaintainTexEnvProgram = GL_TRUE;
11447117f1b4Smrg   }
11457117f1b4Smrg
11463464ebd5Sriastradh   /* Mesa core handles all the formats that mesa core knows about.
11473464ebd5Sriastradh    * Drivers will want to override this list with just the formats
11483464ebd5Sriastradh    * they can handle, and confirm that appropriate fallbacks exist in
11493464ebd5Sriastradh    * _mesa_choose_tex_format().
11503464ebd5Sriastradh    */
11513464ebd5Sriastradh   memset(&ctx->TextureFormatSupported, GL_TRUE,
11523464ebd5Sriastradh	  sizeof(ctx->TextureFormatSupported));
11533464ebd5Sriastradh
11543464ebd5Sriastradh   switch (ctx->API) {
1155b167d5e7Smrg   case API_OPENGL_COMPAT:
1156b167d5e7Smrg      ctx->BeginEnd = create_beginend_table(ctx);
1157b167d5e7Smrg      ctx->Save = _mesa_alloc_dispatch_table();
1158b167d5e7Smrg      if (!ctx->BeginEnd || !ctx->Save)
1159b167d5e7Smrg         goto fail;
1160b167d5e7Smrg
1161b167d5e7Smrg      /* fall-through */
1162b167d5e7Smrg   case API_OPENGL_CORE:
11633464ebd5Sriastradh      break;
11643464ebd5Sriastradh   case API_OPENGLES:
11653464ebd5Sriastradh      /**
11663464ebd5Sriastradh       * GL_OES_texture_cube_map says
11673464ebd5Sriastradh       * "Initially all texture generation modes are set to REFLECTION_MAP_OES"
11683464ebd5Sriastradh       */
11693464ebd5Sriastradh      for (i = 0; i < MAX_TEXTURE_UNITS; i++) {
11703464ebd5Sriastradh	 struct gl_texture_unit *texUnit = &ctx->Texture.Unit[i];
11713464ebd5Sriastradh	 texUnit->GenS.Mode = GL_REFLECTION_MAP_NV;
11723464ebd5Sriastradh	 texUnit->GenT.Mode = GL_REFLECTION_MAP_NV;
11733464ebd5Sriastradh	 texUnit->GenR.Mode = GL_REFLECTION_MAP_NV;
11743464ebd5Sriastradh	 texUnit->GenS._ModeBit = TEXGEN_REFLECTION_MAP_NV;
11753464ebd5Sriastradh	 texUnit->GenT._ModeBit = TEXGEN_REFLECTION_MAP_NV;
11763464ebd5Sriastradh	 texUnit->GenR._ModeBit = TEXGEN_REFLECTION_MAP_NV;
11773464ebd5Sriastradh      }
11783464ebd5Sriastradh      break;
11793464ebd5Sriastradh   case API_OPENGLES2:
11803464ebd5Sriastradh      ctx->FragmentProgram._MaintainTexEnvProgram = GL_TRUE;
11813464ebd5Sriastradh      ctx->VertexProgram._MaintainTnlProgram = GL_TRUE;
11823464ebd5Sriastradh      break;
11833464ebd5Sriastradh   }
1184c1f859d4Smrg
11857117f1b4Smrg   ctx->FirstTimeCurrent = GL_TRUE;
11867117f1b4Smrg
11877117f1b4Smrg   return GL_TRUE;
1188b167d5e7Smrg
1189b167d5e7Smrgfail:
1190b167d5e7Smrg   _mesa_reference_shared_state(ctx, &ctx->Shared, NULL);
1191b167d5e7Smrg   free(ctx->BeginEnd);
1192b167d5e7Smrg   free(ctx->OutsideBeginEnd);
1193b167d5e7Smrg   free(ctx->Save);
1194b167d5e7Smrg   return GL_FALSE;
11957117f1b4Smrg}
11967117f1b4Smrg
11977117f1b4Smrg
11987117f1b4Smrg/**
11993464ebd5Sriastradh * Allocate and initialize a struct gl_context structure.
12007117f1b4Smrg * Note that the driver needs to pass in its dd_function_table here since
12017117f1b4Smrg * we need to at least call driverFunctions->NewTextureObject to initialize
12027117f1b4Smrg * the rendering context.
12037117f1b4Smrg *
12043464ebd5Sriastradh * \param api the GL API type to create the context for
1205b167d5e7Smrg * \param visual a struct gl_config pointer (we copy the struct contents) or
1206b167d5e7Smrg *               NULL to create a configless context
12077117f1b4Smrg * \param share_list another context to share display lists with or NULL
12087117f1b4Smrg * \param driverFunctions points to the dd_function_table into which the
12097117f1b4Smrg *        driver has plugged in all its special functions.
12107117f1b4Smrg *
12113464ebd5Sriastradh * \return pointer to a new __struct gl_contextRec or NULL if error.
12127117f1b4Smrg */
12133464ebd5Sriastradhstruct gl_context *
12143464ebd5Sriastradh_mesa_create_context(gl_api api,
12153464ebd5Sriastradh                     const struct gl_config *visual,
12163464ebd5Sriastradh                     struct gl_context *share_list,
1217b167d5e7Smrg                     const struct dd_function_table *driverFunctions)
12187117f1b4Smrg{
12193464ebd5Sriastradh   struct gl_context *ctx;
12207117f1b4Smrg
1221b167d5e7Smrg   ctx = calloc(1, sizeof(struct gl_context));
12227117f1b4Smrg   if (!ctx)
12237117f1b4Smrg      return NULL;
12247117f1b4Smrg
12253464ebd5Sriastradh   if (_mesa_initialize_context(ctx, api, visual, share_list,
1226b167d5e7Smrg                                driverFunctions)) {
12277117f1b4Smrg      return ctx;
12287117f1b4Smrg   }
12297117f1b4Smrg   else {
1230cdc920a0Smrg      free(ctx);
12317117f1b4Smrg      return NULL;
12327117f1b4Smrg   }
12337117f1b4Smrg}
12347117f1b4Smrg
12357117f1b4Smrg
12367117f1b4Smrg/**
12377117f1b4Smrg * Free the data associated with the given context.
12387117f1b4Smrg *
12393464ebd5Sriastradh * But doesn't free the struct gl_context struct itself.
12407117f1b4Smrg *
12417117f1b4Smrg * \sa _mesa_initialize_context() and init_attrib_groups().
12427117f1b4Smrg */
12437117f1b4Smrgvoid
12443464ebd5Sriastradh_mesa_free_context_data( struct gl_context *ctx )
12457117f1b4Smrg{
12467117f1b4Smrg   if (!_mesa_get_current_context()){
12477117f1b4Smrg      /* No current context, but we may need one in order to delete
12487117f1b4Smrg       * texture objs, etc.  So temporarily bind the context now.
12497117f1b4Smrg       */
12507117f1b4Smrg      _mesa_make_current(ctx, NULL, NULL);
12517117f1b4Smrg   }
12527117f1b4Smrg
12537117f1b4Smrg   /* unreference WinSysDraw/Read buffers */
12544a49301eSmrg   _mesa_reference_framebuffer(&ctx->WinSysDrawBuffer, NULL);
12554a49301eSmrg   _mesa_reference_framebuffer(&ctx->WinSysReadBuffer, NULL);
12564a49301eSmrg   _mesa_reference_framebuffer(&ctx->DrawBuffer, NULL);
12574a49301eSmrg   _mesa_reference_framebuffer(&ctx->ReadBuffer, NULL);
12587117f1b4Smrg
1259c1f859d4Smrg   _mesa_reference_vertprog(ctx, &ctx->VertexProgram.Current, NULL);
1260c1f859d4Smrg   _mesa_reference_vertprog(ctx, &ctx->VertexProgram._Current, NULL);
1261c1f859d4Smrg   _mesa_reference_vertprog(ctx, &ctx->VertexProgram._TnlProgram, NULL);
1262c1f859d4Smrg
1263b167d5e7Smrg   _mesa_reference_geomprog(ctx, &ctx->GeometryProgram.Current, NULL);
1264b167d5e7Smrg   _mesa_reference_geomprog(ctx, &ctx->GeometryProgram._Current, NULL);
1265b167d5e7Smrg
1266c1f859d4Smrg   _mesa_reference_fragprog(ctx, &ctx->FragmentProgram.Current, NULL);
1267c1f859d4Smrg   _mesa_reference_fragprog(ctx, &ctx->FragmentProgram._Current, NULL);
1268c1f859d4Smrg   _mesa_reference_fragprog(ctx, &ctx->FragmentProgram._TexEnvProgram, NULL);
1269c1f859d4Smrg
1270b167d5e7Smrg   _mesa_reference_vao(ctx, &ctx->Array.VAO, NULL);
1271b167d5e7Smrg   _mesa_reference_vao(ctx, &ctx->Array.DefaultVAO, NULL);
1272b167d5e7Smrg
12737117f1b4Smrg   _mesa_free_attrib_data(ctx);
12744a49301eSmrg   _mesa_free_buffer_objects(ctx);
12757117f1b4Smrg   _mesa_free_lighting_data( ctx );
12767117f1b4Smrg   _mesa_free_eval_data( ctx );
12777117f1b4Smrg   _mesa_free_texture_data( ctx );
12787117f1b4Smrg   _mesa_free_matrix_data( ctx );
12797117f1b4Smrg   _mesa_free_viewport_data( ctx );
1280b167d5e7Smrg   _mesa_free_pipeline_data(ctx);
12817117f1b4Smrg   _mesa_free_program_data(ctx);
12827117f1b4Smrg   _mesa_free_shader_state(ctx);
12834a49301eSmrg   _mesa_free_queryobj_data(ctx);
12844a49301eSmrg   _mesa_free_sync_data(ctx);
12854a49301eSmrg   _mesa_free_varray_data(ctx);
12863464ebd5Sriastradh   _mesa_free_transform_feedback(ctx);
1287b167d5e7Smrg   _mesa_free_performance_monitors(ctx);
12884a49301eSmrg
12894a49301eSmrg   _mesa_reference_buffer_object(ctx, &ctx->Pack.BufferObj, NULL);
12904a49301eSmrg   _mesa_reference_buffer_object(ctx, &ctx->Unpack.BufferObj, NULL);
12914a49301eSmrg   _mesa_reference_buffer_object(ctx, &ctx->DefaultPacking.BufferObj, NULL);
12924a49301eSmrg   _mesa_reference_buffer_object(ctx, &ctx->Array.ArrayBufferObj, NULL);
12937117f1b4Smrg
12947117f1b4Smrg   /* free dispatch tables */
1295b167d5e7Smrg   free(ctx->BeginEnd);
1296b167d5e7Smrg   free(ctx->OutsideBeginEnd);
1297cdc920a0Smrg   free(ctx->Save);
12987117f1b4Smrg
12997117f1b4Smrg   /* Shared context state (display lists, textures, etc) */
1300b167d5e7Smrg   _mesa_reference_shared_state(ctx, &ctx->Shared, NULL);
13014a49301eSmrg
13024a49301eSmrg   /* needs to be after freeing shared state */
13034a49301eSmrg   _mesa_free_display_list_data(ctx);
13047117f1b4Smrg
1305b167d5e7Smrg   _mesa_free_errors_data(ctx);
1306cdc920a0Smrg
1307b167d5e7Smrg   free((void *)ctx->Extensions.String);
1308b167d5e7Smrg
1309b167d5e7Smrg   free(ctx->VersionString);
13107117f1b4Smrg
13117117f1b4Smrg   /* unbind the context if it's currently bound */
13127117f1b4Smrg   if (ctx == _mesa_get_current_context()) {
13137117f1b4Smrg      _mesa_make_current(NULL, NULL, NULL);
13147117f1b4Smrg   }
13157117f1b4Smrg}
13167117f1b4Smrg
13177117f1b4Smrg
13187117f1b4Smrg/**
13193464ebd5Sriastradh * Destroy a struct gl_context structure.
13207117f1b4Smrg *
13217117f1b4Smrg * \param ctx GL context.
13227117f1b4Smrg *
13233464ebd5Sriastradh * Calls _mesa_free_context_data() and frees the gl_context object itself.
13247117f1b4Smrg */
13257117f1b4Smrgvoid
13263464ebd5Sriastradh_mesa_destroy_context( struct gl_context *ctx )
13277117f1b4Smrg{
13287117f1b4Smrg   if (ctx) {
13297117f1b4Smrg      _mesa_free_context_data(ctx);
1330cdc920a0Smrg      free( (void *) ctx );
13317117f1b4Smrg   }
13327117f1b4Smrg}
13337117f1b4Smrg
13347117f1b4Smrg
13357117f1b4Smrg/**
13367117f1b4Smrg * Copy attribute groups from one context to another.
13377117f1b4Smrg *
13387117f1b4Smrg * \param src source context
13397117f1b4Smrg * \param dst destination context
13407117f1b4Smrg * \param mask bitwise OR of GL_*_BIT flags
13417117f1b4Smrg *
13427117f1b4Smrg * According to the bits specified in \p mask, copies the corresponding
13437117f1b4Smrg * attributes from \p src into \p dst.  For many of the attributes a simple \c
13447117f1b4Smrg * memcpy is not enough due to the existence of internal pointers in their data
13457117f1b4Smrg * structures.
13467117f1b4Smrg */
13477117f1b4Smrgvoid
13483464ebd5Sriastradh_mesa_copy_context( const struct gl_context *src, struct gl_context *dst,
13493464ebd5Sriastradh                    GLuint mask )
13507117f1b4Smrg{
13517117f1b4Smrg   if (mask & GL_ACCUM_BUFFER_BIT) {
13527117f1b4Smrg      /* OK to memcpy */
13537117f1b4Smrg      dst->Accum = src->Accum;
13547117f1b4Smrg   }
13557117f1b4Smrg   if (mask & GL_COLOR_BUFFER_BIT) {
13567117f1b4Smrg      /* OK to memcpy */
13577117f1b4Smrg      dst->Color = src->Color;
13587117f1b4Smrg   }
13597117f1b4Smrg   if (mask & GL_CURRENT_BIT) {
13607117f1b4Smrg      /* OK to memcpy */
13617117f1b4Smrg      dst->Current = src->Current;
13627117f1b4Smrg   }
13637117f1b4Smrg   if (mask & GL_DEPTH_BUFFER_BIT) {
13647117f1b4Smrg      /* OK to memcpy */
13657117f1b4Smrg      dst->Depth = src->Depth;
13667117f1b4Smrg   }
13677117f1b4Smrg   if (mask & GL_ENABLE_BIT) {
13687117f1b4Smrg      /* no op */
13697117f1b4Smrg   }
13707117f1b4Smrg   if (mask & GL_EVAL_BIT) {
13717117f1b4Smrg      /* OK to memcpy */
13727117f1b4Smrg      dst->Eval = src->Eval;
13737117f1b4Smrg   }
13747117f1b4Smrg   if (mask & GL_FOG_BIT) {
13757117f1b4Smrg      /* OK to memcpy */
13767117f1b4Smrg      dst->Fog = src->Fog;
13777117f1b4Smrg   }
13787117f1b4Smrg   if (mask & GL_HINT_BIT) {
13797117f1b4Smrg      /* OK to memcpy */
13807117f1b4Smrg      dst->Hint = src->Hint;
13817117f1b4Smrg   }
13827117f1b4Smrg   if (mask & GL_LIGHTING_BIT) {
13837117f1b4Smrg      GLuint i;
13847117f1b4Smrg      /* begin with memcpy */
13857117f1b4Smrg      dst->Light = src->Light;
13867117f1b4Smrg      /* fixup linked lists to prevent pointer insanity */
13877117f1b4Smrg      make_empty_list( &(dst->Light.EnabledList) );
13887117f1b4Smrg      for (i = 0; i < MAX_LIGHTS; i++) {
13897117f1b4Smrg         if (dst->Light.Light[i].Enabled) {
13907117f1b4Smrg            insert_at_tail(&(dst->Light.EnabledList), &(dst->Light.Light[i]));
13917117f1b4Smrg         }
13927117f1b4Smrg      }
13937117f1b4Smrg   }
13947117f1b4Smrg   if (mask & GL_LINE_BIT) {
13957117f1b4Smrg      /* OK to memcpy */
13967117f1b4Smrg      dst->Line = src->Line;
13977117f1b4Smrg   }
13987117f1b4Smrg   if (mask & GL_LIST_BIT) {
13997117f1b4Smrg      /* OK to memcpy */
14007117f1b4Smrg      dst->List = src->List;
14017117f1b4Smrg   }
14027117f1b4Smrg   if (mask & GL_PIXEL_MODE_BIT) {
14037117f1b4Smrg      /* OK to memcpy */
14047117f1b4Smrg      dst->Pixel = src->Pixel;
14057117f1b4Smrg   }
14067117f1b4Smrg   if (mask & GL_POINT_BIT) {
14077117f1b4Smrg      /* OK to memcpy */
14087117f1b4Smrg      dst->Point = src->Point;
14097117f1b4Smrg   }
14107117f1b4Smrg   if (mask & GL_POLYGON_BIT) {
14117117f1b4Smrg      /* OK to memcpy */
14127117f1b4Smrg      dst->Polygon = src->Polygon;
14137117f1b4Smrg   }
14147117f1b4Smrg   if (mask & GL_POLYGON_STIPPLE_BIT) {
1415cdc920a0Smrg      /* Use loop instead of memcpy due to problem with Portland Group's
14167117f1b4Smrg       * C compiler.  Reported by John Stone.
14177117f1b4Smrg       */
14187117f1b4Smrg      GLuint i;
14197117f1b4Smrg      for (i = 0; i < 32; i++) {
14207117f1b4Smrg         dst->PolygonStipple[i] = src->PolygonStipple[i];
14217117f1b4Smrg      }
14227117f1b4Smrg   }
14237117f1b4Smrg   if (mask & GL_SCISSOR_BIT) {
14247117f1b4Smrg      /* OK to memcpy */
14257117f1b4Smrg      dst->Scissor = src->Scissor;
14267117f1b4Smrg   }
14277117f1b4Smrg   if (mask & GL_STENCIL_BUFFER_BIT) {
14287117f1b4Smrg      /* OK to memcpy */
14297117f1b4Smrg      dst->Stencil = src->Stencil;
14307117f1b4Smrg   }
14317117f1b4Smrg   if (mask & GL_TEXTURE_BIT) {
14327117f1b4Smrg      /* Cannot memcpy because of pointers */
14337117f1b4Smrg      _mesa_copy_texture_state(src, dst);
14347117f1b4Smrg   }
14357117f1b4Smrg   if (mask & GL_TRANSFORM_BIT) {
14367117f1b4Smrg      /* OK to memcpy */
14377117f1b4Smrg      dst->Transform = src->Transform;
14387117f1b4Smrg   }
14397117f1b4Smrg   if (mask & GL_VIEWPORT_BIT) {
14407117f1b4Smrg      /* Cannot use memcpy, because of pointers in GLmatrix _WindowMap */
1441b167d5e7Smrg      unsigned i;
1442b167d5e7Smrg      for (i = 0; i < src->Const.MaxViewports; i++) {
1443b167d5e7Smrg         dst->ViewportArray[i].X = src->ViewportArray[i].X;
1444b167d5e7Smrg         dst->ViewportArray[i].Y = src->ViewportArray[i].Y;
1445b167d5e7Smrg         dst->ViewportArray[i].Width = src->ViewportArray[i].Width;
1446b167d5e7Smrg         dst->ViewportArray[i].Height = src->ViewportArray[i].Height;
1447b167d5e7Smrg         dst->ViewportArray[i].Near = src->ViewportArray[i].Near;
1448b167d5e7Smrg         dst->ViewportArray[i].Far = src->ViewportArray[i].Far;
1449b167d5e7Smrg         _math_matrix_copy(&dst->ViewportArray[i]._WindowMap,
1450b167d5e7Smrg                           &src->ViewportArray[i]._WindowMap);
1451b167d5e7Smrg      }
14527117f1b4Smrg   }
14537117f1b4Smrg
14547117f1b4Smrg   /* XXX FIXME:  Call callbacks?
14557117f1b4Smrg    */
14567117f1b4Smrg   dst->NewState = _NEW_ALL;
1457b167d5e7Smrg   dst->NewDriverState = ~0;
14587117f1b4Smrg}
14597117f1b4Smrg
14607117f1b4Smrg
14617117f1b4Smrg/**
14627117f1b4Smrg * Check if the given context can render into the given framebuffer
14637117f1b4Smrg * by checking visual attributes.
14647117f1b4Smrg *
1465c1f859d4Smrg * Most of these tests could go away because Mesa is now pretty flexible
1466c1f859d4Smrg * in terms of mixing rendering contexts with framebuffers.  As long
1467c1f859d4Smrg * as RGB vs. CI mode agree, we're probably good.
14687117f1b4Smrg *
14697117f1b4Smrg * \return GL_TRUE if compatible, GL_FALSE otherwise.
14707117f1b4Smrg */
14717117f1b4Smrgstatic GLboolean
14723464ebd5Sriastradhcheck_compatible(const struct gl_context *ctx,
14733464ebd5Sriastradh                 const struct gl_framebuffer *buffer)
14747117f1b4Smrg{
14753464ebd5Sriastradh   const struct gl_config *ctxvis = &ctx->Visual;
14763464ebd5Sriastradh   const struct gl_config *bufvis = &buffer->Visual;
14777117f1b4Smrg
14783464ebd5Sriastradh   if (buffer == _mesa_get_incomplete_framebuffer())
14797117f1b4Smrg      return GL_TRUE;
14807117f1b4Smrg
14817117f1b4Smrg#if 0
14827117f1b4Smrg   /* disabling this fixes the fgl_glxgears pbuffer demo */
14837117f1b4Smrg   if (ctxvis->doubleBufferMode && !bufvis->doubleBufferMode)
14847117f1b4Smrg      return GL_FALSE;
14857117f1b4Smrg#endif
14867117f1b4Smrg   if (ctxvis->stereoMode && !bufvis->stereoMode)
14877117f1b4Smrg      return GL_FALSE;
14887117f1b4Smrg   if (ctxvis->haveAccumBuffer && !bufvis->haveAccumBuffer)
14897117f1b4Smrg      return GL_FALSE;
14907117f1b4Smrg   if (ctxvis->haveDepthBuffer && !bufvis->haveDepthBuffer)
14917117f1b4Smrg      return GL_FALSE;
14927117f1b4Smrg   if (ctxvis->haveStencilBuffer && !bufvis->haveStencilBuffer)
14937117f1b4Smrg      return GL_FALSE;
14947117f1b4Smrg   if (ctxvis->redMask && ctxvis->redMask != bufvis->redMask)
14957117f1b4Smrg      return GL_FALSE;
14967117f1b4Smrg   if (ctxvis->greenMask && ctxvis->greenMask != bufvis->greenMask)
14977117f1b4Smrg      return GL_FALSE;
14987117f1b4Smrg   if (ctxvis->blueMask && ctxvis->blueMask != bufvis->blueMask)
14997117f1b4Smrg      return GL_FALSE;
15007117f1b4Smrg#if 0
15017117f1b4Smrg   /* disabled (see bug 11161) */
15027117f1b4Smrg   if (ctxvis->depthBits && ctxvis->depthBits != bufvis->depthBits)
15037117f1b4Smrg      return GL_FALSE;
15047117f1b4Smrg#endif
15057117f1b4Smrg   if (ctxvis->stencilBits && ctxvis->stencilBits != bufvis->stencilBits)
15067117f1b4Smrg      return GL_FALSE;
15077117f1b4Smrg
15087117f1b4Smrg   return GL_TRUE;
15097117f1b4Smrg}
15107117f1b4Smrg
15117117f1b4Smrg
1512c7037ccdSmrg/**
1513c7037ccdSmrg * Check if the viewport/scissor size has not yet been initialized.
1514c7037ccdSmrg * Initialize the size if the given width and height are non-zero.
1515c7037ccdSmrg */
1516c7037ccdSmrgvoid
15173464ebd5Sriastradh_mesa_check_init_viewport(struct gl_context *ctx, GLuint width, GLuint height)
1518c7037ccdSmrg{
1519c7037ccdSmrg   if (!ctx->ViewportInitialized && width > 0 && height > 0) {
1520b167d5e7Smrg      unsigned i;
1521b167d5e7Smrg
1522c7037ccdSmrg      /* Note: set flag here, before calling _mesa_set_viewport(), to prevent
1523c7037ccdSmrg       * potential infinite recursion.
1524c7037ccdSmrg       */
1525c7037ccdSmrg      ctx->ViewportInitialized = GL_TRUE;
1526b167d5e7Smrg
1527b167d5e7Smrg      /* Note: ctx->Const.MaxViewports may not have been set by the driver
1528b167d5e7Smrg       * yet, so just initialize all of them.
1529b167d5e7Smrg       */
1530b167d5e7Smrg      for (i = 0; i < MAX_VIEWPORTS; i++) {
1531b167d5e7Smrg         _mesa_set_viewport(ctx, i, 0, 0, width, height);
1532b167d5e7Smrg         _mesa_set_scissor(ctx, i, 0, 0, width, height);
1533b167d5e7Smrg      }
1534c7037ccdSmrg   }
1535c7037ccdSmrg}
1536c7037ccdSmrg
1537b167d5e7Smrgstatic void
1538b167d5e7Smrghandle_first_current(struct gl_context *ctx)
1539b167d5e7Smrg{
1540b167d5e7Smrg   GLenum buffer;
1541b167d5e7Smrg   GLint bufferIndex;
1542b167d5e7Smrg
1543b167d5e7Smrg   assert(ctx->Version > 0);
1544b167d5e7Smrg
1545b167d5e7Smrg   ctx->Extensions.String = _mesa_make_extension_string(ctx);
1546b167d5e7Smrg
1547b167d5e7Smrg   check_context_limits(ctx);
1548b167d5e7Smrg
1549b167d5e7Smrg   /* According to GL_MESA_configless_context the default value of
1550b167d5e7Smrg    * glDrawBuffers depends on the config of the first surface it is bound to.
1551b167d5e7Smrg    * For GLES it is always GL_BACK which has a magic interpretation */
1552b167d5e7Smrg   if (!ctx->HasConfig && _mesa_is_desktop_gl(ctx)) {
1553b167d5e7Smrg      if (ctx->DrawBuffer != _mesa_get_incomplete_framebuffer()) {
1554b167d5e7Smrg         if (ctx->DrawBuffer->Visual.doubleBufferMode)
1555b167d5e7Smrg            buffer = GL_BACK;
1556b167d5e7Smrg         else
1557b167d5e7Smrg            buffer = GL_FRONT;
1558b167d5e7Smrg
1559b167d5e7Smrg         _mesa_drawbuffers(ctx, 1, &buffer, NULL /* destMask */);
1560b167d5e7Smrg      }
1561b167d5e7Smrg
1562b167d5e7Smrg      if (ctx->ReadBuffer != _mesa_get_incomplete_framebuffer()) {
1563b167d5e7Smrg         if (ctx->ReadBuffer->Visual.doubleBufferMode) {
1564b167d5e7Smrg            buffer = GL_BACK;
1565b167d5e7Smrg            bufferIndex = BUFFER_BACK_LEFT;
1566b167d5e7Smrg         }
1567b167d5e7Smrg         else {
1568b167d5e7Smrg            buffer = GL_FRONT;
1569b167d5e7Smrg            bufferIndex = BUFFER_FRONT_LEFT;
1570b167d5e7Smrg         }
1571b167d5e7Smrg
1572b167d5e7Smrg         _mesa_readbuffer(ctx, buffer, bufferIndex);
1573b167d5e7Smrg      }
1574b167d5e7Smrg   }
1575b167d5e7Smrg
1576b167d5e7Smrg   /* We can use this to help debug user's problems.  Tell them to set
1577b167d5e7Smrg    * the MESA_INFO env variable before running their app.  Then the
1578b167d5e7Smrg    * first time each context is made current we'll print some useful
1579b167d5e7Smrg    * information.
1580b167d5e7Smrg    */
1581b167d5e7Smrg   if (_mesa_getenv("MESA_INFO")) {
1582b167d5e7Smrg      _mesa_print_info(ctx);
1583b167d5e7Smrg   }
1584b167d5e7Smrg}
1585c7037ccdSmrg
15867117f1b4Smrg/**
15877117f1b4Smrg * Bind the given context to the given drawBuffer and readBuffer and
15887117f1b4Smrg * make it the current context for the calling thread.
15897117f1b4Smrg * We'll render into the drawBuffer and read pixels from the
15907117f1b4Smrg * readBuffer (i.e. glRead/CopyPixels, glCopyTexImage, etc).
15917117f1b4Smrg *
15927117f1b4Smrg * We check that the context's and framebuffer's visuals are compatible
15937117f1b4Smrg * and return immediately if they're not.
15947117f1b4Smrg *
15957117f1b4Smrg * \param newCtx  the new GL context. If NULL then there will be no current GL
15967117f1b4Smrg *                context.
15977117f1b4Smrg * \param drawBuffer  the drawing framebuffer
15987117f1b4Smrg * \param readBuffer  the reading framebuffer
15997117f1b4Smrg */
16004a49301eSmrgGLboolean
16013464ebd5Sriastradh_mesa_make_current( struct gl_context *newCtx,
16023464ebd5Sriastradh                    struct gl_framebuffer *drawBuffer,
16033464ebd5Sriastradh                    struct gl_framebuffer *readBuffer )
16047117f1b4Smrg{
16053464ebd5Sriastradh   GET_CURRENT_CONTEXT(curCtx);
16063464ebd5Sriastradh
16077117f1b4Smrg   if (MESA_VERBOSE & VERBOSE_API)
16087117f1b4Smrg      _mesa_debug(newCtx, "_mesa_make_current()\n");
16097117f1b4Smrg
16107117f1b4Smrg   /* Check that the context's and framebuffer's visuals are compatible.
16117117f1b4Smrg    */
16127117f1b4Smrg   if (newCtx && drawBuffer && newCtx->WinSysDrawBuffer != drawBuffer) {
16137117f1b4Smrg      if (!check_compatible(newCtx, drawBuffer)) {
16147117f1b4Smrg         _mesa_warning(newCtx,
16157117f1b4Smrg              "MakeCurrent: incompatible visuals for context and drawbuffer");
16164a49301eSmrg         return GL_FALSE;
16177117f1b4Smrg      }
16187117f1b4Smrg   }
16197117f1b4Smrg   if (newCtx && readBuffer && newCtx->WinSysReadBuffer != readBuffer) {
16207117f1b4Smrg      if (!check_compatible(newCtx, readBuffer)) {
16217117f1b4Smrg         _mesa_warning(newCtx,
16227117f1b4Smrg              "MakeCurrent: incompatible visuals for context and readbuffer");
16234a49301eSmrg         return GL_FALSE;
16247117f1b4Smrg      }
16257117f1b4Smrg   }
16267117f1b4Smrg
16273464ebd5Sriastradh   if (curCtx &&
16283464ebd5Sriastradh      (curCtx->WinSysDrawBuffer || curCtx->WinSysReadBuffer) &&
16293464ebd5Sriastradh       /* make sure this context is valid for flushing */
16303464ebd5Sriastradh      curCtx != newCtx)
16313464ebd5Sriastradh      _mesa_flush(curCtx);
16323464ebd5Sriastradh
16337117f1b4Smrg   /* We used to call _glapi_check_multithread() here.  Now do it in drivers */
16347117f1b4Smrg   _glapi_set_context((void *) newCtx);
16357117f1b4Smrg   ASSERT(_mesa_get_current_context() == newCtx);
16367117f1b4Smrg
16377117f1b4Smrg   if (!newCtx) {
16387117f1b4Smrg      _glapi_set_dispatch(NULL);  /* none current */
16397117f1b4Smrg   }
16407117f1b4Smrg   else {
16417117f1b4Smrg      _glapi_set_dispatch(newCtx->CurrentDispatch);
16427117f1b4Smrg
16437117f1b4Smrg      if (drawBuffer && readBuffer) {
1644b167d5e7Smrg         ASSERT(_mesa_is_winsys_fbo(drawBuffer));
1645b167d5e7Smrg         ASSERT(_mesa_is_winsys_fbo(readBuffer));
16467117f1b4Smrg         _mesa_reference_framebuffer(&newCtx->WinSysDrawBuffer, drawBuffer);
16477117f1b4Smrg         _mesa_reference_framebuffer(&newCtx->WinSysReadBuffer, readBuffer);
16487117f1b4Smrg
16497117f1b4Smrg         /*
16507117f1b4Smrg          * Only set the context's Draw/ReadBuffer fields if they're NULL
16517117f1b4Smrg          * or not bound to a user-created FBO.
16527117f1b4Smrg          */
1653b167d5e7Smrg         if (!newCtx->DrawBuffer || _mesa_is_winsys_fbo(newCtx->DrawBuffer)) {
16547117f1b4Smrg            _mesa_reference_framebuffer(&newCtx->DrawBuffer, drawBuffer);
16553464ebd5Sriastradh            /* Update the FBO's list of drawbuffers/renderbuffers.
16563464ebd5Sriastradh             * For winsys FBOs this comes from the GL state (which may have
16573464ebd5Sriastradh             * changed since the last time this FBO was bound).
16583464ebd5Sriastradh             */
16593464ebd5Sriastradh            _mesa_update_draw_buffers(newCtx);
16607117f1b4Smrg         }
1661b167d5e7Smrg         if (!newCtx->ReadBuffer || _mesa_is_winsys_fbo(newCtx->ReadBuffer)) {
16627117f1b4Smrg            _mesa_reference_framebuffer(&newCtx->ReadBuffer, readBuffer);
16637117f1b4Smrg         }
16647117f1b4Smrg
1665c1f859d4Smrg         /* XXX only set this flag if we're really changing the draw/read
1666c1f859d4Smrg          * framebuffer bindings.
1667c1f859d4Smrg          */
16687117f1b4Smrg	 newCtx->NewState |= _NEW_BUFFERS;
16697117f1b4Smrg
1670c7037ccdSmrg         if (drawBuffer) {
1671c7037ccdSmrg            _mesa_check_init_viewport(newCtx,
1672c7037ccdSmrg                                      drawBuffer->Width, drawBuffer->Height);
16737117f1b4Smrg         }
16747117f1b4Smrg      }
16757117f1b4Smrg
16767117f1b4Smrg      if (newCtx->FirstTimeCurrent) {
1677b167d5e7Smrg         handle_first_current(newCtx);
16787117f1b4Smrg	 newCtx->FirstTimeCurrent = GL_FALSE;
16797117f1b4Smrg      }
16807117f1b4Smrg   }
16814a49301eSmrg
16824a49301eSmrg   return GL_TRUE;
16837117f1b4Smrg}
16847117f1b4Smrg
16857117f1b4Smrg
16867117f1b4Smrg/**
16877117f1b4Smrg * Make context 'ctx' share the display lists, textures and programs
16887117f1b4Smrg * that are associated with 'ctxToShare'.
16897117f1b4Smrg * Any display lists, textures or programs associated with 'ctx' will
16907117f1b4Smrg * be deleted if nobody else is sharing them.
16917117f1b4Smrg */
16927117f1b4SmrgGLboolean
16933464ebd5Sriastradh_mesa_share_state(struct gl_context *ctx, struct gl_context *ctxToShare)
16947117f1b4Smrg{
16957117f1b4Smrg   if (ctx && ctxToShare && ctx->Shared && ctxToShare->Shared) {
1696b167d5e7Smrg      struct gl_shared_state *oldShared = NULL;
1697b167d5e7Smrg
1698b167d5e7Smrg      /* save ref to old state to prevent it from being deleted immediately */
1699b167d5e7Smrg      _mesa_reference_shared_state(ctx, &oldShared, ctx->Shared);
1700c1f859d4Smrg
1701b167d5e7Smrg      /* update ctx's Shared pointer */
1702b167d5e7Smrg      _mesa_reference_shared_state(ctx, &ctx->Shared, ctxToShare->Shared);
1703c1f859d4Smrg
1704c1f859d4Smrg      update_default_objects(ctx);
1705c1f859d4Smrg
1706b167d5e7Smrg      /* release the old shared state */
1707b167d5e7Smrg      _mesa_reference_shared_state(ctx, &oldShared, NULL);
1708c1f859d4Smrg
17097117f1b4Smrg      return GL_TRUE;
17107117f1b4Smrg   }
17117117f1b4Smrg   else {
17127117f1b4Smrg      return GL_FALSE;
17137117f1b4Smrg   }
17147117f1b4Smrg}
17157117f1b4Smrg
17167117f1b4Smrg
17177117f1b4Smrg
17187117f1b4Smrg/**
17197117f1b4Smrg * \return pointer to the current GL context for this thread.
17207117f1b4Smrg *
17217117f1b4Smrg * Calls _glapi_get_context(). This isn't the fastest way to get the current
17227117f1b4Smrg * context.  If you need speed, see the #GET_CURRENT_CONTEXT macro in
17237117f1b4Smrg * context.h.
17247117f1b4Smrg */
17253464ebd5Sriastradhstruct gl_context *
17267117f1b4Smrg_mesa_get_current_context( void )
17277117f1b4Smrg{
17283464ebd5Sriastradh   return (struct gl_context *) _glapi_get_context();
17297117f1b4Smrg}
17307117f1b4Smrg
17317117f1b4Smrg
17327117f1b4Smrg/**
17337117f1b4Smrg * Get context's current API dispatch table.
17347117f1b4Smrg *
17357117f1b4Smrg * It'll either be the immediate-mode execute dispatcher or the display list
17367117f1b4Smrg * compile dispatcher.
17377117f1b4Smrg *
17387117f1b4Smrg * \param ctx GL context.
17397117f1b4Smrg *
17407117f1b4Smrg * \return pointer to dispatch_table.
17417117f1b4Smrg *
17423464ebd5Sriastradh * Simply returns __struct gl_contextRec::CurrentDispatch.
17437117f1b4Smrg */
17447117f1b4Smrgstruct _glapi_table *
17453464ebd5Sriastradh_mesa_get_dispatch(struct gl_context *ctx)
17467117f1b4Smrg{
17477117f1b4Smrg   return ctx->CurrentDispatch;
17487117f1b4Smrg}
17497117f1b4Smrg
17507117f1b4Smrg/*@}*/
17517117f1b4Smrg
17527117f1b4Smrg
17537117f1b4Smrg/**********************************************************************/
17547117f1b4Smrg/** \name Miscellaneous functions                                     */
17557117f1b4Smrg/**********************************************************************/
17567117f1b4Smrg/*@{*/
17577117f1b4Smrg
17587117f1b4Smrg/**
17597117f1b4Smrg * Record an error.
17607117f1b4Smrg *
17617117f1b4Smrg * \param ctx GL context.
17627117f1b4Smrg * \param error error code.
17637117f1b4Smrg *
17647117f1b4Smrg * Records the given error code and call the driver's dd_function_table::Error
17657117f1b4Smrg * function if defined.
17667117f1b4Smrg *
17677117f1b4Smrg * \sa
17687117f1b4Smrg * This is called via _mesa_error().
17697117f1b4Smrg */
17707117f1b4Smrgvoid
17713464ebd5Sriastradh_mesa_record_error(struct gl_context *ctx, GLenum error)
17727117f1b4Smrg{
17737117f1b4Smrg   if (!ctx)
17747117f1b4Smrg      return;
17757117f1b4Smrg
17767117f1b4Smrg   if (ctx->ErrorValue == GL_NO_ERROR) {
17777117f1b4Smrg      ctx->ErrorValue = error;
17787117f1b4Smrg   }
17797117f1b4Smrg}
17807117f1b4Smrg
17817117f1b4Smrg
17824a49301eSmrg/**
17834a49301eSmrg * Flush commands and wait for completion.
17844a49301eSmrg */
17854a49301eSmrgvoid
17863464ebd5Sriastradh_mesa_finish(struct gl_context *ctx)
17874a49301eSmrg{
1788b167d5e7Smrg   FLUSH_VERTICES( ctx, 0 );
17894a49301eSmrg   FLUSH_CURRENT( ctx, 0 );
17904a49301eSmrg   if (ctx->Driver.Finish) {
17914a49301eSmrg      ctx->Driver.Finish(ctx);
17924a49301eSmrg   }
17934a49301eSmrg}
17944a49301eSmrg
17954a49301eSmrg
17964a49301eSmrg/**
17974a49301eSmrg * Flush commands.
17984a49301eSmrg */
17994a49301eSmrgvoid
18003464ebd5Sriastradh_mesa_flush(struct gl_context *ctx)
18014a49301eSmrg{
1802b167d5e7Smrg   FLUSH_VERTICES( ctx, 0 );
18034a49301eSmrg   FLUSH_CURRENT( ctx, 0 );
18044a49301eSmrg   if (ctx->Driver.Flush) {
18054a49301eSmrg      ctx->Driver.Flush(ctx);
18064a49301eSmrg   }
18074a49301eSmrg}
18084a49301eSmrg
18094a49301eSmrg
18104a49301eSmrg
18117117f1b4Smrg/**
18127117f1b4Smrg * Execute glFinish().
18137117f1b4Smrg *
18147117f1b4Smrg * Calls the #ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH macro and the
18157117f1b4Smrg * dd_function_table::Finish driver callback, if not NULL.
18167117f1b4Smrg */
18177117f1b4Smrgvoid GLAPIENTRY
18187117f1b4Smrg_mesa_Finish(void)
18197117f1b4Smrg{
18207117f1b4Smrg   GET_CURRENT_CONTEXT(ctx);
1821b167d5e7Smrg   ASSERT_OUTSIDE_BEGIN_END(ctx);
18224a49301eSmrg   _mesa_finish(ctx);
18237117f1b4Smrg}
18247117f1b4Smrg
18257117f1b4Smrg
18267117f1b4Smrg/**
18277117f1b4Smrg * Execute glFlush().
18287117f1b4Smrg *
18297117f1b4Smrg * Calls the #ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH macro and the
18307117f1b4Smrg * dd_function_table::Flush driver callback, if not NULL.
18317117f1b4Smrg */
18327117f1b4Smrgvoid GLAPIENTRY
18337117f1b4Smrg_mesa_Flush(void)
18347117f1b4Smrg{
18357117f1b4Smrg   GET_CURRENT_CONTEXT(ctx);
1836b167d5e7Smrg   ASSERT_OUTSIDE_BEGIN_END(ctx);
18374a49301eSmrg   _mesa_flush(ctx);
18384a49301eSmrg}
18394a49301eSmrg
18404a49301eSmrg
1841b167d5e7Smrg/*
1842b167d5e7Smrg * ARB_blend_func_extended - ERRORS section
1843b167d5e7Smrg * "The error INVALID_OPERATION is generated by Begin or any procedure that
1844b167d5e7Smrg *  implicitly calls Begin if any draw buffer has a blend function requiring the
1845b167d5e7Smrg *  second color input (SRC1_COLOR, ONE_MINUS_SRC1_COLOR, SRC1_ALPHA or
1846b167d5e7Smrg *  ONE_MINUS_SRC1_ALPHA), and a framebuffer is bound that has more than
1847b167d5e7Smrg *  the value of MAX_DUAL_SOURCE_DRAW_BUFFERS-1 active color attachements."
18484a49301eSmrg */
1849b167d5e7Smrgstatic GLboolean
1850b167d5e7Smrg_mesa_check_blend_func_error(struct gl_context *ctx)
18514a49301eSmrg{
1852b167d5e7Smrg   GLuint i;
1853b167d5e7Smrg   for (i = ctx->Const.MaxDualSourceDrawBuffers;
1854b167d5e7Smrg	i < ctx->DrawBuffer->_NumColorDrawBuffers;
1855b167d5e7Smrg	i++) {
1856b167d5e7Smrg      if (ctx->Color.Blend[i]._UsesDualSrc) {
1857b167d5e7Smrg	 _mesa_error(ctx, GL_INVALID_OPERATION,
1858b167d5e7Smrg		     "dual source blend on illegal attachment");
1859b167d5e7Smrg	 return GL_FALSE;
1860b167d5e7Smrg      }
1861b167d5e7Smrg   }
1862b167d5e7Smrg   return GL_TRUE;
18634a49301eSmrg}
18644a49301eSmrg
1865b167d5e7Smrgstatic bool
1866b167d5e7Smrgshader_linked_or_absent(struct gl_context *ctx,
1867b167d5e7Smrg                        const struct gl_shader_program *shProg,
1868b167d5e7Smrg                        bool *shader_present, const char *where)
1869b167d5e7Smrg{
1870b167d5e7Smrg   if (shProg) {
1871b167d5e7Smrg      *shader_present = true;
18724a49301eSmrg
1873b167d5e7Smrg      if (!shProg->LinkStatus) {
1874b167d5e7Smrg         _mesa_error(ctx, GL_INVALID_OPERATION, "%s(shader not linked)", where);
1875b167d5e7Smrg         return false;
1876b167d5e7Smrg      }
1877b167d5e7Smrg#if 0 /* not normally enabled */
1878b167d5e7Smrg      {
1879b167d5e7Smrg         char errMsg[100];
1880b167d5e7Smrg         if (!_mesa_validate_shader_program(ctx, shProg, errMsg)) {
1881b167d5e7Smrg            _mesa_warning(ctx, "Shader program %u is invalid: %s",
1882b167d5e7Smrg                          shProg->Name, errMsg);
1883b167d5e7Smrg         }
1884b167d5e7Smrg      }
1885b167d5e7Smrg#endif
1886b167d5e7Smrg   }
1887b167d5e7Smrg
1888b167d5e7Smrg   return true;
1889b167d5e7Smrg}
18904a49301eSmrg
18914a49301eSmrg/**
18924a49301eSmrg * Prior to drawing anything with glBegin, glDrawArrays, etc. this function
18934a49301eSmrg * is called to see if it's valid to render.  This involves checking that
18944a49301eSmrg * the current shader is valid and the framebuffer is complete.
1895b167d5e7Smrg * It also check the current pipeline object is valid if any.
18964a49301eSmrg * If an error is detected it'll be recorded here.
18974a49301eSmrg * \return GL_TRUE if OK to render, GL_FALSE if not
18984a49301eSmrg */
18994a49301eSmrgGLboolean
19003464ebd5Sriastradh_mesa_valid_to_render(struct gl_context *ctx, const char *where)
19014a49301eSmrg{
1902b167d5e7Smrg   bool from_glsl_shader[MESA_SHADER_COMPUTE] = { false };
1903b167d5e7Smrg   unsigned i;
19043464ebd5Sriastradh
19054a49301eSmrg   /* This depends on having up to date derived state (shaders) */
19064a49301eSmrg   if (ctx->NewState)
19074a49301eSmrg      _mesa_update_state(ctx);
19084a49301eSmrg
1909b167d5e7Smrg   for (i = 0; i < MESA_SHADER_COMPUTE; i++) {
1910b167d5e7Smrg      if (!shader_linked_or_absent(ctx, ctx->_Shader->CurrentProgram[i],
1911b167d5e7Smrg                                   &from_glsl_shader[i], where))
19123464ebd5Sriastradh         return GL_FALSE;
19133464ebd5Sriastradh   }
19143464ebd5Sriastradh
19153464ebd5Sriastradh   /* Any shader stages that are not supplied by the GLSL shader and have
19163464ebd5Sriastradh    * assembly shaders enabled must now be validated.
19173464ebd5Sriastradh    */
1918b167d5e7Smrg   if (!from_glsl_shader[MESA_SHADER_VERTEX]
19193464ebd5Sriastradh       && ctx->VertexProgram.Enabled && !ctx->VertexProgram._Enabled) {
19203464ebd5Sriastradh      _mesa_error(ctx, GL_INVALID_OPERATION,
19213464ebd5Sriastradh		  "%s(vertex program not valid)", where);
19223464ebd5Sriastradh      return GL_FALSE;
19233464ebd5Sriastradh   }
19243464ebd5Sriastradh
19253464ebd5Sriastradh   /* FINISHME: If GL_NV_geometry_program4 is ever supported, the current
19263464ebd5Sriastradh    * FINISHME: geometry program should validated here.
19273464ebd5Sriastradh    */
1928b167d5e7Smrg   (void) from_glsl_shader[MESA_SHADER_GEOMETRY];
19293464ebd5Sriastradh
1930b167d5e7Smrg   if (!from_glsl_shader[MESA_SHADER_FRAGMENT]) {
19314a49301eSmrg      if (ctx->FragmentProgram.Enabled && !ctx->FragmentProgram._Enabled) {
19323464ebd5Sriastradh	 _mesa_error(ctx, GL_INVALID_OPERATION,
19333464ebd5Sriastradh		     "%s(fragment program not valid)", where);
19343464ebd5Sriastradh	 return GL_FALSE;
19353464ebd5Sriastradh      }
19363464ebd5Sriastradh
19373464ebd5Sriastradh      /* If drawing to integer-valued color buffers, there must be an
19383464ebd5Sriastradh       * active fragment shader (GL_EXT_texture_integer).
19393464ebd5Sriastradh       */
19403464ebd5Sriastradh      if (ctx->DrawBuffer && ctx->DrawBuffer->_IntegerColor) {
19414a49301eSmrg         _mesa_error(ctx, GL_INVALID_OPERATION,
19423464ebd5Sriastradh                     "%s(integer format but no fragment shader)", where);
19434a49301eSmrg         return GL_FALSE;
19444a49301eSmrg      }
19457117f1b4Smrg   }
19464a49301eSmrg
1947b167d5e7Smrg   /* A pipeline object is bound */
1948b167d5e7Smrg   if (ctx->_Shader->Name && !ctx->_Shader->Validated) {
1949b167d5e7Smrg      /* Error message will be printed inside _mesa_validate_program_pipeline.
1950b167d5e7Smrg       */
1951b167d5e7Smrg      if (!_mesa_validate_program_pipeline(ctx, ctx->_Shader, GL_TRUE)) {
1952b167d5e7Smrg         return GL_FALSE;
1953b167d5e7Smrg      }
1954b167d5e7Smrg   }
1955b167d5e7Smrg
19564a49301eSmrg   if (ctx->DrawBuffer->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) {
19574a49301eSmrg      _mesa_error(ctx, GL_INVALID_FRAMEBUFFER_OPERATION_EXT,
19584a49301eSmrg                  "%s(incomplete framebuffer)", where);
19594a49301eSmrg      return GL_FALSE;
19604a49301eSmrg   }
19614a49301eSmrg
1962b167d5e7Smrg   if (_mesa_check_blend_func_error(ctx) == GL_FALSE) {
1963b167d5e7Smrg      return GL_FALSE;
1964b167d5e7Smrg   }
19653464ebd5Sriastradh
1966b167d5e7Smrg#ifdef DEBUG
1967b167d5e7Smrg   if (ctx->_Shader->Flags & GLSL_LOG) {
1968b167d5e7Smrg      struct gl_shader_program **shProg = ctx->_Shader->CurrentProgram;
1969b167d5e7Smrg      gl_shader_stage i;
19703464ebd5Sriastradh
1971b167d5e7Smrg      for (i = 0; i < MESA_SHADER_STAGES; i++) {
19723464ebd5Sriastradh	 if (shProg[i] == NULL || shProg[i]->_Used
19733464ebd5Sriastradh	     || shProg[i]->_LinkedShaders[i] == NULL)
19743464ebd5Sriastradh	    continue;
19753464ebd5Sriastradh
19763464ebd5Sriastradh	 /* This is the first time this shader is being used.
19773464ebd5Sriastradh	  * Append shader's constants/uniforms to log file.
19783464ebd5Sriastradh	  *
1979b167d5e7Smrg	  * Only log data for the program target that matches the shader
1980b167d5e7Smrg	  * target.  It's possible to have a program bound to the vertex
19813464ebd5Sriastradh	  * shader target that also supplied a fragment shader.  If that
19823464ebd5Sriastradh	  * program isn't also bound to the fragment shader target we don't
19833464ebd5Sriastradh	  * want to log its fragment data.
19843464ebd5Sriastradh	  */
1985b167d5e7Smrg	 _mesa_append_uniforms_to_file(shProg[i]->_LinkedShaders[i]);
19863464ebd5Sriastradh      }
19873464ebd5Sriastradh
1988b167d5e7Smrg      for (i = 0; i < MESA_SHADER_STAGES; i++) {
19893464ebd5Sriastradh	 if (shProg[i] != NULL)
19903464ebd5Sriastradh	    shProg[i]->_Used = GL_TRUE;
19914a49301eSmrg      }
19924a49301eSmrg   }
19934a49301eSmrg#endif
19944a49301eSmrg
19954a49301eSmrg   return GL_TRUE;
19967117f1b4Smrg}
19977117f1b4Smrg
19987117f1b4Smrg
19997117f1b4Smrg/*@}*/
2000