Mesa (master): r600: add ARB_texture_non_power_of_two support.

Dave Airlie airlied at kemper.freedesktop.org
Wed Nov 25 05:49:17 UTC 2009


Module: Mesa
Branch: master
Commit: ce56a867f71d0a74172a00869a3c5cb1862f4b04
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=ce56a867f71d0a74172a00869a3c5cb1862f4b04

Author: Dave Airlie <airlied at redhat.com>
Date:   Wed Nov 25 15:45:31 2009 +1000

r600: add ARB_texture_non_power_of_two support.

This makes the miptree rounds up to the near POT for each level for
all radeons, however since mipmaps aren't support with NPOT on previous
radeons this calculation shouldn't cause any problems. If it does
we can just make it r600 only.

I tested a few mipmap demos on r500 and they all seem to work.

Signed-off-by: Dave Airlie <airlied at redhat.com>

---

 src/mesa/drivers/dri/r600/r600_context.c         |    2 +-
 src/mesa/drivers/dri/radeon/radeon_mipmap_tree.c |   26 +++++++++++++++++----
 2 files changed, 22 insertions(+), 6 deletions(-)

diff --git a/src/mesa/drivers/dri/r600/r600_context.c b/src/mesa/drivers/dri/r600/r600_context.c
index 7de29e5..25314ef 100644
--- a/src/mesa/drivers/dri/r600/r600_context.c
+++ b/src/mesa/drivers/dri/r600/r600_context.c
@@ -111,6 +111,7 @@ static const struct dri_extension card_extensions[] = {
   {"GL_ARB_texture_env_crossbar",	NULL},
   {"GL_ARB_texture_env_dot3",		NULL},
   {"GL_ARB_texture_mirrored_repeat",	NULL},
+  {"GL_ARB_texture_non_power_of_two",   NULL},
   {"GL_ARB_vertex_program",		GL_ARB_vertex_program_functions},
   {"GL_EXT_blend_equation_separate",	GL_EXT_blend_equation_separate_functions},
   {"GL_EXT_blend_func_separate",	GL_EXT_blend_func_separate_functions},
@@ -327,7 +328,6 @@ static void r600InitGLExtensions(GLcontext *ctx)
     ctx->Extensions.ARB_shader_objects = GL_TRUE;
     ctx->Extensions.ARB_vertex_shader = GL_TRUE;
     ctx->Extensions.ARB_fragment_shader = GL_TRUE;
-    ctx->Extensions.ARB_texture_non_power_of_two = GL_TRUE;
     ctx->Extensions.EXT_blend_equation_separate = GL_TRUE;
     ctx->Extensions.ATI_separate_stencil = GL_TRUE;
 
diff --git a/src/mesa/drivers/dri/radeon/radeon_mipmap_tree.c b/src/mesa/drivers/dri/radeon/radeon_mipmap_tree.c
index 46603de..f2f7b2a 100644
--- a/src/mesa/drivers/dri/radeon/radeon_mipmap_tree.c
+++ b/src/mesa/drivers/dri/radeon/radeon_mipmap_tree.c
@@ -68,6 +68,19 @@ static unsigned get_compressed_image_size(
 	return rowStride * ((height + blockHeight - 1) / blockHeight);
 }
 
+static int find_next_power_of_two(GLuint value)
+{
+	int i, tmp;
+
+	i = 0;
+	tmp = value - 1;
+	while (tmp) {
+		tmp >>= 1;
+		i++;
+	}
+	return (1 << i);
+}
+
 /**
  * Compute sizes and fill in offset and blit information for the given
  * image (determined by \p face and \p level).
@@ -80,25 +93,28 @@ static void compute_tex_image_offset(radeonContextPtr rmesa, radeon_mipmap_tree
 {
 	radeon_mipmap_level *lvl = &mt->levels[level];
 	uint32_t row_align;
+	GLuint height;
+
+	height = find_next_power_of_two(lvl->height);
 
 	/* Find image size in bytes */
 	if (_mesa_is_format_compressed(mt->mesaFormat)) {
 		lvl->rowstride = get_aligned_compressed_row_stride(mt->mesaFormat, lvl->width, rmesa->texture_compressed_row_align);
-		lvl->size = get_compressed_image_size(mt->mesaFormat, lvl->rowstride, lvl->height);
+		lvl->size = get_compressed_image_size(mt->mesaFormat, lvl->rowstride, height);
 	} else if (mt->target == GL_TEXTURE_RECTANGLE_NV) {
 		row_align = rmesa->texture_rect_row_align - 1;
 		lvl->rowstride = (_mesa_format_row_stride(mt->mesaFormat, lvl->width) + row_align) & ~row_align;
-		lvl->size = lvl->rowstride * lvl->height;
+		lvl->size = lvl->rowstride * height;
 	} else if (mt->tilebits & RADEON_TXO_MICRO_TILE) {
 		/* 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 = (_mesa_format_row_stride(mt->mesaFormat, lvl->width) * 2 + 31) & ~31;
-		lvl->size = lvl->rowstride * ((lvl->height + 1) / 2) * lvl->depth;
+		lvl->size = lvl->rowstride * ((height + 1) / 2) * lvl->depth;
 	} else {
 		row_align = rmesa->texture_row_align - 1;
 		lvl->rowstride = (_mesa_format_row_stride(mt->mesaFormat, lvl->width) + row_align) & ~row_align;
-		lvl->size = lvl->rowstride * lvl->height * lvl->depth;
+		lvl->size = lvl->rowstride * height * lvl->depth;
 	}
 	assert(lvl->size > 0);
 
@@ -110,7 +126,7 @@ static void compute_tex_image_offset(radeonContextPtr rmesa, radeon_mipmap_tree
 	if (RADEON_DEBUG & RADEON_TEXTURE)
 	  fprintf(stderr,
 		  "level %d, face %d: rs:%d %dx%d at %d\n",
-		  level, face, lvl->rowstride, lvl->width, lvl->height, lvl->faces[face].offset);
+		  level, face, lvl->rowstride, lvl->width, height, lvl->faces[face].offset);
 }
 
 static GLuint minify(GLuint size, GLuint levels)




More information about the mesa-commit mailing list