1 /**************************************************************************
3 Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and
4 VA Linux Systems Inc., Fremont, California.
8 Permission is hereby granted, free of charge, to any person obtaining
9 a copy of this software and associated documentation files (the
10 "Software"), to deal in the Software without restriction, including
11 without limitation the rights to use, copy, modify, merge, publish,
12 distribute, sublicense, and/or sell copies of the Software, and to
13 permit persons to whom the Software is furnished to do so, subject to
14 the following conditions:
16 The above copyright notice and this permission notice (including the
17 next paragraph) shall be included in all copies or substantial
18 portions of the Software.
20 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
23 IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
24 LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25 OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
28 **************************************************************************/
32 * Kevin E. Martin <martin@valinux.com>
33 * Gareth Hughes <gareth@valinux.com>
36 #include "main/glheader.h"
37 #include "main/imports.h"
38 #include "main/colormac.h"
39 #include "main/context.h"
40 #include "main/macros.h"
41 #include "main/texformat.h"
42 #include "main/texobj.h"
43 #include "main/enums.h"
45 #include "radeon_context.h"
46 #include "radeon_mipmap_tree.h"
47 #include "radeon_state.h"
48 #include "radeon_ioctl.h"
49 #include "radeon_swtcl.h"
50 #include "radeon_tex.h"
51 #include "radeon_tcl.h"
54 #define RADEON_TXFORMAT_A8 RADEON_TXFORMAT_I8
55 #define RADEON_TXFORMAT_L8 RADEON_TXFORMAT_I8
56 #define RADEON_TXFORMAT_AL88 RADEON_TXFORMAT_AI88
57 #define RADEON_TXFORMAT_YCBCR RADEON_TXFORMAT_YVYU422
58 #define RADEON_TXFORMAT_YCBCR_REV RADEON_TXFORMAT_VYUY422
59 #define RADEON_TXFORMAT_RGB_DXT1 RADEON_TXFORMAT_DXT1
60 #define RADEON_TXFORMAT_RGBA_DXT1 RADEON_TXFORMAT_DXT1
61 #define RADEON_TXFORMAT_RGBA_DXT3 RADEON_TXFORMAT_DXT23
62 #define RADEON_TXFORMAT_RGBA_DXT5 RADEON_TXFORMAT_DXT45
65 [ MESA_FORMAT_ ## f ] = { RADEON_TXFORMAT_ ## f, 0 }
66 #define _COLOR_REV(f) \
67 [ MESA_FORMAT_ ## f ## _REV ] = { RADEON_TXFORMAT_ ## f, 0 }
69 [ MESA_FORMAT_ ## f ] = { RADEON_TXFORMAT_ ## f | RADEON_TXFORMAT_ALPHA_IN_MAP, 0 }
70 #define _ALPHA_REV(f) \
71 [ MESA_FORMAT_ ## f ## _REV ] = { RADEON_TXFORMAT_ ## f | RADEON_TXFORMAT_ALPHA_IN_MAP, 0 }
73 [ MESA_FORMAT_ ## f ] = { RADEON_TXFORMAT_ ## f, RADEON_YUV_TO_RGB }
75 [ MESA_FORMAT_ ## f ] = { 0xffffffff, 0 }
76 #define VALID_FORMAT(f) ( ((f) <= MESA_FORMAT_RGBA_DXT5) \
77 && (tx_table[f].format != 0xffffffff) )
80 GLuint format
, filter
;
83 static const struct tx_table tx_table
[] =
89 [ MESA_FORMAT_RGB888
] = { RADEON_TXFORMAT_ARGB8888
, 0 },
117 * This function computes the number of bytes of storage needed for
118 * the given texture object (all mipmap levels, all cube faces).
119 * The \c image[face][level].x/y/width/height parameters for upload/blitting
120 * are computed here. \c pp_txfilter, \c pp_txformat, etc. will be set here
123 * \param rmesa Context pointer
124 * \param tObj GL texture object whose images are to be posted to
128 static void radeonSetTexImages( r100ContextPtr rmesa
,
129 struct gl_texture_object
*tObj
)
131 radeonTexObjPtr t
= (radeonTexObjPtr
)tObj
->DriverData
;
132 const struct gl_texture_image
*baseImage
= tObj
->Image
[0][tObj
->BaseLevel
];
133 GLint curOffset
, blitWidth
;
136 GLint log2Width
, log2Height
, log2Depth
;
138 /* Set the hardware texture format
140 if ( !t
->image_override
) {
141 t
->pp_txformat
&= ~(RADEON_TXFORMAT_FORMAT_MASK
|
142 RADEON_TXFORMAT_ALPHA_IN_MAP
);
143 t
->pp_txfilter
&= ~RADEON_YUV_TO_RGB
;
145 if ( VALID_FORMAT( baseImage
->TexFormat
->MesaFormat
) ) {
146 t
->pp_txformat
|= tx_table
[ baseImage
->TexFormat
->MesaFormat
].format
;
147 t
->pp_txfilter
|= tx_table
[ baseImage
->TexFormat
->MesaFormat
].filter
;
150 _mesa_problem(NULL
, "unexpected texture format in %s", __FUNCTION__
);
155 texelBytes
= baseImage
->TexFormat
->TexelBytes
;
157 /* Compute which mipmap levels we really want to send to the hardware.
160 if (tObj
->Target
!= GL_TEXTURE_CUBE_MAP
)
161 driCalculateTextureFirstLastLevel( (driTextureObject
*) t
);
163 /* r100 can't handle mipmaps for cube/3d textures, so don't waste
165 t
->base
.firstLevel
= t
->base
.lastLevel
= tObj
->BaseLevel
;
167 log2Width
= tObj
->Image
[0][t
->base
.firstLevel
]->WidthLog2
;
168 log2Height
= tObj
->Image
[0][t
->base
.firstLevel
]->HeightLog2
;
169 log2Depth
= tObj
->Image
[0][t
->base
.firstLevel
]->DepthLog2
;
171 numLevels
= t
->base
.lastLevel
- t
->base
.firstLevel
+ 1;
173 assert(numLevels
<= RADEON_MAX_TEXTURE_LEVELS
);
175 /* Calculate mipmap offsets and dimensions for blitting (uploading)
176 * The idea is that we lay out the mipmap levels within a block of
177 * memory organized as a rectangle of width BLIT_WIDTH_BYTES.
180 blitWidth
= BLIT_WIDTH_BYTES
;
183 /* figure out if this texture is suitable for tiling. */
184 if (texelBytes
&& (tObj
->Target
!= GL_TEXTURE_RECTANGLE_NV
)) {
185 if (rmesa
->texmicrotile
&& (baseImage
->Height
> 1)) {
186 /* allow 32 (bytes) x 1 mip (which will use two times the space
187 the non-tiled version would use) max if base texture is large enough */
188 if ((numLevels
== 1) ||
189 (((baseImage
->Width
* texelBytes
/ baseImage
->Height
) <= 32) &&
190 (baseImage
->Width
* texelBytes
> 64)) ||
191 ((baseImage
->Width
* texelBytes
/ baseImage
->Height
) <= 16)) {
192 /* R100 has two microtile bits (only the txoffset reg, not the blitter)
193 weird: X2 + OPT: 32bit correct, 16bit completely hosed
194 X2: 32bit correct, 16bit correct
195 OPT: 32bit large mips correct, small mips hosed, 16bit completely hosed */
196 t
->tile_bits
|= RADEON_TXO_MICRO_TILE_X2
/*| RADEON_TXO_MICRO_TILE_OPT*/;
199 if ((baseImage
->Width
* texelBytes
>= 256) && (baseImage
->Height
>= 16)) {
200 /* R100 disables macro tiling only if mip width is smaller than 256 bytes, and not
201 in the case if height is smaller than 16 (not 100% sure), as does the r200,
202 so need to disable macro tiling in that case */
203 if ((numLevels
== 1) || ((baseImage
->Width
* texelBytes
/ baseImage
->Height
) <= 4)) {
204 t
->tile_bits
|= RADEON_TXO_MACRO_TILE
;
209 for (i
= 0; i
< numLevels
; i
++) {
210 const struct gl_texture_image
*texImage
;
213 texImage
= tObj
->Image
[0][i
+ t
->base
.firstLevel
];
217 /* find image size in bytes */
218 if (texImage
->IsCompressed
) {
219 /* need to calculate the size AFTER padding even though the texture is
220 submitted without padding.
221 Only handle pot textures currently - don't know if npot is even possible,
222 size calculation would certainly need (trivial) adjustments.
223 Align (and later pad) to 32byte, not sure what that 64byte blit width is
225 if ((t
->pp_txformat
& RADEON_TXFORMAT_FORMAT_MASK
) == RADEON_TXFORMAT_DXT1
) {
226 /* RGB_DXT1/RGBA_DXT1, 8 bytes per block */
227 if ((texImage
->Width
+ 3) < 8) /* width one block */
228 size
= texImage
->CompressedSize
* 4;
229 else if ((texImage
->Width
+ 3) < 16)
230 size
= texImage
->CompressedSize
* 2;
231 else size
= texImage
->CompressedSize
;
233 else /* DXT3/5, 16 bytes per block */
234 if ((texImage
->Width
+ 3) < 8)
235 size
= texImage
->CompressedSize
* 2;
236 else size
= texImage
->CompressedSize
;
238 else if (tObj
->Target
== GL_TEXTURE_RECTANGLE_NV
) {
239 size
= ((texImage
->Width
* texelBytes
+ 63) & ~63) * texImage
->Height
;
241 else if (t
->tile_bits
& RADEON_TXO_MICRO_TILE_X2
) {
242 /* tile pattern is 16 bytes x2. mipmaps stay 32 byte aligned,
243 though the actual offset may be different (if texture is less than
244 32 bytes width) to the untiled case */
245 int w
= (texImage
->Width
* texelBytes
* 2 + 31) & ~31;
246 size
= (w
* ((texImage
->Height
+ 1) / 2)) * texImage
->Depth
;
247 blitWidth
= MAX2(texImage
->Width
, 64 / texelBytes
);
250 int w
= (texImage
->Width
* texelBytes
+ 31) & ~31;
251 size
= w
* texImage
->Height
* texImage
->Depth
;
252 blitWidth
= MAX2(texImage
->Width
, 64 / texelBytes
);
256 /* Align to 32-byte offset. It is faster to do this unconditionally
257 * (no branch penalty).
260 curOffset
= (curOffset
+ 0x1f) & ~0x1f;
263 t
->image
[0][i
].x
= curOffset
; /* fix x and y coords up later together with offset */
264 t
->image
[0][i
].y
= 0;
265 t
->image
[0][i
].width
= MIN2(size
/ texelBytes
, blitWidth
);
266 t
->image
[0][i
].height
= (size
/ texelBytes
) / t
->image
[0][i
].width
;
269 t
->image
[0][i
].x
= curOffset
% BLIT_WIDTH_BYTES
;
270 t
->image
[0][i
].y
= curOffset
/ BLIT_WIDTH_BYTES
;
271 t
->image
[0][i
].width
= MIN2(size
, BLIT_WIDTH_BYTES
);
272 t
->image
[0][i
].height
= size
/ t
->image
[0][i
].width
;
276 /* for debugging only and only applicable to non-rectangle targets */
277 assert(size
% t
->image
[0][i
].width
== 0);
278 assert(t
->image
[0][i
].x
== 0
279 || (size
< BLIT_WIDTH_BYTES
&& t
->image
[0][i
].height
== 1));
284 "level %d: %dx%d x=%d y=%d w=%d h=%d size=%d at %d\n",
285 i
, texImage
->Width
, texImage
->Height
,
286 t
->image
[0][i
].x
, t
->image
[0][i
].y
,
287 t
->image
[0][i
].width
, t
->image
[0][i
].height
, size
, curOffset
);
293 /* Align the total size of texture memory block.
295 t
->base
.totalSize
= (curOffset
+ RADEON_OFFSET_MASK
) & ~RADEON_OFFSET_MASK
;
297 /* Setup remaining cube face blits, if needed */
298 if (tObj
->Target
== GL_TEXTURE_CUBE_MAP
) {
299 const GLuint faceSize
= t
->base
.totalSize
;
301 /* reuse face 0 x/y/width/height - just update the offset when uploading */
302 for (face
= 1; face
< 6; face
++) {
303 for (i
= 0; i
< numLevels
; i
++) {
304 t
->image
[face
][i
].x
= t
->image
[0][i
].x
;
305 t
->image
[face
][i
].y
= t
->image
[0][i
].y
;
306 t
->image
[face
][i
].width
= t
->image
[0][i
].width
;
307 t
->image
[face
][i
].height
= t
->image
[0][i
].height
;
310 t
->base
.totalSize
= 6 * faceSize
; /* total texmem needed */
315 t
->pp_txfilter
&= ~RADEON_MAX_MIP_LEVEL_MASK
;
316 t
->pp_txfilter
|= (numLevels
- 1) << RADEON_MAX_MIP_LEVEL_SHIFT
;
318 t
->pp_txformat
&= ~(RADEON_TXFORMAT_WIDTH_MASK
|
319 RADEON_TXFORMAT_HEIGHT_MASK
|
320 RADEON_TXFORMAT_CUBIC_MAP_ENABLE
|
321 RADEON_TXFORMAT_F5_WIDTH_MASK
|
322 RADEON_TXFORMAT_F5_HEIGHT_MASK
);
323 t
->pp_txformat
|= ((log2Width
<< RADEON_TXFORMAT_WIDTH_SHIFT
) |
324 (log2Height
<< RADEON_TXFORMAT_HEIGHT_SHIFT
));
326 if (tObj
->Target
== GL_TEXTURE_CUBE_MAP
) {
327 assert(log2Width
== log2Height
);
328 t
->pp_txformat
|= ((log2Width
<< RADEON_TXFORMAT_F5_WIDTH_SHIFT
) |
329 (log2Height
<< RADEON_TXFORMAT_F5_HEIGHT_SHIFT
) |
330 (RADEON_TXFORMAT_CUBIC_MAP_ENABLE
));
331 t
->pp_cubic_faces
= ((log2Width
<< RADEON_FACE_WIDTH_1_SHIFT
) |
332 (log2Height
<< RADEON_FACE_HEIGHT_1_SHIFT
) |
333 (log2Width
<< RADEON_FACE_WIDTH_2_SHIFT
) |
334 (log2Height
<< RADEON_FACE_HEIGHT_2_SHIFT
) |
335 (log2Width
<< RADEON_FACE_WIDTH_3_SHIFT
) |
336 (log2Height
<< RADEON_FACE_HEIGHT_3_SHIFT
) |
337 (log2Width
<< RADEON_FACE_WIDTH_4_SHIFT
) |
338 (log2Height
<< RADEON_FACE_HEIGHT_4_SHIFT
));
341 t
->pp_txsize
= (((tObj
->Image
[0][t
->base
.firstLevel
]->Width
- 1) << 0) |
342 ((tObj
->Image
[0][t
->base
.firstLevel
]->Height
- 1) << 16));
344 /* Only need to round to nearest 32 for textures, but the blitter
345 * requires 64-byte aligned pitches, and we may/may not need the
346 * blitter. NPOT only!
348 if ( !t
->image_override
) {
349 if (baseImage
->IsCompressed
)
350 t
->pp_txpitch
= (tObj
->Image
[0][t
->base
.firstLevel
]->Width
+ 63) & ~(63);
352 t
->pp_txpitch
= ((tObj
->Image
[0][t
->base
.firstLevel
]->Width
* texelBytes
) + 63) & ~(63);
356 t
->dirty_state
= R100_TEX_ALL
;
358 /* FYI: radeonUploadTexImages( rmesa, t ); used to be called here */
363 /* ================================================================
364 * Texture combine functions
367 /* GL_ARB_texture_env_combine support
370 /* The color tables have combine functions for GL_SRC_COLOR,
371 * GL_ONE_MINUS_SRC_COLOR, GL_SRC_ALPHA and GL_ONE_MINUS_SRC_ALPHA.
373 static GLuint radeon_texture_color
[][RADEON_MAX_TEXTURE_UNITS
] =
376 RADEON_COLOR_ARG_A_T0_COLOR
,
377 RADEON_COLOR_ARG_A_T1_COLOR
,
378 RADEON_COLOR_ARG_A_T2_COLOR
381 RADEON_COLOR_ARG_A_T0_COLOR
| RADEON_COMP_ARG_A
,
382 RADEON_COLOR_ARG_A_T1_COLOR
| RADEON_COMP_ARG_A
,
383 RADEON_COLOR_ARG_A_T2_COLOR
| RADEON_COMP_ARG_A
386 RADEON_COLOR_ARG_A_T0_ALPHA
,
387 RADEON_COLOR_ARG_A_T1_ALPHA
,
388 RADEON_COLOR_ARG_A_T2_ALPHA
391 RADEON_COLOR_ARG_A_T0_ALPHA
| RADEON_COMP_ARG_A
,
392 RADEON_COLOR_ARG_A_T1_ALPHA
| RADEON_COMP_ARG_A
,
393 RADEON_COLOR_ARG_A_T2_ALPHA
| RADEON_COMP_ARG_A
397 static GLuint radeon_tfactor_color
[] =
399 RADEON_COLOR_ARG_A_TFACTOR_COLOR
,
400 RADEON_COLOR_ARG_A_TFACTOR_COLOR
| RADEON_COMP_ARG_A
,
401 RADEON_COLOR_ARG_A_TFACTOR_ALPHA
,
402 RADEON_COLOR_ARG_A_TFACTOR_ALPHA
| RADEON_COMP_ARG_A
405 static GLuint radeon_primary_color
[] =
407 RADEON_COLOR_ARG_A_DIFFUSE_COLOR
,
408 RADEON_COLOR_ARG_A_DIFFUSE_COLOR
| RADEON_COMP_ARG_A
,
409 RADEON_COLOR_ARG_A_DIFFUSE_ALPHA
,
410 RADEON_COLOR_ARG_A_DIFFUSE_ALPHA
| RADEON_COMP_ARG_A
413 static GLuint radeon_previous_color
[] =
415 RADEON_COLOR_ARG_A_CURRENT_COLOR
,
416 RADEON_COLOR_ARG_A_CURRENT_COLOR
| RADEON_COMP_ARG_A
,
417 RADEON_COLOR_ARG_A_CURRENT_ALPHA
,
418 RADEON_COLOR_ARG_A_CURRENT_ALPHA
| RADEON_COMP_ARG_A
421 /* GL_ZERO table - indices 0-3
422 * GL_ONE table - indices 1-4
424 static GLuint radeon_zero_color
[] =
426 RADEON_COLOR_ARG_A_ZERO
,
427 RADEON_COLOR_ARG_A_ZERO
| RADEON_COMP_ARG_A
,
428 RADEON_COLOR_ARG_A_ZERO
,
429 RADEON_COLOR_ARG_A_ZERO
| RADEON_COMP_ARG_A
,
430 RADEON_COLOR_ARG_A_ZERO
434 /* The alpha tables only have GL_SRC_ALPHA and GL_ONE_MINUS_SRC_ALPHA.
436 static GLuint radeon_texture_alpha
[][RADEON_MAX_TEXTURE_UNITS
] =
439 RADEON_ALPHA_ARG_A_T0_ALPHA
,
440 RADEON_ALPHA_ARG_A_T1_ALPHA
,
441 RADEON_ALPHA_ARG_A_T2_ALPHA
444 RADEON_ALPHA_ARG_A_T0_ALPHA
| RADEON_COMP_ARG_A
,
445 RADEON_ALPHA_ARG_A_T1_ALPHA
| RADEON_COMP_ARG_A
,
446 RADEON_ALPHA_ARG_A_T2_ALPHA
| RADEON_COMP_ARG_A
450 static GLuint radeon_tfactor_alpha
[] =
452 RADEON_ALPHA_ARG_A_TFACTOR_ALPHA
,
453 RADEON_ALPHA_ARG_A_TFACTOR_ALPHA
| RADEON_COMP_ARG_A
456 static GLuint radeon_primary_alpha
[] =
458 RADEON_ALPHA_ARG_A_DIFFUSE_ALPHA
,
459 RADEON_ALPHA_ARG_A_DIFFUSE_ALPHA
| RADEON_COMP_ARG_A
462 static GLuint radeon_previous_alpha
[] =
464 RADEON_ALPHA_ARG_A_CURRENT_ALPHA
,
465 RADEON_ALPHA_ARG_A_CURRENT_ALPHA
| RADEON_COMP_ARG_A
468 /* GL_ZERO table - indices 0-1
469 * GL_ONE table - indices 1-2
471 static GLuint radeon_zero_alpha
[] =
473 RADEON_ALPHA_ARG_A_ZERO
,
474 RADEON_ALPHA_ARG_A_ZERO
| RADEON_COMP_ARG_A
,
475 RADEON_ALPHA_ARG_A_ZERO
479 /* Extract the arg from slot A, shift it into the correct argument slot
480 * and set the corresponding complement bit.
482 #define RADEON_COLOR_ARG( n, arg ) \
485 ((color_arg[n] & RADEON_COLOR_ARG_MASK) \
486 << RADEON_COLOR_ARG_##arg##_SHIFT); \
488 ((color_arg[n] >> RADEON_COMP_ARG_SHIFT) \
489 << RADEON_COMP_ARG_##arg##_SHIFT); \
492 #define RADEON_ALPHA_ARG( n, arg ) \
495 ((alpha_arg[n] & RADEON_ALPHA_ARG_MASK) \
496 << RADEON_ALPHA_ARG_##arg##_SHIFT); \
498 ((alpha_arg[n] >> RADEON_COMP_ARG_SHIFT) \
499 << RADEON_COMP_ARG_##arg##_SHIFT); \
503 /* ================================================================
504 * Texture unit state management
507 static GLboolean
radeonUpdateTextureEnv( GLcontext
*ctx
, int unit
)
509 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
510 const struct gl_texture_unit
*texUnit
= &ctx
->Texture
.Unit
[unit
];
511 GLuint color_combine
, alpha_combine
;
512 const GLuint color_combine0
= RADEON_COLOR_ARG_A_ZERO
| RADEON_COLOR_ARG_B_ZERO
513 | RADEON_COLOR_ARG_C_CURRENT_COLOR
| RADEON_BLEND_CTL_ADD
514 | RADEON_SCALE_1X
| RADEON_CLAMP_TX
;
515 const GLuint alpha_combine0
= RADEON_ALPHA_ARG_A_ZERO
| RADEON_ALPHA_ARG_B_ZERO
516 | RADEON_ALPHA_ARG_C_CURRENT_ALPHA
| RADEON_BLEND_CTL_ADD
517 | RADEON_SCALE_1X
| RADEON_CLAMP_TX
;
520 /* texUnit->_Current can be NULL if and only if the texture unit is
521 * not actually enabled.
523 assert( (texUnit
->_ReallyEnabled
== 0)
524 || (texUnit
->_Current
!= NULL
) );
526 if ( RADEON_DEBUG
& DEBUG_TEXTURE
) {
527 fprintf( stderr
, "%s( %p, %d )\n", __FUNCTION__
, (void *)ctx
, unit
);
530 /* Set the texture environment state. Isn't this nice and clean?
531 * The chip will automagically set the texture alpha to 0xff when
532 * the texture format does not include an alpha component. This
533 * reduces the amount of special-casing we have to do, alpha-only
534 * textures being a notable exception. Doesn't work for luminance
535 * textures realized with I8 and ALPHA_IN_MAP not set neither (on r100).
537 /* Don't cache these results.
539 rmesa
->state
.texture
.unit
[unit
].format
= 0;
540 rmesa
->state
.texture
.unit
[unit
].envMode
= 0;
542 if ( !texUnit
->_ReallyEnabled
) {
543 color_combine
= color_combine0
;
544 alpha_combine
= alpha_combine0
;
547 GLuint color_arg
[3], alpha_arg
[3];
549 const GLuint numColorArgs
= texUnit
->_CurrentCombine
->_NumArgsRGB
;
550 const GLuint numAlphaArgs
= texUnit
->_CurrentCombine
->_NumArgsA
;
551 GLuint RGBshift
= texUnit
->_CurrentCombine
->ScaleShiftRGB
;
552 GLuint Ashift
= texUnit
->_CurrentCombine
->ScaleShiftA
;
556 * Extract the color and alpha combine function arguments.
558 for ( i
= 0 ; i
< numColorArgs
; i
++ ) {
559 const GLint op
= texUnit
->_CurrentCombine
->OperandRGB
[i
] - GL_SRC_COLOR
;
560 const GLuint srcRGBi
= texUnit
->_CurrentCombine
->SourceRGB
[i
];
565 if (texUnit
->_Current
->Image
[0][0]->_BaseFormat
== GL_ALPHA
)
566 color_arg
[i
] = radeon_zero_color
[op
];
568 color_arg
[i
] = radeon_texture_color
[op
][unit
];
571 color_arg
[i
] = radeon_tfactor_color
[op
];
573 case GL_PRIMARY_COLOR
:
574 color_arg
[i
] = radeon_primary_color
[op
];
577 color_arg
[i
] = radeon_previous_color
[op
];
580 color_arg
[i
] = radeon_zero_color
[op
];
583 color_arg
[i
] = radeon_zero_color
[op
+1];
588 GLuint txunit
= srcRGBi
- GL_TEXTURE0
;
589 if (ctx
->Texture
.Unit
[txunit
]._Current
->Image
[0][0]->_BaseFormat
== GL_ALPHA
)
590 color_arg
[i
] = radeon_zero_color
[op
];
592 /* implement ogl 1.4/1.5 core spec here, not specification of
593 * GL_ARB_texture_env_crossbar (which would require disabling blending
594 * instead of undefined results when referencing not enabled texunit) */
595 color_arg
[i
] = radeon_texture_color
[op
][txunit
];
603 for ( i
= 0 ; i
< numAlphaArgs
; i
++ ) {
604 const GLint op
= texUnit
->_CurrentCombine
->OperandA
[i
] - GL_SRC_ALPHA
;
605 const GLuint srcAi
= texUnit
->_CurrentCombine
->SourceA
[i
];
610 if (texUnit
->_Current
->Image
[0][0]->_BaseFormat
== GL_LUMINANCE
)
611 alpha_arg
[i
] = radeon_zero_alpha
[op
+1];
613 alpha_arg
[i
] = radeon_texture_alpha
[op
][unit
];
616 alpha_arg
[i
] = radeon_tfactor_alpha
[op
];
618 case GL_PRIMARY_COLOR
:
619 alpha_arg
[i
] = radeon_primary_alpha
[op
];
622 alpha_arg
[i
] = radeon_previous_alpha
[op
];
625 alpha_arg
[i
] = radeon_zero_alpha
[op
];
628 alpha_arg
[i
] = radeon_zero_alpha
[op
+1];
633 GLuint txunit
= srcAi
- GL_TEXTURE0
;
634 if (ctx
->Texture
.Unit
[txunit
]._Current
->Image
[0][0]->_BaseFormat
== GL_LUMINANCE
)
635 alpha_arg
[i
] = radeon_zero_alpha
[op
+1];
637 alpha_arg
[i
] = radeon_texture_alpha
[op
][txunit
];
646 * Build up the color and alpha combine functions.
648 switch ( texUnit
->_CurrentCombine
->ModeRGB
) {
650 color_combine
= (RADEON_COLOR_ARG_A_ZERO
|
651 RADEON_COLOR_ARG_B_ZERO
|
652 RADEON_BLEND_CTL_ADD
|
654 RADEON_COLOR_ARG( 0, C
);
657 color_combine
= (RADEON_COLOR_ARG_C_ZERO
|
658 RADEON_BLEND_CTL_ADD
|
660 RADEON_COLOR_ARG( 0, A
);
661 RADEON_COLOR_ARG( 1, B
);
664 color_combine
= (RADEON_COLOR_ARG_B_ZERO
|
666 RADEON_BLEND_CTL_ADD
|
668 RADEON_COLOR_ARG( 0, A
);
669 RADEON_COLOR_ARG( 1, C
);
672 color_combine
= (RADEON_COLOR_ARG_B_ZERO
|
674 RADEON_BLEND_CTL_ADDSIGNED
|
676 RADEON_COLOR_ARG( 0, A
);
677 RADEON_COLOR_ARG( 1, C
);
680 color_combine
= (RADEON_COLOR_ARG_B_ZERO
|
682 RADEON_BLEND_CTL_SUBTRACT
|
684 RADEON_COLOR_ARG( 0, A
);
685 RADEON_COLOR_ARG( 1, C
);
688 color_combine
= (RADEON_BLEND_CTL_BLEND
|
690 RADEON_COLOR_ARG( 0, B
);
691 RADEON_COLOR_ARG( 1, A
);
692 RADEON_COLOR_ARG( 2, C
);
695 case GL_DOT3_RGB_EXT
:
696 case GL_DOT3_RGBA_EXT
:
697 /* The EXT version of the DOT3 extension does not support the
698 * scale factor, but the ARB version (and the version in OpenGL
706 /* The R100 / RV200 only support a 1X multiplier in hardware
709 if ( RGBshift
!= (RADEON_SCALE_1X
>> RADEON_SCALE_SHIFT
) ) {
714 if ( (texUnit
->_CurrentCombine
->ModeRGB
== GL_DOT3_RGBA_EXT
)
715 || (texUnit
->_CurrentCombine
->ModeRGB
== GL_DOT3_RGBA
) ) {
716 /* is it necessary to set this or will it be ignored anyway? */
720 color_combine
= (RADEON_COLOR_ARG_C_ZERO
|
721 RADEON_BLEND_CTL_DOT3
|
723 RADEON_COLOR_ARG( 0, A
);
724 RADEON_COLOR_ARG( 1, B
);
727 case GL_MODULATE_ADD_ATI
:
728 color_combine
= (RADEON_BLEND_CTL_ADD
|
730 RADEON_COLOR_ARG( 0, A
);
731 RADEON_COLOR_ARG( 1, C
);
732 RADEON_COLOR_ARG( 2, B
);
734 case GL_MODULATE_SIGNED_ADD_ATI
:
735 color_combine
= (RADEON_BLEND_CTL_ADDSIGNED
|
737 RADEON_COLOR_ARG( 0, A
);
738 RADEON_COLOR_ARG( 1, C
);
739 RADEON_COLOR_ARG( 2, B
);
741 case GL_MODULATE_SUBTRACT_ATI
:
742 color_combine
= (RADEON_BLEND_CTL_SUBTRACT
|
744 RADEON_COLOR_ARG( 0, A
);
745 RADEON_COLOR_ARG( 1, C
);
746 RADEON_COLOR_ARG( 2, B
);
752 switch ( texUnit
->_CurrentCombine
->ModeA
) {
754 alpha_combine
= (RADEON_ALPHA_ARG_A_ZERO
|
755 RADEON_ALPHA_ARG_B_ZERO
|
756 RADEON_BLEND_CTL_ADD
|
758 RADEON_ALPHA_ARG( 0, C
);
761 alpha_combine
= (RADEON_ALPHA_ARG_C_ZERO
|
762 RADEON_BLEND_CTL_ADD
|
764 RADEON_ALPHA_ARG( 0, A
);
765 RADEON_ALPHA_ARG( 1, B
);
768 alpha_combine
= (RADEON_ALPHA_ARG_B_ZERO
|
770 RADEON_BLEND_CTL_ADD
|
772 RADEON_ALPHA_ARG( 0, A
);
773 RADEON_ALPHA_ARG( 1, C
);
776 alpha_combine
= (RADEON_ALPHA_ARG_B_ZERO
|
778 RADEON_BLEND_CTL_ADDSIGNED
|
780 RADEON_ALPHA_ARG( 0, A
);
781 RADEON_ALPHA_ARG( 1, C
);
784 alpha_combine
= (RADEON_COLOR_ARG_B_ZERO
|
786 RADEON_BLEND_CTL_SUBTRACT
|
788 RADEON_ALPHA_ARG( 0, A
);
789 RADEON_ALPHA_ARG( 1, C
);
792 alpha_combine
= (RADEON_BLEND_CTL_BLEND
|
794 RADEON_ALPHA_ARG( 0, B
);
795 RADEON_ALPHA_ARG( 1, A
);
796 RADEON_ALPHA_ARG( 2, C
);
799 case GL_MODULATE_ADD_ATI
:
800 alpha_combine
= (RADEON_BLEND_CTL_ADD
|
802 RADEON_ALPHA_ARG( 0, A
);
803 RADEON_ALPHA_ARG( 1, C
);
804 RADEON_ALPHA_ARG( 2, B
);
806 case GL_MODULATE_SIGNED_ADD_ATI
:
807 alpha_combine
= (RADEON_BLEND_CTL_ADDSIGNED
|
809 RADEON_ALPHA_ARG( 0, A
);
810 RADEON_ALPHA_ARG( 1, C
);
811 RADEON_ALPHA_ARG( 2, B
);
813 case GL_MODULATE_SUBTRACT_ATI
:
814 alpha_combine
= (RADEON_BLEND_CTL_SUBTRACT
|
816 RADEON_ALPHA_ARG( 0, A
);
817 RADEON_ALPHA_ARG( 1, C
);
818 RADEON_ALPHA_ARG( 2, B
);
824 if ( (texUnit
->_CurrentCombine
->ModeRGB
== GL_DOT3_RGB_EXT
)
825 || (texUnit
->_CurrentCombine
->ModeRGB
== GL_DOT3_RGB
) ) {
826 alpha_combine
|= RADEON_DOT_ALPHA_DONT_REPLICATE
;
830 * Apply the scale factor.
832 color_combine
|= (RGBshift
<< RADEON_SCALE_SHIFT
);
833 alpha_combine
|= (Ashift
<< RADEON_SCALE_SHIFT
);
839 if ( rmesa
->hw
.tex
[unit
].cmd
[TEX_PP_TXCBLEND
] != color_combine
||
840 rmesa
->hw
.tex
[unit
].cmd
[TEX_PP_TXABLEND
] != alpha_combine
) {
841 RADEON_STATECHANGE( rmesa
, tex
[unit
] );
842 rmesa
->hw
.tex
[unit
].cmd
[TEX_PP_TXCBLEND
] = color_combine
;
843 rmesa
->hw
.tex
[unit
].cmd
[TEX_PP_TXABLEND
] = alpha_combine
;
849 void radeonSetTexOffset(__DRIcontext
* pDRICtx
, GLint texname
,
850 unsigned long long offset
, GLint depth
, GLuint pitch
)
852 r100ContextPtr rmesa
= pDRICtx
->driverPrivate
;
853 struct gl_texture_object
*tObj
=
854 _mesa_lookup_texture(rmesa
->radeon
.glCtx
, texname
);
860 t
= (radeonTexObjPtr
) tObj
->DriverData
;
862 t
->image_override
= GL_TRUE
;
867 t
->pp_txoffset
= offset
;
868 t
->pp_txpitch
= pitch
- 32;
872 t
->pp_txformat
= tx_table
[MESA_FORMAT_ARGB8888
].format
;
873 t
->pp_txfilter
|= tx_table
[MESA_FORMAT_ARGB8888
].filter
;
877 t
->pp_txformat
= tx_table
[MESA_FORMAT_RGB888
].format
;
878 t
->pp_txfilter
|= tx_table
[MESA_FORMAT_RGB888
].filter
;
881 t
->pp_txformat
= tx_table
[MESA_FORMAT_RGB565
].format
;
882 t
->pp_txfilter
|= tx_table
[MESA_FORMAT_RGB565
].filter
;
887 #define TEXOBJ_TXFILTER_MASK (RADEON_MAX_MIP_LEVEL_MASK | \
888 RADEON_MIN_FILTER_MASK | \
889 RADEON_MAG_FILTER_MASK | \
890 RADEON_MAX_ANISO_MASK | \
891 RADEON_YUV_TO_RGB | \
892 RADEON_YUV_TEMPERATURE_MASK | \
893 RADEON_CLAMP_S_MASK | \
894 RADEON_CLAMP_T_MASK | \
895 RADEON_BORDER_MODE_D3D )
897 #define TEXOBJ_TXFORMAT_MASK (RADEON_TXFORMAT_WIDTH_MASK | \
898 RADEON_TXFORMAT_HEIGHT_MASK | \
899 RADEON_TXFORMAT_FORMAT_MASK | \
900 RADEON_TXFORMAT_F5_WIDTH_MASK | \
901 RADEON_TXFORMAT_F5_HEIGHT_MASK | \
902 RADEON_TXFORMAT_ALPHA_IN_MAP | \
903 RADEON_TXFORMAT_CUBIC_MAP_ENABLE | \
904 RADEON_TXFORMAT_NON_POWER2)
907 static void import_tex_obj_state( r100ContextPtr rmesa
,
909 radeonTexObjPtr texobj
)
911 /* do not use RADEON_DB_STATE to avoid stale texture caches */
912 uint32_t *cmd
= &rmesa
->hw
.tex
[unit
].cmd
[TEX_CMD_0
];
913 GLuint se_coord_fmt
= rmesa
->hw
.set
.cmd
[SET_SE_COORDFMT
];
915 RADEON_STATECHANGE( rmesa
, tex
[unit
] );
917 cmd
[TEX_PP_TXFILTER
] &= ~TEXOBJ_TXFILTER_MASK
;
918 cmd
[TEX_PP_TXFILTER
] |= texobj
->pp_txfilter
& TEXOBJ_TXFILTER_MASK
;
919 cmd
[TEX_PP_TXFORMAT
] &= ~TEXOBJ_TXFORMAT_MASK
;
920 cmd
[TEX_PP_TXFORMAT
] |= texobj
->pp_txformat
& TEXOBJ_TXFORMAT_MASK
;
921 cmd
[TEX_PP_TXOFFSET
] = texobj
->pp_txoffset
;
922 cmd
[TEX_PP_BORDER_COLOR
] = texobj
->pp_border_color
;
924 if (texobj
->base
.tObj
->Target
== GL_TEXTURE_RECTANGLE_NV
) {
925 GLuint
*txr_cmd
= RADEON_DB_STATE( txr
[unit
] );
926 txr_cmd
[TXR_PP_TEX_SIZE
] = texobj
->pp_txsize
; /* NPOT only! */
927 txr_cmd
[TXR_PP_TEX_PITCH
] = texobj
->pp_txpitch
; /* NPOT only! */
928 RADEON_DB_STATECHANGE( rmesa
, &rmesa
->hw
.txr
[unit
] );
929 se_coord_fmt
|= RADEON_VTX_ST0_NONPARAMETRIC
<< unit
;
932 se_coord_fmt
&= ~(RADEON_VTX_ST0_NONPARAMETRIC
<< unit
);
934 if (texobj
->base
.tObj
->Target
== GL_TEXTURE_CUBE_MAP
) {
935 int *cube_cmd
= &rmesa
->hw
.cube
[unit
].cmd
[CUBE_CMD_0
];
936 GLuint bytesPerFace
= texobj
->base
.totalSize
/ 6;
937 ASSERT(texobj
->base
.totalSize
% 6 == 0);
939 RADEON_STATECHANGE( rmesa
, cube
[unit
] );
940 cube_cmd
[CUBE_PP_CUBIC_FACES
] = texobj
->pp_cubic_faces
;
941 /* dont know if this setup conforms to OpenGL..
942 * at least it matches the behavior of mesa software renderer
944 cube_cmd
[CUBE_PP_CUBIC_OFFSET_0
] = texobj
->pp_txoffset
; /* right */
945 cube_cmd
[CUBE_PP_CUBIC_OFFSET_1
] = texobj
->pp_txoffset
+ 1 * bytesPerFace
; /* left */
946 cube_cmd
[CUBE_PP_CUBIC_OFFSET_2
] = texobj
->pp_txoffset
+ 2 * bytesPerFace
; /* top */
947 cube_cmd
[CUBE_PP_CUBIC_OFFSET_3
] = texobj
->pp_txoffset
+ 3 * bytesPerFace
; /* bottom */
948 cube_cmd
[CUBE_PP_CUBIC_OFFSET_4
] = texobj
->pp_txoffset
+ 4 * bytesPerFace
; /* front */
949 cmd
[TEX_PP_TXOFFSET
] = texobj
->pp_txoffset
+ 5 * bytesPerFace
; /* back */
953 if (se_coord_fmt
!= rmesa
->hw
.set
.cmd
[SET_SE_COORDFMT
]) {
954 RADEON_STATECHANGE( rmesa
, set
);
955 rmesa
->hw
.set
.cmd
[SET_SE_COORDFMT
] = se_coord_fmt
;
958 texobj
->dirty_state
&= ~(1<<unit
);
964 static void set_texgen_matrix( r100ContextPtr rmesa
,
966 const GLfloat
*s_plane
,
967 const GLfloat
*t_plane
,
968 const GLfloat
*r_plane
,
969 const GLfloat
*q_plane
)
971 rmesa
->TexGenMatrix
[unit
].m
[0] = s_plane
[0];
972 rmesa
->TexGenMatrix
[unit
].m
[4] = s_plane
[1];
973 rmesa
->TexGenMatrix
[unit
].m
[8] = s_plane
[2];
974 rmesa
->TexGenMatrix
[unit
].m
[12] = s_plane
[3];
976 rmesa
->TexGenMatrix
[unit
].m
[1] = t_plane
[0];
977 rmesa
->TexGenMatrix
[unit
].m
[5] = t_plane
[1];
978 rmesa
->TexGenMatrix
[unit
].m
[9] = t_plane
[2];
979 rmesa
->TexGenMatrix
[unit
].m
[13] = t_plane
[3];
981 rmesa
->TexGenMatrix
[unit
].m
[2] = r_plane
[0];
982 rmesa
->TexGenMatrix
[unit
].m
[6] = r_plane
[1];
983 rmesa
->TexGenMatrix
[unit
].m
[10] = r_plane
[2];
984 rmesa
->TexGenMatrix
[unit
].m
[14] = r_plane
[3];
986 rmesa
->TexGenMatrix
[unit
].m
[3] = q_plane
[0];
987 rmesa
->TexGenMatrix
[unit
].m
[7] = q_plane
[1];
988 rmesa
->TexGenMatrix
[unit
].m
[11] = q_plane
[2];
989 rmesa
->TexGenMatrix
[unit
].m
[15] = q_plane
[3];
991 rmesa
->TexGenEnabled
|= RADEON_TEXMAT_0_ENABLE
<< unit
;
992 rmesa
->radeon
.NewGLState
|= _NEW_TEXTURE_MATRIX
;
995 /* Returns GL_FALSE if fallback required.
997 static GLboolean
radeon_validate_texgen( GLcontext
*ctx
, GLuint unit
)
999 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
1000 struct gl_texture_unit
*texUnit
= &ctx
->Texture
.Unit
[unit
];
1001 GLuint inputshift
= RADEON_TEXGEN_0_INPUT_SHIFT
+ unit
*4;
1002 GLuint tmp
= rmesa
->TexGenEnabled
;
1003 static const GLfloat reflect
[16] = {
1009 rmesa
->TexGenEnabled
&= ~(RADEON_TEXGEN_TEXMAT_0_ENABLE
<< unit
);
1010 rmesa
->TexGenEnabled
&= ~(RADEON_TEXMAT_0_ENABLE
<< unit
);
1011 rmesa
->TexGenEnabled
&= ~(RADEON_TEXGEN_INPUT_MASK
<< inputshift
);
1012 rmesa
->TexGenNeedNormals
[unit
] = 0;
1014 if ((texUnit
->TexGenEnabled
& (S_BIT
|T_BIT
|R_BIT
|Q_BIT
)) == 0) {
1015 /* Disabled, no fallback:
1017 rmesa
->TexGenEnabled
|=
1018 (RADEON_TEXGEN_INPUT_TEXCOORD_0
+ unit
) << inputshift
;
1021 /* the r100 cannot do texgen for some coords and not for others
1022 * we do not detect such cases (certainly can't do it here) and just
1023 * ASSUME that when S and T are texgen enabled we do not need other
1024 * non-texgen enabled coords, no matter if the R and Q bits are texgen
1025 * enabled. Still check for mixed mode texgen for all coords.
1027 else if ( (texUnit
->TexGenEnabled
& S_BIT
) &&
1028 (texUnit
->TexGenEnabled
& T_BIT
) &&
1029 (texUnit
->GenModeS
== texUnit
->GenModeT
) ) {
1030 if ( ((texUnit
->TexGenEnabled
& R_BIT
) &&
1031 (texUnit
->GenModeS
!= texUnit
->GenModeR
)) ||
1032 ((texUnit
->TexGenEnabled
& Q_BIT
) &&
1033 (texUnit
->GenModeS
!= texUnit
->GenModeQ
)) ) {
1034 /* Mixed modes, fallback:
1036 if (RADEON_DEBUG
& DEBUG_FALLBACKS
)
1037 fprintf(stderr
, "fallback mixed texgen\n");
1040 rmesa
->TexGenEnabled
|= RADEON_TEXGEN_TEXMAT_0_ENABLE
<< unit
;
1043 /* some texgen mode not including both S and T bits */
1044 if (RADEON_DEBUG
& DEBUG_FALLBACKS
)
1045 fprintf(stderr
, "fallback mixed texgen/nontexgen\n");
1049 if ((texUnit
->TexGenEnabled
& (R_BIT
| Q_BIT
)) != 0) {
1050 /* need this here for vtxfmt presumably. Argh we need to set
1051 this from way too many places, would be much easier if we could leave
1052 tcl q coord always enabled as on r200) */
1053 RADEON_STATECHANGE( rmesa
, tcl
);
1054 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXFMT
] |= RADEON_Q_BIT(unit
);
1057 switch (texUnit
->GenModeS
) {
1058 case GL_OBJECT_LINEAR
:
1059 rmesa
->TexGenEnabled
|= RADEON_TEXGEN_INPUT_OBJ
<< inputshift
;
1060 set_texgen_matrix( rmesa
, unit
,
1061 texUnit
->ObjectPlaneS
,
1062 texUnit
->ObjectPlaneT
,
1063 texUnit
->ObjectPlaneR
,
1064 texUnit
->ObjectPlaneQ
);
1068 rmesa
->TexGenEnabled
|= RADEON_TEXGEN_INPUT_EYE
<< inputshift
;
1069 set_texgen_matrix( rmesa
, unit
,
1073 texUnit
->EyePlaneQ
);
1076 case GL_REFLECTION_MAP_NV
:
1077 rmesa
->TexGenNeedNormals
[unit
] = GL_TRUE
;
1078 rmesa
->TexGenEnabled
|= RADEON_TEXGEN_INPUT_EYE_REFLECT
<< inputshift
;
1079 /* TODO: unknown if this is needed/correct */
1080 set_texgen_matrix( rmesa
, unit
, reflect
, reflect
+ 4,
1081 reflect
+ 8, reflect
+ 12 );
1084 case GL_NORMAL_MAP_NV
:
1085 rmesa
->TexGenNeedNormals
[unit
] = GL_TRUE
;
1086 rmesa
->TexGenEnabled
|= RADEON_TEXGEN_INPUT_EYE_NORMAL
<< inputshift
;
1090 /* the mode which everyone uses :-( */
1092 /* Unsupported mode, fallback:
1094 if (RADEON_DEBUG
& DEBUG_FALLBACKS
)
1095 fprintf(stderr
, "fallback GL_SPHERE_MAP\n");
1099 if (tmp
!= rmesa
->TexGenEnabled
) {
1100 rmesa
->radeon
.NewGLState
|= _NEW_TEXTURE_MATRIX
;
1107 static void disable_tex( GLcontext
*ctx
, int unit
)
1109 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
1111 if (rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] & (RADEON_TEX_0_ENABLE
<<unit
)) {
1112 /* Texture unit disabled */
1113 if ( rmesa
->state
.texture
.unit
[unit
].texobj
!= NULL
) {
1114 /* The old texture is no longer bound to this texture unit.
1118 rmesa
->state
.texture
.unit
[unit
].texobj
->base
.bound
&= ~(1UL << unit
);
1119 rmesa
->state
.texture
.unit
[unit
].texobj
= NULL
;
1122 RADEON_STATECHANGE( rmesa
, ctx
);
1123 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] &=
1124 ~((RADEON_TEX_0_ENABLE
| RADEON_TEX_BLEND_0_ENABLE
) << unit
);
1126 RADEON_STATECHANGE( rmesa
, tcl
);
1127 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXFMT
] &= ~(RADEON_ST_BIT(unit
) |
1128 RADEON_Q_BIT(unit
));
1130 if (rmesa
->radeon
.TclFallback
& (RADEON_TCL_FALLBACK_TEXGEN_0
<<unit
)) {
1131 TCL_FALLBACK( ctx
, (RADEON_TCL_FALLBACK_TEXGEN_0
<<unit
), GL_FALSE
);
1132 rmesa
->recheck_texgen
[unit
] = GL_TRUE
;
1135 if (rmesa
->hw
.tex
[unit
].cmd
[TEX_PP_TXFORMAT
] & RADEON_TXFORMAT_CUBIC_MAP_ENABLE
) {
1136 /* this seems to be a genuine (r100 only?) hw bug. Need to remove the
1137 cubic_map bit on unit 2 when the unit is disabled, otherwise every
1138 2nd (2d) mipmap on unit 0 will be broken (may not be needed for other
1139 units, better be safe than sorry though).*/
1140 RADEON_STATECHANGE( rmesa
, tex
[unit
] );
1141 rmesa
->hw
.tex
[unit
].cmd
[TEX_PP_TXFORMAT
] &= ~RADEON_TXFORMAT_CUBIC_MAP_ENABLE
;
1145 GLuint inputshift
= RADEON_TEXGEN_0_INPUT_SHIFT
+ unit
*4;
1146 GLuint tmp
= rmesa
->TexGenEnabled
;
1148 rmesa
->TexGenEnabled
&= ~(RADEON_TEXGEN_TEXMAT_0_ENABLE
<<unit
);
1149 rmesa
->TexGenEnabled
&= ~(RADEON_TEXMAT_0_ENABLE
<<unit
);
1150 rmesa
->TexGenEnabled
&= ~(RADEON_TEXGEN_INPUT_MASK
<<inputshift
);
1151 rmesa
->TexGenNeedNormals
[unit
] = 0;
1152 rmesa
->TexGenEnabled
|=
1153 (RADEON_TEXGEN_INPUT_TEXCOORD_0
+unit
) << inputshift
;
1155 if (tmp
!= rmesa
->TexGenEnabled
) {
1156 rmesa
->recheck_texgen
[unit
] = GL_TRUE
;
1157 rmesa
->radeon
.NewGLState
|= _NEW_TEXTURE_MATRIX
;
1163 static GLboolean
enable_tex_2d( GLcontext
*ctx
, int unit
)
1165 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
1166 struct gl_texture_unit
*texUnit
= &ctx
->Texture
.Unit
[unit
];
1167 struct gl_texture_object
*tObj
= texUnit
->_Current
;
1168 radeonTexObjPtr t
= (radeonTexObjPtr
) tObj
->DriverData
;
1170 /* Need to load the 2d images associated with this unit.
1172 if (t
->pp_txformat
& RADEON_TXFORMAT_NON_POWER2
) {
1173 t
->pp_txformat
&= ~RADEON_TXFORMAT_NON_POWER2
;
1174 t
->base
.dirty_images
[0] = ~0;
1177 ASSERT(tObj
->Target
== GL_TEXTURE_2D
|| tObj
->Target
== GL_TEXTURE_1D
);
1179 if ( t
->base
.dirty_images
[0] ) {
1180 RADEON_FIREVERTICES( rmesa
);
1181 radeonSetTexImages( rmesa
, tObj
);
1182 radeonUploadTexImages( rmesa
, (radeonTexObjPtr
) tObj
->DriverData
, 0 );
1183 if ( !t
->base
.memBlock
&& !t
->image_override
)
1190 static GLboolean
enable_tex_cube( GLcontext
*ctx
, int unit
)
1192 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
1193 struct gl_texture_unit
*texUnit
= &ctx
->Texture
.Unit
[unit
];
1194 struct gl_texture_object
*tObj
= texUnit
->_Current
;
1195 radeonTexObjPtr t
= (radeonTexObjPtr
) tObj
->DriverData
;
1198 /* Need to load the 2d images associated with this unit.
1200 if (t
->pp_txformat
& RADEON_TXFORMAT_NON_POWER2
) {
1201 t
->pp_txformat
&= ~RADEON_TXFORMAT_NON_POWER2
;
1202 for (face
= 0; face
< 6; face
++)
1203 t
->base
.dirty_images
[face
] = ~0;
1206 ASSERT(tObj
->Target
== GL_TEXTURE_CUBE_MAP
);
1208 if ( t
->base
.dirty_images
[0] || t
->base
.dirty_images
[1] ||
1209 t
->base
.dirty_images
[2] || t
->base
.dirty_images
[3] ||
1210 t
->base
.dirty_images
[4] || t
->base
.dirty_images
[5] ) {
1212 RADEON_FIREVERTICES( rmesa
);
1213 /* layout memory space, once for all faces */
1214 radeonSetTexImages( rmesa
, tObj
);
1217 /* upload (per face) */
1218 for (face
= 0; face
< 6; face
++) {
1219 if (t
->base
.dirty_images
[face
]) {
1220 radeonUploadTexImages( rmesa
, (radeonTexObjPtr
) tObj
->DriverData
, face
);
1224 if ( !t
->base
.memBlock
) {
1225 /* texmem alloc failed, use s/w fallback */
1232 static GLboolean
enable_tex_rect( GLcontext
*ctx
, int unit
)
1234 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
1235 struct gl_texture_unit
*texUnit
= &ctx
->Texture
.Unit
[unit
];
1236 struct gl_texture_object
*tObj
= texUnit
->_Current
;
1237 radeonTexObjPtr t
= (radeonTexObjPtr
) tObj
->DriverData
;
1239 if (!(t
->pp_txformat
& RADEON_TXFORMAT_NON_POWER2
)) {
1240 t
->pp_txformat
|= RADEON_TXFORMAT_NON_POWER2
;
1241 t
->base
.dirty_images
[0] = ~0;
1244 ASSERT(tObj
->Target
== GL_TEXTURE_RECTANGLE_NV
);
1246 if ( t
->base
.dirty_images
[0] ) {
1247 RADEON_FIREVERTICES( rmesa
);
1248 radeonSetTexImages( rmesa
, tObj
);
1249 radeonUploadTexImages( rmesa
, (radeonTexObjPtr
) tObj
->DriverData
, 0 );
1250 if ( !t
->base
.memBlock
&&
1251 !t
->image_override
/* && !rmesa->prefer_gart_client_texturing FIXME */ ) {
1252 fprintf(stderr
, "%s: upload failed\n", __FUNCTION__
);
1261 static GLboolean
update_tex_common( GLcontext
*ctx
, int unit
)
1263 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
1264 struct gl_texture_unit
*texUnit
= &ctx
->Texture
.Unit
[unit
];
1265 struct gl_texture_object
*tObj
= texUnit
->_Current
;
1266 radeonTexObjPtr t
= (radeonTexObjPtr
) tObj
->DriverData
;
1269 /* Fallback if there's a texture border */
1270 if ( tObj
->Image
[0][tObj
->BaseLevel
]->Border
> 0 ) {
1271 fprintf(stderr
, "%s: border\n", __FUNCTION__
);
1274 /* yuv conversion only works in first unit */
1275 if (unit
!= 0 && (t
->pp_txfilter
& RADEON_YUV_TO_RGB
))
1278 /* Update state if this is a different texture object to last
1281 if ( rmesa
->state
.texture
.unit
[unit
].texobj
!= t
) {
1282 if ( rmesa
->state
.texture
.unit
[unit
].texobj
!= NULL
) {
1283 /* The old texture is no longer bound to this texture unit.
1287 rmesa
->state
.texture
.unit
[unit
].texobj
->base
.bound
&=
1291 rmesa
->state
.texture
.unit
[unit
].texobj
= t
;
1292 t
->base
.bound
|= (1UL << unit
);
1293 t
->dirty_state
|= 1<<unit
;
1294 driUpdateTextureLRU( (driTextureObject
*) t
); /* XXX: should be locked! */
1300 if ( !(rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] & (RADEON_TEX_0_ENABLE
<<unit
))) {
1301 RADEON_STATECHANGE( rmesa
, ctx
);
1302 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] |=
1303 (RADEON_TEX_0_ENABLE
| RADEON_TEX_BLEND_0_ENABLE
) << unit
;
1305 RADEON_STATECHANGE( rmesa
, tcl
);
1307 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXFMT
] |= RADEON_ST_BIT(unit
);
1309 rmesa
->recheck_texgen
[unit
] = GL_TRUE
;
1312 if (t
->dirty_state
& (1<<unit
)) {
1313 import_tex_obj_state( rmesa
, unit
, t
);
1314 /* may need to update texture matrix (for texrect adjustments) */
1315 rmesa
->radeon
.NewGLState
|= _NEW_TEXTURE_MATRIX
;
1318 if (rmesa
->recheck_texgen
[unit
]) {
1319 GLboolean fallback
= !radeon_validate_texgen( ctx
, unit
);
1320 TCL_FALLBACK( ctx
, (RADEON_TCL_FALLBACK_TEXGEN_0
<<unit
), fallback
);
1321 rmesa
->recheck_texgen
[unit
] = 0;
1322 rmesa
->radeon
.NewGLState
|= _NEW_TEXTURE_MATRIX
;
1325 format
= tObj
->Image
[0][tObj
->BaseLevel
]->_BaseFormat
;
1326 if ( rmesa
->state
.texture
.unit
[unit
].format
!= format
||
1327 rmesa
->state
.texture
.unit
[unit
].envMode
!= texUnit
->EnvMode
) {
1328 rmesa
->state
.texture
.unit
[unit
].format
= format
;
1329 rmesa
->state
.texture
.unit
[unit
].envMode
= texUnit
->EnvMode
;
1330 if ( ! radeonUpdateTextureEnv( ctx
, unit
) ) {
1335 FALLBACK( rmesa
, RADEON_FALLBACK_BORDER_MODE
, t
->border_fallback
);
1336 return !t
->border_fallback
;
1341 * Compute the cached hardware register values for the given texture object.
1343 * \param rmesa Context pointer
1344 * \param t the r300 texture object
1346 static void setup_hardware_state(r100ContextPtr rmesa
, radeonTexObj
*t
)
1348 const struct gl_texture_image
*firstImage
=
1349 t
->base
.Image
[0][t
->mt
->firstLevel
];
1350 GLint log2Width
, log2Height
, log2Depth
, texelBytes
;
1352 log2Width
= firstImage
->WidthLog2
;
1353 log2Height
= firstImage
->HeightLog2
;
1354 log2Depth
= firstImage
->DepthLog2
;
1355 texelBytes
= firstImage
->TexFormat
->TexelBytes
;
1357 if (!t
->image_override
) {
1358 if (VALID_FORMAT(firstImage
->TexFormat
->MesaFormat
)) {
1359 const struct tx_table
*table
= tx_table
;
1361 t
->pp_txformat
&= ~(RADEON_TXFORMAT_FORMAT_MASK
|
1362 RADEON_TXFORMAT_ALPHA_IN_MAP
);
1363 t
->pp_txfilter
&= ~RADEON_YUV_TO_RGB
;
1365 // t->pp_txformat |= table[ firstImage->TexFormat->MesaFormat ].format;
1366 // t->pp_txfilter |= table[ firstImage->TexFormat->MesaFormat ].filter;
1368 _mesa_problem(NULL
, "unexpected texture format in %s",
1374 t
->pp_txfilter
&= ~RADEON_MAX_MIP_LEVEL_MASK
;
1375 t
->pp_txfilter
|= (t
->mt
->lastLevel
- t
->mt
->firstLevel
) << RADEON_MAX_MIP_LEVEL_SHIFT
;
1377 t
->pp_txformat
&= ~(RADEON_TXFORMAT_WIDTH_MASK
|
1378 RADEON_TXFORMAT_HEIGHT_MASK
|
1379 RADEON_TXFORMAT_CUBIC_MAP_ENABLE
|
1380 RADEON_TXFORMAT_F5_WIDTH_MASK
|
1381 RADEON_TXFORMAT_F5_HEIGHT_MASK
);
1382 t
->pp_txformat
|= ((log2Width
<< RADEON_TXFORMAT_WIDTH_SHIFT
) |
1383 (log2Height
<< RADEON_TXFORMAT_HEIGHT_SHIFT
));
1387 if (t
->base
.Target
== GL_TEXTURE_CUBE_MAP
) {
1388 ASSERT(log2Width
== log2Height
);
1389 t
->pp_txformat
|= ((log2Width
<< RADEON_TXFORMAT_F5_WIDTH_SHIFT
) |
1390 (log2Height
<< RADEON_TXFORMAT_F5_HEIGHT_SHIFT
) |
1391 /* don't think we need this bit, if it exists at all - fglrx does not set it */
1392 (RADEON_TXFORMAT_CUBIC_MAP_ENABLE
));
1393 t
->pp_cubic_faces
= ((log2Width
<< RADEON_FACE_WIDTH_1_SHIFT
) |
1394 (log2Height
<< RADEON_FACE_HEIGHT_1_SHIFT
) |
1395 (log2Width
<< RADEON_FACE_WIDTH_2_SHIFT
) |
1396 (log2Height
<< RADEON_FACE_HEIGHT_2_SHIFT
) |
1397 (log2Width
<< RADEON_FACE_WIDTH_3_SHIFT
) |
1398 (log2Height
<< RADEON_FACE_HEIGHT_3_SHIFT
) |
1399 (log2Width
<< RADEON_FACE_WIDTH_4_SHIFT
) |
1400 (log2Height
<< RADEON_FACE_HEIGHT_4_SHIFT
));
1403 t
->pp_txsize
= (((firstImage
->Width
- 1) << RADEON_TEX_USIZE_SHIFT
)
1404 | ((firstImage
->Height
- 1) << RADEON_TEX_VSIZE_SHIFT
));
1406 if ( !t
->image_override
) {
1407 if (firstImage
->IsCompressed
)
1408 t
->pp_txpitch
= (firstImage
->Width
+ 63) & ~(63);
1410 t
->pp_txpitch
= ((firstImage
->Width
* texelBytes
) + 63) & ~(63);
1411 t
->pp_txpitch
-= 32;
1414 if (t
->base
.Target
== GL_TEXTURE_RECTANGLE_NV
) {
1415 t
->pp_txformat
|= RADEON_TXFORMAT_NON_POWER2
;
1420 static GLboolean
radeonUpdateTextureUnit( GLcontext
*ctx
, int unit
)
1422 struct gl_texture_unit
*texUnit
= &ctx
->Texture
.Unit
[unit
];
1424 if ( texUnit
->_ReallyEnabled
& (TEXTURE_RECT_BIT
) ) {
1425 return (enable_tex_rect( ctx
, unit
) &&
1426 update_tex_common( ctx
, unit
));
1428 else if ( texUnit
->_ReallyEnabled
& (TEXTURE_1D_BIT
| TEXTURE_2D_BIT
) ) {
1429 return (enable_tex_2d( ctx
, unit
) &&
1430 update_tex_common( ctx
, unit
));
1432 else if ( texUnit
->_ReallyEnabled
& (TEXTURE_CUBE_BIT
) ) {
1433 return (enable_tex_cube( ctx
, unit
) &&
1434 update_tex_common( ctx
, unit
));
1436 else if ( texUnit
->_ReallyEnabled
) {
1440 disable_tex( ctx
, unit
);
1446 static GLboolean
radeonUpdateTextureUnit( GLcontext
*ctx
, int unit
)
1448 struct gl_texture_unit
*texUnit
= &ctx
->Texture
.Unit
[unit
];
1452 void radeonUpdateTextureState( GLcontext
*ctx
)
1454 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
1457 ok
= (radeonUpdateTextureUnit( ctx
, 0 ) &&
1458 radeonUpdateTextureUnit( ctx
, 1 ) &&
1459 radeonUpdateTextureUnit( ctx
, 2 ));
1461 FALLBACK( rmesa
, RADEON_FALLBACK_TEXTURE
, !ok
);
1463 if (rmesa
->radeon
.TclFallback
)
1464 radeonChooseVertexState( ctx
);