mesa: Switch generate_mipmaps_compressed() to using TexImage2D to upload.
[mesa.git] / src / mesa / drivers / dri / radeon / radeon_texture.c
index 2b655fbd953f8ebcc73c57d0fe18b7845f48fa36..ce0df32bfe43b69757f01ddc877f66f3ca051d56 100644 (file)
 #include "main/glheader.h"
 #include "main/imports.h"
 #include "main/context.h"
 #include "main/glheader.h"
 #include "main/imports.h"
 #include "main/context.h"
-#include "main/convolve.h"
 #include "main/enums.h"
 #include "main/enums.h"
+#include "main/mfeatures.h"
 #include "main/mipmap.h"
 #include "main/mipmap.h"
+#include "main/pbo.h"
 #include "main/texcompress.h"
 #include "main/texstore.h"
 #include "main/teximage.h"
 #include "main/texobj.h"
 #include "main/texcompress.h"
 #include "main/texstore.h"
 #include "main/teximage.h"
 #include "main/texobj.h"
+#include "drivers/common/meta.h"
 
 #include "xmlpool.h"           /* for symbolic values of enum-type options */
 
 
 #include "xmlpool.h"           /* for symbolic values of enum-type options */
 
@@ -76,7 +78,7 @@ void copy_rows(void* dst, GLuint dststride, const void* src, GLuint srcstride,
 /**
  * Allocate an empty texture image object.
  */
 /**
  * Allocate an empty texture image object.
  */
-struct gl_texture_image *radeonNewTextureImage(GLcontext *ctx)
+struct gl_texture_image *radeonNewTextureImage(struct gl_context *ctx)
 {
        return CALLOC(sizeof(radeon_texture_image));
 }
 {
        return CALLOC(sizeof(radeon_texture_image));
 }
@@ -84,7 +86,7 @@ struct gl_texture_image *radeonNewTextureImage(GLcontext *ctx)
 /**
  * Free memory associated with this texture image.
  */
 /**
  * Free memory associated with this texture image.
  */
-void radeonFreeTexImageData(GLcontext *ctx, struct gl_texture_image *timage)
+void radeonFreeTexImageData(struct gl_context *ctx, struct gl_texture_image *timage)
 {
        radeon_texture_image* image = get_radeon_texture_image(timage);
 
 {
        radeon_texture_image* image = get_radeon_texture_image(timage);
 
@@ -154,7 +156,7 @@ void radeon_teximage_unmap(radeon_texture_image *image)
        }
 }
 
        }
 }
 
-static void map_override(GLcontext *ctx, radeonTexObj *t)
+static void map_override(struct gl_context *ctx, radeonTexObj *t)
 {
        radeon_texture_image *img = get_radeon_texture_image(t->base.Image[0][0]);
 
 {
        radeon_texture_image *img = get_radeon_texture_image(t->base.Image[0][0]);
 
@@ -163,7 +165,7 @@ static void map_override(GLcontext *ctx, radeonTexObj *t)
        img->base.Data = t->bo->ptr;
 }
 
        img->base.Data = t->bo->ptr;
 }
 
-static void unmap_override(GLcontext *ctx, radeonTexObj *t)
+static void unmap_override(struct gl_context *ctx, radeonTexObj *t)
 {
        radeon_texture_image *img = get_radeon_texture_image(t->base.Image[0][0]);
 
 {
        radeon_texture_image *img = get_radeon_texture_image(t->base.Image[0][0]);
 
@@ -175,7 +177,7 @@ static void unmap_override(GLcontext *ctx, radeonTexObj *t)
 /**
  * Map a validated texture for reading during software rendering.
  */
 /**
  * Map a validated texture for reading during software rendering.
  */
-void radeonMapTexture(GLcontext *ctx, struct gl_texture_object *texObj)
+void radeonMapTexture(struct gl_context *ctx, struct gl_texture_object *texObj)
 {
        radeonTexObj* t = radeon_tex_obj(texObj);
        int face, level;
 {
        radeonTexObj* t = radeon_tex_obj(texObj);
        int face, level;
@@ -213,7 +215,7 @@ void radeonMapTexture(GLcontext *ctx, struct gl_texture_object *texObj)
        }
 }
 
        }
 }
 
