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