2 * Copyright (C) 2008 Nicolai Haehnle.
3 * Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved.
5 * The Weather Channel (TM) funded Tungsten Graphics to develop the
6 * initial release of the Radeon 8500 driver under the XFree86 license.
7 * This notice must be preserved.
9 * Permission is hereby granted, free of charge, to any person obtaining
10 * a copy of this software and associated documentation files (the
11 * "Software"), to deal in the Software without restriction, including
12 * without limitation the rights to use, copy, modify, merge, publish,
13 * distribute, sublicense, and/or sell copies of the Software, and to
14 * permit persons to whom the Software is furnished to do so, subject to
15 * the following conditions:
17 * The above copyright notice and this permission notice (including the
18 * next paragraph) shall be included in all copies or substantial
19 * portions of the Software.
21 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
22 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
23 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
24 * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
25 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
26 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
27 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
31 #include "main/glheader.h"
32 #include "main/imports.h"
33 #include "main/context.h"
34 #include "main/mipmap.h"
35 #include "main/texformat.h"
36 #include "main/texstore.h"
37 #include "main/teximage.h"
38 #include "main/texobj.h"
40 #include "xmlpool.h" /* for symbolic values of enum-type options */
42 #include "radeon_common.h"
44 #include "radeon_mipmap_tree.h"
48 * Allocate an empty texture image object.
50 struct gl_texture_image
*radeonNewTextureImage(GLcontext
*ctx
)
52 return CALLOC(sizeof(radeon_texture_image
));
56 * Free memory associated with this texture image.
58 void radeonFreeTexImageData(GLcontext
*ctx
, struct gl_texture_image
*timage
)
60 radeon_texture_image
* image
= get_radeon_texture_image(timage
);
63 radeon_miptree_unreference(image
->mt
);
65 assert(!image
->base
.Data
);
67 _mesa_free_texture_image_data(ctx
, timage
);
70 radeon_bo_unref(image
->bo
);
74 _mesa_free_texmemory(timage
->Data
);
79 /* Set Data pointer and additional data for mapped texture image */
80 static void teximage_set_map_data(radeon_texture_image
*image
)
82 radeon_mipmap_level
*lvl
= &image
->mt
->levels
[image
->mtlevel
];
84 image
->base
.Data
= image
->mt
->bo
->ptr
+ lvl
->faces
[image
->mtface
].offset
;
85 image
->base
.RowStride
= lvl
->rowstride
/ image
->mt
->bpp
;
90 * Map a single texture image for glTexImage and friends.
92 void radeon_teximage_map(radeon_texture_image
*image
, GLboolean write_enable
)
95 assert(!image
->base
.Data
);
97 radeon_bo_map(image
->mt
->bo
, write_enable
);
98 teximage_set_map_data(image
);
103 void radeon_teximage_unmap(radeon_texture_image
*image
)
106 assert(image
->base
.Data
);
108 image
->base
.Data
= 0;
109 radeon_bo_unmap(image
->mt
->bo
);
114 * Map a validated texture for reading during software rendering.
116 void radeonMapTexture(GLcontext
*ctx
, struct gl_texture_object
*texObj
)
118 radeonTexObj
* t
= radeon_tex_obj(texObj
);
121 /* for r100 3D sw fallbacks don't have mt */
125 radeon_bo_map(t
->mt
->bo
, GL_FALSE
);
126 for(face
= 0; face
< t
->mt
->faces
; ++face
) {
127 for(level
= t
->mt
->firstLevel
; level
<= t
->mt
->lastLevel
; ++level
)
128 teximage_set_map_data(get_radeon_texture_image(texObj
->Image
[face
][level
]));
132 void radeonUnmapTexture(GLcontext
*ctx
, struct gl_texture_object
*texObj
)
134 radeonTexObj
* t
= radeon_tex_obj(texObj
);
137 /* for r100 3D sw fallbacks don't have mt */
141 for(face
= 0; face
< t
->mt
->faces
; ++face
) {
142 for(level
= t
->mt
->firstLevel
; level
<= t
->mt
->lastLevel
; ++level
)
143 texObj
->Image
[face
][level
]->Data
= 0;
145 radeon_bo_unmap(t
->mt
->bo
);
148 GLuint
radeon_face_for_target(GLenum target
)
151 case GL_TEXTURE_CUBE_MAP_POSITIVE_X
:
152 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X
:
153 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y
:
154 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y
:
155 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z
:
156 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z
:
157 return (GLuint
) target
- (GLuint
) GL_TEXTURE_CUBE_MAP_POSITIVE_X
;
164 * Wraps Mesa's implementation to ensure that the base level image is mapped.
166 * This relies on internal details of _mesa_generate_mipmap, in particular
167 * the fact that the memory for recreated texture images is always freed.
169 static void radeon_generate_mipmap(GLcontext
*ctx
, GLenum target
,
170 struct gl_texture_object
*texObj
)
172 radeonTexObj
* t
= radeon_tex_obj(texObj
);
173 GLuint nr_faces
= (t
->base
.Target
== GL_TEXTURE_CUBE_MAP
) ? 6 : 1;
177 _mesa_generate_mipmap(ctx
, target
, texObj
);
179 for (face
= 0; face
< nr_faces
; face
++) {
180 for (i
= texObj
->BaseLevel
+ 1; i
< texObj
->MaxLevel
; i
++) {
181 radeon_texture_image
*image
;
183 image
= get_radeon_texture_image(texObj
->Image
[face
][i
]);
189 image
->mtface
= face
;
191 radeon_miptree_unreference(image
->mt
);
198 void radeonGenerateMipmap(GLcontext
* ctx
, GLenum target
, struct gl_texture_object
*texObj
)
200 GLuint face
= radeon_face_for_target(target
);
201 radeon_texture_image
*baseimage
= get_radeon_texture_image(texObj
->Image
[face
][texObj
->BaseLevel
]);
203 radeon_teximage_map(baseimage
, GL_FALSE
);
204 radeon_generate_mipmap(ctx
, target
, texObj
);
205 radeon_teximage_unmap(baseimage
);
209 /* try to find a format which will only need a memcopy */
210 static const struct gl_texture_format
*radeonChoose8888TexFormat(radeonContextPtr rmesa
,
215 const GLubyte littleEndian
= *((const GLubyte
*)&ui
);
217 /* r100 can only do this */
218 if (IS_R100_CLASS(rmesa
->radeonScreen
))
219 return _dri_texformat_argb8888
;
221 if ((srcFormat
== GL_RGBA
&& srcType
== GL_UNSIGNED_INT_8_8_8_8
) ||
222 (srcFormat
== GL_RGBA
&& srcType
== GL_UNSIGNED_BYTE
&& !littleEndian
) ||
223 (srcFormat
== GL_ABGR_EXT
&& srcType
== GL_UNSIGNED_INT_8_8_8_8_REV
) ||
224 (srcFormat
== GL_ABGR_EXT
&& srcType
== GL_UNSIGNED_BYTE
&& littleEndian
)) {
225 return &_mesa_texformat_rgba8888
;
226 } else if ((srcFormat
== GL_RGBA
&& srcType
== GL_UNSIGNED_INT_8_8_8_8_REV
) ||
227 (srcFormat
== GL_RGBA
&& srcType
== GL_UNSIGNED_BYTE
&& littleEndian
) ||
228 (srcFormat
== GL_ABGR_EXT
&& srcType
== GL_UNSIGNED_INT_8_8_8_8
) ||
229 (srcFormat
== GL_ABGR_EXT
&& srcType
== GL_UNSIGNED_BYTE
&& !littleEndian
)) {
230 return &_mesa_texformat_rgba8888_rev
;
231 } else if (srcFormat
== GL_BGRA
&& ((srcType
== GL_UNSIGNED_BYTE
&& !littleEndian
) ||
232 srcType
== GL_UNSIGNED_INT_8_8_8_8
)) {
233 return &_mesa_texformat_argb8888_rev
;
234 } else if (srcFormat
== GL_BGRA
&& ((srcType
== GL_UNSIGNED_BYTE
&& littleEndian
) ||
235 srcType
== GL_UNSIGNED_INT_8_8_8_8_REV
)) {
236 return &_mesa_texformat_argb8888
;
238 return _dri_texformat_argb8888
;
241 const struct gl_texture_format
*radeonChooseTextureFormat(GLcontext
* ctx
,
242 GLint internalFormat
,
246 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
247 const GLboolean do32bpt
=
248 (rmesa
->texture_depth
== DRI_CONF_TEXTURE_DEPTH_32
);
249 const GLboolean force16bpt
=
250 (rmesa
->texture_depth
== DRI_CONF_TEXTURE_DEPTH_FORCE_16
);
254 fprintf(stderr
, "InternalFormat=%s(%d) type=%s format=%s\n",
255 _mesa_lookup_enum_by_nr(internalFormat
), internalFormat
,
256 _mesa_lookup_enum_by_nr(type
), _mesa_lookup_enum_by_nr(format
));
257 fprintf(stderr
, "do32bpt=%d force16bpt=%d\n", do32bpt
, force16bpt
);
260 switch (internalFormat
) {
263 case GL_COMPRESSED_RGBA
:
265 case GL_UNSIGNED_INT_10_10_10_2
:
266 case GL_UNSIGNED_INT_2_10_10_10_REV
:
267 return do32bpt
? _dri_texformat_argb8888
:
268 _dri_texformat_argb1555
;
269 case GL_UNSIGNED_SHORT_4_4_4_4
:
270 case GL_UNSIGNED_SHORT_4_4_4_4_REV
:
271 return _dri_texformat_argb4444
;
272 case GL_UNSIGNED_SHORT_5_5_5_1
:
273 case GL_UNSIGNED_SHORT_1_5_5_5_REV
:
274 return _dri_texformat_argb1555
;
276 return do32bpt
? radeonChoose8888TexFormat(rmesa
, format
, type
) :
277 _dri_texformat_argb4444
;
282 case GL_COMPRESSED_RGB
:
284 case GL_UNSIGNED_SHORT_4_4_4_4
:
285 case GL_UNSIGNED_SHORT_4_4_4_4_REV
:
286 return _dri_texformat_argb4444
;
287 case GL_UNSIGNED_SHORT_5_5_5_1
:
288 case GL_UNSIGNED_SHORT_1_5_5_5_REV
:
289 return _dri_texformat_argb1555
;
290 case GL_UNSIGNED_SHORT_5_6_5
:
291 case GL_UNSIGNED_SHORT_5_6_5_REV
:
292 return _dri_texformat_rgb565
;
294 return do32bpt
? _dri_texformat_argb8888
:
295 _dri_texformat_rgb565
;
303 radeonChoose8888TexFormat(rmesa
, format
,type
) :
304 _dri_texformat_argb4444
;
308 return _dri_texformat_argb4444
;
311 return _dri_texformat_argb1555
;
317 return !force16bpt
? _dri_texformat_argb8888
:
318 _dri_texformat_rgb565
;
323 return _dri_texformat_rgb565
;
330 case GL_COMPRESSED_ALPHA
:
331 return _dri_texformat_a8
;
339 case GL_COMPRESSED_LUMINANCE
:
340 return _dri_texformat_l8
;
343 case GL_LUMINANCE_ALPHA
:
344 case GL_LUMINANCE4_ALPHA4
:
345 case GL_LUMINANCE6_ALPHA2
:
346 case GL_LUMINANCE8_ALPHA8
:
347 case GL_LUMINANCE12_ALPHA4
:
348 case GL_LUMINANCE12_ALPHA12
:
349 case GL_LUMINANCE16_ALPHA16
:
350 case GL_COMPRESSED_LUMINANCE_ALPHA
:
351 return _dri_texformat_al88
;
358 case GL_COMPRESSED_INTENSITY
:
359 return _dri_texformat_i8
;
362 if (type
== GL_UNSIGNED_SHORT_8_8_APPLE
||
363 type
== GL_UNSIGNED_BYTE
)
364 return &_mesa_texformat_ycbcr
;
366 return &_mesa_texformat_ycbcr_rev
;
370 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT
:
371 return &_mesa_texformat_rgb_dxt1
;
373 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT
:
374 return &_mesa_texformat_rgba_dxt1
;
378 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT
:
379 return &_mesa_texformat_rgba_dxt3
;
381 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT
:
382 return &_mesa_texformat_rgba_dxt5
;
384 case GL_ALPHA16F_ARB
:
385 return &_mesa_texformat_alpha_float16
;
386 case GL_ALPHA32F_ARB
:
387 return &_mesa_texformat_alpha_float32
;
388 case GL_LUMINANCE16F_ARB
:
389 return &_mesa_texformat_luminance_float16
;
390 case GL_LUMINANCE32F_ARB
:
391 return &_mesa_texformat_luminance_float32
;
392 case GL_LUMINANCE_ALPHA16F_ARB
:
393 return &_mesa_texformat_luminance_alpha_float16
;
394 case GL_LUMINANCE_ALPHA32F_ARB
:
395 return &_mesa_texformat_luminance_alpha_float32
;
396 case GL_INTENSITY16F_ARB
:
397 return &_mesa_texformat_intensity_float16
;
398 case GL_INTENSITY32F_ARB
:
399 return &_mesa_texformat_intensity_float32
;
401 return &_mesa_texformat_rgba_float16
;
403 return &_mesa_texformat_rgba_float32
;
405 return &_mesa_texformat_rgba_float16
;
407 return &_mesa_texformat_rgba_float32
;
409 case GL_DEPTH_COMPONENT
:
410 case GL_DEPTH_COMPONENT16
:
411 case GL_DEPTH_COMPONENT24
:
412 case GL_DEPTH_COMPONENT32
:
415 case GL_UNSIGNED_BYTE
:
416 case GL_UNSIGNED_SHORT
:
417 return &_mesa_texformat_z16
;
418 case GL_UNSIGNED_INT
:
419 return &_mesa_texformat_z32
;
420 case GL_UNSIGNED_INT_24_8_EXT
:
422 return &_mesa_texformat_z24_s8
;
425 return &_mesa_texformat_z16
;
430 "unexpected internalFormat 0x%x in r300ChooseTextureFormat",
431 (int)internalFormat
);
435 return NULL
; /* never get here */
439 * All glTexImage calls go through this function.
441 static void radeon_teximage(
442 GLcontext
*ctx
, int dims
,
443 GLint face
, GLint level
,
444 GLint internalFormat
,
445 GLint width
, GLint height
, GLint depth
,
447 GLenum format
, GLenum type
, const GLvoid
* pixels
,
448 const struct gl_pixelstore_attrib
*packing
,
449 struct gl_texture_object
*texObj
,
450 struct gl_texture_image
*texImage
,
453 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
454 radeonTexObj
* t
= radeon_tex_obj(texObj
);
455 radeon_texture_image
* image
= get_radeon_texture_image(texImage
);
457 radeon_firevertices(rmesa
);
459 t
->validated
= GL_FALSE
;
461 /* Choose and fill in the texture format for this image */
462 texImage
->TexFormat
= radeonChooseTextureFormat(ctx
, internalFormat
, format
, type
);
463 _mesa_set_fetch_functions(texImage
, dims
);
465 if (texImage
->TexFormat
->TexelBytes
== 0) {
466 texImage
->IsCompressed
= GL_TRUE
;
467 texImage
->CompressedSize
=
468 ctx
->Driver
.CompressedTextureSize(ctx
, texImage
->Width
,
469 texImage
->Height
, texImage
->Depth
,
470 texImage
->TexFormat
->MesaFormat
);
472 texImage
->IsCompressed
= GL_FALSE
;
473 texImage
->CompressedSize
= 0;
476 /* Allocate memory for image */
477 radeonFreeTexImageData(ctx
, texImage
); /* Mesa core only clears texImage->Data but not image->mt */
480 radeon_try_alloc_miptree(rmesa
, t
, texImage
, face
, level
);
481 if (t
->mt
&& radeon_miptree_matches_image(t
->mt
, texImage
, face
, level
)) {
483 image
->mtlevel
= level
- t
->mt
->firstLevel
;
484 image
->mtface
= face
;
485 radeon_miptree_reference(t
->mt
);
488 if (texImage
->IsCompressed
) {
489 size
= texImage
->CompressedSize
;
491 size
= texImage
->Width
* texImage
->Height
* texImage
->Depth
* texImage
->TexFormat
->TexelBytes
;
493 texImage
->Data
= _mesa_alloc_texmemory(size
);
496 /* Upload texture image; note that the spec allows pixels to be NULL */
498 pixels
= _mesa_validate_pbo_compressed_teximage(
499 ctx
, imageSize
, pixels
, packing
, "glCompressedTexImage");
501 pixels
= _mesa_validate_pbo_teximage(
502 ctx
, dims
, width
, height
, depth
,
503 format
, type
, pixels
, packing
, "glTexImage");
507 radeon_teximage_map(image
, GL_TRUE
);
510 memcpy(texImage
->Data
, pixels
, imageSize
);
514 radeon_mipmap_level
*lvl
= &image
->mt
->levels
[image
->mtlevel
];
515 dstRowStride
= lvl
->rowstride
;
517 dstRowStride
= texImage
->Width
* texImage
->TexFormat
->TexelBytes
;
519 if (!texImage
->TexFormat
->StoreImage(ctx
, dims
,
520 texImage
->_BaseFormat
,
522 texImage
->Data
, 0, 0, 0, /* dstX/Y/Zoffset */
524 texImage
->ImageOffsets
,
525 width
, height
, depth
,
526 format
, type
, pixels
, packing
))
527 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage");
532 /* SGIS_generate_mipmap */
533 if (level
== texObj
->BaseLevel
&& texObj
->GenerateMipmap
) {
534 radeon_generate_mipmap(ctx
, texObj
->Target
, texObj
);
538 radeon_teximage_unmap(image
);
540 _mesa_unmap_teximage_pbo(ctx
, packing
);
545 void radeonTexImage1D(GLcontext
* ctx
, GLenum target
, GLint level
,
546 GLint internalFormat
,
547 GLint width
, GLint border
,
548 GLenum format
, GLenum type
, const GLvoid
* pixels
,
549 const struct gl_pixelstore_attrib
*packing
,
550 struct gl_texture_object
*texObj
,
551 struct gl_texture_image
*texImage
)
553 radeon_teximage(ctx
, 1, 0, level
, internalFormat
, width
, 1, 1,
554 0, format
, type
, pixels
, packing
, texObj
, texImage
, 0);
557 void radeonTexImage2D(GLcontext
* ctx
, GLenum target
, GLint level
,
558 GLint internalFormat
,
559 GLint width
, GLint height
, GLint border
,
560 GLenum format
, GLenum type
, const GLvoid
* pixels
,
561 const struct gl_pixelstore_attrib
*packing
,
562 struct gl_texture_object
*texObj
,
563 struct gl_texture_image
*texImage
)
566 GLuint face
= radeon_face_for_target(target
);
568 radeon_teximage(ctx
, 2, face
, level
, internalFormat
, width
, height
, 1,
569 0, format
, type
, pixels
, packing
, texObj
, texImage
, 0);
572 void radeonCompressedTexImage2D(GLcontext
* ctx
, GLenum target
,
573 GLint level
, GLint internalFormat
,
574 GLint width
, GLint height
, GLint border
,
575 GLsizei imageSize
, const GLvoid
* data
,
576 struct gl_texture_object
*texObj
,
577 struct gl_texture_image
*texImage
)
579 GLuint face
= radeon_face_for_target(target
);
581 radeon_teximage(ctx
, 2, face
, level
, internalFormat
, width
, height
, 1,
582 imageSize
, 0, 0, data
, 0, texObj
, texImage
, 1);
585 void radeonTexImage3D(GLcontext
* ctx
, GLenum target
, GLint level
,
586 GLint internalFormat
,
587 GLint width
, GLint height
, GLint depth
,
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 radeon_teximage(ctx
, 3, 0, level
, internalFormat
, width
, height
, depth
,
595 0, format
, type
, pixels
, packing
, texObj
, texImage
, 0);
599 * Update a subregion of the given texture image.
601 static void radeon_texsubimage(GLcontext
* ctx
, int dims
, int level
,
602 GLint xoffset
, GLint yoffset
, GLint zoffset
,
603 GLsizei width
, GLsizei height
, GLsizei depth
,
604 GLenum format
, GLenum type
,
605 const GLvoid
* pixels
,
606 const struct gl_pixelstore_attrib
*packing
,
607 struct gl_texture_object
*texObj
,
608 struct gl_texture_image
*texImage
,
611 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
612 radeonTexObj
* t
= radeon_tex_obj(texObj
);
613 radeon_texture_image
* image
= get_radeon_texture_image(texImage
);
615 radeon_firevertices(rmesa
);
617 t
->validated
= GL_FALSE
;
618 pixels
= _mesa_validate_pbo_teximage(ctx
, dims
,
619 width
, height
, depth
, format
, type
, pixels
, packing
, "glTexSubImage1D");
623 radeon_teximage_map(image
, GL_TRUE
);
626 radeon_mipmap_level
*lvl
= &image
->mt
->levels
[image
->mtlevel
];
627 dstRowStride
= lvl
->rowstride
;
629 dstRowStride
= texImage
->RowStride
* texImage
->TexFormat
->TexelBytes
;
632 if (!texImage
->TexFormat
->StoreImage(ctx
, dims
, texImage
->_BaseFormat
,
633 texImage
->TexFormat
, texImage
->Data
,
634 xoffset
, yoffset
, zoffset
,
636 texImage
->ImageOffsets
,
637 width
, height
, depth
,
638 format
, type
, pixels
, packing
))
639 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexSubImage");
644 /* GL_SGIS_generate_mipmap */
645 if (level
== texObj
->BaseLevel
&& texObj
->GenerateMipmap
) {
646 radeon_generate_mipmap(ctx
, texObj
->Target
, texObj
);
648 radeon_teximage_unmap(image
);
650 _mesa_unmap_teximage_pbo(ctx
, packing
);
655 void radeonTexSubImage1D(GLcontext
* ctx
, GLenum target
, GLint level
,
658 GLenum format
, GLenum type
,
659 const GLvoid
* pixels
,
660 const struct gl_pixelstore_attrib
*packing
,
661 struct gl_texture_object
*texObj
,
662 struct gl_texture_image
*texImage
)
664 radeon_texsubimage(ctx
, 1, level
, xoffset
, 0, 0, width
, 1, 1,
665 format
, type
, pixels
, packing
, texObj
, texImage
, 0);
668 void radeonTexSubImage2D(GLcontext
* ctx
, GLenum target
, GLint level
,
669 GLint xoffset
, GLint yoffset
,
670 GLsizei width
, GLsizei height
,
671 GLenum format
, GLenum type
,
672 const GLvoid
* pixels
,
673 const struct gl_pixelstore_attrib
*packing
,
674 struct gl_texture_object
*texObj
,
675 struct gl_texture_image
*texImage
)
677 radeon_texsubimage(ctx
, 2, level
, xoffset
, yoffset
, 0, width
, height
,
678 1, format
, type
, pixels
, packing
, texObj
, texImage
,
682 void radeonCompressedTexSubImage2D(GLcontext
* ctx
, GLenum target
,
683 GLint level
, GLint xoffset
,
684 GLint yoffset
, GLsizei width
,
685 GLsizei height
, GLenum format
,
686 GLsizei imageSize
, const GLvoid
* data
,
687 struct gl_texture_object
*texObj
,
688 struct gl_texture_image
*texImage
)
690 radeon_texsubimage(ctx
, 2, level
, xoffset
, yoffset
, 0, width
, height
, 1,
691 format
, 0, data
, 0, texObj
, texImage
, 1);
695 void radeonTexSubImage3D(GLcontext
* ctx
, GLenum target
, GLint level
,
696 GLint xoffset
, GLint yoffset
, GLint zoffset
,
697 GLsizei width
, GLsizei height
, GLsizei depth
,
698 GLenum format
, GLenum type
,
699 const GLvoid
* pixels
,
700 const struct gl_pixelstore_attrib
*packing
,
701 struct gl_texture_object
*texObj
,
702 struct gl_texture_image
*texImage
)
704 radeon_texsubimage(ctx
, 3, level
, xoffset
, yoffset
, zoffset
, width
, height
, depth
,
705 format
, type
, pixels
, packing
, texObj
, texImage
, 0);
708 static void copy_rows(void* dst
, GLuint dststride
, const void* src
, GLuint srcstride
,
709 GLuint numrows
, GLuint rowsize
)
711 assert(rowsize
<= dststride
);
712 assert(rowsize
<= srcstride
);
714 if (rowsize
== srcstride
&& rowsize
== dststride
) {
715 memcpy(dst
, src
, numrows
*rowsize
);
718 for(i
= 0; i
< numrows
; ++i
) {
719 memcpy(dst
, src
, rowsize
);
728 * Ensure that the given image is stored in the given miptree from now on.
730 static void migrate_image_to_miptree(radeon_mipmap_tree
*mt
, radeon_texture_image
*image
, int face
, int level
)
732 radeon_mipmap_level
*dstlvl
= &mt
->levels
[level
- mt
->firstLevel
];
735 assert(image
->mt
!= mt
);
736 assert(dstlvl
->width
== image
->base
.Width
);
737 assert(dstlvl
->height
== image
->base
.Height
);
738 assert(dstlvl
->depth
== image
->base
.Depth
);
741 radeon_bo_map(mt
->bo
, GL_TRUE
);
742 dest
= mt
->bo
->ptr
+ dstlvl
->faces
[face
].offset
;
745 /* Format etc. should match, so we really just need a memcpy().
746 * In fact, that memcpy() could be done by the hardware in many
747 * cases, provided that we have a proper memory manager.
749 radeon_mipmap_level
*srclvl
= &image
->mt
->levels
[image
->mtlevel
];
751 assert(srclvl
->size
== dstlvl
->size
);
752 assert(srclvl
->rowstride
== dstlvl
->rowstride
);
754 radeon_bo_map(image
->mt
->bo
, GL_FALSE
);
757 image
->mt
->bo
->ptr
+ srclvl
->faces
[face
].offset
,
759 radeon_bo_unmap(image
->mt
->bo
);
761 radeon_miptree_unreference(image
->mt
);
763 uint srcrowstride
= image
->base
.Width
* image
->base
.TexFormat
->TexelBytes
;
766 // WARN_ONCE("%s: tiling not supported yet", __FUNCTION__);
768 copy_rows(dest
, dstlvl
->rowstride
, image
->base
.Data
, srcrowstride
,
769 image
->base
.Height
* image
->base
.Depth
, srcrowstride
);
771 _mesa_free_texmemory(image
->base
.Data
);
772 image
->base
.Data
= 0;
775 radeon_bo_unmap(mt
->bo
);
778 image
->mtface
= face
;
779 image
->mtlevel
= level
;
780 radeon_miptree_reference(image
->mt
);
783 int radeon_validate_texture_miptree(GLcontext
* ctx
, struct gl_texture_object
*texObj
)
785 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
786 radeonTexObj
*t
= radeon_tex_obj(texObj
);
787 radeon_texture_image
*baseimage
= get_radeon_texture_image(texObj
->Image
[0][texObj
->BaseLevel
]);
790 if (t
->validated
|| t
->image_override
)
793 if (RADEON_DEBUG
& DEBUG_TEXTURE
)
794 fprintf(stderr
, "%s: Validating texture %p now\n", __FUNCTION__
, texObj
);
796 if (baseimage
->base
.Border
> 0)
799 /* Ensure a matching miptree exists.
801 * Differing mipmap trees can result when the app uses TexImage to
802 * change texture dimensions.
804 * Prefer to use base image's miptree if it
805 * exists, since that most likely contains more valid data (remember
806 * that the base level is usually significantly larger than the rest
807 * of the miptree, so cubemaps are the only possible exception).
810 baseimage
->mt
!= t
->mt
&&
811 radeon_miptree_matches_texture(baseimage
->mt
, &t
->base
)) {
812 radeon_miptree_unreference(t
->mt
);
813 t
->mt
= baseimage
->mt
;
814 radeon_miptree_reference(t
->mt
);
815 } else if (t
->mt
&& !radeon_miptree_matches_texture(t
->mt
, &t
->base
)) {
816 radeon_miptree_unreference(t
->mt
);
821 if (RADEON_DEBUG
& DEBUG_TEXTURE
)
822 fprintf(stderr
, " Allocate new miptree\n");
823 radeon_try_alloc_miptree(rmesa
, t
, &baseimage
->base
, 0, texObj
->BaseLevel
);
825 _mesa_problem(ctx
, "r300_validate_texture failed to alloc miptree");
830 /* Ensure all images are stored in the single main miptree */
831 for(face
= 0; face
< t
->mt
->faces
; ++face
) {
832 for(level
= t
->mt
->firstLevel
; level
<= t
->mt
->lastLevel
; ++level
) {
833 radeon_texture_image
*image
= get_radeon_texture_image(texObj
->Image
[face
][level
]);
834 if (RADEON_DEBUG
& DEBUG_TEXTURE
)
835 fprintf(stderr
, " face %i, level %i... %p vs %p ", face
, level
, t
->mt
, image
->mt
);
836 if (t
->mt
== image
->mt
) {
837 if (RADEON_DEBUG
& DEBUG_TEXTURE
)
838 fprintf(stderr
, "OK\n");
842 if (RADEON_DEBUG
& DEBUG_TEXTURE
)
843 fprintf(stderr
, "migrating\n");
844 migrate_image_to_miptree(t
->mt
, image
, face
, level
);