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/convolve.h"
35 #include "main/mipmap.h"
36 #include "main/texcompress.h"
37 #include "main/texformat.h"
38 #include "main/texstore.h"
39 #include "main/teximage.h"
40 #include "main/texobj.h"
42 #include "xmlpool.h" /* for symbolic values of enum-type options */
44 #include "radeon_common.h"
46 #include "radeon_mipmap_tree.h"
49 static void copy_rows(void* dst
, GLuint dststride
, const void* src
, GLuint srcstride
,
50 GLuint numrows
, GLuint rowsize
)
52 assert(rowsize
<= dststride
);
53 assert(rowsize
<= srcstride
);
55 if (rowsize
== srcstride
&& rowsize
== dststride
) {
56 memcpy(dst
, src
, numrows
*rowsize
);
59 for(i
= 0; i
< numrows
; ++i
) {
60 memcpy(dst
, src
, rowsize
);
69 * Allocate an empty texture image object.
71 struct gl_texture_image
*radeonNewTextureImage(GLcontext
*ctx
)
73 return CALLOC(sizeof(radeon_texture_image
));
77 * Free memory associated with this texture image.
79 void radeonFreeTexImageData(GLcontext
*ctx
, struct gl_texture_image
*timage
)
81 radeon_texture_image
* image
= get_radeon_texture_image(timage
);
84 radeon_miptree_unreference(image
->mt
);
86 assert(!image
->base
.Data
);
88 _mesa_free_texture_image_data(ctx
, timage
);
91 radeon_bo_unref(image
->bo
);
95 _mesa_free_texmemory(timage
->Data
);
100 /* Set Data pointer and additional data for mapped texture image */
101 static void teximage_set_map_data(radeon_texture_image
*image
)
103 radeon_mipmap_level
*lvl
= &image
->mt
->levels
[image
->mtlevel
];
105 image
->base
.Data
= image
->mt
->bo
->ptr
+ lvl
->faces
[image
->mtface
].offset
;
106 image
->base
.RowStride
= lvl
->rowstride
/ image
->mt
->bpp
;
111 * Map a single texture image for glTexImage and friends.
113 void radeon_teximage_map(radeon_texture_image
*image
, GLboolean write_enable
)
116 assert(!image
->base
.Data
);
118 radeon_bo_map(image
->mt
->bo
, write_enable
);
119 teximage_set_map_data(image
);
124 void radeon_teximage_unmap(radeon_texture_image
*image
)
127 assert(image
->base
.Data
);
129 image
->base
.Data
= 0;
130 radeon_bo_unmap(image
->mt
->bo
);
135 * Map a validated texture for reading during software rendering.
137 void radeonMapTexture(GLcontext
*ctx
, struct gl_texture_object
*texObj
)
139 radeonTexObj
* t
= radeon_tex_obj(texObj
);
142 /* for r100 3D sw fallbacks don't have mt */
146 radeon_bo_map(t
->mt
->bo
, GL_FALSE
);
147 for(face
= 0; face
< t
->mt
->faces
; ++face
) {
148 for(level
= t
->mt
->firstLevel
; level
<= t
->mt
->lastLevel
; ++level
)
149 teximage_set_map_data(get_radeon_texture_image(texObj
->Image
[face
][level
]));
153 void radeonUnmapTexture(GLcontext
*ctx
, struct gl_texture_object
*texObj
)
155 radeonTexObj
* t
= radeon_tex_obj(texObj
);
158 /* for r100 3D sw fallbacks don't have mt */
162 for(face
= 0; face
< t
->mt
->faces
; ++face
) {
163 for(level
= t
->mt
->firstLevel
; level
<= t
->mt
->lastLevel
; ++level
)
164 texObj
->Image
[face
][level
]->Data
= 0;
166 radeon_bo_unmap(t
->mt
->bo
);
169 GLuint
radeon_face_for_target(GLenum target
)
172 case GL_TEXTURE_CUBE_MAP_POSITIVE_X
:
173 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X
:
174 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y
:
175 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y
:
176 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z
:
177 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z
:
178 return (GLuint
) target
- (GLuint
) GL_TEXTURE_CUBE_MAP_POSITIVE_X
;
185 * Wraps Mesa's implementation to ensure that the base level image is mapped.
187 * This relies on internal details of _mesa_generate_mipmap, in particular
188 * the fact that the memory for recreated texture images is always freed.
190 static void radeon_generate_mipmap(GLcontext
*ctx
, GLenum target
,
191 struct gl_texture_object
*texObj
)
193 radeonTexObj
* t
= radeon_tex_obj(texObj
);
194 GLuint nr_faces
= (t
->base
.Target
== GL_TEXTURE_CUBE_MAP
) ? 6 : 1;
198 _mesa_generate_mipmap(ctx
, target
, texObj
);
200 for (face
= 0; face
< nr_faces
; face
++) {
201 for (i
= texObj
->BaseLevel
+ 1; i
< texObj
->MaxLevel
; i
++) {
202 radeon_texture_image
*image
;
204 image
= get_radeon_texture_image(texObj
->Image
[face
][i
]);
210 image
->mtface
= face
;
212 radeon_miptree_unreference(image
->mt
);
219 void radeonGenerateMipmap(GLcontext
* ctx
, GLenum target
, struct gl_texture_object
*texObj
)
221 GLuint face
= radeon_face_for_target(target
);
222 radeon_texture_image
*baseimage
= get_radeon_texture_image(texObj
->Image
[face
][texObj
->BaseLevel
]);
224 radeon_teximage_map(baseimage
, GL_FALSE
);
225 radeon_generate_mipmap(ctx
, target
, texObj
);
226 radeon_teximage_unmap(baseimage
);
230 /* try to find a format which will only need a memcopy */
231 static const struct gl_texture_format
*radeonChoose8888TexFormat(radeonContextPtr rmesa
,
236 const GLubyte littleEndian
= *((const GLubyte
*)&ui
);
238 /* r100 can only do this */
239 if (IS_R100_CLASS(rmesa
->radeonScreen
))
240 return _dri_texformat_argb8888
;
242 if ((srcFormat
== GL_RGBA
&& srcType
== GL_UNSIGNED_INT_8_8_8_8
) ||
243 (srcFormat
== GL_RGBA
&& srcType
== GL_UNSIGNED_BYTE
&& !littleEndian
) ||
244 (srcFormat
== GL_ABGR_EXT
&& srcType
== GL_UNSIGNED_INT_8_8_8_8_REV
) ||
245 (srcFormat
== GL_ABGR_EXT
&& srcType
== GL_UNSIGNED_BYTE
&& littleEndian
)) {
246 return &_mesa_texformat_rgba8888
;
247 } else if ((srcFormat
== GL_RGBA
&& srcType
== GL_UNSIGNED_INT_8_8_8_8_REV
) ||
248 (srcFormat
== GL_RGBA
&& srcType
== GL_UNSIGNED_BYTE
&& littleEndian
) ||
249 (srcFormat
== GL_ABGR_EXT
&& srcType
== GL_UNSIGNED_INT_8_8_8_8
) ||
250 (srcFormat
== GL_ABGR_EXT
&& srcType
== GL_UNSIGNED_BYTE
&& !littleEndian
)) {
251 return &_mesa_texformat_rgba8888_rev
;
252 } else if (srcFormat
== GL_BGRA
&& ((srcType
== GL_UNSIGNED_BYTE
&& !littleEndian
) ||
253 srcType
== GL_UNSIGNED_INT_8_8_8_8
)) {
254 return &_mesa_texformat_argb8888_rev
;
255 } else if (srcFormat
== GL_BGRA
&& ((srcType
== GL_UNSIGNED_BYTE
&& littleEndian
) ||
256 srcType
== GL_UNSIGNED_INT_8_8_8_8_REV
)) {
257 return &_mesa_texformat_argb8888
;
259 return _dri_texformat_argb8888
;
262 const struct gl_texture_format
*radeonChooseTextureFormat(GLcontext
* ctx
,
263 GLint internalFormat
,
267 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
268 const GLboolean do32bpt
=
269 (rmesa
->texture_depth
== DRI_CONF_TEXTURE_DEPTH_32
);
270 const GLboolean force16bpt
=
271 (rmesa
->texture_depth
== DRI_CONF_TEXTURE_DEPTH_FORCE_16
);
275 fprintf(stderr
, "InternalFormat=%s(%d) type=%s format=%s\n",
276 _mesa_lookup_enum_by_nr(internalFormat
), internalFormat
,
277 _mesa_lookup_enum_by_nr(type
), _mesa_lookup_enum_by_nr(format
));
278 fprintf(stderr
, "do32bpt=%d force16bpt=%d\n", do32bpt
, force16bpt
);
281 switch (internalFormat
) {
284 case GL_COMPRESSED_RGBA
:
286 case GL_UNSIGNED_INT_10_10_10_2
:
287 case GL_UNSIGNED_INT_2_10_10_10_REV
:
288 return do32bpt
? _dri_texformat_argb8888
:
289 _dri_texformat_argb1555
;
290 case GL_UNSIGNED_SHORT_4_4_4_4
:
291 case GL_UNSIGNED_SHORT_4_4_4_4_REV
:
292 return _dri_texformat_argb4444
;
293 case GL_UNSIGNED_SHORT_5_5_5_1
:
294 case GL_UNSIGNED_SHORT_1_5_5_5_REV
:
295 return _dri_texformat_argb1555
;
297 return do32bpt
? radeonChoose8888TexFormat(rmesa
, format
, type
) :
298 _dri_texformat_argb4444
;
303 case GL_COMPRESSED_RGB
:
305 case GL_UNSIGNED_SHORT_4_4_4_4
:
306 case GL_UNSIGNED_SHORT_4_4_4_4_REV
:
307 return _dri_texformat_argb4444
;
308 case GL_UNSIGNED_SHORT_5_5_5_1
:
309 case GL_UNSIGNED_SHORT_1_5_5_5_REV
:
310 return _dri_texformat_argb1555
;
311 case GL_UNSIGNED_SHORT_5_6_5
:
312 case GL_UNSIGNED_SHORT_5_6_5_REV
:
313 return _dri_texformat_rgb565
;
315 return do32bpt
? _dri_texformat_argb8888
:
316 _dri_texformat_rgb565
;
324 radeonChoose8888TexFormat(rmesa
, format
,type
) :
325 _dri_texformat_argb4444
;
329 return _dri_texformat_argb4444
;
332 return _dri_texformat_argb1555
;
338 return !force16bpt
? _dri_texformat_argb8888
:
339 _dri_texformat_rgb565
;
344 return _dri_texformat_rgb565
;
351 case GL_COMPRESSED_ALPHA
:
352 return _dri_texformat_a8
;
360 case GL_COMPRESSED_LUMINANCE
:
361 return _dri_texformat_l8
;
364 case GL_LUMINANCE_ALPHA
:
365 case GL_LUMINANCE4_ALPHA4
:
366 case GL_LUMINANCE6_ALPHA2
:
367 case GL_LUMINANCE8_ALPHA8
:
368 case GL_LUMINANCE12_ALPHA4
:
369 case GL_LUMINANCE12_ALPHA12
:
370 case GL_LUMINANCE16_ALPHA16
:
371 case GL_COMPRESSED_LUMINANCE_ALPHA
:
372 return _dri_texformat_al88
;
379 case GL_COMPRESSED_INTENSITY
:
380 return _dri_texformat_i8
;
383 if (type
== GL_UNSIGNED_SHORT_8_8_APPLE
||
384 type
== GL_UNSIGNED_BYTE
)
385 return &_mesa_texformat_ycbcr
;
387 return &_mesa_texformat_ycbcr_rev
;
391 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT
:
392 return &_mesa_texformat_rgb_dxt1
;
394 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT
:
395 return &_mesa_texformat_rgba_dxt1
;
399 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT
:
400 return &_mesa_texformat_rgba_dxt3
;
402 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT
:
403 return &_mesa_texformat_rgba_dxt5
;
405 case GL_ALPHA16F_ARB
:
406 return &_mesa_texformat_alpha_float16
;
407 case GL_ALPHA32F_ARB
:
408 return &_mesa_texformat_alpha_float32
;
409 case GL_LUMINANCE16F_ARB
:
410 return &_mesa_texformat_luminance_float16
;
411 case GL_LUMINANCE32F_ARB
:
412 return &_mesa_texformat_luminance_float32
;
413 case GL_LUMINANCE_ALPHA16F_ARB
:
414 return &_mesa_texformat_luminance_alpha_float16
;
415 case GL_LUMINANCE_ALPHA32F_ARB
:
416 return &_mesa_texformat_luminance_alpha_float32
;
417 case GL_INTENSITY16F_ARB
:
418 return &_mesa_texformat_intensity_float16
;
419 case GL_INTENSITY32F_ARB
:
420 return &_mesa_texformat_intensity_float32
;
422 return &_mesa_texformat_rgba_float16
;
424 return &_mesa_texformat_rgba_float32
;
426 return &_mesa_texformat_rgba_float16
;
428 return &_mesa_texformat_rgba_float32
;
430 case GL_DEPTH_COMPONENT
:
431 case GL_DEPTH_COMPONENT16
:
432 case GL_DEPTH_COMPONENT24
:
433 case GL_DEPTH_COMPONENT32
:
436 case GL_UNSIGNED_BYTE
:
437 case GL_UNSIGNED_SHORT
:
438 return &_mesa_texformat_z16
;
439 case GL_UNSIGNED_INT
:
440 return &_mesa_texformat_z32
;
441 case GL_UNSIGNED_INT_24_8_EXT
:
443 return &_mesa_texformat_z24_s8
;
446 return &_mesa_texformat_z16
;
451 "unexpected internalFormat 0x%x in r300ChooseTextureFormat",
452 (int)internalFormat
);
456 return NULL
; /* never get here */
460 * All glTexImage calls go through this function.
462 static void radeon_teximage(
463 GLcontext
*ctx
, int dims
,
464 GLint face
, GLint level
,
465 GLint internalFormat
,
466 GLint width
, GLint height
, GLint depth
,
468 GLenum format
, GLenum type
, const GLvoid
* pixels
,
469 const struct gl_pixelstore_attrib
*packing
,
470 struct gl_texture_object
*texObj
,
471 struct gl_texture_image
*texImage
,
474 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
475 radeonTexObj
* t
= radeon_tex_obj(texObj
);
476 radeon_texture_image
* image
= get_radeon_texture_image(texImage
);
478 GLint postConvWidth
= width
;
479 GLint postConvHeight
= height
;
482 radeon_firevertices(rmesa
);
484 t
->validated
= GL_FALSE
;
486 if (ctx
->_ImageTransferState
& IMAGE_CONVOLUTION_BIT
) {
487 _mesa_adjust_image_for_convolution(ctx
, dims
, &postConvWidth
,
491 /* Choose and fill in the texture format for this image */
492 texImage
->TexFormat
= radeonChooseTextureFormat(ctx
, internalFormat
, format
, type
);
493 _mesa_set_fetch_functions(texImage
, dims
);
495 if (texImage
->TexFormat
->TexelBytes
== 0) {
497 texImage
->IsCompressed
= GL_TRUE
;
498 texImage
->CompressedSize
=
499 ctx
->Driver
.CompressedTextureSize(ctx
, texImage
->Width
,
500 texImage
->Height
, texImage
->Depth
,
501 texImage
->TexFormat
->MesaFormat
);
503 texImage
->IsCompressed
= GL_FALSE
;
504 texImage
->CompressedSize
= 0;
506 texelBytes
= texImage
->TexFormat
->TexelBytes
;
507 /* Minimum pitch of 32 bytes */
508 if (postConvWidth
* texelBytes
< 32) {
509 postConvWidth
= 32 / texelBytes
;
510 texImage
->RowStride
= postConvWidth
;
513 assert(texImage
->RowStride
== postConvWidth
);
517 /* Allocate memory for image */
518 radeonFreeTexImageData(ctx
, texImage
); /* Mesa core only clears texImage->Data but not image->mt */
521 t
->mt
->firstLevel
== level
&&
522 t
->mt
->lastLevel
== level
&&
523 t
->mt
->target
!= GL_TEXTURE_CUBE_MAP_ARB
&&
524 !radeon_miptree_matches_image(t
->mt
, texImage
, face
, level
)) {
525 radeon_miptree_unreference(t
->mt
);
530 radeon_try_alloc_miptree(rmesa
, t
, texImage
, face
, level
);
531 if (t
->mt
&& radeon_miptree_matches_image(t
->mt
, texImage
, face
, level
)) {
532 radeon_mipmap_level
*lvl
;
534 image
->mtlevel
= level
- t
->mt
->firstLevel
;
535 image
->mtface
= face
;
536 radeon_miptree_reference(t
->mt
);
537 lvl
= &image
->mt
->levels
[image
->mtlevel
];
538 dstRowStride
= lvl
->rowstride
;
541 if (texImage
->IsCompressed
) {
542 size
= texImage
->CompressedSize
;
544 size
= texImage
->Width
* texImage
->Height
* texImage
->Depth
* texImage
->TexFormat
->TexelBytes
;
546 texImage
->Data
= _mesa_alloc_texmemory(size
);
549 /* Upload texture image; note that the spec allows pixels to be NULL */
551 pixels
= _mesa_validate_pbo_compressed_teximage(
552 ctx
, imageSize
, pixels
, packing
, "glCompressedTexImage");
554 pixels
= _mesa_validate_pbo_teximage(
555 ctx
, dims
, width
, height
, depth
,
556 format
, type
, pixels
, packing
, "glTexImage");
560 radeon_teximage_map(image
, GL_TRUE
);
563 memcpy(texImage
->Data
, pixels
, imageSize
);
567 radeon_mipmap_level
*lvl
= &image
->mt
->levels
[image
->mtlevel
];
568 dstRowStride
= lvl
->rowstride
;
570 dstRowStride
= texImage
->Width
* texImage
->TexFormat
->TexelBytes
;
573 if (!texImage
->TexFormat
->StoreImage(ctx
, dims
,
574 texImage
->_BaseFormat
,
576 texImage
->Data
, 0, 0, 0, /* dstX/Y/Zoffset */
578 texImage
->ImageOffsets
,
579 width
, height
, depth
,
580 format
, type
, pixels
, packing
))
581 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage");
586 /* SGIS_generate_mipmap */
587 if (level
== texObj
->BaseLevel
&& texObj
->GenerateMipmap
) {
588 radeon_generate_mipmap(ctx
, texObj
->Target
, texObj
);
591 _mesa_unmap_teximage_pbo(ctx
, packing
);
594 radeon_teximage_unmap(image
);
599 void radeonTexImage1D(GLcontext
* ctx
, GLenum target
, GLint level
,
600 GLint internalFormat
,
601 GLint width
, GLint border
,
602 GLenum format
, GLenum type
, const GLvoid
* pixels
,
603 const struct gl_pixelstore_attrib
*packing
,
604 struct gl_texture_object
*texObj
,
605 struct gl_texture_image
*texImage
)
607 radeon_teximage(ctx
, 1, 0, level
, internalFormat
, width
, 1, 1,
608 0, format
, type
, pixels
, packing
, texObj
, texImage
, 0);
611 void radeonTexImage2D(GLcontext
* ctx
, GLenum target
, GLint level
,
612 GLint internalFormat
,
613 GLint width
, GLint height
, GLint border
,
614 GLenum format
, GLenum type
, const GLvoid
* pixels
,
615 const struct gl_pixelstore_attrib
*packing
,
616 struct gl_texture_object
*texObj
,
617 struct gl_texture_image
*texImage
)
620 GLuint face
= radeon_face_for_target(target
);
622 radeon_teximage(ctx
, 2, face
, level
, internalFormat
, width
, height
, 1,
623 0, format
, type
, pixels
, packing
, texObj
, texImage
, 0);
626 void radeonCompressedTexImage2D(GLcontext
* ctx
, GLenum target
,
627 GLint level
, GLint internalFormat
,
628 GLint width
, GLint height
, GLint border
,
629 GLsizei imageSize
, const GLvoid
* data
,
630 struct gl_texture_object
*texObj
,
631 struct gl_texture_image
*texImage
)
633 GLuint face
= radeon_face_for_target(target
);
635 radeon_teximage(ctx
, 2, face
, level
, internalFormat
, width
, height
, 1,
636 imageSize
, 0, 0, data
, &ctx
->Unpack
, texObj
, texImage
, 1);
639 void radeonTexImage3D(GLcontext
* ctx
, GLenum target
, GLint level
,
640 GLint internalFormat
,
641 GLint width
, GLint height
, GLint depth
,
643 GLenum format
, GLenum type
, const GLvoid
* pixels
,
644 const struct gl_pixelstore_attrib
*packing
,
645 struct gl_texture_object
*texObj
,
646 struct gl_texture_image
*texImage
)
648 radeon_teximage(ctx
, 3, 0, level
, internalFormat
, width
, height
, depth
,
649 0, format
, type
, pixels
, packing
, texObj
, texImage
, 0);
653 * Update a subregion of the given texture image.
655 static void radeon_texsubimage(GLcontext
* ctx
, int dims
, int level
,
656 GLint xoffset
, GLint yoffset
, GLint zoffset
,
657 GLsizei width
, GLsizei height
, GLsizei depth
,
659 GLenum format
, GLenum type
,
660 const GLvoid
* pixels
,
661 const struct gl_pixelstore_attrib
*packing
,
662 struct gl_texture_object
*texObj
,
663 struct gl_texture_image
*texImage
,
666 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
667 radeonTexObj
* t
= radeon_tex_obj(texObj
);
668 radeon_texture_image
* image
= get_radeon_texture_image(texImage
);
670 radeon_firevertices(rmesa
);
672 t
->validated
= GL_FALSE
;
674 pixels
= _mesa_validate_pbo_compressed_teximage(
675 ctx
, imageSize
, pixels
, packing
, "glCompressedTexImage");
677 pixels
= _mesa_validate_pbo_teximage(ctx
, dims
,
678 width
, height
, depth
, format
, type
, pixels
, packing
, "glTexSubImage1D");
683 radeon_teximage_map(image
, GL_TRUE
);
686 radeon_mipmap_level
*lvl
= &image
->mt
->levels
[image
->mtlevel
];
687 dstRowStride
= lvl
->rowstride
;
689 dstRowStride
= texImage
->RowStride
* texImage
->TexFormat
->TexelBytes
;
693 uint32_t srcRowStride
, bytesPerRow
, rows
;
694 dstRowStride
= _mesa_compressed_row_stride(texImage
->TexFormat
->MesaFormat
, texImage
->Width
);
695 srcRowStride
= _mesa_compressed_row_stride(texImage
->TexFormat
->MesaFormat
, width
);
696 bytesPerRow
= srcRowStride
;
699 copy_rows(texImage
->Data
, dstRowStride
, image
->base
.Data
, srcRowStride
, rows
,
703 if (!texImage
->TexFormat
->StoreImage(ctx
, dims
, texImage
->_BaseFormat
,
704 texImage
->TexFormat
, texImage
->Data
,
705 xoffset
, yoffset
, zoffset
,
707 texImage
->ImageOffsets
,
708 width
, height
, depth
,
709 format
, type
, pixels
, packing
))
710 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexSubImage");
715 /* GL_SGIS_generate_mipmap */
716 if (level
== texObj
->BaseLevel
&& texObj
->GenerateMipmap
) {
717 radeon_generate_mipmap(ctx
, texObj
->Target
, texObj
);
719 radeon_teximage_unmap(image
);
721 _mesa_unmap_teximage_pbo(ctx
, packing
);
726 void radeonTexSubImage1D(GLcontext
* ctx
, GLenum target
, GLint level
,
729 GLenum format
, GLenum type
,
730 const GLvoid
* pixels
,
731 const struct gl_pixelstore_attrib
*packing
,
732 struct gl_texture_object
*texObj
,
733 struct gl_texture_image
*texImage
)
735 radeon_texsubimage(ctx
, 1, level
, xoffset
, 0, 0, width
, 1, 1, 0,
736 format
, type
, pixels
, packing
, texObj
, texImage
, 0);
739 void radeonTexSubImage2D(GLcontext
* ctx
, GLenum target
, GLint level
,
740 GLint xoffset
, GLint yoffset
,
741 GLsizei width
, GLsizei height
,
742 GLenum format
, GLenum type
,
743 const GLvoid
* pixels
,
744 const struct gl_pixelstore_attrib
*packing
,
745 struct gl_texture_object
*texObj
,
746 struct gl_texture_image
*texImage
)
748 radeon_texsubimage(ctx
, 2, level
, xoffset
, yoffset
, 0, width
, height
, 1,
749 0, format
, type
, pixels
, packing
, texObj
, texImage
,
753 void radeonCompressedTexSubImage2D(GLcontext
* ctx
, GLenum target
,
754 GLint level
, GLint xoffset
,
755 GLint yoffset
, GLsizei width
,
756 GLsizei height
, GLenum format
,
757 GLsizei imageSize
, const GLvoid
* data
,
758 struct gl_texture_object
*texObj
,
759 struct gl_texture_image
*texImage
)
761 radeon_texsubimage(ctx
, 2, level
, xoffset
, yoffset
, 0, width
, height
, 1,
762 imageSize
, format
, 0, data
, &ctx
->Unpack
, texObj
, texImage
, 1);
766 void radeonTexSubImage3D(GLcontext
* ctx
, GLenum target
, GLint level
,
767 GLint xoffset
, GLint yoffset
, GLint zoffset
,
768 GLsizei width
, GLsizei height
, GLsizei depth
,
769 GLenum format
, GLenum type
,
770 const GLvoid
* pixels
,
771 const struct gl_pixelstore_attrib
*packing
,
772 struct gl_texture_object
*texObj
,
773 struct gl_texture_image
*texImage
)
775 radeon_texsubimage(ctx
, 3, level
, xoffset
, yoffset
, zoffset
, width
, height
, depth
, 0,
776 format
, type
, pixels
, packing
, texObj
, texImage
, 0);
782 * Ensure that the given image is stored in the given miptree from now on.
784 static void migrate_image_to_miptree(radeon_mipmap_tree
*mt
, radeon_texture_image
*image
, int face
, int level
)
786 radeon_mipmap_level
*dstlvl
= &mt
->levels
[level
- mt
->firstLevel
];
789 assert(image
->mt
!= mt
);
790 assert(dstlvl
->width
== image
->base
.Width
);
791 assert(dstlvl
->height
== image
->base
.Height
);
792 assert(dstlvl
->depth
== image
->base
.Depth
);
795 radeon_bo_map(mt
->bo
, GL_TRUE
);
796 dest
= mt
->bo
->ptr
+ dstlvl
->faces
[face
].offset
;
799 /* Format etc. should match, so we really just need a memcpy().
800 * In fact, that memcpy() could be done by the hardware in many
801 * cases, provided that we have a proper memory manager.
803 radeon_mipmap_level
*srclvl
= &image
->mt
->levels
[image
->mtlevel
];
805 assert(srclvl
->size
== dstlvl
->size
);
806 assert(srclvl
->rowstride
== dstlvl
->rowstride
);
808 radeon_bo_map(image
->mt
->bo
, GL_FALSE
);
811 image
->mt
->bo
->ptr
+ srclvl
->faces
[face
].offset
,
813 radeon_bo_unmap(image
->mt
->bo
);
815 radeon_miptree_unreference(image
->mt
);
817 uint32_t srcrowstride
;
819 /* need to confirm this value is correct */
820 if (mt
->compressed
) {
821 height
= image
->base
.Height
/ 4;
822 srcrowstride
= image
->base
.RowStride
* mt
->bpp
;
824 height
= image
->base
.Height
* image
->base
.Depth
;
825 srcrowstride
= image
->base
.Width
* image
->base
.TexFormat
->TexelBytes
;
829 // WARN_ONCE("%s: tiling not supported yet", __FUNCTION__);
831 copy_rows(dest
, dstlvl
->rowstride
, image
->base
.Data
, srcrowstride
,
832 height
, srcrowstride
);
834 _mesa_free_texmemory(image
->base
.Data
);
835 image
->base
.Data
= 0;
838 radeon_bo_unmap(mt
->bo
);
841 image
->mtface
= face
;
842 image
->mtlevel
= level
;
843 radeon_miptree_reference(image
->mt
);
846 int radeon_validate_texture_miptree(GLcontext
* ctx
, struct gl_texture_object
*texObj
)
848 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
849 radeonTexObj
*t
= radeon_tex_obj(texObj
);
850 radeon_texture_image
*baseimage
= get_radeon_texture_image(texObj
->Image
[0][texObj
->BaseLevel
]);
853 if (t
->validated
|| t
->image_override
)
856 if (RADEON_DEBUG
& DEBUG_TEXTURE
)
857 fprintf(stderr
, "%s: Validating texture %p now\n", __FUNCTION__
, texObj
);
859 if (baseimage
->base
.Border
> 0)
862 /* Ensure a matching miptree exists.
864 * Differing mipmap trees can result when the app uses TexImage to
865 * change texture dimensions.
867 * Prefer to use base image's miptree if it
868 * exists, since that most likely contains more valid data (remember
869 * that the base level is usually significantly larger than the rest
870 * of the miptree, so cubemaps are the only possible exception).
873 baseimage
->mt
!= t
->mt
&&
874 radeon_miptree_matches_texture(baseimage
->mt
, &t
->base
)) {
875 radeon_miptree_unreference(t
->mt
);
876 t
->mt
= baseimage
->mt
;
877 radeon_miptree_reference(t
->mt
);
878 } else if (t
->mt
&& !radeon_miptree_matches_texture(t
->mt
, &t
->base
)) {
879 radeon_miptree_unreference(t
->mt
);
884 if (RADEON_DEBUG
& DEBUG_TEXTURE
)
885 fprintf(stderr
, " Allocate new miptree\n");
886 radeon_try_alloc_miptree(rmesa
, t
, &baseimage
->base
, 0, texObj
->BaseLevel
);
888 _mesa_problem(ctx
, "r300_validate_texture failed to alloc miptree");
893 /* Ensure all images are stored in the single main miptree */
894 for(face
= 0; face
< t
->mt
->faces
; ++face
) {
895 for(level
= t
->mt
->firstLevel
; level
<= t
->mt
->lastLevel
; ++level
) {
896 radeon_texture_image
*image
= get_radeon_texture_image(texObj
->Image
[face
][level
]);
897 if (RADEON_DEBUG
& DEBUG_TEXTURE
)
898 fprintf(stderr
, " face %i, level %i... %p vs %p ", face
, level
, t
->mt
, image
->mt
);
899 if (t
->mt
== image
->mt
) {
900 if (RADEON_DEBUG
& DEBUG_TEXTURE
)
901 fprintf(stderr
, "OK\n");
905 if (RADEON_DEBUG
& DEBUG_TEXTURE
)
906 fprintf(stderr
, "migrating\n");
907 migrate_image_to_miptree(t
->mt
, image
, face
, level
);
916 * Need to map texture image into memory before copying image data,
920 radeon_get_tex_image(GLcontext
* ctx
, GLenum target
, GLint level
,
921 GLenum format
, GLenum type
, GLvoid
* pixels
,
922 struct gl_texture_object
*texObj
,
923 struct gl_texture_image
*texImage
, int compressed
)
925 radeon_texture_image
*image
= get_radeon_texture_image(texImage
);
928 /* Map the texture image read-only */
929 radeon_teximage_map(image
, GL_FALSE
);
931 /* Image hasn't been uploaded to a miptree yet */
932 assert(image
->base
.Data
);
936 _mesa_get_compressed_teximage(ctx
, target
, level
, pixels
,
939 _mesa_get_teximage(ctx
, target
, level
, format
, type
, pixels
,
944 radeon_teximage_unmap(image
);
949 radeonGetTexImage(GLcontext
* ctx
, GLenum target
, GLint level
,
950 GLenum format
, GLenum type
, GLvoid
* pixels
,
951 struct gl_texture_object
*texObj
,
952 struct gl_texture_image
*texImage
)
954 radeon_get_tex_image(ctx
, target
, level
, format
, type
, pixels
,
955 texObj
, texImage
, 0);
959 radeonGetCompressedTexImage(GLcontext
*ctx
, GLenum target
, GLint level
,
961 struct gl_texture_object
*texObj
,
962 struct gl_texture_image
*texImage
)
964 radeon_get_tex_image(ctx
, target
, level
, 0, 0, pixels
,
965 texObj
, texImage
, 1);