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/mipmap.h"
38 #include "main/texcompress.h"
39 #include "main/texstore.h"
40 #include "main/teximage.h"
41 #include "main/texobj.h"
42 #include "drivers/common/meta.h"
44 #include "xmlpool.h" /* for symbolic values of enum-type options */
46 #include "radeon_common.h"
48 #include "radeon_mipmap_tree.h"
50 static void teximage_assign_miptree(radeonContextPtr rmesa
,
51 struct gl_texture_object
*texObj
,
52 struct gl_texture_image
*texImage
);
54 static radeon_mipmap_tree
*radeon_miptree_create_for_teximage(radeonContextPtr rmesa
,
55 struct gl_texture_object
*texObj
,
56 struct gl_texture_image
*texImage
);
58 void copy_rows(void* dst
, GLuint dststride
, const void* src
, GLuint srcstride
,
59 GLuint numrows
, GLuint rowsize
)
61 assert(rowsize
<= dststride
);
62 assert(rowsize
<= srcstride
);
64 radeon_print(RADEON_TEXTURE
, RADEON_TRACE
,
65 "%s dst %p, stride %u, src %p, stride %u, "
66 "numrows %u, rowsize %u.\n",
67 __func__
, dst
, dststride
,
71 if (rowsize
== srcstride
&& rowsize
== dststride
) {
72 memcpy(dst
, src
, numrows
*rowsize
);
75 for(i
= 0; i
< numrows
; ++i
) {
76 memcpy(dst
, src
, rowsize
);
85 * Allocate an empty texture image object.
87 struct gl_texture_image
*radeonNewTextureImage(struct gl_context
*ctx
)
89 return calloc(1, sizeof(radeon_texture_image
));
94 * Delete a texture image object.
97 radeonDeleteTextureImage(struct gl_context
*ctx
, struct gl_texture_image
*img
)
99 /* nothing special (yet) for radeon_texture_image */
100 _mesa_delete_texture_image(ctx
, img
);
104 radeonAllocTextureImageBuffer(struct gl_context
*ctx
,
105 struct gl_texture_image
*timage
)
107 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
108 struct gl_texture_object
*texobj
= timage
->TexObject
;
110 ctx
->Driver
.FreeTextureImageBuffer(ctx
, timage
);
112 if (!_swrast_init_texture_image(timage
))
115 teximage_assign_miptree(rmesa
, texobj
, timage
);
122 * Free memory associated with this texture image.
124 void radeonFreeTextureImageBuffer(struct gl_context
*ctx
, struct gl_texture_image
*timage
)
126 radeon_texture_image
* image
= get_radeon_texture_image(timage
);
129 radeon_miptree_unreference(&image
->mt
);
132 radeon_bo_unref(image
->bo
);
136 _swrast_free_texture_image_buffer(ctx
, timage
);
140 * Map texture memory/buffer into user space.
141 * Note: the region of interest parameters are ignored here.
142 * \param mapOut returns start of mapping of region of interest
143 * \param rowStrideOut returns row stride in bytes
146 radeon_map_texture_image(struct gl_context
*ctx
,
147 struct gl_texture_image
*texImage
,
149 GLuint x
, GLuint y
, GLuint w
, GLuint h
,
154 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
155 radeon_texture_image
*image
= get_radeon_texture_image(texImage
);
156 radeon_mipmap_tree
*mt
= image
->mt
;
157 GLuint texel_size
= _mesa_get_format_bytes(texImage
->TexFormat
);
158 GLuint width
= texImage
->Width
;
159 GLuint height
= texImage
->Height
;
160 struct radeon_bo
*bo
= !image
->mt
? image
->bo
: image
->mt
->bo
;
162 GLboolean write
= (mode
& GL_MAP_WRITE_BIT
) != 0;
164 _mesa_get_format_block_size(texImage
->TexFormat
, &bw
, &bh
);
169 if (bo
&& radeon_bo_is_referenced_by_cs(bo
, rmesa
->cmdbuf
.cs
)) {
170 radeon_print(RADEON_TEXTURE
, RADEON_VERBOSE
,
171 "%s for texture that is "
172 "queued for GPU processing.\n",
174 radeon_firevertices(rmesa
);
179 radeon_bo_map(image
->bo
, write
);
180 *stride
= get_texture_image_row_stride(rmesa
, texImage
->TexFormat
, width
, 0, texImage
->TexObject
->Target
);
182 } else if (likely(mt
)) {
184 radeon_mipmap_level
*lvl
= &image
->mt
->levels
[texImage
->Level
];
186 radeon_bo_map(mt
->bo
, write
);
187 base
= mt
->bo
->ptr
+ lvl
->faces
[image
->base
.Base
.Face
].offset
;
189 *stride
= lvl
->rowstride
;
190 *map
= base
+ (slice
* height
) * *stride
;
192 /* texture data is in malloc'd memory */
196 *stride
= _mesa_format_row_stride(texImage
->TexFormat
, width
);
197 *map
= image
->base
.Buffer
+ (slice
* height
) * *stride
;
200 *map
+= y
* *stride
+ x
* texel_size
;
204 radeon_unmap_texture_image(struct gl_context
*ctx
,
205 struct gl_texture_image
*texImage
, GLuint slice
)
207 radeon_texture_image
*image
= get_radeon_texture_image(texImage
);
210 radeon_bo_unmap(image
->bo
);
212 radeon_bo_unmap(image
->mt
->bo
);
215 /* try to find a format which will only need a memcopy */
216 static mesa_format
radeonChoose8888TexFormat(radeonContextPtr rmesa
,
218 GLenum srcType
, GLboolean fbo
)
220 #if defined(RADEON_R100)
221 /* r100 can only do this */
222 return _radeon_texformat_argb8888
;
223 #elif defined(RADEON_R200)
225 const GLubyte littleEndian
= *((const GLubyte
*)&ui
);
228 return _radeon_texformat_argb8888
;
230 if ((srcFormat
== GL_RGBA
&& srcType
== GL_UNSIGNED_INT_8_8_8_8
) ||
231 (srcFormat
== GL_RGBA
&& srcType
== GL_UNSIGNED_BYTE
&& !littleEndian
) ||
232 (srcFormat
== GL_ABGR_EXT
&& srcType
== GL_UNSIGNED_INT_8_8_8_8_REV
) ||
233 (srcFormat
== GL_ABGR_EXT
&& srcType
== GL_UNSIGNED_BYTE
&& littleEndian
)) {
234 return MESA_FORMAT_A8B8G8R8_UNORM
;
235 } else if ((srcFormat
== GL_RGBA
&& srcType
== GL_UNSIGNED_INT_8_8_8_8_REV
) ||
236 (srcFormat
== GL_RGBA
&& srcType
== GL_UNSIGNED_BYTE
&& littleEndian
) ||
237 (srcFormat
== GL_ABGR_EXT
&& srcType
== GL_UNSIGNED_INT_8_8_8_8
) ||
238 (srcFormat
== GL_ABGR_EXT
&& srcType
== GL_UNSIGNED_BYTE
&& !littleEndian
)) {
239 return MESA_FORMAT_R8G8B8A8_UNORM
;
241 return _radeon_texformat_argb8888
;
245 mesa_format
radeonChooseTextureFormat_mesa(struct gl_context
* ctx
,
247 GLint internalFormat
,
251 return radeonChooseTextureFormat(ctx
, internalFormat
, format
,
255 mesa_format
radeonChooseTextureFormat(struct gl_context
* ctx
,
256 GLint internalFormat
,
258 GLenum type
, GLboolean fbo
)
260 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
261 const GLboolean do32bpt
=
262 (rmesa
->texture_depth
== DRI_CONF_TEXTURE_DEPTH_32
);
263 const GLboolean force16bpt
=
264 (rmesa
->texture_depth
== DRI_CONF_TEXTURE_DEPTH_FORCE_16
);
267 radeon_print(RADEON_TEXTURE
, RADEON_TRACE
,
268 "%s InternalFormat=%s(%d) type=%s format=%s\n",
270 _mesa_lookup_enum_by_nr(internalFormat
), internalFormat
,
271 _mesa_lookup_enum_by_nr(type
), _mesa_lookup_enum_by_nr(format
));
272 radeon_print(RADEON_TEXTURE
, RADEON_TRACE
,
273 "%s do32bpt=%d force16bpt=%d\n",
274 __func__
, do32bpt
, force16bpt
);
276 switch (internalFormat
) {
279 case GL_COMPRESSED_RGBA
:
281 case GL_UNSIGNED_INT_10_10_10_2
:
282 case GL_UNSIGNED_INT_2_10_10_10_REV
:
283 return do32bpt
? _radeon_texformat_argb8888
:
284 _radeon_texformat_argb1555
;
285 case GL_UNSIGNED_SHORT_4_4_4_4
:
286 case GL_UNSIGNED_SHORT_4_4_4_4_REV
:
287 return _radeon_texformat_argb4444
;
288 case GL_UNSIGNED_SHORT_5_5_5_1
:
289 case GL_UNSIGNED_SHORT_1_5_5_5_REV
:
290 return _radeon_texformat_argb1555
;
292 return do32bpt
? radeonChoose8888TexFormat(rmesa
, format
, type
, fbo
) :
293 _radeon_texformat_argb4444
;
298 case GL_COMPRESSED_RGB
:
300 case GL_UNSIGNED_SHORT_4_4_4_4
:
301 case GL_UNSIGNED_SHORT_4_4_4_4_REV
:
302 return _radeon_texformat_argb4444
;
303 case GL_UNSIGNED_SHORT_5_5_5_1
:
304 case GL_UNSIGNED_SHORT_1_5_5_5_REV
:
305 return _radeon_texformat_argb1555
;
306 case GL_UNSIGNED_SHORT_5_6_5
:
307 case GL_UNSIGNED_SHORT_5_6_5_REV
:
308 return _radeon_texformat_rgb565
;
310 return do32bpt
? _radeon_texformat_argb8888
:
311 _radeon_texformat_rgb565
;
319 radeonChoose8888TexFormat(rmesa
, format
, type
, fbo
) :
320 _radeon_texformat_argb4444
;
324 return _radeon_texformat_argb4444
;
327 return _radeon_texformat_argb1555
;
333 return !force16bpt
? _radeon_texformat_argb8888
:
334 _radeon_texformat_rgb565
;
339 return _radeon_texformat_rgb565
;
346 case GL_COMPRESSED_ALPHA
:
347 #if defined(RADEON_R200)
348 /* r200: can't use a8 format since interpreting hw I8 as a8 would result
349 in wrong rgb values (same as alpha value instead of 0). */
350 return _radeon_texformat_al88
;
352 return MESA_FORMAT_A_UNORM8
;
360 case GL_COMPRESSED_LUMINANCE
:
361 return MESA_FORMAT_L_UNORM8
;
364 case GL_LUMINANCE_ALPHA
:
365 case GL_LUMINANCE4_ALPHA4
:
366 case GL_LUMINANCE6_ALPHA2
:
367 case GL_LUMINANCE8_ALPHA8
:
368 case GL_LUMINANCE12_ALPHA4
:
369 case GL_LUMINANCE12_ALPHA12
:
370 case GL_LUMINANCE16_ALPHA16
:
371 case GL_COMPRESSED_LUMINANCE_ALPHA
:
372 return _radeon_texformat_al88
;
379 case GL_COMPRESSED_INTENSITY
:
380 return MESA_FORMAT_I_UNORM8
;
383 if (type
== GL_UNSIGNED_SHORT_8_8_APPLE
||
384 type
== GL_UNSIGNED_BYTE
)
385 return MESA_FORMAT_YCBCR
;
387 return MESA_FORMAT_YCBCR_REV
;
391 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT
:
392 return MESA_FORMAT_RGB_DXT1
;
394 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT
:
395 return MESA_FORMAT_RGBA_DXT1
;
399 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT
:
400 return MESA_FORMAT_RGBA_DXT3
;
402 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT
:
403 return MESA_FORMAT_RGBA_DXT5
;
405 case GL_ALPHA16F_ARB
:
406 return MESA_FORMAT_A_FLOAT16
;
407 case GL_ALPHA32F_ARB
:
408 return MESA_FORMAT_A_FLOAT32
;
409 case GL_LUMINANCE16F_ARB
:
410 return MESA_FORMAT_L_FLOAT16
;
411 case GL_LUMINANCE32F_ARB
:
412 return MESA_FORMAT_L_FLOAT32
;
413 case GL_LUMINANCE_ALPHA16F_ARB
:
414 return MESA_FORMAT_LA_FLOAT16
;
415 case GL_LUMINANCE_ALPHA32F_ARB
:
416 return MESA_FORMAT_LA_FLOAT32
;
417 case GL_INTENSITY16F_ARB
:
418 return MESA_FORMAT_I_FLOAT16
;
419 case GL_INTENSITY32F_ARB
:
420 return MESA_FORMAT_I_FLOAT32
;
422 return MESA_FORMAT_RGBA_FLOAT16
;
424 return MESA_FORMAT_RGBA_FLOAT32
;
426 return MESA_FORMAT_RGBA_FLOAT16
;
428 return MESA_FORMAT_RGBA_FLOAT32
;
430 case GL_DEPTH_COMPONENT
:
431 case GL_DEPTH_COMPONENT16
:
432 case GL_DEPTH_COMPONENT24
:
433 case GL_DEPTH_COMPONENT32
:
434 case GL_DEPTH_STENCIL_EXT
:
435 case GL_DEPTH24_STENCIL8_EXT
:
436 return MESA_FORMAT_Z24_UNORM_S8_UINT
;
438 /* EXT_texture_sRGB */
442 case GL_SRGB8_ALPHA8
:
443 case GL_COMPRESSED_SRGB
:
444 case GL_COMPRESSED_SRGB_ALPHA
:
445 return MESA_FORMAT_B8G8R8A8_SRGB
;
449 case GL_COMPRESSED_SLUMINANCE
:
450 return MESA_FORMAT_L_SRGB8
;
452 case GL_SLUMINANCE_ALPHA
:
453 case GL_SLUMINANCE8_ALPHA8
:
454 case GL_COMPRESSED_SLUMINANCE_ALPHA
:
455 return MESA_FORMAT_L8A8_SRGB
;
457 case GL_COMPRESSED_SRGB_S3TC_DXT1_EXT
:
458 return MESA_FORMAT_SRGB_DXT1
;
459 case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT
:
460 return MESA_FORMAT_SRGBA_DXT1
;
461 case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT
:
462 return MESA_FORMAT_SRGBA_DXT3
;
463 case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT
:
464 return MESA_FORMAT_SRGBA_DXT5
;
468 "unexpected internalFormat 0x%x in %s",
469 (int)internalFormat
, __func__
);
470 return MESA_FORMAT_NONE
;
473 return MESA_FORMAT_NONE
; /* never get here */
476 /** Check if given image is valid within current texture object.
478 static void teximage_assign_miptree(radeonContextPtr rmesa
,
479 struct gl_texture_object
*texObj
,
480 struct gl_texture_image
*texImage
)
482 radeonTexObj
*t
= radeon_tex_obj(texObj
);
483 radeon_texture_image
* image
= get_radeon_texture_image(texImage
);
485 /* Try using current miptree, or create new if there isn't any */
486 if (!t
->mt
|| !radeon_miptree_matches_image(t
->mt
, texImage
)) {
487 radeon_miptree_unreference(&t
->mt
);
488 t
->mt
= radeon_miptree_create_for_teximage(rmesa
,
492 radeon_print(RADEON_TEXTURE
, RADEON_NORMAL
,
493 "%s: texObj %p, texImage %p, "
494 "texObj miptree doesn't match, allocated new miptree %p\n",
495 __FUNCTION__
, texObj
, texImage
, t
->mt
);
498 /* Miptree alocation may have failed,
499 * when there was no image for baselevel specified */
501 radeon_miptree_reference(t
->mt
, &image
->mt
);
503 radeon_print(RADEON_TEXTURE
, RADEON_VERBOSE
,
504 "%s Failed to allocate miptree.\n", __func__
);
507 unsigned radeonIsFormatRenderable(mesa_format mesa_format
)
509 if (mesa_format
== _radeon_texformat_argb8888
|| mesa_format
== _radeon_texformat_rgb565
||
510 mesa_format
== _radeon_texformat_argb1555
|| mesa_format
== _radeon_texformat_argb4444
)
515 case MESA_FORMAT_Z_UNORM16
:
516 case MESA_FORMAT_Z24_UNORM_S8_UINT
:
523 void radeon_image_target_texture_2d(struct gl_context
*ctx
, GLenum target
,
524 struct gl_texture_object
*texObj
,
525 struct gl_texture_image
*texImage
,
526 GLeglImageOES image_handle
)
528 radeonContextPtr radeon
= RADEON_CONTEXT(ctx
);
529 radeonTexObj
*t
= radeon_tex_obj(texObj
);
530 radeon_texture_image
*radeonImage
= get_radeon_texture_image(texImage
);
534 screen
= radeon
->dri
.screen
;
535 image
= screen
->dri2
.image
->lookupEGLImage(screen
, image_handle
,
536 screen
->loaderPrivate
);
540 radeonFreeTextureImageBuffer(ctx
, texImage
);
542 texImage
->Width
= image
->width
;
543 texImage
->Height
= image
->height
;
545 texImage
->_BaseFormat
= GL_RGBA
;
546 texImage
->TexFormat
= image
->format
;
547 radeonImage
->base
.RowStride
= image
->pitch
;
548 texImage
->InternalFormat
= image
->internal_format
;
552 radeon_miptree_unreference(&t
->mt
);
556 /* NOTE: The following is *very* ugly and will probably break. But
557 I don't know how to deal with it, without creating a whole new
558 function like radeon_miptree_from_bo() so I'm going with the
559 easy but error-prone way. */
561 radeon_try_alloc_miptree(radeon
, t
);
563 radeon_miptree_reference(t
->mt
, &radeonImage
->mt
);
567 radeon_print(RADEON_TEXTURE
, RADEON_VERBOSE
,
568 "%s Failed to allocate miptree.\n", __func__
);
572 /* Particularly ugly: this is guaranteed to break, if image->bo is
573 not of the required size for a miptree. */
574 radeon_bo_unref(t
->mt
->bo
);
575 radeon_bo_ref(image
->bo
);
576 t
->mt
->bo
= image
->bo
;
578 if (!radeon_miptree_matches_image(t
->mt
, &radeonImage
->base
.Base
))
579 fprintf(stderr
, "miptree doesn't match image\n");
582 mesa_format _radeon_texformat_rgba8888
= MESA_FORMAT_NONE
;
583 mesa_format _radeon_texformat_argb8888
= MESA_FORMAT_NONE
;
584 mesa_format _radeon_texformat_rgb565
= MESA_FORMAT_NONE
;
585 mesa_format _radeon_texformat_argb4444
= MESA_FORMAT_NONE
;
586 mesa_format _radeon_texformat_argb1555
= MESA_FORMAT_NONE
;
587 mesa_format _radeon_texformat_al88
= MESA_FORMAT_NONE
;
592 radeonInitTextureFormats(void)
594 if (_mesa_little_endian()) {
595 _radeon_texformat_rgba8888
= MESA_FORMAT_A8B8G8R8_UNORM
;
596 _radeon_texformat_argb8888
= MESA_FORMAT_B8G8R8A8_UNORM
;
597 _radeon_texformat_rgb565
= MESA_FORMAT_B5G6R5_UNORM
;
598 _radeon_texformat_argb4444
= MESA_FORMAT_B4G4R4A4_UNORM
;
599 _radeon_texformat_argb1555
= MESA_FORMAT_B5G5R5A1_UNORM
;
600 _radeon_texformat_al88
= MESA_FORMAT_L8A8_UNORM
;
603 _radeon_texformat_rgba8888
= MESA_FORMAT_R8G8B8A8_UNORM
;
604 _radeon_texformat_argb8888
= MESA_FORMAT_A8R8G8B8_UNORM
;
605 _radeon_texformat_rgb565
= MESA_FORMAT_R5G6B5_UNORM
;
606 _radeon_texformat_argb4444
= MESA_FORMAT_A4R4G4B4_UNORM
;
607 _radeon_texformat_argb1555
= MESA_FORMAT_A1R5G5B5_UNORM
;
608 _radeon_texformat_al88
= MESA_FORMAT_A8L8_UNORM
;
613 radeon_init_common_texture_funcs(radeonContextPtr radeon
,
614 struct dd_function_table
*functions
)
616 functions
->NewTextureImage
= radeonNewTextureImage
;
617 functions
->DeleteTextureImage
= radeonDeleteTextureImage
;
618 functions
->AllocTextureImageBuffer
= radeonAllocTextureImageBuffer
;
619 functions
->FreeTextureImageBuffer
= radeonFreeTextureImageBuffer
;
620 functions
->MapTextureImage
= radeon_map_texture_image
;
621 functions
->UnmapTextureImage
= radeon_unmap_texture_image
;
623 functions
->ChooseTextureFormat
= radeonChooseTextureFormat_mesa
;
625 functions
->CopyTexSubImage
= radeonCopyTexSubImage
;
627 functions
->Bitmap
= _mesa_meta_Bitmap
;
628 functions
->EGLImageTargetTexture2D
= radeon_image_target_texture_2d
;
630 radeonInitTextureFormats();
633 static radeon_mipmap_tree
*radeon_miptree_create_for_teximage(radeonContextPtr rmesa
,
634 struct gl_texture_object
*texObj
,
635 struct gl_texture_image
*texImage
)
637 radeonTexObj
*t
= radeon_tex_obj(texObj
);
640 int width
, height
, depth
;
643 width
= texImage
->Width
;
644 height
= texImage
->Height
;
645 depth
= texImage
->Depth
;
647 if (texImage
->Level
> texObj
->BaseLevel
&&
649 (texObj
->Target
!= GL_TEXTURE_1D
&& height
== 1) ||
650 (texObj
->Target
== GL_TEXTURE_3D
&& depth
== 1))) {
651 /* For this combination, we're at some lower mipmap level and
652 * some important dimension is 1. We can't extrapolate up to a
653 * likely base level width/height/depth for a full mipmap stack
654 * from this info, so just allocate this one level.
656 firstLevel
= texImage
->Level
;
657 lastLevel
= texImage
->Level
;
659 if (texImage
->Level
< texObj
->BaseLevel
)
662 firstLevel
= texObj
->BaseLevel
;
664 for (i
= texImage
->Level
; i
> firstLevel
; i
--) {
671 if ((texObj
->Sampler
.MinFilter
== GL_NEAREST
||
672 texObj
->Sampler
.MinFilter
== GL_LINEAR
) &&
673 texImage
->Level
== firstLevel
) {
674 lastLevel
= firstLevel
;
676 lastLevel
= firstLevel
+ _mesa_logbase2(MAX2(MAX2(width
, height
), depth
));
680 return radeon_miptree_create(rmesa
, texObj
->Target
,
681 texImage
->TexFormat
, firstLevel
, lastLevel
- firstLevel
+ 1,
682 width
, height
, depth
,