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