2 * Copyright (C) 2009 Maciej Cencora.
3 * Copyright (C) 2008 Nicolai Haehnle.
4 * Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved.
6 * The Weather Channel (TM) funded Tungsten Graphics to develop the
7 * initial release of the Radeon 8500 driver under the XFree86 license.
8 * This notice must be preserved.
10 * Permission is hereby granted, free of charge, to any person obtaining
11 * a copy of this software and associated documentation files (the
12 * "Software"), to deal in the Software without restriction, including
13 * without limitation the rights to use, copy, modify, merge, publish,
14 * distribute, sublicense, and/or sell copies of the Software, and to
15 * permit persons to whom the Software is furnished to do so, subject to
16 * the following conditions:
18 * The above copyright notice and this permission notice (including the
19 * next paragraph) shall be included in all copies or substantial
20 * portions of the Software.
22 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
23 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
25 * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
26 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
27 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
28 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
32 #include "main/glheader.h"
33 #include "main/imports.h"
34 #include "main/context.h"
35 #include "main/enums.h"
36 #include "main/mfeatures.h"
37 #include "main/mipmap.h"
39 #include "main/texcompress.h"
40 #include "main/texstore.h"
41 #include "main/teximage.h"
42 #include "main/texobj.h"
43 #include "drivers/common/meta.h"
45 #include "xmlpool.h" /* for symbolic values of enum-type options */
47 #include "radeon_common.h"
49 #include "radeon_mipmap_tree.h"
51 static void teximage_assign_miptree(radeonContextPtr rmesa
,
52 struct gl_texture_object
*texObj
,
53 struct gl_texture_image
*texImage
);
55 static radeon_mipmap_tree
*radeon_miptree_create_for_teximage(radeonContextPtr rmesa
,
56 struct gl_texture_object
*texObj
,
57 struct gl_texture_image
*texImage
);
59 void copy_rows(void* dst
, GLuint dststride
, const void* src
, GLuint srcstride
,
60 GLuint numrows
, GLuint rowsize
)
62 assert(rowsize
<= dststride
);
63 assert(rowsize
<= srcstride
);
65 radeon_print(RADEON_TEXTURE
, RADEON_TRACE
,
66 "%s dst %p, stride %u, src %p, stride %u, "
67 "numrows %u, rowsize %u.\n",
68 __func__
, dst
, dststride
,
72 if (rowsize
== srcstride
&& rowsize
== dststride
) {
73 memcpy(dst
, src
, numrows
*rowsize
);
76 for(i
= 0; i
< numrows
; ++i
) {
77 memcpy(dst
, src
, rowsize
);
86 * Allocate an empty texture image object.
88 struct gl_texture_image
*radeonNewTextureImage(struct gl_context
*ctx
)
90 return calloc(1, sizeof(radeon_texture_image
));
95 * Delete a texture image object.
98 radeonDeleteTextureImage(struct gl_context
*ctx
, struct gl_texture_image
*img
)
100 /* nothing special (yet) for radeon_texture_image */
101 _mesa_delete_texture_image(ctx
, img
);
105 radeonAllocTextureImageBuffer(struct gl_context
*ctx
,
106 struct gl_texture_image
*timage
)
108 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
109 radeon_texture_image
*image
= get_radeon_texture_image(timage
);
110 struct gl_texture_object
*texobj
= timage
->TexObject
;
113 ctx
->Driver
.FreeTextureImageBuffer(ctx
, timage
);
115 switch (texobj
->Target
) {
117 slices
= timage
->Depth
;
122 assert(!image
->base
.ImageOffsets
);
123 image
->base
.ImageOffsets
= malloc(slices
* sizeof(GLuint
));
124 teximage_assign_miptree(rmesa
, texobj
, timage
);
131 * Free memory associated with this texture image.
133 void radeonFreeTextureImageBuffer(struct gl_context
*ctx
, struct gl_texture_image
*timage
)
135 radeon_texture_image
* image
= get_radeon_texture_image(timage
);
138 radeon_miptree_unreference(&image
->mt
);
140 _swrast_free_texture_image_buffer(ctx
, timage
);
143 radeon_bo_unref(image
->bo
);
146 if (image
->base
.Buffer
) {
147 _mesa_align_free(image
->base
.Buffer
);
148 image
->base
.Buffer
= NULL
;
151 free(image
->base
.ImageOffsets
);
152 image
->base
.ImageOffsets
= NULL
;
155 /* Set Data pointer and additional data for mapped texture image */
156 static void teximage_set_map_data(radeon_texture_image
*image
)
158 radeon_mipmap_level
*lvl
;
161 radeon_warning("%s(%p) Trying to set map data without miptree.\n",
167 lvl
= &image
->mt
->levels
[image
->base
.Base
.Level
];
169 image
->base
.Map
= image
->mt
->bo
->ptr
+ lvl
->faces
[image
->base
.Base
.Face
].offset
;
170 image
->base
.RowStride
= lvl
->rowstride
/ _mesa_get_format_bytes(image
->base
.Base
.TexFormat
);
175 * Map a single texture image for glTexImage and friends.
177 void radeon_teximage_map(radeon_texture_image
*image
, GLboolean write_enable
)
179 radeon_print(RADEON_TEXTURE
, RADEON_VERBOSE
,
180 "%s(img %p), write_enable %s.\n",
182 write_enable
? "true": "false");
184 assert(!image
->base
.Map
);
186 radeon_bo_map(image
->mt
->bo
, write_enable
);
187 teximage_set_map_data(image
);
192 void radeon_teximage_unmap(radeon_texture_image
*image
)
194 radeon_print(RADEON_TEXTURE
, RADEON_VERBOSE
,
198 assert(image
->base
.Map
);
201 radeon_bo_unmap(image
->mt
->bo
);
206 * Map texture memory/buffer into user space.
207 * Note: the region of interest parameters are ignored here.
208 * \param mapOut returns start of mapping of region of interest
209 * \param rowStrideOut returns row stride in bytes
212 radeon_map_texture_image(struct gl_context
*ctx
,
213 struct gl_texture_image
*texImage
,
215 GLuint x
, GLuint y
, GLuint w
, GLuint h
,
220 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
221 radeon_texture_image
*image
= get_radeon_texture_image(texImage
);
222 radeon_mipmap_tree
*mt
= image
->mt
;
223 GLuint texel_size
= _mesa_get_format_bytes(texImage
->TexFormat
);
224 GLuint width
= texImage
->Width
;
225 GLuint height
= texImage
->Height
;
226 struct radeon_bo
*bo
= !image
->mt
? image
->bo
: image
->mt
->bo
;
228 GLboolean write
= (mode
& GL_MAP_WRITE_BIT
) != 0;
230 _mesa_get_format_block_size(texImage
->TexFormat
, &bw
, &bh
);
235 if (bo
&& radeon_bo_is_referenced_by_cs(bo
, rmesa
->cmdbuf
.cs
)) {
236 radeon_print(RADEON_TEXTURE
, RADEON_VERBOSE
,
237 "%s for texture that is "
238 "queued for GPU processing.\n",
240 radeon_firevertices(rmesa
);
245 radeon_bo_map(image
->bo
, write
);
246 *stride
= get_texture_image_row_stride(rmesa
, texImage
->TexFormat
, width
, 0, texImage
->TexObject
->Target
);
248 } else if (likely(mt
)) {
250 radeon_mipmap_level
*lvl
= &image
->mt
->levels
[texImage
->Level
];
252 radeon_bo_map(mt
->bo
, write
);
253 base
= mt
->bo
->ptr
+ lvl
->faces
[image
->base
.Base
.Face
].offset
;
255 *stride
= lvl
->rowstride
;
256 *map
= base
+ (slice
* height
) * *stride
;
258 /* texture data is in malloc'd memory */
262 *stride
= _mesa_format_row_stride(texImage
->TexFormat
, width
);
263 *map
= image
->base
.Buffer
+ (slice
* height
) * *stride
;
266 *map
+= y
* *stride
+ x
* texel_size
;
270 radeon_unmap_texture_image(struct gl_context
*ctx
,
271 struct gl_texture_image
*texImage
, GLuint slice
)
273 radeon_texture_image
*image
= get_radeon_texture_image(texImage
);
276 radeon_bo_unmap(image
->bo
);
278 radeon_bo_unmap(image
->mt
->bo
);
281 /* try to find a format which will only need a memcopy */
282 static gl_format
radeonChoose8888TexFormat(radeonContextPtr rmesa
,
284 GLenum srcType
, GLboolean fbo
)
286 #if defined(RADEON_R100)
287 /* r100 can only do this */
288 return _radeon_texformat_argb8888
;
289 #elif defined(RADEON_R200)
291 const GLubyte littleEndian
= *((const GLubyte
*)&ui
);
294 return _radeon_texformat_argb8888
;
296 if ((srcFormat
== GL_RGBA
&& srcType
== GL_UNSIGNED_INT_8_8_8_8
) ||
297 (srcFormat
== GL_RGBA
&& srcType
== GL_UNSIGNED_BYTE
&& !littleEndian
) ||
298 (srcFormat
== GL_ABGR_EXT
&& srcType
== GL_UNSIGNED_INT_8_8_8_8_REV
) ||
299 (srcFormat
== GL_ABGR_EXT
&& srcType
== GL_UNSIGNED_BYTE
&& littleEndian
)) {
300 return MESA_FORMAT_RGBA8888
;
301 } else if ((srcFormat
== GL_RGBA
&& srcType
== GL_UNSIGNED_INT_8_8_8_8_REV
) ||
302 (srcFormat
== GL_RGBA
&& srcType
== GL_UNSIGNED_BYTE
&& littleEndian
) ||
303 (srcFormat
== GL_ABGR_EXT
&& srcType
== GL_UNSIGNED_INT_8_8_8_8
) ||
304 (srcFormat
== GL_ABGR_EXT
&& srcType
== GL_UNSIGNED_BYTE
&& !littleEndian
)) {
305 return MESA_FORMAT_RGBA8888_REV
;
307 return _radeon_texformat_argb8888
;
311 gl_format
radeonChooseTextureFormat_mesa(struct gl_context
* ctx
,
313 GLint internalFormat
,
317 return radeonChooseTextureFormat(ctx
, internalFormat
, format
,
321 gl_format
radeonChooseTextureFormat(struct gl_context
* ctx
,
322 GLint internalFormat
,
324 GLenum type
, GLboolean fbo
)
326 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
327 const GLboolean do32bpt
=
328 (rmesa
->texture_depth
== DRI_CONF_TEXTURE_DEPTH_32
);
329 const GLboolean force16bpt
=
330 (rmesa
->texture_depth
== DRI_CONF_TEXTURE_DEPTH_FORCE_16
);
333 radeon_print(RADEON_TEXTURE
, RADEON_TRACE
,
334 "%s InternalFormat=%s(%d) type=%s format=%s\n",
336 _mesa_lookup_enum_by_nr(internalFormat
), internalFormat
,
337 _mesa_lookup_enum_by_nr(type
), _mesa_lookup_enum_by_nr(format
));
338 radeon_print(RADEON_TEXTURE
, RADEON_TRACE
,
339 "%s do32bpt=%d force16bpt=%d\n",
340 __func__
, do32bpt
, force16bpt
);
342 switch (internalFormat
) {
345 case GL_COMPRESSED_RGBA
:
347 case GL_UNSIGNED_INT_10_10_10_2
:
348 case GL_UNSIGNED_INT_2_10_10_10_REV
:
349 return do32bpt
? _radeon_texformat_argb8888
:
350 _radeon_texformat_argb1555
;
351 case GL_UNSIGNED_SHORT_4_4_4_4
:
352 case GL_UNSIGNED_SHORT_4_4_4_4_REV
:
353 return _radeon_texformat_argb4444
;
354 case GL_UNSIGNED_SHORT_5_5_5_1
:
355 case GL_UNSIGNED_SHORT_1_5_5_5_REV
:
356 return _radeon_texformat_argb1555
;
358 return do32bpt
? radeonChoose8888TexFormat(rmesa
, format
, type
, fbo
) :
359 _radeon_texformat_argb4444
;
364 case GL_COMPRESSED_RGB
:
366 case GL_UNSIGNED_SHORT_4_4_4_4
:
367 case GL_UNSIGNED_SHORT_4_4_4_4_REV
:
368 return _radeon_texformat_argb4444
;
369 case GL_UNSIGNED_SHORT_5_5_5_1
:
370 case GL_UNSIGNED_SHORT_1_5_5_5_REV
:
371 return _radeon_texformat_argb1555
;
372 case GL_UNSIGNED_SHORT_5_6_5
:
373 case GL_UNSIGNED_SHORT_5_6_5_REV
:
374 return _radeon_texformat_rgb565
;
376 return do32bpt
? _radeon_texformat_argb8888
:
377 _radeon_texformat_rgb565
;
385 radeonChoose8888TexFormat(rmesa
, format
, type
, fbo
) :
386 _radeon_texformat_argb4444
;
390 return _radeon_texformat_argb4444
;
393 return _radeon_texformat_argb1555
;
399 return !force16bpt
? _radeon_texformat_argb8888
:
400 _radeon_texformat_rgb565
;
405 return _radeon_texformat_rgb565
;
412 case GL_COMPRESSED_ALPHA
:
413 #if defined(RADEON_R200)
414 /* r200: can't use a8 format since interpreting hw I8 as a8 would result
415 in wrong rgb values (same as alpha value instead of 0). */
416 return _radeon_texformat_al88
;
418 return MESA_FORMAT_A8
;
426 case GL_COMPRESSED_LUMINANCE
:
427 return MESA_FORMAT_L8
;
430 case GL_LUMINANCE_ALPHA
:
431 case GL_LUMINANCE4_ALPHA4
:
432 case GL_LUMINANCE6_ALPHA2
:
433 case GL_LUMINANCE8_ALPHA8
:
434 case GL_LUMINANCE12_ALPHA4
:
435 case GL_LUMINANCE12_ALPHA12
:
436 case GL_LUMINANCE16_ALPHA16
:
437 case GL_COMPRESSED_LUMINANCE_ALPHA
:
438 return _radeon_texformat_al88
;
445 case GL_COMPRESSED_INTENSITY
:
446 return MESA_FORMAT_I8
;
449 if (type
== GL_UNSIGNED_SHORT_8_8_APPLE
||
450 type
== GL_UNSIGNED_BYTE
)
451 return MESA_FORMAT_YCBCR
;
453 return MESA_FORMAT_YCBCR_REV
;
457 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT
:
458 return MESA_FORMAT_RGB_DXT1
;
460 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT
:
461 return MESA_FORMAT_RGBA_DXT1
;
465 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT
:
466 return MESA_FORMAT_RGBA_DXT3
;
468 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT
:
469 return MESA_FORMAT_RGBA_DXT5
;
471 case GL_ALPHA16F_ARB
:
472 return MESA_FORMAT_ALPHA_FLOAT16
;
473 case GL_ALPHA32F_ARB
:
474 return MESA_FORMAT_ALPHA_FLOAT32
;
475 case GL_LUMINANCE16F_ARB
:
476 return MESA_FORMAT_LUMINANCE_FLOAT16
;
477 case GL_LUMINANCE32F_ARB
:
478 return MESA_FORMAT_LUMINANCE_FLOAT32
;
479 case GL_LUMINANCE_ALPHA16F_ARB
:
480 return MESA_FORMAT_LUMINANCE_ALPHA_FLOAT16
;
481 case GL_LUMINANCE_ALPHA32F_ARB
:
482 return MESA_FORMAT_LUMINANCE_ALPHA_FLOAT32
;
483 case GL_INTENSITY16F_ARB
:
484 return MESA_FORMAT_INTENSITY_FLOAT16
;
485 case GL_INTENSITY32F_ARB
:
486 return MESA_FORMAT_INTENSITY_FLOAT32
;
488 return MESA_FORMAT_RGBA_FLOAT16
;
490 return MESA_FORMAT_RGBA_FLOAT32
;
492 return MESA_FORMAT_RGBA_FLOAT16
;
494 return MESA_FORMAT_RGBA_FLOAT32
;
496 case GL_DEPTH_COMPONENT
:
497 case GL_DEPTH_COMPONENT16
:
498 case GL_DEPTH_COMPONENT24
:
499 case GL_DEPTH_COMPONENT32
:
500 case GL_DEPTH_STENCIL_EXT
:
501 case GL_DEPTH24_STENCIL8_EXT
:
502 return MESA_FORMAT_S8_Z24
;
504 /* EXT_texture_sRGB */
508 case GL_SRGB8_ALPHA8
:
509 case GL_COMPRESSED_SRGB
:
510 case GL_COMPRESSED_SRGB_ALPHA
:
511 return MESA_FORMAT_SARGB8
;
515 case GL_COMPRESSED_SLUMINANCE
:
516 return MESA_FORMAT_SL8
;
518 case GL_SLUMINANCE_ALPHA
:
519 case GL_SLUMINANCE8_ALPHA8
:
520 case GL_COMPRESSED_SLUMINANCE_ALPHA
:
521 return MESA_FORMAT_SLA8
;
523 case GL_COMPRESSED_SRGB_S3TC_DXT1_EXT
:
524 return MESA_FORMAT_SRGB_DXT1
;
525 case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT
:
526 return MESA_FORMAT_SRGBA_DXT1
;
527 case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT
:
528 return MESA_FORMAT_SRGBA_DXT3
;
529 case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT
:
530 return MESA_FORMAT_SRGBA_DXT5
;
534 "unexpected internalFormat 0x%x in %s",
535 (int)internalFormat
, __func__
);
536 return MESA_FORMAT_NONE
;
539 return MESA_FORMAT_NONE
; /* never get here */
542 /** Check if given image is valid within current texture object.
544 static void teximage_assign_miptree(radeonContextPtr rmesa
,
545 struct gl_texture_object
*texObj
,
546 struct gl_texture_image
*texImage
)
548 radeonTexObj
*t
= radeon_tex_obj(texObj
);
549 radeon_texture_image
* image
= get_radeon_texture_image(texImage
);
551 /* Try using current miptree, or create new if there isn't any */
552 if (!t
->mt
|| !radeon_miptree_matches_image(t
->mt
, texImage
)) {
553 radeon_miptree_unreference(&t
->mt
);
554 t
->mt
= radeon_miptree_create_for_teximage(rmesa
,
558 radeon_print(RADEON_TEXTURE
, RADEON_NORMAL
,
559 "%s: texObj %p, texImage %p, "
560 "texObj miptree doesn't match, allocated new miptree %p\n",
561 __FUNCTION__
, texObj
, texImage
, t
->mt
);
564 /* Miptree alocation may have failed,
565 * when there was no image for baselevel specified */
567 radeon_miptree_reference(t
->mt
, &image
->mt
);
569 radeon_print(RADEON_TEXTURE
, RADEON_VERBOSE
,
570 "%s Failed to allocate miptree.\n", __func__
);
573 unsigned radeonIsFormatRenderable(gl_format mesa_format
)
575 if (mesa_format
== _radeon_texformat_argb8888
|| mesa_format
== _radeon_texformat_rgb565
||
576 mesa_format
== _radeon_texformat_argb1555
|| mesa_format
== _radeon_texformat_argb4444
)
581 case MESA_FORMAT_Z16
:
582 case MESA_FORMAT_S8_Z24
:
589 void radeon_image_target_texture_2d(struct gl_context
*ctx
, GLenum target
,
590 struct gl_texture_object
*texObj
,
591 struct gl_texture_image
*texImage
,
592 GLeglImageOES image_handle
)
594 radeonContextPtr radeon
= RADEON_CONTEXT(ctx
);
595 radeonTexObj
*t
= radeon_tex_obj(texObj
);
596 radeon_texture_image
*radeonImage
= get_radeon_texture_image(texImage
);
600 screen
= radeon
->dri
.screen
;
601 image
= screen
->dri2
.image
->lookupEGLImage(screen
, image_handle
,
602 screen
->loaderPrivate
);
606 radeonFreeTextureImageBuffer(ctx
, texImage
);
608 texImage
->Width
= image
->width
;
609 texImage
->Height
= image
->height
;
611 texImage
->_BaseFormat
= GL_RGBA
;
612 texImage
->TexFormat
= image
->format
;
613 radeonImage
->base
.RowStride
= image
->pitch
;
614 texImage
->InternalFormat
= image
->internal_format
;
618 radeon_miptree_unreference(&t
->mt
);
622 /* NOTE: The following is *very* ugly and will probably break. But
623 I don't know how to deal with it, without creating a whole new
624 function like radeon_miptree_from_bo() so I'm going with the
625 easy but error-prone way. */
627 radeon_try_alloc_miptree(radeon
, t
);
629 radeon_miptree_reference(t
->mt
, &radeonImage
->mt
);
633 radeon_print(RADEON_TEXTURE
, RADEON_VERBOSE
,
634 "%s Failed to allocate miptree.\n", __func__
);
638 /* Particularly ugly: this is guaranteed to break, if image->bo is
639 not of the required size for a miptree. */
640 radeon_bo_unref(t
->mt
->bo
);
641 radeon_bo_ref(image
->bo
);
642 t
->mt
->bo
= image
->bo
;
644 if (!radeon_miptree_matches_image(t
->mt
, &radeonImage
->base
.Base
))
645 fprintf(stderr
, "miptree doesn't match image\n");
648 gl_format _radeon_texformat_rgba8888
= MESA_FORMAT_NONE
;
649 gl_format _radeon_texformat_argb8888
= MESA_FORMAT_NONE
;
650 gl_format _radeon_texformat_rgb565
= MESA_FORMAT_NONE
;
651 gl_format _radeon_texformat_argb4444
= MESA_FORMAT_NONE
;
652 gl_format _radeon_texformat_argb1555
= MESA_FORMAT_NONE
;
653 gl_format _radeon_texformat_al88
= MESA_FORMAT_NONE
;
658 radeonInitTextureFormats(void)
660 if (_mesa_little_endian()) {
661 _radeon_texformat_rgba8888
= MESA_FORMAT_RGBA8888
;
662 _radeon_texformat_argb8888
= MESA_FORMAT_ARGB8888
;
663 _radeon_texformat_rgb565
= MESA_FORMAT_RGB565
;
664 _radeon_texformat_argb4444
= MESA_FORMAT_ARGB4444
;
665 _radeon_texformat_argb1555
= MESA_FORMAT_ARGB1555
;
666 _radeon_texformat_al88
= MESA_FORMAT_AL88
;
669 _radeon_texformat_rgba8888
= MESA_FORMAT_RGBA8888_REV
;
670 _radeon_texformat_argb8888
= MESA_FORMAT_ARGB8888_REV
;
671 _radeon_texformat_rgb565
= MESA_FORMAT_RGB565_REV
;
672 _radeon_texformat_argb4444
= MESA_FORMAT_ARGB4444_REV
;
673 _radeon_texformat_argb1555
= MESA_FORMAT_ARGB1555_REV
;
674 _radeon_texformat_al88
= MESA_FORMAT_AL88_REV
;
679 radeon_init_common_texture_funcs(radeonContextPtr radeon
,
680 struct dd_function_table
*functions
)
682 functions
->NewTextureImage
= radeonNewTextureImage
;
683 functions
->DeleteTextureImage
= radeonDeleteTextureImage
;
684 functions
->AllocTextureImageBuffer
= radeonAllocTextureImageBuffer
;
685 functions
->FreeTextureImageBuffer
= radeonFreeTextureImageBuffer
;
686 functions
->MapTextureImage
= radeon_map_texture_image
;
687 functions
->UnmapTextureImage
= radeon_unmap_texture_image
;
689 functions
->ChooseTextureFormat
= radeonChooseTextureFormat_mesa
;
691 functions
->CopyTexSubImage
= radeonCopyTexSubImage
;
693 functions
->Bitmap
= _mesa_meta_Bitmap
;
694 functions
->EGLImageTargetTexture2D
= radeon_image_target_texture_2d
;
696 radeonInitTextureFormats();
700 radeon_swrast_map_image(radeonContextPtr rmesa
,
701 radeon_texture_image
*image
)
704 radeon_mipmap_tree
*mt
;
706 radeon_mipmap_level
*lvl
;
709 if (!image
|| !image
->mt
)
712 texel_size
= _mesa_get_format_bytes(image
->base
.Base
.TexFormat
);
713 level
= image
->base
.Base
.Level
;
714 face
= image
->base
.Base
.Face
;
717 lvl
= &image
->mt
->levels
[level
];
719 rs
= lvl
->rowstride
/ texel_size
;
721 radeon_bo_map(mt
->bo
, 1);
723 image
->base
.Map
= mt
->bo
->ptr
+ lvl
->faces
[face
].offset
;
724 if (mt
->target
== GL_TEXTURE_3D
) {
727 for (i
= 0; i
< mt
->levels
[level
].depth
; i
++)
728 image
->base
.ImageOffsets
[i
] = rs
* lvl
->height
* i
;
730 image
->base
.RowStride
= rs
;
734 radeon_swrast_unmap_image(radeonContextPtr rmesa
,
735 radeon_texture_image
*image
)
737 if (image
&& image
->mt
) {
738 image
->base
.Map
= NULL
;
739 radeon_bo_unmap(image
->mt
->bo
);
744 radeon_swrast_map_texture_images(struct gl_context
*ctx
,
745 struct gl_texture_object
*texObj
)
747 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
748 GLuint nr_faces
= _mesa_num_tex_faces(texObj
->Target
);
751 for (i
= texObj
->BaseLevel
; i
<= texObj
->_MaxLevel
; i
++) {
752 for (face
= 0; face
< nr_faces
; face
++) {
753 radeon_texture_image
*image
= get_radeon_texture_image(texObj
->Image
[face
][i
]);
754 radeon_swrast_map_image(rmesa
, image
);
760 radeon_swrast_unmap_texture_images(struct gl_context
*ctx
,
761 struct gl_texture_object
*texObj
)
763 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
764 GLuint nr_faces
= _mesa_num_tex_faces(texObj
->Target
);
767 for (i
= texObj
->BaseLevel
; i
<= texObj
->_MaxLevel
; i
++) {
768 for (face
= 0; face
< nr_faces
; face
++) {
769 radeon_texture_image
*image
= get_radeon_texture_image(texObj
->Image
[face
][i
]);
770 radeon_swrast_unmap_image(rmesa
, image
);
776 static radeon_mipmap_tree
*radeon_miptree_create_for_teximage(radeonContextPtr rmesa
,
777 struct gl_texture_object
*texObj
,
778 struct gl_texture_image
*texImage
)
780 radeonTexObj
*t
= radeon_tex_obj(texObj
);
783 int width
, height
, depth
;
786 width
= texImage
->Width
;
787 height
= texImage
->Height
;
788 depth
= texImage
->Depth
;
790 if (texImage
->Level
> texObj
->BaseLevel
&&
792 (texObj
->Target
!= GL_TEXTURE_1D
&& height
== 1) ||
793 (texObj
->Target
== GL_TEXTURE_3D
&& depth
== 1))) {
794 /* For this combination, we're at some lower mipmap level and
795 * some important dimension is 1. We can't extrapolate up to a
796 * likely base level width/height/depth for a full mipmap stack
797 * from this info, so just allocate this one level.
799 firstLevel
= texImage
->Level
;
800 lastLevel
= texImage
->Level
;
802 if (texImage
->Level
< texObj
->BaseLevel
)
805 firstLevel
= texObj
->BaseLevel
;
807 for (i
= texImage
->Level
; i
> firstLevel
; i
--) {
814 if ((texObj
->Sampler
.MinFilter
== GL_NEAREST
||
815 texObj
->Sampler
.MinFilter
== GL_LINEAR
) &&
816 texImage
->Level
== firstLevel
) {
817 lastLevel
= firstLevel
;
819 lastLevel
= firstLevel
+ _mesa_logbase2(MAX2(MAX2(width
, height
), depth
));
823 return radeon_miptree_create(rmesa
, texObj
->Target
,
824 texImage
->TexFormat
, firstLevel
, lastLevel
- firstLevel
+ 1,
825 width
, height
, depth
,