Changes to reduce the memory footprint of display lists
[mesa.git] / src / mesa / drivers / glide / fxsetup.c
1 /* -*- mode: C; tab-width:8; -*-
2
3 fxsetup.c - 3Dfx VooDoo rendering mode setup functions
4 */
5
6 /*
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Library General Public
9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Library General Public License for more details.
16 *
17 * You should have received a copy of the GNU Library General Public
18 * License along with this library; if not, write to the Free
19 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 *
21 * See the file fxapi.c for more informations about authors
22 *
23 */
24
25 #ifdef HAVE_CONFIG_H
26 #include "conf.h"
27 #endif
28
29 #if defined(FX)
30
31 #include "fxdrv.h"
32 #include "enums.h"
33
34 static void fxTexValidate(GLcontext *ctx, struct gl_texture_object *tObj)
35 {
36 tfxTexInfo *ti=(tfxTexInfo *)tObj->DriverData;
37 GLint minl,maxl;
38
39 if (MESA_VERBOSE&VERBOSE_DRIVER)
40 fprintf(stderr,"fxmesa: fxTexValidate(...) Start\n");
41
42
43 if(ti->validated) {
44 if (MESA_VERBOSE&VERBOSE_DRIVER) {
45 fprintf(stderr,"fxmesa: fxTexValidate(...) End (validated=GL_TRUE)\n");
46 }
47 return;
48 }
49
50 minl=ti->minLevel=tObj->BaseLevel;
51 maxl=ti->maxLevel=MIN2(tObj->MaxLevel,tObj->Image[0]->MaxLog2);
52
53
54 fxTexGetInfo(tObj->Image[minl]->Width,tObj->Image[minl]->Height,
55 &(FX_largeLodLog2(ti->info)),&(FX_aspectRatioLog2(ti->info)),
56 &(ti->sScale),&(ti->tScale),
57 &(ti->int_sScale),&(ti->int_tScale),
58 NULL,NULL);
59
60 if((tObj->MinFilter!=GL_NEAREST) && (tObj->MinFilter!=GL_LINEAR))
61 fxTexGetInfo(tObj->Image[maxl]->Width,tObj->Image[maxl]->Height,
62 &(FX_smallLodLog2(ti->info)),NULL,
63 NULL,NULL,
64 NULL,NULL,
65 NULL,NULL);
66 else
67 FX_smallLodLog2(ti->info)=FX_largeLodLog2(ti->info);
68
69 fxTexGetFormat(tObj->Image[minl]->Format,&(ti->info.format),&(ti->baseLevelInternalFormat));
70
71 ti->validated=GL_TRUE;
72
73 ti->info.data=NULL;
74
75 if (MESA_VERBOSE&VERBOSE_DRIVER) {
76 fprintf(stderr,"fxmesa: fxTexValidate(...) End\n");
77 }
78 }
79
80 static void fxPrintUnitsMode( const char *msg, GLuint mode )
81 {
82 fprintf(stderr,
83 "%s: (0x%x) %s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s\n",
84 msg,
85 mode,
86 (mode & FX_UM_E0_REPLACE) ? "E0_REPLACE, " : "",
87 (mode & FX_UM_E0_MODULATE) ? "E0_MODULATE, " : "",
88 (mode & FX_UM_E0_DECAL) ? "E0_DECAL, " : "",
89 (mode & FX_UM_E0_BLEND) ? "E0_BLEND, " : "",
90 (mode & FX_UM_E1_REPLACE) ? "E1_REPLACE, " : "",
91 (mode & FX_UM_E1_MODULATE) ? "E1_MODULATE, " : "",
92 (mode & FX_UM_E1_DECAL) ? "E1_DECAL, " : "",
93 (mode & FX_UM_E1_BLEND) ? "E1_BLEND, " : "",
94 (mode & FX_UM_E0_ALPHA) ? "E0_ALPHA, " : "",
95 (mode & FX_UM_E0_LUMINANCE) ? "E0_LUMINANCE, " : "",
96 (mode & FX_UM_E0_LUMINANCE_ALPHA) ? "E0_LUMINANCE_ALPHA, " : "",
97 (mode & FX_UM_E0_INTENSITY) ? "E0_INTENSITY, " : "",
98 (mode & FX_UM_E0_RGB) ? "E0_RGB, " : "",
99 (mode & FX_UM_E0_RGBA) ? "E0_RGBA, " : "",
100 (mode & FX_UM_E1_ALPHA) ? "E1_ALPHA, " : "",
101 (mode & FX_UM_E1_LUMINANCE) ? "E1_LUMINANCE, " : "",
102 (mode & FX_UM_E1_LUMINANCE_ALPHA) ? "E1_LUMINANCE_ALPHA, " : "",
103 (mode & FX_UM_E1_INTENSITY) ? "E1_INTENSITY, " : "",
104 (mode & FX_UM_E1_RGB) ? "E1_RGB, " : "",
105 (mode & FX_UM_E1_RGBA) ? "E1_RGBA, " : "",
106 (mode & FX_UM_COLOR_ITERATED) ? "COLOR_ITERATED, " : "",
107 (mode & FX_UM_COLOR_CONSTANT) ? "COLOR_CONSTANT, " : "",
108 (mode & FX_UM_ALPHA_ITERATED) ? "ALPHA_ITERATED, " : "",
109 (mode & FX_UM_ALPHA_CONSTANT) ? "ALPHA_CONSTANT, " : "");
110 }
111
112 GLuint fxGetTexSetConfiguration(GLcontext *ctx,
113 struct gl_texture_object *tObj0,
114 struct gl_texture_object *tObj1)
115 {
116 GLuint unitsmode=0;
117 GLuint envmode=0;
118 GLuint ifmt=0;
119
120 if((ctx->Light.ShadeModel==GL_SMOOTH) ||
121 (ctx->Point.SmoothFlag) ||
122 (ctx->Line.SmoothFlag) ||
123 (ctx->Polygon.SmoothFlag))
124 unitsmode|=FX_UM_ALPHA_ITERATED;
125 else
126 unitsmode|=FX_UM_ALPHA_CONSTANT;
127
128 if(ctx->Light.ShadeModel==GL_SMOOTH)
129 unitsmode|=FX_UM_COLOR_ITERATED;
130 else
131 unitsmode|=FX_UM_COLOR_CONSTANT;
132
133 if(tObj0) {
134 tfxTexInfo *ti0=(tfxTexInfo *)tObj0->DriverData;
135
136 switch(ti0->baseLevelInternalFormat) {
137 case GL_ALPHA:
138 ifmt|=FX_UM_E0_ALPHA;
139 break;
140 case GL_LUMINANCE:
141 ifmt|=FX_UM_E0_LUMINANCE;
142 break;
143 case GL_LUMINANCE_ALPHA:
144 ifmt|=FX_UM_E0_LUMINANCE_ALPHA;
145 break;
146 case GL_INTENSITY:
147 ifmt|=FX_UM_E0_INTENSITY;
148 break;
149 case GL_RGB:
150 ifmt|=FX_UM_E0_RGB;
151 break;
152 case GL_RGBA:
153 ifmt|=FX_UM_E0_RGBA;
154 break;
155 }
156
157 switch(ctx->Texture.Unit[0].EnvMode) {
158 case GL_DECAL:
159 envmode|=FX_UM_E0_DECAL;
160 break;
161 case GL_MODULATE:
162 envmode|=FX_UM_E0_MODULATE;
163 break;
164 case GL_REPLACE:
165 envmode|=FX_UM_E0_REPLACE;
166 break;
167 case GL_BLEND:
168 envmode|=FX_UM_E0_BLEND;
169 break;
170 case GL_ADD:
171 envmode|=FX_UM_E0_ADD;
172 break;
173 default:
174 /* do nothing */
175 break;
176 }
177 }
178
179 if(tObj1) {
180 tfxTexInfo *ti1=(tfxTexInfo *)tObj1->DriverData;
181
182 switch(ti1->baseLevelInternalFormat) {
183 case GL_ALPHA:
184 ifmt|=FX_UM_E1_ALPHA;
185 break;
186 case GL_LUMINANCE:
187 ifmt|=FX_UM_E1_LUMINANCE;
188 break;
189 case GL_LUMINANCE_ALPHA:
190 ifmt|=FX_UM_E1_LUMINANCE_ALPHA;
191 break;
192 case GL_INTENSITY:
193 ifmt|=FX_UM_E1_INTENSITY;
194 break;
195 case GL_RGB:
196 ifmt|=FX_UM_E1_RGB;
197 break;
198 case GL_RGBA:
199 ifmt|=FX_UM_E1_RGBA;
200 break;
201 default:
202 /* do nothing */
203 break;
204 }
205
206 switch(ctx->Texture.Unit[1].EnvMode) {
207 case GL_DECAL:
208 envmode|=FX_UM_E1_DECAL;
209 break;
210 case GL_MODULATE:
211 envmode|=FX_UM_E1_MODULATE;
212 break;
213 case GL_REPLACE:
214 envmode|=FX_UM_E1_REPLACE;
215 break;
216 case GL_BLEND:
217 envmode|=FX_UM_E1_BLEND;
218 break;
219 case GL_ADD:
220 envmode|=FX_UM_E1_ADD;
221 break;
222 default:
223 /* do nothing */
224 break;
225 }
226 }
227
228 unitsmode|=(ifmt | envmode);
229
230 if (MESA_VERBOSE & (VERBOSE_DRIVER|VERBOSE_TEXTURE))
231 fxPrintUnitsMode("unitsmode", unitsmode);
232
233 return unitsmode;
234 }
235
236 /************************************************************************/
237 /************************* Rendering Mode SetUp *************************/
238 /************************************************************************/
239
240 /************************* Single Texture Set ***************************/
241
242 static void fxSetupSingleTMU(fxMesaContext fxMesa, struct gl_texture_object *tObj)
243 {
244 tfxTexInfo *ti=(tfxTexInfo *)tObj->DriverData;
245
246 if(!ti->tmi.isInTM) {
247 if(ti->LODblend)
248 fxTMMoveInTM(fxMesa,tObj,FX_TMU_SPLIT);
249 else {
250 if(fxMesa->haveTwoTMUs) {
251 if(fxMesa->freeTexMem[FX_TMU0]>grTexTextureMemRequired(GR_MIPMAPLEVELMASK_BOTH,&(ti->info)))
252 fxTMMoveInTM(fxMesa,tObj,FX_TMU0);
253 else
254 fxTMMoveInTM(fxMesa,tObj,FX_TMU1);
255 } else
256 fxTMMoveInTM(fxMesa,tObj,FX_TMU0);
257 }
258 }
259
260 if(ti->LODblend && ti->tmi.whichTMU == FX_TMU_SPLIT) {
261 if((ti->info.format==GR_TEXFMT_P_8) && (!fxMesa->haveGlobalPaletteTexture)) {
262 if (MESA_VERBOSE&VERBOSE_DRIVER) {
263 fprintf(stderr,"fxmesa: uploading texture palette\n");
264 }
265 FX_grTexDownloadTable(GR_TMU0,GR_TEXTABLE_PALETTE,&(ti->palette));
266 FX_grTexDownloadTable(GR_TMU1,GR_TEXTABLE_PALETTE,&(ti->palette));
267 }
268
269 grTexClampMode(GR_TMU0,ti->sClamp,ti->tClamp);
270 grTexClampMode(GR_TMU1,ti->sClamp,ti->tClamp);
271 grTexFilterMode(GR_TMU0,ti->minFilt,ti->maxFilt);
272 grTexFilterMode(GR_TMU1,ti->minFilt,ti->maxFilt);
273 grTexMipMapMode(GR_TMU0,ti->mmMode,ti->LODblend);
274 grTexMipMapMode(GR_TMU1,ti->mmMode,ti->LODblend);
275
276 grTexSource(GR_TMU0,ti->tmi.tm[FX_TMU0]->startAddress,
277 GR_MIPMAPLEVELMASK_ODD,&(ti->info));
278 grTexSource(GR_TMU1,ti->tmi.tm[FX_TMU1]->startAddress,
279 GR_MIPMAPLEVELMASK_EVEN,&(ti->info));
280 } else {
281 if((ti->info.format==GR_TEXFMT_P_8) && (!fxMesa->haveGlobalPaletteTexture)) {
282 if (MESA_VERBOSE&VERBOSE_DRIVER) {
283 fprintf(stderr,"fxmesa: uploading texture palette\n");
284 }
285 FX_grTexDownloadTable(ti->tmi.whichTMU,GR_TEXTABLE_PALETTE,&(ti->palette));
286 }
287
288 /* KW: The alternative is to do the download to the other tmu. If
289 * we get to this point, I think it means we are thrashing the
290 * texture memory, so perhaps it's not a good idea.
291 */
292 if (ti->LODblend && (MESA_VERBOSE&VERBOSE_DRIVER))
293 fprintf(stderr, "fxmesa: not blending texture - only on one tmu\n");
294
295
296 grTexClampMode(ti->tmi.whichTMU,ti->sClamp,ti->tClamp);
297 grTexFilterMode(ti->tmi.whichTMU,ti->minFilt,ti->maxFilt);
298 grTexMipMapMode(ti->tmi.whichTMU,ti->mmMode,FXFALSE);
299
300 grTexSource(ti->tmi.whichTMU,ti->tmi.tm[ti->tmi.whichTMU]->startAddress,
301 GR_MIPMAPLEVELMASK_BOTH,&(ti->info));
302 }
303 }
304
305 static void fxSelectSingleTMUSrc(fxMesaContext fxMesa, GLint tmu, FxBool LODblend)
306 {
307 if (MESA_VERBOSE&VERBOSE_DRIVER) {
308 fprintf(stderr,"fxmesa: fxSelectSingleTMUSrc(%d,%d)\n",tmu,LODblend);
309 }
310
311 if(LODblend) {
312 grTexCombine(GR_TMU0,
313 GR_COMBINE_FUNCTION_BLEND,
314 GR_COMBINE_FACTOR_ONE_MINUS_LOD_FRACTION,
315 GR_COMBINE_FUNCTION_BLEND,
316 GR_COMBINE_FACTOR_ONE_MINUS_LOD_FRACTION,
317 FXFALSE,FXFALSE);
318
319 grTexCombine(GR_TMU1,
320 GR_COMBINE_FUNCTION_LOCAL,GR_COMBINE_FACTOR_NONE,
321 GR_COMBINE_FUNCTION_LOCAL,GR_COMBINE_FACTOR_NONE,
322 FXFALSE,FXFALSE);
323
324 fxMesa->tmuSrc=FX_TMU_SPLIT;
325 } else {
326 if(tmu==FX_TMU0) {
327 grTexCombine(GR_TMU0,
328 GR_COMBINE_FUNCTION_LOCAL,GR_COMBINE_FACTOR_NONE,
329 GR_COMBINE_FUNCTION_LOCAL,GR_COMBINE_FACTOR_NONE,
330 FXFALSE,FXFALSE);
331
332 fxMesa->tmuSrc=FX_TMU0;
333 } else {
334 grTexCombine(GR_TMU1,
335 GR_COMBINE_FUNCTION_LOCAL,GR_COMBINE_FACTOR_NONE,
336 GR_COMBINE_FUNCTION_LOCAL,GR_COMBINE_FACTOR_NONE,
337 FXFALSE,FXFALSE);
338
339 /* GR_COMBINE_FUNCTION_SCALE_OTHER doesn't work ?!? */
340
341 grTexCombine(GR_TMU0,
342 GR_COMBINE_FUNCTION_BLEND,GR_COMBINE_FACTOR_ONE,
343 GR_COMBINE_FUNCTION_BLEND,GR_COMBINE_FACTOR_ONE,
344 FXFALSE,FXFALSE);
345
346 fxMesa->tmuSrc=FX_TMU1;
347 }
348 }
349 }
350
351 void fxSetupTextureSingleTMU(GLcontext *ctx, GLuint textureset)
352 {
353 fxMesaContext fxMesa=(fxMesaContext)ctx->DriverCtx;
354 GrCombineLocal_t localc,locala;
355 GLuint unitsmode;
356 GLint ifmt;
357 tfxTexInfo *ti;
358 struct gl_texture_object *tObj=ctx->Texture.Unit[textureset].CurrentD[2];
359
360 if (MESA_VERBOSE&VERBOSE_DRIVER)
361 fprintf(stderr,"fxmesa: fxSetupTextureSingleTMU(...) Start\n");
362
363
364 ti=(tfxTexInfo *)tObj->DriverData;
365
366 fxTexValidate(ctx,tObj);
367
368 fxSetupSingleTMU(fxMesa,tObj);
369
370 if(fxMesa->tmuSrc!=ti->tmi.whichTMU)
371 fxSelectSingleTMUSrc(fxMesa,ti->tmi.whichTMU,ti->LODblend);
372
373 if(textureset==0 || !fxMesa->haveTwoTMUs)
374 unitsmode=fxGetTexSetConfiguration(ctx,tObj,NULL);
375 else
376 unitsmode=fxGetTexSetConfiguration(ctx,NULL,tObj);
377
378 if(fxMesa->lastUnitsMode==unitsmode)
379 return;
380
381 fxMesa->lastUnitsMode=unitsmode;
382
383 fxMesa->stw_hint_state = 0;
384 FX_grHints(GR_HINT_STWHINT,0);
385
386 ifmt=ti->baseLevelInternalFormat;
387
388 if(unitsmode & FX_UM_ALPHA_ITERATED)
389 locala=GR_COMBINE_LOCAL_ITERATED;
390 else
391 locala=GR_COMBINE_LOCAL_CONSTANT;
392
393 if(unitsmode & FX_UM_COLOR_ITERATED)
394 localc=GR_COMBINE_LOCAL_ITERATED;
395 else
396 localc=GR_COMBINE_LOCAL_CONSTANT;
397
398 if (MESA_VERBOSE & (VERBOSE_DRIVER|VERBOSE_TEXTURE))
399 fprintf(stderr, "fxMesa: fxSetupTextureSingleTMU, envmode is %s\n",
400 gl_lookup_enum_by_nr(ctx->Texture.Unit[textureset].EnvMode));
401
402 switch(ctx->Texture.Unit[textureset].EnvMode) {
403 case GL_DECAL:
404 grAlphaCombine(GR_COMBINE_FUNCTION_LOCAL,
405 GR_COMBINE_FACTOR_NONE,
406 locala,
407 GR_COMBINE_OTHER_NONE,
408 FXFALSE);
409
410 grColorCombine(GR_COMBINE_FUNCTION_BLEND,
411 GR_COMBINE_FACTOR_TEXTURE_ALPHA,
412 localc,
413 GR_COMBINE_OTHER_TEXTURE,
414 FXFALSE);
415 break;
416 case GL_MODULATE:
417 grAlphaCombine(GR_COMBINE_FUNCTION_SCALE_OTHER,
418 GR_COMBINE_FACTOR_LOCAL,
419 locala,
420 GR_COMBINE_OTHER_TEXTURE,
421 FXFALSE);
422
423 if(ifmt==GL_ALPHA)
424 grColorCombine(GR_COMBINE_FUNCTION_LOCAL,
425 GR_COMBINE_FACTOR_NONE,
426 localc,
427 GR_COMBINE_OTHER_NONE,
428 FXFALSE);
429 else
430 grColorCombine(GR_COMBINE_FUNCTION_SCALE_OTHER,
431 GR_COMBINE_FACTOR_LOCAL,
432 localc,
433 GR_COMBINE_OTHER_TEXTURE,
434 FXFALSE);
435 break;
436 case GL_BLEND:
437 #ifndef FX_SILENT
438 fprintf(stderr,"fx Driver: GL_BLEND not yet supported\n");
439 #endif
440 /* TO DO (I think that the Voodoo Graphics isn't able to support GL_BLEND) */
441 break;
442 case GL_REPLACE:
443 if((ifmt==GL_RGB) || (ifmt==GL_LUMINANCE))
444 grAlphaCombine(GR_COMBINE_FUNCTION_LOCAL,
445 GR_COMBINE_FACTOR_NONE,
446 locala,
447 GR_COMBINE_OTHER_NONE,
448 FXFALSE);
449 else
450 grAlphaCombine(GR_COMBINE_FUNCTION_SCALE_OTHER,
451 GR_COMBINE_FACTOR_ONE,
452 locala,
453 GR_COMBINE_OTHER_TEXTURE,
454 FXFALSE);
455
456 if(ifmt==GL_ALPHA)
457 grColorCombine(GR_COMBINE_FUNCTION_LOCAL,
458 GR_COMBINE_FACTOR_NONE,
459 localc,
460 GR_COMBINE_OTHER_NONE,
461 FXFALSE);
462 else
463 grColorCombine(GR_COMBINE_FUNCTION_SCALE_OTHER,
464 GR_COMBINE_FACTOR_ONE,
465 localc,
466 GR_COMBINE_OTHER_TEXTURE,
467 FXFALSE);
468 break;
469 default:
470 #ifndef FX_SILENT
471 fprintf(stderr,"fx Driver: %x Texture.EnvMode not yet supported\n",ctx->Texture.Unit[textureset].EnvMode);
472 #endif
473 break;
474 }
475
476 if (MESA_VERBOSE&VERBOSE_DRIVER) {
477 fprintf(stderr,"fxmesa: fxSetupTextureSingleTMU(...) End\n");
478 }
479 }
480
481 /************************* Double Texture Set ***************************/
482
483 void fxSetupDoubleTMU(fxMesaContext fxMesa, struct gl_texture_object *tObj0,
484 struct gl_texture_object *tObj1)
485 {
486 #define T0_NOT_IN_TMU 0x01
487 #define T1_NOT_IN_TMU 0x02
488 #define T0_IN_TMU0 0x04
489 #define T1_IN_TMU0 0x08
490 #define T0_IN_TMU1 0x10
491 #define T1_IN_TMU1 0x20
492
493 tfxTexInfo *ti0=(tfxTexInfo *)tObj0->DriverData;
494 tfxTexInfo *ti1=(tfxTexInfo *)tObj1->DriverData;
495 GLuint tstate=0;
496
497 if (MESA_VERBOSE&VERBOSE_DRIVER) {
498 fprintf(stderr,"fxmesa: fxSetupDoubleTMU(...)\n");
499 }
500
501 if(ti0->tmi.isInTM) {
502 if(ti0->tmi.whichTMU==FX_TMU0)
503 tstate|=T0_IN_TMU0;
504 else if(ti0->tmi.whichTMU==FX_TMU1)
505 tstate|=T0_IN_TMU1;
506 else {
507 fxTMMoveOutTM(fxMesa,tObj0);
508 tstate|=T0_NOT_IN_TMU;
509 }
510 } else
511 tstate|=T0_NOT_IN_TMU;
512
513 if(ti1->tmi.isInTM) {
514 if(ti1->tmi.whichTMU==FX_TMU0)
515 tstate|=T1_IN_TMU0;
516 else if(ti1->tmi.whichTMU==FX_TMU1)
517 tstate|=T1_IN_TMU1;
518 else {
519 fxTMMoveOutTM(fxMesa,tObj1);
520 tstate|=T1_NOT_IN_TMU;
521 }
522 } else
523 tstate|=T1_NOT_IN_TMU;
524
525 ti0->tmi.lastTimeUsed=fxMesa->texBindNumber;
526 ti1->tmi.lastTimeUsed=fxMesa->texBindNumber;
527
528 /* Move texture maps in TMUs */
529
530 switch(tstate) {
531 case (T0_IN_TMU0 | T1_IN_TMU0):
532 fxTMMoveOutTM(fxMesa,tObj1);
533
534 fxTMMoveInTM(fxMesa,tObj1,FX_TMU1);
535 break;
536
537 case (T0_IN_TMU1 | T1_IN_TMU1):
538 fxTMMoveOutTM(fxMesa,tObj0);
539
540 fxTMMoveInTM(fxMesa,tObj0,FX_TMU0);
541 break;
542
543 case (T0_NOT_IN_TMU | T1_NOT_IN_TMU):
544 fxTMMoveInTM(fxMesa,tObj0,FX_TMU0);
545 fxTMMoveInTM(fxMesa,tObj1,FX_TMU1);
546 break;
547
548 /*** T0/T1 ***/
549
550 case (T0_NOT_IN_TMU | T1_IN_TMU0):
551 fxTMMoveInTM(fxMesa,tObj0,FX_TMU1);
552 break;
553
554 case (T0_NOT_IN_TMU | T1_IN_TMU1):
555 fxTMMoveInTM(fxMesa,tObj0,FX_TMU0);
556 break;
557
558 case (T0_IN_TMU0 | T1_NOT_IN_TMU):
559 fxTMMoveInTM(fxMesa,tObj1,FX_TMU1);
560 break;
561
562 case (T0_IN_TMU1 | T1_NOT_IN_TMU):
563 fxTMMoveInTM(fxMesa,tObj1,FX_TMU0);
564 break;
565
566 /*** Best Case ***/
567
568 case (T0_IN_TMU1 | T1_IN_TMU0):
569 case (T0_IN_TMU0 | T1_IN_TMU1):
570 break;
571
572 default:
573 fprintf(stderr,"fx Driver: internal error in fxSetupDoubleTMU()\n");
574 fxCloseHardware();
575 exit(-1);
576 break;
577 }
578
579 if(!fxMesa->haveGlobalPaletteTexture) {
580 if(ti0->info.format==GR_TEXFMT_P_8) {
581 if (MESA_VERBOSE&VERBOSE_DRIVER) {
582 fprintf(stderr,"fxmesa: uploading texture palette TMU0\n");
583 }
584 FX_grTexDownloadTable(ti0->tmi.whichTMU,GR_TEXTABLE_PALETTE,&(ti0->palette));
585 }
586
587 if(ti1->info.format==GR_TEXFMT_P_8) {
588 if (MESA_VERBOSE&VERBOSE_DRIVER) {
589 fprintf(stderr,"fxmesa: uploading texture palette TMU1\n");
590 }
591 FX_grTexDownloadTable(ti1->tmi.whichTMU,GR_TEXTABLE_PALETTE,&(ti1->palette));
592 }
593 }
594
595 grTexClampMode(ti0->tmi.whichTMU,ti0->sClamp,ti0->tClamp);
596 grTexFilterMode(ti0->tmi.whichTMU,ti0->minFilt,ti0->maxFilt);
597 grTexMipMapMode(ti0->tmi.whichTMU,ti0->mmMode,FXFALSE);
598 grTexSource(ti0->tmi.whichTMU,ti0->tmi.tm[ti0->tmi.whichTMU]->startAddress,
599 GR_MIPMAPLEVELMASK_BOTH,&(ti0->info));
600
601 grTexClampMode(ti1->tmi.whichTMU,ti1->sClamp,ti1->tClamp);
602 grTexFilterMode(ti1->tmi.whichTMU,ti1->minFilt,ti1->maxFilt);
603 grTexMipMapMode(ti1->tmi.whichTMU,ti1->mmMode,FXFALSE);
604 grTexSource(ti1->tmi.whichTMU,ti1->tmi.tm[ti1->tmi.whichTMU]->startAddress,
605 GR_MIPMAPLEVELMASK_BOTH,&(ti1->info));
606
607 #undef T0_NOT_IN_TMU
608 #undef T1_NOT_IN_TMU
609 #undef T0_IN_TMU0
610 #undef T1_IN_TMU0
611 #undef T0_IN_TMU1
612 #undef T1_IN_TMU1
613 }
614
615 static void fxSetupTextureDoubleTMU(GLcontext *ctx)
616 {
617 fxMesaContext fxMesa=(fxMesaContext)ctx->DriverCtx;
618 GrCombineLocal_t localc,locala;
619 tfxTexInfo *ti0,*ti1;
620 struct gl_texture_object *tObj0=ctx->Texture.Unit[0].CurrentD[2];
621 struct gl_texture_object *tObj1=ctx->Texture.Unit[1].CurrentD[2];
622 GLuint envmode,ifmt,unitsmode;
623
624 if (MESA_VERBOSE&VERBOSE_DRIVER) {
625 fprintf(stderr,"fxmesa: fxSetupTextureDoubleTMU(...) Start\n");
626 }
627
628 ti0=(tfxTexInfo *)tObj0->DriverData;
629 fxTexValidate(ctx,tObj0);
630
631 ti1=(tfxTexInfo *)tObj1->DriverData;
632 fxTexValidate(ctx,tObj1);
633
634 fxSetupDoubleTMU(fxMesa,tObj0,tObj1);
635
636 unitsmode=fxGetTexSetConfiguration(ctx,tObj0,tObj1);
637
638 if(fxMesa->lastUnitsMode==unitsmode)
639 return;
640
641 fxMesa->lastUnitsMode=unitsmode;
642
643 fxMesa->stw_hint_state |= GR_STWHINT_ST_DIFF_TMU1;
644 FX_grHints(GR_HINT_STWHINT, fxMesa->stw_hint_state);
645
646 envmode=unitsmode & FX_UM_E_ENVMODE;
647 ifmt=unitsmode & FX_UM_E_IFMT;
648
649 if(unitsmode & FX_UM_ALPHA_ITERATED)
650 locala=GR_COMBINE_LOCAL_ITERATED;
651 else
652 locala=GR_COMBINE_LOCAL_CONSTANT;
653
654 if(unitsmode & FX_UM_COLOR_ITERATED)
655 localc=GR_COMBINE_LOCAL_ITERATED;
656 else
657 localc=GR_COMBINE_LOCAL_CONSTANT;
658
659
660 if (MESA_VERBOSE & (VERBOSE_DRIVER|VERBOSE_TEXTURE))
661 fprintf(stderr, "fxMesa: fxSetupTextureDoubleTMU, envmode is %s/%s\n",
662 gl_lookup_enum_by_nr(ctx->Texture.Unit[0].EnvMode),
663 gl_lookup_enum_by_nr(ctx->Texture.Unit[1].EnvMode));
664
665
666 fxMesa->tmuSrc=FX_TMU_BOTH;
667 switch(envmode) {
668 case (FX_UM_E0_MODULATE | FX_UM_E1_MODULATE):
669 {
670 GLboolean isalpha[FX_NUM_TMU];
671
672 if(ti0->baseLevelInternalFormat==GL_ALPHA)
673 isalpha[ti0->tmi.whichTMU]=GL_TRUE;
674 else
675 isalpha[ti0->tmi.whichTMU]=GL_FALSE;
676
677 if(ti1->baseLevelInternalFormat==GL_ALPHA)
678 isalpha[ti1->tmi.whichTMU]=GL_TRUE;
679 else
680 isalpha[ti1->tmi.whichTMU]=GL_FALSE;
681
682 if(isalpha[FX_TMU1])
683 grTexCombine(GR_TMU1,
684 GR_COMBINE_FUNCTION_ZERO,GR_COMBINE_FACTOR_NONE,
685 GR_COMBINE_FUNCTION_LOCAL,GR_COMBINE_FACTOR_NONE,
686 FXTRUE,FXFALSE);
687 else
688 grTexCombine(GR_TMU1,
689 GR_COMBINE_FUNCTION_LOCAL,GR_COMBINE_FACTOR_NONE,
690 GR_COMBINE_FUNCTION_LOCAL,GR_COMBINE_FACTOR_NONE,
691 FXFALSE,FXFALSE);
692
693 if(isalpha[FX_TMU0])
694 grTexCombine(GR_TMU0,
695 GR_COMBINE_FUNCTION_BLEND_OTHER,GR_COMBINE_FACTOR_ONE,
696 GR_COMBINE_FUNCTION_BLEND_OTHER,GR_COMBINE_FACTOR_LOCAL,
697 FXFALSE,FXFALSE);
698 else
699 grTexCombine(GR_TMU0,
700 GR_COMBINE_FUNCTION_BLEND_OTHER,GR_COMBINE_FACTOR_LOCAL,
701 GR_COMBINE_FUNCTION_BLEND_OTHER,GR_COMBINE_FACTOR_LOCAL,
702 FXFALSE,FXFALSE);
703
704 grColorCombine(GR_COMBINE_FUNCTION_SCALE_OTHER,
705 GR_COMBINE_FACTOR_LOCAL,
706 localc,
707 GR_COMBINE_OTHER_TEXTURE,
708 FXFALSE);
709
710 grAlphaCombine(GR_COMBINE_FUNCTION_SCALE_OTHER,
711 GR_COMBINE_FACTOR_LOCAL,
712 locala,
713 GR_COMBINE_OTHER_TEXTURE,
714 FXFALSE);
715 break;
716 }
717 case (FX_UM_E0_REPLACE | FX_UM_E1_BLEND): /* Only for GLQuake */
718 if(ti1->tmi.whichTMU==FX_TMU1) {
719 grTexCombine(GR_TMU1,
720 GR_COMBINE_FUNCTION_LOCAL,GR_COMBINE_FACTOR_NONE,
721 GR_COMBINE_FUNCTION_LOCAL,GR_COMBINE_FACTOR_NONE,
722 FXTRUE,FXFALSE);
723
724 grTexCombine(GR_TMU0,
725 GR_COMBINE_FUNCTION_BLEND_OTHER,GR_COMBINE_FACTOR_LOCAL,
726 GR_COMBINE_FUNCTION_BLEND_OTHER,GR_COMBINE_FACTOR_LOCAL,
727 FXFALSE,FXFALSE);
728 } else {
729 grTexCombine(GR_TMU1,
730 GR_COMBINE_FUNCTION_LOCAL,GR_COMBINE_FACTOR_NONE,
731 GR_COMBINE_FUNCTION_LOCAL,GR_COMBINE_FACTOR_NONE,
732 FXFALSE,FXFALSE);
733
734 grTexCombine(GR_TMU0,
735 GR_COMBINE_FUNCTION_BLEND_OTHER,GR_COMBINE_FACTOR_ONE_MINUS_LOCAL,
736 GR_COMBINE_FUNCTION_BLEND_OTHER,GR_COMBINE_FACTOR_ONE_MINUS_LOCAL,
737 FXFALSE,FXFALSE);
738 }
739
740 grAlphaCombine(GR_COMBINE_FUNCTION_LOCAL,
741 GR_COMBINE_FACTOR_NONE,
742 locala,
743 GR_COMBINE_OTHER_NONE,
744 FXFALSE);
745
746 grColorCombine(GR_COMBINE_FUNCTION_SCALE_OTHER,
747 GR_COMBINE_FACTOR_ONE,
748 localc,
749 GR_COMBINE_OTHER_TEXTURE,
750 FXFALSE);
751 break;
752 case (FX_UM_E0_REPLACE | FX_UM_E1_MODULATE): /* Quake 2 and 3 */
753 if(ti1->tmi.whichTMU==FX_TMU1) {
754 grTexCombine(GR_TMU1,
755 GR_COMBINE_FUNCTION_LOCAL,GR_COMBINE_FACTOR_NONE,
756 GR_COMBINE_FUNCTION_ZERO,GR_COMBINE_FACTOR_NONE,
757 FXFALSE,FXTRUE);
758
759 grTexCombine(GR_TMU0,
760 GR_COMBINE_FUNCTION_BLEND_OTHER,GR_COMBINE_FACTOR_LOCAL,
761 GR_COMBINE_FUNCTION_BLEND_OTHER,GR_COMBINE_FACTOR_LOCAL,
762 FXFALSE,FXFALSE);
763
764 } else {
765 grTexCombine(GR_TMU1,
766 GR_COMBINE_FUNCTION_LOCAL,GR_COMBINE_FACTOR_NONE,
767 GR_COMBINE_FUNCTION_LOCAL,GR_COMBINE_FACTOR_NONE,
768 FXFALSE,FXFALSE);
769
770 grTexCombine(GR_TMU0,
771 GR_COMBINE_FUNCTION_BLEND_OTHER,GR_COMBINE_FACTOR_LOCAL,
772 GR_COMBINE_FUNCTION_BLEND_OTHER,GR_COMBINE_FACTOR_ONE,
773 FXFALSE,FXFALSE);
774 }
775
776 if(ti0->baseLevelInternalFormat==GL_RGB)
777 grAlphaCombine(GR_COMBINE_FUNCTION_LOCAL,
778 GR_COMBINE_FACTOR_NONE,
779 locala,
780 GR_COMBINE_OTHER_NONE,
781 FXFALSE);
782 else
783 grAlphaCombine(GR_COMBINE_FUNCTION_SCALE_OTHER,
784 GR_COMBINE_FACTOR_ONE,
785 locala,
786 GR_COMBINE_OTHER_NONE,
787 FXFALSE);
788
789
790 grColorCombine(GR_COMBINE_FUNCTION_SCALE_OTHER,
791 GR_COMBINE_FACTOR_ONE,
792 localc,
793 GR_COMBINE_OTHER_TEXTURE,
794 FXFALSE);
795 break;
796
797
798 case (FX_UM_E0_MODULATE | FX_UM_E1_ADD): /* Quake 3 Sky */
799 {
800 GLboolean isalpha[FX_NUM_TMU];
801
802 if(ti0->baseLevelInternalFormat==GL_ALPHA)
803 isalpha[ti0->tmi.whichTMU]=GL_TRUE;
804 else
805 isalpha[ti0->tmi.whichTMU]=GL_FALSE;
806
807 if(ti1->baseLevelInternalFormat==GL_ALPHA)
808 isalpha[ti1->tmi.whichTMU]=GL_TRUE;
809 else
810 isalpha[ti1->tmi.whichTMU]=GL_FALSE;
811
812 if(isalpha[FX_TMU1])
813 grTexCombine(GR_TMU1,
814 GR_COMBINE_FUNCTION_ZERO,GR_COMBINE_FACTOR_NONE,
815 GR_COMBINE_FUNCTION_LOCAL,GR_COMBINE_FACTOR_NONE,
816 FXTRUE,FXFALSE);
817 else
818 grTexCombine(GR_TMU1,
819 GR_COMBINE_FUNCTION_LOCAL,GR_COMBINE_FACTOR_NONE,
820 GR_COMBINE_FUNCTION_LOCAL,GR_COMBINE_FACTOR_NONE,
821 FXFALSE,FXFALSE);
822
823 if(isalpha[FX_TMU0])
824 grTexCombine(GR_TMU0,
825 GR_COMBINE_FUNCTION_SCALE_OTHER,GR_COMBINE_FACTOR_ONE,
826 GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL,GR_COMBINE_FACTOR_ONE,
827 FXFALSE,FXFALSE);
828 else
829 grTexCombine(GR_TMU0,
830 GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL,GR_COMBINE_FACTOR_ONE,
831 GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL,GR_COMBINE_FACTOR_ONE,
832 FXFALSE,FXFALSE);
833
834 grColorCombine(GR_COMBINE_FUNCTION_SCALE_OTHER,
835 GR_COMBINE_FACTOR_LOCAL,
836 localc,
837 GR_COMBINE_OTHER_TEXTURE,
838 FXFALSE);
839
840 grAlphaCombine(GR_COMBINE_FUNCTION_SCALE_OTHER,
841 GR_COMBINE_FACTOR_LOCAL,
842 locala, GR_COMBINE_OTHER_TEXTURE,
843 FXFALSE);
844 break;
845 }
846
847 }
848
849 if (MESA_VERBOSE&VERBOSE_DRIVER) {
850 fprintf(stderr,"fxmesa: fxSetupTextureDoubleTMU(...) End\n");
851 }
852 }
853
854 /************************* No Texture ***************************/
855
856 static void fxSetupTextureNone(GLcontext *ctx)
857 {
858 fxMesaContext fxMesa=(fxMesaContext)ctx->DriverCtx;
859 GrCombineLocal_t localc,locala;
860
861 if (MESA_VERBOSE&VERBOSE_DRIVER) {
862 fprintf(stderr,"fxmesa: fxSetupTextureNone(...)\n");
863 }
864
865 if((ctx->Light.ShadeModel==GL_SMOOTH) ||
866 (ctx->Point.SmoothFlag) ||
867 (ctx->Line.SmoothFlag) ||
868 (ctx->Polygon.SmoothFlag))
869 locala=GR_COMBINE_LOCAL_ITERATED;
870 else
871 locala=GR_COMBINE_LOCAL_CONSTANT;
872
873 if(ctx->Light.ShadeModel==GL_SMOOTH)
874 localc=GR_COMBINE_LOCAL_ITERATED;
875 else
876 localc=GR_COMBINE_LOCAL_CONSTANT;
877
878 grAlphaCombine(GR_COMBINE_FUNCTION_LOCAL,
879 GR_COMBINE_FACTOR_NONE,
880 locala,
881 GR_COMBINE_OTHER_NONE,
882 FXFALSE);
883
884 grColorCombine(GR_COMBINE_FUNCTION_LOCAL,
885 GR_COMBINE_FACTOR_NONE,
886 localc,
887 GR_COMBINE_OTHER_NONE,
888 FXFALSE);
889
890 fxMesa->lastUnitsMode=FX_UM_NONE;
891 }
892
893 /* See below.
894 */
895 static GLboolean fxMultipassTexture( struct vertex_buffer *, GLuint );
896
897
898
899 /************************************************************************/
900 /************************** Texture Mode SetUp **************************/
901 /************************************************************************/
902
903 void fxSetupTexture(GLcontext *ctx)
904 {
905 fxMesaContext fxMesa=(fxMesaContext)ctx->DriverCtx;
906 GLuint tex2Denabled;
907
908 if (MESA_VERBOSE&VERBOSE_DRIVER) {
909 fprintf(stderr,"fxmesa: fxSetupTexture(...)\n");
910 }
911
912 /* Disable multipass texturing.
913 */
914 ctx->Driver.MultipassFunc = 0;
915
916 /* Texture Combine, Color Combine and Alpha Combine.
917 */
918 tex2Denabled = (ctx->Texture.ReallyEnabled & TEXTURE0_2D);
919
920 if (fxMesa->emulateTwoTMUs)
921 tex2Denabled |= (ctx->Texture.ReallyEnabled & TEXTURE1_2D);
922
923 switch(tex2Denabled) {
924 case TEXTURE0_2D:
925 fxSetupTextureSingleTMU(ctx,0);
926 break;
927 case TEXTURE1_2D:
928 fxSetupTextureSingleTMU(ctx,1);
929 break;
930 case (TEXTURE0_2D|TEXTURE1_2D):
931 if (fxMesa->haveTwoTMUs)
932 fxSetupTextureDoubleTMU(ctx);
933 else {
934 if (MESA_VERBOSE&VERBOSE_DRIVER)
935 fprintf(stderr, "fxmesa: enabling fake multitexture\n");
936
937 fxSetupTextureSingleTMU(ctx,0);
938 ctx->Driver.MultipassFunc = fxMultipassTexture;
939 }
940 break;
941 default:
942 fxSetupTextureNone(ctx);
943 break;
944 }
945 }
946
947 /************************************************************************/
948 /**************************** Blend SetUp *******************************/
949 /************************************************************************/
950
951 /* XXX consider supporting GL_INGR_blend_func_separate */
952 void fxDDBlendFunc(GLcontext *ctx, GLenum sfactor, GLenum dfactor)
953 {
954 fxMesaContext fxMesa=(fxMesaContext)ctx->DriverCtx;
955 tfxUnitsState *us=&fxMesa->unitsState;
956 GrAlphaBlendFnc_t sfact,dfact,asfact,adfact;
957
958 /* From the Glide documentation:
959 For alpha source and destination blend function factor
960 parameters, Voodoo Graphics supports only
961 GR_BLEND_ZERO and GR_BLEND_ONE.
962 */
963
964 switch(sfactor) {
965 case GL_ZERO:
966 asfact=sfact=GR_BLEND_ZERO;
967 break;
968 case GL_ONE:
969 asfact=sfact=GR_BLEND_ONE;
970 break;
971 case GL_DST_COLOR:
972 sfact=GR_BLEND_DST_COLOR;
973 asfact=GR_BLEND_ONE;
974 break;
975 case GL_ONE_MINUS_DST_COLOR:
976 sfact=GR_BLEND_ONE_MINUS_DST_COLOR;
977 asfact=GR_BLEND_ONE;
978 break;
979 case GL_SRC_ALPHA:
980 sfact=GR_BLEND_SRC_ALPHA;
981 asfact=GR_BLEND_ONE;
982 break;
983 case GL_ONE_MINUS_SRC_ALPHA:
984 sfact=GR_BLEND_ONE_MINUS_SRC_ALPHA;
985 asfact=GR_BLEND_ONE;
986 break;
987 case GL_DST_ALPHA:
988 sfact=GR_BLEND_DST_ALPHA;
989 asfact=GR_BLEND_ONE;
990 break;
991 case GL_ONE_MINUS_DST_ALPHA:
992 sfact=GR_BLEND_ONE_MINUS_DST_ALPHA;
993 asfact=GR_BLEND_ONE;
994 break;
995 case GL_SRC_ALPHA_SATURATE:
996 sfact=GR_BLEND_ALPHA_SATURATE;
997 asfact=GR_BLEND_ONE;
998 break;
999 case GL_SRC_COLOR:
1000 case GL_ONE_MINUS_SRC_COLOR:
1001 /* USELESS */
1002 asfact=sfact=GR_BLEND_ONE;
1003 break;
1004 default:
1005 asfact=sfact=GR_BLEND_ONE;
1006 break;
1007 }
1008
1009 if((sfact!=us->blendSrcFuncRGB) ||
1010 (asfact!=us->blendSrcFuncAlpha)) {
1011 us->blendSrcFuncRGB=sfact;
1012 us->blendSrcFuncAlpha=asfact;
1013 fxMesa->new_state |= FX_NEW_BLEND;
1014 ctx->Driver.RenderStart = fxSetupFXUnits;
1015 }
1016
1017 switch(dfactor) {
1018 case GL_ZERO:
1019 adfact=dfact=GR_BLEND_ZERO;
1020 break;
1021 case GL_ONE:
1022 adfact=dfact=GR_BLEND_ONE;
1023 break;
1024 case GL_SRC_COLOR:
1025 dfact=GR_BLEND_SRC_COLOR;
1026 adfact=GR_BLEND_ZERO;
1027 break;
1028 case GL_ONE_MINUS_SRC_COLOR:
1029 dfact=GR_BLEND_ONE_MINUS_SRC_COLOR;
1030 adfact=GR_BLEND_ZERO;
1031 break;
1032 case GL_SRC_ALPHA:
1033 dfact=GR_BLEND_SRC_ALPHA;
1034 adfact=GR_BLEND_ZERO;
1035 break;
1036 case GL_ONE_MINUS_SRC_ALPHA:
1037 dfact=GR_BLEND_ONE_MINUS_SRC_ALPHA;
1038 adfact=GR_BLEND_ZERO;
1039 break;
1040 case GL_DST_ALPHA:
1041 dfact=GR_BLEND_DST_ALPHA;
1042 adfact=GR_BLEND_ZERO;
1043 break;
1044 case GL_ONE_MINUS_DST_ALPHA:
1045 dfact=GR_BLEND_ONE_MINUS_DST_ALPHA;
1046 adfact=GR_BLEND_ZERO;
1047 break;
1048 case GL_SRC_ALPHA_SATURATE:
1049 case GL_DST_COLOR:
1050 case GL_ONE_MINUS_DST_COLOR:
1051 /* USELESS */
1052 adfact=dfact=GR_BLEND_ZERO;
1053 break;
1054 default:
1055 adfact=dfact=GR_BLEND_ZERO;
1056 break;
1057 }
1058
1059 if((dfact!=us->blendDstFuncRGB) ||
1060 (adfact!=us->blendDstFuncAlpha)) {
1061 us->blendDstFuncRGB=dfact;
1062 us->blendDstFuncAlpha=adfact;
1063 fxMesa->new_state |= FX_NEW_BLEND;
1064 ctx->Driver.RenderStart = fxSetupFXUnits;
1065 }
1066 }
1067
1068 void fxSetupBlend(GLcontext *ctx)
1069 {
1070 fxMesaContext fxMesa=(fxMesaContext)ctx->DriverCtx;
1071 tfxUnitsState *us=&fxMesa->unitsState;
1072
1073 if(us->blendEnabled)
1074 grAlphaBlendFunction(us->blendSrcFuncRGB,us->blendDstFuncRGB,
1075 us->blendSrcFuncAlpha,us->blendDstFuncAlpha);
1076 else
1077 grAlphaBlendFunction(GR_BLEND_ONE,GR_BLEND_ZERO,GR_BLEND_ONE,GR_BLEND_ZERO);
1078 }
1079
1080 /************************************************************************/
1081 /************************** Alpha Test SetUp ****************************/
1082 /************************************************************************/
1083
1084 void fxDDAlphaFunc(GLcontext *ctx, GLenum func, GLclampf ref)
1085 {
1086 fxMesaContext fxMesa=(fxMesaContext)ctx->DriverCtx;
1087 tfxUnitsState *us=&fxMesa->unitsState;
1088 GrCmpFnc_t newfunc;
1089
1090 switch(func) {
1091 case GL_NEVER:
1092 newfunc=GR_CMP_NEVER;
1093 break;
1094 case GL_LESS:
1095 newfunc=GR_CMP_LESS;
1096 break;
1097 case GL_EQUAL:
1098 newfunc=GR_CMP_EQUAL;
1099 break;
1100 case GL_LEQUAL:
1101 newfunc=GR_CMP_LEQUAL;
1102 break;
1103 case GL_GREATER:
1104 newfunc=GR_CMP_GREATER;
1105 break;
1106 case GL_NOTEQUAL:
1107 newfunc=GR_CMP_NOTEQUAL;
1108 break;
1109 case GL_GEQUAL:
1110 newfunc=GR_CMP_GEQUAL;
1111 break;
1112 case GL_ALWAYS:
1113 newfunc=GR_CMP_ALWAYS;
1114 break;
1115 default:
1116 fprintf(stderr,"fx Driver: internal error in fxDDAlphaFunc()\n");
1117 fxCloseHardware();
1118 exit(-1);
1119 break;
1120 }
1121
1122 if(newfunc!=us->alphaTestFunc) {
1123 us->alphaTestFunc=newfunc;
1124 fxMesa->new_state |= FX_NEW_ALPHA;
1125 ctx->Driver.RenderStart = fxSetupFXUnits;
1126 }
1127
1128 if(ctx->Color.AlphaRef!=us->alphaTestRefValue) {
1129 us->alphaTestRefValue=ctx->Color.AlphaRef;
1130 fxMesa->new_state |= FX_NEW_ALPHA;
1131 ctx->Driver.RenderStart = fxSetupFXUnits;
1132 }
1133 }
1134
1135 static void fxSetupAlphaTest(GLcontext *ctx)
1136 {
1137 fxMesaContext fxMesa=(fxMesaContext)ctx->DriverCtx;
1138 tfxUnitsState *us=&fxMesa->unitsState;
1139
1140 if(us->alphaTestEnabled) {
1141 grAlphaTestFunction(us->alphaTestFunc);
1142 grAlphaTestReferenceValue(us->alphaTestRefValue);
1143 } else
1144 grAlphaTestFunction(GR_CMP_ALWAYS);
1145 }
1146
1147 /************************************************************************/
1148 /************************** Depth Test SetUp ****************************/
1149 /************************************************************************/
1150
1151 void fxDDDepthFunc(GLcontext *ctx, GLenum func)
1152 {
1153 fxMesaContext fxMesa=(fxMesaContext)ctx->DriverCtx;
1154 tfxUnitsState *us=&fxMesa->unitsState;
1155 GrCmpFnc_t dfunc;
1156
1157 switch(func) {
1158 case GL_NEVER:
1159 dfunc=GR_CMP_NEVER;
1160 break;
1161 case GL_LESS:
1162 dfunc=GR_CMP_LESS;
1163 break;
1164 case GL_GEQUAL:
1165 dfunc=GR_CMP_GEQUAL;
1166 break;
1167 case GL_LEQUAL:
1168 dfunc=GR_CMP_LEQUAL;
1169 break;
1170 case GL_GREATER:
1171 dfunc=GR_CMP_GREATER;
1172 break;
1173 case GL_NOTEQUAL:
1174 dfunc=GR_CMP_NOTEQUAL;
1175 break;
1176 case GL_EQUAL:
1177 dfunc=GR_CMP_EQUAL;
1178 break;
1179 case GL_ALWAYS:
1180 dfunc=GR_CMP_ALWAYS;
1181 break;
1182 default:
1183 fprintf(stderr,"fx Driver: internal error in fxDDDepthFunc()\n");
1184 fxCloseHardware();
1185 exit(-1);
1186 break;
1187 }
1188
1189 if(dfunc!=us->depthTestFunc) {
1190 us->depthTestFunc=dfunc;
1191 fxMesa->new_state |= FX_NEW_DEPTH;
1192 ctx->Driver.RenderStart = fxSetupFXUnits;
1193 }
1194
1195 }
1196
1197 void fxDDDepthMask(GLcontext *ctx, GLboolean flag)
1198 {
1199 fxMesaContext fxMesa=(fxMesaContext)ctx->DriverCtx;
1200 tfxUnitsState *us=&fxMesa->unitsState;
1201
1202 if(flag!=us->depthMask) {
1203 us->depthMask=flag;
1204 fxMesa->new_state |= FX_NEW_DEPTH;
1205 ctx->Driver.RenderStart = fxSetupFXUnits;
1206 }
1207 }
1208
1209 void fxSetupDepthTest(GLcontext *ctx)
1210 {
1211 fxMesaContext fxMesa=(fxMesaContext)ctx->DriverCtx;
1212 tfxUnitsState *us=&fxMesa->unitsState;
1213
1214 if(us->depthTestEnabled)
1215 grDepthBufferFunction(us->depthTestFunc);
1216 else
1217 grDepthBufferFunction(GR_CMP_ALWAYS);
1218
1219 grDepthMask(us->depthMask);
1220 }
1221
1222 /************************************************************************/
1223 /**************************** Color Mask SetUp **************************/
1224 /************************************************************************/
1225
1226 GLboolean fxDDColorMask(GLcontext *ctx,
1227 GLboolean r, GLboolean g,
1228 GLboolean b, GLboolean a )
1229 {
1230 fxMesaContext fxMesa=(fxMesaContext)ctx->DriverCtx;
1231 fxMesa->new_state |= FX_NEW_COLOR_MASK;
1232 ctx->Driver.RenderStart = fxSetupFXUnits;
1233 (void) r; (void) g; (void) b; (void) a;
1234 return 1;
1235 }
1236
1237 static void fxSetupColorMask(GLcontext *ctx)
1238 {
1239 fxMesaContext fxMesa = FX_CONTEXT(ctx);
1240
1241 grColorMask(ctx->Color.ColorMask[RCOMP] ||
1242 ctx->Color.ColorMask[GCOMP] ||
1243 ctx->Color.ColorMask[BCOMP],
1244 ctx->Color.ColorMask[ACOMP] && fxMesa->haveAlphaBuffer);
1245 }
1246
1247
1248
1249 /************************************************************************/
1250 /**************************** Fog Mode SetUp ****************************/
1251 /************************************************************************/
1252
1253 void fxFogTableGenerate(GLcontext *ctx)
1254 {
1255 int i;
1256 float f,eyez;
1257 fxMesaContext fxMesa=(fxMesaContext)ctx->DriverCtx;
1258
1259 for(i=0;i<FX_grGetInteger(FX_FOG_TABLE_ENTRIES);i++) {
1260 eyez=guFogTableIndexToW(i);
1261
1262 switch(ctx->Fog.Mode) {
1263 case GL_LINEAR:
1264 f=(ctx->Fog.End-eyez)/(ctx->Fog.End-ctx->Fog.Start);
1265 break;
1266 case GL_EXP:
1267 f=exp(-ctx->Fog.Density*eyez);
1268 break;
1269 case GL_EXP2:
1270 f=exp(-ctx->Fog.Density*ctx->Fog.Density*eyez*eyez);
1271 break;
1272 default: /* That should never happen */
1273 f=0.0f;
1274 break;
1275 }
1276
1277 fxMesa->fogTable[i]=(GrFog_t)((1.0f-CLAMP(f,0.0f,1.0f))*255.0f);
1278 }
1279 }
1280
1281 void fxSetupFog(GLcontext *ctx, GLboolean forceTableRebuild)
1282 {
1283 fxMesaContext fxMesa=(fxMesaContext)ctx->DriverCtx;
1284
1285 if(ctx->Fog.Enabled && ctx->FogMode==FOG_FRAGMENT) {
1286 GLubyte col[4];
1287 grFogMode(GR_FOG_WITH_TABLE);
1288
1289 col[0]=(unsigned int)(255*ctx->Fog.Color[0]);
1290 col[1]=(unsigned int)(255*ctx->Fog.Color[1]);
1291 col[2]=(unsigned int)(255*ctx->Fog.Color[2]);
1292 col[3]=(unsigned int)(255*ctx->Fog.Color[3]);
1293
1294 grFogColorValue(FXCOLOR4(col));
1295
1296 if(forceTableRebuild ||
1297 (fxMesa->fogTableMode!=ctx->Fog.Mode) ||
1298 (fxMesa->fogDensity!=ctx->Fog.Density)) {
1299 fxFogTableGenerate(ctx);
1300
1301 fxMesa->fogTableMode=ctx->Fog.Mode;
1302 fxMesa->fogDensity=ctx->Fog.Density;
1303 }
1304
1305 grFogTable(fxMesa->fogTable);
1306 } else
1307 grFogMode(GR_FOG_DISABLE);
1308 }
1309
1310 void fxDDFogfv( GLcontext *ctx, GLenum pname, const GLfloat *params )
1311 {
1312 FX_CONTEXT(ctx)->new_state |= FX_NEW_FOG;
1313 ctx->Driver.RenderStart = fxSetupFXUnits;
1314 }
1315
1316 /************************************************************************/
1317 /************************** Scissor Test SetUp **************************/
1318 /************************************************************************/
1319
1320 static void fxSetupScissor(GLcontext *ctx)
1321 {
1322 fxMesaContext fxMesa=(fxMesaContext)ctx->DriverCtx;
1323
1324 if (ctx->Scissor.Enabled) {
1325 int ymin, ymax;
1326
1327 ymin=ctx->Scissor.Y;
1328 ymax=ctx->Scissor.Y+ctx->Scissor.Height;
1329
1330 if (ymin<0) ymin=0;
1331
1332 if (ymax>fxMesa->height) ymax=fxMesa->height;
1333
1334 grClipWindow(ctx->Scissor.X,
1335 ymin,
1336 ctx->Scissor.X+ctx->Scissor.Width,
1337 ymax);
1338 } else
1339 grClipWindow(0,0,fxMesa->width,fxMesa->height);
1340 }
1341
1342 void fxDDScissor( GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h )
1343 {
1344 FX_CONTEXT(ctx)->new_state |= FX_NEW_SCISSOR;
1345 ctx->Driver.RenderStart = fxSetupFXUnits;
1346 }
1347
1348 /************************************************************************/
1349 /*************************** Cull mode setup ****************************/
1350 /************************************************************************/
1351
1352
1353 void fxDDCullFace(GLcontext *ctx, GLenum mode)
1354 {
1355 (void) mode;
1356 FX_CONTEXT(ctx)->new_state |= FX_NEW_CULL;
1357 ctx->Driver.RenderStart = fxSetupFXUnits;
1358 }
1359
1360 void fxDDFrontFace(GLcontext *ctx, GLenum mode)
1361 {
1362 (void) mode;
1363 FX_CONTEXT(ctx)->new_state |= FX_NEW_CULL;
1364 ctx->Driver.RenderStart = fxSetupFXUnits;
1365 }
1366
1367
1368 void fxSetupCull(GLcontext *ctx)
1369 {
1370 if(ctx->Polygon.CullFlag) {
1371 switch(ctx->Polygon.CullFaceMode) {
1372 case GL_BACK:
1373 if(ctx->Polygon.FrontFace==GL_CCW)
1374 grCullMode(GR_CULL_NEGATIVE);
1375 else
1376 grCullMode(GR_CULL_POSITIVE);
1377 break;
1378 case GL_FRONT:
1379 if(ctx->Polygon.FrontFace==GL_CCW)
1380 grCullMode(GR_CULL_POSITIVE);
1381 else
1382 grCullMode(GR_CULL_NEGATIVE);
1383 break;
1384 case GL_FRONT_AND_BACK:
1385 grCullMode(GR_CULL_DISABLE);
1386 break;
1387 default:
1388 break;
1389 }
1390 } else
1391 grCullMode(GR_CULL_DISABLE);
1392 }
1393
1394
1395 /************************************************************************/
1396 /****************************** DD Enable ******************************/
1397 /************************************************************************/
1398
1399 void fxDDEnable(GLcontext *ctx, GLenum cap, GLboolean state)
1400 {
1401 fxMesaContext fxMesa=(fxMesaContext)ctx->DriverCtx;
1402 tfxUnitsState *us=&fxMesa->unitsState;
1403
1404 if (MESA_VERBOSE&VERBOSE_DRIVER) {
1405 fprintf(stderr,"fxmesa: fxDDEnable(...)\n");
1406 }
1407
1408 switch(cap) {
1409 case GL_ALPHA_TEST:
1410 if(state!=us->alphaTestEnabled) {
1411 us->alphaTestEnabled=state;
1412 fxMesa->new_state |= FX_NEW_ALPHA;
1413 ctx->Driver.RenderStart = fxSetupFXUnits;
1414 }
1415 break;
1416 case GL_BLEND:
1417 if(state!=us->blendEnabled) {
1418 us->blendEnabled=state;
1419 fxMesa->new_state |= FX_NEW_BLEND;
1420 ctx->Driver.RenderStart = fxSetupFXUnits;
1421 }
1422 break;
1423 case GL_DEPTH_TEST:
1424 if(state!=us->depthTestEnabled) {
1425 us->depthTestEnabled=state;
1426 fxMesa->new_state |= FX_NEW_DEPTH;
1427 ctx->Driver.RenderStart = fxSetupFXUnits;
1428 }
1429 break;
1430 case GL_SCISSOR_TEST:
1431 fxMesa->new_state |= FX_NEW_SCISSOR;
1432 ctx->Driver.RenderStart = fxSetupFXUnits;
1433 break;
1434 case GL_FOG:
1435 fxMesa->new_state |= FX_NEW_FOG;
1436 ctx->Driver.RenderStart = fxSetupFXUnits;
1437 break;
1438 case GL_CULL_FACE:
1439 fxMesa->new_state |= FX_NEW_CULL;
1440 ctx->Driver.RenderStart = fxSetupFXUnits;
1441 break;
1442 case GL_LINE_SMOOTH:
1443 case GL_POINT_SMOOTH:
1444 case GL_POLYGON_SMOOTH:
1445 case GL_TEXTURE_2D:
1446 fxMesa->new_state |= FX_NEW_TEXTURING;
1447 ctx->Driver.RenderStart = fxSetupFXUnits;
1448 break;
1449 default:
1450 ; /* XXX no-op??? */
1451 }
1452 }
1453
1454 /************************************************************************/
1455 /******************** Fake Multitexture Support *************************/
1456 /************************************************************************/
1457
1458 /* Its considered cheeky to try to fake ARB multitexture by doing
1459 * multipass rendering, because it is not possible to emulate the full
1460 * spec in this way. The fact is that the voodoo 2 supports only a
1461 * subset of the possible multitexturing modes, and it is possible to
1462 * support almost the same subset using multipass blending on the
1463 * voodoo 1. In all other cases for both voodoo 1 and 2, we fall back
1464 * to software rendering, satisfying the spec if not the user.
1465 */
1466 static GLboolean fxMultipassTexture( struct vertex_buffer *VB, GLuint pass )
1467 {
1468 GLcontext *ctx = VB->ctx;
1469 fxVertex *v = FX_DRIVER_DATA(VB)->verts;
1470 fxVertex *last = FX_DRIVER_DATA(VB)->last_vert;
1471 fxMesaContext fxMesa = FX_CONTEXT(ctx);
1472
1473 switch (pass) {
1474 case 1:
1475 if (MESA_VERBOSE&(VERBOSE_DRIVER|VERBOSE_PIPELINE|VERBOSE_TEXTURE))
1476 fprintf(stderr, "fxmesa: Second texture pass\n");
1477
1478 for ( ; v != last ; v++) {
1479 v->f[S0COORD] = v->f[S1COORD];
1480 v->f[T0COORD] = v->f[T1COORD];
1481 }
1482
1483 fxMesa->restoreUnitsState = fxMesa->unitsState;
1484 fxMesa->tmu_source[0] = 1;
1485
1486 if (ctx->Depth.Mask) {
1487 switch (ctx->Depth.Func) {
1488 case GL_NEVER:
1489 case GL_ALWAYS:
1490 break;
1491 default:
1492 fxDDDepthFunc( ctx, GL_EQUAL );
1493 break;
1494 }
1495
1496 fxDDDepthMask( ctx, GL_FALSE );
1497 }
1498
1499 if (ctx->Texture.Unit[1].EnvMode == GL_MODULATE) {
1500 fxDDEnable( ctx, GL_BLEND, GL_TRUE );
1501 fxDDBlendFunc( ctx, GL_DST_COLOR, GL_ZERO );
1502 }
1503
1504 fxSetupTextureSingleTMU( ctx, 1 );
1505 fxSetupBlend( ctx );
1506 fxSetupDepthTest( ctx );
1507 break;
1508
1509 case 2:
1510 /* Restore original state.
1511 */
1512 fxMesa->tmu_source[0] = 0;
1513 fxMesa->unitsState = fxMesa->restoreUnitsState;
1514 fxMesa->setupdone &= ~SETUP_TMU0;
1515 fxSetupTextureSingleTMU( ctx, 0 );
1516 fxSetupBlend( ctx );
1517 fxSetupDepthTest( ctx );
1518 break;
1519 }
1520
1521 return pass == 1;
1522 }
1523
1524
1525 /************************************************************************/
1526 /************************** Changes to units state **********************/
1527 /************************************************************************/
1528
1529
1530 /* All units setup is handled under texture setup.
1531 */
1532 void fxDDShadeModel(GLcontext *ctx, GLenum mode)
1533 {
1534 FX_CONTEXT(ctx)->new_state |= FX_NEW_TEXTURING;
1535 ctx->Driver.RenderStart = fxSetupFXUnits;
1536 }
1537
1538
1539
1540 /************************************************************************/
1541 /****************************** Units SetUp *****************************/
1542 /************************************************************************/
1543 void gl_print_fx_state_flags( const char *msg, GLuint flags )
1544 {
1545 fprintf(stderr,
1546 "%s: (0x%x) %s%s%s%s%s%s%s\n",
1547 msg,
1548 flags,
1549 (flags & FX_NEW_TEXTURING) ? "texture, " : "",
1550 (flags & FX_NEW_BLEND) ? "blend, " : "",
1551 (flags & FX_NEW_ALPHA) ? "alpha, " : "",
1552 (flags & FX_NEW_FOG) ? "fog, " : "",
1553 (flags & FX_NEW_SCISSOR) ? "scissor, " : "",
1554 (flags & FX_NEW_COLOR_MASK) ? "colormask, " : "",
1555 (flags & FX_NEW_CULL) ? "cull, " : "");
1556 }
1557
1558 void fxSetupFXUnits( GLcontext *ctx )
1559 {
1560 fxMesaContext fxMesa=(fxMesaContext)ctx->DriverCtx;
1561 GLuint newstate = fxMesa->new_state;
1562
1563
1564 if (MESA_VERBOSE&VERBOSE_DRIVER)
1565 gl_print_fx_state_flags("fxmesa: fxSetupFXUnits", newstate);
1566
1567
1568 if (newstate) {
1569 if (newstate & FX_NEW_TEXTURING)
1570 fxSetupTexture(ctx);
1571
1572 if (newstate & FX_NEW_BLEND)
1573 fxSetupBlend(ctx);
1574
1575 if (newstate & FX_NEW_ALPHA)
1576 fxSetupAlphaTest(ctx);
1577
1578 if (newstate & FX_NEW_DEPTH)
1579 fxSetupDepthTest(ctx);
1580
1581 if (newstate & FX_NEW_FOG)
1582 fxSetupFog(ctx,GL_FALSE);
1583
1584 if (newstate & FX_NEW_SCISSOR)
1585 fxSetupScissor(ctx);
1586
1587 if (newstate & FX_NEW_COLOR_MASK)
1588 fxSetupColorMask(ctx);
1589
1590 if (newstate & FX_NEW_CULL)
1591 fxSetupCull(ctx);
1592
1593 fxMesa->new_state = 0;
1594 /* ctx->Driver.RenderStart = 0; */
1595 }
1596 }
1597
1598
1599
1600 #else
1601
1602
1603 /*
1604 * Need this to provide at least one external definition.
1605 */
1606
1607 int gl_fx_dummy_function_setup(void)
1608 {
1609 return 0;
1610 }
1611
1612 #endif /* FX */