-void radeonUnmapTexture(GLcontext *ctx, struct gl_texture_object *texObj)
+void radeonUnmapTexture(struct gl_context *ctx, struct gl_texture_object *texObj)
 {
        radeonTexObj* t = radeon_tex_obj(texObj);
        int face, level;
 {
        radeonTexObj* t = radeon_tex_obj(texObj);
        int face, level;
@@ -241,12 +243,13 @@ void radeonUnmapTexture(GLcontext *ctx, struct gl_texture_object *texObj)
  * This relies on internal details of _mesa_generate_mipmap, in particular
  * the fact that the memory for recreated texture images is always freed.
  */
  * This relies on internal details of _mesa_generate_mipmap, in particular
  * the fact that the memory for recreated texture images is always freed.
  */
-static void radeon_generate_mipmap(GLcontext *ctx, GLenum target,
+static void radeon_generate_mipmap(struct gl_context *ctx, GLenum target,
                                   struct gl_texture_object *texObj)
 {
        radeonTexObj* t = radeon_tex_obj(texObj);
        GLuint nr_faces = (t->base.Target == GL_TEXTURE_CUBE_MAP) ? 6 : 1;
        int i, face;
                                   struct gl_texture_object *texObj)
 {
        radeonTexObj* t = radeon_tex_obj(texObj);
        GLuint nr_faces = (t->base.Target == GL_TEXTURE_CUBE_MAP) ? 6 : 1;
        int i, face;
+       struct gl_texture_image *first_image;
 
        radeon_print(RADEON_TEXTURE, RADEON_VERBOSE,
                        "%s(%p, tex %p) Target type %s.\n",
 
        radeon_print(RADEON_TEXTURE, RADEON_VERBOSE,
                        "%s(%p, tex %p) Target type %s.\n",
@@ -255,6 +258,13 @@ static void radeon_generate_mipmap(GLcontext *ctx, GLenum target,
 
        _mesa_generate_mipmap(ctx, target, texObj);
 
 
        _mesa_generate_mipmap(ctx, target, texObj);
 
+       /* For the compressed case, we don't need to do the
+        * non-TexImage recovery path below.
+        */
+       first_image = texObj->Image[0][texObj->BaseLevel];
+       if (_mesa_is_format_compressed(first_image->TexFormat))
+               return;
+
        for (face = 0; face < nr_faces; face++) {
                for (i = texObj->BaseLevel + 1; i < texObj->MaxLevel; i++) {
                        radeon_texture_image *image;
        for (face = 0; face < nr_faces; face++) {
                for (i = texObj->BaseLevel + 1; i < texObj->MaxLevel; i++) {
                        radeon_texture_image *image;
@@ -273,7 +283,7 @@ static void radeon_generate_mipmap(GLcontext *ctx, GLenum target,
        
 }
 
        
 }
 
-void radeonGenerateMipmap(GLcontext* ctx, GLenum target, struct gl_texture_object *texObj)
+void radeonGenerateMipmap(struct gl_context* ctx, GLenum target, struct gl_texture_object *texObj)
 {
        radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
        struct radeon_bo *bo;
 {
        radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
        struct radeon_bo *bo;
@@ -294,9 +304,13 @@ void radeonGenerateMipmap(GLcontext* ctx, GLenum target, struct gl_texture_objec
                radeon_firevertices(rmesa);
        }
 
                radeon_firevertices(rmesa);
        }
 
-       radeon_teximage_map(baseimage, GL_FALSE);
-       radeon_generate_mipmap(ctx, target, texObj);
-       radeon_teximage_unmap(baseimage);
+       if (_mesa_meta_check_generate_mipmap_fallback(ctx, target, texObj)) {
+               radeon_teximage_map(baseimage, GL_FALSE);
+               radeon_generate_mipmap(ctx, target, texObj);
+               radeon_teximage_unmap(baseimage);
+       } else {
+               _mesa_meta_GenerateMipmap(ctx, target, texObj);
+       }
 }
 
 
 }
 
 
@@ -334,7 +348,7 @@ static gl_format radeonChoose8888TexFormat(radeonContextPtr rmesa,
                return _dri_texformat_argb8888;
 }
 
                return _dri_texformat_argb8888;
 }
 
-gl_format radeonChooseTextureFormat_mesa(GLcontext * ctx,
+gl_format radeonChooseTextureFormat_mesa(struct gl_context * ctx,
                                         GLint internalFormat,
                                         GLenum format,
                                         GLenum type)
                                         GLint internalFormat,
                                         GLenum format,
                                         GLenum type)
@@ -343,7 +357,7 @@ gl_format radeonChooseTextureFormat_mesa(GLcontext * ctx,
                                         type, 0);
 }
 
                                         type, 0);
 }
 
-gl_format radeonChooseTextureFormat(GLcontext * ctx,
+gl_format radeonChooseTextureFormat(struct gl_context * ctx,
                                    GLint internalFormat,
                                    GLenum format,
                                    GLenum type, GLboolean fbo)
                                    GLint internalFormat,
                                    GLenum format,
                                    GLenum type, GLboolean fbo)
@@ -546,7 +560,7 @@ gl_format radeonChooseTextureFormat(GLcontext * ctx,
        case GL_SRGB8_ALPHA8:
        case GL_COMPRESSED_SRGB:
        case GL_COMPRESSED_SRGB_ALPHA:
        case GL_SRGB8_ALPHA8:
        case GL_COMPRESSED_SRGB:
        case GL_COMPRESSED_SRGB_ALPHA:
-               return MESA_FORMAT_SRGBA8;
+               return MESA_FORMAT_SARGB8;
 
        case GL_SLUMINANCE:
        case GL_SLUMINANCE8:
 
        case GL_SLUMINANCE:
        case GL_SLUMINANCE8:
@@ -637,7 +651,7 @@ static void teximage_assign_miptree(radeonContextPtr rmesa,
                                "%s Failed to allocate miptree.\n", __func__);
 }
 
                                "%s Failed to allocate miptree.\n", __func__);
 }
 
-static GLuint * allocate_image_offsets(GLcontext *ctx,
+static GLuint * allocate_image_offsets(struct gl_context *ctx,
        unsigned alignedWidth,
        unsigned height,
        unsigned depth)
        unsigned alignedWidth,
        unsigned height,
        unsigned depth)
@@ -661,7 +675,7 @@ static GLuint * allocate_image_offsets(GLcontext *ctx,
 /**
  * Update a subregion of the given texture image.
  */
 /**
  * Update a subregion of the given texture image.
  */
-static void radeon_store_teximage(GLcontext* ctx, int dims,
+static void radeon_store_teximage(struct gl_context* ctx, int dims,
                GLint xoffset, GLint yoffset, GLint zoffset,
                GLsizei width, GLsizei height, GLsizei depth,
                GLsizei imageSize,
                GLint xoffset, GLint yoffset, GLint zoffset,
                GLsizei width, GLsizei height, GLsizei depth,
                GLsizei imageSize,
@@ -754,7 +768,7 @@ static void radeon_store_teximage(GLcontext* ctx, int dims,
  * All glTexImage calls go through this function.
  */
 static void radeon_teximage(
  * All glTexImage calls go through this function.
  */
 static void radeon_teximage(
-       GLcontext *ctx, int dims,
+       struct gl_context *ctx, int dims,
        GLenum target, GLint level,
        GLint internalFormat,
        GLint width, GLint height, GLint depth,
        GLenum target, GLint level,
        GLint internalFormat,
        GLint width, GLint height, GLint depth,
@@ -768,8 +782,6 @@ static void radeon_teximage(
        radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
        radeonTexObj* t = radeon_tex_obj(texObj);
        radeon_texture_image* image = get_radeon_texture_image(texImage);
        radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
        radeonTexObj* t = radeon_tex_obj(texObj);
        radeon_texture_image* image = get_radeon_texture_image(texImage);
-       GLint postConvWidth = width;
-       GLint postConvHeight = height;
        GLuint face = _mesa_tex_target_to_face(target);
 
        radeon_print(RADEON_TEXTURE, RADEON_NORMAL,
        GLuint face = _mesa_tex_target_to_face(target);
 
        radeon_print(RADEON_TEXTURE, RADEON_NORMAL,
@@ -790,23 +802,6 @@ static void radeon_teximage(
 
        t->validated = GL_FALSE;
 
 
        t->validated = GL_FALSE;
 
-       if (ctx->_ImageTransferState & IMAGE_CONVOLUTION_BIT) {
-              _mesa_adjust_image_for_convolution(ctx, dims, &postConvWidth,
-                                                 &postConvHeight);
-       }
-
-       if (!_mesa_is_format_compressed(texImage->TexFormat)) {
-               GLuint texelBytes = _mesa_get_format_bytes(texImage->TexFormat);
-               /* Minimum pitch of 32 bytes */
-               if (postConvWidth * texelBytes < 32) {
-                       postConvWidth = 32 / texelBytes;
-                       texImage->RowStride = postConvWidth;
-               }
-               if (!image->mt) {
-                       assert(texImage->RowStride == postConvWidth);
-               }
-       }
-
        /* Mesa core only clears texImage->Data but not image->mt */
        radeonFreeTexImageData(ctx, texImage);
 
        /* Mesa core only clears texImage->Data but not image->mt */
        radeonFreeTexImageData(ctx, texImage);
 
@@ -848,7 +843,7 @@ static void radeon_teximage(
        _mesa_unmap_teximage_pbo(ctx, packing);
 }
 
        _mesa_unmap_teximage_pbo(ctx, packing);
 }
 
-void radeonTexImage1D(GLcontext * ctx, GLenum target, GLint level,
+void radeonTexImage1D(struct gl_context * ctx, GLenum target, GLint level,
                      GLint internalFormat,
                      GLint width, GLint border,
                      GLenum format, GLenum type, const GLvoid * pixels,
                      GLint internalFormat,
                      GLint width, GLint border,
                      GLenum format, GLenum type, const GLvoid * pixels,
@@ -860,7 +855,7 @@ void radeonTexImage1D(GLcontext * ctx, GLenum target, GLint level,
                0, format, type, pixels, packing, texObj, texImage, 0);
 }
 
                0, format, type, pixels, packing, texObj, texImage, 0);
 }
 
-void radeonTexImage2D(GLcontext * ctx, GLenum target, GLint level,
+void radeonTexImage2D(struct gl_context * ctx, GLenum target, GLint level,
                           GLint internalFormat,
                           GLint width, GLint height, GLint border,
                           GLenum format, GLenum type, const GLvoid * pixels,
                           GLint internalFormat,
                           GLint width, GLint height, GLint border,
                           GLenum format, GLenum type, const GLvoid * pixels,
@@ -873,7 +868,7 @@ void radeonTexImage2D(GLcontext * ctx, GLenum target, GLint level,
                0, format, type, pixels, packing, texObj, texImage, 0);
 }
 
                0, format, type, pixels, packing, texObj, texImage, 0);
 }
 
-void radeonCompressedTexImage2D(GLcontext * ctx, GLenum target,
+void radeonCompressedTexImage2D(struct gl_context * ctx, GLenum target,
                                     GLint level, GLint internalFormat,
                                     GLint width, GLint height, GLint border,
                                     GLsizei imageSize, const GLvoid * data,
                                     GLint level, GLint internalFormat,
                                     GLint width, GLint height, GLint border,
                                     GLsizei imageSize, const GLvoid * data,
@@ -884,7 +879,7 @@ void radeonCompressedTexImage2D(GLcontext * ctx, GLenum target,
                imageSize, 0, 0, data, &ctx->Unpack, texObj, texImage, 1);
 }
 
                imageSize, 0, 0, data, &ctx->Unpack, texObj, texImage, 1);
 }
 
-void radeonTexImage3D(GLcontext * ctx, GLenum target, GLint level,
+void radeonTexImage3D(struct gl_context * ctx, GLenum target, GLint level,
                      GLint internalFormat,
                      GLint width, GLint height, GLint depth,
                      GLint border,
                      GLint internalFormat,
                      GLint width, GLint height, GLint depth,
                      GLint border,
@@ -900,7 +895,7 @@ void radeonTexImage3D(GLcontext * ctx, GLenum target, GLint level,
 /**
  * All glTexSubImage calls go through this function.
  */
 /**
  * All glTexSubImage calls go through this function.
  */
-static void radeon_texsubimage(GLcontext* ctx, int dims, GLenum target, int level,
+static void radeon_texsubimage(struct gl_context* ctx, int dims, GLenum target, int level,
                GLint xoffset, GLint yoffset, GLint zoffset,
                GLsizei width, GLsizei height, GLsizei depth,
                GLsizei imageSize,
                GLint xoffset, GLint yoffset, GLint zoffset,
                GLsizei width, GLsizei height, GLsizei depth,
                GLsizei imageSize,
@@ -954,7 +949,7 @@ static void radeon_texsubimage(GLcontext* ctx, int dims, GLenum target, int leve
        _mesa_unmap_teximage_pbo(ctx, packing);
 }
 
        _mesa_unmap_teximage_pbo(ctx, packing);
 }
 
-void radeonTexSubImage1D(GLcontext * ctx, GLenum target, GLint level,
+void radeonTexSubImage1D(struct gl_context * ctx, GLenum target, GLint level,
                         GLint xoffset,
                         GLsizei width,
                         GLenum format, GLenum type,
                         GLint xoffset,
                         GLsizei width,
                         GLenum format, GLenum type,
@@ -967,7 +962,7 @@ void radeonTexSubImage1D(GLcontext * ctx, GLenum target, GLint level,
                format, type, pixels, packing, texObj, texImage, 0);
 }
 
                format, type, pixels, packing, texObj, texImage, 0);
 }
 
-void radeonTexSubImage2D(GLcontext * ctx, GLenum target, GLint level,
+void radeonTexSubImage2D(struct gl_context * ctx, GLenum target, GLint level,
                         GLint xoffset, GLint yoffset,
                         GLsizei width, GLsizei height,
                         GLenum format, GLenum type,
                         GLint xoffset, GLint yoffset,
                         GLsizei width, GLsizei height,
                         GLenum format, GLenum type,
@@ -981,7 +976,7 @@ void radeonTexSubImage2D(GLcontext * ctx, GLenum target, GLint level,
                           0);
 }
 
                           0);
 }
 
-void radeonCompressedTexSubImage2D(GLcontext * ctx, GLenum target,
+void radeonCompressedTexSubImage2D(struct gl_context * ctx, GLenum target,
                                   GLint level, GLint xoffset,
                                   GLint yoffset, GLsizei width,
                                   GLsizei height, GLenum format,
                                   GLint level, GLint xoffset,
                                   GLint yoffset, GLsizei width,
                                   GLsizei height, GLenum format,
@@ -994,7 +989,7 @@ void radeonCompressedTexSubImage2D(GLcontext * ctx, GLenum target,
 }
 
 
 }
 
 
-void radeonTexSubImage3D(GLcontext * ctx, GLenum target, GLint level,
+void radeonTexSubImage3D(struct gl_context * ctx, GLenum target, GLint level,
                         GLint xoffset, GLint yoffset, GLint zoffset,
                         GLsizei width, GLsizei height, GLsizei depth,
                         GLenum format, GLenum type,
                         GLint xoffset, GLint yoffset, GLint zoffset,
                         GLsizei width, GLsizei height, GLsizei depth,
                         GLenum format, GLenum type,
@@ -1022,3 +1017,67 @@ unsigned radeonIsFormatRenderable(gl_format mesa_format)
                        return 0;
        }
 }
                        return 0;
        }
 }
+
+#if FEATURE_OES_EGL_image
+void radeon_image_target_texture_2d(struct gl_context *ctx, GLenum target,
+                                   struct gl_texture_object *texObj,
+                                   struct gl_texture_image *texImage,
+                                   GLeglImageOES image_handle)
+{
+       radeonContextPtr radeon = RADEON_CONTEXT(ctx);
+       radeonTexObj *t = radeon_tex_obj(texObj);
+       radeon_texture_image *radeonImage = get_radeon_texture_image(texImage);
+       __DRIscreen *screen;
+       __DRIimage *image;
+
+       screen = radeon->dri.screen;
+       image = screen->dri2.image->lookupEGLImage(screen, image_handle,
+                                                  screen->loaderPrivate);
+       if (image == NULL)
+               return;
+
+       radeonFreeTexImageData(ctx, texImage);
+
+       texImage->Width = image->width;
+       texImage->Height = image->height;
+       texImage->Depth = 1;
+       texImage->_BaseFormat = GL_RGBA;
+       texImage->TexFormat = image->format;
+       texImage->RowStride = image->pitch;
+       texImage->InternalFormat = image->internal_format;
+
+       if(t->mt)
+       {
+               radeon_miptree_unreference(&t->mt);
+               t->mt = NULL;
+       }
+
+       /* NOTE: The following is *very* ugly and will probably break. But
+          I don't know how to deal with it, without creating a whole new
+          function like radeon_miptree_from_bo() so I'm going with the
+          easy but error-prone way. */
+
+       radeon_try_alloc_miptree(radeon, t);
+
+       radeonImage->mtface = _mesa_tex_target_to_face(target);
+       radeonImage->mtlevel = 0;
+       radeon_miptree_reference(t->mt, &radeonImage->mt);
+
+       if (t->mt == NULL)
+       {
+               radeon_print(RADEON_TEXTURE, RADEON_VERBOSE,
+                            "%s Failed to allocate miptree.\n", __func__);
+               return;
+       }
+
+       /* Particularly ugly: this is guaranteed to break, if image->bo is
+          not of the required size for a miptree. */
+       radeon_bo_unref(t->mt->bo);
+       radeon_bo_ref(image->bo);
+       t->mt->bo = image->bo;
+
+       if (!radeon_miptree_matches_image(t->mt, &radeonImage->base,
+                                         radeonImage->mtface, 0))
+               fprintf(stderr, "miptree doesn't match image\n");
+}
+#endif