1 /* -*- mode: C; tab-width:8; c-basic-offset:2 -*- */
4 * Mesa 3-D graphics library
7 * Copyright (C) 1999-2000 Brian Paul All Rights Reserved.
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:
16 * The above copyright notice and this permission notice shall be included
17 * in all copies or substantial portions of the Software.
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.
27 * Original Mesa / 3Dfx device driver (C) 1999 David Bucciarelli, by the
30 * Thank you for your contribution, David!
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.
38 * Additional Mesa/3Dfx driver developers:
39 * Daryll Strauss <daryll@precisioninsight.com>
40 * Keith Whitwell <keith@precisioninsight.com>
42 * See fxapi.h for more revision/author details.
46 /* fxsetup.c - 3Dfx VooDoo rendering mode setup functions */
58 static GLuint
fxGetTexSetConfiguration(GLcontext
*ctx
,
59 struct gl_texture_object
*tObj0
,
60 struct gl_texture_object
*tObj1
);
61 static void fxSetupTextureSingleTMU_NoLock(GLcontext
*ctx
, GLuint textureset
);
62 static void fxSetupDoubleTMU_NoLock(fxMesaContext fxMesa
,
63 struct gl_texture_object
*tObj0
,
64 struct gl_texture_object
*tObj1
);
65 static void fxSetupTexture_NoLock(GLcontext
*ctx
);
66 static void fxSetupTexture(GLcontext
*ctx
);
67 static void fxSetupBlend(GLcontext
*ctx
);
68 static void fxSetupDepthTest(GLcontext
*ctx
);
69 static void fxSetupScissor(GLcontext
*ctx
);
70 static void fxSetupCull(GLcontext
*ctx
);
71 static void gl_print_fx_state_flags( const char *msg
, GLuint flags
);
72 /*static GLboolean fxMultipassBlend(struct vertex_buffer *, GLuint);*/
73 static GLboolean
fxMultipassTexture( struct vertex_buffer
*, GLuint
);
75 static void fxTexValidate(GLcontext
*ctx
, struct gl_texture_object
*tObj
)
77 tfxTexInfo
*ti
=fxTMGetTexInfo(tObj
);
80 if (MESA_VERBOSE
&VERBOSE_DRIVER
) {
81 fprintf(stderr
,"fxmesa: fxTexValidate(...) Start\n");
85 if (MESA_VERBOSE
&VERBOSE_DRIVER
) {
86 fprintf(stderr
,"fxmesa: fxTexValidate(...) End (validated=GL_TRUE)\n");
92 minl
=ti
->minLevel
=tObj
->BaseLevel
;
93 maxl
=ti
->maxLevel
=MIN2(tObj
->MaxLevel
,tObj
->Image
[0]->MaxLog2
);
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
),
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
,
108 FX_smallLodLog2(ti
->info
)=FX_largeLodLog2(ti
->info
);
110 fxTexGetFormat(tObj
->Image
[minl
]->IntFormat
,&(ti
->info
.format
),&(ti
->baseLevelInternalFormat
));
112 switch (tObj
->WrapS
) {
113 case GL_CLAMP_TO_EDGE
:
114 /* What's this really mean compared to GL_CLAMP? */
122 ; /* silence compiler warning */
124 switch (tObj
->WrapT
) {
125 case GL_CLAMP_TO_EDGE
:
126 /* What's this really mean compared to GL_CLAMP? */
134 ; /* silence compiler warning */
137 ti
->validated
=GL_TRUE
;
141 if (MESA_VERBOSE
&VERBOSE_DRIVER
) {
142 fprintf(stderr
,"fxmesa: fxTexValidate(...) End\n");
146 static void fxPrintUnitsMode( const char *msg
, GLuint mode
)
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",
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, " : "");
178 static GLuint
fxGetTexSetConfiguration(GLcontext
*ctx
,
179 struct gl_texture_object
*tObj0
,
180 struct gl_texture_object
*tObj1
)
186 if((ctx
->Light
.ShadeModel
==GL_SMOOTH
) || 1 ||
187 (ctx
->Point
.SmoothFlag
) ||
188 (ctx
->Line
.SmoothFlag
) ||
189 (ctx
->Polygon
.SmoothFlag
))
190 unitsmode
|=FX_UM_ALPHA_ITERATED
;
192 unitsmode
|=FX_UM_ALPHA_CONSTANT
;
194 if(ctx
->Light
.ShadeModel
==GL_SMOOTH
|| 1)
195 unitsmode
|=FX_UM_COLOR_ITERATED
;
197 unitsmode
|=FX_UM_COLOR_CONSTANT
;
202 OpenGL Feeds Texture 0 into Texture 1
203 Glide Feeds Texture 1 into Texture 0
206 tfxTexInfo
*ti0
=fxTMGetTexInfo(tObj0
);
208 switch(ti0
->baseLevelInternalFormat
) {
210 ifmt
|=FX_UM_E0_ALPHA
;
213 ifmt
|=FX_UM_E0_LUMINANCE
;
215 case GL_LUMINANCE_ALPHA
:
216 ifmt
|=FX_UM_E0_LUMINANCE_ALPHA
;
219 ifmt
|=FX_UM_E0_INTENSITY
;
229 switch(ctx
->Texture
.Unit
[0].EnvMode
) {
231 envmode
|=FX_UM_E0_DECAL
;
234 envmode
|=FX_UM_E0_MODULATE
;
237 envmode
|=FX_UM_E0_REPLACE
;
240 envmode
|=FX_UM_E0_BLEND
;
243 envmode
|=FX_UM_E0_ADD
;
252 tfxTexInfo
*ti1
=fxTMGetTexInfo(tObj1
);
254 switch(ti1
->baseLevelInternalFormat
) {
256 ifmt
|=FX_UM_E1_ALPHA
;
259 ifmt
|=FX_UM_E1_LUMINANCE
;
261 case GL_LUMINANCE_ALPHA
:
262 ifmt
|=FX_UM_E1_LUMINANCE_ALPHA
;
265 ifmt
|=FX_UM_E1_INTENSITY
;
278 switch(ctx
->Texture
.Unit
[1].EnvMode
) {
280 envmode
|=FX_UM_E1_DECAL
;
283 envmode
|=FX_UM_E1_MODULATE
;
286 envmode
|=FX_UM_E1_REPLACE
;
289 envmode
|=FX_UM_E1_BLEND
;
292 envmode
|=FX_UM_E1_ADD
;
300 unitsmode
|=(ifmt
| envmode
);
302 if (MESA_VERBOSE
& (VERBOSE_DRIVER
|VERBOSE_TEXTURE
))
303 fxPrintUnitsMode("unitsmode", unitsmode
);
308 /************************************************************************/
309 /************************* Rendering Mode SetUp *************************/
310 /************************************************************************/
312 /************************* Single Texture Set ***************************/
314 static void fxSetupSingleTMU_NoLock(fxMesaContext fxMesa
, struct gl_texture_object
*tObj
)
316 tfxTexInfo
*ti
=fxTMGetTexInfo(tObj
);
319 /* Make sure we're not loaded incorrectly */
322 if (ti
->whichTMU
!=FX_TMU_SPLIT
)
323 fxTMMoveOutTM(fxMesa
, tObj
);
325 if (ti
->whichTMU
==FX_TMU_SPLIT
)
326 fxTMMoveOutTM(fxMesa
, tObj
);
330 /* Make sure we're loaded correctly */
333 fxTMMoveInTM_NoLock(fxMesa
,tObj
,FX_TMU_SPLIT
);
335 if (fxMesa
->haveTwoTMUs
) {
336 if (fxMesa
->freeTexMem
[FX_TMU0
] >
337 FX_grTexTextureMemRequired_NoLock(GR_MIPMAPLEVELMASK_BOTH
,
339 fxTMMoveInTM_NoLock(fxMesa
,tObj
, FX_TMU0
);
341 fxTMMoveInTM_NoLock(fxMesa
,tObj
, FX_TMU1
);
344 fxTMMoveInTM_NoLock(fxMesa
,tObj
,FX_TMU0
);
348 if (ti
->LODblend
&& ti
->whichTMU
== FX_TMU_SPLIT
) {
349 if ((ti
->info
.format
==GR_TEXFMT_P_8
) && (!fxMesa
->haveGlobalPaletteTexture
)) {
350 if (MESA_VERBOSE
&VERBOSE_DRIVER
) {
351 fprintf(stderr
,"fxmesa: uploading texture palette\n");
353 FX_grTexDownloadTable_NoLock(GR_TMU0
,GR_TEXTABLE_PALETTE
,&(ti
->palette
));
354 FX_grTexDownloadTable_NoLock(GR_TMU1
,GR_TEXTABLE_PALETTE
,&(ti
->palette
));
357 FX_grTexClampMode_NoLock(GR_TMU0
,ti
->sClamp
,ti
->tClamp
);
358 FX_grTexClampMode_NoLock(GR_TMU1
,ti
->sClamp
,ti
->tClamp
);
359 FX_grTexFilterMode_NoLock(GR_TMU0
,ti
->minFilt
,ti
->maxFilt
);
360 FX_grTexFilterMode_NoLock(GR_TMU1
,ti
->minFilt
,ti
->maxFilt
);
361 FX_grTexMipMapMode_NoLock(GR_TMU0
,ti
->mmMode
,ti
->LODblend
);
362 FX_grTexMipMapMode_NoLock(GR_TMU1
,ti
->mmMode
,ti
->LODblend
);
364 FX_grTexSource_NoLock(GR_TMU0
,ti
->tm
[FX_TMU0
]->startAddr
,
365 GR_MIPMAPLEVELMASK_ODD
,&(ti
->info
));
366 FX_grTexSource_NoLock(GR_TMU1
,ti
->tm
[FX_TMU1
]->startAddr
,
367 GR_MIPMAPLEVELMASK_EVEN
,&(ti
->info
));
369 if (ti
->whichTMU
==FX_TMU_BOTH
) tmu
=FX_TMU0
;
370 else tmu
=ti
->whichTMU
;
372 if((ti
->info
.format
==GR_TEXFMT_P_8
) && (!fxMesa
->haveGlobalPaletteTexture
)) {
373 if (MESA_VERBOSE
&VERBOSE_DRIVER
) {
374 fprintf(stderr
,"fxmesa: uploading texture palette\n");
376 FX_grTexDownloadTable_NoLock(tmu
, GR_TEXTABLE_PALETTE
, &(ti
->palette
));
379 /* KW: The alternative is to do the download to the other tmu. If
380 * we get to this point, I think it means we are thrashing the
381 * texture memory, so perhaps it's not a good idea.
383 if (ti
->LODblend
&& (MESA_VERBOSE
&VERBOSE_DRIVER
))
384 fprintf(stderr
, "fxmesa: not blending texture - only on one tmu\n");
386 FX_grTexClampMode_NoLock(tmu
, ti
->sClamp
, ti
->tClamp
);
387 FX_grTexFilterMode_NoLock(tmu
, ti
->minFilt
, ti
->maxFilt
);
388 FX_grTexMipMapMode_NoLock(tmu
, ti
->mmMode
, FXFALSE
);
390 FX_grTexSource_NoLock(tmu
, ti
->tm
[tmu
]->startAddr
,
391 GR_MIPMAPLEVELMASK_BOTH
, &(ti
->info
));
395 static void fxSelectSingleTMUSrc_NoLock(fxMesaContext fxMesa
, GLint tmu
,
398 if (MESA_VERBOSE
&VERBOSE_DRIVER
) {
399 fprintf(stderr
,"fxmesa: fxSelectSingleTMUSrc(%d,%d)\n",tmu
,LODblend
);
403 FX_grTexCombine_NoLock(GR_TMU0
,
404 GR_COMBINE_FUNCTION_BLEND
,
405 GR_COMBINE_FACTOR_ONE_MINUS_LOD_FRACTION
,
406 GR_COMBINE_FUNCTION_BLEND
,
407 GR_COMBINE_FACTOR_ONE_MINUS_LOD_FRACTION
,
410 if (fxMesa
->haveTwoTMUs
)
411 FX_grTexCombine_NoLock(GR_TMU1
,
412 GR_COMBINE_FUNCTION_LOCAL
,GR_COMBINE_FACTOR_NONE
,
413 GR_COMBINE_FUNCTION_LOCAL
,GR_COMBINE_FACTOR_NONE
,
415 fxMesa
->tmuSrc
=FX_TMU_SPLIT
;
419 FX_grTexCombine_NoLock(GR_TMU0
,
420 GR_COMBINE_FUNCTION_LOCAL
,GR_COMBINE_FACTOR_NONE
,
421 GR_COMBINE_FUNCTION_LOCAL
,GR_COMBINE_FACTOR_NONE
,
423 if (fxMesa
->haveTwoTMUs
) {
424 FX_grTexCombine_NoLock(GR_TMU1
,
425 GR_COMBINE_FUNCTION_ZERO
, GR_COMBINE_FACTOR_NONE
,
426 GR_COMBINE_FUNCTION_ZERO
, GR_COMBINE_FACTOR_NONE
,
429 fxMesa
->tmuSrc
=FX_TMU0
;
432 FX_grTexCombine_NoLock(GR_TMU1
,
433 GR_COMBINE_FUNCTION_LOCAL
,GR_COMBINE_FACTOR_NONE
,
434 GR_COMBINE_FUNCTION_LOCAL
,GR_COMBINE_FACTOR_NONE
,
437 /* GR_COMBINE_FUNCTION_SCALE_OTHER doesn't work ?!? */
439 FX_grTexCombine_NoLock(GR_TMU0
,
440 GR_COMBINE_FUNCTION_BLEND
,
441 GR_COMBINE_FACTOR_ONE
,
442 GR_COMBINE_FUNCTION_BLEND
,
443 GR_COMBINE_FACTOR_ONE
,
446 fxMesa
->tmuSrc
=FX_TMU1
;
451 static void fxSetupTextureSingleTMU_NoLock(GLcontext
*ctx
, GLuint textureset
)
453 fxMesaContext fxMesa
=(fxMesaContext
)ctx
->DriverCtx
;
454 GrCombineLocal_t localc
,locala
;
458 struct gl_texture_object
*tObj
=ctx
->Texture
.Unit
[textureset
].CurrentD
[2];
461 if (MESA_VERBOSE
&VERBOSE_DRIVER
) {
462 fprintf(stderr
,"fxmesa: fxSetupTextureSingleTMU(...) Start\n");
465 ti
=fxTMGetTexInfo(tObj
);
467 fxTexValidate(ctx
,tObj
);
469 fxSetupSingleTMU_NoLock(fxMesa
,tObj
);
471 if (ti
->whichTMU
==FX_TMU_BOTH
) tmu
=FX_TMU0
;
472 else tmu
=ti
->whichTMU
;
473 if (fxMesa
->tmuSrc
!=tmu
)
474 fxSelectSingleTMUSrc_NoLock(fxMesa
, tmu
, ti
->LODblend
);
476 if(textureset
==0 || !fxMesa
->haveTwoTMUs
)
477 unitsmode
=fxGetTexSetConfiguration(ctx
,tObj
,NULL
);
479 unitsmode
=fxGetTexSetConfiguration(ctx
,NULL
,tObj
);
481 /* if(fxMesa->lastUnitsMode==unitsmode) */
484 fxMesa
->lastUnitsMode
=unitsmode
;
486 fxMesa
->stw_hint_state
= 0;
487 FX_grHints_NoLock(GR_HINT_STWHINT
,0);
489 ifmt
=ti
->baseLevelInternalFormat
;
491 if(unitsmode
& FX_UM_ALPHA_ITERATED
)
492 locala
=GR_COMBINE_LOCAL_ITERATED
;
494 locala
=GR_COMBINE_LOCAL_CONSTANT
;
496 if(unitsmode
& FX_UM_COLOR_ITERATED
)
497 localc
=GR_COMBINE_LOCAL_ITERATED
;
499 localc
=GR_COMBINE_LOCAL_CONSTANT
;
501 if (MESA_VERBOSE
& (VERBOSE_DRIVER
|VERBOSE_TEXTURE
))
502 fprintf(stderr
, "fxMesa: fxSetupTextureSingleTMU, envmode is %s\n",
503 gl_lookup_enum_by_nr(ctx
->Texture
.Unit
[textureset
].EnvMode
));
505 switch(ctx
->Texture
.Unit
[textureset
].EnvMode
) {
507 FX_grAlphaCombine_NoLock(GR_COMBINE_FUNCTION_LOCAL
,
508 GR_COMBINE_FACTOR_NONE
,
510 GR_COMBINE_OTHER_NONE
,
513 FX_grColorCombine_NoLock(GR_COMBINE_FUNCTION_BLEND
,
514 GR_COMBINE_FACTOR_TEXTURE_ALPHA
,
516 GR_COMBINE_OTHER_TEXTURE
,
520 FX_grAlphaCombine_NoLock(GR_COMBINE_FUNCTION_SCALE_OTHER
,
521 GR_COMBINE_FACTOR_LOCAL
,
523 GR_COMBINE_OTHER_TEXTURE
,
527 FX_grColorCombine_NoLock(GR_COMBINE_FUNCTION_LOCAL
,
528 GR_COMBINE_FACTOR_NONE
,
530 GR_COMBINE_OTHER_NONE
,
533 FX_grColorCombine_NoLock(GR_COMBINE_FUNCTION_SCALE_OTHER
,
534 GR_COMBINE_FACTOR_LOCAL
,
536 GR_COMBINE_OTHER_TEXTURE
,
541 FX_grAlphaCombine_NoLock(GR_COMBINE_FUNCTION_SCALE_OTHER
,
542 GR_COMBINE_FACTOR_LOCAL
,
544 GR_COMBINE_OTHER_TEXTURE
,
547 FX_grColorCombine_NoLock(GR_COMBINE_FUNCTION_LOCAL
,
548 GR_COMBINE_FACTOR_NONE
,
550 GR_COMBINE_OTHER_NONE
,
553 FX_grColorCombine_NoLock(GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL
,
554 GR_COMBINE_FACTOR_LOCAL
,
556 GR_COMBINE_OTHER_TEXTURE
,
558 ctx
->Driver
.MultipassFunc
= fxMultipassBlend
;
560 if (MESA_VERBOSE
&VERBOSE_DRIVER
)
561 fprintf(stderr
,"fx Driver: GL_BLEND not yet supported\n");
565 if((ifmt
==GL_RGB
) || (ifmt
==GL_LUMINANCE
))
566 FX_grAlphaCombine_NoLock(GR_COMBINE_FUNCTION_LOCAL
,
567 GR_COMBINE_FACTOR_NONE
,
569 GR_COMBINE_OTHER_NONE
,
572 FX_grAlphaCombine_NoLock(GR_COMBINE_FUNCTION_SCALE_OTHER
,
573 GR_COMBINE_FACTOR_ONE
,
575 GR_COMBINE_OTHER_TEXTURE
,
579 FX_grColorCombine_NoLock(GR_COMBINE_FUNCTION_LOCAL
,
580 GR_COMBINE_FACTOR_NONE
,
582 GR_COMBINE_OTHER_NONE
,
585 FX_grColorCombine_NoLock(GR_COMBINE_FUNCTION_SCALE_OTHER
,
586 GR_COMBINE_FACTOR_ONE
,
588 GR_COMBINE_OTHER_TEXTURE
,
592 if (MESA_VERBOSE
&VERBOSE_DRIVER
)
593 fprintf(stderr
, "fx Driver: %x Texture.EnvMode not yet supported\n",
594 ctx
->Texture
.Unit
[textureset
].EnvMode
);
598 if (MESA_VERBOSE
&VERBOSE_DRIVER
) {
599 fprintf(stderr
,"fxmesa: fxSetupTextureSingleTMU(...) End\n");
603 static void fxSetupTextureSingleTMU(GLcontext
*ctx
, GLuint textureset
) {
605 fxSetupTextureSingleTMU_NoLock(ctx
, textureset
);
609 /************************* Double Texture Set ***************************/
611 static void fxSetupDoubleTMU_NoLock(fxMesaContext fxMesa
,
612 struct gl_texture_object
*tObj0
,
613 struct gl_texture_object
*tObj1
)
615 #define T0_NOT_IN_TMU 0x01
616 #define T1_NOT_IN_TMU 0x02
617 #define T0_IN_TMU0 0x04
618 #define T1_IN_TMU0 0x08
619 #define T0_IN_TMU1 0x10
620 #define T1_IN_TMU1 0x20
622 tfxTexInfo
*ti0
=fxTMGetTexInfo(tObj0
);
623 tfxTexInfo
*ti1
=fxTMGetTexInfo(tObj1
);
627 if (MESA_VERBOSE
&VERBOSE_DRIVER
) {
628 fprintf(stderr
,"fxmesa: fxSetupDoubleTMU(...)\n");
631 /* We shouldn't need to do this. There is something wrong with
632 mutlitexturing when the TMUs are swapped. So, we're forcing
633 them to always be loaded correctly. !!! */
634 if (ti0
->whichTMU
==FX_TMU1
)
635 fxTMMoveOutTM_NoLock(fxMesa
, tObj0
);
636 if (ti1
->whichTMU
==FX_TMU0
)
637 fxTMMoveOutTM_NoLock(fxMesa
, tObj1
);
640 switch (ti0
->whichTMU
) {
648 tstate
|=T0_IN_TMU0
|T0_IN_TMU1
;
651 tstate
|=T0_NOT_IN_TMU
;
654 } else tstate
|=T0_NOT_IN_TMU
;
657 switch (ti1
->whichTMU
) {
665 tstate
|=T1_IN_TMU0
|T1_IN_TMU1
;
668 tstate
|=T1_NOT_IN_TMU
;
671 } else tstate
|=T1_NOT_IN_TMU
;
673 ti0
->lastTimeUsed
=fxMesa
->texBindNumber
;
674 ti1
->lastTimeUsed
=fxMesa
->texBindNumber
;
676 /* Move texture maps into TMUs */
678 if (!(((tstate
&T0_IN_TMU0
) && (tstate
&T1_IN_TMU1
)) ||
679 ((tstate
&T0_IN_TMU1
) && (tstate
&T1_IN_TMU0
)))) {
680 if (tObj0
==tObj1
) fxTMMoveInTM_NoLock(fxMesa
, tObj1
, FX_TMU_BOTH
);
682 /* Find the minimal way to correct the situation */
683 if ((tstate
&T0_IN_TMU0
) || (tstate
&T1_IN_TMU1
)) {
684 /* We have one in the standard order, setup the other */
685 if (tstate
&T0_IN_TMU0
) { /* T0 is in TMU0, put T1 in TMU1 */
686 fxTMMoveInTM_NoLock(fxMesa
, tObj1
, FX_TMU1
);
688 fxTMMoveInTM_NoLock(fxMesa
, tObj0
, FX_TMU0
);
690 /* tmu0 and tmu1 are setup */
691 } else if ((tstate
&T0_IN_TMU1
) || (tstate
&T1_IN_TMU0
)) {
692 /* we have one in the reverse order, setup the other */
693 if (tstate
&T1_IN_TMU0
) { /* T1 is in TMU0, put T0 in TMU1 */
694 fxTMMoveInTM_NoLock(fxMesa
, tObj0
, FX_TMU1
);
696 fxTMMoveInTM_NoLock(fxMesa
, tObj1
, FX_TMU0
);
700 } else { /* Nothing is loaded */
701 fxTMMoveInTM_NoLock(fxMesa
, tObj0
, FX_TMU0
);
702 fxTMMoveInTM_NoLock(fxMesa
, tObj1
, FX_TMU1
);
703 /* tmu0 and tmu1 are setup */
708 if (!fxMesa
->haveGlobalPaletteTexture
) {
709 if (ti0
->info
.format
==GR_TEXFMT_P_8
) {
710 if (MESA_VERBOSE
&VERBOSE_DRIVER
) {
711 fprintf(stderr
,"fxmesa: uploading texture palette TMU0\n");
713 FX_grTexDownloadTable_NoLock(tmu0
, GR_TEXTABLE_PALETTE
, &(ti0
->palette
));
716 if (ti1
->info
.format
==GR_TEXFMT_P_8
) {
717 if (MESA_VERBOSE
&VERBOSE_DRIVER
) {
718 fprintf(stderr
,"fxmesa: uploading texture palette TMU1\n");
720 FX_grTexDownloadTable_NoLock(tmu1
, GR_TEXTABLE_PALETTE
, &(ti1
->palette
));
724 FX_grTexSource_NoLock(tmu0
, ti0
->tm
[tmu0
]->startAddr
,
725 GR_MIPMAPLEVELMASK_BOTH
, &(ti0
->info
));
726 FX_grTexClampMode_NoLock(tmu0
, ti0
->sClamp
, ti0
->tClamp
);
727 FX_grTexFilterMode_NoLock(tmu0
, ti0
->minFilt
, ti0
->maxFilt
);
728 FX_grTexMipMapMode_NoLock(tmu0
, ti0
->mmMode
, FXFALSE
);
730 FX_grTexSource_NoLock(tmu1
, ti1
->tm
[tmu1
]->startAddr
,
731 GR_MIPMAPLEVELMASK_BOTH
, &(ti1
->info
));
732 FX_grTexClampMode_NoLock(tmu1
, ti1
->sClamp
, ti1
->tClamp
);
733 FX_grTexFilterMode_NoLock(tmu1
, ti1
->minFilt
, ti1
->maxFilt
);
734 FX_grTexMipMapMode_NoLock(tmu1
, ti1
->mmMode
, FXFALSE
);
744 static void fxSetupTextureDoubleTMU_NoLock(GLcontext
*ctx
)
746 fxMesaContext fxMesa
=(fxMesaContext
)ctx
->DriverCtx
;
747 GrCombineLocal_t localc
,locala
;
748 tfxTexInfo
*ti0
,*ti1
;
749 struct gl_texture_object
*tObj0
=ctx
->Texture
.Unit
[0].CurrentD
[2];
750 struct gl_texture_object
*tObj1
=ctx
->Texture
.Unit
[1].CurrentD
[2];
751 GLuint envmode
,ifmt
,unitsmode
;
754 if (MESA_VERBOSE
&VERBOSE_DRIVER
) {
755 fprintf(stderr
,"fxmesa: fxSetupTextureDoubleTMU(...) Start\n");
758 ti0
=fxTMGetTexInfo(tObj0
);
759 fxTexValidate(ctx
,tObj0
);
761 ti1
=fxTMGetTexInfo(tObj1
);
762 fxTexValidate(ctx
,tObj1
);
764 fxSetupDoubleTMU_NoLock(fxMesa
,tObj0
,tObj1
);
766 unitsmode
=fxGetTexSetConfiguration(ctx
,tObj0
,tObj1
);
768 /* if(fxMesa->lastUnitsMode==unitsmode) */
771 fxMesa
->lastUnitsMode
=unitsmode
;
773 fxMesa
->stw_hint_state
|= GR_STWHINT_ST_DIFF_TMU1
;
774 FX_grHints_NoLock(GR_HINT_STWHINT
, fxMesa
->stw_hint_state
);
776 envmode
=unitsmode
& FX_UM_E_ENVMODE
;
777 ifmt
=unitsmode
& FX_UM_E_IFMT
;
779 if(unitsmode
& FX_UM_ALPHA_ITERATED
)
780 locala
=GR_COMBINE_LOCAL_ITERATED
;
782 locala
=GR_COMBINE_LOCAL_CONSTANT
;
784 if(unitsmode
& FX_UM_COLOR_ITERATED
)
785 localc
=GR_COMBINE_LOCAL_ITERATED
;
787 localc
=GR_COMBINE_LOCAL_CONSTANT
;
790 if (MESA_VERBOSE
& (VERBOSE_DRIVER
|VERBOSE_TEXTURE
))
791 fprintf(stderr
, "fxMesa: fxSetupTextureDoubleTMU, envmode is %s/%s\n",
792 gl_lookup_enum_by_nr(ctx
->Texture
.Unit
[0].EnvMode
),
793 gl_lookup_enum_by_nr(ctx
->Texture
.Unit
[1].EnvMode
));
796 if ((ti0
->whichTMU
==FX_TMU1
) || (ti1
->whichTMU
==FX_TMU0
)) {
800 fxMesa
->tmuSrc
=FX_TMU_BOTH
;
802 case (FX_UM_E0_MODULATE
| FX_UM_E1_MODULATE
):
804 GLboolean isalpha
[FX_NUM_TMU
];
806 if(ti0
->baseLevelInternalFormat
==GL_ALPHA
)
807 isalpha
[tmu0
]=GL_TRUE
;
809 isalpha
[tmu0
]=GL_FALSE
;
811 if(ti1
->baseLevelInternalFormat
==GL_ALPHA
)
812 isalpha
[tmu1
]=GL_TRUE
;
814 isalpha
[tmu1
]=GL_FALSE
;
817 FX_grTexCombine_NoLock(GR_TMU1
,
818 GR_COMBINE_FUNCTION_ZERO
,
819 GR_COMBINE_FACTOR_NONE
,
820 GR_COMBINE_FUNCTION_LOCAL
,
821 GR_COMBINE_FACTOR_NONE
,
824 FX_grTexCombine_NoLock(GR_TMU1
,
825 GR_COMBINE_FUNCTION_LOCAL
,
826 GR_COMBINE_FACTOR_NONE
,
827 GR_COMBINE_FUNCTION_LOCAL
,
828 GR_COMBINE_FACTOR_NONE
,
832 FX_grTexCombine_NoLock(GR_TMU0
,
833 GR_COMBINE_FUNCTION_BLEND_OTHER
,
834 GR_COMBINE_FACTOR_ONE
,
835 GR_COMBINE_FUNCTION_BLEND_OTHER
,
836 GR_COMBINE_FACTOR_LOCAL
,
839 FX_grTexCombine_NoLock(GR_TMU0
,
840 GR_COMBINE_FUNCTION_BLEND_OTHER
,
841 GR_COMBINE_FACTOR_LOCAL
,
842 GR_COMBINE_FUNCTION_BLEND_OTHER
,
843 GR_COMBINE_FACTOR_LOCAL
,
846 FX_grColorCombine_NoLock(GR_COMBINE_FUNCTION_SCALE_OTHER
,
847 GR_COMBINE_FACTOR_LOCAL
,
849 GR_COMBINE_OTHER_TEXTURE
,
852 FX_grAlphaCombine_NoLock(GR_COMBINE_FUNCTION_SCALE_OTHER
,
853 GR_COMBINE_FACTOR_LOCAL
,
855 GR_COMBINE_OTHER_TEXTURE
,
859 case (FX_UM_E0_REPLACE
| FX_UM_E1_BLEND
): /* Only for GLQuake */
861 FX_grTexCombine_NoLock(GR_TMU1
,
862 GR_COMBINE_FUNCTION_LOCAL
,
863 GR_COMBINE_FACTOR_NONE
,
864 GR_COMBINE_FUNCTION_LOCAL
,
865 GR_COMBINE_FACTOR_NONE
,
868 FX_grTexCombine_NoLock(GR_TMU0
,
869 GR_COMBINE_FUNCTION_BLEND_OTHER
,
870 GR_COMBINE_FACTOR_LOCAL
,
871 GR_COMBINE_FUNCTION_BLEND_OTHER
,
872 GR_COMBINE_FACTOR_LOCAL
,
875 FX_grTexCombine_NoLock(GR_TMU1
,
876 GR_COMBINE_FUNCTION_LOCAL
,
877 GR_COMBINE_FACTOR_NONE
,
878 GR_COMBINE_FUNCTION_LOCAL
,
879 GR_COMBINE_FACTOR_NONE
,
882 FX_grTexCombine_NoLock(GR_TMU0
,
883 GR_COMBINE_FUNCTION_BLEND_OTHER
,
884 GR_COMBINE_FACTOR_ONE_MINUS_LOCAL
,
885 GR_COMBINE_FUNCTION_BLEND_OTHER
,
886 GR_COMBINE_FACTOR_ONE_MINUS_LOCAL
,
890 FX_grAlphaCombine_NoLock(GR_COMBINE_FUNCTION_LOCAL
,
891 GR_COMBINE_FACTOR_NONE
,
893 GR_COMBINE_OTHER_NONE
,
896 FX_grColorCombine_NoLock(GR_COMBINE_FUNCTION_SCALE_OTHER
,
897 GR_COMBINE_FACTOR_ONE
,
899 GR_COMBINE_OTHER_TEXTURE
,
902 case (FX_UM_E0_REPLACE
| FX_UM_E1_MODULATE
): /* Quake 2 and 3 */
904 FX_grTexCombine_NoLock(GR_TMU1
,
905 GR_COMBINE_FUNCTION_LOCAL
,
906 GR_COMBINE_FACTOR_NONE
,
907 GR_COMBINE_FUNCTION_ZERO
,
908 GR_COMBINE_FACTOR_NONE
,
911 FX_grTexCombine_NoLock(GR_TMU0
,
912 GR_COMBINE_FUNCTION_BLEND_OTHER
,
913 GR_COMBINE_FACTOR_LOCAL
,
914 GR_COMBINE_FUNCTION_BLEND_OTHER
,
915 GR_COMBINE_FACTOR_LOCAL
,
919 FX_grTexCombine_NoLock(GR_TMU1
,
920 GR_COMBINE_FUNCTION_LOCAL
,
921 GR_COMBINE_FACTOR_NONE
,
922 GR_COMBINE_FUNCTION_LOCAL
,
923 GR_COMBINE_FACTOR_NONE
,
926 FX_grTexCombine_NoLock(GR_TMU0
,
927 GR_COMBINE_FUNCTION_BLEND_OTHER
,
928 GR_COMBINE_FACTOR_LOCAL
,
929 GR_COMBINE_FUNCTION_BLEND_OTHER
,
930 GR_COMBINE_FACTOR_ONE
,
934 if(ti0
->baseLevelInternalFormat
==GL_RGB
)
935 FX_grAlphaCombine_NoLock(GR_COMBINE_FUNCTION_LOCAL
,
936 GR_COMBINE_FACTOR_NONE
,
938 GR_COMBINE_OTHER_NONE
,
941 FX_grAlphaCombine_NoLock(GR_COMBINE_FUNCTION_SCALE_OTHER
,
942 GR_COMBINE_FACTOR_ONE
,
944 GR_COMBINE_OTHER_NONE
,
948 FX_grColorCombine_NoLock(GR_COMBINE_FUNCTION_SCALE_OTHER
,
949 GR_COMBINE_FACTOR_ONE
,
951 GR_COMBINE_OTHER_TEXTURE
,
956 case (FX_UM_E0_MODULATE
| FX_UM_E1_ADD
): /* Quake 3 Sky */
958 GLboolean isalpha
[FX_NUM_TMU
];
960 if(ti0
->baseLevelInternalFormat
==GL_ALPHA
)
961 isalpha
[tmu0
]=GL_TRUE
;
963 isalpha
[tmu0
]=GL_FALSE
;
965 if(ti1
->baseLevelInternalFormat
==GL_ALPHA
)
966 isalpha
[tmu1
]=GL_TRUE
;
968 isalpha
[tmu1
]=GL_FALSE
;
971 FX_grTexCombine_NoLock(GR_TMU1
,
972 GR_COMBINE_FUNCTION_ZERO
,
973 GR_COMBINE_FACTOR_NONE
,
974 GR_COMBINE_FUNCTION_LOCAL
,
975 GR_COMBINE_FACTOR_NONE
,
978 FX_grTexCombine_NoLock(GR_TMU1
,
979 GR_COMBINE_FUNCTION_LOCAL
,
980 GR_COMBINE_FACTOR_NONE
,
981 GR_COMBINE_FUNCTION_LOCAL
,
982 GR_COMBINE_FACTOR_NONE
,
986 FX_grTexCombine_NoLock(GR_TMU0
,
987 GR_COMBINE_FUNCTION_SCALE_OTHER
,
988 GR_COMBINE_FACTOR_ONE
,
989 GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL
,
990 GR_COMBINE_FACTOR_ONE
,
993 FX_grTexCombine_NoLock(GR_TMU0
,
994 GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL
,
995 GR_COMBINE_FACTOR_ONE
,
996 GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL
,
997 GR_COMBINE_FACTOR_ONE
,
1000 FX_grColorCombine_NoLock(GR_COMBINE_FUNCTION_SCALE_OTHER
,
1001 GR_COMBINE_FACTOR_LOCAL
,
1003 GR_COMBINE_OTHER_TEXTURE
,
1006 FX_grAlphaCombine_NoLock(GR_COMBINE_FUNCTION_SCALE_OTHER
,
1007 GR_COMBINE_FACTOR_LOCAL
,
1009 GR_COMBINE_OTHER_TEXTURE
,
1014 fprintf(stderr
, "Unexpected dual texture mode encountered\n");
1018 if (MESA_VERBOSE
&VERBOSE_DRIVER
) {
1019 fprintf(stderr
,"fxmesa: fxSetupTextureDoubleTMU(...) End\n");
1023 /************************* No Texture ***************************/
1025 static void fxSetupTextureNone_NoLock(GLcontext
*ctx
)
1027 fxMesaContext fxMesa
=(fxMesaContext
)ctx
->DriverCtx
;
1028 GrCombineLocal_t localc
,locala
;
1030 if (MESA_VERBOSE
&VERBOSE_DRIVER
) {
1031 fprintf(stderr
,"fxmesa: fxSetupTextureNone(...)\n");
1034 if((ctx
->Light
.ShadeModel
==GL_SMOOTH
) || 1 ||
1035 (ctx
->Point
.SmoothFlag
) ||
1036 (ctx
->Line
.SmoothFlag
) ||
1037 (ctx
->Polygon
.SmoothFlag
))
1038 locala
=GR_COMBINE_LOCAL_ITERATED
;
1040 locala
=GR_COMBINE_LOCAL_CONSTANT
;
1042 if(ctx
->Light
.ShadeModel
==GL_SMOOTH
|| 1)
1043 localc
=GR_COMBINE_LOCAL_ITERATED
;
1045 localc
=GR_COMBINE_LOCAL_CONSTANT
;
1047 FX_grAlphaCombine_NoLock(GR_COMBINE_FUNCTION_LOCAL
,
1048 GR_COMBINE_FACTOR_NONE
,
1050 GR_COMBINE_OTHER_NONE
,
1053 FX_grColorCombine_NoLock(GR_COMBINE_FUNCTION_LOCAL
,
1054 GR_COMBINE_FACTOR_NONE
,
1056 GR_COMBINE_OTHER_NONE
,
1059 fxMesa
->lastUnitsMode
=FX_UM_NONE
;
1062 /************************************************************************/
1063 /************************** Texture Mode SetUp **************************/
1064 /************************************************************************/
1066 static void fxSetupTexture_NoLock(GLcontext
*ctx
)
1068 fxMesaContext fxMesa
=(fxMesaContext
)ctx
->DriverCtx
;
1069 GLuint tex2Denabled
;
1071 if (MESA_VERBOSE
&VERBOSE_DRIVER
) {
1072 fprintf(stderr
,"fxmesa: fxSetupTexture(...)\n");
1075 /* Disable multipass texturing.
1077 ctx
->Driver
.MultipassFunc
= 0;
1079 /* Texture Combine, Color Combine and Alpha Combine.
1081 tex2Denabled
= (ctx
->Texture
.ReallyEnabled
& TEXTURE0_2D
);
1083 if (fxMesa
->emulateTwoTMUs
)
1084 tex2Denabled
|= (ctx
->Texture
.ReallyEnabled
& TEXTURE1_2D
);
1086 switch(tex2Denabled
) {
1088 fxSetupTextureSingleTMU_NoLock(ctx
,0);
1091 fxSetupTextureSingleTMU_NoLock(ctx
,1);
1093 case (TEXTURE0_2D
|TEXTURE1_2D
):
1094 if (fxMesa
->haveTwoTMUs
)
1095 fxSetupTextureDoubleTMU_NoLock(ctx
);
1097 if (MESA_VERBOSE
&VERBOSE_DRIVER
)
1098 fprintf(stderr
, "fxmesa: enabling fake multitexture\n");
1100 fxSetupTextureSingleTMU_NoLock(ctx
,0);
1101 ctx
->Driver
.MultipassFunc
= fxMultipassTexture
;
1105 fxSetupTextureNone_NoLock(ctx
);
1110 static void fxSetupTexture(GLcontext
*ctx
) {
1112 fxSetupTexture_NoLock(ctx
);
1116 /************************************************************************/
1117 /**************************** Blend SetUp *******************************/
1118 /************************************************************************/
1120 /* XXX consider supporting GL_INGR_blend_func_separate */
1121 void fxDDBlendFunc(GLcontext
*ctx
, GLenum sfactor
, GLenum dfactor
)
1123 fxMesaContext fxMesa
=(fxMesaContext
)ctx
->DriverCtx
;
1124 tfxUnitsState
*us
=&fxMesa
->unitsState
;
1125 GrAlphaBlendFnc_t sfact
,dfact
,asfact
,adfact
;
1127 /* From the Glide documentation:
1128 For alpha source and destination blend function factor
1129 parameters, Voodoo Graphics supports only
1130 GR_BLEND_ZERO and GR_BLEND_ONE.
1135 asfact
=sfact
=GR_BLEND_ZERO
;
1138 asfact
=sfact
=GR_BLEND_ONE
;
1141 sfact
=GR_BLEND_DST_COLOR
;
1142 asfact
=GR_BLEND_ONE
;
1144 case GL_ONE_MINUS_DST_COLOR
:
1145 sfact
=GR_BLEND_ONE_MINUS_DST_COLOR
;
1146 asfact
=GR_BLEND_ONE
;
1149 sfact
=GR_BLEND_SRC_ALPHA
;
1150 asfact
=GR_BLEND_ONE
;
1152 case GL_ONE_MINUS_SRC_ALPHA
:
1153 sfact
=GR_BLEND_ONE_MINUS_SRC_ALPHA
;
1154 asfact
=GR_BLEND_ONE
;
1157 sfact
=GR_BLEND_DST_ALPHA
;
1158 asfact
=GR_BLEND_ONE
;
1160 case GL_ONE_MINUS_DST_ALPHA
:
1161 sfact
=GR_BLEND_ONE_MINUS_DST_ALPHA
;
1162 asfact
=GR_BLEND_ONE
;
1164 case GL_SRC_ALPHA_SATURATE
:
1165 sfact
=GR_BLEND_ALPHA_SATURATE
;
1166 asfact
=GR_BLEND_ONE
;
1169 case GL_ONE_MINUS_SRC_COLOR
:
1171 asfact
=sfact
=GR_BLEND_ONE
;
1174 asfact
=sfact
=GR_BLEND_ONE
;
1178 if((sfact
!=us
->blendSrcFuncRGB
) ||
1179 (asfact
!=us
->blendSrcFuncAlpha
)) {
1180 us
->blendSrcFuncRGB
=sfact
;
1181 us
->blendSrcFuncAlpha
=asfact
;
1182 fxMesa
->new_state
|= FX_NEW_BLEND
;
1183 ctx
->Driver
.RenderStart
= fxSetupFXUnits
;
1188 adfact
=dfact
=GR_BLEND_ZERO
;
1191 adfact
=dfact
=GR_BLEND_ONE
;
1194 dfact
=GR_BLEND_SRC_COLOR
;
1195 adfact
=GR_BLEND_ZERO
;
1197 case GL_ONE_MINUS_SRC_COLOR
:
1198 dfact
=GR_BLEND_ONE_MINUS_SRC_COLOR
;
1199 adfact
=GR_BLEND_ZERO
;
1202 dfact
=GR_BLEND_SRC_ALPHA
;
1203 adfact
=GR_BLEND_ZERO
;
1205 case GL_ONE_MINUS_SRC_ALPHA
:
1206 dfact
=GR_BLEND_ONE_MINUS_SRC_ALPHA
;
1207 adfact
=GR_BLEND_ZERO
;
1210 /* dfact=GR_BLEND_DST_ALPHA; */
1211 /* We can't do DST_ALPHA */
1213 adfact
=GR_BLEND_ZERO
;
1215 case GL_ONE_MINUS_DST_ALPHA
:
1216 /* dfact=GR_BLEND_ONE_MINUS_DST_ALPHA; */
1217 /* We can't do DST_ALPHA */
1218 dfact
=GR_BLEND_ZERO
;
1219 adfact
=GR_BLEND_ZERO
;
1221 case GL_SRC_ALPHA_SATURATE
:
1223 case GL_ONE_MINUS_DST_COLOR
:
1225 adfact
=dfact
=GR_BLEND_ZERO
;
1228 adfact
=dfact
=GR_BLEND_ZERO
;
1232 if((dfact
!=us
->blendDstFuncRGB
) ||
1233 (adfact
!=us
->blendDstFuncAlpha
)) {
1234 us
->blendDstFuncRGB
=dfact
;
1235 us
->blendDstFuncAlpha
=adfact
;
1236 fxMesa
->new_state
|= FX_NEW_BLEND
;
1237 ctx
->Driver
.RenderStart
= fxSetupFXUnits
;
1241 static void fxSetupBlend(GLcontext
*ctx
)
1243 fxMesaContext fxMesa
=(fxMesaContext
)ctx
->DriverCtx
;
1244 tfxUnitsState
*us
=&fxMesa
->unitsState
;
1246 if(us
->blendEnabled
)
1247 FX_grAlphaBlendFunction(us
->blendSrcFuncRGB
,us
->blendDstFuncRGB
,
1248 us
->blendSrcFuncAlpha
,us
->blendDstFuncAlpha
);
1250 FX_grAlphaBlendFunction(GR_BLEND_ONE
,GR_BLEND_ZERO
,GR_BLEND_ONE
,GR_BLEND_ZERO
);
1253 /************************************************************************/
1254 /************************** Alpha Test SetUp ****************************/
1255 /************************************************************************/
1257 void fxDDAlphaFunc(GLcontext
*ctx
, GLenum func
, GLclampf ref
)
1259 fxMesaContext fxMesa
=(fxMesaContext
)ctx
->DriverCtx
;
1260 tfxUnitsState
*us
=&fxMesa
->unitsState
;
1265 newfunc
=GR_CMP_NEVER
;
1268 newfunc
=GR_CMP_LESS
;
1271 newfunc
=GR_CMP_EQUAL
;
1274 newfunc
=GR_CMP_LEQUAL
;
1277 newfunc
=GR_CMP_GREATER
;
1280 newfunc
=GR_CMP_NOTEQUAL
;
1283 newfunc
=GR_CMP_GEQUAL
;
1286 newfunc
=GR_CMP_ALWAYS
;
1289 fprintf(stderr
,"fx Driver: internal error in fxDDAlphaFunc()\n");
1295 if(newfunc
!=us
->alphaTestFunc
) {
1296 us
->alphaTestFunc
=newfunc
;
1297 fxMesa
->new_state
|= FX_NEW_ALPHA
;
1298 ctx
->Driver
.RenderStart
= fxSetupFXUnits
;
1301 if(ctx
->Color
.AlphaRef
!=us
->alphaTestRefValue
) {
1302 us
->alphaTestRefValue
=ctx
->Color
.AlphaRef
;
1303 fxMesa
->new_state
|= FX_NEW_ALPHA
;
1304 ctx
->Driver
.RenderStart
= fxSetupFXUnits
;
1308 static void fxSetupAlphaTest(GLcontext
*ctx
)
1310 fxMesaContext fxMesa
=(fxMesaContext
)ctx
->DriverCtx
;
1311 tfxUnitsState
*us
=&fxMesa
->unitsState
;
1313 if(us
->alphaTestEnabled
) {
1314 FX_grAlphaTestFunction(us
->alphaTestFunc
);
1315 FX_grAlphaTestReferenceValue(us
->alphaTestRefValue
);
1317 FX_grAlphaTestFunction(GR_CMP_ALWAYS
);
1320 /************************************************************************/
1321 /************************** Depth Test SetUp ****************************/
1322 /************************************************************************/
1324 void fxDDDepthFunc(GLcontext
*ctx
, GLenum func
)
1326 fxMesaContext fxMesa
=(fxMesaContext
)ctx
->DriverCtx
;
1327 tfxUnitsState
*us
=&fxMesa
->unitsState
;
1338 dfunc
=GR_CMP_GEQUAL
;
1341 dfunc
=GR_CMP_LEQUAL
;
1344 dfunc
=GR_CMP_GREATER
;
1347 dfunc
=GR_CMP_NOTEQUAL
;
1353 dfunc
=GR_CMP_ALWAYS
;
1356 fprintf(stderr
,"fx Driver: internal error in fxDDDepthFunc()\n");
1362 if(dfunc
!=us
->depthTestFunc
) {
1363 us
->depthTestFunc
=dfunc
;
1364 fxMesa
->new_state
|= FX_NEW_DEPTH
;
1365 ctx
->Driver
.RenderStart
= fxSetupFXUnits
;
1370 void fxDDDepthMask(GLcontext
*ctx
, GLboolean flag
)
1372 fxMesaContext fxMesa
=(fxMesaContext
)ctx
->DriverCtx
;
1373 tfxUnitsState
*us
=&fxMesa
->unitsState
;
1375 if(flag
!=us
->depthMask
) {
1377 fxMesa
->new_state
|= FX_NEW_DEPTH
;
1378 ctx
->Driver
.RenderStart
= fxSetupFXUnits
;
1382 static void fxSetupDepthTest(GLcontext
*ctx
)
1384 fxMesaContext fxMesa
=(fxMesaContext
)ctx
->DriverCtx
;
1385 tfxUnitsState
*us
=&fxMesa
->unitsState
;
1387 if (us
->depthTestEnabled
) {
1388 FX_grDepthBufferFunction(us
->depthTestFunc
);
1389 FX_grDepthMask(us
->depthMask
);
1392 FX_grDepthBufferFunction(GR_CMP_ALWAYS
);
1393 FX_grDepthMask(FXFALSE
);
1397 /************************************************************************/
1398 /**************************** Color Mask SetUp **************************/
1399 /************************************************************************/
1401 void fxDDColorMask(GLcontext
*ctx
,
1402 GLboolean r
, GLboolean g
,
1403 GLboolean b
, GLboolean a
)
1405 fxMesaContext fxMesa
=(fxMesaContext
)ctx
->DriverCtx
;
1406 fxMesa
->new_state
|= FX_NEW_COLOR_MASK
;
1407 ctx
->Driver
.RenderStart
= fxSetupFXUnits
;
1408 (void) r
; (void) g
; (void) b
; (void) a
;
1412 static void fxSetupColorMask(GLcontext
*ctx
)
1414 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
1416 if (ctx
->Color
.DrawBuffer
== GL_NONE
) {
1417 FX_grColorMask(FXFALSE
, FXFALSE
);
1420 FX_grColorMask(ctx
->Color
.ColorMask
[RCOMP
] ||
1421 ctx
->Color
.ColorMask
[GCOMP
] ||
1422 ctx
->Color
.ColorMask
[BCOMP
],
1423 ctx
->Color
.ColorMask
[ACOMP
] && fxMesa
->haveAlphaBuffer
);
1430 /************************************************************************/
1431 /**************************** Fog Mode SetUp ****************************/
1432 /************************************************************************/
1435 * This is called during state update in order to update the Glide fog state.
1437 static void fxSetupFog(GLcontext
*ctx
)
1439 if (ctx
->Fog
.Enabled
&& ctx
->FogMode
==FOG_FRAGMENT
) {
1440 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
1442 /* update fog color */
1444 col
[0]=(unsigned int)(255*ctx
->Fog
.Color
[0]);
1445 col
[1]=(unsigned int)(255*ctx
->Fog
.Color
[1]);
1446 col
[2]=(unsigned int)(255*ctx
->Fog
.Color
[2]);
1447 col
[3]=(unsigned int)(255*ctx
->Fog
.Color
[3]);
1448 FX_grFogColorValue(FXCOLOR4(col
));
1450 if(fxMesa
->fogTableMode
!= ctx
->Fog
.Mode
||
1451 fxMesa
->fogDensity
!= ctx
->Fog
.Density
||
1452 fxMesa
->fogStart
!= ctx
->Fog
.Start
||
1453 fxMesa
->fogEnd
!= ctx
->Fog
.End
) {
1454 /* reload the fog table */
1455 switch (ctx
->Fog
.Mode
) {
1457 guFogGenerateLinear(fxMesa
->fogTable
, ctx
->Fog
.Start
, ctx
->Fog
.End
);
1460 guFogGenerateExp(fxMesa
->fogTable
, ctx
->Fog
.Density
);
1463 guFogGenerateExp2(fxMesa
->fogTable
, ctx
->Fog
.Density
);
1468 fxMesa
->fogTableMode
= ctx
->Fog
.Mode
;
1469 fxMesa
->fogDensity
= ctx
->Fog
.Density
;
1470 fxMesa
->fogStart
= ctx
->Fog
.Start
;
1471 fxMesa
->fogEnd
= ctx
->Fog
.End
;
1474 FX_grFogTable(fxMesa
->fogTable
);
1475 FX_grFogMode(GR_FOG_WITH_TABLE
);
1478 FX_grFogMode(GR_FOG_DISABLE
);
1482 void fxDDFogfv( GLcontext
*ctx
, GLenum pname
, const GLfloat
*params
)
1484 FX_CONTEXT(ctx
)->new_state
|= FX_NEW_FOG
;
1485 ctx
->Driver
.RenderStart
= fxSetupFXUnits
; /* XXX why is this here? */
1488 /************************************************************************/
1489 /************************** Scissor Test SetUp **************************/
1490 /************************************************************************/
1492 /* This routine is used in managing the lock state, and therefore can't lock */
1493 void fxSetScissorValues(GLcontext
*ctx
)
1495 fxMesaContext fxMesa
=(fxMesaContext
)ctx
->DriverCtx
;
1497 int ymin
, ymax
, check
;
1499 if (ctx
->Scissor
.Enabled
) {
1500 xmin
=ctx
->Scissor
.X
;
1501 xmax
=ctx
->Scissor
.X
+ctx
->Scissor
.Width
;
1502 ymin
=ctx
->Scissor
.Y
;
1503 ymax
=ctx
->Scissor
.Y
+ctx
->Scissor
.Height
;
1509 ymax
=fxMesa
->height
;
1512 xmin
+=fxMesa
->x_offset
;
1513 xmax
+=fxMesa
->x_offset
;
1514 ymin
+=fxMesa
->y_delta
;
1515 ymax
+=fxMesa
->y_delta
;
1516 if (xmin
<fxMesa
->clipMinX
) xmin
=fxMesa
->clipMinX
;
1517 if (xmax
>fxMesa
->clipMaxX
) xmax
=fxMesa
->clipMaxX
;
1518 if (ymin
<fxMesa
->screen_height
-fxMesa
->clipMaxY
)
1519 ymin
=fxMesa
->screen_height
-fxMesa
->clipMaxY
;
1520 if (ymax
>fxMesa
->screen_height
-fxMesa
->clipMinY
)
1521 ymax
=fxMesa
->screen_height
-fxMesa
->clipMinY
;
1522 FX_grClipWindow_NoLock(xmin
, ymin
, xmax
, ymax
);
1525 static void fxSetupScissor(GLcontext
*ctx
)
1527 fxMesaContext fxMesa
=(fxMesaContext
)ctx
->DriverCtx
;
1528 if (!fxMesa
->needClip
) {
1530 fxSetScissorValues(ctx
);
1535 void fxDDScissor( GLcontext
*ctx
, GLint x
, GLint y
, GLsizei w
, GLsizei h
)
1537 FX_CONTEXT(ctx
)->new_state
|= FX_NEW_SCISSOR
;
1538 ctx
->Driver
.RenderStart
= fxSetupFXUnits
;
1541 /************************************************************************/
1542 /*************************** Cull mode setup ****************************/
1543 /************************************************************************/
1546 void fxDDCullFace(GLcontext
*ctx
, GLenum mode
)
1549 FX_CONTEXT(ctx
)->new_state
|= FX_NEW_CULL
;
1550 ctx
->Driver
.RenderStart
= fxSetupFXUnits
;
1553 void fxDDFrontFace(GLcontext
*ctx
, GLenum mode
)
1556 FX_CONTEXT(ctx
)->new_state
|= FX_NEW_CULL
;
1557 ctx
->Driver
.RenderStart
= fxSetupFXUnits
;
1561 static void fxSetupCull(GLcontext
*ctx
)
1563 if (ctx
->Polygon
.CullFlag
) {
1564 switch (ctx
->Polygon
.CullFaceMode
) {
1566 if (ctx
->Polygon
.FrontFace
==GL_CCW
)
1567 FX_CONTEXT(ctx
)->cullMode
=GR_CULL_NEGATIVE
;
1569 FX_CONTEXT(ctx
)->cullMode
=GR_CULL_POSITIVE
;
1572 if(ctx
->Polygon
.FrontFace
==GL_CCW
)
1573 FX_CONTEXT(ctx
)->cullMode
=GR_CULL_POSITIVE
;
1575 FX_CONTEXT(ctx
)->cullMode
=GR_CULL_NEGATIVE
;
1577 case GL_FRONT_AND_BACK
:
1578 FX_CONTEXT(ctx
)->cullMode
=GR_CULL_DISABLE
;
1583 } else FX_CONTEXT(ctx
)->cullMode
=GR_CULL_DISABLE
;
1584 FX_grCullMode(FX_CONTEXT(ctx
)->cullMode
);
1588 /************************************************************************/
1589 /****************************** DD Enable ******************************/
1590 /************************************************************************/
1592 void fxDDEnable(GLcontext
*ctx
, GLenum cap
, GLboolean state
)
1594 fxMesaContext fxMesa
=(fxMesaContext
)ctx
->DriverCtx
;
1595 tfxUnitsState
*us
=&fxMesa
->unitsState
;
1597 if (MESA_VERBOSE
&VERBOSE_DRIVER
) {
1598 fprintf(stderr
,"fxmesa: fxDDEnable(...)\n");
1603 if(state
!=us
->alphaTestEnabled
) {
1604 us
->alphaTestEnabled
=state
;
1605 fxMesa
->new_state
|= FX_NEW_ALPHA
;
1606 ctx
->Driver
.RenderStart
= fxSetupFXUnits
;
1610 if(state
!=us
->blendEnabled
) {
1611 us
->blendEnabled
=state
;
1612 fxMesa
->new_state
|= FX_NEW_BLEND
;
1613 ctx
->Driver
.RenderStart
= fxSetupFXUnits
;
1617 if(state
!=us
->depthTestEnabled
) {
1618 us
->depthTestEnabled
=state
;
1619 fxMesa
->new_state
|= FX_NEW_DEPTH
;
1620 ctx
->Driver
.RenderStart
= fxSetupFXUnits
;
1623 case GL_SCISSOR_TEST
:
1624 fxMesa
->new_state
|= FX_NEW_SCISSOR
;
1625 ctx
->Driver
.RenderStart
= fxSetupFXUnits
;
1627 case GL_SHARED_TEXTURE_PALETTE_EXT
:
1628 fxDDTexUseGlbPalette(ctx
, state
);
1631 fxMesa
->new_state
|= FX_NEW_FOG
;
1632 ctx
->Driver
.RenderStart
= fxSetupFXUnits
;
1635 fxMesa
->new_state
|= FX_NEW_CULL
;
1636 ctx
->Driver
.RenderStart
= fxSetupFXUnits
;
1638 case GL_LINE_SMOOTH
:
1639 case GL_LINE_STIPPLE
:
1640 case GL_POINT_SMOOTH
:
1641 case GL_POLYGON_SMOOTH
:
1643 fxMesa
->new_state
|= FX_NEW_TEXTURING
;
1644 ctx
->Driver
.RenderStart
= fxSetupFXUnits
;
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)
1658 static GLboolean
fxMultipassBlend(struct vertex_buffer
*VB
, GLuint pass
)
1660 GLcontext
*ctx
= VB
->ctx
;
1661 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
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
) {
1674 fxDDDepthFunc(ctx
, GL_EQUAL
);
1677 fxDDDepthMask(ctx
, FALSE
);
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
);
1685 fxSetupDepthTest(ctx
);
1689 /* Reset everything back to normal */
1690 fxMesa
->unitsState
= fxMesa
->restoreUnitsState
;
1691 fxMesa
->setupdone
&= XXX
;
1692 fxSetupTextureSingleTMU(ctx
, XXX
);
1694 fxSetupDepthTest(ctx
);
1702 /************************************************************************/
1703 /******************** Fake Multitexture Support *************************/
1704 /************************************************************************/
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.
1714 static GLboolean
fxMultipassTexture( struct vertex_buffer
*VB
, GLuint pass
)
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
);
1723 if (MESA_VERBOSE
&(VERBOSE_DRIVER
|VERBOSE_PIPELINE
|VERBOSE_TEXTURE
))
1724 fprintf(stderr
, "fxmesa: Second texture pass\n");
1726 for ( ; v
!= last
; v
++) {
1727 v
->f
[S0COORD
] = v
->f
[S1COORD
];
1728 v
->f
[T0COORD
] = v
->f
[T1COORD
];
1731 fxMesa
->restoreUnitsState
= fxMesa
->unitsState
;
1732 fxMesa
->tmu_source
[0] = 1;
1734 if (ctx
->Depth
.Mask
) {
1735 switch (ctx
->Depth
.Func
) {
1740 fxDDDepthFunc( ctx
, GL_EQUAL
);
1744 fxDDDepthMask( ctx
, GL_FALSE
);
1747 if (ctx
->Texture
.Unit
[1].EnvMode
== GL_MODULATE
) {
1748 fxDDEnable( ctx
, GL_BLEND
, GL_TRUE
);
1749 fxDDBlendFunc( ctx
, GL_DST_COLOR
, GL_ZERO
);
1752 fxSetupTextureSingleTMU( ctx
, 1 );
1753 fxSetupBlend( ctx
);
1754 fxSetupDepthTest( ctx
);
1758 /* Restore original state.
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
);
1773 /************************************************************************/
1774 /************************** Changes to units state **********************/
1775 /************************************************************************/
1778 /* All units setup is handled under texture setup.
1780 void fxDDShadeModel(GLcontext
*ctx
, GLenum mode
)
1782 FX_CONTEXT(ctx
)->new_state
|= FX_NEW_TEXTURING
;
1783 ctx
->Driver
.RenderStart
= fxSetupFXUnits
;
1788 /************************************************************************/
1789 /****************************** Units SetUp *****************************/
1790 /************************************************************************/
1791 static void gl_print_fx_state_flags( const char *msg
, GLuint flags
)
1794 "%s: (0x%x) %s%s%s%s%s%s%s\n",
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, " : "");
1806 void fxSetupFXUnits( GLcontext
*ctx
)
1808 fxMesaContext fxMesa
=(fxMesaContext
)ctx
->DriverCtx
;
1809 GLuint newstate
= fxMesa
->new_state
;
1811 if (MESA_VERBOSE
&VERBOSE_DRIVER
)
1812 gl_print_fx_state_flags("fxmesa: fxSetupFXUnits", newstate
);
1815 if (newstate
& FX_NEW_TEXTURING
)
1816 fxSetupTexture(ctx
);
1818 if (newstate
& FX_NEW_BLEND
)
1821 if (newstate
& FX_NEW_ALPHA
)
1822 fxSetupAlphaTest(ctx
);
1824 if (newstate
& FX_NEW_DEPTH
)
1825 fxSetupDepthTest(ctx
);
1827 if (newstate
& FX_NEW_FOG
)
1830 if (newstate
& FX_NEW_SCISSOR
)
1831 fxSetupScissor(ctx
);
1833 if (newstate
& FX_NEW_COLOR_MASK
)
1834 fxSetupColorMask(ctx
);
1836 if (newstate
& FX_NEW_CULL
)
1839 fxMesa
->new_state
= 0;
1840 /* ctx->Driver.RenderStart = 0; */
1850 * Need this to provide at least one external definition.
1853 int gl_fx_dummy_function_setup(void)