blob: e41afe15cee103daa30e0cc6d753b511fe39282b [file] [log] [blame]
Brian Paul3f02f901999-11-24 18:48:30 +00001/* $Id: context.c,v 1.23 1999/11/24 18:48:31 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;
Brian Paul3f02f901999-11-24 18:48:30 +00001207 ctx->DrawBuffer = NULL;
1208 ctx->ReadBuffer = NULL;
jtgafb833d1999-08-19 00:55:39 +00001209
1210 ctx->VB = gl_vb_create_for_immediate( ctx );
1211 if (!ctx->VB) {
Brian Paulbd5cdaf1999-10-13 18:42:49 +00001212 FREE( ctx );
jtgafb833d1999-08-19 00:55:39 +00001213 return NULL;
1214 }
1215 ctx->input = ctx->VB->IM;
1216
1217 ctx->PB = gl_alloc_pb();
1218 if (!ctx->PB) {
Brian Paulbd5cdaf1999-10-13 18:42:49 +00001219 FREE( ctx->VB );
1220 FREE( ctx );
jtgafb833d1999-08-19 00:55:39 +00001221 return NULL;
1222 }
1223
1224 if (share_list) {
1225 /* share the group of display lists of another context */
1226 ctx->Shared = share_list->Shared;
1227 }
1228 else {
1229 /* allocate new group of display lists */
1230 ctx->Shared = alloc_shared_state();
1231 if (!ctx->Shared) {
Brian Paulbd5cdaf1999-10-13 18:42:49 +00001232 FREE(ctx->VB);
1233 FREE(ctx->PB);
1234 FREE(ctx);
jtgafb833d1999-08-19 00:55:39 +00001235 return NULL;
1236 }
1237 }
1238 ctx->Shared->RefCount++;
1239
1240 initialize_context( ctx );
1241 gl_reset_vb( ctx->VB );
1242 gl_reset_input( ctx );
1243
1244
Brian Paulbd5cdaf1999-10-13 18:42:49 +00001245 ctx->ShineTabList = MALLOC_STRUCT( gl_shine_tab );
jtgafb833d1999-08-19 00:55:39 +00001246 make_empty_list( ctx->ShineTabList );
1247
1248 for (i = 0 ; i < 10 ; i++) {
Brian Paulbd5cdaf1999-10-13 18:42:49 +00001249 struct gl_shine_tab *s = MALLOC_STRUCT( gl_shine_tab );
jtgafb833d1999-08-19 00:55:39 +00001250 s->shininess = -1;
1251 s->refcount = 0;
1252 insert_at_tail( ctx->ShineTabList, s );
1253 }
1254
1255 for (i = 0 ; i < 4 ; i++) {
1256 ctx->ShineTable[i] = ctx->ShineTabList->prev;
1257 ctx->ShineTable[i]->refcount++;
1258 }
1259
1260 if (visual->DBflag) {
1261 ctx->Color.DrawBuffer = GL_BACK;
1262 ctx->Color.DriverDrawBuffer = GL_BACK_LEFT;
1263 ctx->Color.DrawDestMask = BACK_LEFT_BIT;
1264 ctx->Pixel.ReadBuffer = GL_BACK;
1265 ctx->Pixel.DriverReadBuffer = GL_BACK_LEFT;
1266 }
1267 else {
1268 ctx->Color.DrawBuffer = GL_FRONT;
1269 ctx->Color.DriverDrawBuffer = GL_FRONT_LEFT;
1270 ctx->Color.DrawDestMask = FRONT_LEFT_BIT;
1271 ctx->Pixel.ReadBuffer = GL_FRONT;
1272 ctx->Pixel.DriverReadBuffer = GL_FRONT_LEFT;
1273 }
1274
Keith Whitwell324beb91999-09-04 14:40:49 +00001275
1276 /* Fill in some driver defaults now.
1277 */
1278 ctx->Driver.AllocDepthBuffer = gl_alloc_depth_buffer;
1279 ctx->Driver.ReadDepthSpanFloat = gl_read_depth_span_float;
1280 ctx->Driver.ReadDepthSpanInt = gl_read_depth_span_int;
1281
jtgafb833d1999-08-19 00:55:39 +00001282#ifdef PROFILE
1283 init_timings( ctx );
1284#endif
1285
jtgafb833d1999-08-19 00:55:39 +00001286 if (!alloc_proxy_textures(ctx)) {
1287 free_shared_state(ctx, ctx->Shared);
Brian Paulbd5cdaf1999-10-13 18:42:49 +00001288 FREE(ctx->VB);
1289 FREE(ctx->PB);
1290 FREE(ctx);
jtgafb833d1999-08-19 00:55:39 +00001291 return NULL;
1292 }
jtgafb833d1999-08-19 00:55:39 +00001293
Brian Paulfbd8f211999-11-11 01:22:25 +00001294 /* setup API dispatch tables */
1295 _mesa_init_exec_table( &ctx->Exec );
1296 _mesa_init_dlist_table( &ctx->Save );
1297 ctx->CurrentDispatch = &ctx->Exec;
jtgafb833d1999-08-19 00:55:39 +00001298
1299 return ctx;
1300}
1301
1302/* Just reads the config files...
1303 */
1304void gl_context_initialize( GLcontext *ctx )
1305{
1306 gl_read_config_file( ctx );
1307}
1308
1309
1310
1311
1312/*
1313 * Destroy a gl_context structure.
1314 */
1315void gl_destroy_context( GLcontext *ctx )
1316{
1317 if (ctx) {
1318
1319 GLuint i;
1320 struct gl_shine_tab *s, *tmps;
1321
1322#ifdef PROFILE
1323 if (getenv("MESA_PROFILE")) {
1324 print_timings( ctx );
1325 }
1326#endif
1327
1328 gl_matrix_dtr( &ctx->ModelView );
1329 for (i = 0 ; i < MAX_MODELVIEW_STACK_DEPTH ; i++) {
1330 gl_matrix_dtr( &ctx->ModelViewStack[i] );
1331 }
Keith Whitwell5a437d51999-09-19 23:43:02 +00001332 gl_matrix_dtr( &ctx->ProjectionMatrix );
1333 for (i = 0 ; i < MAX_PROJECTION_STACK_DEPTH ; i++) {
1334 gl_matrix_dtr( &ctx->ProjectionStack[i] );
1335 }
jtgafb833d1999-08-19 00:55:39 +00001336
Brian Paulbd5cdaf1999-10-13 18:42:49 +00001337 FREE( ctx->PB );
Keith Whitwell5a437d51999-09-19 23:43:02 +00001338
1339 if(ctx->input != ctx->VB->IM)
1340 gl_immediate_free( ctx->input );
1341
1342 gl_vb_free( ctx->VB );
jtgafb833d1999-08-19 00:55:39 +00001343
1344 ctx->Shared->RefCount--;
1345 assert(ctx->Shared->RefCount>=0);
1346 if (ctx->Shared->RefCount==0) {
1347 /* free shared state */
1348 free_shared_state( ctx, ctx->Shared );
1349 }
1350
1351 foreach_s( s, tmps, ctx->ShineTabList ) {
Brian Paulbd5cdaf1999-10-13 18:42:49 +00001352 FREE( s );
jtgafb833d1999-08-19 00:55:39 +00001353 }
Brian Paulbd5cdaf1999-10-13 18:42:49 +00001354 FREE( ctx->ShineTabList );
jtgafb833d1999-08-19 00:55:39 +00001355
1356 /* Free proxy texture objects */
1357 gl_free_texture_object( NULL, ctx->Texture.Proxy1D );
1358 gl_free_texture_object( NULL, ctx->Texture.Proxy2D );
1359 gl_free_texture_object( NULL, ctx->Texture.Proxy3D );
1360
1361 /* Free evaluator data */
1362 if (ctx->EvalMap.Map1Vertex3.Points)
Brian Paulbd5cdaf1999-10-13 18:42:49 +00001363 FREE( ctx->EvalMap.Map1Vertex3.Points );
jtgafb833d1999-08-19 00:55:39 +00001364 if (ctx->EvalMap.Map1Vertex4.Points)
Brian Paulbd5cdaf1999-10-13 18:42:49 +00001365 FREE( ctx->EvalMap.Map1Vertex4.Points );
jtgafb833d1999-08-19 00:55:39 +00001366 if (ctx->EvalMap.Map1Index.Points)
Brian Paulbd5cdaf1999-10-13 18:42:49 +00001367 FREE( ctx->EvalMap.Map1Index.Points );
jtgafb833d1999-08-19 00:55:39 +00001368 if (ctx->EvalMap.Map1Color4.Points)
Brian Paulbd5cdaf1999-10-13 18:42:49 +00001369 FREE( ctx->EvalMap.Map1Color4.Points );
jtgafb833d1999-08-19 00:55:39 +00001370 if (ctx->EvalMap.Map1Normal.Points)
Brian Paulbd5cdaf1999-10-13 18:42:49 +00001371 FREE( ctx->EvalMap.Map1Normal.Points );
jtgafb833d1999-08-19 00:55:39 +00001372 if (ctx->EvalMap.Map1Texture1.Points)
Brian Paulbd5cdaf1999-10-13 18:42:49 +00001373 FREE( ctx->EvalMap.Map1Texture1.Points );
jtgafb833d1999-08-19 00:55:39 +00001374 if (ctx->EvalMap.Map1Texture2.Points)
Brian Paulbd5cdaf1999-10-13 18:42:49 +00001375 FREE( ctx->EvalMap.Map1Texture2.Points );
jtgafb833d1999-08-19 00:55:39 +00001376 if (ctx->EvalMap.Map1Texture3.Points)
Brian Paulbd5cdaf1999-10-13 18:42:49 +00001377 FREE( ctx->EvalMap.Map1Texture3.Points );
jtgafb833d1999-08-19 00:55:39 +00001378 if (ctx->EvalMap.Map1Texture4.Points)
Brian Paulbd5cdaf1999-10-13 18:42:49 +00001379 FREE( ctx->EvalMap.Map1Texture4.Points );
jtgafb833d1999-08-19 00:55:39 +00001380
1381 if (ctx->EvalMap.Map2Vertex3.Points)
Brian Paulbd5cdaf1999-10-13 18:42:49 +00001382 FREE( ctx->EvalMap.Map2Vertex3.Points );
jtgafb833d1999-08-19 00:55:39 +00001383 if (ctx->EvalMap.Map2Vertex4.Points)
Brian Paulbd5cdaf1999-10-13 18:42:49 +00001384 FREE( ctx->EvalMap.Map2Vertex4.Points );
jtgafb833d1999-08-19 00:55:39 +00001385 if (ctx->EvalMap.Map2Index.Points)
Brian Paulbd5cdaf1999-10-13 18:42:49 +00001386 FREE( ctx->EvalMap.Map2Index.Points );
jtgafb833d1999-08-19 00:55:39 +00001387 if (ctx->EvalMap.Map2Color4.Points)
Brian Paulbd5cdaf1999-10-13 18:42:49 +00001388 FREE( ctx->EvalMap.Map2Color4.Points );
jtgafb833d1999-08-19 00:55:39 +00001389 if (ctx->EvalMap.Map2Normal.Points)
Brian Paulbd5cdaf1999-10-13 18:42:49 +00001390 FREE( ctx->EvalMap.Map2Normal.Points );
jtgafb833d1999-08-19 00:55:39 +00001391 if (ctx->EvalMap.Map2Texture1.Points)
Brian Paulbd5cdaf1999-10-13 18:42:49 +00001392 FREE( ctx->EvalMap.Map2Texture1.Points );
jtgafb833d1999-08-19 00:55:39 +00001393 if (ctx->EvalMap.Map2Texture2.Points)
Brian Paulbd5cdaf1999-10-13 18:42:49 +00001394 FREE( ctx->EvalMap.Map2Texture2.Points );
jtgafb833d1999-08-19 00:55:39 +00001395 if (ctx->EvalMap.Map2Texture3.Points)
Brian Paulbd5cdaf1999-10-13 18:42:49 +00001396 FREE( ctx->EvalMap.Map2Texture3.Points );
jtgafb833d1999-08-19 00:55:39 +00001397 if (ctx->EvalMap.Map2Texture4.Points)
Brian Paulbd5cdaf1999-10-13 18:42:49 +00001398 FREE( ctx->EvalMap.Map2Texture4.Points );
jtgafb833d1999-08-19 00:55:39 +00001399
Keith Whitwell5a437d51999-09-19 23:43:02 +00001400 /* Free cache of immediate buffers. */
1401 while (ctx->nr_im_queued-- > 0) {
1402 struct immediate * next = ctx->freed_im_queue->next;
Brian Paulbd5cdaf1999-10-13 18:42:49 +00001403 FREE( ctx->freed_im_queue );
Keith Whitwell5a437d51999-09-19 23:43:02 +00001404 ctx->freed_im_queue = next;
1405 }
1406 gl_extensions_dtr(ctx);
1407
Brian Paulbd5cdaf1999-10-13 18:42:49 +00001408 FREE( (void *) ctx );
jtgafb833d1999-08-19 00:55:39 +00001409
1410#ifndef THREADS
Brian Paulfbd8f211999-11-11 01:22:25 +00001411 if (ctx == _mesa_current_context) {
1412 _mesa_current_context = NULL;
jtgafb833d1999-08-19 00:55:39 +00001413 CURRENT_INPUT = NULL;
1414 }
1415#endif
1416
1417 }
1418}
1419
1420
1421
1422/*
1423 * Create a new framebuffer. A GLframebuffer is a struct which
1424 * encapsulates the depth, stencil and accum buffers and related
1425 * parameters.
1426 * Input: visual - a GLvisual pointer
1427 * Return: pointer to new GLframebuffer struct or NULL if error.
1428 */
1429GLframebuffer *gl_create_framebuffer( GLvisual *visual )
1430{
1431 GLframebuffer *buffer;
1432
Brian Paulbd5cdaf1999-10-13 18:42:49 +00001433 buffer = (GLframebuffer *) CALLOC( sizeof(GLframebuffer) );
jtgafb833d1999-08-19 00:55:39 +00001434 if (!buffer) {
1435 return NULL;
1436 }
1437
1438 buffer->Visual = visual;
1439
1440 return buffer;
1441}
1442
1443
1444
1445/*
1446 * Free a framebuffer struct and its buffers.
1447 */
1448void gl_destroy_framebuffer( GLframebuffer *buffer )
1449{
1450 if (buffer) {
1451 if (buffer->Depth) {
Brian Paulbd5cdaf1999-10-13 18:42:49 +00001452 FREE( buffer->Depth );
jtgafb833d1999-08-19 00:55:39 +00001453 }
1454 if (buffer->Accum) {
Brian Paulbd5cdaf1999-10-13 18:42:49 +00001455 FREE( buffer->Accum );
jtgafb833d1999-08-19 00:55:39 +00001456 }
1457 if (buffer->Stencil) {
Brian Paulbd5cdaf1999-10-13 18:42:49 +00001458 FREE( buffer->Stencil );
jtgafb833d1999-08-19 00:55:39 +00001459 }
1460 if (buffer->FrontLeftAlpha) {
Brian Paulbd5cdaf1999-10-13 18:42:49 +00001461 FREE( buffer->FrontLeftAlpha );
jtgafb833d1999-08-19 00:55:39 +00001462 }
1463 if (buffer->BackLeftAlpha) {
Brian Paulbd5cdaf1999-10-13 18:42:49 +00001464 FREE( buffer->BackLeftAlpha );
jtgafb833d1999-08-19 00:55:39 +00001465 }
1466 if (buffer->FrontRightAlpha) {
Brian Paulbd5cdaf1999-10-13 18:42:49 +00001467 FREE( buffer->FrontRightAlpha );
jtgafb833d1999-08-19 00:55:39 +00001468 }
1469 if (buffer->BackRightAlpha) {
Brian Paulbd5cdaf1999-10-13 18:42:49 +00001470 FREE( buffer->BackRightAlpha );
jtgafb833d1999-08-19 00:55:39 +00001471 }
Brian Paulbd5cdaf1999-10-13 18:42:49 +00001472 FREE(buffer);
jtgafb833d1999-08-19 00:55:39 +00001473 }
1474}
1475
1476
1477
1478/*
1479 * Set the current context, binding the given frame buffer to the context.
1480 */
Brian Paulfbd8f211999-11-11 01:22:25 +00001481void gl_make_current( GLcontext *newCtx, GLframebuffer *buffer )
jtgafb833d1999-08-19 00:55:39 +00001482{
Brian Paul3f02f901999-11-24 18:48:30 +00001483 gl_make_current2( newCtx, buffer, buffer );
1484}
1485
1486
1487/*
1488 * Bind the given context to the given draw-buffer and read-buffer
1489 * and make it the current context for this thread.
1490 */
1491void gl_make_current2( GLcontext *newCtx, GLframebuffer *drawBuffer,
1492 GLframebuffer *readBuffer )
1493{
Brian Paulfbd8f211999-11-11 01:22:25 +00001494 GET_CURRENT_CONTEXT(oldCtx);
jtgafb833d1999-08-19 00:55:39 +00001495
1496 /* Flush the old context
1497 */
Brian Paulfbd8f211999-11-11 01:22:25 +00001498 if (oldCtx) {
1499 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(oldCtx, "gl_make_current");
jtgafb833d1999-08-19 00:55:39 +00001500 }
1501
Brian Paul3f02f901999-11-24 18:48:30 +00001502 /* unbind frame buffers from context */
1503 if (oldCtx && oldCtx->DrawBuffer) {
1504 oldCtx->DrawBuffer = NULL;
1505 }
1506 if (oldCtx && oldCtx->ReadBuffer) {
1507 oldCtx->ReadBuffer = NULL;
jtgafb833d1999-08-19 00:55:39 +00001508 }
Brian Paul04986821999-11-19 22:26:52 +00001509
1510#ifdef THREADS
1511 /* TODO: unbind old buffer from context? */
1512 MesaSetTSD(&mesa_ctx_tsd, (void *) newCtx, mesa_ctx_thread_init);
1513#else
Brian Paulfbd8f211999-11-11 01:22:25 +00001514 _mesa_current_context = newCtx;
Brian Paul04986821999-11-19 22:26:52 +00001515#endif
Brian Paulfbd8f211999-11-11 01:22:25 +00001516 if (newCtx) {
1517 SET_IMMEDIATE(newCtx, newCtx->input);
jtgafb833d1999-08-19 00:55:39 +00001518 }
jtgafb833d1999-08-19 00:55:39 +00001519
Brian Paulfbd8f211999-11-11 01:22:25 +00001520 if (newCtx)
1521 _glapi_set_dispatch(newCtx->CurrentDispatch);
1522 else
1523 _glapi_set_dispatch(NULL); /* none current */
1524
jtgafb833d1999-08-19 00:55:39 +00001525 if (MESA_VERBOSE) fprintf(stderr, "gl_make_current()\n");
1526
Brian Paul3f02f901999-11-24 18:48:30 +00001527 if (newCtx && drawBuffer && readBuffer) {
Brian Paulfbd8f211999-11-11 01:22:25 +00001528 /* TODO: check if newCtx and buffer's visual match??? */
Brian Paul3f02f901999-11-24 18:48:30 +00001529 newCtx->DrawBuffer = drawBuffer;
1530 newCtx->ReadBuffer = readBuffer;
Brian Paulfbd8f211999-11-11 01:22:25 +00001531 newCtx->NewState = NEW_ALL; /* just to be safe */
1532 gl_update_state( newCtx );
jtgafb833d1999-08-19 00:55:39 +00001533 }
1534}
1535
1536
Brian Paul3f02f901999-11-24 18:48:30 +00001537
jtgafb833d1999-08-19 00:55:39 +00001538/*
Brian Paul04986821999-11-19 22:26:52 +00001539 * Return current context handle for the calling thread.
jtgafb833d1999-08-19 00:55:39 +00001540 */
1541GLcontext *gl_get_current_context( void )
1542{
1543#ifdef THREADS
Brian Paul04986821999-11-19 22:26:52 +00001544 return (GLcontext *) MesaGetTSD(&mesa_ctx_tsd);
jtgafb833d1999-08-19 00:55:39 +00001545#else
Brian Paulfbd8f211999-11-11 01:22:25 +00001546 return _mesa_current_context;
jtgafb833d1999-08-19 00:55:39 +00001547#endif
1548}
1549
1550
1551
1552/*
1553 * Copy attribute groups from one context to another.
1554 * Input: src - source context
1555 * dst - destination context
1556 * mask - bitwise OR of GL_*_BIT flags
1557 */
1558void gl_copy_context( const GLcontext *src, GLcontext *dst, GLuint mask )
1559{
1560 if (mask & GL_ACCUM_BUFFER_BIT) {
1561 MEMCPY( &dst->Accum, &src->Accum, sizeof(struct gl_accum_attrib) );
1562 }
1563 if (mask & GL_COLOR_BUFFER_BIT) {
1564 MEMCPY( &dst->Color, &src->Color, sizeof(struct gl_colorbuffer_attrib) );
1565 }
1566 if (mask & GL_CURRENT_BIT) {
1567 MEMCPY( &dst->Current, &src->Current, sizeof(struct gl_current_attrib) );
1568 }
1569 if (mask & GL_DEPTH_BUFFER_BIT) {
1570 MEMCPY( &dst->Depth, &src->Depth, sizeof(struct gl_depthbuffer_attrib) );
1571 }
1572 if (mask & GL_ENABLE_BIT) {
1573 /* no op */
1574 }
1575 if (mask & GL_EVAL_BIT) {
1576 MEMCPY( &dst->Eval, &src->Eval, sizeof(struct gl_eval_attrib) );
1577 }
1578 if (mask & GL_FOG_BIT) {
1579 MEMCPY( &dst->Fog, &src->Fog, sizeof(struct gl_fog_attrib) );
1580 }
1581 if (mask & GL_HINT_BIT) {
1582 MEMCPY( &dst->Hint, &src->Hint, sizeof(struct gl_hint_attrib) );
1583 }
1584 if (mask & GL_LIGHTING_BIT) {
1585 MEMCPY( &dst->Light, &src->Light, sizeof(struct gl_light_attrib) );
1586/* gl_reinit_light_attrib( &dst->Light ); */
1587 }
1588 if (mask & GL_LINE_BIT) {
1589 MEMCPY( &dst->Line, &src->Line, sizeof(struct gl_line_attrib) );
1590 }
1591 if (mask & GL_LIST_BIT) {
1592 MEMCPY( &dst->List, &src->List, sizeof(struct gl_list_attrib) );
1593 }
1594 if (mask & GL_PIXEL_MODE_BIT) {
1595 MEMCPY( &dst->Pixel, &src->Pixel, sizeof(struct gl_pixel_attrib) );
1596 }
1597 if (mask & GL_POINT_BIT) {
1598 MEMCPY( &dst->Point, &src->Point, sizeof(struct gl_point_attrib) );
1599 }
1600 if (mask & GL_POLYGON_BIT) {
1601 MEMCPY( &dst->Polygon, &src->Polygon, sizeof(struct gl_polygon_attrib) );
1602 }
1603 if (mask & GL_POLYGON_STIPPLE_BIT) {
1604 /* Use loop instead of MEMCPY due to problem with Portland Group's
1605 * C compiler. Reported by John Stone.
1606 */
1607 int i;
1608 for (i=0;i<32;i++) {
1609 dst->PolygonStipple[i] = src->PolygonStipple[i];
1610 }
1611 }
1612 if (mask & GL_SCISSOR_BIT) {
1613 MEMCPY( &dst->Scissor, &src->Scissor, sizeof(struct gl_scissor_attrib) );
1614 }
1615 if (mask & GL_STENCIL_BUFFER_BIT) {
1616 MEMCPY( &dst->Stencil, &src->Stencil, sizeof(struct gl_stencil_attrib) );
1617 }
1618 if (mask & GL_TEXTURE_BIT) {
1619 MEMCPY( &dst->Texture, &src->Texture, sizeof(struct gl_texture_attrib) );
1620 }
1621 if (mask & GL_TRANSFORM_BIT) {
1622 MEMCPY( &dst->Transform, &src->Transform, sizeof(struct gl_transform_attrib) );
1623 }
1624 if (mask & GL_VIEWPORT_BIT) {
1625 MEMCPY( &dst->Viewport, &src->Viewport, sizeof(struct gl_viewport_attrib) );
1626 }
1627}
1628
1629
jtgafb833d1999-08-19 00:55:39 +00001630/*
Brian Paulfbd8f211999-11-11 01:22:25 +00001631 * This should be called by device drivers just before they do a
1632 * swapbuffers. Any pending rendering commands will be executed.
jtgafb833d1999-08-19 00:55:39 +00001633 */
Brian Paulfbd8f211999-11-11 01:22:25 +00001634void
1635_mesa_swapbuffers(GLcontext *ctx)
jtgafb833d1999-08-19 00:55:39 +00001636{
Brian Paulfbd8f211999-11-11 01:22:25 +00001637 FLUSH_VB( ctx, "swap buffers" );
jtgafb833d1999-08-19 00:55:39 +00001638}
1639
1640
Brian Paulfbd8f211999-11-11 01:22:25 +00001641/*
1642 * Return pointer to this context's current API dispatch table.
1643 * It'll either be the immediate-mode execute dispatcher or the
1644 * display list compile dispatcher.
1645 */
1646struct _glapi_table *
1647_mesa_get_dispatch(GLcontext *ctx)
1648{
1649 return ctx->CurrentDispatch;
1650}
1651
1652
1653
1654void
1655_mesa_ResizeBuffersMESA( void )
1656{
1657 GET_CURRENT_CONTEXT(ctx);
1658
1659 GLuint buf_width, buf_height;
1660
1661 if (MESA_VERBOSE & VERBOSE_API)
1662 fprintf(stderr, "glResizeBuffersMESA\n");
1663
1664 /* ask device driver for size of output buffer */
1665 (*ctx->Driver.GetBufferSize)( ctx, &buf_width, &buf_height );
1666
1667 /* see if size of device driver's color buffer (window) has changed */
Brian Paul3f02f901999-11-24 18:48:30 +00001668 if (ctx->DrawBuffer->Width == (GLint) buf_width &&
1669 ctx->DrawBuffer->Height == (GLint) buf_height)
Brian Paulfbd8f211999-11-11 01:22:25 +00001670 return;
1671
1672 ctx->NewState |= NEW_RASTER_OPS; /* to update scissor / window bounds */
1673
1674 /* save buffer size */
Brian Paul3f02f901999-11-24 18:48:30 +00001675 ctx->DrawBuffer->Width = buf_width;
1676 ctx->DrawBuffer->Height = buf_height;
Brian Paulfbd8f211999-11-11 01:22:25 +00001677
1678 /* Reallocate other buffers if needed. */
1679 if (ctx->Visual->DepthBits>0) {
1680 /* reallocate depth buffer */
1681 (*ctx->Driver.AllocDepthBuffer)( ctx );
1682 }
1683 if (ctx->Visual->StencilBits>0) {
1684 /* reallocate stencil buffer */
1685 gl_alloc_stencil_buffer( ctx );
1686 }
1687 if (ctx->Visual->AccumBits>0) {
1688 /* reallocate accum buffer */
1689 gl_alloc_accum_buffer( ctx );
1690 }
1691 if (ctx->Visual->SoftwareAlpha) {
1692 gl_alloc_alpha_buffers( ctx );
1693 }
1694}
1695
jtgafb833d1999-08-19 00:55:39 +00001696
1697
1698/**********************************************************************/
1699/***** Miscellaneous functions *****/
1700/**********************************************************************/
1701
1702
1703/*
1704 * This function is called when the Mesa user has stumbled into a code
1705 * path which may not be implemented fully or correctly.
1706 */
1707void gl_problem( const GLcontext *ctx, const char *s )
1708{
1709 fprintf( stderr, "Mesa implementation error: %s\n", s );
1710 fprintf( stderr, "Report to mesa-bugs@mesa3d.org\n" );
1711 (void) ctx;
1712}
1713
1714
1715
1716/*
1717 * This is called to inform the user that he or she has tried to do
1718 * something illogical or if there's likely a bug in their program
1719 * (like enabled depth testing without a depth buffer).
1720 */
1721void gl_warning( const GLcontext *ctx, const char *s )
1722{
1723 GLboolean debug;
1724#ifdef DEBUG
1725 debug = GL_TRUE;
1726#else
1727 if (getenv("MESA_DEBUG")) {
1728 debug = GL_TRUE;
1729 }
1730 else {
1731 debug = GL_FALSE;
1732 }
1733#endif
1734 if (debug) {
1735 fprintf( stderr, "Mesa warning: %s\n", s );
1736 }
1737 (void) ctx;
1738}
1739
1740
1741
1742void gl_compile_error( GLcontext *ctx, GLenum error, const char *s )
1743{
1744 if (ctx->CompileFlag)
1745 gl_save_error( ctx, error, s );
1746
1747 if (ctx->ExecuteFlag)
1748 gl_error( ctx, error, s );
1749}
1750
1751
1752/*
1753 * This is Mesa's error handler. Normally, all that's done is the updating
1754 * of the current error value. If Mesa is compiled with -DDEBUG or if the
1755 * environment variable "MESA_DEBUG" is defined then a real error message
1756 * is printed to stderr.
1757 * Input: error - the error value
1758 * s - a diagnostic string
1759 */
1760void gl_error( GLcontext *ctx, GLenum error, const char *s )
1761{
1762 GLboolean debug;
1763
1764#ifdef DEBUG
1765 debug = GL_TRUE;
1766#else
1767 if (getenv("MESA_DEBUG")) {
1768 debug = GL_TRUE;
1769 }
1770 else {
1771 debug = GL_FALSE;
1772 }
1773#endif
1774
1775 if (debug) {
1776 char errstr[1000];
1777
1778 switch (error) {
1779 case GL_NO_ERROR:
1780 strcpy( errstr, "GL_NO_ERROR" );
1781 break;
1782 case GL_INVALID_VALUE:
1783 strcpy( errstr, "GL_INVALID_VALUE" );
1784 break;
1785 case GL_INVALID_ENUM:
1786 strcpy( errstr, "GL_INVALID_ENUM" );
1787 break;
1788 case GL_INVALID_OPERATION:
1789 strcpy( errstr, "GL_INVALID_OPERATION" );
1790 break;
1791 case GL_STACK_OVERFLOW:
1792 strcpy( errstr, "GL_STACK_OVERFLOW" );
1793 break;
1794 case GL_STACK_UNDERFLOW:
1795 strcpy( errstr, "GL_STACK_UNDERFLOW" );
1796 break;
1797 case GL_OUT_OF_MEMORY:
1798 strcpy( errstr, "GL_OUT_OF_MEMORY" );
1799 break;
1800 default:
1801 strcpy( errstr, "unknown" );
1802 break;
1803 }
1804 fprintf( stderr, "Mesa user error: %s in %s\n", errstr, s );
1805 }
1806
1807 if (ctx->ErrorValue==GL_NO_ERROR) {
1808 ctx->ErrorValue = error;
1809 }
1810
1811 /* Call device driver's error handler, if any. This is used on the Mac. */
1812 if (ctx->Driver.Error) {
1813 (*ctx->Driver.Error)( ctx );
1814 }
1815}
1816
1817
1818
jtgafb833d1999-08-19 00:55:39 +00001819/**********************************************************************/
1820/***** State update logic *****/
1821/**********************************************************************/
1822
1823
1824/*
1825 * Since the device driver may or may not support pixel logic ops we
1826 * have to make some extensive tests to determine whether or not
1827 * software-implemented logic operations have to be used.
1828 */
1829static void update_pixel_logic( GLcontext *ctx )
1830{
1831 if (ctx->Visual->RGBAflag) {
1832 /* RGBA mode blending w/ Logic Op */
1833 if (ctx->Color.ColorLogicOpEnabled) {
1834 if (ctx->Driver.LogicOp
1835 && (*ctx->Driver.LogicOp)( ctx, ctx->Color.LogicOp )) {
1836 /* Device driver can do logic, don't have to do it in software */
1837 ctx->Color.SWLogicOpEnabled = GL_FALSE;
1838 }
1839 else {
1840 /* Device driver can't do logic op so we do it in software */
1841 ctx->Color.SWLogicOpEnabled = GL_TRUE;
1842 }
1843 }
1844 else {
1845 /* no logic op */
1846 if (ctx->Driver.LogicOp) {
1847 (void) (*ctx->Driver.LogicOp)( ctx, GL_COPY );
1848 }
1849 ctx->Color.SWLogicOpEnabled = GL_FALSE;
1850 }
1851 }
1852 else {
1853 /* CI mode Logic Op */
1854 if (ctx->Color.IndexLogicOpEnabled) {
1855 if (ctx->Driver.LogicOp
1856 && (*ctx->Driver.LogicOp)( ctx, ctx->Color.LogicOp )) {
1857 /* Device driver can do logic, don't have to do it in software */
1858 ctx->Color.SWLogicOpEnabled = GL_FALSE;
1859 }
1860 else {
1861 /* Device driver can't do logic op so we do it in software */
1862 ctx->Color.SWLogicOpEnabled = GL_TRUE;
1863 }
1864 }
1865 else {
1866 /* no logic op */
1867 if (ctx->Driver.LogicOp) {
1868 (void) (*ctx->Driver.LogicOp)( ctx, GL_COPY );
1869 }
1870 ctx->Color.SWLogicOpEnabled = GL_FALSE;
1871 }
1872 }
1873}
1874
1875
1876
1877/*
1878 * Check if software implemented RGBA or Color Index masking is needed.
1879 */
1880static void update_pixel_masking( GLcontext *ctx )
1881{
1882 if (ctx->Visual->RGBAflag) {
1883 GLuint *colorMask = (GLuint *) ctx->Color.ColorMask;
1884 if (*colorMask == 0xffffffff) {
1885 /* disable masking */
1886 if (ctx->Driver.ColorMask) {
1887 (void) (*ctx->Driver.ColorMask)( ctx, GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE );
1888 }
1889 ctx->Color.SWmasking = GL_FALSE;
1890 }
1891 else {
1892 /* Ask driver to do color masking, if it can't then
1893 * do it in software
1894 */
1895 GLboolean red = ctx->Color.ColorMask[RCOMP] ? GL_TRUE : GL_FALSE;
1896 GLboolean green = ctx->Color.ColorMask[GCOMP] ? GL_TRUE : GL_FALSE;
1897 GLboolean blue = ctx->Color.ColorMask[BCOMP] ? GL_TRUE : GL_FALSE;
1898 GLboolean alpha = ctx->Color.ColorMask[ACOMP] ? GL_TRUE : GL_FALSE;
1899 if (ctx->Driver.ColorMask
1900 && (*ctx->Driver.ColorMask)( ctx, red, green, blue, alpha )) {
1901 ctx->Color.SWmasking = GL_FALSE;
1902 }
1903 else {
1904 ctx->Color.SWmasking = GL_TRUE;
1905 }
1906 }
1907 }
1908 else {
1909 if (ctx->Color.IndexMask==0xffffffff) {
1910 /* disable masking */
1911 if (ctx->Driver.IndexMask) {
1912 (void) (*ctx->Driver.IndexMask)( ctx, 0xffffffff );
1913 }
1914 ctx->Color.SWmasking = GL_FALSE;
1915 }
1916 else {
1917 /* Ask driver to do index masking, if it can't then
1918 * do it in software
1919 */
1920 if (ctx->Driver.IndexMask
1921 && (*ctx->Driver.IndexMask)( ctx, ctx->Color.IndexMask )) {
1922 ctx->Color.SWmasking = GL_FALSE;
1923 }
1924 else {
1925 ctx->Color.SWmasking = GL_TRUE;
1926 }
1927 }
1928 }
1929}
1930
1931
1932static void update_fog_mode( GLcontext *ctx )
1933{
Keith Whitwell2be79c11999-08-26 14:50:49 +00001934 int old_mode = ctx->FogMode;
1935
jtgafb833d1999-08-19 00:55:39 +00001936 if (ctx->Fog.Enabled) {
1937 if (ctx->Texture.Enabled)
1938 ctx->FogMode = FOG_FRAGMENT;
1939 else if (ctx->Hint.Fog == GL_NICEST)
1940 ctx->FogMode = FOG_FRAGMENT;
1941 else
1942 ctx->FogMode = FOG_VERTEX;
1943
1944 if (ctx->Driver.GetParameteri)
1945 if ((ctx->Driver.GetParameteri)( ctx, DD_HAVE_HARDWARE_FOG ))
1946 ctx->FogMode = FOG_FRAGMENT;
1947 }
1948 else {
1949 ctx->FogMode = FOG_NONE;
1950 }
Keith Whitwell2be79c11999-08-26 14:50:49 +00001951
1952 if (old_mode != ctx->FogMode)
1953 ctx->NewState |= NEW_FOG;
jtgafb833d1999-08-19 00:55:39 +00001954}
1955
1956
1957/*
1958 * Recompute the value of ctx->RasterMask, etc. according to
1959 * the current context.
1960 */
1961static void update_rasterflags( GLcontext *ctx )
1962{
1963 ctx->RasterMask = 0;
1964
1965 if (ctx->Color.AlphaEnabled) ctx->RasterMask |= ALPHATEST_BIT;
1966 if (ctx->Color.BlendEnabled) ctx->RasterMask |= BLEND_BIT;
1967 if (ctx->Depth.Test) ctx->RasterMask |= DEPTH_BIT;
1968 if (ctx->FogMode==FOG_FRAGMENT) ctx->RasterMask |= FOG_BIT;
1969 if (ctx->Color.SWLogicOpEnabled) ctx->RasterMask |= LOGIC_OP_BIT;
1970 if (ctx->Scissor.Enabled) ctx->RasterMask |= SCISSOR_BIT;
1971 if (ctx->Stencil.Enabled) ctx->RasterMask |= STENCIL_BIT;
1972 if (ctx->Color.SWmasking) ctx->RasterMask |= MASKING_BIT;
1973
1974 if (ctx->Visual->SoftwareAlpha && ctx->Color.ColorMask[ACOMP]
1975 && ctx->Color.DrawBuffer != GL_NONE)
1976 ctx->RasterMask |= ALPHABUF_BIT;
1977
1978 if ( ctx->Viewport.X<0
Brian Paul3f02f901999-11-24 18:48:30 +00001979 || ctx->Viewport.X + ctx->Viewport.Width > ctx->DrawBuffer->Width
jtgafb833d1999-08-19 00:55:39 +00001980 || ctx->Viewport.Y<0
Brian Paul3f02f901999-11-24 18:48:30 +00001981 || ctx->Viewport.Y + ctx->Viewport.Height > ctx->DrawBuffer->Height) {
jtgafb833d1999-08-19 00:55:39 +00001982 ctx->RasterMask |= WINCLIP_BIT;
1983 }
1984
1985 /* If we're not drawing to exactly one color buffer set the
1986 * MULTI_DRAW_BIT flag. Also set it if we're drawing to no
1987 * buffers or the RGBA or CI mask disables all writes.
1988 */
1989
1990 ctx->TriangleCaps &= ~DD_MULTIDRAW;
1991
1992 if (ctx->Color.MultiDrawBuffer) {
1993 ctx->RasterMask |= MULTI_DRAW_BIT;
1994 ctx->TriangleCaps |= DD_MULTIDRAW;
1995 }
1996 else if (ctx->Color.DrawBuffer==GL_NONE) {
1997 ctx->RasterMask |= MULTI_DRAW_BIT;
1998 ctx->TriangleCaps |= DD_MULTIDRAW;
1999 }
2000 else if (ctx->Visual->RGBAflag && ctx->Color.ColorMask==0) {
2001 /* all RGBA channels disabled */
2002 ctx->RasterMask |= MULTI_DRAW_BIT;
2003 ctx->TriangleCaps |= DD_MULTIDRAW;
2004 ctx->Color.DrawDestMask = 0;
2005 }
2006 else if (!ctx->Visual->RGBAflag && ctx->Color.IndexMask==0) {
2007 /* all color index bits disabled */
2008 ctx->RasterMask |= MULTI_DRAW_BIT;
2009 ctx->TriangleCaps |= DD_MULTIDRAW;
2010 ctx->Color.DrawDestMask = 0;
2011 }
2012}
2013
2014
2015void gl_print_state( const char *msg, GLuint state )
2016{
2017 fprintf(stderr,
2018 "%s: (0x%x) %s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s\n",
2019 msg,
2020 state,
2021 (state & NEW_LIGHTING) ? "lighting, " : "",
2022 (state & NEW_RASTER_OPS) ? "raster-ops, " : "",
2023 (state & NEW_TEXTURING) ? "texturing, " : "",
2024 (state & NEW_POLYGON) ? "polygon, " : "",
2025 (state & NEW_DRVSTATE0) ? "driver-0, " : "",
2026 (state & NEW_DRVSTATE1) ? "driver-1, " : "",
2027 (state & NEW_DRVSTATE2) ? "driver-2, " : "",
2028 (state & NEW_DRVSTATE3) ? "driver-3, " : "",
2029 (state & NEW_MODELVIEW) ? "modelview, " : "",
2030 (state & NEW_PROJECTION) ? "projection, " : "",
2031 (state & NEW_TEXTURE_MATRIX) ? "texture-matrix, " : "",
2032 (state & NEW_USER_CLIP) ? "user-clip, " : "",
2033 (state & NEW_TEXTURE_ENV) ? "texture-env, " : "",
2034 (state & NEW_CLIENT_STATE) ? "client-state, " : "",
2035 (state & NEW_FOG) ? "fog, " : "",
2036 (state & NEW_NORMAL_TRANSFORM) ? "normal-transform, " : "",
2037 (state & NEW_VIEWPORT) ? "viewport, " : "",
2038 (state & NEW_TEXTURE_ENABLE) ? "texture-enable, " : "");
2039}
2040
2041void gl_print_enable_flags( const char *msg, GLuint flags )
2042{
2043 fprintf(stderr,
2044 "%s: (0x%x) %s%s%s%s%s%s%s%s%s%s%s\n",
2045 msg,
2046 flags,
2047 (flags & ENABLE_TEX0) ? "tex-0, " : "",
2048 (flags & ENABLE_TEX1) ? "tex-1, " : "",
2049 (flags & ENABLE_LIGHT) ? "light, " : "",
2050 (flags & ENABLE_FOG) ? "fog, " : "",
2051 (flags & ENABLE_USERCLIP) ? "userclip, " : "",
2052 (flags & ENABLE_TEXGEN0) ? "tex-gen-0, " : "",
2053 (flags & ENABLE_TEXGEN1) ? "tex-gen-1, " : "",
2054 (flags & ENABLE_TEXMAT0) ? "tex-mat-0, " : "",
2055 (flags & ENABLE_TEXMAT1) ? "tex-mat-1, " : "",
2056 (flags & ENABLE_NORMALIZE) ? "normalize, " : "",
2057 (flags & ENABLE_RESCALE) ? "rescale, " : "");
2058}
2059
2060
2061/*
2062 * If ctx->NewState is non-zero then this function MUST be called before
2063 * rendering any primitive. Basically, function pointers and miscellaneous
2064 * flags are updated to reflect the current state of the state machine.
2065 */
2066void gl_update_state( GLcontext *ctx )
2067{
2068 GLuint i;
2069
2070 if (MESA_VERBOSE & VERBOSE_STATE)
2071 gl_print_state("", ctx->NewState);
2072
2073 if (ctx->NewState & NEW_CLIENT_STATE)
2074 gl_update_client_state( ctx );
2075
2076 if ((ctx->NewState & NEW_TEXTURE_ENABLE) &&
2077 (ctx->Enabled & ENABLE_TEX_ANY) != ctx->Texture.Enabled)
2078 ctx->NewState |= NEW_TEXTURING | NEW_RASTER_OPS;
2079
2080 if (ctx->NewState & NEW_TEXTURE_ENV) {
2081 if (ctx->Texture.Unit[0].EnvMode == ctx->Texture.Unit[0].LastEnvMode &&
2082 ctx->Texture.Unit[1].EnvMode == ctx->Texture.Unit[1].LastEnvMode)
2083 ctx->NewState &= ~NEW_TEXTURE_ENV;
2084 ctx->Texture.Unit[0].LastEnvMode = ctx->Texture.Unit[0].EnvMode;
2085 ctx->Texture.Unit[1].LastEnvMode = ctx->Texture.Unit[1].EnvMode;
2086 }
2087
jtgafb833d1999-08-19 00:55:39 +00002088 if (ctx->NewState & NEW_TEXTURE_MATRIX) {
2089 ctx->Enabled &= ~(ENABLE_TEXMAT0|ENABLE_TEXMAT1);
2090
2091 for (i=0; i < MAX_TEXTURE_UNITS; i++) {
2092 if (ctx->TextureMatrix[i].flags & MAT_DIRTY_ALL_OVER)
2093 {
2094 gl_matrix_analyze( &ctx->TextureMatrix[i] );
2095 ctx->TextureMatrix[i].flags &= ~MAT_DIRTY_DEPENDENTS;
2096
2097 if (ctx->Texture.Unit[i].Enabled &&
2098 ctx->TextureMatrix[i].type != MATRIX_IDENTITY)
2099 ctx->Enabled |= ENABLE_TEXMAT0 << i;
2100 }
2101 }
2102 }
2103
Brian Paulece75ac1999-11-15 22:21:47 +00002104 if (ctx->NewState & (NEW_TEXTURING | NEW_TEXTURE_ENABLE)) {
jtgafb833d1999-08-19 00:55:39 +00002105 ctx->Texture.NeedNormals = GL_FALSE;
2106 gl_update_dirty_texobjs(ctx);
2107 ctx->Enabled &= ~(ENABLE_TEXGEN0|ENABLE_TEXGEN1);
2108 ctx->Texture.ReallyEnabled = 0;
2109
2110 for (i=0; i < MAX_TEXTURE_UNITS; i++) {
2111 if (ctx->Texture.Unit[i].Enabled) {
2112 gl_update_texture_unit( ctx, &ctx->Texture.Unit[i] );
2113
2114 ctx->Texture.ReallyEnabled |=
2115 ctx->Texture.Unit[i].ReallyEnabled<<(i*4);
2116
2117 if (ctx->Texture.Unit[i].GenFlags != 0) {
2118 ctx->Enabled |= ENABLE_TEXGEN0 << i;
2119
2120 if (ctx->Texture.Unit[i].GenFlags & TEXGEN_NEED_NORMALS)
2121 {
2122 ctx->Texture.NeedNormals = GL_TRUE;
2123 ctx->Texture.NeedEyeCoords = GL_TRUE;
2124 }
2125
2126 if (ctx->Texture.Unit[i].GenFlags & TEXGEN_NEED_EYE_COORD)
2127 {
2128 ctx->Texture.NeedEyeCoords = GL_TRUE;
2129 }
2130 }
2131 }
2132 }
2133
2134 ctx->Texture.Enabled = ctx->Enabled & ENABLE_TEX_ANY;
2135 ctx->NeedNormals = (ctx->Light.Enabled || ctx->Texture.NeedNormals);
2136 }
2137
Keith Whitwell2be79c11999-08-26 14:50:49 +00002138 if (ctx->NewState & (NEW_RASTER_OPS | NEW_LIGHTING | NEW_FOG)) {
2139
2140
jtgafb833d1999-08-19 00:55:39 +00002141 if (ctx->NewState & NEW_RASTER_OPS) {
2142 update_pixel_logic(ctx);
2143 update_pixel_masking(ctx);
2144 update_fog_mode(ctx);
2145 update_rasterflags(ctx);
2146 if (ctx->Driver.Dither) {
2147 (*ctx->Driver.Dither)( ctx, ctx->Color.DitherFlag );
2148 }
2149
2150 /* Check if incoming colors can be modified during rasterization */
2151 if (ctx->Fog.Enabled ||
2152 ctx->Texture.Enabled ||
2153 ctx->Color.BlendEnabled ||
2154 ctx->Color.SWmasking ||
2155 ctx->Color.SWLogicOpEnabled) {
2156 ctx->MutablePixels = GL_TRUE;
2157 }
2158 else {
2159 ctx->MutablePixels = GL_FALSE;
2160 }
2161
2162 /* update scissor region */
2163
Brian Paul3f02f901999-11-24 18:48:30 +00002164 ctx->DrawBuffer->Xmin = 0;
2165 ctx->DrawBuffer->Ymin = 0;
2166 ctx->DrawBuffer->Xmax = ctx->DrawBuffer->Width-1;
2167 ctx->DrawBuffer->Ymax = ctx->DrawBuffer->Height-1;
jtgafb833d1999-08-19 00:55:39 +00002168 if (ctx->Scissor.Enabled) {
Brian Paul3f02f901999-11-24 18:48:30 +00002169 if (ctx->Scissor.X > ctx->DrawBuffer->Xmin) {
2170 ctx->DrawBuffer->Xmin = ctx->Scissor.X;
jtgafb833d1999-08-19 00:55:39 +00002171 }
Brian Paul3f02f901999-11-24 18:48:30 +00002172 if (ctx->Scissor.Y > ctx->DrawBuffer->Ymin) {
2173 ctx->DrawBuffer->Ymin = ctx->Scissor.Y;
jtgafb833d1999-08-19 00:55:39 +00002174 }
Brian Paul3f02f901999-11-24 18:48:30 +00002175 if (ctx->Scissor.X + ctx->Scissor.Width - 1 < ctx->DrawBuffer->Xmax) {
2176 ctx->DrawBuffer->Xmax = ctx->Scissor.X + ctx->Scissor.Width - 1;
jtgafb833d1999-08-19 00:55:39 +00002177 }
Brian Paul3f02f901999-11-24 18:48:30 +00002178 if (ctx->Scissor.Y + ctx->Scissor.Height - 1 < ctx->DrawBuffer->Ymax) {
2179 ctx->DrawBuffer->Ymax = ctx->Scissor.Y + ctx->Scissor.Height - 1;
jtgafb833d1999-08-19 00:55:39 +00002180 }
2181 }
2182
Keith Whitwell324beb91999-09-04 14:40:49 +00002183 /* The driver isn't managing the depth buffer.
jtgafb833d1999-08-19 00:55:39 +00002184 */
Keith Whitwell324beb91999-09-04 14:40:49 +00002185 if (ctx->Driver.AllocDepthBuffer == gl_alloc_depth_buffer)
2186 {
2187 if (ctx->Depth.Mask) {
2188 switch (ctx->Depth.Func) {
2189 case GL_LESS:
2190 ctx->Driver.DepthTestSpan = gl_depth_test_span_less;
2191 ctx->Driver.DepthTestPixels = gl_depth_test_pixels_less;
2192 break;
2193 case GL_GREATER:
2194 ctx->Driver.DepthTestSpan = gl_depth_test_span_greater;
2195 ctx->Driver.DepthTestPixels = gl_depth_test_pixels_greater;
2196 break;
2197 default:
2198 ctx->Driver.DepthTestSpan = gl_depth_test_span_generic;
2199 ctx->Driver.DepthTestPixels = gl_depth_test_pixels_generic;
2200 }
2201 }
2202 else {
jtgafb833d1999-08-19 00:55:39 +00002203 ctx->Driver.DepthTestSpan = gl_depth_test_span_generic;
2204 ctx->Driver.DepthTestPixels = gl_depth_test_pixels_generic;
2205 }
2206 }
jtgafb833d1999-08-19 00:55:39 +00002207 }
2208
2209 if (ctx->NewState & NEW_LIGHTING) {
Keith Whitwell2be79c11999-08-26 14:50:49 +00002210 ctx->TriangleCaps &= ~(DD_TRI_LIGHT_TWOSIDE|DD_LIGHTING_CULL);
jtgafb833d1999-08-19 00:55:39 +00002211 if (ctx->Light.Enabled) {
2212 if (ctx->Light.Model.TwoSide)
Keith Whitwell2be79c11999-08-26 14:50:49 +00002213 ctx->TriangleCaps |= (DD_TRI_LIGHT_TWOSIDE|DD_LIGHTING_CULL);
jtgafb833d1999-08-19 00:55:39 +00002214 gl_update_lighting(ctx);
2215 }
2216 }
2217 }
2218
2219 if (ctx->NewState & (NEW_POLYGON | NEW_LIGHTING)) {
2220
Keith Whitwellb6e69371999-09-02 13:16:17 +00002221 ctx->TriangleCaps &= ~DD_TRI_CULL_FRONT_BACK;
jtgafb833d1999-08-19 00:55:39 +00002222
2223 if (ctx->NewState & NEW_POLYGON) {
2224 /* Setup CullBits bitmask */
2225 if (ctx->Polygon.CullFlag) {
Keith Whitwell2be79c11999-08-26 14:50:49 +00002226 ctx->backface_sign = 1;
jtgafb833d1999-08-19 00:55:39 +00002227 switch(ctx->Polygon.CullFaceMode) {
jtgafb833d1999-08-19 00:55:39 +00002228 case GL_BACK:
Keith Whitwell2be79c11999-08-26 14:50:49 +00002229 if(ctx->Polygon.FrontFace==GL_CCW)
2230 ctx->backface_sign = -1;
jtgafb833d1999-08-19 00:55:39 +00002231 ctx->Polygon.CullBits = 1;
2232 break;
Keith Whitwell2be79c11999-08-26 14:50:49 +00002233 case GL_FRONT:
2234 if(ctx->Polygon.FrontFace!=GL_CCW)
2235 ctx->backface_sign = -1;
2236 ctx->Polygon.CullBits = 2;
2237 break;
jtgafb833d1999-08-19 00:55:39 +00002238 default:
2239 case GL_FRONT_AND_BACK:
Keith Whitwell2be79c11999-08-26 14:50:49 +00002240 ctx->backface_sign = 0;
Keith Whitwellb6e69371999-09-02 13:16:17 +00002241 ctx->Polygon.CullBits = 0;
2242 ctx->TriangleCaps |= DD_TRI_CULL_FRONT_BACK;
jtgafb833d1999-08-19 00:55:39 +00002243 break;
2244 }
2245 }
Keith Whitwell2be79c11999-08-26 14:50:49 +00002246 else {
jtgafb833d1999-08-19 00:55:39 +00002247 ctx->Polygon.CullBits = 3;
Keith Whitwell2be79c11999-08-26 14:50:49 +00002248 ctx->backface_sign = 0;
2249 }
jtgafb833d1999-08-19 00:55:39 +00002250
2251 /* Any Polygon offsets enabled? */
2252 ctx->TriangleCaps &= ~DD_TRI_OFFSET;
2253
2254 if (ctx->Polygon.OffsetPoint ||
2255 ctx->Polygon.OffsetLine ||
2256 ctx->Polygon.OffsetFill)
2257 ctx->TriangleCaps |= DD_TRI_OFFSET;
2258
2259 /* reset Z offsets now */
2260 ctx->PointZoffset = 0.0;
2261 ctx->LineZoffset = 0.0;
2262 ctx->PolygonZoffset = 0.0;
2263 }
2264 }
2265
Brian Paulece75ac1999-11-15 22:21:47 +00002266 if (ctx->NewState & ~(NEW_CLIENT_STATE|
jtgafb833d1999-08-19 00:55:39 +00002267 NEW_DRIVER_STATE|NEW_USER_CLIP|
2268 NEW_POLYGON))
2269 gl_update_clipmask(ctx);
2270
2271 if (ctx->NewState & (NEW_LIGHTING|
2272 NEW_RASTER_OPS|
2273 NEW_TEXTURING|
Brian Paulece75ac1999-11-15 22:21:47 +00002274 NEW_TEXTURE_ENABLE|
jtgafb833d1999-08-19 00:55:39 +00002275 NEW_TEXTURE_ENV|
2276 NEW_POLYGON|
2277 NEW_DRVSTATE0|
2278 NEW_DRVSTATE1|
2279 NEW_DRVSTATE2|
2280 NEW_DRVSTATE3|
2281 NEW_USER_CLIP))
2282 {
2283 ctx->IndirectTriangles = ctx->TriangleCaps & ~ctx->Driver.TriangleCaps;
2284 ctx->IndirectTriangles |= DD_SW_RASTERIZE;
2285
Keith Whitwell2be79c11999-08-26 14:50:49 +00002286 if (MESA_VERBOSE&VERBOSE_CULL)
2287 gl_print_tri_caps("initial indirect tris", ctx->IndirectTriangles);
2288
jtgafb833d1999-08-19 00:55:39 +00002289 ctx->Driver.PointsFunc = NULL;
2290 ctx->Driver.LineFunc = NULL;
2291 ctx->Driver.TriangleFunc = NULL;
2292 ctx->Driver.QuadFunc = NULL;
2293 ctx->Driver.RectFunc = NULL;
2294 ctx->Driver.RenderVBClippedTab = NULL;
2295 ctx->Driver.RenderVBCulledTab = NULL;
2296 ctx->Driver.RenderVBRawTab = NULL;
2297
2298 /*
2299 * Here the driver sets up all the ctx->Driver function pointers to
2300 * it's specific, private functions.
2301 */
2302 ctx->Driver.UpdateState(ctx);
2303
Keith Whitwell2be79c11999-08-26 14:50:49 +00002304 if (MESA_VERBOSE&VERBOSE_CULL)
2305 gl_print_tri_caps("indirect tris", ctx->IndirectTriangles);
2306
jtgafb833d1999-08-19 00:55:39 +00002307 /*
2308 * In case the driver didn't hook in an optimized point, line or
2309 * triangle function we'll now select "core/fallback" point, line
2310 * and triangle functions.
2311 */
2312 if (ctx->IndirectTriangles & DD_SW_RASTERIZE) {
2313 gl_set_point_function(ctx);
2314 gl_set_line_function(ctx);
2315 gl_set_triangle_function(ctx);
2316 gl_set_quad_function(ctx);
Keith Whitwell2be79c11999-08-26 14:50:49 +00002317
2318 if ((ctx->IndirectTriangles &
2319 (DD_TRI_SW_RASTERIZE|DD_QUAD_SW_RASTERIZE|DD_TRI_CULL)) ==
2320 (DD_TRI_SW_RASTERIZE|DD_QUAD_SW_RASTERIZE|DD_TRI_CULL))
2321 ctx->IndirectTriangles &= ~DD_TRI_CULL;
jtgafb833d1999-08-19 00:55:39 +00002322 }
2323
Keith Whitwell2be79c11999-08-26 14:50:49 +00002324 if (MESA_VERBOSE&VERBOSE_CULL)
2325 gl_print_tri_caps("indirect tris 2", ctx->IndirectTriangles);
2326
jtgafb833d1999-08-19 00:55:39 +00002327 gl_set_render_vb_function(ctx);
2328 }
2329
2330 /* Should only be calc'd when !need_eye_coords and not culling.
2331 */
2332 if (ctx->NewState & (NEW_MODELVIEW|NEW_PROJECTION)) {
2333 if (ctx->NewState & NEW_MODELVIEW) {
2334 gl_matrix_analyze( &ctx->ModelView );
2335 ctx->ProjectionMatrix.flags &= ~MAT_DIRTY_DEPENDENTS;
2336 }
2337
2338 if (ctx->NewState & NEW_PROJECTION) {
2339 gl_matrix_analyze( &ctx->ProjectionMatrix );
2340 ctx->ProjectionMatrix.flags &= ~MAT_DIRTY_DEPENDENTS;
2341
2342 if (ctx->Transform.AnyClip) {
2343 gl_update_userclip( ctx );
2344 }
2345 }
2346
2347 gl_calculate_model_project_matrix( ctx );
2348 ctx->ModelProjectWinMatrixUptodate = 0;
2349 }
2350
2351 /* Figure out whether we can light in object space or not. If we
2352 * can, find the current positions of the lights in object space
2353 */
Keith Whitwell2be79c11999-08-26 14:50:49 +00002354 if ((ctx->Enabled & (ENABLE_POINT_ATTEN | ENABLE_LIGHT | ENABLE_FOG |
jtgafb833d1999-08-19 00:55:39 +00002355 ENABLE_TEXGEN0 | ENABLE_TEXGEN1)) &&
2356 (ctx->NewState & (NEW_LIGHTING |
Keith Whitwell2be79c11999-08-26 14:50:49 +00002357 NEW_FOG |
jtgafb833d1999-08-19 00:55:39 +00002358 NEW_MODELVIEW |
2359 NEW_PROJECTION |
2360 NEW_TEXTURING |
2361 NEW_RASTER_OPS |
2362 NEW_USER_CLIP)))
2363 {
2364 GLboolean oldcoord, oldnorm;
2365
2366 oldcoord = ctx->NeedEyeCoords;
2367 oldnorm = ctx->NeedEyeNormals;
2368
2369 ctx->NeedNormals = (ctx->Light.Enabled || ctx->Texture.NeedNormals);
2370 ctx->NeedEyeCoords = ((ctx->Fog.Enabled && ctx->Hint.Fog != GL_NICEST) ||
2371 ctx->Point.Attenuated);
2372 ctx->NeedEyeNormals = GL_FALSE;
2373
2374 if (ctx->Light.Enabled) {
2375 if (ctx->Light.Flags & LIGHT_POSITIONAL) {
2376 /* Need length for attenuation */
2377 if (!TEST_MAT_FLAGS( &ctx->ModelView, MAT_FLAGS_LENGTH_PRESERVING))
2378 ctx->NeedEyeCoords = GL_TRUE;
2379 } else if (ctx->Light.NeedVertices) {
2380 /* Need angle for spot calculations */
2381 if (!TEST_MAT_FLAGS( &ctx->ModelView, MAT_FLAGS_ANGLE_PRESERVING))
2382 ctx->NeedEyeCoords = GL_TRUE;
2383 }
2384 ctx->NeedEyeNormals = ctx->NeedEyeCoords;
2385 }
2386 if (ctx->Texture.Enabled || ctx->RenderMode==GL_FEEDBACK) {
2387 if (ctx->Texture.NeedEyeCoords) ctx->NeedEyeCoords = GL_TRUE;
2388 if (ctx->Texture.NeedNormals)
2389 ctx->NeedNormals = ctx->NeedEyeNormals = GL_TRUE;
2390 }
2391
2392 ctx->vb_proj_matrix = &ctx->ModelProjectMatrix;
2393
2394 if (ctx->NeedEyeCoords)
2395 ctx->vb_proj_matrix = &ctx->ProjectionMatrix;
2396
2397 if (ctx->Light.Enabled) {
2398 gl_update_lighting_function(ctx);
2399
2400 if ( (ctx->NewState & NEW_LIGHTING) ||
2401 ((ctx->NewState & (NEW_MODELVIEW| NEW_PROJECTION)) &&
2402 !ctx->NeedEyeCoords) ||
2403 oldcoord != ctx->NeedEyeCoords ||
2404 oldnorm != ctx->NeedEyeNormals) {
2405 gl_compute_light_positions(ctx);
2406 }
2407
2408 ctx->rescale_factor = 1.0F;
2409
2410 if (ctx->ModelView.flags & (MAT_FLAG_UNIFORM_SCALE |
2411 MAT_FLAG_GENERAL_SCALE |
2412 MAT_FLAG_GENERAL_3D |
2413 MAT_FLAG_GENERAL) )
2414
2415 {
2416 GLfloat *m = ctx->ModelView.inv;
2417 GLfloat f = m[2]*m[2] + m[6]*m[6] + m[10]*m[10];
2418 if (f > 1e-12 && (f-1)*(f-1) > 1e-12)
2419 ctx->rescale_factor = 1.0/GL_SQRT(f);
2420 }
2421 }
2422
2423 gl_update_normal_transform( ctx );
2424 }
2425
jtgafb833d1999-08-19 00:55:39 +00002426 gl_update_pipelines(ctx);
2427 ctx->NewState = 0;
2428}