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"
41 #include "main/texgetimage.h"
43 #include "xmlpool.h" /* for symbolic values of enum-type options */
45 #include "radeon_common.h"
47 #include "radeon_mipmap_tree.h"
50 static void copy_rows(void* dst
, GLuint dststride
, const void* src
, GLuint srcstride
,
51 GLuint numrows
, GLuint rowsize
)
53 assert(rowsize
<= dststride
);
54 assert(rowsize
<= srcstride
);
56 if (rowsize
== srcstride
&& rowsize
== dststride
) {
57 memcpy(dst
, src
, numrows
*rowsize
);
60 for(i
= 0; i
< numrows
; ++i
) {
61 memcpy(dst
, src
, rowsize
);
70 * Allocate an empty texture image object.
72 struct gl_texture_image
*radeonNewTextureImage(GLcontext
*ctx
)
74 return CALLOC(sizeof(radeon_texture_image
));
78 * Free memory associated with this texture image.
80 void radeonFreeTexImageData(GLcontext
*ctx
, struct gl_texture_image
*timage
)
82 radeon_texture_image
* image
= get_radeon_texture_image(timage
);
85 radeon_miptree_unreference(image
->mt
);
87 assert(!image
->base
.Data
);
89 _mesa_free_texture_image_data(ctx
, timage
);
92 radeon_bo_unref(image
->bo
);
96 _mesa_free_texmemory(timage
->Data
);
101 /* Set Data pointer and additional data for mapped texture image */
102 static void teximage_set_map_data(radeon_texture_image
*image
)
104 radeon_mipmap_level
*lvl
;
109 lvl
= &image
->mt
->levels
[image
->mtlevel
];
111 image
->base
.Data
= image
->mt
->bo
->ptr
+ lvl
->faces
[image
->mtface
].offset
;
112 image
->base
.RowStride
= lvl
->rowstride
/ image
->mt
->bpp
;
117 * Map a single texture image for glTexImage and friends.
119 void radeon_teximage_map(radeon_texture_image
*image
, GLboolean write_enable
)
122 assert(!image
->base
.Data
);
124 radeon_bo_map(image
->mt
->bo
, write_enable
);
125 teximage_set_map_data(image
);
130 void radeon_teximage_unmap(radeon_texture_image
*image
)
133 assert(image
->base
.Data
);
135 image
->base
.Data
= 0;
136 radeon_bo_unmap(image
->mt
->bo
);
140 static void map_override(GLcontext
*ctx
, radeonTexObj
*t
)
142 radeon_texture_image
*img
= get_radeon_texture_image(t
->base
.Image
[0][0]);
144 radeon_bo_map(t
->bo
, GL_FALSE
);
146 img
->base
.Data
= t
->bo
->ptr
;
147 _mesa_set_fetch_functions(&img
->base
, 2);
150 static void unmap_override(GLcontext
*ctx
, radeonTexObj
*t
)
152 radeon_texture_image
*img
= get_radeon_texture_image(t
->base
.Image
[0][0]);
154 radeon_bo_unmap(t
->bo
);
156 img
->base
.Data
= NULL
;
160 * Map a validated texture for reading during software rendering.
162 void radeonMapTexture(GLcontext
*ctx
, struct gl_texture_object
*texObj
)
164 radeonTexObj
* t
= radeon_tex_obj(texObj
);
167 if (!radeon_validate_texture_miptree(ctx
, texObj
))
170 /* for r100 3D sw fallbacks don't have mt */
171 if (t
->image_override
&& t
->bo
)
172 map_override(ctx
, t
);
177 radeon_bo_map(t
->mt
->bo
, GL_FALSE
);
178 for(face
= 0; face
< t
->mt
->faces
; ++face
) {
179 for(level
= t
->mt
->firstLevel
; level
<= t
->mt
->lastLevel
; ++level
)
180 teximage_set_map_data(get_radeon_texture_image(texObj
->Image
[face
][level
]));
184 void radeonUnmapTexture(GLcontext
*ctx
, struct gl_texture_object
*texObj
)
186 radeonTexObj
* t
= radeon_tex_obj(texObj
);
189 if (t
->image_override
&& t
->bo
)
190 unmap_override(ctx
, t
);
191 /* for r100 3D sw fallbacks don't have mt */
195 for(face
= 0; face
< t
->mt
->faces
; ++face
) {
196 for(level
= t
->mt
->firstLevel
; level
<= t
->mt
->lastLevel
; ++level
)
197 texObj
->Image
[face
][level
]->Data
= 0;
199 radeon_bo_unmap(t
->mt
->bo
);
202 GLuint
radeon_face_for_target(GLenum target
)
205 case GL_TEXTURE_CUBE_MAP_POSITIVE_X
:
206 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X
:
207 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y
:
208 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y
:
209 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z
:
210 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z
:
211 return (GLuint
) target
- (GLuint
) GL_TEXTURE_CUBE_MAP_POSITIVE_X
;
218 * Wraps Mesa's implementation to ensure that the base level image is mapped.
220 * This relies on internal details of _mesa_generate_mipmap, in particular
221 * the fact that the memory for recreated texture images is always freed.
223 static void radeon_generate_mipmap(GLcontext
*ctx
, GLenum target
,
224 struct gl_texture_object
*texObj
)
226 radeonTexObj
* t
= radeon_tex_obj(texObj
);
227 GLuint nr_faces
= (t
->base
.Target
== GL_TEXTURE_CUBE_MAP
) ? 6 : 1;
231 _mesa_generate_mipmap(ctx
, target
, texObj
);
233 for (face
= 0; face
< nr_faces
; face
++) {
234 for (i
= texObj
->BaseLevel
+ 1; i
< texObj
->MaxLevel
; i
++) {
235 radeon_texture_image
*image
;
237 image
= get_radeon_texture_image(texObj
->Image
[face
][i
]);
243 image
->mtface
= face
;
245 radeon_miptree_unreference(image
->mt
);
252 void radeonGenerateMipmap(GLcontext
* ctx
, GLenum target
, struct gl_texture_object
*texObj
)
254 GLuint face
= radeon_face_for_target(target
);
255 radeon_texture_image
*baseimage
= get_radeon_texture_image(texObj
->Image
[face
][texObj
->BaseLevel
]);
257 radeon_teximage_map(baseimage
, GL_FALSE
);
258 radeon_generate_mipmap(ctx
, target
, texObj
);
259 radeon_teximage_unmap(baseimage
);
263 /* try to find a format which will only need a memcopy */
264 static const struct gl_texture_format
*radeonChoose8888TexFormat(radeonContextPtr rmesa
,
266 GLenum srcType
, GLboolean fbo
)
269 const GLubyte littleEndian
= *((const GLubyte
*)&ui
);
271 /* r100 can only do this */
272 if (IS_R100_CLASS(rmesa
->radeonScreen
) || fbo
)
273 return _dri_texformat_argb8888
;
275 if ((srcFormat
== GL_RGBA
&& srcType
== GL_UNSIGNED_INT_8_8_8_8
) ||
276 (srcFormat
== GL_RGBA
&& srcType
== GL_UNSIGNED_BYTE
&& !littleEndian
) ||
277 (srcFormat
== GL_ABGR_EXT
&& srcType
== GL_UNSIGNED_INT_8_8_8_8_REV
) ||
278 (srcFormat
== GL_ABGR_EXT
&& srcType
== GL_UNSIGNED_BYTE
&& littleEndian
)) {
279 return &_mesa_texformat_rgba8888
;
280 } else if ((srcFormat
== GL_RGBA
&& srcType
== GL_UNSIGNED_INT_8_8_8_8_REV
) ||
281 (srcFormat
== GL_RGBA
&& srcType
== GL_UNSIGNED_BYTE
&& littleEndian
) ||
282 (srcFormat
== GL_ABGR_EXT
&& srcType
== GL_UNSIGNED_INT_8_8_8_8
) ||
283 (srcFormat
== GL_ABGR_EXT
&& srcType
== GL_UNSIGNED_BYTE
&& !littleEndian
)) {
284 return &_mesa_texformat_rgba8888_rev
;
285 } else if (IS_R200_CLASS(rmesa
->radeonScreen
)) {
286 return _dri_texformat_argb8888
;
287 } else if (srcFormat
== GL_BGRA
&& ((srcType
== GL_UNSIGNED_BYTE
&& !littleEndian
) ||
288 srcType
== GL_UNSIGNED_INT_8_8_8_8
)) {
289 return &_mesa_texformat_argb8888_rev
;
290 } else if (srcFormat
== GL_BGRA
&& ((srcType
== GL_UNSIGNED_BYTE
&& littleEndian
) ||
291 srcType
== GL_UNSIGNED_INT_8_8_8_8_REV
)) {
292 return &_mesa_texformat_argb8888
;
294 return _dri_texformat_argb8888
;
297 const struct gl_texture_format
*radeonChooseTextureFormat_mesa(GLcontext
* ctx
,
298 GLint internalFormat
,
302 return radeonChooseTextureFormat(ctx
, internalFormat
, format
,
306 const struct gl_texture_format
*radeonChooseTextureFormat(GLcontext
* ctx
,
307 GLint internalFormat
,
309 GLenum type
, GLboolean fbo
)
311 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
312 const GLboolean do32bpt
=
313 (rmesa
->texture_depth
== DRI_CONF_TEXTURE_DEPTH_32
);
314 const GLboolean force16bpt
=
315 (rmesa
->texture_depth
== DRI_CONF_TEXTURE_DEPTH_FORCE_16
);
319 fprintf(stderr
, "InternalFormat=%s(%d) type=%s format=%s\n",
320 _mesa_lookup_enum_by_nr(internalFormat
), internalFormat
,
321 _mesa_lookup_enum_by_nr(type
), _mesa_lookup_enum_by_nr(format
));
322 fprintf(stderr
, "do32bpt=%d force16bpt=%d\n", do32bpt
, force16bpt
);
325 switch (internalFormat
) {
328 case GL_COMPRESSED_RGBA
:
330 case GL_UNSIGNED_INT_10_10_10_2
:
331 case GL_UNSIGNED_INT_2_10_10_10_REV
:
332 return do32bpt
? _dri_texformat_argb8888
:
333 _dri_texformat_argb1555
;
334 case GL_UNSIGNED_SHORT_4_4_4_4
:
335 case GL_UNSIGNED_SHORT_4_4_4_4_REV
:
336 return _dri_texformat_argb4444
;
337 case GL_UNSIGNED_SHORT_5_5_5_1
:
338 case GL_UNSIGNED_SHORT_1_5_5_5_REV
:
339 return _dri_texformat_argb1555
;
341 return do32bpt
? radeonChoose8888TexFormat(rmesa
, format
, type
, fbo
) :
342 _dri_texformat_argb4444
;
347 case GL_COMPRESSED_RGB
:
349 case GL_UNSIGNED_SHORT_4_4_4_4
:
350 case GL_UNSIGNED_SHORT_4_4_4_4_REV
:
351 return _dri_texformat_argb4444
;
352 case GL_UNSIGNED_SHORT_5_5_5_1
:
353 case GL_UNSIGNED_SHORT_1_5_5_5_REV
:
354 return _dri_texformat_argb1555
;
355 case GL_UNSIGNED_SHORT_5_6_5
:
356 case GL_UNSIGNED_SHORT_5_6_5_REV
:
357 return _dri_texformat_rgb565
;
359 return do32bpt
? _dri_texformat_argb8888
:
360 _dri_texformat_rgb565
;
368 radeonChoose8888TexFormat(rmesa
, format
, type
, fbo
) :
369 _dri_texformat_argb4444
;
373 return _dri_texformat_argb4444
;
376 return _dri_texformat_argb1555
;
382 return !force16bpt
? _dri_texformat_argb8888
:
383 _dri_texformat_rgb565
;
388 return _dri_texformat_rgb565
;
395 case GL_COMPRESSED_ALPHA
:
396 /* r200: can't use a8 format since interpreting hw I8 as a8 would result
397 in wrong rgb values (same as alpha value instead of 0). */
398 if (IS_R200_CLASS(rmesa
->radeonScreen
))
399 return _dri_texformat_al88
;
401 return _dri_texformat_a8
;
408 case GL_COMPRESSED_LUMINANCE
:
409 return _dri_texformat_l8
;
412 case GL_LUMINANCE_ALPHA
:
413 case GL_LUMINANCE4_ALPHA4
:
414 case GL_LUMINANCE6_ALPHA2
:
415 case GL_LUMINANCE8_ALPHA8
:
416 case GL_LUMINANCE12_ALPHA4
:
417 case GL_LUMINANCE12_ALPHA12
:
418 case GL_LUMINANCE16_ALPHA16
:
419 case GL_COMPRESSED_LUMINANCE_ALPHA
:
420 return _dri_texformat_al88
;
427 case GL_COMPRESSED_INTENSITY
:
428 return _dri_texformat_i8
;
431 if (type
== GL_UNSIGNED_SHORT_8_8_APPLE
||
432 type
== GL_UNSIGNED_BYTE
)
433 return &_mesa_texformat_ycbcr
;
435 return &_mesa_texformat_ycbcr_rev
;
439 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT
:
440 return &_mesa_texformat_rgb_dxt1
;
442 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT
:
443 return &_mesa_texformat_rgba_dxt1
;
447 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT
:
448 return &_mesa_texformat_rgba_dxt3
;
450 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT
:
451 return &_mesa_texformat_rgba_dxt5
;
453 case GL_ALPHA16F_ARB
:
454 return &_mesa_texformat_alpha_float16
;
455 case GL_ALPHA32F_ARB
:
456 return &_mesa_texformat_alpha_float32
;
457 case GL_LUMINANCE16F_ARB
:
458 return &_mesa_texformat_luminance_float16
;
459 case GL_LUMINANCE32F_ARB
:
460 return &_mesa_texformat_luminance_float32
;
461 case GL_LUMINANCE_ALPHA16F_ARB
:
462 return &_mesa_texformat_luminance_alpha_float16
;
463 case GL_LUMINANCE_ALPHA32F_ARB
:
464 return &_mesa_texformat_luminance_alpha_float32
;
465 case GL_INTENSITY16F_ARB
:
466 return &_mesa_texformat_intensity_float16
;
467 case GL_INTENSITY32F_ARB
:
468 return &_mesa_texformat_intensity_float32
;
470 return &_mesa_texformat_rgba_float16
;
472 return &_mesa_texformat_rgba_float32
;
474 return &_mesa_texformat_rgba_float16
;
476 return &_mesa_texformat_rgba_float32
;
478 case GL_DEPTH_COMPONENT
:
479 case GL_DEPTH_COMPONENT16
:
480 case GL_DEPTH_COMPONENT24
:
481 case GL_DEPTH_COMPONENT32
:
482 case GL_DEPTH_STENCIL_EXT
:
483 case GL_DEPTH24_STENCIL8_EXT
:
484 return &_mesa_texformat_s8_z24
;
486 /* EXT_texture_sRGB */
490 case GL_SRGB8_ALPHA8
:
491 case GL_COMPRESSED_SRGB
:
492 case GL_COMPRESSED_SRGB_ALPHA
:
493 return &_mesa_texformat_srgba8
;
497 case GL_COMPRESSED_SLUMINANCE
:
498 return &_mesa_texformat_sl8
;
500 case GL_SLUMINANCE_ALPHA
:
501 case GL_SLUMINANCE8_ALPHA8
:
502 case GL_COMPRESSED_SLUMINANCE_ALPHA
:
503 return &_mesa_texformat_sla8
;
507 "unexpected internalFormat 0x%x in %s",
508 (int)internalFormat
, __func__
);
512 return NULL
; /* never get here */
516 * All glTexImage calls go through this function.
518 static void radeon_teximage(
519 GLcontext
*ctx
, int dims
,
520 GLenum target
, GLint level
,
521 GLint internalFormat
,
522 GLint width
, GLint height
, GLint depth
,
524 GLenum format
, GLenum type
, const GLvoid
* pixels
,
525 const struct gl_pixelstore_attrib
*packing
,
526 struct gl_texture_object
*texObj
,
527 struct gl_texture_image
*texImage
,
530 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
531 radeonTexObj
* t
= radeon_tex_obj(texObj
);
532 radeon_texture_image
* image
= get_radeon_texture_image(texImage
);
534 GLint postConvWidth
= width
;
535 GLint postConvHeight
= height
;
537 GLuint face
= radeon_face_for_target(target
);
539 radeon_firevertices(rmesa
);
541 t
->validated
= GL_FALSE
;
543 if (ctx
->_ImageTransferState
& IMAGE_CONVOLUTION_BIT
) {
544 _mesa_adjust_image_for_convolution(ctx
, dims
, &postConvWidth
,
548 /* Choose and fill in the texture format for this image */
549 texImage
->TexFormat
= radeonChooseTextureFormat(ctx
, internalFormat
, format
, type
, 0);
550 _mesa_set_fetch_functions(texImage
, dims
);
552 if (texImage
->TexFormat
->TexelBytes
== 0) {
554 texImage
->IsCompressed
= GL_TRUE
;
555 texImage
->CompressedSize
=
556 ctx
->Driver
.CompressedTextureSize(ctx
, texImage
->Width
,
557 texImage
->Height
, texImage
->Depth
,
558 texImage
->TexFormat
->MesaFormat
);
560 texImage
->IsCompressed
= GL_FALSE
;
561 texImage
->CompressedSize
= 0;
563 texelBytes
= texImage
->TexFormat
->TexelBytes
;
564 /* Minimum pitch of 32 bytes */
565 if (postConvWidth
* texelBytes
< 32) {
566 postConvWidth
= 32 / texelBytes
;
567 texImage
->RowStride
= postConvWidth
;
570 assert(texImage
->RowStride
== postConvWidth
);
574 /* Allocate memory for image */
575 radeonFreeTexImageData(ctx
, texImage
); /* Mesa core only clears texImage->Data but not image->mt */
578 t
->mt
->firstLevel
== level
&&
579 t
->mt
->lastLevel
== level
&&
580 t
->mt
->target
!= GL_TEXTURE_CUBE_MAP_ARB
&&
581 !radeon_miptree_matches_image(t
->mt
, texImage
, face
, level
)) {
582 radeon_miptree_unreference(t
->mt
);
587 radeon_try_alloc_miptree(rmesa
, t
, image
, face
, level
);
588 if (t
->mt
&& radeon_miptree_matches_image(t
->mt
, texImage
, face
, level
)) {
589 radeon_mipmap_level
*lvl
;
591 image
->mtlevel
= level
- t
->mt
->firstLevel
;
592 image
->mtface
= face
;
593 radeon_miptree_reference(t
->mt
);
594 lvl
= &image
->mt
->levels
[image
->mtlevel
];
595 dstRowStride
= lvl
->rowstride
;
598 if (texImage
->IsCompressed
) {
599 size
= texImage
->CompressedSize
;
601 size
= texImage
->Width
* texImage
->Height
* texImage
->Depth
* texImage
->TexFormat
->TexelBytes
;
603 texImage
->Data
= _mesa_alloc_texmemory(size
);
606 /* Upload texture image; note that the spec allows pixels to be NULL */
608 pixels
= _mesa_validate_pbo_compressed_teximage(
609 ctx
, imageSize
, pixels
, packing
, "glCompressedTexImage");
611 pixels
= _mesa_validate_pbo_teximage(
612 ctx
, dims
, width
, height
, depth
,
613 format
, type
, pixels
, packing
, "glTexImage");
617 radeon_teximage_map(image
, GL_TRUE
);
620 uint32_t srcRowStride
, bytesPerRow
, rows
;
621 srcRowStride
= _mesa_compressed_row_stride(texImage
->TexFormat
->MesaFormat
, width
);
622 bytesPerRow
= srcRowStride
;
623 rows
= (height
+ 3) / 4;
624 copy_rows(texImage
->Data
, image
->mt
->levels
[level
].rowstride
,
625 pixels
, srcRowStride
, rows
, bytesPerRow
);
627 memcpy(texImage
->Data
, pixels
, imageSize
);
631 GLuint
*dstImageOffsets
;
634 radeon_mipmap_level
*lvl
= &image
->mt
->levels
[image
->mtlevel
];
635 dstRowStride
= lvl
->rowstride
;
637 dstRowStride
= texImage
->Width
* texImage
->TexFormat
->TexelBytes
;
643 dstImageOffsets
= _mesa_malloc(depth
* sizeof(GLuint
)) ;
644 if (!dstImageOffsets
)
645 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage");
647 for (i
= 0; i
< depth
; ++i
) {
648 dstImageOffsets
[i
] = dstRowStride
/texImage
->TexFormat
->TexelBytes
* height
* i
;
651 dstImageOffsets
= texImage
->ImageOffsets
;
654 if (!texImage
->TexFormat
->StoreImage(ctx
, dims
,
655 texImage
->_BaseFormat
,
657 texImage
->Data
, 0, 0, 0, /* dstX/Y/Zoffset */
660 width
, height
, depth
,
661 format
, type
, pixels
, packing
))
662 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage");
665 _mesa_free(dstImageOffsets
);
669 _mesa_unmap_teximage_pbo(ctx
, packing
);
672 radeon_teximage_unmap(image
);
677 void radeonTexImage1D(GLcontext
* ctx
, GLenum target
, GLint level
,
678 GLint internalFormat
,
679 GLint width
, GLint border
,
680 GLenum format
, GLenum type
, const GLvoid
* pixels
,
681 const struct gl_pixelstore_attrib
*packing
,
682 struct gl_texture_object
*texObj
,
683 struct gl_texture_image
*texImage
)
685 radeon_teximage(ctx
, 1, target
, level
, internalFormat
, width
, 1, 1,
686 0, format
, type
, pixels
, packing
, texObj
, texImage
, 0);
689 void radeonTexImage2D(GLcontext
* ctx
, GLenum target
, GLint level
,
690 GLint internalFormat
,
691 GLint width
, GLint height
, GLint border
,
692 GLenum format
, GLenum type
, const GLvoid
* pixels
,
693 const struct gl_pixelstore_attrib
*packing
,
694 struct gl_texture_object
*texObj
,
695 struct gl_texture_image
*texImage
)
698 radeon_teximage(ctx
, 2, target
, level
, internalFormat
, width
, height
, 1,
699 0, format
, type
, pixels
, packing
, texObj
, texImage
, 0);
702 void radeonCompressedTexImage2D(GLcontext
* ctx
, GLenum target
,
703 GLint level
, GLint internalFormat
,
704 GLint width
, GLint height
, GLint border
,
705 GLsizei imageSize
, const GLvoid
* data
,
706 struct gl_texture_object
*texObj
,
707 struct gl_texture_image
*texImage
)
709 radeon_teximage(ctx
, 2, target
, level
, internalFormat
, width
, height
, 1,
710 imageSize
, 0, 0, data
, &ctx
->Unpack
, texObj
, texImage
, 1);
713 void radeonTexImage3D(GLcontext
* ctx
, GLenum target
, GLint level
,
714 GLint internalFormat
,
715 GLint width
, GLint height
, GLint depth
,
717 GLenum format
, GLenum type
, const GLvoid
* pixels
,
718 const struct gl_pixelstore_attrib
*packing
,
719 struct gl_texture_object
*texObj
,
720 struct gl_texture_image
*texImage
)
722 radeon_teximage(ctx
, 3, target
, level
, internalFormat
, width
, height
, depth
,
723 0, format
, type
, pixels
, packing
, texObj
, texImage
, 0);
727 * Update a subregion of the given texture image.
729 static void radeon_texsubimage(GLcontext
* ctx
, int dims
, GLenum target
, int level
,
730 GLint xoffset
, GLint yoffset
, GLint zoffset
,
731 GLsizei width
, GLsizei height
, GLsizei depth
,
733 GLenum format
, GLenum type
,
734 const GLvoid
* pixels
,
735 const struct gl_pixelstore_attrib
*packing
,
736 struct gl_texture_object
*texObj
,
737 struct gl_texture_image
*texImage
,
740 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
741 radeonTexObj
* t
= radeon_tex_obj(texObj
);
742 radeon_texture_image
* image
= get_radeon_texture_image(texImage
);
744 radeon_firevertices(rmesa
);
746 t
->validated
= GL_FALSE
;
748 pixels
= _mesa_validate_pbo_compressed_teximage(
749 ctx
, imageSize
, pixels
, packing
, "glCompressedTexImage");
751 pixels
= _mesa_validate_pbo_teximage(ctx
, dims
,
752 width
, height
, depth
, format
, type
, pixels
, packing
, "glTexSubImage1D");
757 radeon_teximage_map(image
, GL_TRUE
);
760 radeon_mipmap_level
*lvl
= &image
->mt
->levels
[image
->mtlevel
];
761 dstRowStride
= lvl
->rowstride
;
763 dstRowStride
= texImage
->RowStride
* texImage
->TexFormat
->TexelBytes
;
767 uint32_t srcRowStride
, bytesPerRow
, rows
;
770 dstRowStride
= _mesa_compressed_row_stride(texImage
->TexFormat
->MesaFormat
, texImage
->Width
);
771 img_start
= _mesa_compressed_image_address(xoffset
, yoffset
, 0,
772 texImage
->TexFormat
->MesaFormat
,
773 texImage
->Width
, texImage
->Data
);
776 uint32_t blocks_x
= dstRowStride
/ (image
->mt
->bpp
* 4);
777 img_start
= texImage
->Data
+ image
->mt
->bpp
* 4 * (blocks_x
* (yoffset
/ 4) + xoffset
/ 4);
779 srcRowStride
= _mesa_compressed_row_stride(texImage
->TexFormat
->MesaFormat
, width
);
780 bytesPerRow
= srcRowStride
;
781 rows
= (height
+ 3) / 4;
783 copy_rows(img_start
, dstRowStride
, pixels
, srcRowStride
, rows
, bytesPerRow
);
786 if (!texImage
->TexFormat
->StoreImage(ctx
, dims
, texImage
->_BaseFormat
,
787 texImage
->TexFormat
, texImage
->Data
,
788 xoffset
, yoffset
, zoffset
,
790 texImage
->ImageOffsets
,
791 width
, height
, depth
,
792 format
, type
, pixels
, packing
))
793 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexSubImage");
797 radeon_teximage_unmap(image
);
799 _mesa_unmap_teximage_pbo(ctx
, packing
);
804 void radeonTexSubImage1D(GLcontext
* ctx
, GLenum target
, GLint level
,
807 GLenum format
, GLenum type
,
808 const GLvoid
* pixels
,
809 const struct gl_pixelstore_attrib
*packing
,
810 struct gl_texture_object
*texObj
,
811 struct gl_texture_image
*texImage
)
813 radeon_texsubimage(ctx
, 1, target
, level
, xoffset
, 0, 0, width
, 1, 1, 0,
814 format
, type
, pixels
, packing
, texObj
, texImage
, 0);
817 void radeonTexSubImage2D(GLcontext
* ctx
, GLenum target
, GLint level
,
818 GLint xoffset
, GLint yoffset
,
819 GLsizei width
, GLsizei height
,
820 GLenum format
, GLenum type
,
821 const GLvoid
* pixels
,
822 const struct gl_pixelstore_attrib
*packing
,
823 struct gl_texture_object
*texObj
,
824 struct gl_texture_image
*texImage
)
826 radeon_texsubimage(ctx
, 2, target
, level
, xoffset
, yoffset
, 0, width
, height
, 1,
827 0, format
, type
, pixels
, packing
, texObj
, texImage
,
831 void radeonCompressedTexSubImage2D(GLcontext
* ctx
, GLenum target
,
832 GLint level
, GLint xoffset
,
833 GLint yoffset
, GLsizei width
,
834 GLsizei height
, GLenum format
,
835 GLsizei imageSize
, const GLvoid
* data
,
836 struct gl_texture_object
*texObj
,
837 struct gl_texture_image
*texImage
)
839 radeon_texsubimage(ctx
, 2, target
, level
, xoffset
, yoffset
, 0, width
, height
, 1,
840 imageSize
, format
, 0, data
, &ctx
->Unpack
, texObj
, texImage
, 1);
844 void radeonTexSubImage3D(GLcontext
* ctx
, GLenum target
, GLint level
,
845 GLint xoffset
, GLint yoffset
, GLint zoffset
,
846 GLsizei width
, GLsizei height
, GLsizei depth
,
847 GLenum format
, GLenum type
,
848 const GLvoid
* pixels
,
849 const struct gl_pixelstore_attrib
*packing
,
850 struct gl_texture_object
*texObj
,
851 struct gl_texture_image
*texImage
)
853 radeon_texsubimage(ctx
, 3, target
, level
, xoffset
, yoffset
, zoffset
, width
, height
, depth
, 0,
854 format
, type
, pixels
, packing
, texObj
, texImage
, 0);
860 * Ensure that the given image is stored in the given miptree from now on.
862 static void migrate_image_to_miptree(radeon_mipmap_tree
*mt
, radeon_texture_image
*image
, int face
, int level
)
864 radeon_mipmap_level
*dstlvl
= &mt
->levels
[level
- mt
->firstLevel
];
867 assert(image
->mt
!= mt
);
868 assert(dstlvl
->width
== image
->base
.Width
);
869 assert(dstlvl
->height
== image
->base
.Height
);
870 assert(dstlvl
->depth
== image
->base
.Depth
);
873 radeon_bo_map(mt
->bo
, GL_TRUE
);
874 dest
= mt
->bo
->ptr
+ dstlvl
->faces
[face
].offset
;
877 /* Format etc. should match, so we really just need a memcpy().
878 * In fact, that memcpy() could be done by the hardware in many
879 * cases, provided that we have a proper memory manager.
881 radeon_mipmap_level
*srclvl
= &image
->mt
->levels
[image
->mtlevel
-image
->mt
->firstLevel
];
883 assert(srclvl
->size
== dstlvl
->size
);
884 assert(srclvl
->rowstride
== dstlvl
->rowstride
);
886 radeon_bo_map(image
->mt
->bo
, GL_FALSE
);
889 image
->mt
->bo
->ptr
+ srclvl
->faces
[face
].offset
,
891 radeon_bo_unmap(image
->mt
->bo
);
893 radeon_miptree_unreference(image
->mt
);
895 uint32_t srcrowstride
;
897 /* need to confirm this value is correct */
898 if (mt
->compressed
) {
899 height
= (image
->base
.Height
+ 3) / 4;
900 srcrowstride
= _mesa_compressed_row_stride(image
->base
.TexFormat
->MesaFormat
, image
->base
.Width
);
902 height
= image
->base
.Height
* image
->base
.Depth
;
903 srcrowstride
= image
->base
.Width
* image
->base
.TexFormat
->TexelBytes
;
907 // WARN_ONCE("%s: tiling not supported yet", __FUNCTION__);
909 copy_rows(dest
, dstlvl
->rowstride
, image
->base
.Data
, srcrowstride
,
910 height
, srcrowstride
);
912 _mesa_free_texmemory(image
->base
.Data
);
913 image
->base
.Data
= 0;
916 radeon_bo_unmap(mt
->bo
);
919 image
->mtface
= face
;
920 image
->mtlevel
= level
;
921 radeon_miptree_reference(image
->mt
);
924 int radeon_validate_texture_miptree(GLcontext
* ctx
, struct gl_texture_object
*texObj
)
926 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
927 radeonTexObj
*t
= radeon_tex_obj(texObj
);
928 radeon_texture_image
*baseimage
= get_radeon_texture_image(texObj
->Image
[0][texObj
->BaseLevel
]);
931 if (t
->validated
|| t
->image_override
)
934 if (RADEON_DEBUG
& RADEON_TEXTURE
)
935 fprintf(stderr
, "%s: Validating texture %p now\n", __FUNCTION__
, texObj
);
937 if (baseimage
->base
.Border
> 0)
940 /* Ensure a matching miptree exists.
942 * Differing mipmap trees can result when the app uses TexImage to
943 * change texture dimensions.
945 * Prefer to use base image's miptree if it
946 * exists, since that most likely contains more valid data (remember
947 * that the base level is usually significantly larger than the rest
948 * of the miptree, so cubemaps are the only possible exception).
951 baseimage
->mt
!= t
->mt
&&
952 radeon_miptree_matches_texture(baseimage
->mt
, &t
->base
)) {
953 radeon_miptree_unreference(t
->mt
);
954 t
->mt
= baseimage
->mt
;
955 radeon_miptree_reference(t
->mt
);
956 } else if (t
->mt
&& !radeon_miptree_matches_texture(t
->mt
, &t
->base
)) {
957 radeon_miptree_unreference(t
->mt
);
962 if (RADEON_DEBUG
& RADEON_TEXTURE
)
963 fprintf(stderr
, " Allocate new miptree\n");
964 radeon_try_alloc_miptree(rmesa
, t
, baseimage
, 0, texObj
->BaseLevel
);
966 _mesa_problem(ctx
, "radeon_validate_texture failed to alloc miptree");
971 /* Ensure all images are stored in the single main miptree */
972 for(face
= 0; face
< t
->mt
->faces
; ++face
) {
973 for(level
= t
->mt
->firstLevel
; level
<= t
->mt
->lastLevel
; ++level
) {
974 radeon_texture_image
*image
= get_radeon_texture_image(texObj
->Image
[face
][level
]);
975 if (RADEON_DEBUG
& RADEON_TEXTURE
)
976 fprintf(stderr
, " face %i, level %i... %p vs %p ", face
, level
, t
->mt
, image
->mt
);
977 if (t
->mt
== image
->mt
|| (!image
->mt
&& !image
->base
.Data
)) {
978 if (RADEON_DEBUG
& RADEON_TEXTURE
)
979 fprintf(stderr
, "OK\n");
984 if (RADEON_DEBUG
& RADEON_TEXTURE
)
985 fprintf(stderr
, "migrating\n");
986 migrate_image_to_miptree(t
->mt
, image
, face
, level
);
995 * Need to map texture image into memory before copying image data,
999 radeon_get_tex_image(GLcontext
* ctx
, GLenum target
, GLint level
,
1000 GLenum format
, GLenum type
, GLvoid
* pixels
,
1001 struct gl_texture_object
*texObj
,
1002 struct gl_texture_image
*texImage
, int compressed
)
1004 radeon_texture_image
*image
= get_radeon_texture_image(texImage
);
1007 /* Map the texture image read-only */
1008 radeon_teximage_map(image
, GL_FALSE
);
1010 /* Image hasn't been uploaded to a miptree yet */
1011 assert(image
->base
.Data
);
1015 /* FIXME: this can't work for small textures (mips) which
1016 use different hw stride */
1017 _mesa_get_compressed_teximage(ctx
, target
, level
, pixels
,
1020 _mesa_get_teximage(ctx
, target
, level
, format
, type
, pixels
,
1025 radeon_teximage_unmap(image
);
1030 radeonGetTexImage(GLcontext
* ctx
, GLenum target
, GLint level
,
1031 GLenum format
, GLenum type
, GLvoid
* pixels
,
1032 struct gl_texture_object
*texObj
,
1033 struct gl_texture_image
*texImage
)
1035 radeon_get_tex_image(ctx
, target
, level
, format
, type
, pixels
,
1036 texObj
, texImage
, 0);
1040 radeonGetCompressedTexImage(GLcontext
*ctx
, GLenum target
, GLint level
,
1042 struct gl_texture_object
*texObj
,
1043 struct gl_texture_image
*texImage
)
1045 radeon_get_tex_image(ctx
, target
, level
, 0, 0, pixels
,
1046 texObj
, texImage
, 1);