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
298 && !littleEndian
) || (srcFormat
== GL_ABGR_EXT
299 && srcType
== GL_UNSIGNED_INT_8_8_8_8_REV
)
300 || (srcFormat
== GL_ABGR_EXT
&& srcType
== GL_UNSIGNED_BYTE
302 return &_mesa_texformat_rgba8888
;
304 if ((srcFormat
== GL_RGBA
&& srcType
== GL_UNSIGNED_INT_8_8_8_8_REV
)
305 || (srcFormat
== GL_RGBA
&& srcType
== GL_UNSIGNED_BYTE
306 && littleEndian
) || (srcFormat
== GL_ABGR_EXT
307 && srcType
== GL_UNSIGNED_INT_8_8_8_8
)
308 || (srcFormat
== GL_ABGR_EXT
&& srcType
== GL_UNSIGNED_BYTE
310 return &_mesa_texformat_rgba8888_rev
;
311 } else if (srcFormat
== GL_BGRA
&&
312 ((srcType
== GL_UNSIGNED_BYTE
&& !littleEndian
) ||
313 srcType
== GL_UNSIGNED_INT_8_8_8_8
)) {
314 return &_mesa_texformat_argb8888_rev
;
315 } else if (srcFormat
== GL_BGRA
&&
316 ((srcType
== GL_UNSIGNED_BYTE
&& littleEndian
) ||
317 srcType
== GL_UNSIGNED_INT_8_8_8_8_REV
)) {
318 return &_mesa_texformat_argb8888
;
320 return _dri_texformat_argb8888
;
323 static const struct gl_texture_format
*r300ChooseTextureFormat(GLcontext
* ctx
,
329 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
330 const GLboolean do32bpt
=
331 (rmesa
->texture_depth
== DRI_CONF_TEXTURE_DEPTH_32
);
332 const GLboolean force16bpt
=
333 (rmesa
->texture_depth
== DRI_CONF_TEXTURE_DEPTH_FORCE_16
);
337 fprintf(stderr
, "InternalFormat=%s(%d) type=%s format=%s\n",
338 _mesa_lookup_enum_by_nr(internalFormat
), internalFormat
,
339 _mesa_lookup_enum_by_nr(type
), _mesa_lookup_enum_by_nr(format
));
340 fprintf(stderr
, "do32bpt=%d force16bpt=%d\n", do32bpt
, force16bpt
);
343 switch (internalFormat
) {
346 case GL_COMPRESSED_RGBA
:
348 case GL_UNSIGNED_INT_10_10_10_2
:
349 case GL_UNSIGNED_INT_2_10_10_10_REV
:
350 return do32bpt
? _dri_texformat_argb8888
:
351 _dri_texformat_argb1555
;
352 case GL_UNSIGNED_SHORT_4_4_4_4
:
353 case GL_UNSIGNED_SHORT_4_4_4_4_REV
:
354 return _dri_texformat_argb4444
;
355 case GL_UNSIGNED_SHORT_5_5_5_1
:
356 case GL_UNSIGNED_SHORT_1_5_5_5_REV
:
357 return _dri_texformat_argb1555
;
359 return do32bpt
? r300Choose8888TexFormat(format
, type
) :
360 _dri_texformat_argb4444
;
365 case GL_COMPRESSED_RGB
:
367 case GL_UNSIGNED_SHORT_4_4_4_4
:
368 case GL_UNSIGNED_SHORT_4_4_4_4_REV
:
369 return _dri_texformat_argb4444
;
370 case GL_UNSIGNED_SHORT_5_5_5_1
:
371 case GL_UNSIGNED_SHORT_1_5_5_5_REV
:
372 return _dri_texformat_argb1555
;
373 case GL_UNSIGNED_SHORT_5_6_5
:
374 case GL_UNSIGNED_SHORT_5_6_5_REV
:
375 return _dri_texformat_rgb565
;
377 return do32bpt
? _dri_texformat_argb8888
:
378 _dri_texformat_rgb565
;
386 r300Choose8888TexFormat(format
,
387 type
) : _dri_texformat_argb4444
;
391 return _dri_texformat_argb4444
;
394 return _dri_texformat_argb1555
;
400 return !force16bpt
? _dri_texformat_argb8888
:
401 _dri_texformat_rgb565
;
406 return _dri_texformat_rgb565
;
413 case GL_COMPRESSED_ALPHA
:
414 return _dri_texformat_a8
;
422 case GL_COMPRESSED_LUMINANCE
:
423 return _dri_texformat_l8
;
426 case GL_LUMINANCE_ALPHA
:
427 case GL_LUMINANCE4_ALPHA4
:
428 case GL_LUMINANCE6_ALPHA2
:
429 case GL_LUMINANCE8_ALPHA8
:
430 case GL_LUMINANCE12_ALPHA4
:
431 case GL_LUMINANCE12_ALPHA12
:
432 case GL_LUMINANCE16_ALPHA16
:
433 case GL_COMPRESSED_LUMINANCE_ALPHA
:
434 return _dri_texformat_al88
;
441 case GL_COMPRESSED_INTENSITY
:
442 return _dri_texformat_i8
;
445 if (type
== GL_UNSIGNED_SHORT_8_8_APPLE
||
446 type
== GL_UNSIGNED_BYTE
)
447 return &_mesa_texformat_ycbcr
;
449 return &_mesa_texformat_ycbcr_rev
;
453 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT
:
454 return &_mesa_texformat_rgb_dxt1
;
456 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT
:
457 return &_mesa_texformat_rgba_dxt1
;
461 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT
:
462 return &_mesa_texformat_rgba_dxt3
;
464 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT
:
465 return &_mesa_texformat_rgba_dxt5
;
467 case GL_ALPHA16F_ARB
:
468 return &_mesa_texformat_alpha_float16
;
469 case GL_ALPHA32F_ARB
:
470 return &_mesa_texformat_alpha_float32
;
471 case GL_LUMINANCE16F_ARB
:
472 return &_mesa_texformat_luminance_float16
;
473 case GL_LUMINANCE32F_ARB
:
474 return &_mesa_texformat_luminance_float32
;
475 case GL_LUMINANCE_ALPHA16F_ARB
:
476 return &_mesa_texformat_luminance_alpha_float16
;
477 case GL_LUMINANCE_ALPHA32F_ARB
:
478 return &_mesa_texformat_luminance_alpha_float32
;
479 case GL_INTENSITY16F_ARB
:
480 return &_mesa_texformat_intensity_float16
;
481 case GL_INTENSITY32F_ARB
:
482 return &_mesa_texformat_intensity_float32
;
484 return &_mesa_texformat_rgba_float16
;
486 return &_mesa_texformat_rgba_float32
;
488 return &_mesa_texformat_rgba_float16
;
490 return &_mesa_texformat_rgba_float32
;
494 "unexpected internalFormat 0x%x in r300ChooseTextureFormat",
495 (int)internalFormat
);
499 return NULL
; /* never get here */
503 r300ValidateClientStorage(GLcontext
* ctx
, GLenum target
,
504 GLint internalFormat
,
505 GLint srcWidth
, GLint srcHeight
,
506 GLenum format
, GLenum type
, const void *pixels
,
507 const struct gl_pixelstore_attrib
*packing
,
508 struct gl_texture_object
*texObj
,
509 struct gl_texture_image
*texImage
)
511 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
513 if (RADEON_DEBUG
& DEBUG_TEXTURE
)
514 fprintf(stderr
, "intformat %s format %s type %s\n",
515 _mesa_lookup_enum_by_nr(internalFormat
),
516 _mesa_lookup_enum_by_nr(format
),
517 _mesa_lookup_enum_by_nr(type
));
519 if (!ctx
->Unpack
.ClientStorage
)
522 if (ctx
->_ImageTransferState
||
523 texImage
->IsCompressed
|| texObj
->GenerateMipmap
)
526 /* This list is incomplete, may be different on ppc???
528 switch (internalFormat
) {
530 if (format
== GL_BGRA
&& type
== GL_UNSIGNED_INT_8_8_8_8_REV
) {
531 texImage
->TexFormat
= _dri_texformat_argb8888
;
537 if (format
== GL_RGB
&& type
== GL_UNSIGNED_SHORT_5_6_5
) {
538 texImage
->TexFormat
= _dri_texformat_rgb565
;
544 if (format
== GL_YCBCR_MESA
&&
545 type
== GL_UNSIGNED_SHORT_8_8_REV_APPLE
) {
546 texImage
->TexFormat
= &_mesa_texformat_ycbcr_rev
;
547 } else if (format
== GL_YCBCR_MESA
&&
548 (type
== GL_UNSIGNED_SHORT_8_8_APPLE
||
549 type
== GL_UNSIGNED_BYTE
)) {
550 texImage
->TexFormat
= &_mesa_texformat_ycbcr
;
559 /* Could deal with these packing issues, but currently don't:
561 if (packing
->SkipPixels
||
562 packing
->SkipRows
|| packing
->SwapBytes
|| packing
->LsbFirst
) {
567 GLint srcRowStride
= _mesa_image_row_stride(packing
, srcWidth
,
570 if (RADEON_DEBUG
& DEBUG_TEXTURE
)
571 fprintf(stderr
, "%s: srcRowStride %d/%x\n",
572 __FUNCTION__
, srcRowStride
, srcRowStride
);
574 /* Could check this later in upload, pitch restrictions could be
575 * relaxed, but would need to store the image pitch somewhere,
576 * as packing details might change before image is uploaded:
578 if (!r300IsGartMemory(rmesa
, pixels
, srcHeight
* srcRowStride
)
579 || (srcRowStride
& 63))
582 /* Have validated that _mesa_transfer_teximage would be a straight
583 * memcpy at this point. NOTE: future calls to TexSubImage will
584 * overwrite the client data. This is explicitly mentioned in the
587 texImage
->Data
= (void *)pixels
;
588 texImage
->IsClientData
= GL_TRUE
;
589 texImage
->RowStride
=
590 srcRowStride
/ texImage
->TexFormat
->TexelBytes
;
596 static void r300TexImage1D(GLcontext
* ctx
, GLenum target
, GLint level
,
597 GLint internalFormat
,
598 GLint width
, GLint border
,
599 GLenum format
, GLenum type
, const GLvoid
* pixels
,
600 const struct gl_pixelstore_attrib
*packing
,
601 struct gl_texture_object
*texObj
,
602 struct gl_texture_image
*texImage
)
604 driTextureObject
*t
= (driTextureObject
*) texObj
->DriverData
;
607 driSwapOutTextureObject(t
);
609 t
= (driTextureObject
*) r300AllocTexObj(texObj
);
611 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage1D");
616 /* Note, this will call ChooseTextureFormat */
617 _mesa_store_teximage1d(ctx
, target
, level
, internalFormat
,
618 width
, border
, format
, type
, pixels
,
619 &ctx
->Unpack
, texObj
, texImage
);
621 t
->dirty_images
[0] |= (1 << level
);
624 static void r300TexSubImage1D(GLcontext
* ctx
, GLenum target
, GLint level
,
627 GLenum format
, GLenum type
,
628 const GLvoid
* pixels
,
629 const struct gl_pixelstore_attrib
*packing
,
630 struct gl_texture_object
*texObj
,
631 struct gl_texture_image
*texImage
)
633 driTextureObject
*t
= (driTextureObject
*) texObj
->DriverData
;
635 assert(t
); /* this _should_ be true */
637 driSwapOutTextureObject(t
);
639 t
= (driTextureObject
*) r300AllocTexObj(texObj
);
641 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexSubImage1D");
646 _mesa_store_texsubimage1d(ctx
, target
, level
, xoffset
, width
,
647 format
, type
, pixels
, packing
, texObj
,
650 t
->dirty_images
[0] |= (1 << level
);
653 static void r300TexImage2D(GLcontext
* ctx
, GLenum target
, GLint level
,
654 GLint internalFormat
,
655 GLint width
, GLint height
, GLint border
,
656 GLenum format
, GLenum type
, const GLvoid
* pixels
,
657 const struct gl_pixelstore_attrib
*packing
,
658 struct gl_texture_object
*texObj
,
659 struct gl_texture_image
*texImage
)
661 driTextureObject
*t
= (driTextureObject
*) texObj
->DriverData
;
664 /* which cube face or ordinary 2D image */
666 case GL_TEXTURE_CUBE_MAP_POSITIVE_X
:
667 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X
:
668 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y
:
669 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y
:
670 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z
:
671 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z
:
673 (GLuint
) target
- (GLuint
) GL_TEXTURE_CUBE_MAP_POSITIVE_X
;
681 driSwapOutTextureObject(t
);
683 t
= (driTextureObject
*) r300AllocTexObj(texObj
);
685 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage2D");
690 texImage
->IsClientData
= GL_FALSE
;
692 if (r300ValidateClientStorage(ctx
, target
,
695 format
, type
, pixels
,
696 packing
, texObj
, texImage
)) {
697 if (RADEON_DEBUG
& DEBUG_TEXTURE
)
698 fprintf(stderr
, "%s: Using client storage\n",
701 if (RADEON_DEBUG
& DEBUG_TEXTURE
)
702 fprintf(stderr
, "%s: Using normal storage\n",
705 /* Normal path: copy (to cached memory) and eventually upload
706 * via another copy to GART memory and then a blit... Could
707 * eliminate one copy by going straight to (permanent) GART.
709 * Note, this will call r300ChooseTextureFormat.
711 _mesa_store_teximage2d(ctx
, target
, level
, internalFormat
,
712 width
, height
, border
, format
, type
,
713 pixels
, &ctx
->Unpack
, texObj
, texImage
);
715 t
->dirty_images
[face
] |= (1 << level
);
719 static void r300TexSubImage2D(GLcontext
* ctx
, GLenum target
, GLint level
,
720 GLint xoffset
, GLint yoffset
,
721 GLsizei width
, GLsizei height
,
722 GLenum format
, GLenum type
,
723 const GLvoid
* pixels
,
724 const struct gl_pixelstore_attrib
*packing
,
725 struct gl_texture_object
*texObj
,
726 struct gl_texture_image
*texImage
)
728 driTextureObject
*t
= (driTextureObject
*) texObj
->DriverData
;
731 /* which cube face or ordinary 2D image */
733 case GL_TEXTURE_CUBE_MAP_POSITIVE_X
:
734 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X
:
735 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y
:
736 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y
:
737 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z
:
738 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z
:
740 (GLuint
) target
- (GLuint
) GL_TEXTURE_CUBE_MAP_POSITIVE_X
;
747 assert(t
); /* this _should_ be true */
749 driSwapOutTextureObject(t
);
751 t
= (driTextureObject
*) r300AllocTexObj(texObj
);
753 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexSubImage2D");
758 _mesa_store_texsubimage2d(ctx
, target
, level
, xoffset
, yoffset
, width
,
759 height
, format
, type
, pixels
, packing
, texObj
,
762 t
->dirty_images
[face
] |= (1 << level
);
765 static void r300CompressedTexImage2D(GLcontext
* ctx
, GLenum target
,
766 GLint level
, GLint internalFormat
,
767 GLint width
, GLint height
, GLint border
,
768 GLsizei imageSize
, const GLvoid
* data
,
769 struct gl_texture_object
*texObj
,
770 struct gl_texture_image
*texImage
)
772 driTextureObject
*t
= (driTextureObject
*) texObj
->DriverData
;
775 /* which cube face or ordinary 2D image */
777 case GL_TEXTURE_CUBE_MAP_POSITIVE_X
:
778 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X
:
779 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y
:
780 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y
:
781 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z
:
782 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z
:
784 (GLuint
) target
- (GLuint
) GL_TEXTURE_CUBE_MAP_POSITIVE_X
;
792 driSwapOutTextureObject(t
);
794 t
= (driTextureObject
*) r300AllocTexObj(texObj
);
796 _mesa_error(ctx
, GL_OUT_OF_MEMORY
,
797 "glCompressedTexImage2D");
802 texImage
->IsClientData
= GL_FALSE
;
804 /* can't call this, different parameters. Would never evaluate to true anyway currently */
806 if (r300ValidateClientStorage(ctx
, target
,
809 format
, type
, pixels
,
810 packing
, texObj
, texImage
)) {
811 if (RADEON_DEBUG
& DEBUG_TEXTURE
)
812 fprintf(stderr
, "%s: Using client storage\n",
817 if (RADEON_DEBUG
& DEBUG_TEXTURE
)
818 fprintf(stderr
, "%s: Using normal storage\n",
821 /* Normal path: copy (to cached memory) and eventually upload
822 * via another copy to GART memory and then a blit... Could
823 * eliminate one copy by going straight to (permanent) GART.
825 * Note, this will call r300ChooseTextureFormat.
827 _mesa_store_compressed_teximage2d(ctx
, target
, level
,
828 internalFormat
, width
, height
,
829 border
, imageSize
, data
,
832 t
->dirty_images
[face
] |= (1 << level
);
836 static void r300CompressedTexSubImage2D(GLcontext
* ctx
, GLenum target
,
837 GLint level
, GLint xoffset
,
838 GLint yoffset
, GLsizei width
,
839 GLsizei height
, GLenum format
,
840 GLsizei imageSize
, const GLvoid
* data
,
841 struct gl_texture_object
*texObj
,
842 struct gl_texture_image
*texImage
)
844 driTextureObject
*t
= (driTextureObject
*) texObj
->DriverData
;
847 /* which cube face or ordinary 2D image */
849 case GL_TEXTURE_CUBE_MAP_POSITIVE_X
:
850 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X
:
851 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y
:
852 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y
:
853 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z
:
854 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z
:
856 (GLuint
) target
- (GLuint
) GL_TEXTURE_CUBE_MAP_POSITIVE_X
;
863 assert(t
); /* this _should_ be true */
865 driSwapOutTextureObject(t
);
867 t
= (driTextureObject
*) r300AllocTexObj(texObj
);
869 _mesa_error(ctx
, GL_OUT_OF_MEMORY
,
870 "glCompressedTexSubImage3D");
875 _mesa_store_compressed_texsubimage2d(ctx
, target
, level
, xoffset
,
876 yoffset
, width
, height
, format
,
877 imageSize
, data
, texObj
, texImage
);
879 t
->dirty_images
[face
] |= (1 << level
);
882 static void r300TexImage3D(GLcontext
* ctx
, GLenum target
, GLint level
,
883 GLint internalFormat
,
884 GLint width
, GLint height
, GLint depth
,
886 GLenum format
, GLenum type
, const GLvoid
* pixels
,
887 const struct gl_pixelstore_attrib
*packing
,
888 struct gl_texture_object
*texObj
,
889 struct gl_texture_image
*texImage
)
891 driTextureObject
*t
= (driTextureObject
*) texObj
->DriverData
;
894 driSwapOutTextureObject(t
);
896 t
= (driTextureObject
*) r300AllocTexObj(texObj
);
898 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage3D");
903 texImage
->IsClientData
= GL_FALSE
;
906 if (r300ValidateClientStorage(ctx
, target
,
909 format
, type
, pixels
,
910 packing
, texObj
, texImage
)) {
911 if (RADEON_DEBUG
& DEBUG_TEXTURE
)
912 fprintf(stderr
, "%s: Using client storage\n",
917 if (RADEON_DEBUG
& DEBUG_TEXTURE
)
918 fprintf(stderr
, "%s: Using normal storage\n",
921 /* Normal path: copy (to cached memory) and eventually upload
922 * via another copy to GART memory and then a blit... Could
923 * eliminate one copy by going straight to (permanent) GART.
925 * Note, this will call r300ChooseTextureFormat.
927 _mesa_store_teximage3d(ctx
, target
, level
, internalFormat
,
928 width
, height
, depth
, border
,
929 format
, type
, pixels
,
930 &ctx
->Unpack
, texObj
, texImage
);
932 t
->dirty_images
[0] |= (1 << level
);
937 r300TexSubImage3D(GLcontext
* ctx
, GLenum target
, GLint level
,
938 GLint xoffset
, GLint yoffset
, GLint zoffset
,
939 GLsizei width
, GLsizei height
, GLsizei depth
,
940 GLenum format
, GLenum type
,
941 const GLvoid
* pixels
,
942 const struct gl_pixelstore_attrib
*packing
,
943 struct gl_texture_object
*texObj
,
944 struct gl_texture_image
*texImage
)
946 driTextureObject
*t
= (driTextureObject
*) texObj
->DriverData
;
948 /* fprintf(stderr, "%s\n", __FUNCTION__); */
950 assert(t
); /* this _should_ be true */
952 driSwapOutTextureObject(t
);
954 t
= (driTextureObject
*) r300AllocTexObj(texObj
);
956 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexSubImage3D");
959 texObj
->DriverData
= t
;
962 _mesa_store_texsubimage3d(ctx
, target
, level
, xoffset
, yoffset
, zoffset
,
963 width
, height
, depth
,
964 format
, type
, pixels
, packing
, texObj
,
967 t
->dirty_images
[0] |= (1 << level
);
970 static void r300TexEnv(GLcontext
* ctx
, GLenum target
,
971 GLenum pname
, const GLfloat
* param
)
973 if (RADEON_DEBUG
& DEBUG_STATE
) {
974 fprintf(stderr
, "%s( %s )\n",
975 __FUNCTION__
, _mesa_lookup_enum_by_nr(pname
));
978 /* This is incorrect: Need to maintain this data for each of
979 * GL_TEXTURE_{123}D, GL_TEXTURE_RECTANGLE_NV, etc, and switch
980 * between them according to _ReallyEnabled.
983 case GL_TEXTURE_LOD_BIAS_EXT
:{
984 #if 0 /* Needs to be relocated in order to make sure we got the right tmu */
988 /* The R300's LOD bias is a signed 2's complement value with a
989 * range of -16.0 <= bias < 16.0.
991 * NOTE: Add a small bias to the bias for conform mipsel.c test.
995 driQueryOptionb(&rmesa
->radeon
.optionCache
,
996 "no_neg_lod_bias") ? 0.0 : -16.0;
997 bias
= CLAMP(bias
, min
, 16.0);
999 /* 0.0 - 16.0 == 0x0 - 0x1000 */
1000 /* 0.0 - -16.0 == 0x1001 - 0x1fff */
1001 b
= 0x1000 / 16.0 * bias
;
1002 b
&= R300_LOD_BIAS_MASK
;
1005 (rmesa
->hw
.tex
.unknown1
.
1006 cmd
[R300_TEX_VALUE_0
+
1007 unit
] & R300_LOD_BIAS_MASK
)) {
1008 R300_STATECHANGE(rmesa
, tex
.unknown1
);
1009 rmesa
->hw
.tex
.unknown1
.cmd
[R300_TEX_VALUE_0
+
1011 ~R300_LOD_BIAS_MASK
;
1012 rmesa
->hw
.tex
.unknown1
.cmd
[R300_TEX_VALUE_0
+
1025 * Changes variables and flags for a state update, which will happen at the
1026 * next UpdateTextureState
1029 static void r300TexParameter(GLcontext
* ctx
, GLenum target
,
1030 struct gl_texture_object
*texObj
,
1031 GLenum pname
, const GLfloat
* params
)
1033 r300TexObjPtr t
= (r300TexObjPtr
) texObj
->DriverData
;
1035 if (RADEON_DEBUG
& (DEBUG_STATE
| DEBUG_TEXTURE
)) {
1036 fprintf(stderr
, "%s( %s )\n", __FUNCTION__
,
1037 _mesa_lookup_enum_by_nr(pname
));
1041 case GL_TEXTURE_MIN_FILTER
:
1042 case GL_TEXTURE_MAG_FILTER
:
1043 case GL_TEXTURE_MAX_ANISOTROPY_EXT
:
1044 r300SetTexMaxAnisotropy(t
, texObj
->MaxAnisotropy
);
1045 r300SetTexFilter(t
, texObj
->MinFilter
, texObj
->MagFilter
);
1048 case GL_TEXTURE_WRAP_S
:
1049 case GL_TEXTURE_WRAP_T
:
1050 case GL_TEXTURE_WRAP_R
:
1051 r300SetTexWrap(t
, texObj
->WrapS
, texObj
->WrapT
, texObj
->WrapR
);
1054 case GL_TEXTURE_BORDER_COLOR
:
1055 r300SetTexBorderColor(t
, texObj
->_BorderChan
);
1058 case GL_TEXTURE_BASE_LEVEL
:
1059 case GL_TEXTURE_MAX_LEVEL
:
1060 case GL_TEXTURE_MIN_LOD
:
1061 case GL_TEXTURE_MAX_LOD
:
1062 /* This isn't the most efficient solution but there doesn't appear to
1063 * be a nice alternative. Since there's no LOD clamping,
1064 * we just have to rely on loading the right subset of mipmap levels
1065 * to simulate a clamped LOD.
1067 driSwapOutTextureObject((driTextureObject
*) t
);
1074 /* Mark this texobj as dirty (one bit per tex unit)
1076 t
->dirty_state
= TEX_ALL
;
1079 static void r300BindTexture(GLcontext
* ctx
, GLenum target
,
1080 struct gl_texture_object
*texObj
)
1082 if (RADEON_DEBUG
& (DEBUG_STATE
| DEBUG_TEXTURE
)) {
1083 fprintf(stderr
, "%s( %p ) unit=%d\n", __FUNCTION__
,
1084 (void *)texObj
, ctx
->Texture
.CurrentUnit
);
1087 if ((target
== GL_TEXTURE_1D
)
1088 || (target
== GL_TEXTURE_2D
)
1089 || (target
== GL_TEXTURE_3D
)
1090 || (target
== GL_TEXTURE_CUBE_MAP
)
1091 || (target
== GL_TEXTURE_RECTANGLE_NV
)) {
1092 assert(texObj
->DriverData
!= NULL
);
1096 static void r300DeleteTexture(GLcontext
* ctx
, struct gl_texture_object
*texObj
)
1098 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
1099 driTextureObject
*t
= (driTextureObject
*) texObj
->DriverData
;
1101 if (RADEON_DEBUG
& (DEBUG_STATE
| DEBUG_TEXTURE
)) {
1102 fprintf(stderr
, "%s( %p (target = %s) )\n", __FUNCTION__
,
1104 _mesa_lookup_enum_by_nr(texObj
->Target
));
1109 R300_FIREVERTICES(rmesa
);
1112 driDestroyTextureObject(t
);
1114 /* Free mipmap images and the texture object itself */
1115 _mesa_delete_texture_object(ctx
, texObj
);
1119 * Allocate a new texture object.
1120 * Called via ctx->Driver.NewTextureObject.
1121 * Note: this function will be called during context creation to
1122 * allocate the default texture objects.
1123 * Note: we could use containment here to 'derive' the driver-specific
1124 * texture object from the core mesa gl_texture_object. Not done at this time.
1125 * Fixup MaxAnisotropy according to user preference.
1127 static struct gl_texture_object
*r300NewTextureObject(GLcontext
* ctx
,
1131 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
1132 struct gl_texture_object
*obj
;
1133 obj
= _mesa_new_texture_object(ctx
, name
, target
);
1136 obj
->MaxAnisotropy
= rmesa
->initialMaxAnisotropy
;
1138 r300AllocTexObj(obj
);
1142 void r300InitTextureFuncs(struct dd_function_table
*functions
)
1144 /* Note: we only plug in the functions we implement in the driver
1145 * since _mesa_init_driver_functions() was already called.
1147 functions
->ChooseTextureFormat
= r300ChooseTextureFormat
;
1148 functions
->TexImage1D
= r300TexImage1D
;
1149 functions
->TexImage2D
= r300TexImage2D
;
1150 functions
->TexImage3D
= r300TexImage3D
;
1151 functions
->TexSubImage1D
= r300TexSubImage1D
;
1152 functions
->TexSubImage2D
= r300TexSubImage2D
;
1153 functions
->TexSubImage3D
= r300TexSubImage3D
;
1154 functions
->NewTextureObject
= r300NewTextureObject
;
1155 functions
->BindTexture
= r300BindTexture
;
1156 functions
->DeleteTexture
= r300DeleteTexture
;
1157 functions
->IsTextureResident
= driIsTextureResident
;
1159 functions
->TexEnv
= r300TexEnv
;
1160 functions
->TexParameter
= r300TexParameter
;
1162 functions
->CompressedTexImage2D
= r300CompressedTexImage2D
;
1163 functions
->CompressedTexSubImage2D
= r300CompressedTexSubImage2D
;
1165 driInitTextureFormats();