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