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