Mesa (radeon-rewrite): radeon: fix compressed texture upload on all radeons

Dave Airlie airlied at kemper.freedesktop.org
Fri Feb 13 04:47:18 UTC 2009


Module: Mesa
Branch: radeon-rewrite
Commit: 9fd8da299b4a62c6baf49f08067d7c1ddebb0ffd
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=9fd8da299b4a62c6baf49f08067d7c1ddebb0ffd

Author: Dave Airlie <airlied at redhat.com>
Date:   Fri Feb 13 22:49:06 2009 +1000

radeon: fix compressed texture upload on all radeons

tested on r200, texcmp works. May need more verification

---

 src/mesa/drivers/dri/radeon/radeon_mipmap_tree.c |   42 +++++++++++++----
 src/mesa/drivers/dri/radeon/radeon_texture.c     |   55 ++++++++++++++++-----
 2 files changed, 75 insertions(+), 22 deletions(-)

diff --git a/src/mesa/drivers/dri/radeon/radeon_mipmap_tree.c b/src/mesa/drivers/dri/radeon/radeon_mipmap_tree.c
index c21d297..45c1d71 100644
--- a/src/mesa/drivers/dri/radeon/radeon_mipmap_tree.c
+++ b/src/mesa/drivers/dri/radeon/radeon_mipmap_tree.c
@@ -56,6 +56,29 @@ static GLuint radeon_compressed_texture_size(GLcontext *ctx,
 	return size;
 }
 
+
+static int radeon_compressed_num_bytes(GLuint mesaFormat)
+{
+   int bytes = 0;
+   switch(mesaFormat) {
+     
+   case MESA_FORMAT_RGB_FXT1:
+   case MESA_FORMAT_RGBA_FXT1:
+   case MESA_FORMAT_RGB_DXT1:
+   case MESA_FORMAT_RGBA_DXT1:
+     bytes = 2;
+     break;
+     
+   case MESA_FORMAT_RGBA_DXT3:
+   case MESA_FORMAT_RGBA_DXT5:
+     bytes = 4;
+   default:
+     break;
+   }
+   
+   return bytes;
+}
+
 /**
  * Compute sizes and fill in offset and blit information for the given
  * image (determined by \p face and \p level).
@@ -73,18 +96,14 @@ static void compute_tex_image_offset(radeon_mipmap_tree *mt,
 		/* TODO: Is this correct? Need test cases for compressed textures! */
 		GLuint align;
 
