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