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
29 * Daniel Borca <dborca@users.sourceforge.net>, 19 Jul 2004
32 * Gareth Hughes <gareth@valinux.com>, 29 Sep - 1 Oct 2000
35 * Gareth Hughes <gareth@valinux.com>
36 * Brian Paul <brianp@valinux.com>
40 #include "tdfx_state.h"
42 #include "tdfx_texman.h"
43 #include "tdfx_texstate.h"
46 /* =============================================================
51 * These macros are used below when handling COMBINE_EXT.
53 #define TEXENV_OPERAND_INVERTED(operand) \
54 (((operand) == GL_ONE_MINUS_SRC_ALPHA) \
55 || ((operand) == GL_ONE_MINUS_SRC_COLOR))
56 #define TEXENV_OPERAND_ALPHA(operand) \
57 (((operand) == GL_SRC_ALPHA) || ((operand) == GL_ONE_MINUS_SRC_ALPHA))
58 #define TEXENV_SETUP_ARG_A(param, source, operand, iteratedAlpha) \
61 param = GR_CMBX_LOCAL_TEXTURE_ALPHA; \
63 case GL_CONSTANT_EXT: \
64 param = GR_CMBX_TMU_CALPHA; \
66 case GL_PRIMARY_COLOR_EXT: \
67 param = GR_CMBX_ITALPHA; \
69 case GL_PREVIOUS_EXT: \
70 param = iteratedAlpha; \
74 * This is here just to keep from getting \
75 * compiler warnings. \
77 param = GR_CMBX_ZERO; \
81 #define TEXENV_SETUP_ARG_RGB(param, source, operand, iteratedColor, iteratedAlpha) \
82 if (!TEXENV_OPERAND_ALPHA(operand)) { \
85 param = GR_CMBX_LOCAL_TEXTURE_RGB; \
87 case GL_CONSTANT_EXT: \
88 param = GR_CMBX_TMU_CCOLOR; \
90 case GL_PRIMARY_COLOR_EXT: \
91 param = GR_CMBX_ITRGB; \
93 case GL_PREVIOUS_EXT: \
94 param = iteratedColor; \
98 * This is here just to keep from getting \
99 * compiler warnings. \
101 param = GR_CMBX_ZERO; \
107 param = GR_CMBX_LOCAL_TEXTURE_ALPHA; \
109 case GL_CONSTANT_EXT: \
110 param = GR_CMBX_TMU_CALPHA; \
112 case GL_PRIMARY_COLOR_EXT: \
113 param = GR_CMBX_ITALPHA; \
115 case GL_PREVIOUS_EXT: \
116 param = iteratedAlpha; \
120 * This is here just to keep from getting \
121 * compiler warnings. \
123 param = GR_CMBX_ZERO; \
128 #define TEXENV_SETUP_MODE_RGB(param, operand) \
132 param = GR_FUNC_MODE_X; \
134 case GL_ONE_MINUS_SRC_ALPHA: \
135 case GL_ONE_MINUS_SRC_COLOR: \
136 param = GR_FUNC_MODE_ONE_MINUS_X; \
139 param = GR_FUNC_MODE_ZERO; \
143 #define TEXENV_SETUP_MODE_A(param, operand) \
146 param = GR_FUNC_MODE_X; \
148 case GL_ONE_MINUS_SRC_ALPHA: \
149 param = GR_FUNC_MODE_ONE_MINUS_X; \
152 param = GR_FUNC_MODE_ZERO; \
159 * Setup a texture environment on Voodoo5.
160 * Return GL_TRUE for success, GL_FALSE for failure.
161 * If we fail, we'll have to use software rendering.
164 SetupTexEnvNapalm(GLcontext
*ctx
, GLboolean useIteratedRGBA
,
165 const struct gl_texture_unit
*texUnit
, GLenum baseFormat
,
166 struct tdfx_texcombine_ext
*env
)
168 tdfxContextPtr fxMesa
= TDFX_CONTEXT(ctx
);
169 GrTCCUColor_t incomingRGB
, incomingAlpha
;
170 const GLenum envMode
= texUnit
->EnvMode
;
172 if (useIteratedRGBA
) {
173 incomingRGB
= GR_CMBX_ITRGB
;
174 incomingAlpha
= GR_CMBX_ITALPHA
;
177 incomingRGB
= GR_CMBX_OTHER_TEXTURE_RGB
;
178 incomingAlpha
= GR_CMBX_OTHER_TEXTURE_ALPHA
;
182 env
->Color
.Shift
= 0;
183 env
->Color
.Invert
= FXFALSE
;
184 env
->Alpha
.Shift
= 0;
185 env
->Alpha
.Invert
= FXFALSE
;
189 /* -- Setup RGB combiner */
190 if (baseFormat
== GL_ALPHA
) {
192 env
->Color
.SourceA
= incomingRGB
;
196 env
->Color
.SourceA
= GR_CMBX_LOCAL_TEXTURE_RGB
;
198 env
->Color
.ModeA
= GR_FUNC_MODE_X
;
199 env
->Color
.SourceB
= GR_CMBX_ZERO
;
200 env
->Color
.ModeB
= GR_FUNC_MODE_ZERO
;
201 env
->Color
.SourceC
= GR_CMBX_ZERO
;
202 env
->Color
.InvertC
= FXTRUE
;
203 env
->Color
.SourceD
= GR_CMBX_ZERO
;
204 env
->Color
.InvertD
= FXFALSE
;
205 /* -- Setup Alpha combiner */
206 if (baseFormat
== GL_LUMINANCE
|| baseFormat
== GL_RGB
) {
208 env
->Alpha
.SourceD
= incomingAlpha
;
212 env
->Alpha
.SourceD
= GR_CMBX_LOCAL_TEXTURE_ALPHA
;
214 env
->Alpha
.SourceA
= GR_CMBX_ITALPHA
;
215 env
->Alpha
.ModeA
= GR_FUNC_MODE_ZERO
;
216 env
->Alpha
.SourceB
= GR_CMBX_ITALPHA
;
217 env
->Alpha
.ModeB
= GR_FUNC_MODE_ZERO
;
218 env
->Alpha
.SourceC
= GR_CMBX_ZERO
;
219 env
->Alpha
.InvertC
= FXFALSE
;
220 env
->Alpha
.InvertD
= FXFALSE
;
224 /* -- Setup RGB combiner */
225 if (baseFormat
== GL_ALPHA
) {
227 env
->Color
.SourceC
= GR_CMBX_ZERO
;
228 env
->Color
.InvertC
= FXTRUE
;
231 /* Result = Frag * Tex */
232 env
->Color
.SourceC
= GR_CMBX_LOCAL_TEXTURE_RGB
;
233 env
->Color
.InvertC
= FXFALSE
;
235 env
->Color
.SourceA
= incomingRGB
;
236 env
->Color
.ModeA
= GR_FUNC_MODE_X
;
237 env
->Color
.SourceB
= GR_CMBX_ZERO
;
238 env
->Color
.ModeB
= GR_FUNC_MODE_ZERO
;
239 env
->Color
.SourceD
= GR_CMBX_ZERO
;
240 env
->Color
.InvertD
= FXFALSE
;
241 /* -- Setup Alpha combiner */
242 if (baseFormat
== GL_LUMINANCE
|| baseFormat
== GL_RGB
) {
244 env
->Alpha
.SourceA
= incomingAlpha
;
245 env
->Alpha
.SourceC
= GR_CMBX_ZERO
;
246 env
->Alpha
.InvertC
= FXTRUE
;
250 env
->Alpha
.SourceA
= GR_CMBX_LOCAL_TEXTURE_ALPHA
;
251 env
->Alpha
.SourceC
= incomingAlpha
;
252 env
->Alpha
.InvertC
= FXFALSE
;
254 env
->Alpha
.ModeA
= GR_FUNC_MODE_X
;
255 env
->Alpha
.SourceB
= GR_CMBX_ITALPHA
;
256 env
->Alpha
.ModeB
= GR_FUNC_MODE_ZERO
;
257 env
->Alpha
.SourceD
= GR_CMBX_ZERO
;
258 env
->Alpha
.InvertD
= FXFALSE
;
262 /* -- Setup RGB combiner */
263 if (baseFormat
== GL_RGB
) {
265 env
->Color
.SourceB
= GR_CMBX_ZERO
;
266 env
->Color
.ModeB
= GR_FUNC_MODE_X
;
267 env
->Color
.SourceC
= GR_CMBX_ZERO
;
268 env
->Color
.InvertC
= FXTRUE
;
269 env
->Color
.SourceD
= GR_CMBX_ZERO
;
270 env
->Color
.InvertD
= FXFALSE
;
273 /* Rv = Rf * (1 - At) + Rt * At */
274 env
->Color
.SourceB
= incomingRGB
;
275 env
->Color
.ModeB
= GR_FUNC_MODE_NEGATIVE_X
;
276 env
->Color
.SourceC
= GR_CMBX_LOCAL_TEXTURE_ALPHA
;
277 env
->Color
.InvertC
= FXFALSE
;
278 env
->Color
.SourceD
= GR_CMBX_B
;
279 env
->Color
.InvertD
= FXFALSE
;
281 env
->Color
.SourceA
= GR_CMBX_LOCAL_TEXTURE_RGB
;
282 env
->Color
.ModeA
= GR_FUNC_MODE_X
;
283 /* -- Setup Alpha combiner */
285 env
->Alpha
.SourceA
= incomingAlpha
;
286 env
->Alpha
.ModeA
= GR_FUNC_MODE_X
;
287 env
->Alpha
.SourceB
= GR_CMBX_ITALPHA
;
288 env
->Alpha
.ModeB
= GR_FUNC_MODE_ZERO
;
289 env
->Alpha
.SourceC
= GR_CMBX_ZERO
;
290 env
->Alpha
.InvertC
= FXTRUE
;
291 env
->Alpha
.SourceD
= GR_CMBX_ZERO
;
292 env
->Alpha
.InvertD
= FXFALSE
;
296 /* -- Setup RGB combiner */
297 if (baseFormat
== GL_ALPHA
) {
299 env
->Color
.SourceA
= incomingRGB
;
300 env
->Color
.ModeA
= GR_FUNC_MODE_X
;
301 env
->Color
.SourceB
= GR_CMBX_ZERO
;
302 env
->Color
.ModeB
= GR_FUNC_MODE_ZERO
;
303 env
->Color
.SourceC
= GR_CMBX_ZERO
;
304 env
->Color
.InvertC
= FXTRUE
;
305 env
->Color
.SourceD
= GR_CMBX_ZERO
;
306 env
->Color
.InvertD
= FXFALSE
;
309 /* Rv = Rf * (1 - Rt) + Rc * Rt */
310 env
->Color
.SourceA
= GR_CMBX_TMU_CCOLOR
;
311 env
->Color
.ModeA
= GR_FUNC_MODE_X
;
312 env
->Color
.SourceB
= incomingRGB
;
313 env
->Color
.ModeB
= GR_FUNC_MODE_NEGATIVE_X
;
314 env
->Color
.SourceC
= GR_CMBX_LOCAL_TEXTURE_RGB
;
315 env
->Color
.InvertC
= FXFALSE
;
316 env
->Color
.SourceD
= GR_CMBX_B
;
317 env
->Color
.InvertD
= FXFALSE
;
319 /* -- Setup Alpha combiner */
320 if (baseFormat
== GL_LUMINANCE
|| baseFormat
== GL_RGB
) {
322 env
->Alpha
.SourceA
= incomingAlpha
;
323 env
->Alpha
.ModeA
= GR_FUNC_MODE_X
;
324 env
->Alpha
.SourceB
= GR_CMBX_ZERO
;
325 env
->Alpha
.ModeB
= GR_FUNC_MODE_ZERO
;
326 env
->Alpha
.SourceC
= GR_CMBX_ZERO
;
327 env
->Alpha
.InvertC
= FXTRUE
;
328 env
->Alpha
.SourceD
= GR_CMBX_ZERO
;
329 env
->Alpha
.InvertD
= FXFALSE
;
331 else if (baseFormat
== GL_INTENSITY
) {
332 /* Av = Af * (1 - It) + Ac * It */
333 env
->Alpha
.SourceA
= GR_CMBX_TMU_CALPHA
;
334 env
->Alpha
.ModeA
= GR_FUNC_MODE_X
;
335 env
->Alpha
.SourceB
= incomingAlpha
;
336 env
->Alpha
.ModeB
= GR_FUNC_MODE_NEGATIVE_X
;
337 env
->Alpha
.SourceC
= GR_CMBX_LOCAL_TEXTURE_ALPHA
;
338 env
->Alpha
.InvertC
= FXFALSE
;
339 env
->Alpha
.SourceD
= GR_CMBX_B
;
340 env
->Alpha
.InvertD
= FXFALSE
;
344 env
->Alpha
.SourceA
= GR_CMBX_LOCAL_TEXTURE_ALPHA
;
345 env
->Alpha
.ModeA
= GR_FUNC_MODE_X
;
346 env
->Alpha
.SourceB
= GR_CMBX_ITALPHA
;
347 env
->Alpha
.ModeB
= GR_FUNC_MODE_ZERO
;
348 env
->Alpha
.SourceC
= incomingAlpha
;
349 env
->Alpha
.InvertC
= FXFALSE
;
350 env
->Alpha
.SourceD
= GR_CMBX_ZERO
;
351 env
->Alpha
.InvertD
= FXFALSE
;
353 /* Also have to set up the tex env constant color */
354 env
->EnvColor
= PACK_RGBA32(texUnit
->EnvColor
[0] * 255.0F
,
355 texUnit
->EnvColor
[1] * 255.0F
,
356 texUnit
->EnvColor
[2] * 255.0F
,
357 texUnit
->EnvColor
[3] * 255.0F
);
360 /* -- Setup RGB combiner */
361 if (baseFormat
== GL_ALPHA
) {
363 env
->Color
.SourceB
= GR_CMBX_ZERO
;
364 env
->Color
.ModeB
= GR_FUNC_MODE_ZERO
;
368 env
->Color
.SourceB
= GR_CMBX_LOCAL_TEXTURE_RGB
;
369 env
->Color
.ModeB
= GR_FUNC_MODE_X
;
371 env
->Color
.SourceA
= incomingRGB
;
372 env
->Color
.ModeA
= GR_FUNC_MODE_X
;
373 env
->Color
.SourceC
= GR_CMBX_ZERO
;
374 env
->Color
.InvertC
= FXTRUE
;
375 env
->Color
.SourceD
= GR_CMBX_ZERO
;
376 env
->Color
.InvertD
= FXFALSE
;
377 /* -- Setup Alpha combiner */
378 if (baseFormat
== GL_LUMINANCE
|| baseFormat
== GL_RGB
) {
380 env
->Alpha
.SourceA
= incomingAlpha
;
381 env
->Alpha
.SourceB
= GR_CMBX_ITALPHA
;
382 env
->Alpha
.ModeB
= GR_FUNC_MODE_ZERO
;
383 env
->Alpha
.SourceC
= GR_CMBX_ZERO
;
384 env
->Alpha
.InvertC
= FXTRUE
;
387 else if (baseFormat
== GL_INTENSITY
) {
389 env
->Alpha
.SourceA
= incomingAlpha
;
390 env
->Alpha
.SourceB
= GR_CMBX_LOCAL_TEXTURE_ALPHA
;
391 env
->Alpha
.ModeB
= GR_FUNC_MODE_X
;
392 env
->Alpha
.SourceC
= GR_CMBX_ZERO
;
393 env
->Alpha
.InvertC
= FXTRUE
;
397 env
->Alpha
.SourceA
= GR_CMBX_LOCAL_TEXTURE_ALPHA
;
398 env
->Alpha
.SourceB
= GR_CMBX_ITALPHA
;
399 env
->Alpha
.ModeB
= GR_FUNC_MODE_ZERO
;
400 env
->Alpha
.SourceC
= incomingAlpha
;
401 env
->Alpha
.InvertC
= FXFALSE
;
403 env
->Alpha
.ModeA
= GR_FUNC_MODE_X
;
404 env
->Alpha
.SourceD
= GR_CMBX_ZERO
;
405 env
->Alpha
.InvertD
= FXFALSE
;
410 FxU32 A_RGB
, B_RGB
, C_RGB
, D_RGB
;
411 FxU32 Amode_RGB
, Bmode_RGB
;
412 FxBool Cinv_RGB
, Dinv_RGB
, Ginv_RGB
;
414 FxU32 A_A
, B_A
, C_A
, D_A
;
415 FxU32 Amode_A
, Bmode_A
;
416 FxBool Cinv_A
, Dinv_A
, Ginv_A
;
421 * In the formulas below, we write:
422 * o "1(x)" for the identity function applied to x,
424 * o "0(x)" for the constant function 0, so
425 * 0(x) = 0 for all values of x.
427 * Calculate the color combination.
429 Shift_RGB
= texUnit
->Combine
.ScaleShiftRGB
;
430 Shift_A
= texUnit
->Combine
.ScaleShiftA
;
431 switch (texUnit
->Combine
.ModeRGB
) {
434 * The formula is: Arg0
435 * We implement this by the formula:
436 * (Arg0 + 0(0))*(1-0) + 0
438 TEXENV_SETUP_ARG_RGB(A_RGB
,
439 texUnit
->Combine
.SourceRGB
[0],
440 texUnit
->Combine
.OperandRGB
[0],
441 incomingRGB
, incomingAlpha
);
442 TEXENV_SETUP_MODE_RGB(Amode_RGB
,
443 texUnit
->Combine
.OperandRGB
[0]);
444 B_RGB
= C_RGB
= D_RGB
= GR_CMBX_ZERO
;
445 Bmode_RGB
= GR_FUNC_MODE_ZERO
;
447 Dinv_RGB
= Ginv_RGB
= FXFALSE
;
451 * The formula is: Arg0 * Arg1
453 * We implement this by the formula
454 * (Arg0 + 0(0)) * Arg1 + 0(0)
456 TEXENV_SETUP_ARG_RGB(A_RGB
,
457 texUnit
->Combine
.SourceRGB
[0],
458 texUnit
->Combine
.OperandRGB
[0],
459 incomingRGB
, incomingAlpha
);
460 TEXENV_SETUP_MODE_RGB(Amode_RGB
,
461 texUnit
->Combine
.OperandRGB
[0]);
462 B_RGB
= GR_CMBX_ZERO
;
463 Bmode_RGB
= GR_CMBX_ZERO
;
464 TEXENV_SETUP_ARG_RGB(C_RGB
,
465 texUnit
->Combine
.SourceRGB
[1],
466 texUnit
->Combine
.OperandRGB
[1],
467 incomingRGB
, incomingAlpha
);
468 Cinv_RGB
= TEXENV_OPERAND_INVERTED
469 (texUnit
->Combine
.OperandRGB
[1]);
470 D_RGB
= GR_CMBX_ZERO
;
471 Dinv_RGB
= Ginv_RGB
= FXFALSE
;
475 * The formula is Arg0 + Arg1
477 TEXENV_SETUP_ARG_RGB(A_RGB
,
478 texUnit
->Combine
.SourceRGB
[0],
479 texUnit
->Combine
.OperandRGB
[0],
480 incomingRGB
, incomingAlpha
);
481 TEXENV_SETUP_MODE_RGB(Amode_RGB
,
482 texUnit
->Combine
.OperandRGB
[0]);
483 TEXENV_SETUP_ARG_RGB(B_RGB
,
484 texUnit
->Combine
.SourceRGB
[1],
485 texUnit
->Combine
.OperandRGB
[1],
486 incomingRGB
, incomingAlpha
);
487 TEXENV_SETUP_MODE_RGB(Bmode_RGB
,
488 texUnit
->Combine
.OperandRGB
[1]);
489 C_RGB
= D_RGB
= GR_CMBX_ZERO
;
491 Dinv_RGB
= Ginv_RGB
= FXFALSE
;
493 case GL_ADD_SIGNED_EXT
:
495 * The formula is: Arg0 + Arg1 - 0.5.
496 * We compute this by calculating:
497 * (Arg0 - 1/2) + Arg1 if op0 is SRC_{COLOR,ALPHA}
498 * Arg0 + (Arg1 - 1/2) if op1 is SRC_{COLOR,ALPHA}
499 * If both op0 and op1 are ONE_MINUS_SRC_{COLOR,ALPHA}
500 * we cannot implement the formula properly.
502 TEXENV_SETUP_ARG_RGB(A_RGB
,
503 texUnit
->Combine
.SourceRGB
[0],
504 texUnit
->Combine
.OperandRGB
[0],
505 incomingRGB
, incomingAlpha
);
506 TEXENV_SETUP_ARG_RGB(B_RGB
,
507 texUnit
->Combine
.SourceRGB
[1],
508 texUnit
->Combine
.OperandRGB
[1],
509 incomingRGB
, incomingAlpha
);
510 if (!TEXENV_OPERAND_INVERTED(texUnit
->Combine
.OperandRGB
[0])) {
512 * A is not inverted. So, choose it.
514 Amode_RGB
= GR_FUNC_MODE_X_MINUS_HALF
;
515 if (!TEXENV_OPERAND_INVERTED
516 (texUnit
->Combine
.OperandRGB
[1])) {
517 Bmode_RGB
= GR_FUNC_MODE_X
;
520 Bmode_RGB
= GR_FUNC_MODE_ONE_MINUS_X
;
525 * A is inverted, so try to subtract 1/2
528 Amode_RGB
= GR_FUNC_MODE_ONE_MINUS_X
;
529 if (!TEXENV_OPERAND_INVERTED
530 (texUnit
->Combine
.OperandRGB
[1])) {
531 Bmode_RGB
= GR_FUNC_MODE_X_MINUS_HALF
;
535 * Both are inverted. This is the case
536 * we cannot handle properly. We just
537 * choose to not add the - 1/2.
539 Bmode_RGB
= GR_FUNC_MODE_ONE_MINUS_X
;
543 C_RGB
= D_RGB
= GR_CMBX_ZERO
;
545 Dinv_RGB
= Ginv_RGB
= FXFALSE
;
547 case GL_INTERPOLATE_EXT
:
549 * The formula is: Arg0 * Arg2 + Arg1 * (1 - Arg2).
550 * We compute this by the formula:
551 * (Arg0 - Arg1) * Arg2 + Arg1
552 * == Arg0 * Arg2 - Arg1 * Arg2 + Arg1
553 * == Arg0 * Arg2 + Arg1 * (1 - Arg2)
554 * However, if both Arg1 is ONE_MINUS_X, the HW does
555 * not support it properly.
557 TEXENV_SETUP_ARG_RGB(A_RGB
,
558 texUnit
->Combine
.SourceRGB
[0],
559 texUnit
->Combine
.OperandRGB
[0],
560 incomingRGB
, incomingAlpha
);
561 TEXENV_SETUP_MODE_RGB(Amode_RGB
,
562 texUnit
->Combine
.OperandRGB
[0]);
563 TEXENV_SETUP_ARG_RGB(B_RGB
,
564 texUnit
->Combine
.SourceRGB
[1],
565 texUnit
->Combine
.OperandRGB
[1],
566 incomingRGB
, incomingAlpha
);
567 if (TEXENV_OPERAND_INVERTED(texUnit
->Combine
.OperandRGB
[1])) {
569 * This case is wrong.
571 Bmode_RGB
= GR_FUNC_MODE_NEGATIVE_X
;
575 Bmode_RGB
= GR_FUNC_MODE_NEGATIVE_X
;
578 * The Source/Operand for the C value must
579 * specify some kind of alpha value.
581 TEXENV_SETUP_ARG_A(C_RGB
,
582 texUnit
->Combine
.SourceRGB
[2],
583 texUnit
->Combine
.OperandRGB
[2],
587 Dinv_RGB
= Ginv_RGB
= FXFALSE
;
591 * This is here mostly to keep from getting
592 * a compiler warning about these not being set.
593 * However, this should set all the texture values
596 A_RGB
= B_RGB
= C_RGB
= D_RGB
= GR_CMBX_ZERO
;
597 Amode_RGB
= Bmode_RGB
= GR_FUNC_MODE_X
;
598 Cinv_RGB
= Dinv_RGB
= Ginv_RGB
= FXFALSE
;
602 * Calculate the alpha combination.
604 switch (texUnit
->Combine
.ModeA
) {
607 * The formula is: Arg0
608 * We implement this by the formula:
609 * (Arg0 + 0(0))*(1-0) + 0
611 TEXENV_SETUP_ARG_A(A_A
,
612 texUnit
->Combine
.SourceA
[0],
613 texUnit
->Combine
.OperandA
[0],
615 TEXENV_SETUP_MODE_A(Amode_A
,
616 texUnit
->Combine
.OperandA
[0]);
617 B_A
= GR_CMBX_ITALPHA
;
618 Bmode_A
= GR_FUNC_MODE_ZERO
;
619 C_A
= D_A
= GR_CMBX_ZERO
;
621 Dinv_A
= Ginv_A
= FXFALSE
;
625 * The formula is: Arg0 * Arg1
627 * We implement this by the formula
628 * (Arg0 + 0(0)) * Arg1 + 0(0)
630 TEXENV_SETUP_ARG_A(A_A
,
631 texUnit
->Combine
.SourceA
[0],
632 texUnit
->Combine
.OperandA
[0],
634 TEXENV_SETUP_MODE_A(Amode_A
,
635 texUnit
->Combine
.OperandA
[0]);
637 Bmode_A
= GR_CMBX_ZERO
;
638 TEXENV_SETUP_ARG_A(C_A
,
639 texUnit
->Combine
.SourceA
[1],
640 texUnit
->Combine
.OperandA
[1],
642 Cinv_A
= TEXENV_OPERAND_INVERTED
643 (texUnit
->Combine
.OperandA
[1]);
645 Dinv_A
= Ginv_A
= FXFALSE
;
649 * The formula is Arg0 + Arg1
651 TEXENV_SETUP_ARG_A(A_A
,
652 texUnit
->Combine
.SourceA
[0],
653 texUnit
->Combine
.OperandA
[0],
655 TEXENV_SETUP_MODE_A(Amode_A
,
656 texUnit
->Combine
.OperandA
[0]);
657 TEXENV_SETUP_ARG_A(B_A
,
658 texUnit
->Combine
.SourceA
[1],
659 texUnit
->Combine
.OperandA
[1],
661 TEXENV_SETUP_MODE_A(Bmode_A
,
662 texUnit
->Combine
.OperandA
[1]);
663 C_A
= D_A
= GR_CMBX_ZERO
;
665 Dinv_A
= Ginv_A
= FXFALSE
;
667 case GL_ADD_SIGNED_EXT
:
669 * The formula is: Arg0 + Arg1 - 0.5.
670 * We compute this by calculating:
671 * (Arg0 - 1/2) + Arg1 if op0 is SRC_{COLOR,ALPHA}
672 * Arg0 + (Arg1 - 1/2) if op1 is SRC_{COLOR,ALPHA}
673 * If both op0 and op1 are ONE_MINUS_SRC_{COLOR,ALPHA}
674 * we cannot implement the formula properly.
676 TEXENV_SETUP_ARG_A(A_A
,
677 texUnit
->Combine
.SourceA
[0],
678 texUnit
->Combine
.OperandA
[0],
680 TEXENV_SETUP_ARG_A(B_A
,
681 texUnit
->Combine
.SourceA
[1],
682 texUnit
->Combine
.OperandA
[1],
684 if (!TEXENV_OPERAND_INVERTED(texUnit
->Combine
.OperandA
[0])) {
686 * A is not inverted. So, choose it.
688 Amode_A
= GR_FUNC_MODE_X_MINUS_HALF
;
689 if (!TEXENV_OPERAND_INVERTED
690 (texUnit
->Combine
.OperandA
[1])) {
691 Bmode_A
= GR_FUNC_MODE_X
;
693 Bmode_A
= GR_FUNC_MODE_ONE_MINUS_X
;
697 * A is inverted, so try to subtract 1/2
700 Amode_A
= GR_FUNC_MODE_ONE_MINUS_X
;
701 if (!TEXENV_OPERAND_INVERTED
702 (texUnit
->Combine
.OperandA
[1])) {
703 Bmode_A
= GR_FUNC_MODE_X_MINUS_HALF
;
706 * Both are inverted. This is the case
707 * we cannot handle properly. We just
708 * choose to not add the - 1/2.
710 Bmode_A
= GR_FUNC_MODE_ONE_MINUS_X
;
714 C_A
= D_A
= GR_CMBX_ZERO
;
716 Dinv_A
= Ginv_A
= FXFALSE
;
718 case GL_INTERPOLATE_EXT
:
720 * The formula is: Arg0 * Arg2 + Arg1 * (1 - Arg2).
721 * We compute this by the formula:
722 * (Arg0 - Arg1) * Arg2 + Arg1
723 * == Arg0 * Arg2 - Arg1 * Arg2 + Arg1
724 * == Arg0 * Arg2 + Arg1 * (1 - Arg2)
725 * However, if both Arg1 is ONE_MINUS_X, the HW does
726 * not support it properly.
728 TEXENV_SETUP_ARG_A(A_A
,
729 texUnit
->Combine
.SourceA
[0],
730 texUnit
->Combine
.OperandA
[0],
732 TEXENV_SETUP_MODE_A(Amode_A
,
733 texUnit
->Combine
.OperandA
[0]);
734 TEXENV_SETUP_ARG_A(B_A
,
735 texUnit
->Combine
.SourceA
[1],
736 texUnit
->Combine
.OperandA
[1],
738 if (!TEXENV_OPERAND_INVERTED(texUnit
->Combine
.OperandA
[1])) {
739 Bmode_A
= GR_FUNC_MODE_NEGATIVE_X
;
743 * This case is wrong.
745 Bmode_A
= GR_FUNC_MODE_NEGATIVE_X
;
749 * The Source/Operand for the C value must
750 * specify some kind of alpha value.
752 TEXENV_SETUP_ARG_A(C_A
,
753 texUnit
->Combine
.SourceA
[2],
754 texUnit
->Combine
.OperandA
[2],
758 Dinv_A
= Ginv_A
= FXFALSE
;
762 * This is here mostly to keep from getting
763 * a compiler warning about these not being set.
764 * However, this should set all the alpha values
767 A_A
= B_A
= C_A
= D_A
= GR_CMBX_ZERO
;
768 Amode_A
= Bmode_A
= GR_FUNC_MODE_X
;
769 Cinv_A
= Dinv_A
= FXFALSE
;
774 * Save the parameters.
776 env
->Color
.SourceA
= A_RGB
;
777 env
->Color
.ModeA
= Amode_RGB
;
778 env
->Color
.SourceB
= B_RGB
;
779 env
->Color
.ModeB
= Bmode_RGB
;
780 env
->Color
.SourceC
= C_RGB
;
781 env
->Color
.InvertC
= Cinv_RGB
;
782 env
->Color
.SourceD
= D_RGB
;
783 env
->Color
.InvertD
= Dinv_RGB
;
784 env
->Color
.Shift
= Shift_RGB
;
785 env
->Color
.Invert
= Ginv_RGB
;
786 env
->Alpha
.SourceA
= A_A
;
787 env
->Alpha
.ModeA
= Amode_A
;
788 env
->Alpha
.SourceB
= B_A
;
789 env
->Alpha
.ModeB
= Bmode_A
;
790 env
->Alpha
.SourceC
= C_A
;
791 env
->Alpha
.InvertC
= Cinv_A
;
792 env
->Alpha
.SourceD
= D_A
;
793 env
->Alpha
.InvertD
= Dinv_A
;
794 env
->Alpha
.Shift
= Shift_A
;
795 env
->Alpha
.Invert
= Ginv_A
;
796 env
->EnvColor
= PACK_RGBA32(texUnit
->EnvColor
[0] * 255.0F
,
797 texUnit
->EnvColor
[1] * 255.0F
,
798 texUnit
->EnvColor
[2] * 255.0F
,
799 texUnit
->EnvColor
[3] * 255.0F
);
804 _mesa_problem(ctx
, "%s: Bad envMode", __FUNCTION__
);
807 fxMesa
->dirty
|= TDFX_UPLOAD_TEXTURE_ENV
;
809 fxMesa
->ColorCombineExt
.SourceA
= GR_CMBX_TEXTURE_RGB
;
810 fxMesa
->ColorCombineExt
.ModeA
= GR_FUNC_MODE_X
,
811 fxMesa
->ColorCombineExt
.SourceB
= GR_CMBX_ZERO
;
812 fxMesa
->ColorCombineExt
.ModeB
= GR_FUNC_MODE_X
;
813 fxMesa
->ColorCombineExt
.SourceC
= GR_CMBX_ZERO
;
814 fxMesa
->ColorCombineExt
.InvertC
= FXTRUE
;
815 fxMesa
->ColorCombineExt
.SourceD
= GR_CMBX_ZERO
;
816 fxMesa
->ColorCombineExt
.InvertD
= FXFALSE
;
817 fxMesa
->ColorCombineExt
.Shift
= 0;
818 fxMesa
->ColorCombineExt
.Invert
= FXFALSE
;
819 fxMesa
->dirty
|= TDFX_UPLOAD_COLOR_COMBINE
;
820 fxMesa
->AlphaCombineExt
.SourceA
= GR_CMBX_TEXTURE_ALPHA
;
821 fxMesa
->AlphaCombineExt
.ModeA
= GR_FUNC_MODE_X
;
822 fxMesa
->AlphaCombineExt
.SourceB
= GR_CMBX_ZERO
;
823 fxMesa
->AlphaCombineExt
.ModeB
= GR_FUNC_MODE_X
;
824 fxMesa
->AlphaCombineExt
.SourceC
= GR_CMBX_ZERO
;
825 fxMesa
->AlphaCombineExt
.InvertC
= FXTRUE
;
826 fxMesa
->AlphaCombineExt
.SourceD
= GR_CMBX_ZERO
;
827 fxMesa
->AlphaCombineExt
.InvertD
= FXFALSE
;
828 fxMesa
->AlphaCombineExt
.Shift
= 0;
829 fxMesa
->AlphaCombineExt
.Invert
= FXFALSE
;
830 fxMesa
->dirty
|= TDFX_UPLOAD_ALPHA_COMBINE
;
831 return GL_TRUE
; /* success */
837 * Setup the Voodoo3 texture environment for a single texture unit.
838 * Return GL_TRUE for success, GL_FALSE for failure.
839 * If failure, we'll use software rendering.
842 SetupSingleTexEnvVoodoo3(GLcontext
*ctx
, int unit
,
843 GLenum envMode
, GLenum baseFormat
)
845 tdfxContextPtr fxMesa
= TDFX_CONTEXT(ctx
);
846 GrCombineLocal_t localc
, locala
;
847 struct tdfx_combine alphaComb
, colorComb
;
849 if (1 /*iteratedRGBA*/)
850 localc
= locala
= GR_COMBINE_LOCAL_ITERATED
;
852 localc
= locala
= GR_COMBINE_LOCAL_CONSTANT
;
856 alphaComb
.Function
= GR_COMBINE_FUNCTION_LOCAL
;
857 alphaComb
.Factor
= GR_COMBINE_FACTOR_NONE
;
858 alphaComb
.Local
= locala
;
859 alphaComb
.Other
= GR_COMBINE_OTHER_NONE
;
860 alphaComb
.Invert
= FXFALSE
;
861 colorComb
.Function
= GR_COMBINE_FUNCTION_BLEND
;
862 colorComb
.Factor
= GR_COMBINE_FACTOR_TEXTURE_ALPHA
;
863 colorComb
.Local
= localc
;
864 colorComb
.Other
= GR_COMBINE_OTHER_TEXTURE
;
865 colorComb
.Invert
= FXFALSE
;
868 alphaComb
.Function
= GR_COMBINE_FUNCTION_SCALE_OTHER
;
869 alphaComb
.Factor
= GR_COMBINE_FACTOR_LOCAL
;
870 alphaComb
.Local
= locala
;
871 alphaComb
.Other
= GR_COMBINE_OTHER_TEXTURE
;
872 alphaComb
.Invert
= FXFALSE
;
873 if (baseFormat
== GL_ALPHA
) {
874 colorComb
.Function
= GR_COMBINE_FUNCTION_LOCAL
;
875 colorComb
.Factor
= GR_COMBINE_FACTOR_NONE
;
876 colorComb
.Local
= localc
;
877 colorComb
.Other
= GR_COMBINE_OTHER_NONE
;
878 colorComb
.Invert
= FXFALSE
;
881 colorComb
.Function
= GR_COMBINE_FUNCTION_SCALE_OTHER
;
882 colorComb
.Factor
= GR_COMBINE_FACTOR_LOCAL
;
883 colorComb
.Local
= localc
;
884 colorComb
.Other
= GR_COMBINE_OTHER_TEXTURE
;
885 colorComb
.Invert
= FXFALSE
;
891 * XXX we can't do real GL_BLEND mode. These settings assume that
892 * the TexEnv color is black and incoming fragment color is white.
894 if (baseFormat
== GL_LUMINANCE
|| baseFormat
== GL_RGB
) {
896 alphaComb
.Function
= GR_COMBINE_FUNCTION_LOCAL
;
897 alphaComb
.Factor
= GR_COMBINE_FACTOR_NONE
;
898 alphaComb
.Local
= locala
;
899 alphaComb
.Other
= GR_COMBINE_OTHER_NONE
;
900 alphaComb
.Invert
= FXFALSE
;
902 else if (baseFormat
== GL_INTENSITY
) {
903 /* Av = Af * (1 - It) + Ac * It */
904 alphaComb
.Function
= GR_COMBINE_FUNCTION_BLEND
;
905 alphaComb
.Factor
= GR_COMBINE_FACTOR_TEXTURE_ALPHA
;
906 alphaComb
.Local
= locala
;
907 alphaComb
.Other
= GR_COMBINE_OTHER_CONSTANT
;
908 alphaComb
.Invert
= FXFALSE
;
912 alphaComb
.Function
= GR_COMBINE_FUNCTION_SCALE_OTHER
;
913 alphaComb
.Factor
= GR_COMBINE_FACTOR_LOCAL
;
914 alphaComb
.Local
= locala
;
915 alphaComb
.Other
= GR_COMBINE_OTHER_TEXTURE
;
916 alphaComb
.Invert
= FXFALSE
;
918 if (baseFormat
== GL_ALPHA
) {
919 colorComb
.Function
= GR_COMBINE_FUNCTION_LOCAL
;
920 colorComb
.Factor
= GR_COMBINE_FACTOR_NONE
;
921 colorComb
.Local
= localc
;
922 colorComb
.Other
= GR_COMBINE_OTHER_NONE
;
923 colorComb
.Invert
= FXFALSE
;
926 colorComb
.Function
= GR_COMBINE_FUNCTION_BLEND
;
927 colorComb
.Factor
= GR_COMBINE_FACTOR_TEXTURE_RGB
;
928 colorComb
.Local
= localc
;
929 colorComb
.Other
= GR_COMBINE_OTHER_CONSTANT
;
930 colorComb
.Invert
= FXTRUE
;
932 fxMesa
->Color
.MonoColor
= PACK_RGBA32(
933 ctx
->Texture
.Unit
[unit
].EnvColor
[0] * 255.0f
,
934 ctx
->Texture
.Unit
[unit
].EnvColor
[1] * 255.0f
,
935 ctx
->Texture
.Unit
[unit
].EnvColor
[2] * 255.0f
,
936 ctx
->Texture
.Unit
[unit
].EnvColor
[3] * 255.0f
);
937 fxMesa
->dirty
|= TDFX_UPLOAD_CONSTANT_COLOR
;
941 if ((baseFormat
== GL_RGB
) || (baseFormat
== GL_LUMINANCE
)) {
942 alphaComb
.Function
= GR_COMBINE_FUNCTION_LOCAL
;
943 alphaComb
.Factor
= GR_COMBINE_FACTOR_NONE
;
944 alphaComb
.Local
= locala
;
945 alphaComb
.Other
= GR_COMBINE_OTHER_NONE
;
946 alphaComb
.Invert
= FXFALSE
;
949 alphaComb
.Function
= GR_COMBINE_FUNCTION_SCALE_OTHER
;
950 alphaComb
.Factor
= GR_COMBINE_FACTOR_ONE
;
951 alphaComb
.Local
= locala
;
952 alphaComb
.Other
= GR_COMBINE_OTHER_TEXTURE
;
953 alphaComb
.Invert
= FXFALSE
;
955 if (baseFormat
== GL_ALPHA
) {
956 colorComb
.Function
= GR_COMBINE_FUNCTION_LOCAL
;
957 colorComb
.Factor
= GR_COMBINE_FACTOR_NONE
;
958 colorComb
.Local
= localc
;
959 colorComb
.Other
= GR_COMBINE_OTHER_NONE
;
960 colorComb
.Invert
= FXFALSE
;
963 colorComb
.Function
= GR_COMBINE_FUNCTION_SCALE_OTHER
;
964 colorComb
.Factor
= GR_COMBINE_FACTOR_ONE
;
965 colorComb
.Local
= localc
;
966 colorComb
.Other
= GR_COMBINE_OTHER_TEXTURE
;
967 colorComb
.Invert
= FXFALSE
;
972 if (baseFormat
== GL_ALPHA
||
973 baseFormat
== GL_LUMINANCE_ALPHA
||
974 baseFormat
== GL_RGBA
) {
975 /* product of texel and fragment alpha */
976 alphaComb
.Function
= GR_COMBINE_FUNCTION_SCALE_OTHER
;
977 alphaComb
.Factor
= GR_COMBINE_FACTOR_LOCAL
;
978 alphaComb
.Local
= locala
;
979 alphaComb
.Other
= GR_COMBINE_OTHER_TEXTURE
;
980 alphaComb
.Invert
= FXFALSE
;
982 else if (baseFormat
== GL_LUMINANCE
|| baseFormat
== GL_RGB
) {
983 /* fragment alpha is unchanged */
984 alphaComb
.Function
= GR_COMBINE_FUNCTION_LOCAL
;
985 alphaComb
.Factor
= GR_COMBINE_FACTOR_NONE
;
986 alphaComb
.Local
= locala
;
987 alphaComb
.Other
= GR_COMBINE_OTHER_NONE
;
988 alphaComb
.Invert
= FXFALSE
;
991 ASSERT(baseFormat
== GL_INTENSITY
);
992 /* sum of texel and fragment alpha */
993 alphaComb
.Function
= GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL
,
994 alphaComb
.Factor
= GR_COMBINE_FACTOR_ONE
;
995 alphaComb
.Local
= locala
;
996 alphaComb
.Other
= GR_COMBINE_OTHER_TEXTURE
;
997 alphaComb
.Invert
= FXFALSE
;
999 if (baseFormat
== GL_ALPHA
) {
1001 colorComb
.Function
= GR_COMBINE_FUNCTION_LOCAL
;
1002 colorComb
.Factor
= GR_COMBINE_FACTOR_NONE
;
1003 colorComb
.Local
= localc
;
1004 colorComb
.Other
= GR_COMBINE_OTHER_NONE
;
1005 colorComb
.Invert
= FXFALSE
;
1008 /* sum of texel and fragment rgb */
1009 colorComb
.Function
= GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL
,
1010 colorComb
.Factor
= GR_COMBINE_FACTOR_ONE
;
1011 colorComb
.Local
= localc
;
1012 colorComb
.Other
= GR_COMBINE_OTHER_TEXTURE
;
1013 colorComb
.Invert
= FXFALSE
;
1018 (void) memcpy(&colorComb
, &fxMesa
->ColorCombine
, sizeof(colorComb
));
1019 (void) memcpy(&alphaComb
, &fxMesa
->AlphaCombine
, sizeof(alphaComb
));
1020 _mesa_problem(ctx
, "bad texture env mode in %s", __FUNCTION__
);
1024 if (colorComb
.Function
!= fxMesa
->ColorCombine
.Function
||
1025 colorComb
.Factor
!= fxMesa
->ColorCombine
.Factor
||
1026 colorComb
.Local
!= fxMesa
->ColorCombine
.Local
||
1027 colorComb
.Other
!= fxMesa
->ColorCombine
.Other
||
1028 colorComb
.Invert
!= fxMesa
->ColorCombine
.Invert
) {
1029 fxMesa
->ColorCombine
= colorComb
;
1030 fxMesa
->dirty
|= TDFX_UPLOAD_COLOR_COMBINE
;
1033 if (alphaComb
.Function
!= fxMesa
->AlphaCombine
.Function
||
1034 alphaComb
.Factor
!= fxMesa
->AlphaCombine
.Factor
||
1035 alphaComb
.Local
!= fxMesa
->AlphaCombine
.Local
||
1036 alphaComb
.Other
!= fxMesa
->AlphaCombine
.Other
||
1037 alphaComb
.Invert
!= fxMesa
->AlphaCombine
.Invert
) {
1038 fxMesa
->AlphaCombine
= alphaComb
;
1039 fxMesa
->dirty
|= TDFX_UPLOAD_ALPHA_COMBINE
;
1046 * Setup the Voodoo3 texture environment for dual texture units.
1047 * Return GL_TRUE for success, GL_FALSE for failure.
1048 * If failure, we'll use software rendering.
1051 SetupDoubleTexEnvVoodoo3(GLcontext
*ctx
, int tmu0
,
1052 GLenum envMode0
, GLenum baseFormat0
,
1053 GLenum envMode1
, GLenum baseFormat1
)
1055 tdfxContextPtr fxMesa
= TDFX_CONTEXT(ctx
);
1056 const GrCombineLocal_t locala
= GR_COMBINE_LOCAL_ITERATED
;
1057 const GrCombineLocal_t localc
= GR_COMBINE_LOCAL_ITERATED
;
1058 const int tmu1
= 1 - tmu0
;
1060 if (envMode0
== GL_MODULATE
&& envMode1
== GL_MODULATE
) {
1061 GLboolean isalpha
[TDFX_NUM_TMU
];
1063 isalpha
[tmu0
] = (baseFormat0
== GL_ALPHA
);
1064 isalpha
[tmu1
] = (baseFormat1
== GL_ALPHA
);
1066 if (isalpha
[TDFX_TMU1
]) {
1067 fxMesa
->TexCombine
[1].FunctionRGB
= GR_COMBINE_FUNCTION_ZERO
;
1068 fxMesa
->TexCombine
[1].FactorRGB
= GR_COMBINE_FACTOR_NONE
;
1069 fxMesa
->TexCombine
[1].FunctionAlpha
= GR_COMBINE_FUNCTION_LOCAL
;
1070 fxMesa
->TexCombine
[1].FactorAlpha
= GR_COMBINE_FACTOR_NONE
;
1071 fxMesa
->TexCombine
[1].InvertRGB
= FXTRUE
;
1072 fxMesa
->TexCombine
[1].InvertAlpha
= FXFALSE
;
1075 fxMesa
->TexCombine
[1].FunctionRGB
= GR_COMBINE_FUNCTION_LOCAL
;
1076 fxMesa
->TexCombine
[1].FactorRGB
= GR_COMBINE_FACTOR_NONE
;
1077 fxMesa
->TexCombine
[1].FunctionAlpha
= GR_COMBINE_FUNCTION_LOCAL
;
1078 fxMesa
->TexCombine
[1].FactorAlpha
= GR_COMBINE_FACTOR_NONE
;
1079 fxMesa
->TexCombine
[1].InvertRGB
= FXFALSE
;
1080 fxMesa
->TexCombine
[1].InvertAlpha
= FXFALSE
;
1082 if (isalpha
[TDFX_TMU0
]) {
1083 fxMesa
->TexCombine
[0].FunctionRGB
= GR_COMBINE_FUNCTION_BLEND_OTHER
;
1084 fxMesa
->TexCombine
[0].FactorRGB
= GR_COMBINE_FACTOR_ONE
;
1085 fxMesa
->TexCombine
[0].FunctionAlpha
= GR_COMBINE_FUNCTION_BLEND_OTHER
;
1086 fxMesa
->TexCombine
[0].FactorAlpha
= GR_COMBINE_FACTOR_LOCAL
;
1087 fxMesa
->TexCombine
[0].InvertRGB
= FXFALSE
;
1088 fxMesa
->TexCombine
[0].InvertAlpha
= FXFALSE
;
1091 fxMesa
->TexCombine
[0].FunctionRGB
= GR_COMBINE_FUNCTION_BLEND_OTHER
;
1092 fxMesa
->TexCombine
[0].FactorRGB
= GR_COMBINE_FACTOR_LOCAL
;
1093 fxMesa
->TexCombine
[0].FunctionAlpha
= GR_COMBINE_FUNCTION_BLEND_OTHER
;
1094 fxMesa
->TexCombine
[0].FactorAlpha
= GR_COMBINE_FACTOR_LOCAL
;
1095 fxMesa
->TexCombine
[0].InvertRGB
= FXFALSE
;
1096 fxMesa
->TexCombine
[0].InvertAlpha
= FXFALSE
;
1098 fxMesa
->ColorCombine
.Function
= GR_COMBINE_FUNCTION_SCALE_OTHER
;
1099 fxMesa
->ColorCombine
.Factor
= GR_COMBINE_FACTOR_LOCAL
;
1100 fxMesa
->ColorCombine
.Local
= localc
;
1101 fxMesa
->ColorCombine
.Other
= GR_COMBINE_OTHER_TEXTURE
;
1102 fxMesa
->ColorCombine
.Invert
= FXFALSE
;
1103 fxMesa
->AlphaCombine
.Function
= GR_COMBINE_FUNCTION_SCALE_OTHER
;
1104 fxMesa
->AlphaCombine
.Factor
= GR_COMBINE_FACTOR_LOCAL
;
1105 fxMesa
->AlphaCombine
.Local
= locala
;
1106 fxMesa
->AlphaCombine
.Other
= GR_COMBINE_OTHER_TEXTURE
;
1107 fxMesa
->AlphaCombine
.Invert
= FXFALSE
;
1109 else if (envMode0
== GL_REPLACE
&& envMode1
== GL_BLEND
) { /* Quake */
1110 if (tmu0
== TDFX_TMU1
) {
1111 fxMesa
->TexCombine
[1].FunctionRGB
= GR_COMBINE_FUNCTION_LOCAL
;
1112 fxMesa
->TexCombine
[1].FactorRGB
= GR_COMBINE_FACTOR_NONE
;
1113 fxMesa
->TexCombine
[1].FunctionAlpha
= GR_COMBINE_FUNCTION_LOCAL
;
1114 fxMesa
->TexCombine
[1].FactorAlpha
= GR_COMBINE_FACTOR_NONE
;
1115 fxMesa
->TexCombine
[1].InvertRGB
= FXTRUE
;
1116 fxMesa
->TexCombine
[1].InvertAlpha
= FXFALSE
;
1117 fxMesa
->TexCombine
[0].FunctionRGB
= GR_COMBINE_FUNCTION_BLEND_OTHER
;
1118 fxMesa
->TexCombine
[0].FactorRGB
= GR_COMBINE_FACTOR_LOCAL
;
1119 fxMesa
->TexCombine
[0].FunctionAlpha
= GR_COMBINE_FUNCTION_BLEND_OTHER
;
1120 fxMesa
->TexCombine
[0].FactorAlpha
= GR_COMBINE_FACTOR_LOCAL
;
1121 fxMesa
->TexCombine
[0].InvertRGB
= FXFALSE
;
1122 fxMesa
->TexCombine
[0].InvertAlpha
= FXFALSE
;
1125 fxMesa
->TexCombine
[1].FunctionRGB
= GR_COMBINE_FUNCTION_LOCAL
;
1126 fxMesa
->TexCombine
[1].FactorRGB
= GR_COMBINE_FACTOR_NONE
;
1127 fxMesa
->TexCombine
[1].FunctionAlpha
= GR_COMBINE_FUNCTION_LOCAL
;
1128 fxMesa
->TexCombine
[1].FactorAlpha
= GR_COMBINE_FACTOR_NONE
;
1129 fxMesa
->TexCombine
[1].InvertRGB
= FXFALSE
;
1130 fxMesa
->TexCombine
[1].InvertAlpha
= FXFALSE
;
1131 fxMesa
->TexCombine
[0].FunctionRGB
= GR_COMBINE_FUNCTION_BLEND_OTHER
;
1132 fxMesa
->TexCombine
[0].FactorRGB
= GR_COMBINE_FACTOR_ONE_MINUS_LOCAL
;
1133 fxMesa
->TexCombine
[0].FunctionAlpha
= GR_COMBINE_FUNCTION_BLEND_OTHER
;
1134 fxMesa
->TexCombine
[0].FactorAlpha
= GR_COMBINE_FACTOR_ONE_MINUS_LOCAL
;
1135 fxMesa
->TexCombine
[0].InvertRGB
= FXFALSE
;
1136 fxMesa
->TexCombine
[0].InvertAlpha
= FXFALSE
;
1138 fxMesa
->ColorCombine
.Function
= GR_COMBINE_FUNCTION_SCALE_OTHER
;
1139 fxMesa
->ColorCombine
.Factor
= GR_COMBINE_FACTOR_ONE
;
1140 fxMesa
->ColorCombine
.Local
= localc
;
1141 fxMesa
->ColorCombine
.Other
= GR_COMBINE_OTHER_TEXTURE
;
1142 fxMesa
->ColorCombine
.Invert
= FXFALSE
;
1143 fxMesa
->AlphaCombine
.Function
= GR_COMBINE_FUNCTION_LOCAL
;
1144 fxMesa
->AlphaCombine
.Factor
= GR_COMBINE_FACTOR_NONE
;
1145 fxMesa
->AlphaCombine
.Local
= locala
;
1146 fxMesa
->AlphaCombine
.Other
= GR_COMBINE_OTHER_NONE
;
1147 fxMesa
->AlphaCombine
.Invert
= FXFALSE
;
1149 else if (envMode0
== GL_REPLACE
&& envMode1
== GL_MODULATE
) {
1151 if (tmu1
== TDFX_TMU1
) {
1152 fxMesa
->TexCombine
[1].FunctionRGB
= GR_COMBINE_FUNCTION_LOCAL
;
1153 fxMesa
->TexCombine
[1].FactorRGB
= GR_COMBINE_FACTOR_NONE
;
1154 fxMesa
->TexCombine
[1].FunctionAlpha
= GR_COMBINE_FUNCTION_ZERO
;
1155 fxMesa
->TexCombine
[1].FactorAlpha
= GR_COMBINE_FACTOR_NONE
;
1156 fxMesa
->TexCombine
[1].InvertRGB
= FXFALSE
;
1157 fxMesa
->TexCombine
[1].InvertAlpha
= FXTRUE
;
1158 fxMesa
->TexCombine
[0].FunctionRGB
= GR_COMBINE_FUNCTION_BLEND_OTHER
;
1159 fxMesa
->TexCombine
[0].FactorRGB
= GR_COMBINE_FACTOR_LOCAL
;
1160 fxMesa
->TexCombine
[0].FunctionAlpha
= GR_COMBINE_FUNCTION_BLEND_OTHER
;
1161 fxMesa
->TexCombine
[0].FactorAlpha
= GR_COMBINE_FACTOR_LOCAL
;
1162 fxMesa
->TexCombine
[0].InvertRGB
= FXFALSE
;
1163 fxMesa
->TexCombine
[0].InvertAlpha
= FXFALSE
;
1166 fxMesa
->TexCombine
[1].FunctionRGB
= GR_COMBINE_FUNCTION_LOCAL
;
1167 fxMesa
->TexCombine
[1].FactorRGB
= GR_COMBINE_FACTOR_NONE
;
1168 fxMesa
->TexCombine
[1].FunctionAlpha
= GR_COMBINE_FUNCTION_LOCAL
;
1169 fxMesa
->TexCombine
[1].FactorAlpha
= GR_COMBINE_FACTOR_NONE
;
1170 fxMesa
->TexCombine
[1].InvertRGB
= FXFALSE
;
1171 fxMesa
->TexCombine
[1].InvertAlpha
= FXFALSE
;
1172 fxMesa
->TexCombine
[0].FunctionRGB
= GR_COMBINE_FUNCTION_BLEND_OTHER
;
1173 fxMesa
->TexCombine
[0].FactorRGB
= GR_COMBINE_FACTOR_LOCAL
;
1174 fxMesa
->TexCombine
[0].FunctionAlpha
= GR_COMBINE_FUNCTION_BLEND_OTHER
;
1175 fxMesa
->TexCombine
[0].FactorAlpha
= GR_COMBINE_FACTOR_ONE
;
1176 fxMesa
->TexCombine
[0].InvertRGB
= FXFALSE
;
1177 fxMesa
->TexCombine
[0].InvertAlpha
= FXFALSE
;
1180 fxMesa
->ColorCombine
.Function
= GR_COMBINE_FUNCTION_SCALE_OTHER
;
1181 fxMesa
->ColorCombine
.Factor
= GR_COMBINE_FACTOR_ONE
;
1182 fxMesa
->ColorCombine
.Local
= localc
;
1183 fxMesa
->ColorCombine
.Other
= GR_COMBINE_OTHER_TEXTURE
;
1184 fxMesa
->ColorCombine
.Invert
= FXFALSE
;
1185 if (baseFormat0
== GL_RGB
) {
1186 fxMesa
->AlphaCombine
.Function
= GR_COMBINE_FUNCTION_LOCAL
;
1187 fxMesa
->AlphaCombine
.Factor
= GR_COMBINE_FACTOR_NONE
;
1188 fxMesa
->AlphaCombine
.Local
= locala
;
1189 fxMesa
->AlphaCombine
.Other
= GR_COMBINE_OTHER_NONE
;
1190 fxMesa
->AlphaCombine
.Invert
= FXFALSE
;
1193 fxMesa
->AlphaCombine
.Function
= GR_COMBINE_FUNCTION_SCALE_OTHER
;
1194 fxMesa
->AlphaCombine
.Factor
= GR_COMBINE_FACTOR_ONE
;
1195 fxMesa
->AlphaCombine
.Local
= locala
;
1196 fxMesa
->AlphaCombine
.Other
= GR_COMBINE_OTHER_NONE
;
1197 fxMesa
->AlphaCombine
.Invert
= FXFALSE
;
1200 else if (envMode0
== GL_MODULATE
&& envMode1
== GL_ADD
) {
1202 GLboolean isalpha
[TDFX_NUM_TMU
];
1204 isalpha
[tmu0
] = (baseFormat0
== GL_ALPHA
);
1205 isalpha
[tmu1
] = (baseFormat1
== GL_ALPHA
);
1207 if (isalpha
[TDFX_TMU1
]) {
1208 fxMesa
->TexCombine
[1].FunctionRGB
= GR_COMBINE_FUNCTION_ZERO
;
1209 fxMesa
->TexCombine
[1].FactorRGB
= GR_COMBINE_FACTOR_NONE
;
1210 fxMesa
->TexCombine
[1].FunctionAlpha
= GR_COMBINE_FUNCTION_LOCAL
;
1211 fxMesa
->TexCombine
[1].FactorAlpha
= GR_COMBINE_FACTOR_NONE
;
1212 fxMesa
->TexCombine
[1].InvertRGB
= FXTRUE
;
1213 fxMesa
->TexCombine
[1].InvertAlpha
= FXFALSE
;
1216 fxMesa
->TexCombine
[1].FunctionRGB
= GR_COMBINE_FUNCTION_LOCAL
;
1217 fxMesa
->TexCombine
[1].FactorRGB
= GR_COMBINE_FACTOR_NONE
;
1218 fxMesa
->TexCombine
[1].FunctionAlpha
= GR_COMBINE_FUNCTION_LOCAL
;
1219 fxMesa
->TexCombine
[1].FactorAlpha
= GR_COMBINE_FACTOR_NONE
;
1220 fxMesa
->TexCombine
[1].InvertRGB
= FXFALSE
;
1221 fxMesa
->TexCombine
[1].InvertAlpha
= FXFALSE
;
1223 if (isalpha
[TDFX_TMU0
]) {
1224 fxMesa
->TexCombine
[0].FunctionRGB
= GR_COMBINE_FUNCTION_SCALE_OTHER
;
1225 fxMesa
->TexCombine
[0].FactorRGB
= GR_COMBINE_FACTOR_ONE
;
1226 fxMesa
->TexCombine
[0].FunctionAlpha
= GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL
;
1227 fxMesa
->TexCombine
[0].FactorAlpha
= GR_COMBINE_FACTOR_ONE
;
1228 fxMesa
->TexCombine
[0].InvertRGB
= FXFALSE
;
1229 fxMesa
->TexCombine
[0].InvertAlpha
= FXFALSE
;
1232 fxMesa
->TexCombine
[0].FunctionRGB
= GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL
;
1233 fxMesa
->TexCombine
[0].FactorRGB
= GR_COMBINE_FACTOR_ONE
;
1234 fxMesa
->TexCombine
[0].FunctionAlpha
= GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL
;
1235 fxMesa
->TexCombine
[0].FactorAlpha
= GR_COMBINE_FACTOR_ONE
;
1236 fxMesa
->TexCombine
[0].InvertRGB
= FXFALSE
;
1237 fxMesa
->TexCombine
[0].InvertAlpha
= FXFALSE
;
1239 fxMesa
->ColorCombine
.Function
= GR_COMBINE_FUNCTION_SCALE_OTHER
;
1240 fxMesa
->ColorCombine
.Factor
= GR_COMBINE_FACTOR_LOCAL
;
1241 fxMesa
->ColorCombine
.Local
= localc
;
1242 fxMesa
->ColorCombine
.Other
= GR_COMBINE_OTHER_TEXTURE
;
1243 fxMesa
->ColorCombine
.Invert
= FXFALSE
;
1244 fxMesa
->AlphaCombine
.Function
= GR_COMBINE_FUNCTION_SCALE_OTHER
;
1245 fxMesa
->AlphaCombine
.Factor
= GR_COMBINE_FACTOR_LOCAL
;
1246 fxMesa
->AlphaCombine
.Local
= locala
;
1247 fxMesa
->AlphaCombine
.Other
= GR_COMBINE_OTHER_TEXTURE
;
1248 fxMesa
->AlphaCombine
.Invert
= FXFALSE
;
1250 else if (envMode0
== GL_REPLACE
&& envMode1
== GL_ADD
) {
1252 GLboolean isalpha
[TDFX_NUM_TMU
];
1254 isalpha
[tmu0
] = (baseFormat0
== GL_ALPHA
);
1255 isalpha
[tmu1
] = (baseFormat1
== GL_ALPHA
);
1257 if (isalpha
[TDFX_TMU1
]) {
1258 fxMesa
->TexCombine
[1].FunctionRGB
= GR_COMBINE_FUNCTION_ZERO
;
1259 fxMesa
->TexCombine
[1].FactorRGB
= GR_COMBINE_FACTOR_NONE
;
1260 fxMesa
->TexCombine
[1].FunctionAlpha
= GR_COMBINE_FUNCTION_LOCAL
;
1261 fxMesa
->TexCombine
[1].FactorAlpha
= GR_COMBINE_FACTOR_NONE
;
1262 fxMesa
->TexCombine
[1].InvertRGB
= FXTRUE
;
1263 fxMesa
->TexCombine
[1].InvertAlpha
= FXFALSE
;
1265 fxMesa
->TexCombine
[1].FunctionRGB
= GR_COMBINE_FUNCTION_LOCAL
;
1266 fxMesa
->TexCombine
[1].FactorRGB
= GR_COMBINE_FACTOR_NONE
;
1267 fxMesa
->TexCombine
[1].FunctionAlpha
= GR_COMBINE_FUNCTION_LOCAL
;
1268 fxMesa
->TexCombine
[1].FactorAlpha
= GR_COMBINE_FACTOR_NONE
;
1269 fxMesa
->TexCombine
[1].InvertRGB
= FXFALSE
;
1270 fxMesa
->TexCombine
[1].InvertAlpha
= FXFALSE
;
1273 if (isalpha
[TDFX_TMU0
]) {
1274 fxMesa
->TexCombine
[0].FunctionRGB
= GR_COMBINE_FUNCTION_SCALE_OTHER
;
1275 fxMesa
->TexCombine
[0].FactorRGB
= GR_COMBINE_FACTOR_ONE
;
1276 fxMesa
->TexCombine
[0].FunctionAlpha
= GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL
;
1277 fxMesa
->TexCombine
[0].FactorAlpha
= GR_COMBINE_FACTOR_ONE
;
1278 fxMesa
->TexCombine
[0].InvertRGB
= FXFALSE
;
1279 fxMesa
->TexCombine
[0].InvertAlpha
= FXFALSE
;
1281 fxMesa
->TexCombine
[0].FunctionRGB
= GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL
;
1282 fxMesa
->TexCombine
[0].FactorRGB
= GR_COMBINE_FACTOR_ONE
;
1283 fxMesa
->TexCombine
[0].FunctionAlpha
= GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL
;
1284 fxMesa
->TexCombine
[0].FactorAlpha
= GR_COMBINE_FACTOR_ONE
;
1285 fxMesa
->TexCombine
[0].InvertRGB
= FXFALSE
;
1286 fxMesa
->TexCombine
[0].InvertAlpha
= FXFALSE
;
1289 fxMesa
->ColorCombine
.Function
= GR_COMBINE_FUNCTION_SCALE_OTHER
;
1290 fxMesa
->ColorCombine
.Factor
= GR_COMBINE_FACTOR_ONE
;
1291 fxMesa
->ColorCombine
.Local
= localc
;
1292 fxMesa
->ColorCombine
.Other
= GR_COMBINE_OTHER_TEXTURE
;
1293 fxMesa
->ColorCombine
.Invert
= FXFALSE
;
1294 fxMesa
->AlphaCombine
.Function
= GR_COMBINE_FUNCTION_SCALE_OTHER
;
1295 fxMesa
->AlphaCombine
.Factor
= GR_COMBINE_FACTOR_ONE
;
1296 fxMesa
->AlphaCombine
.Local
= locala
;
1297 fxMesa
->AlphaCombine
.Other
= GR_COMBINE_OTHER_TEXTURE
;
1298 fxMesa
->AlphaCombine
.Invert
= FXFALSE
;
1300 else if (envMode1
== GL_REPLACE
) {
1303 fxMesa
->TexCombine
[1].FunctionRGB
= GR_COMBINE_FUNCTION_ZERO
;
1304 fxMesa
->TexCombine
[1].FactorRGB
= GR_COMBINE_FACTOR_NONE
;
1305 fxMesa
->TexCombine
[1].FunctionAlpha
= GR_COMBINE_FUNCTION_ZERO
;
1306 fxMesa
->TexCombine
[1].FactorAlpha
= GR_COMBINE_FACTOR_NONE
;
1307 fxMesa
->TexCombine
[1].InvertRGB
= FXFALSE
;
1308 fxMesa
->TexCombine
[1].InvertAlpha
= FXFALSE
;
1310 fxMesa
->TexCombine
[0].FunctionRGB
= GR_COMBINE_FUNCTION_LOCAL
;
1311 fxMesa
->TexCombine
[0].FactorRGB
= GR_COMBINE_FACTOR_NONE
;
1312 fxMesa
->TexCombine
[0].FunctionAlpha
= GR_COMBINE_FUNCTION_LOCAL
;
1313 fxMesa
->TexCombine
[0].FactorAlpha
= GR_COMBINE_FACTOR_NONE
;
1314 fxMesa
->TexCombine
[0].InvertRGB
= FXFALSE
;
1315 fxMesa
->TexCombine
[0].InvertAlpha
= FXFALSE
;
1317 if ((baseFormat0
== GL_RGB
) && (baseFormat0
== GL_LUMINANCE
)) {
1318 fxMesa
->AlphaCombine
.Function
= GR_COMBINE_FUNCTION_LOCAL
;
1319 fxMesa
->AlphaCombine
.Factor
= GR_COMBINE_FACTOR_NONE
;
1320 fxMesa
->AlphaCombine
.Local
= locala
;
1321 fxMesa
->AlphaCombine
.Other
= GR_COMBINE_OTHER_NONE
;
1322 fxMesa
->AlphaCombine
.Invert
= FXFALSE
;
1324 fxMesa
->AlphaCombine
.Function
= GR_COMBINE_FUNCTION_SCALE_OTHER
;
1325 fxMesa
->AlphaCombine
.Factor
= GR_COMBINE_FACTOR_ONE
;
1326 fxMesa
->AlphaCombine
.Local
= locala
;
1327 fxMesa
->AlphaCombine
.Other
= GR_COMBINE_OTHER_TEXTURE
;
1328 fxMesa
->AlphaCombine
.Invert
= FXFALSE
;
1330 if (baseFormat0
== GL_ALPHA
) {
1331 fxMesa
->ColorCombine
.Function
= GR_COMBINE_FUNCTION_LOCAL
;
1332 fxMesa
->ColorCombine
.Factor
= GR_COMBINE_FACTOR_NONE
;
1333 fxMesa
->ColorCombine
.Local
= localc
;
1334 fxMesa
->ColorCombine
.Other
= GR_COMBINE_OTHER_NONE
;
1335 fxMesa
->ColorCombine
.Invert
= FXFALSE
;
1337 fxMesa
->ColorCombine
.Function
= GR_COMBINE_FUNCTION_SCALE_OTHER
;
1338 fxMesa
->ColorCombine
.Factor
= GR_COMBINE_FACTOR_ONE
;
1339 fxMesa
->ColorCombine
.Local
= localc
;
1340 fxMesa
->ColorCombine
.Other
= GR_COMBINE_OTHER_TEXTURE
;
1341 fxMesa
->ColorCombine
.Invert
= FXFALSE
;
1345 _mesa_problem(ctx
, "%s: Unexpected dual texture mode encountered", __FUNCTION__
);
1349 fxMesa
->dirty
|= TDFX_UPLOAD_TEXTURE_ENV
;
1350 fxMesa
->dirty
|= TDFX_UPLOAD_COLOR_COMBINE
;
1351 fxMesa
->dirty
|= TDFX_UPLOAD_ALPHA_COMBINE
;
1357 * This function makes sure that the correct mipmap levels are loaded
1358 * in the right places in memory and then makes the Glide calls to
1359 * setup the texture source pointers.
1362 setupSingleTMU(tdfxContextPtr fxMesa
, struct gl_texture_object
*tObj
)
1364 struct tdfxSharedState
*shared
= (struct tdfxSharedState
*) fxMesa
->glCtx
->Shared
->DriverData
;
1365 tdfxTexInfo
*ti
= TDFX_TEXTURE_DATA(tObj
);
1366 const GLcontext
*ctx
= fxMesa
->glCtx
;
1368 /* Make sure we're not loaded incorrectly */
1369 if (ti
->isInTM
&& !shared
->umaTexMemory
) {
1370 /* if doing filtering between mipmap levels, alternate mipmap levels
1371 * must be in alternate TMUs.
1374 if (ti
->whichTMU
!= TDFX_TMU_SPLIT
)
1375 tdfxTMMoveOutTM_NoLock(fxMesa
, tObj
);
1378 if (ti
->whichTMU
== TDFX_TMU_SPLIT
)
1379 tdfxTMMoveOutTM_NoLock(fxMesa
, tObj
);
1383 /* Make sure we're loaded correctly */
1385 /* Have to download the texture */
1386 if (shared
->umaTexMemory
) {
1387 tdfxTMMoveInTM_NoLock(fxMesa
, tObj
, TDFX_TMU0
);
1390 /* Voodoo3 (split texture memory) */
1392 tdfxTMMoveInTM_NoLock(fxMesa
, tObj
, TDFX_TMU_SPLIT
);
1396 /* XXX putting textures into the second memory bank when the
1397 * first bank is full is not working at this time.
1399 if (fxMesa
->haveTwoTMUs
) {
1400 GLint memReq
= fxMesa
->Glide
.grTexTextureMemRequired(
1401 GR_MIPMAPLEVELMASK_BOTH
, &(ti
->info
));
1402 if (shared
->freeTexMem
[TDFX_TMU0
] > memReq
) {
1403 tdfxTMMoveInTM_NoLock(fxMesa
, tObj
, TDFX_TMU0
);
1406 tdfxTMMoveInTM_NoLock(fxMesa
, tObj
, TDFX_TMU1
);
1412 tdfxTMMoveInTM_NoLock(fxMesa
, tObj
, TDFX_TMU0
);
1418 if (ti
->LODblend
&& ti
->whichTMU
== TDFX_TMU_SPLIT
) {
1419 /* mipmap levels split between texture banks */
1422 if (ti
->info
.format
== GR_TEXFMT_P_8
&& !ctx
->Texture
.SharedPalette
) {
1423 fxMesa
->TexPalette
.Type
= ti
->paltype
;
1424 fxMesa
->TexPalette
.Data
= &(ti
->palette
);
1425 fxMesa
->dirty
|= TDFX_UPLOAD_TEXTURE_PALETTE
;
1428 for (u
= 0; u
< 2; u
++) {
1429 fxMesa
->TexParams
[u
].sClamp
= ti
->sClamp
;
1430 fxMesa
->TexParams
[u
].tClamp
= ti
->tClamp
;
1431 fxMesa
->TexParams
[u
].minFilt
= ti
->minFilt
;
1432 fxMesa
->TexParams
[u
].magFilt
= ti
->magFilt
;
1433 fxMesa
->TexParams
[u
].mmMode
= ti
->mmMode
;
1434 fxMesa
->TexParams
[u
].LODblend
= ti
->LODblend
;
1435 fxMesa
->TexParams
[u
].LodBias
= ctx
->Texture
.Unit
[u
].LodBias
;
1437 fxMesa
->dirty
|= TDFX_UPLOAD_TEXTURE_PARAMS
;
1439 fxMesa
->TexSource
[0].StartAddress
= ti
->tm
[TDFX_TMU0
]->startAddr
;
1440 fxMesa
->TexSource
[0].EvenOdd
= GR_MIPMAPLEVELMASK_ODD
;
1441 fxMesa
->TexSource
[0].Info
= &(ti
->info
);
1442 fxMesa
->TexSource
[1].StartAddress
= ti
->tm
[TDFX_TMU1
]->startAddr
;
1443 fxMesa
->TexSource
[1].EvenOdd
= GR_MIPMAPLEVELMASK_EVEN
;
1444 fxMesa
->TexSource
[1].Info
= &(ti
->info
);
1445 fxMesa
->dirty
|= TDFX_UPLOAD_TEXTURE_SOURCE
;
1450 if (ti
->whichTMU
== TDFX_TMU_BOTH
)
1455 if (shared
->umaTexMemory
) {
1456 assert(ti
->whichTMU
== TDFX_TMU0
);
1457 assert(tmu
== TDFX_TMU0
);
1460 if (ti
->info
.format
== GR_TEXFMT_P_8
&& !ctx
->Texture
.SharedPalette
) {
1461 fxMesa
->TexPalette
.Type
= ti
->paltype
;
1462 fxMesa
->TexPalette
.Data
= &(ti
->palette
);
1463 fxMesa
->dirty
|= TDFX_UPLOAD_TEXTURE_PALETTE
;
1466 /* KW: The alternative is to do the download to the other tmu. If
1467 * we get to this point, I think it means we are thrashing the
1468 * texture memory, so perhaps it's not a good idea.
1471 if (fxMesa
->TexParams
[tmu
].sClamp
!= ti
->sClamp
||
1472 fxMesa
->TexParams
[tmu
].tClamp
!= ti
->tClamp
||
1473 fxMesa
->TexParams
[tmu
].minFilt
!= ti
->minFilt
||
1474 fxMesa
->TexParams
[tmu
].magFilt
!= ti
->magFilt
||
1475 fxMesa
->TexParams
[tmu
].mmMode
!= ti
->mmMode
||
1476 fxMesa
->TexParams
[tmu
].LODblend
!= FXFALSE
||
1477 fxMesa
->TexParams
[tmu
].LodBias
!= ctx
->Texture
.Unit
[tmu
].LodBias
) {
1478 fxMesa
->TexParams
[tmu
].sClamp
= ti
->sClamp
;
1479 fxMesa
->TexParams
[tmu
].tClamp
= ti
->tClamp
;
1480 fxMesa
->TexParams
[tmu
].minFilt
= ti
->minFilt
;
1481 fxMesa
->TexParams
[tmu
].magFilt
= ti
->magFilt
;
1482 fxMesa
->TexParams
[tmu
].mmMode
= ti
->mmMode
;
1483 fxMesa
->TexParams
[tmu
].LODblend
= FXFALSE
;
1484 fxMesa
->TexParams
[tmu
].LodBias
= ctx
->Texture
.Unit
[tmu
].LodBias
;
1485 fxMesa
->dirty
|= TDFX_UPLOAD_TEXTURE_PARAMS
;
1488 /* Glide texture source info */
1489 fxMesa
->TexSource
[0].Info
= NULL
;
1490 fxMesa
->TexSource
[1].Info
= NULL
;
1492 fxMesa
->TexSource
[tmu
].StartAddress
= ti
->tm
[tmu
]->startAddr
;
1493 fxMesa
->TexSource
[tmu
].EvenOdd
= GR_MIPMAPLEVELMASK_BOTH
;
1494 fxMesa
->TexSource
[tmu
].Info
= &(ti
->info
);
1495 fxMesa
->dirty
|= TDFX_UPLOAD_TEXTURE_SOURCE
;
1499 fxMesa
->sScale0
= ti
->sScale
;
1500 fxMesa
->tScale0
= ti
->tScale
;
1504 selectSingleTMUSrc(tdfxContextPtr fxMesa
, GLint tmu
, FxBool LODblend
)
1507 fxMesa
->TexCombine
[0].FunctionRGB
= GR_COMBINE_FUNCTION_BLEND
;
1508 fxMesa
->TexCombine
[0].FactorRGB
= GR_COMBINE_FACTOR_ONE_MINUS_LOD_FRACTION
;
1509 fxMesa
->TexCombine
[0].FunctionAlpha
= GR_COMBINE_FUNCTION_BLEND
;
1510 fxMesa
->TexCombine
[0].FactorAlpha
= GR_COMBINE_FACTOR_ONE_MINUS_LOD_FRACTION
;
1511 fxMesa
->TexCombine
[0].InvertRGB
= FXFALSE
;
1512 fxMesa
->TexCombine
[0].InvertAlpha
= FXFALSE
;
1514 if (fxMesa
->haveTwoTMUs
) {
1515 const struct gl_shared_state
*mesaShared
= fxMesa
->glCtx
->Shared
;
1516 const struct tdfxSharedState
*shared
= (struct tdfxSharedState
*) mesaShared
->DriverData
;
1519 if (shared
->umaTexMemory
)
1524 fxMesa
->TexCombine
[tmu
].FunctionRGB
= GR_COMBINE_FUNCTION_LOCAL
;
1525 fxMesa
->TexCombine
[tmu
].FactorRGB
= GR_COMBINE_FACTOR_NONE
;
1526 fxMesa
->TexCombine
[tmu
].FunctionAlpha
= GR_COMBINE_FUNCTION_LOCAL
;
1527 fxMesa
->TexCombine
[tmu
].FactorAlpha
= GR_COMBINE_FACTOR_NONE
;
1528 fxMesa
->TexCombine
[tmu
].InvertRGB
= FXFALSE
;
1529 fxMesa
->TexCombine
[tmu
].InvertAlpha
= FXFALSE
;
1531 fxMesa
->tmuSrc
= TDFX_TMU_SPLIT
;
1534 if (tmu
!= TDFX_TMU1
) {
1535 fxMesa
->TexCombine
[0].FunctionRGB
= GR_COMBINE_FUNCTION_LOCAL
;
1536 fxMesa
->TexCombine
[0].FactorRGB
= GR_COMBINE_FACTOR_NONE
;
1537 fxMesa
->TexCombine
[0].FunctionAlpha
= GR_COMBINE_FUNCTION_LOCAL
;
1538 fxMesa
->TexCombine
[0].FactorAlpha
= GR_COMBINE_FACTOR_NONE
;
1539 fxMesa
->TexCombine
[0].InvertRGB
= FXFALSE
;
1540 fxMesa
->TexCombine
[0].InvertAlpha
= FXFALSE
;
1541 if (fxMesa
->haveTwoTMUs
) {
1542 fxMesa
->TexCombine
[1].FunctionRGB
= GR_COMBINE_FUNCTION_ZERO
;
1543 fxMesa
->TexCombine
[1].FactorRGB
= GR_COMBINE_FACTOR_NONE
;
1544 fxMesa
->TexCombine
[1].FunctionAlpha
= GR_COMBINE_FUNCTION_ZERO
;
1545 fxMesa
->TexCombine
[1].FactorAlpha
= GR_COMBINE_FACTOR_NONE
;
1546 fxMesa
->TexCombine
[1].InvertRGB
= FXFALSE
;
1547 fxMesa
->TexCombine
[1].InvertAlpha
= FXFALSE
;
1549 fxMesa
->tmuSrc
= TDFX_TMU0
;
1552 fxMesa
->TexCombine
[1].FunctionRGB
= GR_COMBINE_FUNCTION_LOCAL
;
1553 fxMesa
->TexCombine
[1].FactorRGB
= GR_COMBINE_FACTOR_NONE
;
1554 fxMesa
->TexCombine
[1].FunctionAlpha
= GR_COMBINE_FUNCTION_LOCAL
;
1555 fxMesa
->TexCombine
[1].FactorAlpha
= GR_COMBINE_FACTOR_NONE
;
1556 fxMesa
->TexCombine
[1].InvertRGB
= FXFALSE
;
1557 fxMesa
->TexCombine
[1].InvertAlpha
= FXFALSE
;
1558 /* GR_COMBINE_FUNCTION_SCALE_OTHER doesn't work ?!? */
1559 fxMesa
->TexCombine
[0].FunctionRGB
= GR_COMBINE_FUNCTION_BLEND
;
1560 fxMesa
->TexCombine
[0].FactorRGB
= GR_COMBINE_FACTOR_ONE
;
1561 fxMesa
->TexCombine
[0].FunctionAlpha
= GR_COMBINE_FUNCTION_BLEND
;
1562 fxMesa
->TexCombine
[0].FactorAlpha
= GR_COMBINE_FACTOR_ONE
;
1563 fxMesa
->TexCombine
[0].InvertRGB
= FXFALSE
;
1564 fxMesa
->TexCombine
[0].InvertAlpha
= FXFALSE
;
1565 fxMesa
->tmuSrc
= TDFX_TMU1
;
1569 fxMesa
->dirty
|= TDFX_UPLOAD_TEXTURE_ENV
;
1573 static void print_state(tdfxContextPtr fxMesa
)
1575 GLcontext
*ctx
= fxMesa
->glCtx
;
1576 struct gl_texture_object
*tObj0
= ctx
->Texture
.Unit
[0]._Current
;
1577 struct gl_texture_object
*tObj1
= ctx
->Texture
.Unit
[1]._Current
;
1578 GLenum base0
= tObj0
->Image
[0][tObj0
->BaseLevel
] ? tObj0
->Image
[0][tObj0
->BaseLevel
]->Format
: 99;
1579 GLenum base1
= tObj1
->Image
[0][tObj1
->BaseLevel
] ? tObj1
->Image
[0][tObj1
->BaseLevel
]->Format
: 99;
1581 printf("Unit 0: Enabled: GL=%d Gr=%d\n", ctx
->Texture
.Unit
[0]._ReallyEnabled
,
1582 fxMesa
->TexState
.Enabled
[0]);
1583 printf(" EnvMode: GL=0x%x Gr=0x%x\n", ctx
->Texture
.Unit
[0].EnvMode
,
1584 fxMesa
->TexState
.EnvMode
[0]);
1585 printf(" BaseFmt: GL=0x%x Gr=0x%x\n", base0
, fxMesa
->TexState
.TexFormat
[0]);
1588 printf("Unit 1: Enabled: GL=%d Gr=%d\n", ctx
->Texture
.Unit
[1]._ReallyEnabled
,
1589 fxMesa
->TexState
.Enabled
[1]);
1590 printf(" EnvMode: GL=0x%x Gr:0x%x\n", ctx
->Texture
.Unit
[1].EnvMode
,
1591 fxMesa
->TexState
.EnvMode
[1]);
1592 printf(" BaseFmt: GL=0x%x Gr:0x%x\n", base1
, fxMesa
->TexState
.TexFormat
[1]);
1597 * When we're only using a single texture unit, we always use the 0th
1598 * Glide/hardware unit, regardless if it's GL_TEXTURE0_ARB or GL_TEXTURE1_ARB
1600 * Input: ctx - the context
1601 * unit - the OpenGL texture unit to use.
1603 static void setupTextureSingleTMU(GLcontext
* ctx
, GLuint unit
)
1605 tdfxContextPtr fxMesa
= TDFX_CONTEXT(ctx
);
1607 struct gl_texture_object
*tObj
;
1609 GLenum envMode
, baseFormat
;
1611 tObj
= ctx
->Texture
.Unit
[unit
]._Current
;
1612 if (tObj
->Image
[0][tObj
->BaseLevel
]->Border
> 0) {
1613 FALLBACK(fxMesa
, TDFX_FALLBACK_TEXTURE_BORDER
, GL_TRUE
);
1617 setupSingleTMU(fxMesa
, tObj
);
1619 ti
= TDFX_TEXTURE_DATA(tObj
);
1620 if (ti
->whichTMU
== TDFX_TMU_BOTH
)
1625 if (fxMesa
->tmuSrc
!= tmu
) {
1626 selectSingleTMUSrc(fxMesa
, tmu
, ti
->LODblend
);
1629 if (ti
->reloadImages
)
1630 fxMesa
->dirty
|= TDFX_UPLOAD_TEXTURE_IMAGES
;
1632 /* Check if we really need to update the texenv state */
1633 envMode
= ctx
->Texture
.Unit
[unit
].EnvMode
;
1634 baseFormat
= tObj
->Image
[0][tObj
->BaseLevel
]->_BaseFormat
;
1636 if (TDFX_IS_NAPALM(fxMesa
)) {
1637 /* see if we really need to update the unit */
1638 if (1/*fxMesa->TexState.Enabled[unit] != ctx->Texture.Unit[unit]._ReallyEnabled ||
1639 envMode != fxMesa->TexState.EnvMode[0] ||
1640 envMode == GL_COMBINE_EXT ||
1641 baseFormat != fxMesa->TexState.TexFormat[0]*/) {
1642 struct tdfx_texcombine_ext
*otherEnv
;
1643 if (!SetupTexEnvNapalm(ctx
, GL_TRUE
,
1644 &ctx
->Texture
.Unit
[unit
], baseFormat
,
1645 &fxMesa
->TexCombineExt
[0])) {
1646 /* software fallback */
1647 FALLBACK(fxMesa
, TDFX_FALLBACK_TEXTURE_ENV
, GL_TRUE
);
1649 /* disable other unit */
1650 otherEnv
= &fxMesa
->TexCombineExt
[1];
1651 otherEnv
->Color
.SourceA
= GR_CMBX_ZERO
;
1652 otherEnv
->Color
.ModeA
= GR_FUNC_MODE_ZERO
;
1653 otherEnv
->Color
.SourceB
= GR_CMBX_ZERO
;
1654 otherEnv
->Color
.ModeB
= GR_FUNC_MODE_ZERO
;
1655 otherEnv
->Color
.SourceC
= GR_CMBX_ZERO
;
1656 otherEnv
->Color
.InvertC
= FXFALSE
;
1657 otherEnv
->Color
.SourceD
= GR_CMBX_ZERO
;
1658 otherEnv
->Color
.InvertD
= FXFALSE
;
1659 otherEnv
->Color
.Shift
= 0;
1660 otherEnv
->Color
.Invert
= FXFALSE
;
1661 otherEnv
->Alpha
.SourceA
= GR_CMBX_ITALPHA
;
1662 otherEnv
->Alpha
.ModeA
= GR_FUNC_MODE_ZERO
;
1663 otherEnv
->Alpha
.SourceB
= GR_CMBX_ITALPHA
;
1664 otherEnv
->Alpha
.ModeB
= GR_FUNC_MODE_ZERO
;
1665 otherEnv
->Alpha
.SourceC
= GR_CMBX_ZERO
;
1666 otherEnv
->Alpha
.InvertC
= FXFALSE
;
1667 otherEnv
->Alpha
.SourceD
= GR_CMBX_ZERO
;
1668 otherEnv
->Alpha
.InvertD
= FXFALSE
;
1669 otherEnv
->Alpha
.Shift
= 0;
1670 otherEnv
->Alpha
.Invert
= FXFALSE
;
1673 fxMesa
->TexState
.Enabled
[unit
] = ctx
->Texture
.Unit
[unit
]._ReallyEnabled
;
1674 fxMesa
->TexState
.EnvMode
[0] = envMode
;
1675 fxMesa
->TexState
.TexFormat
[0] = baseFormat
;
1676 fxMesa
->TexState
.EnvMode
[1] = 0;
1677 fxMesa
->TexState
.TexFormat
[1] = 0;
1684 /* see if we really need to update the unit */
1685 if (1/*fxMesa->TexState.Enabled[unit] != ctx->Texture.Unit[unit]._ReallyEnabled ||
1686 envMode != fxMesa->TexState.EnvMode[0] ||
1687 envMode == GL_COMBINE_EXT ||
1688 baseFormat != fxMesa->TexState.TexFormat[0]*/) {
1689 if (!SetupSingleTexEnvVoodoo3(ctx
, unit
, envMode
, baseFormat
)) {
1690 /* software fallback */
1691 FALLBACK(fxMesa
, TDFX_FALLBACK_TEXTURE_ENV
, GL_TRUE
);
1694 fxMesa
->TexState
.Enabled
[unit
] = ctx
->Texture
.Unit
[unit
]._ReallyEnabled
;
1695 fxMesa
->TexState
.EnvMode
[0] = envMode
;
1696 fxMesa
->TexState
.TexFormat
[0] = baseFormat
;
1697 fxMesa
->TexState
.EnvMode
[1] = 0;
1698 fxMesa
->TexState
.TexFormat
[1] = 0;
1706 setupDoubleTMU(tdfxContextPtr fxMesa
,
1707 struct gl_texture_object
*tObj0
,
1708 struct gl_texture_object
*tObj1
)
1710 #define T0_NOT_IN_TMU 0x01
1711 #define T1_NOT_IN_TMU 0x02
1712 #define T0_IN_TMU0 0x04
1713 #define T1_IN_TMU0 0x08
1714 #define T0_IN_TMU1 0x10
1715 #define T1_IN_TMU1 0x20
1717 const struct gl_shared_state
*mesaShared
= fxMesa
->glCtx
->Shared
;
1718 const struct tdfxSharedState
*shared
= (struct tdfxSharedState
*) mesaShared
->DriverData
;
1719 const GLcontext
*ctx
= fxMesa
->glCtx
;
1720 tdfxTexInfo
*ti0
= TDFX_TEXTURE_DATA(tObj0
);
1721 tdfxTexInfo
*ti1
= TDFX_TEXTURE_DATA(tObj1
);
1723 int tmu0
= 0, tmu1
= 1;
1725 if (shared
->umaTexMemory
) {
1727 tdfxTMMoveInTM_NoLock(fxMesa
, tObj0
, TDFX_TMU0
);
1728 assert(ti0
->isInTM
);
1731 tdfxTMMoveInTM_NoLock(fxMesa
, tObj1
, TDFX_TMU0
);
1732 assert(ti1
->isInTM
);
1736 /* We shouldn't need to do this. There is something wrong with
1737 multitexturing when the TMUs are swapped. So, we're forcing
1738 them to always be loaded correctly. !!! */
1739 if (ti0
->whichTMU
== TDFX_TMU1
)
1740 tdfxTMMoveOutTM_NoLock(fxMesa
, tObj0
);
1741 if (ti1
->whichTMU
== TDFX_TMU0
)
1742 tdfxTMMoveOutTM_NoLock(fxMesa
, tObj1
);
1745 switch (ti0
->whichTMU
) {
1747 tstate
|= T0_IN_TMU0
;
1750 tstate
|= T0_IN_TMU1
;
1753 tstate
|= T0_IN_TMU0
| T0_IN_TMU1
;
1755 case TDFX_TMU_SPLIT
:
1756 tstate
|= T0_NOT_IN_TMU
;
1761 tstate
|= T0_NOT_IN_TMU
;
1764 switch (ti1
->whichTMU
) {
1766 tstate
|= T1_IN_TMU0
;
1769 tstate
|= T1_IN_TMU1
;
1772 tstate
|= T1_IN_TMU0
| T1_IN_TMU1
;
1774 case TDFX_TMU_SPLIT
:
1775 tstate
|= T1_NOT_IN_TMU
;
1780 tstate
|= T1_NOT_IN_TMU
;
1782 /* Move texture maps into TMUs */
1784 if (!(((tstate
& T0_IN_TMU0
) && (tstate
& T1_IN_TMU1
)) ||
1785 ((tstate
& T0_IN_TMU1
) && (tstate
& T1_IN_TMU0
)))) {
1786 if (tObj0
== tObj1
) {
1787 tdfxTMMoveInTM_NoLock(fxMesa
, tObj1
, TDFX_TMU_BOTH
);
1790 /* Find the minimal way to correct the situation */
1791 if ((tstate
& T0_IN_TMU0
) || (tstate
& T1_IN_TMU1
)) {
1792 /* We have one in the standard order, setup the other */
1793 if (tstate
& T0_IN_TMU0
) {
1794 /* T0 is in TMU0, put T1 in TMU1 */
1795 tdfxTMMoveInTM_NoLock(fxMesa
, tObj1
, TDFX_TMU1
);
1798 tdfxTMMoveInTM_NoLock(fxMesa
, tObj0
, TDFX_TMU0
);
1800 /* tmu0 and tmu1 are setup */
1802 else if ((tstate
& T0_IN_TMU1
) || (tstate
& T1_IN_TMU0
)) {
1803 /* we have one in the reverse order, setup the other */
1804 if (tstate
& T1_IN_TMU0
) {
1805 /* T1 is in TMU0, put T0 in TMU1 */
1806 tdfxTMMoveInTM_NoLock(fxMesa
, tObj0
, TDFX_TMU1
);
1809 tdfxTMMoveInTM_NoLock(fxMesa
, tObj1
, TDFX_TMU0
);
1814 else { /* Nothing is loaded */
1815 tdfxTMMoveInTM_NoLock(fxMesa
, tObj0
, TDFX_TMU0
);
1816 tdfxTMMoveInTM_NoLock(fxMesa
, tObj1
, TDFX_TMU1
);
1817 /* tmu0 and tmu1 are setup */
1823 ti0
->lastTimeUsed
= fxMesa
->texBindNumber
;
1824 ti1
->lastTimeUsed
= fxMesa
->texBindNumber
;
1827 if (!ctx
->Texture
.SharedPalette
) {
1828 if (ti0
->info
.format
== GR_TEXFMT_P_8
) {
1829 fxMesa
->TexPalette
.Type
= ti0
->paltype
;
1830 fxMesa
->TexPalette
.Data
= &(ti0
->palette
);
1831 fxMesa
->dirty
|= TDFX_UPLOAD_TEXTURE_PALETTE
;
1833 else if (ti1
->info
.format
== GR_TEXFMT_P_8
) {
1834 fxMesa
->TexPalette
.Type
= ti1
->paltype
;
1835 fxMesa
->TexPalette
.Data
= &(ti1
->palette
);
1836 fxMesa
->dirty
|= TDFX_UPLOAD_TEXTURE_PALETTE
;
1839 fxMesa
->TexPalette
.Data
= NULL
;
1846 assert(ti0
->isInTM
);
1847 assert(ti0
->tm
[tmu0
]);
1848 fxMesa
->TexSource
[tmu0
].StartAddress
= ti0
->tm
[tmu0
]->startAddr
;
1849 fxMesa
->TexSource
[tmu0
].EvenOdd
= GR_MIPMAPLEVELMASK_BOTH
;
1850 fxMesa
->TexSource
[tmu0
].Info
= &(ti0
->info
);
1851 fxMesa
->dirty
|= TDFX_UPLOAD_TEXTURE_SOURCE
;
1853 if (fxMesa
->TexParams
[tmu0
].sClamp
!= ti0
->sClamp
||
1854 fxMesa
->TexParams
[tmu0
].tClamp
!= ti0
->tClamp
||
1855 fxMesa
->TexParams
[tmu0
].minFilt
!= ti0
->minFilt
||
1856 fxMesa
->TexParams
[tmu0
].magFilt
!= ti0
->magFilt
||
1857 fxMesa
->TexParams
[tmu0
].mmMode
!= ti0
->mmMode
||
1858 fxMesa
->TexParams
[tmu0
].LODblend
!= FXFALSE
||
1859 fxMesa
->TexParams
[tmu0
].LodBias
!= ctx
->Texture
.Unit
[tmu0
].LodBias
) {
1860 fxMesa
->TexParams
[tmu0
].sClamp
= ti0
->sClamp
;
1861 fxMesa
->TexParams
[tmu0
].tClamp
= ti0
->tClamp
;
1862 fxMesa
->TexParams
[tmu0
].minFilt
= ti0
->minFilt
;
1863 fxMesa
->TexParams
[tmu0
].magFilt
= ti0
->magFilt
;
1864 fxMesa
->TexParams
[tmu0
].mmMode
= ti0
->mmMode
;
1865 fxMesa
->TexParams
[tmu0
].LODblend
= FXFALSE
;
1866 fxMesa
->TexParams
[tmu0
].LodBias
= ctx
->Texture
.Unit
[tmu0
].LodBias
;
1867 fxMesa
->dirty
|= TDFX_UPLOAD_TEXTURE_PARAMS
;
1873 if (shared
->umaTexMemory
) {
1874 ASSERT(ti1
->isInTM
);
1876 fxMesa
->TexSource
[tmu1
].StartAddress
= ti1
->tm
[0]->startAddr
;
1877 fxMesa
->TexSource
[tmu1
].EvenOdd
= GR_MIPMAPLEVELMASK_BOTH
;
1878 fxMesa
->TexSource
[tmu1
].Info
= &(ti1
->info
);
1881 ASSERT(ti1
->isInTM
);
1882 ASSERT(ti1
->tm
[tmu1
]);
1883 fxMesa
->TexSource
[tmu1
].StartAddress
= ti1
->tm
[tmu1
]->startAddr
;
1884 fxMesa
->TexSource
[tmu1
].EvenOdd
= GR_MIPMAPLEVELMASK_BOTH
;
1885 fxMesa
->TexSource
[tmu1
].Info
= &(ti1
->info
);
1888 if (fxMesa
->TexParams
[tmu1
].sClamp
!= ti1
->sClamp
||
1889 fxMesa
->TexParams
[tmu1
].tClamp
!= ti1
->tClamp
||
1890 fxMesa
->TexParams
[tmu1
].minFilt
!= ti1
->minFilt
||
1891 fxMesa
->TexParams
[tmu1
].magFilt
!= ti1
->magFilt
||
1892 fxMesa
->TexParams
[tmu1
].mmMode
!= ti1
->mmMode
||
1893 fxMesa
->TexParams
[tmu1
].LODblend
!= FXFALSE
||
1894 fxMesa
->TexParams
[tmu1
].LodBias
!= ctx
->Texture
.Unit
[tmu1
].LodBias
) {
1895 fxMesa
->TexParams
[tmu1
].sClamp
= ti1
->sClamp
;
1896 fxMesa
->TexParams
[tmu1
].tClamp
= ti1
->tClamp
;
1897 fxMesa
->TexParams
[tmu1
].minFilt
= ti1
->minFilt
;
1898 fxMesa
->TexParams
[tmu1
].magFilt
= ti1
->magFilt
;
1899 fxMesa
->TexParams
[tmu1
].mmMode
= ti1
->mmMode
;
1900 fxMesa
->TexParams
[tmu1
].LODblend
= FXFALSE
;
1901 fxMesa
->TexParams
[tmu1
].LodBias
= ctx
->Texture
.Unit
[tmu1
].LodBias
;
1902 fxMesa
->dirty
|= TDFX_UPLOAD_TEXTURE_PARAMS
;
1905 fxMesa
->sScale0
= ti0
->sScale
;
1906 fxMesa
->tScale0
= ti0
->tScale
;
1907 fxMesa
->sScale1
= ti1
->sScale
;
1908 fxMesa
->tScale1
= ti1
->tScale
;
1910 #undef T0_NOT_IN_TMU
1911 #undef T1_NOT_IN_TMU
1918 static void setupTextureDoubleTMU(GLcontext
* ctx
)
1920 tdfxContextPtr fxMesa
= TDFX_CONTEXT(ctx
);
1921 struct gl_texture_object
*tObj0
= ctx
->Texture
.Unit
[1]._Current
;
1922 struct gl_texture_object
*tObj1
= ctx
->Texture
.Unit
[0]._Current
;
1923 tdfxTexInfo
*ti0
= TDFX_TEXTURE_DATA(tObj0
);
1924 tdfxTexInfo
*ti1
= TDFX_TEXTURE_DATA(tObj1
);
1925 struct gl_texture_image
*baseImage0
= tObj0
->Image
[0][tObj0
->BaseLevel
];
1926 struct gl_texture_image
*baseImage1
= tObj1
->Image
[0][tObj1
->BaseLevel
];
1928 const GLenum envMode0
= ctx
->Texture
.Unit
[0].EnvMode
;
1929 const GLenum envMode1
= ctx
->Texture
.Unit
[1].EnvMode
;
1932 if (baseImage0
->Border
> 0 || baseImage1
->Border
> 0) {
1933 FALLBACK(fxMesa
, TDFX_FALLBACK_TEXTURE_BORDER
, GL_TRUE
);
1937 setupDoubleTMU(fxMesa
, tObj0
, tObj1
);
1939 if (ti0
->reloadImages
|| ti1
->reloadImages
)
1940 fxMesa
->dirty
|= TDFX_UPLOAD_TEXTURE_IMAGES
;
1942 fxMesa
->tmuSrc
= TDFX_TMU_BOTH
;
1944 if (TDFX_IS_NAPALM(fxMesa
)) {
1945 /* Remember, Glide has its texture units numbered in backward
1946 * order compared to OpenGL.
1948 GLboolean hw1
= GL_TRUE
, hw2
= GL_TRUE
;
1950 /* check if we really need to update glide unit 1 */
1951 if (1/*fxMesa->TexState.Enabled[0] != ctx->Texture.Unit[0]._ReallyEnabled ||
1952 envMode0 != fxMesa->TexState.EnvMode[1] ||
1953 envMode0 == GL_COMBINE_EXT ||
1954 baseImage0->Format != fxMesa->TexState.TexFormat[1] ||
1955 (fxMesa->Fallback & TDFX_FALLBACK_TEXTURE_ENV)*/) {
1956 hw1
= SetupTexEnvNapalm(ctx
, GL_TRUE
, &ctx
->Texture
.Unit
[0],
1957 baseImage0
->_BaseFormat
, &fxMesa
->TexCombineExt
[1]);
1959 fxMesa
->TexState
.EnvMode
[1] = envMode0
;
1960 fxMesa
->TexState
.TexFormat
[1] = baseImage0
->_BaseFormat
;
1961 fxMesa
->TexState
.Enabled
[0] = ctx
->Texture
.Unit
[0]._ReallyEnabled
;
1965 /* check if we really need to update glide unit 0 */
1966 if (1/*fxMesa->TexState.Enabled[1] != ctx->Texture.Unit[1]._ReallyEnabled ||
1967 envMode1 != fxMesa->TexState.EnvMode[0] ||
1968 envMode1 == GL_COMBINE_EXT ||
1969 baseImage1->_BaseFormat != fxMesa->TexState.TexFormat[0] ||
1970 (fxMesa->Fallback & TDFX_FALLBACK_TEXTURE_ENV)*/) {
1971 hw2
= SetupTexEnvNapalm(ctx
, GL_FALSE
, &ctx
->Texture
.Unit
[1],
1972 baseImage1
->_BaseFormat
, &fxMesa
->TexCombineExt
[0]);
1974 fxMesa
->TexState
.EnvMode
[0] = envMode1
;
1975 fxMesa
->TexState
.TexFormat
[0] = baseImage1
->_BaseFormat
;
1976 fxMesa
->TexState
.Enabled
[1] = ctx
->Texture
.Unit
[1]._ReallyEnabled
;
1982 FALLBACK(fxMesa
, TDFX_FALLBACK_TEXTURE_ENV
, GL_TRUE
);
1987 if ((ti0
->whichTMU
== TDFX_TMU1
) || (ti1
->whichTMU
== TDFX_TMU0
))
1993 if (1/*fxMesa->TexState.Enabled[0] != ctx->Texture.Unit[0]._ReallyEnabled ||
1994 fxMesa->TexState.Enabled[1] != ctx->Texture.Unit[1]._ReallyEnabled ||
1995 envMode0 != fxMesa->TexState.EnvMode[unit0] ||
1996 envMode0 == GL_COMBINE_EXT ||
1997 envMode1 != fxMesa->TexState.EnvMode[unit1] ||
1998 envMode1 == GL_COMBINE_EXT ||
1999 baseImage0->_BaseFormat != fxMesa->TexState.TexFormat[unit0] ||
2000 baseImage1->_BaseFormat != fxMesa->TexState.TexFormat[unit1] ||
2001 (fxMesa->Fallback & TDFX_FALLBACK_TEXTURE_ENV)*/) {
2003 if (!SetupDoubleTexEnvVoodoo3(ctx
, unit0
,
2004 ctx
->Texture
.Unit
[0].EnvMode
, baseImage0
->_BaseFormat
,
2005 ctx
->Texture
.Unit
[1].EnvMode
, baseImage1
->_BaseFormat
)) {
2006 FALLBACK(fxMesa
, TDFX_FALLBACK_TEXTURE_ENV
, GL_TRUE
);
2010 fxMesa
->TexState
.EnvMode
[unit0
] = envMode0
;
2011 fxMesa
->TexState
.TexFormat
[unit0
] = baseImage0
->_BaseFormat
;
2012 fxMesa
->TexState
.EnvMode
[unit1
] = envMode1
;
2013 fxMesa
->TexState
.TexFormat
[unit1
] = baseImage1
->_BaseFormat
;
2014 fxMesa
->TexState
.Enabled
[0] = ctx
->Texture
.Unit
[0]._ReallyEnabled
;
2015 fxMesa
->TexState
.Enabled
[1] = ctx
->Texture
.Unit
[1]._ReallyEnabled
;
2023 tdfxUpdateTextureState( GLcontext
*ctx
)
2025 tdfxContextPtr fxMesa
= TDFX_CONTEXT(ctx
);
2027 FALLBACK(fxMesa
, TDFX_FALLBACK_TEXTURE_BORDER
, GL_FALSE
);
2028 FALLBACK(fxMesa
, TDFX_FALLBACK_TEXTURE_ENV
, GL_FALSE
);
2030 if (ctx
->Texture
.Unit
[0]._ReallyEnabled
& (TEXTURE_1D_BIT
|TEXTURE_2D_BIT
) &&
2031 ctx
->Texture
.Unit
[1]._ReallyEnabled
== 0) {
2032 LOCK_HARDWARE( fxMesa
); /* XXX remove locking eventually */
2033 setupTextureSingleTMU(ctx
, 0);
2034 UNLOCK_HARDWARE( fxMesa
);
2036 else if (ctx
->Texture
.Unit
[0]._ReallyEnabled
== 0 &&
2037 ctx
->Texture
.Unit
[1]._ReallyEnabled
& (TEXTURE_1D_BIT
|TEXTURE_2D_BIT
)) {
2038 LOCK_HARDWARE( fxMesa
);
2039 setupTextureSingleTMU(ctx
, 1);
2040 UNLOCK_HARDWARE( fxMesa
);
2042 else if (ctx
->Texture
.Unit
[0]._ReallyEnabled
& (TEXTURE_1D_BIT
|TEXTURE_2D_BIT
) &&
2043 ctx
->Texture
.Unit
[1]._ReallyEnabled
& (TEXTURE_1D_BIT
|TEXTURE_2D_BIT
)) {
2044 LOCK_HARDWARE( fxMesa
);
2045 setupTextureDoubleTMU(ctx
);
2046 UNLOCK_HARDWARE( fxMesa
);
2049 /* disable hardware texturing */
2050 if (TDFX_IS_NAPALM(fxMesa
)) {
2051 fxMesa
->ColorCombineExt
.SourceA
= GR_CMBX_ITRGB
;
2052 fxMesa
->ColorCombineExt
.ModeA
= GR_FUNC_MODE_X
;
2053 fxMesa
->ColorCombineExt
.SourceB
= GR_CMBX_ZERO
;
2054 fxMesa
->ColorCombineExt
.ModeB
= GR_FUNC_MODE_ZERO
;
2055 fxMesa
->ColorCombineExt
.SourceC
= GR_CMBX_ZERO
;
2056 fxMesa
->ColorCombineExt
.InvertC
= FXTRUE
;
2057 fxMesa
->ColorCombineExt
.SourceD
= GR_CMBX_ZERO
;
2058 fxMesa
->ColorCombineExt
.InvertD
= FXFALSE
;
2059 fxMesa
->ColorCombineExt
.Shift
= 0;
2060 fxMesa
->ColorCombineExt
.Invert
= FXFALSE
;
2061 fxMesa
->AlphaCombineExt
.SourceA
= GR_CMBX_ITALPHA
;
2062 fxMesa
->AlphaCombineExt
.ModeA
= GR_FUNC_MODE_X
;
2063 fxMesa
->AlphaCombineExt
.SourceB
= GR_CMBX_ZERO
;
2064 fxMesa
->AlphaCombineExt
.ModeB
= GR_FUNC_MODE_ZERO
;
2065 fxMesa
->AlphaCombineExt
.SourceC
= GR_CMBX_ZERO
;
2066 fxMesa
->AlphaCombineExt
.InvertC
= FXTRUE
;
2067 fxMesa
->AlphaCombineExt
.SourceD
= GR_CMBX_ZERO
;
2068 fxMesa
->AlphaCombineExt
.InvertD
= FXFALSE
;
2069 fxMesa
->AlphaCombineExt
.Shift
= 0;
2070 fxMesa
->AlphaCombineExt
.Invert
= FXFALSE
;
2074 fxMesa
->ColorCombine
.Function
= GR_COMBINE_FUNCTION_LOCAL
;
2075 fxMesa
->ColorCombine
.Factor
= GR_COMBINE_FACTOR_NONE
;
2076 fxMesa
->ColorCombine
.Local
= GR_COMBINE_LOCAL_ITERATED
;
2077 fxMesa
->ColorCombine
.Other
= GR_COMBINE_OTHER_NONE
;
2078 fxMesa
->ColorCombine
.Invert
= FXFALSE
;
2079 fxMesa
->AlphaCombine
.Function
= GR_COMBINE_FUNCTION_LOCAL
;
2080 fxMesa
->AlphaCombine
.Factor
= GR_COMBINE_FACTOR_NONE
;
2081 fxMesa
->AlphaCombine
.Local
= GR_COMBINE_LOCAL_ITERATED
;
2082 fxMesa
->AlphaCombine
.Other
= GR_COMBINE_OTHER_NONE
;
2083 fxMesa
->AlphaCombine
.Invert
= FXFALSE
;
2086 fxMesa
->TexState
.Enabled
[0] = 0;
2087 fxMesa
->TexState
.Enabled
[1] = 0;
2088 fxMesa
->TexState
.EnvMode
[0] = 0;
2089 fxMesa
->TexState
.EnvMode
[1] = 0;
2091 fxMesa
->dirty
|= TDFX_UPLOAD_COLOR_COMBINE
;
2092 fxMesa
->dirty
|= TDFX_UPLOAD_ALPHA_COMBINE
;
2094 if (ctx
->Texture
.Unit
[0]._ReallyEnabled
!= 0 ||
2095 ctx
->Texture
.Unit
[1]._ReallyEnabled
!= 0) {
2096 /* software texture (cube map, rect tex, etc */
2097 FALLBACK(fxMesa
, TDFX_FALLBACK_TEXTURE_ENV
, GL_TRUE
);
2105 * This is a special case of texture state update.
2106 * It's used when we've simply bound a new texture to a texture
2107 * unit and the new texture has the exact same attributes as the
2108 * previously bound texture.
2109 * This is very common in Quake3.
2112 tdfxUpdateTextureBinding( GLcontext
*ctx
)
2114 tdfxContextPtr fxMesa
= TDFX_CONTEXT(ctx
);
2115 struct gl_texture_object
*tObj0
= ctx
->Texture
.Unit
[0]._Current
;
2116 struct gl_texture_object
*tObj1
= ctx
->Texture
.Unit
[1]._Current
;
2117 tdfxTexInfo
*ti0
= TDFX_TEXTURE_DATA(tObj0
);
2118 tdfxTexInfo
*ti1
= TDFX_TEXTURE_DATA(tObj1
);
2120 const struct gl_shared_state
*mesaShared
= fxMesa
->glCtx
->Shared
;
2121 const struct tdfxSharedState
*shared
= (struct tdfxSharedState
*) mesaShared
->DriverData
;
2124 fxMesa
->sScale0
= ti0
->sScale
;
2125 fxMesa
->tScale0
= ti0
->tScale
;
2126 if (ti0
->info
.format
== GR_TEXFMT_P_8
) {
2127 fxMesa
->TexPalette
.Type
= ti0
->paltype
;
2128 fxMesa
->TexPalette
.Data
= &(ti0
->palette
);
2129 fxMesa
->dirty
|= TDFX_UPLOAD_TEXTURE_PALETTE
;
2131 else if (ti1
&& ti1
->info
.format
== GR_TEXFMT_P_8
) {
2132 fxMesa
->TexPalette
.Type
= ti1
->paltype
;
2133 fxMesa
->TexPalette
.Data
= &(ti1
->palette
);
2134 fxMesa
->dirty
|= TDFX_UPLOAD_TEXTURE_PALETTE
;
2138 fxMesa
->sScale1
= ti1
->sScale
;
2139 fxMesa
->tScale1
= ti1
->tScale
;
2142 if (ctx
->Texture
.Unit
[0]._ReallyEnabled
& (TEXTURE_1D_BIT
|TEXTURE_2D_BIT
) &&
2143 ctx
->Texture
.Unit
[0]._ReallyEnabled
== 0) {
2144 /* Only unit 0 2D enabled */
2145 if (shared
->umaTexMemory
) {
2146 fxMesa
->TexSource
[0].StartAddress
= ti0
->tm
[0]->startAddr
;
2147 fxMesa
->TexSource
[0].EvenOdd
= GR_MIPMAPLEVELMASK_BOTH
;
2148 fxMesa
->TexSource
[0].Info
= &(ti0
->info
);
2151 if (ti0
->LODblend
&& ti0
->whichTMU
== TDFX_TMU_SPLIT
) {
2152 fxMesa
->TexSource
[0].StartAddress
= ti0
->tm
[TDFX_TMU0
]->startAddr
;
2153 fxMesa
->TexSource
[0].EvenOdd
= GR_MIPMAPLEVELMASK_ODD
;
2154 fxMesa
->TexSource
[0].Info
= &(ti0
->info
);
2155 fxMesa
->TexSource
[1].StartAddress
= ti0
->tm
[TDFX_TMU1
]->startAddr
;
2156 fxMesa
->TexSource
[1].EvenOdd
= GR_MIPMAPLEVELMASK_EVEN
;
2157 fxMesa
->TexSource
[1].Info
= &(ti0
->info
);
2161 if (ti0
->whichTMU
== TDFX_TMU_BOTH
)
2164 tmu
= ti0
->whichTMU
;
2165 fxMesa
->TexSource
[0].Info
= NULL
;
2166 fxMesa
->TexSource
[1].Info
= NULL
;
2168 fxMesa
->TexSource
[tmu
].StartAddress
= ti0
->tm
[tmu
]->startAddr
;
2169 fxMesa
->TexSource
[tmu
].EvenOdd
= GR_MIPMAPLEVELMASK_BOTH
;
2170 fxMesa
->TexSource
[tmu
].Info
= &(ti0
->info
);
2175 else if (ctx
->Texture
.Unit
[0]._ReallyEnabled
== 0 &&
2176 ctx
->Texture
.Unit
[0]._ReallyEnabled
& (TEXTURE_1D_BIT
|TEXTURE_2D_BIT
)) {
2177 /* Only unit 1 2D enabled */
2178 if (shared
->umaTexMemory
) {
2179 fxMesa
->TexSource
[0].StartAddress
= ti1
->tm
[0]->startAddr
;
2180 fxMesa
->TexSource
[0].EvenOdd
= GR_MIPMAPLEVELMASK_BOTH
;
2181 fxMesa
->TexSource
[0].Info
= &(ti1
->info
);
2184 else if (ctx
->Texture
.Unit
[0]._ReallyEnabled
& (TEXTURE_1D_BIT
|TEXTURE_2D_BIT
) &&
2185 ctx
->Texture
.Unit
[0]._ReallyEnabled
& (TEXTURE_1D_BIT
|TEXTURE_2D_BIT
)) {
2186 /* Both 2D enabled */
2187 if (shared
->umaTexMemory
) {
2188 const FxU32 tmu0
= 0, tmu1
= 1;
2189 fxMesa
->TexSource
[tmu0
].StartAddress
= ti0
->tm
[0]->startAddr
;
2190 fxMesa
->TexSource
[tmu0
].EvenOdd
= GR_MIPMAPLEVELMASK_BOTH
;
2191 fxMesa
->TexSource
[tmu0
].Info
= &(ti0
->info
);
2193 fxMesa
->TexSource
[tmu1
].StartAddress
= ti1
->tm
[0]->startAddr
;
2194 fxMesa
->TexSource
[tmu1
].EvenOdd
= GR_MIPMAPLEVELMASK_BOTH
;
2195 fxMesa
->TexSource
[tmu1
].Info
= &(ti1
->info
);
2198 const FxU32 tmu0
= 0, tmu1
= 1;
2199 fxMesa
->TexSource
[tmu0
].StartAddress
= ti0
->tm
[tmu0
]->startAddr
;
2200 fxMesa
->TexSource
[tmu0
].EvenOdd
= GR_MIPMAPLEVELMASK_BOTH
;
2201 fxMesa
->TexSource
[tmu0
].Info
= &(ti0
->info
);
2203 fxMesa
->TexSource
[tmu1
].StartAddress
= ti1
->tm
[tmu1
]->startAddr
;
2204 fxMesa
->TexSource
[tmu1
].EvenOdd
= GR_MIPMAPLEVELMASK_BOTH
;
2205 fxMesa
->TexSource
[tmu1
].Info
= &(ti1
->info
);
2210 fxMesa
->dirty
|= TDFX_UPLOAD_TEXTURE_SOURCE
;