1 /* $XFree86: xc/lib/GL/mesa/src/drv/radeon/radeon_texstate.c,v 1.6 2002/12/16 16:18:59 dawes Exp $ */
2 /**************************************************************************
4 Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and
5 VA Linux Systems Inc., Fremont, California.
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:
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.
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.
29 **************************************************************************/
33 * Kevin E. Martin <martin@valinux.com>
34 * Gareth Hughes <gareth@valinux.com>
42 #include "texformat.h"
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"
53 #define RADEON_TXFORMAT_AL88 RADEON_TXFORMAT_AI88
54 #define RADEON_TXFORMAT_YCBCR RADEON_TXFORMAT_YVYU422
55 #define RADEON_TXFORMAT_YCBCR_REV RADEON_TXFORMAT_VYUY422
58 [ MESA_FORMAT_ ## f ] = { RADEON_TXFORMAT_ ## f, 0 }
60 [ MESA_FORMAT_ ## f ] = { RADEON_TXFORMAT_ ## f | RADEON_TXFORMAT_ALPHA_IN_MAP, 0 }
62 [ MESA_FORMAT_ ## f ] = { RADEON_TXFORMAT_ ## f, RADEON_YUV_TO_RGB }
64 [ MESA_FORMAT_ ## f ] = { 0xffffffff, 0 }
65 #define VALID_FORMAT(f) ( ((f) <= MESA_FORMAT_YCBCR_REV) \
66 && (tx_table[f].format != 0xffffffff) )
69 GLuint format
, filter
;
93 * This function computes the number of bytes of storage needed for
94 * the given texture object (all mipmap levels, all cube faces).
95 * The \c image[face][level].x/y/width/height parameters for upload/blitting
96 * are computed here. \c pp_txfilter, \c pp_txformat, etc. will be set here
99 * \param rmesa Context pointer
100 * \param tObj GL texture object whose images are to be posted to
103 static void radeonSetTexImages( radeonContextPtr rmesa
,
104 struct gl_texture_object
*tObj
)
106 radeonTexObjPtr t
= (radeonTexObjPtr
)tObj
->DriverData
;
107 const struct gl_texture_image
*baseImage
= tObj
->Image
[tObj
->BaseLevel
];
110 GLint firstLevel
=0, lastLevel
=0, numLevels
;
111 GLint log2Width
, log2Height
, log2Depth
;
113 /* Set the hardware texture format
116 t
->pp_txformat
&= ~(RADEON_TXFORMAT_FORMAT_MASK
|
117 RADEON_TXFORMAT_ALPHA_IN_MAP
);
118 t
->pp_txfilter
&= ~RADEON_YUV_TO_RGB
;
120 if ( VALID_FORMAT( baseImage
->TexFormat
->MesaFormat
) ) {
121 t
->pp_txformat
|= tx_table
[ baseImage
->TexFormat
->MesaFormat
].format
;
122 t
->pp_txfilter
|= tx_table
[ baseImage
->TexFormat
->MesaFormat
].filter
;
125 _mesa_problem(NULL
, "unexpected texture format in %s", __FUNCTION__
);
131 /* Compute which mipmap levels we really want to send to the hardware.
132 * This depends on the base image size, GL_TEXTURE_MIN_LOD,
133 * GL_TEXTURE_MAX_LOD, GL_TEXTURE_BASE_LEVEL, and GL_TEXTURE_MAX_LEVEL.
134 * Yes, this looks overly complicated, but it's all needed.
136 switch (tObj
->Target
) {
139 firstLevel
= tObj
->BaseLevel
+ (GLint
)(tObj
->MinLod
+ 0.5);
140 firstLevel
= MAX2(firstLevel
, tObj
->BaseLevel
);
141 lastLevel
= tObj
->BaseLevel
+ (GLint
)(tObj
->MaxLod
+ 0.5);
142 lastLevel
= MAX2(lastLevel
, tObj
->BaseLevel
);
143 lastLevel
= MIN2(lastLevel
, tObj
->BaseLevel
+ baseImage
->MaxLog2
);
144 lastLevel
= MIN2(lastLevel
, tObj
->MaxLevel
);
145 lastLevel
= MAX2(firstLevel
, lastLevel
); /* need at least one level */
146 log2Width
= tObj
->Image
[firstLevel
]->WidthLog2
;
147 log2Height
= tObj
->Image
[firstLevel
]->HeightLog2
;
150 case GL_TEXTURE_RECTANGLE_NV
:
151 firstLevel
= lastLevel
= 0;
152 log2Width
= log2Height
= 1; /* ? */
159 /* save these values */
160 t
->base
.firstLevel
= firstLevel
;
161 t
->base
.lastLevel
= lastLevel
;
163 numLevels
= lastLevel
- firstLevel
+ 1;
165 assert(numLevels
<= RADEON_MAX_TEXTURE_LEVELS
);
167 /* Calculate mipmap offsets and dimensions for blitting (uploading)
168 * The idea is that we lay out the mipmap levels within a block of
169 * memory organized as a rectangle of width BLIT_WIDTH_BYTES.
173 for (i
= 0; i
< numLevels
; i
++) {
174 const struct gl_texture_image
*texImage
;
177 texImage
= tObj
->Image
[i
+ firstLevel
];
181 /* find image size in bytes */
182 if (texImage
->IsCompressed
) {
183 size
= texImage
->CompressedSize
;
185 else if (tObj
->Target
== GL_TEXTURE_RECTANGLE_NV
) {
186 size
= ((texImage
->Width
* texImage
->TexFormat
->TexelBytes
+ 63)
187 & ~63) * texImage
->Height
;
190 int w
= texImage
->Width
* texImage
->TexFormat
->TexelBytes
;
193 size
= w
* texImage
->Height
* texImage
->Depth
;
197 if (curOffset
& 0x1f) {
198 /* align to 32-byte offset */
199 curOffset
= (curOffset
+ 0x1f) & ~0x1f;
202 t
->image
[0][i
].x
= curOffset
% BLIT_WIDTH_BYTES
;
203 t
->image
[0][i
].y
= curOffset
/ BLIT_WIDTH_BYTES
;
204 t
->image
[0][i
].width
= MIN2(size
, BLIT_WIDTH_BYTES
);
205 t
->image
[0][i
].height
= size
/ t
->image
[0][i
].width
;
208 /* for debugging only and only applicable to non-rectangle targets */
209 assert(size
% t
->image
[0][i
].width
== 0);
210 assert(t
->image
[0][i
].x
== 0
211 || (size
< BLIT_WIDTH_BYTES
&& t
->image
[0][i
].height
== 1));
216 "level %d: %dx%d x=%d y=%d w=%d h=%d size=%d at %d\n",
217 i
, texImage
->Width
, texImage
->Height
,
218 t
->image
[0][i
].x
, t
->image
[0][i
].y
,
219 t
->image
[0][i
].width
, t
->image
[0][i
].height
, size
, curOffset
);
225 /* Align the total size of texture memory block.
227 t
->base
.totalSize
= (curOffset
+ RADEON_OFFSET_MASK
) & ~RADEON_OFFSET_MASK
;
231 t
->pp_txfilter
&= ~RADEON_MAX_MIP_LEVEL_MASK
;
232 t
->pp_txfilter
|= (numLevels
- 1) << RADEON_MAX_MIP_LEVEL_SHIFT
;
234 t
->pp_txformat
&= ~(RADEON_TXFORMAT_WIDTH_MASK
|
235 RADEON_TXFORMAT_HEIGHT_MASK
|
236 RADEON_TXFORMAT_CUBIC_MAP_ENABLE
);
237 t
->pp_txformat
|= ((log2Width
<< RADEON_TXFORMAT_WIDTH_SHIFT
) |
238 (log2Height
<< RADEON_TXFORMAT_HEIGHT_SHIFT
));
240 t
->pp_txsize
= (((tObj
->Image
[firstLevel
]->Width
- 1) << 0) |
241 ((tObj
->Image
[firstLevel
]->Height
- 1) << 16));
243 /* Only need to round to nearest 32 for textures, but the blitter
244 * requires 64-byte aligned pitches, and we may/may not need the
245 * blitter. NPOT only!
247 if (baseImage
->IsCompressed
)
248 t
->pp_txpitch
= (tObj
->Image
[firstLevel
]->Width
+ 63) & ~(63);
250 t
->pp_txpitch
= ((tObj
->Image
[firstLevel
]->Width
* baseImage
->TexFormat
->TexelBytes
) + 63) & ~(63);
253 t
->dirty_state
= TEX_ALL
;
255 /* FYI: radeonUploadTexImages( rmesa, t ); used to be called here */
260 /* ================================================================
261 * Texture combine functions
264 #define RADEON_DISABLE 0
265 #define RADEON_REPLACE 1
266 #define RADEON_MODULATE 2
267 #define RADEON_DECAL 3
268 #define RADEON_BLEND 4
270 #define RADEON_MAX_COMBFUNC 6
272 static GLuint radeon_color_combine
[][RADEON_MAX_COMBFUNC
] =
277 /* Disable combiner stage
279 (RADEON_COLOR_ARG_A_ZERO
|
280 RADEON_COLOR_ARG_B_ZERO
|
281 RADEON_COLOR_ARG_C_CURRENT_COLOR
|
282 RADEON_BLEND_CTL_ADD
|
286 /* GL_REPLACE = 0x00802800
288 (RADEON_COLOR_ARG_A_ZERO
|
289 RADEON_COLOR_ARG_B_ZERO
|
290 RADEON_COLOR_ARG_C_T0_COLOR
|
291 RADEON_BLEND_CTL_ADD
|
295 /* GL_MODULATE = 0x00800142
297 (RADEON_COLOR_ARG_A_CURRENT_COLOR
|
298 RADEON_COLOR_ARG_B_T0_COLOR
|
299 RADEON_COLOR_ARG_C_ZERO
|
300 RADEON_BLEND_CTL_ADD
|
304 /* GL_DECAL = 0x008c2d42
306 (RADEON_COLOR_ARG_A_CURRENT_COLOR
|
307 RADEON_COLOR_ARG_B_T0_COLOR
|
308 RADEON_COLOR_ARG_C_T0_ALPHA
|
309 RADEON_BLEND_CTL_BLEND
|
313 /* GL_BLEND = 0x008c2902
315 (RADEON_COLOR_ARG_A_CURRENT_COLOR
|
316 RADEON_COLOR_ARG_B_TFACTOR_COLOR
|
317 RADEON_COLOR_ARG_C_T0_COLOR
|
318 RADEON_BLEND_CTL_BLEND
|
322 /* GL_ADD = 0x00812802
324 (RADEON_COLOR_ARG_A_CURRENT_COLOR
|
325 RADEON_COLOR_ARG_B_ZERO
|
326 RADEON_COLOR_ARG_C_T0_COLOR
|
328 RADEON_BLEND_CTL_ADD
|
336 /* Disable combiner stage
338 (RADEON_COLOR_ARG_A_ZERO
|
339 RADEON_COLOR_ARG_B_ZERO
|
340 RADEON_COLOR_ARG_C_CURRENT_COLOR
|
341 RADEON_BLEND_CTL_ADD
|
345 /* GL_REPLACE = 0x00803000
347 (RADEON_COLOR_ARG_A_ZERO
|
348 RADEON_COLOR_ARG_B_ZERO
|
349 RADEON_COLOR_ARG_C_T1_COLOR
|
350 RADEON_BLEND_CTL_ADD
|
354 /* GL_MODULATE = 0x00800182
356 (RADEON_COLOR_ARG_A_CURRENT_COLOR
|
357 RADEON_COLOR_ARG_B_T1_COLOR
|
358 RADEON_COLOR_ARG_C_ZERO
|
359 RADEON_BLEND_CTL_ADD
|
363 /* GL_DECAL = 0x008c3582
365 (RADEON_COLOR_ARG_A_CURRENT_COLOR
|
366 RADEON_COLOR_ARG_B_T1_COLOR
|
367 RADEON_COLOR_ARG_C_T1_ALPHA
|
368 RADEON_BLEND_CTL_BLEND
|
372 /* GL_BLEND = 0x008c3102
374 (RADEON_COLOR_ARG_A_CURRENT_COLOR
|
375 RADEON_COLOR_ARG_B_TFACTOR_COLOR
|
376 RADEON_COLOR_ARG_C_T1_COLOR
|
377 RADEON_BLEND_CTL_BLEND
|
381 /* GL_ADD = 0x00813002
383 (RADEON_COLOR_ARG_A_CURRENT_COLOR
|
384 RADEON_COLOR_ARG_B_ZERO
|
385 RADEON_COLOR_ARG_C_T1_COLOR
|
387 RADEON_BLEND_CTL_ADD
|
395 /* Disable combiner stage
397 (RADEON_COLOR_ARG_A_ZERO
|
398 RADEON_COLOR_ARG_B_ZERO
|
399 RADEON_COLOR_ARG_C_CURRENT_COLOR
|
400 RADEON_BLEND_CTL_ADD
|
404 /* GL_REPLACE = 0x00803800
406 (RADEON_COLOR_ARG_A_ZERO
|
407 RADEON_COLOR_ARG_B_ZERO
|
408 RADEON_COLOR_ARG_C_T2_COLOR
|
409 RADEON_BLEND_CTL_ADD
|
413 /* GL_MODULATE = 0x008001c2
415 (RADEON_COLOR_ARG_A_CURRENT_COLOR
|
416 RADEON_COLOR_ARG_B_T2_COLOR
|
417 RADEON_COLOR_ARG_C_ZERO
|
418 RADEON_BLEND_CTL_ADD
|
422 /* GL_DECAL = 0x008c3dc2
424 (RADEON_COLOR_ARG_A_CURRENT_COLOR
|
425 RADEON_COLOR_ARG_B_T2_COLOR
|
426 RADEON_COLOR_ARG_C_T2_ALPHA
|
427 RADEON_BLEND_CTL_BLEND
|
431 /* GL_BLEND = 0x008c3902
433 (RADEON_COLOR_ARG_A_CURRENT_COLOR
|
434 RADEON_COLOR_ARG_B_TFACTOR_COLOR
|
435 RADEON_COLOR_ARG_C_T2_COLOR
|
436 RADEON_BLEND_CTL_BLEND
|
440 /* GL_ADD = 0x00813802
442 (RADEON_COLOR_ARG_A_CURRENT_COLOR
|
443 RADEON_COLOR_ARG_B_ZERO
|
444 RADEON_COLOR_ARG_C_T2_COLOR
|
446 RADEON_BLEND_CTL_ADD
|
452 static GLuint radeon_alpha_combine
[][RADEON_MAX_COMBFUNC
] =
457 /* Disable combiner stage
459 (RADEON_ALPHA_ARG_A_ZERO
|
460 RADEON_ALPHA_ARG_B_ZERO
|
461 RADEON_ALPHA_ARG_C_CURRENT_ALPHA
|
462 RADEON_BLEND_CTL_ADD
|
466 /* GL_REPLACE = 0x00800500
468 (RADEON_ALPHA_ARG_A_ZERO
|
469 RADEON_ALPHA_ARG_B_ZERO
|
470 RADEON_ALPHA_ARG_C_T0_ALPHA
|
471 RADEON_BLEND_CTL_ADD
|
475 /* GL_MODULATE = 0x00800051
477 (RADEON_ALPHA_ARG_A_CURRENT_ALPHA
|
478 RADEON_ALPHA_ARG_B_T0_ALPHA
|
479 RADEON_ALPHA_ARG_C_ZERO
|
480 RADEON_BLEND_CTL_ADD
|
484 /* GL_DECAL = 0x00800100
486 (RADEON_ALPHA_ARG_A_ZERO
|
487 RADEON_ALPHA_ARG_B_ZERO
|
488 RADEON_ALPHA_ARG_C_CURRENT_ALPHA
|
489 RADEON_BLEND_CTL_ADD
|
493 /* GL_BLEND = 0x00800051
495 (RADEON_ALPHA_ARG_A_CURRENT_ALPHA
|
496 RADEON_ALPHA_ARG_B_TFACTOR_ALPHA
|
497 RADEON_ALPHA_ARG_C_T0_ALPHA
|
498 RADEON_BLEND_CTL_BLEND
|
502 /* GL_ADD = 0x00800051
504 (RADEON_ALPHA_ARG_A_CURRENT_ALPHA
|
505 RADEON_ALPHA_ARG_B_ZERO
|
506 RADEON_ALPHA_ARG_C_T0_ALPHA
|
508 RADEON_BLEND_CTL_ADD
|
516 /* Disable combiner stage
518 (RADEON_ALPHA_ARG_A_ZERO
|
519 RADEON_ALPHA_ARG_B_ZERO
|
520 RADEON_ALPHA_ARG_C_CURRENT_ALPHA
|
521 RADEON_BLEND_CTL_ADD
|
525 /* GL_REPLACE = 0x00800600
527 (RADEON_ALPHA_ARG_A_ZERO
|
528 RADEON_ALPHA_ARG_B_ZERO
|
529 RADEON_ALPHA_ARG_C_T1_ALPHA
|
530 RADEON_BLEND_CTL_ADD
|
534 /* GL_MODULATE = 0x00800061
536 (RADEON_ALPHA_ARG_A_CURRENT_ALPHA
|
537 RADEON_ALPHA_ARG_B_T1_ALPHA
|
538 RADEON_ALPHA_ARG_C_ZERO
|
539 RADEON_BLEND_CTL_ADD
|
543 /* GL_DECAL = 0x00800100
545 (RADEON_ALPHA_ARG_A_ZERO
|
546 RADEON_ALPHA_ARG_B_ZERO
|
547 RADEON_ALPHA_ARG_C_CURRENT_ALPHA
|
548 RADEON_BLEND_CTL_ADD
|
552 /* GL_BLEND = 0x00800061
554 (RADEON_ALPHA_ARG_A_CURRENT_ALPHA
|
555 RADEON_ALPHA_ARG_B_TFACTOR_ALPHA
|
556 RADEON_ALPHA_ARG_C_T1_ALPHA
|
557 RADEON_BLEND_CTL_BLEND
|
561 /* GL_ADD = 0x00800061
563 (RADEON_ALPHA_ARG_A_CURRENT_ALPHA
|
564 RADEON_ALPHA_ARG_B_ZERO
|
565 RADEON_ALPHA_ARG_C_T1_ALPHA
|
567 RADEON_BLEND_CTL_ADD
|
575 /* Disable combiner stage
577 (RADEON_ALPHA_ARG_A_ZERO
|
578 RADEON_ALPHA_ARG_B_ZERO
|
579 RADEON_ALPHA_ARG_C_CURRENT_ALPHA
|
580 RADEON_BLEND_CTL_ADD
|
584 /* GL_REPLACE = 0x00800700
586 (RADEON_ALPHA_ARG_A_ZERO
|
587 RADEON_ALPHA_ARG_B_ZERO
|
588 RADEON_ALPHA_ARG_C_T2_ALPHA
|
589 RADEON_BLEND_CTL_ADD
|
593 /* GL_MODULATE = 0x00800071
595 (RADEON_ALPHA_ARG_A_CURRENT_ALPHA
|
596 RADEON_ALPHA_ARG_B_T2_ALPHA
|
597 RADEON_ALPHA_ARG_C_ZERO
|
598 RADEON_BLEND_CTL_ADD
|
602 /* GL_DECAL = 0x00800100
604 (RADEON_ALPHA_ARG_A_ZERO
|
605 RADEON_ALPHA_ARG_B_ZERO
|
606 RADEON_ALPHA_ARG_C_CURRENT_ALPHA
|
607 RADEON_BLEND_CTL_ADD
|
611 /* GL_BLEND = 0x00800071
613 (RADEON_ALPHA_ARG_A_CURRENT_ALPHA
|
614 RADEON_ALPHA_ARG_B_TFACTOR_ALPHA
|
615 RADEON_ALPHA_ARG_C_T2_ALPHA
|
616 RADEON_BLEND_CTL_BLEND
|
620 /* GL_ADD = 0x00800021
622 (RADEON_ALPHA_ARG_A_CURRENT_ALPHA
|
623 RADEON_ALPHA_ARG_B_ZERO
|
624 RADEON_ALPHA_ARG_C_T2_ALPHA
|
626 RADEON_BLEND_CTL_ADD
|
633 /* GL_ARB_texture_env_combine support
636 /* The color tables have combine functions for GL_SRC_COLOR,
637 * GL_ONE_MINUS_SRC_COLOR, GL_SRC_ALPHA and GL_ONE_MINUS_SRC_ALPHA.
639 static GLuint radeon_texture_color
[][RADEON_MAX_TEXTURE_UNITS
] =
642 RADEON_COLOR_ARG_A_T0_COLOR
,
643 RADEON_COLOR_ARG_A_T1_COLOR
,
644 RADEON_COLOR_ARG_A_T2_COLOR
647 RADEON_COLOR_ARG_A_T0_COLOR
| RADEON_COMP_ARG_A
,
648 RADEON_COLOR_ARG_A_T1_COLOR
| RADEON_COMP_ARG_A
,
649 RADEON_COLOR_ARG_A_T2_COLOR
| RADEON_COMP_ARG_A
652 RADEON_COLOR_ARG_A_T0_ALPHA
,
653 RADEON_COLOR_ARG_A_T1_ALPHA
,
654 RADEON_COLOR_ARG_A_T2_ALPHA
657 RADEON_COLOR_ARG_A_T0_ALPHA
| RADEON_COMP_ARG_A
,
658 RADEON_COLOR_ARG_A_T1_ALPHA
| RADEON_COMP_ARG_A
,
659 RADEON_COLOR_ARG_A_T2_ALPHA
| RADEON_COMP_ARG_A
663 static GLuint radeon_tfactor_color
[] =
665 RADEON_COLOR_ARG_A_TFACTOR_COLOR
,
666 RADEON_COLOR_ARG_A_TFACTOR_COLOR
| RADEON_COMP_ARG_A
,
667 RADEON_COLOR_ARG_A_TFACTOR_ALPHA
,
668 RADEON_COLOR_ARG_A_TFACTOR_ALPHA
| RADEON_COMP_ARG_A
671 static GLuint radeon_primary_color
[] =
673 RADEON_COLOR_ARG_A_DIFFUSE_COLOR
,
674 RADEON_COLOR_ARG_A_DIFFUSE_COLOR
| RADEON_COMP_ARG_A
,
675 RADEON_COLOR_ARG_A_DIFFUSE_ALPHA
,
676 RADEON_COLOR_ARG_A_DIFFUSE_ALPHA
| RADEON_COMP_ARG_A
679 static GLuint radeon_previous_color
[] =
681 RADEON_COLOR_ARG_A_CURRENT_COLOR
,
682 RADEON_COLOR_ARG_A_CURRENT_COLOR
| RADEON_COMP_ARG_A
,
683 RADEON_COLOR_ARG_A_CURRENT_ALPHA
,
684 RADEON_COLOR_ARG_A_CURRENT_ALPHA
| RADEON_COMP_ARG_A
687 /* GL_ZERO table - indices 0-3
688 * GL_ONE table - indices 1-4
690 static GLuint radeon_zero_color
[] =
692 RADEON_COLOR_ARG_A_ZERO
,
693 RADEON_COLOR_ARG_A_ZERO
| RADEON_COMP_ARG_A
,
694 RADEON_COLOR_ARG_A_ZERO
,
695 RADEON_COLOR_ARG_A_ZERO
| RADEON_COMP_ARG_A
,
696 RADEON_COLOR_ARG_A_ZERO
700 /* The alpha tables only have GL_SRC_ALPHA and GL_ONE_MINUS_SRC_ALPHA.
702 static GLuint radeon_texture_alpha
[][RADEON_MAX_TEXTURE_UNITS
] =
705 RADEON_ALPHA_ARG_A_T0_ALPHA
,
706 RADEON_ALPHA_ARG_A_T1_ALPHA
,
707 RADEON_ALPHA_ARG_A_T2_ALPHA
710 RADEON_ALPHA_ARG_A_T0_ALPHA
| RADEON_COMP_ARG_A
,
711 RADEON_ALPHA_ARG_A_T1_ALPHA
| RADEON_COMP_ARG_A
,
712 RADEON_ALPHA_ARG_A_T2_ALPHA
| RADEON_COMP_ARG_A
716 static GLuint radeon_tfactor_alpha
[] =
718 RADEON_ALPHA_ARG_A_TFACTOR_ALPHA
,
719 RADEON_ALPHA_ARG_A_TFACTOR_ALPHA
| RADEON_COMP_ARG_A
722 static GLuint radeon_primary_alpha
[] =
724 RADEON_ALPHA_ARG_A_DIFFUSE_ALPHA
,
725 RADEON_ALPHA_ARG_A_DIFFUSE_ALPHA
| RADEON_COMP_ARG_A
728 static GLuint radeon_previous_alpha
[] =
730 RADEON_ALPHA_ARG_A_CURRENT_ALPHA
,
731 RADEON_ALPHA_ARG_A_CURRENT_ALPHA
| RADEON_COMP_ARG_A
734 /* GL_ZERO table - indices 0-1
735 * GL_ONE table - indices 1-2
737 static GLuint radeon_zero_alpha
[] =
739 RADEON_ALPHA_ARG_A_ZERO
,
740 RADEON_ALPHA_ARG_A_ZERO
| RADEON_COMP_ARG_A
,
741 RADEON_ALPHA_ARG_A_ZERO
745 /* Extract the arg from slot A, shift it into the correct argument slot
746 * and set the corresponding complement bit.
748 #define RADEON_COLOR_ARG( n, arg ) \
751 ((color_arg[n] & RADEON_COLOR_ARG_MASK) \
752 << RADEON_COLOR_ARG_##arg##_SHIFT); \
754 ((color_arg[n] >> RADEON_COMP_ARG_SHIFT) \
755 << RADEON_COMP_ARG_##arg##_SHIFT); \
758 #define RADEON_ALPHA_ARG( n, arg ) \
761 ((alpha_arg[n] & RADEON_ALPHA_ARG_MASK) \
762 << RADEON_ALPHA_ARG_##arg##_SHIFT); \
764 ((alpha_arg[n] >> RADEON_COMP_ARG_SHIFT) \
765 << RADEON_COMP_ARG_##arg##_SHIFT); \
769 /* ================================================================
770 * Texture unit state management
773 static GLboolean
radeonUpdateTextureEnv( GLcontext
*ctx
, int unit
)
775 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
776 const struct gl_texture_unit
*texUnit
= &ctx
->Texture
.Unit
[unit
];
777 GLuint color_combine
, alpha_combine
;
779 /* texUnit->_Current can be NULL if and only if the texture unit is
780 * not actually enabled.
782 assert( (texUnit
->_ReallyEnabled
== 0)
783 || (texUnit
->_Current
!= NULL
) );
785 if ( RADEON_DEBUG
& DEBUG_TEXTURE
) {
786 fprintf( stderr
, "%s( %p, %d )\n", __FUNCTION__
, ctx
, unit
);
789 /* Set the texture environment state. Isn't this nice and clean?
790 * The chip will automagically set the texture alpha to 0xff when
791 * the texture format does not include an alpha component. This
792 * reduces the amount of special-casing we have to do, alpha-only
793 * textures being a notable exception.
795 if ( !texUnit
->_ReallyEnabled
) {
796 /* Don't cache these results.
798 rmesa
->state
.texture
.unit
[unit
].format
= 0;
799 rmesa
->state
.texture
.unit
[unit
].envMode
= 0;
800 color_combine
= radeon_color_combine
[unit
][RADEON_DISABLE
];
801 alpha_combine
= radeon_alpha_combine
[unit
][RADEON_DISABLE
];
804 const struct gl_texture_object
*tObj
= texUnit
->_Current
;
805 const GLenum format
= tObj
->Image
[tObj
->BaseLevel
]->Format
;
806 GLuint color_arg
[3], alpha_arg
[3];
807 GLuint i
, numColorArgs
= 0, numAlphaArgs
= 0;
808 GLuint RGBshift
= texUnit
->CombineScaleShiftRGB
;
809 GLuint Ashift
= texUnit
->CombineScaleShiftA
;
811 switch ( texUnit
->EnvMode
) {
815 case GL_LUMINANCE_ALPHA
:
817 color_combine
= radeon_color_combine
[unit
][RADEON_REPLACE
];
818 alpha_combine
= radeon_alpha_combine
[unit
][RADEON_REPLACE
];
821 color_combine
= radeon_color_combine
[unit
][RADEON_DISABLE
];
822 alpha_combine
= radeon_alpha_combine
[unit
][RADEON_REPLACE
];
827 color_combine
= radeon_color_combine
[unit
][RADEON_REPLACE
];
828 alpha_combine
= radeon_alpha_combine
[unit
][RADEON_DISABLE
];
839 case GL_LUMINANCE_ALPHA
:
841 color_combine
= radeon_color_combine
[unit
][RADEON_MODULATE
];
842 alpha_combine
= radeon_alpha_combine
[unit
][RADEON_MODULATE
];
845 color_combine
= radeon_color_combine
[unit
][RADEON_DISABLE
];
846 alpha_combine
= radeon_alpha_combine
[unit
][RADEON_MODULATE
];
851 color_combine
= radeon_color_combine
[unit
][RADEON_MODULATE
];
852 alpha_combine
= radeon_alpha_combine
[unit
][RADEON_DISABLE
];
865 color_combine
= radeon_color_combine
[unit
][RADEON_DECAL
];
866 alpha_combine
= radeon_alpha_combine
[unit
][RADEON_DISABLE
];
870 case GL_LUMINANCE_ALPHA
:
872 color_combine
= radeon_color_combine
[unit
][RADEON_DISABLE
];
873 alpha_combine
= radeon_alpha_combine
[unit
][RADEON_DISABLE
];
886 case GL_LUMINANCE_ALPHA
:
888 color_combine
= radeon_color_combine
[unit
][RADEON_BLEND
];
889 alpha_combine
= radeon_alpha_combine
[unit
][RADEON_MODULATE
];
892 color_combine
= radeon_color_combine
[unit
][RADEON_DISABLE
];
893 alpha_combine
= radeon_alpha_combine
[unit
][RADEON_MODULATE
];
896 color_combine
= radeon_color_combine
[unit
][RADEON_BLEND
];
897 alpha_combine
= radeon_alpha_combine
[unit
][RADEON_BLEND
];
910 case GL_LUMINANCE_ALPHA
:
912 color_combine
= radeon_color_combine
[unit
][RADEON_ADD
];
913 alpha_combine
= radeon_alpha_combine
[unit
][RADEON_MODULATE
];
916 color_combine
= radeon_color_combine
[unit
][RADEON_DISABLE
];
917 alpha_combine
= radeon_alpha_combine
[unit
][RADEON_MODULATE
];
920 color_combine
= radeon_color_combine
[unit
][RADEON_ADD
];
921 alpha_combine
= radeon_alpha_combine
[unit
][RADEON_ADD
];
930 /* Don't cache these results.
932 rmesa
->state
.texture
.unit
[unit
].format
= 0;
933 rmesa
->state
.texture
.unit
[unit
].envMode
= 0;
936 * Calculate how many arguments we need to process.
938 switch ( texUnit
->CombineModeRGB
) {
948 case GL_DOT3_RGB_EXT
:
949 case GL_DOT3_RGBA_EXT
:
953 case GL_MODULATE_ADD_ATI
:
954 case GL_MODULATE_SIGNED_ADD_ATI
:
955 case GL_MODULATE_SUBTRACT_ATI
:
962 switch ( texUnit
->CombineModeA
) {
973 case GL_MODULATE_ADD_ATI
:
974 case GL_MODULATE_SIGNED_ADD_ATI
:
975 case GL_MODULATE_SUBTRACT_ATI
:
983 * Extract the color and alpha combine function arguments.
985 for ( i
= 0 ; i
< numColorArgs
; i
++ ) {
986 const GLuint op
= texUnit
->CombineOperandRGB
[i
] - GL_SRC_COLOR
;
989 switch ( texUnit
->CombineSourceRGB
[i
] ) {
991 color_arg
[i
] = radeon_texture_color
[op
][unit
];
994 color_arg
[i
] = radeon_tfactor_color
[op
];
996 case GL_PRIMARY_COLOR
:
997 color_arg
[i
] = radeon_primary_color
[op
];
1000 color_arg
[i
] = radeon_previous_color
[op
];
1003 color_arg
[i
] = radeon_zero_color
[op
];
1006 color_arg
[i
] = radeon_zero_color
[op
+1];
1013 for ( i
= 0 ; i
< numAlphaArgs
; i
++ ) {
1014 const GLuint op
= texUnit
->CombineOperandA
[i
] - GL_SRC_ALPHA
;
1017 switch ( texUnit
->CombineSourceA
[i
] ) {
1019 alpha_arg
[i
] = radeon_texture_alpha
[op
][unit
];
1022 alpha_arg
[i
] = radeon_tfactor_alpha
[op
];
1024 case GL_PRIMARY_COLOR
:
1025 alpha_arg
[i
] = radeon_primary_alpha
[op
];
1028 alpha_arg
[i
] = radeon_previous_alpha
[op
];
1031 alpha_arg
[i
] = radeon_zero_alpha
[op
];
1034 alpha_arg
[i
] = radeon_zero_alpha
[op
+1];
1042 * Build up the color and alpha combine functions.
1044 switch ( texUnit
->CombineModeRGB
) {
1046 color_combine
= (RADEON_COLOR_ARG_A_ZERO
|
1047 RADEON_COLOR_ARG_B_ZERO
|
1048 RADEON_BLEND_CTL_ADD
|
1050 RADEON_COLOR_ARG( 0, C
);
1053 color_combine
= (RADEON_COLOR_ARG_C_ZERO
|
1054 RADEON_BLEND_CTL_ADD
|
1056 RADEON_COLOR_ARG( 0, A
);
1057 RADEON_COLOR_ARG( 1, B
);
1060 color_combine
= (RADEON_COLOR_ARG_B_ZERO
|
1062 RADEON_BLEND_CTL_ADD
|
1064 RADEON_COLOR_ARG( 0, A
);
1065 RADEON_COLOR_ARG( 1, C
);
1068 color_combine
= (RADEON_COLOR_ARG_B_ZERO
|
1070 RADEON_BLEND_CTL_ADDSIGNED
|
1072 RADEON_COLOR_ARG( 0, A
);
1073 RADEON_COLOR_ARG( 1, C
);
1076 color_combine
= (RADEON_COLOR_ARG_B_ZERO
|
1078 RADEON_BLEND_CTL_SUBTRACT
|
1080 RADEON_COLOR_ARG( 0, A
);
1081 RADEON_COLOR_ARG( 1, C
);
1083 case GL_INTERPOLATE
:
1084 color_combine
= (RADEON_BLEND_CTL_BLEND
|
1086 RADEON_COLOR_ARG( 0, B
);
1087 RADEON_COLOR_ARG( 1, A
);
1088 RADEON_COLOR_ARG( 2, C
);
1091 case GL_DOT3_RGB_EXT
:
1092 case GL_DOT3_RGBA_EXT
:
1093 /* The EXT version of the DOT3 extension does not support the
1094 * scale factor, but the ARB version (and the version in OpenGL
1103 /* The R100 / RV200 only support a 1X multiplier in hardware
1104 * w/the ARB version.
1106 if ( RGBshift
!= (RADEON_SCALE_1X
>> RADEON_SCALE_SHIFT
) ) {
1113 color_combine
= (RADEON_COLOR_ARG_C_ZERO
|
1114 RADEON_BLEND_CTL_DOT3
|
1116 RADEON_COLOR_ARG( 0, A
);
1117 RADEON_COLOR_ARG( 1, B
);
1120 case GL_MODULATE_ADD_ATI
:
1121 color_combine
= (RADEON_BLEND_CTL_ADD
|
1123 RADEON_COLOR_ARG( 0, A
);
1124 RADEON_COLOR_ARG( 1, C
);
1125 RADEON_COLOR_ARG( 2, B
);
1127 case GL_MODULATE_SIGNED_ADD_ATI
:
1128 color_combine
= (RADEON_BLEND_CTL_ADDSIGNED
|
1130 RADEON_COLOR_ARG( 0, A
);
1131 RADEON_COLOR_ARG( 1, C
);
1132 RADEON_COLOR_ARG( 2, B
);
1134 case GL_MODULATE_SUBTRACT_ATI
:
1135 color_combine
= (RADEON_BLEND_CTL_SUBTRACT
|
1137 RADEON_COLOR_ARG( 0, A
);
1138 RADEON_COLOR_ARG( 1, C
);
1139 RADEON_COLOR_ARG( 2, B
);
1145 switch ( texUnit
->CombineModeA
) {
1147 alpha_combine
= (RADEON_ALPHA_ARG_A_ZERO
|
1148 RADEON_ALPHA_ARG_B_ZERO
|
1149 RADEON_BLEND_CTL_ADD
|
1151 RADEON_ALPHA_ARG( 0, C
);
1154 alpha_combine
= (RADEON_ALPHA_ARG_C_ZERO
|
1155 RADEON_BLEND_CTL_ADD
|
1157 RADEON_ALPHA_ARG( 0, A
);
1158 RADEON_ALPHA_ARG( 1, B
);
1161 alpha_combine
= (RADEON_ALPHA_ARG_B_ZERO
|
1163 RADEON_BLEND_CTL_ADD
|
1165 RADEON_ALPHA_ARG( 0, A
);
1166 RADEON_ALPHA_ARG( 1, C
);
1169 alpha_combine
= (RADEON_ALPHA_ARG_B_ZERO
|
1171 RADEON_BLEND_CTL_ADDSIGNED
|
1173 RADEON_ALPHA_ARG( 0, A
);
1174 RADEON_ALPHA_ARG( 1, C
);
1177 alpha_combine
= (RADEON_COLOR_ARG_B_ZERO
|
1179 RADEON_BLEND_CTL_SUBTRACT
|
1181 RADEON_ALPHA_ARG( 0, A
);
1182 RADEON_ALPHA_ARG( 1, C
);
1184 case GL_INTERPOLATE
:
1185 alpha_combine
= (RADEON_BLEND_CTL_BLEND
|
1187 RADEON_ALPHA_ARG( 0, B
);
1188 RADEON_ALPHA_ARG( 1, A
);
1189 RADEON_ALPHA_ARG( 2, C
);
1192 case GL_MODULATE_ADD_ATI
:
1193 alpha_combine
= (RADEON_BLEND_CTL_ADD
|
1195 RADEON_ALPHA_ARG( 0, A
);
1196 RADEON_ALPHA_ARG( 1, C
);
1197 RADEON_ALPHA_ARG( 2, B
);
1199 case GL_MODULATE_SIGNED_ADD_ATI
:
1200 alpha_combine
= (RADEON_BLEND_CTL_ADDSIGNED
|
1202 RADEON_ALPHA_ARG( 0, A
);
1203 RADEON_ALPHA_ARG( 1, C
);
1204 RADEON_ALPHA_ARG( 2, B
);
1206 case GL_MODULATE_SUBTRACT_ATI
:
1207 alpha_combine
= (RADEON_BLEND_CTL_SUBTRACT
|
1209 RADEON_ALPHA_ARG( 0, A
);
1210 RADEON_ALPHA_ARG( 1, C
);
1211 RADEON_ALPHA_ARG( 2, B
);
1217 if ( (texUnit
->CombineModeRGB
== GL_DOT3_RGB_EXT
)
1218 || (texUnit
->CombineModeRGB
== GL_DOT3_RGB
) ) {
1219 alpha_combine
|= RADEON_DOT_ALPHA_DONT_REPLICATE
;
1223 * Apply the scale factor.
1225 color_combine
|= (RGBshift
<< RADEON_SCALE_SHIFT
);
1226 alpha_combine
|= (Ashift
<< RADEON_SCALE_SHIFT
);
1237 if ( rmesa
->hw
.tex
[unit
].cmd
[TEX_PP_TXCBLEND
] != color_combine
||
1238 rmesa
->hw
.tex
[unit
].cmd
[TEX_PP_TXABLEND
] != alpha_combine
) {
1239 RADEON_STATECHANGE( rmesa
, tex
[unit
] );
1240 rmesa
->hw
.tex
[unit
].cmd
[TEX_PP_TXCBLEND
] = color_combine
;
1241 rmesa
->hw
.tex
[unit
].cmd
[TEX_PP_TXABLEND
] = alpha_combine
;
1247 #define TEXOBJ_TXFILTER_MASK (RADEON_MAX_MIP_LEVEL_MASK | \
1248 RADEON_MIN_FILTER_MASK | \
1249 RADEON_MAG_FILTER_MASK | \
1250 RADEON_MAX_ANISO_MASK | \
1251 RADEON_YUV_TO_RGB | \
1252 RADEON_YUV_TEMPERATURE_MASK | \
1253 RADEON_CLAMP_S_MASK | \
1254 RADEON_CLAMP_T_MASK | \
1255 RADEON_BORDER_MODE_D3D )
1257 #define TEXOBJ_TXFORMAT_MASK (RADEON_TXFORMAT_WIDTH_MASK | \
1258 RADEON_TXFORMAT_HEIGHT_MASK | \
1259 RADEON_TXFORMAT_FORMAT_MASK | \
1260 RADEON_TXFORMAT_F5_WIDTH_MASK | \
1261 RADEON_TXFORMAT_F5_HEIGHT_MASK | \
1262 RADEON_TXFORMAT_ALPHA_IN_MAP | \
1263 RADEON_TXFORMAT_CUBIC_MAP_ENABLE | \
1264 RADEON_TXFORMAT_NON_POWER2)
1267 static void import_tex_obj_state( radeonContextPtr rmesa
,
1269 radeonTexObjPtr texobj
)
1271 GLuint
*cmd
= RADEON_DB_STATE( tex
[unit
] );
1273 cmd
[TEX_PP_TXFILTER
] &= ~TEXOBJ_TXFILTER_MASK
;
1274 cmd
[TEX_PP_TXFILTER
] |= texobj
->pp_txfilter
& TEXOBJ_TXFILTER_MASK
;
1275 cmd
[TEX_PP_TXFORMAT
] &= ~TEXOBJ_TXFORMAT_MASK
;
1276 cmd
[TEX_PP_TXFORMAT
] |= texobj
->pp_txformat
& TEXOBJ_TXFORMAT_MASK
;
1277 cmd
[TEX_PP_TXOFFSET
] = texobj
->pp_txoffset
;
1278 cmd
[TEX_PP_BORDER_COLOR
] = texobj
->pp_border_color
;
1279 RADEON_DB_STATECHANGE( rmesa
, &rmesa
->hw
.tex
[unit
] );
1281 if (texobj
->base
.tObj
->Target
== GL_TEXTURE_RECTANGLE_NV
) {
1282 GLuint
*txr_cmd
= RADEON_DB_STATE( txr
[unit
] );
1283 txr_cmd
[TXR_PP_TEX_SIZE
] = texobj
->pp_txsize
; /* NPOT only! */
1284 txr_cmd
[TXR_PP_TEX_PITCH
] = texobj
->pp_txpitch
; /* NPOT only! */
1285 RADEON_DB_STATECHANGE( rmesa
, &rmesa
->hw
.txr
[unit
] );
1288 texobj
->dirty_state
&= ~(1<<unit
);
1294 static void set_texgen_matrix( radeonContextPtr rmesa
,
1296 const GLfloat
*s_plane
,
1297 const GLfloat
*t_plane
)
1299 static const GLfloat scale_identity
[4] = { 1,1,1,1 };
1301 if (!TEST_EQ_4V( s_plane
, scale_identity
) ||
1302 !TEST_EQ_4V( t_plane
, scale_identity
)) {
1303 rmesa
->TexGenEnabled
|= RADEON_TEXMAT_0_ENABLE
<<unit
;
1304 rmesa
->TexGenMatrix
[unit
].m
[0] = s_plane
[0];
1305 rmesa
->TexGenMatrix
[unit
].m
[4] = s_plane
[1];
1306 rmesa
->TexGenMatrix
[unit
].m
[8] = s_plane
[2];
1307 rmesa
->TexGenMatrix
[unit
].m
[12] = s_plane
[3];
1309 rmesa
->TexGenMatrix
[unit
].m
[1] = t_plane
[0];
1310 rmesa
->TexGenMatrix
[unit
].m
[5] = t_plane
[1];
1311 rmesa
->TexGenMatrix
[unit
].m
[9] = t_plane
[2];
1312 rmesa
->TexGenMatrix
[unit
].m
[13] = t_plane
[3];
1313 rmesa
->NewGLState
|= _NEW_TEXTURE_MATRIX
;
1317 /* Ignoring the Q texcoord for now.
1319 * Returns GL_FALSE if fallback required.
1321 static GLboolean
radeon_validate_texgen( GLcontext
*ctx
, GLuint unit
)
1323 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
1324 struct gl_texture_unit
*texUnit
= &ctx
->Texture
.Unit
[unit
];
1325 GLuint inputshift
= RADEON_TEXGEN_0_INPUT_SHIFT
+ unit
*4;
1326 GLuint tmp
= rmesa
->TexGenEnabled
;
1328 rmesa
->TexGenEnabled
&= ~(RADEON_TEXGEN_TEXMAT_0_ENABLE
<<unit
);
1329 rmesa
->TexGenEnabled
&= ~(RADEON_TEXMAT_0_ENABLE
<<unit
);
1330 rmesa
->TexGenEnabled
&= ~(RADEON_TEXGEN_INPUT_MASK
<<inputshift
);
1331 rmesa
->TexGenNeedNormals
[unit
] = 0;
1333 if ((texUnit
->TexGenEnabled
& (S_BIT
|T_BIT
)) == 0) {
1334 /* Disabled, no fallback:
1336 rmesa
->TexGenEnabled
|=
1337 (RADEON_TEXGEN_INPUT_TEXCOORD_0
+unit
) << inputshift
;
1340 else if (texUnit
->TexGenEnabled
& Q_BIT
) {
1341 /* Very easy to do this, in fact would remove a fallback case
1342 * elsewhere, but I haven't done it yet... Fallback:
1344 fprintf(stderr
, "fallback Q_BIT\n");
1347 else if ((texUnit
->TexGenEnabled
& (S_BIT
|T_BIT
)) != (S_BIT
|T_BIT
) ||
1348 texUnit
->GenModeS
!= texUnit
->GenModeT
) {
1349 /* Mixed modes, fallback:
1351 /* fprintf(stderr, "fallback mixed texgen\n"); */
1355 rmesa
->TexGenEnabled
|= RADEON_TEXGEN_TEXMAT_0_ENABLE
<< unit
;
1357 switch (texUnit
->GenModeS
) {
1358 case GL_OBJECT_LINEAR
:
1359 rmesa
->TexGenEnabled
|= RADEON_TEXGEN_INPUT_OBJ
<< inputshift
;
1360 set_texgen_matrix( rmesa
, unit
,
1361 texUnit
->ObjectPlaneS
,
1362 texUnit
->ObjectPlaneT
);
1366 rmesa
->TexGenEnabled
|= RADEON_TEXGEN_INPUT_EYE
<< inputshift
;
1367 set_texgen_matrix( rmesa
, unit
,
1369 texUnit
->EyePlaneT
);
1372 case GL_REFLECTION_MAP_NV
:
1373 rmesa
->TexGenNeedNormals
[unit
] = GL_TRUE
;
1374 rmesa
->TexGenEnabled
|= RADEON_TEXGEN_INPUT_EYE_REFLECT
<<inputshift
;
1377 case GL_NORMAL_MAP_NV
:
1378 rmesa
->TexGenNeedNormals
[unit
] = GL_TRUE
;
1379 rmesa
->TexGenEnabled
|= RADEON_TEXGEN_INPUT_EYE_NORMAL
<<inputshift
;
1384 /* Unsupported mode, fallback:
1386 /* fprintf(stderr, "fallback unsupported texgen\n"); */
1390 if (tmp
!= rmesa
->TexGenEnabled
) {
1391 rmesa
->NewGLState
|= _NEW_TEXTURE_MATRIX
;
1398 static void disable_tex( GLcontext
*ctx
, int unit
)
1400 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
1402 if (rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] & (RADEON_TEX_0_ENABLE
<<unit
)) {
1403 /* Texture unit disabled */
1404 if ( rmesa
->state
.texture
.unit
[unit
].texobj
!= NULL
) {
1405 /* The old texture is no longer bound to this texture unit.
1409 rmesa
->state
.texture
.unit
[unit
].texobj
->base
.bound
&= ~(1UL << unit
);
1410 rmesa
->state
.texture
.unit
[unit
].texobj
= NULL
;
1413 RADEON_STATECHANGE( rmesa
, ctx
);
1414 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] &=
1415 ~((RADEON_TEX_0_ENABLE
| RADEON_TEX_BLEND_0_ENABLE
) << unit
);
1417 RADEON_STATECHANGE( rmesa
, tcl
);
1420 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXFMT
] &= ~(RADEON_TCL_VTX_ST0
|
1424 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXFMT
] &= ~(RADEON_TCL_VTX_ST1
|
1432 if (rmesa
->TclFallback
& (RADEON_TCL_FALLBACK_TEXGEN_0
<<unit
)) {
1433 TCL_FALLBACK( ctx
, (RADEON_TCL_FALLBACK_TEXGEN_0
<<unit
), GL_FALSE
);
1434 rmesa
->recheck_texgen
[unit
] = GL_TRUE
;
1440 GLuint inputshift
= RADEON_TEXGEN_0_INPUT_SHIFT
+ unit
*4;
1441 GLuint tmp
= rmesa
->TexGenEnabled
;
1443 rmesa
->TexGenEnabled
&= ~(RADEON_TEXGEN_TEXMAT_0_ENABLE
<<unit
);
1444 rmesa
->TexGenEnabled
&= ~(RADEON_TEXMAT_0_ENABLE
<<unit
);
1445 rmesa
->TexGenEnabled
&= ~(RADEON_TEXGEN_INPUT_MASK
<<inputshift
);
1446 rmesa
->TexGenNeedNormals
[unit
] = 0;
1447 rmesa
->TexGenEnabled
|=
1448 (RADEON_TEXGEN_INPUT_TEXCOORD_0
+unit
) << inputshift
;
1450 if (tmp
!= rmesa
->TexGenEnabled
) {
1451 rmesa
->recheck_texgen
[unit
] = GL_TRUE
;
1452 rmesa
->NewGLState
|= _NEW_TEXTURE_MATRIX
;
1458 static GLboolean
enable_tex_2d( GLcontext
*ctx
, int unit
)
1460 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
1461 struct gl_texture_unit
*texUnit
= &ctx
->Texture
.Unit
[unit
];
1462 struct gl_texture_object
*tObj
= texUnit
->_Current
;
1463 radeonTexObjPtr t
= (radeonTexObjPtr
) tObj
->DriverData
;
1465 /* Need to load the 2d images associated with this unit.
1467 if (t
->pp_txformat
& RADEON_TXFORMAT_NON_POWER2
) {
1468 t
->pp_txformat
&= ~RADEON_TXFORMAT_NON_POWER2
;
1469 t
->base
.dirty_images
[0] = ~0;
1472 ASSERT(tObj
->Target
== GL_TEXTURE_2D
|| tObj
->Target
== GL_TEXTURE_1D
);
1474 if ( t
->base
.dirty_images
[0] ) {
1475 RADEON_FIREVERTICES( rmesa
);
1476 radeonSetTexImages( rmesa
, tObj
);
1477 radeonUploadTexImages( rmesa
, (radeonTexObjPtr
) tObj
->DriverData
, 0 );
1478 if ( !t
->base
.memBlock
)
1485 static GLboolean
enable_tex_rect( GLcontext
*ctx
, int unit
)
1487 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
1488 struct gl_texture_unit
*texUnit
= &ctx
->Texture
.Unit
[unit
];
1489 struct gl_texture_object
*tObj
= texUnit
->_Current
;
1490 radeonTexObjPtr t
= (radeonTexObjPtr
) tObj
->DriverData
;
1492 if (!(t
->pp_txformat
& RADEON_TXFORMAT_NON_POWER2
)) {
1493 t
->pp_txformat
|= RADEON_TXFORMAT_NON_POWER2
;
1494 t
->base
.dirty_images
[0] = ~0;
1497 ASSERT(tObj
->Target
== GL_TEXTURE_RECTANGLE_NV
);
1499 if ( t
->base
.dirty_images
[0] ) {
1500 RADEON_FIREVERTICES( rmesa
);
1501 radeonSetTexImages( rmesa
, tObj
);
1502 radeonUploadTexImages( rmesa
, (radeonTexObjPtr
) tObj
->DriverData
, 0 );
1503 if ( !t
->base
.memBlock
/* && !rmesa->prefer_agp_client_texturing FIXME */ ) {
1504 fprintf(stderr
, "%s: upload failed\n", __FUNCTION__
);
1513 static GLboolean
update_tex_common( GLcontext
*ctx
, int unit
)
1515 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
1516 struct gl_texture_unit
*texUnit
= &ctx
->Texture
.Unit
[unit
];
1517 struct gl_texture_object
*tObj
= texUnit
->_Current
;
1518 radeonTexObjPtr t
= (radeonTexObjPtr
) tObj
->DriverData
;
1521 /* Fallback if there's a texture border */
1522 if ( tObj
->Image
[tObj
->BaseLevel
]->Border
> 0 ) {
1523 fprintf(stderr
, "%s: border\n", __FUNCTION__
);
1527 /* Update state if this is a different texture object to last
1530 if ( rmesa
->state
.texture
.unit
[unit
].texobj
!= t
) {
1531 if ( rmesa
->state
.texture
.unit
[unit
].texobj
!= NULL
) {
1532 /* The old texture is no longer bound to this texture unit.
1536 rmesa
->state
.texture
.unit
[unit
].texobj
->base
.bound
&=
1540 rmesa
->state
.texture
.unit
[unit
].texobj
= t
;
1541 t
->base
.bound
|= (1UL << unit
);
1542 t
->dirty_state
|= 1<<unit
;
1543 driUpdateTextureLRU( (driTextureObject
*) t
); /* XXX: should be locked! */
1549 if ( !(rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] & (RADEON_TEX_0_ENABLE
<<unit
))) {
1550 RADEON_STATECHANGE( rmesa
, ctx
);
1551 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] |=
1552 (RADEON_TEX_0_ENABLE
| RADEON_TEX_BLEND_0_ENABLE
) << unit
;
1554 RADEON_STATECHANGE( rmesa
, tcl
);
1557 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXFMT
] |= RADEON_TCL_VTX_ST0
;
1559 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXFMT
] |= RADEON_TCL_VTX_ST1
;
1561 rmesa
->recheck_texgen
[unit
] = GL_TRUE
;
1564 if (t
->dirty_state
& (1<<unit
)) {
1565 import_tex_obj_state( rmesa
, unit
, t
);
1568 if (rmesa
->recheck_texgen
[unit
]) {
1569 GLboolean fallback
= !radeon_validate_texgen( ctx
, unit
);
1570 TCL_FALLBACK( ctx
, (RADEON_TCL_FALLBACK_TEXGEN_0
<<unit
), fallback
);
1571 rmesa
->recheck_texgen
[unit
] = 0;
1572 rmesa
->NewGLState
|= _NEW_TEXTURE_MATRIX
;
1575 format
= tObj
->Image
[tObj
->BaseLevel
]->Format
;
1576 if ( rmesa
->state
.texture
.unit
[unit
].format
!= format
||
1577 rmesa
->state
.texture
.unit
[unit
].envMode
!= texUnit
->EnvMode
) {
1578 rmesa
->state
.texture
.unit
[unit
].format
= format
;
1579 rmesa
->state
.texture
.unit
[unit
].envMode
= texUnit
->EnvMode
;
1580 if ( ! radeonUpdateTextureEnv( ctx
, unit
) ) {
1585 FALLBACK( rmesa
, RADEON_FALLBACK_BORDER_MODE
, t
->border_fallback
);
1586 return !t
->border_fallback
;
1591 static GLboolean
radeonUpdateTextureUnit( GLcontext
*ctx
, int unit
)
1593 struct gl_texture_unit
*texUnit
= &ctx
->Texture
.Unit
[unit
];
1595 TCL_FALLBACK( ctx
, RADEON_TCL_FALLBACK_TEXRECT_0
<< unit
, 0 );
1597 if ( texUnit
->_ReallyEnabled
& (TEXTURE_RECT_BIT
) ) {
1598 TCL_FALLBACK( ctx
, RADEON_TCL_FALLBACK_TEXRECT_0
<< unit
, 1 );
1600 return (enable_tex_rect( ctx
, unit
) &&
1601 update_tex_common( ctx
, unit
));
1603 else if ( texUnit
->_ReallyEnabled
& (TEXTURE_1D_BIT
| TEXTURE_2D_BIT
) ) {
1604 return (enable_tex_2d( ctx
, unit
) &&
1605 update_tex_common( ctx
, unit
));
1607 else if ( texUnit
->_ReallyEnabled
) {
1611 disable_tex( ctx
, unit
);
1616 void radeonUpdateTextureState( GLcontext
*ctx
)
1618 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
1621 ok
= (radeonUpdateTextureUnit( ctx
, 0 ) &&
1622 radeonUpdateTextureUnit( ctx
, 1 ));
1624 FALLBACK( rmesa
, RADEON_FALLBACK_TEXTURE
, !ok
);
1626 if (rmesa
->TclFallback
)
1627 radeonChooseVertexState( ctx
);