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>
35 #include "main/glheader.h"
36 #include "main/imports.h"
37 #include "main/colormac.h"
38 #include "main/context.h"
39 #include "main/enums.h"
40 #include "main/image.h"
41 #include "main/mipmap.h"
42 #include "main/simple_list.h"
43 #include "main/texformat.h"
44 #include "main/texstore.h"
45 #include "main/teximage.h"
46 #include "main/texobj.h"
50 #include "r300_context.h"
51 #include "r300_state.h"
52 #include "r300_ioctl.h"
53 #include "r300_mipmap_tree.h"
59 static unsigned int translate_wrap_mode(GLenum wrapmode
)
62 case GL_REPEAT
: return R300_TX_REPEAT
;
63 case GL_CLAMP
: return R300_TX_CLAMP
;
64 case GL_CLAMP_TO_EDGE
: return R300_TX_CLAMP_TO_EDGE
;
65 case GL_CLAMP_TO_BORDER
: return R300_TX_CLAMP_TO_BORDER
;
66 case GL_MIRRORED_REPEAT
: return R300_TX_REPEAT
| R300_TX_MIRRORED
;
67 case GL_MIRROR_CLAMP_EXT
: return R300_TX_CLAMP
| R300_TX_MIRRORED
;
68 case GL_MIRROR_CLAMP_TO_EDGE_EXT
: return R300_TX_CLAMP_TO_EDGE
| R300_TX_MIRRORED
;
69 case GL_MIRROR_CLAMP_TO_BORDER_EXT
: return R300_TX_CLAMP_TO_BORDER
| R300_TX_MIRRORED
;
71 _mesa_problem(NULL
, "bad wrap mode in %s", __FUNCTION__
);
78 * Update the cached hardware registers based on the current texture wrap modes.
80 * \param t Texture object whose wrap modes are to be set
82 static void r300UpdateTexWrap(r300TexObjPtr t
)
84 struct gl_texture_object
*tObj
= &t
->base
;
87 ~(R300_TX_WRAP_S_MASK
| R300_TX_WRAP_T_MASK
| R300_TX_WRAP_R_MASK
);
89 t
->filter
|= translate_wrap_mode(tObj
->WrapS
) << R300_TX_WRAP_S_SHIFT
;
91 if (tObj
->Target
!= GL_TEXTURE_1D
) {
92 t
->filter
|= translate_wrap_mode(tObj
->WrapT
) << R300_TX_WRAP_T_SHIFT
;
94 if (tObj
->Target
== GL_TEXTURE_3D
)
95 t
->filter
|= translate_wrap_mode(tObj
->WrapR
) << R300_TX_WRAP_R_SHIFT
;
99 static GLuint
aniso_filter(GLfloat anisotropy
)
101 if (anisotropy
>= 16.0) {
102 return R300_TX_MAX_ANISO_16_TO_1
;
103 } else if (anisotropy
>= 8.0) {
104 return R300_TX_MAX_ANISO_8_TO_1
;
105 } else if (anisotropy
>= 4.0) {
106 return R300_TX_MAX_ANISO_4_TO_1
;
107 } else if (anisotropy
>= 2.0) {
108 return R300_TX_MAX_ANISO_2_TO_1
;
110 return R300_TX_MAX_ANISO_1_TO_1
;
115 * Set the texture magnification and minification modes.
117 * \param t Texture whose filter modes are to be set
118 * \param minf Texture minification mode
119 * \param magf Texture magnification mode
120 * \param anisotropy Maximum anisotropy level
122 static void r300SetTexFilter(r300TexObjPtr t
, GLenum minf
, GLenum magf
, GLfloat anisotropy
)
124 /* Force revalidation to account for switches from/to mipmapping. */
125 t
->validated
= GL_FALSE
;
127 t
->filter
&= ~(R300_TX_MIN_FILTER_MASK
| R300_TX_MIN_FILTER_MIP_MASK
| R300_TX_MAG_FILTER_MASK
| R300_TX_MAX_ANISO_MASK
);
128 t
->filter_1
&= ~R300_EDGE_ANISO_EDGE_ONLY
;
130 /* Note that EXT_texture_filter_anisotropic is extremely vague about
131 * how anisotropic filtering interacts with the "normal" filter modes.
132 * When anisotropic filtering is enabled, we override min and mag
133 * filter settings completely. This includes driconf's settings.
135 if (anisotropy
>= 2.0 && (minf
!= GL_NEAREST
) && (magf
!= GL_NEAREST
)) {
136 t
->filter
|= R300_TX_MAG_FILTER_ANISO
137 | R300_TX_MIN_FILTER_ANISO
138 | R300_TX_MIN_FILTER_MIP_LINEAR
139 | aniso_filter(anisotropy
);
140 if (RADEON_DEBUG
& DEBUG_TEXTURE
)
141 fprintf(stderr
, "Using maximum anisotropy of %f\n", anisotropy
);
147 t
->filter
|= R300_TX_MIN_FILTER_NEAREST
;
150 t
->filter
|= R300_TX_MIN_FILTER_LINEAR
;
152 case GL_NEAREST_MIPMAP_NEAREST
:
153 t
->filter
|= R300_TX_MIN_FILTER_NEAREST
|R300_TX_MIN_FILTER_MIP_NEAREST
;
155 case GL_NEAREST_MIPMAP_LINEAR
:
156 t
->filter
|= R300_TX_MIN_FILTER_NEAREST
|R300_TX_MIN_FILTER_MIP_LINEAR
;
158 case GL_LINEAR_MIPMAP_NEAREST
:
159 t
->filter
|= R300_TX_MIN_FILTER_LINEAR
|R300_TX_MIN_FILTER_MIP_NEAREST
;
161 case GL_LINEAR_MIPMAP_LINEAR
:
162 t
->filter
|= R300_TX_MIN_FILTER_LINEAR
|R300_TX_MIN_FILTER_MIP_LINEAR
;
166 /* Note we don't have 3D mipmaps so only use the mag filter setting
167 * to set the 3D texture filter mode.
171 t
->filter
|= R300_TX_MAG_FILTER_NEAREST
;
174 t
->filter
|= R300_TX_MAG_FILTER_LINEAR
;
179 static void r300SetTexBorderColor(r300TexObjPtr t
, GLubyte c
[4])
181 t
->pp_border_color
= PACK_COLOR_8888(c
[3], c
[0], c
[1], c
[2]);
184 /* try to find a format which will only need a memcopy */
185 static const struct gl_texture_format
*r300Choose8888TexFormat(GLenum srcFormat
,
189 const GLubyte littleEndian
= *((const GLubyte
*)&ui
);
191 if ((srcFormat
== GL_RGBA
&& srcType
== GL_UNSIGNED_INT_8_8_8_8
) ||
192 (srcFormat
== GL_RGBA
&& srcType
== GL_UNSIGNED_BYTE
&& !littleEndian
) ||
193 (srcFormat
== GL_ABGR_EXT
&& srcType
== GL_UNSIGNED_INT_8_8_8_8_REV
) ||
194 (srcFormat
== GL_ABGR_EXT
&& srcType
== GL_UNSIGNED_BYTE
&& littleEndian
)) {
195 return &_mesa_texformat_rgba8888
;
196 } else if ((srcFormat
== GL_RGBA
&& srcType
== GL_UNSIGNED_INT_8_8_8_8_REV
) ||
197 (srcFormat
== GL_RGBA
&& srcType
== GL_UNSIGNED_BYTE
&& littleEndian
) ||
198 (srcFormat
== GL_ABGR_EXT
&& srcType
== GL_UNSIGNED_INT_8_8_8_8
) ||
199 (srcFormat
== GL_ABGR_EXT
&& srcType
== GL_UNSIGNED_BYTE
&& !littleEndian
)) {
200 return &_mesa_texformat_rgba8888_rev
;
201 } else if (srcFormat
== GL_BGRA
&& ((srcType
== GL_UNSIGNED_BYTE
&& !littleEndian
) ||
202 srcType
== GL_UNSIGNED_INT_8_8_8_8
)) {
203 return &_mesa_texformat_argb8888_rev
;
204 } else if (srcFormat
== GL_BGRA
&& ((srcType
== GL_UNSIGNED_BYTE
&& littleEndian
) ||
205 srcType
== GL_UNSIGNED_INT_8_8_8_8_REV
)) {
206 return &_mesa_texformat_argb8888
;
208 return _dri_texformat_argb8888
;
211 static const struct gl_texture_format
*r300ChooseTextureFormat(GLcontext
* ctx
,
217 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
218 const GLboolean do32bpt
=
219 (rmesa
->texture_depth
== DRI_CONF_TEXTURE_DEPTH_32
);
220 const GLboolean force16bpt
=
221 (rmesa
->texture_depth
== DRI_CONF_TEXTURE_DEPTH_FORCE_16
);
225 fprintf(stderr
, "InternalFormat=%s(%d) type=%s format=%s\n",
226 _mesa_lookup_enum_by_nr(internalFormat
), internalFormat
,
227 _mesa_lookup_enum_by_nr(type
), _mesa_lookup_enum_by_nr(format
));
228 fprintf(stderr
, "do32bpt=%d force16bpt=%d\n", do32bpt
, force16bpt
);
231 switch (internalFormat
) {
234 case GL_COMPRESSED_RGBA
:
236 case GL_UNSIGNED_INT_10_10_10_2
:
237 case GL_UNSIGNED_INT_2_10_10_10_REV
:
238 return do32bpt
? _dri_texformat_argb8888
:
239 _dri_texformat_argb1555
;
240 case GL_UNSIGNED_SHORT_4_4_4_4
:
241 case GL_UNSIGNED_SHORT_4_4_4_4_REV
:
242 return _dri_texformat_argb4444
;
243 case GL_UNSIGNED_SHORT_5_5_5_1
:
244 case GL_UNSIGNED_SHORT_1_5_5_5_REV
:
245 return _dri_texformat_argb1555
;
247 return do32bpt
? r300Choose8888TexFormat(format
, type
) :
248 _dri_texformat_argb4444
;
253 case GL_COMPRESSED_RGB
:
255 case GL_UNSIGNED_SHORT_4_4_4_4
:
256 case GL_UNSIGNED_SHORT_4_4_4_4_REV
:
257 return _dri_texformat_argb4444
;
258 case GL_UNSIGNED_SHORT_5_5_5_1
:
259 case GL_UNSIGNED_SHORT_1_5_5_5_REV
:
260 return _dri_texformat_argb1555
;
261 case GL_UNSIGNED_SHORT_5_6_5
:
262 case GL_UNSIGNED_SHORT_5_6_5_REV
:
263 return _dri_texformat_rgb565
;
265 return do32bpt
? _dri_texformat_argb8888
:
266 _dri_texformat_rgb565
;
274 r300Choose8888TexFormat(format
,
275 type
) : _dri_texformat_argb4444
;
279 return _dri_texformat_argb4444
;
282 return _dri_texformat_argb1555
;
288 return !force16bpt
? _dri_texformat_argb8888
:
289 _dri_texformat_rgb565
;
294 return _dri_texformat_rgb565
;
301 case GL_COMPRESSED_ALPHA
:
302 return _dri_texformat_a8
;
310 case GL_COMPRESSED_LUMINANCE
:
311 return _dri_texformat_l8
;
314 case GL_LUMINANCE_ALPHA
:
315 case GL_LUMINANCE4_ALPHA4
:
316 case GL_LUMINANCE6_ALPHA2
:
317 case GL_LUMINANCE8_ALPHA8
:
318 case GL_LUMINANCE12_ALPHA4
:
319 case GL_LUMINANCE12_ALPHA12
:
320 case GL_LUMINANCE16_ALPHA16
:
321 case GL_COMPRESSED_LUMINANCE_ALPHA
:
322 return _dri_texformat_al88
;
329 case GL_COMPRESSED_INTENSITY
:
330 return _dri_texformat_i8
;
333 if (type
== GL_UNSIGNED_SHORT_8_8_APPLE
||
334 type
== GL_UNSIGNED_BYTE
)
335 return &_mesa_texformat_ycbcr
;
337 return &_mesa_texformat_ycbcr_rev
;
341 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT
:
342 return &_mesa_texformat_rgb_dxt1
;
344 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT
:
345 return &_mesa_texformat_rgba_dxt1
;
349 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT
:
350 return &_mesa_texformat_rgba_dxt3
;
352 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT
:
353 return &_mesa_texformat_rgba_dxt5
;
355 case GL_ALPHA16F_ARB
:
356 return &_mesa_texformat_alpha_float16
;
357 case GL_ALPHA32F_ARB
:
358 return &_mesa_texformat_alpha_float32
;
359 case GL_LUMINANCE16F_ARB
:
360 return &_mesa_texformat_luminance_float16
;
361 case GL_LUMINANCE32F_ARB
:
362 return &_mesa_texformat_luminance_float32
;
363 case GL_LUMINANCE_ALPHA16F_ARB
:
364 return &_mesa_texformat_luminance_alpha_float16
;
365 case GL_LUMINANCE_ALPHA32F_ARB
:
366 return &_mesa_texformat_luminance_alpha_float32
;
367 case GL_INTENSITY16F_ARB
:
368 return &_mesa_texformat_intensity_float16
;
369 case GL_INTENSITY32F_ARB
:
370 return &_mesa_texformat_intensity_float32
;
372 return &_mesa_texformat_rgba_float16
;
374 return &_mesa_texformat_rgba_float32
;
376 return &_mesa_texformat_rgba_float16
;
378 return &_mesa_texformat_rgba_float32
;
380 case GL_DEPTH_COMPONENT
:
381 case GL_DEPTH_COMPONENT16
:
382 case GL_DEPTH_COMPONENT24
:
383 case GL_DEPTH_COMPONENT32
:
386 case GL_UNSIGNED_BYTE
:
387 case GL_UNSIGNED_SHORT
:
388 return &_mesa_texformat_z16
;
389 case GL_UNSIGNED_INT
:
390 return &_mesa_texformat_z32
;
391 case GL_UNSIGNED_INT_24_8_EXT
:
393 return &_mesa_texformat_z24_s8
;
396 return &_mesa_texformat_z16
;
401 "unexpected internalFormat 0x%x in r300ChooseTextureFormat",
402 (int)internalFormat
);
406 return NULL
; /* never get here */
411 * Allocate an empty texture image object.
413 static struct gl_texture_image
*r300NewTextureImage(GLcontext
*ctx
)
415 return CALLOC(sizeof(r300_texture_image
));
419 * Free memory associated with this texture image.
421 static void r300FreeTexImageData(GLcontext
*ctx
, struct gl_texture_image
*timage
)
423 r300_texture_image
* image
= get_r300_texture_image(timage
);
426 r300_miptree_unreference(image
->mt
);
428 assert(!image
->base
.Data
);
430 _mesa_free_texture_image_data(ctx
, timage
);
435 /* Set Data pointer and additional data for mapped texture image */
436 static void teximage_set_map_data(r300_texture_image
*image
)
438 r300_mipmap_level
*lvl
= &image
->mt
->levels
[image
->mtlevel
];
439 image
->base
.Data
= image
->mt
->bo
->ptr
+ lvl
->faces
[image
->mtface
].offset
;
440 image
->base
.RowStride
= lvl
->rowstride
/ image
->mt
->bpp
;
445 * Map a single texture image for glTexImage and friends.
447 static void r300_teximage_map(r300_texture_image
*image
, GLboolean write_enable
)
450 assert(!image
->base
.Data
);
452 radeon_bo_map(image
->mt
->bo
, write_enable
);
453 teximage_set_map_data(image
);
458 static void r300_teximage_unmap(r300_texture_image
*image
)
461 assert(image
->base
.Data
);
463 image
->base
.Data
= 0;
464 radeon_bo_unmap(image
->mt
->bo
);
469 * Map a validated texture for reading during software rendering.
471 static void r300MapTexture(GLcontext
*ctx
, struct gl_texture_object
*texObj
)
473 r300TexObj
* t
= r300_tex_obj(texObj
);
476 assert(texObj
->_Complete
);
479 radeon_bo_map(t
->mt
->bo
, GL_FALSE
);
480 for(face
= 0; face
< t
->mt
->faces
; ++face
) {
481 for(level
= t
->mt
->firstLevel
; level
<= t
->mt
->lastLevel
; ++level
)
482 teximage_set_map_data(get_r300_texture_image(texObj
->Image
[face
][level
]));
486 static void r300UnmapTexture(GLcontext
*ctx
, struct gl_texture_object
*texObj
)
488 r300TexObj
* t
= r300_tex_obj(texObj
);
491 assert(texObj
->_Complete
);
494 for(face
= 0; face
< t
->mt
->faces
; ++face
) {
495 for(level
= t
->mt
->firstLevel
; level
<= t
->mt
->lastLevel
; ++level
)
496 texObj
->Image
[face
][level
]->Data
= 0;
498 radeon_bo_unmap(t
->mt
->bo
);
502 * All glTexImage calls go through this function.
504 static void r300_teximage(
505 GLcontext
*ctx
, int dims
,
506 GLint face
, GLint level
,
507 GLint internalFormat
,
508 GLint width
, GLint height
, GLint depth
,
510 GLenum format
, GLenum type
, const GLvoid
* pixels
,
511 const struct gl_pixelstore_attrib
*packing
,
512 struct gl_texture_object
*texObj
,
513 struct gl_texture_image
*texImage
,
516 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
517 r300TexObj
* t
= r300_tex_obj(texObj
);
518 r300_texture_image
* image
= get_r300_texture_image(texImage
);
520 R300_FIREVERTICES(rmesa
);
522 t
->validated
= GL_FALSE
;
524 /* Choose and fill in the texture format for this image */
525 texImage
->TexFormat
= r300ChooseTextureFormat(ctx
, internalFormat
, format
, type
);
526 _mesa_set_fetch_functions(texImage
, dims
);
528 if (texImage
->TexFormat
->TexelBytes
== 0) {
529 texImage
->IsCompressed
= GL_TRUE
;
530 texImage
->CompressedSize
=
531 ctx
->Driver
.CompressedTextureSize(ctx
, texImage
->Width
,
532 texImage
->Height
, texImage
->Depth
,
533 texImage
->TexFormat
->MesaFormat
);
535 texImage
->IsCompressed
= GL_FALSE
;
536 texImage
->CompressedSize
= 0;
539 /* Allocate memory for image */
540 r300FreeTexImageData(ctx
, texImage
); /* Mesa core only clears texImage->Data but not image->mt */
543 r300_try_alloc_miptree(rmesa
, t
, texImage
, face
, level
);
544 if (t
->mt
&& r300_miptree_matches_image(t
->mt
, texImage
, face
, level
)) {
546 image
->mtlevel
= level
- t
->mt
->firstLevel
;
547 image
->mtface
= face
;
548 r300_miptree_reference(t
->mt
);
551 if (texImage
->IsCompressed
) {
552 size
= texImage
->CompressedSize
;
554 size
= texImage
->Width
* texImage
->Height
* texImage
->Depth
* texImage
->TexFormat
->TexelBytes
;
556 texImage
->Data
= _mesa_alloc_texmemory(size
);
559 /* Upload texture image; note that the spec allows pixels to be NULL */
561 pixels
= _mesa_validate_pbo_compressed_teximage(
562 ctx
, imageSize
, pixels
, packing
, "glCompressedTexImage");
564 pixels
= _mesa_validate_pbo_teximage(
565 ctx
, dims
, width
, height
, depth
,
566 format
, type
, pixels
, packing
, "glTexImage");
570 r300_teximage_map(image
, GL_TRUE
);
573 memcpy(texImage
->Data
, pixels
, imageSize
);
577 r300_mipmap_level
*lvl
= &image
->mt
->levels
[image
->mtlevel
];
578 dstRowStride
= lvl
->rowstride
;
580 dstRowStride
= texImage
->Width
* texImage
->TexFormat
->TexelBytes
;
582 if (!texImage
->TexFormat
->StoreImage(ctx
, dims
,
583 texImage
->_BaseFormat
,
585 texImage
->Data
, 0, 0, 0, /* dstX/Y/Zoffset */
587 texImage
->ImageOffsets
,
588 width
, height
, depth
,
589 format
, type
, pixels
, packing
))
590 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage");
593 r300_teximage_unmap(image
);
596 _mesa_unmap_teximage_pbo(ctx
, packing
);
598 /* SGIS_generate_mipmap */
599 if (level
== texObj
->BaseLevel
&& texObj
->GenerateMipmap
) {
600 ctx
->Driver
.GenerateMipmap(ctx
, texObj
->Target
, texObj
);
605 static GLuint
face_for_target(GLenum target
)
608 case GL_TEXTURE_CUBE_MAP_POSITIVE_X
:
609 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X
:
610 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y
:
611 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y
:
612 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z
:
613 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z
:
614 return (GLuint
) target
- (GLuint
) GL_TEXTURE_CUBE_MAP_POSITIVE_X
;
621 static void r300TexImage1D(GLcontext
* ctx
, GLenum target
, GLint level
,
622 GLint internalFormat
,
623 GLint width
, GLint border
,
624 GLenum format
, GLenum type
, const GLvoid
* pixels
,
625 const struct gl_pixelstore_attrib
*packing
,
626 struct gl_texture_object
*texObj
,
627 struct gl_texture_image
*texImage
)
629 r300_teximage(ctx
, 1, 0, level
, internalFormat
, width
, 1, 1,
630 0, format
, type
, pixels
, packing
, texObj
, texImage
, 0);
633 static void r300TexImage2D(GLcontext
* ctx
, GLenum target
, GLint level
,
634 GLint internalFormat
,
635 GLint width
, GLint height
, GLint border
,
636 GLenum format
, GLenum type
, const GLvoid
* pixels
,
637 const struct gl_pixelstore_attrib
*packing
,
638 struct gl_texture_object
*texObj
,
639 struct gl_texture_image
*texImage
)
641 GLuint face
= face_for_target(target
);
643 r300_teximage(ctx
, 2, face
, level
, internalFormat
, width
, height
, 1,
644 0, format
, type
, pixels
, packing
, texObj
, texImage
, 0);
647 static void r300CompressedTexImage2D(GLcontext
* ctx
, GLenum target
,
648 GLint level
, GLint internalFormat
,
649 GLint width
, GLint height
, GLint border
,
650 GLsizei imageSize
, const GLvoid
* data
,
651 struct gl_texture_object
*texObj
,
652 struct gl_texture_image
*texImage
)
654 GLuint face
= face_for_target(target
);
656 r300_teximage(ctx
, 2, face
, level
, internalFormat
, width
, height
, 1,
657 imageSize
, 0, 0, data
, 0, texObj
, texImage
, 1);
660 static void r300TexImage3D(GLcontext
* ctx
, GLenum target
, GLint level
,
661 GLint internalFormat
,
662 GLint width
, GLint height
, GLint depth
,
664 GLenum format
, GLenum type
, const GLvoid
* pixels
,
665 const struct gl_pixelstore_attrib
*packing
,
666 struct gl_texture_object
*texObj
,
667 struct gl_texture_image
*texImage
)
669 r300_teximage(ctx
, 3, 0, level
, internalFormat
, width
, height
, depth
,
670 0, format
, type
, pixels
, packing
, texObj
, texImage
, 0);
674 * Update a subregion of the given texture image.
676 static void r300_texsubimage(GLcontext
* ctx
, int dims
, int level
,
677 GLint xoffset
, GLint yoffset
, GLint zoffset
,
678 GLsizei width
, GLsizei height
, GLsizei depth
,
679 GLenum format
, GLenum type
,
680 const GLvoid
* pixels
,
681 const struct gl_pixelstore_attrib
*packing
,
682 struct gl_texture_object
*texObj
,
683 struct gl_texture_image
*texImage
,
686 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
687 r300_texture_image
* image
= get_r300_texture_image(texImage
);
689 R300_FIREVERTICES(rmesa
);
691 pixels
= _mesa_validate_pbo_teximage(ctx
, dims
,
692 width
, height
, depth
, format
, type
, pixels
, packing
, "glTexSubImage1D");
696 r300_teximage_map(image
, GL_TRUE
);
699 r300_mipmap_level
*lvl
= &image
->mt
->levels
[image
->mtlevel
];
700 dstRowStride
= lvl
->rowstride
;
702 dstRowStride
= texImage
->Width
* texImage
->TexFormat
->TexelBytes
;
705 if (!texImage
->TexFormat
->StoreImage(ctx
, dims
, texImage
->_BaseFormat
,
706 texImage
->TexFormat
, texImage
->Data
,
707 xoffset
, yoffset
, zoffset
,
709 texImage
->ImageOffsets
,
710 width
, height
, depth
,
711 format
, type
, pixels
, packing
))
712 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexSubImage");
714 r300_teximage_unmap(image
);
717 _mesa_unmap_teximage_pbo(ctx
, packing
);
719 /* GL_SGIS_generate_mipmap */
720 if (level
== texObj
->BaseLevel
&& texObj
->GenerateMipmap
) {
721 ctx
->Driver
.GenerateMipmap(ctx
, texObj
->Target
, texObj
);
725 static void r300TexSubImage1D(GLcontext
* ctx
, GLenum target
, GLint level
,
728 GLenum format
, GLenum type
,
729 const GLvoid
* pixels
,
730 const struct gl_pixelstore_attrib
*packing
,
731 struct gl_texture_object
*texObj
,
732 struct gl_texture_image
*texImage
)
734 r300_texsubimage(ctx
, 1, level
, xoffset
, 0, 0, width
, 1, 1,
735 format
, type
, pixels
, packing
, texObj
, texImage
, 0);
738 static void r300TexSubImage2D(GLcontext
* ctx
, GLenum target
, GLint level
,
739 GLint xoffset
, GLint yoffset
,
740 GLsizei width
, GLsizei height
,
741 GLenum format
, GLenum type
,
742 const GLvoid
* pixels
,
743 const struct gl_pixelstore_attrib
*packing
,
744 struct gl_texture_object
*texObj
,
745 struct gl_texture_image
*texImage
)
747 r300_texsubimage(ctx
, 2, level
, xoffset
, yoffset
, 0, width
, height
, 1,
748 format
, type
, pixels
, packing
, texObj
, texImage
, 0);
751 static void r300CompressedTexSubImage2D(GLcontext
* ctx
, GLenum target
,
752 GLint level
, GLint xoffset
,
753 GLint yoffset
, GLsizei width
,
754 GLsizei height
, GLenum format
,
755 GLsizei imageSize
, const GLvoid
* data
,
756 struct gl_texture_object
*texObj
,
757 struct gl_texture_image
*texImage
)
759 r300_texsubimage(ctx
, 2, level
, xoffset
, yoffset
, 0, width
, height
, 1,
760 format
, 0, data
, 0, texObj
, texImage
, 1);
764 r300TexSubImage3D(GLcontext
* ctx
, GLenum target
, GLint level
,
765 GLint xoffset
, GLint yoffset
, GLint zoffset
,
766 GLsizei width
, GLsizei height
, GLsizei depth
,
767 GLenum format
, GLenum type
,
768 const GLvoid
* pixels
,
769 const struct gl_pixelstore_attrib
*packing
,
770 struct gl_texture_object
*texObj
,
771 struct gl_texture_image
*texImage
)
773 r300_texsubimage(ctx
, 3, level
, xoffset
, yoffset
, zoffset
, width
, height
, depth
,
774 format
, type
, pixels
, packing
, texObj
, texImage
, 0);
779 * Wraps Mesa's implementation to ensure that the base level image is mapped.
781 * This relies on internal details of _mesa_generate_mipmap, in particular
782 * the fact that the memory for recreated texture images is always freed.
784 static void r300_generate_mipmap(GLcontext
* ctx
, GLenum target
, struct gl_texture_object
*texObj
)
786 GLuint face
= face_for_target(target
);
787 r300_texture_image
*baseimage
= get_r300_texture_image(texObj
->Image
[face
][texObj
->BaseLevel
]);
789 r300_teximage_map(baseimage
, GL_FALSE
);
790 _mesa_generate_mipmap(ctx
, target
, texObj
);
791 r300_teximage_unmap(baseimage
);
797 * Changes variables and flags for a state update, which will happen at the
798 * next UpdateTextureState
801 static void r300TexParameter(GLcontext
* ctx
, GLenum target
,
802 struct gl_texture_object
*texObj
,
803 GLenum pname
, const GLfloat
* params
)
805 r300TexObj
* t
= r300_tex_obj(texObj
);
807 if (RADEON_DEBUG
& (DEBUG_STATE
| DEBUG_TEXTURE
)) {
808 fprintf(stderr
, "%s( %s )\n", __FUNCTION__
,
809 _mesa_lookup_enum_by_nr(pname
));
813 case GL_TEXTURE_MIN_FILTER
:
814 case GL_TEXTURE_MAG_FILTER
:
815 case GL_TEXTURE_MAX_ANISOTROPY_EXT
:
816 r300SetTexFilter(t
, texObj
->MinFilter
, texObj
->MagFilter
, texObj
->MaxAnisotropy
);
819 case GL_TEXTURE_WRAP_S
:
820 case GL_TEXTURE_WRAP_T
:
821 case GL_TEXTURE_WRAP_R
:
822 r300UpdateTexWrap(t
);
825 case GL_TEXTURE_BORDER_COLOR
:
826 r300SetTexBorderColor(t
, texObj
->_BorderChan
);
829 case GL_TEXTURE_BASE_LEVEL
:
830 case GL_TEXTURE_MAX_LEVEL
:
831 case GL_TEXTURE_MIN_LOD
:
832 case GL_TEXTURE_MAX_LOD
:
833 /* This isn't the most efficient solution but there doesn't appear to
834 * be a nice alternative. Since there's no LOD clamping,
835 * we just have to rely on loading the right subset of mipmap levels
836 * to simulate a clamped LOD.
839 r300_miptree_unreference(t
->mt
);
841 t
->validated
= GL_FALSE
;
845 case GL_DEPTH_TEXTURE_MODE
:
846 if (!texObj
->Image
[0][texObj
->BaseLevel
])
848 if (texObj
->Image
[0][texObj
->BaseLevel
]->TexFormat
->BaseFormat
849 == GL_DEPTH_COMPONENT
) {
850 r300SetDepthTexMode(texObj
);
853 /* If the texture isn't a depth texture, changing this
854 * state won't cause any changes to the hardware.
855 * Don't force a flush of texture state.
865 static void r300DeleteTexture(GLcontext
* ctx
, struct gl_texture_object
*texObj
)
867 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
868 r300TexObj
* t
= r300_tex_obj(texObj
);
870 if (RADEON_DEBUG
& (DEBUG_STATE
| DEBUG_TEXTURE
)) {
871 fprintf(stderr
, "%s( %p (target = %s) )\n", __FUNCTION__
,
873 _mesa_lookup_enum_by_nr(texObj
->Target
));
878 R300_FIREVERTICES(rmesa
);
880 for(i
= 0; i
< R300_MAX_TEXTURE_UNITS
; ++i
)
881 if (rmesa
->hw
.textures
[i
] == t
)
882 rmesa
->hw
.textures
[i
] = 0;
886 r300_miptree_unreference(t
->mt
);
889 _mesa_delete_texture_object(ctx
, texObj
);
893 * Allocate a new texture object.
894 * Called via ctx->Driver.NewTextureObject.
895 * Note: this function will be called during context creation to
896 * allocate the default texture objects.
897 * Fixup MaxAnisotropy according to user preference.
899 static struct gl_texture_object
*r300NewTextureObject(GLcontext
* ctx
,
903 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
904 r300TexObj
* t
= CALLOC_STRUCT(r300_tex_obj
);
907 if (RADEON_DEBUG
& (DEBUG_STATE
| DEBUG_TEXTURE
)) {
908 fprintf(stderr
, "%s( %p (target = %s) )\n", __FUNCTION__
,
909 t
, _mesa_lookup_enum_by_nr(target
));
912 _mesa_initialize_texture_object(&t
->base
, name
, target
);
913 t
->base
.MaxAnisotropy
= rmesa
->initialMaxAnisotropy
;
915 /* Initialize hardware state */
916 r300UpdateTexWrap(t
);
917 r300SetTexFilter(t
, t
->base
.MinFilter
, t
->base
.MagFilter
, t
->base
.MaxAnisotropy
);
918 r300SetTexBorderColor(t
, t
->base
._BorderChan
);
923 void r300InitTextureFuncs(struct dd_function_table
*functions
)
925 /* Note: we only plug in the functions we implement in the driver
926 * since _mesa_init_driver_functions() was already called.
928 functions
->NewTextureImage
= r300NewTextureImage
;
929 functions
->FreeTexImageData
= r300FreeTexImageData
;
930 functions
->MapTexture
= r300MapTexture
;
931 functions
->UnmapTexture
= r300UnmapTexture
;
933 functions
->ChooseTextureFormat
= r300ChooseTextureFormat
;
934 functions
->TexImage1D
= r300TexImage1D
;
935 functions
->TexImage2D
= r300TexImage2D
;
936 functions
->TexImage3D
= r300TexImage3D
;
937 functions
->TexSubImage1D
= r300TexSubImage1D
;
938 functions
->TexSubImage2D
= r300TexSubImage2D
;
939 functions
->TexSubImage3D
= r300TexSubImage3D
;
940 functions
->NewTextureObject
= r300NewTextureObject
;
941 functions
->DeleteTexture
= r300DeleteTexture
;
942 functions
->IsTextureResident
= driIsTextureResident
;
944 functions
->TexParameter
= r300TexParameter
;
946 functions
->CompressedTexImage2D
= r300CompressedTexImage2D
;
947 functions
->CompressedTexSubImage2D
= r300CompressedTexSubImage2D
;
949 functions
->GenerateMipmap
= r300_generate_mipmap
;
951 driInitTextureFormats();