prefixed hash functions with _mesa_
[mesa.git] / src / mesa / main / context.c
1 /* $Id: context.c,v 1.34 2000/01/24 16:19:55 brianp Exp $ */
2
3 /*
4 * Mesa 3-D graphics library
5 * Version: 3.3
6 *
7 * Copyright (C) 1999-2000 Brian Paul All Rights Reserved.
8 *
9 * Permission is hereby granted, free of charge, to any person obtaining a
10 * copy of this software and associated documentation files (the "Software"),
11 * to deal in the Software without restriction, including without limitation
12 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
13 * and/or sell copies of the Software, and to permit persons to whom the
14 * Software is furnished to do so, subject to the following conditions:
15 *
16 * The above copyright notice and this permission notice shall be included
17 * in all copies or substantial portions of the Software.
18 *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
22 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
23 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
24 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 */
26
27
28 #ifdef PC_HEADER
29 #include "all.h"
30 #else
31 #include "glheader.h"
32 #include "accum.h"
33 #include "alphabuf.h"
34 #include "clip.h"
35 #include "context.h"
36 #include "cva.h"
37 #include "depth.h"
38 #include "dispatch.h"
39 #include "dlist.h"
40 #include "eval.h"
41 #include "enums.h"
42 #include "extensions.h"
43 #include "fog.h"
44 #include "get.h"
45 #include "glapi.h"
46 #include "hash.h"
47 #include "light.h"
48 #include "lines.h"
49 #include "dlist.h"
50 #include "macros.h"
51 #include "matrix.h"
52 #include "mem.h"
53 #include "mmath.h"
54 #include "pb.h"
55 #include "pipeline.h"
56 #include "points.h"
57 #include "quads.h"
58 #include "shade.h"
59 #include "simple_list.h"
60 #include "stencil.h"
61 #include "stages.h"
62 #include "triangle.h"
63 #include "translate.h"
64 #include "teximage.h"
65 #include "texobj.h"
66 #include "texstate.h"
67 #include "texture.h"
68 #include "types.h"
69 #include "varray.h"
70 #include "vb.h"
71 #include "vbcull.h"
72 #include "vbfill.h"
73 #include "vbrender.h"
74 #include "vbxform.h"
75 #include "vertices.h"
76 #include "xform.h"
77 #endif
78
79
80
81 /**********************************************************************/
82 /***** Context and Thread management *****/
83 /**********************************************************************/
84
85
86 #if !defined(THREADS)
87
88 struct immediate *_mesa_CurrentInput = NULL;
89
90 #endif
91
92
93
94
95 /**********************************************************************/
96 /***** Profiling functions *****/
97 /**********************************************************************/
98
99 #ifdef PROFILE
100
101 #include <sys/times.h>
102 #include <sys/param.h>
103
104
105 /*
106 * Return system time in seconds.
107 * NOTE: this implementation may not be very portable!
108 */
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 = _mesa_NewHashTable();
476
477 ss->TexObjects = _mesa_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 _mesa_DeleteHashTable(ss->DisplayList);
494 if (ss->TexObjects)
495 _mesa_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 = _mesa_HashFirstEntry(ss->DisplayList);
519 if (list) {
520 gl_destroy_list(ctx, list);
521 }
522 else {
523 break;
524 }
525 }
526 _mesa_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 _mesa_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 #if defined(USE_X86_ASM)
1672 fprintf(stderr, "Mesa x86-optimized: YES\n");
1673 #else
1674 fprintf(stderr, "Mesa x86-optimized: NO\n");
1675 #endif
1676 }
1677 newCtx->FirstTimeCurrent = GL_FALSE;
1678 }
1679 }
1680
1681
1682
1683 /*
1684 * Return current context handle for the calling thread.
1685 * This isn't the fastest way to get the current context.
1686 * If you need speed, see the GET_CURRENT_CONTEXT() macro in context.h
1687 */
1688 GLcontext *gl_get_current_context( void )
1689 {
1690 return (GLcontext *) _glapi_get_current_context();
1691 }
1692
1693
1694
1695 /*
1696 * This should be called by device drivers just before they do a
1697 * swapbuffers. Any pending rendering commands will be executed.
1698 */
1699 void
1700 _mesa_swapbuffers(GLcontext *ctx)
1701 {
1702 FLUSH_VB( ctx, "swap buffers" );
1703 }
1704
1705
1706
1707 /*
1708 * Return pointer to this context's current API dispatch table.
1709 * It'll either be the immediate-mode execute dispatcher or the
1710 * display list compile dispatcher.
1711 */
1712 struct _glapi_table *
1713 _mesa_get_dispatch(GLcontext *ctx)
1714 {
1715 return ctx->CurrentDispatch;
1716 }
1717
1718
1719
1720 void
1721 _mesa_ResizeBuffersMESA( void )
1722 {
1723 GLcontext *ctx = gl_get_current_context();
1724
1725 GLuint buf_width, buf_height;
1726
1727 if (MESA_VERBOSE & VERBOSE_API)
1728 fprintf(stderr, "glResizeBuffersMESA\n");
1729
1730 /* ask device driver for size of output buffer */
1731 (*ctx->Driver.GetBufferSize)( ctx, &buf_width, &buf_height );
1732
1733 /* see if size of device driver's color buffer (window) has changed */
1734 if (ctx->DrawBuffer->Width == (GLint) buf_width &&
1735 ctx->DrawBuffer->Height == (GLint) buf_height)
1736 return;
1737
1738 ctx->NewState |= NEW_RASTER_OPS; /* to update scissor / window bounds */
1739
1740 /* save buffer size */
1741 ctx->DrawBuffer->Width = buf_width;
1742 ctx->DrawBuffer->Height = buf_height;
1743
1744 /* Reallocate other buffers if needed. */
1745 if (ctx->DrawBuffer->UseSoftwareDepthBuffer) {
1746 gl_alloc_depth_buffer( ctx );
1747 }
1748 if (ctx->DrawBuffer->UseSoftwareStencilBuffer) {
1749 gl_alloc_stencil_buffer( ctx );
1750 }
1751 if (ctx->DrawBuffer->UseSoftwareAccumBuffer) {
1752 gl_alloc_accum_buffer( ctx );
1753 }
1754 if (ctx->Visual->SoftwareAlpha) {
1755 gl_alloc_alpha_buffers( ctx );
1756 }
1757 }
1758
1759
1760
1761 /**********************************************************************/
1762 /***** Miscellaneous functions *****/
1763 /**********************************************************************/
1764
1765
1766 /*
1767 * This function is called when the Mesa user has stumbled into a code
1768 * path which may not be implemented fully or correctly.
1769 */
1770 void gl_problem( const GLcontext *ctx, const char *s )
1771 {
1772 fprintf( stderr, "Mesa implementation error: %s\n", s );
1773 fprintf( stderr, "Report to mesa-bugs@mesa3d.org\n" );
1774 (void) ctx;
1775 }
1776
1777
1778
1779 /*
1780 * This is called to inform the user that he or she has tried to do
1781 * something illogical or if there's likely a bug in their program
1782 * (like enabled depth testing without a depth buffer).
1783 */
1784 void gl_warning( const GLcontext *ctx, const char *s )
1785 {
1786 GLboolean debug;
1787 #ifdef DEBUG
1788 debug = GL_TRUE;
1789 #else
1790 if (getenv("MESA_DEBUG")) {
1791 debug = GL_TRUE;
1792 }
1793 else {
1794 debug = GL_FALSE;
1795 }
1796 #endif
1797 if (debug) {
1798 fprintf( stderr, "Mesa warning: %s\n", s );
1799 }
1800 (void) ctx;
1801 }
1802
1803
1804
1805 void gl_compile_error( GLcontext *ctx, GLenum error, const char *s )
1806 {
1807 if (ctx->CompileFlag)
1808 gl_save_error( ctx, error, s );
1809
1810 if (ctx->ExecuteFlag)
1811 gl_error( ctx, error, s );
1812 }
1813
1814
1815 /*
1816 * This is Mesa's error handler. Normally, all that's done is the updating
1817 * of the current error value. If Mesa is compiled with -DDEBUG or if the
1818 * environment variable "MESA_DEBUG" is defined then a real error message
1819 * is printed to stderr.
1820 * Input: error - the error value
1821 * s - a diagnostic string
1822 */
1823 void gl_error( GLcontext *ctx, GLenum error, const char *s )
1824 {
1825 GLboolean debug;
1826
1827 #ifdef DEBUG
1828 debug = GL_TRUE;
1829 #else
1830 if (getenv("MESA_DEBUG")) {
1831 debug = GL_TRUE;
1832 }
1833 else {
1834 debug = GL_FALSE;
1835 }
1836 #endif
1837
1838 if (debug) {
1839 char errstr[1000];
1840
1841 switch (error) {
1842 case GL_NO_ERROR:
1843 strcpy( errstr, "GL_NO_ERROR" );
1844 break;
1845 case GL_INVALID_VALUE:
1846 strcpy( errstr, "GL_INVALID_VALUE" );
1847 break;
1848 case GL_INVALID_ENUM:
1849 strcpy( errstr, "GL_INVALID_ENUM" );
1850 break;
1851 case GL_INVALID_OPERATION:
1852 strcpy( errstr, "GL_INVALID_OPERATION" );
1853 break;
1854 case GL_STACK_OVERFLOW:
1855 strcpy( errstr, "GL_STACK_OVERFLOW" );
1856 break;
1857 case GL_STACK_UNDERFLOW:
1858 strcpy( errstr, "GL_STACK_UNDERFLOW" );
1859 break;
1860 case GL_OUT_OF_MEMORY:
1861 strcpy( errstr, "GL_OUT_OF_MEMORY" );
1862 break;
1863 default:
1864 strcpy( errstr, "unknown" );
1865 break;
1866 }
1867 fprintf( stderr, "Mesa user error: %s in %s\n", errstr, s );
1868 }
1869
1870 if (ctx->ErrorValue==GL_NO_ERROR) {
1871 ctx->ErrorValue = error;
1872 }
1873
1874 /* Call device driver's error handler, if any. This is used on the Mac. */
1875 if (ctx->Driver.Error) {
1876 (*ctx->Driver.Error)( ctx );
1877 }
1878 }
1879
1880
1881
1882 /**********************************************************************/
1883 /***** State update logic *****/
1884 /**********************************************************************/
1885
1886
1887 /*
1888 * Since the device driver may or may not support pixel logic ops we
1889 * have to make some extensive tests to determine whether or not
1890 * software-implemented logic operations have to be used.
1891 */
1892 static void update_pixel_logic( GLcontext *ctx )
1893 {
1894 if (ctx->Visual->RGBAflag) {
1895 /* RGBA mode blending w/ Logic Op */
1896 if (ctx->Color.ColorLogicOpEnabled) {
1897 if (ctx->Driver.LogicOp
1898 && (*ctx->Driver.LogicOp)( ctx, ctx->Color.LogicOp )) {
1899 /* Device driver can do logic, don't have to do it in software */
1900 ctx->Color.SWLogicOpEnabled = GL_FALSE;
1901 }
1902 else {
1903 /* Device driver can't do logic op so we do it in software */
1904 ctx->Color.SWLogicOpEnabled = GL_TRUE;
1905 }
1906 }
1907 else {
1908 /* no logic op */
1909 if (ctx->Driver.LogicOp) {
1910 (void) (*ctx->Driver.LogicOp)( ctx, GL_COPY );
1911 }
1912 ctx->Color.SWLogicOpEnabled = GL_FALSE;
1913 }
1914 }
1915 else {
1916 /* CI mode Logic Op */
1917 if (ctx->Color.IndexLogicOpEnabled) {
1918 if (ctx->Driver.LogicOp
1919 && (*ctx->Driver.LogicOp)( ctx, ctx->Color.LogicOp )) {
1920 /* Device driver can do logic, don't have to do it in software */
1921 ctx->Color.SWLogicOpEnabled = GL_FALSE;
1922 }
1923 else {
1924 /* Device driver can't do logic op so we do it in software */
1925 ctx->Color.SWLogicOpEnabled = GL_TRUE;
1926 }
1927 }
1928 else {
1929 /* no logic op */
1930 if (ctx->Driver.LogicOp) {
1931 (void) (*ctx->Driver.LogicOp)( ctx, GL_COPY );
1932 }
1933 ctx->Color.SWLogicOpEnabled = GL_FALSE;
1934 }
1935 }
1936 }
1937
1938
1939
1940 /*
1941 * Check if software implemented RGBA or Color Index masking is needed.
1942 */
1943 static void update_pixel_masking( GLcontext *ctx )
1944 {
1945 if (ctx->Visual->RGBAflag) {
1946 GLuint *colorMask = (GLuint *) ctx->Color.ColorMask;
1947 if (*colorMask == 0xffffffff) {
1948 /* disable masking */
1949 if (ctx->Driver.ColorMask) {
1950 (void) (*ctx->Driver.ColorMask)( ctx, GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE );
1951 }
1952 ctx->Color.SWmasking = GL_FALSE;
1953 }
1954 else {
1955 /* Ask driver to do color masking, if it can't then
1956 * do it in software
1957 */
1958 GLboolean red = ctx->Color.ColorMask[RCOMP] ? GL_TRUE : GL_FALSE;
1959 GLboolean green = ctx->Color.ColorMask[GCOMP] ? GL_TRUE : GL_FALSE;
1960 GLboolean blue = ctx->Color.ColorMask[BCOMP] ? GL_TRUE : GL_FALSE;
1961 GLboolean alpha = ctx->Color.ColorMask[ACOMP] ? GL_TRUE : GL_FALSE;
1962 if (ctx->Driver.ColorMask
1963 && (*ctx->Driver.ColorMask)( ctx, red, green, blue, alpha )) {
1964 ctx->Color.SWmasking = GL_FALSE;
1965 }
1966 else {
1967 ctx->Color.SWmasking = GL_TRUE;
1968 }
1969 }
1970 }
1971 else {
1972 if (ctx->Color.IndexMask==0xffffffff) {
1973 /* disable masking */
1974 if (ctx->Driver.IndexMask) {
1975 (void) (*ctx->Driver.IndexMask)( ctx, 0xffffffff );
1976 }
1977 ctx->Color.SWmasking = GL_FALSE;
1978 }
1979 else {
1980 /* Ask driver to do index masking, if it can't then
1981 * do it in software
1982 */
1983 if (ctx->Driver.IndexMask
1984 && (*ctx->Driver.IndexMask)( ctx, ctx->Color.IndexMask )) {
1985 ctx->Color.SWmasking = GL_FALSE;
1986 }
1987 else {
1988 ctx->Color.SWmasking = GL_TRUE;
1989 }
1990 }
1991 }
1992 }
1993
1994
1995 static void update_fog_mode( GLcontext *ctx )
1996 {
1997 int old_mode = ctx->FogMode;
1998
1999 if (ctx->Fog.Enabled) {
2000 if (ctx->Texture.Enabled)
2001 ctx->FogMode = FOG_FRAGMENT;
2002 else if (ctx->Hint.Fog == GL_NICEST)
2003 ctx->FogMode = FOG_FRAGMENT;
2004 else
2005 ctx->FogMode = FOG_VERTEX;
2006
2007 if (ctx->Driver.GetParameteri)
2008 if ((ctx->Driver.GetParameteri)( ctx, DD_HAVE_HARDWARE_FOG ))
2009 ctx->FogMode = FOG_FRAGMENT;
2010 }
2011 else {
2012 ctx->FogMode = FOG_NONE;
2013 }
2014
2015 if (old_mode != ctx->FogMode)
2016 ctx->NewState |= NEW_FOG;
2017 }
2018
2019
2020 /*
2021 * Recompute the value of ctx->RasterMask, etc. according to
2022 * the current context.
2023 */
2024 static void update_rasterflags( GLcontext *ctx )
2025 {
2026 ctx->RasterMask = 0;
2027
2028 if (ctx->Color.AlphaEnabled) ctx->RasterMask |= ALPHATEST_BIT;
2029 if (ctx->Color.BlendEnabled) ctx->RasterMask |= BLEND_BIT;
2030 if (ctx->Depth.Test) ctx->RasterMask |= DEPTH_BIT;
2031 if (ctx->FogMode==FOG_FRAGMENT) ctx->RasterMask |= FOG_BIT;
2032 if (ctx->Color.SWLogicOpEnabled) ctx->RasterMask |= LOGIC_OP_BIT;
2033 if (ctx->Scissor.Enabled) ctx->RasterMask |= SCISSOR_BIT;
2034 if (ctx->Stencil.Enabled) ctx->RasterMask |= STENCIL_BIT;
2035 if (ctx->Color.SWmasking) ctx->RasterMask |= MASKING_BIT;
2036
2037 if (ctx->Visual->SoftwareAlpha && ctx->Color.ColorMask[ACOMP]
2038 && ctx->Color.DrawBuffer != GL_NONE)
2039 ctx->RasterMask |= ALPHABUF_BIT;
2040
2041 if ( ctx->Viewport.X<0
2042 || ctx->Viewport.X + ctx->Viewport.Width > ctx->DrawBuffer->Width
2043 || ctx->Viewport.Y<0
2044 || ctx->Viewport.Y + ctx->Viewport.Height > ctx->DrawBuffer->Height) {
2045 ctx->RasterMask |= WINCLIP_BIT;
2046 }
2047
2048 /* If we're not drawing to exactly one color buffer set the
2049 * MULTI_DRAW_BIT flag. Also set it if we're drawing to no
2050 * buffers or the RGBA or CI mask disables all writes.
2051 */
2052
2053 ctx->TriangleCaps &= ~DD_MULTIDRAW;
2054
2055 if (ctx->Color.MultiDrawBuffer) {
2056 ctx->RasterMask |= MULTI_DRAW_BIT;
2057 ctx->TriangleCaps |= DD_MULTIDRAW;
2058 }
2059 else if (ctx->Color.DrawBuffer==GL_NONE) {
2060 ctx->RasterMask |= MULTI_DRAW_BIT;
2061 ctx->TriangleCaps |= DD_MULTIDRAW;
2062 }
2063 else if (ctx->Visual->RGBAflag && ctx->Color.ColorMask==0) {
2064 /* all RGBA channels disabled */
2065 ctx->RasterMask |= MULTI_DRAW_BIT;
2066 ctx->TriangleCaps |= DD_MULTIDRAW;
2067 ctx->Color.DrawDestMask = 0;
2068 }
2069 else if (!ctx->Visual->RGBAflag && ctx->Color.IndexMask==0) {
2070 /* all color index bits disabled */
2071 ctx->RasterMask |= MULTI_DRAW_BIT;
2072 ctx->TriangleCaps |= DD_MULTIDRAW;
2073 ctx->Color.DrawDestMask = 0;
2074 }
2075 }
2076
2077
2078 void gl_print_state( const char *msg, GLuint state )
2079 {
2080 fprintf(stderr,
2081 "%s: (0x%x) %s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s\n",
2082 msg,
2083 state,
2084 (state & NEW_LIGHTING) ? "lighting, " : "",
2085 (state & NEW_RASTER_OPS) ? "raster-ops, " : "",
2086 (state & NEW_TEXTURING) ? "texturing, " : "",
2087 (state & NEW_POLYGON) ? "polygon, " : "",
2088 (state & NEW_DRVSTATE0) ? "driver-0, " : "",
2089 (state & NEW_DRVSTATE1) ? "driver-1, " : "",
2090 (state & NEW_DRVSTATE2) ? "driver-2, " : "",
2091 (state & NEW_DRVSTATE3) ? "driver-3, " : "",
2092 (state & NEW_MODELVIEW) ? "modelview, " : "",
2093 (state & NEW_PROJECTION) ? "projection, " : "",
2094 (state & NEW_TEXTURE_MATRIX) ? "texture-matrix, " : "",
2095 (state & NEW_USER_CLIP) ? "user-clip, " : "",
2096 (state & NEW_TEXTURE_ENV) ? "texture-env, " : "",
2097 (state & NEW_CLIENT_STATE) ? "client-state, " : "",
2098 (state & NEW_FOG) ? "fog, " : "",
2099 (state & NEW_NORMAL_TRANSFORM) ? "normal-transform, " : "",
2100 (state & NEW_VIEWPORT) ? "viewport, " : "",
2101 (state & NEW_TEXTURE_ENABLE) ? "texture-enable, " : "");
2102 }
2103
2104 void gl_print_enable_flags( const char *msg, GLuint flags )
2105 {
2106 fprintf(stderr,
2107 "%s: (0x%x) %s%s%s%s%s%s%s%s%s%s%s\n",
2108 msg,
2109 flags,
2110 (flags & ENABLE_TEX0) ? "tex-0, " : "",
2111 (flags & ENABLE_TEX1) ? "tex-1, " : "",
2112 (flags & ENABLE_LIGHT) ? "light, " : "",
2113 (flags & ENABLE_FOG) ? "fog, " : "",
2114 (flags & ENABLE_USERCLIP) ? "userclip, " : "",
2115 (flags & ENABLE_TEXGEN0) ? "tex-gen-0, " : "",
2116 (flags & ENABLE_TEXGEN1) ? "tex-gen-1, " : "",
2117 (flags & ENABLE_TEXMAT0) ? "tex-mat-0, " : "",
2118 (flags & ENABLE_TEXMAT1) ? "tex-mat-1, " : "",
2119 (flags & ENABLE_NORMALIZE) ? "normalize, " : "",
2120 (flags & ENABLE_RESCALE) ? "rescale, " : "");
2121 }
2122
2123
2124 /*
2125 * If ctx->NewState is non-zero then this function MUST be called before
2126 * rendering any primitive. Basically, function pointers and miscellaneous
2127 * flags are updated to reflect the current state of the state machine.
2128 */
2129 void gl_update_state( GLcontext *ctx )
2130 {
2131 GLuint i;
2132
2133 if (MESA_VERBOSE & VERBOSE_STATE)
2134 gl_print_state("", ctx->NewState);
2135
2136 if (ctx->NewState & NEW_CLIENT_STATE)
2137 gl_update_client_state( ctx );
2138
2139 if ((ctx->NewState & NEW_TEXTURE_ENABLE) &&
2140 (ctx->Enabled & ENABLE_TEX_ANY) != ctx->Texture.Enabled)
2141 ctx->NewState |= NEW_TEXTURING | NEW_RASTER_OPS;
2142
2143 if (ctx->NewState & NEW_TEXTURE_ENV) {
2144 if (ctx->Texture.Unit[0].EnvMode == ctx->Texture.Unit[0].LastEnvMode &&
2145 ctx->Texture.Unit[1].EnvMode == ctx->Texture.Unit[1].LastEnvMode)
2146 ctx->NewState &= ~NEW_TEXTURE_ENV;
2147 ctx->Texture.Unit[0].LastEnvMode = ctx->Texture.Unit[0].EnvMode;
2148 ctx->Texture.Unit[1].LastEnvMode = ctx->Texture.Unit[1].EnvMode;
2149 }
2150
2151 if (ctx->NewState & NEW_TEXTURE_MATRIX) {
2152 ctx->Enabled &= ~(ENABLE_TEXMAT0|ENABLE_TEXMAT1);
2153
2154 for (i=0; i < MAX_TEXTURE_UNITS; i++) {
2155 if (ctx->TextureMatrix[i].flags & MAT_DIRTY_ALL_OVER)
2156 {
2157 gl_matrix_analyze( &ctx->TextureMatrix[i] );
2158 ctx->TextureMatrix[i].flags &= ~MAT_DIRTY_DEPENDENTS;
2159
2160 if (ctx->Texture.Unit[i].Enabled &&
2161 ctx->TextureMatrix[i].type != MATRIX_IDENTITY)
2162 ctx->Enabled |= ENABLE_TEXMAT0 << i;
2163 }
2164 }
2165 }
2166
2167 if (ctx->NewState & (NEW_TEXTURING | NEW_TEXTURE_ENABLE)) {
2168 ctx->Texture.NeedNormals = GL_FALSE;
2169 gl_update_dirty_texobjs(ctx);
2170 ctx->Enabled &= ~(ENABLE_TEXGEN0|ENABLE_TEXGEN1);
2171 ctx->Texture.ReallyEnabled = 0;
2172
2173 for (i=0; i < MAX_TEXTURE_UNITS; i++) {
2174 if (ctx->Texture.Unit[i].Enabled) {
2175 gl_update_texture_unit( ctx, &ctx->Texture.Unit[i] );
2176
2177 ctx->Texture.ReallyEnabled |=
2178 ctx->Texture.Unit[i].ReallyEnabled<<(i*4);
2179
2180 if (ctx->Texture.Unit[i].GenFlags != 0) {
2181 ctx->Enabled |= ENABLE_TEXGEN0 << i;
2182
2183 if (ctx->Texture.Unit[i].GenFlags & TEXGEN_NEED_NORMALS)
2184 {
2185 ctx->Texture.NeedNormals = GL_TRUE;
2186 ctx->Texture.NeedEyeCoords = GL_TRUE;
2187 }
2188
2189 if (ctx->Texture.Unit[i].GenFlags & TEXGEN_NEED_EYE_COORD)
2190 {
2191 ctx->Texture.NeedEyeCoords = GL_TRUE;
2192 }
2193 }
2194 }
2195 }
2196
2197 ctx->Texture.Enabled = ctx->Enabled & ENABLE_TEX_ANY;
2198 ctx->NeedNormals = (ctx->Light.Enabled || ctx->Texture.NeedNormals);
2199 }
2200
2201 if (ctx->NewState & (NEW_RASTER_OPS | NEW_LIGHTING | NEW_FOG)) {
2202
2203
2204 if (ctx->NewState & NEW_RASTER_OPS) {
2205 update_pixel_logic(ctx);
2206 update_pixel_masking(ctx);
2207 update_fog_mode(ctx);
2208 update_rasterflags(ctx);
2209 if (ctx->Driver.Dither) {
2210 (*ctx->Driver.Dither)( ctx, ctx->Color.DitherFlag );
2211 }
2212
2213 /* Check if incoming colors can be modified during rasterization */
2214 if (ctx->Fog.Enabled ||
2215 ctx->Texture.Enabled ||
2216 ctx->Color.BlendEnabled ||
2217 ctx->Color.SWmasking ||
2218 ctx->Color.SWLogicOpEnabled) {
2219 ctx->MutablePixels = GL_TRUE;
2220 }
2221 else {
2222 ctx->MutablePixels = GL_FALSE;
2223 }
2224
2225 /* update scissor region */
2226
2227 ctx->DrawBuffer->Xmin = 0;
2228 ctx->DrawBuffer->Ymin = 0;
2229 ctx->DrawBuffer->Xmax = ctx->DrawBuffer->Width-1;
2230 ctx->DrawBuffer->Ymax = ctx->DrawBuffer->Height-1;
2231 if (ctx->Scissor.Enabled) {
2232 if (ctx->Scissor.X > ctx->DrawBuffer->Xmin) {
2233 ctx->DrawBuffer->Xmin = ctx->Scissor.X;
2234 }
2235 if (ctx->Scissor.Y > ctx->DrawBuffer->Ymin) {
2236 ctx->DrawBuffer->Ymin = ctx->Scissor.Y;
2237 }
2238 if (ctx->Scissor.X + ctx->Scissor.Width - 1 < ctx->DrawBuffer->Xmax) {
2239 ctx->DrawBuffer->Xmax = ctx->Scissor.X + ctx->Scissor.Width - 1;
2240 }
2241 if (ctx->Scissor.Y + ctx->Scissor.Height - 1 < ctx->DrawBuffer->Ymax) {
2242 ctx->DrawBuffer->Ymax = ctx->Scissor.Y + ctx->Scissor.Height - 1;
2243 }
2244 }
2245 }
2246
2247 if (ctx->NewState & NEW_LIGHTING) {
2248 ctx->TriangleCaps &= ~(DD_TRI_LIGHT_TWOSIDE|DD_LIGHTING_CULL);
2249 if (ctx->Light.Enabled) {
2250 if (ctx->Light.Model.TwoSide)
2251 ctx->TriangleCaps |= (DD_TRI_LIGHT_TWOSIDE|DD_LIGHTING_CULL);
2252 gl_update_lighting(ctx);
2253 }
2254 }
2255 }
2256
2257 if (ctx->NewState & (NEW_POLYGON | NEW_LIGHTING)) {
2258
2259 ctx->TriangleCaps &= ~DD_TRI_CULL_FRONT_BACK;
2260
2261 if (ctx->NewState & NEW_POLYGON) {
2262 /* Setup CullBits bitmask */
2263 if (ctx->Polygon.CullFlag) {
2264 ctx->backface_sign = 1;
2265 switch(ctx->Polygon.CullFaceMode) {
2266 case GL_BACK:
2267 if(ctx->Polygon.FrontFace==GL_CCW)
2268 ctx->backface_sign = -1;
2269 ctx->Polygon.CullBits = 1;
2270 break;
2271 case GL_FRONT:
2272 if(ctx->Polygon.FrontFace!=GL_CCW)
2273 ctx->backface_sign = -1;
2274 ctx->Polygon.CullBits = 2;
2275 break;
2276 default:
2277 case GL_FRONT_AND_BACK:
2278 ctx->backface_sign = 0;
2279 ctx->Polygon.CullBits = 0;
2280 ctx->TriangleCaps |= DD_TRI_CULL_FRONT_BACK;
2281 break;
2282 }
2283 }
2284 else {
2285 ctx->Polygon.CullBits = 3;
2286 ctx->backface_sign = 0;
2287 }
2288
2289 /* Any Polygon offsets enabled? */
2290 ctx->TriangleCaps &= ~DD_TRI_OFFSET;
2291
2292 if (ctx->Polygon.OffsetPoint ||
2293 ctx->Polygon.OffsetLine ||
2294 ctx->Polygon.OffsetFill)
2295 ctx->TriangleCaps |= DD_TRI_OFFSET;
2296
2297 /* reset Z offsets now */
2298 ctx->PointZoffset = 0.0;
2299 ctx->LineZoffset = 0.0;
2300 ctx->PolygonZoffset = 0.0;
2301 }
2302 }
2303
2304 if (ctx->NewState & ~(NEW_CLIENT_STATE|
2305 NEW_DRIVER_STATE|NEW_USER_CLIP|
2306 NEW_POLYGON))
2307 gl_update_clipmask(ctx);
2308
2309 if (ctx->NewState & (NEW_LIGHTING|
2310 NEW_RASTER_OPS|
2311 NEW_TEXTURING|
2312 NEW_TEXTURE_ENABLE|
2313 NEW_TEXTURE_ENV|
2314 NEW_POLYGON|
2315 NEW_DRVSTATE0|
2316 NEW_DRVSTATE1|
2317 NEW_DRVSTATE2|
2318 NEW_DRVSTATE3|
2319 NEW_USER_CLIP))
2320 {
2321 ctx->IndirectTriangles = ctx->TriangleCaps & ~ctx->Driver.TriangleCaps;
2322 ctx->IndirectTriangles |= DD_SW_RASTERIZE;
2323
2324 if (MESA_VERBOSE&VERBOSE_CULL)
2325 gl_print_tri_caps("initial indirect tris", ctx->IndirectTriangles);
2326
2327 ctx->Driver.PointsFunc = NULL;
2328 ctx->Driver.LineFunc = NULL;
2329 ctx->Driver.TriangleFunc = NULL;
2330 ctx->Driver.QuadFunc = NULL;
2331 ctx->Driver.RectFunc = NULL;
2332 ctx->Driver.RenderVBClippedTab = NULL;
2333 ctx->Driver.RenderVBCulledTab = NULL;
2334 ctx->Driver.RenderVBRawTab = NULL;
2335
2336 /*
2337 * Here the driver sets up all the ctx->Driver function pointers to
2338 * it's specific, private functions.
2339 */
2340 ctx->Driver.UpdateState(ctx);
2341
2342 if (MESA_VERBOSE&VERBOSE_CULL)
2343 gl_print_tri_caps("indirect tris", ctx->IndirectTriangles);
2344
2345 /*
2346 * In case the driver didn't hook in an optimized point, line or
2347 * triangle function we'll now select "core/fallback" point, line
2348 * and triangle functions.
2349 */
2350 if (ctx->IndirectTriangles & DD_SW_RASTERIZE) {
2351 gl_set_point_function(ctx);
2352 gl_set_line_function(ctx);
2353 gl_set_triangle_function(ctx);
2354 gl_set_quad_function(ctx);
2355
2356 if ((ctx->IndirectTriangles &
2357 (DD_TRI_SW_RASTERIZE|DD_QUAD_SW_RASTERIZE|DD_TRI_CULL)) ==
2358 (DD_TRI_SW_RASTERIZE|DD_QUAD_SW_RASTERIZE|DD_TRI_CULL))
2359 ctx->IndirectTriangles &= ~DD_TRI_CULL;
2360 }
2361
2362 if (MESA_VERBOSE&VERBOSE_CULL)
2363 gl_print_tri_caps("indirect tris 2", ctx->IndirectTriangles);
2364
2365 gl_set_render_vb_function(ctx);
2366 }
2367
2368 /* Should only be calc'd when !need_eye_coords and not culling.
2369 */
2370 if (ctx->NewState & (NEW_MODELVIEW|NEW_PROJECTION)) {
2371 if (ctx->NewState & NEW_MODELVIEW) {
2372 gl_matrix_analyze( &ctx->ModelView );
2373 ctx->ProjectionMatrix.flags &= ~MAT_DIRTY_DEPENDENTS;
2374 }
2375
2376 if (ctx->NewState & NEW_PROJECTION) {
2377 gl_matrix_analyze( &ctx->ProjectionMatrix );
2378 ctx->ProjectionMatrix.flags &= ~MAT_DIRTY_DEPENDENTS;
2379
2380 if (ctx->Transform.AnyClip) {
2381 gl_update_userclip( ctx );
2382 }
2383 }
2384
2385 gl_calculate_model_project_matrix( ctx );
2386 ctx->ModelProjectWinMatrixUptodate = 0;
2387 }
2388
2389 /* Figure out whether we can light in object space or not. If we
2390 * can, find the current positions of the lights in object space
2391 */
2392 if ((ctx->Enabled & (ENABLE_POINT_ATTEN | ENABLE_LIGHT | ENABLE_FOG |
2393 ENABLE_TEXGEN0 | ENABLE_TEXGEN1)) &&
2394 (ctx->NewState & (NEW_LIGHTING |
2395 NEW_FOG |
2396 NEW_MODELVIEW |
2397 NEW_PROJECTION |
2398 NEW_TEXTURING |
2399 NEW_RASTER_OPS |
2400 NEW_USER_CLIP)))
2401 {
2402 GLboolean oldcoord, oldnorm;
2403
2404 oldcoord = ctx->NeedEyeCoords;
2405 oldnorm = ctx->NeedEyeNormals;
2406
2407 ctx->NeedNormals = (ctx->Light.Enabled || ctx->Texture.NeedNormals);
2408 ctx->NeedEyeCoords = ((ctx->Fog.Enabled && ctx->Hint.Fog != GL_NICEST) ||
2409 ctx->Point.Attenuated);
2410 ctx->NeedEyeNormals = GL_FALSE;
2411
2412 if (ctx->Light.Enabled) {
2413 if (ctx->Light.Flags & LIGHT_POSITIONAL) {
2414 /* Need length for attenuation */
2415 if (!TEST_MAT_FLAGS( &ctx->ModelView, MAT_FLAGS_LENGTH_PRESERVING))
2416 ctx->NeedEyeCoords = GL_TRUE;
2417 } else if (ctx->Light.NeedVertices) {
2418 /* Need angle for spot calculations */
2419 if (!TEST_MAT_FLAGS( &ctx->ModelView, MAT_FLAGS_ANGLE_PRESERVING))
2420 ctx->NeedEyeCoords = GL_TRUE;
2421 }
2422 ctx->NeedEyeNormals = ctx->NeedEyeCoords;
2423 }
2424 if (ctx->Texture.Enabled || ctx->RenderMode==GL_FEEDBACK) {
2425 if (ctx->Texture.NeedEyeCoords) ctx->NeedEyeCoords = GL_TRUE;
2426 if (ctx->Texture.NeedNormals)
2427 ctx->NeedNormals = ctx->NeedEyeNormals = GL_TRUE;
2428 }
2429
2430 ctx->vb_proj_matrix = &ctx->ModelProjectMatrix;
2431
2432 if (ctx->NeedEyeCoords)
2433 ctx->vb_proj_matrix = &ctx->ProjectionMatrix;
2434
2435 if (ctx->Light.Enabled) {
2436 gl_update_lighting_function(ctx);
2437
2438 if ( (ctx->NewState & NEW_LIGHTING) ||
2439 ((ctx->NewState & (NEW_MODELVIEW| NEW_PROJECTION)) &&
2440 !ctx->NeedEyeCoords) ||
2441 oldcoord != ctx->NeedEyeCoords ||
2442 oldnorm != ctx->NeedEyeNormals) {
2443 gl_compute_light_positions(ctx);
2444 }
2445
2446 ctx->rescale_factor = 1.0F;
2447
2448 if (ctx->ModelView.flags & (MAT_FLAG_UNIFORM_SCALE |
2449 MAT_FLAG_GENERAL_SCALE |
2450 MAT_FLAG_GENERAL_3D |
2451 MAT_FLAG_GENERAL) )
2452
2453 {
2454 GLfloat *m = ctx->ModelView.inv;
2455 GLfloat f = m[2]*m[2] + m[6]*m[6] + m[10]*m[10];
2456 if (f > 1e-12 && (f-1)*(f-1) > 1e-12)
2457 ctx->rescale_factor = 1.0/GL_SQRT(f);
2458 }
2459 }
2460
2461 gl_update_normal_transform( ctx );
2462 }
2463
2464 gl_update_pipelines(ctx);
2465 ctx->NewState = 0;
2466 }