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