Merge branch 'mesa_7_6_branch'
[mesa.git] / src / mesa / drivers / dri / radeon / radeon_texture.c
index ad501c454cec4e85a0f4e97026dfe6194816148c..7b7392b21798ef395f949ff5e7ec335d15932a4e 100644 (file)
@@ -101,7 +101,12 @@ void radeonFreeTexImageData(GLcontext *ctx, struct gl_texture_image *timage)
 /* Set Data pointer and additional data for mapped texture image */
 static void teximage_set_map_data(radeon_texture_image *image)
 {
-       radeon_mipmap_level *lvl = &image->mt->levels[image->mtlevel];
+       radeon_mipmap_level *lvl;
+
+       if (!image->mt)
+               return;
+
+       lvl = &image->mt->levels[image->mtlevel];
 
        image->base.Data = image->mt->bo->ptr + lvl->faces[image->mtface].offset;
        image->base.RowStride = lvl->rowstride / image->mt->bpp;
@@ -579,7 +584,7 @@ static void radeon_teximage(
        }
 
        if (!t->mt)
-               radeon_try_alloc_miptree(rmesa, t, texImage, face, level);
+               radeon_try_alloc_miptree(rmesa, t, image, face, level);
        if (t->mt && radeon_miptree_matches_image(t->mt, texImage, face, level)) {
                radeon_mipmap_level *lvl;
                image->mt = t->mt;
@@ -610,9 +615,17 @@ static void radeon_teximage(
 
        if (pixels) {
                radeon_teximage_map(image, GL_TRUE);
-
                if (compressed) {
-                       memcpy(texImage->Data, pixels, imageSize);
+                       if (image->mt) {
+                               uint32_t srcRowStride, bytesPerRow, rows;
+                               srcRowStride = _mesa_compressed_row_stride(texImage->TexFormat->MesaFormat, width);
+                               bytesPerRow = srcRowStride;
+                               rows = (height + 3) / 4;
+                               copy_rows(texImage->Data, image->mt->levels[level].rowstride,
+                                         pixels, srcRowStride, rows, bytesPerRow);
+                       } else {
+                               memcpy(texImage->Data, pixels, imageSize);
+                       }
                } else {
                        GLuint dstRowStride;
                        GLuint *dstImageOffsets;
@@ -651,11 +664,6 @@ static void radeon_teximage(
                        if (dims == 3)
                                _mesa_free(dstImageOffsets);
                }
-
-               /* SGIS_generate_mipmap */
-               if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
-                       radeon_generate_mipmap(ctx, target, texObj);
-               }
        }
 
        _mesa_unmap_teximage_pbo(ctx, packing);
@@ -756,14 +764,23 @@ static void radeon_texsubimage(GLcontext* ctx, int dims, GLenum target, int leve
                }
 
                if (compressed) {
-                       uint32_t srcRowStride, bytesPerRow, rows; 
-                       dstRowStride = _mesa_compressed_row_stride(texImage->TexFormat->MesaFormat, texImage->Width);
+                       uint32_t srcRowStride, bytesPerRow, rows;
+                       GLubyte *img_start;
+                       if (!image->mt) {
+                               dstRowStride = _mesa_compressed_row_stride(texImage->TexFormat->MesaFormat, texImage->Width);
+                               img_start = _mesa_compressed_image_address(xoffset, yoffset, 0,
+                                                                          texImage->TexFormat->MesaFormat,
+                                                                          texImage->Width, texImage->Data);
+                       }
+                       else {
+                               uint32_t blocks_x = dstRowStride / (image->mt->bpp * 4);
+                               img_start = texImage->Data + image->mt->bpp * 4 * (blocks_x * (yoffset / 4) + xoffset / 4);
+                       }
                        srcRowStride = _mesa_compressed_row_stride(texImage->TexFormat->MesaFormat, width);
                        bytesPerRow = srcRowStride;
-                       rows = height / 4;
+                       rows = (height + 3) / 4;
 
-                       copy_rows(texImage->Data, dstRowStride,  image->base.Data, srcRowStride, rows,
-                                 bytesPerRow);
+                       copy_rows(img_start, dstRowStride,  pixels, srcRowStride, rows,  bytesPerRow);
                        
                } else {
                        if (!texImage->TexFormat->StoreImage(ctx, dims, texImage->_BaseFormat,
@@ -775,11 +792,6 @@ static void radeon_texsubimage(GLcontext* ctx, int dims, GLenum target, int leve
                                                             format, type, pixels, packing))
                                _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage");
                }
-
-               /* GL_SGIS_generate_mipmap */
-               if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
-                       radeon_generate_mipmap(ctx, target, texObj);
-               }
        }
 
        radeon_teximage_unmap(image);
@@ -884,8 +896,8 @@ static void migrate_image_to_miptree(radeon_mipmap_tree *mt, radeon_texture_imag
                uint32_t height;
                /* need to confirm this value is correct */
                if (mt->compressed) {
-                       height = image->base.Height / 4;
-                       srcrowstride = image->base.RowStride * mt->bpp;
+                       height = (image->base.Height + 3) / 4;
+                       srcrowstride = _mesa_compressed_row_stride(image->base.TexFormat->MesaFormat, image->base.Width);
                } else {
                        height = image->base.Height * image->base.Depth;
                        srcrowstride = image->base.Width * image->base.TexFormat->TexelBytes;
@@ -919,7 +931,7 @@ int radeon_validate_texture_miptree(GLcontext * ctx, struct gl_texture_object *t
        if (t->validated || t->image_override)
                return GL_TRUE;
 
-       if (RADEON_DEBUG & DEBUG_TEXTURE)
+       if (RADEON_DEBUG & RADEON_TEXTURE)
                fprintf(stderr, "%s: Validating texture %p now\n", __FUNCTION__, texObj);
 
        if (baseimage->base.Border > 0)
@@ -947,11 +959,11 @@ int radeon_validate_texture_miptree(GLcontext * ctx, struct gl_texture_object *t
        }
 
        if (!t->mt) {
-               if (RADEON_DEBUG & DEBUG_TEXTURE)
+               if (RADEON_DEBUG & RADEON_TEXTURE)
                        fprintf(stderr, " Allocate new miptree\n");
-               radeon_try_alloc_miptree(rmesa, t, &baseimage->base, 0, texObj->BaseLevel);
+               radeon_try_alloc_miptree(rmesa, t, baseimage, 0, texObj->BaseLevel);
                if (!t->mt) {
-                       _mesa_problem(ctx, "r300_validate_texture failed to alloc miptree");
+                       _mesa_problem(ctx, "radeon_validate_texture failed to alloc miptree");
                        return GL_FALSE;
                }
        }
@@ -960,16 +972,16 @@ int radeon_validate_texture_miptree(GLcontext * ctx, struct gl_texture_object *t
        for(face = 0; face < t->mt->faces; ++face) {
                for(level = t->mt->firstLevel; level <= t->mt->lastLevel; ++level) {
                        radeon_texture_image *image = get_radeon_texture_image(texObj->Image[face][level]);
-                       if (RADEON_DEBUG & DEBUG_TEXTURE)
+                       if (RADEON_DEBUG & RADEON_TEXTURE)
                                fprintf(stderr, " face %i, level %i... %p vs %p ", face, level, t->mt, image->mt);
-                       if (t->mt == image->mt) {
-                               if (RADEON_DEBUG & DEBUG_TEXTURE)
+                       if (t->mt == image->mt || (!image->mt && !image->base.Data)) {
+                               if (RADEON_DEBUG & RADEON_TEXTURE)
                                        fprintf(stderr, "OK\n");
 
                                continue;
                        }
 
-                       if (RADEON_DEBUG & DEBUG_TEXTURE)
+                       if (RADEON_DEBUG & RADEON_TEXTURE)
                                fprintf(stderr, "migrating\n");
                        migrate_image_to_miptree(t->mt, image, face, level);
                }
@@ -1000,6 +1012,8 @@ radeon_get_tex_image(GLcontext * ctx, GLenum target, GLint level,
        }
 
        if (compressed) {
+               /* FIXME: this can't work for small textures (mips) which
+                        use different hw stride */
                _mesa_get_compressed_teximage(ctx, target, level, pixels,
                                              texObj, texImage);
        } else {