Home | History | Annotate | Download | only in nouveau
      1 /*
      2  * Copyright (C) 2009 Francisco Jerez.
      3  * All Rights Reserved.
      4  *
      5  * Permission is hereby granted, free of charge, to any person obtaining
      6  * a copy of this software and associated documentation files (the
      7  * "Software"), to deal in the Software without restriction, including
      8  * without limitation the rights to use, copy, modify, merge, publish,
      9  * distribute, sublicense, and/or sell copies of the Software, and to
     10  * permit persons to whom the Software is furnished to do so, subject to
     11  * the following conditions:
     12  *
     13  * The above copyright notice and this permission notice (including the
     14  * next paragraph) shall be included in all copies or substantial
     15  * portions of the Software.
     16  *
     17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
     18  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
     19  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
     20  * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
     21  * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
     22  * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
     23  * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
     24  *
     25  */
     26 
     27 #include "nouveau_driver.h"
     28 #include "nouveau_context.h"
     29 #include "nouveau_texture.h"
     30 #include "nouveau_fbo.h"
     31 #include "nouveau_util.h"
     32 
     33 #include "main/pbo.h"
     34 #include "main/texobj.h"
     35 #include "main/texstore.h"
     36 #include "main/texformat.h"
     37 #include "main/texcompress.h"
     38 #include "main/texgetimage.h"
     39 #include "main/mipmap.h"
     40 #include "main/teximage.h"
     41 #include "drivers/common/meta.h"
     42 #include "swrast/s_texfetch.h"
     43 
     44 static struct gl_texture_object *
     45 nouveau_texture_new(struct gl_context *ctx, GLuint name, GLenum target)
     46 {
     47 	struct nouveau_texture *nt = CALLOC_STRUCT(nouveau_texture);
     48 
     49 	_mesa_initialize_texture_object(ctx, &nt->base, name, target);
     50 
     51 	return &nt->base;
     52 }
     53 
     54 static void
     55 nouveau_texture_free(struct gl_context *ctx, struct gl_texture_object *t)
     56 {
     57 	struct nouveau_texture *nt = to_nouveau_texture(t);
     58 	int i;
     59 
     60 	for (i = 0; i < MAX_TEXTURE_LEVELS; i++)
     61 		nouveau_surface_ref(NULL, &nt->surfaces[i]);
     62 
     63 	_mesa_delete_texture_object(ctx, t);
     64 }
     65 
     66 static struct gl_texture_image *
     67 nouveau_teximage_new(struct gl_context *ctx)
     68 {
     69 	struct nouveau_teximage *nti = CALLOC_STRUCT(nouveau_teximage);
     70 
     71 	return &nti->base.Base;
     72 }
     73 
     74 static void
     75 nouveau_teximage_free(struct gl_context *ctx, struct gl_texture_image *ti)
     76 {
     77 	struct nouveau_teximage *nti = to_nouveau_teximage(ti);
     78 
     79 	nouveau_surface_ref(NULL, &nti->surface);
     80 }
     81 
     82 static void
     83 nouveau_map_texture_image(struct gl_context *ctx,
     84 			  struct gl_texture_image *ti,
     85 			  GLuint slice,
     86 			  GLuint x, GLuint y, GLuint w, GLuint h,
     87 			  GLbitfield mode,
     88 			  GLubyte **map,
     89 			  GLint *stride)
     90 {
     91 	struct nouveau_teximage *nti = to_nouveau_teximage(ti);
     92 	struct nouveau_surface *s = &nti->surface;
     93 	struct nouveau_surface *st = &nti->transfer.surface;
     94 	struct nouveau_client *client = context_client(ctx);
     95 
     96 	/* Nouveau has no support for 3D or cubemap textures. */
     97 	assert(slice == 0);
     98 
     99 	if (s->bo) {
    100 		if (!(mode & GL_MAP_READ_BIT) &&
    101 		    nouveau_pushbuf_refd(context_push(ctx), s->bo)) {
    102 			unsigned size;
    103 			/*
    104 			 * Heuristic: use a bounce buffer to pipeline
    105 			 * teximage transfers.
    106 			 */
    107 			st->layout = LINEAR;
    108 			st->format = s->format;
    109 			st->cpp = s->cpp;
    110 			st->width = w;
    111 			st->height = h;
    112 			st->pitch = s->pitch;
    113 			nti->transfer.x = x;
    114 			nti->transfer.y = y;
    115 
    116 			size = get_format_blocksy(st->format, h) * st->pitch;
    117 			*map = nouveau_get_scratch(ctx, size,
    118 					  &st->bo, &st->offset);
    119 			*stride = st->pitch;
    120 		} else {
    121 			int ret, flags = 0;
    122 
    123 			if (mode & GL_MAP_READ_BIT)
    124 				flags |= NOUVEAU_BO_RD;
    125 			if (mode & GL_MAP_WRITE_BIT)
    126 				flags |= NOUVEAU_BO_WR;
    127 
    128 			if (!s->bo->map) {
    129 				ret = nouveau_bo_map(s->bo, flags, client);
    130 				assert(!ret);
    131 			}
    132 
    133 			*map = s->bo->map +
    134 				get_format_blocksy(s->format, y) * s->pitch +
    135 				get_format_blocksx(s->format, x) * s->cpp;
    136 			*stride = s->pitch;
    137 		}
    138 	} else {
    139 		*map = nti->base.Buffer +
    140 			get_format_blocksy(s->format, y) * s->pitch +
    141 			get_format_blocksx(s->format, x) * s->cpp;
    142 		*stride = s->pitch;
    143 	}
    144 }
    145 
    146 static void
    147 nouveau_unmap_texture_image(struct gl_context *ctx, struct gl_texture_image *ti,
    148 			    GLuint slice)
    149 {
    150 	struct nouveau_teximage *nti = to_nouveau_teximage(ti);
    151 	struct nouveau_surface *s = &nti->surface;
    152 	struct nouveau_surface *st = &nti->transfer.surface;
    153 
    154 	if (st->bo) {
    155 		context_drv(ctx)->surface_copy(ctx, s, st, nti->transfer.x,
    156 					       nti->transfer.y, 0, 0,
    157 					       st->width, st->height);
    158 		nouveau_surface_ref(NULL, st);
    159 
    160 	}
    161 }
    162 
    163 static mesa_format
    164 nouveau_choose_tex_format(struct gl_context *ctx, GLenum target,
    165                           GLint internalFormat,
    166 			  GLenum srcFormat, GLenum srcType)
    167 {
    168 	switch (internalFormat) {
    169 	case 4:
    170 	case GL_RGBA:
    171 	case GL_RGBA2:
    172 	case GL_RGBA4:
    173 	case GL_RGBA8:
    174 	case GL_RGBA12:
    175 	case GL_RGBA16:
    176 	case GL_RGB10_A2:
    177 	case GL_COMPRESSED_RGBA:
    178 		return MESA_FORMAT_B8G8R8A8_UNORM;
    179 	case GL_RGB5_A1:
    180 		return MESA_FORMAT_B5G5R5A1_UNORM;
    181 
    182 	case GL_RGB:
    183 	case GL_RGB8:
    184 	case GL_RGB10:
    185 	case GL_RGB12:
    186 	case GL_RGB16:
    187 	case GL_COMPRESSED_RGB:
    188 		return MESA_FORMAT_B8G8R8X8_UNORM;
    189 	case 3:
    190 	case GL_R3_G3_B2:
    191 	case GL_RGB4:
    192 	case GL_RGB5:
    193 		return MESA_FORMAT_B5G6R5_UNORM;
    194 
    195 	case 2:
    196 	case GL_LUMINANCE_ALPHA:
    197 	case GL_LUMINANCE4_ALPHA4:
    198 	case GL_LUMINANCE6_ALPHA2:
    199 	case GL_LUMINANCE12_ALPHA4:
    200 	case GL_LUMINANCE12_ALPHA12:
    201 	case GL_LUMINANCE16_ALPHA16:
    202 	case GL_LUMINANCE8_ALPHA8:
    203 	case GL_COMPRESSED_LUMINANCE_ALPHA:
    204 		return MESA_FORMAT_B8G8R8A8_UNORM;
    205 
    206 	case 1:
    207 	case GL_LUMINANCE:
    208 	case GL_LUMINANCE4:
    209 	case GL_LUMINANCE12:
    210 	case GL_LUMINANCE16:
    211 	case GL_LUMINANCE8:
    212 	case GL_COMPRESSED_LUMINANCE:
    213 		return MESA_FORMAT_L_UNORM8;
    214 
    215 	case GL_ALPHA:
    216 	case GL_ALPHA4:
    217 	case GL_ALPHA12:
    218 	case GL_ALPHA16:
    219 	case GL_ALPHA8:
    220 	case GL_COMPRESSED_ALPHA:
    221 		return MESA_FORMAT_A_UNORM8;
    222 
    223 	case GL_INTENSITY:
    224 	case GL_INTENSITY4:
    225 	case GL_INTENSITY12:
    226 	case GL_INTENSITY16:
    227 	case GL_INTENSITY8:
    228 	case GL_COMPRESSED_INTENSITY:
    229 		return MESA_FORMAT_I_UNORM8;
    230 
    231 	case GL_RGB_S3TC:
    232 	case GL_RGB4_S3TC:
    233 	case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
    234 		return MESA_FORMAT_RGB_DXT1;
    235 
    236 	case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
    237 		return MESA_FORMAT_RGBA_DXT1;
    238 
    239 	case GL_RGBA_S3TC:
    240 	case GL_RGBA4_S3TC:
    241 	case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
    242 		return MESA_FORMAT_RGBA_DXT3;
    243 
    244 	case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
    245 		return MESA_FORMAT_RGBA_DXT5;
    246 
    247 	default:
    248 		assert(0);
    249 	}
    250 }
    251 
    252 static GLboolean
    253 teximage_fits(struct gl_texture_object *t, int level)
    254 {
    255 	struct nouveau_surface *s = &to_nouveau_texture(t)->surfaces[level];
    256 	struct gl_texture_image *ti = t->Image[0][level];
    257 
    258 	if (!ti || !to_nouveau_teximage(ti)->surface.bo)
    259 		return GL_FALSE;
    260 
    261 	if (level == t->BaseLevel && (s->offset & 0x7f))
    262 		return GL_FALSE;
    263 
    264 	return t->Target == GL_TEXTURE_RECTANGLE ||
    265 		(s->bo && s->format == ti->TexFormat &&
    266 		 s->width == ti->Width && s->height == ti->Height);
    267 }
    268 
    269 static GLboolean
    270 validate_teximage(struct gl_context *ctx, struct gl_texture_object *t,
    271 		  int level, int x, int y, int z,
    272 		  int width, int height, int depth)
    273 {
    274 	struct gl_texture_image *ti = t->Image[0][level];
    275 
    276 	if (teximage_fits(t, level)) {
    277 		struct nouveau_surface *ss = to_nouveau_texture(t)->surfaces;
    278 		struct nouveau_surface *s = &to_nouveau_teximage(ti)->surface;
    279 
    280 		if (t->Target == GL_TEXTURE_RECTANGLE)
    281 			nouveau_surface_ref(s, &ss[level]);
    282 		else
    283 			context_drv(ctx)->surface_copy(ctx, &ss[level], s,
    284 						       x, y, x, y,
    285 						       width, height);
    286 
    287 		return GL_TRUE;
    288 	}
    289 
    290 	return GL_FALSE;
    291 }
    292 
    293 static int
    294 get_last_level(struct gl_texture_object *t)
    295 {
    296 	struct gl_texture_image *base = t->Image[0][t->BaseLevel];
    297 
    298 	if (t->Sampler.MinFilter == GL_NEAREST ||
    299 	    t->Sampler.MinFilter == GL_LINEAR || !base)
    300 		return t->BaseLevel;
    301 	else
    302 		return MIN2(t->BaseLevel + base->MaxNumLevels - 1, t->MaxLevel);
    303 }
    304 
    305 static void
    306 relayout_texture(struct gl_context *ctx, struct gl_texture_object *t)
    307 {
    308 	struct gl_texture_image *base = t->Image[0][t->BaseLevel];
    309 
    310 	if (base && t->Target != GL_TEXTURE_RECTANGLE) {
    311 		struct nouveau_surface *ss = to_nouveau_texture(t)->surfaces;
    312 		struct nouveau_surface *s = &to_nouveau_teximage(base)->surface;
    313 		int i, ret, last = get_last_level(t);
    314 		enum nouveau_surface_layout layout =
    315 			(_mesa_is_format_compressed(s->format) ? LINEAR : SWIZZLED);
    316 		unsigned size, pitch, offset = 0,
    317 			width = s->width,
    318 			height = s->height;
    319 
    320 		/* Deallocate the old storage. */
    321 		for (i = 0; i < MAX_TEXTURE_LEVELS; i++)
    322 			nouveau_bo_ref(NULL, &ss[i].bo);
    323 
    324 		/* Relayout the mipmap tree. */
    325 		for (i = t->BaseLevel; i <= last; i++) {
    326 			pitch = _mesa_format_row_stride(s->format, width);
    327 			size = get_format_blocksy(s->format, height) * pitch;
    328 
    329 			/* Images larger than 16B have to be aligned. */
    330 			if (size > 16)
    331 				offset = align(offset, 64);
    332 
    333 			ss[i] = (struct nouveau_surface) {
    334 				.offset = offset,
    335 				.layout = layout,
    336 				.format = s->format,
    337 				.width = width,
    338 				.height = height,
    339 				.cpp = s->cpp,
    340 				.pitch = pitch,
    341 			};
    342 
    343 			offset += size;
    344 			width = minify(width, 1);
    345 			height = minify(height, 1);
    346 		}
    347 
    348 		if (t->BaseLevel <= last) {
    349 			/* Get new storage. */
    350 			size = align(offset, 64);
    351 			assert(size);
    352 
    353 			ret = nouveau_bo_new(context_dev(ctx), NOUVEAU_BO_MAP |
    354 					     NOUVEAU_BO_GART | NOUVEAU_BO_VRAM,
    355 					     0, size, NULL, &ss[last].bo);
    356 			assert(!ret);
    357 
    358 			for (i = t->BaseLevel; i < last; i++)
    359 				nouveau_bo_ref(ss[last].bo, &ss[i].bo);
    360 		}
    361 	}
    362 }
    363 
    364 GLboolean
    365 nouveau_texture_validate(struct gl_context *ctx, struct gl_texture_object *t)
    366 {
    367 	struct nouveau_texture *nt = to_nouveau_texture(t);
    368 	int i, last = get_last_level(t);
    369 
    370 	if (!teximage_fits(t, t->BaseLevel) ||
    371 	    !teximage_fits(t, last))
    372 		return GL_FALSE;
    373 
    374 	if (nt->dirty) {
    375 		nt->dirty = GL_FALSE;
    376 
    377 		/* Copy the teximages to the actual miptree. */
    378 		for (i = t->BaseLevel; i <= last; i++) {
    379 			struct nouveau_surface *s = &nt->surfaces[i];
    380 
    381 			validate_teximage(ctx, t, i, 0, 0, 0,
    382 					  s->width, s->height, 1);
    383 		}
    384 
    385 		PUSH_KICK(context_push(ctx));
    386 	}
    387 
    388 	return GL_TRUE;
    389 }
    390 
    391 void
    392 nouveau_texture_reallocate(struct gl_context *ctx, struct gl_texture_object *t)
    393 {
    394 	if (!teximage_fits(t, t->BaseLevel) ||
    395 	    !teximage_fits(t, get_last_level(t))) {
    396 		texture_dirty(t);
    397 		relayout_texture(ctx, t);
    398 		nouveau_texture_validate(ctx, t);
    399 	}
    400 }
    401 
    402 static unsigned
    403 get_teximage_placement(struct gl_texture_image *ti)
    404 {
    405 	if (ti->TexFormat == MESA_FORMAT_A_UNORM8 ||
    406 	    ti->TexFormat == MESA_FORMAT_L_UNORM8 ||
    407 	    ti->TexFormat == MESA_FORMAT_I_UNORM8)
    408 		/* 1 cpp formats will have to be swizzled by the CPU,
    409 		 * so leave them in system RAM for now. */
    410 		return NOUVEAU_BO_MAP;
    411 	else
    412 		return NOUVEAU_BO_GART | NOUVEAU_BO_MAP;
    413 }
    414 
    415 static void
    416 nouveau_compressed_copy(struct gl_context *ctx, GLint dims,
    417 			struct gl_texture_image *ti,
    418 			GLsizei width, GLsizei height, GLsizei depth,
    419 			const GLvoid *src, GLvoid *dst, int row_stride)
    420 {
    421 	struct compressed_pixelstore store;
    422 	int i;
    423 
    424 	_mesa_compute_compressed_pixelstore(dims, ti->TexFormat,
    425 					    width, height, depth,
    426 					    &ctx->Unpack, &store);
    427 
    428 	src += store.SkipBytes;
    429 
    430 	assert(store.CopySlices == 1);
    431 
    432 	/* copy rows of blocks */
    433 	for (i = 0; i < store.CopyRowsPerSlice; i++) {
    434 		memcpy(dst, src, store.CopyBytesPerRow);
    435 		dst += row_stride;
    436 		src += store.TotalBytesPerRow;
    437 	}
    438 }
    439 
    440 static void
    441 nouveau_teximage(struct gl_context *ctx, GLint dims,
    442 		 struct gl_texture_image *ti,
    443 		 GLsizei imageSize,
    444 		 GLenum format, GLenum type, const GLvoid *pixels,
    445 		 const struct gl_pixelstore_attrib *packing,
    446 		 GLboolean compressed)
    447 {
    448 	struct gl_texture_object *t = ti->TexObject;
    449 	const GLuint level = ti->Level;
    450 	struct nouveau_surface *s = &to_nouveau_teximage(ti)->surface;
    451 	struct nouveau_teximage *nti = to_nouveau_teximage(ti);
    452 	int ret;
    453 	GLuint depth = compressed ? 1 : ti->Depth;
    454 
    455 	/* Allocate a new bo for the image. */
    456 	nouveau_surface_alloc(ctx, s, LINEAR, get_teximage_placement(ti),
    457 			      ti->TexFormat, ti->Width, ti->Height);
    458 	nti->base.RowStride = s->pitch / s->cpp;
    459 
    460 	if (compressed)
    461 		pixels = _mesa_validate_pbo_compressed_teximage(ctx,
    462 			dims, imageSize,
    463 			pixels, packing, "glCompressedTexImage");
    464 	else
    465 		pixels = _mesa_validate_pbo_teximage(ctx,
    466 			dims, ti->Width, ti->Height, depth, format, type,
    467 			pixels, packing, "glTexImage");
    468 
    469 	if (pixels) {
    470 		GLubyte *map;
    471 		int row_stride;
    472 
    473 		/* Store the pixel data. */
    474 		nouveau_map_texture_image(ctx, ti, 0,
    475 					  0, 0, ti->Width, ti->Height,
    476 					  GL_MAP_WRITE_BIT,
    477 					  &map, &row_stride);
    478 
    479 		if (compressed) {
    480 			nouveau_compressed_copy(ctx, dims, ti,
    481 						ti->Width, ti->Height, depth,
    482 						pixels, map, row_stride);
    483 		} else {
    484 			ret = _mesa_texstore(ctx, dims, ti->_BaseFormat,
    485 					     ti->TexFormat,
    486 					     row_stride,
    487 					     &map,
    488 					     ti->Width, ti->Height, depth,
    489 					     format, type, pixels, packing);
    490 			assert(ret);
    491 		}
    492 
    493 		nouveau_unmap_texture_image(ctx, ti, 0);
    494 		_mesa_unmap_teximage_pbo(ctx, packing);
    495 
    496 		if (!validate_teximage(ctx, t, level, 0, 0, 0,
    497 				       ti->Width, ti->Height, depth))
    498 			/* It doesn't fit, mark it as dirty. */
    499 			texture_dirty(t);
    500 	}
    501 
    502 	if (level == t->BaseLevel) {
    503 		if (!teximage_fits(t, level))
    504 			relayout_texture(ctx, t);
    505 		nouveau_texture_validate(ctx, t);
    506 	}
    507 
    508 	context_dirty_i(ctx, TEX_OBJ, ctx->Texture.CurrentUnit);
    509 	context_dirty_i(ctx, TEX_ENV, ctx->Texture.CurrentUnit);
    510 }
    511 
    512 
    513 static void
    514 nouveau_teximage_123d(struct gl_context *ctx, GLuint dims,
    515                       struct gl_texture_image *ti,
    516                       GLenum format, GLenum type, const GLvoid *pixels,
    517                       const struct gl_pixelstore_attrib *packing)
    518 {
    519 	nouveau_teximage(ctx, dims, ti, 0, format, type, pixels,
    520 			 packing, GL_FALSE);
    521 }
    522 
    523 static void
    524 nouveau_compressed_teximage(struct gl_context *ctx, GLuint dims,
    525 		    struct gl_texture_image *ti,
    526 		    GLsizei imageSize, const GLvoid *data)
    527 {
    528 	nouveau_teximage(ctx, 2, ti, imageSize, 0, 0, data,
    529 			 &ctx->Unpack, GL_TRUE);
    530 }
    531 
    532 static GLboolean
    533 nouveau_teximage_alloc(struct gl_context *ctx, struct gl_texture_image *ti)
    534 {
    535 	nouveau_teximage(ctx, 3, ti, 0, 0, 0, NULL,
    536 			 &ctx->DefaultPacking,
    537 			 _mesa_is_format_compressed(ti->TexFormat));
    538 	return GL_TRUE;
    539 }
    540 
    541 static void
    542 nouveau_texsubimage(struct gl_context *ctx, GLint dims,
    543 		    struct gl_texture_image *ti,
    544 		    GLint xoffset, GLint yoffset, GLint zoffset,
    545 		    GLint width, GLint height, GLint depth,
    546 		    GLsizei imageSize,
    547 		    GLenum format, GLenum type, const void *pixels,
    548 		    const struct gl_pixelstore_attrib *packing,
    549 		    GLboolean compressed)
    550 {
    551 	int ret;
    552 
    553 	if (compressed)
    554 		pixels = _mesa_validate_pbo_compressed_teximage(ctx,
    555 				dims, imageSize,
    556 				pixels, packing, "glCompressedTexSubImage");
    557 	else
    558 		pixels = _mesa_validate_pbo_teximage(ctx,
    559 				dims, width, height, depth, format, type,
    560 				pixels, packing, "glTexSubImage");
    561 
    562 	if (pixels) {
    563 		GLubyte *map;
    564 		int row_stride;
    565 
    566 		nouveau_map_texture_image(ctx, ti, 0,
    567 					  xoffset, yoffset, width, height,
    568 					  GL_MAP_WRITE_BIT, &map, &row_stride);
    569 
    570 		if (compressed) {
    571 			nouveau_compressed_copy(ctx, dims, ti,
    572 						width, height, depth,
    573 						pixels, map, row_stride);
    574 		} else {
    575 			ret = _mesa_texstore(ctx, dims, ti->_BaseFormat,
    576 					     ti->TexFormat,
    577 					     row_stride, &map,
    578 					     width, height, depth,
    579 					     format, type, pixels, packing);
    580 			assert(ret);
    581 		}
    582 
    583 		nouveau_unmap_texture_image(ctx, ti, 0);
    584 		_mesa_unmap_teximage_pbo(ctx, packing);
    585 	}
    586 
    587 	if (!to_nouveau_texture(ti->TexObject)->dirty)
    588 		validate_teximage(ctx, ti->TexObject, ti->Level,
    589 				  xoffset, yoffset, zoffset,
    590 				  width, height, depth);
    591 }
    592 
    593 static void
    594 nouveau_texsubimage_123d(struct gl_context *ctx, GLuint dims,
    595                          struct gl_texture_image *ti,
    596                          GLint xoffset, GLint yoffset, GLint zoffset,
    597                          GLint width, GLint height, GLint depth,
    598                          GLenum format, GLenum type, const void *pixels,
    599                          const struct gl_pixelstore_attrib *packing)
    600 {
    601 	nouveau_texsubimage(ctx, dims, ti, xoffset, yoffset, zoffset,
    602 			    width, height, depth, 0, format, type, pixels,
    603 			    packing, GL_FALSE);
    604 }
    605 
    606 static void
    607 nouveau_compressed_texsubimage(struct gl_context *ctx, GLuint dims,
    608 		       struct gl_texture_image *ti,
    609 		       GLint xoffset, GLint yoffset, GLint zoffset,
    610 		       GLsizei width, GLint height, GLint depth,
    611 		       GLenum format,
    612 		       GLint imageSize, const void *data)
    613 {
    614 	nouveau_texsubimage(ctx, dims, ti, xoffset, yoffset, zoffset,
    615 			  width, height, depth, imageSize, format, 0, data,
    616 			  &ctx->Unpack, GL_TRUE);
    617 }
    618 
    619 static void
    620 nouveau_bind_texture(struct gl_context *ctx, GLuint texUnit,
    621                      GLenum target, struct gl_texture_object *t)
    622 {
    623 	context_dirty_i(ctx, TEX_OBJ, texUnit);
    624 	context_dirty_i(ctx, TEX_ENV, texUnit);
    625 }
    626 
    627 static mesa_format
    628 get_texbuffer_format(struct gl_renderbuffer *rb, GLint format)
    629 {
    630 	struct nouveau_surface *s = &to_nouveau_renderbuffer(rb)->surface;
    631 
    632 	if (s->cpp < 4)
    633 		return s->format;
    634 	else if (format == __DRI_TEXTURE_FORMAT_RGBA)
    635 		return MESA_FORMAT_B8G8R8A8_UNORM;
    636 	else
    637 		return MESA_FORMAT_B8G8R8X8_UNORM;
    638 }
    639 
    640 void
    641 nouveau_set_texbuffer(__DRIcontext *dri_ctx,
    642 		      GLint target, GLint format,
    643 		      __DRIdrawable *draw)
    644 {
    645 	struct nouveau_context *nctx = dri_ctx->driverPrivate;
    646 	struct gl_context *ctx = &nctx->base;
    647 	struct gl_framebuffer *fb = draw->driverPrivate;
    648 	struct gl_renderbuffer *rb =
    649 		fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer;
    650 	struct gl_texture_object *t = _mesa_get_current_tex_object(ctx, target);
    651 	struct gl_texture_image *ti;
    652 	struct nouveau_teximage *nti;
    653 	struct nouveau_surface *s;
    654 
    655 	_mesa_lock_texture(ctx, t);
    656 	ti = _mesa_get_tex_image(ctx, t, target, 0);
    657 	nti = to_nouveau_teximage(ti);
    658 	s = &to_nouveau_teximage(ti)->surface;
    659 
    660 	/* Update the texture surface with the given drawable. */
    661 	nouveau_update_renderbuffers(dri_ctx, draw);
    662 	nouveau_surface_ref(&to_nouveau_renderbuffer(rb)->surface, s);
    663 
    664         s->format = get_texbuffer_format(rb, format);
    665 
    666 	/* Update the image fields. */
    667 	_mesa_init_teximage_fields(ctx, ti, s->width, s->height,
    668 				   1, 0, s->cpp, s->format);
    669 	nti->base.RowStride = s->pitch / s->cpp;
    670 
    671 	/* Try to validate it. */
    672 	if (!validate_teximage(ctx, t, 0, 0, 0, 0, s->width, s->height, 1))
    673 		nouveau_texture_reallocate(ctx, t);
    674 
    675 	context_dirty_i(ctx, TEX_OBJ, ctx->Texture.CurrentUnit);
    676 	context_dirty_i(ctx, TEX_ENV, ctx->Texture.CurrentUnit);
    677 
    678 	_mesa_unlock_texture(ctx, t);
    679 }
    680 
    681 void
    682 nouveau_texture_functions_init(struct dd_function_table *functions)
    683 {
    684 	functions->NewTextureObject = nouveau_texture_new;
    685 	functions->DeleteTexture = nouveau_texture_free;
    686 	functions->NewTextureImage = nouveau_teximage_new;
    687 	functions->FreeTextureImageBuffer = nouveau_teximage_free;
    688 	functions->AllocTextureImageBuffer = nouveau_teximage_alloc;
    689 	functions->ChooseTextureFormat = nouveau_choose_tex_format;
    690 	functions->TexImage = nouveau_teximage_123d;
    691 	functions->TexSubImage = nouveau_texsubimage_123d;
    692 	functions->CompressedTexImage = nouveau_compressed_teximage;
    693 	functions->CompressedTexSubImage = nouveau_compressed_texsubimage;
    694 	functions->BindTexture = nouveau_bind_texture;
    695 	functions->MapTextureImage = nouveau_map_texture_image;
    696 	functions->UnmapTextureImage = nouveau_unmap_texture_image;
    697 }
    698