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