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/context.h"
34 #include "main/enums.h"
35 #include "main/mipmap.h"
37 #include "main/texcompress.h"
38 #include "main/texstore.h"
39 #include "main/teximage.h"
40 #include "main/texobj.h"
41 #include "drivers/common/meta.h"
43 #include "util/driconf.h" /* for symbolic values of enum-type options */
45 #include "radeon_common.h"
47 #include "radeon_mipmap_tree.h"
49 static void teximage_assign_miptree(radeonContextPtr rmesa
,
50 struct gl_texture_object
*texObj
,
51 struct gl_texture_image
*texImage
);
53 static radeon_mipmap_tree
*radeon_miptree_create_for_teximage(radeonContextPtr rmesa
,
54 struct gl_texture_object
*texObj
,
55 struct gl_texture_image
*texImage
);
57 void copy_rows(void* dst
, GLuint dststride
, const void* src
, GLuint srcstride
,
58 GLuint numrows
, GLuint rowsize
)
60 assert(rowsize
<= dststride
);
61 assert(rowsize
<= srcstride
);
63 radeon_print(RADEON_TEXTURE
, RADEON_TRACE
,
64 "%s dst %p, stride %u, src %p, stride %u, "
65 "numrows %u, rowsize %u.\n",
66 __func__
, dst
, dststride
,
70 if (rowsize
== srcstride
&& rowsize
== dststride
) {
71 memcpy(dst
, src
, numrows
*rowsize
);
74 for(i
= 0; i
< numrows
; ++i
) {
75 memcpy(dst
, src
, rowsize
);
84 * Allocate an empty texture image object.
86 struct gl_texture_image
*radeonNewTextureImage(struct gl_context
*ctx
)
88 return calloc(1, sizeof(radeon_texture_image
));
93 * Delete a texture image object.
96 radeonDeleteTextureImage(struct gl_context
*ctx
, struct gl_texture_image
*img
)
98 /* nothing special (yet) for radeon_texture_image */
99 _mesa_delete_texture_image(ctx
, img
);
103 radeonAllocTextureImageBuffer(struct gl_context
*ctx
,
104 struct gl_texture_image
*timage
)
106 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
107 struct gl_texture_object
*texobj
= timage
->TexObject
;
109 ctx
->Driver
.FreeTextureImageBuffer(ctx
, timage
);
111 if (!_swrast_init_texture_image(timage
))
114 teximage_assign_miptree(rmesa
, texobj
, timage
);
121 * Free memory associated with this texture image.
123 void radeonFreeTextureImageBuffer(struct gl_context
*ctx
, struct gl_texture_image
*timage
)
125 radeon_texture_image
* image
= get_radeon_texture_image(timage
);
128 radeon_miptree_unreference(&image
->mt
);
131 radeon_bo_unref(image
->bo
);
135 _swrast_free_texture_image_buffer(ctx
, timage
);
139 * Map texture memory/buffer into user space.
140 * Note: the region of interest parameters are ignored here.
141 * \param mapOut returns start of mapping of region of interest
142 * \param rowStrideOut returns row stride in bytes
145 radeon_map_texture_image(struct gl_context
*ctx
,
146 struct gl_texture_image
*texImage
,
148 GLuint x
, GLuint y
, GLuint w
, GLuint h
,
153 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
154 radeon_texture_image
*image
= get_radeon_texture_image(texImage
);
155 radeon_mipmap_tree
*mt
= image
->mt
;
156 GLuint texel_size
= _mesa_get_format_bytes(texImage
->TexFormat
);
157 GLuint width
= texImage
->Width
;
158 GLuint height
= texImage
->Height
;
159 struct radeon_bo
*bo
= !image
->mt
? image
->bo
: image
->mt
->bo
;
161 GLboolean write
= (mode
& GL_MAP_WRITE_BIT
) != 0;
163 _mesa_get_format_block_size(texImage
->TexFormat
, &bw
, &bh
);
168 if (bo
&& radeon_bo_is_referenced_by_cs(bo
, rmesa
->cmdbuf
.cs
)) {
169 radeon_print(RADEON_TEXTURE
, RADEON_VERBOSE
,
170 "%s for texture that is "
171 "queued for GPU processing.\n",
173 radeon_firevertices(rmesa
);
178 radeon_bo_map(image
->bo
, write
);
179 *stride
= get_texture_image_row_stride(rmesa
, texImage
->TexFormat
, width
, 0, texImage
->TexObject
->Target
);
181 } else if (likely(mt
)) {
183 radeon_mipmap_level
*lvl
= &image
->mt
->levels
[texImage
->Level
];
185 radeon_bo_map(mt
->bo
, write
);
186 base
= mt
->bo
->ptr
+ lvl
->faces
[image
->base
.Base
.Face
].offset
;
188 *stride
= lvl
->rowstride
;
189 *map
= base
+ (slice
* height
) * *stride
;
191 /* texture data is in malloc'd memory */
195 *stride
= _mesa_format_row_stride(texImage
->TexFormat
, width
);
196 *map
= image
->base
.Buffer
+ (slice
* height
) * *stride
;
199 *map
+= y
* *stride
+ x
* texel_size
;
203 radeon_unmap_texture_image(struct gl_context
*ctx
,
204 struct gl_texture_image
*texImage
, GLuint slice
)
206 radeon_texture_image
*image
= get_radeon_texture_image(texImage
);
209 radeon_bo_unmap(image
->bo
);
211 radeon_bo_unmap(image
->mt
->bo
);
214 /* try to find a format which will only need a memcopy */
215 static mesa_format
radeonChoose8888TexFormat(radeonContextPtr rmesa
,
217 GLenum srcType
, GLboolean fbo
)
219 #if defined(RADEON_R100)
220 /* r100 can only do this */
221 return _radeon_texformat_argb8888
;
222 #elif defined(RADEON_R200)
224 const GLubyte littleEndian
= *((const GLubyte
*)&ui
);
227 /* Unfortunately, regardless the fbo flag, we might still be asked to
228 * attach a texture to a fbo later, which then won't succeed if we chose
229 * one which isn't renderable. And unlike more exotic formats, apps aren't
230 * really prepared for the incomplete framebuffer this results in (they'd
231 * have to retry with same internalFormat even, just different
232 * srcFormat/srcType, which can't really be expected anyway).
233 * Ideally, we'd defer format selection until later (if the texture is
234 * used as a rt it's likely there's never data uploaded to it before attached
235 * to a fbo), but this isn't really possible, so for now just always use
236 * a renderable format.
239 return _radeon_texformat_argb8888
;
241 if ((srcFormat
== GL_RGBA
&& srcType
== GL_UNSIGNED_INT_8_8_8_8
) ||
242 (srcFormat
== GL_RGBA
&& srcType
== GL_UNSIGNED_BYTE
&& !littleEndian
) ||
243 (srcFormat
== GL_ABGR_EXT
&& srcType
== GL_UNSIGNED_INT_8_8_8_8_REV
) ||
244 (srcFormat
== GL_ABGR_EXT
&& srcType
== GL_UNSIGNED_BYTE
&& littleEndian
)) {
245 return MESA_FORMAT_A8B8G8R8_UNORM
;
246 } else if ((srcFormat
== GL_RGBA
&& srcType
== GL_UNSIGNED_INT_8_8_8_8_REV
) ||
247 (srcFormat
== GL_RGBA
&& srcType
== GL_UNSIGNED_BYTE
&& littleEndian
) ||
248 (srcFormat
== GL_ABGR_EXT
&& srcType
== GL_UNSIGNED_INT_8_8_8_8
) ||
249 (srcFormat
== GL_ABGR_EXT
&& srcType
== GL_UNSIGNED_BYTE
&& !littleEndian
)) {
250 return MESA_FORMAT_R8G8B8A8_UNORM
;
252 return _radeon_texformat_argb8888
;
256 mesa_format
radeonChooseTextureFormat_mesa(struct gl_context
* ctx
,
258 GLint internalFormat
,
262 return radeonChooseTextureFormat(ctx
, internalFormat
, format
,
266 mesa_format
radeonChooseTextureFormat(struct gl_context
* ctx
,
267 GLint internalFormat
,
269 GLenum type
, GLboolean fbo
)
271 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
272 const GLboolean do32bpt
=
273 (rmesa
->texture_depth
== DRI_CONF_TEXTURE_DEPTH_32
);
274 const GLboolean force16bpt
=
275 (rmesa
->texture_depth
== DRI_CONF_TEXTURE_DEPTH_FORCE_16
);
278 radeon_print(RADEON_TEXTURE
, RADEON_TRACE
,
279 "%s InternalFormat=%s(%d) type=%s format=%s\n",
281 _mesa_enum_to_string(internalFormat
), internalFormat
,
282 _mesa_enum_to_string(type
), _mesa_enum_to_string(format
));
283 radeon_print(RADEON_TEXTURE
, RADEON_TRACE
,
284 "%s do32bpt=%d force16bpt=%d\n",
285 __func__
, do32bpt
, force16bpt
);
287 switch (internalFormat
) {
290 case GL_COMPRESSED_RGBA
:
292 case GL_UNSIGNED_INT_10_10_10_2
:
293 case GL_UNSIGNED_INT_2_10_10_10_REV
:
294 return do32bpt
? _radeon_texformat_argb8888
:
295 _radeon_texformat_argb1555
;
296 case GL_UNSIGNED_SHORT_4_4_4_4
:
297 case GL_UNSIGNED_SHORT_4_4_4_4_REV
:
298 return _radeon_texformat_argb4444
;
299 case GL_UNSIGNED_SHORT_5_5_5_1
:
300 case GL_UNSIGNED_SHORT_1_5_5_5_REV
:
301 return _radeon_texformat_argb1555
;
303 return do32bpt
? radeonChoose8888TexFormat(rmesa
, format
, type
, fbo
) :
304 _radeon_texformat_argb4444
;
309 case GL_COMPRESSED_RGB
:
311 case GL_UNSIGNED_SHORT_4_4_4_4
:
312 case GL_UNSIGNED_SHORT_4_4_4_4_REV
:
313 return _radeon_texformat_argb4444
;
314 case GL_UNSIGNED_SHORT_5_5_5_1
:
315 case GL_UNSIGNED_SHORT_1_5_5_5_REV
:
316 return _radeon_texformat_argb1555
;
317 case GL_UNSIGNED_SHORT_5_6_5
:
318 case GL_UNSIGNED_SHORT_5_6_5_REV
:
319 return _radeon_texformat_rgb565
;
321 return do32bpt
? _radeon_texformat_argb8888
:
322 _radeon_texformat_rgb565
;
330 radeonChoose8888TexFormat(rmesa
, format
, type
, fbo
) :
331 _radeon_texformat_argb4444
;
335 return _radeon_texformat_argb4444
;
338 return _radeon_texformat_argb1555
;
344 return !force16bpt
? _radeon_texformat_argb8888
:
345 _radeon_texformat_rgb565
;
350 return _radeon_texformat_rgb565
;
357 case GL_COMPRESSED_ALPHA
:
358 #if defined(RADEON_R200)
359 /* r200: can't use a8 format since interpreting hw I8 as a8 would result
360 in wrong rgb values (same as alpha value instead of 0). */
361 return MESA_FORMAT_LA_UNORM8
;
363 return MESA_FORMAT_A_UNORM8
;
371 case GL_COMPRESSED_LUMINANCE
:
372 return MESA_FORMAT_L_UNORM8
;
375 case GL_LUMINANCE_ALPHA
:
376 case GL_LUMINANCE4_ALPHA4
:
377 case GL_LUMINANCE6_ALPHA2
:
378 case GL_LUMINANCE8_ALPHA8
:
379 case GL_LUMINANCE12_ALPHA4
:
380 case GL_LUMINANCE12_ALPHA12
:
381 case GL_LUMINANCE16_ALPHA16
:
382 case GL_COMPRESSED_LUMINANCE_ALPHA
:
383 return MESA_FORMAT_LA_UNORM8
;
390 case GL_COMPRESSED_INTENSITY
:
391 return MESA_FORMAT_I_UNORM8
;
394 if (type
== GL_UNSIGNED_SHORT_8_8_APPLE
||
395 type
== GL_UNSIGNED_BYTE
)
396 return MESA_FORMAT_YCBCR
;
398 return MESA_FORMAT_YCBCR_REV
;
402 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT
:
403 return MESA_FORMAT_RGB_DXT1
;
405 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT
:
406 return MESA_FORMAT_RGBA_DXT1
;
410 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT
:
411 return MESA_FORMAT_RGBA_DXT3
;
413 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT
:
414 return MESA_FORMAT_RGBA_DXT5
;
416 case GL_ALPHA16F_ARB
:
417 return MESA_FORMAT_A_FLOAT16
;
418 case GL_ALPHA32F_ARB
:
419 return MESA_FORMAT_A_FLOAT32
;
420 case GL_LUMINANCE16F_ARB
:
421 return MESA_FORMAT_L_FLOAT16
;
422 case GL_LUMINANCE32F_ARB
:
423 return MESA_FORMAT_L_FLOAT32
;
424 case GL_LUMINANCE_ALPHA16F_ARB
:
425 return MESA_FORMAT_LA_FLOAT16
;
426 case GL_LUMINANCE_ALPHA32F_ARB
:
427 return MESA_FORMAT_LA_FLOAT32
;
428 case GL_INTENSITY16F_ARB
:
429 return MESA_FORMAT_I_FLOAT16
;
430 case GL_INTENSITY32F_ARB
:
431 return MESA_FORMAT_I_FLOAT32
;
433 return MESA_FORMAT_RGBA_FLOAT16
;
435 return MESA_FORMAT_RGBA_FLOAT32
;
437 return MESA_FORMAT_RGBA_FLOAT16
;
439 return MESA_FORMAT_RGBA_FLOAT32
;
441 case GL_DEPTH_COMPONENT
:
442 case GL_DEPTH_COMPONENT16
:
443 case GL_DEPTH_COMPONENT24
:
444 case GL_DEPTH_COMPONENT32
:
445 case GL_DEPTH_STENCIL_EXT
:
446 case GL_DEPTH24_STENCIL8_EXT
:
447 return MESA_FORMAT_Z24_UNORM_S8_UINT
;
449 /* EXT_texture_sRGB */
453 case GL_SRGB8_ALPHA8
:
454 case GL_COMPRESSED_SRGB
:
455 case GL_COMPRESSED_SRGB_ALPHA
:
456 return MESA_FORMAT_B8G8R8A8_SRGB
;
460 case GL_COMPRESSED_SLUMINANCE
:
461 return MESA_FORMAT_L_SRGB8
;
463 case GL_SLUMINANCE_ALPHA
:
464 case GL_SLUMINANCE8_ALPHA8
:
465 case GL_COMPRESSED_SLUMINANCE_ALPHA
:
466 return MESA_FORMAT_LA_SRGB8
;
468 case GL_COMPRESSED_SRGB_S3TC_DXT1_EXT
:
469 return MESA_FORMAT_SRGB_DXT1
;
470 case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT
:
471 return MESA_FORMAT_SRGBA_DXT1
;
472 case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT
:
473 return MESA_FORMAT_SRGBA_DXT3
;
474 case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT
:
475 return MESA_FORMAT_SRGBA_DXT5
;
479 "unexpected internalFormat 0x%x in %s",
480 (int)internalFormat
, __func__
);
481 return MESA_FORMAT_NONE
;
484 return MESA_FORMAT_NONE
; /* never get here */
487 /** Check if given image is valid within current texture object.
489 static void teximage_assign_miptree(radeonContextPtr rmesa
,
490 struct gl_texture_object
*texObj
,
491 struct gl_texture_image
*texImage
)
493 radeonTexObj
*t
= radeon_tex_obj(texObj
);
494 radeon_texture_image
* image
= get_radeon_texture_image(texImage
);
496 /* Try using current miptree, or create new if there isn't any */
497 if (!t
->mt
|| !radeon_miptree_matches_image(t
->mt
, texImage
)) {
498 radeon_miptree_unreference(&t
->mt
);
499 t
->mt
= radeon_miptree_create_for_teximage(rmesa
,
503 radeon_print(RADEON_TEXTURE
, RADEON_NORMAL
,
504 "%s: texObj %p, texImage %p, "
505 "texObj miptree doesn't match, allocated new miptree %p\n",
506 __func__
, texObj
, texImage
, t
->mt
);
509 /* Miptree alocation may have failed,
510 * when there was no image for baselevel specified */
512 radeon_miptree_reference(t
->mt
, &image
->mt
);
514 radeon_print(RADEON_TEXTURE
, RADEON_VERBOSE
,
515 "%s Failed to allocate miptree.\n", __func__
);
518 unsigned radeonIsFormatRenderable(mesa_format mesa_format
)
520 if (mesa_format
== _radeon_texformat_argb8888
|| mesa_format
== _radeon_texformat_rgb565
||
521 mesa_format
== _radeon_texformat_argb1555
|| mesa_format
== _radeon_texformat_argb4444
)
526 case MESA_FORMAT_Z_UNORM16
:
527 case MESA_FORMAT_Z24_UNORM_S8_UINT
:
534 void radeon_image_target_texture_2d(struct gl_context
*ctx
, GLenum target
,
535 struct gl_texture_object
*texObj
,
536 struct gl_texture_image
*texImage
,
537 GLeglImageOES image_handle
)
539 radeonContextPtr radeon
= RADEON_CONTEXT(ctx
);
540 radeonTexObj
*t
= radeon_tex_obj(texObj
);
541 radeon_texture_image
*radeonImage
= get_radeon_texture_image(texImage
);
545 screen
= radeon
->radeonScreen
->driScreen
;
546 image
= screen
->dri2
.image
->lookupEGLImage(screen
, image_handle
,
547 screen
->loaderPrivate
);
551 radeonFreeTextureImageBuffer(ctx
, texImage
);
553 texImage
->Width
= image
->width
;
554 texImage
->Height
= image
->height
;
556 texImage
->_BaseFormat
= GL_RGBA
;
557 texImage
->TexFormat
= image
->format
;
558 radeonImage
->base
.RowStride
= image
->pitch
;
559 texImage
->InternalFormat
= image
->internal_format
;
563 radeon_miptree_unreference(&t
->mt
);
567 /* NOTE: The following is *very* ugly and will probably break. But
568 I don't know how to deal with it, without creating a whole new
569 function like radeon_miptree_from_bo() so I'm going with the
570 easy but error-prone way. */
572 radeon_try_alloc_miptree(radeon
, t
);
574 radeon_miptree_reference(t
->mt
, &radeonImage
->mt
);
578 radeon_print(RADEON_TEXTURE
, RADEON_VERBOSE
,
579 "%s Failed to allocate miptree.\n", __func__
);
583 /* Particularly ugly: this is guaranteed to break, if image->bo is
584 not of the required size for a miptree. */
585 radeon_bo_unref(t
->mt
->bo
);
586 radeon_bo_ref(image
->bo
);
587 t
->mt
->bo
= image
->bo
;
589 if (!radeon_miptree_matches_image(t
->mt
, &radeonImage
->base
.Base
))
590 fprintf(stderr
, "miptree doesn't match image\n");
593 mesa_format _radeon_texformat_rgba8888
= MESA_FORMAT_NONE
;
594 mesa_format _radeon_texformat_argb8888
= MESA_FORMAT_NONE
;
595 mesa_format _radeon_texformat_rgb565
= MESA_FORMAT_NONE
;
596 mesa_format _radeon_texformat_argb4444
= MESA_FORMAT_NONE
;
597 mesa_format _radeon_texformat_argb1555
= MESA_FORMAT_NONE
;
602 radeonInitTextureFormats(void)
604 #if UTIL_ARCH_LITTLE_ENDIAN
605 _radeon_texformat_rgba8888
= MESA_FORMAT_A8B8G8R8_UNORM
;
606 _radeon_texformat_argb8888
= MESA_FORMAT_B8G8R8A8_UNORM
;
607 _radeon_texformat_rgb565
= MESA_FORMAT_B5G6R5_UNORM
;
608 _radeon_texformat_argb4444
= MESA_FORMAT_B4G4R4A4_UNORM
;
609 _radeon_texformat_argb1555
= MESA_FORMAT_B5G5R5A1_UNORM
;
611 _radeon_texformat_rgba8888
= MESA_FORMAT_R8G8B8A8_UNORM
;
612 _radeon_texformat_argb8888
= MESA_FORMAT_A8R8G8B8_UNORM
;
613 _radeon_texformat_rgb565
= MESA_FORMAT_R5G6B5_UNORM
;
614 _radeon_texformat_argb4444
= MESA_FORMAT_A4R4G4B4_UNORM
;
615 _radeon_texformat_argb1555
= MESA_FORMAT_A1R5G5B5_UNORM
;
620 radeon_init_common_texture_funcs(radeonContextPtr radeon
,
621 struct dd_function_table
*functions
)
623 functions
->NewTextureImage
= radeonNewTextureImage
;
624 functions
->DeleteTextureImage
= radeonDeleteTextureImage
;
625 functions
->AllocTextureImageBuffer
= radeonAllocTextureImageBuffer
;
626 functions
->FreeTextureImageBuffer
= radeonFreeTextureImageBuffer
;
627 functions
->MapTextureImage
= radeon_map_texture_image
;
628 functions
->UnmapTextureImage
= radeon_unmap_texture_image
;
630 functions
->ChooseTextureFormat
= radeonChooseTextureFormat_mesa
;
632 functions
->CopyTexSubImage
= radeonCopyTexSubImage
;
634 functions
->Bitmap
= _mesa_meta_Bitmap
;
635 functions
->EGLImageTargetTexture2D
= radeon_image_target_texture_2d
;
637 radeonInitTextureFormats();
640 static radeon_mipmap_tree
*radeon_miptree_create_for_teximage(radeonContextPtr rmesa
,
641 struct gl_texture_object
*texObj
,
642 struct gl_texture_image
*texImage
)
644 radeonTexObj
*t
= radeon_tex_obj(texObj
);
647 int width
, height
, depth
;
650 width
= texImage
->Width
;
651 height
= texImage
->Height
;
652 depth
= texImage
->Depth
;
654 if (texImage
->Level
> texObj
->BaseLevel
&&
656 (texObj
->Target
!= GL_TEXTURE_1D
&& height
== 1) ||
657 (texObj
->Target
== GL_TEXTURE_3D
&& depth
== 1))) {
658 /* For this combination, we're at some lower mipmap level and
659 * some important dimension is 1. We can't extrapolate up to a
660 * likely base level width/height/depth for a full mipmap stack
661 * from this info, so just allocate this one level.
663 firstLevel
= texImage
->Level
;
664 lastLevel
= texImage
->Level
;
666 if (texImage
->Level
< texObj
->BaseLevel
)
669 firstLevel
= texObj
->BaseLevel
;
671 for (i
= texImage
->Level
; i
> firstLevel
; i
--) {
678 if ((texObj
->Sampler
.MinFilter
== GL_NEAREST
||
679 texObj
->Sampler
.MinFilter
== GL_LINEAR
) &&
680 texImage
->Level
== firstLevel
) {
681 lastLevel
= firstLevel
;
683 lastLevel
= firstLevel
+ util_logbase2(MAX2(MAX2(width
, height
), depth
));
687 return radeon_miptree_create(rmesa
, texObj
->Target
,
688 texImage
->TexFormat
, firstLevel
, lastLevel
- firstLevel
+ 1,
689 width
, height
, depth
,