-		if (mt->target == GL_TEXTURE_RECTANGLE_NV)
-			align = 64 / mt->bpp;
-		else
-			align = 32 / mt->bpp;
-		lvl->rowstride = (lvl->width + align - 1) & ~(align - 1);
+		lvl->rowstride = (lvl->width * mt->bpp + 63) & ~63;
 		lvl->size = radeon_compressed_texture_size(mt->radeon->glCtx,
-			lvl->width, lvl->height, lvl->depth, mt->compressed);
+							   lvl->width, lvl->height, lvl->depth, mt->compressed);
 	} else if (mt->target == GL_TEXTURE_RECTANGLE_NV) {
 		lvl->rowstride = (lvl->width * mt->bpp + 63) & ~63;
 		lvl->size = lvl->rowstride * lvl->height;
 	} else if (mt->tilebits & RADEON_TXO_MICRO_TILE) {
-	  /* tile pattern is 16 bytes x2. mipmaps stay 32 byte aligned,
+		/* tile pattern is 16 bytes x2. mipmaps stay 32 byte aligned,
 		 * though the actual offset may be different (if texture is less than
 		 * 32 bytes width) to the untiled case */
 		lvl->rowstride = (lvl->width * mt->bpp * 2 + 31) & ~31;
@@ -160,7 +179,7 @@ radeon_mipmap_tree* radeon_miptree_create(radeonContextPtr rmesa, radeonTexObj *
 	mt->width0 = width0;
 	mt->height0 = height0;
 	mt->depth0 = depth0;
-	mt->bpp = bpp;
+	mt->bpp = compressed ? radeon_compressed_num_bytes(compressed) : bpp;
 	mt->tilebits = tilebits;
 	mt->compressed = compressed;
 
@@ -255,7 +274,12 @@ GLboolean radeon_miptree_matches_image(radeon_mipmap_tree *mt,
 	if (face >= mt->faces || level < mt->firstLevel || level > mt->lastLevel)
 		return GL_FALSE;
 
-	if (texImage->TexFormat->TexelBytes != mt->bpp)
+	if (texImage->IsCompressed != mt->compressed)
+		return GL_FALSE;
+
+	if (!texImage->IsCompressed &&
+	    !mt->compressed &&
+	    texImage->TexFormat->TexelBytes != mt->bpp)
 		return GL_FALSE;
 
 	lvl = &mt->levels[level - mt->firstLevel];
diff --git a/src/mesa/drivers/dri/radeon/radeon_texture.c b/src/mesa/drivers/dri/radeon/radeon_texture.c
index beb21e7..eb87a0d 100644
--- a/src/mesa/drivers/dri/radeon/radeon_texture.c
+++ b/src/mesa/drivers/dri/radeon/radeon_texture.c
@@ -32,6 +32,7 @@
 #include "main/imports.h"
 #include "main/context.h"
 #include "main/mipmap.h"
+#include "main/texcompress.h"
 #include "main/texformat.h"
 #include "main/texstore.h"
 #include "main/teximage.h"
@@ -453,16 +454,26 @@ static void radeon_teximage(
 	radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
 	radeonTexObj* t = radeon_tex_obj(texObj);
 	radeon_texture_image* image = get_radeon_texture_image(texImage);
+	GLuint dstRowStride;
+	GLint postConvWidth = width;
+	GLint postConvHeight = height;
+	GLuint texelBytes;
 
 	radeon_firevertices(rmesa);
 
 	t->validated = GL_FALSE;
 
+	if (ctx->_ImageTransferState & IMAGE_CONVOLUTION_BIT) {
+	       _mesa_adjust_image_for_convolution(ctx, dims, &postConvWidth,
+						  &postConvHeight);
+	}
+
 	/* Choose and fill in the texture format for this image */
 	texImage->TexFormat = radeonChooseTextureFormat(ctx, internalFormat, format, type);
 	_mesa_set_fetch_functions(texImage, dims);
 
 	if (texImage->TexFormat->TexelBytes == 0) {
+		texelBytes = 0;
 		texImage->IsCompressed = GL_TRUE;
 		texImage->CompressedSize =
 			ctx->Driver.CompressedTextureSize(ctx, texImage->Width,
@@ -471,6 +482,16 @@ static void radeon_teximage(
 	} else {
 		texImage->IsCompressed = GL_FALSE;
 		texImage->CompressedSize = 0;
+
+		texelBytes = texImage->TexFormat->TexelBytes;
+		/* Minimum pitch of 32 bytes */
+		if (postConvWidth * texelBytes < 32) {
+		  postConvWidth = 32 / texelBytes;
+		  texImage->RowStride = postConvWidth;
+		}
+		if (!image->mt) {      
+			assert(texImage->RowStride == postConvWidth);
+		}
 	}
 
 	/* Allocate memory for image */
@@ -479,16 +500,22 @@ static void radeon_teximage(
 	if (!t->mt)
 		radeon_try_alloc_miptree(rmesa, t, texImage, face, level);
 	if (t->mt && radeon_miptree_matches_image(t->mt, texImage, face, level)) {
+		radeon_mipmap_level *lvl;
 		image->mt = t->mt;
 		image->mtlevel = level - t->mt->firstLevel;
 		image->mtface = face;
 		radeon_miptree_reference(t->mt);
+		lvl = &image->mt->levels[image->mtlevel];
+		dstRowStride = lvl->rowstride;
 	} else {
 		int size;
 		if (texImage->IsCompressed) {
 			size = texImage->CompressedSize;
+			dstRowStride =
+			  _mesa_compressed_row_stride(texImage->TexFormat->MesaFormat, width);
 		} else {
 			size = texImage->Width * texImage->Height * texImage->Depth * texImage->TexFormat->TexelBytes;
+			dstRowStride = postConvWidth * texelBytes;
 		}
 		texImage->Data = _mesa_alloc_texmemory(size);
 	}
@@ -509,13 +536,6 @@ static void radeon_teximage(
 		if (compressed) {
 			memcpy(texImage->Data, pixels, imageSize);
 		} else {
-			GLuint dstRowStride;
-			if (image->mt) {
-				radeon_mipmap_level *lvl = &image->mt->levels[image->mtlevel];
-				dstRowStride = lvl->rowstride;
-			} else {
-				dstRowStride = texImage->Width * texImage->TexFormat->TexelBytes;
-			}
 			if (!texImage->TexFormat->StoreImage(ctx, dims,
 						texImage->_BaseFormat,
 						texImage->TexFormat,
@@ -534,11 +554,11 @@ static void radeon_teximage(
 		radeon_generate_mipmap(ctx, texObj->Target, texObj);
 	}
 
-	if (pixels) 
-	  radeon_teximage_unmap(image);
-
 	_mesa_unmap_teximage_pbo(ctx, packing);
 
+	if (pixels)
+	  radeon_teximage_unmap(image);
+
 
 }
 
@@ -579,7 +599,7 @@ void radeonCompressedTexImage2D(GLcontext * ctx, GLenum target,
 	GLuint face = radeon_face_for_target(target);
 
 	radeon_teximage(ctx, 2, face, level, internalFormat, width, height, 1,
-		imageSize, 0, 0, data, 0, texObj, texImage, 1);
+		imageSize, 0, 0, data, &ctx->Unpack, texObj, texImage, 1);
 }
 
 void radeonTexImage3D(GLcontext * ctx, GLenum target, GLint level,
@@ -760,13 +780,22 @@ static void migrate_image_to_miptree(radeon_mipmap_tree *mt, radeon_texture_imag
 
 		radeon_miptree_unreference(image->mt);
 	} else {
-		uint srcrowstride = image->base.Width * image->base.TexFormat->TexelBytes;
+		uint32_t srcrowstride;
+		uint32_t height;
+		/* need to confirm this value is correct */
+		if (mt->compressed) {
+			height = image->base.Height / 4;
+			srcrowstride = image->base.RowStride * mt->bpp;
+		} else {
+			height = image->base.Height * image->base.Depth;
+			srcrowstride = image->base.Width * image->base.TexFormat->TexelBytes;
+		}
 
 //		if (mt->tilebits)
 //			WARN_ONCE("%s: tiling not supported yet", __FUNCTION__);
 
 		copy_rows(dest, dstlvl->rowstride, image->base.Data, srcrowstride,
-			image->base.Height * image->base.Depth, srcrowstride);
+			  height, srcrowstride);
 
 		_mesa_free_texmemory(image->base.Data);
 		image->base.Data = 0;




More information about the mesa-commit mailing list