radeon: fix scissors harder.
[mesa.git] / src / mesa / drivers / dri / radeon / radeon_texture.c
index 429ad50a7d46ec239b17d526af14c56f549c3248..fa16f44c18e85c92804082660d7caaea75727be2 100644 (file)
@@ -512,7 +512,7 @@ const struct gl_texture_format *radeonChooseTextureFormat(GLcontext * ctx,
  */
 static void radeon_teximage(
        GLcontext *ctx, int dims,
-       GLint face, GLint level,
+       GLenum target, GLint level,
        GLint internalFormat,
        GLint width, GLint height, GLint depth,
        GLsizei imageSize,
@@ -529,6 +529,7 @@ static void radeon_teximage(
        GLint postConvWidth = width;
        GLint postConvHeight = height;
        GLuint texelBytes;
+       GLuint face = radeon_face_for_target(target);
 
        radeon_firevertices(rmesa);
 
@@ -609,9 +610,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;
@@ -653,7 +662,7 @@ static void radeon_teximage(
 
                /* SGIS_generate_mipmap */
                if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
-                       radeon_generate_mipmap(ctx, texObj->Target, texObj);
+                       radeon_generate_mipmap(ctx, target, texObj);
                }
        }
 
@@ -673,7 +682,7 @@ void radeonTexImage1D(GLcontext * ctx, GLenum target, GLint level,
                      struct gl_texture_object *texObj,
                      struct gl_texture_image *texImage)
 {
-       radeon_teximage(ctx, 1, 0, level, internalFormat, width, 1, 1,
+       radeon_teximage(ctx, 1, target, level, internalFormat, width, 1, 1,
                0, format, type, pixels, packing, texObj, texImage, 0);
 }
 
@@ -686,9 +695,7 @@ void radeonTexImage2D(GLcontext * ctx, GLenum target, GLint level,
                           struct gl_texture_image *texImage)
 
 {
-       GLuint face = radeon_face_for_target(target);
-
-       radeon_teximage(ctx, 2, face, level, internalFormat, width, height, 1,
+       radeon_teximage(ctx, 2, target, level, internalFormat, width, height, 1,
                0, format, type, pixels, packing, texObj, texImage, 0);
 }
 
@@ -699,9 +706,7 @@ void radeonCompressedTexImage2D(GLcontext * ctx, GLenum target,
                                     struct gl_texture_object *texObj,
                                     struct gl_texture_image *texImage)
 {
-       GLuint face = radeon_face_for_target(target);
-
-       radeon_teximage(ctx, 2, face, level, internalFormat, width, height, 1,
+       radeon_teximage(ctx, 2, target, level, internalFormat, width, height, 1,
                imageSize, 0, 0, data, &ctx->Unpack, texObj, texImage, 1);
 }
 
@@ -714,14 +719,14 @@ void radeonTexImage3D(GLcontext * ctx, GLenum target, GLint level,
                      struct gl_texture_object *texObj,
                      struct gl_texture_image *texImage)
 {
-       radeon_teximage(ctx, 3, 0, level, internalFormat, width, height, depth,
+       radeon_teximage(ctx, 3, target, level, internalFormat, width, height, depth,
                0, format, type, pixels, packing, texObj, texImage, 0);
 }
 
 /**
  * Update a subregion of the given texture image.
  */
-static void radeon_texsubimage(GLcontext* ctx, int dims, int level,
+static void radeon_texsubimage(GLcontext* ctx, int dims, GLenum target, int level,
                GLint xoffset, GLint yoffset, GLint zoffset,
                GLsizei width, GLsizei height, GLsizei depth,
                GLsizei imageSize,
@@ -759,14 +764,23 @@ static void radeon_texsubimage(GLcontext* ctx, int dims, int level,
                }
 
                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,
@@ -781,7 +795,7 @@ static void radeon_texsubimage(GLcontext* ctx, int dims, int level,
 
                /* GL_SGIS_generate_mipmap */
                if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
-                       radeon_generate_mipmap(ctx, texObj->Target, texObj);
+                       radeon_generate_mipmap(ctx, target, texObj);
                }
        }
 
@@ -801,7 +815,7 @@ void radeonTexSubImage1D(GLcontext * ctx, GLenum target, GLint level,
                         struct gl_texture_object *texObj,
                         struct gl_texture_image *texImage)
 {
-       radeon_texsubimage(ctx, 1, level, xoffset, 0, 0, width, 1, 1, 0,
+       radeon_texsubimage(ctx, 1, target, level, xoffset, 0, 0, width, 1, 1, 0,
                format, type, pixels, packing, texObj, texImage, 0);
 }
 
@@ -814,7 +828,7 @@ void radeonTexSubImage2D(GLcontext * ctx, GLenum target, GLint level,
                         struct gl_texture_object *texObj,
                         struct gl_texture_image *texImage)
 {
-       radeon_texsubimage(ctx, 2, level, xoffset, yoffset, 0, width, height, 1,
+       radeon_texsubimage(ctx, 2, target, level, xoffset, yoffset, 0, width, height, 1,
                           0, format, type, pixels, packing, texObj, texImage,
                           0);
 }
@@ -827,7 +841,7 @@ void radeonCompressedTexSubImage2D(GLcontext * ctx, GLenum target,
                                   struct gl_texture_object *texObj,
                                   struct gl_texture_image *texImage)
 {
-       radeon_texsubimage(ctx, 2, level, xoffset, yoffset, 0, width, height, 1,
+       radeon_texsubimage(ctx, 2, target, level, xoffset, yoffset, 0, width, height, 1,
                imageSize, format, 0, data, &ctx->Unpack, texObj, texImage, 1);
 }
 
@@ -841,7 +855,7 @@ void radeonTexSubImage3D(GLcontext * ctx, GLenum target, GLint level,
                         struct gl_texture_object *texObj,
                         struct gl_texture_image *texImage)
 {
-       radeon_texsubimage(ctx, 3, level, xoffset, yoffset, zoffset, width, height, depth, 0,
+       radeon_texsubimage(ctx, 3, target, level, xoffset, yoffset, zoffset, width, height, depth, 0,
                format, type, pixels, packing, texObj, texImage, 0);
 }
 
@@ -887,8 +901,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;
@@ -954,7 +968,7 @@ int radeon_validate_texture_miptree(GLcontext * ctx, struct gl_texture_object *t
                        fprintf(stderr, " Allocate new miptree\n");
                radeon_try_alloc_miptree(rmesa, t, &baseimage->base, 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;
                }
        }
@@ -968,6 +982,7 @@ int radeon_validate_texture_miptree(GLcontext * ctx, struct gl_texture_object *t
                        if (t->mt == image->mt) {
                                if (RADEON_DEBUG & DEBUG_TEXTURE)
                                        fprintf(stderr, "OK\n");
+
                                continue;
                        }
 
@@ -1002,6 +1017,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 {