2 Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved.
4 The Weather Channel (TM) funded Tungsten Graphics to develop the
5 initial release of the Radeon 8500 driver under the XFree86 license.
6 This notice must be preserved.
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.
32 * \author Keith Whitwell <keith@tungstengraphics.com>
41 #include "simple_list.h"
42 #include "texformat.h"
48 #include "r300_context.h"
49 #include "r300_state.h"
50 #include "r300_ioctl.h"
56 * Set the texture wrap modes.
58 * \param t Texture object whose wrap modes are to be set
59 * \param swrap Wrap mode for the \a s texture coordinate
60 * \param twrap Wrap mode for the \a t texture coordinate
63 static void r300SetTexWrap(r300TexObjPtr t
, GLenum swrap
, GLenum twrap
,
66 unsigned long hw_swrap
= 0, hw_twrap
= 0, hw_qwrap
= 0;
69 ~(R300_TX_WRAP_S_MASK
| R300_TX_WRAP_T_MASK
| R300_TX_WRAP_Q_MASK
);
73 hw_swrap
|= R300_TX_REPEAT
;
76 hw_swrap
|= R300_TX_CLAMP
;
78 case GL_CLAMP_TO_EDGE
:
79 hw_swrap
|= R300_TX_CLAMP_TO_EDGE
;
81 case GL_CLAMP_TO_BORDER
:
82 hw_swrap
|= R300_TX_CLAMP_TO_BORDER
;
84 case GL_MIRRORED_REPEAT
:
85 hw_swrap
|= R300_TX_REPEAT
| R300_TX_MIRRORED
;
87 case GL_MIRROR_CLAMP_EXT
:
88 hw_swrap
|= R300_TX_CLAMP
| R300_TX_MIRRORED
;
90 case GL_MIRROR_CLAMP_TO_EDGE_EXT
:
91 hw_swrap
|= R300_TX_CLAMP_TO_EDGE
| R300_TX_MIRRORED
;
93 case GL_MIRROR_CLAMP_TO_BORDER_EXT
:
94 hw_swrap
|= R300_TX_CLAMP_TO_BORDER
| R300_TX_MIRRORED
;
97 _mesa_problem(NULL
, "bad S wrap mode in %s", __FUNCTION__
);
102 hw_twrap
|= R300_TX_REPEAT
;
105 hw_twrap
|= R300_TX_CLAMP
;
107 case GL_CLAMP_TO_EDGE
:
108 hw_twrap
|= R300_TX_CLAMP_TO_EDGE
;
110 case GL_CLAMP_TO_BORDER
:
111 hw_twrap
|= R300_TX_CLAMP_TO_BORDER
;
113 case GL_MIRRORED_REPEAT
:
114 hw_twrap
|= R300_TX_REPEAT
| R300_TX_MIRRORED
;
116 case GL_MIRROR_CLAMP_EXT
:
117 hw_twrap
|= R300_TX_CLAMP
| R300_TX_MIRRORED
;
119 case GL_MIRROR_CLAMP_TO_EDGE_EXT
:
120 hw_twrap
|= R300_TX_CLAMP_TO_EDGE
| R300_TX_MIRRORED
;
122 case GL_MIRROR_CLAMP_TO_BORDER_EXT
:
123 hw_twrap
|= R300_TX_CLAMP_TO_BORDER
| R300_TX_MIRRORED
;
126 _mesa_problem(NULL
, "bad T wrap mode in %s", __FUNCTION__
);
131 hw_qwrap
|= R300_TX_REPEAT
;
134 hw_qwrap
|= R300_TX_CLAMP
;
136 case GL_CLAMP_TO_EDGE
:
137 hw_qwrap
|= R300_TX_CLAMP_TO_EDGE
;
139 case GL_CLAMP_TO_BORDER
:
140 hw_qwrap
|= R300_TX_CLAMP_TO_BORDER
;
142 case GL_MIRRORED_REPEAT
:
143 hw_qwrap
|= R300_TX_REPEAT
| R300_TX_MIRRORED
;
145 case GL_MIRROR_CLAMP_EXT
:
146 hw_qwrap
|= R300_TX_CLAMP
| R300_TX_MIRRORED
;
148 case GL_MIRROR_CLAMP_TO_EDGE_EXT
:
149 hw_qwrap
|= R300_TX_CLAMP_TO_EDGE
| R300_TX_MIRRORED
;
151 case GL_MIRROR_CLAMP_TO_BORDER_EXT
:
152 hw_qwrap
|= R300_TX_CLAMP_TO_BORDER
| R300_TX_MIRRORED
;
155 _mesa_problem(NULL
, "bad R wrap mode in %s", __FUNCTION__
);
158 t
->filter
|= hw_swrap
<< R300_TX_WRAP_S_SHIFT
;
159 t
->filter
|= hw_twrap
<< R300_TX_WRAP_T_SHIFT
;
160 t
->filter
|= hw_qwrap
<< R300_TX_WRAP_Q_SHIFT
;
163 static void r300SetTexMaxAnisotropy(r300TexObjPtr t
, GLfloat max
)
166 t
->filter
&= ~R300_TX_MAX_ANISO_MASK
;
169 t
->filter
|= R300_TX_MAX_ANISO_1_TO_1
;
170 } else if (max
<= 2.0) {
171 t
->filter
|= R300_TX_MAX_ANISO_2_TO_1
;
172 } else if (max
<= 4.0) {
173 t
->filter
|= R300_TX_MAX_ANISO_4_TO_1
;
174 } else if (max
<= 8.0) {
175 t
->filter
|= R300_TX_MAX_ANISO_8_TO_1
;
177 t
->filter
|= R300_TX_MAX_ANISO_16_TO_1
;
182 * Set the texture magnification and minification modes.
184 * \param t Texture whose filter modes are to be set
185 * \param minf Texture minification mode
186 * \param magf Texture magnification mode
189 static void r300SetTexFilter(r300TexObjPtr t
, GLenum minf
, GLenum magf
)
191 GLuint anisotropy
= (t
->filter
& R300_TX_MAX_ANISO_MASK
);
193 t
->filter
&= ~(R300_TX_MIN_FILTER_MASK
| R300_TX_MAG_FILTER_MASK
);
195 if (anisotropy
== R300_TX_MAX_ANISO_1_TO_1
) {
198 t
->filter
|= R300_TX_MIN_FILTER_NEAREST
;
201 t
->filter
|= R300_TX_MIN_FILTER_LINEAR
;
203 case GL_NEAREST_MIPMAP_NEAREST
:
204 t
->filter
|= R300_TX_MIN_FILTER_NEAREST_MIP_NEAREST
;
206 case GL_NEAREST_MIPMAP_LINEAR
:
207 t
->filter
|= R300_TX_MIN_FILTER_NEAREST_MIP_LINEAR
;
209 case GL_LINEAR_MIPMAP_NEAREST
:
210 t
->filter
|= R300_TX_MIN_FILTER_LINEAR_MIP_NEAREST
;
212 case GL_LINEAR_MIPMAP_LINEAR
:
213 t
->filter
|= R300_TX_MIN_FILTER_LINEAR_MIP_LINEAR
;
219 t
->filter
|= R300_TX_MIN_FILTER_ANISO_NEAREST
;
222 t
->filter
|= R300_TX_MIN_FILTER_ANISO_LINEAR
;
224 case GL_NEAREST_MIPMAP_NEAREST
:
225 case GL_LINEAR_MIPMAP_NEAREST
:
227 R300_TX_MIN_FILTER_ANISO_NEAREST_MIP_NEAREST
;
229 case GL_NEAREST_MIPMAP_LINEAR
:
230 case GL_LINEAR_MIPMAP_LINEAR
:
232 R300_TX_MIN_FILTER_ANISO_NEAREST_MIP_LINEAR
;
237 /* Note we don't have 3D mipmaps so only use the mag filter setting
238 * to set the 3D texture filter mode.
242 t
->filter
|= R300_TX_MAG_FILTER_NEAREST
;
245 t
->filter
|= R300_TX_MAG_FILTER_LINEAR
;
250 static void r300SetTexBorderColor(r300TexObjPtr t
, GLubyte c
[4])
252 t
->pp_border_color
= PACK_COLOR_8888(c
[0], c
[1], c
[2], c
[3]);
256 * Allocate space for and load the mesa images into the texture memory block.
257 * This will happen before drawing with a new texture, or drawing with a
258 * texture after it was swapped out or teximaged again.
261 static r300TexObjPtr
r300AllocTexObj(struct gl_texture_object
*texObj
)
265 t
= CALLOC_STRUCT(r300_tex_obj
);
266 texObj
->DriverData
= t
;
268 if (RADEON_DEBUG
& DEBUG_TEXTURE
) {
269 fprintf(stderr
, "%s( %p, %p )\n", __FUNCTION__
,
270 (void *)texObj
, (void *)t
);
273 /* Initialize non-image-dependent parts of the state:
275 t
->base
.tObj
= texObj
;
276 t
->border_fallback
= GL_FALSE
;
278 make_empty_list(&t
->base
);
280 r300SetTexWrap(t
, texObj
->WrapS
, texObj
->WrapT
, texObj
->WrapR
);
281 r300SetTexMaxAnisotropy(t
, texObj
->MaxAnisotropy
);
282 r300SetTexFilter(t
, texObj
->MinFilter
, texObj
->MagFilter
);
283 r300SetTexBorderColor(t
, texObj
->_BorderChan
);
289 /* try to find a format which will only need a memcopy */
290 static const struct gl_texture_format
*r300Choose8888TexFormat(GLenum srcFormat
,
294 const GLubyte littleEndian
= *((const GLubyte
*)&ui
);
296 if ((srcFormat
== GL_RGBA
&& srcType
== GL_UNSIGNED_INT_8_8_8_8
) ||
297 (srcFormat
== GL_RGBA
&& srcType
== GL_UNSIGNED_BYTE
&& !littleEndian
) ||
298 (srcFormat
== GL_ABGR_EXT
&& srcType
== GL_UNSIGNED_INT_8_8_8_8_REV
) ||
299 (srcFormat
== GL_ABGR_EXT
&& srcType
== GL_UNSIGNED_BYTE
&& littleEndian
)) {
300 return &_mesa_texformat_rgba8888
;
301 } else if ((srcFormat
== GL_RGBA
&& srcType
== GL_UNSIGNED_INT_8_8_8_8_REV
) ||
302 (srcFormat
== GL_RGBA
&& srcType
== GL_UNSIGNED_BYTE
&& littleEndian
) ||
303 (srcFormat
== GL_ABGR_EXT
&& srcType
== GL_UNSIGNED_INT_8_8_8_8
) ||
304 (srcFormat
== GL_ABGR_EXT
&& srcType
== GL_UNSIGNED_BYTE
&& !littleEndian
)) {
305 return &_mesa_texformat_rgba8888_rev
;
306 } else if (srcFormat
== GL_BGRA
&& ((srcType
== GL_UNSIGNED_BYTE
&& !littleEndian
) ||
307 srcType
== GL_UNSIGNED_INT_8_8_8_8
)) {
308 return &_mesa_texformat_argb8888_rev
;
309 } else if (srcFormat
== GL_BGRA
&& ((srcType
== GL_UNSIGNED_BYTE
&& littleEndian
) ||
310 srcType
== GL_UNSIGNED_INT_8_8_8_8_REV
)) {
311 return &_mesa_texformat_argb8888
;
313 return _dri_texformat_argb8888
;
316 static const struct gl_texture_format
*r300ChooseTextureFormat(GLcontext
* ctx
,
322 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
323 const GLboolean do32bpt
=
324 (rmesa
->texture_depth
== DRI_CONF_TEXTURE_DEPTH_32
);
325 const GLboolean force16bpt
=
326 (rmesa
->texture_depth
== DRI_CONF_TEXTURE_DEPTH_FORCE_16
);
330 fprintf(stderr
, "InternalFormat=%s(%d) type=%s format=%s\n",
331 _mesa_lookup_enum_by_nr(internalFormat
), internalFormat
,
332 _mesa_lookup_enum_by_nr(type
), _mesa_lookup_enum_by_nr(format
));
333 fprintf(stderr
, "do32bpt=%d force16bpt=%d\n", do32bpt
, force16bpt
);
336 switch (internalFormat
) {
339 case GL_COMPRESSED_RGBA
:
341 case GL_UNSIGNED_INT_10_10_10_2
:
342 case GL_UNSIGNED_INT_2_10_10_10_REV
:
343 return do32bpt
? _dri_texformat_argb8888
:
344 _dri_texformat_argb1555
;
345 case GL_UNSIGNED_SHORT_4_4_4_4
:
346 case GL_UNSIGNED_SHORT_4_4_4_4_REV
:
347 return _dri_texformat_argb4444
;
348 case GL_UNSIGNED_SHORT_5_5_5_1
:
349 case GL_UNSIGNED_SHORT_1_5_5_5_REV
:
350 return _dri_texformat_argb1555
;
352 return do32bpt
? r300Choose8888TexFormat(format
, type
) :
353 _dri_texformat_argb4444
;
358 case GL_COMPRESSED_RGB
:
360 case GL_UNSIGNED_SHORT_4_4_4_4
:
361 case GL_UNSIGNED_SHORT_4_4_4_4_REV
:
362 return _dri_texformat_argb4444
;
363 case GL_UNSIGNED_SHORT_5_5_5_1
:
364 case GL_UNSIGNED_SHORT_1_5_5_5_REV
:
365 return _dri_texformat_argb1555
;
366 case GL_UNSIGNED_SHORT_5_6_5
:
367 case GL_UNSIGNED_SHORT_5_6_5_REV
:
368 return _dri_texformat_rgb565
;
370 return do32bpt
? _dri_texformat_argb8888
:
371 _dri_texformat_rgb565
;
379 r300Choose8888TexFormat(format
,
380 type
) : _dri_texformat_argb4444
;
384 return _dri_texformat_argb4444
;
387 return _dri_texformat_argb1555
;
393 return !force16bpt
? _dri_texformat_argb8888
:
394 _dri_texformat_rgb565
;
399 return _dri_texformat_rgb565
;
406 case GL_COMPRESSED_ALPHA
:
407 return _dri_texformat_a8
;
415 case GL_COMPRESSED_LUMINANCE
:
416 return _dri_texformat_l8
;
419 case GL_LUMINANCE_ALPHA
:
420 case GL_LUMINANCE4_ALPHA4
:
421 case GL_LUMINANCE6_ALPHA2
:
422 case GL_LUMINANCE8_ALPHA8
:
423 case GL_LUMINANCE12_ALPHA4
:
424 case GL_LUMINANCE12_ALPHA12
:
425 case GL_LUMINANCE16_ALPHA16
:
426 case GL_COMPRESSED_LUMINANCE_ALPHA
:
427 return _dri_texformat_al88
;
434 case GL_COMPRESSED_INTENSITY
:
435 return _dri_texformat_i8
;
438 if (type
== GL_UNSIGNED_SHORT_8_8_APPLE
||
439 type
== GL_UNSIGNED_BYTE
)
440 return &_mesa_texformat_ycbcr
;
442 return &_mesa_texformat_ycbcr_rev
;
446 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT
:
447 return &_mesa_texformat_rgb_dxt1
;
449 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT
:
450 return &_mesa_texformat_rgba_dxt1
;
454 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT
:
455 return &_mesa_texformat_rgba_dxt3
;
457 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT
:
458 return &_mesa_texformat_rgba_dxt5
;
460 case GL_ALPHA16F_ARB
:
461 return &_mesa_texformat_alpha_float16
;
462 case GL_ALPHA32F_ARB
:
463 return &_mesa_texformat_alpha_float32
;
464 case GL_LUMINANCE16F_ARB
:
465 return &_mesa_texformat_luminance_float16
;
466 case GL_LUMINANCE32F_ARB
:
467 return &_mesa_texformat_luminance_float32
;
468 case GL_LUMINANCE_ALPHA16F_ARB
:
469 return &_mesa_texformat_luminance_alpha_float16
;
470 case GL_LUMINANCE_ALPHA32F_ARB
:
471 return &_mesa_texformat_luminance_alpha_float32
;
472 case GL_INTENSITY16F_ARB
:
473 return &_mesa_texformat_intensity_float16
;
474 case GL_INTENSITY32F_ARB
:
475 return &_mesa_texformat_intensity_float32
;
477 return &_mesa_texformat_rgba_float16
;
479 return &_mesa_texformat_rgba_float32
;
481 return &_mesa_texformat_rgba_float16
;
483 return &_mesa_texformat_rgba_float32
;
487 "unexpected internalFormat 0x%x in r300ChooseTextureFormat",
488 (int)internalFormat
);
492 return NULL
; /* never get here */
496 r300ValidateClientStorage(GLcontext
* ctx
, GLenum target
,
497 GLint internalFormat
,
498 GLint srcWidth
, GLint srcHeight
,
499 GLenum format
, GLenum type
, const void *pixels
,
500 const struct gl_pixelstore_attrib
*packing
,
501 struct gl_texture_object
*texObj
,
502 struct gl_texture_image
*texImage
)
504 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
506 if (RADEON_DEBUG
& DEBUG_TEXTURE
)
507 fprintf(stderr
, "intformat %s format %s type %s\n",
508 _mesa_lookup_enum_by_nr(internalFormat
),
509 _mesa_lookup_enum_by_nr(format
),
510 _mesa_lookup_enum_by_nr(type
));
512 if (!ctx
->Unpack
.ClientStorage
)
515 if (ctx
->_ImageTransferState
||
516 texImage
->IsCompressed
|| texObj
->GenerateMipmap
)
519 /* This list is incomplete, may be different on ppc???
521 switch (internalFormat
) {
523 if (format
== GL_BGRA
&& type
== GL_UNSIGNED_INT_8_8_8_8_REV
) {
524 texImage
->TexFormat
= _dri_texformat_argb8888
;
530 if (format
== GL_RGB
&& type
== GL_UNSIGNED_SHORT_5_6_5
) {
531 texImage
->TexFormat
= _dri_texformat_rgb565
;
537 if (format
== GL_YCBCR_MESA
&&
538 type
== GL_UNSIGNED_SHORT_8_8_REV_APPLE
) {
539 texImage
->TexFormat
= &_mesa_texformat_ycbcr_rev
;
540 } else if (format
== GL_YCBCR_MESA
&&
541 (type
== GL_UNSIGNED_SHORT_8_8_APPLE
||
542 type
== GL_UNSIGNED_BYTE
)) {
543 texImage
->TexFormat
= &_mesa_texformat_ycbcr
;
552 /* Could deal with these packing issues, but currently don't:
554 if (packing
->SkipPixels
||
555 packing
->SkipRows
|| packing
->SwapBytes
|| packing
->LsbFirst
) {
559 GLint srcRowStride
= _mesa_image_row_stride(packing
, srcWidth
,
562 if (RADEON_DEBUG
& DEBUG_TEXTURE
)
563 fprintf(stderr
, "%s: srcRowStride %d/%x\n",
564 __FUNCTION__
, srcRowStride
, srcRowStride
);
566 /* Could check this later in upload, pitch restrictions could be
567 * relaxed, but would need to store the image pitch somewhere,
568 * as packing details might change before image is uploaded:
570 if (!r300IsGartMemory(rmesa
, pixels
, srcHeight
* srcRowStride
)
571 || (srcRowStride
& 63))
574 /* Have validated that _mesa_transfer_teximage would be a straight
575 * memcpy at this point. NOTE: future calls to TexSubImage will
576 * overwrite the client data. This is explicitly mentioned in the
579 texImage
->Data
= (void *)pixels
;
580 texImage
->IsClientData
= GL_TRUE
;
581 texImage
->RowStride
= srcRowStride
/ texImage
->TexFormat
->TexelBytes
;
586 static void r300TexImage1D(GLcontext
* ctx
, GLenum target
, GLint level
,
587 GLint internalFormat
,
588 GLint width
, GLint border
,
589 GLenum format
, GLenum type
, const GLvoid
* pixels
,
590 const struct gl_pixelstore_attrib
*packing
,
591 struct gl_texture_object
*texObj
,
592 struct gl_texture_image
*texImage
)
594 driTextureObject
*t
= (driTextureObject
*) texObj
->DriverData
;
597 driSwapOutTextureObject(t
);
599 t
= (driTextureObject
*) r300AllocTexObj(texObj
);
601 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage1D");
606 /* Note, this will call ChooseTextureFormat */
607 _mesa_store_teximage1d(ctx
, target
, level
, internalFormat
,
608 width
, border
, format
, type
, pixels
,
609 &ctx
->Unpack
, texObj
, texImage
);
611 t
->dirty_images
[0] |= (1 << level
);
614 static void r300TexSubImage1D(GLcontext
* ctx
, GLenum target
, GLint level
,
617 GLenum format
, GLenum type
,
618 const GLvoid
* pixels
,
619 const struct gl_pixelstore_attrib
*packing
,
620 struct gl_texture_object
*texObj
,
621 struct gl_texture_image
*texImage
)
623 driTextureObject
*t
= (driTextureObject
*) texObj
->DriverData
;
625 assert(t
); /* this _should_ be true */
627 driSwapOutTextureObject(t
);
629 t
= (driTextureObject
*) r300AllocTexObj(texObj
);
631 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexSubImage1D");
636 _mesa_store_texsubimage1d(ctx
, target
, level
, xoffset
, width
,
637 format
, type
, pixels
, packing
, texObj
,
640 t
->dirty_images
[0] |= (1 << level
);
643 static void r300TexImage2D(GLcontext
* ctx
, GLenum target
, GLint level
,
644 GLint internalFormat
,
645 GLint width
, GLint height
, GLint border
,
646 GLenum format
, GLenum type
, const GLvoid
* pixels
,
647 const struct gl_pixelstore_attrib
*packing
,
648 struct gl_texture_object
*texObj
,
649 struct gl_texture_image
*texImage
)
651 driTextureObject
*t
= (driTextureObject
*) texObj
->DriverData
;
654 /* which cube face or ordinary 2D image */
656 case GL_TEXTURE_CUBE_MAP_POSITIVE_X
:
657 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X
:
658 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y
:
659 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y
:
660 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z
:
661 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z
:
663 (GLuint
) target
- (GLuint
) GL_TEXTURE_CUBE_MAP_POSITIVE_X
;
671 driSwapOutTextureObject(t
);
673 t
= (driTextureObject
*) r300AllocTexObj(texObj
);
675 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage2D");
680 texImage
->IsClientData
= GL_FALSE
;
682 if (r300ValidateClientStorage(ctx
, target
,
685 format
, type
, pixels
,
686 packing
, texObj
, texImage
)) {
687 if (RADEON_DEBUG
& DEBUG_TEXTURE
)
688 fprintf(stderr
, "%s: Using client storage\n",
691 if (RADEON_DEBUG
& DEBUG_TEXTURE
)
692 fprintf(stderr
, "%s: Using normal storage\n",
695 /* Normal path: copy (to cached memory) and eventually upload
696 * via another copy to GART memory and then a blit... Could
697 * eliminate one copy by going straight to (permanent) GART.
699 * Note, this will call r300ChooseTextureFormat.
701 _mesa_store_teximage2d(ctx
, target
, level
, internalFormat
,
702 width
, height
, border
, format
, type
,
703 pixels
, &ctx
->Unpack
, texObj
, texImage
);
705 t
->dirty_images
[face
] |= (1 << level
);
709 static void r300TexSubImage2D(GLcontext
* ctx
, GLenum target
, GLint level
,
710 GLint xoffset
, GLint yoffset
,
711 GLsizei width
, GLsizei height
,
712 GLenum format
, GLenum type
,
713 const GLvoid
* pixels
,
714 const struct gl_pixelstore_attrib
*packing
,
715 struct gl_texture_object
*texObj
,
716 struct gl_texture_image
*texImage
)
718 driTextureObject
*t
= (driTextureObject
*) texObj
->DriverData
;
721 /* which cube face or ordinary 2D image */
723 case GL_TEXTURE_CUBE_MAP_POSITIVE_X
:
724 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X
:
725 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y
:
726 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y
:
727 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z
:
728 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z
:
730 (GLuint
) target
- (GLuint
) GL_TEXTURE_CUBE_MAP_POSITIVE_X
;
737 assert(t
); /* this _should_ be true */
739 driSwapOutTextureObject(t
);
741 t
= (driTextureObject
*) r300AllocTexObj(texObj
);
743 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexSubImage2D");
748 _mesa_store_texsubimage2d(ctx
, target
, level
, xoffset
, yoffset
, width
,
749 height
, format
, type
, pixels
, packing
, texObj
,
752 t
->dirty_images
[face
] |= (1 << level
);
755 static void r300CompressedTexImage2D(GLcontext
* ctx
, GLenum target
,
756 GLint level
, GLint internalFormat
,
757 GLint width
, GLint height
, GLint border
,
758 GLsizei imageSize
, const GLvoid
* data
,
759 struct gl_texture_object
*texObj
,
760 struct gl_texture_image
*texImage
)
762 driTextureObject
*t
= (driTextureObject
*) texObj
->DriverData
;
765 /* which cube face or ordinary 2D image */
767 case GL_TEXTURE_CUBE_MAP_POSITIVE_X
:
768 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X
:
769 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y
:
770 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y
:
771 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z
:
772 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z
:
774 (GLuint
) target
- (GLuint
) GL_TEXTURE_CUBE_MAP_POSITIVE_X
;
782 driSwapOutTextureObject(t
);
784 t
= (driTextureObject
*) r300AllocTexObj(texObj
);
786 _mesa_error(ctx
, GL_OUT_OF_MEMORY
,
787 "glCompressedTexImage2D");
792 texImage
->IsClientData
= GL_FALSE
;
794 /* can't call this, different parameters. Would never evaluate to true anyway currently */
796 if (r300ValidateClientStorage(ctx
, target
,
799 format
, type
, pixels
,
800 packing
, texObj
, texImage
)) {
801 if (RADEON_DEBUG
& DEBUG_TEXTURE
)
802 fprintf(stderr
, "%s: Using client storage\n",
807 if (RADEON_DEBUG
& DEBUG_TEXTURE
)
808 fprintf(stderr
, "%s: Using normal storage\n",
811 /* Normal path: copy (to cached memory) and eventually upload
812 * via another copy to GART memory and then a blit... Could
813 * eliminate one copy by going straight to (permanent) GART.
815 * Note, this will call r300ChooseTextureFormat.
817 _mesa_store_compressed_teximage2d(ctx
, target
, level
,
818 internalFormat
, width
, height
,
819 border
, imageSize
, data
,
822 t
->dirty_images
[face
] |= (1 << level
);
826 static void r300CompressedTexSubImage2D(GLcontext
* ctx
, GLenum target
,
827 GLint level
, GLint xoffset
,
828 GLint yoffset
, GLsizei width
,
829 GLsizei height
, GLenum format
,
830 GLsizei imageSize
, const GLvoid
* data
,
831 struct gl_texture_object
*texObj
,
832 struct gl_texture_image
*texImage
)
834 driTextureObject
*t
= (driTextureObject
*) texObj
->DriverData
;
837 /* which cube face or ordinary 2D image */
839 case GL_TEXTURE_CUBE_MAP_POSITIVE_X
:
840 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X
:
841 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y
:
842 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y
:
843 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z
:
844 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z
:
846 (GLuint
) target
- (GLuint
) GL_TEXTURE_CUBE_MAP_POSITIVE_X
;
853 assert(t
); /* this _should_ be true */
855 driSwapOutTextureObject(t
);
857 t
= (driTextureObject
*) r300AllocTexObj(texObj
);
859 _mesa_error(ctx
, GL_OUT_OF_MEMORY
,
860 "glCompressedTexSubImage3D");
865 _mesa_store_compressed_texsubimage2d(ctx
, target
, level
, xoffset
,
866 yoffset
, width
, height
, format
,
867 imageSize
, data
, texObj
, texImage
);
869 t
->dirty_images
[face
] |= (1 << level
);
872 static void r300TexImage3D(GLcontext
* ctx
, GLenum target
, GLint level
,
873 GLint internalFormat
,
874 GLint width
, GLint height
, GLint depth
,
876 GLenum format
, GLenum type
, const GLvoid
* pixels
,
877 const struct gl_pixelstore_attrib
*packing
,
878 struct gl_texture_object
*texObj
,
879 struct gl_texture_image
*texImage
)
881 driTextureObject
*t
= (driTextureObject
*) texObj
->DriverData
;
884 driSwapOutTextureObject(t
);
886 t
= (driTextureObject
*) r300AllocTexObj(texObj
);
888 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage3D");
893 texImage
->IsClientData
= GL_FALSE
;
896 if (r300ValidateClientStorage(ctx
, target
,
899 format
, type
, pixels
,
900 packing
, texObj
, texImage
)) {
901 if (RADEON_DEBUG
& DEBUG_TEXTURE
)
902 fprintf(stderr
, "%s: Using client storage\n",
907 if (RADEON_DEBUG
& DEBUG_TEXTURE
)
908 fprintf(stderr
, "%s: Using normal storage\n",
911 /* Normal path: copy (to cached memory) and eventually upload
912 * via another copy to GART memory and then a blit... Could
913 * eliminate one copy by going straight to (permanent) GART.
915 * Note, this will call r300ChooseTextureFormat.
917 _mesa_store_teximage3d(ctx
, target
, level
, internalFormat
,
918 width
, height
, depth
, border
,
919 format
, type
, pixels
,
920 &ctx
->Unpack
, texObj
, texImage
);
922 t
->dirty_images
[0] |= (1 << level
);
927 r300TexSubImage3D(GLcontext
* ctx
, GLenum target
, GLint level
,
928 GLint xoffset
, GLint yoffset
, GLint zoffset
,
929 GLsizei width
, GLsizei height
, GLsizei depth
,
930 GLenum format
, GLenum type
,
931 const GLvoid
* pixels
,
932 const struct gl_pixelstore_attrib
*packing
,
933 struct gl_texture_object
*texObj
,
934 struct gl_texture_image
*texImage
)
936 driTextureObject
*t
= (driTextureObject
*) texObj
->DriverData
;
938 /* fprintf(stderr, "%s\n", __FUNCTION__); */
940 assert(t
); /* this _should_ be true */
942 driSwapOutTextureObject(t
);
944 t
= (driTextureObject
*) r300AllocTexObj(texObj
);
946 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexSubImage3D");
949 texObj
->DriverData
= t
;
952 _mesa_store_texsubimage3d(ctx
, target
, level
, xoffset
, yoffset
, zoffset
,
953 width
, height
, depth
,
954 format
, type
, pixels
, packing
, texObj
,
957 t
->dirty_images
[0] |= (1 << level
);
960 static void r300TexEnv(GLcontext
* ctx
, GLenum target
,
961 GLenum pname
, const GLfloat
* param
)
963 if (RADEON_DEBUG
& DEBUG_STATE
) {
964 fprintf(stderr
, "%s( %s )\n",
965 __FUNCTION__
, _mesa_lookup_enum_by_nr(pname
));
968 /* This is incorrect: Need to maintain this data for each of
969 * GL_TEXTURE_{123}D, GL_TEXTURE_RECTANGLE_NV, etc, and switch
970 * between them according to _ReallyEnabled.
973 case GL_TEXTURE_LOD_BIAS_EXT
:{
974 #if 0 /* Needs to be relocated in order to make sure we got the right tmu */
978 /* The R300's LOD bias is a signed 2's complement value with a
979 * range of -16.0 <= bias < 16.0.
981 * NOTE: Add a small bias to the bias for conform mipsel.c test.
985 driQueryOptionb(&rmesa
->radeon
.optionCache
,
986 "no_neg_lod_bias") ? 0.0 : -16.0;
987 bias
= CLAMP(bias
, min
, 16.0);
989 /* 0.0 - 16.0 == 0x0 - 0x1000 */
990 /* 0.0 - -16.0 == 0x1001 - 0x1fff */
991 b
= 0x1000 / 16.0 * bias
;
992 b
&= R300_LOD_BIAS_MASK
;
995 (rmesa
->hw
.tex
.unknown1
.
996 cmd
[R300_TEX_VALUE_0
+
997 unit
] & R300_LOD_BIAS_MASK
)) {
998 R300_STATECHANGE(rmesa
, tex
.unknown1
);
999 rmesa
->hw
.tex
.unknown1
.cmd
[R300_TEX_VALUE_0
+
1001 ~R300_LOD_BIAS_MASK
;
1002 rmesa
->hw
.tex
.unknown1
.cmd
[R300_TEX_VALUE_0
+
1015 * Changes variables and flags for a state update, which will happen at the
1016 * next UpdateTextureState
1019 static void r300TexParameter(GLcontext
* ctx
, GLenum target
,
1020 struct gl_texture_object
*texObj
,
1021 GLenum pname
, const GLfloat
* params
)
1023 r300TexObjPtr t
= (r300TexObjPtr
) texObj
->DriverData
;
1025 if (RADEON_DEBUG
& (DEBUG_STATE
| DEBUG_TEXTURE
)) {
1026 fprintf(stderr
, "%s( %s )\n", __FUNCTION__
,
1027 _mesa_lookup_enum_by_nr(pname
));
1031 case GL_TEXTURE_MIN_FILTER
:
1032 case GL_TEXTURE_MAG_FILTER
:
1033 case GL_TEXTURE_MAX_ANISOTROPY_EXT
:
1034 r300SetTexMaxAnisotropy(t
, texObj
->MaxAnisotropy
);
1035 r300SetTexFilter(t
, texObj
->MinFilter
, texObj
->MagFilter
);
1038 case GL_TEXTURE_WRAP_S
:
1039 case GL_TEXTURE_WRAP_T
:
1040 case GL_TEXTURE_WRAP_R
:
1041 r300SetTexWrap(t
, texObj
->WrapS
, texObj
->WrapT
, texObj
->WrapR
);
1044 case GL_TEXTURE_BORDER_COLOR
:
1045 r300SetTexBorderColor(t
, texObj
->_BorderChan
);
1048 case GL_TEXTURE_BASE_LEVEL
:
1049 case GL_TEXTURE_MAX_LEVEL
:
1050 case GL_TEXTURE_MIN_LOD
:
1051 case GL_TEXTURE_MAX_LOD
:
1052 /* This isn't the most efficient solution but there doesn't appear to
1053 * be a nice alternative. Since there's no LOD clamping,
1054 * we just have to rely on loading the right subset of mipmap levels
1055 * to simulate a clamped LOD.
1057 driSwapOutTextureObject((driTextureObject
*) t
);
1064 /* Mark this texobj as dirty (one bit per tex unit)
1066 t
->dirty_state
= TEX_ALL
;
1069 static void r300BindTexture(GLcontext
* ctx
, GLenum target
,
1070 struct gl_texture_object
*texObj
)
1072 if (RADEON_DEBUG
& (DEBUG_STATE
| DEBUG_TEXTURE
)) {
1073 fprintf(stderr
, "%s( %p ) unit=%d\n", __FUNCTION__
,
1074 (void *)texObj
, ctx
->Texture
.CurrentUnit
);
1077 if ((target
== GL_TEXTURE_1D
)
1078 || (target
== GL_TEXTURE_2D
)
1079 || (target
== GL_TEXTURE_3D
)
1080 || (target
== GL_TEXTURE_CUBE_MAP
)
1081 || (target
== GL_TEXTURE_RECTANGLE_NV
)) {
1082 assert(texObj
->DriverData
!= NULL
);
1086 static void r300DeleteTexture(GLcontext
* ctx
, struct gl_texture_object
*texObj
)
1088 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
1089 driTextureObject
*t
= (driTextureObject
*) texObj
->DriverData
;
1091 if (RADEON_DEBUG
& (DEBUG_STATE
| DEBUG_TEXTURE
)) {
1092 fprintf(stderr
, "%s( %p (target = %s) )\n", __FUNCTION__
,
1094 _mesa_lookup_enum_by_nr(texObj
->Target
));
1099 R300_FIREVERTICES(rmesa
);
1102 driDestroyTextureObject(t
);
1104 /* Free mipmap images and the texture object itself */
1105 _mesa_delete_texture_object(ctx
, texObj
);
1109 * Allocate a new texture object.
1110 * Called via ctx->Driver.NewTextureObject.
1111 * Note: this function will be called during context creation to
1112 * allocate the default texture objects.
1113 * Note: we could use containment here to 'derive' the driver-specific
1114 * texture object from the core mesa gl_texture_object. Not done at this time.
1115 * Fixup MaxAnisotropy according to user preference.
1117 static struct gl_texture_object
*r300NewTextureObject(GLcontext
* ctx
,
1121 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
1122 struct gl_texture_object
*obj
;
1123 obj
= _mesa_new_texture_object(ctx
, name
, target
);
1126 obj
->MaxAnisotropy
= rmesa
->initialMaxAnisotropy
;
1128 r300AllocTexObj(obj
);
1132 void r300InitTextureFuncs(struct dd_function_table
*functions
)
1134 /* Note: we only plug in the functions we implement in the driver
1135 * since _mesa_init_driver_functions() was already called.
1137 functions
->ChooseTextureFormat
= r300ChooseTextureFormat
;
1138 functions
->TexImage1D
= r300TexImage1D
;
1139 functions
->TexImage2D
= r300TexImage2D
;
1140 functions
->TexImage3D
= r300TexImage3D
;
1141 functions
->TexSubImage1D
= r300TexSubImage1D
;
1142 functions
->TexSubImage2D
= r300TexSubImage2D
;
1143 functions
->TexSubImage3D
= r300TexSubImage3D
;
1144 functions
->NewTextureObject
= r300NewTextureObject
;
1145 functions
->BindTexture
= r300BindTexture
;
1146 functions
->DeleteTexture
= r300DeleteTexture
;
1147 functions
->IsTextureResident
= driIsTextureResident
;
1149 functions
->TexEnv
= r300TexEnv
;
1150 functions
->TexParameter
= r300TexParameter
;
1152 functions
->CompressedTexImage2D
= r300CompressedTexImage2D
;
1153 functions
->CompressedTexSubImage2D
= r300CompressedTexSubImage2D
;
1155 driInitTextureFormats();