48a1ae6926748724cb9050859f8bfaa06697d10a
[mesa.git] / src / mesa / drivers / glide / fxsetup.c
1 /* $Id: fxsetup.c,v 1.38 2002/11/04 20:29:04 brianp Exp $ */
2
3 /*
4 * Mesa 3-D graphics library
5 * Version: 4.0
6 *
7 * Copyright (C) 1999-2001 Brian Paul All Rights Reserved.
8 *
9 * Permission is hereby granted, free of charge, to any person obtaining a
10 * copy of this software and associated documentation files (the "Software"),
11 * to deal in the Software without restriction, including without limitation
12 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
13 * and/or sell copies of the Software, and to permit persons to whom the
14 * Software is furnished to do so, subject to the following conditions:
15 *
16 * The above copyright notice and this permission notice shall be included
17 * in all copies or substantial portions of the Software.
18 *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
22 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
23 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
24 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 */
26
27 /* Authors:
28 * David Bucciarelli
29 * Brian Paul
30 * Daryll Strauss
31 * Keith Whitwell
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 (MESA_VERBOSE & VERBOSE_DRIVER) {
54 fprintf(stderr, "fxmesa: fxTexValidate(...) Start\n");
55 }
56
57 if (ti->validated) {
58 if (MESA_VERBOSE & VERBOSE_DRIVER) {
59 fprintf(stderr,
60 "fxmesa: fxTexValidate(...) End (validated=GL_TRUE)\n");
61 }
62 return;
63 }
64
65 ti->tObj = tObj;
66 minl = ti->minLevel = tObj->BaseLevel;
67 maxl = ti->maxLevel = MIN2(tObj->MaxLevel, tObj->Image[0]->MaxLog2);
68
69 fxTexGetInfo(tObj->Image[minl]->Width, tObj->Image[minl]->Height,
70 &(FX_largeLodLog2(ti->info)), &(FX_aspectRatioLog2(ti->info)),
71 &(ti->sScale), &(ti->tScale),
72 &(ti->int_sScale), &(ti->int_tScale), NULL, NULL);
73
74 if ((tObj->MinFilter != GL_NEAREST) && (tObj->MinFilter != GL_LINEAR))
75 fxTexGetInfo(tObj->Image[maxl]->Width, tObj->Image[maxl]->Height,
76 &(FX_smallLodLog2(ti->info)), NULL,
77 NULL, NULL, NULL, NULL, NULL, NULL);
78 else
79 FX_smallLodLog2(ti->info) = FX_largeLodLog2(ti->info);
80
81 fxTexGetFormat(tObj->Image[minl]->TexFormat->BaseFormat, &(ti->info.format),
82 &(ti->baseLevelInternalFormat));
83
84 switch (tObj->WrapS) {
85 case GL_CLAMP_TO_EDGE:
86 /* What's this really mean compared to GL_CLAMP? */
87 case GL_CLAMP:
88 ti->sClamp = 1;
89 break;
90 case GL_REPEAT:
91 ti->sClamp = 0;
92 break;
93 default:
94 ; /* silence compiler warning */
95 }
96 switch (tObj->WrapT) {
97 case GL_CLAMP_TO_EDGE:
98 /* What's this really mean compared to GL_CLAMP? */
99 case GL_CLAMP:
100 ti->tClamp = 1;
101 break;
102 case GL_REPEAT:
103 ti->tClamp = 0;
104 break;
105 default:
106 ; /* silence compiler warning */
107 }
108
109 ti->validated = GL_TRUE;
110
111 ti->info.data = NULL;
112
113 if (MESA_VERBOSE & VERBOSE_DRIVER) {
114 fprintf(stderr, "fxmesa: fxTexValidate(...) End\n");
115 }
116 }
117
118 static void
119 fxPrintUnitsMode(const char *msg, GLuint mode)
120 {
121 fprintf(stderr,
122 "%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",
123 msg,
124 mode,
125 (mode & FX_UM_E0_REPLACE) ? "E0_REPLACE, " : "",
126 (mode & FX_UM_E0_MODULATE) ? "E0_MODULATE, " : "",
127 (mode & FX_UM_E0_DECAL) ? "E0_DECAL, " : "",
128 (mode & FX_UM_E0_BLEND) ? "E0_BLEND, " : "",
129 (mode & FX_UM_E1_REPLACE) ? "E1_REPLACE, " : "",
130 (mode & FX_UM_E1_MODULATE) ? "E1_MODULATE, " : "",
131 (mode & FX_UM_E1_DECAL) ? "E1_DECAL, " : "",
132 (mode & FX_UM_E1_BLEND) ? "E1_BLEND, " : "",
133 (mode & FX_UM_E0_ALPHA) ? "E0_ALPHA, " : "",
134 (mode & FX_UM_E0_LUMINANCE) ? "E0_LUMINANCE, " : "",
135 (mode & FX_UM_E0_LUMINANCE_ALPHA) ? "E0_LUMINANCE_ALPHA, " : "",
136 (mode & FX_UM_E0_INTENSITY) ? "E0_INTENSITY, " : "",
137 (mode & FX_UM_E0_RGB) ? "E0_RGB, " : "",
138 (mode & FX_UM_E0_RGBA) ? "E0_RGBA, " : "",
139 (mode & FX_UM_E1_ALPHA) ? "E1_ALPHA, " : "",
140 (mode & FX_UM_E1_LUMINANCE) ? "E1_LUMINANCE, " : "",
141 (mode & FX_UM_E1_LUMINANCE_ALPHA) ? "E1_LUMINANCE_ALPHA, " : "",
142 (mode & FX_UM_E1_INTENSITY) ? "E1_INTENSITY, " : "",
143 (mode & FX_UM_E1_RGB) ? "E1_RGB, " : "",
144 (mode & FX_UM_E1_RGBA) ? "E1_RGBA, " : "",
145 (mode & FX_UM_COLOR_ITERATED) ? "COLOR_ITERATED, " : "",
146 (mode & FX_UM_COLOR_CONSTANT) ? "COLOR_CONSTANT, " : "",
147 (mode & FX_UM_ALPHA_ITERATED) ? "ALPHA_ITERATED, " : "",
148 (mode & FX_UM_ALPHA_CONSTANT) ? "ALPHA_CONSTANT, " : "");
149 }
150
151 static GLuint
152 fxGetTexSetConfiguration(GLcontext * ctx,
153 struct gl_texture_object *tObj0,
154 struct gl_texture_object *tObj1)
155 {
156 GLuint unitsmode = 0;
157 GLuint envmode = 0;
158 GLuint ifmt = 0;
159
160 if ((ctx->Light.ShadeModel == GL_SMOOTH) || 1 ||
161 (ctx->Point.SmoothFlag) ||
162 (ctx->Line.SmoothFlag) ||
163 (ctx->Polygon.SmoothFlag)) unitsmode |= FX_UM_ALPHA_ITERATED;
164 else
165 unitsmode |= FX_UM_ALPHA_CONSTANT;
166
167 if (ctx->Light.ShadeModel == GL_SMOOTH || 1)
168 unitsmode |= FX_UM_COLOR_ITERATED;
169 else
170 unitsmode |= FX_UM_COLOR_CONSTANT;
171
172
173
174 /*
175 OpenGL Feeds Texture 0 into Texture 1
176 Glide Feeds Texture 1 into Texture 0
177 */
178 if (tObj0) {
179 tfxTexInfo *ti0 = fxTMGetTexInfo(tObj0);
180
181 switch (ti0->baseLevelInternalFormat) {
182 case GL_ALPHA:
183 ifmt |= FX_UM_E0_ALPHA;
184 break;
185 case GL_LUMINANCE:
186 ifmt |= FX_UM_E0_LUMINANCE;
187 break;
188 case GL_LUMINANCE_ALPHA:
189 ifmt |= FX_UM_E0_LUMINANCE_ALPHA;
190 break;
191 case GL_INTENSITY:
192 ifmt |= FX_UM_E0_INTENSITY;
193 break;
194 case GL_RGB:
195 ifmt |= FX_UM_E0_RGB;
196 break;
197 case GL_RGBA:
198 ifmt |= FX_UM_E0_RGBA;
199 break;
200 }
201
202 switch (ctx->Texture.Unit[0].EnvMode) {
203 case GL_DECAL:
204 envmode |= FX_UM_E0_DECAL;
205 break;
206 case GL_MODULATE:
207 envmode |= FX_UM_E0_MODULATE;
208 break;
209 case GL_REPLACE:
210 envmode |= FX_UM_E0_REPLACE;
211 break;
212 case GL_BLEND:
213 envmode |= FX_UM_E0_BLEND;
214 break;
215 case GL_ADD:
216 envmode |= FX_UM_E0_ADD;
217 break;
218 default:
219 /* do nothing */
220 break;
221 }
222 }
223
224 if (tObj1) {
225 tfxTexInfo *ti1 = fxTMGetTexInfo(tObj1);
226
227 switch (ti1->baseLevelInternalFormat) {
228 case GL_ALPHA:
229 ifmt |= FX_UM_E1_ALPHA;
230 break;
231 case GL_LUMINANCE:
232 ifmt |= FX_UM_E1_LUMINANCE;
233 break;
234 case GL_LUMINANCE_ALPHA:
235 ifmt |= FX_UM_E1_LUMINANCE_ALPHA;
236 break;
237 case GL_INTENSITY:
238 ifmt |= FX_UM_E1_INTENSITY;
239 break;
240 case GL_RGB:
241 ifmt |= FX_UM_E1_RGB;
242 break;
243 case GL_RGBA:
244 ifmt |= FX_UM_E1_RGBA;
245 break;
246 default:
247 /* do nothing */
248 break;
249 }
250
251 switch (ctx->Texture.Unit[1].EnvMode) {
252 case GL_DECAL:
253 envmode |= FX_UM_E1_DECAL;
254 break;
255 case GL_MODULATE:
256 envmode |= FX_UM_E1_MODULATE;
257 break;
258 case GL_REPLACE:
259 envmode |= FX_UM_E1_REPLACE;
260 break;
261 case GL_BLEND:
262 envmode |= FX_UM_E1_BLEND;
263 break;
264 case GL_ADD:
265 envmode |= FX_UM_E1_ADD;
266 break;
267 default:
268 /* do nothing */
269 break;
270 }
271 }
272
273 unitsmode |= (ifmt | envmode);
274
275 if (MESA_VERBOSE & (VERBOSE_DRIVER | VERBOSE_TEXTURE))
276 fxPrintUnitsMode("unitsmode", unitsmode);
277
278 return unitsmode;
279 }
280
281 /************************************************************************/
282 /************************* Rendering Mode SetUp *************************/
283 /************************************************************************/
284
285 /************************* Single Texture Set ***************************/
286
287 static void
288 fxSetupSingleTMU_NoLock(fxMesaContext fxMesa, struct gl_texture_object *tObj)
289 {
290 tfxTexInfo *ti = fxTMGetTexInfo(tObj);
291 int tmu;
292
293 /* Make sure we're not loaded incorrectly */
294 if (ti->isInTM) {
295 if (ti->LODblend) {
296 if (ti->whichTMU != FX_TMU_SPLIT)
297 fxTMMoveOutTM(fxMesa, tObj);
298 }
299 else {
300 if (ti->whichTMU == FX_TMU_SPLIT)
301 fxTMMoveOutTM(fxMesa, tObj);
302 }
303 }
304
305 /* Make sure we're loaded correctly */
306 if (!ti->isInTM) {
307 if (ti->LODblend)
308 fxTMMoveInTM_NoLock(fxMesa, tObj, FX_TMU_SPLIT);
309 else {
310 if (fxMesa->haveTwoTMUs) {
311 if (fxMesa->freeTexMem[FX_TMU0] >
312 FX_grTexTextureMemRequired_NoLock(GR_MIPMAPLEVELMASK_BOTH,
313 &(ti->info))) {
314 fxTMMoveInTM_NoLock(fxMesa, tObj, FX_TMU0);
315 }
316 else {
317 fxTMMoveInTM_NoLock(fxMesa, tObj, FX_TMU1);
318 }
319 }
320 else
321 fxTMMoveInTM_NoLock(fxMesa, tObj, FX_TMU0);
322 }
323 }
324
325 if (ti->LODblend && ti->whichTMU == FX_TMU_SPLIT) {
326 if ((ti->info.format == GR_TEXFMT_P_8)
327 && (!fxMesa->haveGlobalPaletteTexture)) {
328 if (MESA_VERBOSE & VERBOSE_DRIVER) {
329 fprintf(stderr, "fxmesa: uploading texture palette\n");
330 }
331 FX_grTexDownloadTable_NoLock(GR_TMU0, GR_TEXTABLE_PALETTE,
332 &(ti->palette));
333 FX_grTexDownloadTable_NoLock(GR_TMU1, GR_TEXTABLE_PALETTE,
334 &(ti->palette));
335 }
336
337 FX_grTexClampMode_NoLock(GR_TMU0, ti->sClamp, ti->tClamp);
338 FX_grTexClampMode_NoLock(GR_TMU1, ti->sClamp, ti->tClamp);
339 FX_grTexFilterMode_NoLock(GR_TMU0, ti->minFilt, ti->maxFilt);
340 FX_grTexFilterMode_NoLock(GR_TMU1, ti->minFilt, ti->maxFilt);
341 FX_grTexMipMapMode_NoLock(GR_TMU0, ti->mmMode, ti->LODblend);
342 FX_grTexMipMapMode_NoLock(GR_TMU1, ti->mmMode, ti->LODblend);
343
344 FX_grTexSource_NoLock(GR_TMU0, ti->tm[FX_TMU0]->startAddr,
345 GR_MIPMAPLEVELMASK_ODD, &(ti->info));
346 FX_grTexSource_NoLock(GR_TMU1, ti->tm[FX_TMU1]->startAddr,
347 GR_MIPMAPLEVELMASK_EVEN, &(ti->info));
348 }
349 else {
350 if (ti->whichTMU == FX_TMU_BOTH)
351 tmu = FX_TMU0;
352 else
353 tmu = ti->whichTMU;
354
355 if ((ti->info.format == GR_TEXFMT_P_8)
356 && (!fxMesa->haveGlobalPaletteTexture)) {
357 if (MESA_VERBOSE & VERBOSE_DRIVER) {
358 fprintf(stderr, "fxmesa: uploading texture palette\n");
359 }
360 FX_grTexDownloadTable_NoLock(tmu, GR_TEXTABLE_PALETTE,
361 &(ti->palette));
362 }
363
364 /* KW: The alternative is to do the download to the other tmu. If
365 * we get to this point, I think it means we are thrashing the
366 * texture memory, so perhaps it's not a good idea.
367 */
368 if (ti->LODblend && (MESA_VERBOSE & VERBOSE_DRIVER))
369 fprintf(stderr, "fxmesa: not blending texture - only on one tmu\n");
370
371 FX_grTexClampMode_NoLock(tmu, ti->sClamp, ti->tClamp);
372 FX_grTexFilterMode_NoLock(tmu, ti->minFilt, ti->maxFilt);
373 FX_grTexMipMapMode_NoLock(tmu, ti->mmMode, FXFALSE);
374
375 FX_grTexSource_NoLock(tmu, ti->tm[tmu]->startAddr,
376 GR_MIPMAPLEVELMASK_BOTH, &(ti->info));
377 }
378 }
379
380 static void
381 fxSelectSingleTMUSrc_NoLock(fxMesaContext fxMesa, GLint tmu, FxBool LODblend)
382 {
383 if (MESA_VERBOSE & VERBOSE_DRIVER) {
384 fprintf(stderr, "fxmesa: fxSelectSingleTMUSrc(%d,%d)\n", tmu, LODblend);
385 }
386
387 if (LODblend) {
388 FX_grTexCombine_NoLock(GR_TMU0,
389 GR_COMBINE_FUNCTION_BLEND,
390 GR_COMBINE_FACTOR_ONE_MINUS_LOD_FRACTION,
391 GR_COMBINE_FUNCTION_BLEND,
392 GR_COMBINE_FACTOR_ONE_MINUS_LOD_FRACTION,
393 FXFALSE, FXFALSE);
394
395 if (fxMesa->haveTwoTMUs)
396 FX_grTexCombine_NoLock(GR_TMU1,
397 GR_COMBINE_FUNCTION_LOCAL,
398 GR_COMBINE_FACTOR_NONE,
399 GR_COMBINE_FUNCTION_LOCAL,
400 GR_COMBINE_FACTOR_NONE, FXFALSE, FXFALSE);
401 fxMesa->tmuSrc = FX_TMU_SPLIT;
402 }
403 else {
404 if (tmu != FX_TMU1) {
405 FX_grTexCombine_NoLock(GR_TMU0,
406 GR_COMBINE_FUNCTION_LOCAL,
407 GR_COMBINE_FACTOR_NONE,
408 GR_COMBINE_FUNCTION_LOCAL,
409 GR_COMBINE_FACTOR_NONE, FXFALSE, FXFALSE);
410 if (fxMesa->haveTwoTMUs) {
411 FX_grTexCombine_NoLock(GR_TMU1,
412 GR_COMBINE_FUNCTION_ZERO,
413 GR_COMBINE_FACTOR_NONE,
414 GR_COMBINE_FUNCTION_ZERO,
415 GR_COMBINE_FACTOR_NONE, FXFALSE, FXFALSE);
416 }
417 fxMesa->tmuSrc = FX_TMU0;
418 }
419 else {
420 FX_grTexCombine_NoLock(GR_TMU1,
421 GR_COMBINE_FUNCTION_LOCAL,
422 GR_COMBINE_FACTOR_NONE,
423 GR_COMBINE_FUNCTION_LOCAL,
424 GR_COMBINE_FACTOR_NONE, FXFALSE, FXFALSE);
425
426 /* GR_COMBINE_FUNCTION_SCALE_OTHER doesn't work ?!? */
427
428 FX_grTexCombine_NoLock(GR_TMU0,
429 GR_COMBINE_FUNCTION_BLEND,
430 GR_COMBINE_FACTOR_ONE,
431 GR_COMBINE_FUNCTION_BLEND,
432 GR_COMBINE_FACTOR_ONE, FXFALSE, FXFALSE);
433
434 fxMesa->tmuSrc = FX_TMU1;
435 }
436 }
437 }
438
439 static void
440 fxSetupTextureSingleTMU_NoLock(GLcontext * ctx, GLuint textureset)
441 {
442 fxMesaContext fxMesa = (fxMesaContext) ctx->DriverCtx;
443 GrCombineLocal_t localc, locala;
444 GLuint unitsmode;
445 GLint ifmt;
446 tfxTexInfo *ti;
447 struct gl_texture_object *tObj = ctx->Texture.Unit[textureset].Current2D;
448 int tmu;
449
450 if (MESA_VERBOSE & VERBOSE_DRIVER) {
451 fprintf(stderr, "fxmesa: fxSetupTextureSingleTMU(...) Start\n");
452 }
453
454 ti = fxTMGetTexInfo(tObj);
455
456 fxTexValidate(ctx, tObj);
457
458 fxSetupSingleTMU_NoLock(fxMesa, tObj);
459
460 if (ti->whichTMU == FX_TMU_BOTH)
461 tmu = FX_TMU0;
462 else
463 tmu = ti->whichTMU;
464 if (fxMesa->tmuSrc != tmu)
465 fxSelectSingleTMUSrc_NoLock(fxMesa, tmu, ti->LODblend);
466
467 if (textureset == 0 || !fxMesa->haveTwoTMUs)
468 unitsmode = fxGetTexSetConfiguration(ctx, tObj, NULL);
469 else
470 unitsmode = fxGetTexSetConfiguration(ctx, NULL, tObj);
471
472 /* if(fxMesa->lastUnitsMode==unitsmode) */
473 /* return; */
474
475 fxMesa->lastUnitsMode = unitsmode;
476
477 fxMesa->stw_hint_state = 0;
478 FX_grHints_NoLock(GR_HINT_STWHINT, 0);
479
480 ifmt = ti->baseLevelInternalFormat;
481
482 if (unitsmode & FX_UM_ALPHA_ITERATED)
483 locala = GR_COMBINE_LOCAL_ITERATED;
484 else
485 locala = GR_COMBINE_LOCAL_CONSTANT;
486
487 if (unitsmode & FX_UM_COLOR_ITERATED)
488 localc = GR_COMBINE_LOCAL_ITERATED;
489 else
490 localc = GR_COMBINE_LOCAL_CONSTANT;
491
492 if (MESA_VERBOSE & (VERBOSE_DRIVER | VERBOSE_TEXTURE))
493 fprintf(stderr, "fxMesa: fxSetupTextureSingleTMU, envmode is %s\n",
494 _mesa_lookup_enum_by_nr(ctx->Texture.Unit[textureset].EnvMode));
495
496 switch (ctx->Texture.Unit[textureset].EnvMode) {
497 case GL_DECAL:
498 FX_grAlphaCombine_NoLock(GR_COMBINE_FUNCTION_LOCAL,
499 GR_COMBINE_FACTOR_NONE,
500 locala, GR_COMBINE_OTHER_NONE, FXFALSE);
501
502 FX_grColorCombine_NoLock(GR_COMBINE_FUNCTION_BLEND,
503 GR_COMBINE_FACTOR_TEXTURE_ALPHA,
504 localc, GR_COMBINE_OTHER_TEXTURE, FXFALSE);
505 break;
506 case GL_MODULATE:
507 FX_grAlphaCombine_NoLock(GR_COMBINE_FUNCTION_SCALE_OTHER,
508 GR_COMBINE_FACTOR_LOCAL,
509 locala, GR_COMBINE_OTHER_TEXTURE, FXFALSE);
510
511 if (ifmt == GL_ALPHA)
512 FX_grColorCombine_NoLock(GR_COMBINE_FUNCTION_LOCAL,
513 GR_COMBINE_FACTOR_NONE,
514 localc, GR_COMBINE_OTHER_NONE, FXFALSE);
515 else
516 FX_grColorCombine_NoLock(GR_COMBINE_FUNCTION_SCALE_OTHER,
517 GR_COMBINE_FACTOR_LOCAL,
518 localc, GR_COMBINE_OTHER_TEXTURE, FXFALSE);
519 break;
520 case GL_BLEND:
521 if (MESA_VERBOSE & VERBOSE_DRIVER)
522 fprintf(stderr, "fx Driver: GL_BLEND not yet supported\n");
523 break;
524 case GL_REPLACE:
525 if ((ifmt == GL_RGB) || (ifmt == GL_LUMINANCE))
526 FX_grAlphaCombine_NoLock(GR_COMBINE_FUNCTION_LOCAL,
527 GR_COMBINE_FACTOR_NONE,
528 locala, GR_COMBINE_OTHER_NONE, FXFALSE);
529 else
530 FX_grAlphaCombine_NoLock(GR_COMBINE_FUNCTION_SCALE_OTHER,
531 GR_COMBINE_FACTOR_ONE,
532 locala, GR_COMBINE_OTHER_TEXTURE, FXFALSE);
533
534 if (ifmt == GL_ALPHA)
535 FX_grColorCombine_NoLock(GR_COMBINE_FUNCTION_LOCAL,
536 GR_COMBINE_FACTOR_NONE,
537 localc, GR_COMBINE_OTHER_NONE, FXFALSE);
538 else
539 FX_grColorCombine_NoLock(GR_COMBINE_FUNCTION_SCALE_OTHER,
540 GR_COMBINE_FACTOR_ONE,
541 localc, GR_COMBINE_OTHER_TEXTURE, FXFALSE);
542 break;
543 default:
544 if (MESA_VERBOSE & VERBOSE_DRIVER)
545 fprintf(stderr, "fx Driver: %x Texture.EnvMode not yet supported\n",
546 ctx->Texture.Unit[textureset].EnvMode);
547 break;
548 }
549
550 if (MESA_VERBOSE & VERBOSE_DRIVER) {
551 fprintf(stderr, "fxmesa: fxSetupTextureSingleTMU(...) End\n");
552 }
553 }
554
555 #if 00
556 static void
557 fxSetupTextureSingleTMU(GLcontext * ctx, GLuint textureset)
558 {
559 BEGIN_BOARD_LOCK();
560 fxSetupTextureSingleTMU_NoLock(ctx, textureset);
561 END_BOARD_LOCK();
562 }
563 #endif
564
565
566 /************************* Double Texture Set ***************************/
567
568 static void
569 fxSetupDoubleTMU_NoLock(fxMesaContext fxMesa,
570 struct gl_texture_object *tObj0,
571 struct gl_texture_object *tObj1)
572 {
573 #define T0_NOT_IN_TMU 0x01
574 #define T1_NOT_IN_TMU 0x02
575 #define T0_IN_TMU0 0x04
576 #define T1_IN_TMU0 0x08
577 #define T0_IN_TMU1 0x10
578 #define T1_IN_TMU1 0x20
579
580 tfxTexInfo *ti0 = fxTMGetTexInfo(tObj0);
581 tfxTexInfo *ti1 = fxTMGetTexInfo(tObj1);
582 GLuint tstate = 0;
583 int tmu0 = 0, tmu1 = 1;
584
585 if (MESA_VERBOSE & VERBOSE_DRIVER) {
586 fprintf(stderr, "fxmesa: fxSetupDoubleTMU(...)\n");
587 }
588
589 /* We shouldn't need to do this. There is something wrong with
590 mutlitexturing when the TMUs are swapped. So, we're forcing
591 them to always be loaded correctly. !!! */
592 if (ti0->whichTMU == FX_TMU1)
593 fxTMMoveOutTM_NoLock(fxMesa, tObj0);
594 if (ti1->whichTMU == FX_TMU0)
595 fxTMMoveOutTM_NoLock(fxMesa, tObj1);
596
597 if (ti0->isInTM) {
598 switch (ti0->whichTMU) {
599 case FX_TMU0:
600 tstate |= T0_IN_TMU0;
601 break;
602 case FX_TMU1:
603 tstate |= T0_IN_TMU1;
604 break;
605 case FX_TMU_BOTH:
606 tstate |= T0_IN_TMU0 | T0_IN_TMU1;
607 break;
608 case FX_TMU_SPLIT:
609 tstate |= T0_NOT_IN_TMU;
610 break;
611 }
612 }
613 else
614 tstate |= T0_NOT_IN_TMU;
615
616 if (ti1->isInTM) {
617 switch (ti1->whichTMU) {
618 case FX_TMU0:
619 tstate |= T1_IN_TMU0;
620 break;
621 case FX_TMU1:
622 tstate |= T1_IN_TMU1;
623 break;
624 case FX_TMU_BOTH:
625 tstate |= T1_IN_TMU0 | T1_IN_TMU1;
626 break;
627 case FX_TMU_SPLIT:
628 tstate |= T1_NOT_IN_TMU;
629 break;
630 }
631 }
632 else
633 tstate |= T1_NOT_IN_TMU;
634
635 ti0->lastTimeUsed = fxMesa->texBindNumber;
636 ti1->lastTimeUsed = fxMesa->texBindNumber;
637
638 /* Move texture maps into TMUs */
639
640 if (!(((tstate & T0_IN_TMU0) && (tstate & T1_IN_TMU1)) ||
641 ((tstate & T0_IN_TMU1) && (tstate & T1_IN_TMU0)))) {
642 if (tObj0 == tObj1)
643 fxTMMoveInTM_NoLock(fxMesa, tObj1, FX_TMU_BOTH);
644 else {
645 /* Find the minimal way to correct the situation */
646 if ((tstate & T0_IN_TMU0) || (tstate & T1_IN_TMU1)) {
647 /* We have one in the standard order, setup the other */
648 if (tstate & T0_IN_TMU0) { /* T0 is in TMU0, put T1 in TMU1 */
649 fxTMMoveInTM_NoLock(fxMesa, tObj1, FX_TMU1);
650 }
651 else {
652 fxTMMoveInTM_NoLock(fxMesa, tObj0, FX_TMU0);
653 }
654 /* tmu0 and tmu1 are setup */
655 }
656 else if ((tstate & T0_IN_TMU1) || (tstate & T1_IN_TMU0)) {
657 /* we have one in the reverse order, setup the other */
658 if (tstate & T1_IN_TMU0) { /* T1 is in TMU0, put T0 in TMU1 */
659 fxTMMoveInTM_NoLock(fxMesa, tObj0, FX_TMU1);
660 }
661 else {
662 fxTMMoveInTM_NoLock(fxMesa, tObj1, FX_TMU0);
663 }
664 tmu0 = 1;
665 tmu1 = 0;
666 }
667 else { /* Nothing is loaded */
668 fxTMMoveInTM_NoLock(fxMesa, tObj0, FX_TMU0);
669 fxTMMoveInTM_NoLock(fxMesa, tObj1, FX_TMU1);
670 /* tmu0 and tmu1 are setup */
671 }
672 }
673 }
674
675 if (!fxMesa->haveGlobalPaletteTexture) {
676 if (ti0->info.format == GR_TEXFMT_P_8) {
677 if (MESA_VERBOSE & VERBOSE_DRIVER) {
678 fprintf(stderr, "fxmesa: uploading texture palette TMU0\n");
679 }
680 FX_grTexDownloadTable_NoLock(tmu0, GR_TEXTABLE_PALETTE,
681 &(ti0->palette));
682 }
683
684 if (ti1->info.format == GR_TEXFMT_P_8) {
685 if (MESA_VERBOSE & VERBOSE_DRIVER) {
686 fprintf(stderr, "fxmesa: uploading texture palette TMU1\n");
687 }
688 FX_grTexDownloadTable_NoLock(tmu1, GR_TEXTABLE_PALETTE,
689 &(ti1->palette));
690 }
691 }
692
693 FX_grTexSource_NoLock(tmu0, ti0->tm[tmu0]->startAddr,
694 GR_MIPMAPLEVELMASK_BOTH, &(ti0->info));
695 FX_grTexClampMode_NoLock(tmu0, ti0->sClamp, ti0->tClamp);
696 FX_grTexFilterMode_NoLock(tmu0, ti0->minFilt, ti0->maxFilt);
697 FX_grTexMipMapMode_NoLock(tmu0, ti0->mmMode, FXFALSE);
698
699 FX_grTexSource_NoLock(tmu1, ti1->tm[tmu1]->startAddr,
700 GR_MIPMAPLEVELMASK_BOTH, &(ti1->info));
701 FX_grTexClampMode_NoLock(tmu1, ti1->sClamp, ti1->tClamp);
702 FX_grTexFilterMode_NoLock(tmu1, ti1->minFilt, ti1->maxFilt);
703 FX_grTexMipMapMode_NoLock(tmu1, ti1->mmMode, FXFALSE);
704
705 #undef T0_NOT_IN_TMU
706 #undef T1_NOT_IN_TMU
707 #undef T0_IN_TMU0
708 #undef T1_IN_TMU0
709 #undef T0_IN_TMU1
710 #undef T1_IN_TMU1
711 }
712
713 static void
714 fxSetupTextureDoubleTMU_NoLock(GLcontext * ctx)
715 {
716 fxMesaContext fxMesa = (fxMesaContext) ctx->DriverCtx;
717 GrCombineLocal_t localc, locala;
718 tfxTexInfo *ti0, *ti1;
719 struct gl_texture_object *tObj0 = ctx->Texture.Unit[0].Current2D;
720 struct gl_texture_object *tObj1 = ctx->Texture.Unit[1].Current2D;
721 GLuint envmode, ifmt, unitsmode;
722 int tmu0 = 0, tmu1 = 1;
723
724 if (MESA_VERBOSE & VERBOSE_DRIVER) {
725 fprintf(stderr, "fxmesa: fxSetupTextureDoubleTMU(...) Start\n");
726 }
727
728 ti0 = fxTMGetTexInfo(tObj0);
729 fxTexValidate(ctx, tObj0);
730
731 ti1 = fxTMGetTexInfo(tObj1);
732 fxTexValidate(ctx, tObj1);
733
734 fxSetupDoubleTMU_NoLock(fxMesa, tObj0, tObj1);
735
736 unitsmode = fxGetTexSetConfiguration(ctx, tObj0, tObj1);
737
738 /* if(fxMesa->lastUnitsMode==unitsmode) */
739 /* return; */
740
741 fxMesa->lastUnitsMode = unitsmode;
742
743 fxMesa->stw_hint_state |= GR_STWHINT_ST_DIFF_TMU1;
744 FX_grHints_NoLock(GR_HINT_STWHINT, fxMesa->stw_hint_state);
745
746 envmode = unitsmode & FX_UM_E_ENVMODE;
747 ifmt = unitsmode & FX_UM_E_IFMT;
748
749 if (unitsmode & FX_UM_ALPHA_ITERATED)
750 locala = GR_COMBINE_LOCAL_ITERATED;
751 else
752 locala = GR_COMBINE_LOCAL_CONSTANT;
753
754 if (unitsmode & FX_UM_COLOR_ITERATED)
755 localc = GR_COMBINE_LOCAL_ITERATED;
756 else
757 localc = GR_COMBINE_LOCAL_CONSTANT;
758
759
760 if (MESA_VERBOSE & (VERBOSE_DRIVER | VERBOSE_TEXTURE))
761 fprintf(stderr, "fxMesa: fxSetupTextureDoubleTMU, envmode is %s/%s\n",
762 _mesa_lookup_enum_by_nr(ctx->Texture.Unit[0].EnvMode),
763 _mesa_lookup_enum_by_nr(ctx->Texture.Unit[1].EnvMode));
764
765
766 if ((ti0->whichTMU == FX_TMU1) || (ti1->whichTMU == FX_TMU0)) {
767 tmu0 = 1;
768 tmu1 = 0;
769 }
770 fxMesa->tmuSrc = FX_TMU_BOTH;
771 switch (envmode) {
772 case (FX_UM_E0_MODULATE | FX_UM_E1_MODULATE):
773 {
774 GLboolean isalpha[FX_NUM_TMU];
775
776 if (ti0->baseLevelInternalFormat == GL_ALPHA)
777 isalpha[tmu0] = GL_TRUE;
778 else
779 isalpha[tmu0] = GL_FALSE;
780
781 if (ti1->baseLevelInternalFormat == GL_ALPHA)
782 isalpha[tmu1] = GL_TRUE;
783 else
784 isalpha[tmu1] = GL_FALSE;
785
786 if (isalpha[FX_TMU1])
787 FX_grTexCombine_NoLock(GR_TMU1,
788 GR_COMBINE_FUNCTION_ZERO,
789 GR_COMBINE_FACTOR_NONE,
790 GR_COMBINE_FUNCTION_LOCAL,
791 GR_COMBINE_FACTOR_NONE, FXTRUE, FXFALSE);
792 else
793 FX_grTexCombine_NoLock(GR_TMU1,
794 GR_COMBINE_FUNCTION_LOCAL,
795 GR_COMBINE_FACTOR_NONE,
796 GR_COMBINE_FUNCTION_LOCAL,
797 GR_COMBINE_FACTOR_NONE, FXFALSE, FXFALSE);
798
799 if (isalpha[FX_TMU0])
800 FX_grTexCombine_NoLock(GR_TMU0,
801 GR_COMBINE_FUNCTION_BLEND_OTHER,
802 GR_COMBINE_FACTOR_ONE,
803 GR_COMBINE_FUNCTION_BLEND_OTHER,
804 GR_COMBINE_FACTOR_LOCAL, FXFALSE, FXFALSE);
805 else
806 FX_grTexCombine_NoLock(GR_TMU0,
807 GR_COMBINE_FUNCTION_BLEND_OTHER,
808 GR_COMBINE_FACTOR_LOCAL,
809 GR_COMBINE_FUNCTION_BLEND_OTHER,
810 GR_COMBINE_FACTOR_LOCAL, FXFALSE, FXFALSE);
811
812 FX_grColorCombine_NoLock(GR_COMBINE_FUNCTION_SCALE_OTHER,
813 GR_COMBINE_FACTOR_LOCAL,
814 localc, GR_COMBINE_OTHER_TEXTURE, FXFALSE);
815
816 FX_grAlphaCombine_NoLock(GR_COMBINE_FUNCTION_SCALE_OTHER,
817 GR_COMBINE_FACTOR_LOCAL,
818 locala, GR_COMBINE_OTHER_TEXTURE, FXFALSE);
819 break;
820 }
821 case (FX_UM_E0_REPLACE | FX_UM_E1_BLEND): /* Only for GLQuake */
822 if (tmu1 == FX_TMU1) {
823 FX_grTexCombine_NoLock(GR_TMU1,
824 GR_COMBINE_FUNCTION_LOCAL,
825 GR_COMBINE_FACTOR_NONE,
826 GR_COMBINE_FUNCTION_LOCAL,
827 GR_COMBINE_FACTOR_NONE, FXTRUE, FXFALSE);
828
829 FX_grTexCombine_NoLock(GR_TMU0,
830 GR_COMBINE_FUNCTION_BLEND_OTHER,
831 GR_COMBINE_FACTOR_LOCAL,
832 GR_COMBINE_FUNCTION_BLEND_OTHER,
833 GR_COMBINE_FACTOR_LOCAL, FXFALSE, FXFALSE);
834 }
835 else {
836 FX_grTexCombine_NoLock(GR_TMU1,
837 GR_COMBINE_FUNCTION_LOCAL,
838 GR_COMBINE_FACTOR_NONE,
839 GR_COMBINE_FUNCTION_LOCAL,
840 GR_COMBINE_FACTOR_NONE, FXFALSE, FXFALSE);
841
842 FX_grTexCombine_NoLock(GR_TMU0,
843 GR_COMBINE_FUNCTION_BLEND_OTHER,
844 GR_COMBINE_FACTOR_ONE_MINUS_LOCAL,
845 GR_COMBINE_FUNCTION_BLEND_OTHER,
846 GR_COMBINE_FACTOR_ONE_MINUS_LOCAL,
847 FXFALSE, FXFALSE);
848 }
849
850 FX_grAlphaCombine_NoLock(GR_COMBINE_FUNCTION_LOCAL,
851 GR_COMBINE_FACTOR_NONE,
852 locala, GR_COMBINE_OTHER_NONE, FXFALSE);
853
854 FX_grColorCombine_NoLock(GR_COMBINE_FUNCTION_SCALE_OTHER,
855 GR_COMBINE_FACTOR_ONE,
856 localc, GR_COMBINE_OTHER_TEXTURE, FXFALSE);
857 break;
858 case (FX_UM_E0_REPLACE | FX_UM_E1_MODULATE): /* Quake 2 and 3 */
859 if (tmu1 == FX_TMU1) {
860 FX_grTexCombine_NoLock(GR_TMU1,
861 GR_COMBINE_FUNCTION_LOCAL,
862 GR_COMBINE_FACTOR_NONE,
863 GR_COMBINE_FUNCTION_ZERO,
864 GR_COMBINE_FACTOR_NONE, FXFALSE, FXTRUE);
865
866 FX_grTexCombine_NoLock(GR_TMU0,
867 GR_COMBINE_FUNCTION_BLEND_OTHER,
868 GR_COMBINE_FACTOR_LOCAL,
869 GR_COMBINE_FUNCTION_BLEND_OTHER,
870 GR_COMBINE_FACTOR_LOCAL, FXFALSE, FXFALSE);
871
872 }
873 else {
874 FX_grTexCombine_NoLock(GR_TMU1,
875 GR_COMBINE_FUNCTION_LOCAL,
876 GR_COMBINE_FACTOR_NONE,
877 GR_COMBINE_FUNCTION_LOCAL,
878 GR_COMBINE_FACTOR_NONE, FXFALSE, FXFALSE);
879
880 FX_grTexCombine_NoLock(GR_TMU0,
881 GR_COMBINE_FUNCTION_BLEND_OTHER,
882 GR_COMBINE_FACTOR_LOCAL,
883 GR_COMBINE_FUNCTION_BLEND_OTHER,
884 GR_COMBINE_FACTOR_ONE, FXFALSE, FXFALSE);
885 }
886
887 if (ti0->baseLevelInternalFormat == GL_RGB)
888 FX_grAlphaCombine_NoLock(GR_COMBINE_FUNCTION_LOCAL,
889 GR_COMBINE_FACTOR_NONE,
890 locala, GR_COMBINE_OTHER_NONE, FXFALSE);
891 else
892 FX_grAlphaCombine_NoLock(GR_COMBINE_FUNCTION_SCALE_OTHER,
893 GR_COMBINE_FACTOR_ONE,
894 locala, GR_COMBINE_OTHER_NONE, FXFALSE);
895
896
897 FX_grColorCombine_NoLock(GR_COMBINE_FUNCTION_SCALE_OTHER,
898 GR_COMBINE_FACTOR_ONE,
899 localc, GR_COMBINE_OTHER_TEXTURE, FXFALSE);
900 break;
901
902
903 case (FX_UM_E0_MODULATE | FX_UM_E1_ADD): /* Quake 3 Sky */
904 {
905 GLboolean isalpha[FX_NUM_TMU];
906
907 if (ti0->baseLevelInternalFormat == GL_ALPHA)
908 isalpha[tmu0] = GL_TRUE;
909 else
910 isalpha[tmu0] = GL_FALSE;
911
912 if (ti1->baseLevelInternalFormat == GL_ALPHA)
913 isalpha[tmu1] = GL_TRUE;
914 else
915 isalpha[tmu1] = GL_FALSE;
916
917 if (isalpha[FX_TMU1])
918 FX_grTexCombine_NoLock(GR_TMU1,
919 GR_COMBINE_FUNCTION_ZERO,
920 GR_COMBINE_FACTOR_NONE,
921 GR_COMBINE_FUNCTION_LOCAL,
922 GR_COMBINE_FACTOR_NONE, FXTRUE, FXFALSE);
923 else
924 FX_grTexCombine_NoLock(GR_TMU1,
925 GR_COMBINE_FUNCTION_LOCAL,
926 GR_COMBINE_FACTOR_NONE,
927 GR_COMBINE_FUNCTION_LOCAL,
928 GR_COMBINE_FACTOR_NONE, FXFALSE, FXFALSE);
929
930 if (isalpha[FX_TMU0])
931 FX_grTexCombine_NoLock(GR_TMU0,
932 GR_COMBINE_FUNCTION_SCALE_OTHER,
933 GR_COMBINE_FACTOR_ONE,
934 GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL,
935 GR_COMBINE_FACTOR_ONE, FXFALSE, FXFALSE);
936 else
937 FX_grTexCombine_NoLock(GR_TMU0,
938 GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL,
939 GR_COMBINE_FACTOR_ONE,
940 GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL,
941 GR_COMBINE_FACTOR_ONE, FXFALSE, FXFALSE);
942
943 FX_grColorCombine_NoLock(GR_COMBINE_FUNCTION_SCALE_OTHER,
944 GR_COMBINE_FACTOR_LOCAL,
945 localc, GR_COMBINE_OTHER_TEXTURE, FXFALSE);
946
947 FX_grAlphaCombine_NoLock(GR_COMBINE_FUNCTION_SCALE_OTHER,
948 GR_COMBINE_FACTOR_LOCAL,
949 locala, GR_COMBINE_OTHER_TEXTURE, FXFALSE);
950 break;
951 }
952 default:
953 fprintf(stderr, "Unexpected dual texture mode encountered\n");
954 break;
955 }
956
957 if (MESA_VERBOSE & VERBOSE_DRIVER) {
958 fprintf(stderr, "fxmesa: fxSetupTextureDoubleTMU(...) End\n");
959 }
960 }
961
962 /************************* No Texture ***************************/
963
964 static void
965 fxSetupTextureNone_NoLock(GLcontext * ctx)
966 {
967 fxMesaContext fxMesa = (fxMesaContext) ctx->DriverCtx;
968 GrCombineLocal_t localc, locala;
969
970 if (MESA_VERBOSE & VERBOSE_DRIVER) {
971 fprintf(stderr, "fxmesa: fxSetupTextureNone(...)\n");
972 }
973
974 if ((ctx->Light.ShadeModel == GL_SMOOTH) || 1 ||
975 (ctx->Point.SmoothFlag) ||
976 (ctx->Line.SmoothFlag) ||
977 (ctx->Polygon.SmoothFlag)) locala = GR_COMBINE_LOCAL_ITERATED;
978 else
979 locala = GR_COMBINE_LOCAL_CONSTANT;
980
981 if (ctx->Light.ShadeModel == GL_SMOOTH || 1)
982 localc = GR_COMBINE_LOCAL_ITERATED;
983 else
984 localc = GR_COMBINE_LOCAL_CONSTANT;
985
986 FX_grAlphaCombine_NoLock(GR_COMBINE_FUNCTION_LOCAL,
987 GR_COMBINE_FACTOR_NONE,
988 locala, GR_COMBINE_OTHER_NONE, FXFALSE);
989
990 FX_grColorCombine_NoLock(GR_COMBINE_FUNCTION_LOCAL,
991 GR_COMBINE_FACTOR_NONE,
992 localc, GR_COMBINE_OTHER_NONE, FXFALSE);
993
994 fxMesa->lastUnitsMode = FX_UM_NONE;
995 }
996
997 /************************************************************************/
998 /************************** Texture Mode SetUp **************************/
999 /************************************************************************/
1000
1001 static void
1002 fxSetupTexture_NoLock(GLcontext * ctx)
1003 {
1004 fxMesaContext fxMesa = (fxMesaContext) ctx->DriverCtx;
1005
1006 if (MESA_VERBOSE & VERBOSE_DRIVER) {
1007 fprintf(stderr, "fxmesa: fxSetupTexture(...)\n");
1008 }
1009
1010 /* Texture Combine, Color Combine and Alpha Combine. */
1011 if (ctx->Texture.Unit[0]._ReallyEnabled == TEXTURE_2D_BIT &&
1012 ctx->Texture.Unit[1]._ReallyEnabled == TEXTURE_2D_BIT &&
1013 fxMesa->haveTwoTMUs) {
1014 fxSetupTextureDoubleTMU_NoLock(ctx);
1015 }
1016 else if (ctx->Texture.Unit[0]._ReallyEnabled == TEXTURE_2D_BIT) {
1017 fxSetupTextureSingleTMU_NoLock(ctx, 0);
1018 }
1019 else if (ctx->Texture.Unit[1]._ReallyEnabled == TEXTURE_2D_BIT) {
1020 fxSetupTextureSingleTMU_NoLock(ctx, 1);
1021 }
1022 else {
1023 fxSetupTextureNone_NoLock(ctx);
1024 }
1025 }
1026
1027 static void
1028 fxSetupTexture(GLcontext * ctx)
1029 {
1030 BEGIN_BOARD_LOCK();
1031 fxSetupTexture_NoLock(ctx);
1032 END_BOARD_LOCK();
1033 }
1034
1035 /************************************************************************/
1036 /**************************** Blend SetUp *******************************/
1037 /************************************************************************/
1038
1039 /* XXX consider supporting GL_INGR_blend_func_separate */
1040 void
1041 fxDDBlendFunc(GLcontext * ctx, GLenum sfactor, GLenum dfactor)
1042 {
1043 fxMesaContext fxMesa = (fxMesaContext) ctx->DriverCtx;
1044 tfxUnitsState *us = &fxMesa->unitsState;
1045 GrAlphaBlendFnc_t sfact, dfact, asfact, adfact;
1046
1047 /* From the Glide documentation:
1048 For alpha source and destination blend function factor
1049 parameters, Voodoo Graphics supports only
1050 GR_BLEND_ZERO and GR_BLEND_ONE.
1051 */
1052
1053 switch (sfactor) {
1054 case GL_ZERO:
1055 asfact = sfact = GR_BLEND_ZERO;
1056 break;
1057 case GL_ONE:
1058 asfact = sfact = GR_BLEND_ONE;
1059 break;
1060 case GL_DST_COLOR:
1061 sfact = GR_BLEND_DST_COLOR;
1062 asfact = GR_BLEND_ONE;
1063 break;
1064 case GL_ONE_MINUS_DST_COLOR:
1065 sfact = GR_BLEND_ONE_MINUS_DST_COLOR;
1066 asfact = GR_BLEND_ONE;
1067 break;
1068 case GL_SRC_ALPHA:
1069 sfact = GR_BLEND_SRC_ALPHA;
1070 asfact = GR_BLEND_ONE;
1071 break;
1072 case GL_ONE_MINUS_SRC_ALPHA:
1073 sfact = GR_BLEND_ONE_MINUS_SRC_ALPHA;
1074 asfact = GR_BLEND_ONE;
1075 break;
1076 case GL_DST_ALPHA:
1077 sfact = GR_BLEND_DST_ALPHA;
1078 asfact = GR_BLEND_ONE;
1079 break;
1080 case GL_ONE_MINUS_DST_ALPHA:
1081 sfact = GR_BLEND_ONE_MINUS_DST_ALPHA;
1082 asfact = GR_BLEND_ONE;
1083 break;
1084 case GL_SRC_ALPHA_SATURATE:
1085 sfact = GR_BLEND_ALPHA_SATURATE;
1086 asfact = GR_BLEND_ONE;
1087 break;
1088 case GL_SRC_COLOR:
1089 case GL_ONE_MINUS_SRC_COLOR:
1090 /* USELESS */
1091 asfact = sfact = GR_BLEND_ONE;
1092 break;
1093 default:
1094 asfact = sfact = GR_BLEND_ONE;
1095 break;
1096 }
1097
1098 if ((sfact != us->blendSrcFuncRGB) || (asfact != us->blendSrcFuncAlpha)) {
1099 us->blendSrcFuncRGB = sfact;
1100 us->blendSrcFuncAlpha = asfact;
1101 fxMesa->new_state |= FX_NEW_BLEND;
1102 }
1103
1104 switch (dfactor) {
1105 case GL_ZERO:
1106 adfact = dfact = GR_BLEND_ZERO;
1107 break;
1108 case GL_ONE:
1109 adfact = dfact = GR_BLEND_ONE;
1110 break;
1111 case GL_SRC_COLOR:
1112 dfact = GR_BLEND_SRC_COLOR;
1113 adfact = GR_BLEND_ZERO;
1114 break;
1115 case GL_ONE_MINUS_SRC_COLOR:
1116 dfact = GR_BLEND_ONE_MINUS_SRC_COLOR;
1117 adfact = GR_BLEND_ZERO;
1118 break;
1119 case GL_SRC_ALPHA:
1120 dfact = GR_BLEND_SRC_ALPHA;
1121 adfact = GR_BLEND_ZERO;
1122 break;
1123 case GL_ONE_MINUS_SRC_ALPHA:
1124 dfact = GR_BLEND_ONE_MINUS_SRC_ALPHA;
1125 adfact = GR_BLEND_ZERO;
1126 break;
1127 case GL_DST_ALPHA:
1128 /* dfact=GR_BLEND_DST_ALPHA; */
1129 /* We can't do DST_ALPHA */
1130 dfact = GR_BLEND_ONE;
1131 adfact = GR_BLEND_ZERO;
1132 break;
1133 case GL_ONE_MINUS_DST_ALPHA:
1134 /* dfact=GR_BLEND_ONE_MINUS_DST_ALPHA; */
1135 /* We can't do DST_ALPHA */
1136 dfact = GR_BLEND_ZERO;
1137 adfact = GR_BLEND_ZERO;
1138 break;
1139 case GL_SRC_ALPHA_SATURATE:
1140 case GL_DST_COLOR:
1141 case GL_ONE_MINUS_DST_COLOR:
1142 /* USELESS */
1143 adfact = dfact = GR_BLEND_ZERO;
1144 break;
1145 default:
1146 adfact = dfact = GR_BLEND_ZERO;
1147 break;
1148 }
1149
1150 if ((dfact != us->blendDstFuncRGB) || (adfact != us->blendDstFuncAlpha)) {
1151 us->blendDstFuncRGB = dfact;
1152 us->blendDstFuncAlpha = adfact;
1153 fxMesa->new_state |= FX_NEW_BLEND;
1154 }
1155 }
1156
1157 static void
1158 fxSetupBlend(GLcontext * ctx)
1159 {
1160 fxMesaContext fxMesa = (fxMesaContext) ctx->DriverCtx;
1161 tfxUnitsState *us = &fxMesa->unitsState;
1162
1163 if (us->blendEnabled)
1164 FX_grAlphaBlendFunction(us->blendSrcFuncRGB, us->blendDstFuncRGB,
1165 us->blendSrcFuncAlpha, us->blendDstFuncAlpha);
1166 else
1167 FX_grAlphaBlendFunction(GR_BLEND_ONE, GR_BLEND_ZERO, GR_BLEND_ONE,
1168 GR_BLEND_ZERO);
1169 }
1170
1171 /************************************************************************/
1172 /************************** Alpha Test SetUp ****************************/
1173 /************************************************************************/
1174
1175 void
1176 fxDDAlphaFunc(GLcontext * ctx, GLenum func, GLfloat ref)
1177 {
1178 fxMesaContext fxMesa = (fxMesaContext) ctx->DriverCtx;
1179 tfxUnitsState *us = &fxMesa->unitsState;
1180 GrCmpFnc_t newfunc;
1181
1182 switch (func) {
1183 case GL_NEVER:
1184 newfunc = GR_CMP_NEVER;
1185 break;
1186 case GL_LESS:
1187 newfunc = GR_CMP_LESS;
1188 break;
1189 case GL_EQUAL:
1190 newfunc = GR_CMP_EQUAL;
1191 break;
1192 case GL_LEQUAL:
1193 newfunc = GR_CMP_LEQUAL;
1194 break;
1195 case GL_GREATER:
1196 newfunc = GR_CMP_GREATER;
1197 break;
1198 case GL_NOTEQUAL:
1199 newfunc = GR_CMP_NOTEQUAL;
1200 break;
1201 case GL_GEQUAL:
1202 newfunc = GR_CMP_GEQUAL;
1203 break;
1204 case GL_ALWAYS:
1205 newfunc = GR_CMP_ALWAYS;
1206 break;
1207 default:
1208 fprintf(stderr, "fx Driver: internal error in fxDDAlphaFunc()\n");
1209 fxCloseHardware();
1210 exit(-1);
1211 break;
1212 }
1213
1214 if (newfunc != us->alphaTestFunc) {
1215 us->alphaTestFunc = newfunc;
1216 fxMesa->new_state |= FX_NEW_ALPHA;
1217 }
1218
1219 if (ref != us->alphaTestRefValue) {
1220 us->alphaTestRefValue = ref;
1221 fxMesa->new_state |= FX_NEW_ALPHA;
1222 }
1223 }
1224
1225 static void
1226 fxSetupAlphaTest(GLcontext * ctx)
1227 {
1228 fxMesaContext fxMesa = (fxMesaContext) ctx->DriverCtx;
1229 tfxUnitsState *us = &fxMesa->unitsState;
1230
1231 if (us->alphaTestEnabled) {
1232 GrAlpha_t ref = (GLint) (us->alphaTestRefValue * 255.0);
1233 FX_grAlphaTestFunction(us->alphaTestFunc);
1234 FX_grAlphaTestReferenceValue(ref);
1235 }
1236 else
1237 FX_grAlphaTestFunction(GR_CMP_ALWAYS);
1238 }
1239
1240 /************************************************************************/
1241 /************************** Depth Test SetUp ****************************/
1242 /************************************************************************/
1243
1244 void
1245 fxDDDepthFunc(GLcontext * ctx, GLenum func)
1246 {
1247 fxMesaContext fxMesa = (fxMesaContext) ctx->DriverCtx;
1248 tfxUnitsState *us = &fxMesa->unitsState;
1249 GrCmpFnc_t dfunc;
1250
1251 switch (func) {
1252 case GL_NEVER:
1253 dfunc = GR_CMP_NEVER;
1254 break;
1255 case GL_LESS:
1256 dfunc = GR_CMP_LESS;
1257 break;
1258 case GL_GEQUAL:
1259 dfunc = GR_CMP_GEQUAL;
1260 break;
1261 case GL_LEQUAL:
1262 dfunc = GR_CMP_LEQUAL;
1263 break;
1264 case GL_GREATER:
1265 dfunc = GR_CMP_GREATER;
1266 break;
1267 case GL_NOTEQUAL:
1268 dfunc = GR_CMP_NOTEQUAL;
1269 break;
1270 case GL_EQUAL:
1271 dfunc = GR_CMP_EQUAL;
1272 break;
1273 case GL_ALWAYS:
1274 dfunc = GR_CMP_ALWAYS;
1275 break;
1276 default:
1277 fprintf(stderr, "fx Driver: internal error in fxDDDepthFunc()\n");
1278 fxCloseHardware();
1279 exit(-1);
1280 break;
1281 }
1282
1283 if (dfunc != us->depthTestFunc) {
1284 us->depthTestFunc = dfunc;
1285 fxMesa->new_state |= FX_NEW_DEPTH;
1286 }
1287
1288 }
1289
1290 void
1291 fxDDDepthMask(GLcontext * ctx, GLboolean flag)
1292 {
1293 fxMesaContext fxMesa = (fxMesaContext) ctx->DriverCtx;
1294 tfxUnitsState *us = &fxMesa->unitsState;
1295
1296 if (flag != us->depthMask) {
1297 us->depthMask = flag;
1298 fxMesa->new_state |= FX_NEW_DEPTH;
1299 }
1300 }
1301
1302 static void
1303 fxSetupDepthTest(GLcontext * ctx)
1304 {
1305 fxMesaContext fxMesa = (fxMesaContext) ctx->DriverCtx;
1306 tfxUnitsState *us = &fxMesa->unitsState;
1307
1308 if (us->depthTestEnabled) {
1309 FX_grDepthBufferFunction(us->depthTestFunc);
1310 FX_grDepthMask(us->depthMask);
1311 }
1312 else {
1313 FX_grDepthBufferFunction(GR_CMP_ALWAYS);
1314 FX_grDepthMask(FXFALSE);
1315 }
1316 }
1317
1318 /************************************************************************/
1319 /**************************** Color Mask SetUp **************************/
1320 /************************************************************************/
1321
1322 void
1323 fxDDColorMask(GLcontext * ctx,
1324 GLboolean r, GLboolean g, GLboolean b, GLboolean a)
1325 {
1326 fxMesaContext fxMesa = (fxMesaContext) ctx->DriverCtx;
1327 fxMesa->new_state |= FX_NEW_COLOR_MASK;
1328 (void) r;
1329 (void) g;
1330 (void) b;
1331 (void) a;
1332 }
1333
1334 static void
1335 fxSetupColorMask(GLcontext * ctx)
1336 {
1337 fxMesaContext fxMesa = FX_CONTEXT(ctx);
1338
1339 if (ctx->Color.DrawBuffer == GL_NONE) {
1340 FX_grColorMask(FXFALSE, FXFALSE);
1341 }
1342 else {
1343 FX_grColorMask(ctx->Color.ColorMask[RCOMP] ||
1344 ctx->Color.ColorMask[GCOMP] ||
1345 ctx->Color.ColorMask[BCOMP],
1346 ctx->Color.ColorMask[ACOMP] && fxMesa->haveAlphaBuffer);
1347 }
1348 }
1349
1350
1351
1352
1353 /************************************************************************/
1354 /**************************** Fog Mode SetUp ****************************/
1355 /************************************************************************/
1356
1357 /*
1358 * This is called during state update in order to update the Glide fog state.
1359 */
1360 static void
1361 fxSetupFog(GLcontext * ctx)
1362 {
1363 if (ctx->Fog.Enabled /*&& ctx->FogMode==FOG_FRAGMENT */ ) {
1364 fxMesaContext fxMesa = FX_CONTEXT(ctx);
1365
1366 /* update fog color */
1367 GLubyte col[4];
1368 col[0] = (unsigned int) (255 * ctx->Fog.Color[0]);
1369 col[1] = (unsigned int) (255 * ctx->Fog.Color[1]);
1370 col[2] = (unsigned int) (255 * ctx->Fog.Color[2]);
1371 col[3] = (unsigned int) (255 * ctx->Fog.Color[3]);
1372 FX_grFogColorValue(FXCOLOR4(col));
1373
1374 if (fxMesa->fogTableMode != ctx->Fog.Mode ||
1375 fxMesa->fogDensity != ctx->Fog.Density ||
1376 fxMesa->fogStart != ctx->Fog.Start ||
1377 fxMesa->fogEnd != ctx->Fog.End) {
1378 /* reload the fog table */
1379 switch (ctx->Fog.Mode) {
1380 case GL_LINEAR:
1381 guFogGenerateLinear(fxMesa->fogTable, ctx->Fog.Start,
1382 ctx->Fog.End);
1383 break;
1384 case GL_EXP:
1385 guFogGenerateExp(fxMesa->fogTable, ctx->Fog.Density);
1386 break;
1387 case GL_EXP2:
1388 guFogGenerateExp2(fxMesa->fogTable, ctx->Fog.Density);
1389 break;
1390 default:
1391 ;
1392 }
1393 fxMesa->fogTableMode = ctx->Fog.Mode;
1394 fxMesa->fogDensity = ctx->Fog.Density;
1395 fxMesa->fogStart = ctx->Fog.Start;
1396 fxMesa->fogEnd = ctx->Fog.End;
1397 }
1398
1399 FX_grFogTable(fxMesa->fogTable);
1400 FX_grFogMode(GR_FOG_WITH_TABLE);
1401 }
1402 else {
1403 FX_grFogMode(GR_FOG_DISABLE);
1404 }
1405 }
1406
1407 void
1408 fxDDFogfv(GLcontext * ctx, GLenum pname, const GLfloat * params)
1409 {
1410 FX_CONTEXT(ctx)->new_state |= FX_NEW_FOG;
1411 }
1412
1413 /************************************************************************/
1414 /************************** Scissor Test SetUp **************************/
1415 /************************************************************************/
1416
1417 /* This routine is used in managing the lock state, and therefore can't lock */
1418 void
1419 fxSetScissorValues(GLcontext * ctx)
1420 {
1421 fxMesaContext fxMesa = (fxMesaContext) ctx->DriverCtx;
1422 int xmin, xmax;
1423 int ymin, ymax, check;
1424
1425 if (ctx->Scissor.Enabled) {
1426 xmin = ctx->Scissor.X;
1427 xmax = ctx->Scissor.X + ctx->Scissor.Width;
1428 ymin = ctx->Scissor.Y;
1429 ymax = ctx->Scissor.Y + ctx->Scissor.Height;
1430 check = 1;
1431 }
1432 else {
1433 xmin = 0;
1434 ymin = 0;
1435 xmax = fxMesa->width;
1436 ymax = fxMesa->height;
1437 check = 0;
1438 }
1439 if (xmin < fxMesa->clipMinX)
1440 xmin = fxMesa->clipMinX;
1441 if (xmax > fxMesa->clipMaxX)
1442 xmax = fxMesa->clipMaxX;
1443 if (ymin < fxMesa->screen_height - fxMesa->clipMaxY)
1444 ymin = fxMesa->screen_height - fxMesa->clipMaxY;
1445 if (ymax > fxMesa->screen_height - fxMesa->clipMinY)
1446 ymax = fxMesa->screen_height - fxMesa->clipMinY;
1447 FX_grClipWindow_NoLock(xmin, ymin, xmax, ymax);
1448 }
1449
1450 static void
1451 fxSetupScissor(GLcontext * ctx)
1452 {
1453 BEGIN_BOARD_LOCK();
1454 fxSetScissorValues(ctx);
1455 END_BOARD_LOCK();
1456 }
1457
1458 void
1459 fxDDScissor(GLcontext * ctx, GLint x, GLint y, GLsizei w, GLsizei h)
1460 {
1461 FX_CONTEXT(ctx)->new_state |= FX_NEW_SCISSOR;
1462 }
1463
1464 /************************************************************************/
1465 /*************************** Cull mode setup ****************************/
1466 /************************************************************************/
1467
1468
1469 void
1470 fxDDCullFace(GLcontext * ctx, GLenum mode)
1471 {
1472 (void) mode;
1473 FX_CONTEXT(ctx)->new_state |= FX_NEW_CULL;
1474 }
1475
1476 void
1477 fxDDFrontFace(GLcontext * ctx, GLenum mode)
1478 {
1479 (void) mode;
1480 FX_CONTEXT(ctx)->new_state |= FX_NEW_CULL;
1481 }
1482
1483
1484 static void
1485 fxSetupCull(GLcontext * ctx)
1486 {
1487 if (ctx->Polygon.CullFlag) {
1488 switch (ctx->Polygon.CullFaceMode) {
1489 case GL_BACK:
1490 if (ctx->Polygon.FrontFace == GL_CCW)
1491 FX_CONTEXT(ctx)->cullMode = GR_CULL_NEGATIVE;
1492 else
1493 FX_CONTEXT(ctx)->cullMode = GR_CULL_POSITIVE;
1494 break;
1495 case GL_FRONT:
1496 if (ctx->Polygon.FrontFace == GL_CCW)
1497 FX_CONTEXT(ctx)->cullMode = GR_CULL_POSITIVE;
1498 else
1499 FX_CONTEXT(ctx)->cullMode = GR_CULL_NEGATIVE;
1500 break;
1501 case GL_FRONT_AND_BACK:
1502 FX_CONTEXT(ctx)->cullMode = GR_CULL_DISABLE;
1503 break;
1504 default:
1505 break;
1506 }
1507 }
1508 else
1509 FX_CONTEXT(ctx)->cullMode = GR_CULL_DISABLE;
1510
1511 if (FX_CONTEXT(ctx)->raster_primitive == GL_TRIANGLES)
1512 FX_grCullMode(FX_CONTEXT(ctx)->cullMode);
1513 }
1514
1515
1516 /************************************************************************/
1517 /****************************** DD Enable ******************************/
1518 /************************************************************************/
1519
1520 void
1521 fxDDEnable(GLcontext * ctx, GLenum cap, GLboolean state)
1522 {
1523 fxMesaContext fxMesa = (fxMesaContext) ctx->DriverCtx;
1524 tfxUnitsState *us = &fxMesa->unitsState;
1525
1526 if (MESA_VERBOSE & VERBOSE_DRIVER) {
1527 fprintf(stderr, "fxmesa: fxDDEnable(...)\n");
1528 }
1529
1530 switch (cap) {
1531 case GL_ALPHA_TEST:
1532 if (state != us->alphaTestEnabled) {
1533 us->alphaTestEnabled = state;
1534 fxMesa->new_state |= FX_NEW_ALPHA;
1535 }
1536 break;
1537 case GL_BLEND:
1538 if (state != us->blendEnabled) {
1539 us->blendEnabled = state;
1540 fxMesa->new_state |= FX_NEW_BLEND;
1541 }
1542 break;
1543 case GL_DEPTH_TEST:
1544 if (state != us->depthTestEnabled) {
1545 us->depthTestEnabled = state;
1546 fxMesa->new_state |= FX_NEW_DEPTH;
1547 }
1548 break;
1549 case GL_DITHER:
1550 if (state) {
1551 FX_grDitherMode(GR_DITHER_4x4);
1552 }
1553 else {
1554 FX_grDitherMode(GR_DITHER_DISABLE);
1555 }
1556 break;
1557 case GL_SCISSOR_TEST:
1558 fxMesa->new_state |= FX_NEW_SCISSOR;
1559 break;
1560 case GL_SHARED_TEXTURE_PALETTE_EXT:
1561 fxDDTexUseGlbPalette(ctx, state);
1562 break;
1563 case GL_FOG:
1564 fxMesa->new_state |= FX_NEW_FOG;
1565 break;
1566 case GL_CULL_FACE:
1567 fxMesa->new_state |= FX_NEW_CULL;
1568 break;
1569 case GL_LINE_SMOOTH:
1570 case GL_LINE_STIPPLE:
1571 case GL_POINT_SMOOTH:
1572 case GL_POLYGON_SMOOTH:
1573 case GL_TEXTURE_2D:
1574 fxMesa->new_state |= FX_NEW_TEXTURING;
1575 break;
1576 default:
1577 ; /* XXX no-op? */
1578 }
1579 }
1580
1581
1582
1583
1584 /************************************************************************/
1585 /************************** Changes to units state **********************/
1586 /************************************************************************/
1587
1588
1589 /* All units setup is handled under texture setup.
1590 */
1591 void
1592 fxDDShadeModel(GLcontext * ctx, GLenum mode)
1593 {
1594 FX_CONTEXT(ctx)->new_state |= FX_NEW_TEXTURING;
1595 }
1596
1597
1598
1599 /************************************************************************/
1600 /****************************** Units SetUp *****************************/
1601 /************************************************************************/
1602 static void
1603 fx_print_state_flags(const char *msg, GLuint flags)
1604 {
1605 fprintf(stderr,
1606 "%s: (0x%x) %s%s%s%s%s%s%s\n",
1607 msg,
1608 flags,
1609 (flags & FX_NEW_TEXTURING) ? "texture, " : "",
1610 (flags & FX_NEW_BLEND) ? "blend, " : "",
1611 (flags & FX_NEW_ALPHA) ? "alpha, " : "",
1612 (flags & FX_NEW_FOG) ? "fog, " : "",
1613 (flags & FX_NEW_SCISSOR) ? "scissor, " : "",
1614 (flags & FX_NEW_COLOR_MASK) ? "colormask, " : "",
1615 (flags & FX_NEW_CULL) ? "cull, " : "");
1616 }
1617
1618 void
1619 fxSetupFXUnits(GLcontext * ctx)
1620 {
1621 fxMesaContext fxMesa = (fxMesaContext) ctx->DriverCtx;
1622 GLuint newstate = fxMesa->new_state;
1623
1624 if (MESA_VERBOSE & VERBOSE_DRIVER)
1625 fx_print_state_flags("fxmesa: fxSetupFXUnits", newstate);
1626
1627 if (newstate) {
1628 if (newstate & FX_NEW_TEXTURING)
1629 fxSetupTexture(ctx);
1630
1631 if (newstate & FX_NEW_BLEND)
1632 fxSetupBlend(ctx);
1633
1634 if (newstate & FX_NEW_ALPHA)
1635 fxSetupAlphaTest(ctx);
1636
1637 if (newstate & FX_NEW_DEPTH)
1638 fxSetupDepthTest(ctx);
1639
1640 if (newstate & FX_NEW_FOG)
1641 fxSetupFog(ctx);
1642
1643 if (newstate & FX_NEW_SCISSOR)
1644 fxSetupScissor(ctx);
1645
1646 if (newstate & FX_NEW_COLOR_MASK)
1647 fxSetupColorMask(ctx);
1648
1649 if (newstate & FX_NEW_CULL)
1650 fxSetupCull(ctx);
1651
1652 fxMesa->new_state = 0;
1653 }
1654 }
1655
1656
1657
1658 #else
1659
1660
1661 /*
1662 * Need this to provide at least one external definition.
1663 */
1664
1665 extern int gl_fx_dummy_function_setup(void);
1666 int
1667 gl_fx_dummy_function_setup(void)
1668 {
1669 return 0;
1670 }
1671
1672 #endif /* FX */