Merge branch 'mesa_7_7_branch'
[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 "main/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->Combine.ModeRGB) {
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->Combine.ModeA) {
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->Combine.SourceRGB[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 if (mmesa->fcol_used &&
147 mmesa->envcolor[source] != mmesa->envcolor[!source])
148 return GL_FALSE;
149
150 arg1[i] |= ARG_DISABLE;
151 arg2[i] |= TD0_color_arg2_fcol;
152 alpha[i] |= TD0_color_alpha_fcol;
153
154 mmesa->setup.fcol = mmesa->envcolor[source];
155 mmesa->fcol_used = GL_TRUE;
156 break;
157 case GL_PRIMARY_COLOR:
158 arg1[i] |= ARG_DISABLE;
159 /* G400 specs (TDUALSTAGE1) */
160 if (unit == 0 || (mmesa->setup.tdualstage0 &
161 ((TD0_color_sel_mul & TD0_color_sel_add) |
162 (TD0_alpha_sel_mul & TD0_alpha_sel_add)))) {
163 arg2[i] |= TD0_color_arg2_diffuse;
164 alpha[i] |= TD0_color_alpha_diffuse;
165 } else {
166 arg2[i] |= ARG_DISABLE;
167 alpha[i] |= ARG_DISABLE;
168 }
169 break;
170 case GL_PREVIOUS:
171 arg1[i] |= ARG_DISABLE;
172 if (unit == 0) {
173 arg2[i] |= TD0_color_arg2_diffuse;
174 alpha[i] |= TD0_color_alpha_diffuse;
175 } else {
176 arg2[i] |= TD0_color_arg2_prevstage;
177 alpha[i] |= TD0_color_alpha_prevstage;
178 }
179 break;
180 default:
181 return GL_FALSE;
182 }
183
184 switch (texUnit->Combine.OperandRGB[i]) {
185 case GL_SRC_COLOR:
186 arg1[i] |= 0;
187 arg2[i] |= 0;
188 if (texUnit->Combine.SourceRGB[i] == GL_CONSTANT &&
189 RGBA_EQUAL( mmesa->envcolor[source] )) {
190 alpha[i] |= 0;
191 } else {
192 alpha[i] |= ARG_DISABLE;
193 }
194 break;
195 case GL_ONE_MINUS_SRC_COLOR:
196 arg1[i] |= TD0_color_arg1_inv_enable;
197 arg2[i] |= TD0_color_arg2_inv_enable;
198 if (texUnit->Combine.SourceRGB[i] == GL_CONSTANT &&
199 RGBA_EQUAL( mmesa->envcolor[source] )) {
200 alpha[i] |= (TD0_color_alpha1inv_enable |
201 TD0_color_alpha2inv_enable);
202 } else {
203 alpha[i] |= ARG_DISABLE;
204 }
205 break;
206 case GL_SRC_ALPHA:
207 arg1[i] |= TD0_color_arg1_replicatealpha_enable;
208 arg2[i] |= TD0_color_arg2_replicatealpha_enable;
209 alpha[i] |= 0;
210 break;
211 case GL_ONE_MINUS_SRC_ALPHA:
212 arg1[i] |= (TD0_color_arg1_replicatealpha_enable |
213 TD0_color_arg1_inv_enable);
214 arg2[i] |= (TD0_color_arg2_replicatealpha_enable |
215 TD0_color_arg2_inv_enable);
216 alpha[i] |= (TD0_color_alpha1inv_enable |
217 TD0_color_alpha2inv_enable);
218 break;
219 }
220 }
221
222 switch (texUnit->Combine.ModeRGB) {
223 case GL_MODULATE_ADD_ATI:
224 case GL_MODULATE_SIGNED_ADD_ATI:
225 /* Special handling for ATI_texture_env_combine3.
226 * If Arg1 == Arg0 or Arg1 == Arg2 we can use arg1 or arg2 as input for
227 * both multiplier and adder.
228 */
229 /* Arg1 == arg1 */
230 if (arg1[1] == arg1[0]) {
231 if ((arg1[1] | arg2[2]) != ARG_DISABLE) {
232 *reg |= arg1[1] | arg2[2];
233 args[0] = MGA_ARG1; args[1] = MGA_ARG1; args[2] = MGA_ARG2;
234 break;
235 } else
236 if ((arg1[1] | alpha[2]) != ARG_DISABLE) {
237 *reg |= arg1[1] | alpha[2];
238 args[0] = MGA_ARG1; args[1] = MGA_ARG1; args[2] = MGA_ALPHA;
239 break;
240 }
241 }
242 if (arg1[1] == arg1[2]) {
243 if ((arg1[1] | arg2[0]) != ARG_DISABLE) {
244 *reg |= arg1[1] | arg2[0];
245 args[0] = MGA_ARG2; args[1] = MGA_ARG1; args[2] = MGA_ARG1;
246 break;
247 } else
248 if ((arg1[1] | alpha[0]) != ARG_DISABLE) {
249 *reg |= arg1[1] | alpha[0];
250 args[0] = MGA_ALPHA; args[1] = MGA_ARG1; args[2] = MGA_ARG1;
251 break;
252 }
253 }
254 /* fallthrough */
255 case GL_MODULATE_SUBTRACT_ATI:
256 /* Arg1 == arg2 */
257 if (arg2[1] == arg2[0]) {
258 if ((arg2[1] | arg1[2]) != ARG_DISABLE) {
259 *reg |= arg2[1] | arg1[2];
260 args[0] = MGA_ARG2; args[1] = MGA_ARG2; args[2] = MGA_ARG1;
261 break;
262 } else
263 if ((arg2[1] | alpha[2]) != ARG_DISABLE) {
264 *reg |= arg2[1] | alpha[2];
265 args[0] = MGA_ARG2; args[1] = MGA_ARG2; args[2] = MGA_ALPHA;
266 break;
267 }
268 }
269 if (arg2[1] == arg2[2]) {
270 if ((arg2[1] | arg1[0]) != ARG_DISABLE) {
271 *reg |= arg2[1] | arg1[0];
272 args[0] = MGA_ARG1; args[1] = MGA_ARG2; args[2] = MGA_ARG2;
273 break;
274 } else
275 if ((arg2[1] | alpha[0]) != ARG_DISABLE) {
276 *reg |= arg2[1] | alpha[0];
277 args[0] = MGA_ALPHA; args[1] = MGA_ARG2; args[2] = MGA_ARG2;
278 break;
279 }
280 }
281 /* fallthrough */
282 default:
283 /* Find working combo of arg1, arg2 and alpha.
284 *
285 * Keep the Arg0 != alpha cases first since there's
286 * no way to get alpha out by itself (GL_REPLACE).
287 *
288 * Keep the Arg2 == alpha cases first because only alpha has the
289 * capabilities to function as Arg2 (GL_INTERPOLATE). Also good for
290 * GL_ADD, GL_ADD_SIGNED, GL_SUBTRACT since we can't get alpha to the
291 * adder.
292 *
293 * Keep the Arg1 == alpha cases last for GL_MODULATE_ADD_ATI,
294 * GL_MODULATE_SIGNED_ADD_ATI. Again because we can't get alpha to the
295 * adder.
296 *
297 * GL_MODULATE_SUBTRACT_ATI needs special treatment since it requires
298 * that Arg1 == arg2. This requirement clashes with those of other modes.
299 */
300 if ((arg1[0] | arg2[1] | alpha[2]) != ARG_DISABLE) {
301 *reg |= arg1[0] | arg2[1] | alpha[2];
302 args[0] = MGA_ARG1; args[1] = MGA_ARG2; args[2] = MGA_ALPHA;
303 } else
304 if ((arg1[1] | arg2[0] | alpha[2]) != ARG_DISABLE &&
305 texUnit->Combine.ModeRGB != GL_MODULATE_SUBTRACT_ATI) {
306 *reg |= arg1[1] | arg2[0] | alpha[2];
307 args[0] = MGA_ARG2; args[1] = MGA_ARG1; args[2] = MGA_ALPHA;
308 } else
309 if ((arg1[1] | arg2[2] | alpha[0]) != ARG_DISABLE &&
310 texUnit->Combine.ModeRGB != GL_MODULATE_SUBTRACT_ATI) {
311 *reg |= arg1[1] | arg2[2] | alpha[0];
312 args[0] = MGA_ALPHA; args[1] = MGA_ARG1; args[2] = MGA_ARG2;
313 } else
314 if ((arg1[2] | arg2[1] | alpha[0]) != ARG_DISABLE) {
315 *reg |= arg1[2] | arg2[1] | alpha[0];
316 args[0] = MGA_ALPHA; args[1] = MGA_ARG2; args[2] = MGA_ARG1;
317 } else
318 if ((arg1[0] | arg2[2] | alpha[1]) != ARG_DISABLE) {
319 *reg |= arg1[0] | arg2[2] | alpha[1];
320 args[0] = MGA_ARG1; args[1] = MGA_ALPHA; args[2] = MGA_ARG2;
321 } else
322 if ((arg1[2] | arg2[0] | alpha[1]) != ARG_DISABLE) {
323 *reg |= arg1[2] | arg2[0] | alpha[1];
324 args[0] = MGA_ARG2; args[1] = MGA_ALPHA; args[2] = MGA_ARG1;
325 } else {
326 /* nothing suitable */
327 return GL_FALSE;
328 }
329 }
330
331 switch (texUnit->Combine.ModeRGB) {
332 case GL_REPLACE:
333 if (texUnit->Combine.ScaleShiftRGB) {
334 return GL_FALSE;
335 }
336
337 if (args[0] == MGA_ARG1) {
338 *reg |= TD0_color_sel_arg1;
339 } else if (args[0] == MGA_ARG2) {
340 *reg |= TD0_color_sel_arg2;
341 } else if (args[0] == MGA_ALPHA) {
342 /* Can't get alpha out by itself */
343 return GL_FALSE;
344 }
345 break;
346 case GL_MODULATE:
347 if (texUnit->Combine.ScaleShiftRGB == 1) {
348 *reg |= TD0_color_modbright_2x;
349 } else if (texUnit->Combine.ScaleShiftRGB == 2) {
350 *reg |= TD0_color_modbright_4x;
351 }
352
353 *reg |= TD0_color_sel_mul;
354
355 if (args[0] == MGA_ALPHA || args[1] == MGA_ALPHA) {
356 if (args[0] == MGA_ARG1 || args[1] == MGA_ARG1) {
357 *reg |= TD0_color_arg2mul_alpha2;
358 } else if (args[0] == MGA_ARG2 || args[1] == MGA_ARG2) {
359 *reg |= TD0_color_arg1mul_alpha1;
360 }
361 }
362 break;
363 case GL_ADD_SIGNED:
364 *reg |= TD0_color_addbias_enable;
365 /* fallthrough */
366 case GL_ADD:
367 if (args[0] == MGA_ALPHA || args[1] == MGA_ALPHA) {
368 /* Can't get alpha to the adder */
369 return GL_FALSE;
370 }
371 if (texUnit->Combine.ScaleShiftRGB == 1) {
372 *reg |= TD0_color_add2x_enable;
373 } else if (texUnit->Combine.ScaleShiftRGB == 2) {
374 return GL_FALSE;
375 }
376
377 *reg |= (TD0_color_add_add |
378 TD0_color_sel_add);
379 break;
380 case GL_INTERPOLATE:
381 if (args[2] != MGA_ALPHA) {
382 /* Only alpha can function as Arg2 */
383 return GL_FALSE;
384 }
385 if (texUnit->Combine.ScaleShiftRGB == 1) {
386 *reg |= TD0_color_add2x_enable;
387 } else if (texUnit->Combine.ScaleShiftRGB == 2) {
388 return GL_FALSE;
389 }
390
391 *reg |= (TD0_color_arg1mul_alpha1 |
392 TD0_color_blend_enable |
393 TD0_color_arg1add_mulout |
394 TD0_color_arg2add_mulout |
395 TD0_color_add_add |
396 TD0_color_sel_add);
397
398 /* Have to do this with xor since GL_ONE_MINUS_SRC_ALPHA may have
399 * already touched this bit.
400 */
401 *reg ^= TD0_color_alpha1inv_enable;
402
403 if (args[0] == MGA_ARG2) {
404 /* Swap arguments */
405 *reg ^= (TD0_color_arg1mul_alpha1 |
406 TD0_color_arg2mul_alpha2 |
407 TD0_color_alpha1inv_enable |
408 TD0_color_alpha2inv_enable);
409 }
410
411 if (ctx->Texture._EnabledUnits != 0x03) {
412 /* Linear blending mode needs dualtex enabled */
413 *(reg+1) = (TD0_color_arg2_prevstage |
414 TD0_color_sel_arg2 |
415 TD0_alpha_arg2_prevstage |
416 TD0_alpha_sel_arg2);
417 mmesa->force_dualtex = GL_TRUE;
418 }
419 break;
420 case GL_SUBTRACT:
421 if (args[0] == MGA_ALPHA || args[1] == MGA_ALPHA) {
422 /* Can't get alpha to the adder */
423 return GL_FALSE;
424 }
425 if (texUnit->Combine.ScaleShiftRGB == 1) {
426 *reg |= TD0_color_add2x_enable;
427 } else if (texUnit->Combine.ScaleShiftRGB == 2) {
428 return GL_FALSE;
429 }
430
431 *reg |= (TD0_color_add_sub |
432 TD0_color_sel_add);
433
434 if (args[0] == MGA_ARG2) {
435 /* Swap arguments */
436 *reg ^= (TD0_color_arg1_inv_enable |
437 TD0_color_arg2_inv_enable);
438 }
439 break;
440 case GL_MODULATE_SIGNED_ADD_ATI:
441 *reg |= TD0_color_addbias_enable;
442 /* fallthrough */
443 case GL_MODULATE_ADD_ATI:
444 if (args[1] == MGA_ALPHA) {
445 /* Can't get alpha to the adder */
446 return GL_FALSE;
447 }
448 if (texUnit->Combine.ScaleShiftRGB == 1) {
449 *reg |= TD0_color_add2x_enable;
450 } else if (texUnit->Combine.ScaleShiftRGB == 2) {
451 return GL_FALSE;
452 }
453
454 *reg |= (TD0_color_add_add |
455 TD0_color_sel_add);
456
457 if (args[1] == args[0] || args[1] == args[2]) {
458 *reg |= TD0_color_arg1add_mulout;
459 if (args[0] == MGA_ALPHA || args[2] == MGA_ALPHA)
460 *reg |= TD0_color_arg1mul_alpha1;
461
462 if (args[1] == MGA_ARG1) {
463 /* Swap adder arguments */
464 *reg ^= (TD0_color_arg1add_mulout |
465 TD0_color_arg2add_mulout);
466 if (args[0] == MGA_ALPHA || args[2] == MGA_ALPHA) {
467 /* Swap multiplier arguments */
468 *reg ^= (TD0_color_arg1mul_alpha1 |
469 TD0_color_arg2mul_alpha2);
470 }
471 }
472 } else {
473 *reg |= (TD0_color_arg2mul_alpha2 |
474 TD0_color_arg1add_mulout);
475
476 if (args[1] == MGA_ARG1) {
477 /* Swap arguments */
478 *reg ^= (TD0_color_arg1mul_alpha1 |
479 TD0_color_arg2mul_alpha2 |
480 TD0_color_arg1add_mulout |
481 TD0_color_arg2add_mulout);
482 }
483 }
484 break;
485 case GL_MODULATE_SUBTRACT_ATI:
486 if (args[1] != MGA_ARG2) {
487 /* Can't swap arguments */
488 return GL_FALSE;
489 }
490 if (texUnit->Combine.ScaleShiftRGB == 1) {
491 *reg |= TD0_color_add2x_enable;
492 } else if (texUnit->Combine.ScaleShiftRGB == 2) {
493 return GL_FALSE;
494 }
495
496 *reg |= (TD0_color_add_sub |
497 TD0_color_sel_add);
498
499 if (args[1] == args[0] || args[1] == args[2]) {
500 *reg |= TD0_color_arg1add_mulout;
501 if (args[0] == MGA_ALPHA || args[2] == MGA_ALPHA)
502 *reg |= TD0_color_arg1mul_alpha1;
503 } else {
504 *reg |= (TD0_color_arg2mul_alpha2 |
505 TD0_color_arg1add_mulout);
506 }
507 break;
508 }
509
510
511 /* ALPHA */
512 for (i = 0; i < 2; i++) {
513 arg1[i] = 0;
514 arg2[i] = 0;
515 }
516
517 for (i = 0; i < numAlphaArgs; i++) {
518 switch (texUnit->Combine.SourceA[i]) {
519 case GL_TEXTURE:
520 arg1[i] |= 0;
521 arg2[i] |= ARG_DISABLE;
522 break;
523 case GL_TEXTURE0:
524 if (source == 0) {
525 arg1[i] |= 0;
526 arg2[i] |= ARG_DISABLE;
527 } else {
528 if (ctx->Texture._EnabledUnits != 0x03) {
529 /* disable texturing */
530 mmesa->setup.dwgctl &= DC_opcod_MASK;
531 mmesa->setup.dwgctl |= DC_opcod_trap;
532 mmesa->hw.alpha_sel = AC_alphasel_diffused;
533 /* return GL_TRUE since we don't need a fallback */
534 return GL_TRUE;
535 }
536 arg1[i] |= ARG_DISABLE;
537 arg2[i] |= TD0_alpha_arg2_prevtex;
538 }
539 break;
540 case GL_TEXTURE1:
541 if (source == 0) {
542 if (ctx->Texture._EnabledUnits != 0x03) {
543 /* disable texturing */
544 mmesa->setup.dwgctl &= DC_opcod_MASK;
545 mmesa->setup.dwgctl |= DC_opcod_trap;
546 mmesa->hw.alpha_sel = AC_alphasel_diffused;
547 /* return GL_TRUE since we don't need a fallback */
548 return GL_TRUE;
549 }
550 arg1[i] |= ARG_DISABLE;
551 /* G400 specs (TDUALSTAGE0) */
552 arg2[i] |= TD0_alpha_arg2_prevstage;
553 } else {
554 arg1[i] |= 0;
555 arg2[i] |= ARG_DISABLE;
556 }
557 break;
558 case GL_CONSTANT:
559 if (mmesa->fcol_used &&
560 mmesa->envcolor[source] != mmesa->envcolor[!source])
561 return GL_FALSE;
562
563 arg1[i] |= ARG_DISABLE;
564 arg2[i] |= TD0_alpha_arg2_fcol;
565
566 mmesa->setup.fcol = mmesa->envcolor[source];
567 mmesa->fcol_used = GL_TRUE;
568 break;
569 case GL_PRIMARY_COLOR:
570 arg1[i] |= ARG_DISABLE;
571 /* G400 specs (TDUALSTAGE1) */
572 if (unit == 0 || (mmesa->setup.tdualstage0 &
573 ((TD0_color_sel_mul & TD0_color_sel_add) |
574 (TD0_alpha_sel_mul & TD0_alpha_sel_add)))) {
575 arg2[i] |= TD0_alpha_arg2_diffuse;
576 } else {
577 arg2[i] |= ARG_DISABLE;
578 }
579 break;
580 case GL_PREVIOUS:
581 arg1[i] |= ARG_DISABLE;
582 if (unit == 0) {
583 arg2[i] |= TD0_alpha_arg2_diffuse;
584 } else {
585 arg2[i] |= TD0_alpha_arg2_prevstage;
586 }
587 break;
588 default:
589 return GL_FALSE;
590 }
591
592 switch (texUnit->Combine.OperandA[i]) {
593 case GL_SRC_ALPHA:
594 arg1[i] |= 0;
595 arg2[i] |= 0;
596 break;
597 case GL_ONE_MINUS_SRC_ALPHA:
598 arg1[i] |= TD0_alpha_arg1_inv_enable;
599 arg2[i] |= TD0_alpha_arg2_inv_enable;
600 break;
601 }
602 }
603
604 /* Find a working combo of arg1 and arg2 */
605 if ((arg1[0] | arg2[1]) != ARG_DISABLE) {
606 *reg |= arg1[0] | arg2[1];
607 args[0] = MGA_ARG1; args[1] = MGA_ARG2;
608 } else
609 if ((arg1[1] | arg2[0]) != ARG_DISABLE) {
610 *reg |= arg1[1] | arg2[0];
611 args[0] = MGA_ARG2; args[1] = MGA_ARG1;
612 } else {
613 /* nothing suitable */
614 return GL_FALSE;
615 }
616
617 switch (texUnit->Combine.ModeA) {
618 case GL_REPLACE:
619 if (texUnit->Combine.ScaleShiftA) {
620 return GL_FALSE;
621 }
622
623 if (args[0] == MGA_ARG1) {
624 *reg |= TD0_alpha_sel_arg1;
625 } else if (args[0] == MGA_ARG2) {
626 *reg |= TD0_alpha_sel_arg2;
627 }
628 break;
629 case GL_MODULATE:
630 if (texUnit->Combine.ScaleShiftA == 1) {
631 *reg |= TD0_alpha_modbright_2x;
632 } else if (texUnit->Combine.ScaleShiftA == 2) {
633 *reg |= TD0_alpha_modbright_4x;
634 }
635
636 *reg |= TD0_alpha_sel_mul;
637 break;
638 case GL_ADD_SIGNED:
639 *reg |= TD0_alpha_addbias_enable;
640 /* fallthrough */
641 case GL_ADD:
642 if (texUnit->Combine.ScaleShiftA == 1) {
643 *reg |= TD0_alpha_add2x_enable;
644 } else if (texUnit->Combine.ScaleShiftA == 2) {
645 return GL_FALSE;
646 }
647
648 *reg |= (TD0_alpha_add_enable |
649 TD0_alpha_sel_add);
650 break;
651 case GL_SUBTRACT:
652 if (texUnit->Combine.ScaleShiftA == 1) {
653 *reg |= TD0_alpha_add2x_enable;
654 } else if (texUnit->Combine.ScaleShiftA == 2) {
655 return GL_FALSE;
656 }
657
658 *reg |= (TD0_alpha_add_disable |
659 TD0_alpha_sel_add);
660
661 if (args[0] == MGA_ARG2) {
662 /* Swap arguments */
663 *reg ^= (TD0_alpha_arg1_inv_enable |
664 TD0_alpha_arg2_inv_enable);
665 }
666 break;
667 }
668
669 return GL_TRUE;
670 }
671
672