cleanup
[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 /* correct values to set TMU0 in passthrough mode */
507 tex0.FunctionRGB = GR_COMBINE_FUNCTION_BLEND;
508 tex0.FactorRGB = GR_COMBINE_FACTOR_ONE;
509 tex0.FunctionAlpha = GR_COMBINE_FUNCTION_BLEND;
510 tex0.FactorAlpha = GR_COMBINE_FACTOR_ONE;
511
512 fxMesa->tmuSrc = FX_TMU1;
513 }
514 }
515
516 grTexCombine(GR_TMU0,
517 tex0.FunctionRGB,
518 tex0.FactorRGB,
519 tex0.FunctionAlpha,
520 tex0.FactorAlpha,
521 tex0.InvertRGB,
522 tex0.InvertAlpha);
523 if (fxMesa->haveTwoTMUs) {
524 grTexCombine(GR_TMU1,
525 tex1.FunctionRGB,
526 tex1.FactorRGB,
527 tex1.FunctionAlpha,
528 tex1.FactorAlpha,
529 tex1.InvertRGB,
530 tex1.InvertAlpha);
531 }
532 }
533
534 static void
535 fxSetupTextureSingleTMU_NoLock(GLcontext * ctx, GLuint textureset)
536 {
537 fxMesaContext fxMesa = FX_CONTEXT(ctx);
538 struct tdfx_combine alphaComb, colorComb;
539 GrCombineLocal_t localc, locala;
540 GLuint unitsmode;
541 GLint ifmt;
542 tfxTexInfo *ti;
543 struct gl_texture_object *tObj = ctx->Texture.Unit[textureset]._Current;
544 int tmu;
545
546 if (TDFX_DEBUG & VERBOSE_DRIVER) {
547 fprintf(stderr, "fxSetupTextureSingleTMU_NoLock(%d)\n", textureset);
548 }
549
550 ti = fxTMGetTexInfo(tObj);
551
552 fxTexValidate(ctx, tObj);
553
554 fxSetupSingleTMU_NoLock(fxMesa, tObj);
555
556 if (ti->whichTMU == FX_TMU_BOTH)
557 tmu = FX_TMU0;
558 else
559 tmu = ti->whichTMU;
560 if (fxMesa->tmuSrc != tmu)
561 fxSelectSingleTMUSrc_NoLock(fxMesa, tmu, ti->LODblend);
562
563 if (textureset == 0 || !fxMesa->haveTwoTMUs)
564 unitsmode = fxGetTexSetConfiguration(ctx, tObj, NULL);
565 else
566 unitsmode = fxGetTexSetConfiguration(ctx, NULL, tObj);
567
568 /* if(fxMesa->lastUnitsMode==unitsmode) */
569 /* return; */
570
571 fxMesa->lastUnitsMode = unitsmode;
572
573 fxMesa->stw_hint_state = 0;
574 FX_grHints_NoLock(GR_HINT_STWHINT, 0);
575
576 ifmt = ti->baseLevelInternalFormat;
577
578 if (unitsmode & FX_UM_ALPHA_ITERATED)
579 locala = GR_COMBINE_LOCAL_ITERATED;
580 else
581 locala = GR_COMBINE_LOCAL_CONSTANT;
582
583 if (unitsmode & FX_UM_COLOR_ITERATED)
584 localc = GR_COMBINE_LOCAL_ITERATED;
585 else
586 localc = GR_COMBINE_LOCAL_CONSTANT;
587
588 if (TDFX_DEBUG & (VERBOSE_DRIVER | VERBOSE_TEXTURE))
589 fprintf(stderr, "fxSetupTextureSingleTMU_NoLock: envmode is %s\n",
590 _mesa_lookup_enum_by_nr(ctx->Texture.Unit[textureset].EnvMode));
591
592 alphaComb.Local = locala;
593 alphaComb.Invert = FXFALSE;
594 colorComb.Local = localc;
595 colorComb.Invert = FXFALSE;
596
597 switch (ctx->Texture.Unit[textureset].EnvMode) {
598 case GL_DECAL:
599 alphaComb.Function = GR_COMBINE_FUNCTION_LOCAL;
600 alphaComb.Factor = GR_COMBINE_FACTOR_NONE;
601 alphaComb.Other = GR_COMBINE_OTHER_NONE;
602
603 colorComb.Function = GR_COMBINE_FUNCTION_BLEND;
604 colorComb.Factor = GR_COMBINE_FACTOR_TEXTURE_ALPHA;
605 colorComb.Other = GR_COMBINE_OTHER_TEXTURE;
606 break;
607 case GL_MODULATE:
608 alphaComb.Function = GR_COMBINE_FUNCTION_SCALE_OTHER;
609 alphaComb.Factor = GR_COMBINE_FACTOR_LOCAL;
610 alphaComb.Other = GR_COMBINE_OTHER_TEXTURE;
611
612 if (ifmt == GL_ALPHA) {
613 colorComb.Function = GR_COMBINE_FUNCTION_LOCAL;
614 colorComb.Factor = GR_COMBINE_FACTOR_NONE;
615 colorComb.Other = GR_COMBINE_OTHER_NONE;
616 } else {
617 colorComb.Function = GR_COMBINE_FUNCTION_SCALE_OTHER;
618 colorComb.Factor = GR_COMBINE_FACTOR_LOCAL;
619 colorComb.Other = GR_COMBINE_OTHER_TEXTURE;
620 }
621 break;
622 case GL_BLEND:
623 if (ifmt == GL_LUMINANCE || ifmt == GL_RGB) {
624 /* Av = Af */
625 alphaComb.Function = GR_COMBINE_FUNCTION_LOCAL;
626 alphaComb.Factor = GR_COMBINE_FACTOR_NONE;
627 alphaComb.Other = GR_COMBINE_OTHER_NONE;
628 }
629 else if (ifmt == GL_INTENSITY) {
630 /* Av = Af * (1 - It) + Ac * It */
631 alphaComb.Function = GR_COMBINE_FUNCTION_BLEND;
632 alphaComb.Factor = GR_COMBINE_FACTOR_TEXTURE_ALPHA;
633 alphaComb.Other = GR_COMBINE_OTHER_CONSTANT;
634 }
635 else {
636 /* Av = Af * At */
637 alphaComb.Function = GR_COMBINE_FUNCTION_SCALE_OTHER;
638 alphaComb.Factor = GR_COMBINE_FACTOR_LOCAL;
639 alphaComb.Other = GR_COMBINE_OTHER_TEXTURE;
640 }
641
642 if (ifmt == GL_ALPHA) {
643 colorComb.Function = GR_COMBINE_FUNCTION_LOCAL;
644 colorComb.Factor = GR_COMBINE_FACTOR_NONE;
645 colorComb.Other = GR_COMBINE_OTHER_NONE;
646 } else {
647 if (fxMesa->type >= GR_SSTTYPE_Voodoo2) {
648 colorComb.Function = GR_COMBINE_FUNCTION_BLEND;
649 colorComb.Factor = GR_COMBINE_FACTOR_TEXTURE_RGB;
650 colorComb.Other = GR_COMBINE_OTHER_CONSTANT;
651 } else if (ifmt == GL_INTENSITY) {
652 /* just a hack: RGB == ALPHA */
653 colorComb.Function = GR_COMBINE_FUNCTION_BLEND;
654 colorComb.Factor = GR_COMBINE_FACTOR_TEXTURE_ALPHA;
655 colorComb.Other = GR_COMBINE_OTHER_CONSTANT;
656 } else {
657 /* [dBorca] Hack alert:
658 * only Voodoo^2 can GL_BLEND (GR_COMBINE_FACTOR_TEXTURE_RGB)
659 * These settings assume that the TexEnv color is black
660 * and incoming fragment color is white.
661 */
662 colorComb.Function = GR_COMBINE_FUNCTION_SCALE_OTHER;
663 colorComb.Factor = GR_COMBINE_FACTOR_ONE;
664 colorComb.Other = GR_COMBINE_OTHER_TEXTURE;
665 colorComb.Invert = FXTRUE;
666 _mesa_problem(NULL, "can't GL_BLEND with SST1");
667 }
668 }
669
670 grConstantColorValue(
671 (((GLuint)(ctx->Texture.Unit[textureset].EnvColor[0] * 255.0f)) ) |
672 (((GLuint)(ctx->Texture.Unit[textureset].EnvColor[1] * 255.0f)) << 8) |
673 (((GLuint)(ctx->Texture.Unit[textureset].EnvColor[2] * 255.0f)) << 16) |
674 (((GLuint)(ctx->Texture.Unit[textureset].EnvColor[3] * 255.0f)) << 24));
675 break;
676 case GL_REPLACE:
677 if ((ifmt == GL_RGB) || (ifmt == GL_LUMINANCE)) {
678 alphaComb.Function = GR_COMBINE_FUNCTION_LOCAL;
679 alphaComb.Factor = GR_COMBINE_FACTOR_NONE;
680 alphaComb.Other = GR_COMBINE_OTHER_NONE;
681 } else {
682 alphaComb.Function = GR_COMBINE_FUNCTION_SCALE_OTHER;
683 alphaComb.Factor = GR_COMBINE_FACTOR_ONE;
684 alphaComb.Other = GR_COMBINE_OTHER_TEXTURE;
685 }
686
687 if (ifmt == GL_ALPHA) {
688 colorComb.Function = GR_COMBINE_FUNCTION_LOCAL;
689 colorComb.Factor = GR_COMBINE_FACTOR_NONE;
690 colorComb.Other = GR_COMBINE_OTHER_NONE;
691 } else {
692 colorComb.Function = GR_COMBINE_FUNCTION_SCALE_OTHER;
693 colorComb.Factor = GR_COMBINE_FACTOR_ONE;
694 colorComb.Other = GR_COMBINE_OTHER_TEXTURE;
695 }
696 break;
697 case GL_ADD:
698 if (ifmt == GL_ALPHA ||
699 ifmt == GL_LUMINANCE_ALPHA ||
700 ifmt == GL_RGBA) {
701 /* product of texel and fragment alpha */
702 alphaComb.Function = GR_COMBINE_FUNCTION_SCALE_OTHER;
703 alphaComb.Factor = GR_COMBINE_FACTOR_LOCAL;
704 alphaComb.Other = GR_COMBINE_OTHER_TEXTURE;
705 }
706 else if (ifmt == GL_LUMINANCE || ifmt == GL_RGB) {
707 /* fragment alpha is unchanged */
708 alphaComb.Function = GR_COMBINE_FUNCTION_LOCAL;
709 alphaComb.Factor = GR_COMBINE_FACTOR_NONE;
710 alphaComb.Other = GR_COMBINE_OTHER_NONE;
711 }
712 else {
713 /* sum of texel and fragment alpha */
714 alphaComb.Function = GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL;
715 alphaComb.Factor = GR_COMBINE_FACTOR_ONE;
716 alphaComb.Other = GR_COMBINE_OTHER_TEXTURE;
717 }
718
719 if (ifmt == GL_ALPHA) {
720 /* rgb unchanged */
721 colorComb.Function = GR_COMBINE_FUNCTION_LOCAL;
722 colorComb.Factor = GR_COMBINE_FACTOR_NONE;
723 colorComb.Other = GR_COMBINE_OTHER_NONE;
724 }
725 else {
726 /* sum of texel and fragment rgb */
727 colorComb.Function = GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL;
728 colorComb.Factor = GR_COMBINE_FACTOR_ONE;
729 colorComb.Other = GR_COMBINE_OTHER_TEXTURE;
730 }
731 break;
732 default:
733 if (TDFX_DEBUG & VERBOSE_DRIVER) {
734 fprintf(stderr, "fxSetupTextureSingleTMU_NoLock: %x Texture.EnvMode not yet supported\n",
735 ctx->Texture.Unit[textureset].EnvMode);
736 }
737 return;
738 }
739
740 grAlphaCombine(alphaComb.Function,
741 alphaComb.Factor,
742 alphaComb.Local,
743 alphaComb.Other,
744 alphaComb.Invert);
745 grColorCombine(colorComb.Function,
746 colorComb.Factor,
747 colorComb.Local,
748 colorComb.Other,
749 colorComb.Invert);
750 }
751
752 #if 00
753 static void
754 fxSetupTextureSingleTMU(GLcontext * ctx, GLuint textureset)
755 {
756 BEGIN_BOARD_LOCK();
757 fxSetupTextureSingleTMU_NoLock(ctx, textureset);
758 END_BOARD_LOCK();
759 }
760 #endif
761
762
763 /************************* Double Texture Set ***************************/
764
765 static void
766 fxSetupDoubleTMU_NoLock(fxMesaContext fxMesa,
767 struct gl_texture_object *tObj0,
768 struct gl_texture_object *tObj1)
769 {
770 #define T0_NOT_IN_TMU 0x01
771 #define T1_NOT_IN_TMU 0x02
772 #define T0_IN_TMU0 0x04
773 #define T1_IN_TMU0 0x08
774 #define T0_IN_TMU1 0x10
775 #define T1_IN_TMU1 0x20
776
777 tfxTexInfo *ti0 = fxTMGetTexInfo(tObj0);
778 tfxTexInfo *ti1 = fxTMGetTexInfo(tObj1);
779 GLuint tstate = 0;
780 int tmu0 = 0, tmu1 = 1;
781
782 if (TDFX_DEBUG & VERBOSE_DRIVER) {
783 fprintf(stderr, "fxSetupDoubleTMU_NoLock(...)\n");
784 }
785
786 /* We shouldn't need to do this. There is something wrong with
787 mutlitexturing when the TMUs are swapped. So, we're forcing
788 them to always be loaded correctly. !!! */
789 if (ti0->whichTMU == FX_TMU1)
790 fxTMMoveOutTM_NoLock(fxMesa, tObj0);
791 if (ti1->whichTMU == FX_TMU0)
792 fxTMMoveOutTM_NoLock(fxMesa, tObj1);
793
794 if (ti0->isInTM) {
795 switch (ti0->whichTMU) {
796 case FX_TMU0:
797 tstate |= T0_IN_TMU0;
798 break;
799 case FX_TMU1:
800 tstate |= T0_IN_TMU1;
801 break;
802 case FX_TMU_BOTH:
803 tstate |= T0_IN_TMU0 | T0_IN_TMU1;
804 break;
805 case FX_TMU_SPLIT:
806 tstate |= T0_NOT_IN_TMU;
807 break;
808 }
809 }
810 else
811 tstate |= T0_NOT_IN_TMU;
812
813 if (ti1->isInTM) {
814 switch (ti1->whichTMU) {
815 case FX_TMU0:
816 tstate |= T1_IN_TMU0;
817 break;
818 case FX_TMU1:
819 tstate |= T1_IN_TMU1;
820 break;
821 case FX_TMU_BOTH:
822 tstate |= T1_IN_TMU0 | T1_IN_TMU1;
823 break;
824 case FX_TMU_SPLIT:
825 tstate |= T1_NOT_IN_TMU;
826 break;
827 }
828 }
829 else
830 tstate |= T1_NOT_IN_TMU;
831
832 ti0->lastTimeUsed = fxMesa->texBindNumber;
833 ti1->lastTimeUsed = fxMesa->texBindNumber;
834
835 /* Move texture maps into TMUs */
836
837 if (!(((tstate & T0_IN_TMU0) && (tstate & T1_IN_TMU1)) ||
838 ((tstate & T0_IN_TMU1) && (tstate & T1_IN_TMU0)))) {
839 if (tObj0 == tObj1)
840 fxTMMoveInTM_NoLock(fxMesa, tObj1, FX_TMU_BOTH);
841 else {
842 /* Find the minimal way to correct the situation */
843 if ((tstate & T0_IN_TMU0) || (tstate & T1_IN_TMU1)) {
844 /* We have one in the standard order, setup the other */
845 if (tstate & T0_IN_TMU0) { /* T0 is in TMU0, put T1 in TMU1 */
846 fxTMMoveInTM_NoLock(fxMesa, tObj1, FX_TMU1);
847 }
848 else {
849 fxTMMoveInTM_NoLock(fxMesa, tObj0, FX_TMU0);
850 }
851 /* tmu0 and tmu1 are setup */
852 }
853 else if ((tstate & T0_IN_TMU1) || (tstate & T1_IN_TMU0)) {
854 /* we have one in the reverse order, setup the other */
855 if (tstate & T1_IN_TMU0) { /* T1 is in TMU0, put T0 in TMU1 */
856 fxTMMoveInTM_NoLock(fxMesa, tObj0, FX_TMU1);
857 }
858 else {
859 fxTMMoveInTM_NoLock(fxMesa, tObj1, FX_TMU0);
860 }
861 tmu0 = 1;
862 tmu1 = 0;
863 }
864 else { /* Nothing is loaded */
865 fxTMMoveInTM_NoLock(fxMesa, tObj0, FX_TMU0);
866 fxTMMoveInTM_NoLock(fxMesa, tObj1, FX_TMU1);
867 /* tmu0 and tmu1 are setup */
868 }
869 }
870 }
871
872 /* [dBorca] Hack alert:
873 * we put these in reverse order, so that if we can't
874 * do _REAL_ pointcast, the TMU0 table gets broadcasted
875 */
876 if (!fxMesa->haveGlobalPaletteTexture) {
877 /* pointcast */
878 if (ti1->info.format == GR_TEXFMT_P_8) {
879 if (TDFX_DEBUG & VERBOSE_DRIVER) {
880 fprintf(stderr, "fxSetupDoubleTMU_NoLock: uploading texture palette for TMU1\n");
881 }
882 fxMesa->Glide.grTexDownloadTableExt(ti1->whichTMU, ti1->paltype, &(ti1->palette));
883 }
884 if (ti0->info.format == GR_TEXFMT_P_8) {
885 if (TDFX_DEBUG & VERBOSE_DRIVER) {
886 fprintf(stderr, "fxSetupDoubleTMU_NoLock: uploading texture palette for TMU0\n");
887 }
888 fxMesa->Glide.grTexDownloadTableExt(ti0->whichTMU, ti0->paltype, &(ti0->palette));
889 }
890 }
891 #if FX_TC_NCC
892 /* pointcast */
893 if ((ti1->info.format == GR_TEXFMT_AYIQ_8422) ||
894 (ti1->info.format == GR_TEXFMT_YIQ_422)) {
895 if (TDFX_DEBUG & VERBOSE_DRIVER) {
896 fprintf(stderr, "fxSetupDoubleTMU_NoLock: uploading NCC0 table for TMU1\n");
897 }
898 fxMesa->Glide.grTexDownloadTableExt(ti1->whichTMU, GR_TEXTABLE_NCC0, &(ti1->palette));
899 }
900 if ((ti0->info.format == GR_TEXFMT_AYIQ_8422) ||
901 (ti0->info.format == GR_TEXFMT_YIQ_422)) {
902 if (TDFX_DEBUG & VERBOSE_DRIVER) {
903 fprintf(stderr, "fxSetupDoubleTMU_NoLock: uploading NCC0 table for TMU0\n");
904 }
905 fxMesa->Glide.grTexDownloadTableExt(ti0->whichTMU, GR_TEXTABLE_NCC0, &(ti0->palette));
906 }
907 #endif
908
909 grTexSource(tmu0, ti0->tm[tmu0]->startAddr,
910 GR_MIPMAPLEVELMASK_BOTH, &(ti0->info));
911 grTexClampMode(tmu0, ti0->sClamp, ti0->tClamp);
912 grTexFilterMode(tmu0, ti0->minFilt, ti0->maxFilt);
913 grTexMipMapMode(tmu0, ti0->mmMode, FXFALSE);
914
915 grTexSource(tmu1, ti1->tm[tmu1]->startAddr,
916 GR_MIPMAPLEVELMASK_BOTH, &(ti1->info));
917 grTexClampMode(tmu1, ti1->sClamp, ti1->tClamp);
918 grTexFilterMode(tmu1, ti1->minFilt, ti1->maxFilt);
919 grTexMipMapMode(tmu1, ti1->mmMode, FXFALSE);
920
921 #undef T0_NOT_IN_TMU
922 #undef T1_NOT_IN_TMU
923 #undef T0_IN_TMU0
924 #undef T1_IN_TMU0
925 #undef T0_IN_TMU1
926 #undef T1_IN_TMU1
927 }
928
929 static void
930 fxSetupTextureDoubleTMU_NoLock(GLcontext * ctx)
931 {
932 fxMesaContext fxMesa = FX_CONTEXT(ctx);
933 struct tdfx_combine alphaComb, colorComb;
934 struct tdfx_texcombine tex0, tex1;
935 GrCombineLocal_t localc, locala;
936 tfxTexInfo *ti0, *ti1;
937 struct gl_texture_object *tObj0 = ctx->Texture.Unit[1]._Current;
938 struct gl_texture_object *tObj1 = ctx->Texture.Unit[0]._Current;
939 GLuint envmode, ifmt, unitsmode;
940 int tmu0 = 0, tmu1 = 1;
941
942 if (TDFX_DEBUG & VERBOSE_DRIVER) {
943 fprintf(stderr, "fxSetupTextureDoubleTMU_NoLock(...)\n");
944 }
945
946 ti0 = fxTMGetTexInfo(tObj0);
947 fxTexValidate(ctx, tObj0);
948
949 ti1 = fxTMGetTexInfo(tObj1);
950 fxTexValidate(ctx, tObj1);
951
952 fxSetupDoubleTMU_NoLock(fxMesa, tObj0, tObj1);
953
954 unitsmode = fxGetTexSetConfiguration(ctx, tObj0, tObj1);
955
956 /* if(fxMesa->lastUnitsMode==unitsmode) */
957 /* return; */
958
959 fxMesa->lastUnitsMode = unitsmode;
960
961 fxMesa->stw_hint_state |= GR_STWHINT_ST_DIFF_TMU1;
962 FX_grHints_NoLock(GR_HINT_STWHINT, fxMesa->stw_hint_state);
963
964 envmode = unitsmode & FX_UM_E_ENVMODE;
965 ifmt = unitsmode & FX_UM_E_IFMT;
966
967 if (unitsmode & FX_UM_ALPHA_ITERATED)
968 locala = GR_COMBINE_LOCAL_ITERATED;
969 else
970 locala = GR_COMBINE_LOCAL_CONSTANT;
971
972 if (unitsmode & FX_UM_COLOR_ITERATED)
973 localc = GR_COMBINE_LOCAL_ITERATED;
974 else
975 localc = GR_COMBINE_LOCAL_CONSTANT;
976
977
978 if (TDFX_DEBUG & (VERBOSE_DRIVER | VERBOSE_TEXTURE))
979 fprintf(stderr, "fxSetupTextureDoubleTMU_NoLock: envmode is %s/%s\n",
980 _mesa_lookup_enum_by_nr(ctx->Texture.Unit[0].EnvMode),
981 _mesa_lookup_enum_by_nr(ctx->Texture.Unit[1].EnvMode));
982
983
984 if ((ti0->whichTMU == FX_TMU1) || (ti1->whichTMU == FX_TMU0)) {
985 tmu0 = 1;
986 tmu1 = 0;
987 }
988 fxMesa->tmuSrc = FX_TMU_BOTH;
989
990 tex0.InvertRGB = FXFALSE;
991 tex0.InvertAlpha = FXFALSE;
992 tex1.InvertRGB = FXFALSE;
993 tex1.InvertAlpha = FXFALSE;
994 alphaComb.Local = locala;
995 alphaComb.Invert = FXFALSE;
996 colorComb.Local = localc;
997 colorComb.Invert = FXFALSE;
998
999 switch (envmode) {
1000 case (FX_UM_E0_MODULATE | FX_UM_E1_MODULATE):
1001 {
1002 GLboolean isalpha[FX_NUM_TMU];
1003
1004 isalpha[tmu0] = (ti0->baseLevelInternalFormat == GL_ALPHA);
1005 isalpha[tmu1] = (ti1->baseLevelInternalFormat == GL_ALPHA);
1006
1007 if (isalpha[FX_TMU1]) {
1008 tex1.FunctionRGB = GR_COMBINE_FUNCTION_ZERO;
1009 tex1.FactorRGB = GR_COMBINE_FACTOR_NONE;
1010 tex1.FunctionAlpha = GR_COMBINE_FUNCTION_LOCAL;
1011 tex1.FactorAlpha = GR_COMBINE_FACTOR_NONE;
1012 tex1.InvertRGB = FXTRUE;
1013 } else {
1014 tex1.FunctionRGB = GR_COMBINE_FUNCTION_LOCAL;
1015 tex1.FactorRGB = GR_COMBINE_FACTOR_NONE;
1016 tex1.FunctionAlpha = GR_COMBINE_FUNCTION_LOCAL;
1017 tex1.FactorAlpha = GR_COMBINE_FACTOR_NONE;
1018 }
1019
1020 if (isalpha[FX_TMU0]) {
1021 tex0.FunctionRGB = GR_COMBINE_FUNCTION_BLEND_OTHER;
1022 tex0.FactorRGB = GR_COMBINE_FACTOR_ONE;
1023 tex0.FunctionAlpha = GR_COMBINE_FUNCTION_BLEND_OTHER;
1024 tex0.FactorAlpha = GR_COMBINE_FACTOR_LOCAL;
1025 } else {
1026 tex0.FunctionRGB = GR_COMBINE_FUNCTION_BLEND_OTHER;
1027 tex0.FactorRGB = GR_COMBINE_FACTOR_LOCAL;
1028 tex0.FunctionAlpha = GR_COMBINE_FUNCTION_BLEND_OTHER;
1029 tex0.FactorAlpha = GR_COMBINE_FACTOR_LOCAL;
1030 }
1031
1032 colorComb.Function = GR_COMBINE_FUNCTION_SCALE_OTHER;
1033 colorComb.Factor = GR_COMBINE_FACTOR_LOCAL;
1034 colorComb.Other = GR_COMBINE_OTHER_TEXTURE;
1035
1036 alphaComb.Function = GR_COMBINE_FUNCTION_SCALE_OTHER;
1037 alphaComb.Factor = GR_COMBINE_FACTOR_LOCAL;
1038 alphaComb.Other = GR_COMBINE_OTHER_TEXTURE;
1039 break;
1040 }
1041 case (FX_UM_E0_REPLACE | FX_UM_E1_BLEND): /* Only for GLQuake */
1042 if (tmu0 == FX_TMU1) {
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 tex1.InvertRGB = FXTRUE;
1048
1049 tex0.FunctionRGB = GR_COMBINE_FUNCTION_BLEND_OTHER;
1050 tex0.FactorRGB = GR_COMBINE_FACTOR_LOCAL;
1051 tex0.FunctionAlpha = GR_COMBINE_FUNCTION_BLEND_OTHER;
1052 tex0.FactorAlpha = GR_COMBINE_FACTOR_LOCAL;
1053 }
1054 else {
1055 tex1.FunctionRGB = GR_COMBINE_FUNCTION_LOCAL;
1056 tex1.FactorRGB = GR_COMBINE_FACTOR_NONE;
1057 tex1.FunctionAlpha = GR_COMBINE_FUNCTION_LOCAL;
1058 tex1.FactorAlpha = GR_COMBINE_FACTOR_NONE;
1059
1060 tex0.FunctionRGB = GR_COMBINE_FUNCTION_BLEND_OTHER;
1061 tex0.FactorRGB = GR_COMBINE_FACTOR_ONE_MINUS_LOCAL;
1062 tex0.FunctionAlpha = GR_COMBINE_FUNCTION_BLEND_OTHER;
1063 tex0.FactorAlpha = GR_COMBINE_FACTOR_ONE_MINUS_LOCAL;
1064 }
1065
1066 alphaComb.Function = GR_COMBINE_FUNCTION_LOCAL;
1067 alphaComb.Factor = GR_COMBINE_FACTOR_NONE;
1068 alphaComb.Other = GR_COMBINE_OTHER_NONE;
1069
1070 colorComb.Function = GR_COMBINE_FUNCTION_SCALE_OTHER;
1071 colorComb.Factor = GR_COMBINE_FACTOR_ONE;
1072 colorComb.Other = GR_COMBINE_OTHER_TEXTURE;
1073 break;
1074 case (FX_UM_E0_REPLACE | FX_UM_E1_MODULATE): /* Quake 2 and 3 */
1075 if (tmu1 == FX_TMU1) {
1076 tex1.FunctionRGB = GR_COMBINE_FUNCTION_LOCAL;
1077 tex1.FactorRGB = GR_COMBINE_FACTOR_NONE;
1078 tex1.FunctionAlpha = GR_COMBINE_FUNCTION_ZERO;
1079 tex1.FactorAlpha = GR_COMBINE_FACTOR_NONE;
1080 tex1.InvertAlpha = FXTRUE;
1081
1082 tex0.FunctionRGB = GR_COMBINE_FUNCTION_BLEND_OTHER;
1083 tex0.FactorRGB = GR_COMBINE_FACTOR_LOCAL;
1084 tex0.FunctionAlpha = GR_COMBINE_FUNCTION_BLEND_OTHER;
1085 tex0.FactorAlpha = GR_COMBINE_FACTOR_LOCAL;
1086 }
1087 else {
1088 tex1.FunctionRGB = GR_COMBINE_FUNCTION_LOCAL;
1089 tex1.FactorRGB = GR_COMBINE_FACTOR_NONE;
1090 tex1.FunctionAlpha = GR_COMBINE_FUNCTION_LOCAL;
1091 tex1.FactorAlpha = GR_COMBINE_FACTOR_NONE;
1092
1093 tex0.FunctionRGB = GR_COMBINE_FUNCTION_BLEND_OTHER;
1094 tex0.FactorRGB = GR_COMBINE_FACTOR_LOCAL;
1095 tex0.FunctionAlpha = GR_COMBINE_FUNCTION_BLEND_OTHER;
1096 tex0.FactorAlpha = GR_COMBINE_FACTOR_ONE;
1097 }
1098
1099 if (ti0->baseLevelInternalFormat == GL_RGB) {
1100 alphaComb.Function = GR_COMBINE_FUNCTION_LOCAL;
1101 alphaComb.Factor = GR_COMBINE_FACTOR_NONE;
1102 alphaComb.Other = GR_COMBINE_OTHER_NONE;
1103 } else {
1104 alphaComb.Function = GR_COMBINE_FUNCTION_SCALE_OTHER;
1105 alphaComb.Factor = GR_COMBINE_FACTOR_ONE;
1106 alphaComb.Other = GR_COMBINE_OTHER_NONE;
1107 }
1108
1109 colorComb.Function = GR_COMBINE_FUNCTION_SCALE_OTHER;
1110 colorComb.Factor = GR_COMBINE_FACTOR_ONE;
1111 colorComb.Other = GR_COMBINE_OTHER_TEXTURE;
1112 break;
1113
1114
1115 case (FX_UM_E0_MODULATE | FX_UM_E1_ADD): /* Quake 3 Sky */
1116 {
1117 GLboolean isalpha[FX_NUM_TMU];
1118
1119 isalpha[tmu0] = (ti0->baseLevelInternalFormat == GL_ALPHA);
1120 isalpha[tmu1] = (ti1->baseLevelInternalFormat == GL_ALPHA);
1121
1122 if (isalpha[FX_TMU1]) {
1123 tex1.FunctionRGB = GR_COMBINE_FUNCTION_ZERO;
1124 tex1.FactorRGB = GR_COMBINE_FACTOR_NONE;
1125 tex1.FunctionAlpha = GR_COMBINE_FUNCTION_LOCAL;
1126 tex1.FactorAlpha = GR_COMBINE_FACTOR_NONE;
1127 tex1.InvertRGB = FXTRUE;
1128 } else {
1129 tex1.FunctionRGB = GR_COMBINE_FUNCTION_LOCAL;
1130 tex1.FactorRGB = GR_COMBINE_FACTOR_NONE;
1131 tex1.FunctionAlpha = GR_COMBINE_FUNCTION_LOCAL;
1132 tex1.FactorAlpha = GR_COMBINE_FACTOR_NONE;
1133 }
1134
1135 if (isalpha[FX_TMU0]) {
1136 tex0.FunctionRGB = GR_COMBINE_FUNCTION_SCALE_OTHER;
1137 tex0.FactorRGB = GR_COMBINE_FACTOR_ONE;
1138 tex0.FunctionAlpha = GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL;
1139 tex0.FactorAlpha = GR_COMBINE_FACTOR_ONE;
1140 } else {
1141 tex0.FunctionRGB = GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL;
1142 tex0.FactorRGB = GR_COMBINE_FACTOR_ONE;
1143 tex0.FunctionAlpha = GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL;
1144 tex0.FactorAlpha = GR_COMBINE_FACTOR_ONE;
1145 }
1146
1147 colorComb.Function = GR_COMBINE_FUNCTION_SCALE_OTHER;
1148 colorComb.Factor = GR_COMBINE_FACTOR_LOCAL;
1149 colorComb.Other = GR_COMBINE_OTHER_TEXTURE;
1150
1151 alphaComb.Function = GR_COMBINE_FUNCTION_SCALE_OTHER;
1152 alphaComb.Factor = GR_COMBINE_FACTOR_LOCAL;
1153 alphaComb.Other = GR_COMBINE_OTHER_TEXTURE;
1154 break;
1155 }
1156
1157 case (FX_UM_E0_REPLACE | FX_UM_E1_ADD): /* Vulpine Sky */
1158 {
1159 GLboolean isalpha[FX_NUM_TMU];
1160
1161 isalpha[tmu0] = (ti0->baseLevelInternalFormat == GL_ALPHA);
1162 isalpha[tmu1] = (ti1->baseLevelInternalFormat == GL_ALPHA);
1163
1164 if (isalpha[FX_TMU1]) {
1165 tex1.FunctionRGB = GR_COMBINE_FUNCTION_ZERO;
1166 tex1.FactorRGB = GR_COMBINE_FACTOR_NONE;
1167 tex1.FunctionAlpha = GR_COMBINE_FUNCTION_LOCAL;
1168 tex1.FactorAlpha = GR_COMBINE_FACTOR_NONE;
1169 tex1.InvertRGB = FXTRUE;
1170 } else {
1171 tex1.FunctionRGB = GR_COMBINE_FUNCTION_LOCAL;
1172 tex1.FactorRGB = GR_COMBINE_FACTOR_NONE;
1173 tex1.FunctionAlpha = GR_COMBINE_FUNCTION_LOCAL;
1174 tex1.FactorAlpha = GR_COMBINE_FACTOR_NONE;
1175 }
1176
1177 if (isalpha[FX_TMU0]) {
1178 tex0.FunctionRGB = GR_COMBINE_FUNCTION_SCALE_OTHER;
1179 tex0.FactorRGB = GR_COMBINE_FACTOR_ONE;
1180 tex0.FunctionAlpha = GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL;
1181 tex0.FactorAlpha = GR_COMBINE_FACTOR_ONE;
1182 } else {
1183 tex0.FunctionRGB = GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL;
1184 tex0.FactorRGB = GR_COMBINE_FACTOR_ONE;
1185 tex0.FunctionAlpha = GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL;
1186 tex0.FactorAlpha = GR_COMBINE_FACTOR_ONE;
1187 }
1188
1189 colorComb.Function = GR_COMBINE_FUNCTION_SCALE_OTHER;
1190 colorComb.Factor = GR_COMBINE_FACTOR_ONE;
1191 colorComb.Other = GR_COMBINE_OTHER_TEXTURE;
1192
1193 alphaComb.Function = GR_COMBINE_FUNCTION_SCALE_OTHER;
1194 alphaComb.Factor = GR_COMBINE_FACTOR_ONE;
1195 alphaComb.Other = GR_COMBINE_OTHER_TEXTURE;
1196 break;
1197 }
1198
1199 case (FX_UM_E0_MODULATE | FX_UM_E1_REPLACE): /* Homeworld2 */
1200 {
1201 tex1.FunctionRGB = GR_COMBINE_FUNCTION_ZERO;
1202 tex1.FactorRGB = GR_COMBINE_FACTOR_NONE;
1203 tex1.FunctionAlpha = GR_COMBINE_FUNCTION_ZERO;
1204 tex1.FactorAlpha = GR_COMBINE_FACTOR_NONE;
1205
1206 tex0.FunctionRGB = GR_COMBINE_FUNCTION_LOCAL;
1207 tex0.FactorRGB = GR_COMBINE_FACTOR_NONE;
1208 tex0.FunctionAlpha = GR_COMBINE_FUNCTION_LOCAL;
1209 tex0.FactorAlpha = GR_COMBINE_FACTOR_NONE;
1210
1211 if (ifmt & (FX_UM_E0_RGB | FX_UM_E0_LUMINANCE)) {
1212 alphaComb.Function = GR_COMBINE_FUNCTION_LOCAL;
1213 alphaComb.Factor = GR_COMBINE_FACTOR_NONE;
1214 alphaComb.Other = GR_COMBINE_OTHER_NONE;
1215 } else {
1216 alphaComb.Function = GR_COMBINE_FUNCTION_SCALE_OTHER;
1217 alphaComb.Factor = GR_COMBINE_FACTOR_ONE;
1218 alphaComb.Other = GR_COMBINE_OTHER_TEXTURE;
1219 }
1220
1221 if (ifmt & FX_UM_E0_ALPHA) {
1222 colorComb.Function = GR_COMBINE_FUNCTION_LOCAL;
1223 colorComb.Factor = GR_COMBINE_FACTOR_NONE;
1224 colorComb.Other = GR_COMBINE_OTHER_NONE;
1225 } else {
1226 colorComb.Function = GR_COMBINE_FUNCTION_SCALE_OTHER;
1227 colorComb.Factor = GR_COMBINE_FACTOR_ONE;
1228 colorComb.Other = GR_COMBINE_OTHER_TEXTURE;
1229 }
1230 break;
1231 }
1232 default:
1233 fprintf(stderr, "fxSetupTextureDoubleTMU_NoLock: Unexpected dual texture mode encountered\n");
1234 return;
1235 }
1236
1237 grAlphaCombine(alphaComb.Function,
1238 alphaComb.Factor,
1239 alphaComb.Local,
1240 alphaComb.Other,
1241 alphaComb.Invert);
1242 grColorCombine(colorComb.Function,
1243 colorComb.Factor,
1244 colorComb.Local,
1245 colorComb.Other,
1246 colorComb.Invert);
1247 grTexCombine(GR_TMU0,
1248 tex0.FunctionRGB,
1249 tex0.FactorRGB,
1250 tex0.FunctionAlpha,
1251 tex0.FactorAlpha,
1252 tex0.InvertRGB,
1253 tex0.InvertAlpha);
1254 grTexCombine(GR_TMU1,
1255 tex1.FunctionRGB,
1256 tex1.FactorRGB,
1257 tex1.FunctionAlpha,
1258 tex1.FactorAlpha,
1259 tex1.InvertRGB,
1260 tex1.InvertAlpha);
1261 }
1262
1263 /************************* No Texture ***************************/
1264
1265 static void
1266 fxSetupTextureNone_NoLock(GLcontext * ctx)
1267 {
1268 fxMesaContext fxMesa = FX_CONTEXT(ctx);
1269 GrCombineLocal_t localc, locala;
1270
1271 if (TDFX_DEBUG & VERBOSE_DRIVER) {
1272 fprintf(stderr, "fxSetupTextureNone_NoLock(...)\n");
1273 }
1274
1275 if ((ctx->Light.ShadeModel == GL_SMOOTH) || 1 ||
1276 (ctx->Point.SmoothFlag) ||
1277 (ctx->Line.SmoothFlag) ||
1278 (ctx->Polygon.SmoothFlag)) locala = GR_COMBINE_LOCAL_ITERATED;
1279 else
1280 locala = GR_COMBINE_LOCAL_CONSTANT;
1281
1282 if (ctx->Light.ShadeModel == GL_SMOOTH || 1)
1283 localc = GR_COMBINE_LOCAL_ITERATED;
1284 else
1285 localc = GR_COMBINE_LOCAL_CONSTANT;
1286
1287 grAlphaCombine(GR_COMBINE_FUNCTION_LOCAL,
1288 GR_COMBINE_FACTOR_NONE,
1289 locala,
1290 GR_COMBINE_OTHER_NONE,
1291 FXFALSE);
1292
1293 grColorCombine(GR_COMBINE_FUNCTION_LOCAL,
1294 GR_COMBINE_FACTOR_NONE,
1295 localc,
1296 GR_COMBINE_OTHER_NONE,
1297 FXFALSE);
1298
1299 fxMesa->lastUnitsMode = FX_UM_NONE;
1300 }
1301
1302 #include "fxsetup.h"
1303
1304 /************************************************************************/
1305 /************************** Texture Mode SetUp **************************/
1306 /************************************************************************/
1307
1308 static void
1309 fxSetupTexture_NoLock(GLcontext * ctx)
1310 {
1311 fxMesaContext fxMesa = FX_CONTEXT(ctx);
1312
1313 if (TDFX_DEBUG & VERBOSE_DRIVER) {
1314 fprintf(stderr, "fxSetupTexture_NoLock(...)\n");
1315 }
1316
1317 if (fxMesa->HaveCmbExt) {
1318 /* Texture Combine, Color Combine and Alpha Combine. */
1319 if ((ctx->Texture.Unit[0]._ReallyEnabled & (TEXTURE_1D_BIT|TEXTURE_2D_BIT)) &&
1320 (ctx->Texture.Unit[1]._ReallyEnabled & (TEXTURE_1D_BIT|TEXTURE_2D_BIT)) &&
1321 fxMesa->haveTwoTMUs) {
1322 fxSetupTextureDoubleTMUNapalm_NoLock(ctx);
1323 }
1324 else if (ctx->Texture.Unit[0]._ReallyEnabled & (TEXTURE_1D_BIT|TEXTURE_2D_BIT)) {
1325 fxSetupTextureSingleTMUNapalm_NoLock(ctx, 0);
1326 }
1327 else if (ctx->Texture.Unit[1]._ReallyEnabled & (TEXTURE_1D_BIT|TEXTURE_2D_BIT)) {
1328 fxSetupTextureSingleTMUNapalm_NoLock(ctx, 1);
1329 }
1330 else {
1331 fxSetupTextureNoneNapalm_NoLock(ctx);
1332 }
1333 } else {
1334 /* Texture Combine, Color Combine and Alpha Combine. */
1335 if ((ctx->Texture.Unit[0]._ReallyEnabled & (TEXTURE_1D_BIT|TEXTURE_2D_BIT)) &&
1336 (ctx->Texture.Unit[1]._ReallyEnabled & (TEXTURE_1D_BIT|TEXTURE_2D_BIT)) &&
1337 fxMesa->haveTwoTMUs) {
1338 fxSetupTextureDoubleTMU_NoLock(ctx);
1339 }
1340 else if (ctx->Texture.Unit[0]._ReallyEnabled & (TEXTURE_1D_BIT|TEXTURE_2D_BIT)) {
1341 fxSetupTextureSingleTMU_NoLock(ctx, 0);
1342 }
1343 else if (ctx->Texture.Unit[1]._ReallyEnabled & (TEXTURE_1D_BIT|TEXTURE_2D_BIT)) {
1344 fxSetupTextureSingleTMU_NoLock(ctx, 1);
1345 }
1346 else {
1347 fxSetupTextureNone_NoLock(ctx);
1348 }
1349 }
1350 }
1351
1352 void
1353 fxSetupTexture(GLcontext * ctx)
1354 {
1355 BEGIN_BOARD_LOCK();
1356 fxSetupTexture_NoLock(ctx);
1357 END_BOARD_LOCK();
1358 }
1359
1360 /************************************************************************/
1361 /**************************** Blend SetUp *******************************/
1362 /************************************************************************/
1363
1364 void
1365 fxDDBlendFuncSeparate(GLcontext * ctx, GLenum sfactor, GLenum dfactor, GLenum asfactor, GLenum adfactor)
1366 {
1367 fxMesaContext fxMesa = FX_CONTEXT(ctx);
1368 tfxUnitsState *us = &fxMesa->unitsState;
1369 GLboolean isNapalm = (fxMesa->type >= GR_SSTTYPE_Voodoo4);
1370 GLboolean have32bpp = (fxMesa->colDepth == 32);
1371 GLboolean haveAlpha = fxMesa->haveHwAlpha;
1372 GrAlphaBlendFnc_t sfact, dfact, asfact, adfact;
1373
1374 /*
1375 * 15/16 BPP alpha channel alpha blending modes
1376 * 0x0 AZERO Zero
1377 * 0x4 AONE One
1378 *
1379 * 32 BPP alpha channel alpha blending modes
1380 * 0x0 AZERO Zero
1381 * 0x1 ASRC_ALPHA Source alpha
1382 * 0x3 ADST_ALPHA Destination alpha
1383 * 0x4 AONE One
1384 * 0x5 AOMSRC_ALPHA 1 - Source alpha
1385 * 0x7 AOMDST_ALPHA 1 - Destination alpha
1386 *
1387 * If we don't have HW alpha buffer:
1388 * DST_ALPHA == 1
1389 * ONE_MINUS_DST_ALPHA == 0
1390 * Unsupported modes are:
1391 * 1 if used as src blending factor
1392 * 0 if used as dst blending factor
1393 */
1394
1395 switch (sfactor) {
1396 case GL_ZERO:
1397 sfact = GR_BLEND_ZERO;
1398 break;
1399 case GL_ONE:
1400 sfact = GR_BLEND_ONE;
1401 break;
1402 case GL_DST_COLOR:
1403 sfact = GR_BLEND_DST_COLOR;
1404 break;
1405 case GL_ONE_MINUS_DST_COLOR:
1406 sfact = GR_BLEND_ONE_MINUS_DST_COLOR;
1407 break;
1408 case GL_SRC_ALPHA:
1409 sfact = GR_BLEND_SRC_ALPHA;
1410 break;
1411 case GL_ONE_MINUS_SRC_ALPHA:
1412 sfact = GR_BLEND_ONE_MINUS_SRC_ALPHA;
1413 break;
1414 case GL_DST_ALPHA:
1415 sfact = haveAlpha ? GR_BLEND_DST_ALPHA : GR_BLEND_ONE/*bad*/;
1416 break;
1417 case GL_ONE_MINUS_DST_ALPHA:
1418 sfact = haveAlpha ? GR_BLEND_ONE_MINUS_DST_ALPHA : GR_BLEND_ZERO/*bad*/;
1419 break;
1420 case GL_SRC_ALPHA_SATURATE:
1421 sfact = GR_BLEND_ALPHA_SATURATE;
1422 break;
1423 case GL_SRC_COLOR:
1424 if (isNapalm) {
1425 sfact = GR_BLEND_SAME_COLOR_EXT;
1426 break;
1427 }
1428 case GL_ONE_MINUS_SRC_COLOR:
1429 if (isNapalm) {
1430 sfact = GR_BLEND_ONE_MINUS_SAME_COLOR_EXT;
1431 break;
1432 }
1433 default:
1434 sfact = GR_BLEND_ONE;
1435 break;
1436 }
1437
1438 switch (asfactor) {
1439 case GL_ZERO:
1440 asfact = GR_BLEND_ZERO;
1441 break;
1442 case GL_ONE:
1443 asfact = GR_BLEND_ONE;
1444 break;
1445 case GL_SRC_COLOR:
1446 case GL_SRC_ALPHA:
1447 asfact = have32bpp ? GR_BLEND_SRC_ALPHA : GR_BLEND_ONE/*bad*/;
1448 break;
1449 case GL_ONE_MINUS_SRC_COLOR:
1450 case GL_ONE_MINUS_SRC_ALPHA:
1451 asfact = have32bpp ? GR_BLEND_ONE_MINUS_SRC_ALPHA : GR_BLEND_ONE/*bad*/;
1452 break;
1453 case GL_DST_COLOR:
1454 case GL_DST_ALPHA:
1455 asfact = (have32bpp && haveAlpha) ? GR_BLEND_DST_ALPHA : GR_BLEND_ONE/*bad*/;
1456 break;
1457 case GL_ONE_MINUS_DST_COLOR:
1458 case GL_ONE_MINUS_DST_ALPHA:
1459 asfact = (have32bpp && haveAlpha) ? GR_BLEND_ONE_MINUS_DST_ALPHA : GR_BLEND_ZERO/*bad*/;
1460 break;
1461 case GL_SRC_ALPHA_SATURATE:
1462 asfact = GR_BLEND_ONE;
1463 break;
1464 default:
1465 asfact = GR_BLEND_ONE;
1466 break;
1467 }
1468
1469 switch (dfactor) {
1470 case GL_ZERO:
1471 dfact = GR_BLEND_ZERO;
1472 break;
1473 case GL_ONE:
1474 dfact = GR_BLEND_ONE;
1475 break;
1476 case GL_SRC_COLOR:
1477 dfact = GR_BLEND_SRC_COLOR;
1478 break;
1479 case GL_ONE_MINUS_SRC_COLOR:
1480 dfact = GR_BLEND_ONE_MINUS_SRC_COLOR;
1481 break;
1482 case GL_SRC_ALPHA:
1483 dfact = GR_BLEND_SRC_ALPHA;
1484 break;
1485 case GL_ONE_MINUS_SRC_ALPHA:
1486 dfact = GR_BLEND_ONE_MINUS_SRC_ALPHA;
1487 break;
1488 case GL_DST_ALPHA:
1489 dfact = haveAlpha ? GR_BLEND_DST_ALPHA : GR_BLEND_ONE/*bad*/;
1490 break;
1491 case GL_ONE_MINUS_DST_ALPHA:
1492 dfact = haveAlpha ? GR_BLEND_ONE_MINUS_DST_ALPHA : GR_BLEND_ZERO/*bad*/;
1493 break;
1494 case GL_DST_COLOR:
1495 if (isNapalm) {
1496 dfact = GR_BLEND_SAME_COLOR_EXT;
1497 break;
1498 }
1499 case GL_ONE_MINUS_DST_COLOR:
1500 if (isNapalm) {
1501 dfact = GR_BLEND_ONE_MINUS_SAME_COLOR_EXT;
1502 break;
1503 }
1504 default:
1505 dfact = GR_BLEND_ZERO;
1506 break;
1507 }
1508
1509 switch (adfactor) {
1510 case GL_ZERO:
1511 adfact = GR_BLEND_ZERO;
1512 break;
1513 case GL_ONE:
1514 adfact = GR_BLEND_ONE;
1515 break;
1516 case GL_SRC_COLOR:
1517 case GL_SRC_ALPHA:
1518 adfact = have32bpp ? GR_BLEND_SRC_ALPHA : GR_BLEND_ZERO/*bad*/;
1519 break;
1520 case GL_ONE_MINUS_SRC_COLOR:
1521 case GL_ONE_MINUS_SRC_ALPHA:
1522 adfact = have32bpp ? GR_BLEND_ONE_MINUS_SRC_ALPHA : GR_BLEND_ZERO/*bad*/;
1523 break;
1524 case GL_DST_COLOR:
1525 case GL_DST_ALPHA:
1526 adfact = (have32bpp && haveAlpha) ? GR_BLEND_DST_ALPHA : GR_BLEND_ONE/*bad*/;
1527 break;
1528 case GL_ONE_MINUS_DST_COLOR:
1529 case GL_ONE_MINUS_DST_ALPHA:
1530 adfact = (have32bpp && haveAlpha) ? GR_BLEND_ONE_MINUS_DST_ALPHA : GR_BLEND_ZERO/*bad*/;
1531 break;
1532 default:
1533 adfact = GR_BLEND_ZERO;
1534 break;
1535 }
1536
1537 if ((sfact != us->blendSrcFuncRGB) || (asfact != us->blendSrcFuncAlpha)) {
1538 us->blendSrcFuncRGB = sfact;
1539 us->blendSrcFuncAlpha = asfact;
1540 fxMesa->new_state |= FX_NEW_BLEND;
1541 }
1542
1543 if ((dfact != us->blendDstFuncRGB) || (adfact != us->blendDstFuncAlpha)) {
1544 us->blendDstFuncRGB = dfact;
1545 us->blendDstFuncAlpha = adfact;
1546 fxMesa->new_state |= FX_NEW_BLEND;
1547 }
1548 }
1549
1550 void
1551 fxDDBlendEquationSeparate(GLcontext * ctx, GLenum modeRGB, GLenum modeA)
1552 {
1553 fxMesaContext fxMesa = FX_CONTEXT(ctx);
1554 tfxUnitsState *us = &fxMesa->unitsState;
1555 GrAlphaBlendOp_t q;
1556
1557 switch (modeRGB) {
1558 case GL_FUNC_ADD:
1559 q = GR_BLEND_OP_ADD;
1560 break;
1561 case GL_FUNC_SUBTRACT:
1562 q = GR_BLEND_OP_SUB;
1563 break;
1564 case GL_FUNC_REVERSE_SUBTRACT:
1565 q = GR_BLEND_OP_REVSUB;
1566 break;
1567 default:
1568 q = us->blendEqRGB;
1569 }
1570 if (q != us->blendEqRGB) {
1571 us->blendEqRGB = q;
1572 fxMesa->new_state |= FX_NEW_BLEND;
1573 }
1574
1575 switch (modeA) {
1576 case GL_FUNC_ADD:
1577 q = GR_BLEND_OP_ADD;
1578 break;
1579 case GL_FUNC_SUBTRACT:
1580 q = GR_BLEND_OP_SUB;
1581 break;
1582 case GL_FUNC_REVERSE_SUBTRACT:
1583 q = GR_BLEND_OP_REVSUB;
1584 break;
1585 default:
1586 q = us->blendEqAlpha;
1587 }
1588 if (q != us->blendEqAlpha) {
1589 us->blendEqAlpha = q;
1590 fxMesa->new_state |= FX_NEW_BLEND;
1591 }
1592 }
1593
1594 void
1595 fxSetupBlend(GLcontext * ctx)
1596 {
1597 fxMesaContext fxMesa = FX_CONTEXT(ctx);
1598 tfxUnitsState *us = &fxMesa->unitsState;
1599
1600 if (fxMesa->HavePixExt) {
1601 if (us->blendEnabled) {
1602 fxMesa->Glide.grAlphaBlendFunctionExt(us->blendSrcFuncRGB, us->blendDstFuncRGB,
1603 us->blendEqRGB,
1604 us->blendSrcFuncAlpha, us->blendDstFuncAlpha,
1605 us->blendEqAlpha);
1606 } else {
1607 fxMesa->Glide.grAlphaBlendFunctionExt(GR_BLEND_ONE, GR_BLEND_ZERO,
1608 GR_BLEND_OP_ADD,
1609 GR_BLEND_ONE, GR_BLEND_ZERO,
1610 GR_BLEND_OP_ADD);
1611 }
1612 } else {
1613 if (us->blendEnabled) {
1614 grAlphaBlendFunction(us->blendSrcFuncRGB, us->blendDstFuncRGB,
1615 us->blendSrcFuncAlpha, us->blendDstFuncAlpha);
1616 } else {
1617 grAlphaBlendFunction(GR_BLEND_ONE, GR_BLEND_ZERO,
1618 GR_BLEND_ONE, GR_BLEND_ZERO);
1619 }
1620 }
1621 }
1622
1623 /************************************************************************/
1624 /************************** Alpha Test SetUp ****************************/
1625 /************************************************************************/
1626
1627 void
1628 fxDDAlphaFunc(GLcontext * ctx, GLenum func, GLfloat ref)
1629 {
1630 fxMesaContext fxMesa = FX_CONTEXT(ctx);
1631 tfxUnitsState *us = &fxMesa->unitsState;
1632
1633 if (
1634 (us->alphaTestFunc != func)
1635 ||
1636 (us->alphaTestRefValue != ref)
1637 ) {
1638 us->alphaTestFunc = func;
1639 us->alphaTestRefValue = ref;
1640 fxMesa->new_state |= FX_NEW_ALPHA;
1641 }
1642 }
1643
1644 static void
1645 fxSetupAlphaTest(GLcontext * ctx)
1646 {
1647 fxMesaContext fxMesa = FX_CONTEXT(ctx);
1648 tfxUnitsState *us = &fxMesa->unitsState;
1649
1650 if (us->alphaTestEnabled) {
1651 GrAlpha_t ref = (GLint) (us->alphaTestRefValue * 255.0);
1652 grAlphaTestFunction(us->alphaTestFunc - GL_NEVER + GR_CMP_NEVER);
1653 grAlphaTestReferenceValue(ref);
1654 }
1655 else
1656 grAlphaTestFunction(GR_CMP_ALWAYS);
1657 }
1658
1659 /************************************************************************/
1660 /************************** Depth Test SetUp ****************************/
1661 /************************************************************************/
1662
1663 void
1664 fxDDDepthFunc(GLcontext * ctx, GLenum func)
1665 {
1666 fxMesaContext fxMesa = FX_CONTEXT(ctx);
1667 tfxUnitsState *us = &fxMesa->unitsState;
1668
1669 if (us->depthTestFunc != func) {
1670 us->depthTestFunc = func;
1671 fxMesa->new_state |= FX_NEW_DEPTH;
1672 }
1673 }
1674
1675 void
1676 fxDDDepthMask(GLcontext * ctx, GLboolean flag)
1677 {
1678 fxMesaContext fxMesa = FX_CONTEXT(ctx);
1679 tfxUnitsState *us = &fxMesa->unitsState;
1680
1681 if (flag != us->depthMask) {
1682 us->depthMask = flag;
1683 fxMesa->new_state |= FX_NEW_DEPTH;
1684 }
1685 }
1686
1687 void
1688 fxSetupDepthTest(GLcontext * ctx)
1689 {
1690 fxMesaContext fxMesa = FX_CONTEXT(ctx);
1691 tfxUnitsState *us = &fxMesa->unitsState;
1692
1693 if (us->depthTestEnabled) {
1694 grDepthBufferFunction(us->depthTestFunc - GL_NEVER + GR_CMP_NEVER);
1695 grDepthMask(us->depthMask);
1696 }
1697 else {
1698 grDepthBufferFunction(GR_CMP_ALWAYS);
1699 grDepthMask(FXFALSE);
1700 }
1701 }
1702
1703 /************************************************************************/
1704 /************************** Stencil SetUp *******************************/
1705 /************************************************************************/
1706
1707 static GrStencil_t convertGLStencilOp( GLenum op )
1708 {
1709 switch ( op ) {
1710 case GL_KEEP:
1711 return GR_STENCILOP_KEEP;
1712 case GL_ZERO:
1713 return GR_STENCILOP_ZERO;
1714 case GL_REPLACE:
1715 return GR_STENCILOP_REPLACE;
1716 case GL_INCR:
1717 return GR_STENCILOP_INCR_CLAMP;
1718 case GL_DECR:
1719 return GR_STENCILOP_DECR_CLAMP;
1720 case GL_INVERT:
1721 return GR_STENCILOP_INVERT;
1722 case GL_INCR_WRAP_EXT:
1723 return GR_STENCILOP_INCR_WRAP;
1724 case GL_DECR_WRAP_EXT:
1725 return GR_STENCILOP_DECR_WRAP;
1726 default:
1727 _mesa_problem( NULL, "bad stencil op in convertGLStencilOp" );
1728 }
1729 return GR_STENCILOP_KEEP; /* never get, silence compiler warning */
1730 }
1731
1732 void
1733 fxDDStencilFunc (GLcontext *ctx, GLenum func, GLint ref, GLuint mask)
1734 {
1735 fxMesaContext fxMesa = FX_CONTEXT(ctx);
1736 tfxUnitsState *us = &fxMesa->unitsState;
1737
1738 if (
1739 (us->stencilFunction != func)
1740 ||
1741 (us->stencilRefValue != ref)
1742 ||
1743 (us->stencilValueMask != mask)
1744 ) {
1745 us->stencilFunction = func;
1746 us->stencilRefValue = ref;
1747 us->stencilValueMask = mask;
1748 fxMesa->new_state |= FX_NEW_STENCIL;
1749 }
1750 }
1751
1752 void
1753 fxDDStencilMask (GLcontext *ctx, GLuint mask)
1754 {
1755 fxMesaContext fxMesa = FX_CONTEXT(ctx);
1756 tfxUnitsState *us = &fxMesa->unitsState;
1757
1758 if (us->stencilWriteMask != mask) {
1759 us->stencilWriteMask = mask;
1760 fxMesa->new_state |= FX_NEW_STENCIL;
1761 }
1762 }
1763
1764 void
1765 fxDDStencilOp (GLcontext *ctx, GLenum sfail, GLenum zfail, GLenum zpass)
1766 {
1767 fxMesaContext fxMesa = FX_CONTEXT(ctx);
1768 tfxUnitsState *us = &fxMesa->unitsState;
1769
1770 if (
1771 (us->stencilFailFunc != sfail)
1772 ||
1773 (us->stencilZFailFunc != zfail)
1774 ||
1775 (us->stencilZPassFunc != zpass)
1776 ) {
1777 us->stencilFailFunc = sfail;
1778 us->stencilZFailFunc = zfail;
1779 us->stencilZPassFunc = zpass;
1780 fxMesa->new_state |= FX_NEW_STENCIL;
1781 }
1782 }
1783
1784 static void
1785 fxSetupStencil (GLcontext * ctx)
1786 {
1787 fxMesaContext fxMesa = FX_CONTEXT(ctx);
1788 tfxUnitsState *us = &fxMesa->unitsState;
1789
1790 if (us->stencilEnabled) {
1791 grEnable(GR_STENCIL_MODE_EXT);
1792 fxMesa->Glide.grStencilOpExt(convertGLStencilOp(us->stencilFailFunc),
1793 convertGLStencilOp(us->stencilZFailFunc),
1794 convertGLStencilOp(us->stencilZPassFunc));
1795 fxMesa->Glide.grStencilFuncExt(us->stencilFunction - GL_NEVER + GR_CMP_NEVER,
1796 us->stencilRefValue,
1797 us->stencilValueMask);
1798 fxMesa->Glide.grStencilMaskExt(us->stencilWriteMask);
1799 } else {
1800 grDisable(GR_STENCIL_MODE_EXT);
1801 }
1802 }
1803
1804 /************************************************************************/
1805 /**************************** Color Mask SetUp **************************/
1806 /************************************************************************/
1807
1808 void
1809 fxDDColorMask(GLcontext * ctx,
1810 GLboolean r, GLboolean g, GLboolean b, GLboolean a)
1811 {
1812 fxMesaContext fxMesa = FX_CONTEXT(ctx);
1813 fxMesa->new_state |= FX_NEW_COLOR_MASK;
1814 (void) r;
1815 (void) g;
1816 (void) b;
1817 (void) a;
1818 }
1819
1820 void
1821 fxSetupColorMask(GLcontext * ctx)
1822 {
1823 fxMesaContext fxMesa = FX_CONTEXT(ctx);
1824
1825 if (fxMesa->colDepth == 32) {
1826 /* 32bpp mode */
1827 fxMesa->Glide.grColorMaskExt(ctx->Color.ColorMask[RCOMP],
1828 ctx->Color.ColorMask[GCOMP],
1829 ctx->Color.ColorMask[BCOMP],
1830 ctx->Color.ColorMask[ACOMP] && fxMesa->haveHwAlpha);
1831 }
1832 else {
1833 /* 15/16 bpp mode */
1834 grColorMask(ctx->Color.ColorMask[RCOMP] |
1835 ctx->Color.ColorMask[GCOMP] |
1836 ctx->Color.ColorMask[BCOMP],
1837 ctx->Color.ColorMask[ACOMP] && fxMesa->haveHwAlpha);
1838 }
1839 }
1840
1841
1842
1843
1844 /************************************************************************/
1845 /**************************** Fog Mode SetUp ****************************/
1846 /************************************************************************/
1847
1848 /*
1849 * This is called during state update in order to update the Glide fog state.
1850 */
1851 static void
1852 fxSetupFog(GLcontext * ctx)
1853 {
1854 if (ctx->Fog.Enabled /*&& ctx->FogMode==FOG_FRAGMENT */ ) {
1855 fxMesaContext fxMesa = FX_CONTEXT(ctx);
1856
1857 /* update fog color */
1858 GLubyte col[4];
1859 col[0] = (unsigned int) (255 * ctx->Fog.Color[0]);
1860 col[1] = (unsigned int) (255 * ctx->Fog.Color[1]);
1861 col[2] = (unsigned int) (255 * ctx->Fog.Color[2]);
1862 col[3] = (unsigned int) (255 * ctx->Fog.Color[3]);
1863 grFogColorValue(FXCOLOR4(col));
1864
1865 if (fxMesa->fogTableMode != ctx->Fog.Mode ||
1866 fxMesa->fogDensity != ctx->Fog.Density ||
1867 fxMesa->fogStart != ctx->Fog.Start ||
1868 fxMesa->fogEnd != ctx->Fog.End) {
1869 /* reload the fog table */
1870 switch (ctx->Fog.Mode) {
1871 case GL_LINEAR:
1872 guFogGenerateLinear(fxMesa->fogTable, ctx->Fog.Start,
1873 ctx->Fog.End);
1874 if (fxMesa->fogTable[0] > 63) {
1875 /* [dBorca] Hack alert:
1876 * As per Glide3 Programming Guide:
1877 * The difference between consecutive fog values
1878 * must be less than 64.
1879 */
1880 fxMesa->fogTable[0] = 63;
1881 }
1882 break;
1883 case GL_EXP:
1884 guFogGenerateExp(fxMesa->fogTable, ctx->Fog.Density);
1885 break;
1886 case GL_EXP2:
1887 guFogGenerateExp2(fxMesa->fogTable, ctx->Fog.Density);
1888 break;
1889 default:
1890 ;
1891 }
1892 fxMesa->fogTableMode = ctx->Fog.Mode;
1893 fxMesa->fogDensity = ctx->Fog.Density;
1894 fxMesa->fogStart = ctx->Fog.Start;
1895 fxMesa->fogEnd = ctx->Fog.End;
1896 }
1897
1898 grFogTable(fxMesa->fogTable);
1899 if (ctx->Fog.FogCoordinateSource == GL_FOG_COORDINATE_EXT) {
1900 grVertexLayout(GR_PARAM_FOG_EXT, GR_VERTEX_FOG_OFFSET << 2,
1901 GR_PARAM_ENABLE);
1902 grFogMode(GR_FOG_WITH_TABLE_ON_FOGCOORD_EXT);
1903 } else {
1904 grVertexLayout(GR_PARAM_FOG_EXT, GR_VERTEX_FOG_OFFSET << 2,
1905 GR_PARAM_DISABLE);
1906 grFogMode(GR_FOG_WITH_TABLE_ON_Q);
1907 }
1908 }
1909 else {
1910 grFogMode(GR_FOG_DISABLE);
1911 }
1912 }
1913
1914 void
1915 fxDDFogfv(GLcontext * ctx, GLenum pname, const GLfloat * params)
1916 {
1917 FX_CONTEXT(ctx)->new_state |= FX_NEW_FOG;
1918 switch (pname) {
1919 case GL_FOG_COORDINATE_SOURCE_EXT: {
1920 GLenum p = (GLenum)*params;
1921 if (p == GL_FOG_COORDINATE_EXT) {
1922 _swrast_allow_vertex_fog(ctx, GL_TRUE);
1923 _swrast_allow_pixel_fog(ctx, GL_FALSE);
1924 _tnl_allow_vertex_fog( ctx, GL_TRUE);
1925 _tnl_allow_pixel_fog( ctx, GL_FALSE);
1926 } else {
1927 _swrast_allow_vertex_fog(ctx, GL_FALSE);
1928 _swrast_allow_pixel_fog(ctx, GL_TRUE);
1929 _tnl_allow_vertex_fog( ctx, GL_FALSE);
1930 _tnl_allow_pixel_fog( ctx, GL_TRUE);
1931 }
1932 break;
1933 }
1934 default:
1935 ;
1936 }
1937 }
1938
1939 /************************************************************************/
1940 /************************** Scissor Test SetUp **************************/
1941 /************************************************************************/
1942
1943 /* This routine is used in managing the lock state, and therefore can't lock */
1944 void
1945 fxSetScissorValues(GLcontext * ctx)
1946 {
1947 fxMesaContext fxMesa = FX_CONTEXT(ctx);
1948 int xmin, xmax;
1949 int ymin, ymax;
1950
1951 if (ctx->Scissor.Enabled) {
1952 xmin = ctx->Scissor.X;
1953 xmax = ctx->Scissor.X + ctx->Scissor.Width;
1954 ymin = ctx->Scissor.Y;
1955 ymax = ctx->Scissor.Y + ctx->Scissor.Height;
1956
1957 if (xmin < 0)
1958 xmin = 0;
1959 if (xmax > fxMesa->width)
1960 xmax = fxMesa->width;
1961 if (ymin < fxMesa->screen_height - fxMesa->height)
1962 ymin = fxMesa->screen_height - fxMesa->height;
1963 if (ymax > fxMesa->screen_height - 0)
1964 ymax = fxMesa->screen_height - 0;
1965 }
1966 else {
1967 xmin = 0;
1968 ymin = 0;
1969 xmax = fxMesa->width;
1970 ymax = fxMesa->height;
1971 }
1972
1973 fxMesa->clipMinX = xmin;
1974 fxMesa->clipMinY = ymin;
1975 fxMesa->clipMaxX = xmax;
1976 fxMesa->clipMaxY = ymax;
1977 grClipWindow(xmin, ymin, xmax, ymax);
1978 }
1979
1980 void
1981 fxSetupScissor(GLcontext * ctx)
1982 {
1983 BEGIN_BOARD_LOCK();
1984 fxSetScissorValues(ctx);
1985 END_BOARD_LOCK();
1986 }
1987
1988 void
1989 fxDDScissor(GLcontext * ctx, GLint x, GLint y, GLsizei w, GLsizei h)
1990 {
1991 FX_CONTEXT(ctx)->new_state |= FX_NEW_SCISSOR;
1992 }
1993
1994 /************************************************************************/
1995 /*************************** Cull mode setup ****************************/
1996 /************************************************************************/
1997
1998
1999 void
2000 fxDDCullFace(GLcontext * ctx, GLenum mode)
2001 {
2002 (void) mode;
2003 FX_CONTEXT(ctx)->new_state |= FX_NEW_CULL;
2004 }
2005
2006 void
2007 fxDDFrontFace(GLcontext * ctx, GLenum mode)
2008 {
2009 (void) mode;
2010 FX_CONTEXT(ctx)->new_state |= FX_NEW_CULL;
2011 }
2012
2013
2014 void
2015 fxSetupCull(GLcontext * ctx)
2016 {
2017 fxMesaContext fxMesa = FX_CONTEXT(ctx);
2018 GrCullMode_t mode = GR_CULL_DISABLE;
2019
2020 if (ctx->Polygon.CullFlag && (fxMesa->raster_primitive == GL_TRIANGLES)) {
2021 switch (ctx->Polygon.CullFaceMode) {
2022 case GL_BACK:
2023 if (ctx->Polygon.FrontFace == GL_CCW)
2024 mode = GR_CULL_NEGATIVE;
2025 else
2026 mode = GR_CULL_POSITIVE;
2027 break;
2028 case GL_FRONT:
2029 if (ctx->Polygon.FrontFace == GL_CCW)
2030 mode = GR_CULL_POSITIVE;
2031 else
2032 mode = GR_CULL_NEGATIVE;
2033 break;
2034 case GL_FRONT_AND_BACK:
2035 /* Handled as a fallback on triangles in tdfx_tris.c */
2036 return;
2037 default:
2038 ASSERT(0);
2039 break;
2040 }
2041 }
2042
2043 if (fxMesa->cullMode != mode) {
2044 fxMesa->cullMode = mode;
2045 grCullMode(mode);
2046 }
2047 }
2048
2049
2050 /************************************************************************/
2051 /****************************** DD Enable ******************************/
2052 /************************************************************************/
2053
2054 void
2055 fxDDEnable(GLcontext * ctx, GLenum cap, GLboolean state)
2056 {
2057 fxMesaContext fxMesa = FX_CONTEXT(ctx);
2058 tfxUnitsState *us = &fxMesa->unitsState;
2059
2060 if (TDFX_DEBUG & VERBOSE_DRIVER) {
2061 fprintf(stderr, "%s(%s)\n", state ? "fxDDEnable" : "fxDDDisable",
2062 _mesa_lookup_enum_by_nr(cap));
2063 }
2064
2065 switch (cap) {
2066 case GL_ALPHA_TEST:
2067 if (state != us->alphaTestEnabled) {
2068 us->alphaTestEnabled = state;
2069 fxMesa->new_state |= FX_NEW_ALPHA;
2070 }
2071 break;
2072 case GL_BLEND:
2073 if (state != us->blendEnabled) {
2074 us->blendEnabled = state;
2075 fxMesa->new_state |= FX_NEW_BLEND;
2076 }
2077 break;
2078 case GL_DEPTH_TEST:
2079 if (state != us->depthTestEnabled) {
2080 us->depthTestEnabled = state;
2081 fxMesa->new_state |= FX_NEW_DEPTH;
2082 }
2083 break;
2084 case GL_STENCIL_TEST:
2085 if (fxMesa->haveHwStencil && state != us->stencilEnabled) {
2086 us->stencilEnabled = state;
2087 fxMesa->new_state |= FX_NEW_STENCIL;
2088 }
2089 break;
2090 case GL_DITHER:
2091 if (state) {
2092 grDitherMode(GR_DITHER_4x4);
2093 }
2094 else {
2095 grDitherMode(GR_DITHER_DISABLE);
2096 }
2097 break;
2098 case GL_SCISSOR_TEST:
2099 fxMesa->new_state |= FX_NEW_SCISSOR;
2100 break;
2101 case GL_SHARED_TEXTURE_PALETTE_EXT:
2102 fxDDTexUseGlbPalette(ctx, state);
2103 break;
2104 case GL_FOG:
2105 fxMesa->new_state |= FX_NEW_FOG;
2106 break;
2107 case GL_CULL_FACE:
2108 fxMesa->new_state |= FX_NEW_CULL;
2109 break;
2110 case GL_LINE_SMOOTH:
2111 case GL_LINE_STIPPLE:
2112 case GL_POINT_SMOOTH:
2113 case GL_POLYGON_SMOOTH:
2114 case GL_TEXTURE_1D:
2115 case GL_TEXTURE_2D:
2116 fxMesa->new_state |= FX_NEW_TEXTURING;
2117 break;
2118 default:
2119 ; /* XXX no-op? */
2120 }
2121 }
2122
2123
2124
2125
2126 /************************************************************************/
2127 /************************** Changes to units state **********************/
2128 /************************************************************************/
2129
2130
2131 /* All units setup is handled under texture setup.
2132 */
2133 void
2134 fxDDShadeModel(GLcontext * ctx, GLenum mode)
2135 {
2136 FX_CONTEXT(ctx)->new_state |= FX_NEW_TEXTURING;
2137 }
2138
2139
2140
2141 /************************************************************************/
2142 /****************************** Units SetUp *****************************/
2143 /************************************************************************/
2144 static void
2145 fx_print_state_flags(const char *msg, GLuint flags)
2146 {
2147 fprintf(stderr,
2148 "%s: (0x%x) %s%s%s%s%s%s%s%s\n",
2149 msg,
2150 flags,
2151 (flags & FX_NEW_TEXTURING) ? "texture, " : "",
2152 (flags & FX_NEW_BLEND) ? "blend, " : "",
2153 (flags & FX_NEW_ALPHA) ? "alpha, " : "",
2154 (flags & FX_NEW_FOG) ? "fog, " : "",
2155 (flags & FX_NEW_SCISSOR) ? "scissor, " : "",
2156 (flags & FX_NEW_COLOR_MASK) ? "colormask, " : "",
2157 (flags & FX_NEW_CULL) ? "cull, " : "",
2158 (flags & FX_NEW_STENCIL) ? "stencil, " : "");
2159 }
2160
2161 void
2162 fxSetupFXUnits(GLcontext * ctx)
2163 {
2164 fxMesaContext fxMesa = FX_CONTEXT(ctx);
2165 GLuint newstate = fxMesa->new_state;
2166
2167 if (TDFX_DEBUG & VERBOSE_DRIVER)
2168 fx_print_state_flags("fxSetupFXUnits", newstate);
2169
2170 if (newstate) {
2171 if (newstate & FX_NEW_TEXTURING)
2172 fxSetupTexture(ctx);
2173
2174 if (newstate & FX_NEW_BLEND)
2175 fxSetupBlend(ctx);
2176
2177 if (newstate & FX_NEW_ALPHA)
2178 fxSetupAlphaTest(ctx);
2179
2180 if (newstate & FX_NEW_DEPTH)
2181 fxSetupDepthTest(ctx);
2182
2183 if (newstate & FX_NEW_STENCIL)
2184 fxSetupStencil(ctx);
2185
2186 if (newstate & FX_NEW_FOG)
2187 fxSetupFog(ctx);
2188
2189 if (newstate & FX_NEW_SCISSOR)
2190 fxSetupScissor(ctx);
2191
2192 if (newstate & FX_NEW_COLOR_MASK)
2193 fxSetupColorMask(ctx);
2194
2195 if (newstate & FX_NEW_CULL)
2196 fxSetupCull(ctx);
2197
2198 fxMesa->new_state = 0;
2199 }
2200 }
2201
2202
2203
2204 #else
2205
2206
2207 /*
2208 * Need this to provide at least one external definition.
2209 */
2210
2211 extern int gl_fx_dummy_function_setup(void);
2212 int
2213 gl_fx_dummy_function_setup(void)
2214 {
2215 return 0;
2216 }
2217
2218 #endif /* FX */