3 * Mesa 3-D graphics library
6 * Copyright (C) 1999-2000 Brian Paul All Rights Reserved.
8 * Permission is hereby granted, free of charge, to any person obtaining a
9 * copy of this software and associated documentation files (the "Software"),
10 * to deal in the Software without restriction, including without limitation
11 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
12 * and/or sell copies of the Software, and to permit persons to whom the
13 * Software is furnished to do so, subject to the following conditions:
15 * The above copyright notice and this permission notice shall be included
16 * in all copies or substantial portions of the Software.
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
22 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
23 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26 * Original Mesa / 3Dfx device driver (C) 1999 David Bucciarelli, by the
29 * Thank you for your contribution, David!
31 * Please make note of the above copyright/license statement. If you
32 * contributed code or bug fixes to this code under the previous (GNU
33 * Library) license and object to the new license, your code will be
34 * removed at your request. Please see the Mesa docs/COPYRIGHT file
35 * for more information.
37 * Additional Mesa/3Dfx driver developers:
38 * Daryll Strauss <daryll@precisioninsight.com>
39 * Keith Whitwell <keith@precisioninsight.com>
41 * See fxapi.h for more revision/author details.
45 /* fxsetup.c - 3Dfx VooDoo rendering mode setup functions */
57 #include "tnl/t_context.h"
59 static GLuint
fxGetTexSetConfiguration(GLcontext
* ctx
,
60 struct gl_texture_object
*tObj0
,
61 struct gl_texture_object
*tObj1
);
62 static void fxSetupTextureSingleTMU_NoLock(GLcontext
* ctx
,
64 static void fxSetupDoubleTMU_NoLock(fxMesaContext fxMesa
,
65 struct gl_texture_object
*tObj0
,
66 struct gl_texture_object
*tObj1
);
67 static void fxSetupTexture_NoLock(GLcontext
* ctx
);
68 static void fxSetupTexture(GLcontext
* ctx
);
69 static void fxSetupBlend(GLcontext
* ctx
);
70 static void fxSetupDepthTest(GLcontext
* ctx
);
71 static void fxSetupScissor(GLcontext
* ctx
);
72 static void fxSetupCull(GLcontext
* ctx
);
73 static void fx_print_state_flags(const char *msg
, GLuint flags
);
74 /*static GLboolean fxMultipassBlend(struct vertex_buffer *, GLuint);*/
75 static GLboolean
fxMultipassTexture(GLcontext
*, GLuint
);
78 fxTexValidate(GLcontext
* ctx
, struct gl_texture_object
*tObj
)
80 tfxTexInfo
*ti
= fxTMGetTexInfo(tObj
);
83 if (MESA_VERBOSE
& VERBOSE_DRIVER
) {
84 fprintf(stderr
, "fxmesa: fxTexValidate(...) Start\n");
88 if (MESA_VERBOSE
& VERBOSE_DRIVER
) {
90 "fxmesa: fxTexValidate(...) End (validated=GL_TRUE)\n");
96 minl
= ti
->minLevel
= tObj
->BaseLevel
;
97 maxl
= ti
->maxLevel
= MIN2(tObj
->MaxLevel
, tObj
->Image
[0]->MaxLog2
);
99 fxTexGetInfo(tObj
->Image
[minl
]->Width
, tObj
->Image
[minl
]->Height
,
100 &(FX_largeLodLog2(ti
->info
)), &(FX_aspectRatioLog2(ti
->info
)),
101 &(ti
->sScale
), &(ti
->tScale
),
102 &(ti
->int_sScale
), &(ti
->int_tScale
), NULL
, NULL
);
104 if ((tObj
->MinFilter
!= GL_NEAREST
) && (tObj
->MinFilter
!= GL_LINEAR
))
105 fxTexGetInfo(tObj
->Image
[maxl
]->Width
, tObj
->Image
[maxl
]->Height
,
106 &(FX_smallLodLog2(ti
->info
)), NULL
,
107 NULL
, NULL
, NULL
, NULL
, NULL
, NULL
);
109 FX_smallLodLog2(ti
->info
) = FX_largeLodLog2(ti
->info
);
111 fxTexGetFormat(tObj
->Image
[minl
]->TexFormat
->IntFormat
, &(ti
->info
.format
),
112 &(ti
->baseLevelInternalFormat
));
114 switch (tObj
->WrapS
) {
115 case GL_CLAMP_TO_EDGE
:
116 /* What's this really mean compared to GL_CLAMP? */
124 ; /* silence compiler warning */
126 switch (tObj
->WrapT
) {
127 case GL_CLAMP_TO_EDGE
:
128 /* What's this really mean compared to GL_CLAMP? */
136 ; /* silence compiler warning */
139 ti
->validated
= GL_TRUE
;
141 ti
->info
.data
= NULL
;
143 if (MESA_VERBOSE
& VERBOSE_DRIVER
) {
144 fprintf(stderr
, "fxmesa: fxTexValidate(...) End\n");
149 fxPrintUnitsMode(const char *msg
, GLuint mode
)
152 "%s: (0x%x) %s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s\n",
155 (mode
& FX_UM_E0_REPLACE
) ? "E0_REPLACE, " : "",
156 (mode
& FX_UM_E0_MODULATE
) ? "E0_MODULATE, " : "",
157 (mode
& FX_UM_E0_DECAL
) ? "E0_DECAL, " : "",
158 (mode
& FX_UM_E0_BLEND
) ? "E0_BLEND, " : "",
159 (mode
& FX_UM_E1_REPLACE
) ? "E1_REPLACE, " : "",
160 (mode
& FX_UM_E1_MODULATE
) ? "E1_MODULATE, " : "",
161 (mode
& FX_UM_E1_DECAL
) ? "E1_DECAL, " : "",
162 (mode
& FX_UM_E1_BLEND
) ? "E1_BLEND, " : "",
163 (mode
& FX_UM_E0_ALPHA
) ? "E0_ALPHA, " : "",
164 (mode
& FX_UM_E0_LUMINANCE
) ? "E0_LUMINANCE, " : "",
165 (mode
& FX_UM_E0_LUMINANCE_ALPHA
) ? "E0_LUMINANCE_ALPHA, " : "",
166 (mode
& FX_UM_E0_INTENSITY
) ? "E0_INTENSITY, " : "",
167 (mode
& FX_UM_E0_RGB
) ? "E0_RGB, " : "",
168 (mode
& FX_UM_E0_RGBA
) ? "E0_RGBA, " : "",
169 (mode
& FX_UM_E1_ALPHA
) ? "E1_ALPHA, " : "",
170 (mode
& FX_UM_E1_LUMINANCE
) ? "E1_LUMINANCE, " : "",
171 (mode
& FX_UM_E1_LUMINANCE_ALPHA
) ? "E1_LUMINANCE_ALPHA, " : "",
172 (mode
& FX_UM_E1_INTENSITY
) ? "E1_INTENSITY, " : "",
173 (mode
& FX_UM_E1_RGB
) ? "E1_RGB, " : "",
174 (mode
& FX_UM_E1_RGBA
) ? "E1_RGBA, " : "",
175 (mode
& FX_UM_COLOR_ITERATED
) ? "COLOR_ITERATED, " : "",
176 (mode
& FX_UM_COLOR_CONSTANT
) ? "COLOR_CONSTANT, " : "",
177 (mode
& FX_UM_ALPHA_ITERATED
) ? "ALPHA_ITERATED, " : "",
178 (mode
& FX_UM_ALPHA_CONSTANT
) ? "ALPHA_CONSTANT, " : "");
182 fxGetTexSetConfiguration(GLcontext
* ctx
,
183 struct gl_texture_object
*tObj0
,
184 struct gl_texture_object
*tObj1
)
186 GLuint unitsmode
= 0;
190 if ((ctx
->Light
.ShadeModel
== GL_SMOOTH
) || 1 ||
191 (ctx
->Point
.SmoothFlag
) ||
192 (ctx
->Line
.SmoothFlag
) ||
193 (ctx
->Polygon
.SmoothFlag
)) unitsmode
|= FX_UM_ALPHA_ITERATED
;
195 unitsmode
|= FX_UM_ALPHA_CONSTANT
;
197 if (ctx
->Light
.ShadeModel
== GL_SMOOTH
|| 1)
198 unitsmode
|= FX_UM_COLOR_ITERATED
;
200 unitsmode
|= FX_UM_COLOR_CONSTANT
;
205 OpenGL Feeds Texture 0 into Texture 1
206 Glide Feeds Texture 1 into Texture 0
209 tfxTexInfo
*ti0
= fxTMGetTexInfo(tObj0
);
211 switch (ti0
->baseLevelInternalFormat
) {
213 ifmt
|= FX_UM_E0_ALPHA
;
216 ifmt
|= FX_UM_E0_LUMINANCE
;
218 case GL_LUMINANCE_ALPHA
:
219 ifmt
|= FX_UM_E0_LUMINANCE_ALPHA
;
222 ifmt
|= FX_UM_E0_INTENSITY
;
225 ifmt
|= FX_UM_E0_RGB
;
228 ifmt
|= FX_UM_E0_RGBA
;
232 switch (ctx
->Texture
.Unit
[0].EnvMode
) {
234 envmode
|= FX_UM_E0_DECAL
;
237 envmode
|= FX_UM_E0_MODULATE
;
240 envmode
|= FX_UM_E0_REPLACE
;
243 envmode
|= FX_UM_E0_BLEND
;
246 envmode
|= FX_UM_E0_ADD
;
255 tfxTexInfo
*ti1
= fxTMGetTexInfo(tObj1
);
257 switch (ti1
->baseLevelInternalFormat
) {
259 ifmt
|= FX_UM_E1_ALPHA
;
262 ifmt
|= FX_UM_E1_LUMINANCE
;
264 case GL_LUMINANCE_ALPHA
:
265 ifmt
|= FX_UM_E1_LUMINANCE_ALPHA
;
268 ifmt
|= FX_UM_E1_INTENSITY
;
271 ifmt
|= FX_UM_E1_RGB
;
274 ifmt
|= FX_UM_E1_RGBA
;
281 switch (ctx
->Texture
.Unit
[1].EnvMode
) {
283 envmode
|= FX_UM_E1_DECAL
;
286 envmode
|= FX_UM_E1_MODULATE
;
289 envmode
|= FX_UM_E1_REPLACE
;
292 envmode
|= FX_UM_E1_BLEND
;
295 envmode
|= FX_UM_E1_ADD
;
303 unitsmode
|= (ifmt
| envmode
);
305 if (MESA_VERBOSE
& (VERBOSE_DRIVER
| VERBOSE_TEXTURE
))
306 fxPrintUnitsMode("unitsmode", unitsmode
);
311 /************************************************************************/
312 /************************* Rendering Mode SetUp *************************/
313 /************************************************************************/
315 /************************* Single Texture Set ***************************/
318 fxSetupSingleTMU_NoLock(fxMesaContext fxMesa
, struct gl_texture_object
*tObj
)
320 tfxTexInfo
*ti
= fxTMGetTexInfo(tObj
);
323 /* Make sure we're not loaded incorrectly */
326 if (ti
->whichTMU
!= FX_TMU_SPLIT
)
327 fxTMMoveOutTM(fxMesa
, tObj
);
330 if (ti
->whichTMU
== FX_TMU_SPLIT
)
331 fxTMMoveOutTM(fxMesa
, tObj
);
335 /* Make sure we're loaded correctly */
338 fxTMMoveInTM_NoLock(fxMesa
, tObj
, FX_TMU_SPLIT
);
340 if (fxMesa
->haveTwoTMUs
) {
341 if (fxMesa
->freeTexMem
[FX_TMU0
] >
342 FX_grTexTextureMemRequired_NoLock(GR_MIPMAPLEVELMASK_BOTH
,
344 fxTMMoveInTM_NoLock(fxMesa
, tObj
, FX_TMU0
);
347 fxTMMoveInTM_NoLock(fxMesa
, tObj
, FX_TMU1
);
351 fxTMMoveInTM_NoLock(fxMesa
, tObj
, FX_TMU0
);
355 if (ti
->LODblend
&& ti
->whichTMU
== FX_TMU_SPLIT
) {
356 if ((ti
->info
.format
== GR_TEXFMT_P_8
)
357 && (!fxMesa
->haveGlobalPaletteTexture
)) {
358 if (MESA_VERBOSE
& VERBOSE_DRIVER
) {
359 fprintf(stderr
, "fxmesa: uploading texture palette\n");
361 FX_grTexDownloadTable_NoLock(GR_TMU0
, GR_TEXTABLE_PALETTE
,
363 FX_grTexDownloadTable_NoLock(GR_TMU1
, GR_TEXTABLE_PALETTE
,
367 FX_grTexClampMode_NoLock(GR_TMU0
, ti
->sClamp
, ti
->tClamp
);
368 FX_grTexClampMode_NoLock(GR_TMU1
, ti
->sClamp
, ti
->tClamp
);
369 FX_grTexFilterMode_NoLock(GR_TMU0
, ti
->minFilt
, ti
->maxFilt
);
370 FX_grTexFilterMode_NoLock(GR_TMU1
, ti
->minFilt
, ti
->maxFilt
);
371 FX_grTexMipMapMode_NoLock(GR_TMU0
, ti
->mmMode
, ti
->LODblend
);
372 FX_grTexMipMapMode_NoLock(GR_TMU1
, ti
->mmMode
, ti
->LODblend
);
374 FX_grTexSource_NoLock(GR_TMU0
, ti
->tm
[FX_TMU0
]->startAddr
,
375 GR_MIPMAPLEVELMASK_ODD
, &(ti
->info
));
376 FX_grTexSource_NoLock(GR_TMU1
, ti
->tm
[FX_TMU1
]->startAddr
,
377 GR_MIPMAPLEVELMASK_EVEN
, &(ti
->info
));
380 if (ti
->whichTMU
== FX_TMU_BOTH
)
385 if ((ti
->info
.format
== GR_TEXFMT_P_8
)
386 && (!fxMesa
->haveGlobalPaletteTexture
)) {
387 if (MESA_VERBOSE
& VERBOSE_DRIVER
) {
388 fprintf(stderr
, "fxmesa: uploading texture palette\n");
390 FX_grTexDownloadTable_NoLock(tmu
, GR_TEXTABLE_PALETTE
,
394 /* KW: The alternative is to do the download to the other tmu. If
395 * we get to this point, I think it means we are thrashing the
396 * texture memory, so perhaps it's not a good idea.
398 if (ti
->LODblend
&& (MESA_VERBOSE
& VERBOSE_DRIVER
))
399 fprintf(stderr
, "fxmesa: not blending texture - only on one tmu\n");
401 FX_grTexClampMode_NoLock(tmu
, ti
->sClamp
, ti
->tClamp
);
402 FX_grTexFilterMode_NoLock(tmu
, ti
->minFilt
, ti
->maxFilt
);
403 FX_grTexMipMapMode_NoLock(tmu
, ti
->mmMode
, FXFALSE
);
405 FX_grTexSource_NoLock(tmu
, ti
->tm
[tmu
]->startAddr
,
406 GR_MIPMAPLEVELMASK_BOTH
, &(ti
->info
));
411 fxSelectSingleTMUSrc_NoLock(fxMesaContext fxMesa
, GLint tmu
, FxBool LODblend
)
413 if (MESA_VERBOSE
& VERBOSE_DRIVER
) {
414 fprintf(stderr
, "fxmesa: fxSelectSingleTMUSrc(%d,%d)\n", tmu
, LODblend
);
418 FX_grTexCombine_NoLock(GR_TMU0
,
419 GR_COMBINE_FUNCTION_BLEND
,
420 GR_COMBINE_FACTOR_ONE_MINUS_LOD_FRACTION
,
421 GR_COMBINE_FUNCTION_BLEND
,
422 GR_COMBINE_FACTOR_ONE_MINUS_LOD_FRACTION
,
425 if (fxMesa
->haveTwoTMUs
)
426 FX_grTexCombine_NoLock(GR_TMU1
,
427 GR_COMBINE_FUNCTION_LOCAL
,
428 GR_COMBINE_FACTOR_NONE
,
429 GR_COMBINE_FUNCTION_LOCAL
,
430 GR_COMBINE_FACTOR_NONE
, FXFALSE
, FXFALSE
);
431 fxMesa
->tmuSrc
= FX_TMU_SPLIT
;
434 if (tmu
!= FX_TMU1
) {
435 FX_grTexCombine_NoLock(GR_TMU0
,
436 GR_COMBINE_FUNCTION_LOCAL
,
437 GR_COMBINE_FACTOR_NONE
,
438 GR_COMBINE_FUNCTION_LOCAL
,
439 GR_COMBINE_FACTOR_NONE
, FXFALSE
, FXFALSE
);
440 if (fxMesa
->haveTwoTMUs
) {
441 FX_grTexCombine_NoLock(GR_TMU1
,
442 GR_COMBINE_FUNCTION_ZERO
,
443 GR_COMBINE_FACTOR_NONE
,
444 GR_COMBINE_FUNCTION_ZERO
,
445 GR_COMBINE_FACTOR_NONE
, FXFALSE
, FXFALSE
);
447 fxMesa
->tmuSrc
= FX_TMU0
;
450 FX_grTexCombine_NoLock(GR_TMU1
,
451 GR_COMBINE_FUNCTION_LOCAL
,
452 GR_COMBINE_FACTOR_NONE
,
453 GR_COMBINE_FUNCTION_LOCAL
,
454 GR_COMBINE_FACTOR_NONE
, FXFALSE
, FXFALSE
);
456 /* GR_COMBINE_FUNCTION_SCALE_OTHER doesn't work ?!? */
458 FX_grTexCombine_NoLock(GR_TMU0
,
459 GR_COMBINE_FUNCTION_BLEND
,
460 GR_COMBINE_FACTOR_ONE
,
461 GR_COMBINE_FUNCTION_BLEND
,
462 GR_COMBINE_FACTOR_ONE
, FXFALSE
, FXFALSE
);
464 fxMesa
->tmuSrc
= FX_TMU1
;
470 fxSetupTextureSingleTMU_NoLock(GLcontext
* ctx
, GLuint textureset
)
472 fxMesaContext fxMesa
= (fxMesaContext
) ctx
->DriverCtx
;
473 GrCombineLocal_t localc
, locala
;
477 struct gl_texture_object
*tObj
= ctx
->Texture
.Unit
[textureset
].Current2D
;
480 if (MESA_VERBOSE
& VERBOSE_DRIVER
) {
481 fprintf(stderr
, "fxmesa: fxSetupTextureSingleTMU(...) Start\n");
484 ti
= fxTMGetTexInfo(tObj
);
486 fxTexValidate(ctx
, tObj
);
488 fxSetupSingleTMU_NoLock(fxMesa
, tObj
);
490 if (ti
->whichTMU
== FX_TMU_BOTH
)
494 if (fxMesa
->tmuSrc
!= tmu
)
495 fxSelectSingleTMUSrc_NoLock(fxMesa
, tmu
, ti
->LODblend
);
497 if (textureset
== 0 || !fxMesa
->haveTwoTMUs
)
498 unitsmode
= fxGetTexSetConfiguration(ctx
, tObj
, NULL
);
500 unitsmode
= fxGetTexSetConfiguration(ctx
, NULL
, tObj
);
502 /* if(fxMesa->lastUnitsMode==unitsmode) */
505 fxMesa
->lastUnitsMode
= unitsmode
;
507 fxMesa
->stw_hint_state
= 0;
508 FX_grHints_NoLock(GR_HINT_STWHINT
, 0);
510 ifmt
= ti
->baseLevelInternalFormat
;
512 if (unitsmode
& FX_UM_ALPHA_ITERATED
)
513 locala
= GR_COMBINE_LOCAL_ITERATED
;
515 locala
= GR_COMBINE_LOCAL_CONSTANT
;
517 if (unitsmode
& FX_UM_COLOR_ITERATED
)
518 localc
= GR_COMBINE_LOCAL_ITERATED
;
520 localc
= GR_COMBINE_LOCAL_CONSTANT
;
522 if (MESA_VERBOSE
& (VERBOSE_DRIVER
| VERBOSE_TEXTURE
))
523 fprintf(stderr
, "fxMesa: fxSetupTextureSingleTMU, envmode is %s\n",
524 _mesa_lookup_enum_by_nr(ctx
->Texture
.Unit
[textureset
].EnvMode
));
526 switch (ctx
->Texture
.Unit
[textureset
].EnvMode
) {
528 FX_grAlphaCombine_NoLock(GR_COMBINE_FUNCTION_LOCAL
,
529 GR_COMBINE_FACTOR_NONE
,
530 locala
, GR_COMBINE_OTHER_NONE
, FXFALSE
);
532 FX_grColorCombine_NoLock(GR_COMBINE_FUNCTION_BLEND
,
533 GR_COMBINE_FACTOR_TEXTURE_ALPHA
,
534 localc
, GR_COMBINE_OTHER_TEXTURE
, FXFALSE
);
537 FX_grAlphaCombine_NoLock(GR_COMBINE_FUNCTION_SCALE_OTHER
,
538 GR_COMBINE_FACTOR_LOCAL
,
539 locala
, GR_COMBINE_OTHER_TEXTURE
, FXFALSE
);
541 if (ifmt
== GL_ALPHA
)
542 FX_grColorCombine_NoLock(GR_COMBINE_FUNCTION_LOCAL
,
543 GR_COMBINE_FACTOR_NONE
,
544 localc
, GR_COMBINE_OTHER_NONE
, FXFALSE
);
546 FX_grColorCombine_NoLock(GR_COMBINE_FUNCTION_SCALE_OTHER
,
547 GR_COMBINE_FACTOR_LOCAL
,
548 localc
, GR_COMBINE_OTHER_TEXTURE
, FXFALSE
);
552 FX_grAlphaCombine_NoLock(GR_COMBINE_FUNCTION_SCALE_OTHER
,
553 GR_COMBINE_FACTOR_LOCAL
,
554 locala
, GR_COMBINE_OTHER_TEXTURE
, FXFALSE
);
555 if (ifmt
== GL_ALPHA
)
556 FX_grColorCombine_NoLock(GR_COMBINE_FUNCTION_LOCAL
,
557 GR_COMBINE_FACTOR_NONE
,
558 localc
, GR_COMBINE_OTHER_NONE
, FXFALSE
);
560 FX_grColorCombine_NoLock(GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL
,
561 GR_COMBINE_FACTOR_LOCAL
,
562 localc
, GR_COMBINE_OTHER_TEXTURE
, FXTRUE
);
563 ctx
->Driver
.MultipassFunc
= fxMultipassBlend
;
565 if (MESA_VERBOSE
& VERBOSE_DRIVER
)
566 fprintf(stderr
, "fx Driver: GL_BLEND not yet supported\n");
570 if ((ifmt
== GL_RGB
) || (ifmt
== GL_LUMINANCE
))
571 FX_grAlphaCombine_NoLock(GR_COMBINE_FUNCTION_LOCAL
,
572 GR_COMBINE_FACTOR_NONE
,
573 locala
, GR_COMBINE_OTHER_NONE
, FXFALSE
);
575 FX_grAlphaCombine_NoLock(GR_COMBINE_FUNCTION_SCALE_OTHER
,
576 GR_COMBINE_FACTOR_ONE
,
577 locala
, GR_COMBINE_OTHER_TEXTURE
, FXFALSE
);
579 if (ifmt
== GL_ALPHA
)
580 FX_grColorCombine_NoLock(GR_COMBINE_FUNCTION_LOCAL
,
581 GR_COMBINE_FACTOR_NONE
,
582 localc
, GR_COMBINE_OTHER_NONE
, FXFALSE
);
584 FX_grColorCombine_NoLock(GR_COMBINE_FUNCTION_SCALE_OTHER
,
585 GR_COMBINE_FACTOR_ONE
,
586 localc
, GR_COMBINE_OTHER_TEXTURE
, FXFALSE
);
589 if (MESA_VERBOSE
& VERBOSE_DRIVER
)
590 fprintf(stderr
, "fx Driver: %x Texture.EnvMode not yet supported\n",
591 ctx
->Texture
.Unit
[textureset
].EnvMode
);
595 if (MESA_VERBOSE
& VERBOSE_DRIVER
) {
596 fprintf(stderr
, "fxmesa: fxSetupTextureSingleTMU(...) End\n");
601 fxSetupTextureSingleTMU(GLcontext
* ctx
, GLuint textureset
)
604 fxSetupTextureSingleTMU_NoLock(ctx
, textureset
);
608 /************************* Double Texture Set ***************************/
611 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
);
625 int tmu0
= 0, tmu1
= 1;
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
) {
642 tstate
|= T0_IN_TMU0
;
645 tstate
|= T0_IN_TMU1
;
648 tstate
|= T0_IN_TMU0
| T0_IN_TMU1
;
651 tstate
|= T0_NOT_IN_TMU
;
656 tstate
|= T0_NOT_IN_TMU
;
659 switch (ti1
->whichTMU
) {
661 tstate
|= T1_IN_TMU0
;
664 tstate
|= T1_IN_TMU1
;
667 tstate
|= T1_IN_TMU0
| T1_IN_TMU1
;
670 tstate
|= T1_NOT_IN_TMU
;
675 tstate
|= T1_NOT_IN_TMU
;
677 ti0
->lastTimeUsed
= fxMesa
->texBindNumber
;
678 ti1
->lastTimeUsed
= fxMesa
->texBindNumber
;
680 /* Move texture maps into TMUs */
682 if (!(((tstate
& T0_IN_TMU0
) && (tstate
& T1_IN_TMU1
)) ||
683 ((tstate
& T0_IN_TMU1
) && (tstate
& T1_IN_TMU0
)))) {
685 fxTMMoveInTM_NoLock(fxMesa
, tObj1
, FX_TMU_BOTH
);
687 /* Find the minimal way to correct the situation */
688 if ((tstate
& T0_IN_TMU0
) || (tstate
& T1_IN_TMU1
)) {
689 /* We have one in the standard order, setup the other */
690 if (tstate
& T0_IN_TMU0
) { /* T0 is in TMU0, put T1 in TMU1 */
691 fxTMMoveInTM_NoLock(fxMesa
, tObj1
, FX_TMU1
);
694 fxTMMoveInTM_NoLock(fxMesa
, tObj0
, FX_TMU0
);
696 /* tmu0 and tmu1 are setup */
698 else if ((tstate
& T0_IN_TMU1
) || (tstate
& T1_IN_TMU0
)) {
699 /* we have one in the reverse order, setup the other */
700 if (tstate
& T1_IN_TMU0
) { /* T1 is in TMU0, put T0 in TMU1 */
701 fxTMMoveInTM_NoLock(fxMesa
, tObj0
, FX_TMU1
);
704 fxTMMoveInTM_NoLock(fxMesa
, tObj1
, FX_TMU0
);
709 else { /* Nothing is loaded */
710 fxTMMoveInTM_NoLock(fxMesa
, tObj0
, FX_TMU0
);
711 fxTMMoveInTM_NoLock(fxMesa
, tObj1
, FX_TMU1
);
712 /* tmu0 and tmu1 are setup */
717 if (!fxMesa
->haveGlobalPaletteTexture
) {
718 if (ti0
->info
.format
== GR_TEXFMT_P_8
) {
719 if (MESA_VERBOSE
& VERBOSE_DRIVER
) {
720 fprintf(stderr
, "fxmesa: uploading texture palette TMU0\n");
722 FX_grTexDownloadTable_NoLock(tmu0
, GR_TEXTABLE_PALETTE
,
726 if (ti1
->info
.format
== GR_TEXFMT_P_8
) {
727 if (MESA_VERBOSE
& VERBOSE_DRIVER
) {
728 fprintf(stderr
, "fxmesa: uploading texture palette TMU1\n");
730 FX_grTexDownloadTable_NoLock(tmu1
, GR_TEXTABLE_PALETTE
,
735 FX_grTexSource_NoLock(tmu0
, ti0
->tm
[tmu0
]->startAddr
,
736 GR_MIPMAPLEVELMASK_BOTH
, &(ti0
->info
));
737 FX_grTexClampMode_NoLock(tmu0
, ti0
->sClamp
, ti0
->tClamp
);
738 FX_grTexFilterMode_NoLock(tmu0
, ti0
->minFilt
, ti0
->maxFilt
);
739 FX_grTexMipMapMode_NoLock(tmu0
, ti0
->mmMode
, FXFALSE
);
741 FX_grTexSource_NoLock(tmu1
, ti1
->tm
[tmu1
]->startAddr
,
742 GR_MIPMAPLEVELMASK_BOTH
, &(ti1
->info
));
743 FX_grTexClampMode_NoLock(tmu1
, ti1
->sClamp
, ti1
->tClamp
);
744 FX_grTexFilterMode_NoLock(tmu1
, ti1
->minFilt
, ti1
->maxFilt
);
745 FX_grTexMipMapMode_NoLock(tmu1
, ti1
->mmMode
, FXFALSE
);
756 fxSetupTextureDoubleTMU_NoLock(GLcontext
* ctx
)
758 fxMesaContext fxMesa
= (fxMesaContext
) ctx
->DriverCtx
;
759 GrCombineLocal_t localc
, locala
;
760 tfxTexInfo
*ti0
, *ti1
;
761 struct gl_texture_object
*tObj0
= ctx
->Texture
.Unit
[0].Current2D
;
762 struct gl_texture_object
*tObj1
= ctx
->Texture
.Unit
[1].Current2D
;
763 GLuint envmode
, ifmt
, unitsmode
;
764 int tmu0
= 0, tmu1
= 1;
766 if (MESA_VERBOSE
& VERBOSE_DRIVER
) {
767 fprintf(stderr
, "fxmesa: fxSetupTextureDoubleTMU(...) Start\n");
770 ti0
= fxTMGetTexInfo(tObj0
);
771 fxTexValidate(ctx
, tObj0
);
773 ti1
= fxTMGetTexInfo(tObj1
);
774 fxTexValidate(ctx
, tObj1
);
776 fxSetupDoubleTMU_NoLock(fxMesa
, tObj0
, tObj1
);
778 unitsmode
= fxGetTexSetConfiguration(ctx
, tObj0
, tObj1
);
780 /* if(fxMesa->lastUnitsMode==unitsmode) */
783 fxMesa
->lastUnitsMode
= unitsmode
;
785 fxMesa
->stw_hint_state
|= GR_STWHINT_ST_DIFF_TMU1
;
786 FX_grHints_NoLock(GR_HINT_STWHINT
, fxMesa
->stw_hint_state
);
788 envmode
= unitsmode
& FX_UM_E_ENVMODE
;
789 ifmt
= unitsmode
& FX_UM_E_IFMT
;
791 if (unitsmode
& FX_UM_ALPHA_ITERATED
)
792 locala
= GR_COMBINE_LOCAL_ITERATED
;
794 locala
= GR_COMBINE_LOCAL_CONSTANT
;
796 if (unitsmode
& FX_UM_COLOR_ITERATED
)
797 localc
= GR_COMBINE_LOCAL_ITERATED
;
799 localc
= GR_COMBINE_LOCAL_CONSTANT
;
802 if (MESA_VERBOSE
& (VERBOSE_DRIVER
| VERBOSE_TEXTURE
))
803 fprintf(stderr
, "fxMesa: fxSetupTextureDoubleTMU, envmode is %s/%s\n",
804 _mesa_lookup_enum_by_nr(ctx
->Texture
.Unit
[0].EnvMode
),
805 _mesa_lookup_enum_by_nr(ctx
->Texture
.Unit
[1].EnvMode
));
808 if ((ti0
->whichTMU
== FX_TMU1
) || (ti1
->whichTMU
== FX_TMU0
)) {
812 fxMesa
->tmuSrc
= FX_TMU_BOTH
;
814 case (FX_UM_E0_MODULATE
| FX_UM_E1_MODULATE
):
816 GLboolean isalpha
[FX_NUM_TMU
];
818 if (ti0
->baseLevelInternalFormat
== GL_ALPHA
)
819 isalpha
[tmu0
] = GL_TRUE
;
821 isalpha
[tmu0
] = GL_FALSE
;
823 if (ti1
->baseLevelInternalFormat
== GL_ALPHA
)
824 isalpha
[tmu1
] = GL_TRUE
;
826 isalpha
[tmu1
] = GL_FALSE
;
828 if (isalpha
[FX_TMU1
])
829 FX_grTexCombine_NoLock(GR_TMU1
,
830 GR_COMBINE_FUNCTION_ZERO
,
831 GR_COMBINE_FACTOR_NONE
,
832 GR_COMBINE_FUNCTION_LOCAL
,
833 GR_COMBINE_FACTOR_NONE
, FXTRUE
, FXFALSE
);
835 FX_grTexCombine_NoLock(GR_TMU1
,
836 GR_COMBINE_FUNCTION_LOCAL
,
837 GR_COMBINE_FACTOR_NONE
,
838 GR_COMBINE_FUNCTION_LOCAL
,
839 GR_COMBINE_FACTOR_NONE
, FXFALSE
, FXFALSE
);
841 if (isalpha
[FX_TMU0
])
842 FX_grTexCombine_NoLock(GR_TMU0
,
843 GR_COMBINE_FUNCTION_BLEND_OTHER
,
844 GR_COMBINE_FACTOR_ONE
,
845 GR_COMBINE_FUNCTION_BLEND_OTHER
,
846 GR_COMBINE_FACTOR_LOCAL
, FXFALSE
, FXFALSE
);
848 FX_grTexCombine_NoLock(GR_TMU0
,
849 GR_COMBINE_FUNCTION_BLEND_OTHER
,
850 GR_COMBINE_FACTOR_LOCAL
,
851 GR_COMBINE_FUNCTION_BLEND_OTHER
,
852 GR_COMBINE_FACTOR_LOCAL
, FXFALSE
, FXFALSE
);
854 FX_grColorCombine_NoLock(GR_COMBINE_FUNCTION_SCALE_OTHER
,
855 GR_COMBINE_FACTOR_LOCAL
,
856 localc
, GR_COMBINE_OTHER_TEXTURE
, FXFALSE
);
858 FX_grAlphaCombine_NoLock(GR_COMBINE_FUNCTION_SCALE_OTHER
,
859 GR_COMBINE_FACTOR_LOCAL
,
860 locala
, GR_COMBINE_OTHER_TEXTURE
, FXFALSE
);
863 case (FX_UM_E0_REPLACE
| FX_UM_E1_BLEND
): /* Only for GLQuake */
864 if (tmu1
== FX_TMU1
) {
865 FX_grTexCombine_NoLock(GR_TMU1
,
866 GR_COMBINE_FUNCTION_LOCAL
,
867 GR_COMBINE_FACTOR_NONE
,
868 GR_COMBINE_FUNCTION_LOCAL
,
869 GR_COMBINE_FACTOR_NONE
, FXTRUE
, FXFALSE
);
871 FX_grTexCombine_NoLock(GR_TMU0
,
872 GR_COMBINE_FUNCTION_BLEND_OTHER
,
873 GR_COMBINE_FACTOR_LOCAL
,
874 GR_COMBINE_FUNCTION_BLEND_OTHER
,
875 GR_COMBINE_FACTOR_LOCAL
, FXFALSE
, FXFALSE
);
878 FX_grTexCombine_NoLock(GR_TMU1
,
879 GR_COMBINE_FUNCTION_LOCAL
,
880 GR_COMBINE_FACTOR_NONE
,
881 GR_COMBINE_FUNCTION_LOCAL
,
882 GR_COMBINE_FACTOR_NONE
, FXFALSE
, FXFALSE
);
884 FX_grTexCombine_NoLock(GR_TMU0
,
885 GR_COMBINE_FUNCTION_BLEND_OTHER
,
886 GR_COMBINE_FACTOR_ONE_MINUS_LOCAL
,
887 GR_COMBINE_FUNCTION_BLEND_OTHER
,
888 GR_COMBINE_FACTOR_ONE_MINUS_LOCAL
,
892 FX_grAlphaCombine_NoLock(GR_COMBINE_FUNCTION_LOCAL
,
893 GR_COMBINE_FACTOR_NONE
,
894 locala
, GR_COMBINE_OTHER_NONE
, FXFALSE
);
896 FX_grColorCombine_NoLock(GR_COMBINE_FUNCTION_SCALE_OTHER
,
897 GR_COMBINE_FACTOR_ONE
,
898 localc
, GR_COMBINE_OTHER_TEXTURE
, FXFALSE
);
900 case (FX_UM_E0_REPLACE
| FX_UM_E1_MODULATE
): /* Quake 2 and 3 */
901 if (tmu1
== FX_TMU1
) {
902 FX_grTexCombine_NoLock(GR_TMU1
,
903 GR_COMBINE_FUNCTION_LOCAL
,
904 GR_COMBINE_FACTOR_NONE
,
905 GR_COMBINE_FUNCTION_ZERO
,
906 GR_COMBINE_FACTOR_NONE
, FXFALSE
, FXTRUE
);
908 FX_grTexCombine_NoLock(GR_TMU0
,
909 GR_COMBINE_FUNCTION_BLEND_OTHER
,
910 GR_COMBINE_FACTOR_LOCAL
,
911 GR_COMBINE_FUNCTION_BLEND_OTHER
,
912 GR_COMBINE_FACTOR_LOCAL
, FXFALSE
, FXFALSE
);
916 FX_grTexCombine_NoLock(GR_TMU1
,
917 GR_COMBINE_FUNCTION_LOCAL
,
918 GR_COMBINE_FACTOR_NONE
,
919 GR_COMBINE_FUNCTION_LOCAL
,
920 GR_COMBINE_FACTOR_NONE
, FXFALSE
, FXFALSE
);
922 FX_grTexCombine_NoLock(GR_TMU0
,
923 GR_COMBINE_FUNCTION_BLEND_OTHER
,
924 GR_COMBINE_FACTOR_LOCAL
,
925 GR_COMBINE_FUNCTION_BLEND_OTHER
,
926 GR_COMBINE_FACTOR_ONE
, FXFALSE
, FXFALSE
);
929 if (ti0
->baseLevelInternalFormat
== GL_RGB
)
930 FX_grAlphaCombine_NoLock(GR_COMBINE_FUNCTION_LOCAL
,
931 GR_COMBINE_FACTOR_NONE
,
932 locala
, GR_COMBINE_OTHER_NONE
, FXFALSE
);
934 FX_grAlphaCombine_NoLock(GR_COMBINE_FUNCTION_SCALE_OTHER
,
935 GR_COMBINE_FACTOR_ONE
,
936 locala
, GR_COMBINE_OTHER_NONE
, FXFALSE
);
939 FX_grColorCombine_NoLock(GR_COMBINE_FUNCTION_SCALE_OTHER
,
940 GR_COMBINE_FACTOR_ONE
,
941 localc
, GR_COMBINE_OTHER_TEXTURE
, FXFALSE
);
945 case (FX_UM_E0_MODULATE
| FX_UM_E1_ADD
): /* Quake 3 Sky */
947 GLboolean isalpha
[FX_NUM_TMU
];
949 if (ti0
->baseLevelInternalFormat
== GL_ALPHA
)
950 isalpha
[tmu0
] = GL_TRUE
;
952 isalpha
[tmu0
] = GL_FALSE
;
954 if (ti1
->baseLevelInternalFormat
== GL_ALPHA
)
955 isalpha
[tmu1
] = GL_TRUE
;
957 isalpha
[tmu1
] = GL_FALSE
;
959 if (isalpha
[FX_TMU1
])
960 FX_grTexCombine_NoLock(GR_TMU1
,
961 GR_COMBINE_FUNCTION_ZERO
,
962 GR_COMBINE_FACTOR_NONE
,
963 GR_COMBINE_FUNCTION_LOCAL
,
964 GR_COMBINE_FACTOR_NONE
, FXTRUE
, FXFALSE
);
966 FX_grTexCombine_NoLock(GR_TMU1
,
967 GR_COMBINE_FUNCTION_LOCAL
,
968 GR_COMBINE_FACTOR_NONE
,
969 GR_COMBINE_FUNCTION_LOCAL
,
970 GR_COMBINE_FACTOR_NONE
, FXFALSE
, FXFALSE
);
972 if (isalpha
[FX_TMU0
])
973 FX_grTexCombine_NoLock(GR_TMU0
,
974 GR_COMBINE_FUNCTION_SCALE_OTHER
,
975 GR_COMBINE_FACTOR_ONE
,
976 GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL
,
977 GR_COMBINE_FACTOR_ONE
, FXFALSE
, FXFALSE
);
979 FX_grTexCombine_NoLock(GR_TMU0
,
980 GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL
,
981 GR_COMBINE_FACTOR_ONE
,
982 GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL
,
983 GR_COMBINE_FACTOR_ONE
, FXFALSE
, FXFALSE
);
985 FX_grColorCombine_NoLock(GR_COMBINE_FUNCTION_SCALE_OTHER
,
986 GR_COMBINE_FACTOR_LOCAL
,
987 localc
, GR_COMBINE_OTHER_TEXTURE
, FXFALSE
);
989 FX_grAlphaCombine_NoLock(GR_COMBINE_FUNCTION_SCALE_OTHER
,
990 GR_COMBINE_FACTOR_LOCAL
,
991 locala
, GR_COMBINE_OTHER_TEXTURE
, FXFALSE
);
995 fprintf(stderr
, "Unexpected dual texture mode encountered\n");
999 if (MESA_VERBOSE
& VERBOSE_DRIVER
) {
1000 fprintf(stderr
, "fxmesa: fxSetupTextureDoubleTMU(...) End\n");
1004 /************************* No Texture ***************************/
1007 fxSetupTextureNone_NoLock(GLcontext
* ctx
)
1009 fxMesaContext fxMesa
= (fxMesaContext
) ctx
->DriverCtx
;
1010 GrCombineLocal_t localc
, locala
;
1012 if (MESA_VERBOSE
& VERBOSE_DRIVER
) {
1013 fprintf(stderr
, "fxmesa: fxSetupTextureNone(...)\n");
1016 if ((ctx
->Light
.ShadeModel
== GL_SMOOTH
) || 1 ||
1017 (ctx
->Point
.SmoothFlag
) ||
1018 (ctx
->Line
.SmoothFlag
) ||
1019 (ctx
->Polygon
.SmoothFlag
)) locala
= GR_COMBINE_LOCAL_ITERATED
;
1021 locala
= GR_COMBINE_LOCAL_CONSTANT
;
1023 if (ctx
->Light
.ShadeModel
== GL_SMOOTH
|| 1)
1024 localc
= GR_COMBINE_LOCAL_ITERATED
;
1026 localc
= GR_COMBINE_LOCAL_CONSTANT
;
1028 FX_grAlphaCombine_NoLock(GR_COMBINE_FUNCTION_LOCAL
,
1029 GR_COMBINE_FACTOR_NONE
,
1030 locala
, GR_COMBINE_OTHER_NONE
, FXFALSE
);
1032 FX_grColorCombine_NoLock(GR_COMBINE_FUNCTION_LOCAL
,
1033 GR_COMBINE_FACTOR_NONE
,
1034 localc
, GR_COMBINE_OTHER_NONE
, FXFALSE
);
1036 fxMesa
->lastUnitsMode
= FX_UM_NONE
;
1039 /************************************************************************/
1040 /************************** Texture Mode SetUp **************************/
1041 /************************************************************************/
1044 fxSetupTexture_NoLock(GLcontext
* ctx
)
1046 fxMesaContext fxMesa
= (fxMesaContext
) ctx
->DriverCtx
;
1047 GLuint tex2Denabled
;
1049 if (MESA_VERBOSE
& VERBOSE_DRIVER
) {
1050 fprintf(stderr
, "fxmesa: fxSetupTexture(...)\n");
1053 /* Texture Combine, Color Combine and Alpha Combine.
1055 tex2Denabled
= (ctx
->Texture
._ReallyEnabled
& TEXTURE0_2D
);
1057 if (fxMesa
->emulateTwoTMUs
)
1058 tex2Denabled
|= (ctx
->Texture
._ReallyEnabled
& TEXTURE1_2D
);
1060 switch (tex2Denabled
) {
1062 fxSetupTextureSingleTMU_NoLock(ctx
, 0);
1065 fxSetupTextureSingleTMU_NoLock(ctx
, 1);
1067 case (TEXTURE0_2D
| TEXTURE1_2D
):
1068 if (fxMesa
->haveTwoTMUs
)
1069 fxSetupTextureDoubleTMU_NoLock(ctx
);
1071 if (MESA_VERBOSE
& VERBOSE_DRIVER
)
1072 fprintf(stderr
, "fxmesa: enabling fake multitexture\n");
1074 fxSetupTextureSingleTMU_NoLock(ctx
, 0);
1075 /*ctx->Driver.MultipassFunc = fxMultipassTexture;*/
1079 fxSetupTextureNone_NoLock(ctx
);
1085 fxSetupTexture(GLcontext
* ctx
)
1088 fxSetupTexture_NoLock(ctx
);
1092 /************************************************************************/
1093 /**************************** Blend SetUp *******************************/
1094 /************************************************************************/
1096 /* XXX consider supporting GL_INGR_blend_func_separate */
1098 fxDDBlendFunc(GLcontext
* ctx
, GLenum sfactor
, GLenum dfactor
)
1100 fxMesaContext fxMesa
= (fxMesaContext
) ctx
->DriverCtx
;
1101 tfxUnitsState
*us
= &fxMesa
->unitsState
;
1102 GrAlphaBlendFnc_t sfact
, dfact
, asfact
, adfact
;
1104 /* From the Glide documentation:
1105 For alpha source and destination blend function factor
1106 parameters, Voodoo Graphics supports only
1107 GR_BLEND_ZERO and GR_BLEND_ONE.
1112 asfact
= sfact
= GR_BLEND_ZERO
;
1115 asfact
= sfact
= GR_BLEND_ONE
;
1118 sfact
= GR_BLEND_DST_COLOR
;
1119 asfact
= GR_BLEND_ONE
;
1121 case GL_ONE_MINUS_DST_COLOR
:
1122 sfact
= GR_BLEND_ONE_MINUS_DST_COLOR
;
1123 asfact
= GR_BLEND_ONE
;
1126 sfact
= GR_BLEND_SRC_ALPHA
;
1127 asfact
= GR_BLEND_ONE
;
1129 case GL_ONE_MINUS_SRC_ALPHA
:
1130 sfact
= GR_BLEND_ONE_MINUS_SRC_ALPHA
;
1131 asfact
= GR_BLEND_ONE
;
1134 sfact
= GR_BLEND_DST_ALPHA
;
1135 asfact
= GR_BLEND_ONE
;
1137 case GL_ONE_MINUS_DST_ALPHA
:
1138 sfact
= GR_BLEND_ONE_MINUS_DST_ALPHA
;
1139 asfact
= GR_BLEND_ONE
;
1141 case GL_SRC_ALPHA_SATURATE
:
1142 sfact
= GR_BLEND_ALPHA_SATURATE
;
1143 asfact
= GR_BLEND_ONE
;
1146 case GL_ONE_MINUS_SRC_COLOR
:
1148 asfact
= sfact
= GR_BLEND_ONE
;
1151 asfact
= sfact
= GR_BLEND_ONE
;
1155 if ((sfact
!= us
->blendSrcFuncRGB
) || (asfact
!= us
->blendSrcFuncAlpha
)) {
1156 us
->blendSrcFuncRGB
= sfact
;
1157 us
->blendSrcFuncAlpha
= asfact
;
1158 fxMesa
->new_state
|= FX_NEW_BLEND
;
1163 adfact
= dfact
= GR_BLEND_ZERO
;
1166 adfact
= dfact
= GR_BLEND_ONE
;
1169 dfact
= GR_BLEND_SRC_COLOR
;
1170 adfact
= GR_BLEND_ZERO
;
1172 case GL_ONE_MINUS_SRC_COLOR
:
1173 dfact
= GR_BLEND_ONE_MINUS_SRC_COLOR
;
1174 adfact
= GR_BLEND_ZERO
;
1177 dfact
= GR_BLEND_SRC_ALPHA
;
1178 adfact
= GR_BLEND_ZERO
;
1180 case GL_ONE_MINUS_SRC_ALPHA
:
1181 dfact
= GR_BLEND_ONE_MINUS_SRC_ALPHA
;
1182 adfact
= GR_BLEND_ZERO
;
1185 /* dfact=GR_BLEND_DST_ALPHA; */
1186 /* We can't do DST_ALPHA */
1187 dfact
= GR_BLEND_ONE
;
1188 adfact
= GR_BLEND_ZERO
;
1190 case GL_ONE_MINUS_DST_ALPHA
:
1191 /* dfact=GR_BLEND_ONE_MINUS_DST_ALPHA; */
1192 /* We can't do DST_ALPHA */
1193 dfact
= GR_BLEND_ZERO
;
1194 adfact
= GR_BLEND_ZERO
;
1196 case GL_SRC_ALPHA_SATURATE
:
1198 case GL_ONE_MINUS_DST_COLOR
:
1200 adfact
= dfact
= GR_BLEND_ZERO
;
1203 adfact
= dfact
= GR_BLEND_ZERO
;
1207 if ((dfact
!= us
->blendDstFuncRGB
) || (adfact
!= us
->blendDstFuncAlpha
)) {
1208 us
->blendDstFuncRGB
= dfact
;
1209 us
->blendDstFuncAlpha
= adfact
;
1210 fxMesa
->new_state
|= FX_NEW_BLEND
;
1215 fxSetupBlend(GLcontext
* ctx
)
1217 fxMesaContext fxMesa
= (fxMesaContext
) ctx
->DriverCtx
;
1218 tfxUnitsState
*us
= &fxMesa
->unitsState
;
1220 if (us
->blendEnabled
)
1221 FX_grAlphaBlendFunction(us
->blendSrcFuncRGB
, us
->blendDstFuncRGB
,
1222 us
->blendSrcFuncAlpha
, us
->blendDstFuncAlpha
);
1224 FX_grAlphaBlendFunction(GR_BLEND_ONE
, GR_BLEND_ZERO
, GR_BLEND_ONE
,
1228 /************************************************************************/
1229 /************************** Alpha Test SetUp ****************************/
1230 /************************************************************************/
1233 fxDDAlphaFunc(GLcontext
* ctx
, GLenum func
, GLchan ref
)
1235 fxMesaContext fxMesa
= (fxMesaContext
) ctx
->DriverCtx
;
1236 tfxUnitsState
*us
= &fxMesa
->unitsState
;
1241 newfunc
= GR_CMP_NEVER
;
1244 newfunc
= GR_CMP_LESS
;
1247 newfunc
= GR_CMP_EQUAL
;
1250 newfunc
= GR_CMP_LEQUAL
;
1253 newfunc
= GR_CMP_GREATER
;
1256 newfunc
= GR_CMP_NOTEQUAL
;
1259 newfunc
= GR_CMP_GEQUAL
;
1262 newfunc
= GR_CMP_ALWAYS
;
1265 fprintf(stderr
, "fx Driver: internal error in fxDDAlphaFunc()\n");
1271 if (newfunc
!= us
->alphaTestFunc
) {
1272 us
->alphaTestFunc
= newfunc
;
1273 fxMesa
->new_state
|= FX_NEW_ALPHA
;
1276 if (ref
!= us
->alphaTestRefValue
) {
1277 us
->alphaTestRefValue
= ref
;
1278 fxMesa
->new_state
|= FX_NEW_ALPHA
;
1283 fxSetupAlphaTest(GLcontext
* ctx
)
1285 fxMesaContext fxMesa
= (fxMesaContext
) ctx
->DriverCtx
;
1286 tfxUnitsState
*us
= &fxMesa
->unitsState
;
1288 if (us
->alphaTestEnabled
) {
1289 FX_grAlphaTestFunction(us
->alphaTestFunc
);
1290 FX_grAlphaTestReferenceValue(us
->alphaTestRefValue
);
1293 FX_grAlphaTestFunction(GR_CMP_ALWAYS
);
1296 /************************************************************************/
1297 /************************** Depth Test SetUp ****************************/
1298 /************************************************************************/
1301 fxDDDepthFunc(GLcontext
* ctx
, GLenum func
)
1303 fxMesaContext fxMesa
= (fxMesaContext
) ctx
->DriverCtx
;
1304 tfxUnitsState
*us
= &fxMesa
->unitsState
;
1309 dfunc
= GR_CMP_NEVER
;
1312 dfunc
= GR_CMP_LESS
;
1315 dfunc
= GR_CMP_GEQUAL
;
1318 dfunc
= GR_CMP_LEQUAL
;
1321 dfunc
= GR_CMP_GREATER
;
1324 dfunc
= GR_CMP_NOTEQUAL
;
1327 dfunc
= GR_CMP_EQUAL
;
1330 dfunc
= GR_CMP_ALWAYS
;
1333 fprintf(stderr
, "fx Driver: internal error in fxDDDepthFunc()\n");
1339 if (dfunc
!= us
->depthTestFunc
) {
1340 us
->depthTestFunc
= dfunc
;
1341 fxMesa
->new_state
|= FX_NEW_DEPTH
;
1347 fxDDDepthMask(GLcontext
* ctx
, GLboolean flag
)
1349 fxMesaContext fxMesa
= (fxMesaContext
) ctx
->DriverCtx
;
1350 tfxUnitsState
*us
= &fxMesa
->unitsState
;
1352 if (flag
!= us
->depthMask
) {
1353 us
->depthMask
= flag
;
1354 fxMesa
->new_state
|= FX_NEW_DEPTH
;
1359 fxSetupDepthTest(GLcontext
* ctx
)
1361 fxMesaContext fxMesa
= (fxMesaContext
) ctx
->DriverCtx
;
1362 tfxUnitsState
*us
= &fxMesa
->unitsState
;
1364 if (us
->depthTestEnabled
) {
1365 FX_grDepthBufferFunction(us
->depthTestFunc
);
1366 FX_grDepthMask(us
->depthMask
);
1369 FX_grDepthBufferFunction(GR_CMP_ALWAYS
);
1370 FX_grDepthMask(FXFALSE
);
1374 /************************************************************************/
1375 /**************************** Color Mask SetUp **************************/
1376 /************************************************************************/
1379 fxDDColorMask(GLcontext
* ctx
,
1380 GLboolean r
, GLboolean g
, GLboolean b
, GLboolean a
)
1382 fxMesaContext fxMesa
= (fxMesaContext
) ctx
->DriverCtx
;
1383 fxMesa
->new_state
|= FX_NEW_COLOR_MASK
;
1391 fxSetupColorMask(GLcontext
* ctx
)
1393 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
1395 if (ctx
->Color
.DrawBuffer
== GL_NONE
) {
1396 FX_grColorMask(FXFALSE
, FXFALSE
);
1399 FX_grColorMask(ctx
->Color
.ColorMask
[RCOMP
] ||
1400 ctx
->Color
.ColorMask
[GCOMP
] ||
1401 ctx
->Color
.ColorMask
[BCOMP
],
1402 ctx
->Color
.ColorMask
[ACOMP
] && fxMesa
->haveAlphaBuffer
);
1409 /************************************************************************/
1410 /**************************** Fog Mode SetUp ****************************/
1411 /************************************************************************/
1414 * This is called during state update in order to update the Glide fog state.
1417 fxSetupFog(GLcontext
* ctx
)
1419 if (ctx
->Fog
.Enabled
/*&& ctx->FogMode==FOG_FRAGMENT */ ) {
1420 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
1422 /* update fog color */
1424 col
[0] = (unsigned int) (255 * ctx
->Fog
.Color
[0]);
1425 col
[1] = (unsigned int) (255 * ctx
->Fog
.Color
[1]);
1426 col
[2] = (unsigned int) (255 * ctx
->Fog
.Color
[2]);
1427 col
[3] = (unsigned int) (255 * ctx
->Fog
.Color
[3]);
1428 FX_grFogColorValue(FXCOLOR4(col
));
1430 if (fxMesa
->fogTableMode
!= ctx
->Fog
.Mode
||
1431 fxMesa
->fogDensity
!= ctx
->Fog
.Density
||
1432 fxMesa
->fogStart
!= ctx
->Fog
.Start
||
1433 fxMesa
->fogEnd
!= ctx
->Fog
.End
) {
1434 /* reload the fog table */
1435 switch (ctx
->Fog
.Mode
) {
1437 guFogGenerateLinear(fxMesa
->fogTable
, ctx
->Fog
.Start
,
1441 guFogGenerateExp(fxMesa
->fogTable
, ctx
->Fog
.Density
);
1444 guFogGenerateExp2(fxMesa
->fogTable
, ctx
->Fog
.Density
);
1449 fxMesa
->fogTableMode
= ctx
->Fog
.Mode
;
1450 fxMesa
->fogDensity
= ctx
->Fog
.Density
;
1451 fxMesa
->fogStart
= ctx
->Fog
.Start
;
1452 fxMesa
->fogEnd
= ctx
->Fog
.End
;
1455 FX_grFogTable(fxMesa
->fogTable
);
1456 FX_grFogMode(GR_FOG_WITH_TABLE
);
1459 FX_grFogMode(GR_FOG_DISABLE
);
1464 fxDDFogfv(GLcontext
* ctx
, GLenum pname
, const GLfloat
* params
)
1466 FX_CONTEXT(ctx
)->new_state
|= FX_NEW_FOG
;
1469 /************************************************************************/
1470 /************************** Scissor Test SetUp **************************/
1471 /************************************************************************/
1473 /* This routine is used in managing the lock state, and therefore can't lock */
1475 fxSetScissorValues(GLcontext
* ctx
)
1477 fxMesaContext fxMesa
= (fxMesaContext
) ctx
->DriverCtx
;
1479 int ymin
, ymax
, check
;
1481 if (ctx
->Scissor
.Enabled
) {
1482 xmin
= ctx
->Scissor
.X
;
1483 xmax
= ctx
->Scissor
.X
+ ctx
->Scissor
.Width
;
1484 ymin
= ctx
->Scissor
.Y
;
1485 ymax
= ctx
->Scissor
.Y
+ ctx
->Scissor
.Height
;
1491 xmax
= fxMesa
->width
;
1492 ymax
= fxMesa
->height
;
1495 if (xmin
< fxMesa
->clipMinX
)
1496 xmin
= fxMesa
->clipMinX
;
1497 if (xmax
> fxMesa
->clipMaxX
)
1498 xmax
= fxMesa
->clipMaxX
;
1499 if (ymin
< fxMesa
->screen_height
- fxMesa
->clipMaxY
)
1500 ymin
= fxMesa
->screen_height
- fxMesa
->clipMaxY
;
1501 if (ymax
> fxMesa
->screen_height
- fxMesa
->clipMinY
)
1502 ymax
= fxMesa
->screen_height
- fxMesa
->clipMinY
;
1503 FX_grClipWindow_NoLock(xmin
, ymin
, xmax
, ymax
);
1507 fxSetupScissor(GLcontext
* ctx
)
1510 fxSetScissorValues(ctx
);
1515 fxDDScissor(GLcontext
* ctx
, GLint x
, GLint y
, GLsizei w
, GLsizei h
)
1517 FX_CONTEXT(ctx
)->new_state
|= FX_NEW_SCISSOR
;
1520 /************************************************************************/
1521 /*************************** Cull mode setup ****************************/
1522 /************************************************************************/
1526 fxDDCullFace(GLcontext
* ctx
, GLenum mode
)
1529 FX_CONTEXT(ctx
)->new_state
|= FX_NEW_CULL
;
1533 fxDDFrontFace(GLcontext
* ctx
, GLenum mode
)
1536 FX_CONTEXT(ctx
)->new_state
|= FX_NEW_CULL
;
1541 fxSetupCull(GLcontext
* ctx
)
1543 if (ctx
->Polygon
.CullFlag
) {
1544 switch (ctx
->Polygon
.CullFaceMode
) {
1546 if (ctx
->Polygon
.FrontFace
== GL_CCW
)
1547 FX_CONTEXT(ctx
)->cullMode
= GR_CULL_NEGATIVE
;
1549 FX_CONTEXT(ctx
)->cullMode
= GR_CULL_POSITIVE
;
1552 if (ctx
->Polygon
.FrontFace
== GL_CCW
)
1553 FX_CONTEXT(ctx
)->cullMode
= GR_CULL_POSITIVE
;
1555 FX_CONTEXT(ctx
)->cullMode
= GR_CULL_NEGATIVE
;
1557 case GL_FRONT_AND_BACK
:
1558 FX_CONTEXT(ctx
)->cullMode
= GR_CULL_DISABLE
;
1565 FX_CONTEXT(ctx
)->cullMode
= GR_CULL_DISABLE
;
1567 FX_grCullMode(FX_CONTEXT(ctx
)->cullMode
);
1571 /************************************************************************/
1572 /****************************** DD Enable ******************************/
1573 /************************************************************************/
1576 fxDDEnable(GLcontext
* ctx
, GLenum cap
, GLboolean state
)
1578 fxMesaContext fxMesa
= (fxMesaContext
) ctx
->DriverCtx
;
1579 tfxUnitsState
*us
= &fxMesa
->unitsState
;
1581 if (MESA_VERBOSE
& VERBOSE_DRIVER
) {
1582 fprintf(stderr
, "fxmesa: fxDDEnable(...)\n");
1587 if (state
!= us
->alphaTestEnabled
) {
1588 us
->alphaTestEnabled
= state
;
1589 fxMesa
->new_state
|= FX_NEW_ALPHA
;
1593 if (state
!= us
->blendEnabled
) {
1594 us
->blendEnabled
= state
;
1595 fxMesa
->new_state
|= FX_NEW_BLEND
;
1599 if (state
!= us
->depthTestEnabled
) {
1600 us
->depthTestEnabled
= state
;
1601 fxMesa
->new_state
|= FX_NEW_DEPTH
;
1606 FX_grDitherMode(GR_DITHER_4x4
);
1609 FX_grDitherMode(GR_DITHER_DISABLE
);
1612 case GL_SCISSOR_TEST
:
1613 fxMesa
->new_state
|= FX_NEW_SCISSOR
;
1615 case GL_SHARED_TEXTURE_PALETTE_EXT
:
1616 fxDDTexUseGlbPalette(ctx
, state
);
1619 fxMesa
->new_state
|= FX_NEW_FOG
;
1622 fxMesa
->new_state
|= FX_NEW_CULL
;
1624 case GL_LINE_SMOOTH
:
1625 case GL_LINE_STIPPLE
:
1626 case GL_POINT_SMOOTH
:
1627 case GL_POLYGON_SMOOTH
:
1629 fxMesa
->new_state
|= FX_NEW_TEXTURING
;
1638 Multipass to do GL_BLEND texture functions
1639 Cf*(1-Ct) has already been written to the buffer during the first pass
1640 Cc*Ct gets written during the second pass (in this function)
1641 Everything gets reset in the third call (in this function)
1644 fxMultipassBlend(struct vertex_buffer
*VB
, GLuint pass
)
1646 GLcontext
*ctx
= VB
->ctx
;
1647 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
1652 fxMesa
->restoreUnitsState
= fxMesa
->unitsState
;
1653 if (ctx
->Depth
.Mask
) {
1654 /* We don't want to check or change the depth buffers */
1655 switch (ctx
->Depth
.Func
) {
1660 fxDDDepthFunc(ctx
, GL_EQUAL
);
1663 fxDDDepthMask(ctx
, FALSE
);
1665 /* Enable Cc*Ct mode */
1666 /* XXX Set the Constant Color ? */
1667 fxDDEnable(ctx
, GL_BLEND
, GL_TRUE
);
1668 fxDDBlendFunc(ctx
, XXX
, XXX
);
1669 fxSetupTextureSingleTMU(ctx
, XXX
);
1671 fxSetupDepthTest(ctx
);
1675 /* Reset everything back to normal */
1676 fxMesa
->unitsState
= fxMesa
->restoreUnitsState
;
1677 fxMesa
->setup_gone
|= XXX
;
1678 fxSetupTextureSingleTMU(ctx
, XXX
);
1680 fxSetupDepthTest(ctx
);
1688 /************************************************************************/
1689 /******************** Fake Multitexture Support *************************/
1690 /************************************************************************/
1692 /* Its considered cheeky to try to fake ARB multitexture by doing
1693 * multipass rendering, because it is not possible to emulate the full
1694 * spec in this way. The fact is that the voodoo 2 supports only a
1695 * subset of the possible multitexturing modes, and it is possible to
1696 * support almost the same subset using multipass blending on the
1697 * voodoo 1. In all other cases for both voodoo 1 and 2, we fall back
1698 * to software rendering, satisfying the spec if not the user.
1701 fxMultipassTexture(GLcontext
* ctx
, GLuint pass
)
1703 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
1704 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
1705 fxVertex
*v
= fxMesa
->verts
;
1706 fxVertex
*last
= fxMesa
->verts
+ tnl
->vb
.Count
;
1711 (VERBOSE_DRIVER
| VERBOSE_PIPELINE
| VERBOSE_TEXTURE
))
1712 fprintf(stderr
, "fxmesa: Second texture pass\n");
1714 for (; v
!= last
; v
++) {
1715 v
->f
[S0COORD
] = v
->f
[S1COORD
];
1716 v
->f
[T0COORD
] = v
->f
[T1COORD
];
1719 fxMesa
->restoreUnitsState
= fxMesa
->unitsState
;
1720 fxMesa
->tmu_source
[0] = 1;
1722 if (ctx
->Depth
.Mask
) {
1723 switch (ctx
->Depth
.Func
) {
1728 fxDDDepthFunc(ctx
, GL_EQUAL
);
1732 fxDDDepthMask(ctx
, GL_FALSE
);
1735 if (ctx
->Texture
.Unit
[1].EnvMode
== GL_MODULATE
) {
1736 fxDDEnable(ctx
, GL_BLEND
, GL_TRUE
);
1737 fxDDBlendFunc(ctx
, GL_DST_COLOR
, GL_ZERO
);
1740 fxSetupTextureSingleTMU(ctx
, 1);
1742 fxSetupDepthTest(ctx
);
1746 /* Restore original state.
1748 fxMesa
->tmu_source
[0] = 0;
1749 fxMesa
->unitsState
= fxMesa
->restoreUnitsState
;
1750 fxMesa
->setup_gone
|= SETUP_TMU0
;
1751 fxSetupTextureSingleTMU(ctx
, 0);
1753 fxSetupDepthTest(ctx
);
1761 /************************************************************************/
1762 /************************** Changes to units state **********************/
1763 /************************************************************************/
1766 /* All units setup is handled under texture setup.
1769 fxDDShadeModel(GLcontext
* ctx
, GLenum mode
)
1771 FX_CONTEXT(ctx
)->new_state
|= FX_NEW_TEXTURING
;
1776 /************************************************************************/
1777 /****************************** Units SetUp *****************************/
1778 /************************************************************************/
1780 fx_print_state_flags(const char *msg
, GLuint flags
)
1783 "%s: (0x%x) %s%s%s%s%s%s%s\n",
1786 (flags
& FX_NEW_TEXTURING
) ? "texture, " : "",
1787 (flags
& FX_NEW_BLEND
) ? "blend, " : "",
1788 (flags
& FX_NEW_ALPHA
) ? "alpha, " : "",
1789 (flags
& FX_NEW_FOG
) ? "fog, " : "",
1790 (flags
& FX_NEW_SCISSOR
) ? "scissor, " : "",
1791 (flags
& FX_NEW_COLOR_MASK
) ? "colormask, " : "",
1792 (flags
& FX_NEW_CULL
) ? "cull, " : "");
1796 fxSetupFXUnits(GLcontext
* ctx
)
1798 fxMesaContext fxMesa
= (fxMesaContext
) ctx
->DriverCtx
;
1799 GLuint newstate
= fxMesa
->new_state
;
1801 if (MESA_VERBOSE
& VERBOSE_DRIVER
)
1802 fx_print_state_flags("fxmesa: fxSetupFXUnits", newstate
);
1805 if (newstate
& FX_NEW_TEXTURING
)
1806 fxSetupTexture(ctx
);
1808 if (newstate
& FX_NEW_BLEND
)
1811 if (newstate
& FX_NEW_ALPHA
)
1812 fxSetupAlphaTest(ctx
);
1814 if (newstate
& FX_NEW_DEPTH
)
1815 fxSetupDepthTest(ctx
);
1817 if (newstate
& FX_NEW_FOG
)
1820 if (newstate
& FX_NEW_SCISSOR
)
1821 fxSetupScissor(ctx
);
1823 if (newstate
& FX_NEW_COLOR_MASK
)
1824 fxSetupColorMask(ctx
);
1826 if (newstate
& FX_NEW_CULL
)
1829 fxMesa
->draw_point
= fxMesa
->initial_point
;
1830 fxMesa
->draw_line
= fxMesa
->initial_line
;
1831 fxMesa
->draw_tri
= fxMesa
->initial_tri
;
1832 fxMesa
->new_state
= 0;
1842 * Need this to provide at least one external definition.
1845 extern int gl_fx_dummy_function_setup(void);
1847 gl_fx_dummy_function_setup(void)