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