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(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
,
107 gl_format format
, GLsizei width
,
108 GLsizei height
, GLsizei depth
)
110 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
111 radeon_texture_image
*image
= get_radeon_texture_image(timage
);
112 struct gl_texture_object
*texobj
= timage
->TexObject
;
115 ctx
->Driver
.FreeTextureImageBuffer(ctx
, timage
);
117 switch (texobj
->Target
) {
119 slices
= timage
->Depth
;
124 assert(!image
->base
.ImageOffsets
);
125 image
->base
.ImageOffsets
= malloc(slices
* sizeof(GLuint
));
126 teximage_assign_miptree(rmesa
, texobj
, timage
);
133 * Free memory associated with this texture image.
135 void radeonFreeTextureImageBuffer(struct gl_context
*ctx
, struct gl_texture_image
*timage
)
137 radeon_texture_image
* image
= get_radeon_texture_image(timage
);
140 radeon_miptree_unreference(&image
->mt
);
142 _swrast_free_texture_image_buffer(ctx
, timage
);
145 radeon_bo_unref(image
->bo
);
148 if (image
->base
.Buffer
) {
149 _mesa_align_free(image
->base
.Buffer
);
150 image
->base
.Buffer
= NULL
;
153 if (image
->base
.ImageOffsets
) {
154 free(image
->base
.ImageOffsets
);
155 image
->base
.ImageOffsets
= NULL
;
159 /* Set Data pointer and additional data for mapped texture image */
160 static void teximage_set_map_data(radeon_texture_image
*image
)
162 radeon_mipmap_level
*lvl
;
165 radeon_warning("%s(%p) Trying to set map data without miptree.\n",
171 lvl
= &image
->mt
->levels
[image
->base
.Base
.Level
];
173 image
->base
.Map
= image
->mt
->bo
->ptr
+ lvl
->faces
[image
->base
.Base
.Face
].offset
;
174 image
->base
.RowStride
= lvl
->rowstride
/ _mesa_get_format_bytes(image
->base
.Base
.TexFormat
);
179 * Map a single texture image for glTexImage and friends.
181 void radeon_teximage_map(radeon_texture_image
*image
, GLboolean write_enable
)
183 radeon_print(RADEON_TEXTURE
, RADEON_VERBOSE
,
184 "%s(img %p), write_enable %s.\n",
186 write_enable
? "true": "false");
188 assert(!image
->base
.Map
);
190 radeon_bo_map(image
->mt
->bo
, write_enable
);
191 teximage_set_map_data(image
);
196 void radeon_teximage_unmap(radeon_texture_image
*image
)
198 radeon_print(RADEON_TEXTURE
, RADEON_VERBOSE
,
202 assert(image
->base
.Map
);
205 radeon_bo_unmap(image
->mt
->bo
);
210 * Map texture memory/buffer into user space.
211 * Note: the region of interest parameters are ignored here.
212 * \param mapOut returns start of mapping of region of interest
213 * \param rowStrideOut returns row stride in bytes
216 radeon_map_texture_image(struct gl_context
*ctx
,
217 struct gl_texture_image
*texImage
,
219 GLuint x
, GLuint y
, GLuint w
, GLuint h
,
224 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
225 radeon_texture_image
*image
= get_radeon_texture_image(texImage
);
226 radeon_mipmap_tree
*mt
= image
->mt
;
227 GLuint texel_size
= _mesa_get_format_bytes(texImage
->TexFormat
);
228 GLuint width
= texImage
->Width
;
229 GLuint height
= texImage
->Height
;
230 struct radeon_bo
*bo
= !image
->mt
? image
->bo
: image
->mt
->bo
;
232 GLboolean write
= (mode
& GL_MAP_WRITE_BIT
) != 0;
234 _mesa_get_format_block_size(texImage
->TexFormat
, &bw
, &bh
);
239 if (bo
&& radeon_bo_is_referenced_by_cs(bo
, rmesa
->cmdbuf
.cs
)) {
240 radeon_print(RADEON_TEXTURE
, RADEON_VERBOSE
,
241 "%s for texture that is "
242 "queued for GPU processing.\n",
244 radeon_firevertices(rmesa
);
249 radeon_bo_map(image
->bo
, write
);
250 *stride
= get_texture_image_row_stride(rmesa
, texImage
->TexFormat
, width
, 0, texImage
->TexObject
->Target
);
252 } else if (likely(mt
)) {
254 radeon_mipmap_level
*lvl
= &image
->mt
->levels
[texImage
->Level
];
256 radeon_bo_map(mt
->bo
, write
);
257 base
= mt
->bo
->ptr
+ lvl
->faces
[image
->base
.Base
.Face
].offset
;
259 *stride
= lvl
->rowstride
;
260 *map
= base
+ (slice
* height
) * *stride
;
262 /* texture data is in malloc'd memory */
266 *stride
= _mesa_format_row_stride(texImage
->TexFormat
, width
);
267 *map
= image
->base
.Buffer
+ (slice
* height
) * *stride
;
270 *map
+= y
* *stride
+ x
* texel_size
;
274 radeon_unmap_texture_image(struct gl_context
*ctx
,
275 struct gl_texture_image
*texImage
, GLuint slice
)
277 radeon_texture_image
*image
= get_radeon_texture_image(texImage
);
280 radeon_bo_unmap(image
->bo
);
282 radeon_bo_unmap(image
->mt
->bo
);
285 /* try to find a format which will only need a memcopy */
286 static gl_format
radeonChoose8888TexFormat(radeonContextPtr rmesa
,
288 GLenum srcType
, GLboolean fbo
)
290 #if defined(RADEON_R100)
291 /* r100 can only do this */
292 return _radeon_texformat_argb8888
;
293 #elif defined(RADEON_R200)
295 const GLubyte littleEndian
= *((const GLubyte
*)&ui
);
298 return _radeon_texformat_argb8888
;
300 if ((srcFormat
== GL_RGBA
&& srcType
== GL_UNSIGNED_INT_8_8_8_8
) ||
301 (srcFormat
== GL_RGBA
&& srcType
== GL_UNSIGNED_BYTE
&& !littleEndian
) ||
302 (srcFormat
== GL_ABGR_EXT
&& srcType
== GL_UNSIGNED_INT_8_8_8_8_REV
) ||
303 (srcFormat
== GL_ABGR_EXT
&& srcType
== GL_UNSIGNED_BYTE
&& littleEndian
)) {
304 return MESA_FORMAT_RGBA8888
;
305 } else if ((srcFormat
== GL_RGBA
&& srcType
== GL_UNSIGNED_INT_8_8_8_8_REV
) ||
306 (srcFormat
== GL_RGBA
&& srcType
== GL_UNSIGNED_BYTE
&& littleEndian
) ||
307 (srcFormat
== GL_ABGR_EXT
&& srcType
== GL_UNSIGNED_INT_8_8_8_8
) ||
308 (srcFormat
== GL_ABGR_EXT
&& srcType
== GL_UNSIGNED_BYTE
&& !littleEndian
)) {
309 return MESA_FORMAT_RGBA8888_REV
;
311 return _radeon_texformat_argb8888
;
315 gl_format
radeonChooseTextureFormat_mesa(struct gl_context
* ctx
,
316 GLint internalFormat
,
320 return radeonChooseTextureFormat(ctx
, internalFormat
, format
,
324 gl_format
radeonChooseTextureFormat(struct gl_context
* ctx
,
325 GLint internalFormat
,
327 GLenum type
, GLboolean fbo
)
329 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
330 const GLboolean do32bpt
=
331 (rmesa
->texture_depth
== DRI_CONF_TEXTURE_DEPTH_32
);
332 const GLboolean force16bpt
=
333 (rmesa
->texture_depth
== DRI_CONF_TEXTURE_DEPTH_FORCE_16
);
336 radeon_print(RADEON_TEXTURE
, RADEON_TRACE
,
337 "%s InternalFormat=%s(%d) type=%s format=%s\n",
339 _mesa_lookup_enum_by_nr(internalFormat
), internalFormat
,
340 _mesa_lookup_enum_by_nr(type
), _mesa_lookup_enum_by_nr(format
));
341 radeon_print(RADEON_TEXTURE
, RADEON_TRACE
,
342 "%s do32bpt=%d force16bpt=%d\n",
343 __func__
, do32bpt
, force16bpt
);
345 switch (internalFormat
) {
348 case GL_COMPRESSED_RGBA
:
350 case GL_UNSIGNED_INT_10_10_10_2
:
351 case GL_UNSIGNED_INT_2_10_10_10_REV
:
352 return do32bpt
? _radeon_texformat_argb8888
:
353 _radeon_texformat_argb1555
;
354 case GL_UNSIGNED_SHORT_4_4_4_4
:
355 case GL_UNSIGNED_SHORT_4_4_4_4_REV
:
356 return _radeon_texformat_argb4444
;
357 case GL_UNSIGNED_SHORT_5_5_5_1
:
358 case GL_UNSIGNED_SHORT_1_5_5_5_REV
:
359 return _radeon_texformat_argb1555
;
361 return do32bpt
? radeonChoose8888TexFormat(rmesa
, format
, type
, fbo
) :
362 _radeon_texformat_argb4444
;
367 case GL_COMPRESSED_RGB
:
369 case GL_UNSIGNED_SHORT_4_4_4_4
:
370 case GL_UNSIGNED_SHORT_4_4_4_4_REV
:
371 return _radeon_texformat_argb4444
;
372 case GL_UNSIGNED_SHORT_5_5_5_1
:
373 case GL_UNSIGNED_SHORT_1_5_5_5_REV
:
374 return _radeon_texformat_argb1555
;
375 case GL_UNSIGNED_SHORT_5_6_5
:
376 case GL_UNSIGNED_SHORT_5_6_5_REV
:
377 return _radeon_texformat_rgb565
;
379 return do32bpt
? _radeon_texformat_argb8888
:
380 _radeon_texformat_rgb565
;
388 radeonChoose8888TexFormat(rmesa
, format
, type
, fbo
) :
389 _radeon_texformat_argb4444
;
393 return _radeon_texformat_argb4444
;
396 return _radeon_texformat_argb1555
;
402 return !force16bpt
? _radeon_texformat_argb8888
:
403 _radeon_texformat_rgb565
;
408 return _radeon_texformat_rgb565
;
415 case GL_COMPRESSED_ALPHA
:
416 #if defined(RADEON_R200)
417 /* r200: can't use a8 format since interpreting hw I8 as a8 would result
418 in wrong rgb values (same as alpha value instead of 0). */
419 return _radeon_texformat_al88
;
421 return MESA_FORMAT_A8
;
429 case GL_COMPRESSED_LUMINANCE
:
430 return MESA_FORMAT_L8
;
433 case GL_LUMINANCE_ALPHA
:
434 case GL_LUMINANCE4_ALPHA4
:
435 case GL_LUMINANCE6_ALPHA2
:
436 case GL_LUMINANCE8_ALPHA8
:
437 case GL_LUMINANCE12_ALPHA4
:
438 case GL_LUMINANCE12_ALPHA12
:
439 case GL_LUMINANCE16_ALPHA16
:
440 case GL_COMPRESSED_LUMINANCE_ALPHA
:
441 return _radeon_texformat_al88
;
448 case GL_COMPRESSED_INTENSITY
:
449 return MESA_FORMAT_I8
;
452 if (type
== GL_UNSIGNED_SHORT_8_8_APPLE
||
453 type
== GL_UNSIGNED_BYTE
)
454 return MESA_FORMAT_YCBCR
;
456 return MESA_FORMAT_YCBCR_REV
;
460 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT
:
461 return MESA_FORMAT_RGB_DXT1
;
463 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT
:
464 return MESA_FORMAT_RGBA_DXT1
;
468 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT
:
469 return MESA_FORMAT_RGBA_DXT3
;
471 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT
:
472 return MESA_FORMAT_RGBA_DXT5
;
474 case GL_ALPHA16F_ARB
:
475 return MESA_FORMAT_ALPHA_FLOAT16
;
476 case GL_ALPHA32F_ARB
:
477 return MESA_FORMAT_ALPHA_FLOAT32
;
478 case GL_LUMINANCE16F_ARB
:
479 return MESA_FORMAT_LUMINANCE_FLOAT16
;
480 case GL_LUMINANCE32F_ARB
:
481 return MESA_FORMAT_LUMINANCE_FLOAT32
;
482 case GL_LUMINANCE_ALPHA16F_ARB
:
483 return MESA_FORMAT_LUMINANCE_ALPHA_FLOAT16
;
484 case GL_LUMINANCE_ALPHA32F_ARB
:
485 return MESA_FORMAT_LUMINANCE_ALPHA_FLOAT32
;
486 case GL_INTENSITY16F_ARB
:
487 return MESA_FORMAT_INTENSITY_FLOAT16
;
488 case GL_INTENSITY32F_ARB
:
489 return MESA_FORMAT_INTENSITY_FLOAT32
;
491 return MESA_FORMAT_RGBA_FLOAT16
;
493 return MESA_FORMAT_RGBA_FLOAT32
;
495 return MESA_FORMAT_RGBA_FLOAT16
;
497 return MESA_FORMAT_RGBA_FLOAT32
;
499 case GL_DEPTH_COMPONENT
:
500 case GL_DEPTH_COMPONENT16
:
501 case GL_DEPTH_COMPONENT24
:
502 case GL_DEPTH_COMPONENT32
:
503 case GL_DEPTH_STENCIL_EXT
:
504 case GL_DEPTH24_STENCIL8_EXT
:
505 return MESA_FORMAT_S8_Z24
;
507 /* EXT_texture_sRGB */
511 case GL_SRGB8_ALPHA8
:
512 case GL_COMPRESSED_SRGB
:
513 case GL_COMPRESSED_SRGB_ALPHA
:
514 return MESA_FORMAT_SARGB8
;
518 case GL_COMPRESSED_SLUMINANCE
:
519 return MESA_FORMAT_SL8
;
521 case GL_SLUMINANCE_ALPHA
:
522 case GL_SLUMINANCE8_ALPHA8
:
523 case GL_COMPRESSED_SLUMINANCE_ALPHA
:
524 return MESA_FORMAT_SLA8
;
526 case GL_COMPRESSED_SRGB_S3TC_DXT1_EXT
:
527 return MESA_FORMAT_SRGB_DXT1
;
528 case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT
:
529 return MESA_FORMAT_SRGBA_DXT1
;
530 case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT
:
531 return MESA_FORMAT_SRGBA_DXT3
;
532 case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT
:
533 return MESA_FORMAT_SRGBA_DXT5
;
537 "unexpected internalFormat 0x%x in %s",
538 (int)internalFormat
, __func__
);
539 return MESA_FORMAT_NONE
;
542 return MESA_FORMAT_NONE
; /* never get here */
545 /** Check if given image is valid within current texture object.
547 static void teximage_assign_miptree(radeonContextPtr rmesa
,
548 struct gl_texture_object
*texObj
,
549 struct gl_texture_image
*texImage
)
551 radeonTexObj
*t
= radeon_tex_obj(texObj
);
552 radeon_texture_image
* image
= get_radeon_texture_image(texImage
);
554 /* Try using current miptree, or create new if there isn't any */
555 if (!t
->mt
|| !radeon_miptree_matches_image(t
->mt
, texImage
)) {
556 radeon_miptree_unreference(&t
->mt
);
557 t
->mt
= radeon_miptree_create_for_teximage(rmesa
,
561 radeon_print(RADEON_TEXTURE
, RADEON_NORMAL
,
562 "%s: texObj %p, texImage %p, "
563 "texObj miptree doesn't match, allocated new miptree %p\n",
564 __FUNCTION__
, texObj
, texImage
, t
->mt
);
567 /* Miptree alocation may have failed,
568 * when there was no image for baselevel specified */
570 radeon_miptree_reference(t
->mt
, &image
->mt
);
572 radeon_print(RADEON_TEXTURE
, RADEON_VERBOSE
,
573 "%s Failed to allocate miptree.\n", __func__
);
577 * All glTexImage calls go through this function.
579 static void radeon_teximage(
580 struct gl_context
*ctx
, int dims
,
581 struct gl_texture_image
*texImage
,
582 GLint internalFormat
,
583 GLint width
, GLint height
, GLint depth
,
585 GLenum format
, GLenum type
, const GLvoid
* pixels
,
586 const struct gl_pixelstore_attrib
*packing
,
589 _mesa_store_teximage(ctx
, dims
, texImage
, internalFormat
,
590 width
, height
, depth
, 0,
591 format
, type
, pixels
,
596 radeonTexImage(struct gl_context
* ctx
, GLuint dims
,
597 struct gl_texture_image
*texImage
,
598 GLint internalFormat
,
599 GLint width
, GLint height
, GLint depth
,
601 GLenum format
, GLenum type
, const GLvoid
* pixels
,
602 const struct gl_pixelstore_attrib
*packing
)
604 radeon_teximage(ctx
, dims
, texImage
, internalFormat
, width
, height
, depth
,
605 0, format
, type
, pixels
, packing
, 0);
608 unsigned radeonIsFormatRenderable(gl_format mesa_format
)
610 if (mesa_format
== _radeon_texformat_argb8888
|| mesa_format
== _radeon_texformat_rgb565
||
611 mesa_format
== _radeon_texformat_argb1555
|| mesa_format
== _radeon_texformat_argb4444
)
616 case MESA_FORMAT_Z16
:
617 case MESA_FORMAT_S8_Z24
:
624 #if FEATURE_OES_EGL_image
625 void radeon_image_target_texture_2d(struct gl_context
*ctx
, GLenum target
,
626 struct gl_texture_object
*texObj
,
627 struct gl_texture_image
*texImage
,
628 GLeglImageOES image_handle
)
630 radeonContextPtr radeon
= RADEON_CONTEXT(ctx
);
631 radeonTexObj
*t
= radeon_tex_obj(texObj
);
632 radeon_texture_image
*radeonImage
= get_radeon_texture_image(texImage
);
636 screen
= radeon
->dri
.screen
;
637 image
= screen
->dri2
.image
->lookupEGLImage(screen
, image_handle
,
638 screen
->loaderPrivate
);
642 radeonFreeTextureImageBuffer(ctx
, texImage
);
644 texImage
->Width
= image
->width
;
645 texImage
->Height
= image
->height
;
647 texImage
->_BaseFormat
= GL_RGBA
;
648 texImage
->TexFormat
= image
->format
;
649 radeonImage
->base
.RowStride
= image
->pitch
;
650 texImage
->InternalFormat
= image
->internal_format
;
654 radeon_miptree_unreference(&t
->mt
);
658 /* NOTE: The following is *very* ugly and will probably break. But
659 I don't know how to deal with it, without creating a whole new
660 function like radeon_miptree_from_bo() so I'm going with the
661 easy but error-prone way. */
663 radeon_try_alloc_miptree(radeon
, t
);
665 radeon_miptree_reference(t
->mt
, &radeonImage
->mt
);
669 radeon_print(RADEON_TEXTURE
, RADEON_VERBOSE
,
670 "%s Failed to allocate miptree.\n", __func__
);
674 /* Particularly ugly: this is guaranteed to break, if image->bo is
675 not of the required size for a miptree. */
676 radeon_bo_unref(t
->mt
->bo
);
677 radeon_bo_ref(image
->bo
);
678 t
->mt
->bo
= image
->bo
;
680 if (!radeon_miptree_matches_image(t
->mt
, &radeonImage
->base
.Base
))
681 fprintf(stderr
, "miptree doesn't match image\n");
685 gl_format _radeon_texformat_rgba8888
= MESA_FORMAT_NONE
;
686 gl_format _radeon_texformat_argb8888
= MESA_FORMAT_NONE
;
687 gl_format _radeon_texformat_rgb565
= MESA_FORMAT_NONE
;
688 gl_format _radeon_texformat_argb4444
= MESA_FORMAT_NONE
;
689 gl_format _radeon_texformat_argb1555
= MESA_FORMAT_NONE
;
690 gl_format _radeon_texformat_al88
= MESA_FORMAT_NONE
;
695 radeonInitTextureFormats(void)
697 if (_mesa_little_endian()) {
698 _radeon_texformat_rgba8888
= MESA_FORMAT_RGBA8888
;
699 _radeon_texformat_argb8888
= MESA_FORMAT_ARGB8888
;
700 _radeon_texformat_rgb565
= MESA_FORMAT_RGB565
;
701 _radeon_texformat_argb4444
= MESA_FORMAT_ARGB4444
;
702 _radeon_texformat_argb1555
= MESA_FORMAT_ARGB1555
;
703 _radeon_texformat_al88
= MESA_FORMAT_AL88
;
706 _radeon_texformat_rgba8888
= MESA_FORMAT_RGBA8888_REV
;
707 _radeon_texformat_argb8888
= MESA_FORMAT_ARGB8888_REV
;
708 _radeon_texformat_rgb565
= MESA_FORMAT_RGB565_REV
;
709 _radeon_texformat_argb4444
= MESA_FORMAT_ARGB4444_REV
;
710 _radeon_texformat_argb1555
= MESA_FORMAT_ARGB1555_REV
;
711 _radeon_texformat_al88
= MESA_FORMAT_AL88_REV
;
716 radeon_init_common_texture_funcs(radeonContextPtr radeon
,
717 struct dd_function_table
*functions
)
719 functions
->NewTextureImage
= radeonNewTextureImage
;
720 functions
->DeleteTextureImage
= radeonDeleteTextureImage
;
721 functions
->AllocTextureImageBuffer
= radeonAllocTextureImageBuffer
;
722 functions
->FreeTextureImageBuffer
= radeonFreeTextureImageBuffer
;
723 functions
->MapTextureImage
= radeon_map_texture_image
;
724 functions
->UnmapTextureImage
= radeon_unmap_texture_image
;
726 functions
->ChooseTextureFormat
= radeonChooseTextureFormat_mesa
;
728 functions
->TexImage
= radeonTexImage
;
730 functions
->CopyTexSubImage
= radeonCopyTexSubImage
;
732 functions
->Bitmap
= _mesa_meta_Bitmap
;
733 #if FEATURE_OES_EGL_image
734 functions
->EGLImageTargetTexture2D
= radeon_image_target_texture_2d
;
737 radeonInitTextureFormats();
741 radeon_swrast_map_image(radeonContextPtr rmesa
,
742 radeon_texture_image
*image
)
745 radeon_mipmap_tree
*mt
;
747 radeon_mipmap_level
*lvl
;
750 if (!image
|| !image
->mt
)
753 texel_size
= _mesa_get_format_bytes(image
->base
.Base
.TexFormat
);
754 level
= image
->base
.Base
.Level
;
755 face
= image
->base
.Base
.Face
;
758 lvl
= &image
->mt
->levels
[level
];
760 rs
= lvl
->rowstride
/ texel_size
;
762 radeon_bo_map(mt
->bo
, 1);
764 image
->base
.Map
= mt
->bo
->ptr
+ lvl
->faces
[face
].offset
;
765 if (mt
->target
== GL_TEXTURE_3D
) {
768 for (i
= 0; i
< mt
->levels
[level
].depth
; i
++)
769 image
->base
.ImageOffsets
[i
] = rs
* lvl
->height
* i
;
771 image
->base
.RowStride
= rs
;
775 radeon_swrast_unmap_image(radeonContextPtr rmesa
,
776 radeon_texture_image
*image
)
778 if (image
&& image
->mt
) {
779 image
->base
.Map
= NULL
;
780 radeon_bo_unmap(image
->mt
->bo
);
785 radeon_swrast_map_texture_images(struct gl_context
*ctx
,
786 struct gl_texture_object
*texObj
)
788 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
789 GLuint nr_faces
= (texObj
->Target
== GL_TEXTURE_CUBE_MAP
) ? 6 : 1;
792 for (i
= texObj
->BaseLevel
; i
<= texObj
->_MaxLevel
; i
++) {
793 for (face
= 0; face
< nr_faces
; face
++) {
794 radeon_texture_image
*image
= get_radeon_texture_image(texObj
->Image
[face
][i
]);
795 radeon_swrast_map_image(rmesa
, image
);
801 radeon_swrast_unmap_texture_images(struct gl_context
*ctx
,
802 struct gl_texture_object
*texObj
)
804 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
805 GLuint nr_faces
= (texObj
->Target
== GL_TEXTURE_CUBE_MAP
) ? 6 : 1;
808 for (i
= texObj
->BaseLevel
; i
<= texObj
->_MaxLevel
; i
++) {
809 for (face
= 0; face
< nr_faces
; face
++) {
810 radeon_texture_image
*image
= get_radeon_texture_image(texObj
->Image
[face
][i
]);
811 radeon_swrast_unmap_image(rmesa
, image
);
817 static radeon_mipmap_tree
*radeon_miptree_create_for_teximage(radeonContextPtr rmesa
,
818 struct gl_texture_object
*texObj
,
819 struct gl_texture_image
*texImage
)
821 radeonTexObj
*t
= radeon_tex_obj(texObj
);
824 int width
, height
, depth
;
827 width
= texImage
->Width
;
828 height
= texImage
->Height
;
829 depth
= texImage
->Depth
;
831 if (texImage
->Level
> texObj
->BaseLevel
&&
833 (texObj
->Target
!= GL_TEXTURE_1D
&& height
== 1) ||
834 (texObj
->Target
== GL_TEXTURE_3D
&& depth
== 1))) {
835 /* For this combination, we're at some lower mipmap level and
836 * some important dimension is 1. We can't extrapolate up to a
837 * likely base level width/height/depth for a full mipmap stack
838 * from this info, so just allocate this one level.
840 firstLevel
= texImage
->Level
;
841 lastLevel
= texImage
->Level
;
843 if (texImage
->Level
< texObj
->BaseLevel
)
846 firstLevel
= texObj
->BaseLevel
;
848 for (i
= texImage
->Level
; i
> firstLevel
; i
--) {
855 if ((texObj
->Sampler
.MinFilter
== GL_NEAREST
||
856 texObj
->Sampler
.MinFilter
== GL_LINEAR
) &&
857 texImage
->Level
== firstLevel
) {
858 lastLevel
= firstLevel
;
860 lastLevel
= firstLevel
+ _mesa_logbase2(MAX2(MAX2(width
, height
), depth
));
864 return radeon_miptree_create(rmesa
, texObj
->Target
,
865 texImage
->TexFormat
, firstLevel
, lastLevel
- firstLevel
+ 1,
866 width
, height
, depth
,