1 /* -*- mode: c; c-basic-offset: 3 -*-
3 * Copyright 2000 VA Linux Systems Inc., Fremont, California.
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 * and/or sell copies of the Software, and to permit persons to whom the
12 * Software is furnished to do so, subject to the following conditions:
14 * The above copyright notice and this permission notice (including the next
15 * paragraph) shall be included in all copies or substantial portions of the
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21 * VA LINUX SYSTEMS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
22 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
23 * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
26 /* $XFree86: xc/lib/GL/mesa/src/drv/tdfx/tdfx_texstate.c,v 1.2 2002/02/22 21:45:04 dawes Exp $ */
30 * Daniel Borca <dborca@users.sourceforge.net>, 19 Jul 2004
33 * Gareth Hughes <gareth@valinux.com>, 29 Sep - 1 Oct 2000
36 * Gareth Hughes <gareth@valinux.com>
37 * Brian Paul <brianp@valinux.com>
41 #include "tdfx_state.h"
43 #include "tdfx_texman.h"
44 #include "tdfx_texstate.h"
47 /* =============================================================
52 * These macros are used below when handling COMBINE_EXT.
54 #define TEXENV_OPERAND_INVERTED(operand) \
55 (((operand) == GL_ONE_MINUS_SRC_ALPHA) \
56 || ((operand) == GL_ONE_MINUS_SRC_COLOR))
57 #define TEXENV_OPERAND_ALPHA(operand) \
58 (((operand) == GL_SRC_ALPHA) || ((operand) == GL_ONE_MINUS_SRC_ALPHA))
59 #define TEXENV_SETUP_ARG_A(param, source, operand, iteratedAlpha) \
62 param = GR_CMBX_LOCAL_TEXTURE_ALPHA; \
64 case GL_CONSTANT_EXT: \
65 param = GR_CMBX_TMU_CALPHA; \
67 case GL_PRIMARY_COLOR_EXT: \
68 param = GR_CMBX_ITALPHA; \
70 case GL_PREVIOUS_EXT: \
71 param = iteratedAlpha; \
75 * This is here just to keep from getting \
76 * compiler warnings. \
78 param = GR_CMBX_ZERO; \
82 #define TEXENV_SETUP_ARG_RGB(param, source, operand, iteratedColor, iteratedAlpha) \
83 if (!TEXENV_OPERAND_ALPHA(operand)) { \
86 param = GR_CMBX_LOCAL_TEXTURE_RGB; \
88 case GL_CONSTANT_EXT: \
89 param = GR_CMBX_TMU_CCOLOR; \
91 case GL_PRIMARY_COLOR_EXT: \
92 param = GR_CMBX_ITRGB; \
94 case GL_PREVIOUS_EXT: \
95 param = iteratedColor; \
99 * This is here just to keep from getting \
100 * compiler warnings. \
102 param = GR_CMBX_ZERO; \
108 param = GR_CMBX_LOCAL_TEXTURE_ALPHA; \
110 case GL_CONSTANT_EXT: \
111 param = GR_CMBX_TMU_CALPHA; \
113 case GL_PRIMARY_COLOR_EXT: \
114 param = GR_CMBX_ITALPHA; \
116 case GL_PREVIOUS_EXT: \
117 param = iteratedAlpha; \
121 * This is here just to keep from getting \
122 * compiler warnings. \
124 param = GR_CMBX_ZERO; \
129 #define TEXENV_SETUP_MODE_RGB(param, operand) \
133 param = GR_FUNC_MODE_X; \
135 case GL_ONE_MINUS_SRC_ALPHA: \
136 case GL_ONE_MINUS_SRC_COLOR: \
137 param = GR_FUNC_MODE_ONE_MINUS_X; \
140 param = GR_FUNC_MODE_ZERO; \
144 #define TEXENV_SETUP_MODE_A(param, operand) \
147 param = GR_FUNC_MODE_X; \
149 case GL_ONE_MINUS_SRC_ALPHA: \
150 param = GR_FUNC_MODE_ONE_MINUS_X; \
153 param = GR_FUNC_MODE_ZERO; \
160 * Setup a texture environment on Voodoo5.
161 * Return GL_TRUE for success, GL_FALSE for failure.
162 * If we fail, we'll have to use software rendering.
165 SetupTexEnvNapalm(GLcontext
*ctx
, GLboolean useIteratedRGBA
,
166 const struct gl_texture_unit
*texUnit
, GLenum baseFormat
,
167 struct tdfx_texcombine_ext
*env
)
169 tdfxContextPtr fxMesa
= TDFX_CONTEXT(ctx
);
170 GrTCCUColor_t incomingRGB
, incomingAlpha
;
171 const GLenum envMode
= texUnit
->EnvMode
;
173 if (useIteratedRGBA
) {
174 incomingRGB
= GR_CMBX_ITRGB
;
175 incomingAlpha
= GR_CMBX_ITALPHA
;
178 incomingRGB
= GR_CMBX_OTHER_TEXTURE_RGB
;
179 incomingAlpha
= GR_CMBX_OTHER_TEXTURE_ALPHA
;
183 env
->Color
.Shift
= 0;
184 env
->Color
.Invert
= FXFALSE
;
185 env
->Alpha
.Shift
= 0;
186 env
->Alpha
.Invert
= FXFALSE
;
190 /* -- Setup RGB combiner */
191 if (baseFormat
== GL_ALPHA
) {
193 env
->Color
.SourceA
= incomingRGB
;
197 env
->Color
.SourceA
= GR_CMBX_LOCAL_TEXTURE_RGB
;
199 env
->Color
.ModeA
= GR_FUNC_MODE_X
;
200 env
->Color
.SourceB
= GR_CMBX_ZERO
;
201 env
->Color
.ModeB
= GR_FUNC_MODE_ZERO
;
202 env
->Color
.SourceC
= GR_CMBX_ZERO
;
203 env
->Color
.InvertC
= FXTRUE
;
204 env
->Color
.SourceD
= GR_CMBX_ZERO
;
205 env
->Color
.InvertD
= FXFALSE
;
206 /* -- Setup Alpha combiner */
207 if (baseFormat
== GL_LUMINANCE
|| baseFormat
== GL_RGB
) {
209 env
->Alpha
.SourceD
= incomingAlpha
;
213 env
->Alpha
.SourceD
= GR_CMBX_LOCAL_TEXTURE_ALPHA
;
215 env
->Alpha
.SourceA
= GR_CMBX_ITALPHA
;
216 env
->Alpha
.ModeA
= GR_FUNC_MODE_ZERO
;
217 env
->Alpha
.SourceB
= GR_CMBX_ITALPHA
;
218 env
->Alpha
.ModeB
= GR_FUNC_MODE_ZERO
;
219 env
->Alpha
.SourceC
= GR_CMBX_ZERO
;
220 env
->Alpha
.InvertC
= FXFALSE
;
221 env
->Alpha
.InvertD
= FXFALSE
;
225 /* -- Setup RGB combiner */
226 if (baseFormat
== GL_ALPHA
) {
228 env
->Color
.SourceC
= GR_CMBX_ZERO
;
229 env
->Color
.InvertC
= FXTRUE
;
232 /* Result = Frag * Tex */
233 env
->Color
.SourceC
= GR_CMBX_LOCAL_TEXTURE_RGB
;
234 env
->Color
.InvertC
= FXFALSE
;
236 env
->Color
.SourceA
= incomingRGB
;
237 env
->Color
.ModeA
= GR_FUNC_MODE_X
;
238 env
->Color
.SourceB
= GR_CMBX_ZERO
;
239 env
->Color
.ModeB
= GR_FUNC_MODE_ZERO
;
240 env
->Color
.SourceD
= GR_CMBX_ZERO
;
241 env
->Color
.InvertD
= FXFALSE
;
242 /* -- Setup Alpha combiner */
243 if (baseFormat
== GL_LUMINANCE
|| baseFormat
== GL_RGB
) {
245 env
->Alpha
.SourceA
= incomingAlpha
;
246 env
->Alpha
.SourceC
= GR_CMBX_ZERO
;
247 env
->Alpha
.InvertC
= FXTRUE
;
251 env
->Alpha
.SourceA
= GR_CMBX_LOCAL_TEXTURE_ALPHA
;
252 env
->Alpha
.SourceC
= incomingAlpha
;
253 env
->Alpha
.InvertC
= FXFALSE
;
255 env
->Alpha
.ModeA
= GR_FUNC_MODE_X
;
256 env
->Alpha
.SourceB
= GR_CMBX_ITALPHA
;
257 env
->Alpha
.ModeB
= GR_FUNC_MODE_ZERO
;
258 env
->Alpha
.SourceD
= GR_CMBX_ZERO
;
259 env
->Alpha
.InvertD
= FXFALSE
;
263 /* -- Setup RGB combiner */
264 if (baseFormat
== GL_RGB
) {
266 env
->Color
.SourceB
= GR_CMBX_ZERO
;
267 env
->Color
.ModeB
= GR_FUNC_MODE_X
;
268 env
->Color
.SourceC
= GR_CMBX_ZERO
;
269 env
->Color
.InvertC
= FXTRUE
;
270 env
->Color
.SourceD
= GR_CMBX_ZERO
;
271 env
->Color
.InvertD
= FXFALSE
;
274 /* Rv = Rf * (1 - At) + Rt * At */
275 env
->Color
.SourceB
= incomingRGB
;
276 env
->Color
.ModeB
= GR_FUNC_MODE_NEGATIVE_X
;
277 env
->Color
.SourceC
= GR_CMBX_LOCAL_TEXTURE_ALPHA
;
278 env
->Color
.InvertC
= FXFALSE
;
279 env
->Color
.SourceD
= GR_CMBX_B
;
280 env
->Color
.InvertD
= FXFALSE
;
282 env
->Color
.SourceA
= GR_CMBX_LOCAL_TEXTURE_RGB
;
283 env
->Color
.ModeA
= GR_FUNC_MODE_X
;
284 /* -- Setup Alpha combiner */
286 env
->Alpha
.SourceA
= incomingAlpha
;
287 env
->Alpha
.ModeA
= GR_FUNC_MODE_X
;
288 env
->Alpha
.SourceB
= GR_CMBX_ITALPHA
;
289 env
->Alpha
.ModeB
= GR_FUNC_MODE_ZERO
;
290 env
->Alpha
.SourceC
= GR_CMBX_ZERO
;
291 env
->Alpha
.InvertC
= FXTRUE
;
292 env
->Alpha
.SourceD
= GR_CMBX_ZERO
;
293 env
->Alpha
.InvertD
= FXFALSE
;
297 /* -- Setup RGB combiner */
298 if (baseFormat
== GL_ALPHA
) {
300 env
->Color
.SourceA
= incomingRGB
;
301 env
->Color
.ModeA
= GR_FUNC_MODE_X
;
302 env
->Color
.SourceB
= GR_CMBX_ZERO
;
303 env
->Color
.ModeB
= GR_FUNC_MODE_ZERO
;
304 env
->Color
.SourceC
= GR_CMBX_ZERO
;
305 env
->Color
.InvertC
= FXTRUE
;
306 env
->Color
.SourceD
= GR_CMBX_ZERO
;
307 env
->Color
.InvertD
= FXFALSE
;
310 /* Rv = Rf * (1 - Rt) + Rc * Rt */
311 env
->Color
.SourceA
= GR_CMBX_TMU_CCOLOR
;
312 env
->Color
.ModeA
= GR_FUNC_MODE_X
;
313 env
->Color
.SourceB
= incomingRGB
;
314 env
->Color
.ModeB
= GR_FUNC_MODE_NEGATIVE_X
;
315 env
->Color
.SourceC
= GR_CMBX_LOCAL_TEXTURE_RGB
;
316 env
->Color
.InvertC
= FXFALSE
;
317 env
->Color
.SourceD
= GR_CMBX_B
;
318 env
->Color
.InvertD
= FXFALSE
;
320 /* -- Setup Alpha combiner */
321 if (baseFormat
== GL_LUMINANCE
|| baseFormat
== GL_RGB
) {
323 env
->Alpha
.SourceA
= incomingAlpha
;
324 env
->Alpha
.ModeA
= GR_FUNC_MODE_X
;
325 env
->Alpha
.SourceB
= GR_CMBX_ZERO
;
326 env
->Alpha
.ModeB
= GR_FUNC_MODE_ZERO
;
327 env
->Alpha
.SourceC
= GR_CMBX_ZERO
;
328 env
->Alpha
.InvertC
= FXTRUE
;
329 env
->Alpha
.SourceD
= GR_CMBX_ZERO
;
330 env
->Alpha
.InvertD
= FXFALSE
;
332 else if (baseFormat
== GL_INTENSITY
) {
333 /* Av = Af * (1 - It) + Ac * It */
334 env
->Alpha
.SourceA
= GR_CMBX_TMU_CALPHA
;
335 env
->Alpha
.ModeA
= GR_FUNC_MODE_X
;
336 env
->Alpha
.SourceB
= incomingAlpha
;
337 env
->Alpha
.ModeB
= GR_FUNC_MODE_NEGATIVE_X
;
338 env
->Alpha
.SourceC
= GR_CMBX_LOCAL_TEXTURE_ALPHA
;
339 env
->Alpha
.InvertC
= FXFALSE
;
340 env
->Alpha
.SourceD
= GR_CMBX_B
;
341 env
->Alpha
.InvertD
= FXFALSE
;
345 env
->Alpha
.SourceA
= GR_CMBX_LOCAL_TEXTURE_ALPHA
;
346 env
->Alpha
.ModeA
= GR_FUNC_MODE_X
;
347 env
->Alpha
.SourceB
= GR_CMBX_ITALPHA
;
348 env
->Alpha
.ModeB
= GR_FUNC_MODE_ZERO
;
349 env
->Alpha
.SourceC
= incomingAlpha
;
350 env
->Alpha
.InvertC
= FXFALSE
;
351 env
->Alpha
.SourceD
= GR_CMBX_ZERO
;
352 env
->Alpha
.InvertD
= FXFALSE
;
354 /* Also have to set up the tex env constant color */
355 env
->EnvColor
= PACK_RGBA32(texUnit
->EnvColor
[0] * 255.0F
,
356 texUnit
->EnvColor
[1] * 255.0F
,
357 texUnit
->EnvColor
[2] * 255.0F
,
358 texUnit
->EnvColor
[3] * 255.0F
);
361 /* -- Setup RGB combiner */
362 if (baseFormat
== GL_ALPHA
) {
364 env
->Color
.SourceB
= GR_CMBX_ZERO
;
365 env
->Color
.ModeB
= GR_FUNC_MODE_ZERO
;
369 env
->Color
.SourceB
= GR_CMBX_LOCAL_TEXTURE_RGB
;
370 env
->Color
.ModeB
= GR_FUNC_MODE_X
;
372 env
->Color
.SourceA
= incomingRGB
;
373 env
->Color
.ModeA
= GR_FUNC_MODE_X
;
374 env
->Color
.SourceC
= GR_CMBX_ZERO
;
375 env
->Color
.InvertC
= FXTRUE
;
376 env
->Color
.SourceD
= GR_CMBX_ZERO
;
377 env
->Color
.InvertD
= FXFALSE
;
378 /* -- Setup Alpha combiner */
379 if (baseFormat
== GL_LUMINANCE
|| baseFormat
== GL_RGB
) {
381 env
->Alpha
.SourceA
= incomingAlpha
;
382 env
->Alpha
.SourceB
= GR_CMBX_ITALPHA
;
383 env
->Alpha
.ModeB
= GR_FUNC_MODE_ZERO
;
384 env
->Alpha
.SourceC
= GR_CMBX_ZERO
;
385 env
->Alpha
.InvertC
= FXTRUE
;
388 else if (baseFormat
== GL_INTENSITY
) {
390 env
->Alpha
.SourceA
= incomingAlpha
;
391 env
->Alpha
.SourceB
= GR_CMBX_LOCAL_TEXTURE_ALPHA
;
392 env
->Alpha
.ModeB
= GR_FUNC_MODE_X
;
393 env
->Alpha
.SourceC
= GR_CMBX_ZERO
;
394 env
->Alpha
.InvertC
= FXTRUE
;
398 env
->Alpha
.SourceA
= GR_CMBX_LOCAL_TEXTURE_ALPHA
;
399 env
->Alpha
.SourceB
= GR_CMBX_ITALPHA
;
400 env
->Alpha
.ModeB
= GR_FUNC_MODE_ZERO
;
401 env
->Alpha
.SourceC
= incomingAlpha
;
402 env
->Alpha
.InvertC
= FXFALSE
;
404 env
->Alpha
.ModeA
= GR_FUNC_MODE_X
;
405 env
->Alpha
.SourceD
= GR_CMBX_ZERO
;
406 env
->Alpha
.InvertD
= FXFALSE
;
411 FxU32 A_RGB
, B_RGB
, C_RGB
, D_RGB
;
412 FxU32 Amode_RGB
, Bmode_RGB
;
413 FxBool Cinv_RGB
, Dinv_RGB
, Ginv_RGB
;
415 FxU32 A_A
, B_A
, C_A
, D_A
;
416 FxU32 Amode_A
, Bmode_A
;
417 FxBool Cinv_A
, Dinv_A
, Ginv_A
;
422 * In the formulas below, we write:
423 * o "1(x)" for the identity function applied to x,
425 * o "0(x)" for the constant function 0, so
426 * 0(x) = 0 for all values of x.
428 * Calculate the color combination.
430 Shift_RGB
= texUnit
->Combine
.ScaleShiftRGB
;
431 Shift_A
= texUnit
->Combine
.ScaleShiftA
;
432 switch (texUnit
->Combine
.ModeRGB
) {
435 * The formula is: Arg0
436 * We implement this by the formula:
437 * (Arg0 + 0(0))*(1-0) + 0
439 TEXENV_SETUP_ARG_RGB(A_RGB
,
440 texUnit
->Combine
.SourceRGB
[0],
441 texUnit
->Combine
.OperandRGB
[0],
442 incomingRGB
, incomingAlpha
);
443 TEXENV_SETUP_MODE_RGB(Amode_RGB
,
444 texUnit
->Combine
.OperandRGB
[0]);
445 B_RGB
= C_RGB
= D_RGB
= GR_CMBX_ZERO
;
446 Bmode_RGB
= GR_FUNC_MODE_ZERO
;
448 Dinv_RGB
= Ginv_RGB
= FXFALSE
;
452 * The formula is: Arg0 * Arg1
454 * We implement this by the formula
455 * (Arg0 + 0(0)) * Arg1 + 0(0)
457 TEXENV_SETUP_ARG_RGB(A_RGB
,
458 texUnit
->Combine
.SourceRGB
[0],
459 texUnit
->Combine
.OperandRGB
[0],
460 incomingRGB
, incomingAlpha
);
461 TEXENV_SETUP_MODE_RGB(Amode_RGB
,
462 texUnit
->Combine
.OperandRGB
[0]);
463 B_RGB
= GR_CMBX_ZERO
;
464 Bmode_RGB
= GR_CMBX_ZERO
;
465 TEXENV_SETUP_ARG_RGB(C_RGB
,
466 texUnit
->Combine
.SourceRGB
[1],
467 texUnit
->Combine
.OperandRGB
[1],
468 incomingRGB
, incomingAlpha
);
469 Cinv_RGB
= TEXENV_OPERAND_INVERTED
470 (texUnit
->Combine
.OperandRGB
[1]);
471 D_RGB
= GR_CMBX_ZERO
;
472 Dinv_RGB
= Ginv_RGB
= FXFALSE
;
476 * The formula is Arg0 + Arg1
478 TEXENV_SETUP_ARG_RGB(A_RGB
,
479 texUnit
->Combine
.SourceRGB
[0],
480 texUnit
->Combine
.OperandRGB
[0],
481 incomingRGB
, incomingAlpha
);
482 TEXENV_SETUP_MODE_RGB(Amode_RGB
,
483 texUnit
->Combine
.OperandRGB
[0]);
484 TEXENV_SETUP_ARG_RGB(B_RGB
,
485 texUnit
->Combine
.SourceRGB
[1],
486 texUnit
->Combine
.OperandRGB
[1],
487 incomingRGB
, incomingAlpha
);
488 TEXENV_SETUP_MODE_RGB(Bmode_RGB
,
489 texUnit
->Combine
.OperandRGB
[1]);
490 C_RGB
= D_RGB
= GR_CMBX_ZERO
;
492 Dinv_RGB
= Ginv_RGB
= FXFALSE
;
494 case GL_ADD_SIGNED_EXT
:
496 * The formula is: Arg0 + Arg1 - 0.5.
497 * We compute this by calculating:
498 * (Arg0 - 1/2) + Arg1 if op0 is SRC_{COLOR,ALPHA}
499 * Arg0 + (Arg1 - 1/2) if op1 is SRC_{COLOR,ALPHA}
500 * If both op0 and op1 are ONE_MINUS_SRC_{COLOR,ALPHA}
501 * we cannot implement the formula properly.
503 TEXENV_SETUP_ARG_RGB(A_RGB
,
504 texUnit
->Combine
.SourceRGB
[0],
505 texUnit
->Combine
.OperandRGB
[0],
506 incomingRGB
, incomingAlpha
);
507 TEXENV_SETUP_ARG_RGB(B_RGB
,
508 texUnit
->Combine
.SourceRGB
[1],
509 texUnit
->Combine
.OperandRGB
[1],
510 incomingRGB
, incomingAlpha
);
511 if (!TEXENV_OPERAND_INVERTED(texUnit
->Combine
.OperandRGB
[0])) {
513 * A is not inverted. So, choose it.
515 Amode_RGB
= GR_FUNC_MODE_X_MINUS_HALF
;
516 if (!TEXENV_OPERAND_INVERTED
517 (texUnit
->Combine
.OperandRGB
[1])) {
518 Bmode_RGB
= GR_FUNC_MODE_X
;
521 Bmode_RGB
= GR_FUNC_MODE_ONE_MINUS_X
;
526 * A is inverted, so try to subtract 1/2
529 Amode_RGB
= GR_FUNC_MODE_ONE_MINUS_X
;
530 if (!TEXENV_OPERAND_INVERTED
531 (texUnit
->Combine
.OperandRGB
[1])) {
532 Bmode_RGB
= GR_FUNC_MODE_X_MINUS_HALF
;
536 * Both are inverted. This is the case
537 * we cannot handle properly. We just
538 * choose to not add the - 1/2.
540 Bmode_RGB
= GR_FUNC_MODE_ONE_MINUS_X
;
544 C_RGB
= D_RGB
= GR_CMBX_ZERO
;
546 Dinv_RGB
= Ginv_RGB
= FXFALSE
;
548 case GL_INTERPOLATE_EXT
:
550 * The formula is: Arg0 * Arg2 + Arg1 * (1 - Arg2).
551 * We compute this by the formula:
552 * (Arg0 - Arg1) * Arg2 + Arg1
553 * == Arg0 * Arg2 - Arg1 * Arg2 + Arg1
554 * == Arg0 * Arg2 + Arg1 * (1 - Arg2)
555 * However, if both Arg1 is ONE_MINUS_X, the HW does
556 * not support it properly.
558 TEXENV_SETUP_ARG_RGB(A_RGB
,
559 texUnit
->Combine
.SourceRGB
[0],
560 texUnit
->Combine
.OperandRGB
[0],
561 incomingRGB
, incomingAlpha
);
562 TEXENV_SETUP_MODE_RGB(Amode_RGB
,
563 texUnit
->Combine
.OperandRGB
[0]);
564 TEXENV_SETUP_ARG_RGB(B_RGB
,
565 texUnit
->Combine
.SourceRGB
[1],
566 texUnit
->Combine
.OperandRGB
[1],
567 incomingRGB
, incomingAlpha
);
568 if (TEXENV_OPERAND_INVERTED(texUnit
->Combine
.OperandRGB
[1])) {
570 * This case is wrong.
572 Bmode_RGB
= GR_FUNC_MODE_NEGATIVE_X
;
576 Bmode_RGB
= GR_FUNC_MODE_NEGATIVE_X
;
579 * The Source/Operand for the C value must
580 * specify some kind of alpha value.
582 TEXENV_SETUP_ARG_A(C_RGB
,
583 texUnit
->Combine
.SourceRGB
[2],
584 texUnit
->Combine
.OperandRGB
[2],
588 Dinv_RGB
= Ginv_RGB
= FXFALSE
;
592 * This is here mostly to keep from getting
593 * a compiler warning about these not being set.
594 * However, this should set all the texture values
597 A_RGB
= B_RGB
= C_RGB
= D_RGB
= GR_CMBX_ZERO
;
598 Amode_RGB
= Bmode_RGB
= GR_FUNC_MODE_X
;
599 Cinv_RGB
= Dinv_RGB
= Ginv_RGB
= FXFALSE
;
603 * Calculate the alpha combination.
605 switch (texUnit
->Combine
.ModeA
) {
608 * The formula is: Arg0
609 * We implement this by the formula:
610 * (Arg0 + 0(0))*(1-0) + 0
612 TEXENV_SETUP_ARG_A(A_A
,
613 texUnit
->Combine
.SourceA
[0],
614 texUnit
->Combine
.OperandA
[0],
616 TEXENV_SETUP_MODE_A(Amode_A
,
617 texUnit
->Combine
.OperandA
[0]);
618 B_A
= GR_CMBX_ITALPHA
;
619 Bmode_A
= GR_FUNC_MODE_ZERO
;
620 C_A
= D_A
= GR_CMBX_ZERO
;
622 Dinv_A
= Ginv_A
= FXFALSE
;
626 * The formula is: Arg0 * Arg1
628 * We implement this by the formula
629 * (Arg0 + 0(0)) * Arg1 + 0(0)
631 TEXENV_SETUP_ARG_A(A_A
,
632 texUnit
->Combine
.SourceA
[0],
633 texUnit
->Combine
.OperandA
[0],
635 TEXENV_SETUP_MODE_A(Amode_A
,
636 texUnit
->Combine
.OperandA
[0]);
638 Bmode_A
= GR_CMBX_ZERO
;
639 TEXENV_SETUP_ARG_A(C_A
,
640 texUnit
->Combine
.SourceA
[1],
641 texUnit
->Combine
.OperandA
[1],
643 Cinv_A
= TEXENV_OPERAND_INVERTED
644 (texUnit
->Combine
.OperandA
[1]);
646 Dinv_A
= Ginv_A
= FXFALSE
;
650 * The formula is Arg0 + Arg1
652 TEXENV_SETUP_ARG_A(A_A
,
653 texUnit
->Combine
.SourceA
[0],
654 texUnit
->Combine
.OperandA
[0],
656 TEXENV_SETUP_MODE_A(Amode_A
,
657 texUnit
->Combine
.OperandA
[0]);
658 TEXENV_SETUP_ARG_A(B_A
,
659 texUnit
->Combine
.SourceA
[1],
660 texUnit
->Combine
.OperandA
[1],
662 TEXENV_SETUP_MODE_A(Bmode_A
,
663 texUnit
->Combine
.OperandA
[1]);
664 C_A
= D_A
= GR_CMBX_ZERO
;
666 Dinv_A
= Ginv_A
= FXFALSE
;
668 case GL_ADD_SIGNED_EXT
:
670 * The formula is: Arg0 + Arg1 - 0.5.
671 * We compute this by calculating:
672 * (Arg0 - 1/2) + Arg1 if op0 is SRC_{COLOR,ALPHA}
673 * Arg0 + (Arg1 - 1/2) if op1 is SRC_{COLOR,ALPHA}
674 * If both op0 and op1 are ONE_MINUS_SRC_{COLOR,ALPHA}
675 * we cannot implement the formula properly.
677 TEXENV_SETUP_ARG_A(A_A
,
678 texUnit
->Combine
.SourceA
[0],
679 texUnit
->Combine
.OperandA
[0],
681 TEXENV_SETUP_ARG_A(B_A
,
682 texUnit
->Combine
.SourceA
[1],
683 texUnit
->Combine
.OperandA
[1],
685 if (!TEXENV_OPERAND_INVERTED(texUnit
->Combine
.OperandA
[0])) {
687 * A is not inverted. So, choose it.
689 Amode_A
= GR_FUNC_MODE_X_MINUS_HALF
;
690 if (!TEXENV_OPERAND_INVERTED
691 (texUnit
->Combine
.OperandA
[1])) {
692 Bmode_A
= GR_FUNC_MODE_X
;
694 Bmode_A
= GR_FUNC_MODE_ONE_MINUS_X
;
698 * A is inverted, so try to subtract 1/2
701 Amode_A
= GR_FUNC_MODE_ONE_MINUS_X
;
702 if (!TEXENV_OPERAND_INVERTED
703 (texUnit
->Combine
.OperandA
[1])) {
704 Bmode_A
= GR_FUNC_MODE_X_MINUS_HALF
;
707 * Both are inverted. This is the case
708 * we cannot handle properly. We just
709 * choose to not add the - 1/2.
711 Bmode_A
= GR_FUNC_MODE_ONE_MINUS_X
;
715 C_A
= D_A
= GR_CMBX_ZERO
;
717 Dinv_A
= Ginv_A
= FXFALSE
;
719 case GL_INTERPOLATE_EXT
:
721 * The formula is: Arg0 * Arg2 + Arg1 * (1 - Arg2).
722 * We compute this by the formula:
723 * (Arg0 - Arg1) * Arg2 + Arg1
724 * == Arg0 * Arg2 - Arg1 * Arg2 + Arg1
725 * == Arg0 * Arg2 + Arg1 * (1 - Arg2)
726 * However, if both Arg1 is ONE_MINUS_X, the HW does
727 * not support it properly.
729 TEXENV_SETUP_ARG_A(A_A
,
730 texUnit
->Combine
.SourceA
[0],
731 texUnit
->Combine
.OperandA
[0],
733 TEXENV_SETUP_MODE_A(Amode_A
,
734 texUnit
->Combine
.OperandA
[0]);
735 TEXENV_SETUP_ARG_A(B_A
,
736 texUnit
->Combine
.SourceA
[1],
737 texUnit
->Combine
.OperandA
[1],
739 if (!TEXENV_OPERAND_INVERTED(texUnit
->Combine
.OperandA
[1])) {
740 Bmode_A
= GR_FUNC_MODE_NEGATIVE_X
;
744 * This case is wrong.
746 Bmode_A
= GR_FUNC_MODE_NEGATIVE_X
;
750 * The Source/Operand for the C value must
751 * specify some kind of alpha value.
753 TEXENV_SETUP_ARG_A(C_A
,
754 texUnit
->Combine
.SourceA
[2],
755 texUnit
->Combine
.OperandA
[2],
759 Dinv_A
= Ginv_A
= FXFALSE
;
763 * This is here mostly to keep from getting
764 * a compiler warning about these not being set.
765 * However, this should set all the alpha values
768 A_A
= B_A
= C_A
= D_A
= GR_CMBX_ZERO
;
769 Amode_A
= Bmode_A
= GR_FUNC_MODE_X
;
770 Cinv_A
= Dinv_A
= FXFALSE
;
775 * Save the parameters.
777 env
->Color
.SourceA
= A_RGB
;
778 env
->Color
.ModeA
= Amode_RGB
;
779 env
->Color
.SourceB
= B_RGB
;
780 env
->Color
.ModeB
= Bmode_RGB
;
781 env
->Color
.SourceC
= C_RGB
;
782 env
->Color
.InvertC
= Cinv_RGB
;
783 env
->Color
.SourceD
= D_RGB
;
784 env
->Color
.InvertD
= Dinv_RGB
;
785 env
->Color
.Shift
= Shift_RGB
;
786 env
->Color
.Invert
= Ginv_RGB
;
787 env
->Alpha
.SourceA
= A_A
;
788 env
->Alpha
.ModeA
= Amode_A
;
789 env
->Alpha
.SourceB
= B_A
;
790 env
->Alpha
.ModeB
= Bmode_A
;
791 env
->Alpha
.SourceC
= C_A
;
792 env
->Alpha
.InvertC
= Cinv_A
;
793 env
->Alpha
.SourceD
= D_A
;
794 env
->Alpha
.InvertD
= Dinv_A
;
795 env
->Alpha
.Shift
= Shift_A
;
796 env
->Alpha
.Invert
= Ginv_A
;
797 env
->EnvColor
= PACK_RGBA32(texUnit
->EnvColor
[0] * 255.0F
,
798 texUnit
->EnvColor
[1] * 255.0F
,
799 texUnit
->EnvColor
[2] * 255.0F
,
800 texUnit
->EnvColor
[3] * 255.0F
);
805 _mesa_problem(ctx
, "%s: Bad envMode", __FUNCTION__
);
808 fxMesa
->dirty
|= TDFX_UPLOAD_TEXTURE_ENV
;
810 fxMesa
->ColorCombineExt
.SourceA
= GR_CMBX_TEXTURE_RGB
;
811 fxMesa
->ColorCombineExt
.ModeA
= GR_FUNC_MODE_X
,
812 fxMesa
->ColorCombineExt
.SourceB
= GR_CMBX_ZERO
;
813 fxMesa
->ColorCombineExt
.ModeB
= GR_FUNC_MODE_X
;
814 fxMesa
->ColorCombineExt
.SourceC
= GR_CMBX_ZERO
;
815 fxMesa
->ColorCombineExt
.InvertC
= FXTRUE
;
816 fxMesa
->ColorCombineExt
.SourceD
= GR_CMBX_ZERO
;
817 fxMesa
->ColorCombineExt
.InvertD
= FXFALSE
;
818 fxMesa
->ColorCombineExt
.Shift
= 0;
819 fxMesa
->ColorCombineExt
.Invert
= FXFALSE
;
820 fxMesa
->dirty
|= TDFX_UPLOAD_COLOR_COMBINE
;
821 fxMesa
->AlphaCombineExt
.SourceA
= GR_CMBX_TEXTURE_ALPHA
;
822 fxMesa
->AlphaCombineExt
.ModeA
= GR_FUNC_MODE_X
;
823 fxMesa
->AlphaCombineExt
.SourceB
= GR_CMBX_ZERO
;
824 fxMesa
->AlphaCombineExt
.ModeB
= GR_FUNC_MODE_X
;
825 fxMesa
->AlphaCombineExt
.SourceC
= GR_CMBX_ZERO
;
826 fxMesa
->AlphaCombineExt
.InvertC
= FXTRUE
;
827 fxMesa
->AlphaCombineExt
.SourceD
= GR_CMBX_ZERO
;
828 fxMesa
->AlphaCombineExt
.InvertD
= FXFALSE
;
829 fxMesa
->AlphaCombineExt
.Shift
= 0;
830 fxMesa
->AlphaCombineExt
.Invert
= FXFALSE
;
831 fxMesa
->dirty
|= TDFX_UPLOAD_ALPHA_COMBINE
;
832 return GL_TRUE
; /* success */
838 * Setup the Voodoo3 texture environment for a single texture unit.
839 * Return GL_TRUE for success, GL_FALSE for failure.
840 * If failure, we'll use software rendering.
843 SetupSingleTexEnvVoodoo3(GLcontext
*ctx
, int unit
,
844 GLenum envMode
, GLenum baseFormat
)
846 tdfxContextPtr fxMesa
= TDFX_CONTEXT(ctx
);
847 GrCombineLocal_t localc
, locala
;
848 struct tdfx_combine alphaComb
, colorComb
;
850 if (1 /*iteratedRGBA*/)
851 localc
= locala
= GR_COMBINE_LOCAL_ITERATED
;
853 localc
= locala
= GR_COMBINE_LOCAL_CONSTANT
;
857 alphaComb
.Function
= GR_COMBINE_FUNCTION_LOCAL
;
858 alphaComb
.Factor
= GR_COMBINE_FACTOR_NONE
;
859 alphaComb
.Local
= locala
;
860 alphaComb
.Other
= GR_COMBINE_OTHER_NONE
;
861 alphaComb
.Invert
= FXFALSE
;
862 colorComb
.Function
= GR_COMBINE_FUNCTION_BLEND
;
863 colorComb
.Factor
= GR_COMBINE_FACTOR_TEXTURE_ALPHA
;
864 colorComb
.Local
= localc
;
865 colorComb
.Other
= GR_COMBINE_OTHER_TEXTURE
;
866 colorComb
.Invert
= FXFALSE
;
869 alphaComb
.Function
= GR_COMBINE_FUNCTION_SCALE_OTHER
;
870 alphaComb
.Factor
= GR_COMBINE_FACTOR_LOCAL
;
871 alphaComb
.Local
= locala
;
872 alphaComb
.Other
= GR_COMBINE_OTHER_TEXTURE
;
873 alphaComb
.Invert
= FXFALSE
;
874 if (baseFormat
== GL_ALPHA
) {
875 colorComb
.Function
= GR_COMBINE_FUNCTION_LOCAL
;
876 colorComb
.Factor
= GR_COMBINE_FACTOR_NONE
;
877 colorComb
.Local
= localc
;
878 colorComb
.Other
= GR_COMBINE_OTHER_NONE
;
879 colorComb
.Invert
= FXFALSE
;
882 colorComb
.Function
= GR_COMBINE_FUNCTION_SCALE_OTHER
;
883 colorComb
.Factor
= GR_COMBINE_FACTOR_LOCAL
;
884 colorComb
.Local
= localc
;
885 colorComb
.Other
= GR_COMBINE_OTHER_TEXTURE
;
886 colorComb
.Invert
= FXFALSE
;
892 * XXX we can't do real GL_BLEND mode. These settings assume that
893 * the TexEnv color is black and incoming fragment color is white.
895 if (baseFormat
== GL_LUMINANCE
|| baseFormat
== GL_RGB
) {
897 alphaComb
.Function
= GR_COMBINE_FUNCTION_LOCAL
;
898 alphaComb
.Factor
= GR_COMBINE_FACTOR_NONE
;
899 alphaComb
.Local
= locala
;
900 alphaComb
.Other
= GR_COMBINE_OTHER_NONE
;
901 alphaComb
.Invert
= FXFALSE
;
903 else if (baseFormat
== GL_INTENSITY
) {
904 /* Av = Af * (1 - It) + Ac * It */
905 alphaComb
.Function
= GR_COMBINE_FUNCTION_BLEND
;
906 alphaComb
.Factor
= GR_COMBINE_FACTOR_TEXTURE_ALPHA
;
907 alphaComb
.Local
= locala
;
908 alphaComb
.Other
= GR_COMBINE_OTHER_CONSTANT
;
909 alphaComb
.Invert
= FXFALSE
;
913 alphaComb
.Function
= GR_COMBINE_FUNCTION_SCALE_OTHER
;
914 alphaComb
.Factor
= GR_COMBINE_FACTOR_LOCAL
;
915 alphaComb
.Local
= locala
;
916 alphaComb
.Other
= GR_COMBINE_OTHER_TEXTURE
;
917 alphaComb
.Invert
= FXFALSE
;
919 if (baseFormat
== GL_ALPHA
) {
920 colorComb
.Function
= GR_COMBINE_FUNCTION_LOCAL
;
921 colorComb
.Factor
= GR_COMBINE_FACTOR_NONE
;
922 colorComb
.Local
= localc
;
923 colorComb
.Other
= GR_COMBINE_OTHER_NONE
;
924 colorComb
.Invert
= FXFALSE
;
927 colorComb
.Function
= GR_COMBINE_FUNCTION_BLEND
;
928 colorComb
.Factor
= GR_COMBINE_FACTOR_TEXTURE_RGB
;
929 colorComb
.Local
= localc
;
930 colorComb
.Other
= GR_COMBINE_OTHER_CONSTANT
;
931 colorComb
.Invert
= FXTRUE
;
933 fxMesa
->Color
.MonoColor
= PACK_RGBA32(
934 ctx
->Texture
.Unit
[unit
].EnvColor
[0] * 255.0f
,
935 ctx
->Texture
.Unit
[unit
].EnvColor
[1] * 255.0f
,
936 ctx
->Texture
.Unit
[unit
].EnvColor
[2] * 255.0f
,
937 ctx
->Texture
.Unit
[unit
].EnvColor
[3] * 255.0f
);
938 fxMesa
->dirty
|= TDFX_UPLOAD_CONSTANT_COLOR
;
942 if ((baseFormat
== GL_RGB
) || (baseFormat
== GL_LUMINANCE
)) {
943 alphaComb
.Function
= GR_COMBINE_FUNCTION_LOCAL
;
944 alphaComb
.Factor
= GR_COMBINE_FACTOR_NONE
;
945 alphaComb
.Local
= locala
;
946 alphaComb
.Other
= GR_COMBINE_OTHER_NONE
;
947 alphaComb
.Invert
= FXFALSE
;
950 alphaComb
.Function
= GR_COMBINE_FUNCTION_SCALE_OTHER
;
951 alphaComb
.Factor
= GR_COMBINE_FACTOR_ONE
;
952 alphaComb
.Local
= locala
;
953 alphaComb
.Other
= GR_COMBINE_OTHER_TEXTURE
;
954 alphaComb
.Invert
= FXFALSE
;
956 if (baseFormat
== GL_ALPHA
) {
957 colorComb
.Function
= GR_COMBINE_FUNCTION_LOCAL
;
958 colorComb
.Factor
= GR_COMBINE_FACTOR_NONE
;
959 colorComb
.Local
= localc
;
960 colorComb
.Other
= GR_COMBINE_OTHER_NONE
;
961 colorComb
.Invert
= FXFALSE
;
964 colorComb
.Function
= GR_COMBINE_FUNCTION_SCALE_OTHER
;
965 colorComb
.Factor
= GR_COMBINE_FACTOR_ONE
;
966 colorComb
.Local
= localc
;
967 colorComb
.Other
= GR_COMBINE_OTHER_TEXTURE
;
968 colorComb
.Invert
= FXFALSE
;
973 if (baseFormat
== GL_ALPHA
||
974 baseFormat
== GL_LUMINANCE_ALPHA
||
975 baseFormat
== GL_RGBA
) {
976 /* product of texel and fragment alpha */
977 alphaComb
.Function
= GR_COMBINE_FUNCTION_SCALE_OTHER
;
978 alphaComb
.Factor
= GR_COMBINE_FACTOR_LOCAL
;
979 alphaComb
.Local
= locala
;
980 alphaComb
.Other
= GR_COMBINE_OTHER_TEXTURE
;
981 alphaComb
.Invert
= FXFALSE
;
983 else if (baseFormat
== GL_LUMINANCE
|| baseFormat
== GL_RGB
) {
984 /* fragment alpha is unchanged */
985 alphaComb
.Function
= GR_COMBINE_FUNCTION_LOCAL
;
986 alphaComb
.Factor
= GR_COMBINE_FACTOR_NONE
;
987 alphaComb
.Local
= locala
;
988 alphaComb
.Other
= GR_COMBINE_OTHER_NONE
;
989 alphaComb
.Invert
= FXFALSE
;
992 ASSERT(baseFormat
== GL_INTENSITY
);
993 /* sum of texel and fragment alpha */
994 alphaComb
.Function
= GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL
,
995 alphaComb
.Factor
= GR_COMBINE_FACTOR_ONE
;
996 alphaComb
.Local
= locala
;
997 alphaComb
.Other
= GR_COMBINE_OTHER_TEXTURE
;
998 alphaComb
.Invert
= FXFALSE
;
1000 if (baseFormat
== GL_ALPHA
) {
1002 colorComb
.Function
= GR_COMBINE_FUNCTION_LOCAL
;
1003 colorComb
.Factor
= GR_COMBINE_FACTOR_NONE
;
1004 colorComb
.Local
= localc
;
1005 colorComb
.Other
= GR_COMBINE_OTHER_NONE
;
1006 colorComb
.Invert
= FXFALSE
;
1009 /* sum of texel and fragment rgb */
1010 colorComb
.Function
= GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL
,
1011 colorComb
.Factor
= GR_COMBINE_FACTOR_ONE
;
1012 colorComb
.Local
= localc
;
1013 colorComb
.Other
= GR_COMBINE_OTHER_TEXTURE
;
1014 colorComb
.Invert
= FXFALSE
;
1019 _mesa_problem(ctx
, "bad texture env mode in %s", __FUNCTION__
);
1022 if (colorComb
.Function
!= fxMesa
->ColorCombine
.Function
||
1023 colorComb
.Factor
!= fxMesa
->ColorCombine
.Factor
||
1024 colorComb
.Local
!= fxMesa
->ColorCombine
.Local
||
1025 colorComb
.Other
!= fxMesa
->ColorCombine
.Other
||
1026 colorComb
.Invert
!= fxMesa
->ColorCombine
.Invert
) {
1027 fxMesa
->ColorCombine
= colorComb
;
1028 fxMesa
->dirty
|= TDFX_UPLOAD_COLOR_COMBINE
;
1031 if (alphaComb
.Function
!= fxMesa
->AlphaCombine
.Function
||
1032 alphaComb
.Factor
!= fxMesa
->AlphaCombine
.Factor
||
1033 alphaComb
.Local
!= fxMesa
->AlphaCombine
.Local
||
1034 alphaComb
.Other
!= fxMesa
->AlphaCombine
.Other
||
1035 alphaComb
.Invert
!= fxMesa
->AlphaCombine
.Invert
) {
1036 fxMesa
->AlphaCombine
= alphaComb
;
1037 fxMesa
->dirty
|= TDFX_UPLOAD_ALPHA_COMBINE
;
1044 * Setup the Voodoo3 texture environment for dual texture units.
1045 * Return GL_TRUE for success, GL_FALSE for failure.
1046 * If failure, we'll use software rendering.
1049 SetupDoubleTexEnvVoodoo3(GLcontext
*ctx
, int tmu0
,
1050 GLenum envMode0
, GLenum baseFormat0
,
1051 GLenum envMode1
, GLenum baseFormat1
)
1053 tdfxContextPtr fxMesa
= TDFX_CONTEXT(ctx
);
1054 const GrCombineLocal_t locala
= GR_COMBINE_LOCAL_ITERATED
;
1055 const GrCombineLocal_t localc
= GR_COMBINE_LOCAL_ITERATED
;
1056 const int tmu1
= 1 - tmu0
;
1058 if (envMode0
== GL_MODULATE
&& envMode1
== GL_MODULATE
) {
1059 GLboolean isalpha
[TDFX_NUM_TMU
];
1061 isalpha
[tmu0
] = (baseFormat0
== GL_ALPHA
);
1062 isalpha
[tmu1
] = (baseFormat1
== GL_ALPHA
);
1064 if (isalpha
[TDFX_TMU1
]) {
1065 fxMesa
->TexCombine
[1].FunctionRGB
= GR_COMBINE_FUNCTION_ZERO
;
1066 fxMesa
->TexCombine
[1].FactorRGB
= GR_COMBINE_FACTOR_NONE
;
1067 fxMesa
->TexCombine
[1].FunctionAlpha
= GR_COMBINE_FUNCTION_LOCAL
;
1068 fxMesa
->TexCombine
[1].FactorAlpha
= GR_COMBINE_FACTOR_NONE
;
1069 fxMesa
->TexCombine
[1].InvertRGB
= FXTRUE
;
1070 fxMesa
->TexCombine
[1].InvertAlpha
= FXFALSE
;
1073 fxMesa
->TexCombine
[1].FunctionRGB
= GR_COMBINE_FUNCTION_LOCAL
;
1074 fxMesa
->TexCombine
[1].FactorRGB
= GR_COMBINE_FACTOR_NONE
;
1075 fxMesa
->TexCombine
[1].FunctionAlpha
= GR_COMBINE_FUNCTION_LOCAL
;
1076 fxMesa
->TexCombine
[1].FactorAlpha
= GR_COMBINE_FACTOR_NONE
;
1077 fxMesa
->TexCombine
[1].InvertRGB
= FXFALSE
;
1078 fxMesa
->TexCombine
[1].InvertAlpha
= FXFALSE
;
1080 if (isalpha
[TDFX_TMU0
]) {
1081 fxMesa
->TexCombine
[0].FunctionRGB
= GR_COMBINE_FUNCTION_BLEND_OTHER
;
1082 fxMesa
->TexCombine
[0].FactorRGB
= GR_COMBINE_FACTOR_ONE
;
1083 fxMesa
->TexCombine
[0].FunctionAlpha
= GR_COMBINE_FUNCTION_BLEND_OTHER
;
1084 fxMesa
->TexCombine
[0].FactorAlpha
= GR_COMBINE_FACTOR_LOCAL
;
1085 fxMesa
->TexCombine
[0].InvertRGB
= FXFALSE
;
1086 fxMesa
->TexCombine
[0].InvertAlpha
= FXFALSE
;
1089 fxMesa
->TexCombine
[0].FunctionRGB
= GR_COMBINE_FUNCTION_BLEND_OTHER
;
1090 fxMesa
->TexCombine
[0].FactorRGB
= GR_COMBINE_FACTOR_LOCAL
;
1091 fxMesa
->TexCombine
[0].FunctionAlpha
= GR_COMBINE_FUNCTION_BLEND_OTHER
;
1092 fxMesa
->TexCombine
[0].FactorAlpha
= GR_COMBINE_FACTOR_LOCAL
;
1093 fxMesa
->TexCombine
[0].InvertRGB
= FXFALSE
;
1094 fxMesa
->TexCombine
[0].InvertAlpha
= FXFALSE
;
1096 fxMesa
->ColorCombine
.Function
= GR_COMBINE_FUNCTION_SCALE_OTHER
;
1097 fxMesa
->ColorCombine
.Factor
= GR_COMBINE_FACTOR_LOCAL
;
1098 fxMesa
->ColorCombine
.Local
= localc
;
1099 fxMesa
->ColorCombine
.Other
= GR_COMBINE_OTHER_TEXTURE
;
1100 fxMesa
->ColorCombine
.Invert
= FXFALSE
;
1101 fxMesa
->AlphaCombine
.Function
= GR_COMBINE_FUNCTION_SCALE_OTHER
;
1102 fxMesa
->AlphaCombine
.Factor
= GR_COMBINE_FACTOR_LOCAL
;
1103 fxMesa
->AlphaCombine
.Local
= locala
;
1104 fxMesa
->AlphaCombine
.Other
= GR_COMBINE_OTHER_TEXTURE
;
1105 fxMesa
->AlphaCombine
.Invert
= FXFALSE
;
1107 else if (envMode0
== GL_REPLACE
&& envMode1
== GL_BLEND
) { /* Quake */
1108 if (tmu0
== TDFX_TMU1
) {
1109 fxMesa
->TexCombine
[1].FunctionRGB
= GR_COMBINE_FUNCTION_LOCAL
;
1110 fxMesa
->TexCombine
[1].FactorRGB
= GR_COMBINE_FACTOR_NONE
;
1111 fxMesa
->TexCombine
[1].FunctionAlpha
= GR_COMBINE_FUNCTION_LOCAL
;
1112 fxMesa
->TexCombine
[1].FactorAlpha
= GR_COMBINE_FACTOR_NONE
;
1113 fxMesa
->TexCombine
[1].InvertRGB
= FXTRUE
;
1114 fxMesa
->TexCombine
[1].InvertAlpha
= FXFALSE
;
1115 fxMesa
->TexCombine
[0].FunctionRGB
= GR_COMBINE_FUNCTION_BLEND_OTHER
;
1116 fxMesa
->TexCombine
[0].FactorRGB
= GR_COMBINE_FACTOR_LOCAL
;
1117 fxMesa
->TexCombine
[0].FunctionAlpha
= GR_COMBINE_FUNCTION_BLEND_OTHER
;
1118 fxMesa
->TexCombine
[0].FactorAlpha
= GR_COMBINE_FACTOR_LOCAL
;
1119 fxMesa
->TexCombine
[0].InvertRGB
= FXFALSE
;
1120 fxMesa
->TexCombine
[0].InvertAlpha
= FXFALSE
;
1123 fxMesa
->TexCombine
[1].FunctionRGB
= GR_COMBINE_FUNCTION_LOCAL
;
1124 fxMesa
->TexCombine
[1].FactorRGB
= GR_COMBINE_FACTOR_NONE
;
1125 fxMesa
->TexCombine
[1].FunctionAlpha
= GR_COMBINE_FUNCTION_LOCAL
;
1126 fxMesa
->TexCombine
[1].FactorAlpha
= GR_COMBINE_FACTOR_NONE
;
1127 fxMesa
->TexCombine
[1].InvertRGB
= FXFALSE
;
1128 fxMesa
->TexCombine
[1].InvertAlpha
= FXFALSE
;
1129 fxMesa
->TexCombine
[0].FunctionRGB
= GR_COMBINE_FUNCTION_BLEND_OTHER
;
1130 fxMesa
->TexCombine
[0].FactorRGB
= GR_COMBINE_FACTOR_ONE_MINUS_LOCAL
;
1131 fxMesa
->TexCombine
[0].FunctionAlpha
= GR_COMBINE_FUNCTION_BLEND_OTHER
;
1132 fxMesa
->TexCombine
[0].FactorAlpha
= GR_COMBINE_FACTOR_ONE_MINUS_LOCAL
;
1133 fxMesa
->TexCombine
[0].InvertRGB
= FXFALSE
;
1134 fxMesa
->TexCombine
[0].InvertAlpha
= FXFALSE
;
1136 fxMesa
->ColorCombine
.Function
= GR_COMBINE_FUNCTION_SCALE_OTHER
;
1137 fxMesa
->ColorCombine
.Factor
= GR_COMBINE_FACTOR_ONE
;
1138 fxMesa
->ColorCombine
.Local
= localc
;
1139 fxMesa
->ColorCombine
.Other
= GR_COMBINE_OTHER_TEXTURE
;
1140 fxMesa
->ColorCombine
.Invert
= FXFALSE
;
1141 fxMesa
->AlphaCombine
.Function
= GR_COMBINE_FUNCTION_LOCAL
;
1142 fxMesa
->AlphaCombine
.Factor
= GR_COMBINE_FACTOR_NONE
;
1143 fxMesa
->AlphaCombine
.Local
= locala
;
1144 fxMesa
->AlphaCombine
.Other
= GR_COMBINE_OTHER_NONE
;
1145 fxMesa
->AlphaCombine
.Invert
= FXFALSE
;
1147 else if (envMode0
== GL_REPLACE
&& envMode1
== GL_MODULATE
) {
1149 if (tmu1
== TDFX_TMU1
) {
1150 fxMesa
->TexCombine
[1].FunctionRGB
= GR_COMBINE_FUNCTION_LOCAL
;
1151 fxMesa
->TexCombine
[1].FactorRGB
= GR_COMBINE_FACTOR_NONE
;
1152 fxMesa
->TexCombine
[1].FunctionAlpha
= GR_COMBINE_FUNCTION_ZERO
;
1153 fxMesa
->TexCombine
[1].FactorAlpha
= GR_COMBINE_FACTOR_NONE
;
1154 fxMesa
->TexCombine
[1].InvertRGB
= FXFALSE
;
1155 fxMesa
->TexCombine
[1].InvertAlpha
= FXTRUE
;
1156 fxMesa
->TexCombine
[0].FunctionRGB
= GR_COMBINE_FUNCTION_BLEND_OTHER
;
1157 fxMesa
->TexCombine
[0].FactorRGB
= GR_COMBINE_FACTOR_LOCAL
;
1158 fxMesa
->TexCombine
[0].FunctionAlpha
= GR_COMBINE_FUNCTION_BLEND_OTHER
;
1159 fxMesa
->TexCombine
[0].FactorAlpha
= GR_COMBINE_FACTOR_LOCAL
;
1160 fxMesa
->TexCombine
[0].InvertRGB
= FXFALSE
;
1161 fxMesa
->TexCombine
[0].InvertAlpha
= FXFALSE
;
1164 fxMesa
->TexCombine
[1].FunctionRGB
= GR_COMBINE_FUNCTION_LOCAL
;
1165 fxMesa
->TexCombine
[1].FactorRGB
= GR_COMBINE_FACTOR_NONE
;
1166 fxMesa
->TexCombine
[1].FunctionAlpha
= GR_COMBINE_FUNCTION_LOCAL
;
1167 fxMesa
->TexCombine
[1].FactorAlpha
= GR_COMBINE_FACTOR_NONE
;
1168 fxMesa
->TexCombine
[1].InvertRGB
= FXFALSE
;
1169 fxMesa
->TexCombine
[1].InvertAlpha
= FXFALSE
;
1170 fxMesa
->TexCombine
[0].FunctionRGB
= GR_COMBINE_FUNCTION_BLEND_OTHER
;
1171 fxMesa
->TexCombine
[0].FactorRGB
= GR_COMBINE_FACTOR_LOCAL
;
1172 fxMesa
->TexCombine
[0].FunctionAlpha
= GR_COMBINE_FUNCTION_BLEND_OTHER
;
1173 fxMesa
->TexCombine
[0].FactorAlpha
= GR_COMBINE_FACTOR_ONE
;
1174 fxMesa
->TexCombine
[0].InvertRGB
= FXFALSE
;
1175 fxMesa
->TexCombine
[0].InvertAlpha
= FXFALSE
;
1178 fxMesa
->ColorCombine
.Function
= GR_COMBINE_FUNCTION_SCALE_OTHER
;
1179 fxMesa
->ColorCombine
.Factor
= GR_COMBINE_FACTOR_ONE
;
1180 fxMesa
->ColorCombine
.Local
= localc
;
1181 fxMesa
->ColorCombine
.Other
= GR_COMBINE_OTHER_TEXTURE
;
1182 fxMesa
->ColorCombine
.Invert
= FXFALSE
;
1183 if (baseFormat0
== GL_RGB
) {
1184 fxMesa
->AlphaCombine
.Function
= GR_COMBINE_FUNCTION_LOCAL
;
1185 fxMesa
->AlphaCombine
.Factor
= GR_COMBINE_FACTOR_NONE
;
1186 fxMesa
->AlphaCombine
.Local
= locala
;
1187 fxMesa
->AlphaCombine
.Other
= GR_COMBINE_OTHER_NONE
;
1188 fxMesa
->AlphaCombine
.Invert
= FXFALSE
;
1191 fxMesa
->AlphaCombine
.Function
= GR_COMBINE_FUNCTION_SCALE_OTHER
;
1192 fxMesa
->AlphaCombine
.Factor
= GR_COMBINE_FACTOR_ONE
;
1193 fxMesa
->AlphaCombine
.Local
= locala
;
1194 fxMesa
->AlphaCombine
.Other
= GR_COMBINE_OTHER_NONE
;
1195 fxMesa
->AlphaCombine
.Invert
= FXFALSE
;
1198 else if (envMode0
== GL_MODULATE
&& envMode1
== GL_ADD
) {
1200 GLboolean isalpha
[TDFX_NUM_TMU
];
1202 isalpha
[tmu0
] = (baseFormat0
== GL_ALPHA
);
1203 isalpha
[tmu1
] = (baseFormat1
== GL_ALPHA
);
1205 if (isalpha
[TDFX_TMU1
]) {
1206 fxMesa
->TexCombine
[1].FunctionRGB
= GR_COMBINE_FUNCTION_ZERO
;
1207 fxMesa
->TexCombine
[1].FactorRGB
= GR_COMBINE_FACTOR_NONE
;
1208 fxMesa
->TexCombine
[1].FunctionAlpha
= GR_COMBINE_FUNCTION_LOCAL
;
1209 fxMesa
->TexCombine
[1].FactorAlpha
= GR_COMBINE_FACTOR_NONE
;
1210 fxMesa
->TexCombine
[1].InvertRGB
= FXTRUE
;
1211 fxMesa
->TexCombine
[1].InvertAlpha
= FXFALSE
;
1214 fxMesa
->TexCombine
[1].FunctionRGB
= GR_COMBINE_FUNCTION_LOCAL
;
1215 fxMesa
->TexCombine
[1].FactorRGB
= GR_COMBINE_FACTOR_NONE
;
1216 fxMesa
->TexCombine
[1].FunctionAlpha
= GR_COMBINE_FUNCTION_LOCAL
;
1217 fxMesa
->TexCombine
[1].FactorAlpha
= GR_COMBINE_FACTOR_NONE
;
1218 fxMesa
->TexCombine
[1].InvertRGB
= FXFALSE
;
1219 fxMesa
->TexCombine
[1].InvertAlpha
= FXFALSE
;
1221 if (isalpha
[TDFX_TMU0
]) {
1222 fxMesa
->TexCombine
[0].FunctionRGB
= GR_COMBINE_FUNCTION_SCALE_OTHER
;
1223 fxMesa
->TexCombine
[0].FactorRGB
= GR_COMBINE_FACTOR_ONE
;
1224 fxMesa
->TexCombine
[0].FunctionAlpha
= GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL
;
1225 fxMesa
->TexCombine
[0].FactorAlpha
= GR_COMBINE_FACTOR_ONE
;
1226 fxMesa
->TexCombine
[0].InvertRGB
= FXFALSE
;
1227 fxMesa
->TexCombine
[0].InvertAlpha
= FXFALSE
;
1230 fxMesa
->TexCombine
[0].FunctionRGB
= GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL
;
1231 fxMesa
->TexCombine
[0].FactorRGB
= GR_COMBINE_FACTOR_ONE
;
1232 fxMesa
->TexCombine
[0].FunctionAlpha
= GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL
;
1233 fxMesa
->TexCombine
[0].FactorAlpha
= GR_COMBINE_FACTOR_ONE
;
1234 fxMesa
->TexCombine
[0].InvertRGB
= FXFALSE
;
1235 fxMesa
->TexCombine
[0].InvertAlpha
= FXFALSE
;
1237 fxMesa
->ColorCombine
.Function
= GR_COMBINE_FUNCTION_SCALE_OTHER
;
1238 fxMesa
->ColorCombine
.Factor
= GR_COMBINE_FACTOR_LOCAL
;
1239 fxMesa
->ColorCombine
.Local
= localc
;
1240 fxMesa
->ColorCombine
.Other
= GR_COMBINE_OTHER_TEXTURE
;
1241 fxMesa
->ColorCombine
.Invert
= FXFALSE
;
1242 fxMesa
->AlphaCombine
.Function
= GR_COMBINE_FUNCTION_SCALE_OTHER
;
1243 fxMesa
->AlphaCombine
.Factor
= GR_COMBINE_FACTOR_LOCAL
;
1244 fxMesa
->AlphaCombine
.Local
= locala
;
1245 fxMesa
->AlphaCombine
.Other
= GR_COMBINE_OTHER_TEXTURE
;
1246 fxMesa
->AlphaCombine
.Invert
= FXFALSE
;
1248 else if (envMode0
== GL_REPLACE
&& envMode1
== GL_ADD
) {
1250 GLboolean isalpha
[TDFX_NUM_TMU
];
1252 isalpha
[tmu0
] = (baseFormat0
== GL_ALPHA
);
1253 isalpha
[tmu1
] = (baseFormat1
== GL_ALPHA
);
1255 if (isalpha
[TDFX_TMU1
]) {
1256 fxMesa
->TexCombine
[1].FunctionRGB
= GR_COMBINE_FUNCTION_ZERO
;
1257 fxMesa
->TexCombine
[1].FactorRGB
= GR_COMBINE_FACTOR_NONE
;
1258 fxMesa
->TexCombine
[1].FunctionAlpha
= GR_COMBINE_FUNCTION_LOCAL
;
1259 fxMesa
->TexCombine
[1].FactorAlpha
= GR_COMBINE_FACTOR_NONE
;
1260 fxMesa
->TexCombine
[1].InvertRGB
= FXTRUE
;
1261 fxMesa
->TexCombine
[1].InvertAlpha
= FXFALSE
;
1263 fxMesa
->TexCombine
[1].FunctionRGB
= GR_COMBINE_FUNCTION_LOCAL
;
1264 fxMesa
->TexCombine
[1].FactorRGB
= GR_COMBINE_FACTOR_NONE
;
1265 fxMesa
->TexCombine
[1].FunctionAlpha
= GR_COMBINE_FUNCTION_LOCAL
;
1266 fxMesa
->TexCombine
[1].FactorAlpha
= GR_COMBINE_FACTOR_NONE
;
1267 fxMesa
->TexCombine
[1].InvertRGB
= FXFALSE
;
1268 fxMesa
->TexCombine
[1].InvertAlpha
= FXFALSE
;
1271 if (isalpha
[TDFX_TMU0
]) {
1272 fxMesa
->TexCombine
[0].FunctionRGB
= GR_COMBINE_FUNCTION_SCALE_OTHER
;
1273 fxMesa
->TexCombine
[0].FactorRGB
= GR_COMBINE_FACTOR_ONE
;
1274 fxMesa
->TexCombine
[0].FunctionAlpha
= GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL
;
1275 fxMesa
->TexCombine
[0].FactorAlpha
= GR_COMBINE_FACTOR_ONE
;
1276 fxMesa
->TexCombine
[0].InvertRGB
= FXFALSE
;
1277 fxMesa
->TexCombine
[0].InvertAlpha
= FXFALSE
;
1279 fxMesa
->TexCombine
[0].FunctionRGB
= GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL
;
1280 fxMesa
->TexCombine
[0].FactorRGB
= GR_COMBINE_FACTOR_ONE
;
1281 fxMesa
->TexCombine
[0].FunctionAlpha
= GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL
;
1282 fxMesa
->TexCombine
[0].FactorAlpha
= GR_COMBINE_FACTOR_ONE
;
1283 fxMesa
->TexCombine
[0].InvertRGB
= FXFALSE
;
1284 fxMesa
->TexCombine
[0].InvertAlpha
= FXFALSE
;
1287 fxMesa
->ColorCombine
.Function
= GR_COMBINE_FUNCTION_SCALE_OTHER
;
1288 fxMesa
->ColorCombine
.Factor
= GR_COMBINE_FACTOR_ONE
;
1289 fxMesa
->ColorCombine
.Local
= localc
;
1290 fxMesa
->ColorCombine
.Other
= GR_COMBINE_OTHER_TEXTURE
;
1291 fxMesa
->ColorCombine
.Invert
= FXFALSE
;
1292 fxMesa
->AlphaCombine
.Function
= GR_COMBINE_FUNCTION_SCALE_OTHER
;
1293 fxMesa
->AlphaCombine
.Factor
= GR_COMBINE_FACTOR_ONE
;
1294 fxMesa
->AlphaCombine
.Local
= locala
;
1295 fxMesa
->AlphaCombine
.Other
= GR_COMBINE_OTHER_TEXTURE
;
1296 fxMesa
->AlphaCombine
.Invert
= FXFALSE
;
1298 else if (envMode1
== GL_REPLACE
) {
1301 fxMesa
->TexCombine
[1].FunctionRGB
= GR_COMBINE_FUNCTION_ZERO
;
1302 fxMesa
->TexCombine
[1].FactorRGB
= GR_COMBINE_FACTOR_NONE
;
1303 fxMesa
->TexCombine
[1].FunctionAlpha
= GR_COMBINE_FUNCTION_ZERO
;
1304 fxMesa
->TexCombine
[1].FactorAlpha
= GR_COMBINE_FACTOR_NONE
;
1305 fxMesa
->TexCombine
[1].InvertRGB
= FXFALSE
;
1306 fxMesa
->TexCombine
[1].InvertAlpha
= FXFALSE
;
1308 fxMesa
->TexCombine
[0].FunctionRGB
= GR_COMBINE_FUNCTION_LOCAL
;
1309 fxMesa
->TexCombine
[0].FactorRGB
= GR_COMBINE_FACTOR_NONE
;
1310 fxMesa
->TexCombine
[0].FunctionAlpha
= GR_COMBINE_FUNCTION_LOCAL
;
1311 fxMesa
->TexCombine
[0].FactorAlpha
= GR_COMBINE_FACTOR_NONE
;
1312 fxMesa
->TexCombine
[0].InvertRGB
= FXFALSE
;
1313 fxMesa
->TexCombine
[0].InvertAlpha
= FXFALSE
;
1315 if ((baseFormat0
== GL_RGB
) && (baseFormat0
== GL_LUMINANCE
)) {
1316 fxMesa
->AlphaCombine
.Function
= GR_COMBINE_FUNCTION_LOCAL
;
1317 fxMesa
->AlphaCombine
.Factor
= GR_COMBINE_FACTOR_NONE
;
1318 fxMesa
->AlphaCombine
.Local
= locala
;
1319 fxMesa
->AlphaCombine
.Other
= GR_COMBINE_OTHER_NONE
;
1320 fxMesa
->AlphaCombine
.Invert
= FXFALSE
;
1322 fxMesa
->AlphaCombine
.Function
= GR_COMBINE_FUNCTION_SCALE_OTHER
;
1323 fxMesa
->AlphaCombine
.Factor
= GR_COMBINE_FACTOR_ONE
;
1324 fxMesa
->AlphaCombine
.Local
= locala
;
1325 fxMesa
->AlphaCombine
.Other
= GR_COMBINE_OTHER_TEXTURE
;
1326 fxMesa
->AlphaCombine
.Invert
= FXFALSE
;
1328 if (baseFormat0
== GL_ALPHA
) {
1329 fxMesa
->ColorCombine
.Function
= GR_COMBINE_FUNCTION_LOCAL
;
1330 fxMesa
->ColorCombine
.Factor
= GR_COMBINE_FACTOR_NONE
;
1331 fxMesa
->ColorCombine
.Local
= localc
;
1332 fxMesa
->ColorCombine
.Other
= GR_COMBINE_OTHER_NONE
;
1333 fxMesa
->ColorCombine
.Invert
= FXFALSE
;
1335 fxMesa
->ColorCombine
.Function
= GR_COMBINE_FUNCTION_SCALE_OTHER
;
1336 fxMesa
->ColorCombine
.Factor
= GR_COMBINE_FACTOR_ONE
;
1337 fxMesa
->ColorCombine
.Local
= localc
;
1338 fxMesa
->ColorCombine
.Other
= GR_COMBINE_OTHER_TEXTURE
;
1339 fxMesa
->ColorCombine
.Invert
= FXFALSE
;
1343 _mesa_problem(ctx
, "%s: Unexpected dual texture mode encountered", __FUNCTION__
);
1347 fxMesa
->dirty
|= TDFX_UPLOAD_TEXTURE_ENV
;
1348 fxMesa
->dirty
|= TDFX_UPLOAD_COLOR_COMBINE
;
1349 fxMesa
->dirty
|= TDFX_UPLOAD_ALPHA_COMBINE
;
1355 * This function makes sure that the correct mipmap levels are loaded
1356 * in the right places in memory and then makes the Glide calls to
1357 * setup the texture source pointers.
1360 setupSingleTMU(tdfxContextPtr fxMesa
, struct gl_texture_object
*tObj
)
1362 struct tdfxSharedState
*shared
= (struct tdfxSharedState
*) fxMesa
->glCtx
->Shared
->DriverData
;
1363 tdfxTexInfo
*ti
= TDFX_TEXTURE_DATA(tObj
);
1364 const GLcontext
*ctx
= fxMesa
->glCtx
;
1366 /* Make sure we're not loaded incorrectly */
1367 if (ti
->isInTM
&& !shared
->umaTexMemory
) {
1368 /* if doing filtering between mipmap levels, alternate mipmap levels
1369 * must be in alternate TMUs.
1372 if (ti
->whichTMU
!= TDFX_TMU_SPLIT
)
1373 tdfxTMMoveOutTM_NoLock(fxMesa
, tObj
);
1376 if (ti
->whichTMU
== TDFX_TMU_SPLIT
)
1377 tdfxTMMoveOutTM_NoLock(fxMesa
, tObj
);
1381 /* Make sure we're loaded correctly */
1383 /* Have to download the texture */
1384 if (shared
->umaTexMemory
) {
1385 tdfxTMMoveInTM_NoLock(fxMesa
, tObj
, TDFX_TMU0
);
1388 /* Voodoo3 (split texture memory) */
1390 tdfxTMMoveInTM_NoLock(fxMesa
, tObj
, TDFX_TMU_SPLIT
);
1394 /* XXX putting textures into the second memory bank when the
1395 * first bank is full is not working at this time.
1397 if (fxMesa
->haveTwoTMUs
) {
1398 GLint memReq
= fxMesa
->Glide
.grTexTextureMemRequired(
1399 GR_MIPMAPLEVELMASK_BOTH
, &(ti
->info
));
1400 if (shared
->freeTexMem
[TDFX_TMU0
] > memReq
) {
1401 tdfxTMMoveInTM_NoLock(fxMesa
, tObj
, TDFX_TMU0
);
1404 tdfxTMMoveInTM_NoLock(fxMesa
, tObj
, TDFX_TMU1
);
1410 tdfxTMMoveInTM_NoLock(fxMesa
, tObj
, TDFX_TMU0
);
1416 if (ti
->LODblend
&& ti
->whichTMU
== TDFX_TMU_SPLIT
) {
1417 /* mipmap levels split between texture banks */
1420 if (ti
->info
.format
== GR_TEXFMT_P_8
&& !ctx
->Texture
.SharedPalette
) {
1421 fxMesa
->TexPalette
.Type
= ti
->paltype
;
1422 fxMesa
->TexPalette
.Data
= &(ti
->palette
);
1423 fxMesa
->dirty
|= TDFX_UPLOAD_TEXTURE_PALETTE
;
1426 for (u
= 0; u
< 2; u
++) {
1427 fxMesa
->TexParams
[u
].sClamp
= ti
->sClamp
;
1428 fxMesa
->TexParams
[u
].tClamp
= ti
->tClamp
;
1429 fxMesa
->TexParams
[u
].minFilt
= ti
->minFilt
;
1430 fxMesa
->TexParams
[u
].magFilt
= ti
->magFilt
;
1431 fxMesa
->TexParams
[u
].mmMode
= ti
->mmMode
;
1432 fxMesa
->TexParams
[u
].LODblend
= ti
->LODblend
;
1433 fxMesa
->TexParams
[u
].LodBias
= ctx
->Texture
.Unit
[u
].LodBias
;
1435 fxMesa
->dirty
|= TDFX_UPLOAD_TEXTURE_PARAMS
;
1437 fxMesa
->TexSource
[0].StartAddress
= ti
->tm
[TDFX_TMU0
]->startAddr
;
1438 fxMesa
->TexSource
[0].EvenOdd
= GR_MIPMAPLEVELMASK_ODD
;
1439 fxMesa
->TexSource
[0].Info
= &(ti
->info
);
1440 fxMesa
->TexSource
[1].StartAddress
= ti
->tm
[TDFX_TMU1
]->startAddr
;
1441 fxMesa
->TexSource
[1].EvenOdd
= GR_MIPMAPLEVELMASK_EVEN
;
1442 fxMesa
->TexSource
[1].Info
= &(ti
->info
);
1443 fxMesa
->dirty
|= TDFX_UPLOAD_TEXTURE_SOURCE
;
1448 if (ti
->whichTMU
== TDFX_TMU_BOTH
)
1453 if (shared
->umaTexMemory
) {
1454 assert(ti
->whichTMU
== TDFX_TMU0
);
1455 assert(tmu
== TDFX_TMU0
);
1458 if (ti
->info
.format
== GR_TEXFMT_P_8
&& !ctx
->Texture
.SharedPalette
) {
1459 fxMesa
->TexPalette
.Type
= ti
->paltype
;
1460 fxMesa
->TexPalette
.Data
= &(ti
->palette
);
1461 fxMesa
->dirty
|= TDFX_UPLOAD_TEXTURE_PALETTE
;
1464 /* KW: The alternative is to do the download to the other tmu. If
1465 * we get to this point, I think it means we are thrashing the
1466 * texture memory, so perhaps it's not a good idea.
1469 if (fxMesa
->TexParams
[tmu
].sClamp
!= ti
->sClamp
||
1470 fxMesa
->TexParams
[tmu
].tClamp
!= ti
->tClamp
||
1471 fxMesa
->TexParams
[tmu
].minFilt
!= ti
->minFilt
||
1472 fxMesa
->TexParams
[tmu
].magFilt
!= ti
->magFilt
||
1473 fxMesa
->TexParams
[tmu
].mmMode
!= ti
->mmMode
||
1474 fxMesa
->TexParams
[tmu
].LODblend
!= FXFALSE
||
1475 fxMesa
->TexParams
[tmu
].LodBias
!= ctx
->Texture
.Unit
[tmu
].LodBias
) {
1476 fxMesa
->TexParams
[tmu
].sClamp
= ti
->sClamp
;
1477 fxMesa
->TexParams
[tmu
].tClamp
= ti
->tClamp
;
1478 fxMesa
->TexParams
[tmu
].minFilt
= ti
->minFilt
;
1479 fxMesa
->TexParams
[tmu
].magFilt
= ti
->magFilt
;
1480 fxMesa
->TexParams
[tmu
].mmMode
= ti
->mmMode
;
1481 fxMesa
->TexParams
[tmu
].LODblend
= FXFALSE
;
1482 fxMesa
->TexParams
[tmu
].LodBias
= ctx
->Texture
.Unit
[tmu
].LodBias
;
1483 fxMesa
->dirty
|= TDFX_UPLOAD_TEXTURE_PARAMS
;
1486 /* Glide texture source info */
1487 fxMesa
->TexSource
[0].Info
= NULL
;
1488 fxMesa
->TexSource
[1].Info
= NULL
;
1490 fxMesa
->TexSource
[tmu
].StartAddress
= ti
->tm
[tmu
]->startAddr
;
1491 fxMesa
->TexSource
[tmu
].EvenOdd
= GR_MIPMAPLEVELMASK_BOTH
;
1492 fxMesa
->TexSource
[tmu
].Info
= &(ti
->info
);
1493 fxMesa
->dirty
|= TDFX_UPLOAD_TEXTURE_SOURCE
;
1497 fxMesa
->sScale0
= ti
->sScale
;
1498 fxMesa
->tScale0
= ti
->tScale
;
1502 selectSingleTMUSrc(tdfxContextPtr fxMesa
, GLint tmu
, FxBool LODblend
)
1505 fxMesa
->TexCombine
[0].FunctionRGB
= GR_COMBINE_FUNCTION_BLEND
;
1506 fxMesa
->TexCombine
[0].FactorRGB
= GR_COMBINE_FACTOR_ONE_MINUS_LOD_FRACTION
;
1507 fxMesa
->TexCombine
[0].FunctionAlpha
= GR_COMBINE_FUNCTION_BLEND
;
1508 fxMesa
->TexCombine
[0].FactorAlpha
= GR_COMBINE_FACTOR_ONE_MINUS_LOD_FRACTION
;
1509 fxMesa
->TexCombine
[0].InvertRGB
= FXFALSE
;
1510 fxMesa
->TexCombine
[0].InvertAlpha
= FXFALSE
;
1512 if (fxMesa
->haveTwoTMUs
) {
1513 const struct gl_shared_state
*mesaShared
= fxMesa
->glCtx
->Shared
;
1514 const struct tdfxSharedState
*shared
= (struct tdfxSharedState
*) mesaShared
->DriverData
;
1517 if (shared
->umaTexMemory
)
1522 fxMesa
->TexCombine
[tmu
].FunctionRGB
= GR_COMBINE_FUNCTION_LOCAL
;
1523 fxMesa
->TexCombine
[tmu
].FactorRGB
= GR_COMBINE_FACTOR_NONE
;
1524 fxMesa
->TexCombine
[tmu
].FunctionAlpha
= GR_COMBINE_FUNCTION_LOCAL
;
1525 fxMesa
->TexCombine
[tmu
].FactorAlpha
= GR_COMBINE_FACTOR_NONE
;
1526 fxMesa
->TexCombine
[tmu
].InvertRGB
= FXFALSE
;
1527 fxMesa
->TexCombine
[tmu
].InvertAlpha
= FXFALSE
;
1529 fxMesa
->tmuSrc
= TDFX_TMU_SPLIT
;
1532 if (tmu
!= TDFX_TMU1
) {
1533 fxMesa
->TexCombine
[0].FunctionRGB
= GR_COMBINE_FUNCTION_LOCAL
;
1534 fxMesa
->TexCombine
[0].FactorRGB
= GR_COMBINE_FACTOR_NONE
;
1535 fxMesa
->TexCombine
[0].FunctionAlpha
= GR_COMBINE_FUNCTION_LOCAL
;
1536 fxMesa
->TexCombine
[0].FactorAlpha
= GR_COMBINE_FACTOR_NONE
;
1537 fxMesa
->TexCombine
[0].InvertRGB
= FXFALSE
;
1538 fxMesa
->TexCombine
[0].InvertAlpha
= FXFALSE
;
1539 if (fxMesa
->haveTwoTMUs
) {
1540 fxMesa
->TexCombine
[1].FunctionRGB
= GR_COMBINE_FUNCTION_ZERO
;
1541 fxMesa
->TexCombine
[1].FactorRGB
= GR_COMBINE_FACTOR_NONE
;
1542 fxMesa
->TexCombine
[1].FunctionAlpha
= GR_COMBINE_FUNCTION_ZERO
;
1543 fxMesa
->TexCombine
[1].FactorAlpha
= GR_COMBINE_FACTOR_NONE
;
1544 fxMesa
->TexCombine
[1].InvertRGB
= FXFALSE
;
1545 fxMesa
->TexCombine
[1].InvertAlpha
= FXFALSE
;
1547 fxMesa
->tmuSrc
= TDFX_TMU0
;
1550 fxMesa
->TexCombine
[1].FunctionRGB
= GR_COMBINE_FUNCTION_LOCAL
;
1551 fxMesa
->TexCombine
[1].FactorRGB
= GR_COMBINE_FACTOR_NONE
;
1552 fxMesa
->TexCombine
[1].FunctionAlpha
= GR_COMBINE_FUNCTION_LOCAL
;
1553 fxMesa
->TexCombine
[1].FactorAlpha
= GR_COMBINE_FACTOR_NONE
;
1554 fxMesa
->TexCombine
[1].InvertRGB
= FXFALSE
;
1555 fxMesa
->TexCombine
[1].InvertAlpha
= FXFALSE
;
1556 /* GR_COMBINE_FUNCTION_SCALE_OTHER doesn't work ?!? */
1557 fxMesa
->TexCombine
[0].FunctionRGB
= GR_COMBINE_FUNCTION_BLEND
;
1558 fxMesa
->TexCombine
[0].FactorRGB
= GR_COMBINE_FACTOR_ONE
;
1559 fxMesa
->TexCombine
[0].FunctionAlpha
= GR_COMBINE_FUNCTION_BLEND
;
1560 fxMesa
->TexCombine
[0].FactorAlpha
= GR_COMBINE_FACTOR_ONE
;
1561 fxMesa
->TexCombine
[0].InvertRGB
= FXFALSE
;
1562 fxMesa
->TexCombine
[0].InvertAlpha
= FXFALSE
;
1563 fxMesa
->tmuSrc
= TDFX_TMU1
;
1567 fxMesa
->dirty
|= TDFX_UPLOAD_TEXTURE_ENV
;
1571 static void print_state(tdfxContextPtr fxMesa
)
1573 GLcontext
*ctx
= fxMesa
->glCtx
;
1574 struct gl_texture_object
*tObj0
= ctx
->Texture
.Unit
[0]._Current
;
1575 struct gl_texture_object
*tObj1
= ctx
->Texture
.Unit
[1]._Current
;
1576 GLenum base0
= tObj0
->Image
[0][tObj0
->BaseLevel
] ? tObj0
->Image
[0][tObj0
->BaseLevel
]->Format
: 99;
1577 GLenum base1
= tObj1
->Image
[0][tObj1
->BaseLevel
] ? tObj1
->Image
[0][tObj1
->BaseLevel
]->Format
: 99;
1579 printf("Unit 0: Enabled: GL=%d Gr=%d\n", ctx
->Texture
.Unit
[0]._ReallyEnabled
,
1580 fxMesa
->TexState
.Enabled
[0]);
1581 printf(" EnvMode: GL=0x%x Gr=0x%x\n", ctx
->Texture
.Unit
[0].EnvMode
,
1582 fxMesa
->TexState
.EnvMode
[0]);
1583 printf(" BaseFmt: GL=0x%x Gr=0x%x\n", base0
, fxMesa
->TexState
.TexFormat
[0]);
1586 printf("Unit 1: Enabled: GL=%d Gr=%d\n", ctx
->Texture
.Unit
[1]._ReallyEnabled
,
1587 fxMesa
->TexState
.Enabled
[1]);
1588 printf(" EnvMode: GL=0x%x Gr:0x%x\n", ctx
->Texture
.Unit
[1].EnvMode
,
1589 fxMesa
->TexState
.EnvMode
[1]);
1590 printf(" BaseFmt: GL=0x%x Gr:0x%x\n", base1
, fxMesa
->TexState
.TexFormat
[1]);
1595 * When we're only using a single texture unit, we always use the 0th
1596 * Glide/hardware unit, regardless if it's GL_TEXTURE0_ARB or GL_TEXTURE1_ARB
1598 * Input: ctx - the context
1599 * unit - the OpenGL texture unit to use.
1601 static void setupTextureSingleTMU(GLcontext
* ctx
, GLuint unit
)
1603 tdfxContextPtr fxMesa
= TDFX_CONTEXT(ctx
);
1605 struct gl_texture_object
*tObj
;
1607 GLenum envMode
, baseFormat
;
1609 tObj
= ctx
->Texture
.Unit
[unit
]._Current
;
1610 if (tObj
->Image
[0][tObj
->BaseLevel
]->Border
> 0) {
1611 FALLBACK(fxMesa
, TDFX_FALLBACK_TEXTURE_BORDER
, GL_TRUE
);
1615 setupSingleTMU(fxMesa
, tObj
);
1617 ti
= TDFX_TEXTURE_DATA(tObj
);
1618 if (ti
->whichTMU
== TDFX_TMU_BOTH
)
1623 if (fxMesa
->tmuSrc
!= tmu
) {
1624 selectSingleTMUSrc(fxMesa
, tmu
, ti
->LODblend
);
1627 if (ti
->reloadImages
)
1628 fxMesa
->dirty
|= TDFX_UPLOAD_TEXTURE_IMAGES
;
1630 /* Check if we really need to update the texenv state */
1631 envMode
= ctx
->Texture
.Unit
[unit
].EnvMode
;
1632 baseFormat
= tObj
->Image
[0][tObj
->BaseLevel
]->Format
;
1634 if (TDFX_IS_NAPALM(fxMesa
)) {
1635 /* see if we really need to update the unit */
1636 if (1/*fxMesa->TexState.Enabled[unit] != ctx->Texture.Unit[unit]._ReallyEnabled ||
1637 envMode != fxMesa->TexState.EnvMode[0] ||
1638 envMode == GL_COMBINE_EXT ||
1639 baseFormat != fxMesa->TexState.TexFormat[0]*/) {
1640 struct tdfx_texcombine_ext
*otherEnv
;
1641 if (!SetupTexEnvNapalm(ctx
, GL_TRUE
,
1642 &ctx
->Texture
.Unit
[unit
], baseFormat
,
1643 &fxMesa
->TexCombineExt
[0])) {
1644 /* software fallback */
1645 FALLBACK(fxMesa
, TDFX_FALLBACK_TEXTURE_ENV
, GL_TRUE
);
1647 /* disable other unit */
1648 otherEnv
= &fxMesa
->TexCombineExt
[1];
1649 otherEnv
->Color
.SourceA
= GR_CMBX_ZERO
;
1650 otherEnv
->Color
.ModeA
= GR_FUNC_MODE_ZERO
;
1651 otherEnv
->Color
.SourceB
= GR_CMBX_ZERO
;
1652 otherEnv
->Color
.ModeB
= GR_FUNC_MODE_ZERO
;
1653 otherEnv
->Color
.SourceC
= GR_CMBX_ZERO
;
1654 otherEnv
->Color
.InvertC
= FXFALSE
;
1655 otherEnv
->Color
.SourceD
= GR_CMBX_ZERO
;
1656 otherEnv
->Color
.InvertD
= FXFALSE
;
1657 otherEnv
->Color
.Shift
= 0;
1658 otherEnv
->Color
.Invert
= FXFALSE
;
1659 otherEnv
->Alpha
.SourceA
= GR_CMBX_ITALPHA
;
1660 otherEnv
->Alpha
.ModeA
= GR_FUNC_MODE_ZERO
;
1661 otherEnv
->Alpha
.SourceB
= GR_CMBX_ITALPHA
;
1662 otherEnv
->Alpha
.ModeB
= GR_FUNC_MODE_ZERO
;
1663 otherEnv
->Alpha
.SourceC
= GR_CMBX_ZERO
;
1664 otherEnv
->Alpha
.InvertC
= FXFALSE
;
1665 otherEnv
->Alpha
.SourceD
= GR_CMBX_ZERO
;
1666 otherEnv
->Alpha
.InvertD
= FXFALSE
;
1667 otherEnv
->Alpha
.Shift
= 0;
1668 otherEnv
->Alpha
.Invert
= FXFALSE
;
1671 fxMesa
->TexState
.Enabled
[unit
] = ctx
->Texture
.Unit
[unit
]._ReallyEnabled
;
1672 fxMesa
->TexState
.EnvMode
[0] = envMode
;
1673 fxMesa
->TexState
.TexFormat
[0] = baseFormat
;
1674 fxMesa
->TexState
.EnvMode
[1] = 0;
1675 fxMesa
->TexState
.TexFormat
[1] = 0;
1682 /* see if we really need to update the unit */
1683 if (1/*fxMesa->TexState.Enabled[unit] != ctx->Texture.Unit[unit]._ReallyEnabled ||
1684 envMode != fxMesa->TexState.EnvMode[0] ||
1685 envMode == GL_COMBINE_EXT ||
1686 baseFormat != fxMesa->TexState.TexFormat[0]*/) {
1687 if (!SetupSingleTexEnvVoodoo3(ctx
, unit
, envMode
, baseFormat
)) {
1688 /* software fallback */
1689 FALLBACK(fxMesa
, TDFX_FALLBACK_TEXTURE_ENV
, GL_TRUE
);
1692 fxMesa
->TexState
.Enabled
[unit
] = ctx
->Texture
.Unit
[unit
]._ReallyEnabled
;
1693 fxMesa
->TexState
.EnvMode
[0] = envMode
;
1694 fxMesa
->TexState
.TexFormat
[0] = baseFormat
;
1695 fxMesa
->TexState
.EnvMode
[1] = 0;
1696 fxMesa
->TexState
.TexFormat
[1] = 0;
1704 setupDoubleTMU(tdfxContextPtr fxMesa
,
1705 struct gl_texture_object
*tObj0
,
1706 struct gl_texture_object
*tObj1
)
1708 #define T0_NOT_IN_TMU 0x01
1709 #define T1_NOT_IN_TMU 0x02
1710 #define T0_IN_TMU0 0x04
1711 #define T1_IN_TMU0 0x08
1712 #define T0_IN_TMU1 0x10
1713 #define T1_IN_TMU1 0x20
1715 const struct gl_shared_state
*mesaShared
= fxMesa
->glCtx
->Shared
;
1716 const struct tdfxSharedState
*shared
= (struct tdfxSharedState
*) mesaShared
->DriverData
;
1717 const GLcontext
*ctx
= fxMesa
->glCtx
;
1718 tdfxTexInfo
*ti0
= TDFX_TEXTURE_DATA(tObj0
);
1719 tdfxTexInfo
*ti1
= TDFX_TEXTURE_DATA(tObj1
);
1721 int tmu0
= 0, tmu1
= 1;
1723 if (shared
->umaTexMemory
) {
1725 tdfxTMMoveInTM_NoLock(fxMesa
, tObj0
, TDFX_TMU0
);
1726 assert(ti0
->isInTM
);
1729 tdfxTMMoveInTM_NoLock(fxMesa
, tObj1
, TDFX_TMU0
);
1730 assert(ti1
->isInTM
);
1734 /* We shouldn't need to do this. There is something wrong with
1735 multitexturing when the TMUs are swapped. So, we're forcing
1736 them to always be loaded correctly. !!! */
1737 if (ti0
->whichTMU
== TDFX_TMU1
)
1738 tdfxTMMoveOutTM_NoLock(fxMesa
, tObj0
);
1739 if (ti1
->whichTMU
== TDFX_TMU0
)
1740 tdfxTMMoveOutTM_NoLock(fxMesa
, tObj1
);
1743 switch (ti0
->whichTMU
) {
1745 tstate
|= T0_IN_TMU0
;
1748 tstate
|= T0_IN_TMU1
;
1751 tstate
|= T0_IN_TMU0
| T0_IN_TMU1
;
1753 case TDFX_TMU_SPLIT
:
1754 tstate
|= T0_NOT_IN_TMU
;
1759 tstate
|= T0_NOT_IN_TMU
;
1762 switch (ti1
->whichTMU
) {
1764 tstate
|= T1_IN_TMU0
;
1767 tstate
|= T1_IN_TMU1
;
1770 tstate
|= T1_IN_TMU0
| T1_IN_TMU1
;
1772 case TDFX_TMU_SPLIT
:
1773 tstate
|= T1_NOT_IN_TMU
;
1778 tstate
|= T1_NOT_IN_TMU
;
1780 /* Move texture maps into TMUs */
1782 if (!(((tstate
& T0_IN_TMU0
) && (tstate
& T1_IN_TMU1
)) ||
1783 ((tstate
& T0_IN_TMU1
) && (tstate
& T1_IN_TMU0
)))) {
1784 if (tObj0
== tObj1
) {
1785 tdfxTMMoveInTM_NoLock(fxMesa
, tObj1
, TDFX_TMU_BOTH
);
1788 /* Find the minimal way to correct the situation */
1789 if ((tstate
& T0_IN_TMU0
) || (tstate
& T1_IN_TMU1
)) {
1790 /* We have one in the standard order, setup the other */
1791 if (tstate
& T0_IN_TMU0
) {
1792 /* T0 is in TMU0, put T1 in TMU1 */
1793 tdfxTMMoveInTM_NoLock(fxMesa
, tObj1
, TDFX_TMU1
);
1796 tdfxTMMoveInTM_NoLock(fxMesa
, tObj0
, TDFX_TMU0
);
1798 /* tmu0 and tmu1 are setup */
1800 else if ((tstate
& T0_IN_TMU1
) || (tstate
& T1_IN_TMU0
)) {
1801 /* we have one in the reverse order, setup the other */
1802 if (tstate
& T1_IN_TMU0
) {
1803 /* T1 is in TMU0, put T0 in TMU1 */
1804 tdfxTMMoveInTM_NoLock(fxMesa
, tObj0
, TDFX_TMU1
);
1807 tdfxTMMoveInTM_NoLock(fxMesa
, tObj1
, TDFX_TMU0
);
1812 else { /* Nothing is loaded */
1813 tdfxTMMoveInTM_NoLock(fxMesa
, tObj0
, TDFX_TMU0
);
1814 tdfxTMMoveInTM_NoLock(fxMesa
, tObj1
, TDFX_TMU1
);
1815 /* tmu0 and tmu1 are setup */
1821 ti0
->lastTimeUsed
= fxMesa
->texBindNumber
;
1822 ti1
->lastTimeUsed
= fxMesa
->texBindNumber
;
1825 if (!ctx
->Texture
.SharedPalette
) {
1826 if (ti0
->info
.format
== GR_TEXFMT_P_8
) {
1827 fxMesa
->TexPalette
.Type
= ti0
->paltype
;
1828 fxMesa
->TexPalette
.Data
= &(ti0
->palette
);
1829 fxMesa
->dirty
|= TDFX_UPLOAD_TEXTURE_PALETTE
;
1831 else if (ti1
->info
.format
== GR_TEXFMT_P_8
) {
1832 fxMesa
->TexPalette
.Type
= ti1
->paltype
;
1833 fxMesa
->TexPalette
.Data
= &(ti1
->palette
);
1834 fxMesa
->dirty
|= TDFX_UPLOAD_TEXTURE_PALETTE
;
1837 fxMesa
->TexPalette
.Data
= NULL
;
1844 assert(ti0
->isInTM
);
1845 assert(ti0
->tm
[tmu0
]);
1846 fxMesa
->TexSource
[tmu0
].StartAddress
= ti0
->tm
[tmu0
]->startAddr
;
1847 fxMesa
->TexSource
[tmu0
].EvenOdd
= GR_MIPMAPLEVELMASK_BOTH
;
1848 fxMesa
->TexSource
[tmu0
].Info
= &(ti0
->info
);
1849 fxMesa
->dirty
|= TDFX_UPLOAD_TEXTURE_SOURCE
;
1851 if (fxMesa
->TexParams
[tmu0
].sClamp
!= ti0
->sClamp
||
1852 fxMesa
->TexParams
[tmu0
].tClamp
!= ti0
->tClamp
||
1853 fxMesa
->TexParams
[tmu0
].minFilt
!= ti0
->minFilt
||
1854 fxMesa
->TexParams
[tmu0
].magFilt
!= ti0
->magFilt
||
1855 fxMesa
->TexParams
[tmu0
].mmMode
!= ti0
->mmMode
||
1856 fxMesa
->TexParams
[tmu0
].LODblend
!= FXFALSE
||
1857 fxMesa
->TexParams
[tmu0
].LodBias
!= ctx
->Texture
.Unit
[tmu0
].LodBias
) {
1858 fxMesa
->TexParams
[tmu0
].sClamp
= ti0
->sClamp
;
1859 fxMesa
->TexParams
[tmu0
].tClamp
= ti0
->tClamp
;
1860 fxMesa
->TexParams
[tmu0
].minFilt
= ti0
->minFilt
;
1861 fxMesa
->TexParams
[tmu0
].magFilt
= ti0
->magFilt
;
1862 fxMesa
->TexParams
[tmu0
].mmMode
= ti0
->mmMode
;
1863 fxMesa
->TexParams
[tmu0
].LODblend
= FXFALSE
;
1864 fxMesa
->TexParams
[tmu0
].LodBias
= ctx
->Texture
.Unit
[tmu0
].LodBias
;
1865 fxMesa
->dirty
|= TDFX_UPLOAD_TEXTURE_PARAMS
;
1871 if (shared
->umaTexMemory
) {
1872 ASSERT(ti1
->isInTM
);
1874 fxMesa
->TexSource
[tmu1
].StartAddress
= ti1
->tm
[0]->startAddr
;
1875 fxMesa
->TexSource
[tmu1
].EvenOdd
= GR_MIPMAPLEVELMASK_BOTH
;
1876 fxMesa
->TexSource
[tmu1
].Info
= &(ti1
->info
);
1879 ASSERT(ti1
->isInTM
);
1880 ASSERT(ti1
->tm
[tmu1
]);
1881 fxMesa
->TexSource
[tmu1
].StartAddress
= ti1
->tm
[tmu1
]->startAddr
;
1882 fxMesa
->TexSource
[tmu1
].EvenOdd
= GR_MIPMAPLEVELMASK_BOTH
;
1883 fxMesa
->TexSource
[tmu1
].Info
= &(ti1
->info
);
1886 if (fxMesa
->TexParams
[tmu1
].sClamp
!= ti1
->sClamp
||
1887 fxMesa
->TexParams
[tmu1
].tClamp
!= ti1
->tClamp
||
1888 fxMesa
->TexParams
[tmu1
].minFilt
!= ti1
->minFilt
||
1889 fxMesa
->TexParams
[tmu1
].magFilt
!= ti1
->magFilt
||
1890 fxMesa
->TexParams
[tmu1
].mmMode
!= ti1
->mmMode
||
1891 fxMesa
->TexParams
[tmu1
].LODblend
!= FXFALSE
||
1892 fxMesa
->TexParams
[tmu1
].LodBias
!= ctx
->Texture
.Unit
[tmu1
].LodBias
) {
1893 fxMesa
->TexParams
[tmu1
].sClamp
= ti1
->sClamp
;
1894 fxMesa
->TexParams
[tmu1
].tClamp
= ti1
->tClamp
;
1895 fxMesa
->TexParams
[tmu1
].minFilt
= ti1
->minFilt
;
1896 fxMesa
->TexParams
[tmu1
].magFilt
= ti1
->magFilt
;
1897 fxMesa
->TexParams
[tmu1
].mmMode
= ti1
->mmMode
;
1898 fxMesa
->TexParams
[tmu1
].LODblend
= FXFALSE
;
1899 fxMesa
->TexParams
[tmu1
].LodBias
= ctx
->Texture
.Unit
[tmu1
].LodBias
;
1900 fxMesa
->dirty
|= TDFX_UPLOAD_TEXTURE_PARAMS
;
1903 fxMesa
->sScale0
= ti0
->sScale
;
1904 fxMesa
->tScale0
= ti0
->tScale
;
1905 fxMesa
->sScale1
= ti1
->sScale
;
1906 fxMesa
->tScale1
= ti1
->tScale
;
1908 #undef T0_NOT_IN_TMU
1909 #undef T1_NOT_IN_TMU
1916 static void setupTextureDoubleTMU(GLcontext
* ctx
)
1918 tdfxContextPtr fxMesa
= TDFX_CONTEXT(ctx
);
1919 struct gl_texture_object
*tObj0
= ctx
->Texture
.Unit
[1]._Current
;
1920 struct gl_texture_object
*tObj1
= ctx
->Texture
.Unit
[0]._Current
;
1921 tdfxTexInfo
*ti0
= TDFX_TEXTURE_DATA(tObj0
);
1922 tdfxTexInfo
*ti1
= TDFX_TEXTURE_DATA(tObj1
);
1923 struct gl_texture_image
*baseImage0
= tObj0
->Image
[0][tObj0
->BaseLevel
];
1924 struct gl_texture_image
*baseImage1
= tObj1
->Image
[0][tObj1
->BaseLevel
];
1925 const GLenum envMode0
= ctx
->Texture
.Unit
[0].EnvMode
;
1926 const GLenum envMode1
= ctx
->Texture
.Unit
[1].EnvMode
;
1928 if (baseImage0
->Border
> 0 || baseImage1
->Border
> 0) {
1929 FALLBACK(fxMesa
, TDFX_FALLBACK_TEXTURE_BORDER
, GL_TRUE
);
1933 setupDoubleTMU(fxMesa
, tObj0
, tObj1
);
1935 if (ti0
->reloadImages
|| ti1
->reloadImages
)
1936 fxMesa
->dirty
|= TDFX_UPLOAD_TEXTURE_IMAGES
;
1938 fxMesa
->tmuSrc
= TDFX_TMU_BOTH
;
1940 if (TDFX_IS_NAPALM(fxMesa
)) {
1941 /* Remember, Glide has its texture units numbered in backward
1942 * order compared to OpenGL.
1944 GLboolean hw1
= GL_TRUE
, hw2
= GL_TRUE
;
1946 /* check if we really need to update glide unit 1 */
1947 if (1/*fxMesa->TexState.Enabled[0] != ctx->Texture.Unit[0]._ReallyEnabled ||
1948 envMode0 != fxMesa->TexState.EnvMode[1] ||
1949 envMode0 == GL_COMBINE_EXT ||
1950 baseImage0->Format != fxMesa->TexState.TexFormat[1] ||
1951 (fxMesa->Fallback & TDFX_FALLBACK_TEXTURE_ENV)*/) {
1952 hw1
= SetupTexEnvNapalm(ctx
, GL_TRUE
, &ctx
->Texture
.Unit
[0],
1953 baseImage0
->Format
, &fxMesa
->TexCombineExt
[1]);
1955 fxMesa
->TexState
.EnvMode
[1] = envMode0
;
1956 fxMesa
->TexState
.TexFormat
[1] = baseImage0
->Format
;
1957 fxMesa
->TexState
.Enabled
[0] = ctx
->Texture
.Unit
[0]._ReallyEnabled
;
1961 /* check if we really need to update glide unit 0 */
1962 if (1/*fxMesa->TexState.Enabled[1] != ctx->Texture.Unit[1]._ReallyEnabled ||
1963 envMode1 != fxMesa->TexState.EnvMode[0] ||
1964 envMode1 == GL_COMBINE_EXT ||
1965 baseImage1->Format != fxMesa->TexState.TexFormat[0] ||
1966 (fxMesa->Fallback & TDFX_FALLBACK_TEXTURE_ENV)*/) {
1967 hw2
= SetupTexEnvNapalm(ctx
, GL_FALSE
, &ctx
->Texture
.Unit
[1],
1968 baseImage1
->Format
, &fxMesa
->TexCombineExt
[0]);
1970 fxMesa
->TexState
.EnvMode
[0] = envMode1
;
1971 fxMesa
->TexState
.TexFormat
[0] = baseImage1
->Format
;
1972 fxMesa
->TexState
.Enabled
[1] = ctx
->Texture
.Unit
[1]._ReallyEnabled
;
1978 FALLBACK(fxMesa
, TDFX_FALLBACK_TEXTURE_ENV
, GL_TRUE
);
1983 if ((ti0
->whichTMU
== TDFX_TMU1
) || (ti1
->whichTMU
== TDFX_TMU0
))
1989 if (1/*fxMesa->TexState.Enabled[0] != ctx->Texture.Unit[0]._ReallyEnabled ||
1990 fxMesa->TexState.Enabled[1] != ctx->Texture.Unit[1]._ReallyEnabled ||
1991 envMode0 != fxMesa->TexState.EnvMode[unit0] ||
1992 envMode0 == GL_COMBINE_EXT ||
1993 envMode1 != fxMesa->TexState.EnvMode[unit1] ||
1994 envMode1 == GL_COMBINE_EXT ||
1995 baseImage0->Format != fxMesa->TexState.TexFormat[unit0] ||
1996 baseImage1->Format != fxMesa->TexState.TexFormat[unit1] ||
1997 (fxMesa->Fallback & TDFX_FALLBACK_TEXTURE_ENV)*/) {
1999 if (!SetupDoubleTexEnvVoodoo3(ctx
, unit0
,
2000 ctx
->Texture
.Unit
[0].EnvMode
, baseImage0
->Format
,
2001 ctx
->Texture
.Unit
[1].EnvMode
, baseImage1
->Format
)) {
2002 FALLBACK(fxMesa
, TDFX_FALLBACK_TEXTURE_ENV
, GL_TRUE
);
2006 fxMesa
->TexState
.EnvMode
[unit0
] = envMode0
;
2007 fxMesa
->TexState
.TexFormat
[unit0
] = baseImage0
->Format
;
2008 fxMesa
->TexState
.EnvMode
[unit1
] = envMode1
;
2009 fxMesa
->TexState
.TexFormat
[unit1
] = baseImage1
->Format
;
2010 fxMesa
->TexState
.Enabled
[0] = ctx
->Texture
.Unit
[0]._ReallyEnabled
;
2011 fxMesa
->TexState
.Enabled
[1] = ctx
->Texture
.Unit
[1]._ReallyEnabled
;
2019 tdfxUpdateTextureState( GLcontext
*ctx
)
2021 tdfxContextPtr fxMesa
= TDFX_CONTEXT(ctx
);
2023 FALLBACK(fxMesa
, TDFX_FALLBACK_TEXTURE_BORDER
, GL_FALSE
);
2024 FALLBACK(fxMesa
, TDFX_FALLBACK_TEXTURE_ENV
, GL_FALSE
);
2026 if (ctx
->Texture
.Unit
[0]._ReallyEnabled
& (TEXTURE_1D_BIT
|TEXTURE_2D_BIT
) &&
2027 ctx
->Texture
.Unit
[1]._ReallyEnabled
== 0) {
2028 LOCK_HARDWARE( fxMesa
); /* XXX remove locking eventually */
2029 setupTextureSingleTMU(ctx
, 0);
2030 UNLOCK_HARDWARE( fxMesa
);
2032 else if (ctx
->Texture
.Unit
[0]._ReallyEnabled
== 0 &&
2033 ctx
->Texture
.Unit
[1]._ReallyEnabled
& (TEXTURE_1D_BIT
|TEXTURE_2D_BIT
)) {
2034 LOCK_HARDWARE( fxMesa
);
2035 setupTextureSingleTMU(ctx
, 1);
2036 UNLOCK_HARDWARE( fxMesa
);
2038 else if (ctx
->Texture
.Unit
[0]._ReallyEnabled
& (TEXTURE_1D_BIT
|TEXTURE_2D_BIT
) &&
2039 ctx
->Texture
.Unit
[1]._ReallyEnabled
& (TEXTURE_1D_BIT
|TEXTURE_2D_BIT
)) {
2040 LOCK_HARDWARE( fxMesa
);
2041 setupTextureDoubleTMU(ctx
);
2042 UNLOCK_HARDWARE( fxMesa
);
2045 /* disable hardware texturing */
2046 if (TDFX_IS_NAPALM(fxMesa
)) {
2047 fxMesa
->ColorCombineExt
.SourceA
= GR_CMBX_ITRGB
;
2048 fxMesa
->ColorCombineExt
.ModeA
= GR_FUNC_MODE_X
;
2049 fxMesa
->ColorCombineExt
.SourceB
= GR_CMBX_ZERO
;
2050 fxMesa
->ColorCombineExt
.ModeB
= GR_FUNC_MODE_ZERO
;
2051 fxMesa
->ColorCombineExt
.SourceC
= GR_CMBX_ZERO
;
2052 fxMesa
->ColorCombineExt
.InvertC
= FXTRUE
;
2053 fxMesa
->ColorCombineExt
.SourceD
= GR_CMBX_ZERO
;
2054 fxMesa
->ColorCombineExt
.InvertD
= FXFALSE
;
2055 fxMesa
->ColorCombineExt
.Shift
= 0;
2056 fxMesa
->ColorCombineExt
.Invert
= FXFALSE
;
2057 fxMesa
->AlphaCombineExt
.SourceA
= GR_CMBX_ITALPHA
;
2058 fxMesa
->AlphaCombineExt
.ModeA
= GR_FUNC_MODE_X
;
2059 fxMesa
->AlphaCombineExt
.SourceB
= GR_CMBX_ZERO
;
2060 fxMesa
->AlphaCombineExt
.ModeB
= GR_FUNC_MODE_ZERO
;
2061 fxMesa
->AlphaCombineExt
.SourceC
= GR_CMBX_ZERO
;
2062 fxMesa
->AlphaCombineExt
.InvertC
= FXTRUE
;
2063 fxMesa
->AlphaCombineExt
.SourceD
= GR_CMBX_ZERO
;
2064 fxMesa
->AlphaCombineExt
.InvertD
= FXFALSE
;
2065 fxMesa
->AlphaCombineExt
.Shift
= 0;
2066 fxMesa
->AlphaCombineExt
.Invert
= FXFALSE
;
2070 fxMesa
->ColorCombine
.Function
= GR_COMBINE_FUNCTION_LOCAL
;
2071 fxMesa
->ColorCombine
.Factor
= GR_COMBINE_FACTOR_NONE
;
2072 fxMesa
->ColorCombine
.Local
= GR_COMBINE_LOCAL_ITERATED
;
2073 fxMesa
->ColorCombine
.Other
= GR_COMBINE_OTHER_NONE
;
2074 fxMesa
->ColorCombine
.Invert
= FXFALSE
;
2075 fxMesa
->AlphaCombine
.Function
= GR_COMBINE_FUNCTION_LOCAL
;
2076 fxMesa
->AlphaCombine
.Factor
= GR_COMBINE_FACTOR_NONE
;
2077 fxMesa
->AlphaCombine
.Local
= GR_COMBINE_LOCAL_ITERATED
;
2078 fxMesa
->AlphaCombine
.Other
= GR_COMBINE_OTHER_NONE
;
2079 fxMesa
->AlphaCombine
.Invert
= FXFALSE
;
2082 fxMesa
->TexState
.Enabled
[0] = 0;
2083 fxMesa
->TexState
.Enabled
[1] = 0;
2084 fxMesa
->TexState
.EnvMode
[0] = 0;
2085 fxMesa
->TexState
.EnvMode
[1] = 0;
2087 fxMesa
->dirty
|= TDFX_UPLOAD_COLOR_COMBINE
;
2088 fxMesa
->dirty
|= TDFX_UPLOAD_ALPHA_COMBINE
;
2090 if (ctx
->Texture
.Unit
[0]._ReallyEnabled
!= 0 ||
2091 ctx
->Texture
.Unit
[1]._ReallyEnabled
!= 0) {
2092 /* software texture (cube map, rect tex, etc */
2093 FALLBACK(fxMesa
, TDFX_FALLBACK_TEXTURE_ENV
, GL_TRUE
);
2101 * This is a special case of texture state update.
2102 * It's used when we've simply bound a new texture to a texture
2103 * unit and the new texture has the exact same attributes as the
2104 * previously bound texture.
2105 * This is very common in Quake3.
2108 tdfxUpdateTextureBinding( GLcontext
*ctx
)
2110 tdfxContextPtr fxMesa
= TDFX_CONTEXT(ctx
);
2111 struct gl_texture_object
*tObj0
= ctx
->Texture
.Unit
[0]._Current
;
2112 struct gl_texture_object
*tObj1
= ctx
->Texture
.Unit
[1]._Current
;
2113 tdfxTexInfo
*ti0
= TDFX_TEXTURE_DATA(tObj0
);
2114 tdfxTexInfo
*ti1
= TDFX_TEXTURE_DATA(tObj1
);
2116 const struct gl_shared_state
*mesaShared
= fxMesa
->glCtx
->Shared
;
2117 const struct tdfxSharedState
*shared
= (struct tdfxSharedState
*) mesaShared
->DriverData
;
2120 fxMesa
->sScale0
= ti0
->sScale
;
2121 fxMesa
->tScale0
= ti0
->tScale
;
2122 if (ti0
->info
.format
== GR_TEXFMT_P_8
) {
2123 fxMesa
->TexPalette
.Type
= ti0
->paltype
;
2124 fxMesa
->TexPalette
.Data
= &(ti0
->palette
);
2125 fxMesa
->dirty
|= TDFX_UPLOAD_TEXTURE_PALETTE
;
2127 else if (ti1
&& ti1
->info
.format
== GR_TEXFMT_P_8
) {
2128 fxMesa
->TexPalette
.Type
= ti1
->paltype
;
2129 fxMesa
->TexPalette
.Data
= &(ti1
->palette
);
2130 fxMesa
->dirty
|= TDFX_UPLOAD_TEXTURE_PALETTE
;
2134 fxMesa
->sScale1
= ti1
->sScale
;
2135 fxMesa
->tScale1
= ti1
->tScale
;
2138 if (ctx
->Texture
.Unit
[0]._ReallyEnabled
& (TEXTURE_1D_BIT
|TEXTURE_2D_BIT
) &&
2139 ctx
->Texture
.Unit
[0]._ReallyEnabled
== 0) {
2140 /* Only unit 0 2D enabled */
2141 if (shared
->umaTexMemory
) {
2142 fxMesa
->TexSource
[0].StartAddress
= ti0
->tm
[0]->startAddr
;
2143 fxMesa
->TexSource
[0].EvenOdd
= GR_MIPMAPLEVELMASK_BOTH
;
2144 fxMesa
->TexSource
[0].Info
= &(ti0
->info
);
2147 if (ti0
->LODblend
&& ti0
->whichTMU
== TDFX_TMU_SPLIT
) {
2148 fxMesa
->TexSource
[0].StartAddress
= ti0
->tm
[TDFX_TMU0
]->startAddr
;
2149 fxMesa
->TexSource
[0].EvenOdd
= GR_MIPMAPLEVELMASK_ODD
;
2150 fxMesa
->TexSource
[0].Info
= &(ti0
->info
);
2151 fxMesa
->TexSource
[1].StartAddress
= ti0
->tm
[TDFX_TMU1
]->startAddr
;
2152 fxMesa
->TexSource
[1].EvenOdd
= GR_MIPMAPLEVELMASK_EVEN
;
2153 fxMesa
->TexSource
[1].Info
= &(ti0
->info
);
2157 if (ti0
->whichTMU
== TDFX_TMU_BOTH
)
2160 tmu
= ti0
->whichTMU
;
2161 fxMesa
->TexSource
[0].Info
= NULL
;
2162 fxMesa
->TexSource
[1].Info
= NULL
;
2164 fxMesa
->TexSource
[tmu
].StartAddress
= ti0
->tm
[tmu
]->startAddr
;
2165 fxMesa
->TexSource
[tmu
].EvenOdd
= GR_MIPMAPLEVELMASK_BOTH
;
2166 fxMesa
->TexSource
[tmu
].Info
= &(ti0
->info
);
2171 else if (ctx
->Texture
.Unit
[0]._ReallyEnabled
== 0 &&
2172 ctx
->Texture
.Unit
[0]._ReallyEnabled
& (TEXTURE_1D_BIT
|TEXTURE_2D_BIT
)) {
2173 /* Only unit 1 2D enabled */
2174 if (shared
->umaTexMemory
) {
2175 fxMesa
->TexSource
[0].StartAddress
= ti1
->tm
[0]->startAddr
;
2176 fxMesa
->TexSource
[0].EvenOdd
= GR_MIPMAPLEVELMASK_BOTH
;
2177 fxMesa
->TexSource
[0].Info
= &(ti1
->info
);
2180 else if (ctx
->Texture
.Unit
[0]._ReallyEnabled
& (TEXTURE_1D_BIT
|TEXTURE_2D_BIT
) &&
2181 ctx
->Texture
.Unit
[0]._ReallyEnabled
& (TEXTURE_1D_BIT
|TEXTURE_2D_BIT
)) {
2182 /* Both 2D enabled */
2183 if (shared
->umaTexMemory
) {
2184 const FxU32 tmu0
= 0, tmu1
= 1;
2185 fxMesa
->TexSource
[tmu0
].StartAddress
= ti0
->tm
[0]->startAddr
;
2186 fxMesa
->TexSource
[tmu0
].EvenOdd
= GR_MIPMAPLEVELMASK_BOTH
;
2187 fxMesa
->TexSource
[tmu0
].Info
= &(ti0
->info
);
2189 fxMesa
->TexSource
[tmu1
].StartAddress
= ti1
->tm
[0]->startAddr
;
2190 fxMesa
->TexSource
[tmu1
].EvenOdd
= GR_MIPMAPLEVELMASK_BOTH
;
2191 fxMesa
->TexSource
[tmu1
].Info
= &(ti1
->info
);
2194 const FxU32 tmu0
= 0, tmu1
= 1;
2195 fxMesa
->TexSource
[tmu0
].StartAddress
= ti0
->tm
[tmu0
]->startAddr
;
2196 fxMesa
->TexSource
[tmu0
].EvenOdd
= GR_MIPMAPLEVELMASK_BOTH
;
2197 fxMesa
->TexSource
[tmu0
].Info
= &(ti0
->info
);
2199 fxMesa
->TexSource
[tmu1
].StartAddress
= ti1
->tm
[tmu1
]->startAddr
;
2200 fxMesa
->TexSource
[tmu1
].EvenOdd
= GR_MIPMAPLEVELMASK_BOTH
;
2201 fxMesa
->TexSource
[tmu1
].Info
= &(ti1
->info
);
2206 fxMesa
->dirty
|= TDFX_UPLOAD_TEXTURE_SOURCE
;