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>
34 #include "main/glheader.h"
35 #include "main/imports.h"
36 #include "main/colormac.h"
37 #include "main/context.h"
38 #include "main/enums.h"
39 #include "main/image.h"
40 #include "main/simple_list.h"
41 #include "main/texformat.h"
42 #include "main/texstore.h"
43 #include "main/teximage.h"
44 #include "main/texobj.h"
46 #include "radeon_context.h"
47 #include "radeon_state.h"
48 #include "radeon_ioctl.h"
49 #include "radeon_swtcl.h"
50 #include "radeon_tex.h"
57 * Set the texture wrap modes.
59 * \param t Texture object whose wrap modes are to be set
60 * \param swrap Wrap mode for the \a s texture coordinate
61 * \param twrap Wrap mode for the \a t texture coordinate
64 static void radeonSetTexWrap( radeonTexObjPtr t
, GLenum swrap
, GLenum twrap
)
66 GLboolean is_clamp
= GL_FALSE
;
67 GLboolean is_clamp_to_border
= GL_FALSE
;
69 t
->pp_txfilter
&= ~(RADEON_CLAMP_S_MASK
| RADEON_CLAMP_T_MASK
| RADEON_BORDER_MODE_D3D
);
73 t
->pp_txfilter
|= RADEON_CLAMP_S_WRAP
;
76 t
->pp_txfilter
|= RADEON_CLAMP_S_CLAMP_GL
;
79 case GL_CLAMP_TO_EDGE
:
80 t
->pp_txfilter
|= RADEON_CLAMP_S_CLAMP_LAST
;
82 case GL_CLAMP_TO_BORDER
:
83 t
->pp_txfilter
|= RADEON_CLAMP_S_CLAMP_GL
;
84 is_clamp_to_border
= GL_TRUE
;
86 case GL_MIRRORED_REPEAT
:
87 t
->pp_txfilter
|= RADEON_CLAMP_S_MIRROR
;
89 case GL_MIRROR_CLAMP_EXT
:
90 t
->pp_txfilter
|= RADEON_CLAMP_S_MIRROR_CLAMP_GL
;
93 case GL_MIRROR_CLAMP_TO_EDGE_EXT
:
94 t
->pp_txfilter
|= RADEON_CLAMP_S_MIRROR_CLAMP_LAST
;
96 case GL_MIRROR_CLAMP_TO_BORDER_EXT
:
97 t
->pp_txfilter
|= RADEON_CLAMP_S_MIRROR_CLAMP_GL
;
98 is_clamp_to_border
= GL_TRUE
;
101 _mesa_problem(NULL
, "bad S wrap mode in %s", __FUNCTION__
);
106 t
->pp_txfilter
|= RADEON_CLAMP_T_WRAP
;
109 t
->pp_txfilter
|= RADEON_CLAMP_T_CLAMP_GL
;
112 case GL_CLAMP_TO_EDGE
:
113 t
->pp_txfilter
|= RADEON_CLAMP_T_CLAMP_LAST
;
115 case GL_CLAMP_TO_BORDER
:
116 t
->pp_txfilter
|= RADEON_CLAMP_T_CLAMP_GL
;
117 is_clamp_to_border
= GL_TRUE
;
119 case GL_MIRRORED_REPEAT
:
120 t
->pp_txfilter
|= RADEON_CLAMP_T_MIRROR
;
122 case GL_MIRROR_CLAMP_EXT
:
123 t
->pp_txfilter
|= RADEON_CLAMP_T_MIRROR_CLAMP_GL
;
126 case GL_MIRROR_CLAMP_TO_EDGE_EXT
:
127 t
->pp_txfilter
|= RADEON_CLAMP_T_MIRROR_CLAMP_LAST
;
129 case GL_MIRROR_CLAMP_TO_BORDER_EXT
:
130 t
->pp_txfilter
|= RADEON_CLAMP_T_MIRROR_CLAMP_GL
;
131 is_clamp_to_border
= GL_TRUE
;
134 _mesa_problem(NULL
, "bad T wrap mode in %s", __FUNCTION__
);
137 if ( is_clamp_to_border
) {
138 t
->pp_txfilter
|= RADEON_BORDER_MODE_D3D
;
141 t
->border_fallback
= (is_clamp
&& is_clamp_to_border
);
144 static void radeonSetTexMaxAnisotropy( radeonTexObjPtr t
, GLfloat max
)
146 t
->pp_txfilter
&= ~RADEON_MAX_ANISO_MASK
;
149 t
->pp_txfilter
|= RADEON_MAX_ANISO_1_TO_1
;
150 } else if ( max
<= 2.0 ) {
151 t
->pp_txfilter
|= RADEON_MAX_ANISO_2_TO_1
;
152 } else if ( max
<= 4.0 ) {
153 t
->pp_txfilter
|= RADEON_MAX_ANISO_4_TO_1
;
154 } else if ( max
<= 8.0 ) {
155 t
->pp_txfilter
|= RADEON_MAX_ANISO_8_TO_1
;
157 t
->pp_txfilter
|= RADEON_MAX_ANISO_16_TO_1
;
162 * Set the texture magnification and minification modes.
164 * \param t Texture whose filter modes are to be set
165 * \param minf Texture minification mode
166 * \param magf Texture magnification mode
169 static void radeonSetTexFilter( radeonTexObjPtr t
, GLenum minf
, GLenum magf
)
171 GLuint anisotropy
= (t
->pp_txfilter
& RADEON_MAX_ANISO_MASK
);
173 t
->pp_txfilter
&= ~(RADEON_MIN_FILTER_MASK
| RADEON_MAG_FILTER_MASK
);
175 /* r100 chips can't handle mipmaps/aniso for cubemap/volume textures */
176 if ( t
->base
.tObj
->Target
== GL_TEXTURE_CUBE_MAP
) {
179 case GL_NEAREST_MIPMAP_NEAREST
:
180 case GL_NEAREST_MIPMAP_LINEAR
:
181 t
->pp_txfilter
|= RADEON_MIN_FILTER_NEAREST
;
184 case GL_LINEAR_MIPMAP_NEAREST
:
185 case GL_LINEAR_MIPMAP_LINEAR
:
186 t
->pp_txfilter
|= RADEON_MIN_FILTER_LINEAR
;
192 else if ( anisotropy
== RADEON_MAX_ANISO_1_TO_1
) {
195 t
->pp_txfilter
|= RADEON_MIN_FILTER_NEAREST
;
198 t
->pp_txfilter
|= RADEON_MIN_FILTER_LINEAR
;
200 case GL_NEAREST_MIPMAP_NEAREST
:
201 t
->pp_txfilter
|= RADEON_MIN_FILTER_NEAREST_MIP_NEAREST
;
203 case GL_NEAREST_MIPMAP_LINEAR
:
204 t
->pp_txfilter
|= RADEON_MIN_FILTER_LINEAR_MIP_NEAREST
;
206 case GL_LINEAR_MIPMAP_NEAREST
:
207 t
->pp_txfilter
|= RADEON_MIN_FILTER_NEAREST_MIP_LINEAR
;
209 case GL_LINEAR_MIPMAP_LINEAR
:
210 t
->pp_txfilter
|= RADEON_MIN_FILTER_LINEAR_MIP_LINEAR
;
216 t
->pp_txfilter
|= RADEON_MIN_FILTER_ANISO_NEAREST
;
219 t
->pp_txfilter
|= RADEON_MIN_FILTER_ANISO_LINEAR
;
221 case GL_NEAREST_MIPMAP_NEAREST
:
222 case GL_LINEAR_MIPMAP_NEAREST
:
223 t
->pp_txfilter
|= RADEON_MIN_FILTER_ANISO_NEAREST_MIP_NEAREST
;
225 case GL_NEAREST_MIPMAP_LINEAR
:
226 case GL_LINEAR_MIPMAP_LINEAR
:
227 t
->pp_txfilter
|= RADEON_MIN_FILTER_ANISO_NEAREST_MIP_LINEAR
;
234 t
->pp_txfilter
|= RADEON_MAG_FILTER_NEAREST
;
237 t
->pp_txfilter
|= RADEON_MAG_FILTER_LINEAR
;
242 static void radeonSetTexBorderColor( radeonTexObjPtr t
, GLubyte c
[4] )
244 t
->pp_border_color
= radeonPackColor( 4, c
[0], c
[1], c
[2], c
[3] );
249 * Allocate space for and load the mesa images into the texture memory block.
250 * This will happen before drawing with a new texture, or drawing with a
251 * texture after it was swapped out or teximaged again.
254 static radeonTexObjPtr
radeonAllocTexObj( struct gl_texture_object
*texObj
)
258 t
= CALLOC_STRUCT( radeon_tex_obj
);
259 texObj
->DriverData
= t
;
261 if ( RADEON_DEBUG
& DEBUG_TEXTURE
) {
262 fprintf( stderr
, "%s( %p, %p )\n", __FUNCTION__
, (void *)texObj
, (void *)t
);
265 /* Initialize non-image-dependent parts of the state:
267 t
->base
.tObj
= texObj
;
268 t
->border_fallback
= GL_FALSE
;
270 t
->pp_txfilter
= RADEON_BORDER_MODE_OGL
;
271 t
->pp_txformat
= (RADEON_TXFORMAT_ENDIAN_NO_SWAP
|
272 RADEON_TXFORMAT_PERSPECTIVE_ENABLE
);
274 make_empty_list( & t
->base
);
276 radeonSetTexWrap( t
, texObj
->WrapS
, texObj
->WrapT
);
277 radeonSetTexMaxAnisotropy( t
, texObj
->MaxAnisotropy
);
278 radeonSetTexFilter( t
, texObj
->MinFilter
, texObj
->MagFilter
);
279 radeonSetTexBorderColor( t
, texObj
->_BorderChan
);
286 static const struct gl_texture_format
*
287 radeonChooseTextureFormat( GLcontext
*ctx
, GLint internalFormat
,
288 GLenum format
, GLenum type
)
290 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
291 const GLboolean do32bpt
=
292 ( rmesa
->texture_depth
== DRI_CONF_TEXTURE_DEPTH_32
);
293 const GLboolean force16bpt
=
294 ( rmesa
->texture_depth
== DRI_CONF_TEXTURE_DEPTH_FORCE_16
);
297 switch ( internalFormat
) {
300 case GL_COMPRESSED_RGBA
:
302 case GL_UNSIGNED_INT_10_10_10_2
:
303 case GL_UNSIGNED_INT_2_10_10_10_REV
:
304 return do32bpt
? _dri_texformat_argb8888
: _dri_texformat_argb1555
;
305 case GL_UNSIGNED_SHORT_4_4_4_4
:
306 case GL_UNSIGNED_SHORT_4_4_4_4_REV
:
307 return _dri_texformat_argb4444
;
308 case GL_UNSIGNED_SHORT_5_5_5_1
:
309 case GL_UNSIGNED_SHORT_1_5_5_5_REV
:
310 return _dri_texformat_argb1555
;
312 return do32bpt
? _dri_texformat_argb8888
: _dri_texformat_argb4444
;
317 case GL_COMPRESSED_RGB
:
319 case GL_UNSIGNED_SHORT_4_4_4_4
:
320 case GL_UNSIGNED_SHORT_4_4_4_4_REV
:
321 return _dri_texformat_argb4444
;
322 case GL_UNSIGNED_SHORT_5_5_5_1
:
323 case GL_UNSIGNED_SHORT_1_5_5_5_REV
:
324 return _dri_texformat_argb1555
;
325 case GL_UNSIGNED_SHORT_5_6_5
:
326 case GL_UNSIGNED_SHORT_5_6_5_REV
:
327 return _dri_texformat_rgb565
;
329 return do32bpt
? _dri_texformat_argb8888
: _dri_texformat_rgb565
;
337 _dri_texformat_argb8888
: _dri_texformat_argb4444
;
341 return _dri_texformat_argb4444
;
344 return _dri_texformat_argb1555
;
350 return !force16bpt
? _dri_texformat_argb8888
: _dri_texformat_rgb565
;
355 return _dri_texformat_rgb565
;
362 case GL_COMPRESSED_ALPHA
:
363 return _dri_texformat_a8
;
371 case GL_COMPRESSED_LUMINANCE
:
372 return _dri_texformat_l8
;
375 case GL_LUMINANCE_ALPHA
:
376 case GL_LUMINANCE4_ALPHA4
:
377 case GL_LUMINANCE6_ALPHA2
:
378 case GL_LUMINANCE8_ALPHA8
:
379 case GL_LUMINANCE12_ALPHA4
:
380 case GL_LUMINANCE12_ALPHA12
:
381 case GL_LUMINANCE16_ALPHA16
:
382 case GL_COMPRESSED_LUMINANCE_ALPHA
:
383 return _dri_texformat_al88
;
390 case GL_COMPRESSED_INTENSITY
:
391 return _dri_texformat_i8
;
394 if (type
== GL_UNSIGNED_SHORT_8_8_APPLE
||
395 type
== GL_UNSIGNED_BYTE
)
396 return &_mesa_texformat_ycbcr
;
398 return &_mesa_texformat_ycbcr_rev
;
402 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT
:
403 return &_mesa_texformat_rgb_dxt1
;
405 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT
:
406 return &_mesa_texformat_rgba_dxt1
;
410 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT
:
411 return &_mesa_texformat_rgba_dxt3
;
413 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT
:
414 return &_mesa_texformat_rgba_dxt5
;
417 _mesa_problem(ctx
, "unexpected texture format in %s", __FUNCTION__
);
421 return NULL
; /* never get here */
425 static void radeonTexImage1D( GLcontext
*ctx
, GLenum target
, GLint level
,
426 GLint internalFormat
,
427 GLint width
, GLint border
,
428 GLenum format
, GLenum type
, const GLvoid
*pixels
,
429 const struct gl_pixelstore_attrib
*packing
,
430 struct gl_texture_object
*texObj
,
431 struct gl_texture_image
*texImage
)
433 driTextureObject
* t
= (driTextureObject
*) texObj
->DriverData
;
436 driSwapOutTextureObject( t
);
439 t
= (driTextureObject
*) radeonAllocTexObj( texObj
);
441 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage1D");
446 /* Note, this will call ChooseTextureFormat */
447 _mesa_store_teximage1d(ctx
, target
, level
, internalFormat
,
448 width
, border
, format
, type
, pixels
,
449 &ctx
->Unpack
, texObj
, texImage
);
451 t
->dirty_images
[0] |= (1 << level
);
455 static void radeonTexSubImage1D( GLcontext
*ctx
, GLenum target
, GLint level
,
458 GLenum format
, GLenum type
,
459 const GLvoid
*pixels
,
460 const struct gl_pixelstore_attrib
*packing
,
461 struct gl_texture_object
*texObj
,
462 struct gl_texture_image
*texImage
)
464 driTextureObject
* t
= (driTextureObject
*) texObj
->DriverData
;
466 assert( t
); /* this _should_ be true */
468 driSwapOutTextureObject( t
);
471 t
= (driTextureObject
*) radeonAllocTexObj( texObj
);
473 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexSubImage1D");
478 _mesa_store_texsubimage1d(ctx
, target
, level
, xoffset
, width
,
479 format
, type
, pixels
, packing
, texObj
,
482 t
->dirty_images
[0] |= (1 << level
);
486 static void radeonTexImage2D( GLcontext
*ctx
, GLenum target
, GLint level
,
487 GLint internalFormat
,
488 GLint width
, GLint height
, GLint border
,
489 GLenum format
, GLenum type
, const GLvoid
*pixels
,
490 const struct gl_pixelstore_attrib
*packing
,
491 struct gl_texture_object
*texObj
,
492 struct gl_texture_image
*texImage
)
494 driTextureObject
* t
= (driTextureObject
*) texObj
->DriverData
;
497 /* which cube face or ordinary 2D image */
499 case GL_TEXTURE_CUBE_MAP_POSITIVE_X
:
500 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X
:
501 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y
:
502 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y
:
503 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z
:
504 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z
:
505 face
= (GLuint
) target
- (GLuint
) GL_TEXTURE_CUBE_MAP_POSITIVE_X
;
513 driSwapOutTextureObject( t
);
516 t
= (driTextureObject
*) radeonAllocTexObj( texObj
);
518 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage2D");
523 /* Note, this will call ChooseTextureFormat */
524 _mesa_store_teximage2d(ctx
, target
, level
, internalFormat
,
525 width
, height
, border
, format
, type
, pixels
,
526 &ctx
->Unpack
, texObj
, texImage
);
528 t
->dirty_images
[face
] |= (1 << level
);
532 static void radeonTexSubImage2D( GLcontext
*ctx
, GLenum target
, GLint level
,
533 GLint xoffset
, GLint yoffset
,
534 GLsizei width
, GLsizei height
,
535 GLenum format
, GLenum type
,
536 const GLvoid
*pixels
,
537 const struct gl_pixelstore_attrib
*packing
,
538 struct gl_texture_object
*texObj
,
539 struct gl_texture_image
*texImage
)
541 driTextureObject
* t
= (driTextureObject
*) texObj
->DriverData
;
544 /* which cube face or ordinary 2D image */
546 case GL_TEXTURE_CUBE_MAP_POSITIVE_X
:
547 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X
:
548 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y
:
549 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y
:
550 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z
:
551 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z
:
552 face
= (GLuint
) target
- (GLuint
) GL_TEXTURE_CUBE_MAP_POSITIVE_X
;
559 assert( t
); /* this _should_ be true */
561 driSwapOutTextureObject( t
);
564 t
= (driTextureObject
*) radeonAllocTexObj( texObj
);
566 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexSubImage2D");
571 _mesa_store_texsubimage2d(ctx
, target
, level
, xoffset
, yoffset
, width
,
572 height
, format
, type
, pixels
, packing
, texObj
,
575 t
->dirty_images
[face
] |= (1 << level
);
578 static void radeonCompressedTexImage2D( GLcontext
*ctx
, GLenum target
, GLint level
,
579 GLint internalFormat
,
580 GLint width
, GLint height
, GLint border
,
581 GLsizei imageSize
, const GLvoid
*data
,
582 struct gl_texture_object
*texObj
,
583 struct gl_texture_image
*texImage
)
585 driTextureObject
* t
= (driTextureObject
*) texObj
->DriverData
;
588 /* which cube face or ordinary 2D image */
590 case GL_TEXTURE_CUBE_MAP_POSITIVE_X
:
591 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X
:
592 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y
:
593 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y
:
594 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z
:
595 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z
:
596 face
= (GLuint
) target
- (GLuint
) GL_TEXTURE_CUBE_MAP_POSITIVE_X
;
604 driSwapOutTextureObject( t
);
607 t
= (driTextureObject
*) radeonAllocTexObj( texObj
);
609 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glCompressedTexImage2D");
614 /* Note, this will call ChooseTextureFormat */
615 _mesa_store_compressed_teximage2d(ctx
, target
, level
, internalFormat
, width
,
616 height
, border
, imageSize
, data
, texObj
, texImage
);
618 t
->dirty_images
[face
] |= (1 << level
);
622 static void radeonCompressedTexSubImage2D( GLcontext
*ctx
, GLenum target
, GLint level
,
623 GLint xoffset
, GLint yoffset
,
624 GLsizei width
, GLsizei height
,
626 GLsizei imageSize
, const GLvoid
*data
,
627 struct gl_texture_object
*texObj
,
628 struct gl_texture_image
*texImage
)
630 driTextureObject
* t
= (driTextureObject
*) texObj
->DriverData
;
634 /* which cube face or ordinary 2D image */
636 case GL_TEXTURE_CUBE_MAP_POSITIVE_X
:
637 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X
:
638 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y
:
639 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y
:
640 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z
:
641 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z
:
642 face
= (GLuint
) target
- (GLuint
) GL_TEXTURE_CUBE_MAP_POSITIVE_X
;
649 assert( t
); /* this _should_ be true */
651 driSwapOutTextureObject( t
);
654 t
= (driTextureObject
*) radeonAllocTexObj( texObj
);
656 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glCompressedTexSubImage2D");
661 _mesa_store_compressed_texsubimage2d(ctx
, target
, level
, xoffset
, yoffset
, width
,
662 height
, format
, imageSize
, data
, texObj
, texImage
);
664 t
->dirty_images
[face
] |= (1 << level
);
667 #define SCALED_FLOAT_TO_BYTE( x, scale ) \
668 (((GLuint)((255.0F / scale) * (x))) / 2)
670 static void radeonTexEnv( GLcontext
*ctx
, GLenum target
,
671 GLenum pname
, const GLfloat
*param
)
673 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
674 GLuint unit
= ctx
->Texture
.CurrentUnit
;
675 struct gl_texture_unit
*texUnit
= &ctx
->Texture
.Unit
[unit
];
677 if ( RADEON_DEBUG
& DEBUG_STATE
) {
678 fprintf( stderr
, "%s( %s )\n",
679 __FUNCTION__
, _mesa_lookup_enum_by_nr( pname
) );
683 case GL_TEXTURE_ENV_COLOR
: {
686 UNCLAMPED_FLOAT_TO_RGBA_CHAN( c
, texUnit
->EnvColor
);
687 envColor
= radeonPackColor( 4, c
[0], c
[1], c
[2], c
[3] );
688 if ( rmesa
->hw
.tex
[unit
].cmd
[TEX_PP_TFACTOR
] != envColor
) {
689 RADEON_STATECHANGE( rmesa
, tex
[unit
] );
690 rmesa
->hw
.tex
[unit
].cmd
[TEX_PP_TFACTOR
] = envColor
;
695 case GL_TEXTURE_LOD_BIAS_EXT
: {
699 /* The Radeon's LOD bias is a signed 2's complement value with a
700 * range of -1.0 <= bias < 4.0. We break this into two linear
701 * functions, one mapping [-1.0,0.0] to [-128,0] and one mapping
702 * [0.0,4.0] to [0,127].
704 min
= driQueryOptionb (&rmesa
->optionCache
, "no_neg_lod_bias") ?
706 bias
= CLAMP( *param
, min
, 4.0 );
709 } else if ( bias
> 0 ) {
710 b
= ((GLuint
)SCALED_FLOAT_TO_BYTE( bias
, 4.0 )) << RADEON_LOD_BIAS_SHIFT
;
712 b
= ((GLuint
)SCALED_FLOAT_TO_BYTE( bias
, 1.0 )) << RADEON_LOD_BIAS_SHIFT
;
714 if ( (rmesa
->hw
.tex
[unit
].cmd
[TEX_PP_TXFILTER
] & RADEON_LOD_BIAS_MASK
) != b
) {
715 RADEON_STATECHANGE( rmesa
, tex
[unit
] );
716 rmesa
->hw
.tex
[unit
].cmd
[TEX_PP_TXFILTER
] &= ~RADEON_LOD_BIAS_MASK
;
717 rmesa
->hw
.tex
[unit
].cmd
[TEX_PP_TXFILTER
] |= (b
& RADEON_LOD_BIAS_MASK
);
729 * Changes variables and flags for a state update, which will happen at the
730 * next UpdateTextureState
733 static void radeonTexParameter( GLcontext
*ctx
, GLenum target
,
734 struct gl_texture_object
*texObj
,
735 GLenum pname
, const GLfloat
*params
)
737 radeonTexObjPtr t
= (radeonTexObjPtr
) texObj
->DriverData
;
739 if ( RADEON_DEBUG
& (DEBUG_STATE
|DEBUG_TEXTURE
) ) {
740 fprintf( stderr
, "%s( %s )\n", __FUNCTION__
,
741 _mesa_lookup_enum_by_nr( pname
) );
745 case GL_TEXTURE_MIN_FILTER
:
746 case GL_TEXTURE_MAG_FILTER
:
747 case GL_TEXTURE_MAX_ANISOTROPY_EXT
:
748 radeonSetTexMaxAnisotropy( t
, texObj
->MaxAnisotropy
);
749 radeonSetTexFilter( t
, texObj
->MinFilter
, texObj
->MagFilter
);
752 case GL_TEXTURE_WRAP_S
:
753 case GL_TEXTURE_WRAP_T
:
754 radeonSetTexWrap( t
, texObj
->WrapS
, texObj
->WrapT
);
757 case GL_TEXTURE_BORDER_COLOR
:
758 radeonSetTexBorderColor( t
, texObj
->_BorderChan
);
761 case GL_TEXTURE_BASE_LEVEL
:
762 case GL_TEXTURE_MAX_LEVEL
:
763 case GL_TEXTURE_MIN_LOD
:
764 case GL_TEXTURE_MAX_LOD
:
765 /* This isn't the most efficient solution but there doesn't appear to
766 * be a nice alternative. Since there's no LOD clamping,
767 * we just have to rely on loading the right subset of mipmap levels
768 * to simulate a clamped LOD.
770 driSwapOutTextureObject( (driTextureObject
*) t
);
777 /* Mark this texobj as dirty (one bit per tex unit)
779 t
->dirty_state
= TEX_ALL
;
783 static void radeonBindTexture( GLcontext
*ctx
, GLenum target
,
784 struct gl_texture_object
*texObj
)
786 if ( RADEON_DEBUG
& (DEBUG_STATE
|DEBUG_TEXTURE
) ) {
787 fprintf( stderr
, "%s( %p ) unit=%d\n", __FUNCTION__
, (void *)texObj
,
788 ctx
->Texture
.CurrentUnit
);
791 assert( (target
!= GL_TEXTURE_1D
&& target
!= GL_TEXTURE_2D
&&
792 target
!= GL_TEXTURE_RECTANGLE_NV
&& target
!= GL_TEXTURE_CUBE_MAP
) ||
793 (texObj
->DriverData
!= NULL
) );
797 static void radeonDeleteTexture( GLcontext
*ctx
,
798 struct gl_texture_object
*texObj
)
800 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
801 driTextureObject
* t
= (driTextureObject
*) texObj
->DriverData
;
803 if ( RADEON_DEBUG
& (DEBUG_STATE
|DEBUG_TEXTURE
) ) {
804 fprintf( stderr
, "%s( %p (target = %s) )\n", __FUNCTION__
, (void *)texObj
,
805 _mesa_lookup_enum_by_nr( texObj
->Target
) );
810 RADEON_FIREVERTICES( rmesa
);
813 driDestroyTextureObject( t
);
816 /* Free mipmap images and the texture object itself */
817 _mesa_delete_texture_object(ctx
, texObj
);
821 * - Same GEN_MODE for all active bits
822 * - Same EyePlane/ObjPlane for all active bits when using Eye/Obj
823 * - STRQ presumably all supported (matrix means incoming R values
824 * can end up in STQ, this has implications for vertex support,
825 * presumably ok if maos is used, though?)
827 * Basically impossible to do this on the fly - just collect some
828 * basic info & do the checks from ValidateState().
830 static void radeonTexGen( GLcontext
*ctx
,
833 const GLfloat
*params
)
835 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
836 GLuint unit
= ctx
->Texture
.CurrentUnit
;
837 rmesa
->recheck_texgen
[unit
] = GL_TRUE
;
841 * Allocate a new texture object.
842 * Called via ctx->Driver.NewTextureObject.
843 * Note: we could use containment here to 'derive' the driver-specific
844 * texture object from the core mesa gl_texture_object. Not done at this time.
846 static struct gl_texture_object
*
847 radeonNewTextureObject( GLcontext
*ctx
, GLuint name
, GLenum target
)
849 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
850 struct gl_texture_object
*obj
;
851 obj
= _mesa_new_texture_object(ctx
, name
, target
);
854 obj
->MaxAnisotropy
= rmesa
->initialMaxAnisotropy
;
855 radeonAllocTexObj( obj
);
860 void radeonInitTextureFuncs( struct dd_function_table
*functions
)
862 functions
->ChooseTextureFormat
= radeonChooseTextureFormat
;
863 functions
->TexImage1D
= radeonTexImage1D
;
864 functions
->TexImage2D
= radeonTexImage2D
;
865 functions
->TexSubImage1D
= radeonTexSubImage1D
;
866 functions
->TexSubImage2D
= radeonTexSubImage2D
;
868 functions
->NewTextureObject
= radeonNewTextureObject
;
869 functions
->BindTexture
= radeonBindTexture
;
870 functions
->DeleteTexture
= radeonDeleteTexture
;
871 functions
->IsTextureResident
= driIsTextureResident
;
873 functions
->TexEnv
= radeonTexEnv
;
874 functions
->TexParameter
= radeonTexParameter
;
875 functions
->TexGen
= radeonTexGen
;
877 functions
->CompressedTexImage2D
= radeonCompressedTexImage2D
;
878 functions
->CompressedTexSubImage2D
= radeonCompressedTexSubImage2D
;
880 driInitTextureFormats();