Update DRI drivers to current DRI CVS and make them work.
[mesa.git] / src / mesa / drivers / dri / mga / mga_texcombine.c
1 /*
2 * Copyright (c) 2003 Ville Syrjala
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20 * DEALINGS IN THE SOFTWARE.
21 *
22 * Authors:
23 * Ville Syrjala <syrjala@sci.fi>
24 */
25
26 #include "glheader.h"
27
28 #include "mgacontext.h"
29 #include "mgatex.h"
30 #include "mgaregs.h"
31
32 /*
33 * GL_ARB_texture_env_combine
34 * GL_EXT_texture_env_combine
35 * GL_ARB_texture_env_crossbar
36 * GL_ATI_texture_env_combine3
37 */
38
39 #define ARG_DISABLE 0xffffffff
40 #define MGA_ARG1 0
41 #define MGA_ARG2 1
42 #define MGA_ALPHA 2
43
44 GLboolean mgaUpdateTextureEnvCombine( GLcontext *ctx, int unit )
45 {
46 mgaContextPtr mmesa = MGA_CONTEXT(ctx);
47 const int source = mmesa->tmu_source[unit];
48 const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[source];
49 GLuint *reg = ((GLuint *)&mmesa->setup.tdualstage0 + unit);
50 GLuint numColorArgs = 0, numAlphaArgs = 0;
51 GLuint arg1[3], arg2[3], alpha[3];
52 int args[3];
53 int i;
54
55 switch (texUnit->CombineModeRGB) {
56 case GL_REPLACE:
57 numColorArgs = 1;
58 break;
59 case GL_MODULATE:
60 case GL_ADD:
61 case GL_ADD_SIGNED:
62 case GL_SUBTRACT:
63 numColorArgs = 2;
64 break;
65 case GL_INTERPOLATE:
66 case GL_MODULATE_ADD_ATI:
67 case GL_MODULATE_SIGNED_ADD_ATI:
68 case GL_MODULATE_SUBTRACT_ATI:
69 numColorArgs = 3;
70 break;
71 default:
72 return GL_FALSE;
73 }
74
75 switch (texUnit->CombineModeA) {
76 case GL_REPLACE:
77 numAlphaArgs = 1;
78 break;
79 case GL_MODULATE:
80 case GL_ADD:
81 case GL_ADD_SIGNED:
82 case GL_SUBTRACT:
83 numAlphaArgs = 2;
84 break;
85 default:
86 return GL_FALSE;
87 }
88
89 /* Start fresh :) */
90 *reg = 0;
91
92 /* COLOR */
93 for (i = 0; i < 3; i++) {
94 arg1[i] = 0;
95 arg2[i] = 0;
96 alpha[i] = 0;
97 }
98
99 for (i = 0;i < numColorArgs; i++) {
100 switch (texUnit->CombineSourceRGB[i]) {
101 case GL_TEXTURE:
102 arg1[i] |= 0;
103 arg2[i] |= ARG_DISABLE;
104 alpha[i] |= TD0_color_alpha_currtex;
105 break;
106 case GL_TEXTURE0:
107 if (source == 0) {
108 arg1[i] |= 0;
109 arg2[i] |= ARG_DISABLE;
110 alpha[i] |= TD0_color_alpha_currtex;
111 } else {
112 if (ctx->Texture._EnabledUnits != 0x03) {
113 /* disable texturing */
114 mmesa->setup.dwgctl &= DC_opcod_MASK;
115 mmesa->setup.dwgctl |= DC_opcod_trap;
116 mmesa->hw.alpha_sel = AC_alphasel_diffused;
117 /* return GL_TRUE since we don't need a fallback */
118 return GL_TRUE;
119 }
120 arg1[i] |= ARG_DISABLE;
121 arg2[i] |= ARG_DISABLE;
122 alpha[i] |= TD0_color_alpha_prevtex;
123 }
124 break;
125 case GL_TEXTURE1:
126 if (source == 0) {
127 if (ctx->Texture._EnabledUnits != 0x03) {
128 /* disable texturing */
129 mmesa->setup.dwgctl &= DC_opcod_MASK;
130 mmesa->setup.dwgctl |= DC_opcod_trap;
131 mmesa->hw.alpha_sel = AC_alphasel_diffused;
132 /* return GL_TRUE since we don't need a fallback */
133 return GL_TRUE;
134 }
135 arg1[i] |= ARG_DISABLE;
136 /* G400 specs (TDUALSTAGE0) */
137 arg2[i] |= TD0_color_arg2_prevstage;
138 alpha[i] |= TD0_color_alpha_prevstage;
139 } else {
140 arg1[i] |= 0;
141 arg2[i] |= ARG_DISABLE;
142 alpha[i] |= TD0_color_alpha_currtex;
143 }
144 break;
145 case GL_CONSTANT:
146 arg1[i] |= ARG_DISABLE;
147 arg2[i] |= TD0_color_arg2_fcol;
148 alpha[i] |= TD0_color_alpha_fcol;
149 break;
150 case GL_PRIMARY_COLOR:
151 arg1[i] |= ARG_DISABLE;
152 /* G400 specs (TDUALSTAGE1) */
153 if (unit == 0 || (mmesa->setup.tdualstage0 &
154 ((TD0_color_sel_mul & TD0_color_sel_add) |
155 (TD0_alpha_sel_mul & TD0_alpha_sel_add)))) {
156 arg2[i] |= TD0_color_arg2_diffuse;
157 alpha[i] |= TD0_color_alpha_diffuse;
158 } else {
159 arg2[i] |= ARG_DISABLE;
160 alpha[i] |= ARG_DISABLE;
161 }
162 break;
163 case GL_PREVIOUS:
164 arg1[i] |= ARG_DISABLE;
165 if (unit == 0) {
166 arg2[i] |= TD0_color_arg2_diffuse;
167 alpha[i] |= TD0_color_alpha_diffuse;
168 } else {
169 arg2[i] |= TD0_color_arg2_prevstage;
170 alpha[i] |= TD0_color_alpha_prevstage;
171 }
172 break;
173 default:
174 return GL_FALSE;
175 }
176
177 switch (texUnit->CombineOperandRGB[i]) {
178 case GL_SRC_COLOR:
179 arg1[i] |= 0;
180 arg2[i] |= 0;
181 alpha[i] |= ARG_DISABLE;
182 break;
183 case GL_ONE_MINUS_SRC_COLOR:
184 arg1[i] |= TD0_color_arg1_inv_enable;
185 arg2[i] |= TD0_color_arg2_inv_enable;
186 alpha[i] |= ARG_DISABLE;
187 break;
188 case GL_SRC_ALPHA:
189 arg1[i] |= TD0_color_arg1_replicatealpha_enable;
190 arg2[i] |= TD0_color_arg2_replicatealpha_enable;
191 alpha[i] |= 0;
192 break;
193 case GL_ONE_MINUS_SRC_ALPHA:
194 arg1[i] |= (TD0_color_arg1_replicatealpha_enable |
195 TD0_color_arg1_inv_enable);
196 arg2[i] |= (TD0_color_arg2_replicatealpha_enable |
197 TD0_color_arg2_inv_enable);
198 alpha[i] |= (TD0_color_alpha1inv_enable |
199 TD0_color_alpha2inv_enable);
200 break;
201 }
202 }
203
204 switch (texUnit->CombineModeRGB) {
205 case GL_MODULATE_ADD_ATI:
206 case GL_MODULATE_SIGNED_ADD_ATI:
207 /* Special handling for ATI_texture_env_combine3.
208 * If Arg1 == Arg0 or Arg1 == Arg2 we can use arg1 or arg2 as input for
209 * both multiplier and adder.
210 */
211 /* Arg1 == arg1 */
212 if (arg1[1] == arg1[0]) {
213 if ((arg1[1] | arg2[2]) != ARG_DISABLE) {
214 *reg |= arg1[1] | arg2[2];
215 args[0] = MGA_ARG1; args[1] = MGA_ARG1; args[2] = MGA_ARG2;
216 break;
217 } else
218 if ((arg1[1] | alpha[2]) != ARG_DISABLE) {
219 *reg |= arg1[1] | alpha[2];
220 args[0] = MGA_ARG1; args[1] = MGA_ARG1; args[2] = MGA_ALPHA;
221 break;
222 }
223 }
224 if (arg1[1] == arg1[2]) {
225 if ((arg1[1] | arg2[0]) != ARG_DISABLE) {
226 *reg |= arg1[1] | arg2[0];
227 args[0] = MGA_ARG2; args[1] = MGA_ARG1; args[2] = MGA_ARG1;
228 break;
229 } else
230 if ((arg1[1] | alpha[0]) != ARG_DISABLE) {
231 *reg |= arg1[1] | alpha[0];
232 args[0] = MGA_ALPHA; args[1] = MGA_ARG1; args[2] = MGA_ARG1;
233 break;
234 }
235 }
236 /* fallthrough */
237 case GL_MODULATE_SUBTRACT_ATI:
238 /* Arg1 == arg2 */
239 if (arg2[1] == arg2[0]) {
240 if ((arg2[1] | arg1[2]) != ARG_DISABLE) {
241 *reg |= arg2[1] | arg1[2];
242 args[0] = MGA_ARG2; args[1] = MGA_ARG2; args[2] = MGA_ARG1;
243 break;
244 } else
245 if ((arg2[1] | alpha[2]) != ARG_DISABLE) {
246 *reg |= arg2[1] | alpha[2];
247 args[0] = MGA_ARG2; args[1] = MGA_ARG2; args[2] = MGA_ALPHA;
248 break;
249 }
250 }
251 if (arg2[1] == arg2[2]) {
252 if ((arg2[1] | arg1[0]) != ARG_DISABLE) {
253 *reg |= arg2[1] | arg1[0];
254 args[0] = MGA_ARG1; args[1] = MGA_ARG2; args[2] = MGA_ARG2;
255 break;
256 } else
257 if ((arg2[1] | alpha[0]) != ARG_DISABLE) {
258 *reg |= arg2[1] | alpha[0];
259 args[0] = MGA_ALPHA; args[1] = MGA_ARG2; args[2] = MGA_ARG2;
260 break;
261 }
262 }
263 /* fallthrough */
264 default:
265 /* Find working combo of arg1, arg2 and alpha.
266 *
267 * Keep the Arg0 != alpha cases first since there's
268 * no way to get alpha out by itself (GL_REPLACE).
269 *
270 * Keep the Arg2 == alpha cases first because only alpha has the
271 * capabilities to function as Arg2 (GL_INTERPOLATE). Also good for
272 * GL_ADD, GL_ADD_SIGNED, GL_SUBTRACT since we can't get alpha to the
273 * adder.
274 *
275 * Keep the Arg1 == alpha cases last for GL_MODULATE_ADD_ATI,
276 * GL_MODULATE_SIGNED_ADD_ATI. Again because we can't get alpha to the
277 * adder.
278 *
279 * GL_MODULATE_SUBTRACT_ATI needs special treatment since it requires
280 * that Arg1 == arg2. This requirement clashes with those of other modes.
281 */
282 if ((arg1[0] | arg2[1] | alpha[2]) != ARG_DISABLE) {
283 *reg |= arg1[0] | arg2[1] | alpha[2];
284 args[0] = MGA_ARG1; args[1] = MGA_ARG2; args[2] = MGA_ALPHA;
285 } else
286 if ((arg1[1] | arg2[0] | alpha[2]) != ARG_DISABLE &&
287 texUnit->CombineModeRGB != GL_MODULATE_SUBTRACT_ATI) {
288 *reg |= arg1[1] | arg2[0] | alpha[2];
289 args[0] = MGA_ARG2; args[1] = MGA_ARG1; args[2] = MGA_ALPHA;
290 } else
291 if ((arg1[1] | arg2[2] | alpha[0]) != ARG_DISABLE &&
292 texUnit->CombineModeRGB != GL_MODULATE_SUBTRACT_ATI) {
293 *reg |= arg1[1] | arg2[2] | alpha[0];
294 args[0] = MGA_ALPHA; args[1] = MGA_ARG1; args[2] = MGA_ARG2;
295 } else
296 if ((arg1[2] | arg2[1] | alpha[0]) != ARG_DISABLE) {
297 *reg |= arg1[2] | arg2[1] | alpha[0];
298 args[0] = MGA_ALPHA; args[1] = MGA_ARG2; args[2] = MGA_ARG1;
299 } else
300 if ((arg1[0] | arg2[2] | alpha[1]) != ARG_DISABLE) {
301 *reg |= arg1[0] | arg2[2] | alpha[1];
302 args[0] = MGA_ARG1; args[1] = MGA_ALPHA; args[2] = MGA_ARG2;
303 } else
304 if ((arg1[2] | arg2[0] | alpha[1]) != ARG_DISABLE) {
305 *reg |= arg1[2] | arg2[0] | alpha[1];
306 args[0] = MGA_ARG2; args[1] = MGA_ALPHA; args[2] = MGA_ARG1;
307 } else {
308 /* nothing suitable */
309 return GL_FALSE;
310 }
311 }
312
313 switch (texUnit->CombineModeRGB) {
314 case GL_REPLACE:
315 if (texUnit->CombineScaleShiftRGB) {
316 return GL_FALSE;
317 }
318
319 if (args[0] == MGA_ARG1) {
320 *reg |= TD0_color_sel_arg1;
321 } else if (args[0] == MGA_ARG2) {
322 *reg |= TD0_color_sel_arg2;
323 } else if (args[0] == MGA_ALPHA) {
324 /* Can't get alpha out by itself */
325 return GL_FALSE;
326 }
327 break;
328 case GL_MODULATE:
329 if (texUnit->CombineScaleShiftRGB == 1) {
330 *reg |= TD0_color_modbright_2x;
331 } else if (texUnit->CombineScaleShiftRGB == 2) {
332 *reg |= TD0_color_modbright_4x;
333 }
334
335 *reg |= TD0_color_sel_mul;
336
337 if (args[0] == MGA_ALPHA || args[1] == MGA_ALPHA) {
338 if (args[0] == MGA_ARG1 || args[1] == MGA_ARG1) {
339 *reg |= TD0_color_arg2mul_alpha2;
340 } else if (args[0] == MGA_ARG2 || args[1] == MGA_ARG2) {
341 *reg |= TD0_color_arg1mul_alpha1;
342 }
343 }
344 break;
345 case GL_ADD_SIGNED:
346 *reg |= TD0_color_addbias_enable;
347 /* fallthrough */
348 case GL_ADD:
349 if (args[0] == MGA_ALPHA || args[1] == MGA_ALPHA){
350 /* Can't get alpha to the adder */
351 return GL_FALSE;
352 }
353 if (texUnit->CombineScaleShiftRGB == 1) {
354 *reg |= TD0_color_add2x_enable;
355 } else if (texUnit->CombineScaleShiftRGB == 2) {
356 return GL_FALSE;
357 }
358
359 *reg |= (TD0_color_add_add |
360 TD0_color_sel_add);
361 break;
362 case GL_INTERPOLATE:
363 if (args[2] != MGA_ALPHA) {
364 /* Only alpha can function as Arg2 */
365 return GL_FALSE;
366 }
367 if (texUnit->CombineScaleShiftRGB == 1) {
368 *reg |= TD0_color_add2x_enable;
369 } else if (texUnit->CombineScaleShiftRGB == 2) {
370 return GL_FALSE;
371 }
372
373 *reg |= (TD0_color_arg1mul_alpha1 |
374 TD0_color_blend_enable |
375 TD0_color_arg1add_mulout |
376 TD0_color_arg2add_mulout |
377 TD0_color_add_add |
378 TD0_color_sel_add);
379
380 /* Have to do this with xor since GL_ONE_MINUS_SRC_ALPHA may have
381 * already touched this bit.
382 */
383 *reg ^= TD0_color_alpha1inv_enable;
384
385 if (args[0] == MGA_ARG2) {
386 /* Swap arguments */
387 *reg ^= (TD0_color_arg1mul_alpha1 |
388 TD0_color_arg2mul_alpha2 |
389 TD0_color_alpha1inv_enable |
390 TD0_color_alpha2inv_enable);
391 }
392
393 if (ctx->Texture._EnabledUnits != 0x03) {
394 /* Linear blending mode needs dualtex enabled */
395 *(reg+1) = (TD0_color_arg2_prevstage |
396 TD0_color_sel_arg2 |
397 TD0_alpha_arg2_prevstage |
398 TD0_alpha_sel_arg2);
399 mmesa->dualtex_env = GL_TRUE;
400 }
401 break;
402 case GL_SUBTRACT:
403 if (args[0] == MGA_ALPHA || args[1] == MGA_ALPHA) {
404 /* Can't get alpha to the adder */
405 return GL_FALSE;
406 }
407 if (texUnit->CombineScaleShiftRGB == 1) {
408 *reg |= TD0_color_add2x_enable;
409 } else if (texUnit->CombineScaleShiftRGB == 2) {
410 return GL_FALSE;
411 }
412
413 *reg |= (TD0_color_add_sub |
414 TD0_color_sel_add);
415
416 if (args[0] == MGA_ARG2) {
417 /* Swap arguments */
418 *reg ^= (TD0_color_arg1_inv_enable |
419 TD0_color_arg2_inv_enable);
420 }
421 break;
422 case GL_MODULATE_SIGNED_ADD_ATI:
423 *reg |= TD0_color_addbias_enable;
424 /* fallthrough */
425 case GL_MODULATE_ADD_ATI:
426 if (args[1] == MGA_ALPHA) {
427 /* Can't get alpha to the adder */
428 return GL_FALSE;
429 }
430 if (texUnit->CombineScaleShiftRGB == 1) {
431 *reg |= TD0_color_add2x_enable;
432 } else if (texUnit->CombineScaleShiftRGB == 2) {
433 return GL_FALSE;
434 }
435
436 *reg |= (TD0_color_add_add |
437 TD0_color_sel_add);
438
439 if (args[1] == args[0] || args[1] == args[2]) {
440 *reg |= TD0_color_arg1add_mulout;
441 if (args[0] == MGA_ALPHA || args[2] == MGA_ALPHA)
442 *reg |= TD0_color_arg1mul_alpha1;
443
444 if (args[1] == MGA_ARG1) {
445 /* Swap adder arguments */
446 *reg ^= (TD0_color_arg1add_mulout |
447 TD0_color_arg2add_mulout);
448 if (args[0] == MGA_ALPHA || args[2] == MGA_ALPHA) {
449 /* Swap multiplier arguments */
450 *reg ^= (TD0_color_arg1mul_alpha1 |
451 TD0_color_arg2mul_alpha2);
452 }
453 }
454 } else {
455 *reg |= (TD0_color_arg2mul_alpha2 |
456 TD0_color_arg1add_mulout);
457
458 if (args[1] == MGA_ARG1) {
459 /* Swap arguments */
460 *reg ^= (TD0_color_arg1mul_alpha1 |
461 TD0_color_arg2mul_alpha2 |
462 TD0_color_arg1add_mulout |
463 TD0_color_arg2add_mulout);
464 }
465 }
466 break;
467 case GL_MODULATE_SUBTRACT_ATI:
468 if (args[1] != MGA_ARG2) {
469 /* Can't swap arguments */
470 return GL_FALSE;
471 }
472 if (texUnit->CombineScaleShiftRGB == 1) {
473 *reg |= TD0_color_add2x_enable;
474 } else if (texUnit->CombineScaleShiftRGB == 2) {
475 return GL_FALSE;
476 }
477
478 *reg |= (TD0_color_add_sub |
479 TD0_color_sel_add);
480
481 if (args[1] == args[0] || args[1] == args[2]) {
482 *reg |= TD0_color_arg1add_mulout;
483 if (args[0] == MGA_ALPHA || args[2] == MGA_ALPHA)
484 *reg |= TD0_color_arg1mul_alpha1;
485 } else {
486 *reg |= (TD0_color_arg2mul_alpha2 |
487 TD0_color_arg1add_mulout);
488 }
489 break;
490 }
491
492
493 /* ALPHA */
494 for (i = 0; i < 2; i++) {
495 arg1[i] = 0;
496 arg2[i] = 0;
497 }
498
499 for (i = 0; i < numAlphaArgs; i++) {
500 switch (texUnit->CombineSourceA[i]) {
501 case GL_TEXTURE:
502 arg1[i] |= 0;
503 arg2[i] |= ARG_DISABLE;
504 break;
505 case GL_TEXTURE0:
506 if (source == 0) {
507 arg1[i] |= 0;
508 arg2[i] |= ARG_DISABLE;
509 } else {
510 if (ctx->Texture._EnabledUnits != 0x03) {
511 /* disable texturing */
512 mmesa->setup.dwgctl &= DC_opcod_MASK;
513 mmesa->setup.dwgctl |= DC_opcod_trap;
514 mmesa->hw.alpha_sel = AC_alphasel_diffused;
515 /* return GL_TRUE since we don't need a fallback */
516 return GL_TRUE;
517 }
518 arg1[i] |= ARG_DISABLE;
519 arg2[i] |= TD0_alpha_arg2_prevtex;
520 }
521 break;
522 case GL_TEXTURE1:
523 if (source == 0) {
524 if (ctx->Texture._EnabledUnits != 0x03) {
525 /* disable texturing */
526 mmesa->setup.dwgctl &= DC_opcod_MASK;
527 mmesa->setup.dwgctl |= DC_opcod_trap;
528 mmesa->hw.alpha_sel = AC_alphasel_diffused;
529 /* return GL_TRUE since we don't need a fallback */
530 return GL_TRUE;
531 }
532 arg1[i] |= ARG_DISABLE;
533 /* G400 specs (TDUALSTAGE0) */
534 arg2[i] |= TD0_alpha_arg2_prevstage;
535 } else {
536 arg1[i] |= 0;
537 arg2[i] |= ARG_DISABLE;
538 }
539 break;
540 case GL_CONSTANT:
541 arg1[i] |= ARG_DISABLE;
542 arg2[i] |= TD0_alpha_arg2_fcol;
543 break;
544 case GL_PRIMARY_COLOR:
545 arg1[i] |= ARG_DISABLE;
546 /* G400 specs (TDUALSTAGE1) */
547 if (unit == 0 || (mmesa->setup.tdualstage0 &
548 ((TD0_color_sel_mul & TD0_color_sel_add) |
549 (TD0_alpha_sel_mul & TD0_alpha_sel_add)))) {
550 arg2[i] |= TD0_alpha_arg2_diffuse;
551 } else {
552 arg2[i] |= ARG_DISABLE;
553 }
554 break;
555 case GL_PREVIOUS:
556 arg1[i] |= ARG_DISABLE;
557 if (unit == 0) {
558 arg2[i] |= TD0_alpha_arg2_diffuse;
559 } else {
560 arg2[i] |= TD0_alpha_arg2_prevstage;
561 }
562 break;
563 default:
564 return GL_FALSE;
565 }
566
567 switch (texUnit->CombineOperandA[i]) {
568 case GL_SRC_ALPHA:
569 arg1[i] |= 0;
570 arg2[i] |= 0;
571 break;
572 case GL_ONE_MINUS_SRC_ALPHA:
573 arg1[i] |= TD0_alpha_arg1_inv_enable;
574 arg2[i] |= TD0_alpha_arg2_inv_enable;
575 break;
576 }
577 }
578
579 /* Find a working combo of arg1 and arg2 */
580 if ((arg1[0] | arg2[1]) != ARG_DISABLE) {
581 *reg |= arg1[0] | arg2[1];
582 args[0] = MGA_ARG1; args[1] = MGA_ARG2;
583 } else
584 if ((arg1[1] | arg2[0]) != ARG_DISABLE) {
585 *reg |= arg1[1] | arg2[0];
586 args[0] = MGA_ARG2; args[1] = MGA_ARG1;
587 } else {
588 /* nothing suitable */
589 return GL_FALSE;
590 }
591
592 switch (texUnit->CombineModeA) {
593 case GL_REPLACE:
594 if (texUnit->CombineScaleShiftA) {
595 return GL_FALSE;
596 }
597
598 if (args[0] == MGA_ARG1){
599 *reg |= TD0_alpha_sel_arg1;
600 } else if (args[0] == MGA_ARG2) {
601 *reg |= TD0_alpha_sel_arg2;
602 }
603 break;
604 case GL_MODULATE:
605 if (texUnit->CombineScaleShiftA == 1) {
606 *reg |= TD0_alpha_modbright_2x;
607 } else if (texUnit->CombineScaleShiftA == 2) {
608 *reg |= TD0_alpha_modbright_4x;
609 }
610
611 *reg |= TD0_alpha_sel_mul;
612 break;
613 case GL_ADD_SIGNED:
614 *reg |= TD0_alpha_addbias_enable;
615 /* fallthrough */
616 case GL_ADD:
617 if (texUnit->CombineScaleShiftA == 1) {
618 *reg |= TD0_alpha_add2x_enable;
619 } else if (texUnit->CombineScaleShiftA == 2) {
620 return GL_FALSE;
621 }
622
623 *reg |= (TD0_alpha_add_enable |
624 TD0_alpha_sel_add);
625 break;
626 case GL_SUBTRACT:
627 if (texUnit->CombineScaleShiftA == 1) {
628 *reg |= TD0_alpha_add2x_enable;
629 } else if (texUnit->CombineScaleShiftA == 2) {
630 return GL_FALSE;
631 }
632
633 *reg |= (TD0_alpha_add_disable |
634 TD0_alpha_sel_add);
635
636 if (args[0] == MGA_ARG2) {
637 /* Swap arguments */
638 *reg ^= (TD0_alpha_arg1_inv_enable |
639 TD0_alpha_arg2_inv_enable);
640 }
641 break;
642 }
643
644 return GL_TRUE;
645 }
646
647