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