diff options
| author | Maciej Cencora <m.cencora@gmail.com> | 2009-11-29 15:40:13 +0100 | 
|---|---|---|
| committer | Maciej Cencora <m.cencora@gmail.com> | 2009-11-29 17:27:48 +0100 | 
| commit | 63c00c53a3019b801c5eee8a12f7862422f79f10 (patch) | |
| tree | 55a106bc7772bebb5fd22714356c351e69581945 /src/mesa/drivers | |
| parent | 2773556d55fe6043bee3d4c86f7b78906e5d60e0 (diff) | |
radeon: update miptree code a little
Simplify gl image level <-> miptree level mapping (are equal now).
Don't allocate miptree for images that won't fit in it (fixes #25230).
Diffstat (limited to 'src/mesa/drivers')
| -rw-r--r-- | src/mesa/drivers/dri/radeon/radeon_mipmap_tree.c | 70 | ||||
| -rw-r--r-- | src/mesa/drivers/dri/radeon/radeon_mipmap_tree.h | 10 | ||||
| -rw-r--r-- | src/mesa/drivers/dri/radeon/radeon_texture.c | 36 | 
3 files changed, 61 insertions, 55 deletions
| diff --git a/src/mesa/drivers/dri/radeon/radeon_mipmap_tree.c b/src/mesa/drivers/dri/radeon/radeon_mipmap_tree.c index 39b6d50094..a9d601a0b5 100644 --- a/src/mesa/drivers/dri/radeon/radeon_mipmap_tree.c +++ b/src/mesa/drivers/dri/radeon/radeon_mipmap_tree.c @@ -124,20 +124,19 @@ static GLuint minify(GLuint size, GLuint levels)  static void calculate_miptree_layout_r100(radeonContextPtr rmesa, radeon_mipmap_tree *mt)  { -	GLuint curOffset; -	GLuint i; -	GLuint face; +	GLuint curOffset, i, face, level;  	assert(mt->numLevels <= rmesa->glCtx->Const.MaxTextureLevels);  	curOffset = 0;  	for(face = 0; face < mt->faces; face++) { -		for(i = 0; i < mt->numLevels; i++) { -			mt->levels[i].width = minify(mt->width0, i); -			mt->levels[i].height = minify(mt->height0, i); -			mt->levels[i].depth = minify(mt->depth0, i); -			compute_tex_image_offset(rmesa, mt, face, i, &curOffset); +		for(i = 0, level = mt->baseLevel; i < mt->numLevels; i++, level++) { +			mt->levels[level].valid = 1; +			mt->levels[level].width = minify(mt->width0, i); +			mt->levels[level].height = minify(mt->height0, i); +			mt->levels[level].depth = minify(mt->depth0, i); +			compute_tex_image_offset(rmesa, mt, face, level, &curOffset);  		}  	} @@ -147,21 +146,21 @@ static void calculate_miptree_layout_r100(radeonContextPtr rmesa, radeon_mipmap_  static void calculate_miptree_layout_r300(radeonContextPtr rmesa, radeon_mipmap_tree *mt)  { -	GLuint curOffset; -	GLuint i; +	GLuint curOffset, i, level;  	assert(mt->numLevels <= rmesa->glCtx->Const.MaxTextureLevels);  	curOffset = 0; -	for(i = 0; i < mt->numLevels; i++) { +	for(i = 0, level = mt->baseLevel; i < mt->numLevels; i++, level++) {  		GLuint face; -		mt->levels[i].width = minify(mt->width0, i); -		mt->levels[i].height = minify(mt->height0, i); -		mt->levels[i].depth = minify(mt->depth0, i); +		mt->levels[level].valid = 1; +		mt->levels[level].width = minify(mt->width0, i); +		mt->levels[level].height = minify(mt->height0, i); +		mt->levels[level].depth = minify(mt->depth0, i);  		for(face = 0; face < mt->faces; face++) -			compute_tex_image_offset(rmesa, mt, face, i, &curOffset); +			compute_tex_image_offset(rmesa, mt, face, level, &curOffset);  	}  	/* Note the required size in memory */ @@ -277,18 +276,19 @@ static void calculate_min_max_lod(struct gl_texture_object *tObj,   * given face and level.   */  GLboolean radeon_miptree_matches_image(radeon_mipmap_tree *mt, -		struct gl_texture_image *texImage, GLuint face, GLuint mtLevel) +		struct gl_texture_image *texImage, GLuint face, GLuint level)  {  	radeon_mipmap_level *lvl; -	if (face >= mt->faces || mtLevel > mt->numLevels) +	if (face >= mt->faces)  		return GL_FALSE;  	if (texImage->TexFormat != mt->mesaFormat)  		return GL_FALSE; -	lvl = &mt->levels[mtLevel]; -	if (lvl->width != texImage->Width || +	lvl = &mt->levels[level]; +	if (!lvl->valid || +	    lvl->width != texImage->Width ||  	    lvl->height != texImage->Height ||  	    lvl->depth != texImage->Depth)  		return GL_FALSE; @@ -394,38 +394,17 @@ radeon_miptree_image_offset(radeon_mipmap_tree *mt,  }  /** - * Convert radeon miptree texture level to GL texture level - * @param[in] tObj texture object whom level is to be converted - * @param[in] level radeon miptree texture level - * @return GL texture level - */ -unsigned radeon_miptree_level_to_gl_level(struct gl_texture_object *tObj, unsigned level) -{ -	return level + tObj->BaseLevel; -} - -/** - * Convert GL texture level to radeon miptree texture level - * @param[in] tObj texture object whom level is to be converted - * @param[in] level GL texture level - * @return radeon miptree texture level - */ -unsigned radeon_gl_level_to_miptree_level(struct gl_texture_object *tObj, unsigned level) -{ -	return level - tObj->BaseLevel; -} - -/**   * Ensure that the given image is stored in the given miptree from now on.   */  static void migrate_image_to_miptree(radeon_mipmap_tree *mt,  									 radeon_texture_image *image, -									 int face, int mtLevel) +									 int face, int level)  { -	radeon_mipmap_level *dstlvl = &mt->levels[mtLevel]; +	radeon_mipmap_level *dstlvl = &mt->levels[level];  	unsigned char *dest;  	assert(image->mt != mt); +	assert(dstlvl->valid);  	assert(dstlvl->width == image->base.Width);  	assert(dstlvl->height == image->base.Height);  	assert(dstlvl->depth == image->base.Depth); @@ -442,6 +421,7 @@ static void migrate_image_to_miptree(radeon_mipmap_tree *mt,  		radeon_mipmap_level *srclvl = &image->mt->levels[image->mtlevel]; +		assert(image->mtlevel == level);  		assert(srclvl->size == dstlvl->size);  		assert(srclvl->rowstride == dstlvl->rowstride); @@ -479,7 +459,7 @@ static void migrate_image_to_miptree(radeon_mipmap_tree *mt,  	radeon_miptree_reference(mt, &image->mt);  	image->mtface = face; -	image->mtlevel = mtLevel; +	image->mtlevel = level;  }  /** @@ -603,7 +583,7 @@ int radeon_validate_texture_miptree(GLcontext * ctx, struct gl_texture_object *t  				if (src_bo && radeon_bo_is_referenced_by_cs(src_bo, rmesa->cmdbuf.cs)) {  					radeon_firevertices(rmesa);  				} -				migrate_image_to_miptree(dst_miptree, img, face, radeon_gl_level_to_miptree_level(texObj, level)); +				migrate_image_to_miptree(dst_miptree, img, face, level);  			} else if (RADEON_DEBUG & RADEON_TEXTURE) {  				fprintf(stderr, "OK\n");  			} diff --git a/src/mesa/drivers/dri/radeon/radeon_mipmap_tree.h b/src/mesa/drivers/dri/radeon/radeon_mipmap_tree.h index 28b8485095..a10649b5ae 100644 --- a/src/mesa/drivers/dri/radeon/radeon_mipmap_tree.h +++ b/src/mesa/drivers/dri/radeon/radeon_mipmap_tree.h @@ -44,6 +44,7 @@ struct _radeon_mipmap_level {  	GLuint depth;  	GLuint size; /** Size of each image, in bytes */  	GLuint rowstride; /** in bytes */ +	GLuint valid;  	radeon_mipmap_image faces[6];  }; @@ -70,9 +71,9 @@ struct _radeon_mipmap_tree {  	GLuint baseLevel; /** gl_texture_object->baseLevel it was created for */  	GLuint numLevels; /** Number of mip levels stored in this mipmap tree */ -	GLuint width0; /** Width of firstLevel image */ -	GLuint height0; /** Height of firstLevel image */ -	GLuint depth0; /** Depth of firstLevel image */ +	GLuint width0; /** Width of baseLevel image */ +	GLuint height0; /** Height of baseLevel image */ +	GLuint depth0; /** Depth of baseLevel image */  	GLuint tilebits; /** RADEON_TXO_xxx_TILE */ @@ -89,8 +90,5 @@ GLuint radeon_miptree_image_offset(radeon_mipmap_tree *mt,  				   GLuint face, GLuint level);  void radeon_miptree_depth_offsets(radeon_mipmap_tree *mt, GLuint level, GLuint *offsets); -unsigned radeon_miptree_level_to_gl_level(struct gl_texture_object *tObj, unsigned level); -unsigned radeon_gl_level_to_miptree_level(struct gl_texture_object *tObj, unsigned level); -  uint32_t get_base_teximage_offset(radeonTexObj *texObj);  #endif /* __RADEON_MIPMAP_TREE_H_ */ diff --git a/src/mesa/drivers/dri/radeon/radeon_texture.c b/src/mesa/drivers/dri/radeon/radeon_texture.c index c715650d55..0390d376ba 100644 --- a/src/mesa/drivers/dri/radeon/radeon_texture.c +++ b/src/mesa/drivers/dri/radeon/radeon_texture.c @@ -509,6 +509,27 @@ gl_format radeonChooseTextureFormat(GLcontext * ctx,  	return MESA_FORMAT_NONE;		/* never get here */  } +/** Check if given image is valid within current texture object. + */ +static int image_matches_texture_obj(struct gl_texture_object *texObj, +	struct gl_texture_image *texImage, +	unsigned level) +{ +	const struct gl_texture_image *baseImage = texObj->Image[0][level]; + +	if (level < texObj->BaseLevel || level > texObj->MaxLevel) +		return 0; + +	const unsigned levelDiff = level - texObj->BaseLevel; +	const unsigned refWidth = baseImage->Width >> levelDiff; +	const unsigned refHeight = baseImage->Height >> levelDiff; +	const unsigned refDepth = baseImage->Depth >> levelDiff; + +	return (texImage->Width == refWidth && +			texImage->Height == refHeight && +			texImage->Depth == refDepth); +} +  static void teximage_assign_miptree(radeonContextPtr rmesa,  	struct gl_texture_object *texObj,  	struct gl_texture_image *texImage, @@ -518,9 +539,14 @@ static void teximage_assign_miptree(radeonContextPtr rmesa,  	radeonTexObj *t = radeon_tex_obj(texObj);  	radeon_texture_image* image = get_radeon_texture_image(texImage); +	/* Since miptree holds only images for levels <BaseLevel..MaxLevel> +	 * don't allocate the miptree if the teximage won't fit. +	 */ +	if (!image_matches_texture_obj(texObj, texImage, level)) +		return; +  	/* Try using current miptree, or create new if there isn't any */ -	if (!t->mt || !radeon_miptree_matches_image(t->mt, texImage, face, -					radeon_gl_level_to_miptree_level(texObj, level))) { +	if (!t->mt || !radeon_miptree_matches_image(t->mt, texImage, face, level)) {  		radeon_miptree_unreference(&t->mt);  		radeon_try_alloc_miptree(rmesa, t);  		if (RADEON_DEBUG & RADEON_TEXTURE) { @@ -534,7 +560,7 @@ static void teximage_assign_miptree(radeonContextPtr rmesa,  	 * when there was no image for baselevel specified */  	if (t->mt) {  		image->mtface = face; -		image->mtlevel = radeon_gl_level_to_miptree_level(texObj, level); +		image->mtlevel = level;  		radeon_miptree_reference(t->mt, &image->mt);  	}  } @@ -590,6 +616,8 @@ static void radeon_store_teximage(GLcontext* ctx, int dims,  		dstRowStride = _mesa_format_row_stride(texImage->TexFormat, texImage->Width);  	} +	assert(dstRowStride); +  	if (dims == 3) {  		unsigned alignedWidth = dstRowStride/_mesa_get_format_bytes(texImage->TexFormat);  		dstImageOffsets = allocate_image_offsets(ctx, alignedWidth, texImage->Height, texImage->Depth); @@ -704,7 +732,7 @@ static void radeon_teximage(  	if (!t->bo) {  		teximage_assign_miptree(rmesa, texObj, texImage, face, level); -		if (!t->mt) { +		if (!image->mt) {  			int size = _mesa_format_image_size(texImage->TexFormat,  								texImage->Width,  								texImage->Height, | 
