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