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 static unsigned int translate_wrap_mode(GLenum wrapmode
)
59 case GL_REPEAT
: return R300_TX_REPEAT
;
60 case GL_CLAMP
: return R300_TX_CLAMP
;
61 case GL_CLAMP_TO_EDGE
: return R300_TX_CLAMP_TO_EDGE
;
62 case GL_CLAMP_TO_BORDER
: return R300_TX_CLAMP_TO_BORDER
;
63 case GL_MIRRORED_REPEAT
: return R300_TX_REPEAT
| R300_TX_MIRRORED
;
64 case GL_MIRROR_CLAMP_EXT
: return R300_TX_CLAMP
| R300_TX_MIRRORED
;
65 case GL_MIRROR_CLAMP_TO_EDGE_EXT
: return R300_TX_CLAMP_TO_EDGE
| R300_TX_MIRRORED
;
66 case GL_MIRROR_CLAMP_TO_BORDER_EXT
: return R300_TX_CLAMP_TO_BORDER
| R300_TX_MIRRORED
;
68 _mesa_problem(NULL
, "bad wrap mode in %s", __FUNCTION__
);
75 * Update the cached hardware registers based on the current texture wrap modes.
77 * \param t Texture object whose wrap modes are to be set
79 static void r300UpdateTexWrap(r300TexObjPtr t
)
81 struct gl_texture_object
*tObj
= t
->base
.tObj
;
84 ~(R300_TX_WRAP_S_MASK
| R300_TX_WRAP_T_MASK
| R300_TX_WRAP_R_MASK
);
86 t
->filter
|= translate_wrap_mode(tObj
->WrapS
) << R300_TX_WRAP_S_SHIFT
;
88 if (tObj
->Target
!= GL_TEXTURE_1D
) {
89 t
->filter
|= translate_wrap_mode(tObj
->WrapT
) << R300_TX_WRAP_T_SHIFT
;
91 if (tObj
->Target
== GL_TEXTURE_3D
)
92 t
->filter
|= translate_wrap_mode(tObj
->WrapR
) << R300_TX_WRAP_R_SHIFT
;
96 static GLuint
aniso_filter(GLfloat anisotropy
)
98 if (anisotropy
>= 16.0) {
99 return R300_TX_MAX_ANISO_16_TO_1
;
100 } else if (anisotropy
>= 8.0) {
101 return R300_TX_MAX_ANISO_8_TO_1
;
102 } else if (anisotropy
>= 4.0) {
103 return R300_TX_MAX_ANISO_4_TO_1
;
104 } else if (anisotropy
>= 2.0) {
105 return R300_TX_MAX_ANISO_2_TO_1
;
107 return R300_TX_MAX_ANISO_1_TO_1
;
112 * Set the texture magnification and minification modes.
114 * \param t Texture whose filter modes are to be set
115 * \param minf Texture minification mode
116 * \param magf Texture magnification mode
117 * \param anisotropy Maximum anisotropy level
119 static void r300SetTexFilter(r300TexObjPtr t
, GLenum minf
, GLenum magf
, GLfloat anisotropy
)
121 t
->filter
&= ~(R300_TX_MIN_FILTER_MASK
| R300_TX_MIN_FILTER_MIP_MASK
| R300_TX_MAG_FILTER_MASK
| R300_TX_MAX_ANISO_MASK
);
122 t
->filter_1
&= ~R300_EDGE_ANISO_EDGE_ONLY
;
124 /* Note that EXT_texture_filter_anisotropic is extremely vague about
125 * how anisotropic filtering interacts with the "normal" filter modes.
126 * When anisotropic filtering is enabled, we override min and mag
127 * filter settings completely. This includes driconf's settings.
129 if (anisotropy
>= 2.0 && (minf
!= GL_NEAREST
) && (magf
!= GL_NEAREST
)) {
130 t
->filter
|= R300_TX_MAG_FILTER_ANISO
131 | R300_TX_MIN_FILTER_ANISO
132 | R300_TX_MIN_FILTER_MIP_LINEAR
133 | aniso_filter(anisotropy
);
134 if (RADEON_DEBUG
& DEBUG_TEXTURE
)
135 fprintf(stderr
, "Using maximum anisotropy of %f\n", anisotropy
);
141 t
->filter
|= R300_TX_MIN_FILTER_NEAREST
;
144 t
->filter
|= R300_TX_MIN_FILTER_LINEAR
;
146 case GL_NEAREST_MIPMAP_NEAREST
:
147 t
->filter
|= R300_TX_MIN_FILTER_NEAREST
|R300_TX_MIN_FILTER_MIP_NEAREST
;
149 case GL_NEAREST_MIPMAP_LINEAR
:
150 t
->filter
|= R300_TX_MIN_FILTER_NEAREST
|R300_TX_MIN_FILTER_MIP_LINEAR
;
152 case GL_LINEAR_MIPMAP_NEAREST
:
153 t
->filter
|= R300_TX_MIN_FILTER_LINEAR
|R300_TX_MIN_FILTER_MIP_NEAREST
;
155 case GL_LINEAR_MIPMAP_LINEAR
:
156 t
->filter
|= R300_TX_MIN_FILTER_LINEAR
|R300_TX_MIN_FILTER_MIP_LINEAR
;
160 /* Note we don't have 3D mipmaps so only use the mag filter setting
161 * to set the 3D texture filter mode.
165 t
->filter
|= R300_TX_MAG_FILTER_NEAREST
;
168 t
->filter
|= R300_TX_MAG_FILTER_LINEAR
;
173 static void r300SetTexBorderColor(r300TexObjPtr t
, GLubyte c
[4])
175 t
->pp_border_color
= PACK_COLOR_8888(c
[3], c
[0], c
[1], c
[2]);
179 * Allocate space for and load the mesa images into the texture memory block.
180 * This will happen before drawing with a new texture, or drawing with a
181 * texture after it was swapped out or teximaged again.
184 static r300TexObjPtr
r300AllocTexObj(struct gl_texture_object
*texObj
)
188 t
= CALLOC_STRUCT(r300_tex_obj
);
189 texObj
->DriverData
= t
;
191 if (RADEON_DEBUG
& DEBUG_TEXTURE
) {
192 fprintf(stderr
, "%s( %p, %p )\n", __FUNCTION__
,
193 (void *)texObj
, (void *)t
);
196 /* Initialize non-image-dependent parts of the state:
198 t
->base
.tObj
= texObj
;
199 t
->border_fallback
= GL_FALSE
;
201 make_empty_list(&t
->base
);
203 r300UpdateTexWrap(t
);
204 r300SetTexFilter(t
, texObj
->MinFilter
, texObj
->MagFilter
, texObj
->MaxAnisotropy
);
205 r300SetTexBorderColor(t
, texObj
->_BorderChan
);
211 /* try to find a format which will only need a memcopy */
212 static const struct gl_texture_format
*r300Choose8888TexFormat(GLenum srcFormat
,
216 const GLubyte littleEndian
= *((const GLubyte
*)&ui
);
218 if ((srcFormat
== GL_RGBA
&& srcType
== GL_UNSIGNED_INT_8_8_8_8
) ||
219 (srcFormat
== GL_RGBA
&& srcType
== GL_UNSIGNED_BYTE
&& !littleEndian
) ||
220 (srcFormat
== GL_ABGR_EXT
&& srcType
== GL_UNSIGNED_INT_8_8_8_8_REV
) ||
221 (srcFormat
== GL_ABGR_EXT
&& srcType
== GL_UNSIGNED_BYTE
&& littleEndian
)) {
222 return &_mesa_texformat_rgba8888
;
223 } else if ((srcFormat
== GL_RGBA
&& srcType
== GL_UNSIGNED_INT_8_8_8_8_REV
) ||
224 (srcFormat
== GL_RGBA
&& srcType
== GL_UNSIGNED_BYTE
&& littleEndian
) ||
225 (srcFormat
== GL_ABGR_EXT
&& srcType
== GL_UNSIGNED_INT_8_8_8_8
) ||
226 (srcFormat
== GL_ABGR_EXT
&& srcType
== GL_UNSIGNED_BYTE
&& !littleEndian
)) {
227 return &_mesa_texformat_rgba8888_rev
;
228 } else if (srcFormat
== GL_BGRA
&& ((srcType
== GL_UNSIGNED_BYTE
&& !littleEndian
) ||
229 srcType
== GL_UNSIGNED_INT_8_8_8_8
)) {
230 return &_mesa_texformat_argb8888_rev
;
231 } else if (srcFormat
== GL_BGRA
&& ((srcType
== GL_UNSIGNED_BYTE
&& littleEndian
) ||
232 srcType
== GL_UNSIGNED_INT_8_8_8_8_REV
)) {
233 return &_mesa_texformat_argb8888
;
235 return _dri_texformat_argb8888
;
238 static const struct gl_texture_format
*r300ChooseTextureFormat(GLcontext
* ctx
,
244 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
245 const GLboolean do32bpt
=
246 (rmesa
->texture_depth
== DRI_CONF_TEXTURE_DEPTH_32
);
247 const GLboolean force16bpt
=
248 (rmesa
->texture_depth
== DRI_CONF_TEXTURE_DEPTH_FORCE_16
);
252 fprintf(stderr
, "InternalFormat=%s(%d) type=%s format=%s\n",
253 _mesa_lookup_enum_by_nr(internalFormat
), internalFormat
,
254 _mesa_lookup_enum_by_nr(type
), _mesa_lookup_enum_by_nr(format
));
255 fprintf(stderr
, "do32bpt=%d force16bpt=%d\n", do32bpt
, force16bpt
);
258 switch (internalFormat
) {
261 case GL_COMPRESSED_RGBA
:
263 case GL_UNSIGNED_INT_10_10_10_2
:
264 case GL_UNSIGNED_INT_2_10_10_10_REV
:
265 return do32bpt
? _dri_texformat_argb8888
:
266 _dri_texformat_argb1555
;
267 case GL_UNSIGNED_SHORT_4_4_4_4
:
268 case GL_UNSIGNED_SHORT_4_4_4_4_REV
:
269 return _dri_texformat_argb4444
;
270 case GL_UNSIGNED_SHORT_5_5_5_1
:
271 case GL_UNSIGNED_SHORT_1_5_5_5_REV
:
272 return _dri_texformat_argb1555
;
274 return do32bpt
? r300Choose8888TexFormat(format
, type
) :
275 _dri_texformat_argb4444
;
280 case GL_COMPRESSED_RGB
:
282 case GL_UNSIGNED_SHORT_4_4_4_4
:
283 case GL_UNSIGNED_SHORT_4_4_4_4_REV
:
284 return _dri_texformat_argb4444
;
285 case GL_UNSIGNED_SHORT_5_5_5_1
:
286 case GL_UNSIGNED_SHORT_1_5_5_5_REV
:
287 return _dri_texformat_argb1555
;
288 case GL_UNSIGNED_SHORT_5_6_5
:
289 case GL_UNSIGNED_SHORT_5_6_5_REV
:
290 return _dri_texformat_rgb565
;
292 return do32bpt
? _dri_texformat_argb8888
:
293 _dri_texformat_rgb565
;
301 r300Choose8888TexFormat(format
,
302 type
) : _dri_texformat_argb4444
;
306 return _dri_texformat_argb4444
;
309 return _dri_texformat_argb1555
;
315 return !force16bpt
? _dri_texformat_argb8888
:
316 _dri_texformat_rgb565
;
321 return _dri_texformat_rgb565
;
328 case GL_COMPRESSED_ALPHA
:
329 return _dri_texformat_a8
;
337 case GL_COMPRESSED_LUMINANCE
:
338 return _dri_texformat_l8
;
341 case GL_LUMINANCE_ALPHA
:
342 case GL_LUMINANCE4_ALPHA4
:
343 case GL_LUMINANCE6_ALPHA2
:
344 case GL_LUMINANCE8_ALPHA8
:
345 case GL_LUMINANCE12_ALPHA4
:
346 case GL_LUMINANCE12_ALPHA12
:
347 case GL_LUMINANCE16_ALPHA16
:
348 case GL_COMPRESSED_LUMINANCE_ALPHA
:
349 return _dri_texformat_al88
;
356 case GL_COMPRESSED_INTENSITY
:
357 return _dri_texformat_i8
;
360 if (type
== GL_UNSIGNED_SHORT_8_8_APPLE
||
361 type
== GL_UNSIGNED_BYTE
)
362 return &_mesa_texformat_ycbcr
;
364 return &_mesa_texformat_ycbcr_rev
;
368 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT
:
369 return &_mesa_texformat_rgb_dxt1
;
371 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT
:
372 return &_mesa_texformat_rgba_dxt1
;
376 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT
:
377 return &_mesa_texformat_rgba_dxt3
;
379 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT
:
380 return &_mesa_texformat_rgba_dxt5
;
382 case GL_ALPHA16F_ARB
:
383 return &_mesa_texformat_alpha_float16
;
384 case GL_ALPHA32F_ARB
:
385 return &_mesa_texformat_alpha_float32
;
386 case GL_LUMINANCE16F_ARB
:
387 return &_mesa_texformat_luminance_float16
;
388 case GL_LUMINANCE32F_ARB
:
389 return &_mesa_texformat_luminance_float32
;
390 case GL_LUMINANCE_ALPHA16F_ARB
:
391 return &_mesa_texformat_luminance_alpha_float16
;
392 case GL_LUMINANCE_ALPHA32F_ARB
:
393 return &_mesa_texformat_luminance_alpha_float32
;
394 case GL_INTENSITY16F_ARB
:
395 return &_mesa_texformat_intensity_float16
;
396 case GL_INTENSITY32F_ARB
:
397 return &_mesa_texformat_intensity_float32
;
399 return &_mesa_texformat_rgba_float16
;
401 return &_mesa_texformat_rgba_float32
;
403 return &_mesa_texformat_rgba_float16
;
405 return &_mesa_texformat_rgba_float32
;
407 case GL_DEPTH_COMPONENT
:
408 case GL_DEPTH_COMPONENT16
:
409 case GL_DEPTH_COMPONENT24
:
410 case GL_DEPTH_COMPONENT32
:
413 case GL_UNSIGNED_BYTE
:
414 case GL_UNSIGNED_SHORT
:
415 return &_mesa_texformat_z16
;
416 case GL_UNSIGNED_INT
:
417 return &_mesa_texformat_z32
;
418 case GL_UNSIGNED_INT_24_8_EXT
:
420 return &_mesa_texformat_z24_s8
;
423 return &_mesa_texformat_z16
;
428 "unexpected internalFormat 0x%x in r300ChooseTextureFormat",
429 (int)internalFormat
);
433 return NULL
; /* never get here */
437 r300ValidateClientStorage(GLcontext
* ctx
, GLenum target
,
438 GLint internalFormat
,
439 GLint srcWidth
, GLint srcHeight
,
440 GLenum format
, GLenum type
, const void *pixels
,
441 const struct gl_pixelstore_attrib
*packing
,
442 struct gl_texture_object
*texObj
,
443 struct gl_texture_image
*texImage
)
445 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
447 if (RADEON_DEBUG
& DEBUG_TEXTURE
)
448 fprintf(stderr
, "intformat %s format %s type %s\n",
449 _mesa_lookup_enum_by_nr(internalFormat
),
450 _mesa_lookup_enum_by_nr(format
),
451 _mesa_lookup_enum_by_nr(type
));
453 if (!ctx
->Unpack
.ClientStorage
)
456 if (ctx
->_ImageTransferState
||
457 texImage
->IsCompressed
|| texObj
->GenerateMipmap
)
460 /* This list is incomplete, may be different on ppc???
462 switch (internalFormat
) {
464 if (format
== GL_BGRA
&& type
== GL_UNSIGNED_INT_8_8_8_8_REV
) {
465 texImage
->TexFormat
= _dri_texformat_argb8888
;
471 if (format
== GL_RGB
&& type
== GL_UNSIGNED_SHORT_5_6_5
) {
472 texImage
->TexFormat
= _dri_texformat_rgb565
;
478 if (format
== GL_YCBCR_MESA
&&
479 type
== GL_UNSIGNED_SHORT_8_8_REV_APPLE
) {
480 texImage
->TexFormat
= &_mesa_texformat_ycbcr_rev
;
481 } else if (format
== GL_YCBCR_MESA
&&
482 (type
== GL_UNSIGNED_SHORT_8_8_APPLE
||
483 type
== GL_UNSIGNED_BYTE
)) {
484 texImage
->TexFormat
= &_mesa_texformat_ycbcr
;
493 /* Could deal with these packing issues, but currently don't:
495 if (packing
->SkipPixels
||
496 packing
->SkipRows
|| packing
->SwapBytes
|| packing
->LsbFirst
) {
500 GLint srcRowStride
= _mesa_image_row_stride(packing
, srcWidth
,
503 if (RADEON_DEBUG
& DEBUG_TEXTURE
)
504 fprintf(stderr
, "%s: srcRowStride %d/%x\n",
505 __FUNCTION__
, srcRowStride
, srcRowStride
);
507 /* Could check this later in upload, pitch restrictions could be
508 * relaxed, but would need to store the image pitch somewhere,
509 * as packing details might change before image is uploaded:
511 if (!r300IsGartMemory(rmesa
, pixels
, srcHeight
* srcRowStride
)
512 || (srcRowStride
& 63))
515 /* Have validated that _mesa_transfer_teximage would be a straight
516 * memcpy at this point. NOTE: future calls to TexSubImage will
517 * overwrite the client data. This is explicitly mentioned in the
520 texImage
->Data
= (void *)pixels
;
521 texImage
->IsClientData
= GL_TRUE
;
522 texImage
->RowStride
= srcRowStride
/ texImage
->TexFormat
->TexelBytes
;
527 static void r300TexImage1D(GLcontext
* ctx
, GLenum target
, GLint level
,
528 GLint internalFormat
,
529 GLint width
, GLint border
,
530 GLenum format
, GLenum type
, const GLvoid
* pixels
,
531 const struct gl_pixelstore_attrib
*packing
,
532 struct gl_texture_object
*texObj
,
533 struct gl_texture_image
*texImage
)
535 driTextureObject
*t
= (driTextureObject
*) texObj
->DriverData
;
538 driSwapOutTextureObject(t
);
540 t
= (driTextureObject
*) r300AllocTexObj(texObj
);
542 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage1D");
547 /* Note, this will call ChooseTextureFormat */
548 _mesa_store_teximage1d(ctx
, target
, level
, internalFormat
,
549 width
, border
, format
, type
, pixels
,
550 &ctx
->Unpack
, texObj
, texImage
);
552 t
->dirty_images
[0] |= (1 << level
);
555 static void r300TexSubImage1D(GLcontext
* ctx
, GLenum target
, GLint level
,
558 GLenum format
, GLenum type
,
559 const GLvoid
* pixels
,
560 const struct gl_pixelstore_attrib
*packing
,
561 struct gl_texture_object
*texObj
,
562 struct gl_texture_image
*texImage
)
564 driTextureObject
*t
= (driTextureObject
*) texObj
->DriverData
;
566 assert(t
); /* this _should_ be true */
568 driSwapOutTextureObject(t
);
570 t
= (driTextureObject
*) r300AllocTexObj(texObj
);
572 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexSubImage1D");
577 _mesa_store_texsubimage1d(ctx
, target
, level
, xoffset
, width
,
578 format
, type
, pixels
, packing
, texObj
,
581 t
->dirty_images
[0] |= (1 << level
);
584 static void r300TexImage2D(GLcontext
* ctx
, GLenum target
, GLint level
,
585 GLint internalFormat
,
586 GLint width
, GLint height
, GLint border
,
587 GLenum format
, GLenum type
, const GLvoid
* pixels
,
588 const struct gl_pixelstore_attrib
*packing
,
589 struct gl_texture_object
*texObj
,
590 struct gl_texture_image
*texImage
)
592 driTextureObject
*t
= (driTextureObject
*) texObj
->DriverData
;
595 /* which cube face or ordinary 2D image */
597 case GL_TEXTURE_CUBE_MAP_POSITIVE_X
:
598 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X
:
599 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y
:
600 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y
:
601 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z
:
602 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z
:
604 (GLuint
) target
- (GLuint
) GL_TEXTURE_CUBE_MAP_POSITIVE_X
;
612 driSwapOutTextureObject(t
);
614 t
= (driTextureObject
*) r300AllocTexObj(texObj
);
616 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage2D");
621 texImage
->IsClientData
= GL_FALSE
;
623 if (r300ValidateClientStorage(ctx
, target
,
626 format
, type
, pixels
,
627 packing
, texObj
, texImage
)) {
628 if (RADEON_DEBUG
& DEBUG_TEXTURE
)
629 fprintf(stderr
, "%s: Using client storage\n",
632 if (RADEON_DEBUG
& DEBUG_TEXTURE
)
633 fprintf(stderr
, "%s: Using normal storage\n",
636 /* Normal path: copy (to cached memory) and eventually upload
637 * via another copy to GART memory and then a blit... Could
638 * eliminate one copy by going straight to (permanent) GART.
640 * Note, this will call r300ChooseTextureFormat.
642 _mesa_store_teximage2d(ctx
, target
, level
, internalFormat
,
643 width
, height
, border
, format
, type
,
644 pixels
, &ctx
->Unpack
, texObj
, texImage
);
646 t
->dirty_images
[face
] |= (1 << level
);
650 static void r300TexSubImage2D(GLcontext
* ctx
, GLenum target
, GLint level
,
651 GLint xoffset
, GLint yoffset
,
652 GLsizei width
, GLsizei height
,
653 GLenum format
, GLenum type
,
654 const GLvoid
* pixels
,
655 const struct gl_pixelstore_attrib
*packing
,
656 struct gl_texture_object
*texObj
,
657 struct gl_texture_image
*texImage
)
659 driTextureObject
*t
= (driTextureObject
*) texObj
->DriverData
;
662 /* which cube face or ordinary 2D image */
664 case GL_TEXTURE_CUBE_MAP_POSITIVE_X
:
665 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X
:
666 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y
:
667 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y
:
668 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z
:
669 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z
:
671 (GLuint
) target
- (GLuint
) GL_TEXTURE_CUBE_MAP_POSITIVE_X
;
678 assert(t
); /* this _should_ be true */
680 driSwapOutTextureObject(t
);
682 t
= (driTextureObject
*) r300AllocTexObj(texObj
);
684 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexSubImage2D");
689 _mesa_store_texsubimage2d(ctx
, target
, level
, xoffset
, yoffset
, width
,
690 height
, format
, type
, pixels
, packing
, texObj
,
693 t
->dirty_images
[face
] |= (1 << level
);
696 static void r300CompressedTexImage2D(GLcontext
* ctx
, GLenum target
,
697 GLint level
, GLint internalFormat
,
698 GLint width
, GLint height
, GLint border
,
699 GLsizei imageSize
, const GLvoid
* data
,
700 struct gl_texture_object
*texObj
,
701 struct gl_texture_image
*texImage
)
703 driTextureObject
*t
= (driTextureObject
*) texObj
->DriverData
;
706 /* which cube face or ordinary 2D image */
708 case GL_TEXTURE_CUBE_MAP_POSITIVE_X
:
709 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X
:
710 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y
:
711 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y
:
712 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z
:
713 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z
:
715 (GLuint
) target
- (GLuint
) GL_TEXTURE_CUBE_MAP_POSITIVE_X
;
723 driSwapOutTextureObject(t
);
725 t
= (driTextureObject
*) r300AllocTexObj(texObj
);
727 _mesa_error(ctx
, GL_OUT_OF_MEMORY
,
728 "glCompressedTexImage2D");
733 texImage
->IsClientData
= GL_FALSE
;
735 /* can't call this, different parameters. Would never evaluate to true anyway currently */
737 if (r300ValidateClientStorage(ctx
, target
,
740 format
, type
, pixels
,
741 packing
, texObj
, texImage
)) {
742 if (RADEON_DEBUG
& DEBUG_TEXTURE
)
743 fprintf(stderr
, "%s: Using client storage\n",
748 if (RADEON_DEBUG
& DEBUG_TEXTURE
)
749 fprintf(stderr
, "%s: Using normal storage\n",
752 /* Normal path: copy (to cached memory) and eventually upload
753 * via another copy to GART memory and then a blit... Could
754 * eliminate one copy by going straight to (permanent) GART.
756 * Note, this will call r300ChooseTextureFormat.
758 _mesa_store_compressed_teximage2d(ctx
, target
, level
,
759 internalFormat
, width
, height
,
760 border
, imageSize
, data
,
763 t
->dirty_images
[face
] |= (1 << level
);
767 static void r300CompressedTexSubImage2D(GLcontext
* ctx
, GLenum target
,
768 GLint level
, GLint xoffset
,
769 GLint yoffset
, GLsizei width
,
770 GLsizei height
, GLenum format
,
771 GLsizei imageSize
, const GLvoid
* data
,
772 struct gl_texture_object
*texObj
,
773 struct gl_texture_image
*texImage
)
775 driTextureObject
*t
= (driTextureObject
*) texObj
->DriverData
;
778 /* which cube face or ordinary 2D image */
780 case GL_TEXTURE_CUBE_MAP_POSITIVE_X
:
781 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X
:
782 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y
:
783 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y
:
784 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z
:
785 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z
:
787 (GLuint
) target
- (GLuint
) GL_TEXTURE_CUBE_MAP_POSITIVE_X
;
794 assert(t
); /* this _should_ be true */
796 driSwapOutTextureObject(t
);
798 t
= (driTextureObject
*) r300AllocTexObj(texObj
);
800 _mesa_error(ctx
, GL_OUT_OF_MEMORY
,
801 "glCompressedTexSubImage3D");
806 _mesa_store_compressed_texsubimage2d(ctx
, target
, level
, xoffset
,
807 yoffset
, width
, height
, format
,
808 imageSize
, data
, texObj
, texImage
);
810 t
->dirty_images
[face
] |= (1 << level
);
813 static void r300TexImage3D(GLcontext
* ctx
, GLenum target
, GLint level
,
814 GLint internalFormat
,
815 GLint width
, GLint height
, GLint depth
,
817 GLenum format
, GLenum type
, const GLvoid
* pixels
,
818 const struct gl_pixelstore_attrib
*packing
,
819 struct gl_texture_object
*texObj
,
820 struct gl_texture_image
*texImage
)
822 driTextureObject
*t
= (driTextureObject
*) texObj
->DriverData
;
825 driSwapOutTextureObject(t
);
827 t
= (driTextureObject
*) r300AllocTexObj(texObj
);
829 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage3D");
834 texImage
->IsClientData
= GL_FALSE
;
837 if (r300ValidateClientStorage(ctx
, target
,
840 format
, type
, pixels
,
841 packing
, texObj
, texImage
)) {
842 if (RADEON_DEBUG
& DEBUG_TEXTURE
)
843 fprintf(stderr
, "%s: Using client storage\n",
848 if (RADEON_DEBUG
& DEBUG_TEXTURE
)
849 fprintf(stderr
, "%s: Using normal storage\n",
852 /* Normal path: copy (to cached memory) and eventually upload
853 * via another copy to GART memory and then a blit... Could
854 * eliminate one copy by going straight to (permanent) GART.
856 * Note, this will call r300ChooseTextureFormat.
858 _mesa_store_teximage3d(ctx
, target
, level
, internalFormat
,
859 width
, height
, depth
, border
,
860 format
, type
, pixels
,
861 &ctx
->Unpack
, texObj
, texImage
);
863 t
->dirty_images
[0] |= (1 << level
);
868 r300TexSubImage3D(GLcontext
* ctx
, GLenum target
, GLint level
,
869 GLint xoffset
, GLint yoffset
, GLint zoffset
,
870 GLsizei width
, GLsizei height
, GLsizei depth
,
871 GLenum format
, GLenum type
,
872 const GLvoid
* pixels
,
873 const struct gl_pixelstore_attrib
*packing
,
874 struct gl_texture_object
*texObj
,
875 struct gl_texture_image
*texImage
)
877 driTextureObject
*t
= (driTextureObject
*) texObj
->DriverData
;
879 /* fprintf(stderr, "%s\n", __FUNCTION__); */
881 assert(t
); /* this _should_ be true */
883 driSwapOutTextureObject(t
);
885 t
= (driTextureObject
*) r300AllocTexObj(texObj
);
887 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexSubImage3D");
890 texObj
->DriverData
= t
;
893 _mesa_store_texsubimage3d(ctx
, target
, level
, xoffset
, yoffset
, zoffset
,
894 width
, height
, depth
,
895 format
, type
, pixels
, packing
, texObj
,
898 t
->dirty_images
[0] |= (1 << level
);
902 * Changes variables and flags for a state update, which will happen at the
903 * next UpdateTextureState
906 static void r300TexParameter(GLcontext
* ctx
, GLenum target
,
907 struct gl_texture_object
*texObj
,
908 GLenum pname
, const GLfloat
* params
)
910 r300TexObjPtr t
= (r300TexObjPtr
) texObj
->DriverData
;
912 if (RADEON_DEBUG
& (DEBUG_STATE
| DEBUG_TEXTURE
)) {
913 fprintf(stderr
, "%s( %s )\n", __FUNCTION__
,
914 _mesa_lookup_enum_by_nr(pname
));
918 case GL_TEXTURE_MIN_FILTER
:
919 case GL_TEXTURE_MAG_FILTER
:
920 case GL_TEXTURE_MAX_ANISOTROPY_EXT
:
921 r300SetTexFilter(t
, texObj
->MinFilter
, texObj
->MagFilter
, texObj
->MaxAnisotropy
);
924 case GL_TEXTURE_WRAP_S
:
925 case GL_TEXTURE_WRAP_T
:
926 case GL_TEXTURE_WRAP_R
:
927 r300UpdateTexWrap(t
);
930 case GL_TEXTURE_BORDER_COLOR
:
931 r300SetTexBorderColor(t
, texObj
->_BorderChan
);
934 case GL_TEXTURE_BASE_LEVEL
:
935 case GL_TEXTURE_MAX_LEVEL
:
936 case GL_TEXTURE_MIN_LOD
:
937 case GL_TEXTURE_MAX_LOD
:
938 /* This isn't the most efficient solution but there doesn't appear to
939 * be a nice alternative. Since there's no LOD clamping,
940 * we just have to rely on loading the right subset of mipmap levels
941 * to simulate a clamped LOD.
943 driSwapOutTextureObject((driTextureObject
*) t
);
946 case GL_DEPTH_TEXTURE_MODE
:
947 if (texObj
->Image
[0][texObj
->BaseLevel
]->TexFormat
->BaseFormat
948 == GL_DEPTH_COMPONENT
) {
949 r300SetDepthTexMode(texObj
);
952 /* If the texture isn't a depth texture, changing this
953 * state won't cause any changes to the hardware.
954 * Don't force a flush of texture state.
964 static void r300BindTexture(GLcontext
* ctx
, GLenum target
,
965 struct gl_texture_object
*texObj
)
967 if (RADEON_DEBUG
& (DEBUG_STATE
| DEBUG_TEXTURE
)) {
968 fprintf(stderr
, "%s( %p ) unit=%d\n", __FUNCTION__
,
969 (void *)texObj
, ctx
->Texture
.CurrentUnit
);
972 if ((target
== GL_TEXTURE_1D
)
973 || (target
== GL_TEXTURE_2D
)
974 || (target
== GL_TEXTURE_3D
)
975 || (target
== GL_TEXTURE_CUBE_MAP
)
976 || (target
== GL_TEXTURE_RECTANGLE_NV
)) {
977 assert(texObj
->DriverData
!= NULL
);
981 static void r300DeleteTexture(GLcontext
* ctx
, struct gl_texture_object
*texObj
)
983 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
984 driTextureObject
*t
= (driTextureObject
*) texObj
->DriverData
;
986 if (RADEON_DEBUG
& (DEBUG_STATE
| DEBUG_TEXTURE
)) {
987 fprintf(stderr
, "%s( %p (target = %s) )\n", __FUNCTION__
,
989 _mesa_lookup_enum_by_nr(texObj
->Target
));
994 R300_FIREVERTICES(rmesa
);
997 driDestroyTextureObject(t
);
999 /* Free mipmap images and the texture object itself */
1000 _mesa_delete_texture_object(ctx
, texObj
);
1004 * Allocate a new texture object.
1005 * Called via ctx->Driver.NewTextureObject.
1006 * Note: this function will be called during context creation to
1007 * allocate the default texture objects.
1008 * Note: we could use containment here to 'derive' the driver-specific
1009 * texture object from the core mesa gl_texture_object. Not done at this time.
1010 * Fixup MaxAnisotropy according to user preference.
1012 static struct gl_texture_object
*r300NewTextureObject(GLcontext
* ctx
,
1016 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
1017 struct gl_texture_object
*obj
;
1018 obj
= _mesa_new_texture_object(ctx
, name
, target
);
1021 obj
->MaxAnisotropy
= rmesa
->initialMaxAnisotropy
;
1023 r300AllocTexObj(obj
);
1027 void r300InitTextureFuncs(struct dd_function_table
*functions
)
1029 /* Note: we only plug in the functions we implement in the driver
1030 * since _mesa_init_driver_functions() was already called.
1032 functions
->ChooseTextureFormat
= r300ChooseTextureFormat
;
1033 functions
->TexImage1D
= r300TexImage1D
;
1034 functions
->TexImage2D
= r300TexImage2D
;
1035 functions
->TexImage3D
= r300TexImage3D
;
1036 functions
->TexSubImage1D
= r300TexSubImage1D
;
1037 functions
->TexSubImage2D
= r300TexSubImage2D
;
1038 functions
->TexSubImage3D
= r300TexSubImage3D
;
1039 functions
->NewTextureObject
= r300NewTextureObject
;
1040 functions
->BindTexture
= r300BindTexture
;
1041 functions
->DeleteTexture
= r300DeleteTexture
;
1042 functions
->IsTextureResident
= driIsTextureResident
;
1044 functions
->TexParameter
= r300TexParameter
;
1046 functions
->CompressedTexImage2D
= r300CompressedTexImage2D
;
1047 functions
->CompressedTexSubImage2D
= r300CompressedTexSubImage2D
;
1049 driInitTextureFormats();