radeon: emit scissor when using cs path
[mesa.git] / src / mesa / drivers / dri / radeon / radeon_texture.c
index a256440a3c5ae1f2599ce8ff3ea91662751b7562..35ed54243116fe512afb7017c0e679e939408312 100644 (file)
 
 #include "radeon_mipmap_tree.h"
 
+
+static void copy_rows(void* dst, GLuint dststride, const void* src, GLuint srcstride,
+       GLuint numrows, GLuint rowsize)
+{
+       assert(rowsize <= dststride);
+       assert(rowsize <= srcstride);
+
+       if (rowsize == srcstride && rowsize == dststride) {
+               memcpy(dst, src, numrows*rowsize);
+       } else {
+               GLuint i;
+               for(i = 0; i < numrows; ++i) {
+                       memcpy(dst, src, rowsize);
+                       dst += dststride;
+                       src += srcstride;
+               }
+       }
+}
+
 /* textures */
 /**
  * Allocate an empty texture image object.
@@ -112,6 +131,25 @@ void radeon_teximage_unmap(radeon_texture_image *image)
        }
 }
 
+static void map_override(GLcontext *ctx, radeonTexObj *t)
+{
+       radeon_texture_image *img = get_radeon_texture_image(t->base.Image[0][0]);
+
+       radeon_bo_map(t->bo, GL_FALSE);
+
+       img->base.Data = t->bo->ptr;
+       _mesa_set_fetch_functions(&img->base, 2);
+}
+
+static void unmap_override(GLcontext *ctx, radeonTexObj *t)
+{
+       radeon_texture_image *img = get_radeon_texture_image(t->base.Image[0][0]);
+
+       radeon_bo_unmap(t->bo);
+
+       img->base.Data = NULL;
+}
+
 /**
  * Map a validated texture for reading during software rendering.
  */
@@ -120,9 +158,15 @@ void radeonMapTexture(GLcontext *ctx, struct gl_texture_object *texObj)
        radeonTexObj* t = radeon_tex_obj(texObj);
        int face, level;
 
+       if (!radeon_validate_texture_miptree(ctx, texObj))
+         return;
+
        /* for r100 3D sw fallbacks don't have mt */
+       if (t->image_override && t->bo)
+               map_override(ctx, t);
+
        if (!t->mt)
