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