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/texstore.h"
38 #include "main/teximage.h"
39 #include "main/texobj.h"
40 #include "main/texgetimage.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
);
85 assert(!image
->base
.Data
);
87 _mesa_free_texture_image_data(ctx
, timage
);
90 radeon_bo_unref(image
->bo
);
94 _mesa_free_texmemory(timage
->Data
);
99 /* Set Data pointer and additional data for mapped texture image */
100 static void teximage_set_map_data(radeon_texture_image
*image
)
102 radeon_mipmap_level
*lvl
;
107 lvl
= &image
->mt
->levels
[image
->mtlevel
];
109 image
->base
.Data
= image
->mt
->bo
->ptr
+ lvl
->faces
[image
->mtface
].offset
;
110 image
->base
.RowStride
= lvl
->rowstride
/ image
->mt
->bpp
;
115 * Map a single texture image for glTexImage and friends.
117 void radeon_teximage_map(radeon_texture_image
*image
, GLboolean write_enable
)
120 assert(!image
->base
.Data
);
122 radeon_bo_map(image
->mt
->bo
, write_enable
);
123 teximage_set_map_data(image
);
128 void radeon_teximage_unmap(radeon_texture_image
*image
)
131 assert(image
->base
.Data
);
133 image
->base
.Data
= 0;
134 radeon_bo_unmap(image
->mt
->bo
);
138 static void map_override(GLcontext
*ctx
, radeonTexObj
*t
)
140 radeon_texture_image
*img
= get_radeon_texture_image(t
->base
.Image
[0][0]);
142 radeon_bo_map(t
->bo
, GL_FALSE
);
144 img
->base
.Data
= t
->bo
->ptr
;
147 static void unmap_override(GLcontext
*ctx
, radeonTexObj
*t
)
149 radeon_texture_image
*img
= get_radeon_texture_image(t
->base
.Image
[0][0]);
151 radeon_bo_unmap(t
->bo
);
153 img
->base
.Data
= NULL
;
157 * Map a validated texture for reading during software rendering.
159 void radeonMapTexture(GLcontext
*ctx
, struct gl_texture_object
*texObj
)
161 radeonTexObj
* t
= radeon_tex_obj(texObj
);
164 if (!radeon_validate_texture_miptree(ctx
, texObj
))
167 /* for r100 3D sw fallbacks don't have mt */
168 if (t
->image_override
&& t
->bo
)
169 map_override(ctx
, t
);
174 radeon_bo_map(t
->mt
->bo
, GL_FALSE
);
175 for(face
= 0; face
< t
->mt
->faces
; ++face
) {
176 for(level
= t
->mt
->firstLevel
; level
<= t
->mt
->lastLevel
; ++level
)
177 teximage_set_map_data(get_radeon_texture_image(texObj
->Image
[face
][level
]));
181 void radeonUnmapTexture(GLcontext
*ctx
, struct gl_texture_object
*texObj
)
183 radeonTexObj
* t
= radeon_tex_obj(texObj
);
186 if (t
->image_override
&& t
->bo
)
187 unmap_override(ctx
, t
);
188 /* for r100 3D sw fallbacks don't have mt */
192 for(face
= 0; face
< t
->mt
->faces
; ++face
) {
193 for(level
= t
->mt
->firstLevel
; level
<= t
->mt
->lastLevel
; ++level
)
194 texObj
->Image
[face
][level
]->Data
= 0;
196 radeon_bo_unmap(t
->mt
->bo
);
199 GLuint
radeon_face_for_target(GLenum target
)
202 case GL_TEXTURE_CUBE_MAP_POSITIVE_X
:
203 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X
:
204 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y
:
205 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y
:
206 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z
:
207 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z
:
208 return (GLuint
) target
- (GLuint
) GL_TEXTURE_CUBE_MAP_POSITIVE_X
;
215 * Wraps Mesa's implementation to ensure that the base level image is mapped.
217 * This relies on internal details of _mesa_generate_mipmap, in particular
218 * the fact that the memory for recreated texture images is always freed.
220 static void radeon_generate_mipmap(GLcontext
*ctx
, GLenum target
,
221 struct gl_texture_object
*texObj
)
223 radeonTexObj
* t
= radeon_tex_obj(texObj
);
224 GLuint nr_faces
= (t
->base
.Target
== GL_TEXTURE_CUBE_MAP
) ? 6 : 1;
228 _mesa_generate_mipmap(ctx
, target
, texObj
);
230 for (face
= 0; face
< nr_faces
; face
++) {
231 for (i
= texObj
->BaseLevel
+ 1; i
< texObj
->MaxLevel
; i
++) {
232 radeon_texture_image
*image
;
234 image
= get_radeon_texture_image(texObj
->Image
[face
][i
]);
240 image
->mtface
= face
;
242 radeon_miptree_unreference(&image
->mt
);
248 void radeonGenerateMipmap(GLcontext
* ctx
, GLenum target
, struct gl_texture_object
*texObj
)
250 GLuint face
= radeon_face_for_target(target
);
251 radeon_texture_image
*baseimage
= get_radeon_texture_image(texObj
->Image
[face
][texObj
->BaseLevel
]);
253 radeon_teximage_map(baseimage
, GL_FALSE
);
254 radeon_generate_mipmap(ctx
, target
, texObj
);
255 radeon_teximage_unmap(baseimage
);
259 /* try to find a format which will only need a memcopy */
260 static gl_format
radeonChoose8888TexFormat(radeonContextPtr rmesa
,
262 GLenum srcType
, GLboolean fbo
)
265 const GLubyte littleEndian
= *((const GLubyte
*)&ui
);
267 /* r100 can only do this */
268 if (IS_R100_CLASS(rmesa
->radeonScreen
) || fbo
)
269 return _dri_texformat_argb8888
;
271 if ((srcFormat
== GL_RGBA
&& srcType
== GL_UNSIGNED_INT_8_8_8_8
) ||
272 (srcFormat
== GL_RGBA
&& srcType
== GL_UNSIGNED_BYTE
&& !littleEndian
) ||
273 (srcFormat
== GL_ABGR_EXT
&& srcType
== GL_UNSIGNED_INT_8_8_8_8_REV
) ||
274 (srcFormat
== GL_ABGR_EXT
&& srcType
== GL_UNSIGNED_BYTE
&& littleEndian
)) {
275 return MESA_FORMAT_RGBA8888
;
276 } else if ((srcFormat
== GL_RGBA
&& srcType
== GL_UNSIGNED_INT_8_8_8_8_REV
) ||
277 (srcFormat
== GL_RGBA
&& srcType
== GL_UNSIGNED_BYTE
&& littleEndian
) ||
278 (srcFormat
== GL_ABGR_EXT
&& srcType
== GL_UNSIGNED_INT_8_8_8_8
) ||
279 (srcFormat
== GL_ABGR_EXT
&& srcType
== GL_UNSIGNED_BYTE
&& !littleEndian
)) {
280 return MESA_FORMAT_RGBA8888_REV
;
281 } else if (IS_R200_CLASS(rmesa
->radeonScreen
)) {
282 return _dri_texformat_argb8888
;
283 } else if (srcFormat
== GL_BGRA
&& ((srcType
== GL_UNSIGNED_BYTE
&& !littleEndian
) ||
284 srcType
== GL_UNSIGNED_INT_8_8_8_8
)) {
285 return MESA_FORMAT_ARGB8888_REV
;
286 } else if (srcFormat
== GL_BGRA
&& ((srcType
== GL_UNSIGNED_BYTE
&& littleEndian
) ||
287 srcType
== GL_UNSIGNED_INT_8_8_8_8_REV
)) {
288 return MESA_FORMAT_ARGB8888
;
290 return _dri_texformat_argb8888
;
293 gl_format
radeonChooseTextureFormat_mesa(GLcontext
* ctx
,
294 GLint internalFormat
,
298 return radeonChooseTextureFormat(ctx
, internalFormat
, format
,
302 gl_format
radeonChooseTextureFormat(GLcontext
* ctx
,
303 GLint internalFormat
,
305 GLenum type
, GLboolean fbo
)
307 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
308 const GLboolean do32bpt
=
309 (rmesa
->texture_depth
== DRI_CONF_TEXTURE_DEPTH_32
);
310 const GLboolean force16bpt
=
311 (rmesa
->texture_depth
== DRI_CONF_TEXTURE_DEPTH_FORCE_16
);
315 fprintf(stderr
, "InternalFormat=%s(%d) type=%s format=%s\n",
316 _mesa_lookup_enum_by_nr(internalFormat
), internalFormat
,
317 _mesa_lookup_enum_by_nr(type
), _mesa_lookup_enum_by_nr(format
));
318 fprintf(stderr
, "do32bpt=%d force16bpt=%d\n", do32bpt
, force16bpt
);
321 switch (internalFormat
) {
324 case GL_COMPRESSED_RGBA
:
326 case GL_UNSIGNED_INT_10_10_10_2
:
327 case GL_UNSIGNED_INT_2_10_10_10_REV
:
328 return do32bpt
? _dri_texformat_argb8888
:
329 _dri_texformat_argb1555
;
330 case GL_UNSIGNED_SHORT_4_4_4_4
:
331 case GL_UNSIGNED_SHORT_4_4_4_4_REV
:
332 return _dri_texformat_argb4444
;
333 case GL_UNSIGNED_SHORT_5_5_5_1
:
334 case GL_UNSIGNED_SHORT_1_5_5_5_REV
:
335 return _dri_texformat_argb1555
;
337 return do32bpt
? radeonChoose8888TexFormat(rmesa
, format
, type
, fbo
) :
338 _dri_texformat_argb4444
;
343 case GL_COMPRESSED_RGB
:
345 case GL_UNSIGNED_SHORT_4_4_4_4
:
346 case GL_UNSIGNED_SHORT_4_4_4_4_REV
:
347 return _dri_texformat_argb4444
;
348 case GL_UNSIGNED_SHORT_5_5_5_1
:
349 case GL_UNSIGNED_SHORT_1_5_5_5_REV
:
350 return _dri_texformat_argb1555
;
351 case GL_UNSIGNED_SHORT_5_6_5
:
352 case GL_UNSIGNED_SHORT_5_6_5_REV
:
353 return _dri_texformat_rgb565
;
355 return do32bpt
? _dri_texformat_argb8888
:
356 _dri_texformat_rgb565
;
364 radeonChoose8888TexFormat(rmesa
, format
, type
, fbo
) :
365 _dri_texformat_argb4444
;
369 return _dri_texformat_argb4444
;
372 return _dri_texformat_argb1555
;
378 return !force16bpt
? _dri_texformat_argb8888
:
379 _dri_texformat_rgb565
;
384 return _dri_texformat_rgb565
;
391 case GL_COMPRESSED_ALPHA
:
392 /* r200: can't use a8 format since interpreting hw I8 as a8 would result
393 in wrong rgb values (same as alpha value instead of 0). */
394 if (IS_R200_CLASS(rmesa
->radeonScreen
))
395 return _dri_texformat_al88
;
397 return _dri_texformat_a8
;
404 case GL_COMPRESSED_LUMINANCE
:
405 return _dri_texformat_l8
;
408 case GL_LUMINANCE_ALPHA
:
409 case GL_LUMINANCE4_ALPHA4
:
410 case GL_LUMINANCE6_ALPHA2
:
411 case GL_LUMINANCE8_ALPHA8
:
412 case GL_LUMINANCE12_ALPHA4
:
413 case GL_LUMINANCE12_ALPHA12
:
414 case GL_LUMINANCE16_ALPHA16
:
415 case GL_COMPRESSED_LUMINANCE_ALPHA
:
416 return _dri_texformat_al88
;
423 case GL_COMPRESSED_INTENSITY
:
424 return _dri_texformat_i8
;
427 if (type
== GL_UNSIGNED_SHORT_8_8_APPLE
||
428 type
== GL_UNSIGNED_BYTE
)
429 return MESA_FORMAT_YCBCR
;
431 return MESA_FORMAT_YCBCR_REV
;
435 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT
:
436 return MESA_FORMAT_RGB_DXT1
;
438 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT
:
439 return MESA_FORMAT_RGBA_DXT1
;
443 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT
:
444 return MESA_FORMAT_RGBA_DXT3
;
446 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT
:
447 return MESA_FORMAT_RGBA_DXT5
;
449 case GL_ALPHA16F_ARB
:
450 return MESA_FORMAT_ALPHA_FLOAT16
;
451 case GL_ALPHA32F_ARB
:
452 return MESA_FORMAT_ALPHA_FLOAT32
;
453 case GL_LUMINANCE16F_ARB
:
454 return MESA_FORMAT_LUMINANCE_FLOAT16
;
455 case GL_LUMINANCE32F_ARB
:
456 return MESA_FORMAT_LUMINANCE_FLOAT32
;
457 case GL_LUMINANCE_ALPHA16F_ARB
:
458 return MESA_FORMAT_LUMINANCE_ALPHA_FLOAT16
;
459 case GL_LUMINANCE_ALPHA32F_ARB
:
460 return MESA_FORMAT_LUMINANCE_ALPHA_FLOAT32
;
461 case GL_INTENSITY16F_ARB
:
462 return MESA_FORMAT_INTENSITY_FLOAT16
;
463 case GL_INTENSITY32F_ARB
:
464 return MESA_FORMAT_INTENSITY_FLOAT32
;
466 return MESA_FORMAT_RGBA_FLOAT16
;
468 return MESA_FORMAT_RGBA_FLOAT32
;
470 return MESA_FORMAT_RGBA_FLOAT16
;
472 return MESA_FORMAT_RGBA_FLOAT32
;
474 case GL_DEPTH_COMPONENT
:
475 case GL_DEPTH_COMPONENT16
:
476 case GL_DEPTH_COMPONENT24
:
477 case GL_DEPTH_COMPONENT32
:
478 case GL_DEPTH_STENCIL_EXT
:
479 case GL_DEPTH24_STENCIL8_EXT
:
480 return MESA_FORMAT_S8_Z24
;
482 /* EXT_texture_sRGB */
486 case GL_SRGB8_ALPHA8
:
487 case GL_COMPRESSED_SRGB
:
488 case GL_COMPRESSED_SRGB_ALPHA
:
489 return MESA_FORMAT_SRGBA8
;
493 case GL_COMPRESSED_SLUMINANCE
:
494 return MESA_FORMAT_SL8
;
496 case GL_SLUMINANCE_ALPHA
:
497 case GL_SLUMINANCE8_ALPHA8
:
498 case GL_COMPRESSED_SLUMINANCE_ALPHA
:
499 return MESA_FORMAT_SLA8
;
503 "unexpected internalFormat 0x%x in %s",
504 (int)internalFormat
, __func__
);
505 return MESA_FORMAT_NONE
;
508 return MESA_FORMAT_NONE
; /* never get here */
511 static GLuint
* allocate_image_offsets(GLcontext
*ctx
,
512 unsigned alignedWidth
,
519 offsets
= _mesa_malloc(depth
* sizeof(GLuint
)) ;
521 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTex[Sub]Image");
525 for (i
= 0; i
< depth
; ++i
) {
526 offsets
[i
] = alignedWidth
* height
* i
;
533 * All glTexImage calls go through this function.
535 static void radeon_teximage(
536 GLcontext
*ctx
, int dims
,
537 GLenum target
, GLint level
,
538 GLint internalFormat
,
539 GLint width
, GLint height
, GLint depth
,
541 GLenum format
, GLenum type
, const GLvoid
* pixels
,
542 const struct gl_pixelstore_attrib
*packing
,
543 struct gl_texture_object
*texObj
,
544 struct gl_texture_image
*texImage
,
547 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
548 radeonTexObj
* t
= radeon_tex_obj(texObj
);
549 radeon_texture_image
* image
= get_radeon_texture_image(texImage
);
551 GLint postConvWidth
= width
;
552 GLint postConvHeight
= height
;
554 GLuint face
= radeon_face_for_target(target
);
557 struct radeon_bo
*bo
;
558 bo
= !image
->mt
? image
->bo
: image
->mt
->bo
;
559 if (bo
&& radeon_bo_is_referenced_by_cs(bo
, rmesa
->cmdbuf
.cs
)) {
560 radeon_firevertices(rmesa
);
564 t
->validated
= GL_FALSE
;
566 if (ctx
->_ImageTransferState
& IMAGE_CONVOLUTION_BIT
) {
567 _mesa_adjust_image_for_convolution(ctx
, dims
, &postConvWidth
,
571 if (_mesa_is_format_compressed(texImage
->TexFormat
)) {
574 texelBytes
= _mesa_get_format_bytes(texImage
->TexFormat
);
575 /* Minimum pitch of 32 bytes */
576 if (postConvWidth
* texelBytes
< 32) {
577 postConvWidth
= 32 / texelBytes
;
578 texImage
->RowStride
= postConvWidth
;
581 assert(texImage
->RowStride
== postConvWidth
);
585 /* Allocate memory for image */
586 radeonFreeTexImageData(ctx
, texImage
); /* Mesa core only clears texImage->Data but not image->mt */
589 t
->mt
->firstLevel
== level
&&
590 t
->mt
->lastLevel
== level
&&
591 t
->mt
->target
!= GL_TEXTURE_CUBE_MAP_ARB
&&
592 !radeon_miptree_matches_image(t
->mt
, texImage
, face
, level
)) {
593 radeon_miptree_unreference(&t
->mt
);
597 radeon_try_alloc_miptree(rmesa
, t
, image
, face
, level
);
598 if (t
->mt
&& radeon_miptree_matches_image(t
->mt
, texImage
, face
, level
)) {
599 radeon_mipmap_level
*lvl
;
600 image
->mtlevel
= level
- t
->mt
->firstLevel
;
601 image
->mtface
= face
;
602 radeon_miptree_reference(t
->mt
, &image
->mt
);
603 lvl
= &image
->mt
->levels
[image
->mtlevel
];
604 dstRowStride
= lvl
->rowstride
;
607 if (_mesa_is_format_compressed(texImage
->TexFormat
)) {
608 size
= _mesa_format_image_size(texImage
->TexFormat
,
613 size
= texImage
->Width
* texImage
->Height
* texImage
->Depth
* _mesa_get_format_bytes(texImage
->TexFormat
);
615 texImage
->Data
= _mesa_alloc_texmemory(size
);
618 /* Upload texture image; note that the spec allows pixels to be NULL */
620 pixels
= _mesa_validate_pbo_compressed_teximage(
621 ctx
, imageSize
, pixels
, packing
, "glCompressedTexImage");
623 pixels
= _mesa_validate_pbo_teximage(
624 ctx
, dims
, width
, height
, depth
,
625 format
, type
, pixels
, packing
, "glTexImage");
630 radeon_teximage_map(image
, GL_TRUE
);
632 uint32_t srcRowStride
, bytesPerRow
, rows
;
633 srcRowStride
= _mesa_format_row_stride(texImage
->TexFormat
, width
);
634 bytesPerRow
= srcRowStride
;
635 rows
= (height
+ 3) / 4;
636 copy_rows(texImage
->Data
, image
->mt
->levels
[level
].rowstride
,
637 pixels
, srcRowStride
, rows
, bytesPerRow
);
639 memcpy(texImage
->Data
, pixels
, imageSize
);
643 GLuint
*dstImageOffsets
;
646 radeon_mipmap_level
*lvl
= &image
->mt
->levels
[image
->mtlevel
];
647 dstRowStride
= lvl
->rowstride
;
649 dstRowStride
= texImage
->Width
* _mesa_get_format_bytes(texImage
->TexFormat
);
653 unsigned alignedWidth
= dstRowStride
/_mesa_get_format_bytes(texImage
->TexFormat
);
654 dstImageOffsets
= allocate_image_offsets(ctx
, alignedWidth
, height
, depth
);
655 if (!dstImageOffsets
) {
659 dstImageOffsets
= texImage
->ImageOffsets
;
662 radeon_teximage_map(image
, GL_TRUE
);
664 if (!_mesa_texstore(ctx
, dims
,
665 texImage
->_BaseFormat
,
667 texImage
->Data
, 0, 0, 0, /* dstX/Y/Zoffset */
670 width
, height
, depth
,
671 format
, type
, pixels
, packing
)) {
672 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage");
676 _mesa_free(dstImageOffsets
);
680 _mesa_unmap_teximage_pbo(ctx
, packing
);
683 radeon_teximage_unmap(image
);
688 void radeonTexImage1D(GLcontext
* ctx
, GLenum target
, GLint level
,
689 GLint internalFormat
,
690 GLint width
, GLint border
,
691 GLenum format
, GLenum type
, const GLvoid
* pixels
,
692 const struct gl_pixelstore_attrib
*packing
,
693 struct gl_texture_object
*texObj
,
694 struct gl_texture_image
*texImage
)
696 radeon_teximage(ctx
, 1, target
, level
, internalFormat
, width
, 1, 1,
697 0, format
, type
, pixels
, packing
, texObj
, texImage
, 0);
700 void radeonTexImage2D(GLcontext
* ctx
, GLenum target
, GLint level
,
701 GLint internalFormat
,
702 GLint width
, GLint height
, GLint border
,
703 GLenum format
, GLenum type
, const GLvoid
* pixels
,
704 const struct gl_pixelstore_attrib
*packing
,
705 struct gl_texture_object
*texObj
,
706 struct gl_texture_image
*texImage
)
709 radeon_teximage(ctx
, 2, target
, level
, internalFormat
, width
, height
, 1,
710 0, format
, type
, pixels
, packing
, texObj
, texImage
, 0);
713 void radeonCompressedTexImage2D(GLcontext
* ctx
, GLenum target
,
714 GLint level
, GLint internalFormat
,
715 GLint width
, GLint height
, GLint border
,
716 GLsizei imageSize
, const GLvoid
* data
,
717 struct gl_texture_object
*texObj
,
718 struct gl_texture_image
*texImage
)
720 radeon_teximage(ctx
, 2, target
, level
, internalFormat
, width
, height
, 1,
721 imageSize
, 0, 0, data
, &ctx
->Unpack
, texObj
, texImage
, 1);
724 void radeonTexImage3D(GLcontext
* ctx
, GLenum target
, GLint level
,
725 GLint internalFormat
,
726 GLint width
, GLint height
, GLint depth
,
728 GLenum format
, GLenum type
, const GLvoid
* pixels
,
729 const struct gl_pixelstore_attrib
*packing
,
730 struct gl_texture_object
*texObj
,
731 struct gl_texture_image
*texImage
)
733 radeon_teximage(ctx
, 3, target
, level
, internalFormat
, width
, height
, depth
,
734 0, format
, type
, pixels
, packing
, texObj
, texImage
, 0);
738 * Update a subregion of the given texture image.
740 static void radeon_texsubimage(GLcontext
* ctx
, int dims
, GLenum target
, int level
,
741 GLint xoffset
, GLint yoffset
, GLint zoffset
,
742 GLsizei width
, GLsizei height
, GLsizei depth
,
744 GLenum format
, GLenum type
,
745 const GLvoid
* pixels
,
746 const struct gl_pixelstore_attrib
*packing
,
747 struct gl_texture_object
*texObj
,
748 struct gl_texture_image
*texImage
,
751 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
752 radeonTexObj
* t
= radeon_tex_obj(texObj
);
753 radeon_texture_image
* image
= get_radeon_texture_image(texImage
);
756 struct radeon_bo
*bo
;
757 bo
= !image
->mt
? image
->bo
: image
->mt
->bo
;
758 if (bo
&& radeon_bo_is_referenced_by_cs(bo
, rmesa
->cmdbuf
.cs
)) {
759 radeon_firevertices(rmesa
);
763 t
->validated
= GL_FALSE
;
765 pixels
= _mesa_validate_pbo_compressed_teximage(
766 ctx
, imageSize
, pixels
, packing
, "glCompressedTexImage");
768 pixels
= _mesa_validate_pbo_teximage(ctx
, dims
,
769 width
, height
, depth
, format
, type
, pixels
, packing
, "glTexSubImage1D");
774 GLuint
*dstImageOffsets
;
777 radeon_mipmap_level
*lvl
= &image
->mt
->levels
[image
->mtlevel
];
778 dstRowStride
= lvl
->rowstride
;
780 dstRowStride
= texImage
->RowStride
* _mesa_get_format_bytes(texImage
->TexFormat
);
784 unsigned alignedWidth
= dstRowStride
/_mesa_get_format_bytes(texImage
->TexFormat
);
785 dstImageOffsets
= allocate_image_offsets(ctx
, alignedWidth
, height
, depth
);
786 if (!dstImageOffsets
) {
790 dstImageOffsets
= texImage
->ImageOffsets
;
793 radeon_teximage_map(image
, GL_TRUE
);
796 uint32_t srcRowStride
, bytesPerRow
, rows
;
799 dstRowStride
= _mesa_format_row_stride(texImage
->TexFormat
, texImage
->Width
);
800 img_start
= _mesa_compressed_image_address(xoffset
, yoffset
, 0,
802 texImage
->Width
, texImage
->Data
);
805 uint32_t blocks_x
= dstRowStride
/ (image
->mt
->bpp
* 4);
806 img_start
= texImage
->Data
+ image
->mt
->bpp
* 4 * (blocks_x
* (yoffset
/ 4) + xoffset
/ 4);
808 srcRowStride
= _mesa_format_row_stride(texImage
->TexFormat
, width
);
809 bytesPerRow
= srcRowStride
;
810 rows
= (height
+ 3) / 4;
812 copy_rows(img_start
, dstRowStride
, pixels
, srcRowStride
, rows
, bytesPerRow
);
816 if (!_mesa_texstore(ctx
, dims
, texImage
->_BaseFormat
,
817 texImage
->TexFormat
, texImage
->Data
,
818 xoffset
, yoffset
, zoffset
,
821 width
, height
, depth
,
822 format
, type
, pixels
, packing
)) {
823 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexSubImage");
828 _mesa_free(dstImageOffsets
);
832 radeon_teximage_unmap(image
);
834 _mesa_unmap_teximage_pbo(ctx
, packing
);
839 void radeonTexSubImage1D(GLcontext
* ctx
, GLenum target
, GLint level
,
842 GLenum format
, GLenum type
,
843 const GLvoid
* pixels
,
844 const struct gl_pixelstore_attrib
*packing
,
845 struct gl_texture_object
*texObj
,
846 struct gl_texture_image
*texImage
)
848 radeon_texsubimage(ctx
, 1, target
, level
, xoffset
, 0, 0, width
, 1, 1, 0,
849 format
, type
, pixels
, packing
, texObj
, texImage
, 0);
852 void radeonTexSubImage2D(GLcontext
* ctx
, GLenum target
, GLint level
,
853 GLint xoffset
, GLint yoffset
,
854 GLsizei width
, GLsizei height
,
855 GLenum format
, GLenum type
,
856 const GLvoid
* pixels
,
857 const struct gl_pixelstore_attrib
*packing
,
858 struct gl_texture_object
*texObj
,
859 struct gl_texture_image
*texImage
)
861 radeon_texsubimage(ctx
, 2, target
, level
, xoffset
, yoffset
, 0, width
, height
, 1,
862 0, format
, type
, pixels
, packing
, texObj
, texImage
,
866 void radeonCompressedTexSubImage2D(GLcontext
* ctx
, GLenum target
,
867 GLint level
, GLint xoffset
,
868 GLint yoffset
, GLsizei width
,
869 GLsizei height
, GLenum format
,
870 GLsizei imageSize
, const GLvoid
* data
,
871 struct gl_texture_object
*texObj
,
872 struct gl_texture_image
*texImage
)
874 radeon_texsubimage(ctx
, 2, target
, level
, xoffset
, yoffset
, 0, width
, height
, 1,
875 imageSize
, format
, 0, data
, &ctx
->Unpack
, texObj
, texImage
, 1);
879 void radeonTexSubImage3D(GLcontext
* ctx
, GLenum target
, GLint level
,
880 GLint xoffset
, GLint yoffset
, GLint zoffset
,
881 GLsizei width
, GLsizei height
, GLsizei depth
,
882 GLenum format
, GLenum type
,
883 const GLvoid
* pixels
,
884 const struct gl_pixelstore_attrib
*packing
,
885 struct gl_texture_object
*texObj
,
886 struct gl_texture_image
*texImage
)
888 radeon_texsubimage(ctx
, 3, target
, level
, xoffset
, yoffset
, zoffset
, width
, height
, depth
, 0,
889 format
, type
, pixels
, packing
, texObj
, texImage
, 0);
895 * Ensure that the given image is stored in the given miptree from now on.
897 static void migrate_image_to_miptree(radeon_mipmap_tree
*mt
, radeon_texture_image
*image
, int face
, int level
)
899 radeon_mipmap_level
*dstlvl
= &mt
->levels
[level
- mt
->firstLevel
];
902 assert(image
->mt
!= mt
);
903 assert(dstlvl
->width
== image
->base
.Width
);
904 assert(dstlvl
->height
== image
->base
.Height
);
905 assert(dstlvl
->depth
== image
->base
.Depth
);
908 radeon_bo_map(mt
->bo
, GL_TRUE
);
909 dest
= mt
->bo
->ptr
+ dstlvl
->faces
[face
].offset
;
912 /* Format etc. should match, so we really just need a memcpy().
913 * In fact, that memcpy() could be done by the hardware in many
914 * cases, provided that we have a proper memory manager.
916 radeon_mipmap_level
*srclvl
= &image
->mt
->levels
[image
->mtlevel
-image
->mt
->firstLevel
];
918 assert(srclvl
->size
== dstlvl
->size
);
919 assert(srclvl
->rowstride
== dstlvl
->rowstride
);
921 radeon_bo_map(image
->mt
->bo
, GL_FALSE
);
924 image
->mt
->bo
->ptr
+ srclvl
->faces
[face
].offset
,
926 radeon_bo_unmap(image
->mt
->bo
);
928 radeon_miptree_unreference(&image
->mt
);
930 uint32_t srcrowstride
;
932 /* need to confirm this value is correct */
933 if (mt
->compressed
) {
934 height
= (image
->base
.Height
+ 3) / 4;
935 srcrowstride
= _mesa_format_row_stride(image
->base
.TexFormat
, image
->base
.Width
);
937 height
= image
->base
.Height
* image
->base
.Depth
;
938 srcrowstride
= image
->base
.Width
* _mesa_get_format_bytes(image
->base
.TexFormat
);
942 // WARN_ONCE("%s: tiling not supported yet", __FUNCTION__);
944 copy_rows(dest
, dstlvl
->rowstride
, image
->base
.Data
, srcrowstride
,
945 height
, srcrowstride
);
947 _mesa_free_texmemory(image
->base
.Data
);
948 image
->base
.Data
= 0;
951 radeon_bo_unmap(mt
->bo
);
953 image
->mtface
= face
;
954 image
->mtlevel
= level
;
955 radeon_miptree_reference(mt
, &image
->mt
);
958 int radeon_validate_texture_miptree(GLcontext
* ctx
, struct gl_texture_object
*texObj
)
960 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
961 radeonTexObj
*t
= radeon_tex_obj(texObj
);
962 radeon_texture_image
*baseimage
= get_radeon_texture_image(texObj
->Image
[0][texObj
->BaseLevel
]);
965 if (t
->validated
|| t
->image_override
)
968 if (RADEON_DEBUG
& RADEON_TEXTURE
)
969 fprintf(stderr
, "%s: Validating texture %p now\n", __FUNCTION__
, texObj
);
971 if (baseimage
->base
.Border
> 0)
974 /* Ensure a matching miptree exists.
976 * Differing mipmap trees can result when the app uses TexImage to
977 * change texture dimensions.
979 * Prefer to use base image's miptree if it
980 * exists, since that most likely contains more valid data (remember
981 * that the base level is usually significantly larger than the rest
982 * of the miptree, so cubemaps are the only possible exception).
985 baseimage
->mt
!= t
->mt
&&
986 radeon_miptree_matches_texture(baseimage
->mt
, &t
->base
)) {
987 radeon_miptree_unreference(&t
->mt
);
988 radeon_miptree_reference(baseimage
->mt
, &t
->mt
);
989 } else if (t
->mt
&& !radeon_miptree_matches_texture(t
->mt
, &t
->base
)) {
990 radeon_miptree_unreference(&t
->mt
);
994 if (RADEON_DEBUG
& RADEON_TEXTURE
)
995 fprintf(stderr
, " Allocate new miptree\n");
996 radeon_try_alloc_miptree(rmesa
, t
, baseimage
, 0, texObj
->BaseLevel
);
998 _mesa_problem(ctx
, "radeon_validate_texture failed to alloc miptree");
1003 /* Ensure all images are stored in the single main miptree */
1004 for(face
= 0; face
< t
->mt
->faces
; ++face
) {
1005 for(level
= t
->mt
->firstLevel
; level
<= t
->mt
->lastLevel
; ++level
) {
1006 radeon_texture_image
*image
= get_radeon_texture_image(texObj
->Image
[face
][level
]);
1007 if (RADEON_DEBUG
& RADEON_TEXTURE
)
1008 fprintf(stderr
, " face %i, level %i... %p vs %p ", face
, level
, t
->mt
, image
->mt
);
1009 if (t
->mt
== image
->mt
|| (!image
->mt
&& !image
->base
.Data
)) {
1010 if (RADEON_DEBUG
& RADEON_TEXTURE
)
1011 fprintf(stderr
, "OK\n");
1016 if (RADEON_DEBUG
& RADEON_TEXTURE
)
1017 fprintf(stderr
, "migrating\n");
1018 migrate_image_to_miptree(t
->mt
, image
, face
, level
);
1027 * Need to map texture image into memory before copying image data,
1031 radeon_get_tex_image(GLcontext
* ctx
, GLenum target
, GLint level
,
1032 GLenum format
, GLenum type
, GLvoid
* pixels
,
1033 struct gl_texture_object
*texObj
,
1034 struct gl_texture_image
*texImage
, int compressed
)
1036 radeon_texture_image
*image
= get_radeon_texture_image(texImage
);
1039 /* Map the texture image read-only */
1040 radeon_teximage_map(image
, GL_FALSE
);
1042 /* Image hasn't been uploaded to a miptree yet */
1043 assert(image
->base
.Data
);
1047 /* FIXME: this can't work for small textures (mips) which
1048 use different hw stride */
1049 _mesa_get_compressed_teximage(ctx
, target
, level
, pixels
,
1052 _mesa_get_teximage(ctx
, target
, level
, format
, type
, pixels
,
1057 radeon_teximage_unmap(image
);
1062 radeonGetTexImage(GLcontext
* ctx
, GLenum target
, GLint level
,
1063 GLenum format
, GLenum type
, GLvoid
* pixels
,
1064 struct gl_texture_object
*texObj
,
1065 struct gl_texture_image
*texImage
)
1067 radeon_get_tex_image(ctx
, target
, level
, format
, type
, pixels
,
1068 texObj
, texImage
, 0);
1072 radeonGetCompressedTexImage(GLcontext
*ctx
, GLenum target
, GLint level
,
1074 struct gl_texture_object
*texObj
,
1075 struct gl_texture_image
*texImage
)
1077 radeon_get_tex_image(ctx
, target
, level
, 0, 0, pixels
,
1078 texObj
, texImage
, 1);