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