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