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