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