-         return;
+               return;
 
        radeon_bo_map(t->mt->bo, GL_FALSE);
        for(face = 0; face < t->mt->faces; ++face) {
@@ -136,6 +180,8 @@ void radeonUnmapTexture(GLcontext *ctx, struct gl_texture_object *texObj)
        radeonTexObj* t = radeon_tex_obj(texObj);
        int face, level;
 
+       if (t->image_override && t->bo)
+               unmap_override(ctx, t);
        /* for r100 3D sw fallbacks don't have mt */
        if (!t->mt)
          return;
@@ -211,13 +257,13 @@ void radeonGenerateMipmap(GLcontext* ctx, GLenum target, struct gl_texture_objec
 /* try to find a format which will only need a memcopy */
 static const struct gl_texture_format *radeonChoose8888TexFormat(radeonContextPtr rmesa,
                                                                 GLenum srcFormat,
-                                                                GLenum srcType)
+                                                                GLenum srcType, GLboolean fbo)
 {
        const GLuint ui = 1;
        const GLubyte littleEndian = *((const GLubyte *)&ui);
 
        /* r100 can only do this */
-       if (IS_R100_CLASS(rmesa->radeonScreen))
+       if (IS_R100_CLASS(rmesa->radeonScreen) || fbo)
          return _dri_texformat_argb8888;
 
        if ((srcFormat == GL_RGBA && srcType == GL_UNSIGNED_INT_8_8_8_8) ||
@@ -230,6 +276,8 @@ static const struct gl_texture_format *radeonChoose8888TexFormat(radeonContextPt
                   (srcFormat == GL_ABGR_EXT && srcType == GL_UNSIGNED_INT_8_8_8_8) ||
                   (srcFormat == GL_ABGR_EXT && srcType == GL_UNSIGNED_BYTE && !littleEndian)) {
                return &_mesa_texformat_rgba8888_rev;
+       } else if (IS_R200_CLASS(rmesa->radeonScreen)) {
+               return _dri_texformat_argb8888;
        } else if (srcFormat == GL_BGRA && ((srcType == GL_UNSIGNED_BYTE && !littleEndian) ||
                                            srcType == GL_UNSIGNED_INT_8_8_8_8)) {
                return &_mesa_texformat_argb8888_rev;
@@ -240,10 +288,19 @@ static const struct gl_texture_format *radeonChoose8888TexFormat(radeonContextPt
                return _dri_texformat_argb8888;
 }
 
-const struct gl_texture_format *radeonChooseTextureFormat(GLcontext * ctx,
+const struct gl_texture_format *radeonChooseTextureFormat_mesa(GLcontext * ctx,
                                                          GLint internalFormat,
                                                          GLenum format,
                                                          GLenum type)
+{
+       return radeonChooseTextureFormat(ctx, internalFormat, format,
+                                        type, 0);
+}
+
+const struct gl_texture_format *radeonChooseTextureFormat(GLcontext * ctx,
+                                                         GLint internalFormat,
+                                                         GLenum format,
+                                                         GLenum type, GLboolean fbo)
 {
        radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
        const GLboolean do32bpt =
@@ -275,7 +332,7 @@ const struct gl_texture_format *radeonChooseTextureFormat(GLcontext * ctx,
                case GL_UNSIGNED_SHORT_1_5_5_5_REV:
                        return _dri_texformat_argb1555;
                default:
-                       return do32bpt ? radeonChoose8888TexFormat(rmesa, format, type) :
+                       return do32bpt ? radeonChoose8888TexFormat(rmesa, format, type, fbo) :
                            _dri_texformat_argb4444;
                }
 
@@ -302,7 +359,7 @@ const struct gl_texture_format *radeonChooseTextureFormat(GLcontext * ctx,
        case GL_RGBA12:
        case GL_RGBA16:
                return !force16bpt ?
-                       radeonChoose8888TexFormat(rmesa, format,type) :
+                       radeonChoose8888TexFormat(rmesa, format, type, fbo) :
                        _dri_texformat_argb4444;
 
        case GL_RGBA4:
@@ -330,8 +387,12 @@ const struct gl_texture_format *radeonChooseTextureFormat(GLcontext * ctx,
        case GL_ALPHA12:
        case GL_ALPHA16:
        case GL_COMPRESSED_ALPHA:
-               return _dri_texformat_a8;
-
+               /* r200: can't use a8 format since interpreting hw I8 as a8 would result
+                  in wrong rgb values (same as alpha value instead of 0). */
+               if (IS_R200_CLASS(rmesa->radeonScreen))
+                       return _dri_texformat_al88;
+               else
+                       return _dri_texformat_a8;
        case 1:
        case GL_LUMINANCE:
        case GL_LUMINANCE4:
@@ -412,25 +473,13 @@ const struct gl_texture_format *radeonChooseTextureFormat(GLcontext * ctx,
        case GL_DEPTH_COMPONENT16:
        case GL_DEPTH_COMPONENT24:
        case GL_DEPTH_COMPONENT32:
-#if 0
-               switch (type) {
-               case GL_UNSIGNED_BYTE:
-               case GL_UNSIGNED_SHORT:
-                       return &_mesa_texformat_z16;
-               case GL_UNSIGNED_INT:
-                       return &_mesa_texformat_z32;
-               case GL_UNSIGNED_INT_24_8_EXT:
-               default:
-                       return &_mesa_texformat_z24_s8;
-               }
-#else
-               return &_mesa_texformat_z16;
-#endif
-
+       case GL_DEPTH_STENCIL_EXT:
+       case GL_DEPTH24_STENCIL8_EXT:
+               return &_mesa_texformat_s8_z24;
        default:
                _mesa_problem(ctx,
-                             "unexpected internalFormat 0x%x in r300ChooseTextureFormat",
-                             (int)internalFormat);
+                             "unexpected internalFormat 0x%x in %s",
+                             (int)internalFormat, __func__);
                return NULL;
        }
 
@@ -470,7 +519,7 @@ static void radeon_teximage(
        }
 
        /* Choose and fill in the texture format for this image */
-       texImage->TexFormat = radeonChooseTextureFormat(ctx, internalFormat, format, type);
+       texImage->TexFormat = radeonChooseTextureFormat(ctx, internalFormat, format, type, 0);
        _mesa_set_fetch_functions(texImage, dims);
 
        if (texImage->TexFormat->TexelBytes == 0) {
@@ -498,6 +547,15 @@ static void radeon_teximage(
        /* Allocate memory for image */
        radeonFreeTexImageData(ctx, texImage); /* Mesa core only clears texImage->Data but not image->mt */
 
+       if (t->mt &&
+           t->mt->firstLevel == level &&
+           t->mt->lastLevel == level &&
+           t->mt->target != GL_TEXTURE_CUBE_MAP_ARB &&
+           !radeon_miptree_matches_image(t->mt, texImage, face, level)) {
+         radeon_miptree_unreference(t->mt);
+         t->mt = NULL;
+       }
+
        if (!t->mt)
                radeon_try_alloc_miptree(rmesa, t, texImage, face, level);
        if (t->mt && radeon_miptree_matches_image(t->mt, texImage, face, level)) {
@@ -627,12 +685,13 @@ void radeonTexImage3D(GLcontext * ctx, GLenum target, GLint level,
 static void radeon_texsubimage(GLcontext* ctx, int dims, int level,
                GLint xoffset, GLint yoffset, GLint zoffset,
                GLsizei width, GLsizei height, GLsizei depth,
+               GLsizei imageSize,
                GLenum format, GLenum type,
                const GLvoid * pixels,
                const struct gl_pixelstore_attrib *packing,
                struct gl_texture_object *texObj,
                struct gl_texture_image *texImage,
-                              int compressed)
+               int compressed)
 {
        radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
        radeonTexObj* t = radeon_tex_obj(texObj);
@@ -641,8 +700,13 @@ static void radeon_texsubimage(GLcontext* ctx, int dims, int level,
        radeon_firevertices(rmesa);
 
        t->validated = GL_FALSE;
-       pixels = _mesa_validate_pbo_teximage(ctx, dims,
-               width, height, depth, format, type, pixels, packing, "glTexSubImage1D");
+       if (compressed) {
+               pixels = _mesa_validate_pbo_compressed_teximage(
+                       ctx, imageSize, pixels, packing, "glCompressedTexImage");
+       } else {
+               pixels = _mesa_validate_pbo_teximage(ctx, dims,
+                       width, height, depth, format, type, pixels, packing, "glTexSubImage1D");
+       }
 
        if (pixels) {
                GLint dstRowStride;
@@ -655,15 +719,26 @@ static void radeon_texsubimage(GLcontext* ctx, int dims, int level,
                        dstRowStride = texImage->RowStride * texImage->TexFormat->TexelBytes;
                }
 
-               if (!texImage->TexFormat->StoreImage(ctx, dims, texImage->_BaseFormat,
-                               texImage->TexFormat, texImage->Data,
-                               xoffset, yoffset, zoffset,
-                               dstRowStride,
-                               texImage->ImageOffsets,
-                               width, height, depth,
-                               format, type, pixels, packing))
-                       _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage");
-
+               if (compressed) {
+                       uint32_t srcRowStride, bytesPerRow, rows; 
+                       dstRowStride = _mesa_compressed_row_stride(texImage->TexFormat->MesaFormat, texImage->Width);
+                       srcRowStride = _mesa_compressed_row_stride(texImage->TexFormat->MesaFormat, width);
+                       bytesPerRow = srcRowStride;
+                       rows = height / 4;
+
+                       copy_rows(texImage->Data, dstRowStride,  image->base.Data, srcRowStride, rows,
+                                 bytesPerRow);
+                       
+               } else {
+                       if (!texImage->TexFormat->StoreImage(ctx, dims, texImage->_BaseFormat,
+                                                            texImage->TexFormat, texImage->Data,
+                                                            xoffset, yoffset, zoffset,
+                                                            dstRowStride,
+                                                            texImage->ImageOffsets,
+                                                            width, height, depth,
+                                                            format, type, pixels, packing))
+                               _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage");
+               }
 
        }
 
@@ -687,7 +762,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,
+       radeon_texsubimage(ctx, 1, level, xoffset, 0, 0, width, 1, 1, 0,
                format, type, pixels, packing, texObj, texImage, 0);
 }
 
@@ -700,8 +775,8 @@ 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, format, type, pixels, packing, texObj, texImage,
+       radeon_texsubimage(ctx, 2, level, xoffset, yoffset, 0, width, height, 1,
+                          0, format, type, pixels, packing, texObj, texImage,
                           0);
 }
 
@@ -714,7 +789,7 @@ void radeonCompressedTexSubImage2D(GLcontext * ctx, GLenum target,
                                   struct gl_texture_image *texImage)
 {
        radeon_texsubimage(ctx, 2, level, xoffset, yoffset, 0, width, height, 1,
-               format, 0, data, &ctx->Unpack, texObj, texImage, 1);
+               imageSize, format, 0, data, &ctx->Unpack, texObj, texImage, 1);
 }
 
 
@@ -727,27 +802,10 @@ 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,
+       radeon_texsubimage(ctx, 3, level, xoffset, yoffset, zoffset, width, height, depth, 0,
                format, type, pixels, packing, texObj, texImage, 0);
 }
 
-static void copy_rows(void* dst, GLuint dststride, const void* src, GLuint srcstride,
-       GLuint numrows, GLuint rowsize)
-{
-       assert(rowsize <= dststride);
-       assert(rowsize <= srcstride);
-
-       if (rowsize == srcstride && rowsize == dststride) {
-               memcpy(dst, src, numrows*rowsize);
-       } else {
-               GLuint i;
-               for(i = 0; i < numrows; ++i) {
-                       memcpy(dst, src, rowsize);
-                       dst += dststride;
-                       src += srcstride;
-               }
-       }
-}
 
 
 /**