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