summaryrefslogtreecommitdiff
path: root/src/mesa
diff options
context:
space:
mode:
authorNicolai Haehnle <nhaehnle@gmail.com>2009-02-14 20:45:01 +0100
committerNicolai Haehnle <nhaehnle@gmail.com>2009-02-14 20:47:08 +0100
commit2d9471b28159b9af952c6a87868ff648a6055c55 (patch)
tree1dd25e94719533f397e7325420595f77fab65788 /src/mesa
parent9a26164f3525c31607e3e676e0d41e496dada4c2 (diff)
r300: Fix crash in cubemap tree creation
The mip tree creation would crash if the first baselevel image to be uploaded was not the positive-x image. Found with Sauerbraten, also added a regression test to Piglit. Signed-off-by: Nicolai Haehnle <nhaehnle@gmail.com>
Diffstat (limited to 'src/mesa')
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_mipmap_tree.c26
1 files changed, 20 insertions, 6 deletions
diff --git a/src/mesa/drivers/dri/radeon/radeon_mipmap_tree.c b/src/mesa/drivers/dri/radeon/radeon_mipmap_tree.c
index 45c1d71be5..3203ee1cba 100644
--- a/src/mesa/drivers/dri/radeon/radeon_mipmap_tree.c
+++ b/src/mesa/drivers/dri/radeon/radeon_mipmap_tree.c
@@ -213,12 +213,26 @@ void radeon_miptree_unreference(radeon_mipmap_tree *mt)
}
+/**
+ * Calculate first and last mip levels for the given texture object,
+ * where the dimensions are taken from the given texture image at
+ * the given level.
+ *
+ * Note: level is the OpenGL level number, which is not necessarily the same
+ * as the first level that is actually present.
+ *
+ * The base level image of the given texture face must be non-null,
+ * or this will fail.
+ */
static void calculate_first_last_level(struct gl_texture_object *tObj,
- GLuint *pfirstLevel, GLuint *plastLevel)
+ GLuint *pfirstLevel, GLuint *plastLevel,
+ GLuint face, GLuint level)
{
const struct gl_texture_image * const baseImage =
- tObj->Image[0][tObj->BaseLevel];
+ tObj->Image[face][level];
+ assert(baseImage);
+
/* These must be signed values. MinLod and MaxLod can be negative numbers,
* and having firstLevel and lastLevel as signed prevents the need for
* extra sign checks.
@@ -240,10 +254,10 @@ static void calculate_first_last_level(struct gl_texture_object *tObj,
} else {
firstLevel = tObj->BaseLevel + (GLint)(tObj->MinLod + 0.5);
firstLevel = MAX2(firstLevel, tObj->BaseLevel);
- firstLevel = MIN2(firstLevel, tObj->BaseLevel + baseImage->MaxLog2);
+ firstLevel = MIN2(firstLevel, level + baseImage->MaxLog2);
lastLevel = tObj->BaseLevel + (GLint)(tObj->MaxLod + 0.5);
lastLevel = MAX2(lastLevel, tObj->BaseLevel);
- lastLevel = MIN2(lastLevel, tObj->BaseLevel + baseImage->MaxLog2);
+ lastLevel = MIN2(lastLevel, level + baseImage->MaxLog2);
lastLevel = MIN2(lastLevel, tObj->MaxLevel);
lastLevel = MAX2(firstLevel, lastLevel); /* need at least one level */
}
@@ -302,7 +316,7 @@ GLboolean radeon_miptree_matches_texture(radeon_mipmap_tree *mt, struct gl_textu
GLuint numfaces = 1;
GLuint firstLevel, lastLevel;
- calculate_first_last_level(texObj, &firstLevel, &lastLevel);
+ calculate_first_last_level(texObj, &firstLevel, &lastLevel, 0, texObj->BaseLevel);
if (texObj->Target == GL_TEXTURE_CUBE_MAP)
numfaces = 6;
@@ -332,7 +346,7 @@ void radeon_try_alloc_miptree(radeonContextPtr rmesa, radeonTexObj *t,
assert(!t->mt);
- calculate_first_last_level(&t->base, &firstLevel, &lastLevel);
+ calculate_first_last_level(&t->base, &firstLevel, &lastLevel, face, level);
if (t->base.Target == GL_TEXTURE_CUBE_MAP)
numfaces = 6;