6b43f21cd47ef080b69d728d1f8ac30daf039e8a
[mesa.git] / src / mesa / drivers / dri / r128 / r128_texstate.c
1 /* $XFree86: xc/lib/GL/mesa/src/drv/r128/r128_texstate.c,v 1.1 2002/02/22 21:44:58 dawes Exp $ */
2 /**************************************************************************
3
4 Copyright 1999, 2000 ATI Technologies Inc. and Precision Insight, Inc.,
5 Cedar Park, Texas.
6 All Rights Reserved.
7
8 Permission is hereby granted, free of charge, to any person obtaining a
9 copy of this software and associated documentation files (the "Software"),
10 to deal in the Software without restriction, including without limitation
11 on the rights to use, copy, modify, merge, publish, distribute, sub
12 license, and/or sell copies of the Software, and to permit persons to whom
13 the Software is furnished to do so, subject to the following conditions:
14
15 The above copyright notice and this permission notice (including the next
16 paragraph) shall be included in all copies or substantial portions of the
17 Software.
18
19 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
22 ATI, PRECISION INSIGHT AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
23 DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
24 OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
25 USE OR OTHER DEALINGS IN THE SOFTWARE.
26
27 **************************************************************************/
28
29 /*
30 * Authors:
31 * Gareth Hughes <gareth@valinux.com>
32 * Kevin E. Martin <martin@valinux.com>
33 * Brian Paul <brianp@valinux.com>
34 */
35
36 #include "glheader.h"
37 #include "imports.h"
38 #include "context.h"
39 #include "macros.h"
40 #include "texformat.h"
41
42 #include "r128_context.h"
43 #include "r128_state.h"
44 #include "r128_ioctl.h"
45 #include "r128_tris.h"
46 #include "r128_tex.h"
47
48
49 static void r128SetTexImages( r128ContextPtr rmesa,
50 const struct gl_texture_object *tObj )
51 {
52 r128TexObjPtr t = (r128TexObjPtr) tObj->DriverData;
53 struct gl_texture_image *baseImage = tObj->Image[0][tObj->BaseLevel];
54 int log2Pitch, log2Height, log2Size, log2MinSize;
55 int totalSize;
56 int i;
57 GLint firstLevel, lastLevel;
58
59 assert(t);
60 assert(baseImage);
61
62 if ( R128_DEBUG & DEBUG_VERBOSE_API )
63 fprintf( stderr, "%s( %p )\n", __FUNCTION__, (void *) tObj );
64
65 switch (baseImage->TexFormat->MesaFormat) {
66 case MESA_FORMAT_ARGB8888:
67 case MESA_FORMAT_ARGB8888_REV:
68 t->textureFormat = R128_DATATYPE_ARGB8888;
69 break;
70 case MESA_FORMAT_ARGB4444:
71 case MESA_FORMAT_ARGB4444_REV:
72 t->textureFormat = R128_DATATYPE_ARGB4444;
73 break;
74 case MESA_FORMAT_RGB565:
75 case MESA_FORMAT_RGB565_REV:
76 t->textureFormat = R128_DATATYPE_RGB565;
77 break;
78 case MESA_FORMAT_RGB332:
79 t->textureFormat = R128_DATATYPE_RGB8;
80 break;
81 case MESA_FORMAT_CI8:
82 t->textureFormat = R128_DATATYPE_CI8;
83 break;
84 case MESA_FORMAT_YCBCR:
85 t->textureFormat = R128_DATATYPE_YVYU422;
86 break;
87 case MESA_FORMAT_YCBCR_REV:
88 t->textureFormat = R128_DATATYPE_VYUY422;
89 break;
90 default:
91 _mesa_problem(rmesa->glCtx, "Bad texture format in %s", __FUNCTION__);
92 };
93
94 /* Compute which mipmap levels we really want to send to the hardware.
95 */
96
97 driCalculateTextureFirstLastLevel( (driTextureObject *) t );
98 firstLevel = t->base.firstLevel;
99 lastLevel = t->base.lastLevel;
100
101 log2Pitch = tObj->Image[0][firstLevel]->WidthLog2;
102 log2Height = tObj->Image[0][firstLevel]->HeightLog2;
103 log2Size = MAX2(log2Pitch, log2Height);
104 log2MinSize = log2Size;
105
106 t->base.dirty_images[0] = 0;
107 totalSize = 0;
108 for ( i = firstLevel; i <= lastLevel; i++ ) {
109 const struct gl_texture_image *texImage;
110
111 texImage = tObj->Image[0][i];
112 if ( !texImage || !texImage->Data ) {
113 lastLevel = i - 1;
114 break;
115 }
116
117 log2MinSize = texImage->MaxLog2;
118
119 t->image[i - firstLevel].offset = totalSize;
120 t->image[i - firstLevel].width = tObj->Image[0][i]->Width;
121 t->image[i - firstLevel].height = tObj->Image[0][i]->Height;
122
123 t->base.dirty_images[0] |= (1 << i);
124
125 totalSize += (tObj->Image[0][i]->Height *
126 tObj->Image[0][i]->Width *
127 tObj->Image[0][i]->TexFormat->TexelBytes);
128
129 /* Offsets must be 32-byte aligned for host data blits and tiling */
130 totalSize = (totalSize + 31) & ~31;
131 }
132
133 t->base.totalSize = totalSize;
134 t->base.firstLevel = firstLevel;
135 t->base.lastLevel = lastLevel;
136
137 /* Set the texture format */
138 t->setup.tex_cntl &= ~(0xf << 16);
139 t->setup.tex_cntl |= t->textureFormat;
140
141 t->setup.tex_combine_cntl = 0x00000000; /* XXX is this right? */
142
143 t->setup.tex_size_pitch = ((log2Pitch << R128_TEX_PITCH_SHIFT) |
144 (log2Size << R128_TEX_SIZE_SHIFT) |
145 (log2Height << R128_TEX_HEIGHT_SHIFT) |
146 (log2MinSize << R128_TEX_MIN_SIZE_SHIFT));
147
148 for ( i = 0 ; i < R128_MAX_TEXTURE_LEVELS ; i++ ) {
149 t->setup.tex_offset[i] = 0x00000000;
150 }
151
152 if (firstLevel == lastLevel)
153 t->setup.tex_cntl |= R128_MIP_MAP_DISABLE;
154 else
155 t->setup.tex_cntl &= ~R128_MIP_MAP_DISABLE;
156
157 /* FYI: r128UploadTexImages( rmesa, t ); used to be called here */
158 }
159
160
161 /* ================================================================
162 * Texture combine functions
163 */
164
165 #define COLOR_COMB_DISABLE (R128_COMB_DIS | \
166 R128_COLOR_FACTOR_TEX)
167 #define COLOR_COMB_COPY_INPUT (R128_COMB_COPY_INP | \
168 R128_COLOR_FACTOR_TEX)
169 #define COLOR_COMB_MODULATE (R128_COMB_MODULATE | \
170 R128_COLOR_FACTOR_TEX)
171 #define COLOR_COMB_MODULATE_NTEX (R128_COMB_MODULATE | \
172 R128_COLOR_FACTOR_NTEX)
173 #define COLOR_COMB_ADD (R128_COMB_ADD | \
174 R128_COLOR_FACTOR_TEX)
175 #define COLOR_COMB_BLEND_TEX (R128_COMB_BLEND_TEXTURE | \
176 R128_COLOR_FACTOR_TEX)
177 /* Rage 128 Pro/M3 only! */
178 #define COLOR_COMB_BLEND_COLOR (R128_COMB_MODULATE2X | \
179 R128_COMB_FCN_MSB | \
180 R128_COLOR_FACTOR_CONST_COLOR)
181
182 #define ALPHA_COMB_DISABLE (R128_COMB_ALPHA_DIS | \
183 R128_ALPHA_FACTOR_TEX_ALPHA)
184 #define ALPHA_COMB_COPY_INPUT (R128_COMB_ALPHA_COPY_INP | \
185 R128_ALPHA_FACTOR_TEX_ALPHA)
186 #define ALPHA_COMB_MODULATE (R128_COMB_ALPHA_MODULATE | \
187 R128_ALPHA_FACTOR_TEX_ALPHA)
188 #define ALPHA_COMB_MODULATE_NTEX (R128_COMB_ALPHA_MODULATE | \
189 R128_ALPHA_FACTOR_NTEX_ALPHA)
190 #define ALPHA_COMB_ADD (R128_COMB_ALPHA_ADD | \
191 R128_ALPHA_FACTOR_TEX_ALPHA)
192
193 #define INPUT_INTERP (R128_INPUT_FACTOR_INT_COLOR | \
194 R128_INP_FACTOR_A_INT_ALPHA)
195 #define INPUT_PREVIOUS (R128_INPUT_FACTOR_PREV_COLOR | \
196 R128_INP_FACTOR_A_PREV_ALPHA)
197
198 static GLboolean r128UpdateTextureEnv( GLcontext *ctx, int unit )
199 {
200 r128ContextPtr rmesa = R128_CONTEXT(ctx);
201 GLint source = rmesa->tmu_source[unit];
202 const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[source];
203 const struct gl_texture_object *tObj = texUnit->_Current;
204 const GLenum format = tObj->Image[0][tObj->BaseLevel]->_BaseFormat;
205 GLuint combine;
206
207 if ( R128_DEBUG & DEBUG_VERBOSE_API ) {
208 fprintf( stderr, "%s( %p, %d )\n",
209 __FUNCTION__, (void *) ctx, unit );
210 }
211
212 if ( unit == 0 ) {
213 combine = INPUT_INTERP;
214 } else {
215 combine = INPUT_PREVIOUS;
216 }
217
218 /* Set the texture environment state */
219 switch ( texUnit->EnvMode ) {
220 case GL_REPLACE:
221 switch ( format ) {
222 case GL_RGBA:
223 case GL_LUMINANCE_ALPHA:
224 case GL_INTENSITY:
225 combine |= (COLOR_COMB_DISABLE | /* C = Ct */
226 ALPHA_COMB_DISABLE); /* A = At */
227 break;
228 case GL_RGB:
229 case GL_LUMINANCE:
230 combine |= (COLOR_COMB_DISABLE | /* C = Ct */
231 ALPHA_COMB_COPY_INPUT); /* A = Af */
232 break;
233 case GL_ALPHA:
234 combine |= (COLOR_COMB_COPY_INPUT | /* C = Cf */
235 ALPHA_COMB_DISABLE); /* A = At */
236 break;
237 case GL_COLOR_INDEX:
238 default:
239 return GL_FALSE;
240 }
241 break;
242
243 case GL_MODULATE:
244 switch ( format ) {
245 case GL_RGBA:
246 case GL_LUMINANCE_ALPHA:
247 case GL_INTENSITY:
248 combine |= (COLOR_COMB_MODULATE | /* C = CfCt */
249 ALPHA_COMB_MODULATE); /* A = AfAt */
250 break;
251 case GL_RGB:
252 case GL_LUMINANCE:
253 combine |= (COLOR_COMB_MODULATE | /* C = CfCt */
254 ALPHA_COMB_COPY_INPUT); /* A = Af */
255 break;
256 case GL_ALPHA:
257 combine |= (COLOR_COMB_COPY_INPUT | /* C = Cf */
258 ALPHA_COMB_MODULATE); /* A = AfAt */
259 break;
260 case GL_COLOR_INDEX:
261 default:
262 return GL_FALSE;
263 }
264 break;
265
266 case GL_DECAL:
267 switch ( format ) {
268 case GL_RGBA:
269 combine |= (COLOR_COMB_BLEND_TEX | /* C = Cf(1-At)+CtAt */
270 ALPHA_COMB_COPY_INPUT); /* A = Af */
271 break;
272 case GL_RGB:
273 combine |= (COLOR_COMB_DISABLE | /* C = Ct */
274 ALPHA_COMB_COPY_INPUT); /* A = Af */
275 break;
276 case GL_ALPHA:
277 case GL_LUMINANCE:
278 case GL_LUMINANCE_ALPHA:
279 case GL_INTENSITY:
280 /* Undefined behaviour - just copy the incoming fragment */
281 combine |= (COLOR_COMB_COPY_INPUT | /* C = undefined */
282 ALPHA_COMB_COPY_INPUT); /* A = undefined */
283 break;
284 case GL_COLOR_INDEX:
285 default:
286 return GL_FALSE;
287 }
288 break;
289
290 case GL_BLEND:
291 /* Rage 128 Pro and M3 can handle GL_BLEND texturing.
292 */
293 if ( !R128_IS_PLAIN( rmesa ) ) {
294 /* XXX this hasn't been fully tested, I don't have a Pro card. -BP */
295 switch ( format ) {
296 case GL_RGBA:
297 case GL_LUMINANCE_ALPHA:
298 combine |= (COLOR_COMB_BLEND_COLOR | /* C = Cf(1-Ct)+CcCt */
299 ALPHA_COMB_MODULATE); /* A = AfAt */
300 break;
301
302 case GL_RGB:
303 case GL_LUMINANCE:
304 combine |= (COLOR_COMB_BLEND_COLOR | /* C = Cf(1-Ct)+CcCt */
305 ALPHA_COMB_COPY_INPUT); /* A = Af */
306 break;
307
308 case GL_ALPHA:
309 combine |= (COLOR_COMB_COPY_INPUT | /* C = Cf */
310 ALPHA_COMB_MODULATE); /* A = AfAt */
311 break;
312
313 case GL_INTENSITY:
314 /* GH: We could be smarter about this... */
315 switch ( rmesa->env_color & 0xff000000 ) {
316 case 0x00000000:
317 combine |= (COLOR_COMB_BLEND_COLOR | /* C = Cf(1-It)+CcIt */
318 ALPHA_COMB_MODULATE_NTEX); /* A = Af(1-It) */
319 default:
320 combine |= (COLOR_COMB_MODULATE | /* C = fallback */
321 ALPHA_COMB_MODULATE); /* A = fallback */
322 return GL_FALSE;
323 }
324 break;
325
326 case GL_COLOR_INDEX:
327 default:
328 return GL_FALSE;
329 }
330 break;
331 }
332
333 /* Rage 128 has to fake some cases of GL_BLEND, otherwise fallback
334 * to software rendering.
335 */
336 if ( rmesa->blend_flags ) {
337 return GL_FALSE;
338 }
339 switch ( format ) {
340 case GL_RGBA:
341 case GL_LUMINANCE_ALPHA:
342 switch ( rmesa->env_color & 0x00ffffff ) {
343 case 0x00000000:
344 combine |= (COLOR_COMB_MODULATE_NTEX | /* C = Cf(1-Ct) */
345 ALPHA_COMB_MODULATE); /* A = AfAt */
346 break;
347 #if 0
348 /* This isn't right - BP */
349 case 0x00ffffff:
350 if ( unit == 0 ) {
351 combine |= (COLOR_COMB_MODULATE_NTEX | /* C = Cf(1-Ct) */
352 ALPHA_COMB_MODULATE); /* A = AfAt */
353 } else {
354 combine |= (COLOR_COMB_ADD | /* C = Cf+Ct */
355 ALPHA_COMB_COPY_INPUT); /* A = Af */
356 }
357 break;
358 #endif
359 default:
360 combine |= (COLOR_COMB_MODULATE | /* C = fallback */
361 ALPHA_COMB_MODULATE); /* A = fallback */
362 return GL_FALSE;
363 }
364 break;
365 case GL_RGB:
366 case GL_LUMINANCE:
367 switch ( rmesa->env_color & 0x00ffffff ) {
368 case 0x00000000:
369 combine |= (COLOR_COMB_MODULATE_NTEX | /* C = Cf(1-Ct) */
370 ALPHA_COMB_COPY_INPUT); /* A = Af */
371 break;
372 #if 0
373 /* This isn't right - BP */
374 case 0x00ffffff:
375 if ( unit == 0 ) {
376 combine |= (COLOR_COMB_MODULATE_NTEX | /* C = Cf(1-Ct) */
377 ALPHA_COMB_COPY_INPUT); /* A = Af */
378 } else {
379 combine |= (COLOR_COMB_ADD | /* C = Cf+Ct */
380 ALPHA_COMB_COPY_INPUT); /* A = Af */
381 }
382 break;
383 #endif
384 default:
385 combine |= (COLOR_COMB_MODULATE | /* C = fallback */
386 ALPHA_COMB_COPY_INPUT); /* A = fallback */
387 return GL_FALSE;
388 }
389 break;
390 case GL_ALPHA:
391 if ( unit == 0 ) {
392 combine |= (COLOR_COMB_COPY_INPUT | /* C = Cf */
393 ALPHA_COMB_MODULATE); /* A = AfAt */
394 } else {
395 combine |= (COLOR_COMB_COPY_INPUT | /* C = Cf */
396 ALPHA_COMB_COPY_INPUT); /* A = Af */
397 }
398 break;
399 case GL_INTENSITY:
400 switch ( rmesa->env_color & 0x00ffffff ) {
401 case 0x00000000:
402 combine |= COLOR_COMB_MODULATE_NTEX; /* C = Cf(1-It) */
403 break;
404 #if 0
405 /* This isn't right - BP */
406 case 0x00ffffff:
407 if ( unit == 0 ) {
408 combine |= COLOR_COMB_MODULATE_NTEX; /* C = Cf(1-It) */
409 } else {
410 combine |= COLOR_COMB_ADD; /* C = Cf+It */
411 }
412 break;
413 #endif
414 default:
415 combine |= (COLOR_COMB_MODULATE | /* C = fallback */
416 ALPHA_COMB_MODULATE); /* A = fallback */
417 return GL_FALSE;
418 }
419 switch ( rmesa->env_color & 0xff000000 ) {
420 case 0x00000000:
421 combine |= ALPHA_COMB_MODULATE_NTEX; /* A = Af(1-It) */
422 break;
423 #if 0
424 /* This isn't right - BP */
425 case 0xff000000:
426 if ( unit == 0 ) {
427 combine |= ALPHA_COMB_MODULATE_NTEX; /* A = Af(1-It) */
428 } else {
429 combine |= ALPHA_COMB_ADD; /* A = Af+It */
430 }
431 break;
432 #endif
433 default:
434 combine |= (COLOR_COMB_MODULATE | /* C = fallback */
435 ALPHA_COMB_MODULATE); /* A = fallback */
436 return GL_FALSE;
437 }
438 break;
439 case GL_COLOR_INDEX:
440 default:
441 return GL_FALSE;
442 }
443 break;
444
445 case GL_ADD:
446 switch ( format ) {
447 case GL_RGBA:
448 case GL_LUMINANCE_ALPHA:
449 combine |= (COLOR_COMB_ADD | /* C = Cf+Ct */
450 ALPHA_COMB_MODULATE); /* A = AfAt */
451 break;
452 case GL_RGB:
453 case GL_LUMINANCE:
454 combine |= (COLOR_COMB_ADD | /* C = Cf+Ct */
455 ALPHA_COMB_COPY_INPUT); /* A = Af */
456 break;
457 case GL_ALPHA:
458 combine |= (COLOR_COMB_COPY_INPUT | /* C = Cf */
459 ALPHA_COMB_MODULATE); /* A = AfAt */
460 break;
461 case GL_INTENSITY:
462 combine |= (COLOR_COMB_ADD | /* C = Cf+Ct */
463 ALPHA_COMB_ADD); /* A = Af+At */
464 break;
465 case GL_COLOR_INDEX:
466 default:
467 return GL_FALSE;
468 }
469 break;
470
471 default:
472 return GL_FALSE;
473 }
474
475 if ( rmesa->tex_combine[unit] != combine ) {
476 rmesa->tex_combine[unit] = combine;
477 rmesa->dirty |= R128_UPLOAD_TEX0 << unit;
478 }
479 return GL_TRUE;
480 }
481
482 static void disable_tex( GLcontext *ctx, int unit )
483 {
484 r128ContextPtr rmesa = R128_CONTEXT(ctx);
485
486 FLUSH_BATCH( rmesa );
487
488 if ( rmesa->CurrentTexObj[unit] ) {
489 rmesa->CurrentTexObj[unit]->base.bound &= ~(1 << unit);
490 rmesa->CurrentTexObj[unit] = NULL;
491 }
492
493 rmesa->setup.tex_cntl_c &= ~(R128_TEXMAP_ENABLE << unit);
494 rmesa->setup.tex_size_pitch_c &= ~(R128_TEX_SIZE_PITCH_MASK <<
495 (R128_SEC_TEX_SIZE_PITCH_SHIFT * unit));
496 rmesa->dirty |= R128_UPLOAD_CONTEXT;
497
498 /* If either texture unit is disabled, then multitexturing is not
499 * happening.
500 */
501
502 rmesa->blend_flags &= ~R128_BLEND_MULTITEX;
503 }
504
505 static GLboolean enable_tex_2d( GLcontext *ctx, int unit )
506 {
507 r128ContextPtr rmesa = R128_CONTEXT(ctx);
508 const int source = rmesa->tmu_source[unit];
509 const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[source];
510 const struct gl_texture_object *tObj = texUnit->_Current;
511 r128TexObjPtr t = (r128TexObjPtr) tObj->DriverData;
512
513 /* Need to load the 2d images associated with this unit.
514 */
515 if ( t->base.dirty_images[0] ) {
516 /* FIXME: For Radeon, RADEON_FIREVERTICES is called here. Should
517 * FIXME: something similar be done for R128?
518 */
519 /* FLUSH_BATCH( rmesa ); */
520
521 r128SetTexImages( rmesa, tObj );
522 r128UploadTexImages( rmesa, t );
523 if ( !t->base.memBlock )
524 return GL_FALSE;
525 }
526
527 return GL_TRUE;
528 }
529
530 static GLboolean update_tex_common( GLcontext *ctx, int unit )
531 {
532 r128ContextPtr rmesa = R128_CONTEXT(ctx);
533 const int source = rmesa->tmu_source[unit];
534 const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[source];
535 const struct gl_texture_object *tObj = texUnit->_Current;
536 r128TexObjPtr t = (r128TexObjPtr) tObj->DriverData;
537
538
539 /* Fallback if there's a texture border */
540 if ( tObj->Image[0][tObj->BaseLevel]->Border > 0 ) {
541 return GL_FALSE;
542 }
543
544
545 /* Update state if this is a different texture object to last
546 * time.
547 */
548 if ( rmesa->CurrentTexObj[unit] != t ) {
549 if ( rmesa->CurrentTexObj[unit] != NULL ) {
550 /* The old texture is no longer bound to this texture unit.
551 * Mark it as such.
552 */
553
554 rmesa->CurrentTexObj[unit]->base.bound &=
555 ~(1UL << unit);
556 }
557
558 rmesa->CurrentTexObj[unit] = t;
559 t->base.bound |= (1UL << unit);
560 rmesa->dirty |= R128_UPLOAD_TEX0 << unit;
561
562 driUpdateTextureLRU( (driTextureObject *) t ); /* XXX: should be locked! */
563 }
564
565 /* FIXME: We need to update the texture unit if any texture parameters have
566 * changed, but this texture was already bound. This could be changed to
567 * work like the Radeon driver where the texture object has it's own
568 * dirty state flags
569 */
570 rmesa->dirty |= R128_UPLOAD_TEX0 << unit;
571
572 /* register setup */
573 rmesa->setup.tex_size_pitch_c &= ~(R128_TEX_SIZE_PITCH_MASK <<
574 (R128_SEC_TEX_SIZE_PITCH_SHIFT * unit));
575
576 if ( unit == 0 ) {
577 rmesa->setup.tex_cntl_c |= R128_TEXMAP_ENABLE;
578 rmesa->setup.tex_size_pitch_c |= t->setup.tex_size_pitch << 0;
579 rmesa->setup.scale_3d_cntl &= ~R128_TEX_CACHE_SPLIT;
580 t->setup.tex_cntl &= ~R128_SEC_SELECT_SEC_ST;
581 }
582 else {
583 rmesa->setup.tex_cntl_c |= R128_SEC_TEXMAP_ENABLE;
584 rmesa->setup.tex_size_pitch_c |= t->setup.tex_size_pitch << 16;
585 rmesa->setup.scale_3d_cntl |= R128_TEX_CACHE_SPLIT;
586 t->setup.tex_cntl |= R128_SEC_SELECT_SEC_ST;
587
588 /* If the second TMU is enabled, then multitexturing is happening.
589 */
590 if ( R128_IS_PLAIN( rmesa ) )
591 rmesa->blend_flags |= R128_BLEND_MULTITEX;
592 }
593
594 rmesa->dirty |= R128_UPLOAD_CONTEXT;
595
596
597 /* FIXME: The Radeon has some cached state so that it can avoid calling
598 * FIXME: UpdateTextureEnv in some cases. Is that possible here?
599 */
600 return r128UpdateTextureEnv( ctx, unit );
601 }
602
603 static GLboolean updateTextureUnit( GLcontext *ctx, int unit )
604 {
605 r128ContextPtr rmesa = R128_CONTEXT(ctx);
606 const int source = rmesa->tmu_source[unit];
607 const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[source];
608
609
610 if (texUnit->_ReallyEnabled & (TEXTURE_1D_BIT | TEXTURE_2D_BIT)) {
611 return (enable_tex_2d( ctx, unit ) &&
612 update_tex_common( ctx, unit ));
613 }
614 else if ( texUnit->_ReallyEnabled ) {
615 return GL_FALSE;
616 }
617 else {
618 disable_tex( ctx, unit );
619 return GL_TRUE;
620 }
621 }
622
623
624 void r128UpdateTextureState( GLcontext *ctx )
625 {
626 r128ContextPtr rmesa = R128_CONTEXT(ctx);
627 GLboolean ok;
628
629
630 /* This works around a quirk with the R128 hardware. If only OpenGL
631 * TEXTURE1 is enabled, then the hardware TEXTURE0 must be used. The
632 * hardware TEXTURE1 can ONLY be used when hardware TEXTURE0 is also used.
633 */
634
635 rmesa->tmu_source[0] = 0;
636 rmesa->tmu_source[1] = 1;
637
638 if ((ctx->Texture._EnabledUnits & 0x03) == 0x02) {
639 /* only texture 1 enabled */
640 rmesa->tmu_source[0] = 1;
641 rmesa->tmu_source[1] = 0;
642 }
643
644 ok = (updateTextureUnit( ctx, 0 ) &&
645 updateTextureUnit( ctx, 1 ));
646
647 FALLBACK( rmesa, R128_FALLBACK_TEXTURE, !ok );
648 }