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