source: trunk/src/opengl/mesa/3dfx/fxsetup.c

Last change on this file was 3598, checked in by jeroen, 25 years ago

* empty log message *

File size: 56.2 KB
Line 
1/* -*- mode: C; tab-width:8; c-basic-offset:2 -*- */
2
3/*
4 * Mesa 3-D graphics library
5 * Version: 3.3
6 *
7 * Copyright (C) 1999 Brian Paul All Rights Reserved.
8 *
9 * Permission is hereby granted, free of charge, to any person obtaining a
10 * copy of this software and associated documentation files (the "Software"),
11 * to deal in the Software without restriction, including without limitation
12 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
13 * and/or sell copies of the Software, and to permit persons to whom the
14 * Software is furnished to do so, subject to the following conditions:
15 *
16 * The above copyright notice and this permission notice shall be included
17 * in all copies or substantial portions of the Software.
18 *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
22 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
23 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
24 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 *
26 *
27 * Original Mesa / 3Dfx device driver (C) 1999 David Bucciarelli, by the
28 * terms stated above.
29 *
30 * Thank you for your contribution, David!
31 *
32 * Please make note of the above copyright/license statement. If you
33 * contributed code or bug fixes to this code under the previous (GNU
34 * Library) license and object to the new license, your code will be
35 * removed at your request. Please see the Mesa docs/COPYRIGHT file
36 * for more information.
37 *
38 * Additional Mesa/3Dfx driver developers:
39 * Daryll Strauss <daryll@precisioninsight.com>
40 * Keith Whitwell <keith@precisioninsight.com>
41 *
42 * See fxapi.h for more revision/author details.
43 */
44
45
46/* fxsetup.c - 3Dfx VooDoo rendering mode setup functions */
47
48
49#ifdef HAVE_CONFIG_H
50#include "conf.h"
51#endif
52
53#if defined(FX)
54
55#include "fxdrv.h"
56#include "enums.h"
57
58static GLuint fxGetTexSetConfiguration(GLcontext *ctx,
59 struct gl_texture_object *tObj0,
60 struct gl_texture_object *tObj1);
61static void fxSetupTextureSingleTMU_NoLock(GLcontext *ctx, GLuint textureset);
62static void fxSetupDoubleTMU_NoLock(fxMesaContext fxMesa,
63 struct gl_texture_object *tObj0,
64 struct gl_texture_object *tObj1);
65static void fxSetupTexture_NoLock(GLcontext *ctx);
66static void fxSetupTexture(GLcontext *ctx);
67static void fxSetupBlend(GLcontext *ctx);
68static void fxSetupDepthTest(GLcontext *ctx);
69static void fxSetupScissor(GLcontext *ctx);
70static void fxSetupCull(GLcontext *ctx);
71static void gl_print_fx_state_flags( const char *msg, GLuint flags);
72/*static GLboolean fxMultipassBlend(struct vertex_buffer *, GLuint);*/
73static GLboolean fxMultipassTexture( struct vertex_buffer *, GLuint );
74
75static void fxTexValidate(GLcontext *ctx, struct gl_texture_object *tObj)
76{
77 tfxTexInfo *ti=fxTMGetTexInfo(tObj);
78 GLint minl, maxl;
79
80 if (MESA_VERBOSE&VERBOSE_DRIVER) {
81 fprintf(stderr,"fxmesa: fxTexValidate(...) Start\n");
82 }
83
84 if(ti->validated) {
85 if (MESA_VERBOSE&VERBOSE_DRIVER) {
86 fprintf(stderr,"fxmesa: fxTexValidate(...) End (validated=GL_TRUE)\n");
87 }
88 return;
89 }
90
91 ti->tObj=tObj;
92 minl=ti->minLevel=tObj->BaseLevel;
93 maxl=ti->maxLevel=MIN2(tObj->MaxLevel,tObj->Image[0]->MaxLog2);
94
95 fxTexGetInfo(tObj->Image[minl]->Width, tObj->Image[minl]->Height,
96 &(FX_largeLodLog2(ti->info)), &(FX_aspectRatioLog2(ti->info)),
97 &(ti->sScale), &(ti->tScale),
98 &(ti->int_sScale), &(ti->int_tScale),
99 NULL, NULL);
100
101 if((tObj->MinFilter!=GL_NEAREST) && (tObj->MinFilter!=GL_LINEAR))
102 fxTexGetInfo(tObj->Image[maxl]->Width,tObj->Image[maxl]->Height,
103 &(FX_smallLodLog2(ti->info)),NULL,
104 NULL,NULL,
105 NULL,NULL,
106 NULL,NULL);
107 else
108 FX_smallLodLog2(ti->info)=FX_largeLodLog2(ti->info);
109
110 fxTexGetFormat(tObj->Image[minl]->IntFormat,&(ti->info.format),&(ti->baseLevelInternalFormat));
111
112 switch (tObj->WrapS) {
113 case GL_CLAMP_TO_EDGE:
114 /* What's this really mean compared to GL_CLAMP? */
115 case GL_CLAMP:
116 ti->sClamp=1;
117 break;
118 case GL_REPEAT:
119 ti->sClamp=0;
120 break;
121 default:
122 ;
123 }
124 switch (tObj->WrapT) {
125 case GL_CLAMP_TO_EDGE:
126 /* What's this really mean compared to GL_CLAMP? */
127 case GL_CLAMP:
128 ti->tClamp=1;
129 break;
130 case GL_REPEAT:
131 ti->tClamp=0;
132 break;
133 default:
134 ;
135 }
136
137 ti->validated=GL_TRUE;
138
139 ti->info.data=NULL;
140
141 if (MESA_VERBOSE&VERBOSE_DRIVER) {
142 fprintf(stderr,"fxmesa: fxTexValidate(...) End\n");
143 }
144}
145
146static void fxPrintUnitsMode( const char *msg, GLuint mode )
147{
148 fprintf(stderr,
149 "%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",
150 msg,
151 mode,
152 (mode & FX_UM_E0_REPLACE) ? "E0_REPLACE, " : "",
153 (mode & FX_UM_E0_MODULATE) ? "E0_MODULATE, " : "",
154 (mode & FX_UM_E0_DECAL) ? "E0_DECAL, " : "",
155 (mode & FX_UM_E0_BLEND) ? "E0_BLEND, " : "",
156 (mode & FX_UM_E1_REPLACE) ? "E1_REPLACE, " : "",
157 (mode & FX_UM_E1_MODULATE) ? "E1_MODULATE, " : "",
158 (mode & FX_UM_E1_DECAL) ? "E1_DECAL, " : "",
159 (mode & FX_UM_E1_BLEND) ? "E1_BLEND, " : "",
160 (mode & FX_UM_E0_ALPHA) ? "E0_ALPHA, " : "",
161 (mode & FX_UM_E0_LUMINANCE) ? "E0_LUMINANCE, " : "",
162 (mode & FX_UM_E0_LUMINANCE_ALPHA) ? "E0_LUMINANCE_ALPHA, " : "",
163 (mode & FX_UM_E0_INTENSITY) ? "E0_INTENSITY, " : "",
164 (mode & FX_UM_E0_RGB) ? "E0_RGB, " : "",
165 (mode & FX_UM_E0_RGBA) ? "E0_RGBA, " : "",
166 (mode & FX_UM_E1_ALPHA) ? "E1_ALPHA, " : "",
167 (mode & FX_UM_E1_LUMINANCE) ? "E1_LUMINANCE, " : "",
168 (mode & FX_UM_E1_LUMINANCE_ALPHA) ? "E1_LUMINANCE_ALPHA, " : "",
169 (mode & FX_UM_E1_INTENSITY) ? "E1_INTENSITY, " : "",
170 (mode & FX_UM_E1_RGB) ? "E1_RGB, " : "",
171 (mode & FX_UM_E1_RGBA) ? "E1_RGBA, " : "",
172 (mode & FX_UM_COLOR_ITERATED) ? "COLOR_ITERATED, " : "",
173 (mode & FX_UM_COLOR_CONSTANT) ? "COLOR_CONSTANT, " : "",
174 (mode & FX_UM_ALPHA_ITERATED) ? "ALPHA_ITERATED, " : "",
175 (mode & FX_UM_ALPHA_CONSTANT) ? "ALPHA_CONSTANT, " : "");
176}
177
178static GLuint fxGetTexSetConfiguration(GLcontext *ctx,
179 struct gl_texture_object *tObj0,
180 struct gl_texture_object *tObj1)
181{
182 GLuint unitsmode=0;
183 GLuint envmode=0;
184 GLuint ifmt=0;
185
186 if((ctx->Light.ShadeModel==GL_SMOOTH) ||
187 (ctx->Point.SmoothFlag) ||
188 (ctx->Line.SmoothFlag) ||
189 (ctx->Polygon.SmoothFlag))
190 unitsmode|=FX_UM_ALPHA_ITERATED;
191 else
192 unitsmode|=FX_UM_ALPHA_CONSTANT;
193
194 if(ctx->Light.ShadeModel==GL_SMOOTH)
195 unitsmode|=FX_UM_COLOR_ITERATED;
196 else
197 unitsmode|=FX_UM_COLOR_CONSTANT;
198
199 /*
200 OpenGL Feeds Texture 0 into Texture 1
201 Glide Feeds Texture 1 into Texture 0
202 */
203 if(tObj0) {
204 tfxTexInfo *ti0=fxTMGetTexInfo(tObj0);
205
206 switch(ti0->baseLevelInternalFormat) {
207 case GL_ALPHA:
208 ifmt|=FX_UM_E0_ALPHA;
209 break;
210 case GL_LUMINANCE:
211 ifmt|=FX_UM_E0_LUMINANCE;
212 break;
213 case GL_LUMINANCE_ALPHA:
214 ifmt|=FX_UM_E0_LUMINANCE_ALPHA;
215 break;
216 case GL_INTENSITY:
217 ifmt|=FX_UM_E0_INTENSITY;
218 break;
219 case GL_RGB:
220 ifmt|=FX_UM_E0_RGB;
221 break;
222 case GL_RGBA:
223 ifmt|=FX_UM_E0_RGBA;
224 break;
225 }
226
227 switch(ctx->Texture.Unit[0].EnvMode) {
228 case GL_DECAL:
229 envmode|=FX_UM_E0_DECAL;
230 break;
231 case GL_MODULATE:
232 envmode|=FX_UM_E0_MODULATE;
233 break;
234 case GL_REPLACE:
235 envmode|=FX_UM_E0_REPLACE;
236 break;
237 case GL_BLEND:
238 envmode|=FX_UM_E0_BLEND;
239 break;
240 case GL_ADD:
241 envmode|=FX_UM_E0_ADD;
242 break;
243 default:
244 /* do nothing */
245 break;
246 }
247 }
248
249 if(tObj1) {
250 tfxTexInfo *ti1=fxTMGetTexInfo(tObj1);
251
252 switch(ti1->baseLevelInternalFormat) {
253 case GL_ALPHA:
254 ifmt|=FX_UM_E1_ALPHA;
255 break;
256 case GL_LUMINANCE:
257 ifmt|=FX_UM_E1_LUMINANCE;
258 break;
259 case GL_LUMINANCE_ALPHA:
260 ifmt|=FX_UM_E1_LUMINANCE_ALPHA;
261 break;
262 case GL_INTENSITY:
263 ifmt|=FX_UM_E1_INTENSITY;
264 break;
265 case GL_RGB:
266 ifmt|=FX_UM_E1_RGB;
267 break;
268 case GL_RGBA:
269 ifmt|=FX_UM_E1_RGBA;
270 break;
271 default:
272 /* do nothing */
273 break;
274 }
275
276 switch(ctx->Texture.Unit[1].EnvMode) {
277 case GL_DECAL:
278 envmode|=FX_UM_E1_DECAL;
279 break;
280 case GL_MODULATE:
281 envmode|=FX_UM_E1_MODULATE;
282 break;
283 case GL_REPLACE:
284 envmode|=FX_UM_E1_REPLACE;
285 break;
286 case GL_BLEND:
287 envmode|=FX_UM_E1_BLEND;
288 break;
289 case GL_ADD:
290 envmode|=FX_UM_E1_ADD;
291 break;
292 default:
293 /* do nothing */
294 break;
295 }
296 }
297
298 unitsmode|=(ifmt | envmode);
299
300 if (MESA_VERBOSE & (VERBOSE_DRIVER|VERBOSE_TEXTURE))
301 fxPrintUnitsMode("unitsmode", unitsmode);
302
303 return unitsmode;
304}
305
306/************************************************************************/
307/************************* Rendering Mode SetUp *************************/
308/************************************************************************/
309
310/************************* Single Texture Set ***************************/
311
312static void fxSetupSingleTMU_NoLock(fxMesaContext fxMesa, struct gl_texture_object *tObj)
313{
314 tfxTexInfo *ti=fxTMGetTexInfo(tObj);
315 int tmu;
316
317 /* Make sure we're not loaded incorrectly */
318 if (ti->isInTM) {
319 if (ti->LODblend) {
320 if (ti->whichTMU!=FX_TMU_SPLIT)
321 fxTMMoveOutTM(fxMesa, tObj);
322 } else {
323 if (ti->whichTMU==FX_TMU_SPLIT)
324 fxTMMoveOutTM(fxMesa, tObj);
325 }
326 }
327
328 /* Make sure we're loaded correctly */
329 if (!ti->isInTM) {
330 if (ti->LODblend)
331 fxTMMoveInTM_NoLock(fxMesa,tObj,FX_TMU_SPLIT);
332 else {
333 if (fxMesa->haveTwoTMUs) {
334 if (fxMesa->freeTexMem[FX_TMU0] >
335 FX_grTexTextureMemRequired_NoLock(GR_MIPMAPLEVELMASK_BOTH,
336 &(ti->info))) {
337 fxTMMoveInTM_NoLock(fxMesa,tObj, FX_TMU0);
338 } else {
339 fxTMMoveInTM_NoLock(fxMesa,tObj, FX_TMU1);
340 }
341 } else
342 fxTMMoveInTM_NoLock(fxMesa,tObj,FX_TMU0);
343 }
344 }
345
346 if (ti->LODblend && ti->whichTMU == FX_TMU_SPLIT) {
347 if ((ti->info.format==GR_TEXFMT_P_8) && (!fxMesa->haveGlobalPaletteTexture)) {
348 if (MESA_VERBOSE&VERBOSE_DRIVER) {
349 fprintf(stderr,"fxmesa: uploading texture palette\n");
350 }
351 FX_grTexDownloadTable_NoLock(GR_TMU0,GR_TEXTABLE_PALETTE,&(ti->palette));
352 FX_grTexDownloadTable_NoLock(GR_TMU1,GR_TEXTABLE_PALETTE,&(ti->palette));
353 }
354
355 FX_grTexClampMode_NoLock(GR_TMU0,ti->sClamp,ti->tClamp);
356 FX_grTexClampMode_NoLock(GR_TMU1,ti->sClamp,ti->tClamp);
357 FX_grTexFilterMode_NoLock(GR_TMU0,ti->minFilt,ti->maxFilt);
358 FX_grTexFilterMode_NoLock(GR_TMU1,ti->minFilt,ti->maxFilt);
359 FX_grTexMipMapMode_NoLock(GR_TMU0,ti->mmMode,ti->LODblend);
360 FX_grTexMipMapMode_NoLock(GR_TMU1,ti->mmMode,ti->LODblend);
361
362 FX_grTexSource_NoLock(GR_TMU0,ti->tm[FX_TMU0]->startAddr,
363 GR_MIPMAPLEVELMASK_ODD,&(ti->info));
364 FX_grTexSource_NoLock(GR_TMU1,ti->tm[FX_TMU1]->startAddr,
365 GR_MIPMAPLEVELMASK_EVEN,&(ti->info));
366 } else {
367 if (ti->whichTMU==FX_TMU_BOTH) tmu=FX_TMU0;
368 else tmu=ti->whichTMU;
369
370 if((ti->info.format==GR_TEXFMT_P_8) && (!fxMesa->haveGlobalPaletteTexture)) {
371 if (MESA_VERBOSE&VERBOSE_DRIVER) {
372 fprintf(stderr,"fxmesa: uploading texture palette\n");
373 }
374 FX_grTexDownloadTable_NoLock(tmu, GR_TEXTABLE_PALETTE, &(ti->palette));
375 }
376
377 /* KW: The alternative is to do the download to the other tmu. If
378 * we get to this point, I think it means we are thrashing the
379 * texture memory, so perhaps it's not a good idea.
380 */
381 if (ti->LODblend && (MESA_VERBOSE&VERBOSE_DRIVER))
382 fprintf(stderr, "fxmesa: not blending texture - only on one tmu\n");
383
384 FX_grTexClampMode_NoLock(tmu, ti->sClamp, ti->tClamp);
385 FX_grTexFilterMode_NoLock(tmu, ti->minFilt, ti->maxFilt);
386 FX_grTexMipMapMode_NoLock(tmu, ti->mmMode, FXFALSE);
387
388 FX_grTexSource_NoLock(tmu, ti->tm[tmu]->startAddr,
389 GR_MIPMAPLEVELMASK_BOTH, &(ti->info));
390 }
391}
392
393static void fxSelectSingleTMUSrc_NoLock(fxMesaContext fxMesa, GLint tmu,
394 FxBool LODblend)
395{
396 if (MESA_VERBOSE&VERBOSE_DRIVER) {
397 fprintf(stderr,"fxmesa: fxSelectSingleTMUSrc(%d,%d)\n",tmu,LODblend);
398 }
399
400 if (LODblend) {
401 FX_grTexCombine_NoLock(GR_TMU0,
402 GR_COMBINE_FUNCTION_BLEND,
403 GR_COMBINE_FACTOR_ONE_MINUS_LOD_FRACTION,
404 GR_COMBINE_FUNCTION_BLEND,
405 GR_COMBINE_FACTOR_ONE_MINUS_LOD_FRACTION,
406 FXFALSE,FXFALSE);
407
408 if (fxMesa->haveTwoTMUs)
409 FX_grTexCombine_NoLock(GR_TMU1,
410 GR_COMBINE_FUNCTION_LOCAL,GR_COMBINE_FACTOR_NONE,
411 GR_COMBINE_FUNCTION_LOCAL,GR_COMBINE_FACTOR_NONE,
412 FXFALSE,FXFALSE);
413 fxMesa->tmuSrc=FX_TMU_SPLIT;
414 }
415 else {
416 if (tmu!=FX_TMU1) {
417 FX_grTexCombine_NoLock(GR_TMU0,
418 GR_COMBINE_FUNCTION_LOCAL,GR_COMBINE_FACTOR_NONE,
419 GR_COMBINE_FUNCTION_LOCAL,GR_COMBINE_FACTOR_NONE,
420 FXFALSE,FXFALSE);
421 if (fxMesa->haveTwoTMUs) {
422 FX_grTexCombine_NoLock(GR_TMU1,
423 GR_COMBINE_FUNCTION_ZERO, GR_COMBINE_FACTOR_NONE,
424 GR_COMBINE_FUNCTION_ZERO, GR_COMBINE_FACTOR_NONE,
425 FXFALSE,FXFALSE);
426 }
427 fxMesa->tmuSrc=FX_TMU0;
428 }
429 else {
430 FX_grTexCombine_NoLock(GR_TMU1,
431 GR_COMBINE_FUNCTION_LOCAL,GR_COMBINE_FACTOR_NONE,
432 GR_COMBINE_FUNCTION_LOCAL,GR_COMBINE_FACTOR_NONE,
433 FXFALSE,FXFALSE);
434
435 /* GR_COMBINE_FUNCTION_SCALE_OTHER doesn't work ?!? */
436
437 FX_grTexCombine_NoLock(GR_TMU0,
438 GR_COMBINE_FUNCTION_BLEND,
439 GR_COMBINE_FACTOR_ONE,
440 GR_COMBINE_FUNCTION_BLEND,
441 GR_COMBINE_FACTOR_ONE,
442 FXFALSE,FXFALSE);
443
444 fxMesa->tmuSrc=FX_TMU1;
445 }
446 }
447}
448
449static void fxSetupTextureSingleTMU_NoLock(GLcontext *ctx, GLuint textureset)
450{
451 fxMesaContext fxMesa=(fxMesaContext)ctx->DriverCtx;
452 GrCombineLocal_t localc,locala;
453 GLuint unitsmode;
454 GLint ifmt;
455 tfxTexInfo *ti;
456 struct gl_texture_object *tObj=ctx->Texture.Unit[textureset].CurrentD[2];
457 int tmu;
458
459 if (MESA_VERBOSE&VERBOSE_DRIVER) {
460 fprintf(stderr,"fxmesa: fxSetupTextureSingleTMU(...) Start\n");
461 }
462
463 ti=fxTMGetTexInfo(tObj);
464
465 fxTexValidate(ctx,tObj);
466
467 fxSetupSingleTMU_NoLock(fxMesa,tObj);
468
469 if (ti->whichTMU==FX_TMU_BOTH) tmu=FX_TMU0;
470 else tmu=ti->whichTMU;
471 if (fxMesa->tmuSrc!=tmu)
472 fxSelectSingleTMUSrc_NoLock(fxMesa, tmu, ti->LODblend);
473
474 if(textureset==0 || !fxMesa->haveTwoTMUs)
475 unitsmode=fxGetTexSetConfiguration(ctx,tObj,NULL);
476 else
477 unitsmode=fxGetTexSetConfiguration(ctx,NULL,tObj);
478
479 if(fxMesa->lastUnitsMode==unitsmode)
480 return;
481
482 fxMesa->lastUnitsMode=unitsmode;
483
484 fxMesa->stw_hint_state = 0;
485 FX_grHints_NoLock(GR_HINT_STWHINT,0);
486
487 ifmt=ti->baseLevelInternalFormat;
488
489 if(unitsmode & FX_UM_ALPHA_ITERATED)
490 locala=GR_COMBINE_LOCAL_ITERATED;
491 else
492 locala=GR_COMBINE_LOCAL_CONSTANT;
493
494 if(unitsmode & FX_UM_COLOR_ITERATED)
495 localc=GR_COMBINE_LOCAL_ITERATED;
496 else
497 localc=GR_COMBINE_LOCAL_CONSTANT;
498
499 if (MESA_VERBOSE & (VERBOSE_DRIVER|VERBOSE_TEXTURE))
500 fprintf(stderr, "fxMesa: fxSetupTextureSingleTMU, envmode is %s\n",
501 gl_lookup_enum_by_nr(ctx->Texture.Unit[textureset].EnvMode));
502
503 switch(ctx->Texture.Unit[textureset].EnvMode) {
504 case GL_DECAL:
505 FX_grAlphaCombine_NoLock(GR_COMBINE_FUNCTION_LOCAL,
506 GR_COMBINE_FACTOR_NONE,
507 locala,
508 GR_COMBINE_OTHER_NONE,
509 FXFALSE);
510
511 FX_grColorCombine_NoLock(GR_COMBINE_FUNCTION_BLEND,
512 GR_COMBINE_FACTOR_TEXTURE_ALPHA,
513 localc,
514 GR_COMBINE_OTHER_TEXTURE,
515 FXFALSE);
516 break;
517 case GL_MODULATE:
518 FX_grAlphaCombine_NoLock(GR_COMBINE_FUNCTION_SCALE_OTHER,
519 GR_COMBINE_FACTOR_LOCAL,
520 locala,
521 GR_COMBINE_OTHER_TEXTURE,
522 FXFALSE);
523
524 if(ifmt==GL_ALPHA)
525 FX_grColorCombine_NoLock(GR_COMBINE_FUNCTION_LOCAL,
526 GR_COMBINE_FACTOR_NONE,
527 localc,
528 GR_COMBINE_OTHER_NONE,
529 FXFALSE);
530 else
531 FX_grColorCombine_NoLock(GR_COMBINE_FUNCTION_SCALE_OTHER,
532 GR_COMBINE_FACTOR_LOCAL,
533 localc,
534 GR_COMBINE_OTHER_TEXTURE,
535 FXFALSE);
536 break;
537 case GL_BLEND:
538#if 0
539 FX_grAlphaCombine_NoLock(GR_COMBINE_FUNCTION_SCALE_OTHER,
540 GR_COMBINE_FACTOR_LOCAL,
541 locala,
542 GR_COMBINE_OTHER_TEXTURE,
543 FXFALSE);
544 if (ifmt==GL_ALPHA)
545 FX_grColorCombine_NoLock(GR_COMBINE_FUNCTION_LOCAL,
546 GR_COMBINE_FACTOR_NONE,
547 localc,
548 GR_COMBINE_OTHER_NONE,
549 FXFALSE);
550 else
551 FX_grColorCombine_NoLock(GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL,
552 GR_COMBINE_FACTOR_LOCAL,
553 localc,
554 GR_COMBINE_OTHER_TEXTURE,
555 FXTRUE);
556 ctx->Driver.MultipassFunc = fxMultipassBlend;
557#else
558#ifndef FX_SILENT
559 fprintf(stderr,"fx Driver: GL_BLEND not yet supported\n");
560#endif
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#ifndef FX_SILENT
592 fprintf(stderr,"fx Driver: %x Texture.EnvMode not yet supported\n",ctx->Texture.Unit[textureset].EnvMode);
593#endif
594 break;
595 }
596
597 if (MESA_VERBOSE&VERBOSE_DRIVER) {
598 fprintf(stderr,"fxmesa: fxSetupTextureSingleTMU(...) End\n");
599 }
600}
601
602static 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
610static 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
743static 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
1024static 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) ||
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)
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
1065static 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
1109static 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 */
1120void 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
1240static 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
1256void 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
1307static 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
1323void 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
1369void 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
1381static 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 else
1389 FX_grDepthBufferFunction(GR_CMP_ALWAYS);
1390
1391 FX_grDepthMask(us->depthMask);
1392}
1393
1394/************************************************************************/
1395/**************************** Color Mask SetUp **************************/
1396/************************************************************************/
1397
1398GLboolean fxDDColorMask(GLcontext *ctx,
1399 GLboolean r, GLboolean g,
1400 GLboolean b, GLboolean a )
1401{
1402 fxMesaContext fxMesa=(fxMesaContext)ctx->DriverCtx;
1403 fxMesa->new_state |= FX_NEW_COLOR_MASK;
1404 ctx->Driver.RenderStart = fxSetupFXUnits;
1405 (void) r; (void) g; (void) b; (void) a;
1406 return GL_FALSE;
1407}
1408
1409static void fxSetupColorMask(GLcontext *ctx)
1410{
1411 fxMesaContext fxMesa = FX_CONTEXT(ctx);
1412
1413 FX_grColorMask(ctx->Color.ColorMask[RCOMP] ||
1414 ctx->Color.ColorMask[GCOMP] ||
1415 ctx->Color.ColorMask[BCOMP],
1416 ctx->Color.ColorMask[ACOMP] && fxMesa->haveAlphaBuffer);
1417}
1418
1419
1420
1421/************************************************************************/
1422/**************************** Fog Mode SetUp ****************************/
1423/************************************************************************/
1424
1425/*
1426 * This is called during state update in order to update the Glide fog state.
1427 */
1428static void fxSetupFog(GLcontext *ctx)
1429{
1430 if (ctx->Fog.Enabled && ctx->FogMode==FOG_FRAGMENT) {
1431 fxMesaContext fxMesa = FX_CONTEXT(ctx);
1432
1433 /* update fog color */
1434 GLubyte col[4];
1435 col[0]=(unsigned int)(255*ctx->Fog.Color[0]);
1436 col[1]=(unsigned int)(255*ctx->Fog.Color[1]);
1437 col[2]=(unsigned int)(255*ctx->Fog.Color[2]);
1438 col[3]=(unsigned int)(255*ctx->Fog.Color[3]);
1439 FX_grFogColorValue(FXCOLOR4(col));
1440
1441 if(fxMesa->fogTableMode != ctx->Fog.Mode ||
1442 fxMesa->fogDensity != ctx->Fog.Density ||
1443 fxMesa->fogStart != ctx->Fog.Start ||
1444 fxMesa->fogEnd != ctx->Fog.End) {
1445 /* reload the fog table */
1446 switch (ctx->Fog.Mode) {
1447 case GL_LINEAR:
1448 guFogGenerateLinear(fxMesa->fogTable, ctx->Fog.Start, ctx->Fog.End);
1449 break;
1450 case GL_EXP:
1451 guFogGenerateExp(fxMesa->fogTable, ctx->Fog.Density);
1452 break;
1453 case GL_EXP2:
1454 guFogGenerateExp2(fxMesa->fogTable, ctx->Fog.Density);
1455 break;
1456 default:
1457 ;
1458 }
1459 fxMesa->fogTableMode = ctx->Fog.Mode;
1460 fxMesa->fogDensity = ctx->Fog.Density;
1461 fxMesa->fogStart = ctx->Fog.Start;
1462 fxMesa->fogEnd = ctx->Fog.End;
1463 }
1464
1465 FX_grFogTable(fxMesa->fogTable);
1466 FX_grFogMode(GR_FOG_WITH_TABLE);
1467 }
1468 else {
1469 FX_grFogMode(GR_FOG_DISABLE);
1470 }
1471}
1472
1473void fxDDFogfv( GLcontext *ctx, GLenum pname, const GLfloat *params )
1474{
1475 FX_CONTEXT(ctx)->new_state |= FX_NEW_FOG;
1476 ctx->Driver.RenderStart = fxSetupFXUnits;
1477}
1478
1479/************************************************************************/
1480/************************** Scissor Test SetUp **************************/
1481/************************************************************************/
1482
1483/* This routine is used in managing the lock state, and therefore can't lock */
1484void fxSetScissorValues(GLcontext *ctx)
1485{
1486 fxMesaContext fxMesa=(fxMesaContext)ctx->DriverCtx;
1487 int xmin, xmax;
1488 int ymin, ymax, check;
1489
1490 if (ctx->Scissor.Enabled) {
1491 xmin=ctx->Scissor.X;
1492 xmax=ctx->Scissor.X+ctx->Scissor.Width;
1493 ymin=ctx->Scissor.Y;
1494 ymax=ctx->Scissor.Y+ctx->Scissor.Height;
1495 check=1;
1496 } else {
1497 xmin=0;
1498 ymin=0;
1499 xmax=fxMesa->width;
1500 ymax=fxMesa->height;
1501 check=0;
1502 }
1503 xmin+=fxMesa->x_offset;
1504 xmax+=fxMesa->x_offset;
1505 ymin+=fxMesa->y_delta;
1506 ymax+=fxMesa->y_delta;
1507 if (xmin<fxMesa->clipMinX) xmin=fxMesa->clipMinX;
1508 if (xmax>fxMesa->clipMaxX) xmax=fxMesa->clipMaxX;
1509 if (ymin<fxMesa->screen_height-fxMesa->clipMaxY)
1510 ymin=fxMesa->screen_height-fxMesa->clipMaxY;
1511 if (ymax>fxMesa->screen_height-fxMesa->clipMinY)
1512 ymax=fxMesa->screen_height-fxMesa->clipMinY;
1513 FX_grClipWindow_NoLock(xmin, ymin, xmax, ymax);
1514}
1515
1516static void fxSetupScissor(GLcontext *ctx)
1517{
1518 fxMesaContext fxMesa=(fxMesaContext)ctx->DriverCtx;
1519 if (!fxMesa->needClip) {
1520 BEGIN_BOARD_LOCK();
1521 fxSetScissorValues(ctx);
1522 END_BOARD_LOCK();
1523 }
1524}
1525
1526void fxDDScissor( GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h )
1527{
1528 FX_CONTEXT(ctx)->new_state |= FX_NEW_SCISSOR;
1529 ctx->Driver.RenderStart = fxSetupFXUnits;
1530}
1531
1532/************************************************************************/
1533/*************************** Cull mode setup ****************************/
1534/************************************************************************/
1535
1536
1537void fxDDCullFace(GLcontext *ctx, GLenum mode)
1538{
1539 (void) mode;
1540 FX_CONTEXT(ctx)->new_state |= FX_NEW_CULL;
1541 ctx->Driver.RenderStart = fxSetupFXUnits;
1542}
1543
1544void fxDDFrontFace(GLcontext *ctx, GLenum mode)
1545{
1546 (void) mode;
1547 FX_CONTEXT(ctx)->new_state |= FX_NEW_CULL;
1548 ctx->Driver.RenderStart = fxSetupFXUnits;
1549}
1550
1551
1552static void fxSetupCull(GLcontext *ctx)
1553{
1554 if (ctx->Polygon.CullFlag) {
1555 switch (ctx->Polygon.CullFaceMode) {
1556 case GL_BACK:
1557 if (ctx->Polygon.FrontFace==GL_CCW)
1558 FX_CONTEXT(ctx)->cullMode=GR_CULL_NEGATIVE;
1559 else
1560 FX_CONTEXT(ctx)->cullMode=GR_CULL_POSITIVE;
1561 break;
1562 case GL_FRONT:
1563 if(ctx->Polygon.FrontFace==GL_CCW)
1564 FX_CONTEXT(ctx)->cullMode=GR_CULL_POSITIVE;
1565 else
1566 FX_CONTEXT(ctx)->cullMode=GR_CULL_NEGATIVE;
1567 break;
1568 case GL_FRONT_AND_BACK:
1569 FX_CONTEXT(ctx)->cullMode=GR_CULL_DISABLE;
1570 break;
1571 default:
1572 break;
1573 }
1574 } else FX_CONTEXT(ctx)->cullMode=GR_CULL_DISABLE;
1575 FX_grCullMode(FX_CONTEXT(ctx)->cullMode);
1576}
1577
1578
1579/************************************************************************/
1580/****************************** DD Enable ******************************/
1581/************************************************************************/
1582
1583void fxDDEnable(GLcontext *ctx, GLenum cap, GLboolean state)
1584{
1585 fxMesaContext fxMesa=(fxMesaContext)ctx->DriverCtx;
1586 tfxUnitsState *us=&fxMesa->unitsState;
1587
1588 if (MESA_VERBOSE&VERBOSE_DRIVER) {
1589 fprintf(stderr,"fxmesa: fxDDEnable(...)\n");
1590 }
1591
1592 switch(cap) {
1593 case GL_ALPHA_TEST:
1594 if(state!=us->alphaTestEnabled) {
1595 us->alphaTestEnabled=state;
1596 fxMesa->new_state |= FX_NEW_ALPHA;
1597 ctx->Driver.RenderStart = fxSetupFXUnits;
1598 }
1599 break;
1600 case GL_BLEND:
1601 if(state!=us->blendEnabled) {
1602 us->blendEnabled=state;
1603 fxMesa->new_state |= FX_NEW_BLEND;
1604 ctx->Driver.RenderStart = fxSetupFXUnits;
1605 }
1606 break;
1607 case GL_DEPTH_TEST:
1608 if(state!=us->depthTestEnabled) {
1609 us->depthTestEnabled=state;
1610 fxMesa->new_state |= FX_NEW_DEPTH;
1611 ctx->Driver.RenderStart = fxSetupFXUnits;
1612 }
1613 break;
1614 case GL_SCISSOR_TEST:
1615 fxMesa->new_state |= FX_NEW_SCISSOR;
1616 ctx->Driver.RenderStart = fxSetupFXUnits;
1617 break;
1618 case GL_SHARED_TEXTURE_PALETTE_EXT:
1619 fxDDTexUseGlbPalette(ctx, state);
1620 break;
1621 case GL_FOG:
1622 fxMesa->new_state |= FX_NEW_FOG;
1623 ctx->Driver.RenderStart = fxSetupFXUnits;
1624 break;
1625 case GL_CULL_FACE:
1626 fxMesa->new_state |= FX_NEW_CULL;
1627 ctx->Driver.RenderStart = fxSetupFXUnits;
1628 break;
1629 case GL_LINE_SMOOTH:
1630 case GL_LINE_STIPPLE:
1631 case GL_POINT_SMOOTH:
1632 case GL_POLYGON_SMOOTH:
1633 case GL_TEXTURE_2D:
1634 fxMesa->new_state |= FX_NEW_TEXTURING;
1635 ctx->Driver.RenderStart = fxSetupFXUnits;
1636 break;
1637 default:
1638 ; /* XXX no-op? */
1639 }
1640}
1641
1642#if 0
1643/*
1644 Multipass to do GL_BLEND texture functions
1645 Cf*(1-Ct) has already been written to the buffer during the first pass
1646 Cc*Ct gets written during the second pass (in this function)
1647 Everything gets reset in the third call (in this function)
1648*/
1649static GLboolean fxMultipassBlend(struct vertex_buffer *VB, GLuint pass)
1650{
1651 GLcontext *ctx = VB->ctx;
1652 fxMesaContext fxMesa = FX_CONTEXT(ctx);
1653
1654 switch (pass) {
1655 case 1:
1656 /* Add Cc*Ct */
1657 fxMesa->restoreUnitsState=fxMesa->unitsState;
1658 if (ctx->Depth.Mask) {
1659 /* We don't want to check or change the depth buffers */
1660 switch (ctx->Depth.Func) {
1661 case GL_NEVER:
1662 case GL_ALWAYS:
1663 break;
1664 default:
1665 fxDDDepthFunc(ctx, GL_EQUAL);
1666 break;
1667 }
1668 fxDDDepthMask(ctx, FALSE);
1669 }
1670 /* Enable Cc*Ct mode */
1671 /* ? Set the Constant Color ? */
1672 fxDDEnable(ctx, GL_BLEND, GL_TRUE);
1673 fxDDBlendFunc(ctx, XXX, XXX);
1674 fxSetupTextureSingleTMU(ctx, XXX);
1675 fxSetupBlend(ctx);
1676 fxSetupDepthTest(ctx);
1677 break;
1678
1679 case 2:
1680 /* Reset everything back to normal */
1681 fxMesa->unitsState = fxMesa->restoreUnitsState;
1682 fxMesa->setupdone &= XXX;
1683 fxSetupTextureSingleTMU(ctx, XXX);
1684 fxSetupBlend(ctx);
1685 fxSetupDepthTest(ctx);
1686 break;
1687 }
1688
1689 return pass==1;
1690}
1691#endif
1692
1693/************************************************************************/
1694/******************** Fake Multitexture Support *************************/
1695/************************************************************************/
1696
1697/* Its considered cheeky to try to fake ARB multitexture by doing
1698 * multipass rendering, because it is not possible to emulate the full
1699 * spec in this way. The fact is that the voodoo 2 supports only a
1700 * subset of the possible multitexturing modes, and it is possible to
1701 * support almost the same subset using multipass blending on the
1702 * voodoo 1. In all other cases for both voodoo 1 and 2, we fall back
1703 * to software rendering, satisfying the spec if not the user.
1704 */
1705static GLboolean fxMultipassTexture( struct vertex_buffer *VB, GLuint pass )
1706{
1707 GLcontext *ctx = VB->ctx;
1708 fxVertex *v = FX_DRIVER_DATA(VB)->verts;
1709 fxVertex *last = FX_DRIVER_DATA(VB)->last_vert;
1710 fxMesaContext fxMesa = FX_CONTEXT(ctx);
1711
1712 switch (pass) {
1713 case 1:
1714 if (MESA_VERBOSE&(VERBOSE_DRIVER|VERBOSE_PIPELINE|VERBOSE_TEXTURE))
1715 fprintf(stderr, "fxmesa: Second texture pass\n");
1716
1717 for ( ; v != last ; v++) {
1718 v->f[S0COORD] = v->f[S1COORD];
1719 v->f[T0COORD] = v->f[T1COORD];
1720 }
1721
1722 fxMesa->restoreUnitsState = fxMesa->unitsState;
1723 fxMesa->tmu_source[0] = 1;
1724
1725 if (ctx->Depth.Mask) {
1726 switch (ctx->Depth.Func) {
1727 case GL_NEVER:
1728 case GL_ALWAYS:
1729 break;
1730 default:
1731 fxDDDepthFunc( ctx, GL_EQUAL );
1732 break;
1733 }
1734
1735 fxDDDepthMask( ctx, GL_FALSE );
1736 }
1737
1738 if (ctx->Texture.Unit[1].EnvMode == GL_MODULATE) {
1739 fxDDEnable( ctx, GL_BLEND, GL_TRUE );
1740 fxDDBlendFunc( ctx, GL_DST_COLOR, GL_ZERO );
1741 }
1742
1743 fxSetupTextureSingleTMU( ctx, 1 );
1744 fxSetupBlend( ctx );
1745 fxSetupDepthTest( ctx );
1746 break;
1747
1748 case 2:
1749 /* Restore original state.
1750 */
1751 fxMesa->tmu_source[0] = 0;
1752 fxMesa->unitsState = fxMesa->restoreUnitsState;
1753 fxMesa->setupdone &= ~SETUP_TMU0;
1754 fxSetupTextureSingleTMU( ctx, 0 );
1755 fxSetupBlend( ctx );
1756 fxSetupDepthTest( ctx );
1757 break;
1758 }
1759
1760 return pass == 1;
1761}
1762
1763
1764/************************************************************************/
1765/************************** Changes to units state **********************/
1766/************************************************************************/
1767
1768
1769/* All units setup is handled under texture setup.
1770 */
1771void fxDDShadeModel(GLcontext *ctx, GLenum mode)
1772{
1773 FX_CONTEXT(ctx)->new_state |= FX_NEW_TEXTURING;
1774 ctx->Driver.RenderStart = fxSetupFXUnits;
1775}
1776
1777
1778
1779/************************************************************************/
1780/****************************** Units SetUp *****************************/
1781/************************************************************************/
1782static void gl_print_fx_state_flags( const char *msg, GLuint flags )
1783{
1784 fprintf(stderr,
1785 "%s: (0x%x) %s%s%s%s%s%s%s\n",
1786 msg,
1787 flags,
1788 (flags & FX_NEW_TEXTURING) ? "texture, " : "",
1789 (flags & FX_NEW_BLEND) ? "blend, " : "",
1790 (flags & FX_NEW_ALPHA) ? "alpha, " : "",
1791 (flags & FX_NEW_FOG) ? "fog, " : "",
1792 (flags & FX_NEW_SCISSOR) ? "scissor, " : "",
1793 (flags & FX_NEW_COLOR_MASK) ? "colormask, " : "",
1794 (flags & FX_NEW_CULL) ? "cull, " : "");
1795}
1796
1797void fxSetupFXUnits( GLcontext *ctx )
1798{
1799 fxMesaContext fxMesa=(fxMesaContext)ctx->DriverCtx;
1800 GLuint newstate = fxMesa->new_state;
1801
1802 if (MESA_VERBOSE&VERBOSE_DRIVER)
1803 gl_print_fx_state_flags("fxmesa: fxSetupFXUnits", newstate);
1804
1805 if (newstate) {
1806 if (newstate & FX_NEW_TEXTURING)
1807 fxSetupTexture(ctx);
1808
1809 if (newstate & FX_NEW_BLEND)
1810 fxSetupBlend(ctx);
1811
1812 if (newstate & FX_NEW_ALPHA)
1813 fxSetupAlphaTest(ctx);
1814
1815 if (newstate & FX_NEW_DEPTH)
1816 fxSetupDepthTest(ctx);
1817
1818 if (newstate & FX_NEW_FOG)
1819 fxSetupFog(ctx);
1820
1821 if (newstate & FX_NEW_SCISSOR)
1822 fxSetupScissor(ctx);
1823
1824 if (newstate & FX_NEW_COLOR_MASK)
1825 fxSetupColorMask(ctx);
1826
1827 if (newstate & FX_NEW_CULL)
1828 fxSetupCull(ctx);
1829
1830 fxMesa->new_state = 0;
1831/* ctx->Driver.RenderStart = 0; */
1832 }
1833}
1834
1835
1836
1837#else
1838
1839
1840/*
1841 * Need this to provide at least one external definition.
1842 */
1843
1844int gl_fx_dummy_function_setup(void)
1845{
1846 return 0;
1847}
1848
1849#endif /* FX */
Note: See TracBrowser for help on using the repository browser.