X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fmesa%2Fdrivers%2Fdri%2Fnouveau%2Fnouveau_texture.c;h=dc5699c76809681c0f59c96515bfc034dc50b542;hb=da9e6fdfe27065b8ede8b2fe30c8cccc3b573245;hp=dbf9a5cc613f0469881458e39817c6f631c09854;hpb=a6fecdff3e71f080d4caf29d2b0713ab5ce9d5f4;p=mesa.git diff --git a/src/mesa/drivers/dri/nouveau/nouveau_texture.c b/src/mesa/drivers/dri/nouveau/nouveau_texture.c index dbf9a5cc613..dc5699c7680 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_texture.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_texture.c @@ -30,27 +30,29 @@ #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; @@ -62,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); @@ -78,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) { @@ -114,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: @@ -138,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: @@ -146,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_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_RGB_S3TC: + case GL_RGB4_S3TC: + case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: + return MESA_FORMAT_RGB_DXT1; + + 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); @@ -182,14 +255,19 @@ teximage_fits(struct gl_texture_object *t, int level) struct nouveau_surface *s = &to_nouveau_texture(t)->surfaces[level]; struct gl_texture_image *ti = t->Image[0][level]; - return ti && (t->Target == GL_TEXTURE_RECTANGLE || - (s->bo && s->width == ti->Width && - s->height == ti->Height && - s->format == ti->TexFormat)); + if (!ti || !to_nouveau_teximage(ti)->surface.bo) + return GL_FALSE; + + if (level == t->BaseLevel && (s->offset & 0x7f)) + return GL_FALSE; + + return t->Target == GL_TEXTURE_RECTANGLE || + (s->bo && s->format == ti->TexFormat && + s->width == ti->Width && s->height == ti->Height); } 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) { @@ -217,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]; @@ -233,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; @@ -243,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) @@ -251,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); @@ -298,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))) { @@ -318,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; @@ -329,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); } @@ -379,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(ctx, 3, target, level, xoffset, yoffset, zoffset, - width, height, depth, format, type, pixels, - packing, t, ti); -} - -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_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, 1, target, level, xoffset, 0, 0, - width, 1, 1, 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_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; @@ -524,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 @@ -535,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)) @@ -567,44 +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]); - } -} - 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->MapTextureImage = nouveau_map_texture_image; + functions->UnmapTextureImage = nouveau_unmap_texture_image; }