From efa6b5e42b427c1ec9f2d636d280c84e7da71346 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Marek=20Ol=C5=A1=C3=A1k?= Date: Sun, 11 Nov 2012 15:22:32 +0100 Subject: [PATCH] mesa: add MaxNumLevels to gl_texture_image, remove MaxLog2 MaxLog2 led to bugs, because it didn't work well with 1D and 3D textures. NOTE: This is a candidate for the stable branches. v2: correct the comment at MaxNumlevels Reviewed-by: Brian Paul Reviewed-by: Dave Airlie (cherry picked from commit 8111342e814304730bed34446ea816cbc17a5775) Conflicts: src/mesa/main/teximage.h --- src/mesa/drivers/dri/nouveau/nouveau_texture.c | 2 +- src/mesa/drivers/dri/radeon/radeon_mipmap_tree.c | 6 ++-- src/mesa/main/mtypes.h | 3 +- src/mesa/main/teximage.c | 41 +++++++++++++++++++++++- src/mesa/main/teximage.h | 4 +++ 5 files changed, 50 insertions(+), 6 deletions(-) diff --git a/src/mesa/drivers/dri/nouveau/nouveau_texture.c b/src/mesa/drivers/dri/nouveau/nouveau_texture.c index 37f7577..288b510 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_texture.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_texture.c @@ -369,7 +369,7 @@ get_last_level(struct gl_texture_object *t) t->Sampler.MinFilter == GL_LINEAR || !base) return t->BaseLevel; else - return MIN2(t->BaseLevel + base->MaxLog2, t->MaxLevel); + return MIN2(t->BaseLevel + base->MaxNumLevels - 1, t->MaxLevel); } static void diff --git a/src/mesa/drivers/dri/radeon/radeon_mipmap_tree.c b/src/mesa/drivers/dri/radeon/radeon_mipmap_tree.c index 8901090..f4fb3a5 100644 --- a/src/mesa/drivers/dri/radeon/radeon_mipmap_tree.c +++ b/src/mesa/drivers/dri/radeon/radeon_mipmap_tree.c @@ -270,7 +270,7 @@ static void calculate_min_max_lod(struct gl_sampler_object *samp, struct gl_text minLod = MIN2(minLod, tObj->MaxLevel); maxLod = tObj->BaseLevel + (GLint)(samp->MaxLod + 0.5); maxLod = MIN2(maxLod, tObj->MaxLevel); - maxLod = MIN2(maxLod, tObj->Image[0][minLod]->MaxLog2 + minLod); + maxLod = MIN2(maxLod, tObj->Image[0][minLod]->MaxNumLevels - 1 + minLod); maxLod = MAX2(maxLod, minLod); /* need at least one level */ } break; @@ -329,7 +329,7 @@ static GLboolean radeon_miptree_matches_texture(radeon_mipmap_tree *mt, struct g mtBaseLevel = &mt->levels[texObj->BaseLevel - mt->baseLevel]; firstImage = texObj->Image[0][texObj->BaseLevel]; - numLevels = MIN2(texObj->_MaxLevel - texObj->BaseLevel + 1, firstImage->MaxLog2 + 1); + numLevels = MIN2(texObj->_MaxLevel - texObj->BaseLevel + 1, firstImage->MaxNumLevels); if (radeon_is_debug_enabled(RADEON_TEXTURE,RADEON_TRACE)) { fprintf(stderr, "Checking if miptree %p matches texObj %p\n", mt, texObj); @@ -378,7 +378,7 @@ void radeon_try_alloc_miptree(radeonContextPtr rmesa, radeonTexObj *t) } - numLevels = MIN2(texObj->MaxLevel - texObj->BaseLevel + 1, texImg->MaxLog2 + 1); + numLevels = MIN2(texObj->MaxLevel - texObj->BaseLevel + 1, texImg->MaxNumLevels); t->mt = radeon_miptree_create(rmesa, t->base.Target, texImg->TexFormat, texObj->BaseLevel, diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h index f185ffd..6fce70f 100644 --- a/src/mesa/main/mtypes.h +++ b/src/mesa/main/mtypes.h @@ -1205,7 +1205,8 @@ struct gl_texture_image GLuint WidthLog2; /**< = log2(Width2) */ GLuint HeightLog2; /**< = log2(Height2) */ GLuint DepthLog2; /**< = log2(Depth2) */ - GLuint MaxLog2; /**< = MAX(WidthLog2, HeightLog2) */ + GLuint MaxNumLevels; /**< = maximum possible number of mipmap + levels, computed from the dimensions */ struct gl_texture_object *TexObject; /**< Pointer back to parent object */ GLuint Level; /**< Which mipmap level am I? */ diff --git a/src/mesa/main/teximage.c b/src/mesa/main/teximage.c index 38fa9fa..9edd4d8 100644 --- a/src/mesa/main/teximage.c +++ b/src/mesa/main/teximage.c @@ -1002,6 +1002,43 @@ _mesa_get_texture_dimensions(GLenum target) } +/** + * Return the maximum number of mipmap levels for the given target + * and the dimensions. + * The dimensions are expected not to include the border. + */ +GLsizei +_mesa_get_tex_max_num_levels(GLenum target, GLsizei width, GLsizei height, + GLsizei depth) +{ + GLsizei size; + + switch (target) { + case GL_TEXTURE_1D: + case GL_TEXTURE_1D_ARRAY: + size = width; + break; + case GL_TEXTURE_CUBE_MAP: + case GL_TEXTURE_CUBE_MAP_ARRAY: + ASSERT(width == height); + size = width; + break; + case GL_TEXTURE_2D: + case GL_TEXTURE_2D_ARRAY: + size = MAX2(width, height); + break; + case GL_TEXTURE_3D: + size = MAX3(width, height, depth); + break; + case GL_TEXTURE_RECTANGLE: + return 1; + default: + assert(0); + return 1; + } + + return _mesa_logbase2(size) + 1; +} #if 000 /* not used anymore */ @@ -1187,7 +1224,9 @@ _mesa_init_teximage_fields(struct gl_context *ctx, target); } - img->MaxLog2 = MAX2(img->WidthLog2, img->HeightLog2); + img->MaxNumLevels = + _mesa_get_tex_max_num_levels(target, + img->Width2, img->Height2, img->Depth2); img->TexFormat = format; } diff --git a/src/mesa/main/teximage.h b/src/mesa/main/teximage.h index 36fd1c2..a2565ec 100644 --- a/src/mesa/main/teximage.h +++ b/src/mesa/main/teximage.h @@ -138,6 +138,10 @@ _mesa_tex_target_to_face(GLenum target); extern GLint _mesa_get_texture_dimensions(GLenum target); +extern GLsizei +_mesa_get_tex_max_num_levels(GLenum target, GLsizei width, GLsizei height, + GLsizei depth); + extern GLenum _mesa_es_error_check_format_and_type(GLenum format, GLenum type, unsigned dimensions); -- 2.7.4