context.c revision 68ee4bc7caf5a48c8a5c51efc258e74eb9689905
1/* $Id: context.c,v 1.35 2000/01/28 19:02:22 brianp Exp $ */
2
3/*
4 * Mesa 3-D graphics library
5 * Version:  3.3
6 *
7 * Copyright (C) 1999-2000  Brian Paul   All Rights Reserved.
8 *
9 * Permission is hereby granted, free of charge, to any person obtaining a
10 * copy of this software and associated documentation files (the "Software"),
11 * to deal in the Software without restriction, including without limitation
12 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
13 * and/or sell copies of the Software, and to permit persons to whom the
14 * Software is furnished to do so, subject to the following conditions:
15 *
16 * The above copyright notice and this permission notice shall be included
17 * in all copies or substantial portions of the Software.
18 *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
22 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
23 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
24 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 */
26
27
28#ifdef PC_HEADER
29#include "all.h"
30#else
31#include "glheader.h"
32#include "accum.h"
33#include "alphabuf.h"
34#include "clip.h"
35#include "context.h"
36#include "cva.h"
37#include "depth.h"
38#include "dispatch.h"
39#include "dlist.h"
40#include "eval.h"
41#include "enums.h"
42#include "extensions.h"
43#include "fog.h"
44#include "get.h"
45#include "glapi.h"
46#include "hash.h"
47#include "light.h"
48#include "lines.h"
49#include "dlist.h"
50#include "macros.h"
51#include "matrix.h"
52#include "mem.h"
53#include "mmath.h"
54#include "pb.h"
55#include "pipeline.h"
56#include "points.h"
57#include "quads.h"
58#include "shade.h"
59#include "simple_list.h"
60#include "stencil.h"
61#include "stages.h"
62#include "triangle.h"
63#include "translate.h"
64#include "teximage.h"
65#include "texobj.h"
66#include "texstate.h"
67#include "texture.h"
68#include "types.h"
69#include "varray.h"
70#include "vb.h"
71#include "vbcull.h"
72#include "vbfill.h"
73#include "vbrender.h"
74#include "vbxform.h"
75#include "vertices.h"
76#include "xform.h"
77#endif
78
79
80
81/**********************************************************************/
82/*****                  Context and Thread management             *****/
83/**********************************************************************/
84
85
86#if !defined(THREADS)
87
88struct immediate *_mesa_CurrentInput = NULL;
89
90#endif
91
92
93
94
95/**********************************************************************/
96/*****                   Profiling functions                      *****/
97/**********************************************************************/
98
99#ifdef PROFILE
100
101#include <sys/times.h>
102#include <sys/param.h>
103
104
105/*
106 * Return system time in seconds.
107 * NOTE:  this implementation may not be very portable!
108 */
109GLdouble gl_time( void )
110{
111   static GLdouble prev_time = 0.0;
112   static GLdouble time;
113   struct tms tm;
114   clock_t clk;
115
116   clk = times(&tm);
117
118#ifdef CLK_TCK
119   time = (double)clk / (double)CLK_TCK;
120#else
121   time = (double)clk / (double)HZ;
122#endif
123
124   if (time>prev_time) {
125      prev_time = time;
126      return time;
127   }
128   else {
129      return prev_time;
130   }
131}
132
133/*
134 * Reset the timing/profiling counters
135 */
136static void init_timings( GLcontext *ctx )
137{
138   ctx->BeginEndCount = 0;
139   ctx->BeginEndTime = 0.0;
140   ctx->VertexCount = 0;
141   ctx->VertexTime = 0.0;
142   ctx->PointCount = 0;
143   ctx->PointTime = 0.0;
144   ctx->LineCount = 0;
145   ctx->LineTime = 0.0;
146   ctx->PolygonCount = 0;
147   ctx->PolygonTime = 0.0;
148   ctx->ClearCount = 0;
149   ctx->ClearTime = 0.0;
150   ctx->SwapCount = 0;
151   ctx->SwapTime = 0.0;
152}
153
154
155/*
156 * Print the accumulated timing/profiling data.
157 */
158static void print_timings( GLcontext *ctx )
159{
160   GLdouble beginendrate;
161   GLdouble vertexrate;
162   GLdouble pointrate;
163   GLdouble linerate;
164   GLdouble polygonrate;
165   GLdouble overhead;
166   GLdouble clearrate;
167   GLdouble swaprate;
168   GLdouble avgvertices;
169
170   if (ctx->BeginEndTime>0.0) {
171      beginendrate = ctx->BeginEndCount / ctx->BeginEndTime;
172   }
173   else {
174      beginendrate = 0.0;
175   }
176   if (ctx->VertexTime>0.0) {
177      vertexrate = ctx->VertexCount / ctx->VertexTime;
178   }
179   else {
180      vertexrate = 0.0;
181   }
182   if (ctx->PointTime>0.0) {
183      pointrate = ctx->PointCount / ctx->PointTime;
184   }
185   else {
186      pointrate = 0.0;
187   }
188   if (ctx->LineTime>0.0) {
189      linerate = ctx->LineCount / ctx->LineTime;
190   }
191   else {
192      linerate = 0.0;
193   }
194   if (ctx->PolygonTime>0.0) {
195      polygonrate = ctx->PolygonCount / ctx->PolygonTime;
196   }
197   else {
198      polygonrate = 0.0;
199   }
200   if (ctx->ClearTime>0.0) {
201      clearrate = ctx->ClearCount / ctx->ClearTime;
202   }
203   else {
204      clearrate = 0.0;
205   }
206   if (ctx->SwapTime>0.0) {
207      swaprate = ctx->SwapCount / ctx->SwapTime;
208   }
209   else {
210      swaprate = 0.0;
211   }
212
213   if (ctx->BeginEndCount>0) {
214      avgvertices = (GLdouble) ctx->VertexCount / (GLdouble) ctx->BeginEndCount;
215   }
216   else {
217      avgvertices = 0.0;
218   }
219
220   overhead = ctx->BeginEndTime - ctx->VertexTime - ctx->PointTime
221              - ctx->LineTime - ctx->PolygonTime;
222
223
224   printf("                          Count   Time (s)    Rate (/s) \n");
225   printf("--------------------------------------------------------\n");
226   printf("glBegin/glEnd           %7d  %8.3f   %10.3f\n",
227          ctx->BeginEndCount, ctx->BeginEndTime, beginendrate);
228   printf("  vertexes transformed  %7d  %8.3f   %10.3f\n",
229          ctx->VertexCount, ctx->VertexTime, vertexrate );
230   printf("  points rasterized     %7d  %8.3f   %10.3f\n",
231          ctx->PointCount, ctx->PointTime, pointrate );
232   printf("  lines rasterized      %7d  %8.3f   %10.3f\n",
233          ctx->LineCount, ctx->LineTime, linerate );
234   printf("  polygons rasterized   %7d  %8.3f   %10.3f\n",
235          ctx->PolygonCount, ctx->PolygonTime, polygonrate );
236   printf("  overhead                       %8.3f\n", overhead );
237   printf("glClear                 %7d  %8.3f   %10.3f\n",
238          ctx->ClearCount, ctx->ClearTime, clearrate );
239   printf("SwapBuffers             %7d  %8.3f   %10.3f\n",
240          ctx->SwapCount, ctx->SwapTime, swaprate );
241   printf("\n");
242
243   printf("Average number of vertices per begin/end: %8.3f\n", avgvertices );
244}
245#endif
246
247
248
249
250
251/**********************************************************************/
252/***** GL Visual allocation/destruction                           *****/
253/**********************************************************************/
254
255
256/*
257 * Allocate a new GLvisual object.
258 * Input:  rgbFlag - GL_TRUE=RGB(A) mode, GL_FALSE=Color Index mode
259 *         alphaFlag - alloc software alpha buffers?
260 *         dbFlag - double buffering?
261 *         stereoFlag - stereo buffer?
262 *         depthFits - requested minimum bits per depth buffer value
263 *         stencilFits - requested minimum bits per stencil buffer value
264 *         accumFits - requested minimum bits per accum buffer component
265 *         indexFits - number of bits per pixel if rgbFlag==GL_FALSE
266 *         red/green/blue/alphaFits - number of bits per color component
267 *                                     in frame buffer for RGB(A) mode.
268 * Return:  pointer to new GLvisual or NULL if requested parameters can't
269 *          be met.
270 */
271GLvisual *gl_create_visual( GLboolean rgbFlag,
272                            GLboolean alphaFlag,
273                            GLboolean dbFlag,
274                            GLboolean stereoFlag,
275                            GLint depthBits,
276                            GLint stencilBits,
277                            GLint accumBits,
278                            GLint indexBits,
279                            GLint redBits,
280                            GLint greenBits,
281                            GLint blueBits,
282                            GLint alphaBits )
283{
284   GLvisual *vis;
285
286   if (depthBits > (GLint) (8*sizeof(GLdepth))) {
287      /* can't meet depth buffer requirements */
288      return NULL;
289   }
290   if (stencilBits > (GLint) (8*sizeof(GLstencil))) {
291      /* can't meet stencil buffer requirements */
292      return NULL;
293   }
294   if (accumBits > (GLint) (8*sizeof(GLaccum))) {
295      /* can't meet accum buffer requirements */
296      return NULL;
297   }
298
299   vis = (GLvisual *) CALLOC( sizeof(GLvisual) );
300   if (!vis) {
301      return NULL;
302   }
303
304   vis->RGBAflag   = rgbFlag;
305   vis->DBflag     = dbFlag;
306   vis->StereoFlag = stereoFlag;
307   vis->RedBits    = redBits;
308   vis->GreenBits  = greenBits;
309   vis->BlueBits   = blueBits;
310   vis->AlphaBits  = alphaFlag ? 8*sizeof(GLubyte) : alphaBits;
311
312   vis->IndexBits   = indexBits;
313   vis->DepthBits   = (depthBits>0) ? 8*sizeof(GLdepth) : 0;
314   vis->AccumBits   = (accumBits>0) ? 8*sizeof(GLaccum) : 0;
315   vis->StencilBits = (stencilBits>0) ? 8*sizeof(GLstencil) : 0;
316
317   vis->SoftwareAlpha = alphaFlag;
318
319   return vis;
320}
321
322
323
324void gl_destroy_visual( GLvisual *vis )
325{
326   FREE( vis );
327}
328
329
330
331/**********************************************************************/
332/***** GL Framebuffer allocation/destruction                      *****/
333/**********************************************************************/
334
335
336/*
337 * Create a new framebuffer.  A GLframebuffer is a struct which
338 * encapsulates the depth, stencil and accum buffers and related
339 * parameters.
340 * Input:  visual - a GLvisual pointer
341 *         softwareDepth - create/use a software depth buffer?
342 *         softwareStencil - create/use a software stencil buffer?
343 *         softwareAccum - create/use a software accum buffer?
344 *         softwareAlpha - create/use a software alpha buffer?
345
346 * Return:  pointer to new GLframebuffer struct or NULL if error.
347 */
348GLframebuffer *gl_create_framebuffer( GLvisual *visual,
349                                      GLboolean softwareDepth,
350                                      GLboolean softwareStencil,
351                                      GLboolean softwareAccum,
352                                      GLboolean softwareAlpha )
353{
354   GLframebuffer *buffer;
355
356   buffer = CALLOC_STRUCT(gl_frame_buffer);
357   if (!buffer) {
358      return NULL;
359   }
360
361   /* sanity checks */
362   if (softwareDepth ) {
363      assert(visual->DepthBits > 0);
364   }
365   if (softwareStencil) {
366      assert(visual->StencilBits > 0);
367   }
368   if (softwareAccum) {
369      assert(visual->RGBAflag);
370      assert(visual->AccumBits > 0);
371   }
372   if (softwareAlpha) {
373      assert(visual->RGBAflag);
374      assert(visual->AlphaBits > 0);
375   }
376
377   buffer->Visual = visual;
378   buffer->UseSoftwareDepthBuffer = softwareDepth;
379   buffer->UseSoftwareStencilBuffer = softwareStencil;
380   buffer->UseSoftwareAccumBuffer = softwareAccum;
381   buffer->UseSoftwareAlphaBuffers = softwareAlpha;
382
383   return buffer;
384}
385
386
387
388/*
389 * Free a framebuffer struct and its buffers.
390 */
391void gl_destroy_framebuffer( GLframebuffer *buffer )
392{
393   if (buffer) {
394      if (buffer->Depth) {
395         FREE( buffer->Depth );
396      }
397      if (buffer->Accum) {
398         FREE( buffer->Accum );
399      }
400      if (buffer->Stencil) {
401         FREE( buffer->Stencil );
402      }
403      if (buffer->FrontLeftAlpha) {
404         FREE( buffer->FrontLeftAlpha );
405      }
406      if (buffer->BackLeftAlpha) {
407         FREE( buffer->BackLeftAlpha );
408      }
409      if (buffer->FrontRightAlpha) {
410         FREE( buffer->FrontRightAlpha );
411      }
412      if (buffer->BackRightAlpha) {
413         FREE( buffer->BackRightAlpha );
414      }
415      FREE(buffer);
416   }
417}
418
419
420
421/**********************************************************************/
422/*****       Context allocation, initialization, destroying       *****/
423/**********************************************************************/
424
425
426/*
427 * This function just calls all the various one-time-init functions in Mesa.
428 */
429static void one_time_init( void )
430{
431   static GLboolean alreadyCalled = GL_FALSE;
432   if (!alreadyCalled) {
433      /* do some implementation tests */
434      assert( sizeof(GLbyte) == 1 );
435      assert( sizeof(GLshort) >= 2 );
436      assert( sizeof(GLint) >= 4 );
437      assert( sizeof(GLubyte) == 1 );
438      assert( sizeof(GLushort) >= 2 );
439      assert( sizeof(GLuint) >= 4 );
440
441      gl_init_clip();
442      gl_init_eval();
443      gl_init_fog();
444      gl_init_math();
445      gl_init_lists();
446      gl_init_shade();
447      gl_init_texture();
448      gl_init_transformation();
449      gl_init_translate();
450      gl_init_vbrender();
451      gl_init_vbxform();
452      gl_init_vertices();
453
454      if (getenv("MESA_DEBUG")) {
455         _glapi_noop_enable_warnings(GL_TRUE);
456      }
457      else {
458         _glapi_noop_enable_warnings(GL_FALSE);
459      }
460
461#if defined(DEBUG) && defined(__DATE__) && defined(__TIME__)
462   fprintf(stderr, "Mesa DEBUG build %s %s\n", __DATE__, __TIME__);
463#endif
464
465      alreadyCalled = GL_TRUE;
466   }
467}
468
469
470
471/*
472 * Allocate and initialize a shared context state structure.
473 */
474static struct gl_shared_state *alloc_shared_state( void )
475{
476   GLuint d;
477   struct gl_shared_state *ss;
478   GLboolean outOfMemory;
479
480   ss = CALLOC_STRUCT(gl_shared_state);
481   if (!ss)
482      return NULL;
483
484   ss->DisplayList = _mesa_NewHashTable();
485
486   ss->TexObjects = _mesa_NewHashTable();
487
488   /* Default Texture objects */
489   outOfMemory = GL_FALSE;
490   for (d = 1 ; d <= 3 ; d++) {
491      ss->DefaultD[d] = gl_alloc_texture_object(ss, 0, d);
492      if (!ss->DefaultD[d]) {
493         outOfMemory = GL_TRUE;
494         break;
495      }
496      ss->DefaultD[d]->RefCount++; /* don't free if not in use */
497   }
498
499   if (!ss->DisplayList || !ss->TexObjects || outOfMemory) {
500      /* Ran out of memory at some point.  Free everything and return NULL */
501      if (ss->DisplayList)
502         _mesa_DeleteHashTable(ss->DisplayList);
503      if (ss->TexObjects)
504         _mesa_DeleteHashTable(ss->TexObjects);
505      if (ss->DefaultD[1])
506         gl_free_texture_object(ss, ss->DefaultD[1]);
507      if (ss->DefaultD[2])
508         gl_free_texture_object(ss, ss->DefaultD[2]);
509      if (ss->DefaultD[3])
510         gl_free_texture_object(ss, ss->DefaultD[3]);
511      FREE(ss);
512      return NULL;
513   }
514   else {
515      return ss;
516   }
517}
518
519
520/*
521 * Deallocate a shared state context and all children structures.
522 */
523static void free_shared_state( GLcontext *ctx, struct gl_shared_state *ss )
524{
525   /* Free display lists */
526   while (1) {
527      GLuint list = _mesa_HashFirstEntry(ss->DisplayList);
528      if (list) {
529         gl_destroy_list(ctx, list);
530      }
531      else {
532         break;
533      }
534   }
535   _mesa_DeleteHashTable(ss->DisplayList);
536
537   /* Free texture objects */
538   while (ss->TexObjectList)
539   {
540      if (ctx->Driver.DeleteTexture)
541         (*ctx->Driver.DeleteTexture)( ctx, ss->TexObjectList );
542      /* this function removes from linked list too! */
543      gl_free_texture_object(ss, ss->TexObjectList);
544   }
545   _mesa_DeleteHashTable(ss->TexObjects);
546
547   FREE(ss);
548}
549
550
551
552/*
553 * Initialize the nth light.  Note that the defaults for light 0 are
554 * different than the other lights.
555 */
556static void init_light( struct gl_light *l, GLuint n )
557{
558   make_empty_list( l );
559
560   ASSIGN_4V( l->Ambient, 0.0, 0.0, 0.0, 1.0 );
561   if (n==0) {
562      ASSIGN_4V( l->Diffuse, 1.0, 1.0, 1.0, 1.0 );
563      ASSIGN_4V( l->Specular, 1.0, 1.0, 1.0, 1.0 );
564   }
565   else {
566      ASSIGN_4V( l->Diffuse, 0.0, 0.0, 0.0, 1.0 );
567      ASSIGN_4V( l->Specular, 0.0, 0.0, 0.0, 1.0 );
568   }
569   ASSIGN_4V( l->EyePosition, 0.0, 0.0, 1.0, 0.0 );
570   ASSIGN_3V( l->EyeDirection, 0.0, 0.0, -1.0 );
571   l->SpotExponent = 0.0;
572   gl_compute_spot_exp_table( l );
573   l->SpotCutoff = 180.0;
574   l->CosCutoff = 0.0;		/* KW: -ve values not admitted */
575   l->ConstantAttenuation = 1.0;
576   l->LinearAttenuation = 0.0;
577   l->QuadraticAttenuation = 0.0;
578   l->Enabled = GL_FALSE;
579}
580
581
582
583static void init_lightmodel( struct gl_lightmodel *lm )
584{
585   ASSIGN_4V( lm->Ambient, 0.2, 0.2, 0.2, 1.0 );
586   lm->LocalViewer = GL_FALSE;
587   lm->TwoSide = GL_FALSE;
588   lm->ColorControl = GL_SINGLE_COLOR;
589}
590
591
592static void init_material( struct gl_material *m )
593{
594   ASSIGN_4V( m->Ambient,  0.2, 0.2, 0.2, 1.0 );
595   ASSIGN_4V( m->Diffuse,  0.8, 0.8, 0.8, 1.0 );
596   ASSIGN_4V( m->Specular, 0.0, 0.0, 0.0, 1.0 );
597   ASSIGN_4V( m->Emission, 0.0, 0.0, 0.0, 1.0 );
598   m->Shininess = 0.0;
599   m->AmbientIndex = 0;
600   m->DiffuseIndex = 1;
601   m->SpecularIndex = 1;
602}
603
604
605
606static void init_texture_unit( GLcontext *ctx, GLuint unit )
607{
608   struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
609
610   texUnit->EnvMode = GL_MODULATE;
611   ASSIGN_4V( texUnit->EnvColor, 0.0, 0.0, 0.0, 0.0 );
612   texUnit->TexGenEnabled = 0;
613   texUnit->GenModeS = GL_EYE_LINEAR;
614   texUnit->GenModeT = GL_EYE_LINEAR;
615   texUnit->GenModeR = GL_EYE_LINEAR;
616   texUnit->GenModeQ = GL_EYE_LINEAR;
617   /* Yes, these plane coefficients are correct! */
618   ASSIGN_4V( texUnit->ObjectPlaneS, 1.0, 0.0, 0.0, 0.0 );
619   ASSIGN_4V( texUnit->ObjectPlaneT, 0.0, 1.0, 0.0, 0.0 );
620   ASSIGN_4V( texUnit->ObjectPlaneR, 0.0, 0.0, 0.0, 0.0 );
621   ASSIGN_4V( texUnit->ObjectPlaneQ, 0.0, 0.0, 0.0, 0.0 );
622   ASSIGN_4V( texUnit->EyePlaneS, 1.0, 0.0, 0.0, 0.0 );
623   ASSIGN_4V( texUnit->EyePlaneT, 0.0, 1.0, 0.0, 0.0 );
624   ASSIGN_4V( texUnit->EyePlaneR, 0.0, 0.0, 0.0, 0.0 );
625   ASSIGN_4V( texUnit->EyePlaneQ, 0.0, 0.0, 0.0, 0.0 );
626
627   texUnit->CurrentD[1] = ctx->Shared->DefaultD[1];
628   texUnit->CurrentD[2] = ctx->Shared->DefaultD[2];
629   texUnit->CurrentD[3] = ctx->Shared->DefaultD[3];
630}
631
632
633static void init_fallback_arrays( GLcontext *ctx )
634{
635   struct gl_client_array *cl;
636   GLuint i;
637
638   cl = &ctx->Fallback.Normal;
639   cl->Size = 3;
640   cl->Type = GL_FLOAT;
641   cl->Stride = 0;
642   cl->StrideB = 0;
643   cl->Ptr = (void *) ctx->Current.Normal;
644   cl->Enabled = 1;
645
646   cl = &ctx->Fallback.Color;
647   cl->Size = 4;
648   cl->Type = GL_UNSIGNED_BYTE;
649   cl->Stride = 0;
650   cl->StrideB = 0;
651   cl->Ptr = (void *) ctx->Current.ByteColor;
652   cl->Enabled = 1;
653
654   cl = &ctx->Fallback.Index;
655   cl->Size = 1;
656   cl->Type = GL_UNSIGNED_INT;
657   cl->Stride = 0;
658   cl->StrideB = 0;
659   cl->Ptr = (void *) &ctx->Current.Index;
660   cl->Enabled = 1;
661
662   for (i = 0 ; i < MAX_TEXTURE_UNITS ; i++) {
663      cl = &ctx->Fallback.TexCoord[i];
664      cl->Size = 4;
665      cl->Type = GL_FLOAT;
666      cl->Stride = 0;
667      cl->StrideB = 0;
668      cl->Ptr = (void *) ctx->Current.Texcoord[i];
669      cl->Enabled = 1;
670   }
671
672   cl = &ctx->Fallback.EdgeFlag;
673   cl->Size = 1;
674   cl->Type = GL_UNSIGNED_BYTE;
675   cl->Stride = 0;
676   cl->StrideB = 0;
677   cl->Ptr = (void *) &ctx->Current.EdgeFlag;
678   cl->Enabled = 1;
679}
680
681
682/* Initialize a 1-D evaluator map */
683static void init_1d_map( struct gl_1d_map *map, int n, const float *initial )
684{
685   map->Order = 1;
686   map->u1 = 0.0;
687   map->u2 = 1.0;
688   map->Points = (GLfloat *) MALLOC(n * sizeof(GLfloat));
689   if (map->Points) {
690      GLint i;
691      for (i=0;i<n;i++)
692         map->Points[i] = initial[i];
693   }
694}
695
696
697/* Initialize a 2-D evaluator map */
698static void init_2d_map( struct gl_2d_map *map, int n, const float *initial )
699{
700   map->Uorder = 1;
701   map->Vorder = 1;
702   map->u1 = 0.0;
703   map->u2 = 1.0;
704   map->v1 = 0.0;
705   map->v2 = 1.0;
706   map->Points = (GLfloat *) MALLOC(n * sizeof(GLfloat));
707   if (map->Points) {
708      GLint i;
709      for (i=0;i<n;i++)
710         map->Points[i] = initial[i];
711   }
712}
713
714
715static void init_color_table( struct gl_color_table *p )
716{
717   p->Table[0] = 255;
718   p->Table[1] = 255;
719   p->Table[2] = 255;
720   p->Table[3] = 255;
721   p->Size = 1;
722   p->IntFormat = GL_RGBA;
723   p->Format = GL_RGBA;
724}
725
726
727/*
728 * Initialize the attribute groups in a GLcontext.
729 */
730static void init_attrib_groups( GLcontext *ctx )
731{
732   GLuint i, j;
733
734   assert(ctx);
735
736   /* Constants, may be overriden by device driver */
737   ctx->Const.MaxTextureLevels = MAX_TEXTURE_LEVELS;
738   ctx->Const.MaxTextureSize = 1 << (MAX_TEXTURE_LEVELS - 1);
739   ctx->Const.MaxTextureUnits = MAX_TEXTURE_UNITS;
740   ctx->Const.MaxArrayLockSize = MAX_ARRAY_LOCK_SIZE;
741
742   /* Modelview matrix */
743   gl_matrix_ctr( &ctx->ModelView );
744   gl_matrix_alloc_inv( &ctx->ModelView );
745
746   ctx->ModelViewStackDepth = 0;
747   for (i = 0 ; i < MAX_MODELVIEW_STACK_DEPTH ; i++) {
748      gl_matrix_ctr( &ctx->ModelViewStack[i] );
749      gl_matrix_alloc_inv( &ctx->ModelViewStack[i] );
750   }
751
752   /* Projection matrix - need inv for user clipping in clip space*/
753   gl_matrix_ctr( &ctx->ProjectionMatrix );
754   gl_matrix_alloc_inv( &ctx->ProjectionMatrix );
755
756   gl_matrix_ctr( &ctx->ModelProjectMatrix );
757   gl_matrix_ctr( &ctx->ModelProjectWinMatrix );
758   ctx->ModelProjectWinMatrixUptodate = GL_FALSE;
759
760   ctx->ProjectionStackDepth = 0;
761   ctx->NearFarStack[0][0] = 1.0; /* These values seem weird by make */
762   ctx->NearFarStack[0][1] = 0.0; /* sense mathematically. */
763
764   for (i = 0 ; i < MAX_PROJECTION_STACK_DEPTH ; i++) {
765      gl_matrix_ctr( &ctx->ProjectionStack[i] );
766      gl_matrix_alloc_inv( &ctx->ProjectionStack[i] );
767   }
768
769   /* Texture matrix */
770   for (i=0; i<MAX_TEXTURE_UNITS; i++) {
771      gl_matrix_ctr( &ctx->TextureMatrix[i] );
772      ctx->TextureStackDepth[i] = 0;
773      for (j = 0 ; j < MAX_TEXTURE_STACK_DEPTH ; j++) {
774         ctx->TextureStack[i][j].inv = 0;
775      }
776   }
777
778   /* Accumulate buffer group */
779   ASSIGN_4V( ctx->Accum.ClearColor, 0.0, 0.0, 0.0, 0.0 );
780
781   /* Color buffer group */
782   ctx->Color.IndexMask = 0xffffffff;
783   ctx->Color.ColorMask[0] = 0xff;
784   ctx->Color.ColorMask[1] = 0xff;
785   ctx->Color.ColorMask[2] = 0xff;
786   ctx->Color.ColorMask[3] = 0xff;
787   ctx->Color.SWmasking = GL_FALSE;
788   ctx->Color.ClearIndex = 0;
789   ASSIGN_4V( ctx->Color.ClearColor, 0.0, 0.0, 0.0, 0.0 );
790   ctx->Color.DrawBuffer = GL_FRONT;
791   ctx->Color.AlphaEnabled = GL_FALSE;
792   ctx->Color.AlphaFunc = GL_ALWAYS;
793   ctx->Color.AlphaRef = 0;
794   ctx->Color.BlendEnabled = GL_FALSE;
795   ctx->Color.BlendSrcRGB = GL_ONE;
796   ctx->Color.BlendDstRGB = GL_ZERO;
797   ctx->Color.BlendSrcA = GL_ONE;
798   ctx->Color.BlendDstA = GL_ZERO;
799   ctx->Color.BlendEquation = GL_FUNC_ADD_EXT;
800   ctx->Color.BlendFunc = NULL;  /* this pointer set only when needed */
801   ASSIGN_4V( ctx->Color.BlendColor, 0.0, 0.0, 0.0, 0.0 );
802   ctx->Color.IndexLogicOpEnabled = GL_FALSE;
803   ctx->Color.ColorLogicOpEnabled = GL_FALSE;
804   ctx->Color.SWLogicOpEnabled = GL_FALSE;
805   ctx->Color.LogicOp = GL_COPY;
806   ctx->Color.DitherFlag = GL_TRUE;
807   ctx->Color.MultiDrawBuffer = GL_FALSE;
808
809   /* Current group */
810   ASSIGN_4V( ctx->Current.ByteColor, 255, 255, 255, 255);
811   ctx->Current.Index = 1;
812   for (i=0; i<MAX_TEXTURE_UNITS; i++)
813      ASSIGN_4V( ctx->Current.Texcoord[i], 0.0, 0.0, 0.0, 1.0 );
814   ASSIGN_4V( ctx->Current.RasterPos, 0.0, 0.0, 0.0, 1.0 );
815   ctx->Current.RasterDistance = 0.0;
816   ASSIGN_4V( ctx->Current.RasterColor, 1.0, 1.0, 1.0, 1.0 );
817   ctx->Current.RasterIndex = 1;
818   for (i=0; i<MAX_TEXTURE_UNITS; i++)
819      ASSIGN_4V( ctx->Current.RasterMultiTexCoord[i], 0.0, 0.0, 0.0, 1.0 );
820   ctx->Current.RasterTexCoord = ctx->Current.RasterMultiTexCoord[0];
821   ctx->Current.RasterPosValid = GL_TRUE;
822   ctx->Current.EdgeFlag = GL_TRUE;
823   ASSIGN_3V( ctx->Current.Normal, 0.0, 0.0, 1.0 );
824   ctx->Current.Primitive = (GLenum) (GL_POLYGON + 1);
825
826   ctx->Current.Flag = (VERT_NORM|VERT_INDEX|VERT_RGBA|VERT_EDGE|
827                        VERT_TEX0_1|VERT_TEX1_1|VERT_MATERIAL);
828
829   init_fallback_arrays( ctx );
830
831   /* Depth buffer group */
832   ctx->Depth.Test = GL_FALSE;
833   ctx->Depth.Clear = 1.0;
834   ctx->Depth.Func = GL_LESS;
835   ctx->Depth.Mask = GL_TRUE;
836
837   /* Evaluators group */
838   ctx->Eval.Map1Color4 = GL_FALSE;
839   ctx->Eval.Map1Index = GL_FALSE;
840   ctx->Eval.Map1Normal = GL_FALSE;
841   ctx->Eval.Map1TextureCoord1 = GL_FALSE;
842   ctx->Eval.Map1TextureCoord2 = GL_FALSE;
843   ctx->Eval.Map1TextureCoord3 = GL_FALSE;
844   ctx->Eval.Map1TextureCoord4 = GL_FALSE;
845   ctx->Eval.Map1Vertex3 = GL_FALSE;
846   ctx->Eval.Map1Vertex4 = GL_FALSE;
847   ctx->Eval.Map2Color4 = GL_FALSE;
848   ctx->Eval.Map2Index = GL_FALSE;
849   ctx->Eval.Map2Normal = GL_FALSE;
850   ctx->Eval.Map2TextureCoord1 = GL_FALSE;
851   ctx->Eval.Map2TextureCoord2 = GL_FALSE;
852   ctx->Eval.Map2TextureCoord3 = GL_FALSE;
853   ctx->Eval.Map2TextureCoord4 = GL_FALSE;
854   ctx->Eval.Map2Vertex3 = GL_FALSE;
855   ctx->Eval.Map2Vertex4 = GL_FALSE;
856   ctx->Eval.AutoNormal = GL_FALSE;
857   ctx->Eval.MapGrid1un = 1;
858   ctx->Eval.MapGrid1u1 = 0.0;
859   ctx->Eval.MapGrid1u2 = 1.0;
860   ctx->Eval.MapGrid2un = 1;
861   ctx->Eval.MapGrid2vn = 1;
862   ctx->Eval.MapGrid2u1 = 0.0;
863   ctx->Eval.MapGrid2u2 = 1.0;
864   ctx->Eval.MapGrid2v1 = 0.0;
865   ctx->Eval.MapGrid2v2 = 1.0;
866
867   /* Evaluator data */
868   {
869      static GLfloat vertex[4] = { 0.0, 0.0, 0.0, 1.0 };
870      static GLfloat normal[3] = { 0.0, 0.0, 1.0 };
871      static GLfloat index[1] = { 1.0 };
872      static GLfloat color[4] = { 1.0, 1.0, 1.0, 1.0 };
873      static GLfloat texcoord[4] = { 0.0, 0.0, 0.0, 1.0 };
874
875      init_1d_map( &ctx->EvalMap.Map1Vertex3, 3, vertex );
876      init_1d_map( &ctx->EvalMap.Map1Vertex4, 4, vertex );
877      init_1d_map( &ctx->EvalMap.Map1Index, 1, index );
878      init_1d_map( &ctx->EvalMap.Map1Color4, 4, color );
879      init_1d_map( &ctx->EvalMap.Map1Normal, 3, normal );
880      init_1d_map( &ctx->EvalMap.Map1Texture1, 1, texcoord );
881      init_1d_map( &ctx->EvalMap.Map1Texture2, 2, texcoord );
882      init_1d_map( &ctx->EvalMap.Map1Texture3, 3, texcoord );
883      init_1d_map( &ctx->EvalMap.Map1Texture4, 4, texcoord );
884
885      init_2d_map( &ctx->EvalMap.Map2Vertex3, 3, vertex );
886      init_2d_map( &ctx->EvalMap.Map2Vertex4, 4, vertex );
887      init_2d_map( &ctx->EvalMap.Map2Index, 1, index );
888      init_2d_map( &ctx->EvalMap.Map2Color4, 4, color );
889      init_2d_map( &ctx->EvalMap.Map2Normal, 3, normal );
890      init_2d_map( &ctx->EvalMap.Map2Texture1, 1, texcoord );
891      init_2d_map( &ctx->EvalMap.Map2Texture2, 2, texcoord );
892      init_2d_map( &ctx->EvalMap.Map2Texture3, 3, texcoord );
893      init_2d_map( &ctx->EvalMap.Map2Texture4, 4, texcoord );
894   }
895
896   /* Fog group */
897   ctx->Fog.Enabled = GL_FALSE;
898   ctx->Fog.Mode = GL_EXP;
899   ASSIGN_4V( ctx->Fog.Color, 0.0, 0.0, 0.0, 0.0 );
900   ctx->Fog.Index = 0.0;
901   ctx->Fog.Density = 1.0;
902   ctx->Fog.Start = 0.0;
903   ctx->Fog.End = 1.0;
904
905   /* Hint group */
906   ctx->Hint.PerspectiveCorrection = GL_DONT_CARE;
907   ctx->Hint.PointSmooth = GL_DONT_CARE;
908   ctx->Hint.LineSmooth = GL_DONT_CARE;
909   ctx->Hint.PolygonSmooth = GL_DONT_CARE;
910   ctx->Hint.Fog = GL_DONT_CARE;
911
912   ctx->Hint.AllowDrawWin = GL_TRUE;
913   ctx->Hint.AllowDrawSpn = GL_TRUE;
914   ctx->Hint.AllowDrawMem = GL_TRUE;
915   ctx->Hint.StrictLighting = GL_TRUE;
916
917   /* Pipeline */
918   gl_pipeline_init( ctx );
919   gl_cva_init( ctx );
920
921   /* Extensions */
922   gl_extensions_ctr( ctx );
923
924   ctx->AllowVertexCull = CLIP_CULLED_BIT;
925
926   /* Lighting group */
927   for (i=0;i<MAX_LIGHTS;i++) {
928      init_light( &ctx->Light.Light[i], i );
929   }
930   make_empty_list( &ctx->Light.EnabledList );
931
932   init_lightmodel( &ctx->Light.Model );
933   init_material( &ctx->Light.Material[0] );
934   init_material( &ctx->Light.Material[1] );
935   ctx->Light.ShadeModel = GL_SMOOTH;
936   ctx->Light.Enabled = GL_FALSE;
937   ctx->Light.ColorMaterialFace = GL_FRONT_AND_BACK;
938   ctx->Light.ColorMaterialMode = GL_AMBIENT_AND_DIFFUSE;
939   ctx->Light.ColorMaterialBitmask
940      = gl_material_bitmask( ctx,
941                             GL_FRONT_AND_BACK,
942                             GL_AMBIENT_AND_DIFFUSE, ~0, 0 );
943
944   ctx->Light.ColorMaterialEnabled = GL_FALSE;
945
946   /* Lighting miscellaneous */
947   ctx->ShineTabList = MALLOC_STRUCT( gl_shine_tab );
948   make_empty_list( ctx->ShineTabList );
949   for (i = 0 ; i < 10 ; i++) {
950      struct gl_shine_tab *s = MALLOC_STRUCT( gl_shine_tab );
951      s->shininess = -1;
952      s->refcount = 0;
953      insert_at_tail( ctx->ShineTabList, s );
954   }
955   for (i = 0 ; i < 4 ; i++) {
956      ctx->ShineTable[i] = ctx->ShineTabList->prev;
957      ctx->ShineTable[i]->refcount++;
958   }
959
960
961   /* Line group */
962   ctx->Line.SmoothFlag = GL_FALSE;
963   ctx->Line.StippleFlag = GL_FALSE;
964   ctx->Line.Width = 1.0;
965   ctx->Line.StipplePattern = 0xffff;
966   ctx->Line.StippleFactor = 1;
967
968   /* Display List group */
969   ctx->List.ListBase = 0;
970
971   /* Pixel group */
972   ctx->Pixel.RedBias = 0.0;
973   ctx->Pixel.RedScale = 1.0;
974   ctx->Pixel.GreenBias = 0.0;
975   ctx->Pixel.GreenScale = 1.0;
976   ctx->Pixel.BlueBias = 0.0;
977   ctx->Pixel.BlueScale = 1.0;
978   ctx->Pixel.AlphaBias = 0.0;
979   ctx->Pixel.AlphaScale = 1.0;
980   ctx->Pixel.ScaleOrBiasRGBA = GL_FALSE;
981   ctx->Pixel.DepthBias = 0.0;
982   ctx->Pixel.DepthScale = 1.0;
983   ctx->Pixel.IndexOffset = 0;
984   ctx->Pixel.IndexShift = 0;
985   ctx->Pixel.ZoomX = 1.0;
986   ctx->Pixel.ZoomY = 1.0;
987   ctx->Pixel.MapColorFlag = GL_FALSE;
988   ctx->Pixel.MapStencilFlag = GL_FALSE;
989   ctx->Pixel.MapStoSsize = 1;
990   ctx->Pixel.MapItoIsize = 1;
991   ctx->Pixel.MapItoRsize = 1;
992   ctx->Pixel.MapItoGsize = 1;
993   ctx->Pixel.MapItoBsize = 1;
994   ctx->Pixel.MapItoAsize = 1;
995   ctx->Pixel.MapRtoRsize = 1;
996   ctx->Pixel.MapGtoGsize = 1;
997   ctx->Pixel.MapBtoBsize = 1;
998   ctx->Pixel.MapAtoAsize = 1;
999   ctx->Pixel.MapStoS[0] = 0;
1000   ctx->Pixel.MapItoI[0] = 0;
1001   ctx->Pixel.MapItoR[0] = 0.0;
1002   ctx->Pixel.MapItoG[0] = 0.0;
1003   ctx->Pixel.MapItoB[0] = 0.0;
1004   ctx->Pixel.MapItoA[0] = 0.0;
1005   ctx->Pixel.MapItoR8[0] = 0;
1006   ctx->Pixel.MapItoG8[0] = 0;
1007   ctx->Pixel.MapItoB8[0] = 0;
1008   ctx->Pixel.MapItoA8[0] = 0;
1009   ctx->Pixel.MapRtoR[0] = 0.0;
1010   ctx->Pixel.MapGtoG[0] = 0.0;
1011   ctx->Pixel.MapBtoB[0] = 0.0;
1012   ctx->Pixel.MapAtoA[0] = 0.0;
1013
1014   /* Point group */
1015   ctx->Point.SmoothFlag = GL_FALSE;
1016   ctx->Point.Size = 1.0;
1017   ctx->Point.Params[0] = 1.0;
1018   ctx->Point.Params[1] = 0.0;
1019   ctx->Point.Params[2] = 0.0;
1020   ctx->Point.Attenuated = GL_FALSE;
1021   ctx->Point.MinSize = 0.0;
1022   ctx->Point.MaxSize = (GLfloat) MAX_POINT_SIZE;
1023   ctx->Point.Threshold = 1.0;
1024
1025   /* Polygon group */
1026   ctx->Polygon.CullFlag = GL_FALSE;
1027   ctx->Polygon.CullFaceMode = GL_BACK;
1028   ctx->Polygon.FrontFace = GL_CCW;
1029   ctx->Polygon.FrontBit = 0;
1030   ctx->Polygon.FrontMode = GL_FILL;
1031   ctx->Polygon.BackMode = GL_FILL;
1032   ctx->Polygon.Unfilled = GL_FALSE;
1033   ctx->Polygon.SmoothFlag = GL_FALSE;
1034   ctx->Polygon.StippleFlag = GL_FALSE;
1035   ctx->Polygon.OffsetFactor = 0.0F;
1036   ctx->Polygon.OffsetUnits = 0.0F;
1037   ctx->Polygon.OffsetPoint = GL_FALSE;
1038   ctx->Polygon.OffsetLine = GL_FALSE;
1039   ctx->Polygon.OffsetFill = GL_FALSE;
1040
1041   /* Polygon Stipple group */
1042   MEMSET( ctx->PolygonStipple, 0xff, 32*sizeof(GLuint) );
1043
1044   /* Scissor group */
1045   ctx->Scissor.Enabled = GL_FALSE;
1046   ctx->Scissor.X = 0;
1047   ctx->Scissor.Y = 0;
1048   ctx->Scissor.Width = 0;
1049   ctx->Scissor.Height = 0;
1050
1051   /* Stencil group */
1052   ctx->Stencil.Enabled = GL_FALSE;
1053   ctx->Stencil.Function = GL_ALWAYS;
1054   ctx->Stencil.FailFunc = GL_KEEP;
1055   ctx->Stencil.ZPassFunc = GL_KEEP;
1056   ctx->Stencil.ZFailFunc = GL_KEEP;
1057   ctx->Stencil.Ref = 0;
1058   ctx->Stencil.ValueMask = STENCIL_MAX;
1059   ctx->Stencil.Clear = 0;
1060   ctx->Stencil.WriteMask = STENCIL_MAX;
1061
1062   /* Texture group */
1063   ctx->Texture.CurrentUnit = 0;      /* multitexture */
1064   ctx->Texture.CurrentTransformUnit = 0; /* multitexture */
1065   ctx->Texture.Enabled = 0;
1066   for (i=0; i<MAX_TEXTURE_UNITS; i++)
1067      init_texture_unit( ctx, i );
1068   init_color_table(&ctx->Texture.Palette);
1069
1070   /* Transformation group */
1071   ctx->Transform.MatrixMode = GL_MODELVIEW;
1072   ctx->Transform.Normalize = GL_FALSE;
1073   ctx->Transform.RescaleNormals = GL_FALSE;
1074   for (i=0;i<MAX_CLIP_PLANES;i++) {
1075      ctx->Transform.ClipEnabled[i] = GL_FALSE;
1076      ASSIGN_4V( ctx->Transform.EyeUserPlane[i], 0.0, 0.0, 0.0, 0.0 );
1077   }
1078   ctx->Transform.AnyClip = GL_FALSE;
1079
1080   /* Viewport group */
1081   ctx->Viewport.X = 0;
1082   ctx->Viewport.Y = 0;
1083   ctx->Viewport.Width = 0;
1084   ctx->Viewport.Height = 0;
1085   ctx->Viewport.Near = 0.0;
1086   ctx->Viewport.Far = 1.0;
1087   gl_matrix_ctr(&ctx->Viewport.WindowMap);
1088
1089#define Sz 10
1090#define Tz 14
1091   ctx->Viewport.WindowMap.m[Sz] = 0.5 * DEPTH_SCALE;
1092   ctx->Viewport.WindowMap.m[Tz] = 0.5 * DEPTH_SCALE;
1093#undef Sz
1094#undef Tz
1095
1096   ctx->Viewport.WindowMap.flags = MAT_FLAG_GENERAL_SCALE|MAT_FLAG_TRANSLATION;
1097   ctx->Viewport.WindowMap.type = MATRIX_3D_NO_ROT;
1098
1099   /* Vertex arrays */
1100   ctx->Array.Vertex.Size = 4;
1101   ctx->Array.Vertex.Type = GL_FLOAT;
1102   ctx->Array.Vertex.Stride = 0;
1103   ctx->Array.Vertex.StrideB = 0;
1104   ctx->Array.Vertex.Ptr = NULL;
1105   ctx->Array.Vertex.Enabled = GL_FALSE;
1106   ctx->Array.Normal.Type = GL_FLOAT;
1107   ctx->Array.Normal.Stride = 0;
1108   ctx->Array.Normal.StrideB = 0;
1109   ctx->Array.Normal.Ptr = NULL;
1110   ctx->Array.Normal.Enabled = GL_FALSE;
1111   ctx->Array.Color.Size = 4;
1112   ctx->Array.Color.Type = GL_FLOAT;
1113   ctx->Array.Color.Stride = 0;
1114   ctx->Array.Color.StrideB = 0;
1115   ctx->Array.Color.Ptr = NULL;
1116   ctx->Array.Color.Enabled = GL_FALSE;
1117   ctx->Array.Index.Type = GL_FLOAT;
1118   ctx->Array.Index.Stride = 0;
1119   ctx->Array.Index.StrideB = 0;
1120   ctx->Array.Index.Ptr = NULL;
1121   ctx->Array.Index.Enabled = GL_FALSE;
1122   for (i = 0; i < MAX_TEXTURE_UNITS; i++) {
1123      ctx->Array.TexCoord[i].Size = 4;
1124      ctx->Array.TexCoord[i].Type = GL_FLOAT;
1125      ctx->Array.TexCoord[i].Stride = 0;
1126      ctx->Array.TexCoord[i].StrideB = 0;
1127      ctx->Array.TexCoord[i].Ptr = NULL;
1128      ctx->Array.TexCoord[i].Enabled = GL_FALSE;
1129   }
1130   ctx->Array.TexCoordInterleaveFactor = 1;
1131   ctx->Array.EdgeFlag.Stride = 0;
1132   ctx->Array.EdgeFlag.StrideB = 0;
1133   ctx->Array.EdgeFlag.Ptr = NULL;
1134   ctx->Array.EdgeFlag.Enabled = GL_FALSE;
1135   ctx->Array.ActiveTexture = 0;   /* GL_ARB_multitexture */
1136
1137   /* Pixel transfer */
1138   ctx->Pack.Alignment = 4;
1139   ctx->Pack.RowLength = 0;
1140   ctx->Pack.ImageHeight = 0;
1141   ctx->Pack.SkipPixels = 0;
1142   ctx->Pack.SkipRows = 0;
1143   ctx->Pack.SkipImages = 0;
1144   ctx->Pack.SwapBytes = GL_FALSE;
1145   ctx->Pack.LsbFirst = GL_FALSE;
1146   ctx->Unpack.Alignment = 4;
1147   ctx->Unpack.RowLength = 0;
1148   ctx->Unpack.ImageHeight = 0;
1149   ctx->Unpack.SkipPixels = 0;
1150   ctx->Unpack.SkipRows = 0;
1151   ctx->Unpack.SkipImages = 0;
1152   ctx->Unpack.SwapBytes = GL_FALSE;
1153   ctx->Unpack.LsbFirst = GL_FALSE;
1154
1155   /* Feedback */
1156   ctx->Feedback.Type = GL_2D;   /* TODO: verify */
1157   ctx->Feedback.Buffer = NULL;
1158   ctx->Feedback.BufferSize = 0;
1159   ctx->Feedback.Count = 0;
1160
1161   /* Selection/picking */
1162   ctx->Select.Buffer = NULL;
1163   ctx->Select.BufferSize = 0;
1164   ctx->Select.BufferCount = 0;
1165   ctx->Select.Hits = 0;
1166   ctx->Select.NameStackDepth = 0;
1167
1168   /* Optimized Accum buffer */
1169   ctx->IntegerAccumMode = GL_TRUE;
1170   ctx->IntegerAccumScaler = 0.0;
1171
1172   /* Renderer and client attribute stacks */
1173   ctx->AttribStackDepth = 0;
1174   ctx->ClientAttribStackDepth = 0;
1175
1176   /* Miscellaneous */
1177   ctx->NewState = NEW_ALL;
1178   ctx->RenderMode = GL_RENDER;
1179   ctx->StippleCounter = 0;
1180   ctx->NeedNormals = GL_FALSE;
1181   ctx->DoViewportMapping = GL_TRUE;
1182
1183   ctx->NeedEyeCoords = GL_FALSE;
1184   ctx->NeedEyeNormals = GL_FALSE;
1185   ctx->vb_proj_matrix = &ctx->ModelProjectMatrix;
1186
1187   /* Display list */
1188   ctx->CallDepth = 0;
1189   ctx->ExecuteFlag = GL_TRUE;
1190   ctx->CompileFlag = GL_FALSE;
1191   ctx->CurrentListPtr = NULL;
1192   ctx->CurrentBlock = NULL;
1193   ctx->CurrentListNum = 0;
1194   ctx->CurrentPos = 0;
1195
1196   ctx->ErrorValue = (GLenum) GL_NO_ERROR;
1197
1198   ctx->CatchSignals = GL_TRUE;
1199
1200   /* For debug/development only */
1201   ctx->NoRaster = getenv("MESA_NO_RASTER") ? GL_TRUE : GL_FALSE;
1202   ctx->FirstTimeCurrent = GL_TRUE;
1203
1204   /* Dither disable */
1205   ctx->NoDither = getenv("MESA_NO_DITHER") ? GL_TRUE : GL_FALSE;
1206   if (ctx->NoDither) {
1207      if (getenv("MESA_DEBUG")) {
1208         fprintf(stderr, "MESA_NO_DITHER set - dithering disabled\n");
1209      }
1210      ctx->Color.DitherFlag = GL_FALSE;
1211   }
1212}
1213
1214
1215
1216
1217/*
1218 * Allocate the proxy textures.  If we run out of memory part way through
1219 * the allocations clean up and return GL_FALSE.
1220 * Return:  GL_TRUE=success, GL_FALSE=failure
1221 */
1222static GLboolean alloc_proxy_textures( GLcontext *ctx )
1223{
1224   GLboolean out_of_memory;
1225   GLint i;
1226
1227   ctx->Texture.Proxy1D = gl_alloc_texture_object(NULL, 0, 1);
1228   if (!ctx->Texture.Proxy1D) {
1229      return GL_FALSE;
1230   }
1231
1232   ctx->Texture.Proxy2D = gl_alloc_texture_object(NULL, 0, 2);
1233   if (!ctx->Texture.Proxy2D) {
1234      gl_free_texture_object(NULL, ctx->Texture.Proxy1D);
1235      return GL_FALSE;
1236   }
1237
1238   ctx->Texture.Proxy3D = gl_alloc_texture_object(NULL, 0, 3);
1239   if (!ctx->Texture.Proxy3D) {
1240      gl_free_texture_object(NULL, ctx->Texture.Proxy1D);
1241      gl_free_texture_object(NULL, ctx->Texture.Proxy2D);
1242      return GL_FALSE;
1243   }
1244
1245   out_of_memory = GL_FALSE;
1246   for (i=0;i<MAX_TEXTURE_LEVELS;i++) {
1247      ctx->Texture.Proxy1D->Image[i] = gl_alloc_texture_image();
1248      ctx->Texture.Proxy2D->Image[i] = gl_alloc_texture_image();
1249      ctx->Texture.Proxy3D->Image[i] = gl_alloc_texture_image();
1250      if (!ctx->Texture.Proxy1D->Image[i]
1251          || !ctx->Texture.Proxy2D->Image[i]
1252          || !ctx->Texture.Proxy3D->Image[i]) {
1253         out_of_memory = GL_TRUE;
1254      }
1255   }
1256   if (out_of_memory) {
1257      for (i=0;i<MAX_TEXTURE_LEVELS;i++) {
1258         if (ctx->Texture.Proxy1D->Image[i]) {
1259            gl_free_texture_image(ctx->Texture.Proxy1D->Image[i]);
1260         }
1261         if (ctx->Texture.Proxy2D->Image[i]) {
1262            gl_free_texture_image(ctx->Texture.Proxy2D->Image[i]);
1263         }
1264         if (ctx->Texture.Proxy3D->Image[i]) {
1265            gl_free_texture_image(ctx->Texture.Proxy3D->Image[i]);
1266         }
1267      }
1268      gl_free_texture_object(NULL, ctx->Texture.Proxy1D);
1269      gl_free_texture_object(NULL, ctx->Texture.Proxy2D);
1270      gl_free_texture_object(NULL, ctx->Texture.Proxy3D);
1271      return GL_FALSE;
1272   }
1273   else {
1274      return GL_TRUE;
1275   }
1276}
1277
1278
1279
1280/*
1281 * Initialize a GLcontext struct.
1282 */
1283GLboolean gl_initialize_context_data( GLcontext *ctx,
1284                                      GLvisual *visual,
1285                                      GLcontext *share_list,
1286                                      void *driver_ctx,
1287                                      GLboolean direct )
1288{
1289   (void) direct;  /* not used */
1290
1291   /* misc one-time initializations */
1292   one_time_init();
1293
1294   ctx->DriverCtx = driver_ctx;
1295   ctx->Visual = visual;
1296   ctx->DrawBuffer = NULL;
1297   ctx->ReadBuffer = NULL;
1298
1299   ctx->VB = gl_vb_create_for_immediate( ctx );
1300   if (!ctx->VB) {
1301      FREE( ctx );
1302      return GL_FALSE;
1303   }
1304   ctx->input = ctx->VB->IM;
1305
1306   ctx->PB = gl_alloc_pb();
1307   if (!ctx->PB) {
1308      FREE( ctx->VB );
1309      FREE( ctx );
1310      return GL_FALSE;
1311   }
1312
1313   if (share_list) {
1314      /* share the group of display lists of another context */
1315      ctx->Shared = share_list->Shared;
1316   }
1317   else {
1318      /* allocate new group of display lists */
1319      ctx->Shared = alloc_shared_state();
1320      if (!ctx->Shared) {
1321         FREE(ctx->VB);
1322         FREE(ctx->PB);
1323         FREE(ctx);
1324         return GL_FALSE;
1325      }
1326   }
1327   ctx->Shared->RefCount++;
1328
1329   init_attrib_groups( ctx );
1330
1331   gl_reset_vb( ctx->VB );
1332   gl_reset_input( ctx );
1333
1334   if (visual->DBflag) {
1335      ctx->Color.DrawBuffer = GL_BACK;
1336      ctx->Color.DriverDrawBuffer = GL_BACK_LEFT;
1337      ctx->Color.DrawDestMask = BACK_LEFT_BIT;
1338      ctx->Pixel.ReadBuffer = GL_BACK;
1339      ctx->Pixel.DriverReadBuffer = GL_BACK_LEFT;
1340   }
1341   else {
1342      ctx->Color.DrawBuffer = GL_FRONT;
1343      ctx->Color.DriverDrawBuffer = GL_FRONT_LEFT;
1344      ctx->Color.DrawDestMask = FRONT_LEFT_BIT;
1345      ctx->Pixel.ReadBuffer = GL_FRONT;
1346      ctx->Pixel.DriverReadBuffer = GL_FRONT_LEFT;
1347   }
1348
1349#ifdef PROFILE
1350   init_timings( ctx );
1351#endif
1352
1353   if (!alloc_proxy_textures(ctx)) {
1354      free_shared_state(ctx, ctx->Shared);
1355      FREE(ctx->VB);
1356      FREE(ctx->PB);
1357      FREE(ctx);
1358      return GL_FALSE;
1359   }
1360
1361   /* setup API dispatch tables */
1362   _mesa_init_exec_table( &ctx->Exec );
1363   _mesa_init_dlist_table( &ctx->Save );
1364   ctx->CurrentDispatch = &ctx->Exec;
1365
1366   return GL_TRUE;
1367}
1368
1369
1370
1371/*
1372 * Allocate and initialize a GLcontext structure.
1373 * Input:  visual - a GLvisual pointer
1374 *         sharelist - another context to share display lists with or NULL
1375 *         driver_ctx - pointer to device driver's context state struct
1376 * Return:  pointer to a new gl_context struct or NULL if error.
1377 */
1378GLcontext *gl_create_context( GLvisual *visual,
1379                              GLcontext *share_list,
1380                              void *driver_ctx,
1381                              GLboolean direct )
1382{
1383   GLcontext *ctx = (GLcontext *) CALLOC( sizeof(GLcontext) );
1384   if (!ctx) {
1385      return NULL;
1386   }
1387
1388   if (gl_initialize_context_data(ctx, visual, share_list,
1389                                  driver_ctx, direct)) {
1390      return ctx;
1391   }
1392   else {
1393      FREE(ctx);
1394      return NULL;
1395   }
1396}
1397
1398
1399
1400/*
1401 * Free the data associated with the given context.
1402 * But don't free() the GLcontext struct itself!
1403 */
1404void gl_free_context_data( GLcontext *ctx )
1405{
1406   GLuint i;
1407   struct gl_shine_tab *s, *tmps;
1408
1409   /* if we're destroying the current context, unbind it first */
1410   if (ctx == gl_get_current_context()) {
1411      gl_make_current(NULL, NULL);
1412   }
1413
1414#ifdef PROFILE
1415   if (getenv("MESA_PROFILE")) {
1416      print_timings( ctx );
1417   }
1418#endif
1419
1420   gl_matrix_dtr( &ctx->ModelView );
1421   for (i = 0 ; i < MAX_MODELVIEW_STACK_DEPTH ; i++) {
1422      gl_matrix_dtr( &ctx->ModelViewStack[i] );
1423   }
1424   gl_matrix_dtr( &ctx->ProjectionMatrix );
1425   for (i = 0 ; i < MAX_PROJECTION_STACK_DEPTH ; i++) {
1426      gl_matrix_dtr( &ctx->ProjectionStack[i] );
1427   }
1428
1429   FREE( ctx->PB );
1430
1431   if(ctx->input != ctx->VB->IM)
1432      gl_immediate_free( ctx->input );
1433
1434   gl_vb_free( ctx->VB );
1435
1436   ctx->Shared->RefCount--;
1437   assert(ctx->Shared->RefCount>=0);
1438   if (ctx->Shared->RefCount==0) {
1439      /* free shared state */
1440      free_shared_state( ctx, ctx->Shared );
1441   }
1442
1443   foreach_s( s, tmps, ctx->ShineTabList ) {
1444      FREE( s );
1445   }
1446   FREE( ctx->ShineTabList );
1447
1448   /* Free proxy texture objects */
1449   gl_free_texture_object( NULL, ctx->Texture.Proxy1D );
1450   gl_free_texture_object( NULL, ctx->Texture.Proxy2D );
1451   gl_free_texture_object( NULL, ctx->Texture.Proxy3D );
1452
1453   /* Free evaluator data */
1454   if (ctx->EvalMap.Map1Vertex3.Points)
1455      FREE( ctx->EvalMap.Map1Vertex3.Points );
1456   if (ctx->EvalMap.Map1Vertex4.Points)
1457      FREE( ctx->EvalMap.Map1Vertex4.Points );
1458   if (ctx->EvalMap.Map1Index.Points)
1459      FREE( ctx->EvalMap.Map1Index.Points );
1460   if (ctx->EvalMap.Map1Color4.Points)
1461      FREE( ctx->EvalMap.Map1Color4.Points );
1462   if (ctx->EvalMap.Map1Normal.Points)
1463      FREE( ctx->EvalMap.Map1Normal.Points );
1464   if (ctx->EvalMap.Map1Texture1.Points)
1465      FREE( ctx->EvalMap.Map1Texture1.Points );
1466   if (ctx->EvalMap.Map1Texture2.Points)
1467      FREE( ctx->EvalMap.Map1Texture2.Points );
1468   if (ctx->EvalMap.Map1Texture3.Points)
1469      FREE( ctx->EvalMap.Map1Texture3.Points );
1470   if (ctx->EvalMap.Map1Texture4.Points)
1471      FREE( ctx->EvalMap.Map1Texture4.Points );
1472
1473   if (ctx->EvalMap.Map2Vertex3.Points)
1474      FREE( ctx->EvalMap.Map2Vertex3.Points );
1475   if (ctx->EvalMap.Map2Vertex4.Points)
1476      FREE( ctx->EvalMap.Map2Vertex4.Points );
1477   if (ctx->EvalMap.Map2Index.Points)
1478      FREE( ctx->EvalMap.Map2Index.Points );
1479   if (ctx->EvalMap.Map2Color4.Points)
1480      FREE( ctx->EvalMap.Map2Color4.Points );
1481   if (ctx->EvalMap.Map2Normal.Points)
1482      FREE( ctx->EvalMap.Map2Normal.Points );
1483   if (ctx->EvalMap.Map2Texture1.Points)
1484      FREE( ctx->EvalMap.Map2Texture1.Points );
1485   if (ctx->EvalMap.Map2Texture2.Points)
1486      FREE( ctx->EvalMap.Map2Texture2.Points );
1487   if (ctx->EvalMap.Map2Texture3.Points)
1488      FREE( ctx->EvalMap.Map2Texture3.Points );
1489   if (ctx->EvalMap.Map2Texture4.Points)
1490      FREE( ctx->EvalMap.Map2Texture4.Points );
1491
1492   /* Free cache of immediate buffers. */
1493   while (ctx->nr_im_queued-- > 0) {
1494      struct immediate * next = ctx->freed_im_queue->next;
1495      FREE( ctx->freed_im_queue );
1496      ctx->freed_im_queue = next;
1497   }
1498   gl_extensions_dtr(ctx);
1499}
1500
1501
1502
1503/*
1504 * Destroy a GLcontext structure.
1505 */
1506void gl_destroy_context( GLcontext *ctx )
1507{
1508   if (ctx) {
1509      gl_free_context_data(ctx);
1510      FREE( (void *) ctx );
1511   }
1512}
1513
1514
1515
1516/*
1517 * Called by the driver after both the context and driver are fully
1518 * initialized.  Currently just reads the config file.
1519 */
1520void gl_context_initialize( GLcontext *ctx )
1521{
1522   gl_read_config_file( ctx );
1523}
1524
1525
1526
1527/*
1528 * Copy attribute groups from one context to another.
1529 * Input:  src - source context
1530 *         dst - destination context
1531 *         mask - bitwise OR of GL_*_BIT flags
1532 */
1533void gl_copy_context( const GLcontext *src, GLcontext *dst, GLuint mask )
1534{
1535   if (mask & GL_ACCUM_BUFFER_BIT) {
1536      MEMCPY( &dst->Accum, &src->Accum, sizeof(struct gl_accum_attrib) );
1537   }
1538   if (mask & GL_COLOR_BUFFER_BIT) {
1539      MEMCPY( &dst->Color, &src->Color, sizeof(struct gl_colorbuffer_attrib) );
1540   }
1541   if (mask & GL_CURRENT_BIT) {
1542      MEMCPY( &dst->Current, &src->Current, sizeof(struct gl_current_attrib) );
1543   }
1544   if (mask & GL_DEPTH_BUFFER_BIT) {
1545      MEMCPY( &dst->Depth, &src->Depth, sizeof(struct gl_depthbuffer_attrib) );
1546   }
1547   if (mask & GL_ENABLE_BIT) {
1548      /* no op */
1549   }
1550   if (mask & GL_EVAL_BIT) {
1551      MEMCPY( &dst->Eval, &src->Eval, sizeof(struct gl_eval_attrib) );
1552   }
1553   if (mask & GL_FOG_BIT) {
1554      MEMCPY( &dst->Fog, &src->Fog, sizeof(struct gl_fog_attrib) );
1555   }
1556   if (mask & GL_HINT_BIT) {
1557      MEMCPY( &dst->Hint, &src->Hint, sizeof(struct gl_hint_attrib) );
1558   }
1559   if (mask & GL_LIGHTING_BIT) {
1560      MEMCPY( &dst->Light, &src->Light, sizeof(struct gl_light_attrib) );
1561      /*       gl_reinit_light_attrib( &dst->Light ); */
1562   }
1563   if (mask & GL_LINE_BIT) {
1564      MEMCPY( &dst->Line, &src->Line, sizeof(struct gl_line_attrib) );
1565   }
1566   if (mask & GL_LIST_BIT) {
1567      MEMCPY( &dst->List, &src->List, sizeof(struct gl_list_attrib) );
1568   }
1569   if (mask & GL_PIXEL_MODE_BIT) {
1570      MEMCPY( &dst->Pixel, &src->Pixel, sizeof(struct gl_pixel_attrib) );
1571   }
1572   if (mask & GL_POINT_BIT) {
1573      MEMCPY( &dst->Point, &src->Point, sizeof(struct gl_point_attrib) );
1574   }
1575   if (mask & GL_POLYGON_BIT) {
1576      MEMCPY( &dst->Polygon, &src->Polygon, sizeof(struct gl_polygon_attrib) );
1577   }
1578   if (mask & GL_POLYGON_STIPPLE_BIT) {
1579      /* Use loop instead of MEMCPY due to problem with Portland Group's
1580       * C compiler.  Reported by John Stone.
1581       */
1582      int i;
1583      for (i=0;i<32;i++) {
1584         dst->PolygonStipple[i] = src->PolygonStipple[i];
1585      }
1586   }
1587   if (mask & GL_SCISSOR_BIT) {
1588      MEMCPY( &dst->Scissor, &src->Scissor, sizeof(struct gl_scissor_attrib) );
1589   }
1590   if (mask & GL_STENCIL_BUFFER_BIT) {
1591      MEMCPY( &dst->Stencil, &src->Stencil, sizeof(struct gl_stencil_attrib) );
1592   }
1593   if (mask & GL_TEXTURE_BIT) {
1594      MEMCPY( &dst->Texture, &src->Texture, sizeof(struct gl_texture_attrib) );
1595   }
1596   if (mask & GL_TRANSFORM_BIT) {
1597      MEMCPY( &dst->Transform, &src->Transform, sizeof(struct gl_transform_attrib) );
1598   }
1599   if (mask & GL_VIEWPORT_BIT) {
1600      MEMCPY( &dst->Viewport, &src->Viewport, sizeof(struct gl_viewport_attrib) );
1601   }
1602}
1603
1604
1605/*
1606 * Set the current context, binding the given frame buffer to the context.
1607 */
1608void gl_make_current( GLcontext *newCtx, GLframebuffer *buffer )
1609{
1610   gl_make_current2( newCtx, buffer, buffer );
1611}
1612
1613
1614/*
1615 * Bind the given context to the given draw-buffer and read-buffer
1616 * and make it the current context for this thread.
1617 */
1618void gl_make_current2( GLcontext *newCtx, GLframebuffer *drawBuffer,
1619                       GLframebuffer *readBuffer )
1620{
1621#if 0
1622   GLcontext *oldCtx = gl_get_current_context();
1623
1624   /* Flush the old context
1625    */
1626   if (oldCtx) {
1627      ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(oldCtx, "gl_make_current");
1628
1629      /* unbind frame buffers from context */
1630      if (oldCtx->DrawBuffer) {
1631         oldCtx->DrawBuffer = NULL;
1632      }
1633      if (oldCtx->ReadBuffer) {
1634         oldCtx->ReadBuffer = NULL;
1635      }
1636   }
1637#endif
1638
1639   /* We call this function periodically (just here for now) in
1640    * order to detect when multithreading has begun.
1641    */
1642   _glapi_check_multithread();
1643
1644   _glapi_set_current_context((void *) newCtx);
1645   ASSERT(gl_get_current_context() == newCtx);
1646   if (newCtx) {
1647      SET_IMMEDIATE(newCtx, newCtx->input);
1648      _glapi_set_dispatch(newCtx->CurrentDispatch);
1649   }
1650   else {
1651      _glapi_set_dispatch(NULL);  /* none current */
1652   }
1653
1654   if (MESA_VERBOSE) fprintf(stderr, "gl_make_current()\n");
1655
1656   if (newCtx && drawBuffer && readBuffer) {
1657      /* TODO: check if newCtx and buffer's visual match??? */
1658      newCtx->DrawBuffer = drawBuffer;
1659      newCtx->ReadBuffer = readBuffer;
1660      newCtx->NewState = NEW_ALL;   /* just to be safe */
1661      gl_update_state( newCtx );
1662   }
1663
1664   /* We can use this to help debug user's problems.  Tell the to set
1665    * the MESA_INFO env variable before running their app.  Then the
1666    * first time each context is made current we'll print some useful
1667    * information.
1668    */
1669   if (newCtx && newCtx->FirstTimeCurrent) {
1670      if (getenv("MESA_INFO")) {
1671         fprintf(stderr, "Mesa GL_VERSION = %s\n", (char *) _mesa_GetString(GL_VERSION));
1672         fprintf(stderr, "Mesa GL_RENDERER = %s\n", (char *) _mesa_GetString(GL_RENDERER));
1673         fprintf(stderr, "Mesa GL_VENDOR = %s\n", (char *) _mesa_GetString(GL_VENDOR));
1674         fprintf(stderr, "Mesa GL_EXTENSIONS = %s\n", (char *) _mesa_GetString(GL_EXTENSIONS));
1675#if defined(THREADS)
1676         fprintf(stderr, "Mesa thread-safe: YES\n");
1677#else
1678         fprintf(stderr, "Mesa thread-safe: NO\n");
1679#endif
1680#if defined(USE_X86_ASM)
1681         fprintf(stderr, "Mesa x86-optimized: YES\n");
1682#else
1683         fprintf(stderr, "Mesa x86-optimized: NO\n");
1684#endif
1685      }
1686      newCtx->FirstTimeCurrent = GL_FALSE;
1687   }
1688}
1689
1690
1691
1692/*
1693 * Return current context handle for the calling thread.
1694 * This isn't the fastest way to get the current context.
1695 * If you need speed, see the GET_CURRENT_CONTEXT() macro in context.h
1696 */
1697GLcontext *gl_get_current_context( void )
1698{
1699   return (GLcontext *) _glapi_get_current_context();
1700}
1701
1702
1703
1704/*
1705 * This should be called by device drivers just before they do a
1706 * swapbuffers.  Any pending rendering commands will be executed.
1707 */
1708void
1709_mesa_swapbuffers(GLcontext *ctx)
1710{
1711   FLUSH_VB( ctx, "swap buffers" );
1712}
1713
1714
1715
1716/*
1717 * Return pointer to this context's current API dispatch table.
1718 * It'll either be the immediate-mode execute dispatcher or the
1719 * display list compile dispatcher.
1720 */
1721struct _glapi_table *
1722_mesa_get_dispatch(GLcontext *ctx)
1723{
1724   return ctx->CurrentDispatch;
1725}
1726
1727
1728
1729void
1730_mesa_ResizeBuffersMESA( void )
1731{
1732   GLcontext *ctx = gl_get_current_context();
1733
1734   GLuint buf_width, buf_height;
1735
1736   if (MESA_VERBOSE & VERBOSE_API)
1737      fprintf(stderr, "glResizeBuffersMESA\n");
1738
1739   /* ask device driver for size of output buffer */
1740   (*ctx->Driver.GetBufferSize)( ctx, &buf_width, &buf_height );
1741
1742   /* see if size of device driver's color buffer (window) has changed */
1743   if (ctx->DrawBuffer->Width == (GLint) buf_width &&
1744       ctx->DrawBuffer->Height == (GLint) buf_height)
1745      return;
1746
1747   ctx->NewState |= NEW_RASTER_OPS;  /* to update scissor / window bounds */
1748
1749   /* save buffer size */
1750   ctx->DrawBuffer->Width = buf_width;
1751   ctx->DrawBuffer->Height = buf_height;
1752
1753   /* Reallocate other buffers if needed. */
1754   if (ctx->DrawBuffer->UseSoftwareDepthBuffer) {
1755      gl_alloc_depth_buffer( ctx );
1756   }
1757   if (ctx->DrawBuffer->UseSoftwareStencilBuffer) {
1758      gl_alloc_stencil_buffer( ctx );
1759   }
1760   if (ctx->DrawBuffer->UseSoftwareAccumBuffer) {
1761      gl_alloc_accum_buffer( ctx );
1762   }
1763   if (ctx->Visual->SoftwareAlpha) {
1764      gl_alloc_alpha_buffers( ctx );
1765   }
1766}
1767
1768
1769
1770/**********************************************************************/
1771/*****                Miscellaneous functions                     *****/
1772/**********************************************************************/
1773
1774
1775/*
1776 * This function is called when the Mesa user has stumbled into a code
1777 * path which may not be implemented fully or correctly.
1778 */
1779void gl_problem( const GLcontext *ctx, const char *s )
1780{
1781   fprintf( stderr, "Mesa implementation error: %s\n", s );
1782   fprintf( stderr, "Report to mesa-bugs@mesa3d.org\n" );
1783   (void) ctx;
1784}
1785
1786
1787
1788/*
1789 * This is called to inform the user that he or she has tried to do
1790 * something illogical or if there's likely a bug in their program
1791 * (like enabled depth testing without a depth buffer).
1792 */
1793void gl_warning( const GLcontext *ctx, const char *s )
1794{
1795   GLboolean debug;
1796#ifdef DEBUG
1797   debug = GL_TRUE;
1798#else
1799   if (getenv("MESA_DEBUG")) {
1800      debug = GL_TRUE;
1801   }
1802   else {
1803      debug = GL_FALSE;
1804   }
1805#endif
1806   if (debug) {
1807      fprintf( stderr, "Mesa warning: %s\n", s );
1808   }
1809   (void) ctx;
1810}
1811
1812
1813
1814void gl_compile_error( GLcontext *ctx, GLenum error, const char *s )
1815{
1816   if (ctx->CompileFlag)
1817      gl_save_error( ctx, error, s );
1818
1819   if (ctx->ExecuteFlag)
1820      gl_error( ctx, error, s );
1821}
1822
1823
1824/*
1825 * This is Mesa's error handler.  Normally, all that's done is the updating
1826 * of the current error value.  If Mesa is compiled with -DDEBUG or if the
1827 * environment variable "MESA_DEBUG" is defined then a real error message
1828 * is printed to stderr.
1829 * Input:  error - the error value
1830 *         s - a diagnostic string
1831 */
1832void gl_error( GLcontext *ctx, GLenum error, const char *s )
1833{
1834   GLboolean debug;
1835
1836#ifdef DEBUG
1837   debug = GL_TRUE;
1838#else
1839   if (getenv("MESA_DEBUG")) {
1840      debug = GL_TRUE;
1841   }
1842   else {
1843      debug = GL_FALSE;
1844   }
1845#endif
1846
1847   if (debug) {
1848      char errstr[1000];
1849
1850      switch (error) {
1851	 case GL_NO_ERROR:
1852	    strcpy( errstr, "GL_NO_ERROR" );
1853	    break;
1854	 case GL_INVALID_VALUE:
1855	    strcpy( errstr, "GL_INVALID_VALUE" );
1856	    break;
1857	 case GL_INVALID_ENUM:
1858	    strcpy( errstr, "GL_INVALID_ENUM" );
1859	    break;
1860	 case GL_INVALID_OPERATION:
1861	    strcpy( errstr, "GL_INVALID_OPERATION" );
1862	    break;
1863	 case GL_STACK_OVERFLOW:
1864	    strcpy( errstr, "GL_STACK_OVERFLOW" );
1865	    break;
1866	 case GL_STACK_UNDERFLOW:
1867	    strcpy( errstr, "GL_STACK_UNDERFLOW" );
1868	    break;
1869	 case GL_OUT_OF_MEMORY:
1870	    strcpy( errstr, "GL_OUT_OF_MEMORY" );
1871	    break;
1872	 default:
1873	    strcpy( errstr, "unknown" );
1874	    break;
1875      }
1876      fprintf( stderr, "Mesa user error: %s in %s\n", errstr, s );
1877   }
1878
1879   if (ctx->ErrorValue==GL_NO_ERROR) {
1880      ctx->ErrorValue = error;
1881   }
1882
1883   /* Call device driver's error handler, if any.  This is used on the Mac. */
1884   if (ctx->Driver.Error) {
1885      (*ctx->Driver.Error)( ctx );
1886   }
1887}
1888
1889
1890
1891/**********************************************************************/
1892/*****                   State update logic                       *****/
1893/**********************************************************************/
1894
1895
1896/*
1897 * Since the device driver may or may not support pixel logic ops we
1898 * have to make some extensive tests to determine whether or not
1899 * software-implemented logic operations have to be used.
1900 */
1901static void update_pixel_logic( GLcontext *ctx )
1902{
1903   if (ctx->Visual->RGBAflag) {
1904      /* RGBA mode blending w/ Logic Op */
1905      if (ctx->Color.ColorLogicOpEnabled) {
1906	 if (ctx->Driver.LogicOp
1907             && (*ctx->Driver.LogicOp)( ctx, ctx->Color.LogicOp )) {
1908	    /* Device driver can do logic, don't have to do it in software */
1909	    ctx->Color.SWLogicOpEnabled = GL_FALSE;
1910	 }
1911	 else {
1912	    /* Device driver can't do logic op so we do it in software */
1913	    ctx->Color.SWLogicOpEnabled = GL_TRUE;
1914	 }
1915      }
1916      else {
1917	 /* no logic op */
1918	 if (ctx->Driver.LogicOp) {
1919            (void) (*ctx->Driver.LogicOp)( ctx, GL_COPY );
1920         }
1921	 ctx->Color.SWLogicOpEnabled = GL_FALSE;
1922      }
1923   }
1924   else {
1925      /* CI mode Logic Op */
1926      if (ctx->Color.IndexLogicOpEnabled) {
1927	 if (ctx->Driver.LogicOp
1928             && (*ctx->Driver.LogicOp)( ctx, ctx->Color.LogicOp )) {
1929	    /* Device driver can do logic, don't have to do it in software */
1930	    ctx->Color.SWLogicOpEnabled = GL_FALSE;
1931	 }
1932	 else {
1933	    /* Device driver can't do logic op so we do it in software */
1934	    ctx->Color.SWLogicOpEnabled = GL_TRUE;
1935	 }
1936      }
1937      else {
1938	 /* no logic op */
1939	 if (ctx->Driver.LogicOp) {
1940            (void) (*ctx->Driver.LogicOp)( ctx, GL_COPY );
1941         }
1942	 ctx->Color.SWLogicOpEnabled = GL_FALSE;
1943      }
1944   }
1945}
1946
1947
1948
1949/*
1950 * Check if software implemented RGBA or Color Index masking is needed.
1951 */
1952static void update_pixel_masking( GLcontext *ctx )
1953{
1954   if (ctx->Visual->RGBAflag) {
1955      GLuint *colorMask = (GLuint *) ctx->Color.ColorMask;
1956      if (*colorMask == 0xffffffff) {
1957         /* disable masking */
1958         if (ctx->Driver.ColorMask) {
1959            (void) (*ctx->Driver.ColorMask)( ctx, GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE );
1960         }
1961         ctx->Color.SWmasking = GL_FALSE;
1962      }
1963      else {
1964         /* Ask driver to do color masking, if it can't then
1965          * do it in software
1966          */
1967         GLboolean red   = ctx->Color.ColorMask[RCOMP] ? GL_TRUE : GL_FALSE;
1968         GLboolean green = ctx->Color.ColorMask[GCOMP] ? GL_TRUE : GL_FALSE;
1969         GLboolean blue  = ctx->Color.ColorMask[BCOMP] ? GL_TRUE : GL_FALSE;
1970         GLboolean alpha = ctx->Color.ColorMask[ACOMP] ? GL_TRUE : GL_FALSE;
1971         if (ctx->Driver.ColorMask
1972             && (*ctx->Driver.ColorMask)( ctx, red, green, blue, alpha )) {
1973            ctx->Color.SWmasking = GL_FALSE;
1974         }
1975         else {
1976            ctx->Color.SWmasking = GL_TRUE;
1977         }
1978      }
1979   }
1980   else {
1981      if (ctx->Color.IndexMask==0xffffffff) {
1982         /* disable masking */
1983         if (ctx->Driver.IndexMask) {
1984            (void) (*ctx->Driver.IndexMask)( ctx, 0xffffffff );
1985         }
1986         ctx->Color.SWmasking = GL_FALSE;
1987      }
1988      else {
1989         /* Ask driver to do index masking, if it can't then
1990          * do it in software
1991          */
1992         if (ctx->Driver.IndexMask
1993             && (*ctx->Driver.IndexMask)( ctx, ctx->Color.IndexMask )) {
1994            ctx->Color.SWmasking = GL_FALSE;
1995         }
1996         else {
1997            ctx->Color.SWmasking = GL_TRUE;
1998         }
1999      }
2000   }
2001}
2002
2003
2004static void update_fog_mode( GLcontext *ctx )
2005{
2006   int old_mode = ctx->FogMode;
2007
2008   if (ctx->Fog.Enabled) {
2009      if (ctx->Texture.Enabled)
2010         ctx->FogMode = FOG_FRAGMENT;
2011      else if (ctx->Hint.Fog == GL_NICEST)
2012         ctx->FogMode = FOG_FRAGMENT;
2013      else
2014         ctx->FogMode = FOG_VERTEX;
2015
2016      if (ctx->Driver.GetParameteri)
2017         if ((ctx->Driver.GetParameteri)( ctx, DD_HAVE_HARDWARE_FOG ))
2018            ctx->FogMode = FOG_FRAGMENT;
2019   }
2020   else {
2021      ctx->FogMode = FOG_NONE;
2022   }
2023
2024   if (old_mode != ctx->FogMode)
2025      ctx->NewState |= NEW_FOG;
2026}
2027
2028
2029/*
2030 * Recompute the value of ctx->RasterMask, etc. according to
2031 * the current context.
2032 */
2033static void update_rasterflags( GLcontext *ctx )
2034{
2035   ctx->RasterMask = 0;
2036
2037   if (ctx->Color.AlphaEnabled)		ctx->RasterMask |= ALPHATEST_BIT;
2038   if (ctx->Color.BlendEnabled)		ctx->RasterMask |= BLEND_BIT;
2039   if (ctx->Depth.Test)			ctx->RasterMask |= DEPTH_BIT;
2040   if (ctx->FogMode==FOG_FRAGMENT)	ctx->RasterMask |= FOG_BIT;
2041   if (ctx->Color.SWLogicOpEnabled)	ctx->RasterMask |= LOGIC_OP_BIT;
2042   if (ctx->Scissor.Enabled)		ctx->RasterMask |= SCISSOR_BIT;
2043   if (ctx->Stencil.Enabled)		ctx->RasterMask |= STENCIL_BIT;
2044   if (ctx->Color.SWmasking)		ctx->RasterMask |= MASKING_BIT;
2045
2046   if (ctx->Visual->SoftwareAlpha && ctx->Color.ColorMask[ACOMP]
2047       && ctx->Color.DrawBuffer != GL_NONE)
2048      ctx->RasterMask |= ALPHABUF_BIT;
2049
2050   if (   ctx->Viewport.X<0
2051       || ctx->Viewport.X + ctx->Viewport.Width > ctx->DrawBuffer->Width
2052       || ctx->Viewport.Y<0
2053       || ctx->Viewport.Y + ctx->Viewport.Height > ctx->DrawBuffer->Height) {
2054      ctx->RasterMask |= WINCLIP_BIT;
2055   }
2056
2057   /* If we're not drawing to exactly one color buffer set the
2058    * MULTI_DRAW_BIT flag.  Also set it if we're drawing to no
2059    * buffers or the RGBA or CI mask disables all writes.
2060    */
2061
2062   ctx->TriangleCaps &= ~DD_MULTIDRAW;
2063
2064   if (ctx->Color.MultiDrawBuffer) {
2065      ctx->RasterMask |= MULTI_DRAW_BIT;
2066      ctx->TriangleCaps |= DD_MULTIDRAW;
2067   }
2068   else if (ctx->Color.DrawBuffer==GL_NONE) {
2069      ctx->RasterMask |= MULTI_DRAW_BIT;
2070      ctx->TriangleCaps |= DD_MULTIDRAW;
2071   }
2072   else if (ctx->Visual->RGBAflag && ctx->Color.ColorMask==0) {
2073      /* all RGBA channels disabled */
2074      ctx->RasterMask |= MULTI_DRAW_BIT;
2075      ctx->TriangleCaps |= DD_MULTIDRAW;
2076      ctx->Color.DrawDestMask = 0;
2077   }
2078   else if (!ctx->Visual->RGBAflag && ctx->Color.IndexMask==0) {
2079      /* all color index bits disabled */
2080      ctx->RasterMask |= MULTI_DRAW_BIT;
2081      ctx->TriangleCaps |= DD_MULTIDRAW;
2082      ctx->Color.DrawDestMask = 0;
2083   }
2084}
2085
2086
2087void gl_print_state( const char *msg, GLuint state )
2088{
2089   fprintf(stderr,
2090	   "%s: (0x%x) %s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s\n",
2091	   msg,
2092	   state,
2093	   (state & NEW_LIGHTING)         ? "lighting, " : "",
2094	   (state & NEW_RASTER_OPS)       ? "raster-ops, " : "",
2095	   (state & NEW_TEXTURING)        ? "texturing, " : "",
2096	   (state & NEW_POLYGON)          ? "polygon, " : "",
2097	   (state & NEW_DRVSTATE0)        ? "driver-0, " : "",
2098	   (state & NEW_DRVSTATE1)        ? "driver-1, " : "",
2099	   (state & NEW_DRVSTATE2)        ? "driver-2, " : "",
2100	   (state & NEW_DRVSTATE3)        ? "driver-3, " : "",
2101	   (state & NEW_MODELVIEW)        ? "modelview, " : "",
2102	   (state & NEW_PROJECTION)       ? "projection, " : "",
2103	   (state & NEW_TEXTURE_MATRIX)   ? "texture-matrix, " : "",
2104	   (state & NEW_USER_CLIP)        ? "user-clip, " : "",
2105	   (state & NEW_TEXTURE_ENV)      ? "texture-env, " : "",
2106	   (state & NEW_CLIENT_STATE)     ? "client-state, " : "",
2107	   (state & NEW_FOG)              ? "fog, " : "",
2108	   (state & NEW_NORMAL_TRANSFORM) ? "normal-transform, " : "",
2109	   (state & NEW_VIEWPORT)         ? "viewport, " : "",
2110	   (state & NEW_TEXTURE_ENABLE)   ? "texture-enable, " : "");
2111}
2112
2113void gl_print_enable_flags( const char *msg, GLuint flags )
2114{
2115   fprintf(stderr,
2116	   "%s: (0x%x) %s%s%s%s%s%s%s%s%s%s%s\n",
2117	   msg,
2118	   flags,
2119	   (flags & ENABLE_TEX0)       ? "tex-0, " : "",
2120	   (flags & ENABLE_TEX1)       ? "tex-1, " : "",
2121	   (flags & ENABLE_LIGHT)      ? "light, " : "",
2122	   (flags & ENABLE_FOG)        ? "fog, " : "",
2123	   (flags & ENABLE_USERCLIP)   ? "userclip, " : "",
2124	   (flags & ENABLE_TEXGEN0)    ? "tex-gen-0, " : "",
2125	   (flags & ENABLE_TEXGEN1)    ? "tex-gen-1, " : "",
2126	   (flags & ENABLE_TEXMAT0)    ? "tex-mat-0, " : "",
2127	   (flags & ENABLE_TEXMAT1)    ? "tex-mat-1, " : "",
2128	   (flags & ENABLE_NORMALIZE)  ? "normalize, " : "",
2129	   (flags & ENABLE_RESCALE)    ? "rescale, " : "");
2130}
2131
2132
2133/*
2134 * If ctx->NewState is non-zero then this function MUST be called before
2135 * rendering any primitive.  Basically, function pointers and miscellaneous
2136 * flags are updated to reflect the current state of the state machine.
2137 */
2138void gl_update_state( GLcontext *ctx )
2139{
2140   GLuint i;
2141
2142   if (MESA_VERBOSE & VERBOSE_STATE)
2143      gl_print_state("", ctx->NewState);
2144
2145   if (ctx->NewState & NEW_CLIENT_STATE)
2146      gl_update_client_state( ctx );
2147
2148   if ((ctx->NewState & NEW_TEXTURE_ENABLE) &&
2149       (ctx->Enabled & ENABLE_TEX_ANY) != ctx->Texture.Enabled)
2150      ctx->NewState |= NEW_TEXTURING | NEW_RASTER_OPS;
2151
2152   if (ctx->NewState & NEW_TEXTURE_ENV) {
2153      if (ctx->Texture.Unit[0].EnvMode == ctx->Texture.Unit[0].LastEnvMode &&
2154	  ctx->Texture.Unit[1].EnvMode == ctx->Texture.Unit[1].LastEnvMode)
2155	 ctx->NewState &= ~NEW_TEXTURE_ENV;
2156      ctx->Texture.Unit[0].LastEnvMode = ctx->Texture.Unit[0].EnvMode;
2157      ctx->Texture.Unit[1].LastEnvMode = ctx->Texture.Unit[1].EnvMode;
2158   }
2159
2160   if (ctx->NewState & NEW_TEXTURE_MATRIX) {
2161      ctx->Enabled &= ~(ENABLE_TEXMAT0|ENABLE_TEXMAT1);
2162
2163      for (i=0; i < MAX_TEXTURE_UNITS; i++) {
2164	 if (ctx->TextureMatrix[i].flags & MAT_DIRTY_ALL_OVER)
2165	 {
2166	    gl_matrix_analyze( &ctx->TextureMatrix[i] );
2167	    ctx->TextureMatrix[i].flags &= ~MAT_DIRTY_DEPENDENTS;
2168
2169	    if (ctx->Texture.Unit[i].Enabled &&
2170		ctx->TextureMatrix[i].type != MATRIX_IDENTITY)
2171	       ctx->Enabled |= ENABLE_TEXMAT0 << i;
2172	 }
2173      }
2174   }
2175
2176   if (ctx->NewState & (NEW_TEXTURING | NEW_TEXTURE_ENABLE)) {
2177      ctx->Texture.NeedNormals = GL_FALSE;
2178      gl_update_dirty_texobjs(ctx);
2179      ctx->Enabled &= ~(ENABLE_TEXGEN0|ENABLE_TEXGEN1);
2180      ctx->Texture.ReallyEnabled = 0;
2181
2182      for (i=0; i < MAX_TEXTURE_UNITS; i++) {
2183	 if (ctx->Texture.Unit[i].Enabled) {
2184	    gl_update_texture_unit( ctx, &ctx->Texture.Unit[i] );
2185
2186	    ctx->Texture.ReallyEnabled |=
2187	       ctx->Texture.Unit[i].ReallyEnabled<<(i*4);
2188
2189	    if (ctx->Texture.Unit[i].GenFlags != 0) {
2190	       ctx->Enabled |= ENABLE_TEXGEN0 << i;
2191
2192	       if (ctx->Texture.Unit[i].GenFlags & TEXGEN_NEED_NORMALS)
2193	       {
2194		  ctx->Texture.NeedNormals = GL_TRUE;
2195		  ctx->Texture.NeedEyeCoords = GL_TRUE;
2196	       }
2197
2198	       if (ctx->Texture.Unit[i].GenFlags & TEXGEN_NEED_EYE_COORD)
2199	       {
2200		  ctx->Texture.NeedEyeCoords = GL_TRUE;
2201	       }
2202	    }
2203	 }
2204      }
2205
2206      ctx->Texture.Enabled = ctx->Enabled & ENABLE_TEX_ANY;
2207      ctx->NeedNormals = (ctx->Light.Enabled || ctx->Texture.NeedNormals);
2208   }
2209
2210   if (ctx->NewState & (NEW_RASTER_OPS | NEW_LIGHTING | NEW_FOG)) {
2211
2212
2213      if (ctx->NewState & NEW_RASTER_OPS) {
2214	 update_pixel_logic(ctx);
2215	 update_pixel_masking(ctx);
2216	 update_fog_mode(ctx);
2217	 update_rasterflags(ctx);
2218	 if (ctx->Driver.Dither) {
2219	    (*ctx->Driver.Dither)( ctx, ctx->Color.DitherFlag );
2220	 }
2221
2222	 /* Check if incoming colors can be modified during rasterization */
2223	 if (ctx->Fog.Enabled ||
2224	     ctx->Texture.Enabled ||
2225	     ctx->Color.BlendEnabled ||
2226	     ctx->Color.SWmasking ||
2227	     ctx->Color.SWLogicOpEnabled) {
2228	    ctx->MutablePixels = GL_TRUE;
2229	 }
2230	 else {
2231	    ctx->MutablePixels = GL_FALSE;
2232	 }
2233
2234	 /* update scissor region */
2235
2236	 ctx->DrawBuffer->Xmin = 0;
2237	 ctx->DrawBuffer->Ymin = 0;
2238	 ctx->DrawBuffer->Xmax = ctx->DrawBuffer->Width-1;
2239	 ctx->DrawBuffer->Ymax = ctx->DrawBuffer->Height-1;
2240	 if (ctx->Scissor.Enabled) {
2241	    if (ctx->Scissor.X > ctx->DrawBuffer->Xmin) {
2242	       ctx->DrawBuffer->Xmin = ctx->Scissor.X;
2243	    }
2244	    if (ctx->Scissor.Y > ctx->DrawBuffer->Ymin) {
2245	       ctx->DrawBuffer->Ymin = ctx->Scissor.Y;
2246	    }
2247	    if (ctx->Scissor.X + ctx->Scissor.Width - 1 < ctx->DrawBuffer->Xmax) {
2248	       ctx->DrawBuffer->Xmax = ctx->Scissor.X + ctx->Scissor.Width - 1;
2249	    }
2250	    if (ctx->Scissor.Y + ctx->Scissor.Height - 1 < ctx->DrawBuffer->Ymax) {
2251	       ctx->DrawBuffer->Ymax = ctx->Scissor.Y + ctx->Scissor.Height - 1;
2252	    }
2253	 }
2254      }
2255
2256      if (ctx->NewState & NEW_LIGHTING) {
2257	 ctx->TriangleCaps &= ~(DD_TRI_LIGHT_TWOSIDE|DD_LIGHTING_CULL);
2258	 if (ctx->Light.Enabled) {
2259	    if (ctx->Light.Model.TwoSide)
2260	       ctx->TriangleCaps |= (DD_TRI_LIGHT_TWOSIDE|DD_LIGHTING_CULL);
2261	    gl_update_lighting(ctx);
2262	 }
2263      }
2264   }
2265
2266   if (ctx->NewState & (NEW_POLYGON | NEW_LIGHTING)) {
2267
2268      ctx->TriangleCaps &= ~DD_TRI_CULL_FRONT_BACK;
2269
2270      if (ctx->NewState & NEW_POLYGON) {
2271	 /* Setup CullBits bitmask */
2272	 if (ctx->Polygon.CullFlag) {
2273	    ctx->backface_sign = 1;
2274	    switch(ctx->Polygon.CullFaceMode) {
2275	    case GL_BACK:
2276	       if(ctx->Polygon.FrontFace==GL_CCW)
2277		  ctx->backface_sign = -1;
2278	       ctx->Polygon.CullBits = 1;
2279	       break;
2280	    case GL_FRONT:
2281	       if(ctx->Polygon.FrontFace!=GL_CCW)
2282		  ctx->backface_sign = -1;
2283	       ctx->Polygon.CullBits = 2;
2284	       break;
2285	    default:
2286	    case GL_FRONT_AND_BACK:
2287	       ctx->backface_sign = 0;
2288	       ctx->Polygon.CullBits = 0;
2289	       ctx->TriangleCaps |= DD_TRI_CULL_FRONT_BACK;
2290	       break;
2291	    }
2292	 }
2293	 else {
2294	    ctx->Polygon.CullBits = 3;
2295	    ctx->backface_sign = 0;
2296	 }
2297
2298	 /* Any Polygon offsets enabled? */
2299	 ctx->TriangleCaps &= ~DD_TRI_OFFSET;
2300
2301	 if (ctx->Polygon.OffsetPoint ||
2302	     ctx->Polygon.OffsetLine ||
2303	     ctx->Polygon.OffsetFill)
2304	    ctx->TriangleCaps |= DD_TRI_OFFSET;
2305
2306	 /* reset Z offsets now */
2307	 ctx->PointZoffset   = 0.0;
2308	 ctx->LineZoffset    = 0.0;
2309	 ctx->PolygonZoffset = 0.0;
2310      }
2311   }
2312
2313   if (ctx->NewState & ~(NEW_CLIENT_STATE|
2314			 NEW_DRIVER_STATE|NEW_USER_CLIP|
2315			 NEW_POLYGON))
2316      gl_update_clipmask(ctx);
2317
2318   if (ctx->NewState & (NEW_LIGHTING|
2319			NEW_RASTER_OPS|
2320			NEW_TEXTURING|
2321			NEW_TEXTURE_ENABLE|
2322			NEW_TEXTURE_ENV|
2323			NEW_POLYGON|
2324			NEW_DRVSTATE0|
2325			NEW_DRVSTATE1|
2326			NEW_DRVSTATE2|
2327			NEW_DRVSTATE3|
2328			NEW_USER_CLIP))
2329   {
2330      ctx->IndirectTriangles = ctx->TriangleCaps & ~ctx->Driver.TriangleCaps;
2331      ctx->IndirectTriangles |= DD_SW_RASTERIZE;
2332
2333      if (MESA_VERBOSE&VERBOSE_CULL)
2334	 gl_print_tri_caps("initial indirect tris", ctx->IndirectTriangles);
2335
2336      ctx->Driver.PointsFunc = NULL;
2337      ctx->Driver.LineFunc = NULL;
2338      ctx->Driver.TriangleFunc = NULL;
2339      ctx->Driver.QuadFunc = NULL;
2340      ctx->Driver.RectFunc = NULL;
2341      ctx->Driver.RenderVBClippedTab = NULL;
2342      ctx->Driver.RenderVBCulledTab = NULL;
2343      ctx->Driver.RenderVBRawTab = NULL;
2344
2345      /*
2346       * Here the driver sets up all the ctx->Driver function pointers to
2347       * it's specific, private functions.
2348       */
2349      ctx->Driver.UpdateState(ctx);
2350
2351      if (MESA_VERBOSE&VERBOSE_CULL)
2352	 gl_print_tri_caps("indirect tris", ctx->IndirectTriangles);
2353
2354      /*
2355       * In case the driver didn't hook in an optimized point, line or
2356       * triangle function we'll now select "core/fallback" point, line
2357       * and triangle functions.
2358       */
2359      if (ctx->IndirectTriangles & DD_SW_RASTERIZE) {
2360	 gl_set_point_function(ctx);
2361	 gl_set_line_function(ctx);
2362	 gl_set_triangle_function(ctx);
2363	 gl_set_quad_function(ctx);
2364
2365	 if ((ctx->IndirectTriangles &
2366	      (DD_TRI_SW_RASTERIZE|DD_QUAD_SW_RASTERIZE|DD_TRI_CULL)) ==
2367	     (DD_TRI_SW_RASTERIZE|DD_QUAD_SW_RASTERIZE|DD_TRI_CULL))
2368	    ctx->IndirectTriangles &= ~DD_TRI_CULL;
2369      }
2370
2371      if (MESA_VERBOSE&VERBOSE_CULL)
2372	 gl_print_tri_caps("indirect tris 2", ctx->IndirectTriangles);
2373
2374      gl_set_render_vb_function(ctx);
2375   }
2376
2377   /* Should only be calc'd when !need_eye_coords and not culling.
2378    */
2379   if (ctx->NewState & (NEW_MODELVIEW|NEW_PROJECTION)) {
2380      if (ctx->NewState & NEW_MODELVIEW) {
2381	 gl_matrix_analyze( &ctx->ModelView );
2382	 ctx->ProjectionMatrix.flags &= ~MAT_DIRTY_DEPENDENTS;
2383      }
2384
2385      if (ctx->NewState & NEW_PROJECTION) {
2386	 gl_matrix_analyze( &ctx->ProjectionMatrix );
2387	 ctx->ProjectionMatrix.flags &= ~MAT_DIRTY_DEPENDENTS;
2388
2389	 if (ctx->Transform.AnyClip) {
2390	    gl_update_userclip( ctx );
2391	 }
2392      }
2393
2394      gl_calculate_model_project_matrix( ctx );
2395      ctx->ModelProjectWinMatrixUptodate = 0;
2396   }
2397
2398   /* Figure out whether we can light in object space or not.  If we
2399    * can, find the current positions of the lights in object space
2400    */
2401   if ((ctx->Enabled & (ENABLE_POINT_ATTEN | ENABLE_LIGHT | ENABLE_FOG |
2402			ENABLE_TEXGEN0 | ENABLE_TEXGEN1)) &&
2403       (ctx->NewState & (NEW_LIGHTING |
2404                         NEW_FOG |
2405			 NEW_MODELVIEW |
2406			 NEW_PROJECTION |
2407			 NEW_TEXTURING |
2408			 NEW_RASTER_OPS |
2409			 NEW_USER_CLIP)))
2410   {
2411      GLboolean oldcoord, oldnorm;
2412
2413      oldcoord = ctx->NeedEyeCoords;
2414      oldnorm = ctx->NeedEyeNormals;
2415
2416      ctx->NeedNormals = (ctx->Light.Enabled || ctx->Texture.NeedNormals);
2417      ctx->NeedEyeCoords = ((ctx->Fog.Enabled && ctx->Hint.Fog != GL_NICEST) ||
2418			    ctx->Point.Attenuated);
2419      ctx->NeedEyeNormals = GL_FALSE;
2420
2421      if (ctx->Light.Enabled) {
2422	 if (ctx->Light.Flags & LIGHT_POSITIONAL) {
2423	    /* Need length for attenuation */
2424	    if (!TEST_MAT_FLAGS( &ctx->ModelView, MAT_FLAGS_LENGTH_PRESERVING))
2425	       ctx->NeedEyeCoords = GL_TRUE;
2426	 } else if (ctx->Light.NeedVertices) {
2427	    /* Need angle for spot calculations */
2428	    if (!TEST_MAT_FLAGS( &ctx->ModelView, MAT_FLAGS_ANGLE_PRESERVING))
2429	       ctx->NeedEyeCoords = GL_TRUE;
2430	 }
2431	 ctx->NeedEyeNormals = ctx->NeedEyeCoords;
2432      }
2433      if (ctx->Texture.Enabled || ctx->RenderMode==GL_FEEDBACK) {
2434	 if (ctx->Texture.NeedEyeCoords) ctx->NeedEyeCoords = GL_TRUE;
2435	 if (ctx->Texture.NeedNormals)
2436	    ctx->NeedNormals = ctx->NeedEyeNormals = GL_TRUE;
2437      }
2438
2439      ctx->vb_proj_matrix = &ctx->ModelProjectMatrix;
2440
2441      if (ctx->NeedEyeCoords)
2442	 ctx->vb_proj_matrix = &ctx->ProjectionMatrix;
2443
2444      if (ctx->Light.Enabled) {
2445	 gl_update_lighting_function(ctx);
2446
2447	 if ( (ctx->NewState & NEW_LIGHTING) ||
2448	      ((ctx->NewState & (NEW_MODELVIEW| NEW_PROJECTION)) &&
2449	       !ctx->NeedEyeCoords) ||
2450	      oldcoord != ctx->NeedEyeCoords ||
2451	      oldnorm != ctx->NeedEyeNormals) {
2452	    gl_compute_light_positions(ctx);
2453	 }
2454
2455	 ctx->rescale_factor = 1.0F;
2456
2457	 if (ctx->ModelView.flags & (MAT_FLAG_UNIFORM_SCALE |
2458				     MAT_FLAG_GENERAL_SCALE |
2459				     MAT_FLAG_GENERAL_3D |
2460				     MAT_FLAG_GENERAL) )
2461
2462	 {
2463	    GLfloat *m = ctx->ModelView.inv;
2464	    GLfloat f = m[2]*m[2] + m[6]*m[6] + m[10]*m[10];
2465	    if (f > 1e-12 && (f-1)*(f-1) > 1e-12)
2466	       ctx->rescale_factor = 1.0/GL_SQRT(f);
2467	 }
2468      }
2469
2470      gl_update_normal_transform( ctx );
2471   }
2472
2473   gl_update_pipelines(ctx);
2474   ctx->NewState = 0;
2475}
2476