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