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