blob: ee95173d0780a381bb3334e00ba2c624b681d442 [file] [log] [blame]
Brian Paul45224fa1999-09-07 22:31:30 +00001/* $Id: context.c,v 1.6 1999/09/07 22:31:30 brianp 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
jtgafb833d1999-08-19 00:55:39 +00001007 /* Renderer and client attribute stacks */
1008 ctx->AttribStackDepth = 0;
1009 ctx->ClientAttribStackDepth = 0;
1010
1011 /*** Miscellaneous ***/
1012 ctx->NewState = NEW_ALL;
1013 ctx->RenderMode = GL_RENDER;
1014 ctx->StippleCounter = 0;
1015 ctx->NeedNormals = GL_FALSE;
1016 ctx->DoViewportMapping = GL_TRUE;
1017
1018 ctx->NeedEyeCoords = GL_FALSE;
1019 ctx->NeedEyeNormals = GL_FALSE;
1020 ctx->vb_proj_matrix = &ctx->ModelProjectMatrix;
1021
1022 /* Display list */
1023 ctx->CallDepth = 0;
1024 ctx->ExecuteFlag = GL_TRUE;
1025 ctx->CompileFlag = GL_FALSE;
1026 ctx->CurrentListPtr = NULL;
1027 ctx->CurrentBlock = NULL;
1028 ctx->CurrentListNum = 0;
1029 ctx->CurrentPos = 0;
1030
1031 ctx->ErrorValue = (GLenum) GL_NO_ERROR;
1032
1033 ctx->CatchSignals = GL_TRUE;
1034
1035 /* For debug/development only */
1036 ctx->NoRaster = getenv("MESA_NO_RASTER") ? GL_TRUE : GL_FALSE;
1037
1038 /* Dither disable */
1039 ctx->NoDither = getenv("MESA_NO_DITHER") ? GL_TRUE : GL_FALSE;
1040 if (ctx->NoDither) {
1041 if (getenv("MESA_DEBUG")) {
1042 fprintf(stderr, "MESA_NO_DITHER set - dithering disabled\n");
1043 }
1044 ctx->Color.DitherFlag = GL_FALSE;
1045 }
1046 }
1047}
1048
1049
1050
1051/*
1052 * Allocate a new GLvisual object.
1053 * Input: rgbFlag - GL_TRUE=RGB(A) mode, GL_FALSE=Color Index mode
1054 * alphaFlag - alloc software alpha buffers?
1055 * dbFlag - double buffering?
1056 * stereoFlag - stereo buffer?
1057 * depthFits - requested minimum bits per depth buffer value
1058 * stencilFits - requested minimum bits per stencil buffer value
1059 * accumFits - requested minimum bits per accum buffer component
1060 * indexFits - number of bits per pixel if rgbFlag==GL_FALSE
1061 * red/green/blue/alphaFits - number of bits per color component
1062 * in frame buffer for RGB(A) mode.
1063 * Return: pointer to new GLvisual or NULL if requested parameters can't
1064 * be met.
1065 */
1066GLvisual *gl_create_visual( GLboolean rgbFlag,
1067 GLboolean alphaFlag,
1068 GLboolean dbFlag,
1069 GLboolean stereoFlag,
1070 GLint depthBits,
1071 GLint stencilBits,
1072 GLint accumBits,
1073 GLint indexBits,
1074 GLint redBits,
1075 GLint greenBits,
1076 GLint blueBits,
1077 GLint alphaBits )
1078{
1079 GLvisual *vis;
1080
1081 if (depthBits > (GLint) (8*sizeof(GLdepth))) {
1082 /* can't meet depth buffer requirements */
1083 return NULL;
1084 }
1085 if (stencilBits > (GLint) (8*sizeof(GLstencil))) {
1086 /* can't meet stencil buffer requirements */
1087 return NULL;
1088 }
1089 if (accumBits > (GLint) (8*sizeof(GLaccum))) {
1090 /* can't meet accum buffer requirements */
1091 return NULL;
1092 }
1093
1094 vis = (GLvisual *) calloc( 1, sizeof(GLvisual) );
1095 if (!vis) {
1096 return NULL;
1097 }
1098
1099 vis->RGBAflag = rgbFlag;
1100 vis->DBflag = dbFlag;
1101 vis->StereoFlag = stereoFlag;
1102 vis->RedBits = redBits;
1103 vis->GreenBits = greenBits;
1104 vis->BlueBits = blueBits;
1105 vis->AlphaBits = alphaFlag ? 8*sizeof(GLubyte) : alphaBits;
1106
1107 vis->IndexBits = indexBits;
1108 vis->DepthBits = (depthBits>0) ? 8*sizeof(GLdepth) : 0;
1109 vis->AccumBits = (accumBits>0) ? 8*sizeof(GLaccum) : 0;
1110 vis->StencilBits = (stencilBits>0) ? 8*sizeof(GLstencil) : 0;
1111
1112 vis->SoftwareAlpha = alphaFlag;
1113
1114 return vis;
1115}
1116
1117
1118
1119void gl_destroy_visual( GLvisual *vis )
1120{
1121 free( vis );
1122}
1123
1124
1125
1126/*
1127 * Allocate the proxy textures. If we run out of memory part way through
1128 * the allocations clean up and return GL_FALSE.
1129 * Return: GL_TRUE=success, GL_FALSE=failure
1130 */
1131static GLboolean alloc_proxy_textures( GLcontext *ctx )
1132{
1133 GLboolean out_of_memory;
1134 GLint i;
1135
1136 ctx->Texture.Proxy1D = gl_alloc_texture_object(NULL, 0, 1);
1137 if (!ctx->Texture.Proxy1D) {
1138 return GL_FALSE;
1139 }
1140
1141 ctx->Texture.Proxy2D = gl_alloc_texture_object(NULL, 0, 2);
1142 if (!ctx->Texture.Proxy2D) {
1143 gl_free_texture_object(NULL, ctx->Texture.Proxy1D);
1144 return GL_FALSE;
1145 }
1146
1147 ctx->Texture.Proxy3D = gl_alloc_texture_object(NULL, 0, 3);
1148 if (!ctx->Texture.Proxy3D) {
1149 gl_free_texture_object(NULL, ctx->Texture.Proxy1D);
1150 gl_free_texture_object(NULL, ctx->Texture.Proxy2D);
1151 return GL_FALSE;
1152 }
1153
1154 out_of_memory = GL_FALSE;
1155 for (i=0;i<MAX_TEXTURE_LEVELS;i++) {
1156 ctx->Texture.Proxy1D->Image[i] = gl_alloc_texture_image();
1157 ctx->Texture.Proxy2D->Image[i] = gl_alloc_texture_image();
1158 ctx->Texture.Proxy3D->Image[i] = gl_alloc_texture_image();
1159 if (!ctx->Texture.Proxy1D->Image[i]
1160 || !ctx->Texture.Proxy2D->Image[i]
1161 || !ctx->Texture.Proxy3D->Image[i]) {
1162 out_of_memory = GL_TRUE;
1163 }
1164 }
1165 if (out_of_memory) {
1166 for (i=0;i<MAX_TEXTURE_LEVELS;i++) {
1167 if (ctx->Texture.Proxy1D->Image[i]) {
1168 gl_free_texture_image(ctx->Texture.Proxy1D->Image[i]);
1169 }
1170 if (ctx->Texture.Proxy2D->Image[i]) {
1171 gl_free_texture_image(ctx->Texture.Proxy2D->Image[i]);
1172 }
1173 if (ctx->Texture.Proxy3D->Image[i]) {
1174 gl_free_texture_image(ctx->Texture.Proxy3D->Image[i]);
1175 }
1176 }
1177 gl_free_texture_object(NULL, ctx->Texture.Proxy1D);
1178 gl_free_texture_object(NULL, ctx->Texture.Proxy2D);
1179 gl_free_texture_object(NULL, ctx->Texture.Proxy3D);
1180 return GL_FALSE;
1181 }
1182 else {
1183 return GL_TRUE;
1184 }
1185}
1186
1187
1188
1189#define MALLOC_STRUCT(T) (struct T *) malloc( sizeof(struct T) )
1190
1191/*
1192 * Allocate and initialize a GLcontext structure.
1193 * Input: visual - a GLvisual pointer
1194 * sharelist - another context to share display lists with or NULL
1195 * driver_ctx - pointer to device driver's context state struct
1196 * Return: pointer to a new gl_context struct or NULL if error.
1197 */
1198GLcontext *gl_create_context( GLvisual *visual,
1199 GLcontext *share_list,
1200 void *driver_ctx,
1201 GLboolean direct )
1202{
1203 GLcontext *ctx;
1204 GLuint i;
1205
1206 (void) direct; /* not used */
1207
1208 /* do some implementation tests */
1209 assert( sizeof(GLbyte) == 1 );
1210 assert( sizeof(GLshort) >= 2 );
1211 assert( sizeof(GLint) >= 4 );
1212 assert( sizeof(GLubyte) == 1 );
1213 assert( sizeof(GLushort) >= 2 );
1214 assert( sizeof(GLuint) >= 4 );
1215
1216 /* misc one-time initializations */
1217 one_time_init();
1218
1219 ctx = (GLcontext *) calloc( 1, sizeof(GLcontext) );
1220 if (!ctx) {
1221 return NULL;
1222 }
1223
1224 ctx->DriverCtx = driver_ctx;
1225 ctx->Visual = visual;
1226 ctx->Buffer = NULL;
1227
1228 ctx->VB = gl_vb_create_for_immediate( ctx );
1229 if (!ctx->VB) {
1230 free( ctx );
1231 return NULL;
1232 }
1233 ctx->input = ctx->VB->IM;
1234
1235 ctx->PB = gl_alloc_pb();
1236 if (!ctx->PB) {
1237 free( ctx->VB );
1238 free( ctx );
1239 return NULL;
1240 }
1241
1242 if (share_list) {
1243 /* share the group of display lists of another context */
1244 ctx->Shared = share_list->Shared;
1245 }
1246 else {
1247 /* allocate new group of display lists */
1248 ctx->Shared = alloc_shared_state();
1249 if (!ctx->Shared) {
1250 free(ctx->VB);
1251 free(ctx->PB);
1252 free(ctx);
1253 return NULL;
1254 }
1255 }
1256 ctx->Shared->RefCount++;
1257
1258 initialize_context( ctx );
1259 gl_reset_vb( ctx->VB );
1260 gl_reset_input( ctx );
1261
1262
1263 ctx->ShineTabList = MALLOC_STRUCT( gl_shine_tab );
1264 make_empty_list( ctx->ShineTabList );
1265
1266 for (i = 0 ; i < 10 ; i++) {
1267 struct gl_shine_tab *s = MALLOC_STRUCT( gl_shine_tab );
1268 s->shininess = -1;
1269 s->refcount = 0;
1270 insert_at_tail( ctx->ShineTabList, s );
1271 }
1272
1273 for (i = 0 ; i < 4 ; i++) {
1274 ctx->ShineTable[i] = ctx->ShineTabList->prev;
1275 ctx->ShineTable[i]->refcount++;
1276 }
1277
1278 if (visual->DBflag) {
1279 ctx->Color.DrawBuffer = GL_BACK;
1280 ctx->Color.DriverDrawBuffer = GL_BACK_LEFT;
1281 ctx->Color.DrawDestMask = BACK_LEFT_BIT;
1282 ctx->Pixel.ReadBuffer = GL_BACK;
1283 ctx->Pixel.DriverReadBuffer = GL_BACK_LEFT;
1284 }
1285 else {
1286 ctx->Color.DrawBuffer = GL_FRONT;
1287 ctx->Color.DriverDrawBuffer = GL_FRONT_LEFT;
1288 ctx->Color.DrawDestMask = FRONT_LEFT_BIT;
1289 ctx->Pixel.ReadBuffer = GL_FRONT;
1290 ctx->Pixel.DriverReadBuffer = GL_FRONT_LEFT;
1291 }
1292
Keith Whitwell324beb91999-09-04 14:40:49 +00001293
1294 /* Fill in some driver defaults now.
1295 */
1296 ctx->Driver.AllocDepthBuffer = gl_alloc_depth_buffer;
1297 ctx->Driver.ReadDepthSpanFloat = gl_read_depth_span_float;
1298 ctx->Driver.ReadDepthSpanInt = gl_read_depth_span_int;
1299
1300
1301
jtgafb833d1999-08-19 00:55:39 +00001302#ifdef PROFILE
1303 init_timings( ctx );
1304#endif
1305
1306#ifdef GL_VERSION_1_1
1307 if (!alloc_proxy_textures(ctx)) {
1308 free_shared_state(ctx, ctx->Shared);
1309 free(ctx->VB);
1310 free(ctx->PB);
1311 free(ctx);
1312 return NULL;
1313 }
1314#endif
1315
1316 gl_init_api_function_pointers( ctx );
1317 ctx->API = ctx->Exec; /* GL_EXECUTE is default */
1318
1319 return ctx;
1320}
1321
1322/* Just reads the config files...
1323 */
1324void gl_context_initialize( GLcontext *ctx )
1325{
1326 gl_read_config_file( ctx );
1327}
1328
1329
1330
1331
1332/*
1333 * Destroy a gl_context structure.
1334 */
1335void gl_destroy_context( GLcontext *ctx )
1336{
1337 if (ctx) {
1338
1339 GLuint i;
1340 struct gl_shine_tab *s, *tmps;
1341
1342#ifdef PROFILE
1343 if (getenv("MESA_PROFILE")) {
1344 print_timings( ctx );
1345 }
1346#endif
1347
1348 gl_matrix_dtr( &ctx->ModelView );
1349 for (i = 0 ; i < MAX_MODELVIEW_STACK_DEPTH ; i++) {
1350 gl_matrix_dtr( &ctx->ModelViewStack[i] );
1351 }
1352
1353
1354 free( ctx->PB );
1355 free( ctx->VB );
1356
1357 ctx->Shared->RefCount--;
1358 assert(ctx->Shared->RefCount>=0);
1359 if (ctx->Shared->RefCount==0) {
1360 /* free shared state */
1361 free_shared_state( ctx, ctx->Shared );
1362 }
1363
1364 foreach_s( s, tmps, ctx->ShineTabList ) {
1365 free( s );
1366 }
1367 free( ctx->ShineTabList );
1368
1369 /* Free proxy texture objects */
1370 gl_free_texture_object( NULL, ctx->Texture.Proxy1D );
1371 gl_free_texture_object( NULL, ctx->Texture.Proxy2D );
1372 gl_free_texture_object( NULL, ctx->Texture.Proxy3D );
1373
1374 /* Free evaluator data */
1375 if (ctx->EvalMap.Map1Vertex3.Points)
1376 free( ctx->EvalMap.Map1Vertex3.Points );
1377 if (ctx->EvalMap.Map1Vertex4.Points)
1378 free( ctx->EvalMap.Map1Vertex4.Points );
1379 if (ctx->EvalMap.Map1Index.Points)
1380 free( ctx->EvalMap.Map1Index.Points );
1381 if (ctx->EvalMap.Map1Color4.Points)
1382 free( ctx->EvalMap.Map1Color4.Points );
1383 if (ctx->EvalMap.Map1Normal.Points)
1384 free( ctx->EvalMap.Map1Normal.Points );
1385 if (ctx->EvalMap.Map1Texture1.Points)
1386 free( ctx->EvalMap.Map1Texture1.Points );
1387 if (ctx->EvalMap.Map1Texture2.Points)
1388 free( ctx->EvalMap.Map1Texture2.Points );
1389 if (ctx->EvalMap.Map1Texture3.Points)
1390 free( ctx->EvalMap.Map1Texture3.Points );
1391 if (ctx->EvalMap.Map1Texture4.Points)
1392 free( ctx->EvalMap.Map1Texture4.Points );
1393
1394 if (ctx->EvalMap.Map2Vertex3.Points)
1395 free( ctx->EvalMap.Map2Vertex3.Points );
1396 if (ctx->EvalMap.Map2Vertex4.Points)
1397 free( ctx->EvalMap.Map2Vertex4.Points );
1398 if (ctx->EvalMap.Map2Index.Points)
1399 free( ctx->EvalMap.Map2Index.Points );
1400 if (ctx->EvalMap.Map2Color4.Points)
1401 free( ctx->EvalMap.Map2Color4.Points );
1402 if (ctx->EvalMap.Map2Normal.Points)
1403 free( ctx->EvalMap.Map2Normal.Points );
1404 if (ctx->EvalMap.Map2Texture1.Points)
1405 free( ctx->EvalMap.Map2Texture1.Points );
1406 if (ctx->EvalMap.Map2Texture2.Points)
1407 free( ctx->EvalMap.Map2Texture2.Points );
1408 if (ctx->EvalMap.Map2Texture3.Points)
1409 free( ctx->EvalMap.Map2Texture3.Points );
1410 if (ctx->EvalMap.Map2Texture4.Points)
1411 free( ctx->EvalMap.Map2Texture4.Points );
1412
1413 free( (void *) ctx );
1414
1415#ifndef THREADS
1416 if (ctx==CC) {
1417 CC = NULL;
1418 CURRENT_INPUT = NULL;
1419 }
1420#endif
1421
1422 }
1423}
1424
1425
1426
1427/*
1428 * Create a new framebuffer. A GLframebuffer is a struct which
1429 * encapsulates the depth, stencil and accum buffers and related
1430 * parameters.
1431 * Input: visual - a GLvisual pointer
1432 * Return: pointer to new GLframebuffer struct or NULL if error.
1433 */
1434GLframebuffer *gl_create_framebuffer( GLvisual *visual )
1435{
1436 GLframebuffer *buffer;
1437
1438 buffer = (GLframebuffer *) calloc( 1, sizeof(GLframebuffer) );
1439 if (!buffer) {
1440 return NULL;
1441 }
1442
1443 buffer->Visual = visual;
1444
1445 return buffer;
1446}
1447
1448
1449
1450/*
1451 * Free a framebuffer struct and its buffers.
1452 */
1453void gl_destroy_framebuffer( GLframebuffer *buffer )
1454{
1455 if (buffer) {
1456 if (buffer->Depth) {
1457 free( buffer->Depth );
1458 }
1459 if (buffer->Accum) {
1460 free( buffer->Accum );
1461 }
1462 if (buffer->Stencil) {
1463 free( buffer->Stencil );
1464 }
1465 if (buffer->FrontLeftAlpha) {
1466 free( buffer->FrontLeftAlpha );
1467 }
1468 if (buffer->BackLeftAlpha) {
1469 free( buffer->BackLeftAlpha );
1470 }
1471 if (buffer->FrontRightAlpha) {
1472 free( buffer->FrontRightAlpha );
1473 }
1474 if (buffer->BackRightAlpha) {
1475 free( buffer->BackRightAlpha );
1476 }
1477 free(buffer);
1478 }
1479}
1480
1481
1482
1483/*
1484 * Set the current context, binding the given frame buffer to the context.
1485 */
1486void gl_make_current( GLcontext *ctx, GLframebuffer *buffer )
1487{
1488 GET_CONTEXT;
1489
1490 /* Flush the old context
1491 */
1492 if (CC) {
1493 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(CC, "gl_make_current");
1494 }
1495
1496#ifdef THREADS
1497 /* TODO: unbind old buffer from context? */
1498 set_thread_context( ctx );
1499#else
1500 if (CC && CC->Buffer) {
1501 /* unbind frame buffer from context */
1502 CC->Buffer = NULL;
1503 }
1504 CC = ctx;
1505 if (ctx) {
1506 SET_IMMEDIATE(ctx, ctx->input);
1507 }
1508#endif
1509
1510 if (MESA_VERBOSE) fprintf(stderr, "gl_make_current()\n");
1511
1512 if (ctx && buffer) {
1513 /* TODO: check if ctx and buffer's visual match??? */
1514 ctx->Buffer = buffer; /* Bind the frame buffer to the context */
1515 ctx->NewState = NEW_ALL; /* just to be safe */
1516 gl_update_state( ctx );
1517 }
1518}
1519
1520
1521/*
1522 * Return current context handle.
1523 */
1524GLcontext *gl_get_current_context( void )
1525{
1526#ifdef THREADS
1527 return gl_get_thread_context();
1528#else
1529 return CC;
1530#endif
1531}
1532
1533
1534
1535/*
1536 * Copy attribute groups from one context to another.
1537 * Input: src - source context
1538 * dst - destination context
1539 * mask - bitwise OR of GL_*_BIT flags
1540 */
1541void gl_copy_context( const GLcontext *src, GLcontext *dst, GLuint mask )
1542{
1543 if (mask & GL_ACCUM_BUFFER_BIT) {
1544 MEMCPY( &dst->Accum, &src->Accum, sizeof(struct gl_accum_attrib) );
1545 }
1546 if (mask & GL_COLOR_BUFFER_BIT) {
1547 MEMCPY( &dst->Color, &src->Color, sizeof(struct gl_colorbuffer_attrib) );
1548 }
1549 if (mask & GL_CURRENT_BIT) {
1550 MEMCPY( &dst->Current, &src->Current, sizeof(struct gl_current_attrib) );
1551 }
1552 if (mask & GL_DEPTH_BUFFER_BIT) {
1553 MEMCPY( &dst->Depth, &src->Depth, sizeof(struct gl_depthbuffer_attrib) );
1554 }
1555 if (mask & GL_ENABLE_BIT) {
1556 /* no op */
1557 }
1558 if (mask & GL_EVAL_BIT) {
1559 MEMCPY( &dst->Eval, &src->Eval, sizeof(struct gl_eval_attrib) );
1560 }
1561 if (mask & GL_FOG_BIT) {
1562 MEMCPY( &dst->Fog, &src->Fog, sizeof(struct gl_fog_attrib) );
1563 }
1564 if (mask & GL_HINT_BIT) {
1565 MEMCPY( &dst->Hint, &src->Hint, sizeof(struct gl_hint_attrib) );
1566 }
1567 if (mask & GL_LIGHTING_BIT) {
1568 MEMCPY( &dst->Light, &src->Light, sizeof(struct gl_light_attrib) );
1569/* gl_reinit_light_attrib( &dst->Light ); */
1570 }
1571 if (mask & GL_LINE_BIT) {
1572 MEMCPY( &dst->Line, &src->Line, sizeof(struct gl_line_attrib) );
1573 }
1574 if (mask & GL_LIST_BIT) {
1575 MEMCPY( &dst->List, &src->List, sizeof(struct gl_list_attrib) );
1576 }
1577 if (mask & GL_PIXEL_MODE_BIT) {
1578 MEMCPY( &dst->Pixel, &src->Pixel, sizeof(struct gl_pixel_attrib) );
1579 }
1580 if (mask & GL_POINT_BIT) {
1581 MEMCPY( &dst->Point, &src->Point, sizeof(struct gl_point_attrib) );
1582 }
1583 if (mask & GL_POLYGON_BIT) {
1584 MEMCPY( &dst->Polygon, &src->Polygon, sizeof(struct gl_polygon_attrib) );
1585 }
1586 if (mask & GL_POLYGON_STIPPLE_BIT) {
1587 /* Use loop instead of MEMCPY due to problem with Portland Group's
1588 * C compiler. Reported by John Stone.
1589 */
1590 int i;
1591 for (i=0;i<32;i++) {
1592 dst->PolygonStipple[i] = src->PolygonStipple[i];
1593 }
1594 }
1595 if (mask & GL_SCISSOR_BIT) {
1596 MEMCPY( &dst->Scissor, &src->Scissor, sizeof(struct gl_scissor_attrib) );
1597 }
1598 if (mask & GL_STENCIL_BUFFER_BIT) {
1599 MEMCPY( &dst->Stencil, &src->Stencil, sizeof(struct gl_stencil_attrib) );
1600 }
1601 if (mask & GL_TEXTURE_BIT) {
1602 MEMCPY( &dst->Texture, &src->Texture, sizeof(struct gl_texture_attrib) );
1603 }
1604 if (mask & GL_TRANSFORM_BIT) {
1605 MEMCPY( &dst->Transform, &src->Transform, sizeof(struct gl_transform_attrib) );
1606 }
1607 if (mask & GL_VIEWPORT_BIT) {
1608 MEMCPY( &dst->Viewport, &src->Viewport, sizeof(struct gl_viewport_attrib) );
1609 }
1610}
1611
1612
1613
1614/*
1615 * Someday a GLS library or OpenGL-like debugger may call this function
1616 * to register it's own set of API entry points.
1617 * Input: ctx - the context to set API pointers for
1618 * api - if NULL, restore original API pointers
1619 * else, set API function table to this table.
1620 */
1621void gl_set_api_table( GLcontext *ctx, const struct gl_api_table *api )
1622{
1623 if (api) {
1624 MEMCPY( &ctx->API, api, sizeof(struct gl_api_table) );
1625 }
1626 else {
1627 MEMCPY( &ctx->API, &ctx->Exec, sizeof(struct gl_api_table) );
1628 }
1629}
1630
1631
1632
1633
1634/**********************************************************************/
1635/***** Miscellaneous functions *****/
1636/**********************************************************************/
1637
1638
1639/*
1640 * This function is called when the Mesa user has stumbled into a code
1641 * path which may not be implemented fully or correctly.
1642 */
1643void gl_problem( const GLcontext *ctx, const char *s )
1644{
1645 fprintf( stderr, "Mesa implementation error: %s\n", s );
1646 fprintf( stderr, "Report to mesa-bugs@mesa3d.org\n" );
1647 (void) ctx;
1648}
1649
1650
1651
1652/*
1653 * This is called to inform the user that he or she has tried to do
1654 * something illogical or if there's likely a bug in their program
1655 * (like enabled depth testing without a depth buffer).
1656 */
1657void gl_warning( const GLcontext *ctx, const char *s )
1658{
1659 GLboolean debug;
1660#ifdef DEBUG
1661 debug = GL_TRUE;
1662#else
1663 if (getenv("MESA_DEBUG")) {
1664 debug = GL_TRUE;
1665 }
1666 else {
1667 debug = GL_FALSE;
1668 }
1669#endif
1670 if (debug) {
1671 fprintf( stderr, "Mesa warning: %s\n", s );
1672 }
1673 (void) ctx;
1674}
1675
1676
1677
1678void gl_compile_error( GLcontext *ctx, GLenum error, const char *s )
1679{
1680 if (ctx->CompileFlag)
1681 gl_save_error( ctx, error, s );
1682
1683 if (ctx->ExecuteFlag)
1684 gl_error( ctx, error, s );
1685}
1686
1687
1688/*
1689 * This is Mesa's error handler. Normally, all that's done is the updating
1690 * of the current error value. If Mesa is compiled with -DDEBUG or if the
1691 * environment variable "MESA_DEBUG" is defined then a real error message
1692 * is printed to stderr.
1693 * Input: error - the error value
1694 * s - a diagnostic string
1695 */
1696void gl_error( GLcontext *ctx, GLenum error, const char *s )
1697{
1698 GLboolean debug;
1699
1700#ifdef DEBUG
1701 debug = GL_TRUE;
1702#else
1703 if (getenv("MESA_DEBUG")) {
1704 debug = GL_TRUE;
1705 }
1706 else {
1707 debug = GL_FALSE;
1708 }
1709#endif
1710
1711 if (debug) {
1712 char errstr[1000];
1713
1714 switch (error) {
1715 case GL_NO_ERROR:
1716 strcpy( errstr, "GL_NO_ERROR" );
1717 break;
1718 case GL_INVALID_VALUE:
1719 strcpy( errstr, "GL_INVALID_VALUE" );
1720 break;
1721 case GL_INVALID_ENUM:
1722 strcpy( errstr, "GL_INVALID_ENUM" );
1723 break;
1724 case GL_INVALID_OPERATION:
1725 strcpy( errstr, "GL_INVALID_OPERATION" );
1726 break;
1727 case GL_STACK_OVERFLOW:
1728 strcpy( errstr, "GL_STACK_OVERFLOW" );
1729 break;
1730 case GL_STACK_UNDERFLOW:
1731 strcpy( errstr, "GL_STACK_UNDERFLOW" );
1732 break;
1733 case GL_OUT_OF_MEMORY:
1734 strcpy( errstr, "GL_OUT_OF_MEMORY" );
1735 break;
1736 default:
1737 strcpy( errstr, "unknown" );
1738 break;
1739 }
1740 fprintf( stderr, "Mesa user error: %s in %s\n", errstr, s );
1741 }
1742
1743 if (ctx->ErrorValue==GL_NO_ERROR) {
1744 ctx->ErrorValue = error;
1745 }
1746
1747 /* Call device driver's error handler, if any. This is used on the Mac. */
1748 if (ctx->Driver.Error) {
1749 (*ctx->Driver.Error)( ctx );
1750 }
1751}
1752
1753
1754
1755/*
1756 * Execute a glGetError command
1757 */
1758GLenum gl_GetError( GLcontext *ctx )
1759{
1760 GLenum e = ctx->ErrorValue;
1761
1762 ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL( ctx, "glGetError", 0);
1763
1764 if (MESA_VERBOSE & VERBOSE_API)
1765 fprintf(stderr, "glGetError <-- %s\n", gl_lookup_enum_by_nr(e));
1766
1767 ctx->ErrorValue = (GLenum) GL_NO_ERROR;
1768 return e;
1769}
1770
1771
1772
1773void gl_ResizeBuffersMESA( GLcontext *ctx )
1774{
1775 GLuint buf_width, buf_height;
1776
1777 if (MESA_VERBOSE & VERBOSE_API)
1778 fprintf(stderr, "glResizeBuffersMESA\n");
1779
1780 /* ask device driver for size of output buffer */
1781 (*ctx->Driver.GetBufferSize)( ctx, &buf_width, &buf_height );
1782
1783 /* see if size of device driver's color buffer (window) has changed */
1784 if (ctx->Buffer->Width == (GLint) buf_width &&
1785 ctx->Buffer->Height == (GLint) buf_height)
1786 return;
1787
1788 ctx->NewState |= NEW_RASTER_OPS; /* to update scissor / window bounds */
1789
1790 /* save buffer size */
1791 ctx->Buffer->Width = buf_width;
1792 ctx->Buffer->Height = buf_height;
1793
1794 /* Reallocate other buffers if needed. */
1795 if (ctx->Visual->DepthBits>0) {
1796 /* reallocate depth buffer */
1797 (*ctx->Driver.AllocDepthBuffer)( ctx );
1798 }
1799 if (ctx->Visual->StencilBits>0) {
1800 /* reallocate stencil buffer */
1801 gl_alloc_stencil_buffer( ctx );
1802 }
1803 if (ctx->Visual->AccumBits>0) {
1804 /* reallocate accum buffer */
1805 gl_alloc_accum_buffer( ctx );
1806 }
1807 if (ctx->Visual->SoftwareAlpha) {
1808 gl_alloc_alpha_buffers( ctx );
1809 }
1810}
1811
1812
1813
1814
1815/**********************************************************************/
1816/***** State update logic *****/
1817/**********************************************************************/
1818
1819
1820/*
1821 * Since the device driver may or may not support pixel logic ops we
1822 * have to make some extensive tests to determine whether or not
1823 * software-implemented logic operations have to be used.
1824 */
1825static void update_pixel_logic( GLcontext *ctx )
1826{
1827 if (ctx->Visual->RGBAflag) {
1828 /* RGBA mode blending w/ Logic Op */
1829 if (ctx->Color.ColorLogicOpEnabled) {
1830 if (ctx->Driver.LogicOp
1831 && (*ctx->Driver.LogicOp)( ctx, ctx->Color.LogicOp )) {
1832 /* Device driver can do logic, don't have to do it in software */
1833 ctx->Color.SWLogicOpEnabled = GL_FALSE;
1834 }
1835 else {
1836 /* Device driver can't do logic op so we do it in software */
1837 ctx->Color.SWLogicOpEnabled = GL_TRUE;
1838 }
1839 }
1840 else {
1841 /* no logic op */
1842 if (ctx->Driver.LogicOp) {
1843 (void) (*ctx->Driver.LogicOp)( ctx, GL_COPY );
1844 }
1845 ctx->Color.SWLogicOpEnabled = GL_FALSE;
1846 }
1847 }
1848 else {
1849 /* CI mode Logic Op */
1850 if (ctx->Color.IndexLogicOpEnabled) {
1851 if (ctx->Driver.LogicOp
1852 && (*ctx->Driver.LogicOp)( ctx, ctx->Color.LogicOp )) {
1853 /* Device driver can do logic, don't have to do it in software */
1854 ctx->Color.SWLogicOpEnabled = GL_FALSE;
1855 }
1856 else {
1857 /* Device driver can't do logic op so we do it in software */
1858 ctx->Color.SWLogicOpEnabled = GL_TRUE;
1859 }
1860 }
1861 else {
1862 /* no logic op */
1863 if (ctx->Driver.LogicOp) {
1864 (void) (*ctx->Driver.LogicOp)( ctx, GL_COPY );
1865 }
1866 ctx->Color.SWLogicOpEnabled = GL_FALSE;
1867 }
1868 }
1869}
1870
1871
1872
1873/*
1874 * Check if software implemented RGBA or Color Index masking is needed.
1875 */
1876static void update_pixel_masking( GLcontext *ctx )
1877{
1878 if (ctx->Visual->RGBAflag) {
1879 GLuint *colorMask = (GLuint *) ctx->Color.ColorMask;
1880 if (*colorMask == 0xffffffff) {
1881 /* disable masking */
1882 if (ctx->Driver.ColorMask) {
1883 (void) (*ctx->Driver.ColorMask)( ctx, GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE );
1884 }
1885 ctx->Color.SWmasking = GL_FALSE;
1886 }
1887 else {
1888 /* Ask driver to do color masking, if it can't then
1889 * do it in software
1890 */
1891 GLboolean red = ctx->Color.ColorMask[RCOMP] ? GL_TRUE : GL_FALSE;
1892 GLboolean green = ctx->Color.ColorMask[GCOMP] ? GL_TRUE : GL_FALSE;
1893 GLboolean blue = ctx->Color.ColorMask[BCOMP] ? GL_TRUE : GL_FALSE;
1894 GLboolean alpha = ctx->Color.ColorMask[ACOMP] ? GL_TRUE : GL_FALSE;
1895 if (ctx->Driver.ColorMask
1896 && (*ctx->Driver.ColorMask)( ctx, red, green, blue, alpha )) {
1897 ctx->Color.SWmasking = GL_FALSE;
1898 }
1899 else {
1900 ctx->Color.SWmasking = GL_TRUE;
1901 }
1902 }
1903 }
1904 else {
1905 if (ctx->Color.IndexMask==0xffffffff) {
1906 /* disable masking */
1907 if (ctx->Driver.IndexMask) {
1908 (void) (*ctx->Driver.IndexMask)( ctx, 0xffffffff );
1909 }
1910 ctx->Color.SWmasking = GL_FALSE;
1911 }
1912 else {
1913 /* Ask driver to do index masking, if it can't then
1914 * do it in software
1915 */
1916 if (ctx->Driver.IndexMask
1917 && (*ctx->Driver.IndexMask)( ctx, ctx->Color.IndexMask )) {
1918 ctx->Color.SWmasking = GL_FALSE;
1919 }
1920 else {
1921 ctx->Color.SWmasking = GL_TRUE;
1922 }
1923 }
1924 }
1925}
1926
1927
1928static void update_fog_mode( GLcontext *ctx )
1929{
Keith Whitwell2be79c11999-08-26 14:50:49 +00001930 int old_mode = ctx->FogMode;
1931
jtgafb833d1999-08-19 00:55:39 +00001932 if (ctx->Fog.Enabled) {
1933 if (ctx->Texture.Enabled)
1934 ctx->FogMode = FOG_FRAGMENT;
1935 else if (ctx->Hint.Fog == GL_NICEST)
1936 ctx->FogMode = FOG_FRAGMENT;
1937 else
1938 ctx->FogMode = FOG_VERTEX;
1939
1940 if (ctx->Driver.GetParameteri)
1941 if ((ctx->Driver.GetParameteri)( ctx, DD_HAVE_HARDWARE_FOG ))
1942 ctx->FogMode = FOG_FRAGMENT;
1943 }
1944 else {
1945 ctx->FogMode = FOG_NONE;
1946 }
Keith Whitwell2be79c11999-08-26 14:50:49 +00001947
1948 if (old_mode != ctx->FogMode)
1949 ctx->NewState |= NEW_FOG;
jtgafb833d1999-08-19 00:55:39 +00001950}
1951
1952
1953/*
1954 * Recompute the value of ctx->RasterMask, etc. according to
1955 * the current context.
1956 */
1957static void update_rasterflags( GLcontext *ctx )
1958{
1959 ctx->RasterMask = 0;
1960
1961 if (ctx->Color.AlphaEnabled) ctx->RasterMask |= ALPHATEST_BIT;
1962 if (ctx->Color.BlendEnabled) ctx->RasterMask |= BLEND_BIT;
1963 if (ctx->Depth.Test) ctx->RasterMask |= DEPTH_BIT;
1964 if (ctx->FogMode==FOG_FRAGMENT) ctx->RasterMask |= FOG_BIT;
1965 if (ctx->Color.SWLogicOpEnabled) ctx->RasterMask |= LOGIC_OP_BIT;
1966 if (ctx->Scissor.Enabled) ctx->RasterMask |= SCISSOR_BIT;
1967 if (ctx->Stencil.Enabled) ctx->RasterMask |= STENCIL_BIT;
1968 if (ctx->Color.SWmasking) ctx->RasterMask |= MASKING_BIT;
1969
1970 if (ctx->Visual->SoftwareAlpha && ctx->Color.ColorMask[ACOMP]
1971 && ctx->Color.DrawBuffer != GL_NONE)
1972 ctx->RasterMask |= ALPHABUF_BIT;
1973
1974 if ( ctx->Viewport.X<0
1975 || ctx->Viewport.X + ctx->Viewport.Width > ctx->Buffer->Width
1976 || ctx->Viewport.Y<0
1977 || ctx->Viewport.Y + ctx->Viewport.Height > ctx->Buffer->Height) {
1978 ctx->RasterMask |= WINCLIP_BIT;
1979 }
1980
1981 /* If we're not drawing to exactly one color buffer set the
1982 * MULTI_DRAW_BIT flag. Also set it if we're drawing to no
1983 * buffers or the RGBA or CI mask disables all writes.
1984 */
1985
1986 ctx->TriangleCaps &= ~DD_MULTIDRAW;
1987
1988 if (ctx->Color.MultiDrawBuffer) {
1989 ctx->RasterMask |= MULTI_DRAW_BIT;
1990 ctx->TriangleCaps |= DD_MULTIDRAW;
1991 }
1992 else if (ctx->Color.DrawBuffer==GL_NONE) {
1993 ctx->RasterMask |= MULTI_DRAW_BIT;
1994 ctx->TriangleCaps |= DD_MULTIDRAW;
1995 }
1996 else if (ctx->Visual->RGBAflag && ctx->Color.ColorMask==0) {
1997 /* all RGBA channels disabled */
1998 ctx->RasterMask |= MULTI_DRAW_BIT;
1999 ctx->TriangleCaps |= DD_MULTIDRAW;
2000 ctx->Color.DrawDestMask = 0;
2001 }
2002 else if (!ctx->Visual->RGBAflag && ctx->Color.IndexMask==0) {
2003 /* all color index bits disabled */
2004 ctx->RasterMask |= MULTI_DRAW_BIT;
2005 ctx->TriangleCaps |= DD_MULTIDRAW;
2006 ctx->Color.DrawDestMask = 0;
2007 }
2008}
2009
2010
2011void gl_print_state( const char *msg, GLuint state )
2012{
2013 fprintf(stderr,
2014 "%s: (0x%x) %s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s\n",
2015 msg,
2016 state,
2017 (state & NEW_LIGHTING) ? "lighting, " : "",
2018 (state & NEW_RASTER_OPS) ? "raster-ops, " : "",
2019 (state & NEW_TEXTURING) ? "texturing, " : "",
2020 (state & NEW_POLYGON) ? "polygon, " : "",
2021 (state & NEW_DRVSTATE0) ? "driver-0, " : "",
2022 (state & NEW_DRVSTATE1) ? "driver-1, " : "",
2023 (state & NEW_DRVSTATE2) ? "driver-2, " : "",
2024 (state & NEW_DRVSTATE3) ? "driver-3, " : "",
2025 (state & NEW_MODELVIEW) ? "modelview, " : "",
2026 (state & NEW_PROJECTION) ? "projection, " : "",
2027 (state & NEW_TEXTURE_MATRIX) ? "texture-matrix, " : "",
2028 (state & NEW_USER_CLIP) ? "user-clip, " : "",
2029 (state & NEW_TEXTURE_ENV) ? "texture-env, " : "",
2030 (state & NEW_CLIENT_STATE) ? "client-state, " : "",
2031 (state & NEW_FOG) ? "fog, " : "",
2032 (state & NEW_NORMAL_TRANSFORM) ? "normal-transform, " : "",
2033 (state & NEW_VIEWPORT) ? "viewport, " : "",
2034 (state & NEW_TEXTURE_ENABLE) ? "texture-enable, " : "");
2035}
2036
2037void gl_print_enable_flags( const char *msg, GLuint flags )
2038{
2039 fprintf(stderr,
2040 "%s: (0x%x) %s%s%s%s%s%s%s%s%s%s%s\n",
2041 msg,
2042 flags,
2043 (flags & ENABLE_TEX0) ? "tex-0, " : "",
2044 (flags & ENABLE_TEX1) ? "tex-1, " : "",
2045 (flags & ENABLE_LIGHT) ? "light, " : "",
2046 (flags & ENABLE_FOG) ? "fog, " : "",
2047 (flags & ENABLE_USERCLIP) ? "userclip, " : "",
2048 (flags & ENABLE_TEXGEN0) ? "tex-gen-0, " : "",
2049 (flags & ENABLE_TEXGEN1) ? "tex-gen-1, " : "",
2050 (flags & ENABLE_TEXMAT0) ? "tex-mat-0, " : "",
2051 (flags & ENABLE_TEXMAT1) ? "tex-mat-1, " : "",
2052 (flags & ENABLE_NORMALIZE) ? "normalize, " : "",
2053 (flags & ENABLE_RESCALE) ? "rescale, " : "");
2054}
2055
2056
2057/*
2058 * If ctx->NewState is non-zero then this function MUST be called before
2059 * rendering any primitive. Basically, function pointers and miscellaneous
2060 * flags are updated to reflect the current state of the state machine.
2061 */
2062void gl_update_state( GLcontext *ctx )
2063{
2064 GLuint i;
2065
2066 if (MESA_VERBOSE & VERBOSE_STATE)
2067 gl_print_state("", ctx->NewState);
2068
2069 if (ctx->NewState & NEW_CLIENT_STATE)
2070 gl_update_client_state( ctx );
2071
2072 if ((ctx->NewState & NEW_TEXTURE_ENABLE) &&
2073 (ctx->Enabled & ENABLE_TEX_ANY) != ctx->Texture.Enabled)
2074 ctx->NewState |= NEW_TEXTURING | NEW_RASTER_OPS;
2075
2076 if (ctx->NewState & NEW_TEXTURE_ENV) {
2077 if (ctx->Texture.Unit[0].EnvMode == ctx->Texture.Unit[0].LastEnvMode &&
2078 ctx->Texture.Unit[1].EnvMode == ctx->Texture.Unit[1].LastEnvMode)
2079 ctx->NewState &= ~NEW_TEXTURE_ENV;
2080 ctx->Texture.Unit[0].LastEnvMode = ctx->Texture.Unit[0].EnvMode;
2081 ctx->Texture.Unit[1].LastEnvMode = ctx->Texture.Unit[1].EnvMode;
2082 }
2083
2084 if ((ctx->NewState & ~(NEW_CLIENT_STATE|NEW_TEXTURE_ENABLE)) == 0)
2085 goto finished;
2086
2087 if (ctx->NewState & NEW_TEXTURE_MATRIX) {
2088 ctx->Enabled &= ~(ENABLE_TEXMAT0|ENABLE_TEXMAT1);
2089
2090 for (i=0; i < MAX_TEXTURE_UNITS; i++) {
2091 if (ctx->TextureMatrix[i].flags & MAT_DIRTY_ALL_OVER)
2092 {
2093 gl_matrix_analyze( &ctx->TextureMatrix[i] );
2094 ctx->TextureMatrix[i].flags &= ~MAT_DIRTY_DEPENDENTS;
2095
2096 if (ctx->Texture.Unit[i].Enabled &&
2097 ctx->TextureMatrix[i].type != MATRIX_IDENTITY)
2098 ctx->Enabled |= ENABLE_TEXMAT0 << i;
2099 }
2100 }
2101 }
2102
2103 if (ctx->NewState & NEW_TEXTURING) {
2104 ctx->Texture.NeedNormals = GL_FALSE;
2105 gl_update_dirty_texobjs(ctx);
2106 ctx->Enabled &= ~(ENABLE_TEXGEN0|ENABLE_TEXGEN1);
2107 ctx->Texture.ReallyEnabled = 0;
2108
2109 for (i=0; i < MAX_TEXTURE_UNITS; i++) {
2110 if (ctx->Texture.Unit[i].Enabled) {
2111 gl_update_texture_unit( ctx, &ctx->Texture.Unit[i] );
2112
2113 ctx->Texture.ReallyEnabled |=
2114 ctx->Texture.Unit[i].ReallyEnabled<<(i*4);
2115
2116 if (ctx->Texture.Unit[i].GenFlags != 0) {
2117 ctx->Enabled |= ENABLE_TEXGEN0 << i;
2118
2119 if (ctx->Texture.Unit[i].GenFlags & TEXGEN_NEED_NORMALS)
2120 {
2121 ctx->Texture.NeedNormals = GL_TRUE;
2122 ctx->Texture.NeedEyeCoords = GL_TRUE;
2123 }
2124
2125 if (ctx->Texture.Unit[i].GenFlags & TEXGEN_NEED_EYE_COORD)
2126 {
2127 ctx->Texture.NeedEyeCoords = GL_TRUE;
2128 }
2129 }
2130 }
2131 }
2132
2133 ctx->Texture.Enabled = ctx->Enabled & ENABLE_TEX_ANY;
2134 ctx->NeedNormals = (ctx->Light.Enabled || ctx->Texture.NeedNormals);
2135 }
2136
Keith Whitwell2be79c11999-08-26 14:50:49 +00002137 if (ctx->NewState & (NEW_RASTER_OPS | NEW_LIGHTING | NEW_FOG)) {
2138
2139
jtgafb833d1999-08-19 00:55:39 +00002140 if (ctx->NewState & NEW_RASTER_OPS) {
2141 update_pixel_logic(ctx);
2142 update_pixel_masking(ctx);
2143 update_fog_mode(ctx);
2144 update_rasterflags(ctx);
2145 if (ctx->Driver.Dither) {
2146 (*ctx->Driver.Dither)( ctx, ctx->Color.DitherFlag );
2147 }
2148
2149 /* Check if incoming colors can be modified during rasterization */
2150 if (ctx->Fog.Enabled ||
2151 ctx->Texture.Enabled ||
2152 ctx->Color.BlendEnabled ||
2153 ctx->Color.SWmasking ||
2154 ctx->Color.SWLogicOpEnabled) {
2155 ctx->MutablePixels = GL_TRUE;
2156 }
2157 else {
2158 ctx->MutablePixels = GL_FALSE;
2159 }
2160
2161 /* update scissor region */
2162
2163 ctx->Buffer->Xmin = 0;
2164 ctx->Buffer->Ymin = 0;
2165 ctx->Buffer->Xmax = ctx->Buffer->Width-1;
2166 ctx->Buffer->Ymax = ctx->Buffer->Height-1;
2167 if (ctx->Scissor.Enabled) {
2168 if (ctx->Scissor.X > ctx->Buffer->Xmin) {
2169 ctx->Buffer->Xmin = ctx->Scissor.X;
2170 }
2171 if (ctx->Scissor.Y > ctx->Buffer->Ymin) {
2172 ctx->Buffer->Ymin = ctx->Scissor.Y;
2173 }
2174 if (ctx->Scissor.X + ctx->Scissor.Width - 1 < ctx->Buffer->Xmax) {
2175 ctx->Buffer->Xmax = ctx->Scissor.X + ctx->Scissor.Width - 1;
2176 }
2177 if (ctx->Scissor.Y + ctx->Scissor.Height - 1 < ctx->Buffer->Ymax) {
2178 ctx->Buffer->Ymax = ctx->Scissor.Y + ctx->Scissor.Height - 1;
2179 }
2180 }
2181
Keith Whitwell324beb91999-09-04 14:40:49 +00002182 /* The driver isn't managing the depth buffer.
jtgafb833d1999-08-19 00:55:39 +00002183 */
Keith Whitwell324beb91999-09-04 14:40:49 +00002184 if (ctx->Driver.AllocDepthBuffer == gl_alloc_depth_buffer)
2185 {
2186 if (ctx->Depth.Mask) {
2187 switch (ctx->Depth.Func) {
2188 case GL_LESS:
2189 ctx->Driver.DepthTestSpan = gl_depth_test_span_less;
2190 ctx->Driver.DepthTestPixels = gl_depth_test_pixels_less;
2191 break;
2192 case GL_GREATER:
2193 ctx->Driver.DepthTestSpan = gl_depth_test_span_greater;
2194 ctx->Driver.DepthTestPixels = gl_depth_test_pixels_greater;
2195 break;
2196 default:
2197 ctx->Driver.DepthTestSpan = gl_depth_test_span_generic;
2198 ctx->Driver.DepthTestPixels = gl_depth_test_pixels_generic;
2199 }
2200 }
2201 else {
jtgafb833d1999-08-19 00:55:39 +00002202 ctx->Driver.DepthTestSpan = gl_depth_test_span_generic;
2203 ctx->Driver.DepthTestPixels = gl_depth_test_pixels_generic;
2204 }
2205 }
jtgafb833d1999-08-19 00:55:39 +00002206 }
2207
2208 if (ctx->NewState & NEW_LIGHTING) {
Keith Whitwell2be79c11999-08-26 14:50:49 +00002209 ctx->TriangleCaps &= ~(DD_TRI_LIGHT_TWOSIDE|DD_LIGHTING_CULL);
jtgafb833d1999-08-19 00:55:39 +00002210 if (ctx->Light.Enabled) {
2211 if (ctx->Light.Model.TwoSide)
Keith Whitwell2be79c11999-08-26 14:50:49 +00002212 ctx->TriangleCaps |= (DD_TRI_LIGHT_TWOSIDE|DD_LIGHTING_CULL);
jtgafb833d1999-08-19 00:55:39 +00002213 gl_update_lighting(ctx);
2214 }
2215 }
2216 }
2217
2218 if (ctx->NewState & (NEW_POLYGON | NEW_LIGHTING)) {
2219
Keith Whitwellb6e69371999-09-02 13:16:17 +00002220 ctx->TriangleCaps &= ~DD_TRI_CULL_FRONT_BACK;
jtgafb833d1999-08-19 00:55:39 +00002221
2222 if (ctx->NewState & NEW_POLYGON) {
2223 /* Setup CullBits bitmask */
2224 if (ctx->Polygon.CullFlag) {
Keith Whitwell2be79c11999-08-26 14:50:49 +00002225 ctx->backface_sign = 1;
jtgafb833d1999-08-19 00:55:39 +00002226 switch(ctx->Polygon.CullFaceMode) {
jtgafb833d1999-08-19 00:55:39 +00002227 case GL_BACK:
Keith Whitwell2be79c11999-08-26 14:50:49 +00002228 if(ctx->Polygon.FrontFace==GL_CCW)
2229 ctx->backface_sign = -1;
jtgafb833d1999-08-19 00:55:39 +00002230 ctx->Polygon.CullBits = 1;
2231 break;
Keith Whitwell2be79c11999-08-26 14:50:49 +00002232 case GL_FRONT:
2233 if(ctx->Polygon.FrontFace!=GL_CCW)
2234 ctx->backface_sign = -1;
2235 ctx->Polygon.CullBits = 2;
2236 break;
jtgafb833d1999-08-19 00:55:39 +00002237 default:
2238 case GL_FRONT_AND_BACK:
Keith Whitwell2be79c11999-08-26 14:50:49 +00002239 ctx->backface_sign = 0;
Keith Whitwellb6e69371999-09-02 13:16:17 +00002240 ctx->Polygon.CullBits = 0;
2241 ctx->TriangleCaps |= DD_TRI_CULL_FRONT_BACK;
jtgafb833d1999-08-19 00:55:39 +00002242 break;
2243 }
2244 }
Keith Whitwell2be79c11999-08-26 14:50:49 +00002245 else {
jtgafb833d1999-08-19 00:55:39 +00002246 ctx->Polygon.CullBits = 3;
Keith Whitwell2be79c11999-08-26 14:50:49 +00002247 ctx->backface_sign = 0;
2248 }
jtgafb833d1999-08-19 00:55:39 +00002249
2250 /* Any Polygon offsets enabled? */
2251 ctx->TriangleCaps &= ~DD_TRI_OFFSET;
2252
2253 if (ctx->Polygon.OffsetPoint ||
2254 ctx->Polygon.OffsetLine ||
2255 ctx->Polygon.OffsetFill)
2256 ctx->TriangleCaps |= DD_TRI_OFFSET;
2257
2258 /* reset Z offsets now */
2259 ctx->PointZoffset = 0.0;
2260 ctx->LineZoffset = 0.0;
2261 ctx->PolygonZoffset = 0.0;
2262 }
2263 }
2264
2265 if (ctx->NewState & ~(NEW_CLIENT_STATE|NEW_TEXTURE_ENABLE|
2266 NEW_DRIVER_STATE|NEW_USER_CLIP|
2267 NEW_POLYGON))
2268 gl_update_clipmask(ctx);
2269
2270 if (ctx->NewState & (NEW_LIGHTING|
2271 NEW_RASTER_OPS|
2272 NEW_TEXTURING|
2273 NEW_TEXTURE_ENV|
2274 NEW_POLYGON|
2275 NEW_DRVSTATE0|
2276 NEW_DRVSTATE1|
2277 NEW_DRVSTATE2|
2278 NEW_DRVSTATE3|
2279 NEW_USER_CLIP))
2280 {
2281 ctx->IndirectTriangles = ctx->TriangleCaps & ~ctx->Driver.TriangleCaps;
2282 ctx->IndirectTriangles |= DD_SW_RASTERIZE;
2283
Keith Whitwell2be79c11999-08-26 14:50:49 +00002284 if (MESA_VERBOSE&VERBOSE_CULL)
2285 gl_print_tri_caps("initial indirect tris", ctx->IndirectTriangles);
2286
jtgafb833d1999-08-19 00:55:39 +00002287 ctx->Driver.PointsFunc = NULL;
2288 ctx->Driver.LineFunc = NULL;
2289 ctx->Driver.TriangleFunc = NULL;
2290 ctx->Driver.QuadFunc = NULL;
2291 ctx->Driver.RectFunc = NULL;
2292 ctx->Driver.RenderVBClippedTab = NULL;
2293 ctx->Driver.RenderVBCulledTab = NULL;
2294 ctx->Driver.RenderVBRawTab = NULL;
2295
2296 /*
2297 * Here the driver sets up all the ctx->Driver function pointers to
2298 * it's specific, private functions.
2299 */
2300 ctx->Driver.UpdateState(ctx);
2301
Keith Whitwell2be79c11999-08-26 14:50:49 +00002302 if (MESA_VERBOSE&VERBOSE_CULL)
2303 gl_print_tri_caps("indirect tris", ctx->IndirectTriangles);
2304
jtgafb833d1999-08-19 00:55:39 +00002305 /*
2306 * In case the driver didn't hook in an optimized point, line or
2307 * triangle function we'll now select "core/fallback" point, line
2308 * and triangle functions.
2309 */
2310 if (ctx->IndirectTriangles & DD_SW_RASTERIZE) {
2311 gl_set_point_function(ctx);
2312 gl_set_line_function(ctx);
2313 gl_set_triangle_function(ctx);
2314 gl_set_quad_function(ctx);
Keith Whitwell2be79c11999-08-26 14:50:49 +00002315
2316 if ((ctx->IndirectTriangles &
2317 (DD_TRI_SW_RASTERIZE|DD_QUAD_SW_RASTERIZE|DD_TRI_CULL)) ==
2318 (DD_TRI_SW_RASTERIZE|DD_QUAD_SW_RASTERIZE|DD_TRI_CULL))
2319 ctx->IndirectTriangles &= ~DD_TRI_CULL;
jtgafb833d1999-08-19 00:55:39 +00002320 }
2321
Keith Whitwell2be79c11999-08-26 14:50:49 +00002322 if (MESA_VERBOSE&VERBOSE_CULL)
2323 gl_print_tri_caps("indirect tris 2", ctx->IndirectTriangles);
2324
jtgafb833d1999-08-19 00:55:39 +00002325 gl_set_render_vb_function(ctx);
2326 }
2327
2328 /* Should only be calc'd when !need_eye_coords and not culling.
2329 */
2330 if (ctx->NewState & (NEW_MODELVIEW|NEW_PROJECTION)) {
2331 if (ctx->NewState & NEW_MODELVIEW) {
2332 gl_matrix_analyze( &ctx->ModelView );
2333 ctx->ProjectionMatrix.flags &= ~MAT_DIRTY_DEPENDENTS;
2334 }
2335
2336 if (ctx->NewState & NEW_PROJECTION) {
2337 gl_matrix_analyze( &ctx->ProjectionMatrix );
2338 ctx->ProjectionMatrix.flags &= ~MAT_DIRTY_DEPENDENTS;
2339
2340 if (ctx->Transform.AnyClip) {
2341 gl_update_userclip( ctx );
2342 }
2343 }
2344
2345 gl_calculate_model_project_matrix( ctx );
2346 ctx->ModelProjectWinMatrixUptodate = 0;
2347 }
2348
2349 /* Figure out whether we can light in object space or not. If we
2350 * can, find the current positions of the lights in object space
2351 */
Keith Whitwell2be79c11999-08-26 14:50:49 +00002352 if ((ctx->Enabled & (ENABLE_POINT_ATTEN | ENABLE_LIGHT | ENABLE_FOG |
jtgafb833d1999-08-19 00:55:39 +00002353 ENABLE_TEXGEN0 | ENABLE_TEXGEN1)) &&
2354 (ctx->NewState & (NEW_LIGHTING |
Keith Whitwell2be79c11999-08-26 14:50:49 +00002355 NEW_FOG |
jtgafb833d1999-08-19 00:55:39 +00002356 NEW_MODELVIEW |
2357 NEW_PROJECTION |
2358 NEW_TEXTURING |
2359 NEW_RASTER_OPS |
2360 NEW_USER_CLIP)))
2361 {
2362 GLboolean oldcoord, oldnorm;
2363
2364 oldcoord = ctx->NeedEyeCoords;
2365 oldnorm = ctx->NeedEyeNormals;
2366
2367 ctx->NeedNormals = (ctx->Light.Enabled || ctx->Texture.NeedNormals);
2368 ctx->NeedEyeCoords = ((ctx->Fog.Enabled && ctx->Hint.Fog != GL_NICEST) ||
2369 ctx->Point.Attenuated);
2370 ctx->NeedEyeNormals = GL_FALSE;
2371
2372 if (ctx->Light.Enabled) {
2373 if (ctx->Light.Flags & LIGHT_POSITIONAL) {
2374 /* Need length for attenuation */
2375 if (!TEST_MAT_FLAGS( &ctx->ModelView, MAT_FLAGS_LENGTH_PRESERVING))
2376 ctx->NeedEyeCoords = GL_TRUE;
2377 } else if (ctx->Light.NeedVertices) {
2378 /* Need angle for spot calculations */
2379 if (!TEST_MAT_FLAGS( &ctx->ModelView, MAT_FLAGS_ANGLE_PRESERVING))
2380 ctx->NeedEyeCoords = GL_TRUE;
2381 }
2382 ctx->NeedEyeNormals = ctx->NeedEyeCoords;
2383 }
2384 if (ctx->Texture.Enabled || ctx->RenderMode==GL_FEEDBACK) {
2385 if (ctx->Texture.NeedEyeCoords) ctx->NeedEyeCoords = GL_TRUE;
2386 if (ctx->Texture.NeedNormals)
2387 ctx->NeedNormals = ctx->NeedEyeNormals = GL_TRUE;
2388 }
2389
2390 ctx->vb_proj_matrix = &ctx->ModelProjectMatrix;
2391
2392 if (ctx->NeedEyeCoords)
2393 ctx->vb_proj_matrix = &ctx->ProjectionMatrix;
2394
2395 if (ctx->Light.Enabled) {
2396 gl_update_lighting_function(ctx);
2397
2398 if ( (ctx->NewState & NEW_LIGHTING) ||
2399 ((ctx->NewState & (NEW_MODELVIEW| NEW_PROJECTION)) &&
2400 !ctx->NeedEyeCoords) ||
2401 oldcoord != ctx->NeedEyeCoords ||
2402 oldnorm != ctx->NeedEyeNormals) {
2403 gl_compute_light_positions(ctx);
2404 }
2405
2406 ctx->rescale_factor = 1.0F;
2407
2408 if (ctx->ModelView.flags & (MAT_FLAG_UNIFORM_SCALE |
2409 MAT_FLAG_GENERAL_SCALE |
2410 MAT_FLAG_GENERAL_3D |
2411 MAT_FLAG_GENERAL) )
2412
2413 {
2414 GLfloat *m = ctx->ModelView.inv;
2415 GLfloat f = m[2]*m[2] + m[6]*m[6] + m[10]*m[10];
2416 if (f > 1e-12 && (f-1)*(f-1) > 1e-12)
2417 ctx->rescale_factor = 1.0/GL_SQRT(f);
2418 }
2419 }
2420
2421 gl_update_normal_transform( ctx );
2422 }
2423
2424 finished:
2425 gl_update_pipelines(ctx);
2426 ctx->NewState = 0;
2427}