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"
41 #include "tdfx_texman.h"
42 #include "tdfx_texstate.h"
45 /* =============================================================
50 * These macros are used below when handling COMBINE_EXT.
52 #define TEXENV_OPERAND_INVERTED(operand) \
53 (((operand) == GL_ONE_MINUS_SRC_ALPHA) \
54 || ((operand) == GL_ONE_MINUS_SRC_COLOR))
55 #define TEXENV_OPERAND_ALPHA(operand) \
56 (((operand) == GL_SRC_ALPHA) || ((operand) == GL_ONE_MINUS_SRC_ALPHA))
57 #define TEXENV_SETUP_ARG_A(param, source, operand, iteratedAlpha) \
60 param = GR_CMBX_LOCAL_TEXTURE_ALPHA; \
62 case GL_CONSTANT_EXT: \
63 param = GR_CMBX_TMU_CALPHA; \
65 case GL_PRIMARY_COLOR_EXT: \
66 param = GR_CMBX_ITALPHA; \
68 case GL_PREVIOUS_EXT: \
69 param = iteratedAlpha; \
73 * This is here just to keep from getting \
74 * compiler warnings. \
76 param = GR_CMBX_ZERO; \
80 #define TEXENV_SETUP_ARG_RGB(param, source, operand, iteratedColor, iteratedAlpha) \
81 if (!TEXENV_OPERAND_ALPHA(operand)) { \
84 param = GR_CMBX_LOCAL_TEXTURE_RGB; \
86 case GL_CONSTANT_EXT: \
87 param = GR_CMBX_TMU_CCOLOR; \
89 case GL_PRIMARY_COLOR_EXT: \
90 param = GR_CMBX_ITRGB; \
92 case GL_PREVIOUS_EXT: \
93 param = iteratedColor; \
97 * This is here just to keep from getting \
98 * compiler warnings. \
100 param = GR_CMBX_ZERO; \
106 param = GR_CMBX_LOCAL_TEXTURE_ALPHA; \
108 case GL_CONSTANT_EXT: \
109 param = GR_CMBX_TMU_CALPHA; \
111 case GL_PRIMARY_COLOR_EXT: \
112 param = GR_CMBX_ITALPHA; \
114 case GL_PREVIOUS_EXT: \
115 param = iteratedAlpha; \
119 * This is here just to keep from getting \
120 * compiler warnings. \
122 param = GR_CMBX_ZERO; \
127 #define TEXENV_SETUP_MODE_RGB(param, operand) \
131 param = GR_FUNC_MODE_X; \
133 case GL_ONE_MINUS_SRC_ALPHA: \
134 case GL_ONE_MINUS_SRC_COLOR: \
135 param = GR_FUNC_MODE_ONE_MINUS_X; \
138 param = GR_FUNC_MODE_ZERO; \
142 #define TEXENV_SETUP_MODE_A(param, operand) \
145 param = GR_FUNC_MODE_X; \
147 case GL_ONE_MINUS_SRC_ALPHA: \
148 param = GR_FUNC_MODE_ONE_MINUS_X; \
151 param = GR_FUNC_MODE_ZERO; \
158 * Setup a texture environment on Voodoo5.
159 * Return GL_TRUE for success, GL_FALSE for failure.
160 * If we fail, we'll have to use software rendering.
163 SetupTexEnvNapalm(GLcontext
*ctx
, GLboolean useIteratedRGBA
,
164 const struct gl_texture_unit
*texUnit
, GLenum baseFormat
,
165 struct tdfx_texcombine_ext
*env
)
167 tdfxContextPtr fxMesa
= TDFX_CONTEXT(ctx
);
168 GrTCCUColor_t incomingRGB
, incomingAlpha
;
169 const GLenum envMode
= texUnit
->EnvMode
;
171 if (useIteratedRGBA
) {
172 incomingRGB
= GR_CMBX_ITRGB
;
173 incomingAlpha
= GR_CMBX_ITALPHA
;
176 incomingRGB
= GR_CMBX_OTHER_TEXTURE_RGB
;
177 incomingAlpha
= GR_CMBX_OTHER_TEXTURE_ALPHA
;
181 env
->Color
.Shift
= 0;
182 env
->Color
.Invert
= FXFALSE
;
183 env
->Alpha
.Shift
= 0;
184 env
->Alpha
.Invert
= FXFALSE
;
188 /* -- Setup RGB combiner */
189 if (baseFormat
== GL_ALPHA
) {
191 env
->Color
.SourceA
= incomingRGB
;
195 env
->Color
.SourceA
= GR_CMBX_LOCAL_TEXTURE_RGB
;
197 env
->Color
.ModeA
= GR_FUNC_MODE_X
;
198 env
->Color
.SourceB
= GR_CMBX_ZERO
;
199 env
->Color
.ModeB
= GR_FUNC_MODE_ZERO
;
200 env
->Color
.SourceC
= GR_CMBX_ZERO
;
201 env
->Color
.InvertC
= FXTRUE
;
202 env
->Color
.SourceD
= GR_CMBX_ZERO
;
203 env
->Color
.InvertD
= FXFALSE
;
204 /* -- Setup Alpha combiner */
205 if (baseFormat
== GL_LUMINANCE
|| baseFormat
== GL_RGB
) {
207 env
->Alpha
.SourceD
= incomingAlpha
;
211 env
->Alpha
.SourceD
= GR_CMBX_LOCAL_TEXTURE_ALPHA
;
213 env
->Alpha
.SourceA
= GR_CMBX_ITALPHA
;
214 env
->Alpha
.ModeA
= GR_FUNC_MODE_ZERO
;
215 env
->Alpha
.SourceB
= GR_CMBX_ITALPHA
;
216 env
->Alpha
.ModeB
= GR_FUNC_MODE_ZERO
;
217 env
->Alpha
.SourceC
= GR_CMBX_ZERO
;
218 env
->Alpha
.InvertC
= FXFALSE
;
219 env
->Alpha
.InvertD
= FXFALSE
;
223 /* -- Setup RGB combiner */
224 if (baseFormat
== GL_ALPHA
) {
226 env
->Color
.SourceC
= GR_CMBX_ZERO
;
227 env
->Color
.InvertC
= FXTRUE
;
230 /* Result = Frag * Tex */
231 env
->Color
.SourceC
= GR_CMBX_LOCAL_TEXTURE_RGB
;
232 env
->Color
.InvertC
= FXFALSE
;
234 env
->Color
.SourceA
= incomingRGB
;
235 env
->Color
.ModeA
= GR_FUNC_MODE_X
;
236 env
->Color
.SourceB
= GR_CMBX_ZERO
;
237 env
->Color
.ModeB
= GR_FUNC_MODE_ZERO
;
238 env
->Color
.SourceD
= GR_CMBX_ZERO
;
239 env
->Color
.InvertD
= FXFALSE
;
240 /* -- Setup Alpha combiner */
241 if (baseFormat
== GL_LUMINANCE
|| baseFormat
== GL_RGB
) {
243 env
->Alpha
.SourceA
= incomingAlpha
;
244 env
->Alpha
.SourceC
= GR_CMBX_ZERO
;
245 env
->Alpha
.InvertC
= FXTRUE
;
249 env
->Alpha
.SourceA
= GR_CMBX_LOCAL_TEXTURE_ALPHA
;
250 env
->Alpha
.SourceC
= incomingAlpha
;
251 env
->Alpha
.InvertC
= FXFALSE
;
253 env
->Alpha
.ModeA
= GR_FUNC_MODE_X
;
254 env
->Alpha
.SourceB
= GR_CMBX_ITALPHA
;
255 env
->Alpha
.ModeB
= GR_FUNC_MODE_ZERO
;
256 env
->Alpha
.SourceD
= GR_CMBX_ZERO
;
257 env
->Alpha
.InvertD
= FXFALSE
;
261 /* -- Setup RGB combiner */
262 if (baseFormat
== GL_RGB
) {
264 env
->Color
.SourceB
= GR_CMBX_ZERO
;
265 env
->Color
.ModeB
= GR_FUNC_MODE_X
;
266 env
->Color
.SourceC
= GR_CMBX_ZERO
;
267 env
->Color
.InvertC
= FXTRUE
;
268 env
->Color
.SourceD
= GR_CMBX_ZERO
;
269 env
->Color
.InvertD
= FXFALSE
;
272 /* Rv = Rf * (1 - At) + Rt * At */
273 env
->Color
.SourceB
= incomingRGB
;
274 env
->Color
.ModeB
= GR_FUNC_MODE_NEGATIVE_X
;
275 env
->Color
.SourceC
= GR_CMBX_LOCAL_TEXTURE_ALPHA
;
276 env
->Color
.InvertC
= FXFALSE
;
277 env
->Color
.SourceD
= GR_CMBX_B
;
278 env
->Color
.InvertD
= FXFALSE
;
280 env
->Color
.SourceA
= GR_CMBX_LOCAL_TEXTURE_RGB
;
281 env
->Color
.ModeA
= GR_FUNC_MODE_X
;
282 /* -- Setup Alpha combiner */
284 env
->Alpha
.SourceA
= incomingAlpha
;
285 env
->Alpha
.ModeA
= GR_FUNC_MODE_X
;
286 env
->Alpha
.SourceB
= GR_CMBX_ITALPHA
;
287 env
->Alpha
.ModeB
= GR_FUNC_MODE_ZERO
;
288 env
->Alpha
.SourceC
= GR_CMBX_ZERO
;
289 env
->Alpha
.InvertC
= FXTRUE
;
290 env
->Alpha
.SourceD
= GR_CMBX_ZERO
;
291 env
->Alpha
.InvertD
= FXFALSE
;
295 /* -- Setup RGB combiner */
296 if (baseFormat
== GL_ALPHA
) {
298 env
->Color
.SourceA
= incomingRGB
;
299 env
->Color
.ModeA
= GR_FUNC_MODE_X
;
300 env
->Color
.SourceB
= GR_CMBX_ZERO
;
301 env
->Color
.ModeB
= GR_FUNC_MODE_ZERO
;
302 env
->Color
.SourceC
= GR_CMBX_ZERO
;
303 env
->Color
.InvertC
= FXTRUE
;
304 env
->Color
.SourceD
= GR_CMBX_ZERO
;
305 env
->Color
.InvertD
= FXFALSE
;
308 /* Rv = Rf * (1 - Rt) + Rc * Rt */
309 env
->Color
.SourceA
= GR_CMBX_TMU_CCOLOR
;
310 env
->Color
.ModeA
= GR_FUNC_MODE_X
;
311 env
->Color
.SourceB
= incomingRGB
;
312 env
->Color
.ModeB
= GR_FUNC_MODE_NEGATIVE_X
;
313 env
->Color
.SourceC
= GR_CMBX_LOCAL_TEXTURE_RGB
;
314 env
->Color
.InvertC
= FXFALSE
;
315 env
->Color
.SourceD
= GR_CMBX_B
;
316 env
->Color
.InvertD
= FXFALSE
;
318 /* -- Setup Alpha combiner */
319 if (baseFormat
== GL_LUMINANCE
|| baseFormat
== GL_RGB
) {
321 env
->Alpha
.SourceA
= incomingAlpha
;
322 env
->Alpha
.ModeA
= GR_FUNC_MODE_X
;
323 env
->Alpha
.SourceB
= GR_CMBX_ZERO
;
324 env
->Alpha
.ModeB
= GR_FUNC_MODE_ZERO
;
325 env
->Alpha
.SourceC
= GR_CMBX_ZERO
;
326 env
->Alpha
.InvertC
= FXTRUE
;
327 env
->Alpha
.SourceD
= GR_CMBX_ZERO
;
328 env
->Alpha
.InvertD
= FXFALSE
;
330 else if (baseFormat
== GL_INTENSITY
) {
331 /* Av = Af * (1 - It) + Ac * It */
332 env
->Alpha
.SourceA
= GR_CMBX_TMU_CALPHA
;
333 env
->Alpha
.ModeA
= GR_FUNC_MODE_X
;
334 env
->Alpha
.SourceB
= incomingAlpha
;
335 env
->Alpha
.ModeB
= GR_FUNC_MODE_NEGATIVE_X
;
336 env
->Alpha
.SourceC
= GR_CMBX_LOCAL_TEXTURE_ALPHA
;
337 env
->Alpha
.InvertC
= FXFALSE
;
338 env
->Alpha
.SourceD
= GR_CMBX_B
;
339 env
->Alpha
.InvertD
= FXFALSE
;
343 env
->Alpha
.SourceA
= GR_CMBX_LOCAL_TEXTURE_ALPHA
;
344 env
->Alpha
.ModeA
= GR_FUNC_MODE_X
;
345 env
->Alpha
.SourceB
= GR_CMBX_ITALPHA
;
346 env
->Alpha
.ModeB
= GR_FUNC_MODE_ZERO
;
347 env
->Alpha
.SourceC
= incomingAlpha
;
348 env
->Alpha
.InvertC
= FXFALSE
;
349 env
->Alpha
.SourceD
= GR_CMBX_ZERO
;
350 env
->Alpha
.InvertD
= FXFALSE
;
352 /* Also have to set up the tex env constant color */
353 env
->EnvColor
= PACK_RGBA32(texUnit
->EnvColor
[0] * 255.0F
,
354 texUnit
->EnvColor
[1] * 255.0F
,
355 texUnit
->EnvColor
[2] * 255.0F
,
356 texUnit
->EnvColor
[3] * 255.0F
);
359 /* -- Setup RGB combiner */
360 if (baseFormat
== GL_ALPHA
) {
362 env
->Color
.SourceB
= GR_CMBX_ZERO
;
363 env
->Color
.ModeB
= GR_FUNC_MODE_ZERO
;
367 env
->Color
.SourceB
= GR_CMBX_LOCAL_TEXTURE_RGB
;
368 env
->Color
.ModeB
= GR_FUNC_MODE_X
;
370 env
->Color
.SourceA
= incomingRGB
;
371 env
->Color
.ModeA
= GR_FUNC_MODE_X
;
372 env
->Color
.SourceC
= GR_CMBX_ZERO
;
373 env
->Color
.InvertC
= FXTRUE
;
374 env
->Color
.SourceD
= GR_CMBX_ZERO
;
375 env
->Color
.InvertD
= FXFALSE
;
376 /* -- Setup Alpha combiner */
377 if (baseFormat
== GL_LUMINANCE
|| baseFormat
== GL_RGB
) {
379 env
->Alpha
.SourceA
= incomingAlpha
;
380 env
->Alpha
.SourceB
= GR_CMBX_ITALPHA
;
381 env
->Alpha
.ModeB
= GR_FUNC_MODE_ZERO
;
382 env
->Alpha
.SourceC
= GR_CMBX_ZERO
;
383 env
->Alpha
.InvertC
= FXTRUE
;
386 else if (baseFormat
== GL_INTENSITY
) {
388 env
->Alpha
.SourceA
= incomingAlpha
;
389 env
->Alpha
.SourceB
= GR_CMBX_LOCAL_TEXTURE_ALPHA
;
390 env
->Alpha
.ModeB
= GR_FUNC_MODE_X
;
391 env
->Alpha
.SourceC
= GR_CMBX_ZERO
;
392 env
->Alpha
.InvertC
= FXTRUE
;
396 env
->Alpha
.SourceA
= GR_CMBX_LOCAL_TEXTURE_ALPHA
;
397 env
->Alpha
.SourceB
= GR_CMBX_ITALPHA
;
398 env
->Alpha
.ModeB
= GR_FUNC_MODE_ZERO
;
399 env
->Alpha
.SourceC
= incomingAlpha
;
400 env
->Alpha
.InvertC
= FXFALSE
;
402 env
->Alpha
.ModeA
= GR_FUNC_MODE_X
;
403 env
->Alpha
.SourceD
= GR_CMBX_ZERO
;
404 env
->Alpha
.InvertD
= FXFALSE
;
409 FxU32 A_RGB
, B_RGB
, C_RGB
, D_RGB
;
410 FxU32 Amode_RGB
, Bmode_RGB
;
411 FxBool Cinv_RGB
, Dinv_RGB
, Ginv_RGB
;
413 FxU32 A_A
, B_A
, C_A
, D_A
;
414 FxU32 Amode_A
, Bmode_A
;
415 FxBool Cinv_A
, Dinv_A
, Ginv_A
;
420 * In the formulas below, we write:
421 * o "1(x)" for the identity function applied to x,
423 * o "0(x)" for the constant function 0, so
424 * 0(x) = 0 for all values of x.
426 * Calculate the color combination.
428 Shift_RGB
= texUnit
->Combine
.ScaleShiftRGB
;
429 Shift_A
= texUnit
->Combine
.ScaleShiftA
;
430 switch (texUnit
->Combine
.ModeRGB
) {
433 * The formula is: Arg0
434 * We implement this by the formula:
435 * (Arg0 + 0(0))*(1-0) + 0
437 TEXENV_SETUP_ARG_RGB(A_RGB
,
438 texUnit
->Combine
.SourceRGB
[0],
439 texUnit
->Combine
.OperandRGB
[0],
440 incomingRGB
, incomingAlpha
);
441 TEXENV_SETUP_MODE_RGB(Amode_RGB
,
442 texUnit
->Combine
.OperandRGB
[0]);
443 B_RGB
= C_RGB
= D_RGB
= GR_CMBX_ZERO
;
444 Bmode_RGB
= GR_FUNC_MODE_ZERO
;
446 Dinv_RGB
= Ginv_RGB
= FXFALSE
;
450 * The formula is: Arg0 * Arg1
452 * We implement this by the formula
453 * (Arg0 + 0(0)) * Arg1 + 0(0)
455 TEXENV_SETUP_ARG_RGB(A_RGB
,
456 texUnit
->Combine
.SourceRGB
[0],
457 texUnit
->Combine
.OperandRGB
[0],
458 incomingRGB
, incomingAlpha
);
459 TEXENV_SETUP_MODE_RGB(Amode_RGB
,
460 texUnit
->Combine
.OperandRGB
[0]);
461 B_RGB
= GR_CMBX_ZERO
;
462 Bmode_RGB
= GR_CMBX_ZERO
;
463 TEXENV_SETUP_ARG_RGB(C_RGB
,
464 texUnit
->Combine
.SourceRGB
[1],
465 texUnit
->Combine
.OperandRGB
[1],
466 incomingRGB
, incomingAlpha
);
467 Cinv_RGB
= TEXENV_OPERAND_INVERTED
468 (texUnit
->Combine
.OperandRGB
[1]);
469 D_RGB
= GR_CMBX_ZERO
;
470 Dinv_RGB
= Ginv_RGB
= FXFALSE
;
474 * The formula is Arg0 + Arg1
476 TEXENV_SETUP_ARG_RGB(A_RGB
,
477 texUnit
->Combine
.SourceRGB
[0],
478 texUnit
->Combine
.OperandRGB
[0],
479 incomingRGB
, incomingAlpha
);
480 TEXENV_SETUP_MODE_RGB(Amode_RGB
,
481 texUnit
->Combine
.OperandRGB
[0]);
482 TEXENV_SETUP_ARG_RGB(B_RGB
,
483 texUnit
->Combine
.SourceRGB
[1],
484 texUnit
->Combine
.OperandRGB
[1],
485 incomingRGB
, incomingAlpha
);
486 TEXENV_SETUP_MODE_RGB(Bmode_RGB
,
487 texUnit
->Combine
.OperandRGB
[1]);
488 C_RGB
= D_RGB
= GR_CMBX_ZERO
;
490 Dinv_RGB
= Ginv_RGB
= FXFALSE
;
492 case GL_ADD_SIGNED_EXT
:
494 * The formula is: Arg0 + Arg1 - 0.5.
495 * We compute this by calculating:
496 * (Arg0 - 1/2) + Arg1 if op0 is SRC_{COLOR,ALPHA}
497 * Arg0 + (Arg1 - 1/2) if op1 is SRC_{COLOR,ALPHA}
498 * If both op0 and op1 are ONE_MINUS_SRC_{COLOR,ALPHA}
499 * we cannot implement the formula properly.
501 TEXENV_SETUP_ARG_RGB(A_RGB
,
502 texUnit
->Combine
.SourceRGB
[0],
503 texUnit
->Combine
.OperandRGB
[0],
504 incomingRGB
, incomingAlpha
);
505 TEXENV_SETUP_ARG_RGB(B_RGB
,
506 texUnit
->Combine
.SourceRGB
[1],
507 texUnit
->Combine
.OperandRGB
[1],
508 incomingRGB
, incomingAlpha
);
509 if (!TEXENV_OPERAND_INVERTED(texUnit
->Combine
.OperandRGB
[0])) {
511 * A is not inverted. So, choose it.
513 Amode_RGB
= GR_FUNC_MODE_X_MINUS_HALF
;
514 if (!TEXENV_OPERAND_INVERTED
515 (texUnit
->Combine
.OperandRGB
[1])) {
516 Bmode_RGB
= GR_FUNC_MODE_X
;
519 Bmode_RGB
= GR_FUNC_MODE_ONE_MINUS_X
;
524 * A is inverted, so try to subtract 1/2
527 Amode_RGB
= GR_FUNC_MODE_ONE_MINUS_X
;
528 if (!TEXENV_OPERAND_INVERTED
529 (texUnit
->Combine
.OperandRGB
[1])) {
530 Bmode_RGB
= GR_FUNC_MODE_X_MINUS_HALF
;
534 * Both are inverted. This is the case
535 * we cannot handle properly. We just
536 * choose to not add the - 1/2.
538 Bmode_RGB
= GR_FUNC_MODE_ONE_MINUS_X
;
542 C_RGB
= D_RGB
= GR_CMBX_ZERO
;
544 Dinv_RGB
= Ginv_RGB
= FXFALSE
;
546 case GL_INTERPOLATE_EXT
:
548 * The formula is: Arg0 * Arg2 + Arg1 * (1 - Arg2).
549 * We compute this by the formula:
550 * (Arg0 - Arg1) * Arg2 + Arg1
551 * == Arg0 * Arg2 - Arg1 * Arg2 + Arg1
552 * == Arg0 * Arg2 + Arg1 * (1 - Arg2)
553 * However, if both Arg1 is ONE_MINUS_X, the HW does
554 * not support it properly.
556 TEXENV_SETUP_ARG_RGB(A_RGB
,
557 texUnit
->Combine
.SourceRGB
[0],
558 texUnit
->Combine
.OperandRGB
[0],
559 incomingRGB
, incomingAlpha
);
560 TEXENV_SETUP_MODE_RGB(Amode_RGB
,
561 texUnit
->Combine
.OperandRGB
[0]);
562 TEXENV_SETUP_ARG_RGB(B_RGB
,
563 texUnit
->Combine
.SourceRGB
[1],
564 texUnit
->Combine
.OperandRGB
[1],
565 incomingRGB
, incomingAlpha
);
566 if (TEXENV_OPERAND_INVERTED(texUnit
->Combine
.OperandRGB
[1])) {
568 * This case is wrong.
570 Bmode_RGB
= GR_FUNC_MODE_NEGATIVE_X
;
574 Bmode_RGB
= GR_FUNC_MODE_NEGATIVE_X
;
577 * The Source/Operand for the C value must
578 * specify some kind of alpha value.
580 TEXENV_SETUP_ARG_A(C_RGB
,
581 texUnit
->Combine
.SourceRGB
[2],
582 texUnit
->Combine
.OperandRGB
[2],
586 Dinv_RGB
= Ginv_RGB
= FXFALSE
;
590 * This is here mostly to keep from getting
591 * a compiler warning about these not being set.
592 * However, this should set all the texture values
595 A_RGB
= B_RGB
= C_RGB
= D_RGB
= GR_CMBX_ZERO
;
596 Amode_RGB
= Bmode_RGB
= GR_FUNC_MODE_X
;
597 Cinv_RGB
= Dinv_RGB
= Ginv_RGB
= FXFALSE
;
601 * Calculate the alpha combination.
603 switch (texUnit
->Combine
.ModeA
) {
606 * The formula is: Arg0
607 * We implement this by the formula:
608 * (Arg0 + 0(0))*(1-0) + 0
610 TEXENV_SETUP_ARG_A(A_A
,
611 texUnit
->Combine
.SourceA
[0],
612 texUnit
->Combine
.OperandA
[0],
614 TEXENV_SETUP_MODE_A(Amode_A
,
615 texUnit
->Combine
.OperandA
[0]);
616 B_A
= GR_CMBX_ITALPHA
;
617 Bmode_A
= GR_FUNC_MODE_ZERO
;
618 C_A
= D_A
= GR_CMBX_ZERO
;
620 Dinv_A
= Ginv_A
= FXFALSE
;
624 * The formula is: Arg0 * Arg1
626 * We implement this by the formula
627 * (Arg0 + 0(0)) * Arg1 + 0(0)
629 TEXENV_SETUP_ARG_A(A_A
,
630 texUnit
->Combine
.SourceA
[0],
631 texUnit
->Combine
.OperandA
[0],
633 TEXENV_SETUP_MODE_A(Amode_A
,
634 texUnit
->Combine
.OperandA
[0]);
636 Bmode_A
= GR_CMBX_ZERO
;
637 TEXENV_SETUP_ARG_A(C_A
,
638 texUnit
->Combine
.SourceA
[1],
639 texUnit
->Combine
.OperandA
[1],
641 Cinv_A
= TEXENV_OPERAND_INVERTED
642 (texUnit
->Combine
.OperandA
[1]);
644 Dinv_A
= Ginv_A
= FXFALSE
;
648 * The formula is Arg0 + Arg1
650 TEXENV_SETUP_ARG_A(A_A
,
651 texUnit
->Combine
.SourceA
[0],
652 texUnit
->Combine
.OperandA
[0],
654 TEXENV_SETUP_MODE_A(Amode_A
,
655 texUnit
->Combine
.OperandA
[0]);
656 TEXENV_SETUP_ARG_A(B_A
,
657 texUnit
->Combine
.SourceA
[1],
658 texUnit
->Combine
.OperandA
[1],
660 TEXENV_SETUP_MODE_A(Bmode_A
,
661 texUnit
->Combine
.OperandA
[1]);
662 C_A
= D_A
= GR_CMBX_ZERO
;
664 Dinv_A
= Ginv_A
= FXFALSE
;
666 case GL_ADD_SIGNED_EXT
:
668 * The formula is: Arg0 + Arg1 - 0.5.
669 * We compute this by calculating:
670 * (Arg0 - 1/2) + Arg1 if op0 is SRC_{COLOR,ALPHA}
671 * Arg0 + (Arg1 - 1/2) if op1 is SRC_{COLOR,ALPHA}
672 * If both op0 and op1 are ONE_MINUS_SRC_{COLOR,ALPHA}
673 * we cannot implement the formula properly.
675 TEXENV_SETUP_ARG_A(A_A
,
676 texUnit
->Combine
.SourceA
[0],
677 texUnit
->Combine
.OperandA
[0],
679 TEXENV_SETUP_ARG_A(B_A
,
680 texUnit
->Combine
.SourceA
[1],
681 texUnit
->Combine
.OperandA
[1],
683 if (!TEXENV_OPERAND_INVERTED(texUnit
->Combine
.OperandA
[0])) {
685 * A is not inverted. So, choose it.
687 Amode_A
= GR_FUNC_MODE_X_MINUS_HALF
;
688 if (!TEXENV_OPERAND_INVERTED
689 (texUnit
->Combine
.OperandA
[1])) {
690 Bmode_A
= GR_FUNC_MODE_X
;
692 Bmode_A
= GR_FUNC_MODE_ONE_MINUS_X
;
696 * A is inverted, so try to subtract 1/2
699 Amode_A
= GR_FUNC_MODE_ONE_MINUS_X
;
700 if (!TEXENV_OPERAND_INVERTED
701 (texUnit
->Combine
.OperandA
[1])) {
702 Bmode_A
= GR_FUNC_MODE_X_MINUS_HALF
;
705 * Both are inverted. This is the case
706 * we cannot handle properly. We just
707 * choose to not add the - 1/2.
709 Bmode_A
= GR_FUNC_MODE_ONE_MINUS_X
;
713 C_A
= D_A
= GR_CMBX_ZERO
;
715 Dinv_A
= Ginv_A
= FXFALSE
;
717 case GL_INTERPOLATE_EXT
:
719 * The formula is: Arg0 * Arg2 + Arg1 * (1 - Arg2).
720 * We compute this by the formula:
721 * (Arg0 - Arg1) * Arg2 + Arg1
722 * == Arg0 * Arg2 - Arg1 * Arg2 + Arg1
723 * == Arg0 * Arg2 + Arg1 * (1 - Arg2)
724 * However, if both Arg1 is ONE_MINUS_X, the HW does
725 * not support it properly.
727 TEXENV_SETUP_ARG_A(A_A
,
728 texUnit
->Combine
.SourceA
[0],
729 texUnit
->Combine
.OperandA
[0],
731 TEXENV_SETUP_MODE_A(Amode_A
,
732 texUnit
->Combine
.OperandA
[0]);
733 TEXENV_SETUP_ARG_A(B_A
,
734 texUnit
->Combine
.SourceA
[1],
735 texUnit
->Combine
.OperandA
[1],
737 if (!TEXENV_OPERAND_INVERTED(texUnit
->Combine
.OperandA
[1])) {
738 Bmode_A
= GR_FUNC_MODE_NEGATIVE_X
;
742 * This case is wrong.
744 Bmode_A
= GR_FUNC_MODE_NEGATIVE_X
;
748 * The Source/Operand for the C value must
749 * specify some kind of alpha value.
751 TEXENV_SETUP_ARG_A(C_A
,
752 texUnit
->Combine
.SourceA
[2],
753 texUnit
->Combine
.OperandA
[2],
757 Dinv_A
= Ginv_A
= FXFALSE
;
761 * This is here mostly to keep from getting
762 * a compiler warning about these not being set.
763 * However, this should set all the alpha values
766 A_A
= B_A
= C_A
= D_A
= GR_CMBX_ZERO
;
767 Amode_A
= Bmode_A
= GR_FUNC_MODE_X
;
768 Cinv_A
= Dinv_A
= FXFALSE
;
773 * Save the parameters.
775 env
->Color
.SourceA
= A_RGB
;
776 env
->Color
.ModeA
= Amode_RGB
;
777 env
->Color
.SourceB
= B_RGB
;
778 env
->Color
.ModeB
= Bmode_RGB
;
779 env
->Color
.SourceC
= C_RGB
;
780 env
->Color
.InvertC
= Cinv_RGB
;
781 env
->Color
.SourceD
= D_RGB
;
782 env
->Color
.InvertD
= Dinv_RGB
;
783 env
->Color
.Shift
= Shift_RGB
;
784 env
->Color
.Invert
= Ginv_RGB
;
785 env
->Alpha
.SourceA
= A_A
;
786 env
->Alpha
.ModeA
= Amode_A
;
787 env
->Alpha
.SourceB
= B_A
;
788 env
->Alpha
.ModeB
= Bmode_A
;
789 env
->Alpha
.SourceC
= C_A
;
790 env
->Alpha
.InvertC
= Cinv_A
;
791 env
->Alpha
.SourceD
= D_A
;
792 env
->Alpha
.InvertD
= Dinv_A
;
793 env
->Alpha
.Shift
= Shift_A
;
794 env
->Alpha
.Invert
= Ginv_A
;
795 env
->EnvColor
= PACK_RGBA32(texUnit
->EnvColor
[0] * 255.0F
,
796 texUnit
->EnvColor
[1] * 255.0F
,
797 texUnit
->EnvColor
[2] * 255.0F
,
798 texUnit
->EnvColor
[3] * 255.0F
);
803 _mesa_problem(ctx
, "%s: Bad envMode", __FUNCTION__
);
806 fxMesa
->dirty
|= TDFX_UPLOAD_TEXTURE_ENV
;
808 fxMesa
->ColorCombineExt
.SourceA
= GR_CMBX_TEXTURE_RGB
;
809 fxMesa
->ColorCombineExt
.ModeA
= GR_FUNC_MODE_X
,
810 fxMesa
->ColorCombineExt
.SourceB
= GR_CMBX_ZERO
;
811 fxMesa
->ColorCombineExt
.ModeB
= GR_FUNC_MODE_X
;
812 fxMesa
->ColorCombineExt
.SourceC
= GR_CMBX_ZERO
;
813 fxMesa
->ColorCombineExt
.InvertC
= FXTRUE
;
814 fxMesa
->ColorCombineExt
.SourceD
= GR_CMBX_ZERO
;
815 fxMesa
->ColorCombineExt
.InvertD
= FXFALSE
;
816 fxMesa
->ColorCombineExt
.Shift
= 0;
817 fxMesa
->ColorCombineExt
.Invert
= FXFALSE
;
818 fxMesa
->dirty
|= TDFX_UPLOAD_COLOR_COMBINE
;
819 fxMesa
->AlphaCombineExt
.SourceA
= GR_CMBX_TEXTURE_ALPHA
;
820 fxMesa
->AlphaCombineExt
.ModeA
= GR_FUNC_MODE_X
;
821 fxMesa
->AlphaCombineExt
.SourceB
= GR_CMBX_ZERO
;
822 fxMesa
->AlphaCombineExt
.ModeB
= GR_FUNC_MODE_X
;
823 fxMesa
->AlphaCombineExt
.SourceC
= GR_CMBX_ZERO
;
824 fxMesa
->AlphaCombineExt
.InvertC
= FXTRUE
;
825 fxMesa
->AlphaCombineExt
.SourceD
= GR_CMBX_ZERO
;
826 fxMesa
->AlphaCombineExt
.InvertD
= FXFALSE
;
827 fxMesa
->AlphaCombineExt
.Shift
= 0;
828 fxMesa
->AlphaCombineExt
.Invert
= FXFALSE
;
829 fxMesa
->dirty
|= TDFX_UPLOAD_ALPHA_COMBINE
;
830 return GL_TRUE
; /* success */
836 * Setup the Voodoo3 texture environment for a single texture unit.
837 * Return GL_TRUE for success, GL_FALSE for failure.
838 * If failure, we'll use software rendering.
841 SetupSingleTexEnvVoodoo3(GLcontext
*ctx
, int unit
,
842 GLenum envMode
, GLenum baseFormat
)
844 tdfxContextPtr fxMesa
= TDFX_CONTEXT(ctx
);
845 GrCombineLocal_t localc
, locala
;
846 struct tdfx_combine alphaComb
, colorComb
;
848 if (1 /*iteratedRGBA*/)
849 localc
= locala
= GR_COMBINE_LOCAL_ITERATED
;
851 localc
= locala
= GR_COMBINE_LOCAL_CONSTANT
;
855 alphaComb
.Function
= GR_COMBINE_FUNCTION_LOCAL
;
856 alphaComb
.Factor
= GR_COMBINE_FACTOR_NONE
;
857 alphaComb
.Local
= locala
;
858 alphaComb
.Other
= GR_COMBINE_OTHER_NONE
;
859 alphaComb
.Invert
= FXFALSE
;
860 colorComb
.Function
= GR_COMBINE_FUNCTION_BLEND
;
861 colorComb
.Factor
= GR_COMBINE_FACTOR_TEXTURE_ALPHA
;
862 colorComb
.Local
= localc
;
863 colorComb
.Other
= GR_COMBINE_OTHER_TEXTURE
;
864 colorComb
.Invert
= FXFALSE
;
867 alphaComb
.Function
= GR_COMBINE_FUNCTION_SCALE_OTHER
;
868 alphaComb
.Factor
= GR_COMBINE_FACTOR_LOCAL
;
869 alphaComb
.Local
= locala
;
870 alphaComb
.Other
= GR_COMBINE_OTHER_TEXTURE
;
871 alphaComb
.Invert
= FXFALSE
;
872 if (baseFormat
== GL_ALPHA
) {
873 colorComb
.Function
= GR_COMBINE_FUNCTION_LOCAL
;
874 colorComb
.Factor
= GR_COMBINE_FACTOR_NONE
;
875 colorComb
.Local
= localc
;
876 colorComb
.Other
= GR_COMBINE_OTHER_NONE
;
877 colorComb
.Invert
= FXFALSE
;
880 colorComb
.Function
= GR_COMBINE_FUNCTION_SCALE_OTHER
;
881 colorComb
.Factor
= GR_COMBINE_FACTOR_LOCAL
;
882 colorComb
.Local
= localc
;
883 colorComb
.Other
= GR_COMBINE_OTHER_TEXTURE
;
884 colorComb
.Invert
= FXFALSE
;
890 * XXX we can't do real GL_BLEND mode. These settings assume that
891 * the TexEnv color is black and incoming fragment color is white.
893 if (baseFormat
== GL_LUMINANCE
|| baseFormat
== GL_RGB
) {
895 alphaComb
.Function
= GR_COMBINE_FUNCTION_LOCAL
;
896 alphaComb
.Factor
= GR_COMBINE_FACTOR_NONE
;
897 alphaComb
.Local
= locala
;
898 alphaComb
.Other
= GR_COMBINE_OTHER_NONE
;
899 alphaComb
.Invert
= FXFALSE
;
901 else if (baseFormat
== GL_INTENSITY
) {
902 /* Av = Af * (1 - It) + Ac * It */
903 alphaComb
.Function
= GR_COMBINE_FUNCTION_BLEND
;
904 alphaComb
.Factor
= GR_COMBINE_FACTOR_TEXTURE_ALPHA
;
905 alphaComb
.Local
= locala
;
906 alphaComb
.Other
= GR_COMBINE_OTHER_CONSTANT
;
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_BLEND
;
926 colorComb
.Factor
= GR_COMBINE_FACTOR_TEXTURE_RGB
;
927 colorComb
.Local
= localc
;
928 colorComb
.Other
= GR_COMBINE_OTHER_CONSTANT
;
929 colorComb
.Invert
= FXTRUE
;
931 fxMesa
->Color
.MonoColor
= PACK_RGBA32(
932 ctx
->Texture
.Unit
[unit
].EnvColor
[0] * 255.0f
,
933 ctx
->Texture
.Unit
[unit
].EnvColor
[1] * 255.0f
,
934 ctx
->Texture
.Unit
[unit
].EnvColor
[2] * 255.0f
,
935 ctx
->Texture
.Unit
[unit
].EnvColor
[3] * 255.0f
);
936 fxMesa
->dirty
|= TDFX_UPLOAD_CONSTANT_COLOR
;
940 if ((baseFormat
== GL_RGB
) || (baseFormat
== GL_LUMINANCE
)) {
941 alphaComb
.Function
= GR_COMBINE_FUNCTION_LOCAL
;
942 alphaComb
.Factor
= GR_COMBINE_FACTOR_NONE
;
943 alphaComb
.Local
= locala
;
944 alphaComb
.Other
= GR_COMBINE_OTHER_NONE
;
945 alphaComb
.Invert
= FXFALSE
;
948 alphaComb
.Function
= GR_COMBINE_FUNCTION_SCALE_OTHER
;
949 alphaComb
.Factor
= GR_COMBINE_FACTOR_ONE
;
950 alphaComb
.Local
= locala
;
951 alphaComb
.Other
= GR_COMBINE_OTHER_TEXTURE
;
952 alphaComb
.Invert
= FXFALSE
;
954 if (baseFormat
== GL_ALPHA
) {
955 colorComb
.Function
= GR_COMBINE_FUNCTION_LOCAL
;
956 colorComb
.Factor
= GR_COMBINE_FACTOR_NONE
;
957 colorComb
.Local
= localc
;
958 colorComb
.Other
= GR_COMBINE_OTHER_NONE
;
959 colorComb
.Invert
= FXFALSE
;
962 colorComb
.Function
= GR_COMBINE_FUNCTION_SCALE_OTHER
;
963 colorComb
.Factor
= GR_COMBINE_FACTOR_ONE
;
964 colorComb
.Local
= localc
;
965 colorComb
.Other
= GR_COMBINE_OTHER_TEXTURE
;
966 colorComb
.Invert
= FXFALSE
;
971 if (baseFormat
== GL_ALPHA
||
972 baseFormat
== GL_LUMINANCE_ALPHA
||
973 baseFormat
== GL_RGBA
) {
974 /* product of texel and fragment alpha */
975 alphaComb
.Function
= GR_COMBINE_FUNCTION_SCALE_OTHER
;
976 alphaComb
.Factor
= GR_COMBINE_FACTOR_LOCAL
;
977 alphaComb
.Local
= locala
;
978 alphaComb
.Other
= GR_COMBINE_OTHER_TEXTURE
;
979 alphaComb
.Invert
= FXFALSE
;
981 else if (baseFormat
== GL_LUMINANCE
|| baseFormat
== GL_RGB
) {
982 /* fragment alpha is unchanged */
983 alphaComb
.Function
= GR_COMBINE_FUNCTION_LOCAL
;
984 alphaComb
.Factor
= GR_COMBINE_FACTOR_NONE
;
985 alphaComb
.Local
= locala
;
986 alphaComb
.Other
= GR_COMBINE_OTHER_NONE
;
987 alphaComb
.Invert
= FXFALSE
;
990 ASSERT(baseFormat
== GL_INTENSITY
);
991 /* sum of texel and fragment alpha */
992 alphaComb
.Function
= GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL
,
993 alphaComb
.Factor
= GR_COMBINE_FACTOR_ONE
;
994 alphaComb
.Local
= locala
;
995 alphaComb
.Other
= GR_COMBINE_OTHER_TEXTURE
;
996 alphaComb
.Invert
= FXFALSE
;
998 if (baseFormat
== GL_ALPHA
) {
1000 colorComb
.Function
= GR_COMBINE_FUNCTION_LOCAL
;
1001 colorComb
.Factor
= GR_COMBINE_FACTOR_NONE
;
1002 colorComb
.Local
= localc
;
1003 colorComb
.Other
= GR_COMBINE_OTHER_NONE
;
1004 colorComb
.Invert
= FXFALSE
;
1007 /* sum of texel and fragment rgb */
1008 colorComb
.Function
= GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL
,
1009 colorComb
.Factor
= GR_COMBINE_FACTOR_ONE
;
1010 colorComb
.Local
= localc
;
1011 colorComb
.Other
= GR_COMBINE_OTHER_TEXTURE
;
1012 colorComb
.Invert
= FXFALSE
;
1017 (void) memcpy(&colorComb
, &fxMesa
->ColorCombine
, sizeof(colorComb
));
1018 (void) memcpy(&alphaComb
, &fxMesa
->AlphaCombine
, sizeof(alphaComb
));
1019 _mesa_problem(ctx
, "bad texture env mode in %s", __FUNCTION__
);
1023 if (colorComb
.Function
!= fxMesa
->ColorCombine
.Function
||
1024 colorComb
.Factor
!= fxMesa
->ColorCombine
.Factor
||
1025 colorComb
.Local
!= fxMesa
->ColorCombine
.Local
||
1026 colorComb
.Other
!= fxMesa
->ColorCombine
.Other
||
1027 colorComb
.Invert
!= fxMesa
->ColorCombine
.Invert
) {
1028 fxMesa
->ColorCombine
= colorComb
;
1029 fxMesa
->dirty
|= TDFX_UPLOAD_COLOR_COMBINE
;
1032 if (alphaComb
.Function
!= fxMesa
->AlphaCombine
.Function
||
1033 alphaComb
.Factor
!= fxMesa
->AlphaCombine
.Factor
||
1034 alphaComb
.Local
!= fxMesa
->AlphaCombine
.Local
||
1035 alphaComb
.Other
!= fxMesa
->AlphaCombine
.Other
||
1036 alphaComb
.Invert
!= fxMesa
->AlphaCombine
.Invert
) {
1037 fxMesa
->AlphaCombine
= alphaComb
;
1038 fxMesa
->dirty
|= TDFX_UPLOAD_ALPHA_COMBINE
;
1045 * Setup the Voodoo3 texture environment for dual texture units.
1046 * Return GL_TRUE for success, GL_FALSE for failure.
1047 * If failure, we'll use software rendering.
1050 SetupDoubleTexEnvVoodoo3(GLcontext
*ctx
, int tmu0
,
1051 GLenum envMode0
, GLenum baseFormat0
,
1052 GLenum envMode1
, GLenum baseFormat1
)
1054 tdfxContextPtr fxMesa
= TDFX_CONTEXT(ctx
);
1055 const GrCombineLocal_t locala
= GR_COMBINE_LOCAL_ITERATED
;
1056 const GrCombineLocal_t localc
= GR_COMBINE_LOCAL_ITERATED
;
1057 const int tmu1
= 1 - tmu0
;
1059 if (envMode0
== GL_MODULATE
&& envMode1
== GL_MODULATE
) {
1060 GLboolean isalpha
[TDFX_NUM_TMU
];
1062 isalpha
[tmu0
] = (baseFormat0
== GL_ALPHA
);
1063 isalpha
[tmu1
] = (baseFormat1
== GL_ALPHA
);
1065 if (isalpha
[TDFX_TMU1
]) {
1066 fxMesa
->TexCombine
[1].FunctionRGB
= GR_COMBINE_FUNCTION_ZERO
;
1067 fxMesa
->TexCombine
[1].FactorRGB
= GR_COMBINE_FACTOR_NONE
;
1068 fxMesa
->TexCombine
[1].FunctionAlpha
= GR_COMBINE_FUNCTION_LOCAL
;
1069 fxMesa
->TexCombine
[1].FactorAlpha
= GR_COMBINE_FACTOR_NONE
;
1070 fxMesa
->TexCombine
[1].InvertRGB
= FXTRUE
;
1071 fxMesa
->TexCombine
[1].InvertAlpha
= FXFALSE
;
1074 fxMesa
->TexCombine
[1].FunctionRGB
= GR_COMBINE_FUNCTION_LOCAL
;
1075 fxMesa
->TexCombine
[1].FactorRGB
= GR_COMBINE_FACTOR_NONE
;
1076 fxMesa
->TexCombine
[1].FunctionAlpha
= GR_COMBINE_FUNCTION_LOCAL
;
1077 fxMesa
->TexCombine
[1].FactorAlpha
= GR_COMBINE_FACTOR_NONE
;
1078 fxMesa
->TexCombine
[1].InvertRGB
= FXFALSE
;
1079 fxMesa
->TexCombine
[1].InvertAlpha
= FXFALSE
;
1081 if (isalpha
[TDFX_TMU0
]) {
1082 fxMesa
->TexCombine
[0].FunctionRGB
= GR_COMBINE_FUNCTION_BLEND_OTHER
;
1083 fxMesa
->TexCombine
[0].FactorRGB
= GR_COMBINE_FACTOR_ONE
;
1084 fxMesa
->TexCombine
[0].FunctionAlpha
= GR_COMBINE_FUNCTION_BLEND_OTHER
;
1085 fxMesa
->TexCombine
[0].FactorAlpha
= GR_COMBINE_FACTOR_LOCAL
;
1086 fxMesa
->TexCombine
[0].InvertRGB
= FXFALSE
;
1087 fxMesa
->TexCombine
[0].InvertAlpha
= FXFALSE
;
1090 fxMesa
->TexCombine
[0].FunctionRGB
= GR_COMBINE_FUNCTION_BLEND_OTHER
;
1091 fxMesa
->TexCombine
[0].FactorRGB
= GR_COMBINE_FACTOR_LOCAL
;
1092 fxMesa
->TexCombine
[0].FunctionAlpha
= GR_COMBINE_FUNCTION_BLEND_OTHER
;
1093 fxMesa
->TexCombine
[0].FactorAlpha
= GR_COMBINE_FACTOR_LOCAL
;
1094 fxMesa
->TexCombine
[0].InvertRGB
= FXFALSE
;
1095 fxMesa
->TexCombine
[0].InvertAlpha
= FXFALSE
;
1097 fxMesa
->ColorCombine
.Function
= GR_COMBINE_FUNCTION_SCALE_OTHER
;
1098 fxMesa
->ColorCombine
.Factor
= GR_COMBINE_FACTOR_LOCAL
;
1099 fxMesa
->ColorCombine
.Local
= localc
;
1100 fxMesa
->ColorCombine
.Other
= GR_COMBINE_OTHER_TEXTURE
;
1101 fxMesa
->ColorCombine
.Invert
= FXFALSE
;
1102 fxMesa
->AlphaCombine
.Function
= GR_COMBINE_FUNCTION_SCALE_OTHER
;
1103 fxMesa
->AlphaCombine
.Factor
= GR_COMBINE_FACTOR_LOCAL
;
1104 fxMesa
->AlphaCombine
.Local
= locala
;
1105 fxMesa
->AlphaCombine
.Other
= GR_COMBINE_OTHER_TEXTURE
;
1106 fxMesa
->AlphaCombine
.Invert
= FXFALSE
;
1108 else if (envMode0
== GL_REPLACE
&& envMode1
== GL_BLEND
) { /* Quake */
1109 if (tmu0
== TDFX_TMU1
) {
1110 fxMesa
->TexCombine
[1].FunctionRGB
= GR_COMBINE_FUNCTION_LOCAL
;
1111 fxMesa
->TexCombine
[1].FactorRGB
= GR_COMBINE_FACTOR_NONE
;
1112 fxMesa
->TexCombine
[1].FunctionAlpha
= GR_COMBINE_FUNCTION_LOCAL
;
1113 fxMesa
->TexCombine
[1].FactorAlpha
= GR_COMBINE_FACTOR_NONE
;
1114 fxMesa
->TexCombine
[1].InvertRGB
= FXTRUE
;
1115 fxMesa
->TexCombine
[1].InvertAlpha
= FXFALSE
;
1116 fxMesa
->TexCombine
[0].FunctionRGB
= GR_COMBINE_FUNCTION_BLEND_OTHER
;
1117 fxMesa
->TexCombine
[0].FactorRGB
= GR_COMBINE_FACTOR_LOCAL
;
1118 fxMesa
->TexCombine
[0].FunctionAlpha
= GR_COMBINE_FUNCTION_BLEND_OTHER
;
1119 fxMesa
->TexCombine
[0].FactorAlpha
= GR_COMBINE_FACTOR_LOCAL
;
1120 fxMesa
->TexCombine
[0].InvertRGB
= FXFALSE
;
1121 fxMesa
->TexCombine
[0].InvertAlpha
= FXFALSE
;
1124 fxMesa
->TexCombine
[1].FunctionRGB
= GR_COMBINE_FUNCTION_LOCAL
;
1125 fxMesa
->TexCombine
[1].FactorRGB
= GR_COMBINE_FACTOR_NONE
;
1126 fxMesa
->TexCombine
[1].FunctionAlpha
= GR_COMBINE_FUNCTION_LOCAL
;
1127 fxMesa
->TexCombine
[1].FactorAlpha
= GR_COMBINE_FACTOR_NONE
;
1128 fxMesa
->TexCombine
[1].InvertRGB
= FXFALSE
;
1129 fxMesa
->TexCombine
[1].InvertAlpha
= FXFALSE
;
1130 fxMesa
->TexCombine
[0].FunctionRGB
= GR_COMBINE_FUNCTION_BLEND_OTHER
;
1131 fxMesa
->TexCombine
[0].FactorRGB
= GR_COMBINE_FACTOR_ONE_MINUS_LOCAL
;
1132 fxMesa
->TexCombine
[0].FunctionAlpha
= GR_COMBINE_FUNCTION_BLEND_OTHER
;
1133 fxMesa
->TexCombine
[0].FactorAlpha
= GR_COMBINE_FACTOR_ONE_MINUS_LOCAL
;
1134 fxMesa
->TexCombine
[0].InvertRGB
= FXFALSE
;
1135 fxMesa
->TexCombine
[0].InvertAlpha
= FXFALSE
;
1137 fxMesa
->ColorCombine
.Function
= GR_COMBINE_FUNCTION_SCALE_OTHER
;
1138 fxMesa
->ColorCombine
.Factor
= GR_COMBINE_FACTOR_ONE
;
1139 fxMesa
->ColorCombine
.Local
= localc
;
1140 fxMesa
->ColorCombine
.Other
= GR_COMBINE_OTHER_TEXTURE
;
1141 fxMesa
->ColorCombine
.Invert
= FXFALSE
;
1142 fxMesa
->AlphaCombine
.Function
= GR_COMBINE_FUNCTION_LOCAL
;
1143 fxMesa
->AlphaCombine
.Factor
= GR_COMBINE_FACTOR_NONE
;
1144 fxMesa
->AlphaCombine
.Local
= locala
;
1145 fxMesa
->AlphaCombine
.Other
= GR_COMBINE_OTHER_NONE
;
1146 fxMesa
->AlphaCombine
.Invert
= FXFALSE
;
1148 else if (envMode0
== GL_REPLACE
&& envMode1
== GL_MODULATE
) {
1150 if (tmu1
== TDFX_TMU1
) {
1151 fxMesa
->TexCombine
[1].FunctionRGB
= GR_COMBINE_FUNCTION_LOCAL
;
1152 fxMesa
->TexCombine
[1].FactorRGB
= GR_COMBINE_FACTOR_NONE
;
1153 fxMesa
->TexCombine
[1].FunctionAlpha
= GR_COMBINE_FUNCTION_ZERO
;
1154 fxMesa
->TexCombine
[1].FactorAlpha
= GR_COMBINE_FACTOR_NONE
;
1155 fxMesa
->TexCombine
[1].InvertRGB
= FXFALSE
;
1156 fxMesa
->TexCombine
[1].InvertAlpha
= FXTRUE
;
1157 fxMesa
->TexCombine
[0].FunctionRGB
= GR_COMBINE_FUNCTION_BLEND_OTHER
;
1158 fxMesa
->TexCombine
[0].FactorRGB
= GR_COMBINE_FACTOR_LOCAL
;
1159 fxMesa
->TexCombine
[0].FunctionAlpha
= GR_COMBINE_FUNCTION_BLEND_OTHER
;
1160 fxMesa
->TexCombine
[0].FactorAlpha
= GR_COMBINE_FACTOR_LOCAL
;
1161 fxMesa
->TexCombine
[0].InvertRGB
= FXFALSE
;
1162 fxMesa
->TexCombine
[0].InvertAlpha
= FXFALSE
;
1165 fxMesa
->TexCombine
[1].FunctionRGB
= GR_COMBINE_FUNCTION_LOCAL
;
1166 fxMesa
->TexCombine
[1].FactorRGB
= GR_COMBINE_FACTOR_NONE
;
1167 fxMesa
->TexCombine
[1].FunctionAlpha
= GR_COMBINE_FUNCTION_LOCAL
;
1168 fxMesa
->TexCombine
[1].FactorAlpha
= GR_COMBINE_FACTOR_NONE
;
1169 fxMesa
->TexCombine
[1].InvertRGB
= FXFALSE
;
1170 fxMesa
->TexCombine
[1].InvertAlpha
= FXFALSE
;
1171 fxMesa
->TexCombine
[0].FunctionRGB
= GR_COMBINE_FUNCTION_BLEND_OTHER
;
1172 fxMesa
->TexCombine
[0].FactorRGB
= GR_COMBINE_FACTOR_LOCAL
;
1173 fxMesa
->TexCombine
[0].FunctionAlpha
= GR_COMBINE_FUNCTION_BLEND_OTHER
;
1174 fxMesa
->TexCombine
[0].FactorAlpha
= GR_COMBINE_FACTOR_ONE
;
1175 fxMesa
->TexCombine
[0].InvertRGB
= FXFALSE
;
1176 fxMesa
->TexCombine
[0].InvertAlpha
= FXFALSE
;
1179 fxMesa
->ColorCombine
.Function
= GR_COMBINE_FUNCTION_SCALE_OTHER
;
1180 fxMesa
->ColorCombine
.Factor
= GR_COMBINE_FACTOR_ONE
;
1181 fxMesa
->ColorCombine
.Local
= localc
;
1182 fxMesa
->ColorCombine
.Other
= GR_COMBINE_OTHER_TEXTURE
;
1183 fxMesa
->ColorCombine
.Invert
= FXFALSE
;
1184 if (baseFormat0
== GL_RGB
) {
1185 fxMesa
->AlphaCombine
.Function
= GR_COMBINE_FUNCTION_LOCAL
;
1186 fxMesa
->AlphaCombine
.Factor
= GR_COMBINE_FACTOR_NONE
;
1187 fxMesa
->AlphaCombine
.Local
= locala
;
1188 fxMesa
->AlphaCombine
.Other
= GR_COMBINE_OTHER_NONE
;
1189 fxMesa
->AlphaCombine
.Invert
= FXFALSE
;
1192 fxMesa
->AlphaCombine
.Function
= GR_COMBINE_FUNCTION_SCALE_OTHER
;
1193 fxMesa
->AlphaCombine
.Factor
= GR_COMBINE_FACTOR_ONE
;
1194 fxMesa
->AlphaCombine
.Local
= locala
;
1195 fxMesa
->AlphaCombine
.Other
= GR_COMBINE_OTHER_NONE
;
1196 fxMesa
->AlphaCombine
.Invert
= FXFALSE
;
1199 else if (envMode0
== GL_MODULATE
&& envMode1
== GL_ADD
) {
1201 GLboolean isalpha
[TDFX_NUM_TMU
];
1203 isalpha
[tmu0
] = (baseFormat0
== GL_ALPHA
);
1204 isalpha
[tmu1
] = (baseFormat1
== GL_ALPHA
);
1206 if (isalpha
[TDFX_TMU1
]) {
1207 fxMesa
->TexCombine
[1].FunctionRGB
= GR_COMBINE_FUNCTION_ZERO
;
1208 fxMesa
->TexCombine
[1].FactorRGB
= GR_COMBINE_FACTOR_NONE
;
1209 fxMesa
->TexCombine
[1].FunctionAlpha
= GR_COMBINE_FUNCTION_LOCAL
;
1210 fxMesa
->TexCombine
[1].FactorAlpha
= GR_COMBINE_FACTOR_NONE
;
1211 fxMesa
->TexCombine
[1].InvertRGB
= FXTRUE
;
1212 fxMesa
->TexCombine
[1].InvertAlpha
= FXFALSE
;
1215 fxMesa
->TexCombine
[1].FunctionRGB
= GR_COMBINE_FUNCTION_LOCAL
;
1216 fxMesa
->TexCombine
[1].FactorRGB
= GR_COMBINE_FACTOR_NONE
;
1217 fxMesa
->TexCombine
[1].FunctionAlpha
= GR_COMBINE_FUNCTION_LOCAL
;
1218 fxMesa
->TexCombine
[1].FactorAlpha
= GR_COMBINE_FACTOR_NONE
;
1219 fxMesa
->TexCombine
[1].InvertRGB
= FXFALSE
;
1220 fxMesa
->TexCombine
[1].InvertAlpha
= FXFALSE
;
1222 if (isalpha
[TDFX_TMU0
]) {
1223 fxMesa
->TexCombine
[0].FunctionRGB
= GR_COMBINE_FUNCTION_SCALE_OTHER
;
1224 fxMesa
->TexCombine
[0].FactorRGB
= GR_COMBINE_FACTOR_ONE
;
1225 fxMesa
->TexCombine
[0].FunctionAlpha
= GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL
;
1226 fxMesa
->TexCombine
[0].FactorAlpha
= GR_COMBINE_FACTOR_ONE
;
1227 fxMesa
->TexCombine
[0].InvertRGB
= FXFALSE
;
1228 fxMesa
->TexCombine
[0].InvertAlpha
= FXFALSE
;
1231 fxMesa
->TexCombine
[0].FunctionRGB
= GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL
;
1232 fxMesa
->TexCombine
[0].FactorRGB
= GR_COMBINE_FACTOR_ONE
;
1233 fxMesa
->TexCombine
[0].FunctionAlpha
= GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL
;
1234 fxMesa
->TexCombine
[0].FactorAlpha
= GR_COMBINE_FACTOR_ONE
;
1235 fxMesa
->TexCombine
[0].InvertRGB
= FXFALSE
;
1236 fxMesa
->TexCombine
[0].InvertAlpha
= FXFALSE
;
1238 fxMesa
->ColorCombine
.Function
= GR_COMBINE_FUNCTION_SCALE_OTHER
;
1239 fxMesa
->ColorCombine
.Factor
= GR_COMBINE_FACTOR_LOCAL
;
1240 fxMesa
->ColorCombine
.Local
= localc
;
1241 fxMesa
->ColorCombine
.Other
= GR_COMBINE_OTHER_TEXTURE
;
1242 fxMesa
->ColorCombine
.Invert
= FXFALSE
;
1243 fxMesa
->AlphaCombine
.Function
= GR_COMBINE_FUNCTION_SCALE_OTHER
;
1244 fxMesa
->AlphaCombine
.Factor
= GR_COMBINE_FACTOR_LOCAL
;
1245 fxMesa
->AlphaCombine
.Local
= locala
;
1246 fxMesa
->AlphaCombine
.Other
= GR_COMBINE_OTHER_TEXTURE
;
1247 fxMesa
->AlphaCombine
.Invert
= FXFALSE
;
1249 else if (envMode0
== GL_REPLACE
&& envMode1
== GL_ADD
) {
1251 GLboolean isalpha
[TDFX_NUM_TMU
];
1253 isalpha
[tmu0
] = (baseFormat0
== GL_ALPHA
);
1254 isalpha
[tmu1
] = (baseFormat1
== GL_ALPHA
);
1256 if (isalpha
[TDFX_TMU1
]) {
1257 fxMesa
->TexCombine
[1].FunctionRGB
= GR_COMBINE_FUNCTION_ZERO
;
1258 fxMesa
->TexCombine
[1].FactorRGB
= GR_COMBINE_FACTOR_NONE
;
1259 fxMesa
->TexCombine
[1].FunctionAlpha
= GR_COMBINE_FUNCTION_LOCAL
;
1260 fxMesa
->TexCombine
[1].FactorAlpha
= GR_COMBINE_FACTOR_NONE
;
1261 fxMesa
->TexCombine
[1].InvertRGB
= FXTRUE
;
1262 fxMesa
->TexCombine
[1].InvertAlpha
= FXFALSE
;
1264 fxMesa
->TexCombine
[1].FunctionRGB
= GR_COMBINE_FUNCTION_LOCAL
;
1265 fxMesa
->TexCombine
[1].FactorRGB
= GR_COMBINE_FACTOR_NONE
;
1266 fxMesa
->TexCombine
[1].FunctionAlpha
= GR_COMBINE_FUNCTION_LOCAL
;
1267 fxMesa
->TexCombine
[1].FactorAlpha
= GR_COMBINE_FACTOR_NONE
;
1268 fxMesa
->TexCombine
[1].InvertRGB
= FXFALSE
;
1269 fxMesa
->TexCombine
[1].InvertAlpha
= FXFALSE
;
1272 if (isalpha
[TDFX_TMU0
]) {
1273 fxMesa
->TexCombine
[0].FunctionRGB
= GR_COMBINE_FUNCTION_SCALE_OTHER
;
1274 fxMesa
->TexCombine
[0].FactorRGB
= GR_COMBINE_FACTOR_ONE
;
1275 fxMesa
->TexCombine
[0].FunctionAlpha
= GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL
;
1276 fxMesa
->TexCombine
[0].FactorAlpha
= GR_COMBINE_FACTOR_ONE
;
1277 fxMesa
->TexCombine
[0].InvertRGB
= FXFALSE
;
1278 fxMesa
->TexCombine
[0].InvertAlpha
= FXFALSE
;
1280 fxMesa
->TexCombine
[0].FunctionRGB
= GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL
;
1281 fxMesa
->TexCombine
[0].FactorRGB
= GR_COMBINE_FACTOR_ONE
;
1282 fxMesa
->TexCombine
[0].FunctionAlpha
= GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL
;
1283 fxMesa
->TexCombine
[0].FactorAlpha
= GR_COMBINE_FACTOR_ONE
;
1284 fxMesa
->TexCombine
[0].InvertRGB
= FXFALSE
;
1285 fxMesa
->TexCombine
[0].InvertAlpha
= FXFALSE
;
1288 fxMesa
->ColorCombine
.Function
= GR_COMBINE_FUNCTION_SCALE_OTHER
;
1289 fxMesa
->ColorCombine
.Factor
= GR_COMBINE_FACTOR_ONE
;
1290 fxMesa
->ColorCombine
.Local
= localc
;
1291 fxMesa
->ColorCombine
.Other
= GR_COMBINE_OTHER_TEXTURE
;
1292 fxMesa
->ColorCombine
.Invert
= FXFALSE
;
1293 fxMesa
->AlphaCombine
.Function
= GR_COMBINE_FUNCTION_SCALE_OTHER
;
1294 fxMesa
->AlphaCombine
.Factor
= GR_COMBINE_FACTOR_ONE
;
1295 fxMesa
->AlphaCombine
.Local
= locala
;
1296 fxMesa
->AlphaCombine
.Other
= GR_COMBINE_OTHER_TEXTURE
;
1297 fxMesa
->AlphaCombine
.Invert
= FXFALSE
;
1299 else if (envMode1
== GL_REPLACE
) {
1302 fxMesa
->TexCombine
[1].FunctionRGB
= GR_COMBINE_FUNCTION_ZERO
;
1303 fxMesa
->TexCombine
[1].FactorRGB
= GR_COMBINE_FACTOR_NONE
;
1304 fxMesa
->TexCombine
[1].FunctionAlpha
= GR_COMBINE_FUNCTION_ZERO
;
1305 fxMesa
->TexCombine
[1].FactorAlpha
= GR_COMBINE_FACTOR_NONE
;
1306 fxMesa
->TexCombine
[1].InvertRGB
= FXFALSE
;
1307 fxMesa
->TexCombine
[1].InvertAlpha
= FXFALSE
;
1309 fxMesa
->TexCombine
[0].FunctionRGB
= GR_COMBINE_FUNCTION_LOCAL
;
1310 fxMesa
->TexCombine
[0].FactorRGB
= GR_COMBINE_FACTOR_NONE
;
1311 fxMesa
->TexCombine
[0].FunctionAlpha
= GR_COMBINE_FUNCTION_LOCAL
;
1312 fxMesa
->TexCombine
[0].FactorAlpha
= GR_COMBINE_FACTOR_NONE
;
1313 fxMesa
->TexCombine
[0].InvertRGB
= FXFALSE
;
1314 fxMesa
->TexCombine
[0].InvertAlpha
= FXFALSE
;
1316 if ((baseFormat0
== GL_RGB
) || (baseFormat0
== GL_LUMINANCE
)) {
1317 fxMesa
->AlphaCombine
.Function
= GR_COMBINE_FUNCTION_LOCAL
;
1318 fxMesa
->AlphaCombine
.Factor
= GR_COMBINE_FACTOR_NONE
;
1319 fxMesa
->AlphaCombine
.Local
= locala
;
1320 fxMesa
->AlphaCombine
.Other
= GR_COMBINE_OTHER_NONE
;
1321 fxMesa
->AlphaCombine
.Invert
= FXFALSE
;
1323 fxMesa
->AlphaCombine
.Function
= GR_COMBINE_FUNCTION_SCALE_OTHER
;
1324 fxMesa
->AlphaCombine
.Factor
= GR_COMBINE_FACTOR_ONE
;
1325 fxMesa
->AlphaCombine
.Local
= locala
;
1326 fxMesa
->AlphaCombine
.Other
= GR_COMBINE_OTHER_TEXTURE
;
1327 fxMesa
->AlphaCombine
.Invert
= FXFALSE
;
1329 if (baseFormat0
== GL_ALPHA
) {
1330 fxMesa
->ColorCombine
.Function
= GR_COMBINE_FUNCTION_LOCAL
;
1331 fxMesa
->ColorCombine
.Factor
= GR_COMBINE_FACTOR_NONE
;
1332 fxMesa
->ColorCombine
.Local
= localc
;
1333 fxMesa
->ColorCombine
.Other
= GR_COMBINE_OTHER_NONE
;
1334 fxMesa
->ColorCombine
.Invert
= FXFALSE
;
1336 fxMesa
->ColorCombine
.Function
= GR_COMBINE_FUNCTION_SCALE_OTHER
;
1337 fxMesa
->ColorCombine
.Factor
= GR_COMBINE_FACTOR_ONE
;
1338 fxMesa
->ColorCombine
.Local
= localc
;
1339 fxMesa
->ColorCombine
.Other
= GR_COMBINE_OTHER_TEXTURE
;
1340 fxMesa
->ColorCombine
.Invert
= FXFALSE
;
1344 _mesa_problem(ctx
, "%s: Unexpected dual texture mode encountered", __FUNCTION__
);
1348 fxMesa
->dirty
|= TDFX_UPLOAD_TEXTURE_ENV
;
1349 fxMesa
->dirty
|= TDFX_UPLOAD_COLOR_COMBINE
;
1350 fxMesa
->dirty
|= TDFX_UPLOAD_ALPHA_COMBINE
;
1356 * This function makes sure that the correct mipmap levels are loaded
1357 * in the right places in memory and then makes the Glide calls to
1358 * setup the texture source pointers.
1361 setupSingleTMU(tdfxContextPtr fxMesa
, struct gl_texture_object
*tObj
)
1363 struct tdfxSharedState
*shared
= (struct tdfxSharedState
*) fxMesa
->glCtx
->Shared
->DriverData
;
1364 tdfxTexInfo
*ti
= TDFX_TEXTURE_DATA(tObj
);
1365 const GLcontext
*ctx
= fxMesa
->glCtx
;
1367 /* Make sure we're not loaded incorrectly */
1368 if (ti
->isInTM
&& !shared
->umaTexMemory
) {
1369 /* if doing filtering between mipmap levels, alternate mipmap levels
1370 * must be in alternate TMUs.
1373 if (ti
->whichTMU
!= TDFX_TMU_SPLIT
)
1374 tdfxTMMoveOutTM_NoLock(fxMesa
, tObj
);
1377 if (ti
->whichTMU
== TDFX_TMU_SPLIT
)
1378 tdfxTMMoveOutTM_NoLock(fxMesa
, tObj
);
1382 /* Make sure we're loaded correctly */
1384 /* Have to download the texture */
1385 if (shared
->umaTexMemory
) {
1386 tdfxTMMoveInTM_NoLock(fxMesa
, tObj
, TDFX_TMU0
);
1389 /* Voodoo3 (split texture memory) */
1391 tdfxTMMoveInTM_NoLock(fxMesa
, tObj
, TDFX_TMU_SPLIT
);
1395 /* XXX putting textures into the second memory bank when the
1396 * first bank is full is not working at this time.
1398 if (fxMesa
->haveTwoTMUs
) {
1399 GLint memReq
= fxMesa
->Glide
.grTexTextureMemRequired(
1400 GR_MIPMAPLEVELMASK_BOTH
, &(ti
->info
));
1401 if (shared
->freeTexMem
[TDFX_TMU0
] > memReq
) {
1402 tdfxTMMoveInTM_NoLock(fxMesa
, tObj
, TDFX_TMU0
);
1405 tdfxTMMoveInTM_NoLock(fxMesa
, tObj
, TDFX_TMU1
);
1411 tdfxTMMoveInTM_NoLock(fxMesa
, tObj
, TDFX_TMU0
);
1417 if (ti
->LODblend
&& ti
->whichTMU
== TDFX_TMU_SPLIT
) {
1418 /* mipmap levels split between texture banks */
1421 if (ti
->info
.format
== GR_TEXFMT_P_8
&& !ctx
->Texture
.SharedPalette
) {
1422 fxMesa
->TexPalette
.Type
= ti
->paltype
;
1423 fxMesa
->TexPalette
.Data
= &(ti
->palette
);
1424 fxMesa
->dirty
|= TDFX_UPLOAD_TEXTURE_PALETTE
;
1427 for (u
= 0; u
< 2; u
++) {
1428 fxMesa
->TexParams
[u
].sClamp
= ti
->sClamp
;
1429 fxMesa
->TexParams
[u
].tClamp
= ti
->tClamp
;
1430 fxMesa
->TexParams
[u
].minFilt
= ti
->minFilt
;
1431 fxMesa
->TexParams
[u
].magFilt
= ti
->magFilt
;
1432 fxMesa
->TexParams
[u
].mmMode
= ti
->mmMode
;
1433 fxMesa
->TexParams
[u
].LODblend
= ti
->LODblend
;
1434 fxMesa
->TexParams
[u
].LodBias
= ctx
->Texture
.Unit
[u
].LodBias
;
1436 fxMesa
->dirty
|= TDFX_UPLOAD_TEXTURE_PARAMS
;
1438 fxMesa
->TexSource
[0].StartAddress
= ti
->tm
[TDFX_TMU0
]->startAddr
;
1439 fxMesa
->TexSource
[0].EvenOdd
= GR_MIPMAPLEVELMASK_ODD
;
1440 fxMesa
->TexSource
[0].Info
= &(ti
->info
);
1441 fxMesa
->TexSource
[1].StartAddress
= ti
->tm
[TDFX_TMU1
]->startAddr
;
1442 fxMesa
->TexSource
[1].EvenOdd
= GR_MIPMAPLEVELMASK_EVEN
;
1443 fxMesa
->TexSource
[1].Info
= &(ti
->info
);
1444 fxMesa
->dirty
|= TDFX_UPLOAD_TEXTURE_SOURCE
;
1449 if (ti
->whichTMU
== TDFX_TMU_BOTH
)
1454 if (shared
->umaTexMemory
) {
1455 assert(ti
->whichTMU
== TDFX_TMU0
);
1456 assert(tmu
== TDFX_TMU0
);
1459 if (ti
->info
.format
== GR_TEXFMT_P_8
&& !ctx
->Texture
.SharedPalette
) {
1460 fxMesa
->TexPalette
.Type
= ti
->paltype
;
1461 fxMesa
->TexPalette
.Data
= &(ti
->palette
);
1462 fxMesa
->dirty
|= TDFX_UPLOAD_TEXTURE_PALETTE
;
1465 /* KW: The alternative is to do the download to the other tmu. If
1466 * we get to this point, I think it means we are thrashing the
1467 * texture memory, so perhaps it's not a good idea.
1470 if (fxMesa
->TexParams
[tmu
].sClamp
!= ti
->sClamp
||
1471 fxMesa
->TexParams
[tmu
].tClamp
!= ti
->tClamp
||
1472 fxMesa
->TexParams
[tmu
].minFilt
!= ti
->minFilt
||
1473 fxMesa
->TexParams
[tmu
].magFilt
!= ti
->magFilt
||
1474 fxMesa
->TexParams
[tmu
].mmMode
!= ti
->mmMode
||
1475 fxMesa
->TexParams
[tmu
].LODblend
!= FXFALSE
||
1476 fxMesa
->TexParams
[tmu
].LodBias
!= ctx
->Texture
.Unit
[tmu
].LodBias
) {
1477 fxMesa
->TexParams
[tmu
].sClamp
= ti
->sClamp
;
1478 fxMesa
->TexParams
[tmu
].tClamp
= ti
->tClamp
;
1479 fxMesa
->TexParams
[tmu
].minFilt
= ti
->minFilt
;
1480 fxMesa
->TexParams
[tmu
].magFilt
= ti
->magFilt
;
1481 fxMesa
->TexParams
[tmu
].mmMode
= ti
->mmMode
;
1482 fxMesa
->TexParams
[tmu
].LODblend
= FXFALSE
;
1483 fxMesa
->TexParams
[tmu
].LodBias
= ctx
->Texture
.Unit
[tmu
].LodBias
;
1484 fxMesa
->dirty
|= TDFX_UPLOAD_TEXTURE_PARAMS
;
1487 /* Glide texture source info */
1488 fxMesa
->TexSource
[0].Info
= NULL
;
1489 fxMesa
->TexSource
[1].Info
= NULL
;
1491 fxMesa
->TexSource
[tmu
].StartAddress
= ti
->tm
[tmu
]->startAddr
;
1492 fxMesa
->TexSource
[tmu
].EvenOdd
= GR_MIPMAPLEVELMASK_BOTH
;
1493 fxMesa
->TexSource
[tmu
].Info
= &(ti
->info
);
1494 fxMesa
->dirty
|= TDFX_UPLOAD_TEXTURE_SOURCE
;
1498 fxMesa
->sScale0
= ti
->sScale
;
1499 fxMesa
->tScale0
= ti
->tScale
;
1503 selectSingleTMUSrc(tdfxContextPtr fxMesa
, GLint tmu
, FxBool LODblend
)
1506 fxMesa
->TexCombine
[0].FunctionRGB
= GR_COMBINE_FUNCTION_BLEND
;
1507 fxMesa
->TexCombine
[0].FactorRGB
= GR_COMBINE_FACTOR_ONE_MINUS_LOD_FRACTION
;
1508 fxMesa
->TexCombine
[0].FunctionAlpha
= GR_COMBINE_FUNCTION_BLEND
;
1509 fxMesa
->TexCombine
[0].FactorAlpha
= GR_COMBINE_FACTOR_ONE_MINUS_LOD_FRACTION
;
1510 fxMesa
->TexCombine
[0].InvertRGB
= FXFALSE
;
1511 fxMesa
->TexCombine
[0].InvertAlpha
= FXFALSE
;
1513 if (fxMesa
->haveTwoTMUs
) {
1514 const struct gl_shared_state
*mesaShared
= fxMesa
->glCtx
->Shared
;
1515 const struct tdfxSharedState
*shared
= (struct tdfxSharedState
*) mesaShared
->DriverData
;
1518 if (shared
->umaTexMemory
)
1523 fxMesa
->TexCombine
[tmu
].FunctionRGB
= GR_COMBINE_FUNCTION_LOCAL
;
1524 fxMesa
->TexCombine
[tmu
].FactorRGB
= GR_COMBINE_FACTOR_NONE
;
1525 fxMesa
->TexCombine
[tmu
].FunctionAlpha
= GR_COMBINE_FUNCTION_LOCAL
;
1526 fxMesa
->TexCombine
[tmu
].FactorAlpha
= GR_COMBINE_FACTOR_NONE
;
1527 fxMesa
->TexCombine
[tmu
].InvertRGB
= FXFALSE
;
1528 fxMesa
->TexCombine
[tmu
].InvertAlpha
= FXFALSE
;
1530 fxMesa
->tmuSrc
= TDFX_TMU_SPLIT
;
1533 if (tmu
!= TDFX_TMU1
) {
1534 fxMesa
->TexCombine
[0].FunctionRGB
= GR_COMBINE_FUNCTION_LOCAL
;
1535 fxMesa
->TexCombine
[0].FactorRGB
= GR_COMBINE_FACTOR_NONE
;
1536 fxMesa
->TexCombine
[0].FunctionAlpha
= GR_COMBINE_FUNCTION_LOCAL
;
1537 fxMesa
->TexCombine
[0].FactorAlpha
= GR_COMBINE_FACTOR_NONE
;
1538 fxMesa
->TexCombine
[0].InvertRGB
= FXFALSE
;
1539 fxMesa
->TexCombine
[0].InvertAlpha
= FXFALSE
;
1540 if (fxMesa
->haveTwoTMUs
) {
1541 fxMesa
->TexCombine
[1].FunctionRGB
= GR_COMBINE_FUNCTION_ZERO
;
1542 fxMesa
->TexCombine
[1].FactorRGB
= GR_COMBINE_FACTOR_NONE
;
1543 fxMesa
->TexCombine
[1].FunctionAlpha
= GR_COMBINE_FUNCTION_ZERO
;
1544 fxMesa
->TexCombine
[1].FactorAlpha
= GR_COMBINE_FACTOR_NONE
;
1545 fxMesa
->TexCombine
[1].InvertRGB
= FXFALSE
;
1546 fxMesa
->TexCombine
[1].InvertAlpha
= FXFALSE
;
1548 fxMesa
->tmuSrc
= TDFX_TMU0
;
1551 fxMesa
->TexCombine
[1].FunctionRGB
= GR_COMBINE_FUNCTION_LOCAL
;
1552 fxMesa
->TexCombine
[1].FactorRGB
= GR_COMBINE_FACTOR_NONE
;
1553 fxMesa
->TexCombine
[1].FunctionAlpha
= GR_COMBINE_FUNCTION_LOCAL
;
1554 fxMesa
->TexCombine
[1].FactorAlpha
= GR_COMBINE_FACTOR_NONE
;
1555 fxMesa
->TexCombine
[1].InvertRGB
= FXFALSE
;
1556 fxMesa
->TexCombine
[1].InvertAlpha
= FXFALSE
;
1557 /* GR_COMBINE_FUNCTION_SCALE_OTHER doesn't work ?!? */
1558 fxMesa
->TexCombine
[0].FunctionRGB
= GR_COMBINE_FUNCTION_BLEND
;
1559 fxMesa
->TexCombine
[0].FactorRGB
= GR_COMBINE_FACTOR_ONE
;
1560 fxMesa
->TexCombine
[0].FunctionAlpha
= GR_COMBINE_FUNCTION_BLEND
;
1561 fxMesa
->TexCombine
[0].FactorAlpha
= GR_COMBINE_FACTOR_ONE
;
1562 fxMesa
->TexCombine
[0].InvertRGB
= FXFALSE
;
1563 fxMesa
->TexCombine
[0].InvertAlpha
= FXFALSE
;
1564 fxMesa
->tmuSrc
= TDFX_TMU1
;
1568 fxMesa
->dirty
|= TDFX_UPLOAD_TEXTURE_ENV
;
1572 static void print_state(tdfxContextPtr fxMesa
)
1574 GLcontext
*ctx
= fxMesa
->glCtx
;
1575 struct gl_texture_object
*tObj0
= ctx
->Texture
.Unit
[0]._Current
;
1576 struct gl_texture_object
*tObj1
= ctx
->Texture
.Unit
[1]._Current
;
1577 GLenum base0
= tObj0
->Image
[0][tObj0
->BaseLevel
] ? tObj0
->Image
[0][tObj0
->BaseLevel
]->Format
: 99;
1578 GLenum base1
= tObj1
->Image
[0][tObj1
->BaseLevel
] ? tObj1
->Image
[0][tObj1
->BaseLevel
]->Format
: 99;
1580 printf("Unit 0: Enabled: GL=%d Gr=%d\n", ctx
->Texture
.Unit
[0]._ReallyEnabled
,
1581 fxMesa
->TexState
.Enabled
[0]);
1582 printf(" EnvMode: GL=0x%x Gr=0x%x\n", ctx
->Texture
.Unit
[0].EnvMode
,
1583 fxMesa
->TexState
.EnvMode
[0]);
1584 printf(" BaseFmt: GL=0x%x Gr=0x%x\n", base0
, fxMesa
->TexState
.TexFormat
[0]);
1587 printf("Unit 1: Enabled: GL=%d Gr=%d\n", ctx
->Texture
.Unit
[1]._ReallyEnabled
,
1588 fxMesa
->TexState
.Enabled
[1]);
1589 printf(" EnvMode: GL=0x%x Gr:0x%x\n", ctx
->Texture
.Unit
[1].EnvMode
,
1590 fxMesa
->TexState
.EnvMode
[1]);
1591 printf(" BaseFmt: GL=0x%x Gr:0x%x\n", base1
, fxMesa
->TexState
.TexFormat
[1]);
1596 * When we're only using a single texture unit, we always use the 0th
1597 * Glide/hardware unit, regardless if it's GL_TEXTURE0_ARB or GL_TEXTURE1_ARB
1599 * Input: ctx - the context
1600 * unit - the OpenGL texture unit to use.
1602 static void setupTextureSingleTMU(GLcontext
* ctx
, GLuint unit
)
1604 tdfxContextPtr fxMesa
= TDFX_CONTEXT(ctx
);
1606 struct gl_texture_object
*tObj
;
1608 GLenum envMode
, baseFormat
;
1610 tObj
= ctx
->Texture
.Unit
[unit
]._Current
;
1611 if (tObj
->Image
[0][tObj
->BaseLevel
]->Border
> 0) {
1612 FALLBACK(fxMesa
, TDFX_FALLBACK_TEXTURE_BORDER
, GL_TRUE
);
1616 setupSingleTMU(fxMesa
, tObj
);
1618 ti
= TDFX_TEXTURE_DATA(tObj
);
1619 if (ti
->whichTMU
== TDFX_TMU_BOTH
)
1624 if (fxMesa
->tmuSrc
!= tmu
) {
1625 selectSingleTMUSrc(fxMesa
, tmu
, ti
->LODblend
);
1628 if (ti
->reloadImages
)
1629 fxMesa
->dirty
|= TDFX_UPLOAD_TEXTURE_IMAGES
;
1631 /* Check if we really need to update the texenv state */
1632 envMode
= ctx
->Texture
.Unit
[unit
].EnvMode
;
1633 baseFormat
= tObj
->Image
[0][tObj
->BaseLevel
]->_BaseFormat
;
1635 if (TDFX_IS_NAPALM(fxMesa
)) {
1636 /* see if we really need to update the unit */
1637 if (1/*fxMesa->TexState.Enabled[unit] != ctx->Texture.Unit[unit]._ReallyEnabled ||
1638 envMode != fxMesa->TexState.EnvMode[0] ||
1639 envMode == GL_COMBINE_EXT ||
1640 baseFormat != fxMesa->TexState.TexFormat[0]*/) {
1641 struct tdfx_texcombine_ext
*otherEnv
;
1642 if (!SetupTexEnvNapalm(ctx
, GL_TRUE
,
1643 &ctx
->Texture
.Unit
[unit
], baseFormat
,
1644 &fxMesa
->TexCombineExt
[0])) {
1645 /* software fallback */
1646 FALLBACK(fxMesa
, TDFX_FALLBACK_TEXTURE_ENV
, GL_TRUE
);
1648 /* disable other unit */
1649 otherEnv
= &fxMesa
->TexCombineExt
[1];
1650 otherEnv
->Color
.SourceA
= GR_CMBX_ZERO
;
1651 otherEnv
->Color
.ModeA
= GR_FUNC_MODE_ZERO
;
1652 otherEnv
->Color
.SourceB
= GR_CMBX_ZERO
;
1653 otherEnv
->Color
.ModeB
= GR_FUNC_MODE_ZERO
;
1654 otherEnv
->Color
.SourceC
= GR_CMBX_ZERO
;
1655 otherEnv
->Color
.InvertC
= FXFALSE
;
1656 otherEnv
->Color
.SourceD
= GR_CMBX_ZERO
;
1657 otherEnv
->Color
.InvertD
= FXFALSE
;
1658 otherEnv
->Color
.Shift
= 0;
1659 otherEnv
->Color
.Invert
= FXFALSE
;
1660 otherEnv
->Alpha
.SourceA
= GR_CMBX_ITALPHA
;
1661 otherEnv
->Alpha
.ModeA
= GR_FUNC_MODE_ZERO
;
1662 otherEnv
->Alpha
.SourceB
= GR_CMBX_ITALPHA
;
1663 otherEnv
->Alpha
.ModeB
= GR_FUNC_MODE_ZERO
;
1664 otherEnv
->Alpha
.SourceC
= GR_CMBX_ZERO
;
1665 otherEnv
->Alpha
.InvertC
= FXFALSE
;
1666 otherEnv
->Alpha
.SourceD
= GR_CMBX_ZERO
;
1667 otherEnv
->Alpha
.InvertD
= FXFALSE
;
1668 otherEnv
->Alpha
.Shift
= 0;
1669 otherEnv
->Alpha
.Invert
= FXFALSE
;
1672 fxMesa
->TexState
.Enabled
[unit
] = ctx
->Texture
.Unit
[unit
]._ReallyEnabled
;
1673 fxMesa
->TexState
.EnvMode
[0] = envMode
;
1674 fxMesa
->TexState
.TexFormat
[0] = baseFormat
;
1675 fxMesa
->TexState
.EnvMode
[1] = 0;
1676 fxMesa
->TexState
.TexFormat
[1] = 0;
1683 /* see if we really need to update the unit */
1684 if (1/*fxMesa->TexState.Enabled[unit] != ctx->Texture.Unit[unit]._ReallyEnabled ||
1685 envMode != fxMesa->TexState.EnvMode[0] ||
1686 envMode == GL_COMBINE_EXT ||
1687 baseFormat != fxMesa->TexState.TexFormat[0]*/) {
1688 if (!SetupSingleTexEnvVoodoo3(ctx
, unit
, envMode
, baseFormat
)) {
1689 /* software fallback */
1690 FALLBACK(fxMesa
, TDFX_FALLBACK_TEXTURE_ENV
, GL_TRUE
);
1693 fxMesa
->TexState
.Enabled
[unit
] = ctx
->Texture
.Unit
[unit
]._ReallyEnabled
;
1694 fxMesa
->TexState
.EnvMode
[0] = envMode
;
1695 fxMesa
->TexState
.TexFormat
[0] = baseFormat
;
1696 fxMesa
->TexState
.EnvMode
[1] = 0;
1697 fxMesa
->TexState
.TexFormat
[1] = 0;
1705 setupDoubleTMU(tdfxContextPtr fxMesa
,
1706 struct gl_texture_object
*tObj0
,
1707 struct gl_texture_object
*tObj1
)
1709 #define T0_NOT_IN_TMU 0x01
1710 #define T1_NOT_IN_TMU 0x02
1711 #define T0_IN_TMU0 0x04
1712 #define T1_IN_TMU0 0x08
1713 #define T0_IN_TMU1 0x10
1714 #define T1_IN_TMU1 0x20
1716 const struct gl_shared_state
*mesaShared
= fxMesa
->glCtx
->Shared
;
1717 const struct tdfxSharedState
*shared
= (struct tdfxSharedState
*) mesaShared
->DriverData
;
1718 const GLcontext
*ctx
= fxMesa
->glCtx
;
1719 tdfxTexInfo
*ti0
= TDFX_TEXTURE_DATA(tObj0
);
1720 tdfxTexInfo
*ti1
= TDFX_TEXTURE_DATA(tObj1
);
1722 int tmu0
= 0, tmu1
= 1;
1724 if (shared
->umaTexMemory
) {
1726 tdfxTMMoveInTM_NoLock(fxMesa
, tObj0
, TDFX_TMU0
);
1727 assert(ti0
->isInTM
);
1730 tdfxTMMoveInTM_NoLock(fxMesa
, tObj1
, TDFX_TMU0
);
1731 assert(ti1
->isInTM
);
1735 /* We shouldn't need to do this. There is something wrong with
1736 multitexturing when the TMUs are swapped. So, we're forcing
1737 them to always be loaded correctly. !!! */
1738 if (ti0
->whichTMU
== TDFX_TMU1
)
1739 tdfxTMMoveOutTM_NoLock(fxMesa
, tObj0
);
1740 if (ti1
->whichTMU
== TDFX_TMU0
)
1741 tdfxTMMoveOutTM_NoLock(fxMesa
, tObj1
);
1744 switch (ti0
->whichTMU
) {
1746 tstate
|= T0_IN_TMU0
;
1749 tstate
|= T0_IN_TMU1
;
1752 tstate
|= T0_IN_TMU0
| T0_IN_TMU1
;
1754 case TDFX_TMU_SPLIT
:
1755 tstate
|= T0_NOT_IN_TMU
;
1760 tstate
|= T0_NOT_IN_TMU
;
1763 switch (ti1
->whichTMU
) {
1765 tstate
|= T1_IN_TMU0
;
1768 tstate
|= T1_IN_TMU1
;
1771 tstate
|= T1_IN_TMU0
| T1_IN_TMU1
;
1773 case TDFX_TMU_SPLIT
:
1774 tstate
|= T1_NOT_IN_TMU
;
1779 tstate
|= T1_NOT_IN_TMU
;
1781 /* Move texture maps into TMUs */
1783 if (!(((tstate
& T0_IN_TMU0
) && (tstate
& T1_IN_TMU1
)) ||
1784 ((tstate
& T0_IN_TMU1
) && (tstate
& T1_IN_TMU0
)))) {
1785 if (tObj0
== tObj1
) {
1786 tdfxTMMoveInTM_NoLock(fxMesa
, tObj1
, TDFX_TMU_BOTH
);
1789 /* Find the minimal way to correct the situation */
1790 if ((tstate
& T0_IN_TMU0
) || (tstate
& T1_IN_TMU1
)) {
1791 /* We have one in the standard order, setup the other */
1792 if (tstate
& T0_IN_TMU0
) {
1793 /* T0 is in TMU0, put T1 in TMU1 */
1794 tdfxTMMoveInTM_NoLock(fxMesa
, tObj1
, TDFX_TMU1
);
1797 tdfxTMMoveInTM_NoLock(fxMesa
, tObj0
, TDFX_TMU0
);
1799 /* tmu0 and tmu1 are setup */
1801 else if ((tstate
& T0_IN_TMU1
) || (tstate
& T1_IN_TMU0
)) {
1802 /* we have one in the reverse order, setup the other */
1803 if (tstate
& T1_IN_TMU0
) {
1804 /* T1 is in TMU0, put T0 in TMU1 */
1805 tdfxTMMoveInTM_NoLock(fxMesa
, tObj0
, TDFX_TMU1
);
1808 tdfxTMMoveInTM_NoLock(fxMesa
, tObj1
, TDFX_TMU0
);
1813 else { /* Nothing is loaded */
1814 tdfxTMMoveInTM_NoLock(fxMesa
, tObj0
, TDFX_TMU0
);
1815 tdfxTMMoveInTM_NoLock(fxMesa
, tObj1
, TDFX_TMU1
);
1816 /* tmu0 and tmu1 are setup */
1822 ti0
->lastTimeUsed
= fxMesa
->texBindNumber
;
1823 ti1
->lastTimeUsed
= fxMesa
->texBindNumber
;
1826 if (!ctx
->Texture
.SharedPalette
) {
1827 if (ti0
->info
.format
== GR_TEXFMT_P_8
) {
1828 fxMesa
->TexPalette
.Type
= ti0
->paltype
;
1829 fxMesa
->TexPalette
.Data
= &(ti0
->palette
);
1830 fxMesa
->dirty
|= TDFX_UPLOAD_TEXTURE_PALETTE
;
1832 else if (ti1
->info
.format
== GR_TEXFMT_P_8
) {
1833 fxMesa
->TexPalette
.Type
= ti1
->paltype
;
1834 fxMesa
->TexPalette
.Data
= &(ti1
->palette
);
1835 fxMesa
->dirty
|= TDFX_UPLOAD_TEXTURE_PALETTE
;
1838 fxMesa
->TexPalette
.Data
= NULL
;
1845 assert(ti0
->isInTM
);
1846 assert(ti0
->tm
[tmu0
]);
1847 fxMesa
->TexSource
[tmu0
].StartAddress
= ti0
->tm
[tmu0
]->startAddr
;
1848 fxMesa
->TexSource
[tmu0
].EvenOdd
= GR_MIPMAPLEVELMASK_BOTH
;
1849 fxMesa
->TexSource
[tmu0
].Info
= &(ti0
->info
);
1850 fxMesa
->dirty
|= TDFX_UPLOAD_TEXTURE_SOURCE
;
1852 if (fxMesa
->TexParams
[tmu0
].sClamp
!= ti0
->sClamp
||
1853 fxMesa
->TexParams
[tmu0
].tClamp
!= ti0
->tClamp
||
1854 fxMesa
->TexParams
[tmu0
].minFilt
!= ti0
->minFilt
||
1855 fxMesa
->TexParams
[tmu0
].magFilt
!= ti0
->magFilt
||
1856 fxMesa
->TexParams
[tmu0
].mmMode
!= ti0
->mmMode
||
1857 fxMesa
->TexParams
[tmu0
].LODblend
!= FXFALSE
||
1858 fxMesa
->TexParams
[tmu0
].LodBias
!= ctx
->Texture
.Unit
[tmu0
].LodBias
) {
1859 fxMesa
->TexParams
[tmu0
].sClamp
= ti0
->sClamp
;
1860 fxMesa
->TexParams
[tmu0
].tClamp
= ti0
->tClamp
;
1861 fxMesa
->TexParams
[tmu0
].minFilt
= ti0
->minFilt
;
1862 fxMesa
->TexParams
[tmu0
].magFilt
= ti0
->magFilt
;
1863 fxMesa
->TexParams
[tmu0
].mmMode
= ti0
->mmMode
;
1864 fxMesa
->TexParams
[tmu0
].LODblend
= FXFALSE
;
1865 fxMesa
->TexParams
[tmu0
].LodBias
= ctx
->Texture
.Unit
[tmu0
].LodBias
;
1866 fxMesa
->dirty
|= TDFX_UPLOAD_TEXTURE_PARAMS
;
1872 if (shared
->umaTexMemory
) {
1873 ASSERT(ti1
->isInTM
);
1875 fxMesa
->TexSource
[tmu1
].StartAddress
= ti1
->tm
[0]->startAddr
;
1876 fxMesa
->TexSource
[tmu1
].EvenOdd
= GR_MIPMAPLEVELMASK_BOTH
;
1877 fxMesa
->TexSource
[tmu1
].Info
= &(ti1
->info
);
1880 ASSERT(ti1
->isInTM
);
1881 ASSERT(ti1
->tm
[tmu1
]);
1882 fxMesa
->TexSource
[tmu1
].StartAddress
= ti1
->tm
[tmu1
]->startAddr
;
1883 fxMesa
->TexSource
[tmu1
].EvenOdd
= GR_MIPMAPLEVELMASK_BOTH
;
1884 fxMesa
->TexSource
[tmu1
].Info
= &(ti1
->info
);
1887 if (fxMesa
->TexParams
[tmu1
].sClamp
!= ti1
->sClamp
||
1888 fxMesa
->TexParams
[tmu1
].tClamp
!= ti1
->tClamp
||
1889 fxMesa
->TexParams
[tmu1
].minFilt
!= ti1
->minFilt
||
1890 fxMesa
->TexParams
[tmu1
].magFilt
!= ti1
->magFilt
||
1891 fxMesa
->TexParams
[tmu1
].mmMode
!= ti1
->mmMode
||
1892 fxMesa
->TexParams
[tmu1
].LODblend
!= FXFALSE
||
1893 fxMesa
->TexParams
[tmu1
].LodBias
!= ctx
->Texture
.Unit
[tmu1
].LodBias
) {
1894 fxMesa
->TexParams
[tmu1
].sClamp
= ti1
->sClamp
;
1895 fxMesa
->TexParams
[tmu1
].tClamp
= ti1
->tClamp
;
1896 fxMesa
->TexParams
[tmu1
].minFilt
= ti1
->minFilt
;
1897 fxMesa
->TexParams
[tmu1
].magFilt
= ti1
->magFilt
;
1898 fxMesa
->TexParams
[tmu1
].mmMode
= ti1
->mmMode
;
1899 fxMesa
->TexParams
[tmu1
].LODblend
= FXFALSE
;
1900 fxMesa
->TexParams
[tmu1
].LodBias
= ctx
->Texture
.Unit
[tmu1
].LodBias
;
1901 fxMesa
->dirty
|= TDFX_UPLOAD_TEXTURE_PARAMS
;
1904 fxMesa
->sScale0
= ti0
->sScale
;
1905 fxMesa
->tScale0
= ti0
->tScale
;
1906 fxMesa
->sScale1
= ti1
->sScale
;
1907 fxMesa
->tScale1
= ti1
->tScale
;
1909 #undef T0_NOT_IN_TMU
1910 #undef T1_NOT_IN_TMU
1917 static void setupTextureDoubleTMU(GLcontext
* ctx
)
1919 tdfxContextPtr fxMesa
= TDFX_CONTEXT(ctx
);
1920 struct gl_texture_object
*tObj0
= ctx
->Texture
.Unit
[1]._Current
;
1921 struct gl_texture_object
*tObj1
= ctx
->Texture
.Unit
[0]._Current
;
1922 tdfxTexInfo
*ti0
= TDFX_TEXTURE_DATA(tObj0
);
1923 tdfxTexInfo
*ti1
= TDFX_TEXTURE_DATA(tObj1
);
1924 struct gl_texture_image
*baseImage0
= tObj0
->Image
[0][tObj0
->BaseLevel
];
1925 struct gl_texture_image
*baseImage1
= tObj1
->Image
[0][tObj1
->BaseLevel
];
1927 const GLenum envMode0
= ctx
->Texture
.Unit
[0].EnvMode
;
1928 const GLenum envMode1
= ctx
->Texture
.Unit
[1].EnvMode
;
1931 if (baseImage0
->Border
> 0 || baseImage1
->Border
> 0) {
1932 FALLBACK(fxMesa
, TDFX_FALLBACK_TEXTURE_BORDER
, GL_TRUE
);
1936 setupDoubleTMU(fxMesa
, tObj0
, tObj1
);
1938 if (ti0
->reloadImages
|| ti1
->reloadImages
)
1939 fxMesa
->dirty
|= TDFX_UPLOAD_TEXTURE_IMAGES
;
1941 fxMesa
->tmuSrc
= TDFX_TMU_BOTH
;
1943 if (TDFX_IS_NAPALM(fxMesa
)) {
1944 /* Remember, Glide has its texture units numbered in backward
1945 * order compared to OpenGL.
1947 GLboolean hw1
= GL_TRUE
, hw2
= GL_TRUE
;
1949 /* check if we really need to update glide unit 1 */
1950 if (1/*fxMesa->TexState.Enabled[0] != ctx->Texture.Unit[0]._ReallyEnabled ||
1951 envMode0 != fxMesa->TexState.EnvMode[1] ||
1952 envMode0 == GL_COMBINE_EXT ||
1953 baseImage0->Format != fxMesa->TexState.TexFormat[1] ||
1954 (fxMesa->Fallback & TDFX_FALLBACK_TEXTURE_ENV)*/) {
1955 hw1
= SetupTexEnvNapalm(ctx
, GL_TRUE
, &ctx
->Texture
.Unit
[0],
1956 baseImage0
->_BaseFormat
, &fxMesa
->TexCombineExt
[1]);
1958 fxMesa
->TexState
.EnvMode
[1] = envMode0
;
1959 fxMesa
->TexState
.TexFormat
[1] = baseImage0
->_BaseFormat
;
1960 fxMesa
->TexState
.Enabled
[0] = ctx
->Texture
.Unit
[0]._ReallyEnabled
;
1964 /* check if we really need to update glide unit 0 */
1965 if (1/*fxMesa->TexState.Enabled[1] != ctx->Texture.Unit[1]._ReallyEnabled ||
1966 envMode1 != fxMesa->TexState.EnvMode[0] ||
1967 envMode1 == GL_COMBINE_EXT ||
1968 baseImage1->_BaseFormat != fxMesa->TexState.TexFormat[0] ||
1969 (fxMesa->Fallback & TDFX_FALLBACK_TEXTURE_ENV)*/) {
1970 hw2
= SetupTexEnvNapalm(ctx
, GL_FALSE
, &ctx
->Texture
.Unit
[1],
1971 baseImage1
->_BaseFormat
, &fxMesa
->TexCombineExt
[0]);
1973 fxMesa
->TexState
.EnvMode
[0] = envMode1
;
1974 fxMesa
->TexState
.TexFormat
[0] = baseImage1
->_BaseFormat
;
1975 fxMesa
->TexState
.Enabled
[1] = ctx
->Texture
.Unit
[1]._ReallyEnabled
;
1981 FALLBACK(fxMesa
, TDFX_FALLBACK_TEXTURE_ENV
, GL_TRUE
);
1986 if ((ti0
->whichTMU
== TDFX_TMU1
) || (ti1
->whichTMU
== TDFX_TMU0
))
1992 if (1/*fxMesa->TexState.Enabled[0] != ctx->Texture.Unit[0]._ReallyEnabled ||
1993 fxMesa->TexState.Enabled[1] != ctx->Texture.Unit[1]._ReallyEnabled ||
1994 envMode0 != fxMesa->TexState.EnvMode[unit0] ||
1995 envMode0 == GL_COMBINE_EXT ||
1996 envMode1 != fxMesa->TexState.EnvMode[unit1] ||
1997 envMode1 == GL_COMBINE_EXT ||
1998 baseImage0->_BaseFormat != fxMesa->TexState.TexFormat[unit0] ||
1999 baseImage1->_BaseFormat != fxMesa->TexState.TexFormat[unit1] ||
2000 (fxMesa->Fallback & TDFX_FALLBACK_TEXTURE_ENV)*/) {
2002 if (!SetupDoubleTexEnvVoodoo3(ctx
, unit0
,
2003 ctx
->Texture
.Unit
[0].EnvMode
, baseImage0
->_BaseFormat
,
2004 ctx
->Texture
.Unit
[1].EnvMode
, baseImage1
->_BaseFormat
)) {
2005 FALLBACK(fxMesa
, TDFX_FALLBACK_TEXTURE_ENV
, GL_TRUE
);
2009 fxMesa
->TexState
.EnvMode
[unit0
] = envMode0
;
2010 fxMesa
->TexState
.TexFormat
[unit0
] = baseImage0
->_BaseFormat
;
2011 fxMesa
->TexState
.EnvMode
[unit1
] = envMode1
;
2012 fxMesa
->TexState
.TexFormat
[unit1
] = baseImage1
->_BaseFormat
;
2013 fxMesa
->TexState
.Enabled
[0] = ctx
->Texture
.Unit
[0]._ReallyEnabled
;
2014 fxMesa
->TexState
.Enabled
[1] = ctx
->Texture
.Unit
[1]._ReallyEnabled
;
2022 tdfxUpdateTextureState( GLcontext
*ctx
)
2024 tdfxContextPtr fxMesa
= TDFX_CONTEXT(ctx
);
2026 FALLBACK(fxMesa
, TDFX_FALLBACK_TEXTURE_BORDER
, GL_FALSE
);
2027 FALLBACK(fxMesa
, TDFX_FALLBACK_TEXTURE_ENV
, GL_FALSE
);
2029 if (ctx
->Texture
.Unit
[0]._ReallyEnabled
& (TEXTURE_1D_BIT
|TEXTURE_2D_BIT
) &&
2030 ctx
->Texture
.Unit
[1]._ReallyEnabled
== 0) {
2031 LOCK_HARDWARE( fxMesa
); /* XXX remove locking eventually */
2032 setupTextureSingleTMU(ctx
, 0);
2033 UNLOCK_HARDWARE( fxMesa
);
2035 else if (ctx
->Texture
.Unit
[0]._ReallyEnabled
== 0 &&
2036 ctx
->Texture
.Unit
[1]._ReallyEnabled
& (TEXTURE_1D_BIT
|TEXTURE_2D_BIT
)) {
2037 LOCK_HARDWARE( fxMesa
);
2038 setupTextureSingleTMU(ctx
, 1);
2039 UNLOCK_HARDWARE( fxMesa
);
2041 else if (ctx
->Texture
.Unit
[0]._ReallyEnabled
& (TEXTURE_1D_BIT
|TEXTURE_2D_BIT
) &&
2042 ctx
->Texture
.Unit
[1]._ReallyEnabled
& (TEXTURE_1D_BIT
|TEXTURE_2D_BIT
)) {
2043 LOCK_HARDWARE( fxMesa
);
2044 setupTextureDoubleTMU(ctx
);
2045 UNLOCK_HARDWARE( fxMesa
);
2048 /* disable hardware texturing */
2049 if (TDFX_IS_NAPALM(fxMesa
)) {
2050 fxMesa
->ColorCombineExt
.SourceA
= GR_CMBX_ITRGB
;
2051 fxMesa
->ColorCombineExt
.ModeA
= GR_FUNC_MODE_X
;
2052 fxMesa
->ColorCombineExt
.SourceB
= GR_CMBX_ZERO
;
2053 fxMesa
->ColorCombineExt
.ModeB
= GR_FUNC_MODE_ZERO
;
2054 fxMesa
->ColorCombineExt
.SourceC
= GR_CMBX_ZERO
;
2055 fxMesa
->ColorCombineExt
.InvertC
= FXTRUE
;
2056 fxMesa
->ColorCombineExt
.SourceD
= GR_CMBX_ZERO
;
2057 fxMesa
->ColorCombineExt
.InvertD
= FXFALSE
;
2058 fxMesa
->ColorCombineExt
.Shift
= 0;
2059 fxMesa
->ColorCombineExt
.Invert
= FXFALSE
;
2060 fxMesa
->AlphaCombineExt
.SourceA
= GR_CMBX_ITALPHA
;
2061 fxMesa
->AlphaCombineExt
.ModeA
= GR_FUNC_MODE_X
;
2062 fxMesa
->AlphaCombineExt
.SourceB
= GR_CMBX_ZERO
;
2063 fxMesa
->AlphaCombineExt
.ModeB
= GR_FUNC_MODE_ZERO
;
2064 fxMesa
->AlphaCombineExt
.SourceC
= GR_CMBX_ZERO
;
2065 fxMesa
->AlphaCombineExt
.InvertC
= FXTRUE
;
2066 fxMesa
->AlphaCombineExt
.SourceD
= GR_CMBX_ZERO
;
2067 fxMesa
->AlphaCombineExt
.InvertD
= FXFALSE
;
2068 fxMesa
->AlphaCombineExt
.Shift
= 0;
2069 fxMesa
->AlphaCombineExt
.Invert
= FXFALSE
;
2073 fxMesa
->ColorCombine
.Function
= GR_COMBINE_FUNCTION_LOCAL
;
2074 fxMesa
->ColorCombine
.Factor
= GR_COMBINE_FACTOR_NONE
;
2075 fxMesa
->ColorCombine
.Local
= GR_COMBINE_LOCAL_ITERATED
;
2076 fxMesa
->ColorCombine
.Other
= GR_COMBINE_OTHER_NONE
;
2077 fxMesa
->ColorCombine
.Invert
= FXFALSE
;
2078 fxMesa
->AlphaCombine
.Function
= GR_COMBINE_FUNCTION_LOCAL
;
2079 fxMesa
->AlphaCombine
.Factor
= GR_COMBINE_FACTOR_NONE
;
2080 fxMesa
->AlphaCombine
.Local
= GR_COMBINE_LOCAL_ITERATED
;
2081 fxMesa
->AlphaCombine
.Other
= GR_COMBINE_OTHER_NONE
;
2082 fxMesa
->AlphaCombine
.Invert
= FXFALSE
;
2085 fxMesa
->TexState
.Enabled
[0] = 0;
2086 fxMesa
->TexState
.Enabled
[1] = 0;
2087 fxMesa
->TexState
.EnvMode
[0] = 0;
2088 fxMesa
->TexState
.EnvMode
[1] = 0;
2090 fxMesa
->dirty
|= TDFX_UPLOAD_COLOR_COMBINE
;
2091 fxMesa
->dirty
|= TDFX_UPLOAD_ALPHA_COMBINE
;
2093 if (ctx
->Texture
.Unit
[0]._ReallyEnabled
!= 0 ||
2094 ctx
->Texture
.Unit
[1]._ReallyEnabled
!= 0) {
2095 /* software texture (cube map, rect tex, etc */
2096 FALLBACK(fxMesa
, TDFX_FALLBACK_TEXTURE_ENV
, GL_TRUE
);
2104 * This is a special case of texture state update.
2105 * It's used when we've simply bound a new texture to a texture
2106 * unit and the new texture has the exact same attributes as the
2107 * previously bound texture.
2108 * This is very common in Quake3.
2111 tdfxUpdateTextureBinding( GLcontext
*ctx
)
2113 tdfxContextPtr fxMesa
= TDFX_CONTEXT(ctx
);
2114 struct gl_texture_object
*tObj0
= ctx
->Texture
.Unit
[0]._Current
;
2115 struct gl_texture_object
*tObj1
= ctx
->Texture
.Unit
[1]._Current
;
2116 tdfxTexInfo
*ti0
= TDFX_TEXTURE_DATA(tObj0
);
2117 tdfxTexInfo
*ti1
= TDFX_TEXTURE_DATA(tObj1
);
2119 const struct gl_shared_state
*mesaShared
= fxMesa
->glCtx
->Shared
;
2120 const struct tdfxSharedState
*shared
= (struct tdfxSharedState
*) mesaShared
->DriverData
;
2123 fxMesa
->sScale0
= ti0
->sScale
;
2124 fxMesa
->tScale0
= ti0
->tScale
;
2125 if (ti0
->info
.format
== GR_TEXFMT_P_8
) {
2126 fxMesa
->TexPalette
.Type
= ti0
->paltype
;
2127 fxMesa
->TexPalette
.Data
= &(ti0
->palette
);
2128 fxMesa
->dirty
|= TDFX_UPLOAD_TEXTURE_PALETTE
;
2130 else if (ti1
&& ti1
->info
.format
== GR_TEXFMT_P_8
) {
2131 fxMesa
->TexPalette
.Type
= ti1
->paltype
;
2132 fxMesa
->TexPalette
.Data
= &(ti1
->palette
);
2133 fxMesa
->dirty
|= TDFX_UPLOAD_TEXTURE_PALETTE
;
2137 fxMesa
->sScale1
= ti1
->sScale
;
2138 fxMesa
->tScale1
= ti1
->tScale
;
2141 if (ctx
->Texture
.Unit
[0]._ReallyEnabled
& (TEXTURE_1D_BIT
|TEXTURE_2D_BIT
) &&
2142 ctx
->Texture
.Unit
[0]._ReallyEnabled
== 0) {
2143 /* Only unit 0 2D enabled */
2144 if (shared
->umaTexMemory
) {
2145 fxMesa
->TexSource
[0].StartAddress
= ti0
->tm
[0]->startAddr
;
2146 fxMesa
->TexSource
[0].EvenOdd
= GR_MIPMAPLEVELMASK_BOTH
;
2147 fxMesa
->TexSource
[0].Info
= &(ti0
->info
);
2150 if (ti0
->LODblend
&& ti0
->whichTMU
== TDFX_TMU_SPLIT
) {
2151 fxMesa
->TexSource
[0].StartAddress
= ti0
->tm
[TDFX_TMU0
]->startAddr
;
2152 fxMesa
->TexSource
[0].EvenOdd
= GR_MIPMAPLEVELMASK_ODD
;
2153 fxMesa
->TexSource
[0].Info
= &(ti0
->info
);
2154 fxMesa
->TexSource
[1].StartAddress
= ti0
->tm
[TDFX_TMU1
]->startAddr
;
2155 fxMesa
->TexSource
[1].EvenOdd
= GR_MIPMAPLEVELMASK_EVEN
;
2156 fxMesa
->TexSource
[1].Info
= &(ti0
->info
);
2160 if (ti0
->whichTMU
== TDFX_TMU_BOTH
)
2163 tmu
= ti0
->whichTMU
;
2164 fxMesa
->TexSource
[0].Info
= NULL
;
2165 fxMesa
->TexSource
[1].Info
= NULL
;
2167 fxMesa
->TexSource
[tmu
].StartAddress
= ti0
->tm
[tmu
]->startAddr
;
2168 fxMesa
->TexSource
[tmu
].EvenOdd
= GR_MIPMAPLEVELMASK_BOTH
;
2169 fxMesa
->TexSource
[tmu
].Info
= &(ti0
->info
);
2174 else if (ctx
->Texture
.Unit
[0]._ReallyEnabled
== 0 &&
2175 ctx
->Texture
.Unit
[0]._ReallyEnabled
& (TEXTURE_1D_BIT
|TEXTURE_2D_BIT
)) {
2176 /* Only unit 1 2D enabled */
2177 if (shared
->umaTexMemory
) {
2178 fxMesa
->TexSource
[0].StartAddress
= ti1
->tm
[0]->startAddr
;
2179 fxMesa
->TexSource
[0].EvenOdd
= GR_MIPMAPLEVELMASK_BOTH
;
2180 fxMesa
->TexSource
[0].Info
= &(ti1
->info
);
2183 else if (ctx
->Texture
.Unit
[0]._ReallyEnabled
& (TEXTURE_1D_BIT
|TEXTURE_2D_BIT
) &&
2184 ctx
->Texture
.Unit
[0]._ReallyEnabled
& (TEXTURE_1D_BIT
|TEXTURE_2D_BIT
)) {
2185 /* Both 2D enabled */
2186 if (shared
->umaTexMemory
) {
2187 const FxU32 tmu0
= 0, tmu1
= 1;
2188 fxMesa
->TexSource
[tmu0
].StartAddress
= ti0
->tm
[0]->startAddr
;
2189 fxMesa
->TexSource
[tmu0
].EvenOdd
= GR_MIPMAPLEVELMASK_BOTH
;
2190 fxMesa
->TexSource
[tmu0
].Info
= &(ti0
->info
);
2192 fxMesa
->TexSource
[tmu1
].StartAddress
= ti1
->tm
[0]->startAddr
;
2193 fxMesa
->TexSource
[tmu1
].EvenOdd
= GR_MIPMAPLEVELMASK_BOTH
;
2194 fxMesa
->TexSource
[tmu1
].Info
= &(ti1
->info
);
2197 const FxU32 tmu0
= 0, tmu1
= 1;
2198 fxMesa
->TexSource
[tmu0
].StartAddress
= ti0
->tm
[tmu0
]->startAddr
;
2199 fxMesa
->TexSource
[tmu0
].EvenOdd
= GR_MIPMAPLEVELMASK_BOTH
;
2200 fxMesa
->TexSource
[tmu0
].Info
= &(ti0
->info
);
2202 fxMesa
->TexSource
[tmu1
].StartAddress
= ti1
->tm
[tmu1
]->startAddr
;
2203 fxMesa
->TexSource
[tmu1
].EvenOdd
= GR_MIPMAPLEVELMASK_BOTH
;
2204 fxMesa
->TexSource
[tmu1
].Info
= &(ti1
->info
);
2209 fxMesa
->dirty
|= TDFX_UPLOAD_TEXTURE_SOURCE
;