b6bbb0c85b63964a74d570bd02a1ee3d71e71146
[mesa.git] / src / mesa / drivers / glide / fxsetup.c
1 /* -*- mode: C; tab-width:8; c-basic-offset:2 -*- */
2
3 /*
4 * Mesa 3-D graphics library
5 * Version: 3.3
6 *
7 * Copyright (C) 1999-2000 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 * Original Mesa / 3Dfx device driver (C) 1999 David Bucciarelli, by the
28 * terms stated above.
29 *
30 * Thank you for your contribution, David!
31 *
32 * Please make note of the above copyright/license statement. If you
33 * contributed code or bug fixes to this code under the previous (GNU
34 * Library) license and object to the new license, your code will be
35 * removed at your request. Please see the Mesa docs/COPYRIGHT file
36 * for more information.
37 *
38 * Additional Mesa/3Dfx driver developers:
39 * Daryll Strauss <daryll@precisioninsight.com>
40 * Keith Whitwell <keith@precisioninsight.com>
41 *
42 * See fxapi.h for more revision/author details.
43 */
44
45
46 /* fxsetup.c - 3Dfx VooDoo rendering mode setup functions */
47
48
49 #ifdef HAVE_CONFIG_H
50 #include "conf.h"
51 #endif
52
53 #if defined(FX)
54
55 #include "fxdrv.h"
56 #include "enums.h"
57
58 static GLuint fxGetTexSetConfiguration(GLcontext *ctx,
59 struct gl_texture_object *tObj0,
60 struct gl_texture_object *tObj1);
61 static void fxSetupTextureSingleTMU_NoLock(GLcontext *ctx, GLuint textureset);
62 static void fxSetupDoubleTMU_NoLock(fxMesaContext fxMesa,
63 struct gl_texture_object *tObj0,
64 struct gl_texture_object *tObj1);
65 static void fxSetupTexture_NoLock(GLcontext *ctx);
66 static void fxSetupTexture(GLcontext *ctx);
67 static void fxSetupBlend(GLcontext *ctx);
68 static void fxSetupDepthTest(GLcontext *ctx);
69 static void fxSetupScissor(GLcontext *ctx);
70 static void fxSetupCull(GLcontext *ctx);
71 static void gl_print_fx_state_flags( const char *msg, GLuint flags);
72 /*static GLboolean fxMultipassBlend(struct vertex_buffer *, GLuint);*/
73 static GLboolean fxMultipassTexture( struct vertex_buffer *, GLuint );
74
75 static void fxTexValidate(GLcontext *ctx, struct gl_texture_object *tObj)
76 {
77 tfxTexInfo *ti=fxTMGetTexInfo(tObj);
78 GLint minl, maxl;
79
80 if (MESA_VERBOSE&VERBOSE_DRIVER) {
81 fprintf(stderr,"fxmesa: fxTexValidate(...) Start\n");
82 }
83
84 if(ti->validated) {
85 if (MESA_VERBOSE&VERBOSE_DRIVER) {
86 fprintf(stderr,"fxmesa: fxTexValidate(...) End (validated=GL_TRUE)\n");
87 }
88 return;
89 }
90
91 ti->tObj=tObj;
92 minl=ti->minLevel=tObj->BaseLevel;
93 maxl=ti->maxLevel=MIN2(tObj->MaxLevel,tObj->Image[0]->MaxLog2);
94
95 fxTexGetInfo(tObj->Image[minl]->Width, tObj->Image[minl]->Height,
96 &(FX_largeLodLog2(ti->info)), &(FX_aspectRatioLog2(ti->info)),
97 &(ti->sScale), &(ti->tScale),
98 &(ti->int_sScale), &(ti->int_tScale),
99 NULL, NULL);
100
101 if((tObj->MinFilter!=GL_NEAREST) && (tObj->MinFilter!=GL_LINEAR))
102 fxTexGetInfo(tObj->Image[maxl]->Width,tObj->Image[maxl]->Height,
103 &(FX_smallLodLog2(ti->info)),NULL,
104 NULL,NULL,
105 NULL,NULL,
106 NULL,NULL);
107 else
108 FX_smallLodLog2(ti->info)=FX_largeLodLog2(ti->info);
109
110 fxTexGetFormat(tObj->Image[minl]->IntFormat,&(ti->info.format),&(ti->baseLevelInternalFormat));
111
112 switch (tObj->WrapS) {
113 case GL_CLAMP_TO_EDGE:
114 /* What's this really mean compared to GL_CLAMP? */
115 case GL_CLAMP:
116 ti->sClamp=1;
117 break;
118 case GL_REPEAT:
119 ti->sClamp=0;
120 break;
121 default:
122 ; /* silence compiler warning */
123 }
124 switch (tObj->WrapT) {
125 case GL_CLAMP_TO_EDGE:
126 /* What's this really mean compared to GL_CLAMP? */
127 case GL_CLAMP:
128 ti->tClamp=1;
129 break;
130 case GL_REPEAT:
131 ti->tClamp=0;
132 break;
133 default:
134 ; /* silence compiler warning */
135 }
136
137 ti->validated=GL_TRUE;
138
139 ti->info.data=NULL;
140
141 if (MESA_VERBOSE&VERBOSE_DRIVER) {
142 fprintf(stderr,"fxmesa: fxTexValidate(...) End\n");
143 }
144 }
145
146 static void fxPrintUnitsMode( const char *msg, GLuint mode )
147 {
148 fprintf(stderr,
149 "%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",
150 msg,
151 mode,
152 (mode & FX_UM_E0_REPLACE) ? "E0_REPLACE, " : "",
153 (mode & FX_UM_E0_MODULATE) ? "E0_MODULATE, " : "",
154 (mode & FX_UM_E0_DECAL) ? "E0_DECAL, " : "",
155 (mode & FX_UM_E0_BLEND) ? "E0_BLEND, " : "",
156 (mode & FX_UM_E1_REPLACE) ? "E1_REPLACE, " : "",
157 (mode & FX_UM_E1_MODULATE) ? "E1_MODULATE, " : "",
158 (mode & FX_UM_E1_DECAL) ? "E1_DECAL, " : "",
159 (mode & FX_UM_E1_BLEND) ? "E1_BLEND, " : "",
160 (mode & FX_UM_E0_ALPHA) ? "E0_ALPHA, " : "",
161 (mode & FX_UM_E0_LUMINANCE) ? "E0_LUMINANCE, " : "",
162 (mode & FX_UM_E0_LUMINANCE_ALPHA) ? "E0_LUMINANCE_ALPHA, " : "",
163 (mode & FX_UM_E0_INTENSITY) ? "E0_INTENSITY, " : "",
164 (mode & FX_UM_E0_RGB) ? "E0_RGB, " : "",
165 (mode & FX_UM_E0_RGBA) ? "E0_RGBA, " : "",
166 (mode & FX_UM_E1_ALPHA) ? "E1_ALPHA, " : "",
167 (mode & FX_UM_E1_LUMINANCE) ? "E1_LUMINANCE, " : "",
168 (mode & FX_UM_E1_LUMINANCE_ALPHA) ? "E1_LUMINANCE_ALPHA, " : "",
169 (mode & FX_UM_E1_INTENSITY) ? "E1_INTENSITY, " : "",
170 (mode & FX_UM_E1_RGB) ? "E1_RGB, " : "",
171 (mode & FX_UM_E1_RGBA) ? "E1_RGBA, " : "",
172 (mode & FX_UM_COLOR_ITERATED) ? "COLOR_ITERATED, " : "",
173 (mode & FX_UM_COLOR_CONSTANT) ? "COLOR_CONSTANT, " : "",
174 (mode & FX_UM_ALPHA_ITERATED) ? "ALPHA_ITERATED, " : "",
175 (mode & FX_UM_ALPHA_CONSTANT) ? "ALPHA_CONSTANT, " : "");
176 }
177
178 static GLuint fxGetTexSetConfiguration(GLcontext *ctx,
179 struct gl_texture_object *tObj0,
180 struct gl_texture_object *tObj1)
181 {
182 GLuint unitsmode=0;
183 GLuint envmode=0;
184 GLuint ifmt=0;
185
186 if((ctx->Light.ShadeModel==GL_SMOOTH) || 1 ||
187 (ctx->Point.SmoothFlag) ||
188 (ctx->Line.SmoothFlag) ||
189 (ctx->Polygon.SmoothFlag))
190 unitsmode|=FX_UM_ALPHA_ITERATED;
191 else
192 unitsmode|=FX_UM_ALPHA_CONSTANT;
193
194 if(ctx->Light.ShadeModel==GL_SMOOTH || 1)
195 unitsmode|=FX_UM_COLOR_ITERATED;
196 else
197 unitsmode|=FX_UM_COLOR_CONSTANT;
198
199
200
201 /*
202 OpenGL Feeds Texture 0 into Texture 1
203 Glide Feeds Texture 1 into Texture 0
204 */
205 if(tObj0) {
206 tfxTexInfo *ti0=fxTMGetTexInfo(tObj0);
207
208 switch(ti0->baseLevelInternalFormat) {
209 case GL_ALPHA:
210 ifmt|=FX_UM_E0_ALPHA;
211 break;
212 case GL_LUMINANCE:
213 ifmt|=FX_UM_E0_LUMINANCE;
214 break;
215 case GL_LUMINANCE_ALPHA:
216 ifmt|=FX_UM_E0_LUMINANCE_ALPHA;
217 break;
218 case GL_INTENSITY:
219 ifmt|=FX_UM_E0_INTENSITY;
220 break;
221 case GL_RGB:
222 ifmt|=FX_UM_E0_RGB;
223 break;
224 case GL_RGBA:
225 ifmt|=FX_UM_E0_RGBA;
226 break;
227 }
228
229 switch(ctx->Texture.Unit[0].EnvMode) {
230 case GL_DECAL:
231 envmode|=FX_UM_E0_DECAL;
232 break;
233 case GL_MODULATE:
234 envmode|=FX_UM_E0_MODULATE;
235 break;
236 case GL_REPLACE:
237 envmode|=FX_UM_E0_REPLACE;
238 break;
239 case GL_BLEND:
240 envmode|=FX_UM_E0_BLEND;
241 break;
242 case GL_ADD:
243 envmode|=FX_UM_E0_ADD;
244 break;
245 default:
246 /* do nothing */
247 break;
248 }
249 }
250
251 if(tObj1) {
252 tfxTexInfo *ti1=fxTMGetTexInfo(tObj1);
253
254 switch(ti1->baseLevelInternalFormat) {
255 case GL_ALPHA:
256 ifmt|=FX_UM_E1_ALPHA;
257 break;
258 case GL_LUMINANCE:
259 ifmt|=FX_UM_E1_LUMINANCE;
260 break;
261 case GL_LUMINANCE_ALPHA:
262 ifmt|=FX_UM_E1_LUMINANCE_ALPHA;
263 break;
264 case GL_INTENSITY:
265 ifmt|=FX_UM_E1_INTENSITY;
266 break;
267 case GL_RGB:
268 ifmt|=FX_UM_E1_RGB;
269 break;
270 case GL_RGBA:
271 ifmt|=FX_UM_E1_RGBA;
272 break;
273 default:
274 /* do nothing */
275 break;
276 }
277
278 switch(ctx->Texture.Unit[1].EnvMode) {
279 case GL_DECAL:
280 envmode|=FX_UM_E1_DECAL;
281 break;
282 case GL_MODULATE:
283 envmode|=FX_UM_E1_MODULATE;
284 break;
285 case GL_REPLACE:
286 envmode|=FX_UM_E1_REPLACE;
287 break;
288 case GL_BLEND:
289 envmode|=FX_UM_E1_BLEND;
290 break;
291 case GL_ADD:
292 envmode|=FX_UM_E1_ADD;
293 break;
294 default:
295 /* do nothing */
296 break;
297 }
298 }
299
300 unitsmode|=(ifmt | envmode);
301
302 if (MESA_VERBOSE & (VERBOSE_DRIVER|VERBOSE_TEXTURE))
303 fxPrintUnitsMode("unitsmode", unitsmode);
304
305 return unitsmode;
306 }
307
308 /************************************************************************/
309 /************************* Rendering Mode SetUp *************************/
310 /************************************************************************/
311
312 /************************* Single Texture Set ***************************/
313
314 static void fxSetupSingleTMU_NoLock(fxMesaContext fxMesa, struct gl_texture_object *tObj)
315 {
316 tfxTexInfo *ti=fxTMGetTexInfo(tObj);
317 int tmu;
318
319 /* Make sure we're not loaded incorrectly */
320 if (ti->isInTM) {
321 if (ti->LODblend) {
322 if (ti->whichTMU!=FX_TMU_SPLIT)
323 fxTMMoveOutTM(fxMesa, tObj);
324 } else {
325 if (ti->whichTMU==FX_TMU_SPLIT)
326 fxTMMoveOutTM(fxMesa, tObj);
327 }
328 }
329
330 /* Make sure we're loaded correctly */
331 if (!ti->isInTM) {
332 if (ti->LODblend)
333 fxTMMoveInTM_NoLock(fxMesa,tObj,FX_TMU_SPLIT);
334 else {
335 if (fxMesa->haveTwoTMUs) {
336 if (fxMesa->freeTexMem[FX_TMU0] >
337 FX_grTexTextureMemRequired_NoLock(GR_MIPMAPLEVELMASK_BOTH,
338 &(ti->info))) {
339 fxTMMoveInTM_NoLock(fxMesa,tObj, FX_TMU0);
340 } else {
341 fxTMMoveInTM_NoLock(fxMesa,tObj, FX_TMU1);
342 }
343 } else
344 fxTMMoveInTM_NoLock(fxMesa,tObj,FX_TMU0);
345 }
346 }
347
348 if (ti->LODblend && ti->whichTMU == FX_TMU_SPLIT) {
349 if ((ti->info.format==GR_TEXFMT_P_8) && (!fxMesa->haveGlobalPaletteTexture)) {
350 if (MESA_VERBOSE&VERBOSE_DRIVER) {
351 fprintf(stderr,"fxmesa: uploading texture palette\n");
352 }
353 FX_grTexDownloadTable_NoLock(GR_TMU0,GR_TEXTABLE_PALETTE,&(ti->palette));
354 FX_grTexDownloadTable_NoLock(GR_TMU1,GR_TEXTABLE_PALETTE,&(ti->palette));
355 }
356
357 FX_grTexClampMode_NoLock(GR_TMU0,ti->sClamp,ti->tClamp);
358 FX_grTexClampMode_NoLock(GR_TMU1,ti->sClamp,ti->tClamp);
359 FX_grTexFilterMode_NoLock(GR_TMU0,ti->minFilt,ti->maxFilt);
360 FX_grTexFilterMode_NoLock(GR_TMU1,ti->minFilt,ti->maxFilt);
361 FX_grTexMipMapMode_NoLock(GR_TMU0,ti->mmMode,ti->LODblend);
362 FX_grTexMipMapMode_NoLock(GR_TMU1,ti->mmMode,ti->LODblend);
363
364 FX_grTexSource_NoLock(GR_TMU0,ti->tm[FX_TMU0]->startAddr,
365 GR_MIPMAPLEVELMASK_ODD,&(ti->info));
366 FX_grTexSource_NoLock(GR_TMU1,ti->tm[FX_TMU1]->startAddr,
367 GR_MIPMAPLEVELMASK_EVEN,&(ti->info));
368 } else {
369 if (ti->whichTMU==FX_TMU_BOTH) tmu=FX_TMU0;
370 else tmu=ti->whichTMU;
371
372 if((ti->info.format==GR_TEXFMT_P_8) && (!fxMesa->haveGlobalPaletteTexture)) {
373 if (MESA_VERBOSE&VERBOSE_DRIVER) {
374 fprintf(stderr,"fxmesa: uploading texture palette\n");
375 }
376 FX_grTexDownloadTable_NoLock(tmu, GR_TEXTABLE_PALETTE, &(ti->palette));
377 }
378
379 /* KW: The alternative is to do the download to the other tmu. If
380 * we get to this point, I think it means we are thrashing the
381 * texture memory, so perhaps it's not a good idea.
382 */
383 if (ti->LODblend && (MESA_VERBOSE&VERBOSE_DRIVER))
384 fprintf(stderr, "fxmesa: not blending texture - only on one tmu\n");
385
386 FX_grTexClampMode_NoLock(tmu, ti->sClamp, ti->tClamp);
387 FX_grTexFilterMode_NoLock(tmu, ti->minFilt, ti->maxFilt);
388 FX_grTexMipMapMode_NoLock(tmu, ti->mmMode, FXFALSE);
389
390 FX_grTexSource_NoLock(tmu, ti->tm[tmu]->startAddr,
391 GR_MIPMAPLEVELMASK_BOTH, &(ti->info));
392 }
393 }
394
395 static void fxSelectSingleTMUSrc_NoLock(fxMesaContext fxMesa, GLint tmu,
396 FxBool LODblend)
397 {
398 if (MESA_VERBOSE&VERBOSE_DRIVER) {
399 fprintf(stderr,"fxmesa: fxSelectSingleTMUSrc(%d,%d)\n",tmu,LODblend);
400 }
401
402 if (LODblend) {
403 FX_grTexCombine_NoLock(GR_TMU0,
404 GR_COMBINE_FUNCTION_BLEND,
405 GR_COMBINE_FACTOR_ONE_MINUS_LOD_FRACTION,
406 GR_COMBINE_FUNCTION_BLEND,
407 GR_COMBINE_FACTOR_ONE_MINUS_LOD_FRACTION,
408 FXFALSE,FXFALSE);
409
410 if (fxMesa->haveTwoTMUs)
411 FX_grTexCombine_NoLock(GR_TMU1,
412 GR_COMBINE_FUNCTION_LOCAL,GR_COMBINE_FACTOR_NONE,
413 GR_COMBINE_FUNCTION_LOCAL,GR_COMBINE_FACTOR_NONE,
414 FXFALSE,FXFALSE);
415 fxMesa->tmuSrc=FX_TMU_SPLIT;
416 }
417 else {
418 if (tmu!=FX_TMU1) {
419 FX_grTexCombine_NoLock(GR_TMU0,
420 GR_COMBINE_FUNCTION_LOCAL,GR_COMBINE_FACTOR_NONE,
421 GR_COMBINE_FUNCTION_LOCAL,GR_COMBINE_FACTOR_NONE,
422 FXFALSE,FXFALSE);
423 if (fxMesa->haveTwoTMUs) {
424 FX_grTexCombine_NoLock(GR_TMU1,
425 GR_COMBINE_FUNCTION_ZERO, GR_COMBINE_FACTOR_NONE,
426 GR_COMBINE_FUNCTION_ZERO, GR_COMBINE_FACTOR_NONE,
427 FXFALSE,FXFALSE);
428 }
429 fxMesa->tmuSrc=FX_TMU0;
430 }
431 else {
432 FX_grTexCombine_NoLock(GR_TMU1,
433 GR_COMBINE_FUNCTION_LOCAL,GR_COMBINE_FACTOR_NONE,
434 GR_COMBINE_FUNCTION_LOCAL,GR_COMBINE_FACTOR_NONE,
435 FXFALSE,FXFALSE);
436
437 /* GR_COMBINE_FUNCTION_SCALE_OTHER doesn't work ?!? */
438
439 FX_grTexCombine_NoLock(GR_TMU0,
440 GR_COMBINE_FUNCTION_BLEND,
441 GR_COMBINE_FACTOR_ONE,
442 GR_COMBINE_FUNCTION_BLEND,
443 GR_COMBINE_FACTOR_ONE,
444 FXFALSE,FXFALSE);
445
446 fxMesa->tmuSrc=FX_TMU1;
447 }
448 }
449 }
450
451 static void fxSetupTextureSingleTMU_NoLock(GLcontext *ctx, GLuint textureset)
452 {
453 fxMesaContext fxMesa=(fxMesaContext)ctx->DriverCtx;
454 GrCombineLocal_t localc,locala;
455 GLuint unitsmode;
456 GLint ifmt;
457 tfxTexInfo *ti;
458 struct gl_texture_object *tObj=ctx->Texture.Unit[textureset].CurrentD[2];
459 int tmu;
460
461 if (MESA_VERBOSE&VERBOSE_DRIVER) {
462 fprintf(stderr,"fxmesa: fxSetupTextureSingleTMU(...) Start\n");
463 }
464
465 ti=fxTMGetTexInfo(tObj);
466
467 fxTexValidate(ctx,tObj);
468
469 fxSetupSingleTMU_NoLock(fxMesa,tObj);
470
471 if (ti->whichTMU==FX_TMU_BOTH) tmu=FX_TMU0;
472 else tmu=ti->whichTMU;
473 if (fxMesa->tmuSrc!=tmu)
474 fxSelectSingleTMUSrc_NoLock(fxMesa, tmu, ti->LODblend);
475
476 if(textureset==0 || !fxMesa->haveTwoTMUs)
477 unitsmode=fxGetTexSetConfiguration(ctx,tObj,NULL);
478 else
479 unitsmode=fxGetTexSetConfiguration(ctx,NULL,tObj);
480
481 /* if(fxMesa->lastUnitsMode==unitsmode) */
482 /* return; */
483
484 fxMesa->lastUnitsMode=unitsmode;
485
486 fxMesa->stw_hint_state = 0;
487 FX_grHints_NoLock(GR_HINT_STWHINT,0);
488
489 ifmt=ti->baseLevelInternalFormat;
490
491 if(unitsmode & FX_UM_ALPHA_ITERATED)
492 locala=GR_COMBINE_LOCAL_ITERATED;
493 else
494 locala=GR_COMBINE_LOCAL_CONSTANT;
495
496 if(unitsmode & FX_UM_COLOR_ITERATED)
497 localc=GR_COMBINE_LOCAL_ITERATED;
498 else
499 localc=GR_COMBINE_LOCAL_CONSTANT;
500
501 if (MESA_VERBOSE & (VERBOSE_DRIVER|VERBOSE_TEXTURE))
502 fprintf(stderr, "fxMesa: fxSetupTextureSingleTMU, envmode is %s\n",
503 gl_lookup_enum_by_nr(ctx->Texture.Unit[textureset].EnvMode));
504
505 switch(ctx->Texture.Unit[textureset].EnvMode) {
506 case GL_DECAL:
507 FX_grAlphaCombine_NoLock(GR_COMBINE_FUNCTION_LOCAL,
508 GR_COMBINE_FACTOR_NONE,
509 locala,
510 GR_COMBINE_OTHER_NONE,
511 FXFALSE);
512
513 FX_grColorCombine_NoLock(GR_COMBINE_FUNCTION_BLEND,
514 GR_COMBINE_FACTOR_TEXTURE_ALPHA,
515 localc,
516 GR_COMBINE_OTHER_TEXTURE,
517 FXFALSE);
518 break;
519 case GL_MODULATE:
520 FX_grAlphaCombine_NoLock(GR_COMBINE_FUNCTION_SCALE_OTHER,
521 GR_COMBINE_FACTOR_LOCAL,
522 locala,
523 GR_COMBINE_OTHER_TEXTURE,
524 FXFALSE);
525
526 if(ifmt==GL_ALPHA)
527 FX_grColorCombine_NoLock(GR_COMBINE_FUNCTION_LOCAL,
528 GR_COMBINE_FACTOR_NONE,
529 localc,
530 GR_COMBINE_OTHER_NONE,
531 FXFALSE);
532 else
533 FX_grColorCombine_NoLock(GR_COMBINE_FUNCTION_SCALE_OTHER,
534 GR_COMBINE_FACTOR_LOCAL,
535 localc,
536 GR_COMBINE_OTHER_TEXTURE,
537 FXFALSE);
538 break;
539 case GL_BLEND:
540 #if 0
541 FX_grAlphaCombine_NoLock(GR_COMBINE_FUNCTION_SCALE_OTHER,
542 GR_COMBINE_FACTOR_LOCAL,
543 locala,
544 GR_COMBINE_OTHER_TEXTURE,
545 FXFALSE);
546 if (ifmt==GL_ALPHA)
547 FX_grColorCombine_NoLock(GR_COMBINE_FUNCTION_LOCAL,
548 GR_COMBINE_FACTOR_NONE,
549 localc,
550 GR_COMBINE_OTHER_NONE,
551 FXFALSE);
552 else
553 FX_grColorCombine_NoLock(GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL,
554 GR_COMBINE_FACTOR_LOCAL,
555 localc,
556 GR_COMBINE_OTHER_TEXTURE,
557 FXTRUE);
558 ctx->Driver.MultipassFunc = fxMultipassBlend;
559 #else
560 if (MESA_VERBOSE&VERBOSE_DRIVER)
561 fprintf(stderr,"fx Driver: GL_BLEND not yet supported\n");
562 #endif
563 break;
564 case GL_REPLACE:
565 if((ifmt==GL_RGB) || (ifmt==GL_LUMINANCE))
566 FX_grAlphaCombine_NoLock(GR_COMBINE_FUNCTION_LOCAL,
567 GR_COMBINE_FACTOR_NONE,
568 locala,
569 GR_COMBINE_OTHER_NONE,
570 FXFALSE);
571 else
572 FX_grAlphaCombine_NoLock(GR_COMBINE_FUNCTION_SCALE_OTHER,
573 GR_COMBINE_FACTOR_ONE,
574 locala,
575 GR_COMBINE_OTHER_TEXTURE,
576 FXFALSE);
577
578 if(ifmt==GL_ALPHA)
579 FX_grColorCombine_NoLock(GR_COMBINE_FUNCTION_LOCAL,
580 GR_COMBINE_FACTOR_NONE,
581 localc,
582 GR_COMBINE_OTHER_NONE,
583 FXFALSE);
584 else
585 FX_grColorCombine_NoLock(GR_COMBINE_FUNCTION_SCALE_OTHER,
586 GR_COMBINE_FACTOR_ONE,
587 localc,
588 GR_COMBINE_OTHER_TEXTURE,
589 FXFALSE);
590 break;
591 default:
592 if (MESA_VERBOSE&VERBOSE_DRIVER)
593 fprintf(stderr, "fx Driver: %x Texture.EnvMode not yet supported\n",
594 ctx->Texture.Unit[textureset].EnvMode);
595 break;
596 }
597
598 if (MESA_VERBOSE&VERBOSE_DRIVER) {
599 fprintf(stderr,"fxmesa: fxSetupTextureSingleTMU(...) End\n");
600 }
601 }
602
603 static void fxSetupTextureSingleTMU(GLcontext *ctx, GLuint textureset) {
604 BEGIN_BOARD_LOCK();
605 fxSetupTextureSingleTMU_NoLock(ctx, textureset);
606 END_BOARD_LOCK();
607 }
608
609 /************************* Double Texture Set ***************************/
610
611 static void fxSetupDoubleTMU_NoLock(fxMesaContext fxMesa,
612 struct gl_texture_object *tObj0,
613 struct gl_texture_object *tObj1)
614 {
615 #define T0_NOT_IN_TMU 0x01
616 #define T1_NOT_IN_TMU 0x02
617 #define T0_IN_TMU0 0x04
618 #define T1_IN_TMU0 0x08
619 #define T0_IN_TMU1 0x10
620 #define T1_IN_TMU1 0x20
621
622 tfxTexInfo *ti0=fxTMGetTexInfo(tObj0);
623 tfxTexInfo *ti1=fxTMGetTexInfo(tObj1);
624 GLuint tstate=0;
625 int tmu0=0, tmu1=1;
626
627 if (MESA_VERBOSE&VERBOSE_DRIVER) {
628 fprintf(stderr,"fxmesa: fxSetupDoubleTMU(...)\n");
629 }
630
631 /* We shouldn't need to do this. There is something wrong with
632 mutlitexturing when the TMUs are swapped. So, we're forcing
633 them to always be loaded correctly. !!! */
634 if (ti0->whichTMU==FX_TMU1)
635 fxTMMoveOutTM_NoLock(fxMesa, tObj0);
636 if (ti1->whichTMU==FX_TMU0)
637 fxTMMoveOutTM_NoLock(fxMesa, tObj1);
638
639 if (ti0->isInTM) {
640 switch (ti0->whichTMU) {
641 case FX_TMU0:
642 tstate|=T0_IN_TMU0;
643 break;
644 case FX_TMU1:
645 tstate|=T0_IN_TMU1;
646 break;
647 case FX_TMU_BOTH:
648 tstate|=T0_IN_TMU0|T0_IN_TMU1;
649 break;
650 case FX_TMU_SPLIT:
651 tstate|=T0_NOT_IN_TMU;
652 break;
653 }
654 } else tstate|=T0_NOT_IN_TMU;
655
656 if (ti1->isInTM) {
657 switch (ti1->whichTMU) {
658 case FX_TMU0:
659 tstate|=T1_IN_TMU0;
660 break;
661 case FX_TMU1:
662 tstate|=T1_IN_TMU1;
663 break;
664 case FX_TMU_BOTH:
665 tstate|=T1_IN_TMU0|T1_IN_TMU1;
666 break;
667 case FX_TMU_SPLIT:
668 tstate|=T1_NOT_IN_TMU;
669 break;
670 }
671 } else tstate|=T1_NOT_IN_TMU;
672
673 ti0->lastTimeUsed=fxMesa->texBindNumber;
674 ti1->lastTimeUsed=fxMesa->texBindNumber;
675
676 /* Move texture maps into TMUs */
677
678 if (!(((tstate&T0_IN_TMU0) && (tstate&T1_IN_TMU1)) ||
679 ((tstate&T0_IN_TMU1) && (tstate&T1_IN_TMU0)))) {
680 if (tObj0==tObj1) fxTMMoveInTM_NoLock(fxMesa, tObj1, FX_TMU_BOTH);
681 else {
682 /* Find the minimal way to correct the situation */
683 if ((tstate&T0_IN_TMU0) || (tstate&T1_IN_TMU1)) {
684 /* We have one in the standard order, setup the other */
685 if (tstate&T0_IN_TMU0) { /* T0 is in TMU0, put T1 in TMU1 */
686 fxTMMoveInTM_NoLock(fxMesa, tObj1, FX_TMU1);
687 } else {
688 fxTMMoveInTM_NoLock(fxMesa, tObj0, FX_TMU0);
689 }
690 /* tmu0 and tmu1 are setup */
691 } else if ((tstate&T0_IN_TMU1) || (tstate&T1_IN_TMU0)) {
692 /* we have one in the reverse order, setup the other */
693 if (tstate&T1_IN_TMU0) { /* T1 is in TMU0, put T0 in TMU1 */
694 fxTMMoveInTM_NoLock(fxMesa, tObj0, FX_TMU1);
695 } else {
696 fxTMMoveInTM_NoLock(fxMesa, tObj1, FX_TMU0);
697 }
698 tmu0=1;
699 tmu1=0;
700 } else { /* Nothing is loaded */
701 fxTMMoveInTM_NoLock(fxMesa, tObj0, FX_TMU0);
702 fxTMMoveInTM_NoLock(fxMesa, tObj1, FX_TMU1);
703 /* tmu0 and tmu1 are setup */
704 }
705 }
706 }
707
708 if (!fxMesa->haveGlobalPaletteTexture) {
709 if (ti0->info.format==GR_TEXFMT_P_8) {
710 if (MESA_VERBOSE&VERBOSE_DRIVER) {
711 fprintf(stderr,"fxmesa: uploading texture palette TMU0\n");
712 }
713 FX_grTexDownloadTable_NoLock(tmu0, GR_TEXTABLE_PALETTE, &(ti0->palette));
714 }
715
716 if (ti1->info.format==GR_TEXFMT_P_8) {
717 if (MESA_VERBOSE&VERBOSE_DRIVER) {
718 fprintf(stderr,"fxmesa: uploading texture palette TMU1\n");
719 }
720 FX_grTexDownloadTable_NoLock(tmu1, GR_TEXTABLE_PALETTE, &(ti1->palette));
721 }
722 }
723
724 FX_grTexSource_NoLock(tmu0, ti0->tm[tmu0]->startAddr,
725 GR_MIPMAPLEVELMASK_BOTH, &(ti0->info));
726 FX_grTexClampMode_NoLock(tmu0, ti0->sClamp, ti0->tClamp);
727 FX_grTexFilterMode_NoLock(tmu0, ti0->minFilt, ti0->maxFilt);
728 FX_grTexMipMapMode_NoLock(tmu0, ti0->mmMode, FXFALSE);
729
730 FX_grTexSource_NoLock(tmu1, ti1->tm[tmu1]->startAddr,
731 GR_MIPMAPLEVELMASK_BOTH, &(ti1->info));
732 FX_grTexClampMode_NoLock(tmu1, ti1->sClamp, ti1->tClamp);
733 FX_grTexFilterMode_NoLock(tmu1, ti1->minFilt, ti1->maxFilt);
734 FX_grTexMipMapMode_NoLock(tmu1, ti1->mmMode, FXFALSE);
735
736 #undef T0_NOT_IN_TMU
737 #undef T1_NOT_IN_TMU
738 #undef T0_IN_TMU0
739 #undef T1_IN_TMU0
740 #undef T0_IN_TMU1
741 #undef T1_IN_TMU1
742 }
743
744 static void fxSetupTextureDoubleTMU_NoLock(GLcontext *ctx)
745 {
746 fxMesaContext fxMesa=(fxMesaContext)ctx->DriverCtx;
747 GrCombineLocal_t localc,locala;
748 tfxTexInfo *ti0,*ti1;
749 struct gl_texture_object *tObj0=ctx->Texture.Unit[0].CurrentD[2];
750 struct gl_texture_object *tObj1=ctx->Texture.Unit[1].CurrentD[2];
751 GLuint envmode,ifmt,unitsmode;
752 int tmu0=0, tmu1=1;
753
754 if (MESA_VERBOSE&VERBOSE_DRIVER) {
755 fprintf(stderr,"fxmesa: fxSetupTextureDoubleTMU(...) Start\n");
756 }
757
758 ti0=fxTMGetTexInfo(tObj0);
759 fxTexValidate(ctx,tObj0);
760
761 ti1=fxTMGetTexInfo(tObj1);
762 fxTexValidate(ctx,tObj1);
763
764 fxSetupDoubleTMU_NoLock(fxMesa,tObj0,tObj1);
765
766 unitsmode=fxGetTexSetConfiguration(ctx,tObj0,tObj1);
767
768 /* if(fxMesa->lastUnitsMode==unitsmode) */
769 /* return; */
770
771 fxMesa->lastUnitsMode=unitsmode;
772
773 fxMesa->stw_hint_state |= GR_STWHINT_ST_DIFF_TMU1;
774 FX_grHints_NoLock(GR_HINT_STWHINT, fxMesa->stw_hint_state);
775
776 envmode=unitsmode & FX_UM_E_ENVMODE;
777 ifmt=unitsmode & FX_UM_E_IFMT;
778
779 if(unitsmode & FX_UM_ALPHA_ITERATED)
780 locala=GR_COMBINE_LOCAL_ITERATED;
781 else
782 locala=GR_COMBINE_LOCAL_CONSTANT;
783
784 if(unitsmode & FX_UM_COLOR_ITERATED)
785 localc=GR_COMBINE_LOCAL_ITERATED;
786 else
787 localc=GR_COMBINE_LOCAL_CONSTANT;
788
789
790 if (MESA_VERBOSE & (VERBOSE_DRIVER|VERBOSE_TEXTURE))
791 fprintf(stderr, "fxMesa: fxSetupTextureDoubleTMU, envmode is %s/%s\n",
792 gl_lookup_enum_by_nr(ctx->Texture.Unit[0].EnvMode),
793 gl_lookup_enum_by_nr(ctx->Texture.Unit[1].EnvMode));
794
795
796 if ((ti0->whichTMU==FX_TMU1) || (ti1->whichTMU==FX_TMU0)) {
797 tmu0=1;
798 tmu1=0;
799 }
800 fxMesa->tmuSrc=FX_TMU_BOTH;
801 switch(envmode) {
802 case (FX_UM_E0_MODULATE | FX_UM_E1_MODULATE):
803 {
804 GLboolean isalpha[FX_NUM_TMU];
805
806 if(ti0->baseLevelInternalFormat==GL_ALPHA)
807 isalpha[tmu0]=GL_TRUE;
808 else
809 isalpha[tmu0]=GL_FALSE;
810
811 if(ti1->baseLevelInternalFormat==GL_ALPHA)
812 isalpha[tmu1]=GL_TRUE;
813 else
814 isalpha[tmu1]=GL_FALSE;
815
816 if(isalpha[FX_TMU1])
817 FX_grTexCombine_NoLock(GR_TMU1,
818 GR_COMBINE_FUNCTION_ZERO,
819 GR_COMBINE_FACTOR_NONE,
820 GR_COMBINE_FUNCTION_LOCAL,
821 GR_COMBINE_FACTOR_NONE,
822 FXTRUE,FXFALSE);
823 else
824 FX_grTexCombine_NoLock(GR_TMU1,
825 GR_COMBINE_FUNCTION_LOCAL,
826 GR_COMBINE_FACTOR_NONE,
827 GR_COMBINE_FUNCTION_LOCAL,
828 GR_COMBINE_FACTOR_NONE,
829 FXFALSE,FXFALSE);
830
831 if(isalpha[FX_TMU0])
832 FX_grTexCombine_NoLock(GR_TMU0,
833 GR_COMBINE_FUNCTION_BLEND_OTHER,
834 GR_COMBINE_FACTOR_ONE,
835 GR_COMBINE_FUNCTION_BLEND_OTHER,
836 GR_COMBINE_FACTOR_LOCAL,
837 FXFALSE,FXFALSE);
838 else
839 FX_grTexCombine_NoLock(GR_TMU0,
840 GR_COMBINE_FUNCTION_BLEND_OTHER,
841 GR_COMBINE_FACTOR_LOCAL,
842 GR_COMBINE_FUNCTION_BLEND_OTHER,
843 GR_COMBINE_FACTOR_LOCAL,
844 FXFALSE,FXFALSE);
845
846 FX_grColorCombine_NoLock(GR_COMBINE_FUNCTION_SCALE_OTHER,
847 GR_COMBINE_FACTOR_LOCAL,
848 localc,
849 GR_COMBINE_OTHER_TEXTURE,
850 FXFALSE);
851
852 FX_grAlphaCombine_NoLock(GR_COMBINE_FUNCTION_SCALE_OTHER,
853 GR_COMBINE_FACTOR_LOCAL,
854 locala,
855 GR_COMBINE_OTHER_TEXTURE,
856 FXFALSE);
857 break;
858 }
859 case (FX_UM_E0_REPLACE | FX_UM_E1_BLEND): /* Only for GLQuake */
860 if (tmu1==FX_TMU1) {
861 FX_grTexCombine_NoLock(GR_TMU1,
862 GR_COMBINE_FUNCTION_LOCAL,
863 GR_COMBINE_FACTOR_NONE,
864 GR_COMBINE_FUNCTION_LOCAL,
865 GR_COMBINE_FACTOR_NONE,
866 FXTRUE,FXFALSE);
867
868 FX_grTexCombine_NoLock(GR_TMU0,
869 GR_COMBINE_FUNCTION_BLEND_OTHER,
870 GR_COMBINE_FACTOR_LOCAL,
871 GR_COMBINE_FUNCTION_BLEND_OTHER,
872 GR_COMBINE_FACTOR_LOCAL,
873 FXFALSE,FXFALSE);
874 } else {
875 FX_grTexCombine_NoLock(GR_TMU1,
876 GR_COMBINE_FUNCTION_LOCAL,
877 GR_COMBINE_FACTOR_NONE,
878 GR_COMBINE_FUNCTION_LOCAL,
879 GR_COMBINE_FACTOR_NONE,
880 FXFALSE,FXFALSE);
881
882 FX_grTexCombine_NoLock(GR_TMU0,
883 GR_COMBINE_FUNCTION_BLEND_OTHER,
884 GR_COMBINE_FACTOR_ONE_MINUS_LOCAL,
885 GR_COMBINE_FUNCTION_BLEND_OTHER,
886 GR_COMBINE_FACTOR_ONE_MINUS_LOCAL,
887 FXFALSE,FXFALSE);
888 }
889
890 FX_grAlphaCombine_NoLock(GR_COMBINE_FUNCTION_LOCAL,
891 GR_COMBINE_FACTOR_NONE,
892 locala,
893 GR_COMBINE_OTHER_NONE,
894 FXFALSE);
895
896 FX_grColorCombine_NoLock(GR_COMBINE_FUNCTION_SCALE_OTHER,
897 GR_COMBINE_FACTOR_ONE,
898 localc,
899 GR_COMBINE_OTHER_TEXTURE,
900 FXFALSE);
901 break;
902 case (FX_UM_E0_REPLACE | FX_UM_E1_MODULATE): /* Quake 2 and 3 */
903 if (tmu1==FX_TMU1) {
904 FX_grTexCombine_NoLock(GR_TMU1,
905 GR_COMBINE_FUNCTION_LOCAL,
906 GR_COMBINE_FACTOR_NONE,
907 GR_COMBINE_FUNCTION_ZERO,
908 GR_COMBINE_FACTOR_NONE,
909 FXFALSE,FXTRUE);
910
911 FX_grTexCombine_NoLock(GR_TMU0,
912 GR_COMBINE_FUNCTION_BLEND_OTHER,
913 GR_COMBINE_FACTOR_LOCAL,
914 GR_COMBINE_FUNCTION_BLEND_OTHER,
915 GR_COMBINE_FACTOR_LOCAL,
916 FXFALSE,FXFALSE);
917
918 } else {
919 FX_grTexCombine_NoLock(GR_TMU1,
920 GR_COMBINE_FUNCTION_LOCAL,
921 GR_COMBINE_FACTOR_NONE,
922 GR_COMBINE_FUNCTION_LOCAL,
923 GR_COMBINE_FACTOR_NONE,
924 FXFALSE,FXFALSE);
925
926 FX_grTexCombine_NoLock(GR_TMU0,
927 GR_COMBINE_FUNCTION_BLEND_OTHER,
928 GR_COMBINE_FACTOR_LOCAL,
929 GR_COMBINE_FUNCTION_BLEND_OTHER,
930 GR_COMBINE_FACTOR_ONE,
931 FXFALSE,FXFALSE);
932 }
933
934 if(ti0->baseLevelInternalFormat==GL_RGB)
935 FX_grAlphaCombine_NoLock(GR_COMBINE_FUNCTION_LOCAL,
936 GR_COMBINE_FACTOR_NONE,
937 locala,
938 GR_COMBINE_OTHER_NONE,
939 FXFALSE);
940 else
941 FX_grAlphaCombine_NoLock(GR_COMBINE_FUNCTION_SCALE_OTHER,
942 GR_COMBINE_FACTOR_ONE,
943 locala,
944 GR_COMBINE_OTHER_NONE,
945 FXFALSE);
946
947
948 FX_grColorCombine_NoLock(GR_COMBINE_FUNCTION_SCALE_OTHER,
949 GR_COMBINE_FACTOR_ONE,
950 localc,
951 GR_COMBINE_OTHER_TEXTURE,
952 FXFALSE);
953 break;
954
955
956 case (FX_UM_E0_MODULATE | FX_UM_E1_ADD): /* Quake 3 Sky */
957 {
958 GLboolean isalpha[FX_NUM_TMU];
959
960 if(ti0->baseLevelInternalFormat==GL_ALPHA)
961 isalpha[tmu0]=GL_TRUE;
962 else
963 isalpha[tmu0]=GL_FALSE;
964
965 if(ti1->baseLevelInternalFormat==GL_ALPHA)
966 isalpha[tmu1]=GL_TRUE;
967 else
968 isalpha[tmu1]=GL_FALSE;
969
970 if(isalpha[FX_TMU1])
971 FX_grTexCombine_NoLock(GR_TMU1,
972 GR_COMBINE_FUNCTION_ZERO,
973 GR_COMBINE_FACTOR_NONE,
974 GR_COMBINE_FUNCTION_LOCAL,
975 GR_COMBINE_FACTOR_NONE,
976 FXTRUE,FXFALSE);
977 else
978 FX_grTexCombine_NoLock(GR_TMU1,
979 GR_COMBINE_FUNCTION_LOCAL,
980 GR_COMBINE_FACTOR_NONE,
981 GR_COMBINE_FUNCTION_LOCAL,
982 GR_COMBINE_FACTOR_NONE,
983 FXFALSE,FXFALSE);
984
985 if(isalpha[FX_TMU0])
986 FX_grTexCombine_NoLock(GR_TMU0,
987 GR_COMBINE_FUNCTION_SCALE_OTHER,
988 GR_COMBINE_FACTOR_ONE,
989 GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL,
990 GR_COMBINE_FACTOR_ONE,
991 FXFALSE,FXFALSE);
992 else
993 FX_grTexCombine_NoLock(GR_TMU0,
994 GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL,
995 GR_COMBINE_FACTOR_ONE,
996 GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL,
997 GR_COMBINE_FACTOR_ONE,
998 FXFALSE,FXFALSE);
999
1000 FX_grColorCombine_NoLock(GR_COMBINE_FUNCTION_SCALE_OTHER,
1001 GR_COMBINE_FACTOR_LOCAL,
1002 localc,
1003 GR_COMBINE_OTHER_TEXTURE,
1004 FXFALSE);
1005
1006 FX_grAlphaCombine_NoLock(GR_COMBINE_FUNCTION_SCALE_OTHER,
1007 GR_COMBINE_FACTOR_LOCAL,
1008 locala,
1009 GR_COMBINE_OTHER_TEXTURE,
1010 FXFALSE);
1011 break;
1012 }
1013 default:
1014 fprintf(stderr, "Unexpected dual texture mode encountered\n");
1015 break;
1016 }
1017
1018 if (MESA_VERBOSE&VERBOSE_DRIVER) {
1019 fprintf(stderr,"fxmesa: fxSetupTextureDoubleTMU(...) End\n");
1020 }
1021 }
1022
1023 /************************* No Texture ***************************/
1024
1025 static void fxSetupTextureNone_NoLock(GLcontext *ctx)
1026 {
1027 fxMesaContext fxMesa=(fxMesaContext)ctx->DriverCtx;
1028 GrCombineLocal_t localc,locala;
1029
1030 if (MESA_VERBOSE&VERBOSE_DRIVER) {
1031 fprintf(stderr,"fxmesa: fxSetupTextureNone(...)\n");
1032 }
1033
1034 if((ctx->Light.ShadeModel==GL_SMOOTH) || 1 ||
1035 (ctx->Point.SmoothFlag) ||
1036 (ctx->Line.SmoothFlag) ||
1037 (ctx->Polygon.SmoothFlag))
1038 locala=GR_COMBINE_LOCAL_ITERATED;
1039 else
1040 locala=GR_COMBINE_LOCAL_CONSTANT;
1041
1042 if(ctx->Light.ShadeModel==GL_SMOOTH || 1)
1043 localc=GR_COMBINE_LOCAL_ITERATED;
1044 else
1045 localc=GR_COMBINE_LOCAL_CONSTANT;
1046
1047 FX_grAlphaCombine_NoLock(GR_COMBINE_FUNCTION_LOCAL,
1048 GR_COMBINE_FACTOR_NONE,
1049 locala,
1050 GR_COMBINE_OTHER_NONE,
1051 FXFALSE);
1052
1053 FX_grColorCombine_NoLock(GR_COMBINE_FUNCTION_LOCAL,
1054 GR_COMBINE_FACTOR_NONE,
1055 localc,
1056 GR_COMBINE_OTHER_NONE,
1057 FXFALSE);
1058
1059 fxMesa->lastUnitsMode=FX_UM_NONE;
1060 }
1061
1062 /************************************************************************/
1063 /************************** Texture Mode SetUp **************************/
1064 /************************************************************************/
1065
1066 static void fxSetupTexture_NoLock(GLcontext *ctx)
1067 {
1068 fxMesaContext fxMesa=(fxMesaContext)ctx->DriverCtx;
1069 GLuint tex2Denabled;
1070
1071 if (MESA_VERBOSE&VERBOSE_DRIVER) {
1072 fprintf(stderr,"fxmesa: fxSetupTexture(...)\n");
1073 }
1074
1075 /* Disable multipass texturing.
1076 */
1077 ctx->Driver.MultipassFunc = 0;
1078
1079 /* Texture Combine, Color Combine and Alpha Combine.
1080 */
1081 tex2Denabled = (ctx->Texture.ReallyEnabled & TEXTURE0_2D);
1082
1083 if (fxMesa->emulateTwoTMUs)
1084 tex2Denabled |= (ctx->Texture.ReallyEnabled & TEXTURE1_2D);
1085
1086 switch(tex2Denabled) {
1087 case TEXTURE0_2D:
1088 fxSetupTextureSingleTMU_NoLock(ctx,0);
1089 break;
1090 case TEXTURE1_2D:
1091 fxSetupTextureSingleTMU_NoLock(ctx,1);
1092 break;
1093 case (TEXTURE0_2D|TEXTURE1_2D):
1094 if (fxMesa->haveTwoTMUs)
1095 fxSetupTextureDoubleTMU_NoLock(ctx);
1096 else {
1097 if (MESA_VERBOSE&VERBOSE_DRIVER)
1098 fprintf(stderr, "fxmesa: enabling fake multitexture\n");
1099
1100 fxSetupTextureSingleTMU_NoLock(ctx,0);
1101 ctx->Driver.MultipassFunc = fxMultipassTexture;
1102 }
1103 break;
1104 default:
1105 fxSetupTextureNone_NoLock(ctx);
1106 break;
1107 }
1108 }
1109
1110 static void fxSetupTexture(GLcontext *ctx) {
1111 BEGIN_BOARD_LOCK();
1112 fxSetupTexture_NoLock(ctx);
1113 END_BOARD_LOCK();
1114 }
1115
1116 /************************************************************************/
1117 /**************************** Blend SetUp *******************************/
1118 /************************************************************************/
1119
1120 /* XXX consider supporting GL_INGR_blend_func_separate */
1121 void fxDDBlendFunc(GLcontext *ctx, GLenum sfactor, GLenum dfactor)
1122 {
1123 fxMesaContext fxMesa=(fxMesaContext)ctx->DriverCtx;
1124 tfxUnitsState *us=&fxMesa->unitsState;
1125 GrAlphaBlendFnc_t sfact,dfact,asfact,adfact;
1126
1127 /* From the Glide documentation:
1128 For alpha source and destination blend function factor
1129 parameters, Voodoo Graphics supports only
1130 GR_BLEND_ZERO and GR_BLEND_ONE.
1131 */
1132
1133 switch(sfactor) {
1134 case GL_ZERO:
1135 asfact=sfact=GR_BLEND_ZERO;
1136 break;
1137 case GL_ONE:
1138 asfact=sfact=GR_BLEND_ONE;
1139 break;
1140 case GL_DST_COLOR:
1141 sfact=GR_BLEND_DST_COLOR;
1142 asfact=GR_BLEND_ONE;
1143 break;
1144 case GL_ONE_MINUS_DST_COLOR:
1145 sfact=GR_BLEND_ONE_MINUS_DST_COLOR;
1146 asfact=GR_BLEND_ONE;
1147 break;
1148 case GL_SRC_ALPHA:
1149 sfact=GR_BLEND_SRC_ALPHA;
1150 asfact=GR_BLEND_ONE;
1151 break;
1152 case GL_ONE_MINUS_SRC_ALPHA:
1153 sfact=GR_BLEND_ONE_MINUS_SRC_ALPHA;
1154 asfact=GR_BLEND_ONE;
1155 break;
1156 case GL_DST_ALPHA:
1157 sfact=GR_BLEND_DST_ALPHA;
1158 asfact=GR_BLEND_ONE;
1159 break;
1160 case GL_ONE_MINUS_DST_ALPHA:
1161 sfact=GR_BLEND_ONE_MINUS_DST_ALPHA;
1162 asfact=GR_BLEND_ONE;
1163 break;
1164 case GL_SRC_ALPHA_SATURATE:
1165 sfact=GR_BLEND_ALPHA_SATURATE;
1166 asfact=GR_BLEND_ONE;
1167 break;
1168 case GL_SRC_COLOR:
1169 case GL_ONE_MINUS_SRC_COLOR:
1170 /* USELESS */
1171 asfact=sfact=GR_BLEND_ONE;
1172 break;
1173 default:
1174 asfact=sfact=GR_BLEND_ONE;
1175 break;
1176 }
1177
1178 if((sfact!=us->blendSrcFuncRGB) ||
1179 (asfact!=us->blendSrcFuncAlpha)) {
1180 us->blendSrcFuncRGB=sfact;
1181 us->blendSrcFuncAlpha=asfact;
1182 fxMesa->new_state |= FX_NEW_BLEND;
1183 ctx->Driver.RenderStart = fxSetupFXUnits;
1184 }
1185
1186 switch(dfactor) {
1187 case GL_ZERO:
1188 adfact=dfact=GR_BLEND_ZERO;
1189 break;
1190 case GL_ONE:
1191 adfact=dfact=GR_BLEND_ONE;
1192 break;
1193 case GL_SRC_COLOR:
1194 dfact=GR_BLEND_SRC_COLOR;
1195 adfact=GR_BLEND_ZERO;
1196 break;
1197 case GL_ONE_MINUS_SRC_COLOR:
1198 dfact=GR_BLEND_ONE_MINUS_SRC_COLOR;
1199 adfact=GR_BLEND_ZERO;
1200 break;
1201 case GL_SRC_ALPHA:
1202 dfact=GR_BLEND_SRC_ALPHA;
1203 adfact=GR_BLEND_ZERO;
1204 break;
1205 case GL_ONE_MINUS_SRC_ALPHA:
1206 dfact=GR_BLEND_ONE_MINUS_SRC_ALPHA;
1207 adfact=GR_BLEND_ZERO;
1208 break;
1209 case GL_DST_ALPHA:
1210 /* dfact=GR_BLEND_DST_ALPHA; */
1211 /* We can't do DST_ALPHA */
1212 dfact=GR_BLEND_ONE;
1213 adfact=GR_BLEND_ZERO;
1214 break;
1215 case GL_ONE_MINUS_DST_ALPHA:
1216 /* dfact=GR_BLEND_ONE_MINUS_DST_ALPHA; */
1217 /* We can't do DST_ALPHA */
1218 dfact=GR_BLEND_ZERO;
1219 adfact=GR_BLEND_ZERO;
1220 break;
1221 case GL_SRC_ALPHA_SATURATE:
1222 case GL_DST_COLOR:
1223 case GL_ONE_MINUS_DST_COLOR:
1224 /* USELESS */
1225 adfact=dfact=GR_BLEND_ZERO;
1226 break;
1227 default:
1228 adfact=dfact=GR_BLEND_ZERO;
1229 break;
1230 }
1231
1232 if((dfact!=us->blendDstFuncRGB) ||
1233 (adfact!=us->blendDstFuncAlpha)) {
1234 us->blendDstFuncRGB=dfact;
1235 us->blendDstFuncAlpha=adfact;
1236 fxMesa->new_state |= FX_NEW_BLEND;
1237 ctx->Driver.RenderStart = fxSetupFXUnits;
1238 }
1239 }
1240
1241 static void fxSetupBlend(GLcontext *ctx)
1242 {
1243 fxMesaContext fxMesa=(fxMesaContext)ctx->DriverCtx;
1244 tfxUnitsState *us=&fxMesa->unitsState;
1245
1246 if(us->blendEnabled)
1247 FX_grAlphaBlendFunction(us->blendSrcFuncRGB,us->blendDstFuncRGB,
1248 us->blendSrcFuncAlpha,us->blendDstFuncAlpha);
1249 else
1250 FX_grAlphaBlendFunction(GR_BLEND_ONE,GR_BLEND_ZERO,GR_BLEND_ONE,GR_BLEND_ZERO);
1251 }
1252
1253 /************************************************************************/
1254 /************************** Alpha Test SetUp ****************************/
1255 /************************************************************************/
1256
1257 void fxDDAlphaFunc(GLcontext *ctx, GLenum func, GLclampf ref)
1258 {
1259 fxMesaContext fxMesa=(fxMesaContext)ctx->DriverCtx;
1260 tfxUnitsState *us=&fxMesa->unitsState;
1261 GrCmpFnc_t newfunc;
1262
1263 switch(func) {
1264 case GL_NEVER:
1265 newfunc=GR_CMP_NEVER;
1266 break;
1267 case GL_LESS:
1268 newfunc=GR_CMP_LESS;
1269 break;
1270 case GL_EQUAL:
1271 newfunc=GR_CMP_EQUAL;
1272 break;
1273 case GL_LEQUAL:
1274 newfunc=GR_CMP_LEQUAL;
1275 break;
1276 case GL_GREATER:
1277 newfunc=GR_CMP_GREATER;
1278 break;
1279 case GL_NOTEQUAL:
1280 newfunc=GR_CMP_NOTEQUAL;
1281 break;
1282 case GL_GEQUAL:
1283 newfunc=GR_CMP_GEQUAL;
1284 break;
1285 case GL_ALWAYS:
1286 newfunc=GR_CMP_ALWAYS;
1287 break;
1288 default:
1289 fprintf(stderr,"fx Driver: internal error in fxDDAlphaFunc()\n");
1290 fxCloseHardware();
1291 exit(-1);
1292 break;
1293 }
1294
1295 if(newfunc!=us->alphaTestFunc) {
1296 us->alphaTestFunc=newfunc;
1297 fxMesa->new_state |= FX_NEW_ALPHA;
1298 ctx->Driver.RenderStart = fxSetupFXUnits;
1299 }
1300
1301 if(ctx->Color.AlphaRef!=us->alphaTestRefValue) {
1302 us->alphaTestRefValue=ctx->Color.AlphaRef;
1303 fxMesa->new_state |= FX_NEW_ALPHA;
1304 ctx->Driver.RenderStart = fxSetupFXUnits;
1305 }
1306 }
1307
1308 static void fxSetupAlphaTest(GLcontext *ctx)
1309 {
1310 fxMesaContext fxMesa=(fxMesaContext)ctx->DriverCtx;
1311 tfxUnitsState *us=&fxMesa->unitsState;
1312
1313 if(us->alphaTestEnabled) {
1314 FX_grAlphaTestFunction(us->alphaTestFunc);
1315 FX_grAlphaTestReferenceValue(us->alphaTestRefValue);
1316 } else
1317 FX_grAlphaTestFunction(GR_CMP_ALWAYS);
1318 }
1319
1320 /************************************************************************/
1321 /************************** Depth Test SetUp ****************************/
1322 /************************************************************************/
1323
1324 void fxDDDepthFunc(GLcontext *ctx, GLenum func)
1325 {
1326 fxMesaContext fxMesa=(fxMesaContext)ctx->DriverCtx;
1327 tfxUnitsState *us=&fxMesa->unitsState;
1328 GrCmpFnc_t dfunc;
1329
1330 switch(func) {
1331 case GL_NEVER:
1332 dfunc=GR_CMP_NEVER;
1333 break;
1334 case GL_LESS:
1335 dfunc=GR_CMP_LESS;
1336 break;
1337 case GL_GEQUAL:
1338 dfunc=GR_CMP_GEQUAL;
1339 break;
1340 case GL_LEQUAL:
1341 dfunc=GR_CMP_LEQUAL;
1342 break;
1343 case GL_GREATER:
1344 dfunc=GR_CMP_GREATER;
1345 break;
1346 case GL_NOTEQUAL:
1347 dfunc=GR_CMP_NOTEQUAL;
1348 break;
1349 case GL_EQUAL:
1350 dfunc=GR_CMP_EQUAL;
1351 break;
1352 case GL_ALWAYS:
1353 dfunc=GR_CMP_ALWAYS;
1354 break;
1355 default:
1356 fprintf(stderr,"fx Driver: internal error in fxDDDepthFunc()\n");
1357 fxCloseHardware();
1358 exit(-1);
1359 break;
1360 }
1361
1362 if(dfunc!=us->depthTestFunc) {
1363 us->depthTestFunc=dfunc;
1364 fxMesa->new_state |= FX_NEW_DEPTH;
1365 ctx->Driver.RenderStart = fxSetupFXUnits;
1366 }
1367
1368 }
1369
1370 void fxDDDepthMask(GLcontext *ctx, GLboolean flag)
1371 {
1372 fxMesaContext fxMesa=(fxMesaContext)ctx->DriverCtx;
1373 tfxUnitsState *us=&fxMesa->unitsState;
1374
1375 if(flag!=us->depthMask) {
1376 us->depthMask=flag;
1377 fxMesa->new_state |= FX_NEW_DEPTH;
1378 ctx->Driver.RenderStart = fxSetupFXUnits;
1379 }
1380 }
1381
1382 static void fxSetupDepthTest(GLcontext *ctx)
1383 {
1384 fxMesaContext fxMesa=(fxMesaContext)ctx->DriverCtx;
1385 tfxUnitsState *us=&fxMesa->unitsState;
1386
1387 if (us->depthTestEnabled) {
1388 FX_grDepthBufferFunction(us->depthTestFunc);
1389 FX_grDepthMask(us->depthMask);
1390 }
1391 else {
1392 FX_grDepthBufferFunction(GR_CMP_ALWAYS);
1393 FX_grDepthMask(FXFALSE);
1394 }
1395 }
1396
1397 /************************************************************************/
1398 /**************************** Color Mask SetUp **************************/
1399 /************************************************************************/
1400
1401 void fxDDColorMask(GLcontext *ctx,
1402 GLboolean r, GLboolean g,
1403 GLboolean b, GLboolean a )
1404 {
1405 fxMesaContext fxMesa=(fxMesaContext)ctx->DriverCtx;
1406 fxMesa->new_state |= FX_NEW_COLOR_MASK;
1407 ctx->Driver.RenderStart = fxSetupFXUnits;
1408 (void) r; (void) g; (void) b; (void) a;
1409 return GL_FALSE;
1410 }
1411
1412 static void fxSetupColorMask(GLcontext *ctx)
1413 {
1414 fxMesaContext fxMesa = FX_CONTEXT(ctx);
1415
1416 if (ctx->Color.DrawBuffer == GL_NONE) {
1417 FX_grColorMask(FXFALSE, FXFALSE);
1418 }
1419 else {
1420 FX_grColorMask(ctx->Color.ColorMask[RCOMP] ||
1421 ctx->Color.ColorMask[GCOMP] ||
1422 ctx->Color.ColorMask[BCOMP],
1423 ctx->Color.ColorMask[ACOMP] && fxMesa->haveAlphaBuffer);
1424 }
1425 }
1426
1427
1428
1429
1430 /************************************************************************/
1431 /**************************** Fog Mode SetUp ****************************/
1432 /************************************************************************/
1433
1434 /*
1435 * This is called during state update in order to update the Glide fog state.
1436 */
1437 static void fxSetupFog(GLcontext *ctx)
1438 {
1439 if (ctx->Fog.Enabled && ctx->FogMode==FOG_FRAGMENT) {
1440 fxMesaContext fxMesa = FX_CONTEXT(ctx);
1441
1442 /* update fog color */
1443 GLubyte col[4];
1444 col[0]=(unsigned int)(255*ctx->Fog.Color[0]);
1445 col[1]=(unsigned int)(255*ctx->Fog.Color[1]);
1446 col[2]=(unsigned int)(255*ctx->Fog.Color[2]);
1447 col[3]=(unsigned int)(255*ctx->Fog.Color[3]);
1448 FX_grFogColorValue(FXCOLOR4(col));
1449
1450 if(fxMesa->fogTableMode != ctx->Fog.Mode ||
1451 fxMesa->fogDensity != ctx->Fog.Density ||
1452 fxMesa->fogStart != ctx->Fog.Start ||
1453 fxMesa->fogEnd != ctx->Fog.End) {
1454 /* reload the fog table */
1455 switch (ctx->Fog.Mode) {
1456 case GL_LINEAR:
1457 guFogGenerateLinear(fxMesa->fogTable, ctx->Fog.Start, ctx->Fog.End);
1458 break;
1459 case GL_EXP:
1460 guFogGenerateExp(fxMesa->fogTable, ctx->Fog.Density);
1461 break;
1462 case GL_EXP2:
1463 guFogGenerateExp2(fxMesa->fogTable, ctx->Fog.Density);
1464 break;
1465 default:
1466 ;
1467 }
1468 fxMesa->fogTableMode = ctx->Fog.Mode;
1469 fxMesa->fogDensity = ctx->Fog.Density;
1470 fxMesa->fogStart = ctx->Fog.Start;
1471 fxMesa->fogEnd = ctx->Fog.End;
1472 }
1473
1474 FX_grFogTable(fxMesa->fogTable);
1475 FX_grFogMode(GR_FOG_WITH_TABLE);
1476 }
1477 else {
1478 FX_grFogMode(GR_FOG_DISABLE);
1479 }
1480 }
1481
1482 void fxDDFogfv( GLcontext *ctx, GLenum pname, const GLfloat *params )
1483 {
1484 FX_CONTEXT(ctx)->new_state |= FX_NEW_FOG;
1485 ctx->Driver.RenderStart = fxSetupFXUnits; /* XXX why is this here? */
1486 }
1487
1488 /************************************************************************/
1489 /************************** Scissor Test SetUp **************************/
1490 /************************************************************************/
1491
1492 /* This routine is used in managing the lock state, and therefore can't lock */
1493 void fxSetScissorValues(GLcontext *ctx)
1494 {
1495 fxMesaContext fxMesa=(fxMesaContext)ctx->DriverCtx;
1496 int xmin, xmax;
1497 int ymin, ymax, check;
1498
1499 if (ctx->Scissor.Enabled) {
1500 xmin=ctx->Scissor.X;
1501 xmax=ctx->Scissor.X+ctx->Scissor.Width;
1502 ymin=ctx->Scissor.Y;
1503 ymax=ctx->Scissor.Y+ctx->Scissor.Height;
1504 check=1;
1505 } else {
1506 xmin=0;
1507 ymin=0;
1508 xmax=fxMesa->width;
1509 ymax=fxMesa->height;
1510 check=0;
1511 }
1512 xmin+=fxMesa->x_offset;
1513 xmax+=fxMesa->x_offset;
1514 ymin+=fxMesa->y_delta;
1515 ymax+=fxMesa->y_delta;
1516 if (xmin<fxMesa->clipMinX) xmin=fxMesa->clipMinX;
1517 if (xmax>fxMesa->clipMaxX) xmax=fxMesa->clipMaxX;
1518 if (ymin<fxMesa->screen_height-fxMesa->clipMaxY)
1519 ymin=fxMesa->screen_height-fxMesa->clipMaxY;
1520 if (ymax>fxMesa->screen_height-fxMesa->clipMinY)
1521 ymax=fxMesa->screen_height-fxMesa->clipMinY;
1522 FX_grClipWindow_NoLock(xmin, ymin, xmax, ymax);
1523 }
1524
1525 static void fxSetupScissor(GLcontext *ctx)
1526 {
1527 fxMesaContext fxMesa=(fxMesaContext)ctx->DriverCtx;
1528 if (!fxMesa->needClip) {
1529 BEGIN_BOARD_LOCK();
1530 fxSetScissorValues(ctx);
1531 END_BOARD_LOCK();
1532 }
1533 }
1534
1535 void fxDDScissor( GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h )
1536 {
1537 FX_CONTEXT(ctx)->new_state |= FX_NEW_SCISSOR;
1538 ctx->Driver.RenderStart = fxSetupFXUnits;
1539 }
1540
1541 /************************************************************************/
1542 /*************************** Cull mode setup ****************************/
1543 /************************************************************************/
1544
1545
1546 void fxDDCullFace(GLcontext *ctx, GLenum mode)
1547 {
1548 (void) mode;
1549 FX_CONTEXT(ctx)->new_state |= FX_NEW_CULL;
1550 ctx->Driver.RenderStart = fxSetupFXUnits;
1551 }
1552
1553 void fxDDFrontFace(GLcontext *ctx, GLenum mode)
1554 {
1555 (void) mode;
1556 FX_CONTEXT(ctx)->new_state |= FX_NEW_CULL;
1557 ctx->Driver.RenderStart = fxSetupFXUnits;
1558 }
1559
1560
1561 static void fxSetupCull(GLcontext *ctx)
1562 {
1563 if (ctx->Polygon.CullFlag) {
1564 switch (ctx->Polygon.CullFaceMode) {
1565 case GL_BACK:
1566 if (ctx->Polygon.FrontFace==GL_CCW)
1567 FX_CONTEXT(ctx)->cullMode=GR_CULL_NEGATIVE;
1568 else
1569 FX_CONTEXT(ctx)->cullMode=GR_CULL_POSITIVE;
1570 break;
1571 case GL_FRONT:
1572 if(ctx->Polygon.FrontFace==GL_CCW)
1573 FX_CONTEXT(ctx)->cullMode=GR_CULL_POSITIVE;
1574 else
1575 FX_CONTEXT(ctx)->cullMode=GR_CULL_NEGATIVE;
1576 break;
1577 case GL_FRONT_AND_BACK:
1578 FX_CONTEXT(ctx)->cullMode=GR_CULL_DISABLE;
1579 break;
1580 default:
1581 break;
1582 }
1583 } else FX_CONTEXT(ctx)->cullMode=GR_CULL_DISABLE;
1584 FX_grCullMode(FX_CONTEXT(ctx)->cullMode);
1585 }
1586
1587
1588 /************************************************************************/
1589 /****************************** DD Enable ******************************/
1590 /************************************************************************/
1591
1592 void fxDDEnable(GLcontext *ctx, GLenum cap, GLboolean state)
1593 {
1594 fxMesaContext fxMesa=(fxMesaContext)ctx->DriverCtx;
1595 tfxUnitsState *us=&fxMesa->unitsState;
1596
1597 if (MESA_VERBOSE&VERBOSE_DRIVER) {
1598 fprintf(stderr,"fxmesa: fxDDEnable(...)\n");
1599 }
1600
1601 switch(cap) {
1602 case GL_ALPHA_TEST:
1603 if(state!=us->alphaTestEnabled) {
1604 us->alphaTestEnabled=state;
1605 fxMesa->new_state |= FX_NEW_ALPHA;
1606 ctx->Driver.RenderStart = fxSetupFXUnits;
1607 }
1608 break;
1609 case GL_BLEND:
1610 if(state!=us->blendEnabled) {
1611 us->blendEnabled=state;
1612 fxMesa->new_state |= FX_NEW_BLEND;
1613 ctx->Driver.RenderStart = fxSetupFXUnits;
1614 }
1615 break;
1616 case GL_DEPTH_TEST:
1617 if(state!=us->depthTestEnabled) {
1618 us->depthTestEnabled=state;
1619 fxMesa->new_state |= FX_NEW_DEPTH;
1620 ctx->Driver.RenderStart = fxSetupFXUnits;
1621 }
1622 break;
1623 case GL_SCISSOR_TEST:
1624 fxMesa->new_state |= FX_NEW_SCISSOR;
1625 ctx->Driver.RenderStart = fxSetupFXUnits;
1626 break;
1627 case GL_SHARED_TEXTURE_PALETTE_EXT:
1628 fxDDTexUseGlbPalette(ctx, state);
1629 break;
1630 case GL_FOG:
1631 fxMesa->new_state |= FX_NEW_FOG;
1632 ctx->Driver.RenderStart = fxSetupFXUnits;
1633 break;
1634 case GL_CULL_FACE:
1635 fxMesa->new_state |= FX_NEW_CULL;
1636 ctx->Driver.RenderStart = fxSetupFXUnits;
1637 break;
1638 case GL_LINE_SMOOTH:
1639 case GL_LINE_STIPPLE:
1640 case GL_POINT_SMOOTH:
1641 case GL_POLYGON_SMOOTH:
1642 case GL_TEXTURE_2D:
1643 fxMesa->new_state |= FX_NEW_TEXTURING;
1644 ctx->Driver.RenderStart = fxSetupFXUnits;
1645 break;
1646 default:
1647 ; /* XXX no-op? */
1648 }
1649 }
1650
1651 #if 0
1652 /*
1653 Multipass to do GL_BLEND texture functions
1654 Cf*(1-Ct) has already been written to the buffer during the first pass
1655 Cc*Ct gets written during the second pass (in this function)
1656 Everything gets reset in the third call (in this function)
1657 */
1658 static GLboolean fxMultipassBlend(struct vertex_buffer *VB, GLuint pass)
1659 {
1660 GLcontext *ctx = VB->ctx;
1661 fxMesaContext fxMesa = FX_CONTEXT(ctx);
1662
1663 switch (pass) {
1664 case 1:
1665 /* Add Cc*Ct */
1666 fxMesa->restoreUnitsState=fxMesa->unitsState;
1667 if (ctx->Depth.Mask) {
1668 /* We don't want to check or change the depth buffers */
1669 switch (ctx->Depth.Func) {
1670 case GL_NEVER:
1671 case GL_ALWAYS:
1672 break;
1673 default:
1674 fxDDDepthFunc(ctx, GL_EQUAL);
1675 break;
1676 }
1677 fxDDDepthMask(ctx, FALSE);
1678 }
1679 /* Enable Cc*Ct mode */
1680 /* XXX Set the Constant Color ? */
1681 fxDDEnable(ctx, GL_BLEND, GL_TRUE);
1682 fxDDBlendFunc(ctx, XXX, XXX);
1683 fxSetupTextureSingleTMU(ctx, XXX);
1684 fxSetupBlend(ctx);
1685 fxSetupDepthTest(ctx);
1686 break;
1687
1688 case 2:
1689 /* Reset everything back to normal */
1690 fxMesa->unitsState = fxMesa->restoreUnitsState;
1691 fxMesa->setupdone &= XXX;
1692 fxSetupTextureSingleTMU(ctx, XXX);
1693 fxSetupBlend(ctx);
1694 fxSetupDepthTest(ctx);
1695 break;
1696 }
1697
1698 return pass==1;
1699 }
1700 #endif
1701
1702 /************************************************************************/
1703 /******************** Fake Multitexture Support *************************/
1704 /************************************************************************/
1705
1706 /* Its considered cheeky to try to fake ARB multitexture by doing
1707 * multipass rendering, because it is not possible to emulate the full
1708 * spec in this way. The fact is that the voodoo 2 supports only a
1709 * subset of the possible multitexturing modes, and it is possible to
1710 * support almost the same subset using multipass blending on the
1711 * voodoo 1. In all other cases for both voodoo 1 and 2, we fall back
1712 * to software rendering, satisfying the spec if not the user.
1713 */
1714 static GLboolean fxMultipassTexture( struct vertex_buffer *VB, GLuint pass )
1715 {
1716 GLcontext *ctx = VB->ctx;
1717 fxVertex *v = FX_DRIVER_DATA(VB)->verts;
1718 fxVertex *last = FX_DRIVER_DATA(VB)->last_vert;
1719 fxMesaContext fxMesa = FX_CONTEXT(ctx);
1720
1721 switch (pass) {
1722 case 1:
1723 if (MESA_VERBOSE&(VERBOSE_DRIVER|VERBOSE_PIPELINE|VERBOSE_TEXTURE))
1724 fprintf(stderr, "fxmesa: Second texture pass\n");
1725
1726 for ( ; v != last ; v++) {
1727 v->f[S0COORD] = v->f[S1COORD];
1728 v->f[T0COORD] = v->f[T1COORD];
1729 }
1730
1731 fxMesa->restoreUnitsState = fxMesa->unitsState;
1732 fxMesa->tmu_source[0] = 1;
1733
1734 if (ctx->Depth.Mask) {
1735 switch (ctx->Depth.Func) {
1736 case GL_NEVER:
1737 case GL_ALWAYS:
1738 break;
1739 default:
1740 fxDDDepthFunc( ctx, GL_EQUAL );
1741 break;
1742 }
1743
1744 fxDDDepthMask( ctx, GL_FALSE );
1745 }
1746
1747 if (ctx->Texture.Unit[1].EnvMode == GL_MODULATE) {
1748 fxDDEnable( ctx, GL_BLEND, GL_TRUE );
1749 fxDDBlendFunc( ctx, GL_DST_COLOR, GL_ZERO );
1750 }
1751
1752 fxSetupTextureSingleTMU( ctx, 1 );
1753 fxSetupBlend( ctx );
1754 fxSetupDepthTest( ctx );
1755 break;
1756
1757 case 2:
1758 /* Restore original state.
1759 */
1760 fxMesa->tmu_source[0] = 0;
1761 fxMesa->unitsState = fxMesa->restoreUnitsState;
1762 fxMesa->setupdone &= ~SETUP_TMU0;
1763 fxSetupTextureSingleTMU( ctx, 0 );
1764 fxSetupBlend( ctx );
1765 fxSetupDepthTest( ctx );
1766 break;
1767 }
1768
1769 return pass == 1;
1770 }
1771
1772
1773 /************************************************************************/
1774 /************************** Changes to units state **********************/
1775 /************************************************************************/
1776
1777
1778 /* All units setup is handled under texture setup.
1779 */
1780 void fxDDShadeModel(GLcontext *ctx, GLenum mode)
1781 {
1782 FX_CONTEXT(ctx)->new_state |= FX_NEW_TEXTURING;
1783 ctx->Driver.RenderStart = fxSetupFXUnits;
1784 }
1785
1786
1787
1788 /************************************************************************/
1789 /****************************** Units SetUp *****************************/
1790 /************************************************************************/
1791 static void gl_print_fx_state_flags( const char *msg, GLuint flags )
1792 {
1793 fprintf(stderr,
1794 "%s: (0x%x) %s%s%s%s%s%s%s\n",
1795 msg,
1796 flags,
1797 (flags & FX_NEW_TEXTURING) ? "texture, " : "",
1798 (flags & FX_NEW_BLEND) ? "blend, " : "",
1799 (flags & FX_NEW_ALPHA) ? "alpha, " : "",
1800 (flags & FX_NEW_FOG) ? "fog, " : "",
1801 (flags & FX_NEW_SCISSOR) ? "scissor, " : "",
1802 (flags & FX_NEW_COLOR_MASK) ? "colormask, " : "",
1803 (flags & FX_NEW_CULL) ? "cull, " : "");
1804 }
1805
1806 void fxSetupFXUnits( GLcontext *ctx )
1807 {
1808 fxMesaContext fxMesa=(fxMesaContext)ctx->DriverCtx;
1809 GLuint newstate = fxMesa->new_state;
1810
1811 if (MESA_VERBOSE&VERBOSE_DRIVER)
1812 gl_print_fx_state_flags("fxmesa: fxSetupFXUnits", newstate);
1813
1814 if (newstate) {
1815 if (newstate & FX_NEW_TEXTURING)
1816 fxSetupTexture(ctx);
1817
1818 if (newstate & FX_NEW_BLEND)
1819 fxSetupBlend(ctx);
1820
1821 if (newstate & FX_NEW_ALPHA)
1822 fxSetupAlphaTest(ctx);
1823
1824 if (newstate & FX_NEW_DEPTH)
1825 fxSetupDepthTest(ctx);
1826
1827 if (newstate & FX_NEW_FOG)
1828 fxSetupFog(ctx);
1829
1830 if (newstate & FX_NEW_SCISSOR)
1831 fxSetupScissor(ctx);
1832
1833 if (newstate & FX_NEW_COLOR_MASK)
1834 fxSetupColorMask(ctx);
1835
1836 if (newstate & FX_NEW_CULL)
1837 fxSetupCull(ctx);
1838
1839 fxMesa->new_state = 0;
1840 /* ctx->Driver.RenderStart = 0; */
1841 }
1842 }
1843
1844
1845
1846 #else
1847
1848
1849 /*
1850 * Need this to provide at least one external definition.
1851 */
1852
1853 int gl_fx_dummy_function_setup(void)
1854 {
1855 return 0;
1856 }
1857
1858 #endif /* FX */