1 /* $XFree86: xc/lib/GL/mesa/src/drv/radeon/radeon_tex.c,v 1.6 2002/09/16 18:05:20 eich Exp $ */
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.
31 * Gareth Hughes <gareth@valinux.com>
32 * Brian Paul <brianp@valinux.com>
41 #include "simple_list.h"
42 #include "texformat.h"
48 #include "radeon_context.h"
49 #include "radeon_state.h"
50 #include "radeon_ioctl.h"
51 #include "radeon_swtcl.h"
52 #include "radeon_tex.h"
59 * Set the texture wrap modes.
61 * \param t Texture object whose wrap modes are to be set
62 * \param swrap Wrap mode for the \a s texture coordinate
63 * \param twrap Wrap mode for the \a t texture coordinate
66 static void radeonSetTexWrap( radeonTexObjPtr t
, GLenum swrap
, GLenum twrap
)
68 GLboolean is_clamp
= GL_FALSE
;
69 GLboolean is_clamp_to_border
= GL_FALSE
;
71 t
->pp_txfilter
&= ~(RADEON_CLAMP_S_MASK
| RADEON_CLAMP_T_MASK
| RADEON_BORDER_MODE_D3D
);
75 t
->pp_txfilter
|= RADEON_CLAMP_S_WRAP
;
78 t
->pp_txfilter
|= RADEON_CLAMP_S_CLAMP_GL
;
81 case GL_CLAMP_TO_EDGE
:
82 t
->pp_txfilter
|= RADEON_CLAMP_S_CLAMP_LAST
;
84 case GL_CLAMP_TO_BORDER
:
85 t
->pp_txfilter
|= RADEON_CLAMP_S_CLAMP_GL
;
86 is_clamp_to_border
= GL_TRUE
;
88 case GL_MIRRORED_REPEAT
:
89 t
->pp_txfilter
|= RADEON_CLAMP_S_MIRROR
;
91 case GL_MIRROR_CLAMP_EXT
:
92 t
->pp_txfilter
|= RADEON_CLAMP_S_MIRROR_CLAMP_GL
;
95 case GL_MIRROR_CLAMP_TO_EDGE_EXT
:
96 t
->pp_txfilter
|= RADEON_CLAMP_S_MIRROR_CLAMP_LAST
;
98 case GL_MIRROR_CLAMP_TO_BORDER_EXT
:
99 t
->pp_txfilter
|= RADEON_CLAMP_S_MIRROR_CLAMP_GL
;
100 is_clamp_to_border
= GL_TRUE
;
103 _mesa_problem(NULL
, "bad S wrap mode in %s", __FUNCTION__
);
108 t
->pp_txfilter
|= RADEON_CLAMP_T_WRAP
;
111 t
->pp_txfilter
|= RADEON_CLAMP_T_CLAMP_GL
;
114 case GL_CLAMP_TO_EDGE
:
115 t
->pp_txfilter
|= RADEON_CLAMP_T_CLAMP_LAST
;
117 case GL_CLAMP_TO_BORDER
:
118 t
->pp_txfilter
|= RADEON_CLAMP_T_CLAMP_GL
;
119 is_clamp_to_border
= GL_TRUE
;
121 case GL_MIRRORED_REPEAT
:
122 t
->pp_txfilter
|= RADEON_CLAMP_T_MIRROR
;
124 case GL_MIRROR_CLAMP_EXT
:
125 t
->pp_txfilter
|= RADEON_CLAMP_T_MIRROR_CLAMP_GL
;
128 case GL_MIRROR_CLAMP_TO_EDGE_EXT
:
129 t
->pp_txfilter
|= RADEON_CLAMP_T_MIRROR_CLAMP_LAST
;
131 case GL_MIRROR_CLAMP_TO_BORDER_EXT
:
132 t
->pp_txfilter
|= RADEON_CLAMP_T_MIRROR_CLAMP_GL
;
133 is_clamp_to_border
= GL_TRUE
;
136 _mesa_problem(NULL
, "bad T wrap mode in %s", __FUNCTION__
);
139 if ( is_clamp_to_border
) {
140 t
->pp_txfilter
|= RADEON_BORDER_MODE_D3D
;
143 t
->border_fallback
= (is_clamp
&& is_clamp_to_border
);
146 static void radeonSetTexMaxAnisotropy( radeonTexObjPtr t
, GLfloat max
)
148 t
->pp_txfilter
&= ~RADEON_MAX_ANISO_MASK
;
151 t
->pp_txfilter
|= RADEON_MAX_ANISO_1_TO_1
;
152 } else if ( max
<= 2.0 ) {
153 t
->pp_txfilter
|= RADEON_MAX_ANISO_2_TO_1
;
154 } else if ( max
<= 4.0 ) {
155 t
->pp_txfilter
|= RADEON_MAX_ANISO_4_TO_1
;
156 } else if ( max
<= 8.0 ) {
157 t
->pp_txfilter
|= RADEON_MAX_ANISO_8_TO_1
;
159 t
->pp_txfilter
|= RADEON_MAX_ANISO_16_TO_1
;
164 * Set the texture magnification and minification modes.
166 * \param t Texture whose filter modes are to be set
167 * \param minf Texture minification mode
168 * \param magf Texture magnification mode
171 static void radeonSetTexFilter( radeonTexObjPtr t
, GLenum minf
, GLenum magf
)
173 GLuint anisotropy
= (t
->pp_txfilter
& RADEON_MAX_ANISO_MASK
);
175 t
->pp_txfilter
&= ~(RADEON_MIN_FILTER_MASK
| RADEON_MAG_FILTER_MASK
);
177 /* r100 chips can't handle mipmaps/aniso for cubemap/volume textures */
178 if ( t
->base
.tObj
->Target
== GL_TEXTURE_CUBE_MAP
) {
181 case GL_NEAREST_MIPMAP_NEAREST
:
182 case GL_NEAREST_MIPMAP_LINEAR
:
183 t
->pp_txfilter
|= RADEON_MIN_FILTER_NEAREST
;
186 case GL_LINEAR_MIPMAP_NEAREST
:
187 case GL_LINEAR_MIPMAP_LINEAR
:
188 t
->pp_txfilter
|= RADEON_MIN_FILTER_LINEAR
;
194 else if ( anisotropy
== RADEON_MAX_ANISO_1_TO_1
) {
197 t
->pp_txfilter
|= RADEON_MIN_FILTER_NEAREST
;
200 t
->pp_txfilter
|= RADEON_MIN_FILTER_LINEAR
;
202 case GL_NEAREST_MIPMAP_NEAREST
:
203 t
->pp_txfilter
|= RADEON_MIN_FILTER_NEAREST_MIP_NEAREST
;
205 case GL_NEAREST_MIPMAP_LINEAR
:
206 t
->pp_txfilter
|= RADEON_MIN_FILTER_LINEAR_MIP_NEAREST
;
208 case GL_LINEAR_MIPMAP_NEAREST
:
209 t
->pp_txfilter
|= RADEON_MIN_FILTER_NEAREST_MIP_LINEAR
;
211 case GL_LINEAR_MIPMAP_LINEAR
:
212 t
->pp_txfilter
|= RADEON_MIN_FILTER_LINEAR_MIP_LINEAR
;
218 t
->pp_txfilter
|= RADEON_MIN_FILTER_ANISO_NEAREST
;
221 t
->pp_txfilter
|= RADEON_MIN_FILTER_ANISO_LINEAR
;
223 case GL_NEAREST_MIPMAP_NEAREST
:
224 case GL_LINEAR_MIPMAP_NEAREST
:
225 t
->pp_txfilter
|= RADEON_MIN_FILTER_ANISO_NEAREST_MIP_NEAREST
;
227 case GL_NEAREST_MIPMAP_LINEAR
:
228 case GL_LINEAR_MIPMAP_LINEAR
:
229 t
->pp_txfilter
|= RADEON_MIN_FILTER_ANISO_NEAREST_MIP_LINEAR
;
236 t
->pp_txfilter
|= RADEON_MAG_FILTER_NEAREST
;
239 t
->pp_txfilter
|= RADEON_MAG_FILTER_LINEAR
;
244 static void radeonSetTexBorderColor( radeonTexObjPtr t
, GLubyte c
[4] )
246 t
->pp_border_color
= radeonPackColor( 4, c
[0], c
[1], c
[2], c
[3] );
251 * Allocate space for and load the mesa images into the texture memory block.
252 * This will happen before drawing with a new texture, or drawing with a
253 * texture after it was swapped out or teximaged again.
256 static radeonTexObjPtr
radeonAllocTexObj( struct gl_texture_object
*texObj
)
260 t
= CALLOC_STRUCT( radeon_tex_obj
);
261 texObj
->DriverData
= t
;
263 if ( RADEON_DEBUG
& DEBUG_TEXTURE
) {
264 fprintf( stderr
, "%s( %p, %p )\n", __FUNCTION__
, (void *)texObj
, (void *)t
);
267 /* Initialize non-image-dependent parts of the state:
269 t
->base
.tObj
= texObj
;
270 t
->border_fallback
= GL_FALSE
;
272 t
->pp_txfilter
= RADEON_BORDER_MODE_OGL
;
273 t
->pp_txformat
= (RADEON_TXFORMAT_ENDIAN_NO_SWAP
|
274 RADEON_TXFORMAT_PERSPECTIVE_ENABLE
);
276 make_empty_list( & t
->base
);
278 radeonSetTexWrap( t
, texObj
->WrapS
, texObj
->WrapT
);
279 radeonSetTexMaxAnisotropy( t
, texObj
->MaxAnisotropy
);
280 radeonSetTexFilter( t
, texObj
->MinFilter
, texObj
->MagFilter
);
281 radeonSetTexBorderColor( t
, texObj
->_BorderChan
);
288 static const struct gl_texture_format
*
289 radeonChooseTextureFormat( GLcontext
*ctx
, GLint internalFormat
,
290 GLenum format
, GLenum type
)
292 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
293 const GLboolean do32bpt
=
294 ( rmesa
->texture_depth
== DRI_CONF_TEXTURE_DEPTH_32
);
295 const GLboolean force16bpt
=
296 ( rmesa
->texture_depth
== DRI_CONF_TEXTURE_DEPTH_FORCE_16
);
299 switch ( internalFormat
) {
302 case GL_COMPRESSED_RGBA
:
304 case GL_UNSIGNED_INT_10_10_10_2
:
305 case GL_UNSIGNED_INT_2_10_10_10_REV
:
306 return do32bpt
? _dri_texformat_argb8888
: _dri_texformat_argb1555
;
307 case GL_UNSIGNED_SHORT_4_4_4_4
:
308 case GL_UNSIGNED_SHORT_4_4_4_4_REV
:
309 return _dri_texformat_argb4444
;
310 case GL_UNSIGNED_SHORT_5_5_5_1
:
311 case GL_UNSIGNED_SHORT_1_5_5_5_REV
:
312 return _dri_texformat_argb1555
;
314 return do32bpt
? _dri_texformat_rgba8888
: _dri_texformat_argb4444
;
319 case GL_COMPRESSED_RGB
:
321 case GL_UNSIGNED_SHORT_4_4_4_4
:
322 case GL_UNSIGNED_SHORT_4_4_4_4_REV
:
323 return _dri_texformat_argb4444
;
324 case GL_UNSIGNED_SHORT_5_5_5_1
:
325 case GL_UNSIGNED_SHORT_1_5_5_5_REV
:
326 return _dri_texformat_argb1555
;
327 case GL_UNSIGNED_SHORT_5_6_5
:
328 case GL_UNSIGNED_SHORT_5_6_5_REV
:
329 return _dri_texformat_rgb565
;
331 return do32bpt
? _dri_texformat_rgba8888
: _dri_texformat_rgb565
;
339 _dri_texformat_rgba8888
: _dri_texformat_argb4444
;
343 return _dri_texformat_argb4444
;
346 return _dri_texformat_argb1555
;
352 return !force16bpt
? _dri_texformat_rgba8888
: _dri_texformat_rgb565
;
357 return _dri_texformat_rgb565
;
364 case GL_COMPRESSED_ALPHA
:
365 return _dri_texformat_a8
;
373 case GL_COMPRESSED_LUMINANCE
:
374 return _dri_texformat_l8
;
377 case GL_LUMINANCE_ALPHA
:
378 case GL_LUMINANCE4_ALPHA4
:
379 case GL_LUMINANCE6_ALPHA2
:
380 case GL_LUMINANCE8_ALPHA8
:
381 case GL_LUMINANCE12_ALPHA4
:
382 case GL_LUMINANCE12_ALPHA12
:
383 case GL_LUMINANCE16_ALPHA16
:
384 case GL_COMPRESSED_LUMINANCE_ALPHA
:
385 return _dri_texformat_al88
;
392 case GL_COMPRESSED_INTENSITY
:
393 return _dri_texformat_i8
;
396 if (type
== GL_UNSIGNED_SHORT_8_8_APPLE
||
397 type
== GL_UNSIGNED_BYTE
)
398 return &_mesa_texformat_ycbcr
;
400 return &_mesa_texformat_ycbcr_rev
;
404 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT
:
405 return &_mesa_texformat_rgb_dxt1
;
407 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT
:
408 return &_mesa_texformat_rgba_dxt1
;
412 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT
:
413 return &_mesa_texformat_rgba_dxt3
;
415 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT
:
416 return &_mesa_texformat_rgba_dxt5
;
419 _mesa_problem(ctx
, "unexpected texture format in %s", __FUNCTION__
);
423 return NULL
; /* never get here */
427 static void radeonTexImage1D( GLcontext
*ctx
, GLenum target
, GLint level
,
428 GLint internalFormat
,
429 GLint width
, GLint border
,
430 GLenum format
, GLenum type
, const GLvoid
*pixels
,
431 const struct gl_pixelstore_attrib
*packing
,
432 struct gl_texture_object
*texObj
,
433 struct gl_texture_image
*texImage
)
435 driTextureObject
* t
= (driTextureObject
*) texObj
->DriverData
;
438 driSwapOutTextureObject( t
);
441 t
= (driTextureObject
*) radeonAllocTexObj( texObj
);
443 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage1D");
448 /* Note, this will call ChooseTextureFormat */
449 _mesa_store_teximage1d(ctx
, target
, level
, internalFormat
,
450 width
, border
, format
, type
, pixels
,
451 &ctx
->Unpack
, texObj
, texImage
);
453 t
->dirty_images
[0] |= (1 << level
);
457 static void radeonTexSubImage1D( GLcontext
*ctx
, GLenum target
, GLint level
,
460 GLenum format
, GLenum type
,
461 const GLvoid
*pixels
,
462 const struct gl_pixelstore_attrib
*packing
,
463 struct gl_texture_object
*texObj
,
464 struct gl_texture_image
*texImage
)
466 driTextureObject
* t
= (driTextureObject
*) texObj
->DriverData
;
468 assert( t
); /* this _should_ be true */
470 driSwapOutTextureObject( t
);
473 t
= (driTextureObject
*) radeonAllocTexObj( texObj
);
475 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexSubImage1D");
480 _mesa_store_texsubimage1d(ctx
, target
, level
, xoffset
, width
,
481 format
, type
, pixels
, packing
, texObj
,
484 t
->dirty_images
[0] |= (1 << level
);
488 static void radeonTexImage2D( GLcontext
*ctx
, GLenum target
, GLint level
,
489 GLint internalFormat
,
490 GLint width
, GLint height
, GLint border
,
491 GLenum format
, GLenum type
, const GLvoid
*pixels
,
492 const struct gl_pixelstore_attrib
*packing
,
493 struct gl_texture_object
*texObj
,
494 struct gl_texture_image
*texImage
)
496 driTextureObject
* t
= (driTextureObject
*) texObj
->DriverData
;
499 /* which cube face or ordinary 2D image */
501 case GL_TEXTURE_CUBE_MAP_POSITIVE_X
:
502 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X
:
503 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y
:
504 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y
:
505 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z
:
506 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z
:
507 face
= (GLuint
) target
- (GLuint
) GL_TEXTURE_CUBE_MAP_POSITIVE_X
;
515 driSwapOutTextureObject( t
);
518 t
= (driTextureObject
*) radeonAllocTexObj( texObj
);
520 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage2D");
525 /* Note, this will call ChooseTextureFormat */
526 _mesa_store_teximage2d(ctx
, target
, level
, internalFormat
,
527 width
, height
, border
, format
, type
, pixels
,
528 &ctx
->Unpack
, texObj
, texImage
);
530 t
->dirty_images
[face
] |= (1 << level
);
534 static void radeonTexSubImage2D( GLcontext
*ctx
, GLenum target
, GLint level
,
535 GLint xoffset
, GLint yoffset
,
536 GLsizei width
, GLsizei height
,
537 GLenum format
, GLenum type
,
538 const GLvoid
*pixels
,
539 const struct gl_pixelstore_attrib
*packing
,
540 struct gl_texture_object
*texObj
,
541 struct gl_texture_image
*texImage
)
543 driTextureObject
* t
= (driTextureObject
*) texObj
->DriverData
;
546 /* which cube face or ordinary 2D image */
548 case GL_TEXTURE_CUBE_MAP_POSITIVE_X
:
549 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X
:
550 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y
:
551 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y
:
552 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z
:
553 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z
:
554 face
= (GLuint
) target
- (GLuint
) GL_TEXTURE_CUBE_MAP_POSITIVE_X
;
561 assert( t
); /* this _should_ be true */
563 driSwapOutTextureObject( t
);
566 t
= (driTextureObject
*) radeonAllocTexObj( texObj
);
568 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexSubImage2D");
573 _mesa_store_texsubimage2d(ctx
, target
, level
, xoffset
, yoffset
, width
,
574 height
, format
, type
, pixels
, packing
, texObj
,
577 t
->dirty_images
[face
] |= (1 << level
);
580 static void radeonCompressedTexImage2D( GLcontext
*ctx
, GLenum target
, GLint level
,
581 GLint internalFormat
,
582 GLint width
, GLint height
, GLint border
,
583 GLsizei imageSize
, const GLvoid
*data
,
584 struct gl_texture_object
*texObj
,
585 struct gl_texture_image
*texImage
)
587 driTextureObject
* t
= (driTextureObject
*) texObj
->DriverData
;
590 /* which cube face or ordinary 2D image */
592 case GL_TEXTURE_CUBE_MAP_POSITIVE_X
:
593 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X
:
594 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y
:
595 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y
:
596 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z
:
597 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z
:
598 face
= (GLuint
) target
- (GLuint
) GL_TEXTURE_CUBE_MAP_POSITIVE_X
;
606 driSwapOutTextureObject( t
);
609 t
= (driTextureObject
*) radeonAllocTexObj( texObj
);
611 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glCompressedTexImage2D");
616 /* Note, this will call ChooseTextureFormat */
617 _mesa_store_compressed_teximage2d(ctx
, target
, level
, internalFormat
, width
,
618 height
, border
, imageSize
, data
, texObj
, texImage
);
620 t
->dirty_images
[face
] |= (1 << level
);
624 static void radeonCompressedTexSubImage2D( GLcontext
*ctx
, GLenum target
, GLint level
,
625 GLint xoffset
, GLint yoffset
,
626 GLsizei width
, GLsizei height
,
628 GLsizei imageSize
, const GLvoid
*data
,
629 struct gl_texture_object
*texObj
,
630 struct gl_texture_image
*texImage
)
632 driTextureObject
* t
= (driTextureObject
*) texObj
->DriverData
;
636 /* which cube face or ordinary 2D image */
638 case GL_TEXTURE_CUBE_MAP_POSITIVE_X
:
639 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X
:
640 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y
:
641 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y
:
642 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z
:
643 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z
:
644 face
= (GLuint
) target
- (GLuint
) GL_TEXTURE_CUBE_MAP_POSITIVE_X
;
651 assert( t
); /* this _should_ be true */
653 driSwapOutTextureObject( t
);
656 t
= (driTextureObject
*) radeonAllocTexObj( texObj
);
658 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glCompressedTexSubImage2D");
663 _mesa_store_compressed_texsubimage2d(ctx
, target
, level
, xoffset
, yoffset
, width
,
664 height
, format
, imageSize
, data
, texObj
, texImage
);
666 t
->dirty_images
[face
] |= (1 << level
);
669 #define SCALED_FLOAT_TO_BYTE( x, scale ) \
670 (((GLuint)((255.0F / scale) * (x))) / 2)
672 static void radeonTexEnv( GLcontext
*ctx
, GLenum target
,
673 GLenum pname
, const GLfloat
*param
)
675 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
676 GLuint unit
= ctx
->Texture
.CurrentUnit
;
677 struct gl_texture_unit
*texUnit
= &ctx
->Texture
.Unit
[unit
];
679 if ( RADEON_DEBUG
& DEBUG_STATE
) {
680 fprintf( stderr
, "%s( %s )\n",
681 __FUNCTION__
, _mesa_lookup_enum_by_nr( pname
) );
685 case GL_TEXTURE_ENV_COLOR
: {
688 UNCLAMPED_FLOAT_TO_RGBA_CHAN( c
, texUnit
->EnvColor
);
689 envColor
= radeonPackColor( 4, c
[0], c
[1], c
[2], c
[3] );
690 if ( rmesa
->hw
.tex
[unit
].cmd
[TEX_PP_TFACTOR
] != envColor
) {
691 RADEON_STATECHANGE( rmesa
, tex
[unit
] );
692 rmesa
->hw
.tex
[unit
].cmd
[TEX_PP_TFACTOR
] = envColor
;
697 case GL_TEXTURE_LOD_BIAS_EXT
: {
701 /* The Radeon's LOD bias is a signed 2's complement value with a
702 * range of -1.0 <= bias < 4.0. We break this into two linear
703 * functions, one mapping [-1.0,0.0] to [-128,0] and one mapping
704 * [0.0,4.0] to [0,127].
706 min
= driQueryOptionb (&rmesa
->optionCache
, "no_neg_lod_bias") ?
708 bias
= CLAMP( *param
, min
, 4.0 );
711 } else if ( bias
> 0 ) {
712 b
= ((GLuint
)SCALED_FLOAT_TO_BYTE( bias
, 4.0 )) << RADEON_LOD_BIAS_SHIFT
;
714 b
= ((GLuint
)SCALED_FLOAT_TO_BYTE( bias
, 1.0 )) << RADEON_LOD_BIAS_SHIFT
;
716 if ( (rmesa
->hw
.tex
[unit
].cmd
[TEX_PP_TXFILTER
] & RADEON_LOD_BIAS_MASK
) != b
) {
717 RADEON_STATECHANGE( rmesa
, tex
[unit
] );
718 rmesa
->hw
.tex
[unit
].cmd
[TEX_PP_TXFILTER
] &= ~RADEON_LOD_BIAS_MASK
;
719 rmesa
->hw
.tex
[unit
].cmd
[TEX_PP_TXFILTER
] |= (b
& RADEON_LOD_BIAS_MASK
);
731 * Changes variables and flags for a state update, which will happen at the
732 * next UpdateTextureState
735 static void radeonTexParameter( GLcontext
*ctx
, GLenum target
,
736 struct gl_texture_object
*texObj
,
737 GLenum pname
, const GLfloat
*params
)
739 radeonTexObjPtr t
= (radeonTexObjPtr
) texObj
->DriverData
;
741 if ( RADEON_DEBUG
& (DEBUG_STATE
|DEBUG_TEXTURE
) ) {
742 fprintf( stderr
, "%s( %s )\n", __FUNCTION__
,
743 _mesa_lookup_enum_by_nr( pname
) );
747 case GL_TEXTURE_MIN_FILTER
:
748 case GL_TEXTURE_MAG_FILTER
:
749 case GL_TEXTURE_MAX_ANISOTROPY_EXT
:
750 radeonSetTexMaxAnisotropy( t
, texObj
->MaxAnisotropy
);
751 radeonSetTexFilter( t
, texObj
->MinFilter
, texObj
->MagFilter
);
754 case GL_TEXTURE_WRAP_S
:
755 case GL_TEXTURE_WRAP_T
:
756 radeonSetTexWrap( t
, texObj
->WrapS
, texObj
->WrapT
);
759 case GL_TEXTURE_BORDER_COLOR
:
760 radeonSetTexBorderColor( t
, texObj
->_BorderChan
);
763 case GL_TEXTURE_BASE_LEVEL
:
764 case GL_TEXTURE_MAX_LEVEL
:
765 case GL_TEXTURE_MIN_LOD
:
766 case GL_TEXTURE_MAX_LOD
:
767 /* This isn't the most efficient solution but there doesn't appear to
768 * be a nice alternative. Since there's no LOD clamping,
769 * we just have to rely on loading the right subset of mipmap levels
770 * to simulate a clamped LOD.
772 driSwapOutTextureObject( (driTextureObject
*) t
);
779 /* Mark this texobj as dirty (one bit per tex unit)
781 t
->dirty_state
= TEX_ALL
;
785 static void radeonBindTexture( GLcontext
*ctx
, GLenum target
,
786 struct gl_texture_object
*texObj
)
788 if ( RADEON_DEBUG
& (DEBUG_STATE
|DEBUG_TEXTURE
) ) {
789 fprintf( stderr
, "%s( %p ) unit=%d\n", __FUNCTION__
, (void *)texObj
,
790 ctx
->Texture
.CurrentUnit
);
793 assert( (target
!= GL_TEXTURE_1D
&& target
!= GL_TEXTURE_2D
&&
794 target
!= GL_TEXTURE_RECTANGLE_NV
&& target
!= GL_TEXTURE_CUBE_MAP
) ||
795 (texObj
->DriverData
!= NULL
) );
799 static void radeonDeleteTexture( GLcontext
*ctx
,
800 struct gl_texture_object
*texObj
)
802 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
803 driTextureObject
* t
= (driTextureObject
*) texObj
->DriverData
;
805 if ( RADEON_DEBUG
& (DEBUG_STATE
|DEBUG_TEXTURE
) ) {
806 fprintf( stderr
, "%s( %p (target = %s) )\n", __FUNCTION__
, (void *)texObj
,
807 _mesa_lookup_enum_by_nr( texObj
->Target
) );
812 RADEON_FIREVERTICES( rmesa
);
815 driDestroyTextureObject( t
);
818 /* Free mipmap images and the texture object itself */
819 _mesa_delete_texture_object(ctx
, texObj
);
823 * - Same GEN_MODE for all active bits
824 * - Same EyePlane/ObjPlane for all active bits when using Eye/Obj
825 * - STRQ presumably all supported (matrix means incoming R values
826 * can end up in STQ, this has implications for vertex support,
827 * presumably ok if maos is used, though?)
829 * Basically impossible to do this on the fly - just collect some
830 * basic info & do the checks from ValidateState().
832 static void radeonTexGen( GLcontext
*ctx
,
835 const GLfloat
*params
)
837 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
838 GLuint unit
= ctx
->Texture
.CurrentUnit
;
839 rmesa
->recheck_texgen
[unit
] = GL_TRUE
;
843 * Allocate a new texture object.
844 * Called via ctx->Driver.NewTextureObject.
845 * Note: we could use containment here to 'derive' the driver-specific
846 * texture object from the core mesa gl_texture_object. Not done at this time.
848 static struct gl_texture_object
*
849 radeonNewTextureObject( GLcontext
*ctx
, GLuint name
, GLenum target
)
851 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
852 struct gl_texture_object
*obj
;
853 obj
= _mesa_new_texture_object(ctx
, name
, target
);
856 obj
->MaxAnisotropy
= rmesa
->initialMaxAnisotropy
;
857 radeonAllocTexObj( obj
);
862 void radeonInitTextureFuncs( struct dd_function_table
*functions
)
864 functions
->ChooseTextureFormat
= radeonChooseTextureFormat
;
865 functions
->TexImage1D
= radeonTexImage1D
;
866 functions
->TexImage2D
= radeonTexImage2D
;
867 functions
->TexSubImage1D
= radeonTexSubImage1D
;
868 functions
->TexSubImage2D
= radeonTexSubImage2D
;
870 functions
->NewTextureObject
= radeonNewTextureObject
;
871 functions
->BindTexture
= radeonBindTexture
;
872 functions
->DeleteTexture
= radeonDeleteTexture
;
873 functions
->IsTextureResident
= driIsTextureResident
;
875 functions
->TexEnv
= radeonTexEnv
;
876 functions
->TexParameter
= radeonTexParameter
;
877 functions
->TexGen
= radeonTexGen
;
879 functions
->CompressedTexImage2D
= radeonCompressedTexImage2D
;
880 functions
->CompressedTexSubImage2D
= radeonCompressedTexSubImage2D
;
882 driInitTextureFormats();