Introduce .editorconfig
[mesa.git] / src / mesa / drivers / dri / nouveau / nouveau_texture.c
index 14c7b5f64b77c147855e528e75594778e4c958cf..dc5699c76809681c0f59c96515bfc034dc50b542 100644 (file)
 #include "nouveau_fbo.h"
 #include "nouveau_util.h"
 
+#include "main/pbo.h"
 #include "main/texobj.h"
 #include "main/texstore.h"
 #include "main/texformat.h"
 #include "main/texcompress.h"
 #include "main/texgetimage.h"
 #include "main/mipmap.h"
-#include "main/texfetch.h"
 #include "main/teximage.h"
 #include "drivers/common/meta.h"
+#include "swrast/s_texfetch.h"
 
 static struct gl_texture_object *
-nouveau_texture_new(GLcontext *ctx, GLuint name, GLenum target)
+nouveau_texture_new(struct gl_context *ctx, GLuint name, GLenum target)
 {
        struct nouveau_texture *nt = CALLOC_STRUCT(nouveau_texture);
 
-       _mesa_initialize_texture_object(&nt->base, name, target);
+       _mesa_initialize_texture_object(ctx, &nt->base, name, target);
 
        return &nt->base;
 }
 
 static void
-nouveau_texture_free(GLcontext *ctx, struct gl_texture_object *t)
+nouveau_texture_free(struct gl_context *ctx, struct gl_texture_object *t)
 {
        struct nouveau_texture *nt = to_nouveau_texture(t);
        int i;
@@ -63,15 +64,15 @@ nouveau_texture_free(GLcontext *ctx, struct gl_texture_object *t)
 }
 
 static struct gl_texture_image *
-nouveau_teximage_new(GLcontext *ctx)
+nouveau_teximage_new(struct gl_context *ctx)
 {
        struct nouveau_teximage *nti = CALLOC_STRUCT(nouveau_teximage);
 
-       return &nti->base;
+       return &nti->base.Base;
 }
 
 static void
-nouveau_teximage_free(GLcontext *ctx, struct gl_texture_image *ti)
+nouveau_teximage_free(struct gl_context *ctx, struct gl_texture_image *ti)
 {
        struct nouveau_teximage *nti = to_nouveau_teximage(ti);
 
@@ -79,31 +80,89 @@ nouveau_teximage_free(GLcontext *ctx, struct gl_texture_image *ti)
 }
 
 static void
