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 * Gareth Hughes <gareth@valinux.com>, 29 Sep - 1 Oct 2000
33 * Gareth Hughes <gareth@valinux.com>
34 * Brian Paul <brianp@valinux.com>
38 #include "tdfx_state.h"
40 #include "tdfx_texman.h"
41 #include "tdfx_texstate.h"
44 /* =============================================================
49 * These macros are used below when handling COMBINE_EXT.
51 #define TEXENV_OPERAND_INVERTED(operand) \
52 (((operand) == GL_ONE_MINUS_SRC_ALPHA) \
53 || ((operand) == GL_ONE_MINUS_SRC_COLOR))
54 #define TEXENV_OPERAND_ALPHA(operand) \
55 (((operand) == GL_SRC_ALPHA) || ((operand) == GL_ONE_MINUS_SRC_ALPHA))
56 #define TEXENV_SETUP_ARG_A(param, source, operand, iteratedAlpha) \
59 param = GR_CMBX_LOCAL_TEXTURE_ALPHA; \
61 case GL_CONSTANT_EXT: \
62 param = GR_CMBX_TMU_CALPHA; \
64 case GL_PRIMARY_COLOR_EXT: \
65 param = GR_CMBX_ITALPHA; \
67 case GL_PREVIOUS_EXT: \
68 param = iteratedAlpha; \
72 * This is here just to keep from getting \
73 * compiler warnings. \
75 param = GR_CMBX_ZERO; \
79 #define TEXENV_SETUP_ARG_RGB(param, source, operand, iteratedColor, iteratedAlpha) \
80 if (!TEXENV_OPERAND_ALPHA(operand)) { \
83 param = GR_CMBX_LOCAL_TEXTURE_RGB; \
85 case GL_CONSTANT_EXT: \
86 param = GR_CMBX_TMU_CCOLOR; \
88 case GL_PRIMARY_COLOR_EXT: \
89 param = GR_CMBX_ITRGB; \
91 case GL_PREVIOUS_EXT: \
92 param = iteratedColor; \
96 * This is here just to keep from getting \
97 * compiler warnings. \
99 param = GR_CMBX_ZERO; \
105 param = GR_CMBX_LOCAL_TEXTURE_ALPHA; \
107 case GL_CONSTANT_EXT: \
108 param = GR_CMBX_TMU_CALPHA; \
110 case GL_PRIMARY_COLOR_EXT: \
111 param = GR_CMBX_ITALPHA; \
113 case GL_PREVIOUS_EXT: \
114 param = iteratedAlpha; \
118 * This is here just to keep from getting \
119 * compiler warnings. \
121 param = GR_CMBX_ZERO; \
126 #define TEXENV_SETUP_MODE_RGB(param, operand) \
130 param = GR_FUNC_MODE_X; \
132 case GL_ONE_MINUS_SRC_ALPHA: \
133 case GL_ONE_MINUS_SRC_COLOR: \
134 param = GR_FUNC_MODE_ONE_MINUS_X; \
137 param = GR_FUNC_MODE_ZERO; \
141 #define TEXENV_SETUP_MODE_A(param, operand) \
144 param = GR_FUNC_MODE_X; \
146 case GL_ONE_MINUS_SRC_ALPHA: \
147 param = GR_FUNC_MODE_ONE_MINUS_X; \
150 param = GR_FUNC_MODE_ZERO; \
157 * Setup a texture environment on Voodoo5.
158 * Return GL_TRUE for success, GL_FALSE for failure.
159 * If we fail, we'll have to use software rendering.
162 SetupTexEnvNapalm(GLcontext
*ctx
, GLboolean useIteratedRGBA
,
163 const struct gl_texture_unit
*texUnit
, GLenum baseFormat
,
164 struct tdfx_texcombine_ext
*env
)
166 tdfxContextPtr fxMesa
= TDFX_CONTEXT(ctx
);
167 GrTCCUColor_t incomingRGB
, incomingAlpha
;
168 const GLenum envMode
= texUnit
->EnvMode
;
170 if (useIteratedRGBA
) {
171 incomingRGB
= GR_CMBX_ITRGB
;
172 incomingAlpha
= GR_CMBX_ITALPHA
;
175 incomingRGB
= GR_CMBX_OTHER_TEXTURE_RGB
;
176 incomingAlpha
= GR_CMBX_OTHER_TEXTURE_ALPHA
;
180 env
->Color
.Shift
= 0;
181 env
->Color
.Invert
= FXFALSE
;
182 env
->Alpha
.Shift
= 0;
183 env
->Alpha
.Invert
= FXFALSE
;
187 /* -- Setup RGB combiner */
188 if (baseFormat
== GL_ALPHA
) {
190 env
->Color
.SourceA
= incomingRGB
;
194 env
->Color
.SourceA
= GR_CMBX_LOCAL_TEXTURE_RGB
;
196 env
->Color
.ModeA
= GR_FUNC_MODE_X
;
197 env
->Color
.SourceB
= GR_CMBX_ZERO
;
198 env
->Color
.ModeB
= GR_FUNC_MODE_ZERO
;
199 env
->Color
.SourceC
= GR_CMBX_ZERO
;
200 env
->Color
.InvertC
= FXTRUE
;
201 env
->Color
.SourceD
= GR_CMBX_ZERO
;
202 env
->Color
.InvertD
= FXFALSE
;
203 /* -- Setup Alpha combiner */
204 if (baseFormat
== GL_LUMINANCE
|| baseFormat
== GL_RGB
) {
206 env
->Alpha
.SourceD
= incomingAlpha
;
210 env
->Alpha
.SourceD
= GR_CMBX_LOCAL_TEXTURE_ALPHA
;
212 env
->Alpha
.SourceA
= GR_CMBX_ITALPHA
;
213 env
->Alpha
.ModeA
= GR_FUNC_MODE_ZERO
;
214 env
->Alpha
.SourceB
= GR_CMBX_ITALPHA
;
215 env
->Alpha
.ModeB
= GR_FUNC_MODE_ZERO
;
216 env
->Alpha
.SourceC
= GR_CMBX_ZERO
;
217 env
->Alpha
.InvertC
= FXFALSE
;
218 env
->Alpha
.InvertD
= FXFALSE
;
222 /* -- Setup RGB combiner */
223 if (baseFormat
== GL_ALPHA
) {
225 env
->Color
.SourceC
= GR_CMBX_ZERO
;
226 env
->Color
.InvertC
= FXTRUE
;
229 /* Result = Frag * Tex */
230 env
->Color
.SourceC
= GR_CMBX_LOCAL_TEXTURE_RGB
;
231 env
->Color
.InvertC
= FXFALSE
;
233 env
->Color
.SourceA
= incomingRGB
;
234 env
->Color
.ModeA
= GR_FUNC_MODE_X
;
235 env
->Color
.SourceB
= GR_CMBX_ZERO
;
236 env
->Color
.ModeB
= GR_FUNC_MODE_ZERO
;
237 env
->Color
.SourceD
= GR_CMBX_ZERO
;
238 env
->Color
.InvertD
= FXFALSE
;
239 /* -- Setup Alpha combiner */
240 if (baseFormat
== GL_LUMINANCE
|| baseFormat
== GL_RGB
) {
242 env
->Alpha
.SourceA
= incomingAlpha
;
243 env
->Alpha
.SourceC
= GR_CMBX_ZERO
;
244 env
->Alpha
.InvertC
= FXTRUE
;
248 env
->Alpha
.SourceA
= GR_CMBX_LOCAL_TEXTURE_ALPHA
;
249 env
->Alpha
.SourceC
= incomingAlpha
;
250 env
->Alpha
.InvertC
= FXFALSE
;
252 env
->Alpha
.ModeA
= GR_FUNC_MODE_X
;
253 env
->Alpha
.SourceB
= GR_CMBX_ITALPHA
;
254 env
->Alpha
.ModeB
= GR_FUNC_MODE_ZERO
;
255 env
->Alpha
.SourceD
= GR_CMBX_ZERO
;
256 env
->Alpha
.InvertD
= FXFALSE
;
260 /* -- Setup RGB combiner */
261 if (baseFormat
== GL_RGB
) {
263 env
->Color
.SourceB
= GR_CMBX_ZERO
;
264 env
->Color
.ModeB
= GR_FUNC_MODE_X
;
265 env
->Color
.SourceC
= GR_CMBX_ZERO
;
266 env
->Color
.InvertC
= FXTRUE
;
267 env
->Color
.SourceD
= GR_CMBX_ZERO
;
268 env
->Color
.InvertD
= FXFALSE
;
271 /* Rv = Rf * (1 - At) + Rt * At */
272 env
->Color
.SourceB
= incomingRGB
;
273 env
->Color
.ModeB
= GR_FUNC_MODE_NEGATIVE_X
;
274 env
->Color
.SourceC
= GR_CMBX_LOCAL_TEXTURE_ALPHA
;
275 env
->Color
.InvertC
= FXFALSE
;
276 env
->Color
.SourceD
= GR_CMBX_B
;
277 env
->Color
.InvertD
= FXFALSE
;
279 env
->Color
.SourceA
= GR_CMBX_LOCAL_TEXTURE_RGB
;
280 env
->Color
.ModeA
= GR_FUNC_MODE_X
;
281 /* -- Setup Alpha combiner */
283 env
->Alpha
.SourceA
= incomingAlpha
;
284 env
->Alpha
.ModeA
= GR_FUNC_MODE_X
;
285 env
->Alpha
.SourceB
= GR_CMBX_ITALPHA
;
286 env
->Alpha
.ModeB
= GR_FUNC_MODE_ZERO
;
287 env
->Alpha
.SourceC
= GR_CMBX_ZERO
;
288 env
->Alpha
.InvertC
= FXTRUE
;
289 env
->Alpha
.SourceD
= GR_CMBX_ZERO
;
290 env
->Alpha
.InvertD
= FXFALSE
;
294 /* -- Setup RGB combiner */
295 if (baseFormat
== GL_ALPHA
) {
297 env
->Color
.SourceA
= incomingRGB
;
298 env
->Color
.ModeA
= GR_FUNC_MODE_X
;
299 env
->Color
.SourceB
= GR_CMBX_ZERO
;
300 env
->Color
.ModeB
= GR_FUNC_MODE_ZERO
;
301 env
->Color
.SourceC
= GR_CMBX_ZERO
;
302 env
->Color
.InvertC
= FXTRUE
;
303 env
->Color
.SourceD
= GR_CMBX_ZERO
;
304 env
->Color
.InvertD
= FXFALSE
;
307 /* Rv = Rf * (1 - Rt) + Rc * Rt */
308 env
->Color
.SourceA
= GR_CMBX_TMU_CCOLOR
;
309 env
->Color
.ModeA
= GR_FUNC_MODE_X
;
310 env
->Color
.SourceB
= incomingRGB
;
311 env
->Color
.ModeB
= GR_FUNC_MODE_NEGATIVE_X
;
312 env
->Color
.SourceC
= GR_CMBX_LOCAL_TEXTURE_RGB
;
313 env
->Color
.InvertC
= FXFALSE
;
314 env
->Color
.SourceD
= GR_CMBX_B
;
315 env
->Color
.InvertD
= FXFALSE
;
317 /* -- Setup Alpha combiner */
318 if (baseFormat
== GL_LUMINANCE
|| baseFormat
== GL_RGB
) {
320 env
->Alpha
.SourceA
= incomingAlpha
;
321 env
->Alpha
.ModeA
= GR_FUNC_MODE_X
;
322 env
->Alpha
.SourceB
= GR_CMBX_ZERO
;
323 env
->Alpha
.ModeB
= GR_FUNC_MODE_ZERO
;
324 env
->Alpha
.SourceC
= GR_CMBX_ZERO
;
325 env
->Alpha
.InvertC
= FXTRUE
;
326 env
->Alpha
.SourceD
= GR_CMBX_ZERO
;
327 env
->Alpha
.InvertD
= FXFALSE
;
329 else if (baseFormat
== GL_INTENSITY
) {
330 /* Av = Af * (1 - It) + Ac * It */
331 env
->Alpha
.SourceA
= GR_CMBX_TMU_CALPHA
;
332 env
->Alpha
.ModeA
= GR_FUNC_MODE_X
;
333 env
->Alpha
.SourceB
= incomingAlpha
;
334 env
->Alpha
.ModeB
= GR_FUNC_MODE_NEGATIVE_X
;
335 env
->Alpha
.SourceC
= GR_CMBX_LOCAL_TEXTURE_ALPHA
;
336 env
->Alpha
.InvertC
= FXFALSE
;
337 env
->Alpha
.SourceD
= GR_CMBX_B
;
338 env
->Alpha
.InvertD
= FXFALSE
;
342 env
->Alpha
.SourceA
= GR_CMBX_LOCAL_TEXTURE_ALPHA
;
343 env
->Alpha
.ModeA
= GR_FUNC_MODE_X
;
344 env
->Alpha
.SourceB
= GR_CMBX_ITALPHA
;
345 env
->Alpha
.ModeB
= GR_FUNC_MODE_ZERO
;
346 env
->Alpha
.SourceC
= incomingAlpha
;
347 env
->Alpha
.InvertC
= FXFALSE
;
348 env
->Alpha
.SourceD
= GR_CMBX_ZERO
;
349 env
->Alpha
.InvertD
= FXFALSE
;
351 /* Also have to set up the tex env constant color */
352 env
->EnvColor
= PACK_RGBA32(texUnit
->EnvColor
[0] * 255.0F
,
353 texUnit
->EnvColor
[1] * 255.0F
,
354 texUnit
->EnvColor
[2] * 255.0F
,
355 texUnit
->EnvColor
[3] * 255.0F
);
358 /* -- Setup RGB combiner */
359 if (baseFormat
== GL_ALPHA
) {
361 env
->Color
.SourceB
= GR_CMBX_ZERO
;
362 env
->Color
.ModeB
= GR_FUNC_MODE_ZERO
;
366 env
->Color
.SourceB
= GR_CMBX_LOCAL_TEXTURE_RGB
;
367 env
->Color
.ModeB
= GR_FUNC_MODE_X
;
369 env
->Color
.SourceA
= incomingRGB
;
370 env
->Color
.ModeA
= GR_FUNC_MODE_X
;
371 env
->Color
.SourceC
= GR_CMBX_ZERO
;
372 env
->Color
.InvertC
= FXTRUE
;
373 env
->Color
.SourceD
= GR_CMBX_ZERO
;
374 env
->Color
.InvertD
= FXFALSE
;
375 /* -- Setup Alpha combiner */
376 if (baseFormat
== GL_LUMINANCE
|| baseFormat
== GL_RGB
) {
378 env
->Alpha
.SourceA
= incomingAlpha
;
379 env
->Alpha
.SourceB
= GR_CMBX_ITALPHA
;
380 env
->Alpha
.ModeB
= GR_FUNC_MODE_ZERO
;
381 env
->Alpha
.SourceC
= GR_CMBX_ZERO
;
382 env
->Alpha
.InvertC
= FXTRUE
;
385 else if (baseFormat
== GL_INTENSITY
) {
387 env
->Alpha
.SourceA
= incomingAlpha
;
388 env
->Alpha
.SourceB
= GR_CMBX_LOCAL_TEXTURE_ALPHA
;
389 env
->Alpha
.ModeB
= GR_FUNC_MODE_X
;
390 env
->Alpha
.SourceC
= GR_CMBX_ZERO
;
391 env
->Alpha
.InvertC
= FXTRUE
;
395 env
->Alpha
.SourceA
= GR_CMBX_LOCAL_TEXTURE_ALPHA
;
396 env
->Alpha
.SourceB
= GR_CMBX_ITALPHA
;
397 env
->Alpha
.ModeB
= GR_FUNC_MODE_ZERO
;
398 env
->Alpha
.SourceC
= incomingAlpha
;
399 env
->Alpha
.InvertC
= FXFALSE
;
401 env
->Alpha
.ModeA
= GR_FUNC_MODE_X
;
402 env
->Alpha
.SourceD
= GR_CMBX_ZERO
;
403 env
->Alpha
.InvertD
= FXFALSE
;
408 FxU32 A_RGB
, B_RGB
, C_RGB
, D_RGB
;
409 FxU32 Amode_RGB
, Bmode_RGB
;
410 FxBool Cinv_RGB
, Dinv_RGB
, Ginv_RGB
;
412 FxU32 A_A
, B_A
, C_A
, D_A
;
413 FxU32 Amode_A
, Bmode_A
;
414 FxBool Cinv_A
, Dinv_A
, Ginv_A
;
419 * In the formulas below, we write:
420 * o "1(x)" for the identity function applied to x,
422 * o "0(x)" for the constant function 0, so
423 * 0(x) = 0 for all values of x.
425 * Calculate the color combination.
427 Shift_RGB
= texUnit
->CombineScaleShiftRGB
;
428 Shift_A
= texUnit
->CombineScaleShiftA
;
429 switch (texUnit
->CombineModeRGB
) {
432 * The formula is: Arg0
433 * We implement this by the formula:
434 * (Arg0 + 0(0))*(1-0) + 0
436 TEXENV_SETUP_ARG_RGB(A_RGB
,
437 texUnit
->CombineSourceRGB
[0],
438 texUnit
->CombineOperandRGB
[0],
439 incomingRGB
, incomingAlpha
);
440 TEXENV_SETUP_MODE_RGB(Amode_RGB
,
441 texUnit
->CombineOperandRGB
[0]);
442 B_RGB
= C_RGB
= D_RGB
= GR_CMBX_ZERO
;
443 Bmode_RGB
= GR_FUNC_MODE_ZERO
;
445 Dinv_RGB
= Ginv_RGB
= FXFALSE
;
449 * The formula is: Arg0 * Arg1
451 * We implement this by the formula
452 * (Arg0 + 0(0)) * Arg1 + 0(0)
454 TEXENV_SETUP_ARG_RGB(A_RGB
,
455 texUnit
->CombineSourceRGB
[0],
456 texUnit
->CombineOperandRGB
[0],
457 incomingRGB
, incomingAlpha
);
458 TEXENV_SETUP_MODE_RGB(Amode_RGB
,
459 texUnit
->CombineOperandRGB
[0]);
460 B_RGB
= GR_CMBX_ZERO
;
461 Bmode_RGB
= GR_CMBX_ZERO
;
462 TEXENV_SETUP_ARG_RGB(C_RGB
,
463 texUnit
->CombineSourceRGB
[1],
464 texUnit
->CombineOperandRGB
[1],
465 incomingRGB
, incomingAlpha
);
466 Cinv_RGB
= TEXENV_OPERAND_INVERTED
467 (texUnit
->CombineOperandRGB
[1]);
468 D_RGB
= GR_CMBX_ZERO
;
469 Dinv_RGB
= Ginv_RGB
= FXFALSE
;
473 * The formula is Arg0 + Arg1
475 TEXENV_SETUP_ARG_RGB(A_RGB
,
476 texUnit
->CombineSourceRGB
[0],
477 texUnit
->CombineOperandRGB
[0],
478 incomingRGB
, incomingAlpha
);
479 TEXENV_SETUP_MODE_RGB(Amode_RGB
,
480 texUnit
->CombineOperandRGB
[0]);
481 TEXENV_SETUP_ARG_RGB(B_RGB
,
482 texUnit
->CombineSourceRGB
[1],
483 texUnit
->CombineOperandRGB
[1],
484 incomingRGB
, incomingAlpha
);
485 TEXENV_SETUP_MODE_RGB(Bmode_RGB
,
486 texUnit
->CombineOperandRGB
[1]);
487 C_RGB
= D_RGB
= GR_CMBX_ZERO
;
489 Dinv_RGB
= Ginv_RGB
= FXFALSE
;
491 case GL_ADD_SIGNED_EXT
:
493 * The formula is: Arg0 + Arg1 - 0.5.
494 * We compute this by calculating:
495 * (Arg0 - 1/2) + Arg1 if op0 is SRC_{COLOR,ALPHA}
496 * Arg0 + (Arg1 - 1/2) if op1 is SRC_{COLOR,ALPHA}
497 * If both op0 and op1 are ONE_MINUS_SRC_{COLOR,ALPHA}
498 * we cannot implement the formula properly.
500 TEXENV_SETUP_ARG_RGB(A_RGB
,
501 texUnit
->CombineSourceRGB
[0],
502 texUnit
->CombineOperandRGB
[0],
503 incomingRGB
, incomingAlpha
);
504 TEXENV_SETUP_ARG_RGB(B_RGB
,
505 texUnit
->CombineSourceRGB
[1],
506 texUnit
->CombineOperandRGB
[1],
507 incomingRGB
, incomingAlpha
);
508 if (!TEXENV_OPERAND_INVERTED(texUnit
->CombineOperandRGB
[0])) {
510 * A is not inverted. So, choose it.
512 Amode_RGB
= GR_FUNC_MODE_X_MINUS_HALF
;
513 if (!TEXENV_OPERAND_INVERTED
514 (texUnit
->CombineOperandRGB
[1])) {
515 Bmode_RGB
= GR_FUNC_MODE_X
;
518 Bmode_RGB
= GR_FUNC_MODE_ONE_MINUS_X
;
523 * A is inverted, so try to subtract 1/2
526 Amode_RGB
= GR_FUNC_MODE_ONE_MINUS_X
;
527 if (!TEXENV_OPERAND_INVERTED
528 (texUnit
->CombineOperandRGB
[1])) {
529 Bmode_RGB
= GR_FUNC_MODE_X_MINUS_HALF
;
533 * Both are inverted. This is the case
534 * we cannot handle properly. We just
535 * choose to not add the - 1/2.
537 Bmode_RGB
= GR_FUNC_MODE_ONE_MINUS_X
;
541 C_RGB
= D_RGB
= GR_CMBX_ZERO
;
543 Dinv_RGB
= Ginv_RGB
= FXFALSE
;
545 case GL_INTERPOLATE_EXT
:
547 * The formula is: Arg0 * Arg2 + Arg1 * (1 - Arg2).
548 * We compute this by the formula:
549 * (Arg0 - Arg1) * Arg2 + Arg1
550 * == Arg0 * Arg2 - Arg1 * Arg2 + Arg1
551 * == Arg0 * Arg2 + Arg1 * (1 - Arg2)
552 * However, if both Arg1 is ONE_MINUS_X, the HW does
553 * not support it properly.
555 TEXENV_SETUP_ARG_RGB(A_RGB
,
556 texUnit
->CombineSourceRGB
[0],
557 texUnit
->CombineOperandRGB
[0],
558 incomingRGB
, incomingAlpha
);
559 TEXENV_SETUP_MODE_RGB(Amode_RGB
,
560 texUnit
->CombineOperandRGB
[0]);
561 TEXENV_SETUP_ARG_RGB(B_RGB
,
562 texUnit
->CombineSourceRGB
[1],
563 texUnit
->CombineOperandRGB
[1],
564 incomingRGB
, incomingAlpha
);
565 if (TEXENV_OPERAND_INVERTED(texUnit
->CombineOperandRGB
[1])) {
567 * This case is wrong.
569 Bmode_RGB
= GR_FUNC_MODE_NEGATIVE_X
;
573 Bmode_RGB
= GR_FUNC_MODE_NEGATIVE_X
;
576 * The Source/Operand for the C value must
577 * specify some kind of alpha value.
579 TEXENV_SETUP_ARG_A(C_RGB
,
580 texUnit
->CombineSourceRGB
[2],
581 texUnit
->CombineOperandRGB
[2],
585 Dinv_RGB
= Ginv_RGB
= FXFALSE
;
589 * This is here mostly to keep from getting
590 * a compiler warning about these not being set.
591 * However, this should set all the texture values
594 A_RGB
= B_RGB
= C_RGB
= D_RGB
= GR_CMBX_ZERO
;
595 Amode_RGB
= Bmode_RGB
= GR_FUNC_MODE_X
;
596 Cinv_RGB
= Dinv_RGB
= Ginv_RGB
= FXFALSE
;
600 * Calculate the alpha combination.
602 switch (texUnit
->CombineModeA
) {
605 * The formula is: Arg0
606 * We implement this by the formula:
607 * (Arg0 + 0(0))*(1-0) + 0
609 TEXENV_SETUP_ARG_A(A_A
,
610 texUnit
->CombineSourceA
[0],
611 texUnit
->CombineOperandA
[0],
613 TEXENV_SETUP_MODE_A(Amode_A
,
614 texUnit
->CombineOperandA
[0]);
615 B_A
= GR_CMBX_ITALPHA
;
616 Bmode_A
= GR_FUNC_MODE_ZERO
;
617 C_A
= D_A
= GR_CMBX_ZERO
;
619 Dinv_A
= Ginv_A
= FXFALSE
;
623 * The formula is: Arg0 * Arg1
625 * We implement this by the formula
626 * (Arg0 + 0(0)) * Arg1 + 0(0)
628 TEXENV_SETUP_ARG_A(A_A
,
629 texUnit
->CombineSourceA
[0],
630 texUnit
->CombineOperandA
[0],
632 TEXENV_SETUP_MODE_A(Amode_A
,
633 texUnit
->CombineOperandA
[0]);
635 Bmode_A
= GR_CMBX_ZERO
;
636 TEXENV_SETUP_ARG_A(C_A
,
637 texUnit
->CombineSourceA
[1],
638 texUnit
->CombineOperandA
[1],
640 Cinv_A
= TEXENV_OPERAND_INVERTED
641 (texUnit
->CombineOperandA
[1]);
643 Dinv_A
= Ginv_A
= FXFALSE
;
647 * The formula is Arg0 + Arg1
649 TEXENV_SETUP_ARG_A(A_A
,
650 texUnit
->CombineSourceA
[0],
651 texUnit
->CombineOperandA
[0],
653 TEXENV_SETUP_MODE_A(Amode_A
,
654 texUnit
->CombineOperandA
[0]);
655 TEXENV_SETUP_ARG_A(B_A
,
656 texUnit
->CombineSourceA
[1],
657 texUnit
->CombineOperandA
[1],
659 TEXENV_SETUP_MODE_A(Bmode_A
,
660 texUnit
->CombineOperandA
[1]);
661 C_A
= D_A
= GR_CMBX_ZERO
;
663 Dinv_A
= Ginv_A
= FXFALSE
;
665 case GL_ADD_SIGNED_EXT
:
667 * The formula is: Arg0 + Arg1 - 0.5.
668 * We compute this by calculating:
669 * (Arg0 - 1/2) + Arg1 if op0 is SRC_{COLOR,ALPHA}
670 * Arg0 + (Arg1 - 1/2) if op1 is SRC_{COLOR,ALPHA}
671 * If both op0 and op1 are ONE_MINUS_SRC_{COLOR,ALPHA}
672 * we cannot implement the formula properly.
674 TEXENV_SETUP_ARG_A(A_A
,
675 texUnit
->CombineSourceA
[0],
676 texUnit
->CombineOperandA
[0],
678 TEXENV_SETUP_ARG_A(B_A
,
679 texUnit
->CombineSourceA
[1],
680 texUnit
->CombineOperandA
[1],
682 if (!TEXENV_OPERAND_INVERTED(texUnit
->CombineOperandA
[0])) {
684 * A is not inverted. So, choose it.
686 Amode_A
= GR_FUNC_MODE_X_MINUS_HALF
;
687 if (!TEXENV_OPERAND_INVERTED
688 (texUnit
->CombineOperandA
[1])) {
689 Bmode_A
= GR_FUNC_MODE_X
;
691 Bmode_A
= GR_FUNC_MODE_ONE_MINUS_X
;
695 * A is inverted, so try to subtract 1/2
698 Amode_A
= GR_FUNC_MODE_ONE_MINUS_X
;
699 if (!TEXENV_OPERAND_INVERTED
700 (texUnit
->CombineOperandA
[1])) {
701 Bmode_A
= GR_FUNC_MODE_X_MINUS_HALF
;
704 * Both are inverted. This is the case
705 * we cannot handle properly. We just
706 * choose to not add the - 1/2.
708 Bmode_A
= GR_FUNC_MODE_ONE_MINUS_X
;
712 C_A
= D_A
= GR_CMBX_ZERO
;
714 Dinv_A
= Ginv_A
= FXFALSE
;
716 case GL_INTERPOLATE_EXT
:
718 * The formula is: Arg0 * Arg2 + Arg1 * (1 - Arg2).
719 * We compute this by the formula:
720 * (Arg0 - Arg1) * Arg2 + Arg1
721 * == Arg0 * Arg2 - Arg1 * Arg2 + Arg1
722 * == Arg0 * Arg2 + Arg1 * (1 - Arg2)
723 * However, if both Arg1 is ONE_MINUS_X, the HW does
724 * not support it properly.
726 TEXENV_SETUP_ARG_A(A_A
,
727 texUnit
->CombineSourceA
[0],
728 texUnit
->CombineOperandA
[0],
730 TEXENV_SETUP_MODE_A(Amode_A
,
731 texUnit
->CombineOperandA
[0]);
732 TEXENV_SETUP_ARG_A(B_A
,
733 texUnit
->CombineSourceA
[1],
734 texUnit
->CombineOperandA
[1],
736 if (!TEXENV_OPERAND_INVERTED(texUnit
->CombineOperandA
[1])) {
737 Bmode_A
= GR_FUNC_MODE_NEGATIVE_X
;
741 * This case is wrong.
743 Bmode_A
= GR_FUNC_MODE_NEGATIVE_X
;
747 * The Source/Operand for the C value must
748 * specify some kind of alpha value.
750 TEXENV_SETUP_ARG_A(C_A
,
751 texUnit
->CombineSourceA
[2],
752 texUnit
->CombineOperandA
[2],
756 Dinv_A
= Ginv_A
= FXFALSE
;
760 * This is here mostly to keep from getting
761 * a compiler warning about these not being set.
762 * However, this should set all the alpha values
765 A_A
= B_A
= C_A
= D_A
= GR_CMBX_ZERO
;
766 Amode_A
= Bmode_A
= GR_FUNC_MODE_X
;
767 Cinv_A
= Dinv_A
= FXFALSE
;
772 * Save the parameters.
774 env
->Color
.SourceA
= A_RGB
;
775 env
->Color
.ModeA
= Amode_RGB
;
776 env
->Color
.SourceB
= B_RGB
;
777 env
->Color
.ModeB
= Bmode_RGB
;
778 env
->Color
.SourceC
= C_RGB
;
779 env
->Color
.InvertC
= Cinv_RGB
;
780 env
->Color
.SourceD
= D_RGB
;
781 env
->Color
.InvertD
= Dinv_RGB
;
782 env
->Color
.Shift
= Shift_RGB
;
783 env
->Color
.Invert
= Ginv_RGB
;
784 env
->Alpha
.SourceA
= A_A
;
785 env
->Alpha
.ModeA
= Amode_A
;
786 env
->Alpha
.SourceB
= B_A
;
787 env
->Alpha
.ModeB
= Bmode_A
;
788 env
->Alpha
.SourceC
= C_A
;
789 env
->Alpha
.InvertC
= Cinv_A
;
790 env
->Alpha
.SourceD
= D_A
;
791 env
->Alpha
.InvertD
= Dinv_A
;
792 env
->Alpha
.Shift
= Shift_A
;
793 env
->Alpha
.Invert
= Ginv_A
;
794 env
->EnvColor
= PACK_RGBA32(texUnit
->EnvColor
[0] * 255.0F
,
795 texUnit
->EnvColor
[1] * 255.0F
,
796 texUnit
->EnvColor
[2] * 255.0F
,
797 texUnit
->EnvColor
[3] * 255.0F
);
802 _mesa_problem(ctx
, "%s: Bad envMode", __FUNCTION__
);
805 fxMesa
->dirty
|= TDFX_UPLOAD_TEXTURE_ENV
;
807 fxMesa
->ColorCombineExt
.SourceA
= GR_CMBX_TEXTURE_RGB
;
808 fxMesa
->ColorCombineExt
.ModeA
= GR_FUNC_MODE_X
,
809 fxMesa
->ColorCombineExt
.SourceB
= GR_CMBX_ZERO
;
810 fxMesa
->ColorCombineExt
.ModeB
= GR_FUNC_MODE_X
;
811 fxMesa
->ColorCombineExt
.SourceC
= GR_CMBX_ZERO
;
812 fxMesa
->ColorCombineExt
.InvertC
= FXTRUE
;
813 fxMesa
->ColorCombineExt
.SourceD
= GR_CMBX_ZERO
;
814 fxMesa
->ColorCombineExt
.InvertD
= FXFALSE
;
815 fxMesa
->ColorCombineExt
.Shift
= 0;
816 fxMesa
->ColorCombineExt
.Invert
= FXFALSE
;
817 fxMesa
->dirty
|= TDFX_UPLOAD_COLOR_COMBINE
;
818 fxMesa
->AlphaCombineExt
.SourceA
= GR_CMBX_TEXTURE_ALPHA
;
819 fxMesa
->AlphaCombineExt
.ModeA
= GR_FUNC_MODE_X
;
820 fxMesa
->AlphaCombineExt
.SourceB
= GR_CMBX_ZERO
;
821 fxMesa
->AlphaCombineExt
.ModeB
= GR_FUNC_MODE_X
;
822 fxMesa
->AlphaCombineExt
.SourceC
= GR_CMBX_ZERO
;
823 fxMesa
->AlphaCombineExt
.InvertC
= FXTRUE
;
824 fxMesa
->AlphaCombineExt
.SourceD
= GR_CMBX_ZERO
;
825 fxMesa
->AlphaCombineExt
.InvertD
= FXFALSE
;
826 fxMesa
->AlphaCombineExt
.Shift
= 0;
827 fxMesa
->AlphaCombineExt
.Invert
= FXFALSE
;
828 fxMesa
->dirty
|= TDFX_UPLOAD_ALPHA_COMBINE
;
829 return GL_TRUE
; /* success */
835 * Setup the Voodoo3 texture environment for a single texture unit.
836 * Return GL_TRUE for success, GL_FALSE for failure.
837 * If failure, we'll use software rendering.
840 SetupSingleTexEnvVoodoo3(GLcontext
*ctx
, int unit
,
841 GLenum envMode
, GLenum baseFormat
)
843 tdfxContextPtr fxMesa
= TDFX_CONTEXT(ctx
);
844 GrCombineLocal_t localc
, locala
;
845 struct tdfx_combine alphaComb
, colorComb
;
847 if (1 /*iteratedRGBA*/)
848 localc
= locala
= GR_COMBINE_LOCAL_ITERATED
;
850 localc
= locala
= GR_COMBINE_LOCAL_CONSTANT
;
854 alphaComb
.Function
= GR_COMBINE_FUNCTION_LOCAL
;
855 alphaComb
.Factor
= GR_COMBINE_FACTOR_NONE
;
856 alphaComb
.Local
= locala
;
857 alphaComb
.Other
= GR_COMBINE_OTHER_NONE
;
858 alphaComb
.Invert
= FXFALSE
;
859 colorComb
.Function
= GR_COMBINE_FUNCTION_BLEND
;
860 colorComb
.Factor
= GR_COMBINE_FACTOR_TEXTURE_ALPHA
;
861 colorComb
.Local
= localc
;
862 colorComb
.Other
= GR_COMBINE_OTHER_TEXTURE
;
863 colorComb
.Invert
= FXFALSE
;
866 alphaComb
.Function
= GR_COMBINE_FUNCTION_SCALE_OTHER
;
867 alphaComb
.Factor
= GR_COMBINE_FACTOR_LOCAL
;
868 alphaComb
.Local
= locala
;
869 alphaComb
.Other
= GR_COMBINE_OTHER_TEXTURE
;
870 alphaComb
.Invert
= FXFALSE
;
871 if (baseFormat
== GL_ALPHA
) {
872 colorComb
.Function
= GR_COMBINE_FUNCTION_LOCAL
;
873 colorComb
.Factor
= GR_COMBINE_FACTOR_NONE
;
874 colorComb
.Local
= localc
;
875 colorComb
.Other
= GR_COMBINE_OTHER_NONE
;
876 colorComb
.Invert
= FXFALSE
;
879 colorComb
.Function
= GR_COMBINE_FUNCTION_SCALE_OTHER
;
880 colorComb
.Factor
= GR_COMBINE_FACTOR_LOCAL
;
881 colorComb
.Local
= localc
;
882 colorComb
.Other
= GR_COMBINE_OTHER_TEXTURE
;
883 colorComb
.Invert
= FXFALSE
;
889 * XXX we can't do real GL_BLEND mode. These settings assume that
890 * the TexEnv color is black and incoming fragment color is white.
892 if (baseFormat
== GL_LUMINANCE
|| baseFormat
== GL_RGB
) {
894 alphaComb
.Function
= GR_COMBINE_FUNCTION_LOCAL
;
895 alphaComb
.Factor
= GR_COMBINE_FACTOR_NONE
;
896 alphaComb
.Local
= locala
;
897 alphaComb
.Other
= GR_COMBINE_OTHER_NONE
;
898 alphaComb
.Invert
= FXFALSE
;
900 else if (baseFormat
== GL_INTENSITY
) {
901 /* Av = Af * (1 - It) + Ac * It */
902 /* XXX this is wrong */
903 alphaComb
.Function
= GR_COMBINE_FUNCTION_LOCAL
;
904 alphaComb
.Factor
= GR_COMBINE_FACTOR_NONE
;
905 alphaComb
.Local
= locala
;
906 alphaComb
.Other
= GR_COMBINE_OTHER_NONE
;
907 alphaComb
.Invert
= FXFALSE
;
911 alphaComb
.Function
= GR_COMBINE_FUNCTION_SCALE_OTHER
;
912 alphaComb
.Factor
= GR_COMBINE_FACTOR_LOCAL
;
913 alphaComb
.Local
= locala
;
914 alphaComb
.Other
= GR_COMBINE_OTHER_TEXTURE
;
915 alphaComb
.Invert
= FXFALSE
;
917 if (baseFormat
== GL_ALPHA
) {
918 colorComb
.Function
= GR_COMBINE_FUNCTION_LOCAL
;
919 colorComb
.Factor
= GR_COMBINE_FACTOR_NONE
;
920 colorComb
.Local
= localc
;
921 colorComb
.Other
= GR_COMBINE_OTHER_NONE
;
922 colorComb
.Invert
= FXFALSE
;
925 colorComb
.Function
= GR_COMBINE_FUNCTION_SCALE_OTHER
;
926 colorComb
.Factor
= GR_COMBINE_FACTOR_ONE
;
927 colorComb
.Local
= localc
;
928 colorComb
.Other
= GR_COMBINE_OTHER_TEXTURE
;
929 colorComb
.Invert
= FXTRUE
;
931 /* XXX return GL_FALSE for modes we don't support */
935 if ((baseFormat
== GL_RGB
) || (baseFormat
== GL_LUMINANCE
)) {
936 alphaComb
.Function
= GR_COMBINE_FUNCTION_LOCAL
;
937 alphaComb
.Factor
= GR_COMBINE_FACTOR_NONE
;
938 alphaComb
.Local
= locala
;
939 alphaComb
.Other
= GR_COMBINE_OTHER_NONE
;
940 alphaComb
.Invert
= FXFALSE
;
943 alphaComb
.Function
= GR_COMBINE_FUNCTION_SCALE_OTHER
;
944 alphaComb
.Factor
= GR_COMBINE_FACTOR_ONE
;
945 alphaComb
.Local
= locala
;
946 alphaComb
.Other
= GR_COMBINE_OTHER_TEXTURE
;
947 alphaComb
.Invert
= FXFALSE
;
949 if (baseFormat
== GL_ALPHA
) {
950 colorComb
.Function
= GR_COMBINE_FUNCTION_LOCAL
;
951 colorComb
.Factor
= GR_COMBINE_FACTOR_NONE
;
952 colorComb
.Local
= localc
;
953 colorComb
.Other
= GR_COMBINE_OTHER_NONE
;
954 colorComb
.Invert
= FXFALSE
;
957 colorComb
.Function
= GR_COMBINE_FUNCTION_SCALE_OTHER
;
958 colorComb
.Factor
= GR_COMBINE_FACTOR_ONE
;
959 colorComb
.Local
= localc
;
960 colorComb
.Other
= GR_COMBINE_OTHER_TEXTURE
;
961 colorComb
.Invert
= FXFALSE
;
966 if (baseFormat
== GL_ALPHA
||
967 baseFormat
== GL_LUMINANCE_ALPHA
||
968 baseFormat
== GL_RGBA
) {
969 /* product of texel and fragment alpha */
970 alphaComb
.Function
= GR_COMBINE_FUNCTION_SCALE_OTHER
;
971 alphaComb
.Factor
= GR_COMBINE_FACTOR_LOCAL
;
972 alphaComb
.Local
= locala
;
973 alphaComb
.Other
= GR_COMBINE_OTHER_TEXTURE
;
974 alphaComb
.Invert
= FXFALSE
;
976 else if (baseFormat
== GL_LUMINANCE
|| baseFormat
== GL_RGB
) {
977 /* fragment alpha is unchanged */
978 alphaComb
.Function
= GR_COMBINE_FUNCTION_LOCAL
;
979 alphaComb
.Factor
= GR_COMBINE_FACTOR_NONE
;
980 alphaComb
.Local
= locala
;
981 alphaComb
.Other
= GR_COMBINE_OTHER_NONE
;
982 alphaComb
.Invert
= FXFALSE
;
985 ASSERT(baseFormat
== GL_INTENSITY
);
986 /* sum of texel and fragment alpha */
987 alphaComb
.Function
= GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL
,
988 alphaComb
.Factor
= GR_COMBINE_FACTOR_ONE
;
989 alphaComb
.Local
= locala
;
990 alphaComb
.Other
= GR_COMBINE_OTHER_TEXTURE
;
991 alphaComb
.Invert
= FXFALSE
;
993 if (baseFormat
== GL_ALPHA
) {
995 colorComb
.Function
= GR_COMBINE_FUNCTION_LOCAL
;
996 colorComb
.Factor
= GR_COMBINE_FACTOR_NONE
;
997 colorComb
.Local
= localc
;
998 colorComb
.Other
= GR_COMBINE_OTHER_NONE
;
999 colorComb
.Invert
= FXFALSE
;
1002 /* sum of texel and fragment rgb */
1003 colorComb
.Function
= GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL
,
1004 colorComb
.Factor
= GR_COMBINE_FACTOR_ONE
;
1005 colorComb
.Local
= localc
;
1006 colorComb
.Other
= GR_COMBINE_OTHER_TEXTURE
;
1007 colorComb
.Invert
= FXFALSE
;
1012 _mesa_problem(ctx
, "bad texture env mode in %s", __FUNCTION__
);
1015 if (colorComb
.Function
!= fxMesa
->ColorCombine
.Function
||
1016 colorComb
.Factor
!= fxMesa
->ColorCombine
.Factor
||
1017 colorComb
.Local
!= fxMesa
->ColorCombine
.Local
||
1018 colorComb
.Other
!= fxMesa
->ColorCombine
.Other
||
1019 colorComb
.Invert
!= fxMesa
->ColorCombine
.Invert
) {
1020 fxMesa
->ColorCombine
= colorComb
;
1021 fxMesa
->dirty
|= TDFX_UPLOAD_COLOR_COMBINE
;
1024 if (alphaComb
.Function
!= fxMesa
->AlphaCombine
.Function
||
1025 alphaComb
.Factor
!= fxMesa
->AlphaCombine
.Factor
||
1026 alphaComb
.Local
!= fxMesa
->AlphaCombine
.Local
||
1027 alphaComb
.Other
!= fxMesa
->AlphaCombine
.Other
||
1028 alphaComb
.Invert
!= fxMesa
->AlphaCombine
.Invert
) {
1029 fxMesa
->AlphaCombine
= alphaComb
;
1030 fxMesa
->dirty
|= TDFX_UPLOAD_ALPHA_COMBINE
;
1037 * Setup the Voodoo3 texture environment for dual texture units.
1038 * Return GL_TRUE for success, GL_FALSE for failure.
1039 * If failure, we'll use software rendering.
1042 SetupDoubleTexEnvVoodoo3(GLcontext
*ctx
, int tmu0
,
1043 GLenum envMode0
, GLenum baseFormat0
,
1044 GLenum envMode1
, GLenum baseFormat1
)
1046 tdfxContextPtr fxMesa
= TDFX_CONTEXT(ctx
);
1047 const GrCombineLocal_t locala
= GR_COMBINE_LOCAL_ITERATED
;
1048 const GrCombineLocal_t localc
= GR_COMBINE_LOCAL_ITERATED
;
1049 const int tmu1
= 1 - tmu0
;
1051 if (envMode0
== GL_MODULATE
&& envMode1
== GL_MODULATE
) {
1052 GLboolean isalpha
[TDFX_NUM_TMU
];
1054 if (baseFormat0
== GL_ALPHA
)
1055 isalpha
[tmu0
] = GL_TRUE
;
1057 isalpha
[tmu0
] = GL_FALSE
;
1059 if (baseFormat1
== GL_ALPHA
)
1060 isalpha
[tmu1
] = GL_TRUE
;
1062 isalpha
[tmu1
] = GL_FALSE
;
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 (tmu1
== 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
];
1201 if (baseFormat0
== GL_ALPHA
)
1202 isalpha
[tmu0
] = GL_TRUE
;
1204 isalpha
[tmu0
] = GL_FALSE
;
1205 if (baseFormat1
== GL_ALPHA
)
1206 isalpha
[tmu1
] = GL_TRUE
;
1208 isalpha
[tmu1
] = GL_FALSE
;
1210 if (isalpha
[TDFX_TMU1
]) {
1211 fxMesa
->TexCombine
[1].FunctionRGB
= GR_COMBINE_FUNCTION_ZERO
;
1212 fxMesa
->TexCombine
[1].FactorRGB
= GR_COMBINE_FACTOR_NONE
;
1213 fxMesa
->TexCombine
[1].FunctionAlpha
= GR_COMBINE_FUNCTION_LOCAL
;
1214 fxMesa
->TexCombine
[1].FactorAlpha
= GR_COMBINE_FACTOR_NONE
;
1215 fxMesa
->TexCombine
[1].InvertRGB
= FXTRUE
;
1216 fxMesa
->TexCombine
[1].InvertAlpha
= FXFALSE
;
1219 fxMesa
->TexCombine
[1].FunctionRGB
= GR_COMBINE_FUNCTION_LOCAL
;
1220 fxMesa
->TexCombine
[1].FactorRGB
= GR_COMBINE_FACTOR_NONE
;
1221 fxMesa
->TexCombine
[1].FunctionAlpha
= GR_COMBINE_FUNCTION_LOCAL
;
1222 fxMesa
->TexCombine
[1].FactorAlpha
= GR_COMBINE_FACTOR_NONE
;
1223 fxMesa
->TexCombine
[1].InvertRGB
= FXFALSE
;
1224 fxMesa
->TexCombine
[1].InvertAlpha
= FXFALSE
;
1226 if (isalpha
[TDFX_TMU0
]) {
1227 fxMesa
->TexCombine
[0].FunctionRGB
= GR_COMBINE_FUNCTION_SCALE_OTHER
;
1228 fxMesa
->TexCombine
[0].FactorRGB
= GR_COMBINE_FACTOR_ONE
;
1229 fxMesa
->TexCombine
[0].FunctionAlpha
= GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL
;
1230 fxMesa
->TexCombine
[0].FactorAlpha
= GR_COMBINE_FACTOR_ONE
;
1231 fxMesa
->TexCombine
[0].InvertRGB
= FXFALSE
;
1232 fxMesa
->TexCombine
[0].InvertAlpha
= FXFALSE
;
1235 fxMesa
->TexCombine
[0].FunctionRGB
= GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL
;
1236 fxMesa
->TexCombine
[0].FactorRGB
= GR_COMBINE_FACTOR_ONE
;
1237 fxMesa
->TexCombine
[0].FunctionAlpha
= GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL
;
1238 fxMesa
->TexCombine
[0].FactorAlpha
= GR_COMBINE_FACTOR_ONE
;
1239 fxMesa
->TexCombine
[0].InvertRGB
= FXFALSE
;
1240 fxMesa
->TexCombine
[0].InvertAlpha
= FXFALSE
;
1242 fxMesa
->ColorCombine
.Function
= GR_COMBINE_FUNCTION_SCALE_OTHER
;
1243 fxMesa
->ColorCombine
.Factor
= GR_COMBINE_FACTOR_LOCAL
;
1244 fxMesa
->ColorCombine
.Local
= localc
;
1245 fxMesa
->ColorCombine
.Other
= GR_COMBINE_OTHER_TEXTURE
;
1246 fxMesa
->ColorCombine
.Invert
= FXFALSE
;
1247 fxMesa
->AlphaCombine
.Function
= GR_COMBINE_FUNCTION_SCALE_OTHER
;
1248 fxMesa
->AlphaCombine
.Factor
= GR_COMBINE_FACTOR_LOCAL
;
1249 fxMesa
->AlphaCombine
.Local
= locala
;
1250 fxMesa
->AlphaCombine
.Other
= GR_COMBINE_OTHER_TEXTURE
;
1251 fxMesa
->AlphaCombine
.Invert
= FXFALSE
;
1254 /*_mesa_problem(ctx, "%s: Unexpected dual texture mode encountered", __FUNCTION__);*/
1258 fxMesa
->dirty
|= TDFX_UPLOAD_TEXTURE_ENV
;
1259 fxMesa
->dirty
|= TDFX_UPLOAD_COLOR_COMBINE
;
1260 fxMesa
->dirty
|= TDFX_UPLOAD_ALPHA_COMBINE
;
1266 * This function makes sure that the correct mipmap levels are loaded
1267 * in the right places in memory and then makes the Glide calls to
1268 * setup the texture source pointers.
1271 setupSingleTMU(tdfxContextPtr fxMesa
, struct gl_texture_object
*tObj
)
1273 struct tdfxSharedState
*shared
= (struct tdfxSharedState
*) fxMesa
->glCtx
->Shared
->DriverData
;
1274 tdfxTexInfo
*ti
= TDFX_TEXTURE_DATA(tObj
);
1275 const GLcontext
*ctx
= fxMesa
->glCtx
;
1277 /* Make sure we're not loaded incorrectly */
1278 if (ti
->isInTM
&& !shared
->umaTexMemory
) {
1279 /* if doing filtering between mipmap levels, alternate mipmap levels
1280 * must be in alternate TMUs.
1283 if (ti
->whichTMU
!= TDFX_TMU_SPLIT
)
1284 tdfxTMMoveOutTM_NoLock(fxMesa
, tObj
);
1287 if (ti
->whichTMU
== TDFX_TMU_SPLIT
)
1288 tdfxTMMoveOutTM_NoLock(fxMesa
, tObj
);
1292 /* Make sure we're loaded correctly */
1294 /* Have to download the texture */
1295 if (shared
->umaTexMemory
) {
1296 tdfxTMMoveInTM_NoLock(fxMesa
, tObj
, TDFX_TMU0
);
1299 /* Voodoo3 (split texture memory) */
1301 tdfxTMMoveInTM_NoLock(fxMesa
, tObj
, TDFX_TMU_SPLIT
);
1305 /* XXX putting textures into the second memory bank when the
1306 * first bank is full is not working at this time.
1308 if (fxMesa
->haveTwoTMUs
) {
1309 GLint memReq
= fxMesa
->Glide
.grTexTextureMemRequired(
1310 GR_MIPMAPLEVELMASK_BOTH
, &(ti
->info
));
1311 if (shared
->freeTexMem
[TDFX_TMU0
] > memReq
) {
1312 tdfxTMMoveInTM_NoLock(fxMesa
, tObj
, TDFX_TMU0
);
1315 tdfxTMMoveInTM_NoLock(fxMesa
, tObj
, TDFX_TMU1
);
1321 tdfxTMMoveInTM_NoLock(fxMesa
, tObj
, TDFX_TMU0
);
1327 if (ti
->LODblend
&& ti
->whichTMU
== TDFX_TMU_SPLIT
) {
1328 /* mipmap levels split between texture banks */
1331 if (ti
->info
.format
== GR_TEXFMT_P_8
&& !ctx
->Texture
.SharedPalette
) {
1332 fxMesa
->TexPalette
.Type
= GR_TEXTABLE_PALETTE_6666_EXT
;
1333 fxMesa
->TexPalette
.Data
= &(ti
->palette
);
1334 fxMesa
->dirty
|= TDFX_UPLOAD_TEXTURE_PALETTE
;
1337 for (u
= 0; u
< 2; u
++) {
1338 fxMesa
->TexParams
[u
].sClamp
= ti
->sClamp
;
1339 fxMesa
->TexParams
[u
].tClamp
= ti
->tClamp
;
1340 fxMesa
->TexParams
[u
].minFilt
= ti
->minFilt
;
1341 fxMesa
->TexParams
[u
].magFilt
= ti
->magFilt
;
1342 fxMesa
->TexParams
[u
].mmMode
= ti
->mmMode
;
1343 fxMesa
->TexParams
[u
].LODblend
= ti
->LODblend
;
1344 fxMesa
->TexParams
[u
].LodBias
= ctx
->Texture
.Unit
[u
].LodBias
;
1346 fxMesa
->dirty
|= TDFX_UPLOAD_TEXTURE_PARAMS
;
1348 fxMesa
->TexSource
[0].StartAddress
= ti
->tm
[TDFX_TMU0
]->startAddr
;
1349 fxMesa
->TexSource
[0].EvenOdd
= GR_MIPMAPLEVELMASK_ODD
;
1350 fxMesa
->TexSource
[0].Info
= &(ti
->info
);
1351 fxMesa
->TexSource
[1].StartAddress
= ti
->tm
[TDFX_TMU1
]->startAddr
;
1352 fxMesa
->TexSource
[1].EvenOdd
= GR_MIPMAPLEVELMASK_EVEN
;
1353 fxMesa
->TexSource
[1].Info
= &(ti
->info
);
1354 fxMesa
->dirty
|= TDFX_UPLOAD_TEXTURE_SOURCE
;
1359 if (ti
->whichTMU
== TDFX_TMU_BOTH
)
1364 if (shared
->umaTexMemory
) {
1365 assert(ti
->whichTMU
== TDFX_TMU0
);
1366 assert(tmu
== TDFX_TMU0
);
1369 if (ti
->info
.format
== GR_TEXFMT_P_8
&& !ctx
->Texture
.SharedPalette
) {
1370 fxMesa
->TexPalette
.Type
= GR_TEXTABLE_PALETTE_6666_EXT
;
1371 fxMesa
->TexPalette
.Data
= &(ti
->palette
);
1372 fxMesa
->dirty
|= TDFX_UPLOAD_TEXTURE_PALETTE
;
1375 /* KW: The alternative is to do the download to the other tmu. If
1376 * we get to this point, I think it means we are thrashing the
1377 * texture memory, so perhaps it's not a good idea.
1380 if (fxMesa
->TexParams
[tmu
].sClamp
!= ti
->sClamp
||
1381 fxMesa
->TexParams
[tmu
].tClamp
!= ti
->tClamp
||
1382 fxMesa
->TexParams
[tmu
].minFilt
!= ti
->minFilt
||
1383 fxMesa
->TexParams
[tmu
].magFilt
!= ti
->magFilt
||
1384 fxMesa
->TexParams
[tmu
].mmMode
!= ti
->mmMode
||
1385 fxMesa
->TexParams
[tmu
].LODblend
!= FXFALSE
||
1386 fxMesa
->TexParams
[tmu
].LodBias
!= ctx
->Texture
.Unit
[tmu
].LodBias
) {
1387 fxMesa
->TexParams
[tmu
].sClamp
= ti
->sClamp
;
1388 fxMesa
->TexParams
[tmu
].tClamp
= ti
->tClamp
;
1389 fxMesa
->TexParams
[tmu
].minFilt
= ti
->minFilt
;
1390 fxMesa
->TexParams
[tmu
].magFilt
= ti
->magFilt
;
1391 fxMesa
->TexParams
[tmu
].mmMode
= ti
->mmMode
;
1392 fxMesa
->TexParams
[tmu
].LODblend
= FXFALSE
;
1393 fxMesa
->TexParams
[tmu
].LodBias
= ctx
->Texture
.Unit
[tmu
].LodBias
;
1394 fxMesa
->dirty
|= TDFX_UPLOAD_TEXTURE_PARAMS
;
1397 /* Glide texture source info */
1398 fxMesa
->TexSource
[0].Info
= NULL
;
1399 fxMesa
->TexSource
[1].Info
= NULL
;
1401 fxMesa
->TexSource
[tmu
].StartAddress
= ti
->tm
[tmu
]->startAddr
;
1402 fxMesa
->TexSource
[tmu
].EvenOdd
= GR_MIPMAPLEVELMASK_BOTH
;
1403 fxMesa
->TexSource
[tmu
].Info
= &(ti
->info
);
1404 fxMesa
->dirty
|= TDFX_UPLOAD_TEXTURE_SOURCE
;
1408 fxMesa
->sScale0
= ti
->sScale
;
1409 fxMesa
->tScale0
= ti
->tScale
;
1413 selectSingleTMUSrc(tdfxContextPtr fxMesa
, GLint tmu
, FxBool LODblend
)
1416 fxMesa
->TexCombine
[0].FunctionRGB
= GR_COMBINE_FUNCTION_BLEND
;
1417 fxMesa
->TexCombine
[0].FactorRGB
= GR_COMBINE_FACTOR_ONE_MINUS_LOD_FRACTION
;
1418 fxMesa
->TexCombine
[0].FunctionAlpha
= GR_COMBINE_FUNCTION_BLEND
;
1419 fxMesa
->TexCombine
[0].FactorAlpha
= GR_COMBINE_FACTOR_ONE_MINUS_LOD_FRACTION
;
1420 fxMesa
->TexCombine
[0].InvertRGB
= FXFALSE
;
1421 fxMesa
->TexCombine
[0].InvertAlpha
= FXFALSE
;
1423 if (fxMesa
->haveTwoTMUs
) {
1424 const struct gl_shared_state
*mesaShared
= fxMesa
->glCtx
->Shared
;
1425 const struct tdfxSharedState
*shared
= (struct tdfxSharedState
*) mesaShared
->DriverData
;
1428 if (shared
->umaTexMemory
)
1433 fxMesa
->TexCombine
[tmu
].FunctionRGB
= GR_COMBINE_FUNCTION_LOCAL
;
1434 fxMesa
->TexCombine
[tmu
].FactorRGB
= GR_COMBINE_FACTOR_NONE
;
1435 fxMesa
->TexCombine
[tmu
].FunctionAlpha
= GR_COMBINE_FUNCTION_LOCAL
;
1436 fxMesa
->TexCombine
[tmu
].FactorAlpha
= GR_COMBINE_FACTOR_NONE
;
1437 fxMesa
->TexCombine
[tmu
].InvertRGB
= FXFALSE
;
1438 fxMesa
->TexCombine
[tmu
].InvertAlpha
= FXFALSE
;
1440 fxMesa
->tmuSrc
= TDFX_TMU_SPLIT
;
1443 if (tmu
!= TDFX_TMU1
) {
1444 fxMesa
->TexCombine
[0].FunctionRGB
= GR_COMBINE_FUNCTION_LOCAL
;
1445 fxMesa
->TexCombine
[0].FactorRGB
= GR_COMBINE_FACTOR_NONE
;
1446 fxMesa
->TexCombine
[0].FunctionAlpha
= GR_COMBINE_FUNCTION_LOCAL
;
1447 fxMesa
->TexCombine
[0].FactorAlpha
= GR_COMBINE_FACTOR_NONE
;
1448 fxMesa
->TexCombine
[0].InvertRGB
= FXFALSE
;
1449 fxMesa
->TexCombine
[0].InvertAlpha
= FXFALSE
;
1450 if (fxMesa
->haveTwoTMUs
) {
1451 fxMesa
->TexCombine
[1].FunctionRGB
= GR_COMBINE_FUNCTION_ZERO
;
1452 fxMesa
->TexCombine
[1].FactorRGB
= GR_COMBINE_FACTOR_NONE
;
1453 fxMesa
->TexCombine
[1].FunctionAlpha
= GR_COMBINE_FUNCTION_ZERO
;
1454 fxMesa
->TexCombine
[1].FactorAlpha
= GR_COMBINE_FACTOR_NONE
;
1455 fxMesa
->TexCombine
[1].InvertRGB
= FXFALSE
;
1456 fxMesa
->TexCombine
[1].InvertAlpha
= FXFALSE
;
1458 fxMesa
->tmuSrc
= TDFX_TMU0
;
1461 fxMesa
->TexCombine
[1].FunctionRGB
= GR_COMBINE_FUNCTION_LOCAL
;
1462 fxMesa
->TexCombine
[1].FactorRGB
= GR_COMBINE_FACTOR_NONE
;
1463 fxMesa
->TexCombine
[1].FunctionAlpha
= GR_COMBINE_FUNCTION_LOCAL
;
1464 fxMesa
->TexCombine
[1].FactorAlpha
= GR_COMBINE_FACTOR_NONE
;
1465 fxMesa
->TexCombine
[1].InvertRGB
= FXFALSE
;
1466 fxMesa
->TexCombine
[1].InvertAlpha
= FXFALSE
;
1467 /* GR_COMBINE_FUNCTION_SCALE_OTHER doesn't work ?!? */
1468 fxMesa
->TexCombine
[0].FunctionRGB
= GR_COMBINE_FUNCTION_BLEND
;
1469 fxMesa
->TexCombine
[0].FactorRGB
= GR_COMBINE_FACTOR_ONE
;
1470 fxMesa
->TexCombine
[0].FunctionAlpha
= GR_COMBINE_FUNCTION_BLEND
;
1471 fxMesa
->TexCombine
[0].FactorAlpha
= GR_COMBINE_FACTOR_ONE
;
1472 fxMesa
->TexCombine
[0].InvertRGB
= FXFALSE
;
1473 fxMesa
->TexCombine
[0].InvertAlpha
= FXFALSE
;
1474 fxMesa
->tmuSrc
= TDFX_TMU1
;
1478 fxMesa
->dirty
|= TDFX_UPLOAD_TEXTURE_ENV
;
1481 static void print_state(tdfxContextPtr fxMesa
)
1483 GLcontext
*ctx
= fxMesa
->glCtx
;
1484 struct gl_texture_object
*tObj0
= ctx
->Texture
.Unit
[0].Current2D
;
1485 struct gl_texture_object
*tObj1
= ctx
->Texture
.Unit
[1].Current2D
;
1486 GLenum base0
= tObj0
->Image
[tObj0
->BaseLevel
] ? tObj0
->Image
[tObj0
->BaseLevel
]->Format
: 99;
1487 GLenum base1
= tObj1
->Image
[tObj1
->BaseLevel
] ? tObj1
->Image
[tObj1
->BaseLevel
]->Format
: 99;
1489 printf("Unit 0: Enabled: GL=%d Gr=%d\n", ctx
->Texture
.Unit
[0]._ReallyEnabled
,
1490 fxMesa
->TexState
.Enabled
[0]);
1491 printf(" EnvMode: GL=0x%x Gr=0x%x\n", ctx
->Texture
.Unit
[0].EnvMode
,
1492 fxMesa
->TexState
.EnvMode
[0]);
1493 printf(" BaseFmt: GL=0x%x Gr=0x%x\n", base0
, fxMesa
->TexState
.TexFormat
[0]);
1496 printf("Unit 1: Enabled: GL=%d Gr=%d\n", ctx
->Texture
.Unit
[1]._ReallyEnabled
,
1497 fxMesa
->TexState
.Enabled
[1]);
1498 printf(" EnvMode: GL=0x%x Gr:0x%x\n", ctx
->Texture
.Unit
[1].EnvMode
,
1499 fxMesa
->TexState
.EnvMode
[1]);
1500 printf(" BaseFmt: GL=0x%x Gr:0x%x\n", base1
, fxMesa
->TexState
.TexFormat
[1]);
1505 * When we're only using a single texture unit, we always use the 0th
1506 * Glide/hardware unit, regardless if it's GL_TEXTURE0_ARB or GL_TEXTURE1_ARB
1508 * Input: ctx - the context
1509 * unit - the OpenGL texture unit to use.
1511 static void setupTextureSingleTMU(GLcontext
* ctx
, GLuint unit
)
1513 tdfxContextPtr fxMesa
= TDFX_CONTEXT(ctx
);
1515 struct gl_texture_object
*tObj
;
1517 GLenum envMode
, baseFormat
;
1519 tObj
= ctx
->Texture
.Unit
[unit
].Current2D
;
1520 if (tObj
->Image
[tObj
->BaseLevel
]->Border
> 0) {
1521 FALLBACK(fxMesa
, TDFX_FALLBACK_TEXTURE_BORDER
, GL_TRUE
);
1525 setupSingleTMU(fxMesa
, tObj
);
1527 ti
= TDFX_TEXTURE_DATA(tObj
);
1528 if (ti
->whichTMU
== TDFX_TMU_BOTH
)
1533 if (fxMesa
->tmuSrc
!= tmu
) {
1534 selectSingleTMUSrc(fxMesa
, tmu
, ti
->LODblend
);
1537 if (ti
->reloadImages
)
1538 fxMesa
->dirty
|= TDFX_UPLOAD_TEXTURE_IMAGES
;
1540 /* Check if we really need to update the texenv state */
1541 envMode
= ctx
->Texture
.Unit
[unit
].EnvMode
;
1542 baseFormat
= tObj
->Image
[tObj
->BaseLevel
]->Format
;
1544 if (TDFX_IS_NAPALM(fxMesa
)) {
1545 /* see if we really need to update the unit */
1546 if (fxMesa
->TexState
.Enabled
[unit
] != ctx
->Texture
.Unit
[unit
]._ReallyEnabled
||
1547 envMode
!= fxMesa
->TexState
.EnvMode
[0] ||
1548 envMode
== GL_COMBINE_EXT
||
1549 baseFormat
!= fxMesa
->TexState
.TexFormat
[0]) {
1550 struct tdfx_texcombine_ext
*otherEnv
;
1551 if (!SetupTexEnvNapalm(ctx
, GL_TRUE
,
1552 &ctx
->Texture
.Unit
[unit
], baseFormat
,
1553 &fxMesa
->TexCombineExt
[0])) {
1554 /* software fallback */
1555 FALLBACK(fxMesa
, TDFX_FALLBACK_TEXTURE_ENV
, GL_TRUE
);
1557 /* disable other unit */
1558 otherEnv
= &fxMesa
->TexCombineExt
[1];
1559 otherEnv
->Color
.SourceA
= GR_CMBX_ZERO
;
1560 otherEnv
->Color
.ModeA
= GR_FUNC_MODE_ZERO
;
1561 otherEnv
->Color
.SourceB
= GR_CMBX_ZERO
;
1562 otherEnv
->Color
.ModeB
= GR_FUNC_MODE_ZERO
;
1563 otherEnv
->Color
.SourceC
= GR_CMBX_ZERO
;
1564 otherEnv
->Color
.InvertC
= FXFALSE
;
1565 otherEnv
->Color
.SourceD
= GR_CMBX_ZERO
;
1566 otherEnv
->Color
.InvertD
= FXFALSE
;
1567 otherEnv
->Color
.Shift
= 0;
1568 otherEnv
->Color
.Invert
= FXFALSE
;
1569 otherEnv
->Alpha
.SourceA
= GR_CMBX_ITALPHA
;
1570 otherEnv
->Alpha
.ModeA
= GR_FUNC_MODE_ZERO
;
1571 otherEnv
->Alpha
.SourceB
= GR_CMBX_ITALPHA
;
1572 otherEnv
->Alpha
.ModeB
= GR_FUNC_MODE_ZERO
;
1573 otherEnv
->Alpha
.SourceC
= GR_CMBX_ZERO
;
1574 otherEnv
->Alpha
.InvertC
= FXFALSE
;
1575 otherEnv
->Alpha
.SourceD
= GR_CMBX_ZERO
;
1576 otherEnv
->Alpha
.InvertD
= FXFALSE
;
1577 otherEnv
->Alpha
.Shift
= 0;
1578 otherEnv
->Alpha
.Invert
= FXFALSE
;
1580 fxMesa
->TexState
.Enabled
[unit
] = ctx
->Texture
.Unit
[unit
]._ReallyEnabled
;
1581 fxMesa
->TexState
.EnvMode
[0] = envMode
;
1582 fxMesa
->TexState
.TexFormat
[0] = baseFormat
;
1583 fxMesa
->TexState
.EnvMode
[1] = 0;
1584 fxMesa
->TexState
.TexFormat
[1] = 0;
1590 /* see if we really need to update the unit */
1591 if (fxMesa
->TexState
.Enabled
[unit
] != ctx
->Texture
.Unit
[unit
]._ReallyEnabled
||
1592 envMode
!= fxMesa
->TexState
.EnvMode
[0] ||
1593 envMode
== GL_COMBINE_EXT
||
1594 baseFormat
!= fxMesa
->TexState
.TexFormat
[0]) {
1595 if (!SetupSingleTexEnvVoodoo3(ctx
, tmu
, envMode
, baseFormat
)) {
1596 /* software fallback */
1597 FALLBACK(fxMesa
, TDFX_FALLBACK_TEXTURE_ENV
, GL_TRUE
);
1599 fxMesa
->TexState
.Enabled
[unit
] = ctx
->Texture
.Unit
[unit
]._ReallyEnabled
;
1600 fxMesa
->TexState
.EnvMode
[0] = envMode
;
1601 fxMesa
->TexState
.TexFormat
[0] = baseFormat
;
1602 fxMesa
->TexState
.EnvMode
[1] = 0;
1603 fxMesa
->TexState
.TexFormat
[1] = 0;
1610 setupDoubleTMU(tdfxContextPtr fxMesa
,
1611 struct gl_texture_object
*tObj0
,
1612 struct gl_texture_object
*tObj1
)
1614 #define T0_NOT_IN_TMU 0x01
1615 #define T1_NOT_IN_TMU 0x02
1616 #define T0_IN_TMU0 0x04
1617 #define T1_IN_TMU0 0x08
1618 #define T0_IN_TMU1 0x10
1619 #define T1_IN_TMU1 0x20
1621 const struct gl_shared_state
*mesaShared
= fxMesa
->glCtx
->Shared
;
1622 const struct tdfxSharedState
*shared
= (struct tdfxSharedState
*) mesaShared
->DriverData
;
1623 const GLcontext
*ctx
= fxMesa
->glCtx
;
1624 tdfxTexInfo
*ti0
= TDFX_TEXTURE_DATA(tObj0
);
1625 tdfxTexInfo
*ti1
= TDFX_TEXTURE_DATA(tObj1
);
1627 int tmu0
= 0, tmu1
= 1;
1629 if (shared
->umaTexMemory
) {
1631 tdfxTMMoveInTM_NoLock(fxMesa
, tObj0
, TDFX_TMU0
);
1632 assert(ti0
->isInTM
);
1635 tdfxTMMoveInTM_NoLock(fxMesa
, tObj1
, TDFX_TMU0
);
1636 assert(ti1
->isInTM
);
1640 /* We shouldn't need to do this. There is something wrong with
1641 multitexturing when the TMUs are swapped. So, we're forcing
1642 them to always be loaded correctly. !!! */
1643 if (ti0
->whichTMU
== TDFX_TMU1
)
1644 tdfxTMMoveOutTM_NoLock(fxMesa
, tObj0
);
1645 if (ti1
->whichTMU
== TDFX_TMU0
)
1646 tdfxTMMoveOutTM_NoLock(fxMesa
, tObj1
);
1649 switch (ti0
->whichTMU
) {
1651 tstate
|= T0_IN_TMU0
;
1654 tstate
|= T0_IN_TMU1
;
1657 tstate
|= T0_IN_TMU0
| T0_IN_TMU1
;
1659 case TDFX_TMU_SPLIT
:
1660 tstate
|= T0_NOT_IN_TMU
;
1665 tstate
|= T0_NOT_IN_TMU
;
1668 switch (ti1
->whichTMU
) {
1670 tstate
|= T1_IN_TMU0
;
1673 tstate
|= T1_IN_TMU1
;
1676 tstate
|= T1_IN_TMU0
| T1_IN_TMU1
;
1678 case TDFX_TMU_SPLIT
:
1679 tstate
|= T1_NOT_IN_TMU
;
1684 tstate
|= T1_NOT_IN_TMU
;
1686 /* Move texture maps into TMUs */
1688 if (!(((tstate
& T0_IN_TMU0
) && (tstate
& T1_IN_TMU1
)) ||
1689 ((tstate
& T0_IN_TMU1
) && (tstate
& T1_IN_TMU0
)))) {
1690 if (tObj0
== tObj1
) {
1691 tdfxTMMoveInTM_NoLock(fxMesa
, tObj1
, TDFX_TMU_BOTH
);
1694 /* Find the minimal way to correct the situation */
1695 if ((tstate
& T0_IN_TMU0
) || (tstate
& T1_IN_TMU1
)) {
1696 /* We have one in the standard order, setup the other */
1697 if (tstate
& T0_IN_TMU0
) {
1698 /* T0 is in TMU0, put T1 in TMU1 */
1699 tdfxTMMoveInTM_NoLock(fxMesa
, tObj1
, TDFX_TMU1
);
1702 tdfxTMMoveInTM_NoLock(fxMesa
, tObj0
, TDFX_TMU0
);
1704 /* tmu0 and tmu1 are setup */
1706 else if ((tstate
& T0_IN_TMU1
) || (tstate
& T1_IN_TMU0
)) {
1707 /* we have one in the reverse order, setup the other */
1708 if (tstate
& T1_IN_TMU0
) {
1709 /* T1 is in TMU0, put T0 in TMU1 */
1710 tdfxTMMoveInTM_NoLock(fxMesa
, tObj0
, TDFX_TMU1
);
1713 tdfxTMMoveInTM_NoLock(fxMesa
, tObj1
, TDFX_TMU0
);
1718 else { /* Nothing is loaded */
1719 tdfxTMMoveInTM_NoLock(fxMesa
, tObj0
, TDFX_TMU0
);
1720 tdfxTMMoveInTM_NoLock(fxMesa
, tObj1
, TDFX_TMU1
);
1721 /* tmu0 and tmu1 are setup */
1727 ti0
->lastTimeUsed
= fxMesa
->texBindNumber
;
1728 ti1
->lastTimeUsed
= fxMesa
->texBindNumber
;
1731 if (!ctx
->Texture
.SharedPalette
) {
1732 if (ti0
->info
.format
== GR_TEXFMT_P_8
) {
1733 fxMesa
->TexPalette
.Type
= GR_TEXTABLE_PALETTE_6666_EXT
;
1734 fxMesa
->TexPalette
.Data
= &(ti0
->palette
);
1735 fxMesa
->dirty
|= TDFX_UPLOAD_TEXTURE_PALETTE
;
1737 else if (ti1
->info
.format
== GR_TEXFMT_P_8
) {
1738 fxMesa
->TexPalette
.Type
= GR_TEXTABLE_PALETTE_6666_EXT
;
1739 fxMesa
->TexPalette
.Data
= &(ti1
->palette
);
1740 fxMesa
->dirty
|= TDFX_UPLOAD_TEXTURE_PALETTE
;
1743 fxMesa
->TexPalette
.Data
= NULL
;
1750 assert(ti0
->isInTM
);
1751 assert(ti0
->tm
[tmu0
]);
1752 fxMesa
->TexSource
[tmu0
].StartAddress
= ti0
->tm
[tmu0
]->startAddr
;
1753 fxMesa
->TexSource
[tmu0
].EvenOdd
= GR_MIPMAPLEVELMASK_BOTH
;
1754 fxMesa
->TexSource
[tmu0
].Info
= &(ti0
->info
);
1755 fxMesa
->dirty
|= TDFX_UPLOAD_TEXTURE_SOURCE
;
1757 if (fxMesa
->TexParams
[tmu0
].sClamp
!= ti0
->sClamp
||
1758 fxMesa
->TexParams
[tmu0
].tClamp
!= ti0
->tClamp
||
1759 fxMesa
->TexParams
[tmu0
].minFilt
!= ti0
->minFilt
||
1760 fxMesa
->TexParams
[tmu0
].magFilt
!= ti0
->magFilt
||
1761 fxMesa
->TexParams
[tmu0
].mmMode
!= ti0
->mmMode
||
1762 fxMesa
->TexParams
[tmu0
].LODblend
!= FXFALSE
||
1763 fxMesa
->TexParams
[tmu0
].LodBias
!= ctx
->Texture
.Unit
[tmu0
].LodBias
) {
1764 fxMesa
->TexParams
[tmu0
].sClamp
= ti0
->sClamp
;
1765 fxMesa
->TexParams
[tmu0
].tClamp
= ti0
->tClamp
;
1766 fxMesa
->TexParams
[tmu0
].minFilt
= ti0
->minFilt
;
1767 fxMesa
->TexParams
[tmu0
].magFilt
= ti0
->magFilt
;
1768 fxMesa
->TexParams
[tmu0
].mmMode
= ti0
->mmMode
;
1769 fxMesa
->TexParams
[tmu0
].LODblend
= FXFALSE
;
1770 fxMesa
->TexParams
[tmu0
].LodBias
= ctx
->Texture
.Unit
[tmu0
].LodBias
;
1771 fxMesa
->dirty
|= TDFX_UPLOAD_TEXTURE_PARAMS
;
1777 if (shared
->umaTexMemory
) {
1778 ASSERT(ti1
->isInTM
);
1780 fxMesa
->TexSource
[tmu1
].StartAddress
= ti1
->tm
[0]->startAddr
;
1781 fxMesa
->TexSource
[tmu1
].EvenOdd
= GR_MIPMAPLEVELMASK_BOTH
;
1782 fxMesa
->TexSource
[tmu1
].Info
= &(ti1
->info
);
1785 ASSERT(ti1
->isInTM
);
1786 ASSERT(ti1
->tm
[tmu1
]);
1787 fxMesa
->TexSource
[tmu1
].StartAddress
= ti1
->tm
[tmu1
]->startAddr
;
1788 fxMesa
->TexSource
[tmu1
].EvenOdd
= GR_MIPMAPLEVELMASK_BOTH
;
1789 fxMesa
->TexSource
[tmu1
].Info
= &(ti1
->info
);
1792 if (fxMesa
->TexParams
[tmu1
].sClamp
!= ti1
->sClamp
||
1793 fxMesa
->TexParams
[tmu1
].tClamp
!= ti1
->tClamp
||
1794 fxMesa
->TexParams
[tmu1
].minFilt
!= ti1
->minFilt
||
1795 fxMesa
->TexParams
[tmu1
].magFilt
!= ti1
->magFilt
||
1796 fxMesa
->TexParams
[tmu1
].mmMode
!= ti1
->mmMode
||
1797 fxMesa
->TexParams
[tmu1
].LODblend
!= FXFALSE
||
1798 fxMesa
->TexParams
[tmu1
].LodBias
!= ctx
->Texture
.Unit
[tmu1
].LodBias
) {
1799 fxMesa
->TexParams
[tmu1
].sClamp
= ti1
->sClamp
;
1800 fxMesa
->TexParams
[tmu1
].tClamp
= ti1
->tClamp
;
1801 fxMesa
->TexParams
[tmu1
].minFilt
= ti1
->minFilt
;
1802 fxMesa
->TexParams
[tmu1
].magFilt
= ti1
->magFilt
;
1803 fxMesa
->TexParams
[tmu1
].mmMode
= ti1
->mmMode
;
1804 fxMesa
->TexParams
[tmu1
].LODblend
= FXFALSE
;
1805 fxMesa
->TexParams
[tmu1
].LodBias
= ctx
->Texture
.Unit
[tmu1
].LodBias
;
1806 fxMesa
->dirty
|= TDFX_UPLOAD_TEXTURE_PARAMS
;
1809 fxMesa
->sScale0
= ti0
->sScale
;
1810 fxMesa
->tScale0
= ti0
->tScale
;
1811 fxMesa
->sScale1
= ti1
->sScale
;
1812 fxMesa
->tScale1
= ti1
->tScale
;
1814 #undef T0_NOT_IN_TMU
1815 #undef T1_NOT_IN_TMU
1822 static void setupTextureDoubleTMU(GLcontext
* ctx
)
1824 tdfxContextPtr fxMesa
= TDFX_CONTEXT(ctx
);
1825 struct gl_texture_object
*tObj0
= ctx
->Texture
.Unit
[0].Current2D
;
1826 struct gl_texture_object
*tObj1
= ctx
->Texture
.Unit
[1].Current2D
;
1827 tdfxTexInfo
*ti0
= TDFX_TEXTURE_DATA(tObj0
);
1828 tdfxTexInfo
*ti1
= TDFX_TEXTURE_DATA(tObj1
);
1829 struct gl_texture_image
*baseImage0
= tObj0
->Image
[tObj0
->BaseLevel
];
1830 struct gl_texture_image
*baseImage1
= tObj1
->Image
[tObj1
->BaseLevel
];
1831 const GLenum envMode0
= ctx
->Texture
.Unit
[0].EnvMode
;
1832 const GLenum envMode1
= ctx
->Texture
.Unit
[1].EnvMode
;
1834 if (baseImage0
->Border
> 0 || baseImage1
->Border
> 0) {
1835 FALLBACK(fxMesa
, TDFX_FALLBACK_TEXTURE_BORDER
, GL_TRUE
);
1839 setupDoubleTMU(fxMesa
, tObj0
, tObj1
);
1841 if (ti0
->reloadImages
|| ti1
->reloadImages
)
1842 fxMesa
->dirty
|= TDFX_UPLOAD_TEXTURE_IMAGES
;
1844 fxMesa
->tmuSrc
= TDFX_TMU_BOTH
;
1846 if (TDFX_IS_NAPALM(fxMesa
)) {
1847 /* Remember, Glide has its texture units numbered in backward
1848 * order compared to OpenGL.
1850 GLboolean hw1
= GL_TRUE
, hw2
= GL_TRUE
;
1852 /* check if we really need to update glide unit 1 */
1853 if (fxMesa
->TexState
.Enabled
[0] != ctx
->Texture
.Unit
[0]._ReallyEnabled
||
1854 envMode0
!= fxMesa
->TexState
.EnvMode
[1] ||
1855 envMode0
== GL_COMBINE_EXT
||
1856 baseImage0
->Format
!= fxMesa
->TexState
.TexFormat
[1] ||
1857 (fxMesa
->Fallback
& TDFX_FALLBACK_TEXTURE_ENV
)) {
1858 hw1
= SetupTexEnvNapalm(ctx
, GL_TRUE
, &ctx
->Texture
.Unit
[0],
1859 baseImage0
->Format
, &fxMesa
->TexCombineExt
[1]);
1860 fxMesa
->TexState
.EnvMode
[1] = envMode0
;
1861 fxMesa
->TexState
.TexFormat
[1] = baseImage0
->Format
;
1862 fxMesa
->TexState
.Enabled
[0] = ctx
->Texture
.Unit
[0]._ReallyEnabled
;
1865 /* check if we really need to update glide unit 0 */
1866 if (fxMesa
->TexState
.Enabled
[1] != ctx
->Texture
.Unit
[1]._ReallyEnabled
||
1867 envMode1
!= fxMesa
->TexState
.EnvMode
[0] ||
1868 envMode1
== GL_COMBINE_EXT
||
1869 baseImage1
->Format
!= fxMesa
->TexState
.TexFormat
[0] ||
1870 (fxMesa
->Fallback
& TDFX_FALLBACK_TEXTURE_ENV
)) {
1871 hw2
= SetupTexEnvNapalm(ctx
, GL_FALSE
, &ctx
->Texture
.Unit
[1],
1872 baseImage1
->Format
, &fxMesa
->TexCombineExt
[0]);
1873 fxMesa
->TexState
.EnvMode
[0] = envMode1
;
1874 fxMesa
->TexState
.TexFormat
[0] = baseImage1
->Format
;
1875 fxMesa
->TexState
.Enabled
[1] = ctx
->Texture
.Unit
[1]._ReallyEnabled
;
1880 FALLBACK(fxMesa
, TDFX_FALLBACK_TEXTURE_ENV
, GL_TRUE
);
1885 if ((ti0
->whichTMU
== TDFX_TMU1
) || (ti1
->whichTMU
== TDFX_TMU0
))
1891 if (fxMesa
->TexState
.Enabled
[0] != ctx
->Texture
.Unit
[0]._ReallyEnabled
||
1892 fxMesa
->TexState
.Enabled
[1] != ctx
->Texture
.Unit
[1]._ReallyEnabled
||
1893 envMode0
!= fxMesa
->TexState
.EnvMode
[unit0
] ||
1894 envMode0
== GL_COMBINE_EXT
||
1895 envMode1
!= fxMesa
->TexState
.EnvMode
[unit1
] ||
1896 envMode1
== GL_COMBINE_EXT
||
1897 baseImage0
->Format
!= fxMesa
->TexState
.TexFormat
[unit0
] ||
1898 baseImage1
->Format
!= fxMesa
->TexState
.TexFormat
[unit1
] ||
1899 (fxMesa
->Fallback
& TDFX_FALLBACK_TEXTURE_ENV
)) {
1901 if (!SetupDoubleTexEnvVoodoo3(ctx
, unit0
,
1902 ctx
->Texture
.Unit
[0].EnvMode
, baseImage0
->Format
,
1903 ctx
->Texture
.Unit
[1].EnvMode
, baseImage1
->Format
)) {
1904 FALLBACK(fxMesa
, TDFX_FALLBACK_TEXTURE_ENV
, GL_TRUE
);
1907 fxMesa
->TexState
.EnvMode
[unit0
] = envMode0
;
1908 fxMesa
->TexState
.TexFormat
[unit0
] = baseImage0
->Format
;
1909 fxMesa
->TexState
.EnvMode
[unit1
] = envMode1
;
1910 fxMesa
->TexState
.TexFormat
[unit1
] = baseImage1
->Format
;
1911 fxMesa
->TexState
.Enabled
[0] = ctx
->Texture
.Unit
[0]._ReallyEnabled
;
1912 fxMesa
->TexState
.Enabled
[1] = ctx
->Texture
.Unit
[1]._ReallyEnabled
;
1919 tdfxUpdateTextureState( GLcontext
*ctx
)
1921 tdfxContextPtr fxMesa
= TDFX_CONTEXT(ctx
);
1923 FALLBACK(fxMesa
, TDFX_FALLBACK_TEXTURE_BORDER
, GL_FALSE
);
1924 FALLBACK(fxMesa
, TDFX_FALLBACK_TEXTURE_ENV
, GL_FALSE
);
1926 if (ctx
->Texture
.Unit
[0]._ReallyEnabled
== TEXTURE_2D_BIT
&&
1927 ctx
->Texture
.Unit
[1]._ReallyEnabled
== 0) {
1928 LOCK_HARDWARE( fxMesa
); /* XXX remove locking eventually */
1929 setupTextureSingleTMU(ctx
, 0);
1930 UNLOCK_HARDWARE( fxMesa
);
1932 else if (ctx
->Texture
.Unit
[0]._ReallyEnabled
== 0 &&
1933 ctx
->Texture
.Unit
[1]._ReallyEnabled
== TEXTURE_2D_BIT
) {
1934 LOCK_HARDWARE( fxMesa
);
1935 setupTextureSingleTMU(ctx
, 1);
1936 UNLOCK_HARDWARE( fxMesa
);
1938 else if (ctx
->Texture
.Unit
[0]._ReallyEnabled
== TEXTURE_2D_BIT
&&
1939 ctx
->Texture
.Unit
[1]._ReallyEnabled
== TEXTURE_2D_BIT
) {
1940 LOCK_HARDWARE( fxMesa
);
1941 setupTextureDoubleTMU(ctx
);
1942 UNLOCK_HARDWARE( fxMesa
);
1945 /* disable hardware texturing */
1946 if (TDFX_IS_NAPALM(fxMesa
)) {
1947 fxMesa
->ColorCombineExt
.SourceA
= GR_CMBX_ITRGB
;
1948 fxMesa
->ColorCombineExt
.ModeA
= GR_FUNC_MODE_X
;
1949 fxMesa
->ColorCombineExt
.SourceB
= GR_CMBX_ZERO
;
1950 fxMesa
->ColorCombineExt
.ModeB
= GR_FUNC_MODE_ZERO
;
1951 fxMesa
->ColorCombineExt
.SourceC
= GR_CMBX_ZERO
;
1952 fxMesa
->ColorCombineExt
.InvertC
= FXTRUE
;
1953 fxMesa
->ColorCombineExt
.SourceD
= GR_CMBX_ZERO
;
1954 fxMesa
->ColorCombineExt
.InvertD
= FXFALSE
;
1955 fxMesa
->ColorCombineExt
.Shift
= 0;
1956 fxMesa
->ColorCombineExt
.Invert
= FXFALSE
;
1957 fxMesa
->AlphaCombineExt
.SourceA
= GR_CMBX_ITALPHA
;
1958 fxMesa
->AlphaCombineExt
.ModeA
= GR_FUNC_MODE_X
;
1959 fxMesa
->AlphaCombineExt
.SourceB
= GR_CMBX_ZERO
;
1960 fxMesa
->AlphaCombineExt
.ModeB
= GR_FUNC_MODE_ZERO
;
1961 fxMesa
->AlphaCombineExt
.SourceC
= GR_CMBX_ZERO
;
1962 fxMesa
->AlphaCombineExt
.InvertC
= FXTRUE
;
1963 fxMesa
->AlphaCombineExt
.SourceD
= GR_CMBX_ZERO
;
1964 fxMesa
->AlphaCombineExt
.InvertD
= FXFALSE
;
1965 fxMesa
->AlphaCombineExt
.Shift
= 0;
1966 fxMesa
->AlphaCombineExt
.Invert
= FXFALSE
;
1970 fxMesa
->ColorCombine
.Function
= GR_COMBINE_FUNCTION_LOCAL
;
1971 fxMesa
->ColorCombine
.Factor
= GR_COMBINE_FACTOR_NONE
;
1972 fxMesa
->ColorCombine
.Local
= GR_COMBINE_LOCAL_ITERATED
;
1973 fxMesa
->ColorCombine
.Other
= GR_COMBINE_OTHER_NONE
;
1974 fxMesa
->ColorCombine
.Invert
= FXFALSE
;
1975 fxMesa
->AlphaCombine
.Function
= GR_COMBINE_FUNCTION_LOCAL
;
1976 fxMesa
->AlphaCombine
.Factor
= GR_COMBINE_FACTOR_NONE
;
1977 fxMesa
->AlphaCombine
.Local
= GR_COMBINE_LOCAL_ITERATED
;
1978 fxMesa
->AlphaCombine
.Other
= GR_COMBINE_OTHER_NONE
;
1979 fxMesa
->AlphaCombine
.Invert
= FXFALSE
;
1982 fxMesa
->TexState
.Enabled
[0] = 0;
1983 fxMesa
->TexState
.Enabled
[1] = 0;
1984 fxMesa
->TexState
.EnvMode
[0] = 0;
1985 fxMesa
->TexState
.EnvMode
[1] = 0;
1987 fxMesa
->dirty
|= TDFX_UPLOAD_COLOR_COMBINE
;
1988 fxMesa
->dirty
|= TDFX_UPLOAD_ALPHA_COMBINE
;
1990 if (ctx
->Texture
.Unit
[0]._ReallyEnabled
!= 0 ||
1991 ctx
->Texture
.Unit
[1]._ReallyEnabled
!= 0) {
1992 /* software texture (cube map, rect tex, etc */
1993 FALLBACK(fxMesa
, TDFX_FALLBACK_TEXTURE_ENV
, GL_TRUE
);
2001 * This is a special case of texture state update.
2002 * It's used when we've simply bound a new texture to a texture
2003 * unit and the new texture has the exact same attributes as the
2004 * previously bound texture.
2005 * This is very common in Quake3.
2008 tdfxUpdateTextureBinding( GLcontext
*ctx
)
2010 tdfxContextPtr fxMesa
= TDFX_CONTEXT(ctx
);
2011 struct gl_texture_object
*tObj0
= ctx
->Texture
.Unit
[0].Current2D
;
2012 struct gl_texture_object
*tObj1
= ctx
->Texture
.Unit
[1].Current2D
;
2013 tdfxTexInfo
*ti0
= TDFX_TEXTURE_DATA(tObj0
);
2014 tdfxTexInfo
*ti1
= TDFX_TEXTURE_DATA(tObj1
);
2016 const struct gl_shared_state
*mesaShared
= fxMesa
->glCtx
->Shared
;
2017 const struct tdfxSharedState
*shared
= (struct tdfxSharedState
*) mesaShared
->DriverData
;
2020 fxMesa
->sScale0
= ti0
->sScale
;
2021 fxMesa
->tScale0
= ti0
->tScale
;
2022 if (ti0
->info
.format
== GR_TEXFMT_P_8
) {
2023 fxMesa
->TexPalette
.Type
= GR_TEXTABLE_PALETTE_6666_EXT
;
2024 fxMesa
->TexPalette
.Data
= &(ti0
->palette
);
2025 fxMesa
->dirty
|= TDFX_UPLOAD_TEXTURE_PALETTE
;
2027 else if (ti1
&& ti1
->info
.format
== GR_TEXFMT_P_8
) {
2028 fxMesa
->TexPalette
.Type
= GR_TEXTABLE_PALETTE_6666_EXT
;
2029 fxMesa
->TexPalette
.Data
= &(ti1
->palette
);
2030 fxMesa
->dirty
|= TDFX_UPLOAD_TEXTURE_PALETTE
;
2034 fxMesa
->sScale1
= ti1
->sScale
;
2035 fxMesa
->tScale1
= ti1
->tScale
;
2038 if (ctx
->Texture
.Unit
[0]._ReallyEnabled
== TEXTURE_2D_BIT
&&
2039 ctx
->Texture
.Unit
[0]._ReallyEnabled
== 0) {
2040 /* Only unit 0 2D enabled */
2041 if (shared
->umaTexMemory
) {
2042 fxMesa
->TexSource
[0].StartAddress
= ti0
->tm
[0]->startAddr
;
2043 fxMesa
->TexSource
[0].EvenOdd
= GR_MIPMAPLEVELMASK_BOTH
;
2044 fxMesa
->TexSource
[0].Info
= &(ti0
->info
);
2047 if (ti0
->LODblend
&& ti0
->whichTMU
== TDFX_TMU_SPLIT
) {
2048 fxMesa
->TexSource
[0].StartAddress
= ti0
->tm
[TDFX_TMU0
]->startAddr
;
2049 fxMesa
->TexSource
[0].EvenOdd
= GR_MIPMAPLEVELMASK_ODD
;
2050 fxMesa
->TexSource
[0].Info
= &(ti0
->info
);
2051 fxMesa
->TexSource
[1].StartAddress
= ti0
->tm
[TDFX_TMU1
]->startAddr
;
2052 fxMesa
->TexSource
[1].EvenOdd
= GR_MIPMAPLEVELMASK_EVEN
;
2053 fxMesa
->TexSource
[1].Info
= &(ti0
->info
);
2057 if (ti0
->whichTMU
== TDFX_TMU_BOTH
)
2060 tmu
= ti0
->whichTMU
;
2061 fxMesa
->TexSource
[0].Info
= NULL
;
2062 fxMesa
->TexSource
[1].Info
= NULL
;
2064 fxMesa
->TexSource
[tmu
].StartAddress
= ti0
->tm
[tmu
]->startAddr
;
2065 fxMesa
->TexSource
[tmu
].EvenOdd
= GR_MIPMAPLEVELMASK_BOTH
;
2066 fxMesa
->TexSource
[tmu
].Info
= &(ti0
->info
);
2071 else if (ctx
->Texture
.Unit
[0]._ReallyEnabled
== 0 &&
2072 ctx
->Texture
.Unit
[0]._ReallyEnabled
== TEXTURE_2D_BIT
) {
2073 /* Only unit 1 2D enabled */
2074 if (shared
->umaTexMemory
) {
2075 fxMesa
->TexSource
[0].StartAddress
= ti1
->tm
[0]->startAddr
;
2076 fxMesa
->TexSource
[0].EvenOdd
= GR_MIPMAPLEVELMASK_BOTH
;
2077 fxMesa
->TexSource
[0].Info
= &(ti1
->info
);
2080 else if (ctx
->Texture
.Unit
[0]._ReallyEnabled
== TEXTURE_2D_BIT
&&
2081 ctx
->Texture
.Unit
[0]._ReallyEnabled
== TEXTURE_2D_BIT
) {
2082 /* Both 2D enabled */
2083 if (shared
->umaTexMemory
) {
2084 const FxU32 tmu0
= 0, tmu1
= 1;
2085 fxMesa
->TexSource
[tmu0
].StartAddress
= ti0
->tm
[0]->startAddr
;
2086 fxMesa
->TexSource
[tmu0
].EvenOdd
= GR_MIPMAPLEVELMASK_BOTH
;
2087 fxMesa
->TexSource
[tmu0
].Info
= &(ti0
->info
);
2089 fxMesa
->TexSource
[tmu1
].StartAddress
= ti1
->tm
[0]->startAddr
;
2090 fxMesa
->TexSource
[tmu1
].EvenOdd
= GR_MIPMAPLEVELMASK_BOTH
;
2091 fxMesa
->TexSource
[tmu1
].Info
= &(ti1
->info
);
2094 const FxU32 tmu0
= 0, tmu1
= 1;
2095 fxMesa
->TexSource
[tmu0
].StartAddress
= ti0
->tm
[tmu0
]->startAddr
;
2096 fxMesa
->TexSource
[tmu0
].EvenOdd
= GR_MIPMAPLEVELMASK_BOTH
;
2097 fxMesa
->TexSource
[tmu0
].Info
= &(ti0
->info
);
2099 fxMesa
->TexSource
[tmu1
].StartAddress
= ti1
->tm
[tmu1
]->startAddr
;
2100 fxMesa
->TexSource
[tmu1
].EvenOdd
= GR_MIPMAPLEVELMASK_BOTH
;
2101 fxMesa
->TexSource
[tmu1
].Info
= &(ti1
->info
);
2106 fxMesa
->dirty
|= TDFX_UPLOAD_TEXTURE_SOURCE
;