make render_quads_verts call EMIT_PRIM with the arguments in the right order,
[mesa.git] / src / mesa / drivers / dri / radeon / radeon_texstate.c
1 /* $XFree86: xc/lib/GL/mesa/src/drv/radeon/radeon_texstate.c,v 1.6 2002/12/16 16:18:59 dawes Exp $ */
2 /**************************************************************************
3
4 Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and
5 VA Linux Systems Inc., Fremont, California.
6
7 All Rights Reserved.
8
9 Permission is hereby granted, free of charge, to any person obtaining
10 a copy of this software and associated documentation files (the
11 "Software"), to deal in the Software without restriction, including
12 without limitation the rights to use, copy, modify, merge, publish,
13 distribute, sublicense, and/or sell copies of the Software, and to
14 permit persons to whom the Software is furnished to do so, subject to
15 the following conditions:
16
17 The above copyright notice and this permission notice (including the
18 next paragraph) shall be included in all copies or substantial
19 portions of the Software.
20
21 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
22 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
23 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
24 IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
25 LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
26 OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
27 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
28
29 **************************************************************************/
30
31 /*
32 * Authors:
33 * Kevin E. Martin <martin@valinux.com>
34 * Gareth Hughes <gareth@valinux.com>
35 */
36
37 #include "glheader.h"
38 #include "imports.h"
39 #include "colormac.h"
40 #include "context.h"
41 #include "macros.h"
42 #include "texformat.h"
43 #include "enums.h"
44
45 #include "radeon_context.h"
46 #include "radeon_state.h"
47 #include "radeon_ioctl.h"
48 #include "radeon_swtcl.h"
49 #include "radeon_tex.h"
50 #include "radeon_tcl.h"
51
52
53 #define RADEON_TXFORMAT_A8 RADEON_TXFORMAT_I8
54 #define RADEON_TXFORMAT_L8 RADEON_TXFORMAT_I8
55 #define RADEON_TXFORMAT_AL88 RADEON_TXFORMAT_AI88
56 #define RADEON_TXFORMAT_YCBCR RADEON_TXFORMAT_YVYU422
57 #define RADEON_TXFORMAT_YCBCR_REV RADEON_TXFORMAT_VYUY422
58 #define RADEON_TXFORMAT_RGB_DXT1 RADEON_TXFORMAT_DXT1
59 #define RADEON_TXFORMAT_RGBA_DXT1 RADEON_TXFORMAT_DXT1
60 #define RADEON_TXFORMAT_RGBA_DXT3 RADEON_TXFORMAT_DXT23
61 #define RADEON_TXFORMAT_RGBA_DXT5 RADEON_TXFORMAT_DXT45
62
63 #define _COLOR(f) \
64 [ MESA_FORMAT_ ## f ] = { RADEON_TXFORMAT_ ## f, 0 }
65 #define _COLOR_REV(f) \
66 [ MESA_FORMAT_ ## f ## _REV ] = { RADEON_TXFORMAT_ ## f, 0 }
67 #define _ALPHA(f) \
68 [ MESA_FORMAT_ ## f ] = { RADEON_TXFORMAT_ ## f | RADEON_TXFORMAT_ALPHA_IN_MAP, 0 }
69 #define _ALPHA_REV(f) \
70 [ MESA_FORMAT_ ## f ## _REV ] = { RADEON_TXFORMAT_ ## f | RADEON_TXFORMAT_ALPHA_IN_MAP, 0 }
71 #define _YUV(f) \
72 [ MESA_FORMAT_ ## f ] = { RADEON_TXFORMAT_ ## f, RADEON_YUV_TO_RGB }
73 #define _INVALID(f) \
74 [ MESA_FORMAT_ ## f ] = { 0xffffffff, 0 }
75 #define VALID_FORMAT(f) ( ((f) <= MESA_FORMAT_RGBA_DXT5) \
76 && (tx_table[f].format != 0xffffffff) )
77
78 static const struct {
79 GLuint format, filter;
80 }
81 tx_table[] =
82 {
83 _ALPHA(RGBA8888),
84 _ALPHA_REV(RGBA8888),
85 _ALPHA(ARGB8888),
86 _ALPHA_REV(ARGB8888),
87 _INVALID(RGB888),
88 _COLOR(RGB565),
89 _COLOR_REV(RGB565),
90 _ALPHA(ARGB4444),
91 _ALPHA_REV(ARGB4444),
92 _ALPHA(ARGB1555),
93 _ALPHA_REV(ARGB1555),
94 _ALPHA(AL88),
95 _ALPHA_REV(AL88),
96 _ALPHA(A8),
97 _COLOR(L8),
98 _ALPHA(I8),
99 _INVALID(CI8),
100 _YUV(YCBCR),
101 _YUV(YCBCR_REV),
102 _INVALID(RGB_FXT1),
103 _INVALID(RGBA_FXT1),
104 _COLOR(RGB_DXT1),
105 _ALPHA(RGBA_DXT1),
106 _ALPHA(RGBA_DXT3),
107 _ALPHA(RGBA_DXT5),
108 };
109
110 #undef _COLOR
111 #undef _ALPHA
112 #undef _INVALID
113
114 /**
115 * This function computes the number of bytes of storage needed for
116 * the given texture object (all mipmap levels, all cube faces).
117 * The \c image[face][level].x/y/width/height parameters for upload/blitting
118 * are computed here. \c pp_txfilter, \c pp_txformat, etc. will be set here
119 * too.
120 *
121 * \param rmesa Context pointer
122 * \param tObj GL texture object whose images are to be posted to
123 * hardware state.
124 */
125 static void radeonSetTexImages( radeonContextPtr rmesa,
126 struct gl_texture_object *tObj )
127 {
128 radeonTexObjPtr t = (radeonTexObjPtr)tObj->DriverData;
129 const struct gl_texture_image *baseImage = tObj->Image[0][tObj->BaseLevel];
130 GLint curOffset;
131 GLint i;
132 GLint numLevels;
133 GLint log2Width, log2Height, log2Depth;
134
135 /* Set the hardware texture format
136 */
137
138 t->pp_txformat &= ~(RADEON_TXFORMAT_FORMAT_MASK |
139 RADEON_TXFORMAT_ALPHA_IN_MAP);
140 t->pp_txfilter &= ~RADEON_YUV_TO_RGB;
141
142 if ( VALID_FORMAT( baseImage->TexFormat->MesaFormat ) ) {
143 t->pp_txformat |= tx_table[ baseImage->TexFormat->MesaFormat ].format;
144 t->pp_txfilter |= tx_table[ baseImage->TexFormat->MesaFormat ].filter;
145 }
146 else {
147 _mesa_problem(NULL, "unexpected texture format in %s", __FUNCTION__);
148 return;
149 }
150
151
152 /* Compute which mipmap levels we really want to send to the hardware.
153 */
154
155 driCalculateTextureFirstLastLevel( (driTextureObject *) t );
156 log2Width = tObj->Image[0][t->base.firstLevel]->WidthLog2;
157 log2Height = tObj->Image[0][t->base.firstLevel]->HeightLog2;
158 log2Depth = tObj->Image[0][t->base.firstLevel]->DepthLog2;
159
160 numLevels = t->base.lastLevel - t->base.firstLevel + 1;
161
162 assert(numLevels <= RADEON_MAX_TEXTURE_LEVELS);
163
164 /* Calculate mipmap offsets and dimensions for blitting (uploading)
165 * The idea is that we lay out the mipmap levels within a block of
166 * memory organized as a rectangle of width BLIT_WIDTH_BYTES.
167 */
168 curOffset = 0;
169
170 for (i = 0; i < numLevels; i++) {
171 const struct gl_texture_image *texImage;
172 GLuint size;
173
174 texImage = tObj->Image[0][i + t->base.firstLevel];
175 if ( !texImage )
176 break;
177
178 /* find image size in bytes */
179 if (texImage->IsCompressed) {
180 /* need to calculate the size AFTER padding even though the texture is
181 submitted without padding.
182 Only handle pot textures currently - don't know if npot is even possible,
183 size calculation would certainly need (trivial) adjustments.
184 Align (and later pad) to 32byte, not sure what that 64byte blit width is
185 good for? */
186 if ((t->pp_txformat & RADEON_TXFORMAT_FORMAT_MASK) == RADEON_TXFORMAT_DXT1) {
187 /* RGB_DXT1/RGBA_DXT1, 8 bytes per block */
188 if ((texImage->Width + 3) < 8) /* width one block */
189 size = texImage->CompressedSize * 4;
190 else if ((texImage->Width + 3) < 16)
191 size = texImage->CompressedSize * 2;
192 else size = texImage->CompressedSize;
193 }
194 else /* DXT3/5, 16 bytes per block */
195 if ((texImage->Width + 3) < 8)
196 size = texImage->CompressedSize * 2;
197 else size = texImage->CompressedSize;
198 }
199 else if (tObj->Target == GL_TEXTURE_RECTANGLE_NV) {
200 size = ((texImage->Width * texImage->TexFormat->TexelBytes + 63)
201 & ~63) * texImage->Height;
202 }
203 else {
204 int w = texImage->Width * texImage->TexFormat->TexelBytes;
205 if (w < 32)
206 w = 32;
207 size = w * texImage->Height * texImage->Depth;
208 }
209 assert(size > 0);
210
211
212 /* Align to 32-byte offset. It is faster to do this unconditionally
213 * (no branch penalty).
214 */
215
216 curOffset = (curOffset + 0x1f) & ~0x1f;
217
218 t->image[0][i].x = curOffset % BLIT_WIDTH_BYTES;
219 t->image[0][i].y = curOffset / BLIT_WIDTH_BYTES;
220 t->image[0][i].width = MIN2(size, BLIT_WIDTH_BYTES);
221 t->image[0][i].height = size / t->image[0][i].width;
222
223 #if 0
224 /* for debugging only and only applicable to non-rectangle targets */
225 assert(size % t->image[0][i].width == 0);
226 assert(t->image[0][i].x == 0
227 || (size < BLIT_WIDTH_BYTES && t->image[0][i].height == 1));
228 #endif
229
230 if (0)
231 fprintf(stderr,
232 "level %d: %dx%d x=%d y=%d w=%d h=%d size=%d at %d\n",
233 i, texImage->Width, texImage->Height,
234 t->image[0][i].x, t->image[0][i].y,
235 t->image[0][i].width, t->image[0][i].height, size, curOffset);
236
237 curOffset += size;
238
239 }
240
241 /* Align the total size of texture memory block.
242 */
243 t->base.totalSize = (curOffset + RADEON_OFFSET_MASK) & ~RADEON_OFFSET_MASK;
244
245 /* Hardware state:
246 */
247 t->pp_txfilter &= ~RADEON_MAX_MIP_LEVEL_MASK;
248 t->pp_txfilter |= (numLevels - 1) << RADEON_MAX_MIP_LEVEL_SHIFT;
249
250 t->pp_txformat &= ~(RADEON_TXFORMAT_WIDTH_MASK |
251 RADEON_TXFORMAT_HEIGHT_MASK |
252 RADEON_TXFORMAT_CUBIC_MAP_ENABLE);
253 t->pp_txformat |= ((log2Width << RADEON_TXFORMAT_WIDTH_SHIFT) |
254 (log2Height << RADEON_TXFORMAT_HEIGHT_SHIFT));
255
256 t->pp_txsize = (((tObj->Image[0][t->base.firstLevel]->Width - 1) << 0) |
257 ((tObj->Image[0][t->base.firstLevel]->Height - 1) << 16));
258
259 /* Only need to round to nearest 32 for textures, but the blitter
260 * requires 64-byte aligned pitches, and we may/may not need the
261 * blitter. NPOT only!
262 */
263 if (baseImage->IsCompressed)
264 t->pp_txpitch = (tObj->Image[0][t->base.firstLevel]->Width + 63) & ~(63);
265 else
266 t->pp_txpitch = ((tObj->Image[0][t->base.firstLevel]->Width * baseImage->TexFormat->TexelBytes) + 63) & ~(63);
267 t->pp_txpitch -= 32;
268
269 t->dirty_state = TEX_ALL;
270
271 /* FYI: radeonUploadTexImages( rmesa, t ); used to be called here */
272 }
273
274
275
276 /* ================================================================
277 * Texture combine functions
278 */
279
280 /* GL_ARB_texture_env_combine support
281 */
282
283 /* The color tables have combine functions for GL_SRC_COLOR,
284 * GL_ONE_MINUS_SRC_COLOR, GL_SRC_ALPHA and GL_ONE_MINUS_SRC_ALPHA.
285 */
286 static GLuint radeon_texture_color[][RADEON_MAX_TEXTURE_UNITS] =
287 {
288 {
289 RADEON_COLOR_ARG_A_T0_COLOR,
290 RADEON_COLOR_ARG_A_T1_COLOR,
291 RADEON_COLOR_ARG_A_T2_COLOR
292 },
293 {
294 RADEON_COLOR_ARG_A_T0_COLOR | RADEON_COMP_ARG_A,
295 RADEON_COLOR_ARG_A_T1_COLOR | RADEON_COMP_ARG_A,
296 RADEON_COLOR_ARG_A_T2_COLOR | RADEON_COMP_ARG_A
297 },
298 {
299 RADEON_COLOR_ARG_A_T0_ALPHA,
300 RADEON_COLOR_ARG_A_T1_ALPHA,
301 RADEON_COLOR_ARG_A_T2_ALPHA
302 },
303 {
304 RADEON_COLOR_ARG_A_T0_ALPHA | RADEON_COMP_ARG_A,
305 RADEON_COLOR_ARG_A_T1_ALPHA | RADEON_COMP_ARG_A,
306 RADEON_COLOR_ARG_A_T2_ALPHA | RADEON_COMP_ARG_A
307 },
308 };
309
310 static GLuint radeon_tfactor_color[] =
311 {
312 RADEON_COLOR_ARG_A_TFACTOR_COLOR,
313 RADEON_COLOR_ARG_A_TFACTOR_COLOR | RADEON_COMP_ARG_A,
314 RADEON_COLOR_ARG_A_TFACTOR_ALPHA,
315 RADEON_COLOR_ARG_A_TFACTOR_ALPHA | RADEON_COMP_ARG_A
316 };
317
318 static GLuint radeon_primary_color[] =
319 {
320 RADEON_COLOR_ARG_A_DIFFUSE_COLOR,
321 RADEON_COLOR_ARG_A_DIFFUSE_COLOR | RADEON_COMP_ARG_A,
322 RADEON_COLOR_ARG_A_DIFFUSE_ALPHA,
323 RADEON_COLOR_ARG_A_DIFFUSE_ALPHA | RADEON_COMP_ARG_A
324 };
325
326 static GLuint radeon_previous_color[] =
327 {
328 RADEON_COLOR_ARG_A_CURRENT_COLOR,
329 RADEON_COLOR_ARG_A_CURRENT_COLOR | RADEON_COMP_ARG_A,
330 RADEON_COLOR_ARG_A_CURRENT_ALPHA,
331 RADEON_COLOR_ARG_A_CURRENT_ALPHA | RADEON_COMP_ARG_A
332 };
333
334 /* GL_ZERO table - indices 0-3
335 * GL_ONE table - indices 1-4
336 */
337 static GLuint radeon_zero_color[] =
338 {
339 RADEON_COLOR_ARG_A_ZERO,
340 RADEON_COLOR_ARG_A_ZERO | RADEON_COMP_ARG_A,
341 RADEON_COLOR_ARG_A_ZERO,
342 RADEON_COLOR_ARG_A_ZERO | RADEON_COMP_ARG_A,
343 RADEON_COLOR_ARG_A_ZERO
344 };
345
346
347 /* The alpha tables only have GL_SRC_ALPHA and GL_ONE_MINUS_SRC_ALPHA.
348 */
349 static GLuint radeon_texture_alpha[][RADEON_MAX_TEXTURE_UNITS] =
350 {
351 {
352 RADEON_ALPHA_ARG_A_T0_ALPHA,
353 RADEON_ALPHA_ARG_A_T1_ALPHA,
354 RADEON_ALPHA_ARG_A_T2_ALPHA
355 },
356 {
357 RADEON_ALPHA_ARG_A_T0_ALPHA | RADEON_COMP_ARG_A,
358 RADEON_ALPHA_ARG_A_T1_ALPHA | RADEON_COMP_ARG_A,
359 RADEON_ALPHA_ARG_A_T2_ALPHA | RADEON_COMP_ARG_A
360 },
361 };
362
363 static GLuint radeon_tfactor_alpha[] =
364 {
365 RADEON_ALPHA_ARG_A_TFACTOR_ALPHA,
366 RADEON_ALPHA_ARG_A_TFACTOR_ALPHA | RADEON_COMP_ARG_A
367 };
368
369 static GLuint radeon_primary_alpha[] =
370 {
371 RADEON_ALPHA_ARG_A_DIFFUSE_ALPHA,
372 RADEON_ALPHA_ARG_A_DIFFUSE_ALPHA | RADEON_COMP_ARG_A
373 };
374
375 static GLuint radeon_previous_alpha[] =
376 {
377 RADEON_ALPHA_ARG_A_CURRENT_ALPHA,
378 RADEON_ALPHA_ARG_A_CURRENT_ALPHA | RADEON_COMP_ARG_A
379 };
380
381 /* GL_ZERO table - indices 0-1
382 * GL_ONE table - indices 1-2
383 */
384 static GLuint radeon_zero_alpha[] =
385 {
386 RADEON_ALPHA_ARG_A_ZERO,
387 RADEON_ALPHA_ARG_A_ZERO | RADEON_COMP_ARG_A,
388 RADEON_ALPHA_ARG_A_ZERO
389 };
390
391
392 /* Extract the arg from slot A, shift it into the correct argument slot
393 * and set the corresponding complement bit.
394 */
395 #define RADEON_COLOR_ARG( n, arg ) \
396 do { \
397 color_combine |= \
398 ((color_arg[n] & RADEON_COLOR_ARG_MASK) \
399 << RADEON_COLOR_ARG_##arg##_SHIFT); \
400 color_combine |= \
401 ((color_arg[n] >> RADEON_COMP_ARG_SHIFT) \
402 << RADEON_COMP_ARG_##arg##_SHIFT); \
403 } while (0)
404
405 #define RADEON_ALPHA_ARG( n, arg ) \
406 do { \
407 alpha_combine |= \
408 ((alpha_arg[n] & RADEON_ALPHA_ARG_MASK) \
409 << RADEON_ALPHA_ARG_##arg##_SHIFT); \
410 alpha_combine |= \
411 ((alpha_arg[n] >> RADEON_COMP_ARG_SHIFT) \
412 << RADEON_COMP_ARG_##arg##_SHIFT); \
413 } while (0)
414
415
416 /* ================================================================
417 * Texture unit state management
418 */
419
420 static GLboolean radeonUpdateTextureEnv( GLcontext *ctx, int unit )
421 {
422 radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
423 const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
424 GLuint color_combine, alpha_combine;
425 const GLuint color_combine0 = RADEON_COLOR_ARG_A_ZERO | RADEON_COLOR_ARG_B_ZERO
426 | RADEON_COLOR_ARG_C_CURRENT_COLOR | RADEON_BLEND_CTL_ADD
427 | RADEON_SCALE_1X | RADEON_CLAMP_TX;
428 const GLuint alpha_combine0 = RADEON_ALPHA_ARG_A_ZERO | RADEON_ALPHA_ARG_B_ZERO
429 | RADEON_ALPHA_ARG_C_CURRENT_ALPHA | RADEON_BLEND_CTL_ADD
430 | RADEON_SCALE_1X | RADEON_CLAMP_TX;
431
432
433 /* texUnit->_Current can be NULL if and only if the texture unit is
434 * not actually enabled.
435 */
436 assert( (texUnit->_ReallyEnabled == 0)
437 || (texUnit->_Current != NULL) );
438
439 if ( RADEON_DEBUG & DEBUG_TEXTURE ) {
440 fprintf( stderr, "%s( %p, %d )\n", __FUNCTION__, (void *)ctx, unit );
441 }
442
443 /* Set the texture environment state. Isn't this nice and clean?
444 * The chip will automagically set the texture alpha to 0xff when
445 * the texture format does not include an alpha component. This
446 * reduces the amount of special-casing we have to do, alpha-only
447 * textures being a notable exception.
448 */
449 /* Don't cache these results.
450 */
451 rmesa->state.texture.unit[unit].format = 0;
452 rmesa->state.texture.unit[unit].envMode = 0;
453
454 if ( !texUnit->_ReallyEnabled ) {
455 color_combine = color_combine0;
456 alpha_combine = alpha_combine0;
457 }
458 else {
459 GLuint color_arg[3], alpha_arg[3];
460 GLuint i;
461 const GLuint numColorArgs = texUnit->_CurrentCombine->_NumArgsRGB;
462 const GLuint numAlphaArgs = texUnit->_CurrentCombine->_NumArgsA;
463 GLuint RGBshift = texUnit->_CurrentCombine->ScaleShiftRGB;
464 GLuint Ashift = texUnit->_CurrentCombine->ScaleShiftA;
465
466
467 /* Step 1:
468 * Extract the color and alpha combine function arguments.
469 */
470 for ( i = 0 ; i < numColorArgs ; i++ ) {
471 const GLint op = texUnit->_CurrentCombine->OperandRGB[i] - GL_SRC_COLOR;
472 const GLuint srcRGBi = texUnit->_CurrentCombine->SourceRGB[i];
473 assert(op >= 0);
474 assert(op <= 3);
475 switch ( srcRGBi ) {
476 case GL_TEXTURE:
477 color_arg[i] = radeon_texture_color[op][unit];
478 break;
479 case GL_CONSTANT:
480 color_arg[i] = radeon_tfactor_color[op];
481 break;
482 case GL_PRIMARY_COLOR:
483 color_arg[i] = radeon_primary_color[op];
484 break;
485 case GL_PREVIOUS:
486 color_arg[i] = radeon_previous_color[op];
487 break;
488 case GL_ZERO:
489 color_arg[i] = radeon_zero_color[op];
490 break;
491 case GL_ONE:
492 color_arg[i] = radeon_zero_color[op+1];
493 break;
494 case GL_TEXTURE0:
495 case GL_TEXTURE1:
496 case GL_TEXTURE2:
497 /* implement ogl 1.4/1.5 core spec here, not specification of
498 * GL_ARB_texture_env_crossbar (which would require disabling blending
499 * instead of undefined results when referencing not enabled texunit) */
500 color_arg[i] = radeon_texture_color[op][srcRGBi - GL_TEXTURE0];
501 break;
502 default:
503 return GL_FALSE;
504 }
505 }
506
507 for ( i = 0 ; i < numAlphaArgs ; i++ ) {
508 const GLint op = texUnit->_CurrentCombine->OperandA[i] - GL_SRC_ALPHA;
509 const GLuint srcAi = texUnit->_CurrentCombine->SourceA[i];
510 assert(op >= 0);
511 assert(op <= 1);
512 switch ( srcAi ) {
513 case GL_TEXTURE:
514 alpha_arg[i] = radeon_texture_alpha[op][unit];
515 break;
516 case GL_CONSTANT:
517 alpha_arg[i] = radeon_tfactor_alpha[op];
518 break;
519 case GL_PRIMARY_COLOR:
520 alpha_arg[i] = radeon_primary_alpha[op];
521 break;
522 case GL_PREVIOUS:
523 alpha_arg[i] = radeon_previous_alpha[op];
524 break;
525 case GL_ZERO:
526 alpha_arg[i] = radeon_zero_alpha[op];
527 break;
528 case GL_ONE:
529 alpha_arg[i] = radeon_zero_alpha[op+1];
530 break;
531 case GL_TEXTURE0:
532 case GL_TEXTURE1:
533 case GL_TEXTURE2:
534 alpha_arg[i] = radeon_texture_alpha[op][srcAi - GL_TEXTURE0];
535 break;
536 default:
537 return GL_FALSE;
538 }
539 }
540
541 /* Step 2:
542 * Build up the color and alpha combine functions.
543 */
544 switch ( texUnit->_CurrentCombine->ModeRGB ) {
545 case GL_REPLACE:
546 color_combine = (RADEON_COLOR_ARG_A_ZERO |
547 RADEON_COLOR_ARG_B_ZERO |
548 RADEON_BLEND_CTL_ADD |
549 RADEON_CLAMP_TX);
550 RADEON_COLOR_ARG( 0, C );
551 break;
552 case GL_MODULATE:
553 color_combine = (RADEON_COLOR_ARG_C_ZERO |
554 RADEON_BLEND_CTL_ADD |
555 RADEON_CLAMP_TX);
556 RADEON_COLOR_ARG( 0, A );
557 RADEON_COLOR_ARG( 1, B );
558 break;
559 case GL_ADD:
560 color_combine = (RADEON_COLOR_ARG_B_ZERO |
561 RADEON_COMP_ARG_B |
562 RADEON_BLEND_CTL_ADD |
563 RADEON_CLAMP_TX);
564 RADEON_COLOR_ARG( 0, A );
565 RADEON_COLOR_ARG( 1, C );
566 break;
567 case GL_ADD_SIGNED:
568 color_combine = (RADEON_COLOR_ARG_B_ZERO |
569 RADEON_COMP_ARG_B |
570 RADEON_BLEND_CTL_ADDSIGNED |
571 RADEON_CLAMP_TX);
572 RADEON_COLOR_ARG( 0, A );
573 RADEON_COLOR_ARG( 1, C );
574 break;
575 case GL_SUBTRACT:
576 color_combine = (RADEON_COLOR_ARG_B_ZERO |
577 RADEON_COMP_ARG_B |
578 RADEON_BLEND_CTL_SUBTRACT |
579 RADEON_CLAMP_TX);
580 RADEON_COLOR_ARG( 0, A );
581 RADEON_COLOR_ARG( 1, C );
582 break;
583 case GL_INTERPOLATE:
584 color_combine = (RADEON_BLEND_CTL_BLEND |
585 RADEON_CLAMP_TX);
586 RADEON_COLOR_ARG( 0, B );
587 RADEON_COLOR_ARG( 1, A );
588 RADEON_COLOR_ARG( 2, C );
589 break;
590
591 case GL_DOT3_RGB_EXT:
592 case GL_DOT3_RGBA_EXT:
593 /* The EXT version of the DOT3 extension does not support the
594 * scale factor, but the ARB version (and the version in OpenGL
595 * 1.3) does.
596 */
597 RGBshift = 0;
598 /* FALLTHROUGH */
599
600 case GL_DOT3_RGB:
601 case GL_DOT3_RGBA:
602 /* The R100 / RV200 only support a 1X multiplier in hardware
603 * w/the ARB version.
604 */
605 if ( RGBshift != (RADEON_SCALE_1X >> RADEON_SCALE_SHIFT) ) {
606 return GL_FALSE;
607 }
608
609 RGBshift += 2;
610 if ( (texUnit->_CurrentCombine->ModeRGB == GL_DOT3_RGBA_EXT)
611 || (texUnit->_CurrentCombine->ModeRGB == GL_DOT3_RGBA) ) {
612 /* is it necessary to set this or will it be ignored anyway? */
613 Ashift = RGBshift;
614 }
615
616 color_combine = (RADEON_COLOR_ARG_C_ZERO |
617 RADEON_BLEND_CTL_DOT3 |
618 RADEON_CLAMP_TX);
619 RADEON_COLOR_ARG( 0, A );
620 RADEON_COLOR_ARG( 1, B );
621 break;
622
623 case GL_MODULATE_ADD_ATI:
624 color_combine = (RADEON_BLEND_CTL_ADD |
625 RADEON_CLAMP_TX);
626 RADEON_COLOR_ARG( 0, A );
627 RADEON_COLOR_ARG( 1, C );
628 RADEON_COLOR_ARG( 2, B );
629 break;
630 case GL_MODULATE_SIGNED_ADD_ATI:
631 color_combine = (RADEON_BLEND_CTL_ADDSIGNED |
632 RADEON_CLAMP_TX);
633 RADEON_COLOR_ARG( 0, A );
634 RADEON_COLOR_ARG( 1, C );
635 RADEON_COLOR_ARG( 2, B );
636 break;
637 case GL_MODULATE_SUBTRACT_ATI:
638 color_combine = (RADEON_BLEND_CTL_SUBTRACT |
639 RADEON_CLAMP_TX);
640 RADEON_COLOR_ARG( 0, A );
641 RADEON_COLOR_ARG( 1, C );
642 RADEON_COLOR_ARG( 2, B );
643 break;
644 default:
645 return GL_FALSE;
646 }
647
648 switch ( texUnit->_CurrentCombine->ModeA ) {
649 case GL_REPLACE:
650 alpha_combine = (RADEON_ALPHA_ARG_A_ZERO |
651 RADEON_ALPHA_ARG_B_ZERO |
652 RADEON_BLEND_CTL_ADD |
653 RADEON_CLAMP_TX);
654 RADEON_ALPHA_ARG( 0, C );
655 break;
656 case GL_MODULATE:
657 alpha_combine = (RADEON_ALPHA_ARG_C_ZERO |
658 RADEON_BLEND_CTL_ADD |
659 RADEON_CLAMP_TX);
660 RADEON_ALPHA_ARG( 0, A );
661 RADEON_ALPHA_ARG( 1, B );
662 break;
663 case GL_ADD:
664 alpha_combine = (RADEON_ALPHA_ARG_B_ZERO |
665 RADEON_COMP_ARG_B |
666 RADEON_BLEND_CTL_ADD |
667 RADEON_CLAMP_TX);
668 RADEON_ALPHA_ARG( 0, A );
669 RADEON_ALPHA_ARG( 1, C );
670 break;
671 case GL_ADD_SIGNED:
672 alpha_combine = (RADEON_ALPHA_ARG_B_ZERO |
673 RADEON_COMP_ARG_B |
674 RADEON_BLEND_CTL_ADDSIGNED |
675 RADEON_CLAMP_TX);
676 RADEON_ALPHA_ARG( 0, A );
677 RADEON_ALPHA_ARG( 1, C );
678 break;
679 case GL_SUBTRACT:
680 alpha_combine = (RADEON_COLOR_ARG_B_ZERO |
681 RADEON_COMP_ARG_B |
682 RADEON_BLEND_CTL_SUBTRACT |
683 RADEON_CLAMP_TX);
684 RADEON_ALPHA_ARG( 0, A );
685 RADEON_ALPHA_ARG( 1, C );
686 break;
687 case GL_INTERPOLATE:
688 alpha_combine = (RADEON_BLEND_CTL_BLEND |
689 RADEON_CLAMP_TX);
690 RADEON_ALPHA_ARG( 0, B );
691 RADEON_ALPHA_ARG( 1, A );
692 RADEON_ALPHA_ARG( 2, C );
693 break;
694
695 case GL_MODULATE_ADD_ATI:
696 alpha_combine = (RADEON_BLEND_CTL_ADD |
697 RADEON_CLAMP_TX);
698 RADEON_ALPHA_ARG( 0, A );
699 RADEON_ALPHA_ARG( 1, C );
700 RADEON_ALPHA_ARG( 2, B );
701 break;
702 case GL_MODULATE_SIGNED_ADD_ATI:
703 alpha_combine = (RADEON_BLEND_CTL_ADDSIGNED |
704 RADEON_CLAMP_TX);
705 RADEON_ALPHA_ARG( 0, A );
706 RADEON_ALPHA_ARG( 1, C );
707 RADEON_ALPHA_ARG( 2, B );
708 break;
709 case GL_MODULATE_SUBTRACT_ATI:
710 alpha_combine = (RADEON_BLEND_CTL_SUBTRACT |
711 RADEON_CLAMP_TX);
712 RADEON_ALPHA_ARG( 0, A );
713 RADEON_ALPHA_ARG( 1, C );
714 RADEON_ALPHA_ARG( 2, B );
715 break;
716 default:
717 return GL_FALSE;
718 }
719
720 if ( (texUnit->_CurrentCombine->ModeRGB == GL_DOT3_RGB_EXT)
721 || (texUnit->_CurrentCombine->ModeRGB == GL_DOT3_RGB) ) {
722 alpha_combine |= RADEON_DOT_ALPHA_DONT_REPLICATE;
723 }
724
725 /* Step 3:
726 * Apply the scale factor.
727 */
728 color_combine |= (RGBshift << RADEON_SCALE_SHIFT);
729 alpha_combine |= (Ashift << RADEON_SCALE_SHIFT);
730
731 /* All done!
732 */
733 }
734
735 if ( rmesa->hw.tex[unit].cmd[TEX_PP_TXCBLEND] != color_combine ||
736 rmesa->hw.tex[unit].cmd[TEX_PP_TXABLEND] != alpha_combine ) {
737 RADEON_STATECHANGE( rmesa, tex[unit] );
738 rmesa->hw.tex[unit].cmd[TEX_PP_TXCBLEND] = color_combine;
739 rmesa->hw.tex[unit].cmd[TEX_PP_TXABLEND] = alpha_combine;
740 }
741
742 return GL_TRUE;
743 }
744
745 #define TEXOBJ_TXFILTER_MASK (RADEON_MAX_MIP_LEVEL_MASK | \
746 RADEON_MIN_FILTER_MASK | \
747 RADEON_MAG_FILTER_MASK | \
748 RADEON_MAX_ANISO_MASK | \
749 RADEON_YUV_TO_RGB | \
750 RADEON_YUV_TEMPERATURE_MASK | \
751 RADEON_CLAMP_S_MASK | \
752 RADEON_CLAMP_T_MASK | \
753 RADEON_BORDER_MODE_D3D )
754
755 #define TEXOBJ_TXFORMAT_MASK (RADEON_TXFORMAT_WIDTH_MASK | \
756 RADEON_TXFORMAT_HEIGHT_MASK | \
757 RADEON_TXFORMAT_FORMAT_MASK | \
758 RADEON_TXFORMAT_F5_WIDTH_MASK | \
759 RADEON_TXFORMAT_F5_HEIGHT_MASK | \
760 RADEON_TXFORMAT_ALPHA_IN_MAP | \
761 RADEON_TXFORMAT_CUBIC_MAP_ENABLE | \
762 RADEON_TXFORMAT_NON_POWER2)
763
764
765 static void import_tex_obj_state( radeonContextPtr rmesa,
766 int unit,
767 radeonTexObjPtr texobj )
768 {
769 GLuint *cmd = RADEON_DB_STATE( tex[unit] );
770
771 cmd[TEX_PP_TXFILTER] &= ~TEXOBJ_TXFILTER_MASK;
772 cmd[TEX_PP_TXFILTER] |= texobj->pp_txfilter & TEXOBJ_TXFILTER_MASK;
773 cmd[TEX_PP_TXFORMAT] &= ~TEXOBJ_TXFORMAT_MASK;
774 cmd[TEX_PP_TXFORMAT] |= texobj->pp_txformat & TEXOBJ_TXFORMAT_MASK;
775 cmd[TEX_PP_TXOFFSET] = texobj->pp_txoffset;
776 cmd[TEX_PP_BORDER_COLOR] = texobj->pp_border_color;
777 RADEON_DB_STATECHANGE( rmesa, &rmesa->hw.tex[unit] );
778
779 if (texobj->base.tObj->Target == GL_TEXTURE_RECTANGLE_NV) {
780 GLuint *txr_cmd = RADEON_DB_STATE( txr[unit] );
781 txr_cmd[TXR_PP_TEX_SIZE] = texobj->pp_txsize; /* NPOT only! */
782 txr_cmd[TXR_PP_TEX_PITCH] = texobj->pp_txpitch; /* NPOT only! */
783 RADEON_DB_STATECHANGE( rmesa, &rmesa->hw.txr[unit] );
784 }
785
786 texobj->dirty_state &= ~(1<<unit);
787 }
788
789
790
791
792 static void set_texgen_matrix( radeonContextPtr rmesa,
793 GLuint unit,
794 const GLfloat *s_plane,
795 const GLfloat *t_plane )
796 {
797 static const GLfloat scale_identity[4] = { 1,1,1,1 };
798
799 if (!TEST_EQ_4V( s_plane, scale_identity) ||
800 !TEST_EQ_4V( t_plane, scale_identity)) {
801 rmesa->TexGenEnabled |= RADEON_TEXMAT_0_ENABLE<<unit;
802 rmesa->TexGenMatrix[unit].m[0] = s_plane[0];
803 rmesa->TexGenMatrix[unit].m[4] = s_plane[1];
804 rmesa->TexGenMatrix[unit].m[8] = s_plane[2];
805 rmesa->TexGenMatrix[unit].m[12] = s_plane[3];
806
807 rmesa->TexGenMatrix[unit].m[1] = t_plane[0];
808 rmesa->TexGenMatrix[unit].m[5] = t_plane[1];
809 rmesa->TexGenMatrix[unit].m[9] = t_plane[2];
810 rmesa->TexGenMatrix[unit].m[13] = t_plane[3];
811 rmesa->NewGLState |= _NEW_TEXTURE_MATRIX;
812 }
813 }
814
815 /* Ignoring the Q texcoord for now.
816 *
817 * Returns GL_FALSE if fallback required.
818 */
819 static GLboolean radeon_validate_texgen( GLcontext *ctx, GLuint unit )
820 {
821 radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
822 struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
823 GLuint inputshift = RADEON_TEXGEN_0_INPUT_SHIFT + unit*4;
824 GLuint tmp = rmesa->TexGenEnabled;
825
826 rmesa->TexGenEnabled &= ~(RADEON_TEXGEN_TEXMAT_0_ENABLE<<unit);
827 rmesa->TexGenEnabled &= ~(RADEON_TEXMAT_0_ENABLE<<unit);
828 rmesa->TexGenEnabled &= ~(RADEON_TEXGEN_INPUT_MASK<<inputshift);
829 rmesa->TexGenNeedNormals[unit] = 0;
830
831 if ((texUnit->TexGenEnabled & (S_BIT|T_BIT)) == 0) {
832 /* Disabled, no fallback:
833 */
834 rmesa->TexGenEnabled |=
835 (RADEON_TEXGEN_INPUT_TEXCOORD_0+unit) << inputshift;
836 return GL_TRUE;
837 }
838 else if (texUnit->TexGenEnabled & Q_BIT) {
839 /* Very easy to do this, in fact would remove a fallback case
840 * elsewhere, but I haven't done it yet... Fallback:
841 */
842 fprintf(stderr, "fallback Q_BIT\n");
843 return GL_FALSE;
844 }
845 else if ((texUnit->TexGenEnabled & (S_BIT|T_BIT)) != (S_BIT|T_BIT) ||
846 texUnit->GenModeS != texUnit->GenModeT) {
847 /* Mixed modes, fallback:
848 */
849 /* fprintf(stderr, "fallback mixed texgen\n"); */
850 return GL_FALSE;
851 }
852 else
853 rmesa->TexGenEnabled |= RADEON_TEXGEN_TEXMAT_0_ENABLE << unit;
854
855 switch (texUnit->GenModeS) {
856 case GL_OBJECT_LINEAR:
857 rmesa->TexGenEnabled |= RADEON_TEXGEN_INPUT_OBJ << inputshift;
858 set_texgen_matrix( rmesa, unit,
859 texUnit->ObjectPlaneS,
860 texUnit->ObjectPlaneT);
861 break;
862
863 case GL_EYE_LINEAR:
864 rmesa->TexGenEnabled |= RADEON_TEXGEN_INPUT_EYE << inputshift;
865 set_texgen_matrix( rmesa, unit,
866 texUnit->EyePlaneS,
867 texUnit->EyePlaneT);
868 break;
869
870 case GL_REFLECTION_MAP_NV:
871 rmesa->TexGenNeedNormals[unit] = GL_TRUE;
872 rmesa->TexGenEnabled |= RADEON_TEXGEN_INPUT_EYE_REFLECT<<inputshift;
873 break;
874
875 case GL_NORMAL_MAP_NV:
876 rmesa->TexGenNeedNormals[unit] = GL_TRUE;
877 rmesa->TexGenEnabled |= RADEON_TEXGEN_INPUT_EYE_NORMAL<<inputshift;
878 break;
879
880 case GL_SPHERE_MAP:
881 default:
882 /* Unsupported mode, fallback:
883 */
884 /* fprintf(stderr, "fallback unsupported texgen\n"); */
885 return GL_FALSE;
886 }
887
888 if (tmp != rmesa->TexGenEnabled) {
889 rmesa->NewGLState |= _NEW_TEXTURE_MATRIX;
890 }
891
892 return GL_TRUE;
893 }
894
895
896 static void disable_tex( GLcontext *ctx, int unit )
897 {
898 radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
899
900 if (rmesa->hw.ctx.cmd[CTX_PP_CNTL] & (RADEON_TEX_0_ENABLE<<unit)) {
901 /* Texture unit disabled */
902 if ( rmesa->state.texture.unit[unit].texobj != NULL ) {
903 /* The old texture is no longer bound to this texture unit.
904 * Mark it as such.
905 */
906
907 rmesa->state.texture.unit[unit].texobj->base.bound &= ~(1UL << unit);
908 rmesa->state.texture.unit[unit].texobj = NULL;
909 }
910
911 RADEON_STATECHANGE( rmesa, ctx );
912 rmesa->hw.ctx.cmd[CTX_PP_CNTL] &=
913 ~((RADEON_TEX_0_ENABLE | RADEON_TEX_BLEND_0_ENABLE) << unit);
914
915 RADEON_STATECHANGE( rmesa, tcl );
916 switch (unit) {
917 case 0:
918 rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] &= ~(RADEON_TCL_VTX_ST0 |
919 RADEON_TCL_VTX_Q0);
920 break;
921 case 1:
922 rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] &= ~(RADEON_TCL_VTX_ST1 |
923 RADEON_TCL_VTX_Q1);
924 break;
925 default:
926 break;
927 }
928
929
930 if (rmesa->TclFallback & (RADEON_TCL_FALLBACK_TEXGEN_0<<unit)) {
931 TCL_FALLBACK( ctx, (RADEON_TCL_FALLBACK_TEXGEN_0<<unit), GL_FALSE);
932 rmesa->recheck_texgen[unit] = GL_TRUE;
933 }
934
935
936
937 {
938 GLuint inputshift = RADEON_TEXGEN_0_INPUT_SHIFT + unit*4;
939 GLuint tmp = rmesa->TexGenEnabled;
940
941 rmesa->TexGenEnabled &= ~(RADEON_TEXGEN_TEXMAT_0_ENABLE<<unit);
942 rmesa->TexGenEnabled &= ~(RADEON_TEXMAT_0_ENABLE<<unit);
943 rmesa->TexGenEnabled &= ~(RADEON_TEXGEN_INPUT_MASK<<inputshift);
944 rmesa->TexGenNeedNormals[unit] = 0;
945 rmesa->TexGenEnabled |=
946 (RADEON_TEXGEN_INPUT_TEXCOORD_0+unit) << inputshift;
947
948 if (tmp != rmesa->TexGenEnabled) {
949 rmesa->recheck_texgen[unit] = GL_TRUE;
950 rmesa->NewGLState |= _NEW_TEXTURE_MATRIX;
951 }
952 }
953 }
954 }
955
956 static GLboolean enable_tex_2d( GLcontext *ctx, int unit )
957 {
958 radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
959 struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
960 struct gl_texture_object *tObj = texUnit->_Current;
961 radeonTexObjPtr t = (radeonTexObjPtr) tObj->DriverData;
962
963 /* Need to load the 2d images associated with this unit.
964 */
965 if (t->pp_txformat & RADEON_TXFORMAT_NON_POWER2) {
966 t->pp_txformat &= ~RADEON_TXFORMAT_NON_POWER2;
967 t->base.dirty_images[0] = ~0;
968 }
969
970 ASSERT(tObj->Target == GL_TEXTURE_2D || tObj->Target == GL_TEXTURE_1D);
971
972 if ( t->base.dirty_images[0] ) {
973 RADEON_FIREVERTICES( rmesa );
974 radeonSetTexImages( rmesa, tObj );
975 radeonUploadTexImages( rmesa, (radeonTexObjPtr) tObj->DriverData, 0 );
976 if ( !t->base.memBlock )
977 return GL_FALSE;
978 }
979
980 return GL_TRUE;
981 }
982
983 static GLboolean enable_tex_rect( GLcontext *ctx, int unit )
984 {
985 radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
986 struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
987 struct gl_texture_object *tObj = texUnit->_Current;
988 radeonTexObjPtr t = (radeonTexObjPtr) tObj->DriverData;
989
990 if (!(t->pp_txformat & RADEON_TXFORMAT_NON_POWER2)) {
991 t->pp_txformat |= RADEON_TXFORMAT_NON_POWER2;
992 t->base.dirty_images[0] = ~0;
993 }
994
995 ASSERT(tObj->Target == GL_TEXTURE_RECTANGLE_NV);
996
997 if ( t->base.dirty_images[0] ) {
998 RADEON_FIREVERTICES( rmesa );
999 radeonSetTexImages( rmesa, tObj );
1000 radeonUploadTexImages( rmesa, (radeonTexObjPtr) tObj->DriverData, 0 );
1001 if ( !t->base.memBlock /* && !rmesa->prefer_gart_client_texturing FIXME */ ) {
1002 fprintf(stderr, "%s: upload failed\n", __FUNCTION__);
1003 return GL_FALSE;
1004 }
1005 }
1006
1007 return GL_TRUE;
1008 }
1009
1010
1011 static GLboolean update_tex_common( GLcontext *ctx, int unit )
1012 {
1013 radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
1014 struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
1015 struct gl_texture_object *tObj = texUnit->_Current;
1016 radeonTexObjPtr t = (radeonTexObjPtr) tObj->DriverData;
1017 GLenum format;
1018
1019 /* Fallback if there's a texture border */
1020 if ( tObj->Image[0][tObj->BaseLevel]->Border > 0 ) {
1021 fprintf(stderr, "%s: border\n", __FUNCTION__);
1022 return GL_FALSE;
1023 }
1024
1025 /* Update state if this is a different texture object to last
1026 * time.
1027 */
1028 if ( rmesa->state.texture.unit[unit].texobj != t ) {
1029 if ( rmesa->state.texture.unit[unit].texobj != NULL ) {
1030 /* The old texture is no longer bound to this texture unit.
1031 * Mark it as such.
1032 */
1033
1034 rmesa->state.texture.unit[unit].texobj->base.bound &=
1035 ~(1UL << unit);
1036 }
1037
1038 rmesa->state.texture.unit[unit].texobj = t;
1039 t->base.bound |= (1UL << unit);
1040 t->dirty_state |= 1<<unit;
1041 driUpdateTextureLRU( (driTextureObject *) t ); /* XXX: should be locked! */
1042 }
1043
1044
1045 /* Newly enabled?
1046 */
1047 if ( !(rmesa->hw.ctx.cmd[CTX_PP_CNTL] & (RADEON_TEX_0_ENABLE<<unit))) {
1048 RADEON_STATECHANGE( rmesa, ctx );
1049 rmesa->hw.ctx.cmd[CTX_PP_CNTL] |=
1050 (RADEON_TEX_0_ENABLE | RADEON_TEX_BLEND_0_ENABLE) << unit;
1051
1052 RADEON_STATECHANGE( rmesa, tcl );
1053
1054 if (unit == 0)
1055 rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] |= RADEON_TCL_VTX_ST0;
1056 else
1057 rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] |= RADEON_TCL_VTX_ST1;
1058
1059 rmesa->recheck_texgen[unit] = GL_TRUE;
1060 }
1061
1062 if (t->dirty_state & (1<<unit)) {
1063 import_tex_obj_state( rmesa, unit, t );
1064 }
1065
1066 if (rmesa->recheck_texgen[unit]) {
1067 GLboolean fallback = !radeon_validate_texgen( ctx, unit );
1068 TCL_FALLBACK( ctx, (RADEON_TCL_FALLBACK_TEXGEN_0<<unit), fallback);
1069 rmesa->recheck_texgen[unit] = 0;
1070 rmesa->NewGLState |= _NEW_TEXTURE_MATRIX;
1071 }
1072
1073 format = tObj->Image[0][tObj->BaseLevel]->Format;
1074 if ( rmesa->state.texture.unit[unit].format != format ||
1075 rmesa->state.texture.unit[unit].envMode != texUnit->EnvMode ) {
1076 rmesa->state.texture.unit[unit].format = format;
1077 rmesa->state.texture.unit[unit].envMode = texUnit->EnvMode;
1078 if ( ! radeonUpdateTextureEnv( ctx, unit ) ) {
1079 return GL_FALSE;
1080 }
1081 }
1082
1083 FALLBACK( rmesa, RADEON_FALLBACK_BORDER_MODE, t->border_fallback );
1084 return !t->border_fallback;
1085 }
1086
1087
1088
1089 static GLboolean radeonUpdateTextureUnit( GLcontext *ctx, int unit )
1090 {
1091 struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
1092
1093 TCL_FALLBACK( ctx, RADEON_TCL_FALLBACK_TEXRECT_0 << unit, 0 );
1094
1095 if ( texUnit->_ReallyEnabled & (TEXTURE_RECT_BIT) ) {
1096 TCL_FALLBACK( ctx, RADEON_TCL_FALLBACK_TEXRECT_0 << unit, 1 );
1097
1098 return (enable_tex_rect( ctx, unit ) &&
1099 update_tex_common( ctx, unit ));
1100 }
1101 else if ( texUnit->_ReallyEnabled & (TEXTURE_1D_BIT | TEXTURE_2D_BIT) ) {
1102 return (enable_tex_2d( ctx, unit ) &&
1103 update_tex_common( ctx, unit ));
1104 }
1105 else if ( texUnit->_ReallyEnabled ) {
1106 return GL_FALSE;
1107 }
1108 else {
1109 disable_tex( ctx, unit );
1110 return GL_TRUE;
1111 }
1112 }
1113
1114 void radeonUpdateTextureState( GLcontext *ctx )
1115 {
1116 radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
1117 GLboolean ok;
1118
1119 ok = (radeonUpdateTextureUnit( ctx, 0 ) &&
1120 radeonUpdateTextureUnit( ctx, 1 ));
1121
1122 FALLBACK( rmesa, RADEON_FALLBACK_TEXTURE, !ok );
1123
1124 if (rmesa->TclFallback)
1125 radeonChooseVertexState( ctx );
1126 }