2 Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and
3 VA Linux Systems Inc., Fremont, California.
7 Permission is hereby granted, free of charge, to any person obtaining
8 a copy of this software and associated documentation files (the
9 "Software"), to deal in the Software without restriction, including
10 without limitation the rights to use, copy, modify, merge, publish,
11 distribute, sublicense, and/or sell copies of the Software, and to
12 permit persons to whom the Software is furnished to do so, subject to
13 the following conditions:
15 The above copyright notice and this permission notice (including the
16 next paragraph) shall be included in all copies or substantial
17 portions of the Software.
19 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
20 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
22 IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
23 LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
24 OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
25 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
30 * Gareth Hughes <gareth@valinux.com>
31 * Brian Paul <brianp@valinux.com>
40 #include "simple_list.h"
41 #include "texformat.h"
47 #include "radeon_context.h"
48 #include "radeon_state.h"
49 #include "radeon_ioctl.h"
50 #include "radeon_swtcl.h"
51 #include "radeon_tex.h"
58 * Set the texture wrap modes.
60 * \param t Texture object whose wrap modes are to be set
61 * \param swrap Wrap mode for the \a s texture coordinate
62 * \param twrap Wrap mode for the \a t texture coordinate
65 static void radeonSetTexWrap( radeonTexObjPtr t
, GLenum swrap
, GLenum twrap
)
67 GLboolean is_clamp
= GL_FALSE
;
68 GLboolean is_clamp_to_border
= GL_FALSE
;
70 t
->pp_txfilter
&= ~(RADEON_CLAMP_S_MASK
| RADEON_CLAMP_T_MASK
| RADEON_BORDER_MODE_D3D
);
74 t
->pp_txfilter
|= RADEON_CLAMP_S_WRAP
;
77 t
->pp_txfilter
|= RADEON_CLAMP_S_CLAMP_GL
;
80 case GL_CLAMP_TO_EDGE
:
81 t
->pp_txfilter
|= RADEON_CLAMP_S_CLAMP_LAST
;
83 case GL_CLAMP_TO_BORDER
:
84 t
->pp_txfilter
|= RADEON_CLAMP_S_CLAMP_GL
;
85 is_clamp_to_border
= GL_TRUE
;
87 case GL_MIRRORED_REPEAT
:
88 t
->pp_txfilter
|= RADEON_CLAMP_S_MIRROR
;
90 case GL_MIRROR_CLAMP_EXT
:
91 t
->pp_txfilter
|= RADEON_CLAMP_S_MIRROR_CLAMP_GL
;
94 case GL_MIRROR_CLAMP_TO_EDGE_EXT
:
95 t
->pp_txfilter
|= RADEON_CLAMP_S_MIRROR_CLAMP_LAST
;
97 case GL_MIRROR_CLAMP_TO_BORDER_EXT
:
98 t
->pp_txfilter
|= RADEON_CLAMP_S_MIRROR_CLAMP_GL
;
99 is_clamp_to_border
= GL_TRUE
;
102 _mesa_problem(NULL
, "bad S wrap mode in %s", __FUNCTION__
);
107 t
->pp_txfilter
|= RADEON_CLAMP_T_WRAP
;
110 t
->pp_txfilter
|= RADEON_CLAMP_T_CLAMP_GL
;
113 case GL_CLAMP_TO_EDGE
:
114 t
->pp_txfilter
|= RADEON_CLAMP_T_CLAMP_LAST
;
116 case GL_CLAMP_TO_BORDER
:
117 t
->pp_txfilter
|= RADEON_CLAMP_T_CLAMP_GL
;
118 is_clamp_to_border
= GL_TRUE
;
120 case GL_MIRRORED_REPEAT
:
121 t
->pp_txfilter
|= RADEON_CLAMP_T_MIRROR
;
123 case GL_MIRROR_CLAMP_EXT
:
124 t
->pp_txfilter
|= RADEON_CLAMP_T_MIRROR_CLAMP_GL
;
127 case GL_MIRROR_CLAMP_TO_EDGE_EXT
:
128 t
->pp_txfilter
|= RADEON_CLAMP_T_MIRROR_CLAMP_LAST
;
130 case GL_MIRROR_CLAMP_TO_BORDER_EXT
:
131 t
->pp_txfilter
|= RADEON_CLAMP_T_MIRROR_CLAMP_GL
;
132 is_clamp_to_border
= GL_TRUE
;
135 _mesa_problem(NULL
, "bad T wrap mode in %s", __FUNCTION__
);
138 if ( is_clamp_to_border
) {
139 t
->pp_txfilter
|= RADEON_BORDER_MODE_D3D
;
142 t
->border_fallback
= (is_clamp
&& is_clamp_to_border
);
145 static void radeonSetTexMaxAnisotropy( radeonTexObjPtr t
, GLfloat max
)
147 t
->pp_txfilter
&= ~RADEON_MAX_ANISO_MASK
;
150 t
->pp_txfilter
|= RADEON_MAX_ANISO_1_TO_1
;
151 } else if ( max
<= 2.0 ) {
152 t
->pp_txfilter
|= RADEON_MAX_ANISO_2_TO_1
;
153 } else if ( max
<= 4.0 ) {
154 t
->pp_txfilter
|= RADEON_MAX_ANISO_4_TO_1
;
155 } else if ( max
<= 8.0 ) {
156 t
->pp_txfilter
|= RADEON_MAX_ANISO_8_TO_1
;
158 t
->pp_txfilter
|= RADEON_MAX_ANISO_16_TO_1
;
163 * Set the texture magnification and minification modes.
165 * \param t Texture whose filter modes are to be set
166 * \param minf Texture minification mode
167 * \param magf Texture magnification mode
170 static void radeonSetTexFilter( radeonTexObjPtr t
, GLenum minf
, GLenum magf
)
172 GLuint anisotropy
= (t
->pp_txfilter
& RADEON_MAX_ANISO_MASK
);
174 t
->pp_txfilter
&= ~(RADEON_MIN_FILTER_MASK
| RADEON_MAG_FILTER_MASK
);
176 /* r100 chips can't handle mipmaps/aniso for cubemap/volume textures */
177 if ( t
->base
.tObj
->Target
== GL_TEXTURE_CUBE_MAP
) {
180 case GL_NEAREST_MIPMAP_NEAREST
:
181 case GL_NEAREST_MIPMAP_LINEAR
:
182 t
->pp_txfilter
|= RADEON_MIN_FILTER_NEAREST
;
185 case GL_LINEAR_MIPMAP_NEAREST
:
186 case GL_LINEAR_MIPMAP_LINEAR
:
187 t
->pp_txfilter
|= RADEON_MIN_FILTER_LINEAR
;
193 else if ( anisotropy
== RADEON_MAX_ANISO_1_TO_1
) {
196 t
->pp_txfilter
|= RADEON_MIN_FILTER_NEAREST
;
199 t
->pp_txfilter
|= RADEON_MIN_FILTER_LINEAR
;
201 case GL_NEAREST_MIPMAP_NEAREST
:
202 t
->pp_txfilter
|= RADEON_MIN_FILTER_NEAREST_MIP_NEAREST
;
204 case GL_NEAREST_MIPMAP_LINEAR
:
205 t
->pp_txfilter
|= RADEON_MIN_FILTER_LINEAR_MIP_NEAREST
;
207 case GL_LINEAR_MIPMAP_NEAREST
:
208 t
->pp_txfilter
|= RADEON_MIN_FILTER_NEAREST_MIP_LINEAR
;
210 case GL_LINEAR_MIPMAP_LINEAR
:
211 t
->pp_txfilter
|= RADEON_MIN_FILTER_LINEAR_MIP_LINEAR
;
217 t
->pp_txfilter
|= RADEON_MIN_FILTER_ANISO_NEAREST
;
220 t
->pp_txfilter
|= RADEON_MIN_FILTER_ANISO_LINEAR
;
222 case GL_NEAREST_MIPMAP_NEAREST
:
223 case GL_LINEAR_MIPMAP_NEAREST
:
224 t
->pp_txfilter
|= RADEON_MIN_FILTER_ANISO_NEAREST_MIP_NEAREST
;
226 case GL_NEAREST_MIPMAP_LINEAR
:
227 case GL_LINEAR_MIPMAP_LINEAR
:
228 t
->pp_txfilter
|= RADEON_MIN_FILTER_ANISO_NEAREST_MIP_LINEAR
;
235 t
->pp_txfilter
|= RADEON_MAG_FILTER_NEAREST
;
238 t
->pp_txfilter
|= RADEON_MAG_FILTER_LINEAR
;
243 static void radeonSetTexBorderColor( radeonTexObjPtr t
, GLubyte c
[4] )
245 t
->pp_border_color
= radeonPackColor( 4, c
[0], c
[1], c
[2], c
[3] );
250 * Allocate space for and load the mesa images into the texture memory block.
251 * This will happen before drawing with a new texture, or drawing with a
252 * texture after it was swapped out or teximaged again.
255 static radeonTexObjPtr
radeonAllocTexObj( struct gl_texture_object
*texObj
)
259 t
= CALLOC_STRUCT( radeon_tex_obj
);
260 texObj
->DriverData
= t
;
262 if ( RADEON_DEBUG
& DEBUG_TEXTURE
) {
263 fprintf( stderr
, "%s( %p, %p )\n", __FUNCTION__
, (void *)texObj
, (void *)t
);
266 /* Initialize non-image-dependent parts of the state:
268 t
->base
.tObj
= texObj
;
269 t
->border_fallback
= GL_FALSE
;
271 t
->pp_txfilter
= RADEON_BORDER_MODE_OGL
;
272 t
->pp_txformat
= (RADEON_TXFORMAT_ENDIAN_NO_SWAP
|
273 RADEON_TXFORMAT_PERSPECTIVE_ENABLE
);
275 make_empty_list( & t
->base
);
277 radeonSetTexWrap( t
, texObj
->WrapS
, texObj
->WrapT
);
278 radeonSetTexMaxAnisotropy( t
, texObj
->MaxAnisotropy
);
279 radeonSetTexFilter( t
, texObj
->MinFilter
, texObj
->MagFilter
);
280 radeonSetTexBorderColor( t
, texObj
->_BorderChan
);
287 static const struct gl_texture_format
*
288 radeonChooseTextureFormat( GLcontext
*ctx
, GLint internalFormat
,
289 GLenum format
, GLenum type
)
291 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
292 const GLboolean do32bpt
=
293 ( rmesa
->texture_depth
== DRI_CONF_TEXTURE_DEPTH_32
);
294 const GLboolean force16bpt
=
295 ( rmesa
->texture_depth
== DRI_CONF_TEXTURE_DEPTH_FORCE_16
);
298 switch ( internalFormat
) {
301 case GL_COMPRESSED_RGBA
:
303 case GL_UNSIGNED_INT_10_10_10_2
:
304 case GL_UNSIGNED_INT_2_10_10_10_REV
:
305 return do32bpt
? _dri_texformat_argb8888
: _dri_texformat_argb1555
;
306 case GL_UNSIGNED_SHORT_4_4_4_4
:
307 case GL_UNSIGNED_SHORT_4_4_4_4_REV
:
308 return _dri_texformat_argb4444
;
309 case GL_UNSIGNED_SHORT_5_5_5_1
:
310 case GL_UNSIGNED_SHORT_1_5_5_5_REV
:
311 return _dri_texformat_argb1555
;
313 return do32bpt
? _dri_texformat_argb8888
: _dri_texformat_argb4444
;
318 case GL_COMPRESSED_RGB
:
320 case GL_UNSIGNED_SHORT_4_4_4_4
:
321 case GL_UNSIGNED_SHORT_4_4_4_4_REV
:
322 return _dri_texformat_argb4444
;
323 case GL_UNSIGNED_SHORT_5_5_5_1
:
324 case GL_UNSIGNED_SHORT_1_5_5_5_REV
:
325 return _dri_texformat_argb1555
;
326 case GL_UNSIGNED_SHORT_5_6_5
:
327 case GL_UNSIGNED_SHORT_5_6_5_REV
:
328 return _dri_texformat_rgb565
;
330 return do32bpt
? _dri_texformat_argb8888
: _dri_texformat_rgb565
;
338 _dri_texformat_argb8888
: _dri_texformat_argb4444
;
342 return _dri_texformat_argb4444
;
345 return _dri_texformat_argb1555
;
351 return !force16bpt
? _dri_texformat_argb8888
: _dri_texformat_rgb565
;
356 return _dri_texformat_rgb565
;
363 case GL_COMPRESSED_ALPHA
:
364 return _dri_texformat_a8
;
372 case GL_COMPRESSED_LUMINANCE
:
373 return _dri_texformat_l8
;
376 case GL_LUMINANCE_ALPHA
:
377 case GL_LUMINANCE4_ALPHA4
:
378 case GL_LUMINANCE6_ALPHA2
:
379 case GL_LUMINANCE8_ALPHA8
:
380 case GL_LUMINANCE12_ALPHA4
:
381 case GL_LUMINANCE12_ALPHA12
:
382 case GL_LUMINANCE16_ALPHA16
:
383 case GL_COMPRESSED_LUMINANCE_ALPHA
:
384 return _dri_texformat_al88
;
391 case GL_COMPRESSED_INTENSITY
:
392 return _dri_texformat_i8
;
395 if (type
== GL_UNSIGNED_SHORT_8_8_APPLE
||
396 type
== GL_UNSIGNED_BYTE
)
397 return &_mesa_texformat_ycbcr
;
399 return &_mesa_texformat_ycbcr_rev
;
403 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT
:
404 return &_mesa_texformat_rgb_dxt1
;
406 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT
:
407 return &_mesa_texformat_rgba_dxt1
;
411 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT
:
412 return &_mesa_texformat_rgba_dxt3
;
414 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT
:
415 return &_mesa_texformat_rgba_dxt5
;
418 _mesa_problem(ctx
, "unexpected texture format in %s", __FUNCTION__
);
422 return NULL
; /* never get here */
426 static void radeonTexImage1D( GLcontext
*ctx
, GLenum target
, GLint level
,
427 GLint internalFormat
,
428 GLint width
, GLint border
,
429 GLenum format
, GLenum type
, const GLvoid
*pixels
,
430 const struct gl_pixelstore_attrib
*packing
,
431 struct gl_texture_object
*texObj
,
432 struct gl_texture_image
*texImage
)
434 driTextureObject
* t
= (driTextureObject
*) texObj
->DriverData
;
437 driSwapOutTextureObject( t
);
440 t
= (driTextureObject
*) radeonAllocTexObj( texObj
);
442 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage1D");
447 /* Note, this will call ChooseTextureFormat */
448 _mesa_store_teximage1d(ctx
, target
, level
, internalFormat
,
449 width
, border
, format
, type
, pixels
,
450 &ctx
->Unpack
, texObj
, texImage
);
452 t
->dirty_images
[0] |= (1 << level
);
456 static void radeonTexSubImage1D( GLcontext
*ctx
, GLenum target
, GLint level
,
459 GLenum format
, GLenum type
,
460 const GLvoid
*pixels
,
461 const struct gl_pixelstore_attrib
*packing
,
462 struct gl_texture_object
*texObj
,
463 struct gl_texture_image
*texImage
)
465 driTextureObject
* t
= (driTextureObject
*) texObj
->DriverData
;
467 assert( t
); /* this _should_ be true */
469 driSwapOutTextureObject( t
);
472 t
= (driTextureObject
*) radeonAllocTexObj( texObj
);
474 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexSubImage1D");
479 _mesa_store_texsubimage1d(ctx
, target
, level
, xoffset
, width
,
480 format
, type
, pixels
, packing
, texObj
,
483 t
->dirty_images
[0] |= (1 << level
);
487 static void radeonTexImage2D( GLcontext
*ctx
, GLenum target
, GLint level
,
488 GLint internalFormat
,
489 GLint width
, GLint height
, GLint border
,
490 GLenum format
, GLenum type
, const GLvoid
*pixels
,
491 const struct gl_pixelstore_attrib
*packing
,
492 struct gl_texture_object
*texObj
,
493 struct gl_texture_image
*texImage
)
495 driTextureObject
* t
= (driTextureObject
*) texObj
->DriverData
;
498 /* which cube face or ordinary 2D image */
500 case GL_TEXTURE_CUBE_MAP_POSITIVE_X
:
501 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X
:
502 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y
:
503 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y
:
504 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z
:
505 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z
:
506 face
= (GLuint
) target
- (GLuint
) GL_TEXTURE_CUBE_MAP_POSITIVE_X
;
514 driSwapOutTextureObject( t
);
517 t
= (driTextureObject
*) radeonAllocTexObj( texObj
);
519 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage2D");
524 /* Note, this will call ChooseTextureFormat */
525 _mesa_store_teximage2d(ctx
, target
, level
, internalFormat
,
526 width
, height
, border
, format
, type
, pixels
,
527 &ctx
->Unpack
, texObj
, texImage
);
529 t
->dirty_images
[face
] |= (1 << level
);
533 static void radeonTexSubImage2D( GLcontext
*ctx
, GLenum target
, GLint level
,
534 GLint xoffset
, GLint yoffset
,
535 GLsizei width
, GLsizei height
,
536 GLenum format
, GLenum type
,
537 const GLvoid
*pixels
,
538 const struct gl_pixelstore_attrib
*packing
,
539 struct gl_texture_object
*texObj
,
540 struct gl_texture_image
*texImage
)
542 driTextureObject
* t
= (driTextureObject
*) texObj
->DriverData
;
545 /* which cube face or ordinary 2D image */
547 case GL_TEXTURE_CUBE_MAP_POSITIVE_X
:
548 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X
:
549 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y
:
550 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y
:
551 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z
:
552 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z
:
553 face
= (GLuint
) target
- (GLuint
) GL_TEXTURE_CUBE_MAP_POSITIVE_X
;
560 assert( t
); /* this _should_ be true */
562 driSwapOutTextureObject( t
);
565 t
= (driTextureObject
*) radeonAllocTexObj( texObj
);
567 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexSubImage2D");
572 _mesa_store_texsubimage2d(ctx
, target
, level
, xoffset
, yoffset
, width
,
573 height
, format
, type
, pixels
, packing
, texObj
,
576 t
->dirty_images
[face
] |= (1 << level
);
579 static void radeonCompressedTexImage2D( GLcontext
*ctx
, GLenum target
, GLint level
,
580 GLint internalFormat
,
581 GLint width
, GLint height
, GLint border
,
582 GLsizei imageSize
, const GLvoid
*data
,
583 struct gl_texture_object
*texObj
,
584 struct gl_texture_image
*texImage
)
586 driTextureObject
* t
= (driTextureObject
*) texObj
->DriverData
;
589 /* which cube face or ordinary 2D image */
591 case GL_TEXTURE_CUBE_MAP_POSITIVE_X
:
592 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X
:
593 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y
:
594 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y
:
595 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z
:
596 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z
:
597 face
= (GLuint
) target
- (GLuint
) GL_TEXTURE_CUBE_MAP_POSITIVE_X
;
605 driSwapOutTextureObject( t
);
608 t
= (driTextureObject
*) radeonAllocTexObj( texObj
);
610 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glCompressedTexImage2D");
615 /* Note, this will call ChooseTextureFormat */
616 _mesa_store_compressed_teximage2d(ctx
, target
, level
, internalFormat
, width
,
617 height
, border
, imageSize
, data
, texObj
, texImage
);
619 t
->dirty_images
[face
] |= (1 << level
);
623 static void radeonCompressedTexSubImage2D( GLcontext
*ctx
, GLenum target
, GLint level
,
624 GLint xoffset
, GLint yoffset
,
625 GLsizei width
, GLsizei height
,
627 GLsizei imageSize
, const GLvoid
*data
,
628 struct gl_texture_object
*texObj
,
629 struct gl_texture_image
*texImage
)
631 driTextureObject
* t
= (driTextureObject
*) texObj
->DriverData
;
635 /* which cube face or ordinary 2D image */
637 case GL_TEXTURE_CUBE_MAP_POSITIVE_X
:
638 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X
:
639 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y
:
640 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y
:
641 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z
:
642 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z
:
643 face
= (GLuint
) target
- (GLuint
) GL_TEXTURE_CUBE_MAP_POSITIVE_X
;
650 assert( t
); /* this _should_ be true */
652 driSwapOutTextureObject( t
);
655 t
= (driTextureObject
*) radeonAllocTexObj( texObj
);
657 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glCompressedTexSubImage2D");
662 _mesa_store_compressed_texsubimage2d(ctx
, target
, level
, xoffset
, yoffset
, width
,
663 height
, format
, imageSize
, data
, texObj
, texImage
);
665 t
->dirty_images
[face
] |= (1 << level
);
668 #define SCALED_FLOAT_TO_BYTE( x, scale ) \
669 (((GLuint)((255.0F / scale) * (x))) / 2)
671 static void radeonTexEnv( GLcontext
*ctx
, GLenum target
,
672 GLenum pname
, const GLfloat
*param
)
674 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
675 GLuint unit
= ctx
->Texture
.CurrentUnit
;
676 struct gl_texture_unit
*texUnit
= &ctx
->Texture
.Unit
[unit
];
678 if ( RADEON_DEBUG
& DEBUG_STATE
) {
679 fprintf( stderr
, "%s( %s )\n",
680 __FUNCTION__
, _mesa_lookup_enum_by_nr( pname
) );
684 case GL_TEXTURE_ENV_COLOR
: {
687 UNCLAMPED_FLOAT_TO_RGBA_CHAN( c
, texUnit
->EnvColor
);
688 envColor
= radeonPackColor( 4, c
[0], c
[1], c
[2], c
[3] );
689 if ( rmesa
->hw
.tex
[unit
].cmd
[TEX_PP_TFACTOR
] != envColor
) {
690 RADEON_STATECHANGE( rmesa
, tex
[unit
] );
691 rmesa
->hw
.tex
[unit
].cmd
[TEX_PP_TFACTOR
] = envColor
;
696 case GL_TEXTURE_LOD_BIAS_EXT
: {
700 /* The Radeon's LOD bias is a signed 2's complement value with a
701 * range of -1.0 <= bias < 4.0. We break this into two linear
702 * functions, one mapping [-1.0,0.0] to [-128,0] and one mapping
703 * [0.0,4.0] to [0,127].
705 min
= driQueryOptionb (&rmesa
->optionCache
, "no_neg_lod_bias") ?
707 bias
= CLAMP( *param
, min
, 4.0 );
710 } else if ( bias
> 0 ) {
711 b
= ((GLuint
)SCALED_FLOAT_TO_BYTE( bias
, 4.0 )) << RADEON_LOD_BIAS_SHIFT
;
713 b
= ((GLuint
)SCALED_FLOAT_TO_BYTE( bias
, 1.0 )) << RADEON_LOD_BIAS_SHIFT
;
715 if ( (rmesa
->hw
.tex
[unit
].cmd
[TEX_PP_TXFILTER
] & RADEON_LOD_BIAS_MASK
) != b
) {
716 RADEON_STATECHANGE( rmesa
, tex
[unit
] );
717 rmesa
->hw
.tex
[unit
].cmd
[TEX_PP_TXFILTER
] &= ~RADEON_LOD_BIAS_MASK
;
718 rmesa
->hw
.tex
[unit
].cmd
[TEX_PP_TXFILTER
] |= (b
& RADEON_LOD_BIAS_MASK
);
730 * Changes variables and flags for a state update, which will happen at the
731 * next UpdateTextureState
734 static void radeonTexParameter( GLcontext
*ctx
, GLenum target
,
735 struct gl_texture_object
*texObj
,
736 GLenum pname
, const GLfloat
*params
)
738 radeonTexObjPtr t
= (radeonTexObjPtr
) texObj
->DriverData
;
740 if ( RADEON_DEBUG
& (DEBUG_STATE
|DEBUG_TEXTURE
) ) {
741 fprintf( stderr
, "%s( %s )\n", __FUNCTION__
,
742 _mesa_lookup_enum_by_nr( pname
) );
746 case GL_TEXTURE_MIN_FILTER
:
747 case GL_TEXTURE_MAG_FILTER
:
748 case GL_TEXTURE_MAX_ANISOTROPY_EXT
:
749 radeonSetTexMaxAnisotropy( t
, texObj
->MaxAnisotropy
);
750 radeonSetTexFilter( t
, texObj
->MinFilter
, texObj
->MagFilter
);
753 case GL_TEXTURE_WRAP_S
:
754 case GL_TEXTURE_WRAP_T
:
755 radeonSetTexWrap( t
, texObj
->WrapS
, texObj
->WrapT
);
758 case GL_TEXTURE_BORDER_COLOR
:
759 radeonSetTexBorderColor( t
, texObj
->_BorderChan
);
762 case GL_TEXTURE_BASE_LEVEL
:
763 case GL_TEXTURE_MAX_LEVEL
:
764 case GL_TEXTURE_MIN_LOD
:
765 case GL_TEXTURE_MAX_LOD
:
766 /* This isn't the most efficient solution but there doesn't appear to
767 * be a nice alternative. Since there's no LOD clamping,
768 * we just have to rely on loading the right subset of mipmap levels
769 * to simulate a clamped LOD.
771 driSwapOutTextureObject( (driTextureObject
*) t
);
778 /* Mark this texobj as dirty (one bit per tex unit)
780 t
->dirty_state
= TEX_ALL
;
784 static void radeonBindTexture( GLcontext
*ctx
, GLenum target
,
785 struct gl_texture_object
*texObj
)
787 if ( RADEON_DEBUG
& (DEBUG_STATE
|DEBUG_TEXTURE
) ) {
788 fprintf( stderr
, "%s( %p ) unit=%d\n", __FUNCTION__
, (void *)texObj
,
789 ctx
->Texture
.CurrentUnit
);
792 assert( (target
!= GL_TEXTURE_1D
&& target
!= GL_TEXTURE_2D
&&
793 target
!= GL_TEXTURE_RECTANGLE_NV
&& target
!= GL_TEXTURE_CUBE_MAP
) ||
794 (texObj
->DriverData
!= NULL
) );
798 static void radeonDeleteTexture( GLcontext
*ctx
,
799 struct gl_texture_object
*texObj
)
801 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
802 driTextureObject
* t
= (driTextureObject
*) texObj
->DriverData
;
804 if ( RADEON_DEBUG
& (DEBUG_STATE
|DEBUG_TEXTURE
) ) {
805 fprintf( stderr
, "%s( %p (target = %s) )\n", __FUNCTION__
, (void *)texObj
,
806 _mesa_lookup_enum_by_nr( texObj
->Target
) );
811 RADEON_FIREVERTICES( rmesa
);
814 driDestroyTextureObject( t
);
817 /* Free mipmap images and the texture object itself */
818 _mesa_delete_texture_object(ctx
, texObj
);
822 * - Same GEN_MODE for all active bits
823 * - Same EyePlane/ObjPlane for all active bits when using Eye/Obj
824 * - STRQ presumably all supported (matrix means incoming R values
825 * can end up in STQ, this has implications for vertex support,
826 * presumably ok if maos is used, though?)
828 * Basically impossible to do this on the fly - just collect some
829 * basic info & do the checks from ValidateState().
831 static void radeonTexGen( GLcontext
*ctx
,
834 const GLfloat
*params
)
836 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
837 GLuint unit
= ctx
->Texture
.CurrentUnit
;
838 rmesa
->recheck_texgen
[unit
] = GL_TRUE
;
842 * Allocate a new texture object.
843 * Called via ctx->Driver.NewTextureObject.
844 * Note: we could use containment here to 'derive' the driver-specific
845 * texture object from the core mesa gl_texture_object. Not done at this time.
847 static struct gl_texture_object
*
848 radeonNewTextureObject( GLcontext
*ctx
, GLuint name
, GLenum target
)
850 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
851 struct gl_texture_object
*obj
;
852 obj
= _mesa_new_texture_object(ctx
, name
, target
);
855 obj
->MaxAnisotropy
= rmesa
->initialMaxAnisotropy
;
856 radeonAllocTexObj( obj
);
861 void radeonInitTextureFuncs( struct dd_function_table
*functions
)
863 functions
->ChooseTextureFormat
= radeonChooseTextureFormat
;
864 functions
->TexImage1D
= radeonTexImage1D
;
865 functions
->TexImage2D
= radeonTexImage2D
;
866 functions
->TexSubImage1D
= radeonTexSubImage1D
;
867 functions
->TexSubImage2D
= radeonTexSubImage2D
;
869 functions
->NewTextureObject
= radeonNewTextureObject
;
870 functions
->BindTexture
= radeonBindTexture
;
871 functions
->DeleteTexture
= radeonDeleteTexture
;
872 functions
->IsTextureResident
= driIsTextureResident
;
874 functions
->TexEnv
= radeonTexEnv
;
875 functions
->TexParameter
= radeonTexParameter
;
876 functions
->TexGen
= radeonTexGen
;
878 functions
->CompressedTexImage2D
= radeonCompressedTexImage2D
;
879 functions
->CompressedTexSubImage2D
= radeonCompressedTexSubImage2D
;
881 driInitTextureFormats();