-nouveau_teximage_map(GLcontext *ctx, struct gl_texture_image *ti)
+nouveau_map_texture_image(struct gl_context *ctx,
+                         struct gl_texture_image *ti,
+                         GLuint slice,
+                         GLuint x, GLuint y, GLuint w, GLuint h,
+                         GLbitfield mode,
+                         GLubyte **map,
+                         GLint *stride)
 {
-       struct nouveau_surface *s = &to_nouveau_teximage(ti)->surface;
-       int ret;
+       struct nouveau_teximage *nti = to_nouveau_teximage(ti);
+       struct nouveau_surface *s = &nti->surface;
+       struct nouveau_surface *st = &nti->transfer.surface;
+       struct nouveau_client *client = context_client(ctx);
 
-       if (s->bo) {
-               ret = nouveau_bo_map(s->bo, NOUVEAU_BO_RDWR);
-               assert(!ret);
+       /* Nouveau has no support for 3D or cubemap textures. */
+       assert(slice == 0);
 
-               ti->Data = s->bo->map;
+       if (s->bo) {
+               if (!(mode & GL_MAP_READ_BIT) &&
+                   nouveau_pushbuf_refd(context_push(ctx), s->bo)) {
+                       unsigned size;
+                       /*
+                        * Heuristic: use a bounce buffer to pipeline
+                        * teximage transfers.
+                        */
+                       st->layout = LINEAR;
+                       st->format = s->format;
+                       st->cpp = s->cpp;
+                       st->width = w;
+                       st->height = h;
+                       st->pitch = s->pitch;
+                       nti->transfer.x = x;
+                       nti->transfer.y = y;
+
+                       size = get_format_blocksy(st->format, h) * st->pitch;
+                       *map = nouveau_get_scratch(ctx, size,
+                                         &st->bo, &st->offset);
+                       *stride = st->pitch;
+               } else {
+                       int ret, flags = 0;
+
+                       if (mode & GL_MAP_READ_BIT)
+                               flags |= NOUVEAU_BO_RD;
+                       if (mode & GL_MAP_WRITE_BIT)
+                               flags |= NOUVEAU_BO_WR;
+
+                       if (!s->bo->map) {
+                               ret = nouveau_bo_map(s->bo, flags, client);
+                               assert(!ret);
+                       }
+
+                       *map = s->bo->map +
+                               get_format_blocksy(s->format, y) * s->pitch +
+                               get_format_blocksx(s->format, x) * s->cpp;
+                       *stride = s->pitch;
+               }
+       } else {
+               *map = nti->base.Buffer +
+                       get_format_blocksy(s->format, y) * s->pitch +
+                       get_format_blocksx(s->format, x) * s->cpp;
+               *stride = s->pitch;
        }
 }
 
 static void
-nouveau_teximage_unmap(GLcontext *ctx, struct gl_texture_image *ti)
+nouveau_unmap_texture_image(struct gl_context *ctx, struct gl_texture_image *ti,
+                           GLuint slice)
 {
-       struct nouveau_surface *s = &to_nouveau_teximage(ti)->surface;
+       struct nouveau_teximage *nti = to_nouveau_teximage(ti);
+       struct nouveau_surface *s = &nti->surface;
+       struct nouveau_surface *st = &nti->transfer.surface;
 
-       if (s->bo)
-               nouveau_bo_unmap(s->bo);
-       ti->Data = NULL;
+       if (st->bo) {
+               context_drv(ctx)->surface_copy(ctx, s, st, nti->transfer.x,
+                                              nti->transfer.y, 0, 0,
+                                              st->width, st->height);
+               nouveau_surface_ref(NULL, st);
+
+       }
 }
 
-static gl_format
-nouveau_choose_tex_format(GLcontext *ctx, GLint internalFormat,
+static mesa_format
+nouveau_choose_tex_format(struct gl_context *ctx, GLenum target,
+                          GLint internalFormat,
                          GLenum srcFormat, GLenum srcType)
 {
        switch (internalFormat) {
@@ -115,21 +174,23 @@ nouveau_choose_tex_format(GLcontext *ctx, GLint internalFormat,
        case GL_RGBA12:
        case GL_RGBA16:
        case GL_RGB10_A2:
-               return MESA_FORMAT_ARGB8888;
+       case GL_COMPRESSED_RGBA:
+               return MESA_FORMAT_B8G8R8A8_UNORM;
        case GL_RGB5_A1:
-               return MESA_FORMAT_ARGB1555;
+               return MESA_FORMAT_B5G5R5A1_UNORM;
 
        case GL_RGB:
        case GL_RGB8:
        case GL_RGB10:
        case GL_RGB12:
        case GL_RGB16:
-               return MESA_FORMAT_XRGB8888;
+       case GL_COMPRESSED_RGB:
+               return MESA_FORMAT_B8G8R8X8_UNORM;
        case 3:
        case GL_R3_G3_B2:
        case GL_RGB4:
        case GL_RGB5:
-               return MESA_FORMAT_RGB565;
+               return MESA_FORMAT_B5G6R5_UNORM;
 
        case 2:
        case GL_LUMINANCE_ALPHA:
@@ -139,7 +200,8 @@ nouveau_choose_tex_format(GLcontext *ctx, GLint internalFormat,
        case GL_LUMINANCE12_ALPHA12:
        case GL_LUMINANCE16_ALPHA16:
        case GL_LUMINANCE8_ALPHA8:
-               return MESA_FORMAT_ARGB8888;
+       case GL_COMPRESSED_LUMINANCE_ALPHA:
+               return MESA_FORMAT_B8G8R8A8_UNORM;
 
        case 1:
        case GL_LUMINANCE:
@@ -147,30 +209,40 @@ nouveau_choose_tex_format(GLcontext *ctx, GLint internalFormat,
        case GL_LUMINANCE12:
        case GL_LUMINANCE16:
        case GL_LUMINANCE8:
-               return MESA_FORMAT_L8;
+       case GL_COMPRESSED_LUMINANCE:
+               return MESA_FORMAT_L_UNORM8;
 
        case GL_ALPHA:
        case GL_ALPHA4:
        case GL_ALPHA12:
        case GL_ALPHA16:
        case GL_ALPHA8:
-               return MESA_FORMAT_A8;
+       case GL_COMPRESSED_ALPHA:
+               return MESA_FORMAT_A_UNORM8;
 
        case GL_INTENSITY:
        case GL_INTENSITY4:
        case GL_INTENSITY12:
        case GL_INTENSITY16:
        case GL_INTENSITY8:
-               return MESA_FORMAT_I8;
+       case GL_COMPRESSED_INTENSITY:
+               return MESA_FORMAT_I_UNORM8;
+
+       case GL_RGB_S3TC:
+       case GL_RGB4_S3TC:
+       case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
+               return MESA_FORMAT_RGB_DXT1;
 
-       case GL_COLOR_INDEX:
-       case GL_COLOR_INDEX1_EXT:
-       case GL_COLOR_INDEX2_EXT:
-       case GL_COLOR_INDEX4_EXT:
-       case GL_COLOR_INDEX12_EXT:
-       case GL_COLOR_INDEX16_EXT:
-       case GL_COLOR_INDEX8_EXT:
-               return MESA_FORMAT_CI8;
+       case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
+               return MESA_FORMAT_RGBA_DXT1;
+
+       case GL_RGBA_S3TC:
+       case GL_RGBA4_S3TC:
+       case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
+               return MESA_FORMAT_RGBA_DXT3;
+
+       case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
+               return MESA_FORMAT_RGBA_DXT5;
 
        default:
                assert(0);
@@ -195,7 +267,7 @@ teximage_fits(struct gl_texture_object *t, int level)
 }
 
 static GLboolean
-validate_teximage(GLcontext *ctx, struct gl_texture_object *t,
+validate_teximage(struct gl_context *ctx, struct gl_texture_object *t,
                  int level, int x, int y, int z,
                  int width, int height, int depth)
 {
@@ -223,15 +295,15 @@ get_last_level(struct gl_texture_object *t)
 {
        struct gl_texture_image *base = t->Image[0][t->BaseLevel];
 
-       if (t->MinFilter == GL_NEAREST ||
-           t->MinFilter == GL_LINEAR || !base)
+       if (t->Sampler.MinFilter == GL_NEAREST ||
+           t->Sampler.MinFilter == GL_LINEAR || !base)
                return t->BaseLevel;
        else
-               return MIN2(t->BaseLevel + base->MaxLog2, t->MaxLevel);
+               return MIN2(t->BaseLevel + base->MaxNumLevels - 1, t->MaxLevel);
 }
 
 static void
-relayout_texture(GLcontext *ctx, struct gl_texture_object *t)
+relayout_texture(struct gl_context *ctx, struct gl_texture_object *t)
 {
        struct gl_texture_image *base = t->Image[0][t->BaseLevel];
 
@@ -239,7 +311,9 @@ relayout_texture(GLcontext *ctx, struct gl_texture_object *t)
                struct nouveau_surface *ss = to_nouveau_texture(t)->surfaces;
                struct nouveau_surface *s = &to_nouveau_teximage(base)->surface;
                int i, ret, last = get_last_level(t);
-               unsigned size, offset = 0,
+               enum nouveau_surface_layout layout =
+                       (_mesa_is_format_compressed(s->format) ? LINEAR : SWIZZLED);
+               unsigned size, pitch, offset = 0,
                        width = s->width,
                        height = s->height;
 
@@ -249,7 +323,8 @@ relayout_texture(GLcontext *ctx, struct gl_texture_object *t)
 
                /* Relayout the mipmap tree. */
                for (i = t->BaseLevel; i <= last; i++) {
-                       size = width * height * s->cpp;
+                       pitch = _mesa_format_row_stride(s->format, width);
+                       size = get_format_blocksy(s->format, height) * pitch;
 
                        /* Images larger than 16B have to be aligned. */
                        if (size > 16)
@@ -257,34 +332,37 @@ relayout_texture(GLcontext *ctx, struct gl_texture_object *t)
 
                        ss[i] = (struct nouveau_surface) {
                                .offset = offset,
-                               .layout = SWIZZLED,
+                               .layout = layout,
                                .format = s->format,
                                .width = width,
                                .height = height,
                                .cpp = s->cpp,
-                               .pitch = width * s->cpp,
+                               .pitch = pitch,
                        };
 
                        offset += size;
-                       width = MAX2(1, width / 2);
-                       height = MAX2(1, height / 2);
+                       width = minify(width, 1);
+                       height = minify(height, 1);
                }
 
-               /* Get new storage. */
-               size = align(offset, 64);
+               if (t->BaseLevel <= last) {
+                       /* Get new storage. */
+                       size = align(offset, 64);
+                       assert(size);
 
-               ret = nouveau_bo_new(context_dev(ctx), NOUVEAU_BO_MAP |
-                                    NOUVEAU_BO_GART | NOUVEAU_BO_VRAM,
-                                    0, size, &ss[last].bo);
-               assert(!ret);
+                       ret = nouveau_bo_new(context_dev(ctx), NOUVEAU_BO_MAP |
+                                            NOUVEAU_BO_GART | NOUVEAU_BO_VRAM,
+                                            0, size, NULL, &ss[last].bo);
+                       assert(!ret);
 
-               for (i = t->BaseLevel; i < last; i++)
-                       nouveau_bo_ref(ss[last].bo, &ss[i].bo);
+                       for (i = t->BaseLevel; i < last; i++)
+                               nouveau_bo_ref(ss[last].bo, &ss[i].bo);
+               }
        }
 }
 
 GLboolean
-nouveau_texture_validate(GLcontext *ctx, struct gl_texture_object *t)
+nouveau_texture_validate(struct gl_context *ctx, struct gl_texture_object *t)
 {
        struct nouveau_texture *nt = to_nouveau_texture(t);
        int i, last = get_last_level(t);
@@ -304,14 +382,14 @@ nouveau_texture_validate(GLcontext *ctx, struct gl_texture_object *t)
                                          s->width, s->height, 1);
                }
 
-               FIRE_RING(context_chan(ctx));
+               PUSH_KICK(context_push(ctx));
        }
 
        return GL_TRUE;
 }
 
 void
-nouveau_texture_reallocate(GLcontext *ctx, struct gl_texture_object *t)
+nouveau_texture_reallocate(struct gl_context *ctx, struct gl_texture_object *t)
 {
        if (!teximage_fits(t, t->BaseLevel) ||
            !teximage_fits(t, get_last_level(t))) {
@@ -324,9 +402,9 @@ nouveau_texture_reallocate(GLcontext *ctx, struct gl_texture_object *t)
 static unsigned
 get_teximage_placement(struct gl_texture_image *ti)
 {
-       if (ti->TexFormat == MESA_FORMAT_A8 ||
-           ti->TexFormat == MESA_FORMAT_L8 ||
-           ti->TexFormat == MESA_FORMAT_I8)
+       if (ti->TexFormat == MESA_FORMAT_A_UNORM8 ||
+           ti->TexFormat == MESA_FORMAT_L_UNORM8 ||
+           ti->TexFormat == MESA_FORMAT_I_UNORM8)
                /* 1 cpp formats will have to be swizzled by the CPU,
                 * so leave them in system RAM for now. */
                return NOUVEAU_BO_MAP;
@@ -335,42 +413,88 @@ get_teximage_placement(struct gl_texture_image *ti)
 }
 
 static void
-nouveau_teximage(GLcontext *ctx, GLint dims, GLenum target, GLint level,
-                GLint internalFormat,
-                GLint width, GLint height, GLint depth, GLint border,
+nouveau_compressed_copy(struct gl_context *ctx, GLint dims,
+                       struct gl_texture_image *ti,
+                       GLsizei width, GLsizei height, GLsizei depth,
+                       const GLvoid *src, GLvoid *dst, int row_stride)
+{
+       struct compressed_pixelstore store;
+       int i;
+
+       _mesa_compute_compressed_pixelstore(dims, ti->TexFormat,
+                                           width, height, depth,
+                                           &ctx->Unpack, &store);
+
+       src += store.SkipBytes;
+
+       assert(store.CopySlices == 1);
+
+       /* copy rows of blocks */
+       for (i = 0; i < store.CopyRowsPerSlice; i++) {
+               memcpy(dst, src, store.CopyBytesPerRow);
+               dst += row_stride;
+               src += store.TotalBytesPerRow;
+       }
+}
+
+static void
+nouveau_teximage(struct gl_context *ctx, GLint dims,
+                struct gl_texture_image *ti,
+                GLsizei imageSize,
                 GLenum format, GLenum type, const GLvoid *pixels,
                 const struct gl_pixelstore_attrib *packing,
-                struct gl_texture_object *t,
-                struct gl_texture_image *ti)
+                GLboolean compressed)
 {
+       struct gl_texture_object *t = ti->TexObject;
+       const GLuint level = ti->Level;
        struct nouveau_surface *s = &to_nouveau_teximage(ti)->surface;
+       struct nouveau_teximage *nti = to_nouveau_teximage(ti);
        int ret;
+       GLuint depth = compressed ? 1 : ti->Depth;
 
        /* Allocate a new bo for the image. */
        nouveau_surface_alloc(ctx, s, LINEAR, get_teximage_placement(ti),
-                             ti->TexFormat, width, height);
-       ti->RowStride = s->pitch / s->cpp;
+                             ti->TexFormat, ti->Width, ti->Height);
+       nti->base.RowStride = s->pitch / s->cpp;
+
+       if (compressed)
+               pixels = _mesa_validate_pbo_compressed_teximage(ctx,
+                       dims, imageSize,
+                       pixels, packing, "glCompressedTexImage");
+       else
+               pixels = _mesa_validate_pbo_teximage(ctx,
+                       dims, ti->Width, ti->Height, depth, format, type,
+                       pixels, packing, "glTexImage");
 
-       pixels = _mesa_validate_pbo_teximage(ctx, dims, width, height, depth,
-                                            format, type, pixels, packing,
-                                            "glTexImage");
        if (pixels) {
-               /* Store the pixel data. */
-               nouveau_teximage_map(ctx, ti);
+               GLubyte *map;
+               int row_stride;
 
-               ret = _mesa_texstore(ctx, dims, ti->_BaseFormat,
-                                    ti->TexFormat, ti->Data,
-                                    0, 0, 0, s->pitch,
-                                    ti->ImageOffsets,
-                                    width, height, depth,
-                                    format, type, pixels, packing);
-               assert(ret);
+               /* Store the pixel data. */
+               nouveau_map_texture_image(ctx, ti, 0,
+                                         0, 0, ti->Width, ti->Height,
+                                         GL_MAP_WRITE_BIT,
+                                         &map, &row_stride);
+
+               if (compressed) {
+                       nouveau_compressed_copy(ctx, dims, ti,
+                                               ti->Width, ti->Height, depth,
+                                               pixels, map, row_stride);
+               } else {
+                       ret = _mesa_texstore(ctx, dims, ti->_BaseFormat,
+                                            ti->TexFormat,
+                                            row_stride,
+                                            &map,
+                                            ti->Width, ti->Height, depth,
+                                            format, type, pixels, packing);
+                       assert(ret);
+               }
 
-               nouveau_teximage_unmap(ctx, ti);
+               nouveau_unmap_texture_image(ctx, ti, 0);
                _mesa_unmap_teximage_pbo(ctx, packing);
 
                if (!validate_teximage(ctx, t, level, 0, 0, 0,
-                                      width, height, depth))
+                                      ti->Width, ti->Height, depth))
                        /* It doesn't fit, mark it as dirty. */
                        texture_dirty(t);
        }
@@ -385,144 +509,122 @@ nouveau_teximage(GLcontext *ctx, GLint dims, GLenum target, GLint level,
        context_dirty_i(ctx, TEX_ENV, ctx->Texture.CurrentUnit);
 }
 
+
 static void
-nouveau_teximage_1d(GLcontext *ctx, GLenum target, GLint level,
-                   GLint internalFormat,
-                   GLint width, GLint border,
-                   GLenum format, GLenum type, const GLvoid *pixels,
-                   const struct gl_pixelstore_attrib *packing,
-                   struct gl_texture_object *t,
-                   struct gl_texture_image *ti)
+nouveau_teximage_123d(struct gl_context *ctx, GLuint dims,
+                      struct gl_texture_image *ti,
+                      GLenum format, GLenum type, const GLvoid *pixels,
+                      const struct gl_pixelstore_attrib *packing)
 {
-       nouveau_teximage(ctx, 1, target, level, internalFormat,
-                        width, 1, 1, border, format, type, pixels,
-                        packing, t, ti);
+       nouveau_teximage(ctx, dims, ti, 0, format, type, pixels,
+                        packing, GL_FALSE);
 }
 
 static void
-nouveau_teximage_2d(GLcontext *ctx, GLenum target, GLint level,
-                   GLint internalFormat,
-                   GLint width, GLint height, GLint border,
-                   GLenum format, GLenum type, const GLvoid *pixels,
-                   const struct gl_pixelstore_attrib *packing,
-                   struct gl_texture_object *t,
-                   struct gl_texture_image *ti)
+nouveau_compressed_teximage(struct gl_context *ctx, GLuint dims,
+                   struct gl_texture_image *ti,
+                   GLsizei imageSize, const GLvoid *data)
 {
-       nouveau_teximage(ctx, 2, target, level, internalFormat,
-                        width, height, 1, border, format, type, pixels,
-                        packing, t, ti);
+       nouveau_teximage(ctx, 2, ti, imageSize, 0, 0, data,
+                        &ctx->Unpack, GL_TRUE);
 }
 
-static void
-nouveau_teximage_3d(GLcontext *ctx, GLenum target, GLint level,
-                   GLint internalFormat,
-                   GLint width, GLint height, GLint depth, GLint border,
-                   GLenum format, GLenum type, const GLvoid *pixels,
-                   const struct gl_pixelstore_attrib *packing,
-                   struct gl_texture_object *t,
-                   struct gl_texture_image *ti)
+static GLboolean
+nouveau_teximage_alloc(struct gl_context *ctx, struct gl_texture_image *ti)
 {
-       nouveau_teximage(ctx, 3, target, level, internalFormat,
-                        width, height, depth, border, format, type, pixels,
-                        packing, t, ti);
+       nouveau_teximage(ctx, 3, ti, 0, 0, 0, NULL,
+                        &ctx->DefaultPacking,
+                        _mesa_is_format_compressed(ti->TexFormat));
+       return GL_TRUE;
 }
 
 static void
-nouveau_texsubimage(GLcontext *ctx, GLint dims, GLenum target, GLint level,
+nouveau_texsubimage(struct gl_context *ctx, GLint dims,
+                   struct gl_texture_image *ti,
                    GLint xoffset, GLint yoffset, GLint zoffset,
                    GLint width, GLint height, GLint depth,
+                   GLsizei imageSize,
                    GLenum format, GLenum type, const void *pixels,
                    const struct gl_pixelstore_attrib *packing,
-                   struct gl_texture_object *t,
-                   struct gl_texture_image *ti)
+                   GLboolean compressed)
 {
-       struct nouveau_surface *s = &to_nouveau_teximage(ti)->surface;
        int ret;
 
-       pixels = _mesa_validate_pbo_teximage(ctx, dims, width, height, depth,
-                                            format, type, pixels, packing,
-                                            "glTexSubImage");
-       if (pixels) {
-               nouveau_teximage_map(ctx, ti);
+       if (compressed)
+               pixels = _mesa_validate_pbo_compressed_teximage(ctx,
+                               dims, imageSize,
+                               pixels, packing, "glCompressedTexSubImage");
+       else
+               pixels = _mesa_validate_pbo_teximage(ctx,
+                               dims, width, height, depth, format, type,
+                               pixels, packing, "glTexSubImage");
 
-               ret = _mesa_texstore(ctx, 3, ti->_BaseFormat, ti->TexFormat,
-                                    ti->Data, xoffset, yoffset, zoffset,
-                                    s->pitch, ti->ImageOffsets,
-                                    width, height, depth, format, type,
-                                    pixels, packing);
-               assert(ret);
+       if (pixels) {
+               GLubyte *map;
+               int row_stride;
+
+               nouveau_map_texture_image(ctx, ti, 0,
+                                         xoffset, yoffset, width, height,
+                                         GL_MAP_WRITE_BIT, &map, &row_stride);
+
+               if (compressed) {
+                       nouveau_compressed_copy(ctx, dims, ti,
+                                               width, height, depth,
+                                               pixels, map, row_stride);
+               } else {
+                       ret = _mesa_texstore(ctx, dims, ti->_BaseFormat,
+                                            ti->TexFormat,
+                                            row_stride, &map,
+                                            width, height, depth,
+                                            format, type, pixels, packing);
+                       assert(ret);
+               }
 
-               nouveau_teximage_unmap(ctx, ti);
+               nouveau_unmap_texture_image(ctx, ti, 0);
                _mesa_unmap_teximage_pbo(ctx, packing);
        }
 
-       if (!to_nouveau_texture(t)->dirty)
-               validate_teximage(ctx, t, level, xoffset, yoffset, zoffset,
+       if (!to_nouveau_texture(ti->TexObject)->dirty)
+               validate_teximage(ctx, ti->TexObject, ti->Level,
+                                 xoffset, yoffset, zoffset,
                                  width, height, depth);
 }
 
 static void
-nouveau_texsubimage_3d(GLcontext *ctx, GLenum target, GLint level,
-                      GLint xoffset, GLint yoffset, GLint zoffset,
-                      GLint width, GLint height, GLint depth,
-                      GLenum format, GLenum type, const void *pixels,
-                      const struct gl_pixelstore_attrib *packing,
-                      struct gl_texture_object *t,
-                      struct gl_texture_image *ti)
+nouveau_texsubimage_123d(struct gl_context *ctx, GLuint dims,
+                         struct gl_texture_image *ti,
+                         GLint xoffset, GLint yoffset, GLint zoffset,
+                         GLint width, GLint height, GLint depth,
+                         GLenum format, GLenum type, const void *pixels,
+                         const struct gl_pixelstore_attrib *packing)
 {
-       nouveau_texsubimage(ctx, 3, target, level, xoffset, yoffset, zoffset,
-                           width, height, depth, format, type, pixels,
-                           packing, t, ti);
+       nouveau_texsubimage(ctx, dims, ti, xoffset, yoffset, zoffset,
+                           width, height, depth, 0, format, type, pixels,
+                           packing, GL_FALSE);
 }
 
 static void
-nouveau_texsubimage_2d(GLcontext *ctx, GLenum target, GLint level,
-                      GLint xoffset, GLint yoffset,
-                      GLint width, GLint height,
-                      GLenum format, GLenum type, const void *pixels,
-                      const struct gl_pixelstore_attrib *packing,
-                      struct gl_texture_object *t,
-                      struct gl_texture_image *ti)
-{
-       nouveau_texsubimage(ctx, 2, target, level, xoffset, yoffset, 0,
-                           width, height, 1, format, type, pixels,
-                           packing, t, ti);
-}
-
-static void
-nouveau_texsubimage_1d(GLcontext *ctx, GLenum target, GLint level,
-                      GLint xoffset, GLint width,
-                      GLenum format, GLenum type, const void *pixels,
-                      const struct gl_pixelstore_attrib *packing,
-                      struct gl_texture_object *t,
-                      struct gl_texture_image *ti)
-{
-       nouveau_texsubimage(ctx, 1, target, level, xoffset, 0, 0,
-                           width, 1, 1, format, type, pixels,
-                           packing, t, ti);
-}
-
-static void
-nouveau_get_teximage(GLcontext *ctx, GLenum target, GLint level,
-                    GLenum format, GLenum type, GLvoid *pixels,
-                    struct gl_texture_object *t,
-                    struct gl_texture_image *ti)
+nouveau_compressed_texsubimage(struct gl_context *ctx, GLuint dims,
+                      struct gl_texture_image *ti,
+                      GLint xoffset, GLint yoffset, GLint zoffset,
+                      GLsizei width, GLint height, GLint depth,
+                      GLenum format,
+                      GLint imageSize, const void *data)
 {
-       nouveau_teximage_map(ctx, ti);
-       _mesa_get_teximage(ctx, target, level, format, type, pixels,
-                          t, ti);
-       nouveau_teximage_unmap(ctx, ti);
+       nouveau_texsubimage(ctx, dims, ti, xoffset, yoffset, zoffset,
+                         width, height, depth, imageSize, format, 0, data,
+                         &ctx->Unpack, GL_TRUE);
 }
 
 static void
-nouveau_bind_texture(GLcontext *ctx, GLenum target,
-                    struct gl_texture_object *t)
+nouveau_bind_texture(struct gl_context *ctx, GLuint texUnit,
+                     GLenum target, struct gl_texture_object *t)
 {
-       context_dirty_i(ctx, TEX_OBJ, ctx->Texture.CurrentUnit);
-       context_dirty_i(ctx, TEX_ENV, ctx->Texture.CurrentUnit);
+       context_dirty_i(ctx, TEX_OBJ, texUnit);
+       context_dirty_i(ctx, TEX_ENV, texUnit);
 }
 
-static gl_format
+static mesa_format
 get_texbuffer_format(struct gl_renderbuffer *rb, GLint format)
 {
        struct nouveau_surface *s = &to_nouveau_renderbuffer(rb)->surface;
@@ -530,9 +632,9 @@ get_texbuffer_format(struct gl_renderbuffer *rb, GLint format)
        if (s->cpp < 4)
                return s->format;
        else if (format == __DRI_TEXTURE_FORMAT_RGBA)
-               return MESA_FORMAT_ARGB8888;
+               return MESA_FORMAT_B8G8R8A8_UNORM;
        else
-               return MESA_FORMAT_XRGB8888;
+               return MESA_FORMAT_B8G8R8X8_UNORM;
 }
 
 void
@@ -541,27 +643,30 @@ nouveau_set_texbuffer(__DRIcontext *dri_ctx,
                      __DRIdrawable *draw)
 {
        struct nouveau_context *nctx = dri_ctx->driverPrivate;
-       GLcontext *ctx = &nctx->base;
+       struct gl_context *ctx = &nctx->base;
        struct gl_framebuffer *fb = draw->driverPrivate;
        struct gl_renderbuffer *rb =
                fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer;
        struct gl_texture_object *t = _mesa_get_current_tex_object(ctx, target);
        struct gl_texture_image *ti;
+       struct nouveau_teximage *nti;
        struct nouveau_surface *s;
 
        _mesa_lock_texture(ctx, t);
        ti = _mesa_get_tex_image(ctx, t, target, 0);
+       nti = to_nouveau_teximage(ti);
        s = &to_nouveau_teximage(ti)->surface;
 
        /* Update the texture surface with the given drawable. */
        nouveau_update_renderbuffers(dri_ctx, draw);
        nouveau_surface_ref(&to_nouveau_renderbuffer(rb)->surface, s);
 
+        s->format = get_texbuffer_format(rb, format);
+
        /* Update the image fields. */
-       _mesa_init_teximage_fields(ctx, target, ti, s->width, s->height,
-                                  1, 0, s->cpp);
-       ti->RowStride = s->pitch / s->cpp;
-       ti->TexFormat = s->format = get_texbuffer_format(rb, format);
+       _mesa_init_teximage_fields(ctx, ti, s->width, s->height,
+                                  1, 0, s->cpp, s->format);
+       nti->base.RowStride = s->pitch / s->cpp;
 
        /* Try to validate it. */
        if (!validate_teximage(ctx, t, 0, 0, 0, 0, s->width, s->height, 1))
@@ -573,92 +678,20 @@ nouveau_set_texbuffer(__DRIcontext *dri_ctx,
        _mesa_unlock_texture(ctx, t);
 }
 
-static void
-nouveau_texture_map(GLcontext *ctx, struct gl_texture_object *t)
-{
-       int i;
-
-       for (i = t->BaseLevel; i < t->_MaxLevel; i++) {
-               if (t->Image[0][i])
-                       nouveau_teximage_map(ctx, t->Image[0][i]);
-       }
-}
-
-static void
-nouveau_texture_unmap(GLcontext *ctx, struct gl_texture_object *t)
-{
-       int i;
-
-       for (i = t->BaseLevel; i < t->_MaxLevel; i++) {
-               if (t->Image[0][i])
-                       nouveau_teximage_unmap(ctx, t->Image[0][i]);
-       }
-}
-
-static void
-store_mipmap(GLcontext *ctx, GLenum target, int first, int last,
-            struct gl_texture_object *t)
-{
-       struct gl_pixelstore_attrib packing = {
-               .BufferObj = ctx->Shared->NullBufferObj,
-               .Alignment = 1
-       };
-       GLenum format = t->Image[0][t->BaseLevel]->TexFormat;
-       unsigned base_format, type, comps;
-       int i;
-
-       base_format = _mesa_get_format_base_format(format);
-       _mesa_format_to_type_and_comps(format, &type, &comps);
-
-       for (i = first; i <= last; i++) {
-               struct gl_texture_image *ti = t->Image[0][i];
-               void *data = ti->Data;
-
-               nouveau_teximage(ctx, 3, target, i, ti->InternalFormat,
-                                ti->Width, ti->Height, ti->Depth,
-                                ti->Border, base_format, type, data,
-                                &packing, t, ti);
-
-               _mesa_free_texmemory(data);
-       }
-}
-
-static void
-nouveau_generate_mipmap(GLcontext *ctx, GLenum target,
-                       struct gl_texture_object *t)
-{
-       if (_mesa_meta_check_generate_mipmap_fallback(ctx, target, t)) {
-               struct gl_texture_image *base = t->Image[0][t->BaseLevel];
-
-               nouveau_teximage_map(ctx, base);
-               _mesa_generate_mipmap(ctx, target, t);
-               nouveau_teximage_unmap(ctx, base);
-
-               store_mipmap(ctx, target, t->BaseLevel + 1,
-                            get_last_level(t), t);
-
-       } else {
-               _mesa_meta_GenerateMipmap(ctx, target, t);
-       }
-}
-
 void
 nouveau_texture_functions_init(struct dd_function_table *functions)
 {
        functions->NewTextureObject = nouveau_texture_new;
        functions->DeleteTexture = nouveau_texture_free;
        functions->NewTextureImage = nouveau_teximage_new;
-       functions->FreeTexImageData = nouveau_teximage_free;
+       functions->FreeTextureImageBuffer = nouveau_teximage_free;
+       functions->AllocTextureImageBuffer = nouveau_teximage_alloc;
        functions->ChooseTextureFormat = nouveau_choose_tex_format;
-       functions->TexImage1D = nouveau_teximage_1d;
-       functions->TexImage2D = nouveau_teximage_2d;
-       functions->TexImage3D = nouveau_teximage_3d;
-       functions->TexSubImage1D = nouveau_texsubimage_1d;
-       functions->TexSubImage2D = nouveau_texsubimage_2d;
-       functions->TexSubImage3D = nouveau_texsubimage_3d;
-       functions->GetTexImage = nouveau_get_teximage;
+       functions->TexImage = nouveau_teximage_123d;
+       functions->TexSubImage = nouveau_texsubimage_123d;
+       functions->CompressedTexImage = nouveau_compressed_teximage;
+       functions->CompressedTexSubImage = nouveau_compressed_texsubimage;
        functions->BindTexture = nouveau_bind_texture;
-       functions->MapTexture = nouveau_texture_map;
-       functions->UnmapTexture = nouveau_texture_unmap;
-       functions->GenerateMipmap = nouveau_generate_mipmap;
+       functions->MapTextureImage = nouveau_map_texture_image;
+       functions->UnmapTextureImage = nouveau_unmap_texture_image;
 }