Replace ctx->Driver.StencilOp/Func/Mask() functions with
[mesa.git] / src / mesa / drivers / glide / fxsetup.c
1 /*
2 * Mesa 3-D graphics library
3 * Version: 4.0
4 *
5 * Copyright (C) 1999-2001 Brian Paul All Rights Reserved.
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 * and/or sell copies of the Software, and to permit persons to whom the
12 * Software is furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice shall be included
15 * in all copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
21 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 */
24
25 /* Authors:
26 * David Bucciarelli
27 * Brian Paul
28 * Daryll Strauss
29 * Keith Whitwell
30 * Daniel Borca
31 * Hiroshi Morii
32 */
33
34 /* fxsetup.c - 3Dfx VooDoo rendering mode setup functions */
35
36
37 #ifdef HAVE_CONFIG_H
38 #include "conf.h"
39 #endif
40
41 #if defined(FX)
42
43 #include "fxdrv.h"
44 #include "enums.h"
45 #include "tnl.h"
46 #include "tnl/t_context.h"
47 #include "swrast.h"
48 #include "texstore.h"
49
50
51 static void
52 fxTexValidate(GLcontext * ctx, struct gl_texture_object *tObj)
53 {
54 tfxTexInfo *ti = fxTMGetTexInfo(tObj);
55 GLint minl, maxl;
56
57 if (ti->validated) {
58 if (TDFX_DEBUG & VERBOSE_DRIVER) {
59 fprintf(stderr, "fxTexValidate(NOP)\n");
60 }
61 return;
62 }
63
64 if (TDFX_DEBUG & VERBOSE_DRIVER) {
65 fprintf(stderr, "fxTexValidate(%p (%d))\n", (void *)tObj, tObj->Name);
66 }
67
68 ti->tObj = tObj;
69 minl = ti->minLevel = tObj->BaseLevel;
70 maxl = ti->maxLevel = MIN2(tObj->MaxLevel, tObj->Image[0][0]->MaxLog2);
71
72 #if FX_RESCALE_BIG_TEXURES_HACK
73 {
74 fxMesaContext fxMesa = FX_CONTEXT(ctx);
75 /* [dBorca]
76 * Fake textures larger than HW supports:
77 * 1) we have mipmaps. Then we just push up to the first supported
78 * LOD. A possible drawback is that Mesa will ignore the skipped
79 * LODs on further texture handling.
80 * Will this interfere with GL_TEXTURE_[MIN|BASE]_LEVEL? How?
81 * 2) we don't have mipmaps. We need to rescale the big LOD in place.
82 * The above approach is somehow dumb! we might have rescaled
83 * once in TexImage2D to accomodate aspect ratio, and now we
84 * are rescaling again. The thing is, in TexImage2D we don't
85 * know whether we'll hit 1) or 2) by the time of validation.
86 */
87 if ((tObj->MinFilter == GL_NEAREST) || (tObj->MinFilter == GL_LINEAR)) {
88 /* no mipmaps! */
89 struct gl_texture_image *texImage = tObj->Image[0][minl];
90 tfxMipMapLevel *mml = FX_MIPMAP_DATA(texImage);
91 GLint _w, _h, maxSize = 1 << fxMesa->textureMaxLod;
92 if ((mml->width > maxSize) || (mml->height > maxSize)) {
93 /* need to rescale */
94 GLint texelBytes = texImage->TexFormat->TexelBytes;
95 GLvoid *texImage_Data = texImage->Data;
96 _w = MIN2(texImage->Width, maxSize);
97 _h = MIN2(texImage->Height, maxSize);
98 if (TDFX_DEBUG & VERBOSE_TEXTURE) {
99 fprintf(stderr, "fxTexValidate: rescaling %d x %d -> %d x %d\n",
100 texImage->Width, texImage->Height, _w, _h);
101 }
102 /* we should leave these as is and... (!) */
103 texImage->Width = _w;
104 texImage->Height = _h;
105 fxTexGetInfo(_w, _h, NULL, NULL, NULL, NULL,
106 &(mml->wScale), &(mml->hScale));
107 _w *= mml->wScale;
108 _h *= mml->hScale;
109 texImage->Data = _mesa_malloc(_w * _h * texelBytes);
110 _mesa_rescale_teximage2d(texelBytes,
111 mml->width,
112 _w * texelBytes, /* dst stride */
113 mml->width, mml->height, /* src */
114 _w, _h, /* dst */
115 texImage_Data /*src*/, texImage->Data /*dst*/ );
116 _mesa_free(texImage_Data);
117 mml->width = _w;
118 mml->height = _h;
119 /* (!) ... and set mml->wScale = _w / texImage->Width */
120 }
121 } else {
122 /* mipmapping */
123 if (maxl - minl > fxMesa->textureMaxLod) {
124 /* skip a certain number of LODs */
125 minl += maxl - fxMesa->textureMaxLod;
126 if (TDFX_DEBUG & VERBOSE_TEXTURE) {
127 fprintf(stderr, "fxTexValidate: skipping %d LODs\n", minl - ti->minLevel);
128 }
129 ti->minLevel = tObj->BaseLevel = minl;
130 }
131 }
132 }
133 #endif
134
135 fxTexGetInfo(tObj->Image[0][minl]->Width, tObj->Image[0][minl]->Height,
136 &(FX_largeLodLog2(ti->info)), &(FX_aspectRatioLog2(ti->info)),
137 &(ti->sScale), &(ti->tScale),
138 NULL, NULL);
139
140 if ((tObj->MinFilter != GL_NEAREST) && (tObj->MinFilter != GL_LINEAR))
141 fxTexGetInfo(tObj->Image[0][maxl]->Width, tObj->Image[0][maxl]->Height,
142 &(FX_smallLodLog2(ti->info)), NULL,
143 NULL, NULL, NULL, NULL);
144 else
145 FX_smallLodLog2(ti->info) = FX_largeLodLog2(ti->info);
146
147 /* [dBorca] this is necessary because of fxDDCompressedTexImage2D */
148 if (ti->padded) {
149 struct gl_texture_image *texImage = tObj->Image[0][minl];
150 tfxMipMapLevel *mml = FX_MIPMAP_DATA(texImage);
151 if (mml->wScale != 1 || mml->hScale != 1) {
152 ti->sScale /= mml->wScale;
153 ti->tScale /= mml->hScale;
154 }
155 }
156
157 ti->baseLevelInternalFormat = tObj->Image[0][minl]->Format;
158
159 ti->validated = GL_TRUE;
160
161 ti->info.data = NULL;
162 }
163
164 static void
165 fxPrintUnitsMode(const char *msg, GLuint mode)
166 {
167 fprintf(stderr,
168 "%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",
169 msg,
170 mode,
171 (mode & FX_UM_E0_REPLACE) ? "E0_REPLACE, " : "",
172 (mode & FX_UM_E0_MODULATE) ? "E0_MODULATE, " : "",
173 (mode & FX_UM_E0_DECAL) ? "E0_DECAL, " : "",
174 (mode & FX_UM_E0_BLEND) ? "E0_BLEND, " : "",
175 (mode & FX_UM_E1_REPLACE) ? "E1_REPLACE, " : "",
176 (mode & FX_UM_E1_MODULATE) ? "E1_MODULATE, " : "",
177 (mode & FX_UM_E1_DECAL) ? "E1_DECAL, " : "",
178 (mode & FX_UM_E1_BLEND) ? "E1_BLEND, " : "",
179 (mode & FX_UM_E0_ALPHA) ? "E0_ALPHA, " : "",
180 (mode & FX_UM_E0_LUMINANCE) ? "E0_LUMINANCE, " : "",
181 (mode & FX_UM_E0_LUMINANCE_ALPHA) ? "E0_LUMINANCE_ALPHA, " : "",
182 (mode & FX_UM_E0_INTENSITY) ? "E0_INTENSITY, " : "",
183 (mode & FX_UM_E0_RGB) ? "E0_RGB, " : "",
184 (mode & FX_UM_E0_RGBA) ? "E0_RGBA, " : "",
185 (mode & FX_UM_E1_ALPHA) ? "E1_ALPHA, " : "",
186 (mode & FX_UM_E1_LUMINANCE) ? "E1_LUMINANCE, " : "",
187 (mode & FX_UM_E1_LUMINANCE_ALPHA) ? "E1_LUMINANCE_ALPHA, " : "",
188 (mode & FX_UM_E1_INTENSITY) ? "E1_INTENSITY, " : "",
189 (mode & FX_UM_E1_RGB) ? "E1_RGB, " : "",
190 (mode & FX_UM_E1_RGBA) ? "E1_RGBA, " : "",
191 (mode & FX_UM_COLOR_ITERATED) ? "COLOR_ITERATED, " : "",
192 (mode & FX_UM_COLOR_CONSTANT) ? "COLOR_CONSTANT, " : "",
193 (mode & FX_UM_ALPHA_ITERATED) ? "ALPHA_ITERATED, " : "",
194 (mode & FX_UM_ALPHA_CONSTANT) ? "ALPHA_CONSTANT, " : "");
195 }
196
197 static GLuint
198 fxGetTexSetConfiguration(GLcontext * ctx,
199 struct gl_texture_object *tObj0,
200 struct gl_texture_object *tObj1)
201 {
202 GLuint unitsmode = 0;
203 GLuint envmode = 0;
204 GLuint ifmt = 0;
205
206 if ((ctx->Light.ShadeModel == GL_SMOOTH) || 1 ||
207 (ctx->Point.SmoothFlag) ||
208 (ctx->Line.SmoothFlag) ||
209 (ctx->Polygon.SmoothFlag)) unitsmode |= FX_UM_ALPHA_ITERATED;
210 else
211 unitsmode |= FX_UM_ALPHA_CONSTANT;
212
213 if (ctx->Light.ShadeModel == GL_SMOOTH || 1)
214 unitsmode |= FX_UM_COLOR_ITERATED;
215 else
216 unitsmode |= FX_UM_COLOR_CONSTANT;
217
218
219
220 /*
221 OpenGL Feeds Texture 0 into Texture 1
222 Glide Feeds Texture 1 into Texture 0
223 */
224 if (tObj0) {
225 tfxTexInfo *ti0 = fxTMGetTexInfo(tObj0);
226
227 switch (ti0->baseLevelInternalFormat) {
228 case GL_ALPHA:
229 ifmt |= FX_UM_E0_ALPHA;
230 break;
231 case GL_LUMINANCE:
232 ifmt |= FX_UM_E0_LUMINANCE;
233 break;
234 case GL_LUMINANCE_ALPHA:
235 ifmt |= FX_UM_E0_LUMINANCE_ALPHA;
236 break;
237 case GL_INTENSITY:
238 ifmt |= FX_UM_E0_INTENSITY;
239 break;
240 case GL_RGB:
241 ifmt |= FX_UM_E0_RGB;
242 break;
243 case GL_RGBA:
244 ifmt |= FX_UM_E0_RGBA;
245 break;
246 }
247
248 switch (ctx->Texture.Unit[0].EnvMode) {
249 case GL_DECAL:
250 envmode |= FX_UM_E0_DECAL;
251 break;
252 case GL_MODULATE:
253 envmode |= FX_UM_E0_MODULATE;
254 break;
255 case GL_REPLACE:
256 envmode |= FX_UM_E0_REPLACE;
257 break;
258 case GL_BLEND:
259 envmode |= FX_UM_E0_BLEND;
260 break;
261 case GL_ADD:
262 envmode |= FX_UM_E0_ADD;
263 break;
264 default:
265 /* do nothing */
266 break;
267 }
268 }
269
270 if (tObj1) {
271 tfxTexInfo *ti1 = fxTMGetTexInfo(tObj1);
272
273 switch (ti1->baseLevelInternalFormat) {
274 case GL_ALPHA:
275 ifmt |= FX_UM_E1_ALPHA;
276 break;
277 case GL_LUMINANCE:
278 ifmt |= FX_UM_E1_LUMINANCE;
279 break;
280 case GL_LUMINANCE_ALPHA:
281 ifmt |= FX_UM_E1_LUMINANCE_ALPHA;
282 break;
283 case GL_INTENSITY:
284 ifmt |= FX_UM_E1_INTENSITY;
285 break;
286 case GL_RGB:
287 ifmt |= FX_UM_E1_RGB;
288 break;
289 case GL_RGBA:
290 ifmt |= FX_UM_E1_RGBA;
291 break;
292 default:
293 /* do nothing */
294 break;
295 }
296
297 switch (ctx->Texture.Unit[1].EnvMode) {
298 case GL_DECAL:
299 envmode |= FX_UM_E1_DECAL;
300 break;
301 case GL_MODULATE:
302 envmode |= FX_UM_E1_MODULATE;
303 break;
304 case GL_REPLACE:
305 envmode |= FX_UM_E1_REPLACE;
306 break;
307 case GL_BLEND:
308 envmode |= FX_UM_E1_BLEND;
309 break;
310 case GL_ADD:
311 envmode |= FX_UM_E1_ADD;
312 break;
313 default:
314 /* do nothing */
315 break;
316 }
317 }
318
319 unitsmode |= (ifmt | envmode);
320
321 if (TDFX_DEBUG & (VERBOSE_DRIVER | VERBOSE_TEXTURE))
322 fxPrintUnitsMode("fxGetTexSetConfiguration", unitsmode);
323
324 return unitsmode;
325 }
326
327 /************************************************************************/
328 /************************* Rendering Mode SetUp *************************/
329 /************************************************************************/
330
331 /************************* Single Texture Set ***************************/
332
333 static void
334 fxSetupSingleTMU_NoLock(fxMesaContext fxMesa, struct gl_texture_object *tObj)
335 {
336 tfxTexInfo *ti = fxTMGetTexInfo(tObj);
337 int tmu;
338
339 if (TDFX_DEBUG & VERBOSE_DRIVER) {
340 fprintf(stderr, "fxSetupSingleTMU_NoLock(%p (%d))\n", (void *)tObj, tObj->Name);
341 }
342
343 ti->lastTimeUsed = fxMesa->texBindNumber;
344
345 /* Make sure we're not loaded incorrectly */
346 if (ti->isInTM) {
347 if (ti->LODblend) {
348 if (ti->whichTMU != FX_TMU_SPLIT)
349 fxTMMoveOutTM(fxMesa, tObj);
350 }
351 else {
352 if (ti->whichTMU == FX_TMU_SPLIT)
353 fxTMMoveOutTM(fxMesa, tObj);
354 }
355 }
356
357 /* Make sure we're loaded correctly */
358 if (!ti->isInTM) {
359 if (ti->LODblend)
360 fxTMMoveInTM_NoLock(fxMesa, tObj, FX_TMU_SPLIT);
361 else {
362 if (fxMesa->haveTwoTMUs) {
363 if (fxTMCheckStartAddr(fxMesa, FX_TMU0, ti)) {
364 fxTMMoveInTM_NoLock(fxMesa, tObj, FX_TMU0);
365 }
366 else {
367 fxTMMoveInTM_NoLock(fxMesa, tObj, FX_TMU1);
368 }
369 }
370 else
371 fxTMMoveInTM_NoLock(fxMesa, tObj, FX_TMU0);
372 }
373 }
374
375 if (ti->LODblend && ti->whichTMU == FX_TMU_SPLIT) {
376 /* broadcast */
377 if ((ti->info.format == GR_TEXFMT_P_8)
378 && (!fxMesa->haveGlobalPaletteTexture)) {
379 if (TDFX_DEBUG & VERBOSE_DRIVER) {
380 fprintf(stderr, "fxSetupSingleTMU_NoLock: uploading texture palette\n");
381 }
382 grTexDownloadTable(ti->paltype, &(ti->palette));
383 }
384
385 grTexClampMode(GR_TMU0, ti->sClamp, ti->tClamp);
386 grTexClampMode(GR_TMU1, ti->sClamp, ti->tClamp);
387 grTexFilterMode(GR_TMU0, ti->minFilt, ti->maxFilt);
388 grTexFilterMode(GR_TMU1, ti->minFilt, ti->maxFilt);
389 grTexMipMapMode(GR_TMU0, ti->mmMode, ti->LODblend);
390 grTexMipMapMode(GR_TMU1, ti->mmMode, ti->LODblend);
391
392 grTexSource(GR_TMU0, ti->tm[FX_TMU0]->startAddr,
393 GR_MIPMAPLEVELMASK_ODD, &(ti->info));
394 grTexSource(GR_TMU1, ti->tm[FX_TMU1]->startAddr,
395 GR_MIPMAPLEVELMASK_EVEN, &(ti->info));
396 }
397 else {
398 if (ti->whichTMU == FX_TMU_BOTH)
399 tmu = FX_TMU0;
400 else
401 tmu = ti->whichTMU;
402
403 /* pointcast */
404 if ((ti->info.format == GR_TEXFMT_P_8)
405 && (!fxMesa->haveGlobalPaletteTexture)) {
406 if (TDFX_DEBUG & VERBOSE_DRIVER) {
407 fprintf(stderr, "fxSetupSingleTMU_NoLock: uploading texture palette\n");
408 }
409 fxMesa->Glide.grTexDownloadTableExt(tmu, ti->paltype, &(ti->palette));
410 }
411
412 /* KW: The alternative is to do the download to the other tmu. If
413 * we get to this point, I think it means we are thrashing the
414 * texture memory, so perhaps it's not a good idea.
415 */
416 if (ti->LODblend && (TDFX_DEBUG & VERBOSE_DRIVER)) {
417 fprintf(stderr, "fxSetupSingleTMU_NoLock: not blending texture - only one tmu\n");
418 }
419
420 grTexClampMode(tmu, ti->sClamp, ti->tClamp);
421 grTexFilterMode(tmu, ti->minFilt, ti->maxFilt);
422 grTexMipMapMode(tmu, ti->mmMode, FXFALSE);
423
424 grTexSource(tmu, ti->tm[tmu]->startAddr, GR_MIPMAPLEVELMASK_BOTH, &(ti->info));
425 }
426 }
427
428 static void
429 fxSelectSingleTMUSrc_NoLock(fxMesaContext fxMesa, GLint tmu, FxBool LODblend)
430 {
431 struct tdfx_texcombine tex0, tex1;
432
433 if (TDFX_DEBUG & VERBOSE_DRIVER) {
434 fprintf(stderr, "fxSelectSingleTMUSrc_NoLock(%d, %d)\n", tmu, LODblend);
435 }
436
437 tex0.InvertRGB = FXFALSE;
438 tex0.InvertAlpha = FXFALSE;
439 tex1.InvertRGB = FXFALSE;
440 tex1.InvertAlpha = FXFALSE;
441
442 if (LODblend) {
443 tex0.FunctionRGB = GR_COMBINE_FUNCTION_BLEND;
444 tex0.FactorRGB = GR_COMBINE_FACTOR_ONE_MINUS_LOD_FRACTION;
445 tex0.FunctionAlpha = GR_COMBINE_FUNCTION_BLEND;
446 tex0.FactorAlpha = GR_COMBINE_FACTOR_ONE_MINUS_LOD_FRACTION;
447
448 tex1.FunctionRGB = GR_COMBINE_FUNCTION_LOCAL;
449 tex1.FactorRGB = GR_COMBINE_FACTOR_NONE;
450 tex1.FunctionAlpha = GR_COMBINE_FUNCTION_LOCAL;
451 tex1.FactorAlpha = GR_COMBINE_FACTOR_NONE;
452
453 fxMesa->tmuSrc = FX_TMU_SPLIT;
454 }
455 else {
456 if (tmu != FX_TMU1) {
457 tex0.FunctionRGB = GR_COMBINE_FUNCTION_LOCAL;
458 tex0.FactorRGB = GR_COMBINE_FACTOR_NONE;
459 tex0.FunctionAlpha = GR_COMBINE_FUNCTION_LOCAL;
460 tex0.FactorAlpha = GR_COMBINE_FACTOR_NONE;
461
462 tex1.FunctionRGB = GR_COMBINE_FUNCTION_ZERO;
463 tex1.FactorRGB = GR_COMBINE_FACTOR_NONE;
464 tex1.FunctionAlpha = GR_COMBINE_FUNCTION_ZERO;
465 tex1.FactorAlpha = GR_COMBINE_FACTOR_NONE;
466
467 fxMesa->tmuSrc = FX_TMU0;
468 }
469 else {
470 tex1.FunctionRGB = GR_COMBINE_FUNCTION_LOCAL;
471 tex1.FactorRGB = GR_COMBINE_FACTOR_NONE;
472 tex1.FunctionAlpha = GR_COMBINE_FUNCTION_LOCAL;
473 tex1.FactorAlpha = GR_COMBINE_FACTOR_NONE;
474
475 /* correct values to set TMU0 in passthrough mode */
476 tex0.FunctionRGB = GR_COMBINE_FUNCTION_BLEND;
477 tex0.FactorRGB = GR_COMBINE_FACTOR_ONE;
478 tex0.FunctionAlpha = GR_COMBINE_FUNCTION_BLEND;
479 tex0.FactorAlpha = GR_COMBINE_FACTOR_ONE;
480
481 fxMesa->tmuSrc = FX_TMU1;
482 }
483 }
484
485 grTexCombine(GR_TMU0,
486 tex0.FunctionRGB,
487 tex0.FactorRGB,
488 tex0.FunctionAlpha,
489 tex0.FactorAlpha,
490 tex0.InvertRGB,
491 tex0.InvertAlpha);
492 if (fxMesa->haveTwoTMUs) {
493 grTexCombine(GR_TMU1,
494 tex1.FunctionRGB,
495 tex1.FactorRGB,
496 tex1.FunctionAlpha,
497 tex1.FactorAlpha,
498 tex1.InvertRGB,
499 tex1.InvertAlpha);
500 }
501 }
502
503 static void
504 fxSetupTextureSingleTMU_NoLock(GLcontext * ctx, GLuint textureset)
505 {
506 fxMesaContext fxMesa = FX_CONTEXT(ctx);
507 struct tdfx_combine alphaComb, colorComb;
508 GrCombineLocal_t localc, locala;
509 GLuint unitsmode;
510 GLint ifmt;
511 tfxTexInfo *ti;
512 struct gl_texture_object *tObj = ctx->Texture.Unit[textureset]._Current;
513 int tmu;
514
515 if (TDFX_DEBUG & VERBOSE_DRIVER) {
516 fprintf(stderr, "fxSetupTextureSingleTMU_NoLock(%d)\n", textureset);
517 }
518
519 ti = fxTMGetTexInfo(tObj);
520
521 fxTexValidate(ctx, tObj);
522
523 fxSetupSingleTMU_NoLock(fxMesa, tObj);
524
525 if (ti->whichTMU == FX_TMU_BOTH)
526 tmu = FX_TMU0;
527 else
528 tmu = ti->whichTMU;
529 if (fxMesa->tmuSrc != tmu)
530 fxSelectSingleTMUSrc_NoLock(fxMesa, tmu, ti->LODblend);
531
532 if (textureset == 0 || !fxMesa->haveTwoTMUs)
533 unitsmode = fxGetTexSetConfiguration(ctx, tObj, NULL);
534 else
535 unitsmode = fxGetTexSetConfiguration(ctx, NULL, tObj);
536
537 /* if(fxMesa->lastUnitsMode==unitsmode) */
538 /* return; */
539
540 fxMesa->lastUnitsMode = unitsmode;
541
542 fxMesa->stw_hint_state = 0;
543 FX_grHints_NoLock(GR_HINT_STWHINT, 0);
544
545 ifmt = ti->baseLevelInternalFormat;
546
547 if (unitsmode & FX_UM_ALPHA_ITERATED)
548 locala = GR_COMBINE_LOCAL_ITERATED;
549 else
550 locala = GR_COMBINE_LOCAL_CONSTANT;
551
552 if (unitsmode & FX_UM_COLOR_ITERATED)
553 localc = GR_COMBINE_LOCAL_ITERATED;
554 else
555 localc = GR_COMBINE_LOCAL_CONSTANT;
556
557 if (TDFX_DEBUG & (VERBOSE_DRIVER | VERBOSE_TEXTURE))
558 fprintf(stderr, "fxSetupTextureSingleTMU_NoLock: envmode is %s\n",
559 _mesa_lookup_enum_by_nr(ctx->Texture.Unit[textureset].EnvMode));
560
561 alphaComb.Local = locala;
562 alphaComb.Invert = FXFALSE;
563 colorComb.Local = localc;
564 colorComb.Invert = FXFALSE;
565
566 switch (ctx->Texture.Unit[textureset].EnvMode) {
567 case GL_DECAL:
568 alphaComb.Function = GR_COMBINE_FUNCTION_LOCAL;
569 alphaComb.Factor = GR_COMBINE_FACTOR_NONE;
570 alphaComb.Other = GR_COMBINE_OTHER_NONE;
571
572 colorComb.Function = GR_COMBINE_FUNCTION_BLEND;
573 colorComb.Factor = GR_COMBINE_FACTOR_TEXTURE_ALPHA;
574 colorComb.Other = GR_COMBINE_OTHER_TEXTURE;
575 break;
576 case GL_MODULATE:
577 alphaComb.Function = GR_COMBINE_FUNCTION_SCALE_OTHER;
578 alphaComb.Factor = GR_COMBINE_FACTOR_LOCAL;
579 alphaComb.Other = GR_COMBINE_OTHER_TEXTURE;
580
581 if (ifmt == GL_ALPHA) {
582 colorComb.Function = GR_COMBINE_FUNCTION_LOCAL;
583 colorComb.Factor = GR_COMBINE_FACTOR_NONE;
584 colorComb.Other = GR_COMBINE_OTHER_NONE;
585 } else {
586 colorComb.Function = GR_COMBINE_FUNCTION_SCALE_OTHER;
587 colorComb.Factor = GR_COMBINE_FACTOR_LOCAL;
588 colorComb.Other = GR_COMBINE_OTHER_TEXTURE;
589 }
590 break;
591 case GL_BLEND:
592 if (ifmt == GL_LUMINANCE || ifmt == GL_RGB) {
593 /* Av = Af */
594 alphaComb.Function = GR_COMBINE_FUNCTION_LOCAL;
595 alphaComb.Factor = GR_COMBINE_FACTOR_NONE;
596 alphaComb.Other = GR_COMBINE_OTHER_NONE;
597 }
598 else if (ifmt == GL_INTENSITY) {
599 /* Av = Af * (1 - It) + Ac * It */
600 alphaComb.Function = GR_COMBINE_FUNCTION_BLEND;
601 alphaComb.Factor = GR_COMBINE_FACTOR_TEXTURE_ALPHA;
602 alphaComb.Other = GR_COMBINE_OTHER_CONSTANT;
603 }
604 else {
605 /* Av = Af * At */
606 alphaComb.Function = GR_COMBINE_FUNCTION_SCALE_OTHER;
607 alphaComb.Factor = GR_COMBINE_FACTOR_LOCAL;
608 alphaComb.Other = GR_COMBINE_OTHER_TEXTURE;
609 }
610
611 if (ifmt == GL_ALPHA) {
612 colorComb.Function = GR_COMBINE_FUNCTION_LOCAL;
613 colorComb.Factor = GR_COMBINE_FACTOR_NONE;
614 colorComb.Other = GR_COMBINE_OTHER_NONE;
615 } else {
616 if (fxMesa->type >= GR_SSTTYPE_Voodoo2) {
617 colorComb.Function = GR_COMBINE_FUNCTION_BLEND;
618 colorComb.Factor = GR_COMBINE_FACTOR_TEXTURE_RGB;
619 colorComb.Other = GR_COMBINE_OTHER_CONSTANT;
620 } else if (ifmt == GL_INTENSITY) {
621 /* just a hack: RGB == ALPHA */
622 colorComb.Function = GR_COMBINE_FUNCTION_BLEND;
623 colorComb.Factor = GR_COMBINE_FACTOR_TEXTURE_ALPHA;
624 colorComb.Other = GR_COMBINE_OTHER_CONSTANT;
625 } else {
626 /* Only Voodoo^2 can GL_BLEND (GR_COMBINE_FACTOR_TEXTURE_RGB)
627 * These settings assume that the TexEnv color is black and
628 * incoming fragment color is white.
629 */
630 colorComb.Function = GR_COMBINE_FUNCTION_SCALE_OTHER;
631 colorComb.Factor = GR_COMBINE_FACTOR_ONE;
632 colorComb.Other = GR_COMBINE_OTHER_TEXTURE;
633 colorComb.Invert = FXTRUE;
634 _mesa_problem(NULL, "can't GL_BLEND with SST1");
635 }
636 }
637
638 grConstantColorValue(
639 (((GLuint)(ctx->Texture.Unit[textureset].EnvColor[0] * 255.0f)) ) |
640 (((GLuint)(ctx->Texture.Unit[textureset].EnvColor[1] * 255.0f)) << 8) |
641 (((GLuint)(ctx->Texture.Unit[textureset].EnvColor[2] * 255.0f)) << 16) |
642 (((GLuint)(ctx->Texture.Unit[textureset].EnvColor[3] * 255.0f)) << 24));
643 break;
644 case GL_REPLACE:
645 if ((ifmt == GL_RGB) || (ifmt == GL_LUMINANCE)) {
646 alphaComb.Function = GR_COMBINE_FUNCTION_LOCAL;
647 alphaComb.Factor = GR_COMBINE_FACTOR_NONE;
648 alphaComb.Other = GR_COMBINE_OTHER_NONE;
649 } else {
650 alphaComb.Function = GR_COMBINE_FUNCTION_SCALE_OTHER;
651 alphaComb.Factor = GR_COMBINE_FACTOR_ONE;
652 alphaComb.Other = GR_COMBINE_OTHER_TEXTURE;
653 }
654
655 if (ifmt == GL_ALPHA) {
656 colorComb.Function = GR_COMBINE_FUNCTION_LOCAL;
657 colorComb.Factor = GR_COMBINE_FACTOR_NONE;
658 colorComb.Other = GR_COMBINE_OTHER_NONE;
659 } else {
660 colorComb.Function = GR_COMBINE_FUNCTION_SCALE_OTHER;
661 colorComb.Factor = GR_COMBINE_FACTOR_ONE;
662 colorComb.Other = GR_COMBINE_OTHER_TEXTURE;
663 }
664 break;
665 case GL_ADD:
666 if (ifmt == GL_ALPHA ||
667 ifmt == GL_LUMINANCE_ALPHA ||
668 ifmt == GL_RGBA) {
669 /* product of texel and fragment alpha */
670 alphaComb.Function = GR_COMBINE_FUNCTION_SCALE_OTHER;
671 alphaComb.Factor = GR_COMBINE_FACTOR_LOCAL;
672 alphaComb.Other = GR_COMBINE_OTHER_TEXTURE;
673 }
674 else if (ifmt == GL_LUMINANCE || ifmt == GL_RGB) {
675 /* fragment alpha is unchanged */
676 alphaComb.Function = GR_COMBINE_FUNCTION_LOCAL;
677 alphaComb.Factor = GR_COMBINE_FACTOR_NONE;
678 alphaComb.Other = GR_COMBINE_OTHER_NONE;
679 }
680 else {
681 /* sum of texel and fragment alpha */
682 alphaComb.Function = GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL;
683 alphaComb.Factor = GR_COMBINE_FACTOR_ONE;
684 alphaComb.Other = GR_COMBINE_OTHER_TEXTURE;
685 }
686
687 if (ifmt == GL_ALPHA) {
688 /* rgb unchanged */
689 colorComb.Function = GR_COMBINE_FUNCTION_LOCAL;
690 colorComb.Factor = GR_COMBINE_FACTOR_NONE;
691 colorComb.Other = GR_COMBINE_OTHER_NONE;
692 }
693 else {
694 /* sum of texel and fragment rgb */
695 colorComb.Function = GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL;
696 colorComb.Factor = GR_COMBINE_FACTOR_ONE;
697 colorComb.Other = GR_COMBINE_OTHER_TEXTURE;
698 }
699 break;
700 default:
701 if (TDFX_DEBUG & VERBOSE_DRIVER) {
702 fprintf(stderr, "fxSetupTextureSingleTMU_NoLock: %x Texture.EnvMode not yet supported\n",
703 ctx->Texture.Unit[textureset].EnvMode);
704 }
705 return;
706 }
707
708 grAlphaCombine(alphaComb.Function,
709 alphaComb.Factor,
710 alphaComb.Local,
711 alphaComb.Other,
712 alphaComb.Invert);
713 grColorCombine(colorComb.Function,
714 colorComb.Factor,
715 colorComb.Local,
716 colorComb.Other,
717 colorComb.Invert);
718 }
719
720 #if 00
721 static void
722 fxSetupTextureSingleTMU(GLcontext * ctx, GLuint textureset)
723 {
724 BEGIN_BOARD_LOCK();
725 fxSetupTextureSingleTMU_NoLock(ctx, textureset);
726 END_BOARD_LOCK();
727 }
728 #endif
729
730
731 /************************* Double Texture Set ***************************/
732
733 static void
734 fxSetupDoubleTMU_NoLock(fxMesaContext fxMesa,
735 struct gl_texture_object *tObj0,
736 struct gl_texture_object *tObj1)
737 {
738 #define T0_NOT_IN_TMU 0x01
739 #define T1_NOT_IN_TMU 0x02
740 #define T0_IN_TMU0 0x04
741 #define T1_IN_TMU0 0x08
742 #define T0_IN_TMU1 0x10
743 #define T1_IN_TMU1 0x20
744
745 tfxTexInfo *ti0 = fxTMGetTexInfo(tObj0);
746 tfxTexInfo *ti1 = fxTMGetTexInfo(tObj1);
747 GLuint tstate = 0;
748 int tmu0 = 0, tmu1 = 1;
749
750 if (TDFX_DEBUG & VERBOSE_DRIVER) {
751 fprintf(stderr, "fxSetupDoubleTMU_NoLock(...)\n");
752 }
753
754 /* We shouldn't need to do this. There is something wrong with
755 mutlitexturing when the TMUs are swapped. So, we're forcing
756 them to always be loaded correctly. !!! */
757 if (ti0->whichTMU == FX_TMU1)
758 fxTMMoveOutTM_NoLock(fxMesa, tObj0);
759 if (ti1->whichTMU == FX_TMU0)
760 fxTMMoveOutTM_NoLock(fxMesa, tObj1);
761
762 if (ti0->isInTM) {
763 switch (ti0->whichTMU) {
764 case FX_TMU0:
765 tstate |= T0_IN_TMU0;
766 break;
767 case FX_TMU1:
768 tstate |= T0_IN_TMU1;
769 break;
770 case FX_TMU_BOTH:
771 tstate |= T0_IN_TMU0 | T0_IN_TMU1;
772 break;
773 case FX_TMU_SPLIT:
774 tstate |= T0_NOT_IN_TMU;
775 break;
776 }
777 }
778 else
779 tstate |= T0_NOT_IN_TMU;
780
781 if (ti1->isInTM) {
782 switch (ti1->whichTMU) {
783 case FX_TMU0:
784 tstate |= T1_IN_TMU0;
785 break;
786 case FX_TMU1:
787 tstate |= T1_IN_TMU1;
788 break;
789 case FX_TMU_BOTH:
790 tstate |= T1_IN_TMU0 | T1_IN_TMU1;
791 break;
792 case FX_TMU_SPLIT:
793 tstate |= T1_NOT_IN_TMU;
794 break;
795 }
796 }
797 else
798 tstate |= T1_NOT_IN_TMU;
799
800 ti0->lastTimeUsed = fxMesa->texBindNumber;
801 ti1->lastTimeUsed = fxMesa->texBindNumber;
802
803 /* Move texture maps into TMUs */
804
805 if (!(((tstate & T0_IN_TMU0) && (tstate & T1_IN_TMU1)) ||
806 ((tstate & T0_IN_TMU1) && (tstate & T1_IN_TMU0)))) {
807 if (tObj0 == tObj1)
808 fxTMMoveInTM_NoLock(fxMesa, tObj1, FX_TMU_BOTH);
809 else {
810 /* Find the minimal way to correct the situation */
811 if ((tstate & T0_IN_TMU0) || (tstate & T1_IN_TMU1)) {
812 /* We have one in the standard order, setup the other */
813 if (tstate & T0_IN_TMU0) { /* T0 is in TMU0, put T1 in TMU1 */
814 fxTMMoveInTM_NoLock(fxMesa, tObj1, FX_TMU1);
815 }
816 else {
817 fxTMMoveInTM_NoLock(fxMesa, tObj0, FX_TMU0);
818 }
819 /* tmu0 and tmu1 are setup */
820 }
821 else if ((tstate & T0_IN_TMU1) || (tstate & T1_IN_TMU0)) {
822 /* we have one in the reverse order, setup the other */
823 if (tstate & T1_IN_TMU0) { /* T1 is in TMU0, put T0 in TMU1 */
824 fxTMMoveInTM_NoLock(fxMesa, tObj0, FX_TMU1);
825 }
826 else {
827 fxTMMoveInTM_NoLock(fxMesa, tObj1, FX_TMU0);
828 }
829 tmu0 = 1;
830 tmu1 = 0;
831 }
832 else { /* Nothing is loaded */
833 fxTMMoveInTM_NoLock(fxMesa, tObj0, FX_TMU0);
834 fxTMMoveInTM_NoLock(fxMesa, tObj1, FX_TMU1);
835 /* tmu0 and tmu1 are setup */
836 }
837 }
838 }
839
840 /* [dBorca] Hack alert:
841 * we put these in reverse order, so that if we can't
842 * do _REAL_ pointcast, the TMU0 table gets broadcasted
843 */
844 if (!fxMesa->haveGlobalPaletteTexture) {
845 /* pointcast */
846 if (ti1->info.format == GR_TEXFMT_P_8) {
847 if (TDFX_DEBUG & VERBOSE_DRIVER) {
848 fprintf(stderr, "fxSetupDoubleTMU_NoLock: uploading texture palette for TMU1\n");
849 }
850 fxMesa->Glide.grTexDownloadTableExt(ti1->whichTMU, ti1->paltype, &(ti1->palette));
851 }
852 if (ti0->info.format == GR_TEXFMT_P_8) {
853 if (TDFX_DEBUG & VERBOSE_DRIVER) {
854 fprintf(stderr, "fxSetupDoubleTMU_NoLock: uploading texture palette for TMU0\n");
855 }
856 fxMesa->Glide.grTexDownloadTableExt(ti0->whichTMU, ti0->paltype, &(ti0->palette));
857 }
858 }
859
860 grTexSource(tmu0, ti0->tm[tmu0]->startAddr,
861 GR_MIPMAPLEVELMASK_BOTH, &(ti0->info));
862 grTexClampMode(tmu0, ti0->sClamp, ti0->tClamp);
863 grTexFilterMode(tmu0, ti0->minFilt, ti0->maxFilt);
864 grTexMipMapMode(tmu0, ti0->mmMode, FXFALSE);
865
866 grTexSource(tmu1, ti1->tm[tmu1]->startAddr,
867 GR_MIPMAPLEVELMASK_BOTH, &(ti1->info));
868 grTexClampMode(tmu1, ti1->sClamp, ti1->tClamp);
869 grTexFilterMode(tmu1, ti1->minFilt, ti1->maxFilt);
870 grTexMipMapMode(tmu1, ti1->mmMode, FXFALSE);
871
872 #undef T0_NOT_IN_TMU
873 #undef T1_NOT_IN_TMU
874 #undef T0_IN_TMU0
875 #undef T1_IN_TMU0
876 #undef T0_IN_TMU1
877 #undef T1_IN_TMU1
878 }
879
880 static void
881 fxSetupTextureDoubleTMU_NoLock(GLcontext * ctx)
882 {
883 fxMesaContext fxMesa = FX_CONTEXT(ctx);
884 struct tdfx_combine alphaComb, colorComb;
885 struct tdfx_texcombine tex0, tex1;
886 GrCombineLocal_t localc, locala;
887 tfxTexInfo *ti0, *ti1;
888 struct gl_texture_object *tObj0 = ctx->Texture.Unit[1]._Current;
889 struct gl_texture_object *tObj1 = ctx->Texture.Unit[0]._Current;
890 GLuint envmode, ifmt, unitsmode;
891 int tmu0 = 0, tmu1 = 1;
892
893 if (TDFX_DEBUG & VERBOSE_DRIVER) {
894 fprintf(stderr, "fxSetupTextureDoubleTMU_NoLock(...)\n");
895 }
896
897 ti0 = fxTMGetTexInfo(tObj0);
898 fxTexValidate(ctx, tObj0);
899
900 ti1 = fxTMGetTexInfo(tObj1);
901 fxTexValidate(ctx, tObj1);
902
903 fxSetupDoubleTMU_NoLock(fxMesa, tObj0, tObj1);
904
905 unitsmode = fxGetTexSetConfiguration(ctx, tObj0, tObj1);
906
907 /* if(fxMesa->lastUnitsMode==unitsmode) */
908 /* return; */
909
910 fxMesa->lastUnitsMode = unitsmode;
911
912 fxMesa->stw_hint_state |= GR_STWHINT_ST_DIFF_TMU1;
913 FX_grHints_NoLock(GR_HINT_STWHINT, fxMesa->stw_hint_state);
914
915 envmode = unitsmode & FX_UM_E_ENVMODE;
916 ifmt = unitsmode & FX_UM_E_IFMT;
917
918 if (unitsmode & FX_UM_ALPHA_ITERATED)
919 locala = GR_COMBINE_LOCAL_ITERATED;
920 else
921 locala = GR_COMBINE_LOCAL_CONSTANT;
922
923 if (unitsmode & FX_UM_COLOR_ITERATED)
924 localc = GR_COMBINE_LOCAL_ITERATED;
925 else
926 localc = GR_COMBINE_LOCAL_CONSTANT;
927
928
929 if (TDFX_DEBUG & (VERBOSE_DRIVER | VERBOSE_TEXTURE))
930 fprintf(stderr, "fxSetupTextureDoubleTMU_NoLock: envmode is %s/%s\n",
931 _mesa_lookup_enum_by_nr(ctx->Texture.Unit[0].EnvMode),
932 _mesa_lookup_enum_by_nr(ctx->Texture.Unit[1].EnvMode));
933
934
935 if ((ti0->whichTMU == FX_TMU1) || (ti1->whichTMU == FX_TMU0)) {
936 tmu0 = 1;
937 tmu1 = 0;
938 }
939 fxMesa->tmuSrc = FX_TMU_BOTH;
940
941 tex0.InvertRGB = FXFALSE;
942 tex0.InvertAlpha = FXFALSE;
943 tex1.InvertRGB = FXFALSE;
944 tex1.InvertAlpha = FXFALSE;
945 alphaComb.Local = locala;
946 alphaComb.Invert = FXFALSE;
947 colorComb.Local = localc;
948 colorComb.Invert = FXFALSE;
949
950 switch (envmode) {
951 case (FX_UM_E0_MODULATE | FX_UM_E1_MODULATE):
952 {
953 GLboolean isalpha[FX_NUM_TMU];
954
955 isalpha[tmu0] = (ti0->baseLevelInternalFormat == GL_ALPHA);
956 isalpha[tmu1] = (ti1->baseLevelInternalFormat == GL_ALPHA);
957
958 if (isalpha[FX_TMU1]) {
959 tex1.FunctionRGB = GR_COMBINE_FUNCTION_ZERO;
960 tex1.FactorRGB = GR_COMBINE_FACTOR_NONE;
961 tex1.FunctionAlpha = GR_COMBINE_FUNCTION_LOCAL;
962 tex1.FactorAlpha = GR_COMBINE_FACTOR_NONE;
963 tex1.InvertRGB = FXTRUE;
964 } else {
965 tex1.FunctionRGB = GR_COMBINE_FUNCTION_LOCAL;
966 tex1.FactorRGB = GR_COMBINE_FACTOR_NONE;
967 tex1.FunctionAlpha = GR_COMBINE_FUNCTION_LOCAL;
968 tex1.FactorAlpha = GR_COMBINE_FACTOR_NONE;
969 }
970
971 if (isalpha[FX_TMU0]) {
972 tex0.FunctionRGB = GR_COMBINE_FUNCTION_BLEND_OTHER;
973 tex0.FactorRGB = GR_COMBINE_FACTOR_ONE;
974 tex0.FunctionAlpha = GR_COMBINE_FUNCTION_BLEND_OTHER;
975 tex0.FactorAlpha = GR_COMBINE_FACTOR_LOCAL;
976 } else {
977 tex0.FunctionRGB = GR_COMBINE_FUNCTION_BLEND_OTHER;
978 tex0.FactorRGB = GR_COMBINE_FACTOR_LOCAL;
979 tex0.FunctionAlpha = GR_COMBINE_FUNCTION_BLEND_OTHER;
980 tex0.FactorAlpha = GR_COMBINE_FACTOR_LOCAL;
981 }
982
983 colorComb.Function = GR_COMBINE_FUNCTION_SCALE_OTHER;
984 colorComb.Factor = GR_COMBINE_FACTOR_LOCAL;
985 colorComb.Other = GR_COMBINE_OTHER_TEXTURE;
986
987 alphaComb.Function = GR_COMBINE_FUNCTION_SCALE_OTHER;
988 alphaComb.Factor = GR_COMBINE_FACTOR_LOCAL;
989 alphaComb.Other = GR_COMBINE_OTHER_TEXTURE;
990 break;
991 }
992 case (FX_UM_E0_REPLACE | FX_UM_E1_BLEND): /* Only for GLQuake */
993 if (tmu0 == FX_TMU1) {
994 tex1.FunctionRGB = GR_COMBINE_FUNCTION_LOCAL;
995 tex1.FactorRGB = GR_COMBINE_FACTOR_NONE;
996 tex1.FunctionAlpha = GR_COMBINE_FUNCTION_LOCAL;
997 tex1.FactorAlpha = GR_COMBINE_FACTOR_NONE;
998 tex1.InvertRGB = FXTRUE;
999
1000 tex0.FunctionRGB = GR_COMBINE_FUNCTION_BLEND_OTHER;
1001 tex0.FactorRGB = GR_COMBINE_FACTOR_LOCAL;
1002 tex0.FunctionAlpha = GR_COMBINE_FUNCTION_BLEND_OTHER;
1003 tex0.FactorAlpha = GR_COMBINE_FACTOR_LOCAL;
1004 }
1005 else {
1006 tex1.FunctionRGB = GR_COMBINE_FUNCTION_LOCAL;
1007 tex1.FactorRGB = GR_COMBINE_FACTOR_NONE;
1008 tex1.FunctionAlpha = GR_COMBINE_FUNCTION_LOCAL;
1009 tex1.FactorAlpha = GR_COMBINE_FACTOR_NONE;
1010
1011 tex0.FunctionRGB = GR_COMBINE_FUNCTION_BLEND_OTHER;
1012 tex0.FactorRGB = GR_COMBINE_FACTOR_ONE_MINUS_LOCAL;
1013 tex0.FunctionAlpha = GR_COMBINE_FUNCTION_BLEND_OTHER;
1014 tex0.FactorAlpha = GR_COMBINE_FACTOR_ONE_MINUS_LOCAL;
1015 }
1016
1017 alphaComb.Function = GR_COMBINE_FUNCTION_LOCAL;
1018 alphaComb.Factor = GR_COMBINE_FACTOR_NONE;
1019 alphaComb.Other = GR_COMBINE_OTHER_NONE;
1020
1021 colorComb.Function = GR_COMBINE_FUNCTION_SCALE_OTHER;
1022 colorComb.Factor = GR_COMBINE_FACTOR_ONE;
1023 colorComb.Other = GR_COMBINE_OTHER_TEXTURE;
1024 break;
1025 case (FX_UM_E0_REPLACE | FX_UM_E1_MODULATE): /* Quake 2 and 3 */
1026 if (tmu1 == FX_TMU1) {
1027 tex1.FunctionRGB = GR_COMBINE_FUNCTION_LOCAL;
1028 tex1.FactorRGB = GR_COMBINE_FACTOR_NONE;
1029 tex1.FunctionAlpha = GR_COMBINE_FUNCTION_ZERO;
1030 tex1.FactorAlpha = GR_COMBINE_FACTOR_NONE;
1031 tex1.InvertAlpha = FXTRUE;
1032
1033 tex0.FunctionRGB = GR_COMBINE_FUNCTION_BLEND_OTHER;
1034 tex0.FactorRGB = GR_COMBINE_FACTOR_LOCAL;
1035 tex0.FunctionAlpha = GR_COMBINE_FUNCTION_BLEND_OTHER;
1036 tex0.FactorAlpha = GR_COMBINE_FACTOR_LOCAL;
1037 }
1038 else {
1039 tex1.FunctionRGB = GR_COMBINE_FUNCTION_LOCAL;
1040 tex1.FactorRGB = GR_COMBINE_FACTOR_NONE;
1041 tex1.FunctionAlpha = GR_COMBINE_FUNCTION_LOCAL;
1042 tex1.FactorAlpha = GR_COMBINE_FACTOR_NONE;
1043
1044 tex0.FunctionRGB = GR_COMBINE_FUNCTION_BLEND_OTHER;
1045 tex0.FactorRGB = GR_COMBINE_FACTOR_LOCAL;
1046 tex0.FunctionAlpha = GR_COMBINE_FUNCTION_BLEND_OTHER;
1047 tex0.FactorAlpha = GR_COMBINE_FACTOR_ONE;
1048 }
1049
1050 if (ti0->baseLevelInternalFormat == GL_RGB) {
1051 alphaComb.Function = GR_COMBINE_FUNCTION_LOCAL;
1052 alphaComb.Factor = GR_COMBINE_FACTOR_NONE;
1053 alphaComb.Other = GR_COMBINE_OTHER_NONE;
1054 } else {
1055 alphaComb.Function = GR_COMBINE_FUNCTION_SCALE_OTHER;
1056 alphaComb.Factor = GR_COMBINE_FACTOR_ONE;
1057 alphaComb.Other = GR_COMBINE_OTHER_NONE;
1058 }
1059
1060 colorComb.Function = GR_COMBINE_FUNCTION_SCALE_OTHER;
1061 colorComb.Factor = GR_COMBINE_FACTOR_ONE;
1062 colorComb.Other = GR_COMBINE_OTHER_TEXTURE;
1063 break;
1064
1065
1066 case (FX_UM_E0_MODULATE | FX_UM_E1_ADD): /* Quake 3 Sky */
1067 {
1068 GLboolean isalpha[FX_NUM_TMU];
1069
1070 isalpha[tmu0] = (ti0->baseLevelInternalFormat == GL_ALPHA);
1071 isalpha[tmu1] = (ti1->baseLevelInternalFormat == GL_ALPHA);
1072
1073 if (isalpha[FX_TMU1]) {
1074 tex1.FunctionRGB = GR_COMBINE_FUNCTION_ZERO;
1075 tex1.FactorRGB = GR_COMBINE_FACTOR_NONE;
1076 tex1.FunctionAlpha = GR_COMBINE_FUNCTION_LOCAL;
1077 tex1.FactorAlpha = GR_COMBINE_FACTOR_NONE;
1078 tex1.InvertRGB = FXTRUE;
1079 } else {
1080 tex1.FunctionRGB = GR_COMBINE_FUNCTION_LOCAL;
1081 tex1.FactorRGB = GR_COMBINE_FACTOR_NONE;
1082 tex1.FunctionAlpha = GR_COMBINE_FUNCTION_LOCAL;
1083 tex1.FactorAlpha = GR_COMBINE_FACTOR_NONE;
1084 }
1085
1086 if (isalpha[FX_TMU0]) {
1087 tex0.FunctionRGB = GR_COMBINE_FUNCTION_SCALE_OTHER;
1088 tex0.FactorRGB = GR_COMBINE_FACTOR_ONE;
1089 tex0.FunctionAlpha = GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL;
1090 tex0.FactorAlpha = GR_COMBINE_FACTOR_ONE;
1091 } else {
1092 tex0.FunctionRGB = GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL;
1093 tex0.FactorRGB = GR_COMBINE_FACTOR_ONE;
1094 tex0.FunctionAlpha = GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL;
1095 tex0.FactorAlpha = GR_COMBINE_FACTOR_ONE;
1096 }
1097
1098 colorComb.Function = GR_COMBINE_FUNCTION_SCALE_OTHER;
1099 colorComb.Factor = GR_COMBINE_FACTOR_LOCAL;
1100 colorComb.Other = GR_COMBINE_OTHER_TEXTURE;
1101
1102 alphaComb.Function = GR_COMBINE_FUNCTION_SCALE_OTHER;
1103 alphaComb.Factor = GR_COMBINE_FACTOR_LOCAL;
1104 alphaComb.Other = GR_COMBINE_OTHER_TEXTURE;
1105 break;
1106 }
1107
1108 case (FX_UM_E0_REPLACE | FX_UM_E1_ADD): /* Vulpine Sky */
1109 {
1110 GLboolean isalpha[FX_NUM_TMU];
1111
1112 isalpha[tmu0] = (ti0->baseLevelInternalFormat == GL_ALPHA);
1113 isalpha[tmu1] = (ti1->baseLevelInternalFormat == GL_ALPHA);
1114
1115 if (isalpha[FX_TMU1]) {
1116 tex1.FunctionRGB = GR_COMBINE_FUNCTION_ZERO;
1117 tex1.FactorRGB = GR_COMBINE_FACTOR_NONE;
1118 tex1.FunctionAlpha = GR_COMBINE_FUNCTION_LOCAL;
1119 tex1.FactorAlpha = GR_COMBINE_FACTOR_NONE;
1120 tex1.InvertRGB = FXTRUE;
1121 } else {
1122 tex1.FunctionRGB = GR_COMBINE_FUNCTION_LOCAL;
1123 tex1.FactorRGB = GR_COMBINE_FACTOR_NONE;
1124 tex1.FunctionAlpha = GR_COMBINE_FUNCTION_LOCAL;
1125 tex1.FactorAlpha = GR_COMBINE_FACTOR_NONE;
1126 }
1127
1128 if (isalpha[FX_TMU0]) {
1129 tex0.FunctionRGB = GR_COMBINE_FUNCTION_SCALE_OTHER;
1130 tex0.FactorRGB = GR_COMBINE_FACTOR_ONE;
1131 tex0.FunctionAlpha = GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL;
1132 tex0.FactorAlpha = GR_COMBINE_FACTOR_ONE;
1133 } else {
1134 tex0.FunctionRGB = GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL;
1135 tex0.FactorRGB = GR_COMBINE_FACTOR_ONE;
1136 tex0.FunctionAlpha = GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL;
1137 tex0.FactorAlpha = GR_COMBINE_FACTOR_ONE;
1138 }
1139
1140 colorComb.Function = GR_COMBINE_FUNCTION_SCALE_OTHER;
1141 colorComb.Factor = GR_COMBINE_FACTOR_ONE;
1142 colorComb.Other = GR_COMBINE_OTHER_TEXTURE;
1143
1144 alphaComb.Function = GR_COMBINE_FUNCTION_SCALE_OTHER;
1145 alphaComb.Factor = GR_COMBINE_FACTOR_ONE;
1146 alphaComb.Other = GR_COMBINE_OTHER_TEXTURE;
1147 break;
1148 }
1149
1150 case (FX_UM_E0_MODULATE | FX_UM_E1_REPLACE): /* Homeworld2 */
1151 {
1152 tex1.FunctionRGB = GR_COMBINE_FUNCTION_ZERO;
1153 tex1.FactorRGB = GR_COMBINE_FACTOR_NONE;
1154 tex1.FunctionAlpha = GR_COMBINE_FUNCTION_ZERO;
1155 tex1.FactorAlpha = GR_COMBINE_FACTOR_NONE;
1156
1157 tex0.FunctionRGB = GR_COMBINE_FUNCTION_LOCAL;
1158 tex0.FactorRGB = GR_COMBINE_FACTOR_NONE;
1159 tex0.FunctionAlpha = GR_COMBINE_FUNCTION_LOCAL;
1160 tex0.FactorAlpha = GR_COMBINE_FACTOR_NONE;
1161
1162 if (ifmt & (FX_UM_E0_RGB | FX_UM_E0_LUMINANCE)) {
1163 alphaComb.Function = GR_COMBINE_FUNCTION_LOCAL;
1164 alphaComb.Factor = GR_COMBINE_FACTOR_NONE;
1165 alphaComb.Other = GR_COMBINE_OTHER_NONE;
1166 } else {
1167 alphaComb.Function = GR_COMBINE_FUNCTION_SCALE_OTHER;
1168 alphaComb.Factor = GR_COMBINE_FACTOR_ONE;
1169 alphaComb.Other = GR_COMBINE_OTHER_TEXTURE;
1170 }
1171
1172 if (ifmt & FX_UM_E0_ALPHA) {
1173 colorComb.Function = GR_COMBINE_FUNCTION_LOCAL;
1174 colorComb.Factor = GR_COMBINE_FACTOR_NONE;
1175 colorComb.Other = GR_COMBINE_OTHER_NONE;
1176 } else {
1177 colorComb.Function = GR_COMBINE_FUNCTION_SCALE_OTHER;
1178 colorComb.Factor = GR_COMBINE_FACTOR_ONE;
1179 colorComb.Other = GR_COMBINE_OTHER_TEXTURE;
1180 }
1181 break;
1182 }
1183 default:
1184 fprintf(stderr, "fxSetupTextureDoubleTMU_NoLock: Unexpected dual texture mode encountered\n");
1185 return;
1186 }
1187
1188 grAlphaCombine(alphaComb.Function,
1189 alphaComb.Factor,
1190 alphaComb.Local,
1191 alphaComb.Other,
1192 alphaComb.Invert);
1193 grColorCombine(colorComb.Function,
1194 colorComb.Factor,
1195 colorComb.Local,
1196 colorComb.Other,
1197 colorComb.Invert);
1198 grTexCombine(GR_TMU0,
1199 tex0.FunctionRGB,
1200 tex0.FactorRGB,
1201 tex0.FunctionAlpha,
1202 tex0.FactorAlpha,
1203 tex0.InvertRGB,
1204 tex0.InvertAlpha);
1205 grTexCombine(GR_TMU1,
1206 tex1.FunctionRGB,
1207 tex1.FactorRGB,
1208 tex1.FunctionAlpha,
1209 tex1.FactorAlpha,
1210 tex1.InvertRGB,
1211 tex1.InvertAlpha);
1212 }
1213
1214 /************************* No Texture ***************************/
1215
1216 static void
1217 fxSetupTextureNone_NoLock(GLcontext * ctx)
1218 {
1219 fxMesaContext fxMesa = FX_CONTEXT(ctx);
1220 GrCombineLocal_t localc, locala;
1221
1222 if (TDFX_DEBUG & VERBOSE_DRIVER) {
1223 fprintf(stderr, "fxSetupTextureNone_NoLock(...)\n");
1224 }
1225
1226 if ((ctx->Light.ShadeModel == GL_SMOOTH) || 1 ||
1227 (ctx->Point.SmoothFlag) ||
1228 (ctx->Line.SmoothFlag) ||
1229 (ctx->Polygon.SmoothFlag)) locala = GR_COMBINE_LOCAL_ITERATED;
1230 else
1231 locala = GR_COMBINE_LOCAL_CONSTANT;
1232
1233 if (ctx->Light.ShadeModel == GL_SMOOTH || 1)
1234 localc = GR_COMBINE_LOCAL_ITERATED;
1235 else
1236 localc = GR_COMBINE_LOCAL_CONSTANT;
1237
1238 grAlphaCombine(GR_COMBINE_FUNCTION_LOCAL,
1239 GR_COMBINE_FACTOR_NONE,
1240 locala,
1241 GR_COMBINE_OTHER_NONE,
1242 FXFALSE);
1243
1244 grColorCombine(GR_COMBINE_FUNCTION_LOCAL,
1245 GR_COMBINE_FACTOR_NONE,
1246 localc,
1247 GR_COMBINE_OTHER_NONE,
1248 FXFALSE);
1249
1250 fxMesa->lastUnitsMode = FX_UM_NONE;
1251 }
1252
1253 #include "fxsetup.h"
1254
1255 /************************************************************************/
1256 /************************** Texture Mode SetUp **************************/
1257 /************************************************************************/
1258
1259 static void
1260 fxSetupTexture_NoLock(GLcontext * ctx)
1261 {
1262 fxMesaContext fxMesa = FX_CONTEXT(ctx);
1263
1264 if (TDFX_DEBUG & VERBOSE_DRIVER) {
1265 fprintf(stderr, "fxSetupTexture_NoLock(...)\n");
1266 }
1267
1268 if (fxMesa->HaveCmbExt) {
1269 /* Texture Combine, Color Combine and Alpha Combine. */
1270 if ((ctx->Texture.Unit[0]._ReallyEnabled & (TEXTURE_1D_BIT|TEXTURE_2D_BIT)) &&
1271 (ctx->Texture.Unit[1]._ReallyEnabled & (TEXTURE_1D_BIT|TEXTURE_2D_BIT)) &&
1272 fxMesa->haveTwoTMUs) {
1273 fxSetupTextureDoubleTMUNapalm_NoLock(ctx);
1274 }
1275 else if (ctx->Texture.Unit[0]._ReallyEnabled & (TEXTURE_1D_BIT|TEXTURE_2D_BIT)) {
1276 fxSetupTextureSingleTMUNapalm_NoLock(ctx, 0);
1277 }
1278 else if (ctx->Texture.Unit[1]._ReallyEnabled & (TEXTURE_1D_BIT|TEXTURE_2D_BIT)) {
1279 fxSetupTextureSingleTMUNapalm_NoLock(ctx, 1);
1280 }
1281 else {
1282 fxSetupTextureNoneNapalm_NoLock(ctx);
1283 }
1284 } else {
1285 /* Texture Combine, Color Combine and Alpha Combine. */
1286 if ((ctx->Texture.Unit[0]._ReallyEnabled & (TEXTURE_1D_BIT|TEXTURE_2D_BIT)) &&
1287 (ctx->Texture.Unit[1]._ReallyEnabled & (TEXTURE_1D_BIT|TEXTURE_2D_BIT)) &&
1288 fxMesa->haveTwoTMUs) {
1289 fxSetupTextureDoubleTMU_NoLock(ctx);
1290 }
1291 else if (ctx->Texture.Unit[0]._ReallyEnabled & (TEXTURE_1D_BIT|TEXTURE_2D_BIT)) {
1292 fxSetupTextureSingleTMU_NoLock(ctx, 0);
1293 }
1294 else if (ctx->Texture.Unit[1]._ReallyEnabled & (TEXTURE_1D_BIT|TEXTURE_2D_BIT)) {
1295 fxSetupTextureSingleTMU_NoLock(ctx, 1);
1296 }
1297 else {
1298 fxSetupTextureNone_NoLock(ctx);
1299 }
1300 }
1301 }
1302
1303 void
1304 fxSetupTexture(GLcontext * ctx)
1305 {
1306 BEGIN_BOARD_LOCK();
1307 fxSetupTexture_NoLock(ctx);
1308 END_BOARD_LOCK();
1309 }
1310
1311 /************************************************************************/
1312 /**************************** Blend SetUp *******************************/
1313 /************************************************************************/
1314
1315 void
1316 fxDDBlendFuncSeparate(GLcontext * ctx, GLenum sfactor, GLenum dfactor, GLenum asfactor, GLenum adfactor)
1317 {
1318 fxMesaContext fxMesa = FX_CONTEXT(ctx);
1319 tfxUnitsState *us = &fxMesa->unitsState;
1320 GLboolean isNapalm = (fxMesa->type >= GR_SSTTYPE_Voodoo4);
1321 GLboolean have32bpp = (fxMesa->colDepth == 32);
1322 GLboolean haveAlpha = fxMesa->haveHwAlpha;
1323 GrAlphaBlendFnc_t sfact, dfact, asfact, adfact;
1324
1325 /*
1326 * 15/16 BPP alpha channel alpha blending modes
1327 * 0x0 AZERO Zero
1328 * 0x4 AONE One
1329 *
1330 * 32 BPP alpha channel alpha blending modes
1331 * 0x0 AZERO Zero
1332 * 0x1 ASRC_ALPHA Source alpha
1333 * 0x3 ADST_ALPHA Destination alpha
1334 * 0x4 AONE One
1335 * 0x5 AOMSRC_ALPHA 1 - Source alpha
1336 * 0x7 AOMDST_ALPHA 1 - Destination alpha
1337 *
1338 * If we don't have HW alpha buffer:
1339 * DST_ALPHA == 1
1340 * ONE_MINUS_DST_ALPHA == 0
1341 * Unsupported modes are:
1342 * 1 if used as src blending factor
1343 * 0 if used as dst blending factor
1344 */
1345
1346 switch (sfactor) {
1347 case GL_ZERO:
1348 sfact = GR_BLEND_ZERO;
1349 break;
1350 case GL_ONE:
1351 sfact = GR_BLEND_ONE;
1352 break;
1353 case GL_DST_COLOR:
1354 sfact = GR_BLEND_DST_COLOR;
1355 break;
1356 case GL_ONE_MINUS_DST_COLOR:
1357 sfact = GR_BLEND_ONE_MINUS_DST_COLOR;
1358 break;
1359 case GL_SRC_ALPHA:
1360 sfact = GR_BLEND_SRC_ALPHA;
1361 break;
1362 case GL_ONE_MINUS_SRC_ALPHA:
1363 sfact = GR_BLEND_ONE_MINUS_SRC_ALPHA;
1364 break;
1365 case GL_DST_ALPHA:
1366 sfact = haveAlpha ? GR_BLEND_DST_ALPHA : GR_BLEND_ONE/*bad*/;
1367 break;
1368 case GL_ONE_MINUS_DST_ALPHA:
1369 sfact = haveAlpha ? GR_BLEND_ONE_MINUS_DST_ALPHA : GR_BLEND_ZERO/*bad*/;
1370 break;
1371 case GL_SRC_ALPHA_SATURATE:
1372 sfact = GR_BLEND_ALPHA_SATURATE;
1373 break;
1374 case GL_SRC_COLOR:
1375 if (isNapalm) {
1376 sfact = GR_BLEND_SAME_COLOR_EXT;
1377 break;
1378 }
1379 case GL_ONE_MINUS_SRC_COLOR:
1380 if (isNapalm) {
1381 sfact = GR_BLEND_ONE_MINUS_SAME_COLOR_EXT;
1382 break;
1383 }
1384 default:
1385 sfact = GR_BLEND_ONE;
1386 break;
1387 }
1388
1389 switch (asfactor) {
1390 case GL_ZERO:
1391 asfact = GR_BLEND_ZERO;
1392 break;
1393 case GL_ONE:
1394 asfact = GR_BLEND_ONE;
1395 break;
1396 case GL_SRC_COLOR:
1397 case GL_SRC_ALPHA:
1398 asfact = have32bpp ? GR_BLEND_SRC_ALPHA : GR_BLEND_ONE/*bad*/;
1399 break;
1400 case GL_ONE_MINUS_SRC_COLOR:
1401 case GL_ONE_MINUS_SRC_ALPHA:
1402 asfact = have32bpp ? GR_BLEND_ONE_MINUS_SRC_ALPHA : GR_BLEND_ONE/*bad*/;
1403 break;
1404 case GL_DST_COLOR:
1405 case GL_DST_ALPHA:
1406 asfact = (have32bpp && haveAlpha) ? GR_BLEND_DST_ALPHA : GR_BLEND_ONE/*bad*/;
1407 break;
1408 case GL_ONE_MINUS_DST_COLOR:
1409 case GL_ONE_MINUS_DST_ALPHA:
1410 asfact = (have32bpp && haveAlpha) ? GR_BLEND_ONE_MINUS_DST_ALPHA : GR_BLEND_ZERO/*bad*/;
1411 break;
1412 case GL_SRC_ALPHA_SATURATE:
1413 asfact = GR_BLEND_ONE;
1414 break;
1415 default:
1416 asfact = GR_BLEND_ONE;
1417 break;
1418 }
1419
1420 switch (dfactor) {
1421 case GL_ZERO:
1422 dfact = GR_BLEND_ZERO;
1423 break;
1424 case GL_ONE:
1425 dfact = GR_BLEND_ONE;
1426 break;
1427 case GL_SRC_COLOR:
1428 dfact = GR_BLEND_SRC_COLOR;
1429 break;
1430 case GL_ONE_MINUS_SRC_COLOR:
1431 dfact = GR_BLEND_ONE_MINUS_SRC_COLOR;
1432 break;
1433 case GL_SRC_ALPHA:
1434 dfact = GR_BLEND_SRC_ALPHA;
1435 break;
1436 case GL_ONE_MINUS_SRC_ALPHA:
1437 dfact = GR_BLEND_ONE_MINUS_SRC_ALPHA;
1438 break;
1439 case GL_DST_ALPHA:
1440 dfact = haveAlpha ? GR_BLEND_DST_ALPHA : GR_BLEND_ONE/*bad*/;
1441 break;
1442 case GL_ONE_MINUS_DST_ALPHA:
1443 dfact = haveAlpha ? GR_BLEND_ONE_MINUS_DST_ALPHA : GR_BLEND_ZERO/*bad*/;
1444 break;
1445 case GL_DST_COLOR:
1446 if (isNapalm) {
1447 dfact = GR_BLEND_SAME_COLOR_EXT;
1448 break;
1449 }
1450 case GL_ONE_MINUS_DST_COLOR:
1451 if (isNapalm) {
1452 dfact = GR_BLEND_ONE_MINUS_SAME_COLOR_EXT;
1453 break;
1454 }
1455 default:
1456 dfact = GR_BLEND_ZERO;
1457 break;
1458 }
1459
1460 switch (adfactor) {
1461 case GL_ZERO:
1462 adfact = GR_BLEND_ZERO;
1463 break;
1464 case GL_ONE:
1465 adfact = GR_BLEND_ONE;
1466 break;
1467 case GL_SRC_COLOR:
1468 case GL_SRC_ALPHA:
1469 adfact = have32bpp ? GR_BLEND_SRC_ALPHA : GR_BLEND_ZERO/*bad*/;
1470 break;
1471 case GL_ONE_MINUS_SRC_COLOR:
1472 case GL_ONE_MINUS_SRC_ALPHA:
1473 adfact = have32bpp ? GR_BLEND_ONE_MINUS_SRC_ALPHA : GR_BLEND_ZERO/*bad*/;
1474 break;
1475 case GL_DST_COLOR:
1476 case GL_DST_ALPHA:
1477 adfact = (have32bpp && haveAlpha) ? GR_BLEND_DST_ALPHA : GR_BLEND_ONE/*bad*/;
1478 break;
1479 case GL_ONE_MINUS_DST_COLOR:
1480 case GL_ONE_MINUS_DST_ALPHA:
1481 adfact = (have32bpp && haveAlpha) ? GR_BLEND_ONE_MINUS_DST_ALPHA : GR_BLEND_ZERO/*bad*/;
1482 break;
1483 default:
1484 adfact = GR_BLEND_ZERO;
1485 break;
1486 }
1487
1488 if ((sfact != us->blendSrcFuncRGB) || (asfact != us->blendSrcFuncAlpha)) {
1489 us->blendSrcFuncRGB = sfact;
1490 us->blendSrcFuncAlpha = asfact;
1491 fxMesa->new_state |= FX_NEW_BLEND;
1492 }
1493
1494 if ((dfact != us->blendDstFuncRGB) || (adfact != us->blendDstFuncAlpha)) {
1495 us->blendDstFuncRGB = dfact;
1496 us->blendDstFuncAlpha = adfact;
1497 fxMesa->new_state |= FX_NEW_BLEND;
1498 }
1499 }
1500
1501 void
1502 fxDDBlendEquationSeparate(GLcontext * ctx, GLenum modeRGB, GLenum modeA)
1503 {
1504 fxMesaContext fxMesa = FX_CONTEXT(ctx);
1505 tfxUnitsState *us = &fxMesa->unitsState;
1506 GrAlphaBlendOp_t q;
1507
1508 switch (modeRGB) {
1509 case GL_FUNC_ADD:
1510 q = GR_BLEND_OP_ADD;
1511 break;
1512 case GL_FUNC_SUBTRACT:
1513 q = GR_BLEND_OP_SUB;
1514 break;
1515 case GL_FUNC_REVERSE_SUBTRACT:
1516 q = GR_BLEND_OP_REVSUB;
1517 break;
1518 default:
1519 q = us->blendEqRGB;
1520 }
1521 if (q != us->blendEqRGB) {
1522 us->blendEqRGB = q;
1523 fxMesa->new_state |= FX_NEW_BLEND;
1524 }
1525
1526 switch (modeA) {
1527 case GL_FUNC_ADD:
1528 q = GR_BLEND_OP_ADD;
1529 break;
1530 case GL_FUNC_SUBTRACT:
1531 q = GR_BLEND_OP_SUB;
1532 break;
1533 case GL_FUNC_REVERSE_SUBTRACT:
1534 q = GR_BLEND_OP_REVSUB;
1535 break;
1536 default:
1537 q = us->blendEqAlpha;
1538 }
1539 if (q != us->blendEqAlpha) {
1540 us->blendEqAlpha = q;
1541 fxMesa->new_state |= FX_NEW_BLEND;
1542 }
1543 }
1544
1545 void
1546 fxSetupBlend(GLcontext * ctx)
1547 {
1548 fxMesaContext fxMesa = FX_CONTEXT(ctx);
1549 tfxUnitsState *us = &fxMesa->unitsState;
1550
1551 if (fxMesa->HavePixExt) {
1552 if (us->blendEnabled) {
1553 fxMesa->Glide.grAlphaBlendFunctionExt(us->blendSrcFuncRGB, us->blendDstFuncRGB,
1554 us->blendEqRGB,
1555 us->blendSrcFuncAlpha, us->blendDstFuncAlpha,
1556 us->blendEqAlpha);
1557 } else {
1558 fxMesa->Glide.grAlphaBlendFunctionExt(GR_BLEND_ONE, GR_BLEND_ZERO,
1559 GR_BLEND_OP_ADD,
1560 GR_BLEND_ONE, GR_BLEND_ZERO,
1561 GR_BLEND_OP_ADD);
1562 }
1563 } else {
1564 if (us->blendEnabled) {
1565 grAlphaBlendFunction(us->blendSrcFuncRGB, us->blendDstFuncRGB,
1566 us->blendSrcFuncAlpha, us->blendDstFuncAlpha);
1567 } else {
1568 grAlphaBlendFunction(GR_BLEND_ONE, GR_BLEND_ZERO,
1569 GR_BLEND_ONE, GR_BLEND_ZERO);
1570 }
1571 }
1572 }
1573
1574 /************************************************************************/
1575 /************************** Alpha Test SetUp ****************************/
1576 /************************************************************************/
1577
1578 void
1579 fxDDAlphaFunc(GLcontext * ctx, GLenum func, GLfloat ref)
1580 {
1581 fxMesaContext fxMesa = FX_CONTEXT(ctx);
1582 tfxUnitsState *us = &fxMesa->unitsState;
1583
1584 if (
1585 (us->alphaTestFunc != func)
1586 ||
1587 (us->alphaTestRefValue != ref)
1588 ) {
1589 us->alphaTestFunc = func;
1590 us->alphaTestRefValue = ref;
1591 fxMesa->new_state |= FX_NEW_ALPHA;
1592 }
1593 }
1594
1595 static void
1596 fxSetupAlphaTest(GLcontext * ctx)
1597 {
1598 fxMesaContext fxMesa = FX_CONTEXT(ctx);
1599 tfxUnitsState *us = &fxMesa->unitsState;
1600
1601 if (us->alphaTestEnabled) {
1602 GrAlpha_t ref = (GLint) (us->alphaTestRefValue * 255.0);
1603 grAlphaTestFunction(us->alphaTestFunc - GL_NEVER + GR_CMP_NEVER);
1604 grAlphaTestReferenceValue(ref);
1605 }
1606 else
1607 grAlphaTestFunction(GR_CMP_ALWAYS);
1608 }
1609
1610 /************************************************************************/
1611 /************************** Depth Test SetUp ****************************/
1612 /************************************************************************/
1613
1614 void
1615 fxDDDepthFunc(GLcontext * ctx, GLenum func)
1616 {
1617 fxMesaContext fxMesa = FX_CONTEXT(ctx);
1618 tfxUnitsState *us = &fxMesa->unitsState;
1619
1620 if (us->depthTestFunc != func) {
1621 us->depthTestFunc = func;
1622 fxMesa->new_state |= FX_NEW_DEPTH;
1623 }
1624 }
1625
1626 void
1627 fxDDDepthMask(GLcontext * ctx, GLboolean flag)
1628 {
1629 fxMesaContext fxMesa = FX_CONTEXT(ctx);
1630 tfxUnitsState *us = &fxMesa->unitsState;
1631
1632 if (flag != us->depthMask) {
1633 us->depthMask = flag;
1634 fxMesa->new_state |= FX_NEW_DEPTH;
1635 }
1636 }
1637
1638 void
1639 fxSetupDepthTest(GLcontext * ctx)
1640 {
1641 fxMesaContext fxMesa = FX_CONTEXT(ctx);
1642 tfxUnitsState *us = &fxMesa->unitsState;
1643
1644 if (us->depthTestEnabled) {
1645 grDepthBufferFunction(us->depthTestFunc - GL_NEVER + GR_CMP_NEVER);
1646 grDepthMask(us->depthMask);
1647 }
1648 else {
1649 grDepthBufferFunction(GR_CMP_ALWAYS);
1650 grDepthMask(FXFALSE);
1651 }
1652 }
1653
1654 /************************************************************************/
1655 /************************** Stencil SetUp *******************************/
1656 /************************************************************************/
1657
1658 static GrStencil_t convertGLStencilOp( GLenum op )
1659 {
1660 switch ( op ) {
1661 case GL_KEEP:
1662 return GR_STENCILOP_KEEP;
1663 case GL_ZERO:
1664 return GR_STENCILOP_ZERO;
1665 case GL_REPLACE:
1666 return GR_STENCILOP_REPLACE;
1667 case GL_INCR:
1668 return GR_STENCILOP_INCR_CLAMP;
1669 case GL_DECR:
1670 return GR_STENCILOP_DECR_CLAMP;
1671 case GL_INVERT:
1672 return GR_STENCILOP_INVERT;
1673 case GL_INCR_WRAP_EXT:
1674 return GR_STENCILOP_INCR_WRAP;
1675 case GL_DECR_WRAP_EXT:
1676 return GR_STENCILOP_DECR_WRAP;
1677 default:
1678 _mesa_problem( NULL, "bad stencil op in convertGLStencilOp" );
1679 }
1680 return GR_STENCILOP_KEEP; /* never get, silence compiler warning */
1681 }
1682
1683 void
1684 fxDDStencilFuncSeparate (GLcontext *ctx, GLenum face, GLenum func,
1685 GLint ref, GLuint mask)
1686 {
1687 fxMesaContext fxMesa = FX_CONTEXT(ctx);
1688 tfxUnitsState *us = &fxMesa->unitsState;
1689
1690 if (ctx->Stencil.ActiveFace) {
1691 return;
1692 }
1693
1694 if (
1695 (us->stencilFunction != func)
1696 ||
1697 (us->stencilRefValue != ref)
1698 ||
1699 (us->stencilValueMask != mask)
1700 ) {
1701 us->stencilFunction = func;
1702 us->stencilRefValue = ref;
1703 us->stencilValueMask = mask;
1704 fxMesa->new_state |= FX_NEW_STENCIL;
1705 }
1706 }
1707
1708 void
1709 fxDDStencilMaskSeparate (GLcontext *ctx, GLenum face, GLuint mask)
1710 {
1711 fxMesaContext fxMesa = FX_CONTEXT(ctx);
1712 tfxUnitsState *us = &fxMesa->unitsState;
1713
1714 if (ctx->Stencil.ActiveFace) {
1715 return;
1716 }
1717
1718 if (us->stencilWriteMask != mask) {
1719 us->stencilWriteMask = mask;
1720 fxMesa->new_state |= FX_NEW_STENCIL;
1721 }
1722 }
1723
1724 void
1725 fxDDStencilOpSeparate (GLcontext *ctx, GLenum face, GLenum sfail,
1726 GLenum zfail, GLenum zpass)
1727 {
1728 fxMesaContext fxMesa = FX_CONTEXT(ctx);
1729 tfxUnitsState *us = &fxMesa->unitsState;
1730
1731 if (ctx->Stencil.ActiveFace) {
1732 return;
1733 }
1734
1735 if (
1736 (us->stencilFailFunc != sfail)
1737 ||
1738 (us->stencilZFailFunc != zfail)
1739 ||
1740 (us->stencilZPassFunc != zpass)
1741 ) {
1742 us->stencilFailFunc = sfail;
1743 us->stencilZFailFunc = zfail;
1744 us->stencilZPassFunc = zpass;
1745 fxMesa->new_state |= FX_NEW_STENCIL;
1746 }
1747 }
1748
1749 void
1750 fxSetupStencil (GLcontext * ctx)
1751 {
1752 fxMesaContext fxMesa = FX_CONTEXT(ctx);
1753 tfxUnitsState *us = &fxMesa->unitsState;
1754
1755 if (us->stencilEnabled) {
1756 GrCmpFnc_t stencilFailFunc = GR_STENCILOP_KEEP;
1757 GrCmpFnc_t stencilZFailFunc = GR_STENCILOP_KEEP;
1758 GrCmpFnc_t stencilZPassFunc = GR_STENCILOP_KEEP;
1759 if (!fxMesa->multipass) {
1760 stencilFailFunc = convertGLStencilOp(us->stencilFailFunc);
1761 stencilZFailFunc = convertGLStencilOp(us->stencilZFailFunc);
1762 stencilZPassFunc = convertGLStencilOp(us->stencilZPassFunc);
1763 }
1764 grEnable(GR_STENCIL_MODE_EXT);
1765 fxMesa->Glide.grStencilOpExt(stencilFailFunc,
1766 stencilZFailFunc,
1767 stencilZPassFunc);
1768 fxMesa->Glide.grStencilFuncExt(us->stencilFunction - GL_NEVER + GR_CMP_NEVER,
1769 us->stencilRefValue,
1770 us->stencilValueMask);
1771 fxMesa->Glide.grStencilMaskExt(us->stencilWriteMask);
1772 } else {
1773 grDisable(GR_STENCIL_MODE_EXT);
1774 }
1775 }
1776
1777 void
1778 fxSetupStencilFace (GLcontext * ctx, GLint face)
1779 {
1780 fxMesaContext fxMesa = FX_CONTEXT(ctx);
1781 tfxUnitsState *us = &fxMesa->unitsState;
1782
1783 if (us->stencilEnabled) {
1784 GrCmpFnc_t stencilFailFunc = GR_STENCILOP_KEEP;
1785 GrCmpFnc_t stencilZFailFunc = GR_STENCILOP_KEEP;
1786 GrCmpFnc_t stencilZPassFunc = GR_STENCILOP_KEEP;
1787 if (!fxMesa->multipass) {
1788 stencilFailFunc = convertGLStencilOp(ctx->Stencil.FailFunc[face]);
1789 stencilZFailFunc = convertGLStencilOp(ctx->Stencil.ZFailFunc[face]);
1790 stencilZPassFunc = convertGLStencilOp(ctx->Stencil.ZPassFunc[face]);
1791 }
1792 grEnable(GR_STENCIL_MODE_EXT);
1793 fxMesa->Glide.grStencilOpExt(stencilFailFunc,
1794 stencilZFailFunc,
1795 stencilZPassFunc);
1796 fxMesa->Glide.grStencilFuncExt(ctx->Stencil.Function[face] - GL_NEVER + GR_CMP_NEVER,
1797 ctx->Stencil.Ref[face],
1798 ctx->Stencil.ValueMask[face]);
1799 fxMesa->Glide.grStencilMaskExt(ctx->Stencil.WriteMask[face]);
1800 } else {
1801 grDisable(GR_STENCIL_MODE_EXT);
1802 }
1803 }
1804
1805 /************************************************************************/
1806 /**************************** Color Mask SetUp **************************/
1807 /************************************************************************/
1808
1809 void
1810 fxDDColorMask(GLcontext * ctx,
1811 GLboolean r, GLboolean g, GLboolean b, GLboolean a)
1812 {
1813 fxMesaContext fxMesa = FX_CONTEXT(ctx);
1814 fxMesa->new_state |= FX_NEW_COLOR_MASK;
1815 (void) r;
1816 (void) g;
1817 (void) b;
1818 (void) a;
1819 }
1820
1821 void
1822 fxSetupColorMask(GLcontext * ctx)
1823 {
1824 fxMesaContext fxMesa = FX_CONTEXT(ctx);
1825
1826 if (fxMesa->colDepth == 32) {
1827 /* 32bpp mode */
1828 fxMesa->Glide.grColorMaskExt(ctx->Color.ColorMask[RCOMP],
1829 ctx->Color.ColorMask[GCOMP],
1830 ctx->Color.ColorMask[BCOMP],
1831 ctx->Color.ColorMask[ACOMP] && fxMesa->haveHwAlpha);
1832 }
1833 else {
1834 /* 15/16 bpp mode */
1835 grColorMask(ctx->Color.ColorMask[RCOMP] |
1836 ctx->Color.ColorMask[GCOMP] |
1837 ctx->Color.ColorMask[BCOMP],
1838 ctx->Color.ColorMask[ACOMP] && fxMesa->haveHwAlpha);
1839 }
1840 }
1841
1842
1843
1844
1845 /************************************************************************/
1846 /**************************** Fog Mode SetUp ****************************/
1847 /************************************************************************/
1848
1849 /*
1850 * This is called during state update in order to update the Glide fog state.
1851 */
1852 static void
1853 fxSetupFog(GLcontext * ctx)
1854 {
1855 if (ctx->Fog.Enabled /*&& ctx->FogMode==FOG_FRAGMENT */ ) {
1856 fxMesaContext fxMesa = FX_CONTEXT(ctx);
1857
1858 /* update fog color */
1859 GLubyte col[4];
1860 col[0] = (unsigned int) (255 * ctx->Fog.Color[0]);
1861 col[1] = (unsigned int) (255 * ctx->Fog.Color[1]);
1862 col[2] = (unsigned int) (255 * ctx->Fog.Color[2]);
1863 col[3] = (unsigned int) (255 * ctx->Fog.Color[3]);
1864 grFogColorValue(FXCOLOR4(col));
1865
1866 if (fxMesa->fogTableMode != ctx->Fog.Mode ||
1867 fxMesa->fogDensity != ctx->Fog.Density ||
1868 fxMesa->fogStart != ctx->Fog.Start ||
1869 fxMesa->fogEnd != ctx->Fog.End) {
1870 /* reload the fog table */
1871 switch (ctx->Fog.Mode) {
1872 case GL_LINEAR:
1873 guFogGenerateLinear(fxMesa->fogTable, ctx->Fog.Start,
1874 ctx->Fog.End);
1875 if (fxMesa->fogTable[0] > 63) {
1876 /* [dBorca] Hack alert:
1877 * As per Glide3 Programming Guide:
1878 * The difference between consecutive fog values
1879 * must be less than 64.
1880 */
1881 fxMesa->fogTable[0] = 63;
1882 }
1883 break;
1884 case GL_EXP:
1885 guFogGenerateExp(fxMesa->fogTable, ctx->Fog.Density);
1886 break;
1887 case GL_EXP2:
1888 guFogGenerateExp2(fxMesa->fogTable, ctx->Fog.Density);
1889 break;
1890 default:
1891 ;
1892 }
1893 fxMesa->fogTableMode = ctx->Fog.Mode;
1894 fxMesa->fogDensity = ctx->Fog.Density;
1895 fxMesa->fogStart = ctx->Fog.Start;
1896 fxMesa->fogEnd = ctx->Fog.End;
1897 }
1898
1899 grFogTable(fxMesa->fogTable);
1900 if (ctx->Fog.FogCoordinateSource == GL_FOG_COORDINATE_EXT) {
1901 grVertexLayout(GR_PARAM_FOG_EXT, GR_VERTEX_FOG_OFFSET << 2,
1902 GR_PARAM_ENABLE);
1903 grFogMode(GR_FOG_WITH_TABLE_ON_FOGCOORD_EXT);
1904 } else {
1905 grVertexLayout(GR_PARAM_FOG_EXT, GR_VERTEX_FOG_OFFSET << 2,
1906 GR_PARAM_DISABLE);
1907 grFogMode(GR_FOG_WITH_TABLE_ON_Q);
1908 }
1909 }
1910 else {
1911 grFogMode(GR_FOG_DISABLE);
1912 }
1913 }
1914
1915 void
1916 fxDDFogfv(GLcontext * ctx, GLenum pname, const GLfloat * params)
1917 {
1918 FX_CONTEXT(ctx)->new_state |= FX_NEW_FOG;
1919 switch (pname) {
1920 case GL_FOG_COORDINATE_SOURCE_EXT: {
1921 GLenum p = (GLenum)*params;
1922 if (p == GL_FOG_COORDINATE_EXT) {
1923 _swrast_allow_vertex_fog(ctx, GL_TRUE);
1924 _swrast_allow_pixel_fog(ctx, GL_FALSE);
1925 _tnl_allow_vertex_fog( ctx, GL_TRUE);
1926 _tnl_allow_pixel_fog( ctx, GL_FALSE);
1927 } else {
1928 _swrast_allow_vertex_fog(ctx, GL_FALSE);
1929 _swrast_allow_pixel_fog(ctx, GL_TRUE);
1930 _tnl_allow_vertex_fog( ctx, GL_FALSE);
1931 _tnl_allow_pixel_fog( ctx, GL_TRUE);
1932 }
1933 break;
1934 }
1935 default:
1936 ;
1937 }
1938 }
1939
1940 /************************************************************************/
1941 /************************** Scissor Test SetUp **************************/
1942 /************************************************************************/
1943
1944 /* This routine is used in managing the lock state, and therefore can't lock */
1945 void
1946 fxSetScissorValues(GLcontext * ctx)
1947 {
1948 fxMesaContext fxMesa = FX_CONTEXT(ctx);
1949 int xmin, xmax;
1950 int ymin, ymax;
1951
1952 if (ctx->Scissor.Enabled) {
1953 xmin = ctx->Scissor.X;
1954 xmax = ctx->Scissor.X + ctx->Scissor.Width;
1955 ymin = ctx->Scissor.Y;
1956 ymax = ctx->Scissor.Y + ctx->Scissor.Height;
1957
1958 if (xmin < 0)
1959 xmin = 0;
1960 if (xmax > fxMesa->width)
1961 xmax = fxMesa->width;
1962 if (ymin < fxMesa->screen_height - fxMesa->height)
1963 ymin = fxMesa->screen_height - fxMesa->height;
1964 if (ymax > fxMesa->screen_height - 0)
1965 ymax = fxMesa->screen_height - 0;
1966 }
1967 else {
1968 xmin = 0;
1969 ymin = 0;
1970 xmax = fxMesa->width;
1971 ymax = fxMesa->height;
1972 }
1973
1974 fxMesa->clipMinX = xmin;
1975 fxMesa->clipMinY = ymin;
1976 fxMesa->clipMaxX = xmax;
1977 fxMesa->clipMaxY = ymax;
1978 grClipWindow(xmin, ymin, xmax, ymax);
1979 }
1980
1981 void
1982 fxSetupScissor(GLcontext * ctx)
1983 {
1984 BEGIN_BOARD_LOCK();
1985 fxSetScissorValues(ctx);
1986 END_BOARD_LOCK();
1987 }
1988
1989 void
1990 fxDDScissor(GLcontext * ctx, GLint x, GLint y, GLsizei w, GLsizei h)
1991 {
1992 FX_CONTEXT(ctx)->new_state |= FX_NEW_SCISSOR;
1993 }
1994
1995 /************************************************************************/
1996 /*************************** Cull mode setup ****************************/
1997 /************************************************************************/
1998
1999
2000 void
2001 fxDDCullFace(GLcontext * ctx, GLenum mode)
2002 {
2003 (void) mode;
2004 FX_CONTEXT(ctx)->new_state |= FX_NEW_CULL;
2005 }
2006
2007 void
2008 fxDDFrontFace(GLcontext * ctx, GLenum mode)
2009 {
2010 (void) mode;
2011 FX_CONTEXT(ctx)->new_state |= FX_NEW_CULL;
2012 }
2013
2014
2015 void
2016 fxSetupCull(GLcontext * ctx)
2017 {
2018 fxMesaContext fxMesa = FX_CONTEXT(ctx);
2019 GrCullMode_t mode = GR_CULL_DISABLE;
2020
2021 if (ctx->Polygon.CullFlag && (fxMesa->raster_primitive == GL_TRIANGLES)) {
2022 switch (ctx->Polygon.CullFaceMode) {
2023 case GL_BACK:
2024 if (ctx->Polygon.FrontFace == GL_CCW)
2025 mode = GR_CULL_NEGATIVE;
2026 else
2027 mode = GR_CULL_POSITIVE;
2028 break;
2029 case GL_FRONT:
2030 if (ctx->Polygon.FrontFace == GL_CCW)
2031 mode = GR_CULL_POSITIVE;
2032 else
2033 mode = GR_CULL_NEGATIVE;
2034 break;
2035 case GL_FRONT_AND_BACK:
2036 /* Handled as a fallback on triangles in tdfx_tris.c */
2037 return;
2038 default:
2039 ASSERT(0);
2040 break;
2041 }
2042 }
2043
2044 if (fxMesa->cullMode != mode) {
2045 fxMesa->cullMode = mode;
2046 grCullMode(mode);
2047 }
2048 }
2049
2050
2051 /************************************************************************/
2052 /****************************** DD Enable ******************************/
2053 /************************************************************************/
2054
2055 void
2056 fxDDEnable(GLcontext * ctx, GLenum cap, GLboolean state)
2057 {
2058 fxMesaContext fxMesa = FX_CONTEXT(ctx);
2059 tfxUnitsState *us = &fxMesa->unitsState;
2060
2061 if (TDFX_DEBUG & VERBOSE_DRIVER) {
2062 fprintf(stderr, "%s(%s)\n", state ? "fxDDEnable" : "fxDDDisable",
2063 _mesa_lookup_enum_by_nr(cap));
2064 }
2065
2066 switch (cap) {
2067 case GL_ALPHA_TEST:
2068 if (state != us->alphaTestEnabled) {
2069 us->alphaTestEnabled = state;
2070 fxMesa->new_state |= FX_NEW_ALPHA;
2071 }
2072 break;
2073 case GL_BLEND:
2074 if (state != us->blendEnabled) {
2075 us->blendEnabled = state;
2076 fxMesa->new_state |= FX_NEW_BLEND;
2077 }
2078 break;
2079 case GL_DEPTH_TEST:
2080 if (state != us->depthTestEnabled) {
2081 us->depthTestEnabled = state;
2082 fxMesa->new_state |= FX_NEW_DEPTH;
2083 }
2084 break;
2085 case GL_STENCIL_TEST:
2086 if (fxMesa->haveHwStencil && state != us->stencilEnabled) {
2087 us->stencilEnabled = state;
2088 fxMesa->new_state |= FX_NEW_STENCIL;
2089 }
2090 break;
2091 case GL_DITHER:
2092 if (state) {
2093 grDitherMode(GR_DITHER_4x4);
2094 }
2095 else {
2096 grDitherMode(GR_DITHER_DISABLE);
2097 }
2098 break;
2099 case GL_SCISSOR_TEST:
2100 fxMesa->new_state |= FX_NEW_SCISSOR;
2101 break;
2102 case GL_SHARED_TEXTURE_PALETTE_EXT:
2103 fxDDTexUseGlbPalette(ctx, state);
2104 break;
2105 case GL_FOG:
2106 fxMesa->new_state |= FX_NEW_FOG;
2107 break;
2108 case GL_CULL_FACE:
2109 fxMesa->new_state |= FX_NEW_CULL;
2110 break;
2111 case GL_LINE_SMOOTH:
2112 case GL_LINE_STIPPLE:
2113 case GL_POINT_SMOOTH:
2114 case GL_POLYGON_SMOOTH:
2115 case GL_TEXTURE_1D:
2116 case GL_TEXTURE_2D:
2117 fxMesa->new_state |= FX_NEW_TEXTURING;
2118 break;
2119 default:
2120 ; /* XXX no-op? */
2121 }
2122 }
2123
2124
2125
2126
2127 /************************************************************************/
2128 /************************** Changes to units state **********************/
2129 /************************************************************************/
2130
2131
2132 /* All units setup is handled under texture setup.
2133 */
2134 void
2135 fxDDShadeModel(GLcontext * ctx, GLenum mode)
2136 {
2137 FX_CONTEXT(ctx)->new_state |= FX_NEW_TEXTURING;
2138 }
2139
2140
2141
2142 /************************************************************************/
2143 /****************************** Units SetUp *****************************/
2144 /************************************************************************/
2145 static void
2146 fx_print_state_flags(const char *msg, GLuint flags)
2147 {
2148 fprintf(stderr,
2149 "%s: (0x%x) %s%s%s%s%s%s%s%s\n",
2150 msg,
2151 flags,
2152 (flags & FX_NEW_TEXTURING) ? "texture, " : "",
2153 (flags & FX_NEW_BLEND) ? "blend, " : "",
2154 (flags & FX_NEW_ALPHA) ? "alpha, " : "",
2155 (flags & FX_NEW_FOG) ? "fog, " : "",
2156 (flags & FX_NEW_SCISSOR) ? "scissor, " : "",
2157 (flags & FX_NEW_COLOR_MASK) ? "colormask, " : "",
2158 (flags & FX_NEW_CULL) ? "cull, " : "",
2159 (flags & FX_NEW_STENCIL) ? "stencil, " : "");
2160 }
2161
2162 void
2163 fxSetupFXUnits(GLcontext * ctx)
2164 {
2165 fxMesaContext fxMesa = FX_CONTEXT(ctx);
2166 GLuint newstate = fxMesa->new_state;
2167
2168 if (TDFX_DEBUG & VERBOSE_DRIVER)
2169 fx_print_state_flags("fxSetupFXUnits", newstate);
2170
2171 if (newstate) {
2172 if (newstate & FX_NEW_TEXTURING)
2173 fxSetupTexture(ctx);
2174
2175 if (newstate & FX_NEW_BLEND)
2176 fxSetupBlend(ctx);
2177
2178 if (newstate & FX_NEW_ALPHA)
2179 fxSetupAlphaTest(ctx);
2180
2181 if (newstate & FX_NEW_DEPTH)
2182 fxSetupDepthTest(ctx);
2183
2184 if (newstate & FX_NEW_STENCIL)
2185 fxSetupStencil(ctx);
2186
2187 if (newstate & FX_NEW_FOG)
2188 fxSetupFog(ctx);
2189
2190 if (newstate & FX_NEW_SCISSOR)
2191 fxSetupScissor(ctx);
2192
2193 if (newstate & FX_NEW_COLOR_MASK)
2194 fxSetupColorMask(ctx);
2195
2196 if (newstate & FX_NEW_CULL)
2197 fxSetupCull(ctx);
2198
2199 fxMesa->new_state = 0;
2200 }
2201 }
2202
2203
2204
2205 #else
2206
2207
2208 /*
2209 * Need this to provide at least one external definition.
2210 */
2211
2212 extern int gl_fx_dummy_function_setup(void);
2213 int
2214 gl_fx_dummy_function_setup(void)
2215 {
2216 return 0;
2217 }
2218
2219 #endif /* FX */