mesa: replace gl_texture_format with gl_format
[mesa.git] / src / mesa / drivers / dri / mga / mga_texstate.c
1 /*
2 * Copyright 2000-2001 VA Linux Systems, Inc.
3 * (c) Copyright IBM Corporation 2002
4 * All Rights Reserved.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * on the rights to use, copy, modify, merge, publish, distribute, sub
10 * license, and/or sell copies of the Software, and to permit persons to whom
11 * the Software is furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice (including the next
14 * paragraph) shall be included in all copies or substantial portions of the
15 * Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
20 * VA LINUX SYSTEMS, IBM AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
21 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
22 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
23 * USE OR OTHER DEALINGS IN THE SOFTWARE.
24 *
25 * Authors:
26 * Ian Romanick <idr@us.ibm.com>
27 * Keith Whitwell <keithw@tungstengraphics.com>
28 */
29
30 #include <stdlib.h>
31 #include "main/mm.h"
32 #include "mgacontext.h"
33 #include "mgatex.h"
34 #include "mgaregs.h"
35 #include "mgatris.h"
36 #include "mgaioctl.h"
37
38 #include "main/context.h"
39 #include "main/enums.h"
40 #include "main/macros.h"
41 #include "main/imports.h"
42
43 #include "main/simple_list.h"
44 #include "main/texformat.h"
45
46 #define MGA_USE_TABLE_FOR_FORMAT
47 #ifdef MGA_USE_TABLE_FOR_FORMAT
48 #define TMC_nr_tformat (MESA_FORMAT_YCBCR_REV + 1)
49 static const unsigned TMC_tformat[ TMC_nr_tformat ] =
50 {
51 [MESA_FORMAT_ARGB8888] = TMC_tformat_tw32,
52 [MESA_FORMAT_RGB565] = TMC_tformat_tw16,
53 [MESA_FORMAT_ARGB4444] = TMC_tformat_tw12,
54 [MESA_FORMAT_ARGB1555] = TMC_tformat_tw15,
55 [MESA_FORMAT_AL88] = TMC_tformat_tw8al,
56 [MESA_FORMAT_I8] = TMC_tformat_tw8a,
57 [MESA_FORMAT_CI8] = TMC_tformat_tw8 ,
58 [MESA_FORMAT_YCBCR] = TMC_tformat_tw422uyvy,
59 [MESA_FORMAT_YCBCR_REV] = TMC_tformat_tw422,
60 };
61 #endif
62
63 static void
64 mgaSetTexImages( mgaContextPtr mmesa,
65 const struct gl_texture_object * tObj )
66 {
67 mgaTextureObjectPtr t = (mgaTextureObjectPtr) tObj->DriverData;
68 struct gl_texture_image *baseImage = tObj->Image[0][ tObj->BaseLevel ];
69 GLint totalSize;
70 GLint width, height;
71 GLint i;
72 GLint numLevels;
73 GLint log2Width, log2Height;
74 GLuint txformat = 0;
75 GLint ofs;
76
77 /* Set the hardware texture format
78 */
79 #ifndef MGA_USE_TABLE_FOR_FORMAT
80 switch (baseImage->TexFormat->MesaFormat) {
81
82 case MESA_FORMAT_ARGB8888: txformat = TMC_tformat_tw32; break;
83 case MESA_FORMAT_RGB565: txformat = TMC_tformat_tw16; break;
84 case MESA_FORMAT_ARGB4444: txformat = TMC_tformat_tw12; break;
85 case MESA_FORMAT_ARGB1555: txformat = TMC_tformat_tw15; break;
86 case MESA_FORMAT_AL88: txformat = TMC_tformat_tw8al; break;
87 case MESA_FORMAT_I8: txformat = TMC_tformat_tw8a; break;
88 case MESA_FORMAT_CI8: txformat = TMC_tformat_tw8; break;
89 case MESA_FORMAT_YCBCR: txformat = TMC_tformat_tw422uyvy; break;
90 case MESA_FORMAT_YCBCR_REV: txformat = TMC_tformat_tw422; break;
91
92 default:
93 _mesa_problem(NULL, "unexpected texture format in %s", __FUNCTION__);
94 return;
95 }
96 #else
97 if ( (baseImage->TexFormat >= TMC_nr_tformat)
98 || (TMC_tformat[ baseImage->TexFormat ] == 0) )
99 {
100 _mesa_problem(NULL, "unexpected texture format in %s", __FUNCTION__);
101 return;
102 }
103
104 txformat = TMC_tformat[ baseImage->TexFormat ];
105
106 #endif /* MGA_USE_TABLE_FOR_FORMAT */
107
108 driCalculateTextureFirstLastLevel( (driTextureObject *) t );
109 if (tObj->Target == GL_TEXTURE_RECTANGLE_NV) {
110 log2Width = 0;
111 log2Height = 0;
112 } else {
113 log2Width = tObj->Image[0][t->base.firstLevel]->WidthLog2;
114 log2Height = tObj->Image[0][t->base.firstLevel]->HeightLog2;
115 }
116
117 width = tObj->Image[0][t->base.firstLevel]->Width;
118 height = tObj->Image[0][t->base.firstLevel]->Height;
119
120 numLevels = MIN2( t->base.lastLevel - t->base.firstLevel + 1,
121 MGA_IS_G200(mmesa) ? G200_TEX_MAXLEVELS : G400_TEX_MAXLEVELS);
122
123
124 totalSize = 0;
125 for ( i = 0 ; i < numLevels ; i++ ) {
126 const struct gl_texture_image * const texImage =
127 tObj->Image[0][ i + t->base.firstLevel ];
128 int size;
129
130 if (texImage == NULL)
131 break;
132
133 size = texImage->Width * texImage->Height *
134 _mesa_get_format_bytes(baseImage->TexFormat);
135
136 t->offsets[i] = totalSize;
137 t->base.dirty_images[0] |= (1<<i);
138
139 /* All mipmaps must be 32-byte aligned */
140 totalSize += (size + 31) & ~31;
141
142 /* Since G400 calculates the offsets in hardware
143 * it can't handle more than one < 32 byte mipmap.
144 *
145 * Further testing has indicated that it can't
146 * handle any < 32 byte mipmaps.
147 */
148 if (MGA_IS_G400( mmesa ) && size <= 32) {
149 i++;
150 break;
151 }
152 }
153
154 /* save these values */
155 numLevels = i;
156 t->base.lastLevel = t->base.firstLevel + numLevels - 1;
157 t->base.totalSize = totalSize;
158
159 /* setup hardware register values */
160 t->setup.texctl &= (TMC_tformat_MASK & TMC_tpitch_MASK
161 & TMC_tpitchext_MASK);
162 t->setup.texctl |= txformat;
163
164
165 /* Set the texture width. In order to support non-power of 2 textures and
166 * textures larger than 1024 texels wide, "linear" pitch must be used. For
167 * the linear pitch, if the width is 2048, a value of zero is used.
168 */
169
170 t->setup.texctl |= TMC_tpitchlin_enable;
171 t->setup.texctl |= MGA_FIELD( TMC_tpitchext, width & (2048 - 1) );
172
173
174 /* G400 specifies the number of mip levels in a strange way. Since there
175 * are up to 11 levels, it requires 4 bits. Three of the bits are at the
176 * high end of TEXFILTER. The other bit is in the middle. Weird.
177 */
178 numLevels--;
179 t->setup.texfilter &= TF_mapnb_MASK & TF_mapnbhigh_MASK & TF_reserved_MASK;
180 t->setup.texfilter |= MGA_FIELD( TF_mapnb, numLevels & 0x7 );
181 t->setup.texfilter |= MGA_FIELD( TF_mapnbhigh, (numLevels >> 3) & 0x1 );
182
183 /* warp texture registers */
184 ofs = MGA_IS_G200(mmesa) ? 28 : 11;
185
186 t->setup.texwidth = (MGA_FIELD(TW_twmask, width - 1) |
187 MGA_FIELD(TW_rfw, (10 - log2Width - 8) & 63 ) |
188 MGA_FIELD(TW_tw, (log2Width + ofs ) | 0x40 ));
189
190 t->setup.texheight = (MGA_FIELD(TH_thmask, height - 1) |
191 MGA_FIELD(TH_rfh, (10 - log2Height - 8) & 63 ) |
192 MGA_FIELD(TH_th, (log2Height + ofs ) | 0x40 ));
193
194 mgaUploadTexImages( mmesa, t );
195 }
196
197
198 /* ================================================================
199 * Texture unit state management
200 */
201
202 static void mgaUpdateTextureEnvG200( GLcontext *ctx, GLuint unit )
203 {
204 mgaContextPtr mmesa = MGA_CONTEXT(ctx);
205 struct gl_texture_object *tObj = ctx->Texture.Unit[0]._Current;
206 mgaTextureObjectPtr t = (mgaTextureObjectPtr) tObj->DriverData;
207 GLenum format = tObj->Image[0][tObj->BaseLevel]->_BaseFormat;
208
209 if (tObj != ctx->Texture.Unit[0].CurrentTex[TEXTURE_2D_INDEX] &&
210 tObj != ctx->Texture.Unit[0].CurrentTex[TEXTURE_RECT_INDEX])
211 return;
212
213
214 t->setup.texctl &= ~TMC_tmodulate_enable;
215 t->setup.texctl2 &= ~(TMC_decalblend_enable |
216 TMC_idecal_enable |
217 TMC_decaldis_enable);
218
219 switch (ctx->Texture.Unit[0].EnvMode) {
220 case GL_REPLACE:
221 if (format == GL_ALPHA)
222 t->setup.texctl2 |= TMC_idecal_enable;
223
224 if (format == GL_RGB || format == GL_LUMINANCE)
225 mmesa->hw.alpha_sel = AC_alphasel_diffused;
226 else
227 mmesa->hw.alpha_sel = AC_alphasel_fromtex;
228 break;
229
230 case GL_MODULATE:
231 t->setup.texctl |= TMC_tmodulate_enable;
232
233 if (format == GL_ALPHA)
234 t->setup.texctl2 |= (TMC_idecal_enable |
235 TMC_decaldis_enable);
236
237 if (format == GL_RGB || format == GL_LUMINANCE)
238 mmesa->hw.alpha_sel = AC_alphasel_diffused;
239 else
240 mmesa->hw.alpha_sel = AC_alphasel_modulated;
241 break;
242
243 case GL_DECAL:
244 if (format == GL_RGB || format == GL_RGBA)
245 t->setup.texctl2 |= TMC_decalblend_enable;
246 else
247 t->setup.texctl2 |= TMC_idecal_enable;
248
249 mmesa->hw.alpha_sel = AC_alphasel_diffused;
250 break;
251
252 case GL_BLEND:
253 if (format == GL_ALPHA) {
254 t->setup.texctl2 |= TMC_idecal_enable;
255 mmesa->hw.alpha_sel = AC_alphasel_modulated;
256 } else {
257 t->texenv_fallback = GL_TRUE;
258 }
259 break;
260
261 default:
262 break;
263 }
264 }
265
266
267 #define MGA_REPLACE 0
268 #define MGA_MODULATE 1
269 #define MGA_DECAL 2
270 #define MGA_ADD 3
271 #define MGA_MAX_COMBFUNC 4
272
273 static const GLuint g400_color_combine[][MGA_MAX_COMBFUNC] =
274 {
275 /* Unit 0:
276 */
277 {
278 /* GL_REPLACE
279 * Cv = Cs
280 * Av = Af
281 */
282 (TD0_color_sel_arg1 |
283 TD0_alpha_arg2_diffuse |
284 TD0_alpha_sel_arg2),
285
286 /* GL_MODULATE
287 * Cv = Cf Cs
288 * Av = Af
289 */
290 (TD0_color_arg2_diffuse |
291 TD0_color_sel_mul |
292 TD0_alpha_arg2_diffuse |
293 TD0_alpha_sel_arg2),
294
295 /* GL_DECAL
296 * Cv = Cs
297 * Av = Af
298 */
299 (TD0_color_sel_arg1 |
300 TD0_alpha_arg2_diffuse |
301 TD0_alpha_sel_arg2),
302
303 /* GL_ADD
304 * Cv = Cf + Cs
305 * Av = Af
306 */
307 (TD0_color_arg2_diffuse |
308 TD0_color_add_add |
309 TD0_color_sel_add |
310 TD0_alpha_arg2_diffuse |
311 TD0_alpha_sel_arg2),
312 },
313
314 /* Unit 1:
315 */
316 {
317 /* GL_REPLACE
318 * Cv = Cs
319 * Av = Ap
320 */
321 (TD0_color_sel_arg1 |
322 TD0_alpha_arg2_prevstage |
323 TD0_alpha_sel_arg2),
324
325 /* GL_MODULATE
326 * Cv = Cp Cs
327 * Av = Ap
328 */
329 (TD0_color_arg2_prevstage |
330 TD0_color_sel_mul |
331 TD0_alpha_arg2_prevstage |
332 TD0_alpha_sel_arg2),
333
334 /* GL_DECAL
335 * Cv = Cs
336 * Av = Ap
337 */
338 (TD0_color_sel_arg1 |
339 TD0_alpha_arg2_prevstage |
340 TD0_alpha_sel_arg2),
341
342 /* GL_ADD
343 * Cv = Cp + Cs
344 * Av = Ap
345 */
346 (TD0_color_arg2_prevstage |
347 TD0_color_add_add |
348 TD0_color_sel_add |
349 TD0_alpha_arg2_prevstage |
350 TD0_alpha_sel_arg2),
351 },
352 };
353
354 static const GLuint g400_color_alpha_combine[][MGA_MAX_COMBFUNC] =
355 {
356 /* Unit 0:
357 */
358 {
359 /* GL_REPLACE
360 * Cv = Cs
361 * Av = As
362 */
363 (TD0_color_sel_arg1 |
364 TD0_alpha_sel_arg1),
365
366 /* GL_MODULATE
367 * Cv = Cf Cs
368 * Av = Af As
369 */
370 (TD0_color_arg2_diffuse |
371 TD0_color_sel_mul |
372 TD0_alpha_arg2_diffuse |
373 TD0_alpha_sel_mul),
374
375 /* GL_DECAL
376 * tmp = Cf ( 1 - As )
377 * Cv = tmp + Cs As
378 * Av = Af
379 */
380 (TD0_color_arg2_diffuse |
381 TD0_color_alpha_currtex |
382 TD0_color_alpha1inv_enable |
383 TD0_color_arg1mul_alpha1 |
384 TD0_color_blend_enable |
385 TD0_color_arg1add_mulout |
386 TD0_color_arg2add_mulout |
387 TD0_color_add_add |
388 TD0_color_sel_add |
389 TD0_alpha_arg2_diffuse |
390 TD0_alpha_sel_arg2),
391
392 /* GL_ADD
393 * Cv = Cf + Cs
394 * Av = Af As
395 */
396 (TD0_color_arg2_diffuse |
397 TD0_color_add_add |
398 TD0_color_sel_add |
399 TD0_alpha_arg2_diffuse |
400 TD0_alpha_sel_mul),
401 },
402
403 /* Unit 1:
404 */
405 {
406 /* GL_REPLACE
407 * Cv = Cs
408 * Av = As
409 */
410 (TD0_color_sel_arg1 |
411 TD0_alpha_sel_arg1),
412
413 /* GL_MODULATE
414 * Cv = Cp Cs
415 * Av = Ap As
416 */
417 (TD0_color_arg2_prevstage |
418 TD0_color_sel_mul |
419 TD0_alpha_arg2_prevstage |
420 TD0_alpha_sel_mul),
421
422 /* GL_DECAL
423 * tmp = Cp ( 1 - As )
424 * Cv = tmp + Cs As
425 * Av = Ap
426 */
427 (TD0_color_arg2_prevstage |
428 TD0_color_alpha_currtex |
429 TD0_color_alpha1inv_enable |
430 TD0_color_arg1mul_alpha1 |
431 TD0_color_blend_enable |
432 TD0_color_arg1add_mulout |
433 TD0_color_arg2add_mulout |
434 TD0_color_add_add |
435 TD0_color_sel_add |
436 TD0_alpha_arg2_prevstage |
437 TD0_alpha_sel_arg2),
438
439 /* GL_ADD
440 * Cv = Cp + Cs
441 * Av = Ap As
442 */
443 (TD0_color_arg2_prevstage |
444 TD0_color_add_add |
445 TD0_color_sel_add |
446 TD0_alpha_arg2_prevstage |
447 TD0_alpha_sel_mul),
448 },
449 };
450
451 static const GLuint g400_alpha_combine[][MGA_MAX_COMBFUNC] =
452 {
453 /* Unit 0:
454 */
455 {
456 /* GL_REPLACE
457 * Cv = Cf
458 * Av = As
459 */
460 (TD0_color_arg2_diffuse |
461 TD0_color_sel_arg2 |
462 TD0_alpha_sel_arg1),
463
464 /* GL_MODULATE
465 * Cv = Cf
466 * Av = Af As
467 */
468 (TD0_color_arg2_diffuse |
469 TD0_color_sel_arg2 |
470 TD0_alpha_arg2_diffuse |
471 TD0_alpha_sel_mul),
472
473 /* GL_DECAL (undefined)
474 * Cv = Cf
475 * Av = Af
476 */
477 (TD0_color_arg2_diffuse |
478 TD0_color_sel_arg2 |
479 TD0_alpha_arg2_diffuse |
480 TD0_alpha_sel_arg2),
481
482 /* GL_ADD
483 * Cv = Cf
484 * Av = Af As
485 */
486 (TD0_color_arg2_diffuse |
487 TD0_color_sel_arg2 |
488 TD0_alpha_arg2_diffuse |
489 TD0_alpha_sel_mul),
490 },
491
492 /* Unit 1:
493 */
494 {
495 /* GL_REPLACE
496 * Cv = Cp
497 * Av = As
498 */
499 (TD0_color_arg2_prevstage |
500 TD0_color_sel_arg2 |
501 TD0_alpha_sel_arg1),
502
503 /* GL_MODULATE
504 * Cv = Cp
505 * Av = Ap As
506 */
507 (TD0_color_arg2_prevstage |
508 TD0_color_sel_arg2 |
509 TD0_alpha_arg2_prevstage |
510 TD0_alpha_sel_mul),
511
512 /* GL_DECAL (undefined)
513 * Cv = Cp
514 * Av = Ap
515 */
516 (TD0_color_arg2_prevstage |
517 TD0_color_sel_arg2 |
518 TD0_alpha_arg2_prevstage |
519 TD0_alpha_sel_arg2),
520
521 /* GL_ADD
522 * Cv = Cp
523 * Av = Ap As
524 */
525 (TD0_color_arg2_prevstage |
526 TD0_color_sel_arg2 |
527 TD0_alpha_arg2_prevstage |
528 TD0_alpha_sel_mul),
529 },
530 };
531
532 static GLboolean mgaUpdateTextureEnvBlend( GLcontext *ctx, int unit )
533 {
534 mgaContextPtr mmesa = MGA_CONTEXT(ctx);
535 const int source = mmesa->tmu_source[unit];
536 const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[source];
537 const struct gl_texture_object *tObj = texUnit->_Current;
538 GLuint *reg = ((GLuint *)&mmesa->setup.tdualstage0 + unit);
539 GLenum format = tObj->Image[0][tObj->BaseLevel]->_BaseFormat;
540
541 *reg = 0;
542
543 if (format == GL_ALPHA) {
544 /* Cv = Cf */
545 *reg |= (TD0_color_arg2_diffuse |
546 TD0_color_sel_arg2);
547 /* Av = Af As */
548 *reg |= (TD0_alpha_arg2_diffuse |
549 TD0_alpha_sel_mul);
550 return GL_TRUE;
551 }
552
553 /* C1 = Cf ( 1 - Cs ) */
554 *reg |= (TD0_color_arg1_inv_enable |
555 TD0_color_arg2_diffuse |
556 TD0_color_sel_mul);
557
558 if (format == GL_RGB || format == GL_LUMINANCE) {
559 /* A1 = Af */
560 *reg |= (TD0_alpha_arg2_diffuse |
561 TD0_alpha_sel_arg2);
562 } else
563 if (format == GL_RGBA || format == GL_LUMINANCE_ALPHA) {
564 /* A1 = Af As */
565 *reg |= (TD0_alpha_arg2_diffuse |
566 TD0_alpha_sel_mul);
567 } else
568 if (format == GL_INTENSITY) {
569 /* A1 = Af ( 1 - As ) */
570 *reg |= (TD0_alpha_arg1_inv_enable |
571 TD0_alpha_arg2_diffuse |
572 TD0_alpha_sel_mul);
573 }
574
575 if (RGB_ZERO(mmesa->envcolor[source]) &&
576 (format != GL_INTENSITY || ALPHA_ZERO(mmesa->envcolor[source])))
577 return GL_TRUE; /* all done */
578
579 if (ctx->Texture._EnabledUnits == 0x03)
580 return GL_FALSE; /* need both units */
581
582 mmesa->force_dualtex = GL_TRUE;
583 reg = &mmesa->setup.tdualstage1;
584 *reg = 0;
585
586 if (RGB_ZERO(mmesa->envcolor[source])) {
587 /* Cv = C1 */
588 *reg |= (TD0_color_arg2_prevstage |
589 TD0_color_sel_arg2);
590 } else
591 if (RGB_ONE(mmesa->envcolor[source])) {
592 /* Cv = C1 + Cs */
593 *reg |= (TD0_color_arg2_prevstage |
594 TD0_color_add_add |
595 TD0_color_sel_add);
596 } else
597 if (RGBA_EQUAL(mmesa->envcolor[source])) {
598 /* Cv = C1 + Cc Cs */
599 *reg |= (TD0_color_arg2_prevstage |
600 TD0_color_alpha_fcol |
601 TD0_color_arg2mul_alpha2 |
602 TD0_color_arg1add_mulout |
603 TD0_color_add_add |
604 TD0_color_sel_add);
605
606 mmesa->setup.fcol = mmesa->envcolor[source];
607 } else {
608 return GL_FALSE;
609 }
610
611 if (format != GL_INTENSITY || ALPHA_ZERO(mmesa->envcolor[source])) {
612 /* Av = A1 */
613 *reg |= (TD0_alpha_arg2_prevstage |
614 TD0_alpha_sel_arg2);
615 } else
616 if (ALPHA_ONE(mmesa->envcolor[source])) {
617 /* Av = A1 + As */
618 *reg |= (TD0_alpha_arg2_prevstage |
619 TD0_alpha_add_enable |
620 TD0_alpha_sel_add);
621 } else {
622 return GL_FALSE;
623 }
624
625 return GL_TRUE;
626 }
627
628 static void mgaUpdateTextureEnvG400( GLcontext *ctx, GLuint unit )
629 {
630 mgaContextPtr mmesa = MGA_CONTEXT( ctx );
631 const int source = mmesa->tmu_source[unit];
632 const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[source];
633 const struct gl_texture_object *tObj = texUnit->_Current;
634 GLuint *reg = ((GLuint *)&mmesa->setup.tdualstage0 + unit);
635 mgaTextureObjectPtr t = (mgaTextureObjectPtr) tObj->DriverData;
636 GLenum format = tObj->Image[0][tObj->BaseLevel]->_BaseFormat;
637
638 if (tObj != ctx->Texture.Unit[source].CurrentTex[TEXTURE_2D_INDEX] &&
639 tObj != ctx->Texture.Unit[source].CurrentTex[TEXTURE_RECT_INDEX])
640 return;
641
642 switch (ctx->Texture.Unit[source].EnvMode) {
643 case GL_REPLACE:
644 if (format == GL_ALPHA) {
645 *reg = g400_alpha_combine[unit][MGA_REPLACE];
646 } else if (format == GL_RGB || format == GL_LUMINANCE) {
647 *reg = g400_color_combine[unit][MGA_REPLACE];
648 } else {
649 *reg = g400_color_alpha_combine[unit][MGA_REPLACE];
650 }
651 break;
652
653 case GL_MODULATE:
654 if (format == GL_ALPHA) {
655 *reg = g400_alpha_combine[unit][MGA_MODULATE];
656 } else if (format == GL_RGB || format == GL_LUMINANCE) {
657 *reg = g400_color_combine[unit][MGA_MODULATE];
658 } else {
659 *reg = g400_color_alpha_combine[unit][MGA_MODULATE];
660 }
661 break;
662
663 case GL_DECAL:
664 if (format == GL_RGB) {
665 *reg = g400_color_combine[unit][MGA_DECAL];
666 } else if (format == GL_RGBA) {
667 *reg = g400_color_alpha_combine[unit][MGA_DECAL];
668 if (ctx->Texture._EnabledUnits != 0x03) {
669 /* Linear blending mode needs dual texturing enabled */
670 *(reg+1) = (TD0_color_arg2_prevstage |
671 TD0_color_sel_arg2 |
672 TD0_alpha_arg2_prevstage |
673 TD0_alpha_sel_arg2);
674 mmesa->force_dualtex = GL_TRUE;
675 }
676 } else {
677 /* Undefined */
678 *reg = g400_alpha_combine[unit][MGA_DECAL];
679 }
680 break;
681
682 case GL_ADD:
683 if (format == GL_ALPHA) {
684 *reg = g400_alpha_combine[unit][MGA_ADD];
685 } else if (format == GL_RGB || format == GL_LUMINANCE) {
686 *reg = g400_color_combine[unit][MGA_ADD];
687 } else if (format == GL_RGBA || format == GL_LUMINANCE_ALPHA) {
688 *reg = g400_color_alpha_combine[unit][MGA_ADD];
689 } else if (format == GL_INTENSITY) {
690 /* Cv = Cf + Cs
691 * Av = Af + As
692 */
693 if (unit == 0) {
694 *reg = (TD0_color_arg2_diffuse |
695 TD0_color_add_add |
696 TD0_color_sel_add |
697 TD0_alpha_arg2_diffuse |
698 TD0_alpha_add_enable |
699 TD0_alpha_sel_add);
700 } else {
701 *reg = (TD0_color_arg2_prevstage |
702 TD0_color_add_add |
703 TD0_color_sel_add |
704 TD0_alpha_arg2_prevstage |
705 TD0_alpha_add_enable |
706 TD0_alpha_sel_add);
707 }
708 }
709 break;
710
711 case GL_BLEND:
712 if (!mgaUpdateTextureEnvBlend(ctx, unit))
713 t->texenv_fallback = GL_TRUE;
714 break;
715
716 case GL_COMBINE:
717 if (!mgaUpdateTextureEnvCombine(ctx, unit))
718 t->texenv_fallback = GL_TRUE;
719 break;
720 default:
721 break;
722 }
723 }
724
725 static void disable_tex( GLcontext *ctx, int unit )
726 {
727 mgaContextPtr mmesa = MGA_CONTEXT( ctx );
728
729 /* Texture unit disabled */
730
731 if ( mmesa->CurrentTexObj[unit] != NULL ) {
732 /* The old texture is no longer bound to this texture unit.
733 * Mark it as such.
734 */
735
736 mmesa->CurrentTexObj[unit]->base.bound &= ~(1UL << unit);
737 mmesa->CurrentTexObj[unit] = NULL;
738 }
739
740 if ( unit != 0 && !mmesa->force_dualtex ) {
741 mmesa->setup.tdualstage1 = mmesa->setup.tdualstage0;
742 }
743
744 if ( ctx->Texture._EnabledUnits == 0 ) {
745 mmesa->setup.dwgctl &= DC_opcod_MASK;
746 mmesa->setup.dwgctl |= DC_opcod_trap;
747 mmesa->hw.alpha_sel = AC_alphasel_diffused;
748 }
749
750 mmesa->dirty |= MGA_UPLOAD_CONTEXT | (MGA_UPLOAD_TEX0 << unit);
751 }
752
753 static GLboolean enable_tex( GLcontext *ctx, int unit )
754 {
755 mgaContextPtr mmesa = MGA_CONTEXT(ctx);
756 const int source = mmesa->tmu_source[unit];
757 const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[source];
758 const struct gl_texture_object *tObj = texUnit->_Current;
759 mgaTextureObjectPtr t = (mgaTextureObjectPtr) tObj->DriverData;
760
761 /* Upload teximages (not pipelined)
762 */
763 if (t->base.dirty_images[0]) {
764 FLUSH_BATCH( mmesa );
765 mgaSetTexImages( mmesa, tObj );
766 if ( t->base.memBlock == NULL ) {
767 return GL_FALSE;
768 }
769 }
770
771 return GL_TRUE;
772 }
773
774 static GLboolean update_tex_common( GLcontext *ctx, int unit )
775 {
776 mgaContextPtr mmesa = MGA_CONTEXT(ctx);
777 const int source = mmesa->tmu_source[unit];
778 const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[source];
779 struct gl_texture_object *tObj = texUnit->_Current;
780 mgaTextureObjectPtr t = (mgaTextureObjectPtr) tObj->DriverData;
781
782 /* Fallback if there's a texture border */
783 if ( tObj->Image[0][tObj->BaseLevel]->Border > 0 ) {
784 return GL_FALSE;
785 }
786
787
788 /* Update state if this is a different texture object to last
789 * time.
790 */
791 if ( mmesa->CurrentTexObj[unit] != t ) {
792 if ( mmesa->CurrentTexObj[unit] != NULL ) {
793 /* The old texture is no longer bound to this texture unit.
794 * Mark it as such.
795 */
796
797 mmesa->CurrentTexObj[unit]->base.bound &= ~(1UL << unit);
798 }
799
800 mmesa->CurrentTexObj[unit] = t;
801 t->base.bound |= (1UL << unit);
802
803 driUpdateTextureLRU( (driTextureObject *) t ); /* done too often */
804 }
805
806 /* register setup */
807 if ( unit == 1 ) {
808 mmesa->setup.tdualstage1 = mmesa->setup.tdualstage0;
809 }
810
811 t->texenv_fallback = GL_FALSE;
812
813 /* Set this before mgaUpdateTextureEnvG400() since
814 * GL_ARB_texture_env_crossbar may have to disable texturing.
815 */
816 mmesa->setup.dwgctl &= DC_opcod_MASK;
817 mmesa->setup.dwgctl |= DC_opcod_texture_trap;
818
819 /* FIXME: The Radeon has some cached state so that it can avoid calling
820 * FIXME: UpdateTextureEnv in some cases. Is that possible here?
821 */
822 if (MGA_IS_G400(mmesa)) {
823 /* G400: Regardless of texture env mode, we use the alpha from the
824 * texture unit (AC_alphasel_fromtex) since it will have already
825 * been modulated by the incoming fragment color, if needed.
826 * We don't want (AC_alphasel_modulate) since that'll effectively
827 * do the modulation twice.
828 */
829 mmesa->hw.alpha_sel = AC_alphasel_fromtex;
830
831 mgaUpdateTextureEnvG400( ctx, unit );
832 } else {
833 mgaUpdateTextureEnvG200( ctx, unit );
834 }
835
836 t->setup.texctl2 &= TMC_dualtex_MASK;
837 if (ctx->Texture._EnabledUnits == 0x03 || mmesa->force_dualtex) {
838 t->setup.texctl2 |= TMC_dualtex_enable;
839 }
840
841 mmesa->dirty |= MGA_UPLOAD_CONTEXT | (MGA_UPLOAD_TEX0 << unit);
842
843 FALLBACK( ctx, MGA_FALLBACK_BORDER_MODE, t->border_fallback );
844 return !t->border_fallback && !t->texenv_fallback;
845 }
846
847
848 static GLboolean updateTextureUnit( GLcontext *ctx, int unit )
849 {
850 mgaContextPtr mmesa = MGA_CONTEXT( ctx );
851 const int source = mmesa->tmu_source[unit];
852 const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[source];
853
854
855 if ( texUnit->_ReallyEnabled == TEXTURE_2D_BIT ||
856 texUnit->_ReallyEnabled == TEXTURE_RECT_BIT ) {
857 return(enable_tex( ctx, unit ) &&
858 update_tex_common( ctx, unit ));
859 }
860 else if ( texUnit->_ReallyEnabled ) {
861 return GL_FALSE;
862 }
863 else {
864 disable_tex( ctx, unit );
865 return GL_TRUE;
866 }
867 }
868
869 /* The G400 is now programmed quite differently wrt texture environment.
870 */
871 void mgaUpdateTextureState( GLcontext *ctx )
872 {
873 mgaContextPtr mmesa = MGA_CONTEXT( ctx );
874 GLboolean ok;
875 unsigned i;
876
877 mmesa->force_dualtex = GL_FALSE;
878 mmesa->fcol_used = GL_FALSE;
879
880 /* This works around a quirk with the MGA hardware. If only OpenGL
881 * TEXTURE1 is enabled, then the hardware TEXTURE0 must be used. The
882 * hardware TEXTURE1 can ONLY be used when hardware TEXTURE0 is also used.
883 */
884
885 mmesa->tmu_source[0] = 0;
886 mmesa->tmu_source[1] = 1;
887
888 if ((ctx->Texture._EnabledUnits & 0x03) == 0x02) {
889 /* only texture 1 enabled */
890 mmesa->tmu_source[0] = 1;
891 mmesa->tmu_source[1] = 0;
892 }
893
894 for ( i = 0, ok = GL_TRUE
895 ; (i < ctx->Const.MaxTextureUnits) && ok
896 ; i++ ) {
897 ok = updateTextureUnit( ctx, i );
898 }
899
900 FALLBACK( ctx, MGA_FALLBACK_TEXTURE, !ok );
901 }