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