r600: add ARB_texture_non_power_of_two support.
authorDave Airlie <airlied@redhat.com>
Wed, 25 Nov 2009 05:45:31 +0000 (15:45 +1000)
committerDave Airlie <airlied@redhat.com>
Wed, 25 Nov 2009 05:45:31 +0000 (15:45 +1000)
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@redhat.com>
src/mesa/drivers/dri/r600/r600_context.c
src/mesa/drivers/dri/radeon/radeon_mipmap_tree.c

index 7de29e5bb87aea3a43bb215e6460f784fa7b5077..25314eff56320caa11e92c77606cb6d1bd467026 100644 (file)
@@ -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;
 
index 46603de2e76c338c56642edeb28ca24ca27856dc..f2f7b2a9fdca7e36e6fe9d7341bd856ce4df28a1 100644 (file)
@@ -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)