1bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez/*
2bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez * Copyright (C) 2009 Francisco Jerez.
3bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez * All Rights Reserved.
4bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez *
5bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez * Permission is hereby granted, free of charge, to any person obtaining
6bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez * a copy of this software and associated documentation files (the
7bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez * "Software"), to deal in the Software without restriction, including
8bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez * without limitation the rights to use, copy, modify, merge, publish,
9bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez * distribute, sublicense, and/or sell copies of the Software, and to
10bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez * permit persons to whom the Software is furnished to do so, subject to
11bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez * the following conditions:
12bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez *
13bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez * The above copyright notice and this permission notice (including the
14bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez * next paragraph) shall be included in all copies or substantial
15bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez * portions of the Software.
16bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez *
17bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
20bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
21bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
22bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
23bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez *
25bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez */
26bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
27bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez#include "nouveau_driver.h"
28bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez#include "nouveau_context.h"
29bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez#include "nouveau_texture.h"
304a7e9b5df453055ed6eedce1ea5c1d4a2f810fa7Francisco Jerez#include "nouveau_fbo.h"
31bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez#include "nouveau_util.h"
32bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
338042d751debb7a8375e8bc587189fea9a5a8371dJohannes Obermayr#include "main/pbo.h"
34bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez#include "main/texobj.h"
35bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez#include "main/texstore.h"
36bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez#include "main/texformat.h"
37bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez#include "main/texcompress.h"
38bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez#include "main/texgetimage.h"
39bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez#include "main/mipmap.h"
404a7e9b5df453055ed6eedce1ea5c1d4a2f810fa7Francisco Jerez#include "main/teximage.h"
41e96a52e9933eea7264a42983db1428368bcb4962Francisco Jerez#include "drivers/common/meta.h"
42baeefef2c0445bfd717a3086fdd9b5bd5d9cb675Brian Paul#include "swrast/s_texfetch.h"
43bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
44bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerezstatic struct gl_texture_object *
45f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergnouveau_texture_new(struct gl_context *ctx, GLuint name, GLenum target)
46bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez{
47bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	struct nouveau_texture *nt = CALLOC_STRUCT(nouveau_texture);
48bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
49a6b1a7c0d269256ffbaf2300710601cde8ac872cMarek Olšák	_mesa_initialize_texture_object(ctx, &nt->base, name, target);
50bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
51bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	return &nt->base;
52bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez}
53bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
54bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerezstatic void
55f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergnouveau_texture_free(struct gl_context *ctx, struct gl_texture_object *t)
56bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez{
57bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	struct nouveau_texture *nt = to_nouveau_texture(t);
58bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	int i;
59bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
60bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	for (i = 0; i < MAX_TEXTURE_LEVELS; i++)
61bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		nouveau_surface_ref(NULL, &nt->surfaces[i]);
62bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
63bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	_mesa_delete_texture_object(ctx, t);
64bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez}
65bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
66bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerezstatic struct gl_texture_image *
67f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergnouveau_teximage_new(struct gl_context *ctx)
68bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez{
69bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	struct nouveau_teximage *nti = CALLOC_STRUCT(nouveau_teximage);
70bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
716e0f9001fe3fb191c2928bd09aa9e9d05ddf4ea9Brian Paul	return &nti->base.Base;
72bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez}
73bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
74bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerezstatic void
75f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergnouveau_teximage_free(struct gl_context *ctx, struct gl_texture_image *ti)
76bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez{
77bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	struct nouveau_teximage *nti = to_nouveau_teximage(ti);
78bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
79bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	nouveau_surface_ref(NULL, &nti->surface);
80bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez}
81bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
82bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerezstatic void
835b257442a8a46fdabdaad54c5f18a44f02696590Eric Anholtnouveau_map_texture_image(struct gl_context *ctx,
845b257442a8a46fdabdaad54c5f18a44f02696590Eric Anholt			  struct gl_texture_image *ti,
855b257442a8a46fdabdaad54c5f18a44f02696590Eric Anholt			  GLuint slice,
865b257442a8a46fdabdaad54c5f18a44f02696590Eric Anholt			  GLuint x, GLuint y, GLuint w, GLuint h,
875b257442a8a46fdabdaad54c5f18a44f02696590Eric Anholt			  GLbitfield mode,
885b257442a8a46fdabdaad54c5f18a44f02696590Eric Anholt			  GLubyte **map,
895b257442a8a46fdabdaad54c5f18a44f02696590Eric Anholt			  GLint *stride)
905b257442a8a46fdabdaad54c5f18a44f02696590Eric Anholt{
915b257442a8a46fdabdaad54c5f18a44f02696590Eric Anholt	struct nouveau_teximage *nti = to_nouveau_teximage(ti);
925b257442a8a46fdabdaad54c5f18a44f02696590Eric Anholt	struct nouveau_surface *s = &nti->surface;
935b257442a8a46fdabdaad54c5f18a44f02696590Eric Anholt	struct nouveau_surface *st = &nti->transfer.surface;
942e47d01c9e5325906cf3bb979279599991c6328eBen Skeggs	struct nouveau_client *client = context_client(ctx);
955b257442a8a46fdabdaad54c5f18a44f02696590Eric Anholt
965b257442a8a46fdabdaad54c5f18a44f02696590Eric Anholt	/* Nouveau has no support for 3D or cubemap textures. */
975b257442a8a46fdabdaad54c5f18a44f02696590Eric Anholt	assert(slice == 0);
985b257442a8a46fdabdaad54c5f18a44f02696590Eric Anholt
995b257442a8a46fdabdaad54c5f18a44f02696590Eric Anholt	if (s->bo) {
1005b257442a8a46fdabdaad54c5f18a44f02696590Eric Anholt		if (!(mode & GL_MAP_READ_BIT) &&
1012e47d01c9e5325906cf3bb979279599991c6328eBen Skeggs		    nouveau_pushbuf_refd(context_push(ctx), s->bo)) {
1026d5efe96ee710ca1dd5f745f74a5bbfa4fd42fd9Viktor Novotný			unsigned size;
1035b257442a8a46fdabdaad54c5f18a44f02696590Eric Anholt			/*
1045b257442a8a46fdabdaad54c5f18a44f02696590Eric Anholt			 * Heuristic: use a bounce buffer to pipeline
1055b257442a8a46fdabdaad54c5f18a44f02696590Eric Anholt			 * teximage transfers.
1065b257442a8a46fdabdaad54c5f18a44f02696590Eric Anholt			 */
1075b257442a8a46fdabdaad54c5f18a44f02696590Eric Anholt			st->layout = LINEAR;
1085b257442a8a46fdabdaad54c5f18a44f02696590Eric Anholt			st->format = s->format;
1095b257442a8a46fdabdaad54c5f18a44f02696590Eric Anholt			st->cpp = s->cpp;
1105b257442a8a46fdabdaad54c5f18a44f02696590Eric Anholt			st->width = w;
1115b257442a8a46fdabdaad54c5f18a44f02696590Eric Anholt			st->height = h;
1125b257442a8a46fdabdaad54c5f18a44f02696590Eric Anholt			st->pitch = s->pitch;
1135b257442a8a46fdabdaad54c5f18a44f02696590Eric Anholt			nti->transfer.x = x;
1145b257442a8a46fdabdaad54c5f18a44f02696590Eric Anholt			nti->transfer.y = y;
1155b257442a8a46fdabdaad54c5f18a44f02696590Eric Anholt
1166d5efe96ee710ca1dd5f745f74a5bbfa4fd42fd9Viktor Novotný			size = get_format_blocksy(st->format, h) * st->pitch;
1176d5efe96ee710ca1dd5f745f74a5bbfa4fd42fd9Viktor Novotný			*map = nouveau_get_scratch(ctx, size,
1186d5efe96ee710ca1dd5f745f74a5bbfa4fd42fd9Viktor Novotný					  &st->bo, &st->offset);
1195b257442a8a46fdabdaad54c5f18a44f02696590Eric Anholt			*stride = st->pitch;
1205b257442a8a46fdabdaad54c5f18a44f02696590Eric Anholt		} else {
1215b257442a8a46fdabdaad54c5f18a44f02696590Eric Anholt			int ret, flags = 0;
1225b257442a8a46fdabdaad54c5f18a44f02696590Eric Anholt
1235b257442a8a46fdabdaad54c5f18a44f02696590Eric Anholt			if (mode & GL_MAP_READ_BIT)
1245b257442a8a46fdabdaad54c5f18a44f02696590Eric Anholt				flags |= NOUVEAU_BO_RD;
1255b257442a8a46fdabdaad54c5f18a44f02696590Eric Anholt			if (mode & GL_MAP_WRITE_BIT)
1265b257442a8a46fdabdaad54c5f18a44f02696590Eric Anholt				flags |= NOUVEAU_BO_WR;
1275b257442a8a46fdabdaad54c5f18a44f02696590Eric Anholt
1285b257442a8a46fdabdaad54c5f18a44f02696590Eric Anholt			if (!s->bo->map) {
1292e47d01c9e5325906cf3bb979279599991c6328eBen Skeggs				ret = nouveau_bo_map(s->bo, flags, client);
1305b257442a8a46fdabdaad54c5f18a44f02696590Eric Anholt				assert(!ret);
1315b257442a8a46fdabdaad54c5f18a44f02696590Eric Anholt			}
1325b257442a8a46fdabdaad54c5f18a44f02696590Eric Anholt
1336d5efe96ee710ca1dd5f745f74a5bbfa4fd42fd9Viktor Novotný			*map = s->bo->map +
1346d5efe96ee710ca1dd5f745f74a5bbfa4fd42fd9Viktor Novotný				get_format_blocksy(s->format, y) * s->pitch +
1356d5efe96ee710ca1dd5f745f74a5bbfa4fd42fd9Viktor Novotný				get_format_blocksx(s->format, x) * s->cpp;
1365b257442a8a46fdabdaad54c5f18a44f02696590Eric Anholt			*stride = s->pitch;
1375b257442a8a46fdabdaad54c5f18a44f02696590Eric Anholt		}
1385b257442a8a46fdabdaad54c5f18a44f02696590Eric Anholt	} else {
139ea05e259c9490657a5062480a06ff1cd1b924043Eric Anholt		*map = nti->base.Buffer +
1406d5efe96ee710ca1dd5f745f74a5bbfa4fd42fd9Viktor Novotný			get_format_blocksy(s->format, y) * s->pitch +
1416d5efe96ee710ca1dd5f745f74a5bbfa4fd42fd9Viktor Novotný			get_format_blocksx(s->format, x) * s->cpp;
1425b257442a8a46fdabdaad54c5f18a44f02696590Eric Anholt		*stride = s->pitch;
1435b257442a8a46fdabdaad54c5f18a44f02696590Eric Anholt	}
1445b257442a8a46fdabdaad54c5f18a44f02696590Eric Anholt}
1455b257442a8a46fdabdaad54c5f18a44f02696590Eric Anholt
1465b257442a8a46fdabdaad54c5f18a44f02696590Eric Anholtstatic void
1475b257442a8a46fdabdaad54c5f18a44f02696590Eric Anholtnouveau_unmap_texture_image(struct gl_context *ctx, struct gl_texture_image *ti,
1485b257442a8a46fdabdaad54c5f18a44f02696590Eric Anholt			    GLuint slice)
1495b257442a8a46fdabdaad54c5f18a44f02696590Eric Anholt{
1505b257442a8a46fdabdaad54c5f18a44f02696590Eric Anholt	struct nouveau_teximage *nti = to_nouveau_teximage(ti);
1515b257442a8a46fdabdaad54c5f18a44f02696590Eric Anholt	struct nouveau_surface *s = &nti->surface;
1525b257442a8a46fdabdaad54c5f18a44f02696590Eric Anholt	struct nouveau_surface *st = &nti->transfer.surface;
1535b257442a8a46fdabdaad54c5f18a44f02696590Eric Anholt
1545b257442a8a46fdabdaad54c5f18a44f02696590Eric Anholt	if (st->bo) {
1555b257442a8a46fdabdaad54c5f18a44f02696590Eric Anholt		context_drv(ctx)->surface_copy(ctx, s, st, nti->transfer.x,
1565b257442a8a46fdabdaad54c5f18a44f02696590Eric Anholt					       nti->transfer.y, 0, 0,
1575b257442a8a46fdabdaad54c5f18a44f02696590Eric Anholt					       st->width, st->height);
1585b257442a8a46fdabdaad54c5f18a44f02696590Eric Anholt		nouveau_surface_ref(NULL, st);
1595b257442a8a46fdabdaad54c5f18a44f02696590Eric Anholt
1605b257442a8a46fdabdaad54c5f18a44f02696590Eric Anholt	}
1615b257442a8a46fdabdaad54c5f18a44f02696590Eric Anholt}
1625b257442a8a46fdabdaad54c5f18a44f02696590Eric Anholt
16371fe9437169cfdafda8814aa814bb85429fb6cfcMark Muellerstatic mesa_format
164d47a6ada9ca9670c60fc141fabadf40c63031c08Brian Paulnouveau_choose_tex_format(struct gl_context *ctx, GLenum target,
165d47a6ada9ca9670c60fc141fabadf40c63031c08Brian Paul                          GLint internalFormat,
166bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez			  GLenum srcFormat, GLenum srcType)
167bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez{
168bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	switch (internalFormat) {
169bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	case 4:
170bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	case GL_RGBA:
17151e8a66fa197de7e17fb94d901a4cf26f0812670Francisco Jerez	case GL_RGBA2:
17251e8a66fa197de7e17fb94d901a4cf26f0812670Francisco Jerez	case GL_RGBA4:
17351e8a66fa197de7e17fb94d901a4cf26f0812670Francisco Jerez	case GL_RGBA8:
174bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	case GL_RGBA12:
175bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	case GL_RGBA16:
17651e8a66fa197de7e17fb94d901a4cf26f0812670Francisco Jerez	case GL_RGB10_A2:
177c5ca972c076187aacc3ff110a1db8c86a8a47426Francisco Jerez	case GL_COMPRESSED_RGBA:
178ef145ba4ded6aafb28e3bda02fb348e6b8bff12aMark Mueller		return MESA_FORMAT_B8G8R8A8_UNORM;
17951e8a66fa197de7e17fb94d901a4cf26f0812670Francisco Jerez	case GL_RGB5_A1:
180eeed49f5f290793870c60b5b635b977a732a1eb4Mark Mueller		return MESA_FORMAT_B5G5R5A1_UNORM;
18151e8a66fa197de7e17fb94d901a4cf26f0812670Francisco Jerez
182bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	case GL_RGB:
183bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	case GL_RGB8:
184bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	case GL_RGB10:
185bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	case GL_RGB12:
186bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	case GL_RGB16:
187c5ca972c076187aacc3ff110a1db8c86a8a47426Francisco Jerez	case GL_COMPRESSED_RGB:
188ef145ba4ded6aafb28e3bda02fb348e6b8bff12aMark Mueller		return MESA_FORMAT_B8G8R8X8_UNORM;
189bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	case 3:
190bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	case GL_R3_G3_B2:
191bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	case GL_RGB4:
192bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	case GL_RGB5:
193eeed49f5f290793870c60b5b635b977a732a1eb4Mark Mueller		return MESA_FORMAT_B5G6R5_UNORM;
194bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
195bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	case 2:
196bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	case GL_LUMINANCE_ALPHA:
197bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	case GL_LUMINANCE4_ALPHA4:
198bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	case GL_LUMINANCE6_ALPHA2:
199bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	case GL_LUMINANCE12_ALPHA4:
200bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	case GL_LUMINANCE12_ALPHA12:
201bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	case GL_LUMINANCE16_ALPHA16:
202bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	case GL_LUMINANCE8_ALPHA8:
203c5ca972c076187aacc3ff110a1db8c86a8a47426Francisco Jerez	case GL_COMPRESSED_LUMINANCE_ALPHA:
204ef145ba4ded6aafb28e3bda02fb348e6b8bff12aMark Mueller		return MESA_FORMAT_B8G8R8A8_UNORM;
205bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
20651e8a66fa197de7e17fb94d901a4cf26f0812670Francisco Jerez	case 1:
20751e8a66fa197de7e17fb94d901a4cf26f0812670Francisco Jerez	case GL_LUMINANCE:
20851e8a66fa197de7e17fb94d901a4cf26f0812670Francisco Jerez	case GL_LUMINANCE4:
20951e8a66fa197de7e17fb94d901a4cf26f0812670Francisco Jerez	case GL_LUMINANCE12:
21051e8a66fa197de7e17fb94d901a4cf26f0812670Francisco Jerez	case GL_LUMINANCE16:
21151e8a66fa197de7e17fb94d901a4cf26f0812670Francisco Jerez	case GL_LUMINANCE8:
212c5ca972c076187aacc3ff110a1db8c86a8a47426Francisco Jerez	case GL_COMPRESSED_LUMINANCE:
21350a01d2acafb2a937e62b24258e2e777c0cd1489Mark Mueller		return MESA_FORMAT_L_UNORM8;
21451e8a66fa197de7e17fb94d901a4cf26f0812670Francisco Jerez
21551e8a66fa197de7e17fb94d901a4cf26f0812670Francisco Jerez	case GL_ALPHA:
21651e8a66fa197de7e17fb94d901a4cf26f0812670Francisco Jerez	case GL_ALPHA4:
21751e8a66fa197de7e17fb94d901a4cf26f0812670Francisco Jerez	case GL_ALPHA12:
21851e8a66fa197de7e17fb94d901a4cf26f0812670Francisco Jerez	case GL_ALPHA16:
21951e8a66fa197de7e17fb94d901a4cf26f0812670Francisco Jerez	case GL_ALPHA8:
220c5ca972c076187aacc3ff110a1db8c86a8a47426Francisco Jerez	case GL_COMPRESSED_ALPHA:
22150a01d2acafb2a937e62b24258e2e777c0cd1489Mark Mueller		return MESA_FORMAT_A_UNORM8;
22251e8a66fa197de7e17fb94d901a4cf26f0812670Francisco Jerez
223bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	case GL_INTENSITY:
224bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	case GL_INTENSITY4:
225bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	case GL_INTENSITY12:
226bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	case GL_INTENSITY16:
227bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	case GL_INTENSITY8:
228b676df9abf46bca84ab2f7c36dd5a556a1524966Ilia Mirkin	case GL_COMPRESSED_INTENSITY:
22950a01d2acafb2a937e62b24258e2e777c0cd1489Mark Mueller		return MESA_FORMAT_I_UNORM8;
230bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
2316d5efe96ee710ca1dd5f745f74a5bbfa4fd42fd9Viktor Novotný	case GL_RGB_S3TC:
2326d5efe96ee710ca1dd5f745f74a5bbfa4fd42fd9Viktor Novotný	case GL_RGB4_S3TC:
2336d5efe96ee710ca1dd5f745f74a5bbfa4fd42fd9Viktor Novotný	case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
2346d5efe96ee710ca1dd5f745f74a5bbfa4fd42fd9Viktor Novotný		return MESA_FORMAT_RGB_DXT1;
2356d5efe96ee710ca1dd5f745f74a5bbfa4fd42fd9Viktor Novotný
2366d5efe96ee710ca1dd5f745f74a5bbfa4fd42fd9Viktor Novotný	case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
2376d5efe96ee710ca1dd5f745f74a5bbfa4fd42fd9Viktor Novotný		return MESA_FORMAT_RGBA_DXT1;
2386d5efe96ee710ca1dd5f745f74a5bbfa4fd42fd9Viktor Novotný
2396d5efe96ee710ca1dd5f745f74a5bbfa4fd42fd9Viktor Novotný	case GL_RGBA_S3TC:
2406d5efe96ee710ca1dd5f745f74a5bbfa4fd42fd9Viktor Novotný	case GL_RGBA4_S3TC:
2416d5efe96ee710ca1dd5f745f74a5bbfa4fd42fd9Viktor Novotný	case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
2426d5efe96ee710ca1dd5f745f74a5bbfa4fd42fd9Viktor Novotný		return MESA_FORMAT_RGBA_DXT3;
2436d5efe96ee710ca1dd5f745f74a5bbfa4fd42fd9Viktor Novotný
2446d5efe96ee710ca1dd5f745f74a5bbfa4fd42fd9Viktor Novotný	case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
2456d5efe96ee710ca1dd5f745f74a5bbfa4fd42fd9Viktor Novotný		return MESA_FORMAT_RGBA_DXT5;
2466d5efe96ee710ca1dd5f745f74a5bbfa4fd42fd9Viktor Novotný
247bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	default:
248bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		assert(0);
249bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	}
250bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez}
251bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
252323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerezstatic GLboolean
25398add55fffc29e0c40859fd5e9cec47fa1e352f5Francisco Jerezteximage_fits(struct gl_texture_object *t, int level)
254323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez{
255323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez	struct nouveau_surface *s = &to_nouveau_texture(t)->surfaces[level];
25650be9bc6ce8582b3d3cd4fa47976cbeac28b8c26Xavier Chantry	struct gl_texture_image *ti = t->Image[0][level];
257323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez
258bec626ff63ad1d5c7c3e4b5b1d7a741e4f7d55acFrancisco Jerez	if (!ti || !to_nouveau_teximage(ti)->surface.bo)
259bec626ff63ad1d5c7c3e4b5b1d7a741e4f7d55acFrancisco Jerez		return GL_FALSE;
260bec626ff63ad1d5c7c3e4b5b1d7a741e4f7d55acFrancisco Jerez
26198add55fffc29e0c40859fd5e9cec47fa1e352f5Francisco Jerez	if (level == t->BaseLevel && (s->offset & 0x7f))
262bec626ff63ad1d5c7c3e4b5b1d7a741e4f7d55acFrancisco Jerez		return GL_FALSE;
263bec626ff63ad1d5c7c3e4b5b1d7a741e4f7d55acFrancisco Jerez
264bec626ff63ad1d5c7c3e4b5b1d7a741e4f7d55acFrancisco Jerez	return t->Target == GL_TEXTURE_RECTANGLE ||
265bec626ff63ad1d5c7c3e4b5b1d7a741e4f7d55acFrancisco Jerez		(s->bo && s->format == ti->TexFormat &&
266bec626ff63ad1d5c7c3e4b5b1d7a741e4f7d55acFrancisco Jerez		 s->width == ti->Width && s->height == ti->Height);
267323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez}
268323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez
269323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerezstatic GLboolean
270f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergvalidate_teximage(struct gl_context *ctx, struct gl_texture_object *t,
271323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez		  int level, int x, int y, int z,
272323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez		  int width, int height, int depth)
273323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez{
274323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez	struct gl_texture_image *ti = t->Image[0][level];
275323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez
27698add55fffc29e0c40859fd5e9cec47fa1e352f5Francisco Jerez	if (teximage_fits(t, level)) {
277323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez		struct nouveau_surface *ss = to_nouveau_texture(t)->surfaces;
278323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez		struct nouveau_surface *s = &to_nouveau_teximage(ti)->surface;
279323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez
280a7b8d105a6efe4056633f7129f80aac1f13cc246Francisco Jerez		if (t->Target == GL_TEXTURE_RECTANGLE)
281a7b8d105a6efe4056633f7129f80aac1f13cc246Francisco Jerez			nouveau_surface_ref(s, &ss[level]);
282a7b8d105a6efe4056633f7129f80aac1f13cc246Francisco Jerez		else
283a7b8d105a6efe4056633f7129f80aac1f13cc246Francisco Jerez			context_drv(ctx)->surface_copy(ctx, &ss[level], s,
284a7b8d105a6efe4056633f7129f80aac1f13cc246Francisco Jerez						       x, y, x, y,
285a7b8d105a6efe4056633f7129f80aac1f13cc246Francisco Jerez						       width, height);
286323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez
287323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez		return GL_TRUE;
288323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez	}
289323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez
290323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez	return GL_FALSE;
291323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez}
292323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez
293323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerezstatic int
294323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerezget_last_level(struct gl_texture_object *t)
295323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez{
296323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez	struct gl_texture_image *base = t->Image[0][t->BaseLevel];
297323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez
298ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul	if (t->Sampler.MinFilter == GL_NEAREST ||
299ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul	    t->Sampler.MinFilter == GL_LINEAR || !base)
300323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez		return t->BaseLevel;
301323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez	else
3028111342e814304730bed34446ea816cbc17a5775Marek Olšák		return MIN2(t->BaseLevel + base->MaxNumLevels - 1, t->MaxLevel);
303323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez}
304323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez
305323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerezstatic void
306f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergrelayout_texture(struct gl_context *ctx, struct gl_texture_object *t)
307323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez{
308323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez	struct gl_texture_image *base = t->Image[0][t->BaseLevel];
309323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez
310a7b8d105a6efe4056633f7129f80aac1f13cc246Francisco Jerez	if (base && t->Target != GL_TEXTURE_RECTANGLE) {
311323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez		struct nouveau_surface *ss = to_nouveau_texture(t)->surfaces;
312323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez		struct nouveau_surface *s = &to_nouveau_teximage(base)->surface;
313323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez		int i, ret, last = get_last_level(t);
3146d5efe96ee710ca1dd5f745f74a5bbfa4fd42fd9Viktor Novotný		enum nouveau_surface_layout layout =
3156d5efe96ee710ca1dd5f745f74a5bbfa4fd42fd9Viktor Novotný			(_mesa_is_format_compressed(s->format) ? LINEAR : SWIZZLED);
3166d5efe96ee710ca1dd5f745f74a5bbfa4fd42fd9Viktor Novotný		unsigned size, pitch, offset = 0,
317323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez			width = s->width,
318323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez			height = s->height;
319323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez
320323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez		/* Deallocate the old storage. */
321323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez		for (i = 0; i < MAX_TEXTURE_LEVELS; i++)
322323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez			nouveau_bo_ref(NULL, &ss[i].bo);
323323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez
324323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez		/* Relayout the mipmap tree. */
325323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez		for (i = t->BaseLevel; i <= last; i++) {
3266d5efe96ee710ca1dd5f745f74a5bbfa4fd42fd9Viktor Novotný			pitch = _mesa_format_row_stride(s->format, width);
3276d5efe96ee710ca1dd5f745f74a5bbfa4fd42fd9Viktor Novotný			size = get_format_blocksy(s->format, height) * pitch;
328323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez
329323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez			/* Images larger than 16B have to be aligned. */
330323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez			if (size > 16)
331323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez				offset = align(offset, 64);
332323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez
333323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez			ss[i] = (struct nouveau_surface) {
334323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez				.offset = offset,
3356d5efe96ee710ca1dd5f745f74a5bbfa4fd42fd9Viktor Novotný				.layout = layout,
336323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez				.format = s->format,
337323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez				.width = width,
338323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez				.height = height,
339323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez				.cpp = s->cpp,
3406d5efe96ee710ca1dd5f745f74a5bbfa4fd42fd9Viktor Novotný				.pitch = pitch,
341323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez			};
342323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez
343323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez			offset += size;
34447c0b5ecdd14ab5b07e4d3016e8dff7c9c3abb8bEric Anholt			width = minify(width, 1);
34547c0b5ecdd14ab5b07e4d3016e8dff7c9c3abb8bEric Anholt			height = minify(height, 1);
346323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez		}
347323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez
348d72d67832bd7a5f2aa0c402333a7de6804ad35efIlia Mirkin		if (t->BaseLevel <= last) {
349d72d67832bd7a5f2aa0c402333a7de6804ad35efIlia Mirkin			/* Get new storage. */
350d72d67832bd7a5f2aa0c402333a7de6804ad35efIlia Mirkin			size = align(offset, 64);
351d72d67832bd7a5f2aa0c402333a7de6804ad35efIlia Mirkin			assert(size);
352d72d67832bd7a5f2aa0c402333a7de6804ad35efIlia Mirkin
353d72d67832bd7a5f2aa0c402333a7de6804ad35efIlia Mirkin			ret = nouveau_bo_new(context_dev(ctx), NOUVEAU_BO_MAP |
354d72d67832bd7a5f2aa0c402333a7de6804ad35efIlia Mirkin					     NOUVEAU_BO_GART | NOUVEAU_BO_VRAM,
355d72d67832bd7a5f2aa0c402333a7de6804ad35efIlia Mirkin					     0, size, NULL, &ss[last].bo);
356d72d67832bd7a5f2aa0c402333a7de6804ad35efIlia Mirkin			assert(!ret);
357d72d67832bd7a5f2aa0c402333a7de6804ad35efIlia Mirkin
358d72d67832bd7a5f2aa0c402333a7de6804ad35efIlia Mirkin			for (i = t->BaseLevel; i < last; i++)
359d72d67832bd7a5f2aa0c402333a7de6804ad35efIlia Mirkin				nouveau_bo_ref(ss[last].bo, &ss[i].bo);
360d72d67832bd7a5f2aa0c402333a7de6804ad35efIlia Mirkin		}
361323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez	}
362323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez}
363323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez
364323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco JerezGLboolean
365f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergnouveau_texture_validate(struct gl_context *ctx, struct gl_texture_object *t)
366323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez{
367323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez	struct nouveau_texture *nt = to_nouveau_texture(t);
368323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez	int i, last = get_last_level(t);
369323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez
37098add55fffc29e0c40859fd5e9cec47fa1e352f5Francisco Jerez	if (!teximage_fits(t, t->BaseLevel) ||
37198add55fffc29e0c40859fd5e9cec47fa1e352f5Francisco Jerez	    !teximage_fits(t, last))
372323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez		return GL_FALSE;
373323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez
374323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez	if (nt->dirty) {
375323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez		nt->dirty = GL_FALSE;
376323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez
377323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez		/* Copy the teximages to the actual miptree. */
378323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez		for (i = t->BaseLevel; i <= last; i++) {
379323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez			struct nouveau_surface *s = &nt->surfaces[i];
380323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez
381323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez			validate_teximage(ctx, t, i, 0, 0, 0,
382323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez					  s->width, s->height, 1);
383323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez		}
3843c0eab714816618314324ac02712fa59e5ed385aFrancisco Jerez
3852e47d01c9e5325906cf3bb979279599991c6328eBen Skeggs		PUSH_KICK(context_push(ctx));
386323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez	}
387323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez
388323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez	return GL_TRUE;
389323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez}
390323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez
391323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerezvoid
392f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergnouveau_texture_reallocate(struct gl_context *ctx, struct gl_texture_object *t)
393323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez{
39498add55fffc29e0c40859fd5e9cec47fa1e352f5Francisco Jerez	if (!teximage_fits(t, t->BaseLevel) ||
39598add55fffc29e0c40859fd5e9cec47fa1e352f5Francisco Jerez	    !teximage_fits(t, get_last_level(t))) {
39650be9bc6ce8582b3d3cd4fa47976cbeac28b8c26Xavier Chantry		texture_dirty(t);
39750be9bc6ce8582b3d3cd4fa47976cbeac28b8c26Xavier Chantry		relayout_texture(ctx, t);
39850be9bc6ce8582b3d3cd4fa47976cbeac28b8c26Xavier Chantry		nouveau_texture_validate(ctx, t);
39950be9bc6ce8582b3d3cd4fa47976cbeac28b8c26Xavier Chantry	}
400323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez}
401323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez
402323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerezstatic unsigned
403323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerezget_teximage_placement(struct gl_texture_image *ti)
404323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez{
40550a01d2acafb2a937e62b24258e2e777c0cd1489Mark Mueller	if (ti->TexFormat == MESA_FORMAT_A_UNORM8 ||
40650a01d2acafb2a937e62b24258e2e777c0cd1489Mark Mueller	    ti->TexFormat == MESA_FORMAT_L_UNORM8 ||
40750a01d2acafb2a937e62b24258e2e777c0cd1489Mark Mueller	    ti->TexFormat == MESA_FORMAT_I_UNORM8)
408323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez		/* 1 cpp formats will have to be swizzled by the CPU,
409323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez		 * so leave them in system RAM for now. */
410323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez		return NOUVEAU_BO_MAP;
411323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez	else
412323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez		return NOUVEAU_BO_GART | NOUVEAU_BO_MAP;
413323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez}
414323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez
415bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerezstatic void
416d78b533c29bcd607c5e2d8b51aec6a0da50a3b5bIlia Mirkinnouveau_compressed_copy(struct gl_context *ctx, GLint dims,
417d78b533c29bcd607c5e2d8b51aec6a0da50a3b5bIlia Mirkin			struct gl_texture_image *ti,
418d78b533c29bcd607c5e2d8b51aec6a0da50a3b5bIlia Mirkin			GLsizei width, GLsizei height, GLsizei depth,
419d78b533c29bcd607c5e2d8b51aec6a0da50a3b5bIlia Mirkin			const GLvoid *src, GLvoid *dst, int row_stride)
420d78b533c29bcd607c5e2d8b51aec6a0da50a3b5bIlia Mirkin{
421d78b533c29bcd607c5e2d8b51aec6a0da50a3b5bIlia Mirkin	struct compressed_pixelstore store;
422d78b533c29bcd607c5e2d8b51aec6a0da50a3b5bIlia Mirkin	int i;
423d78b533c29bcd607c5e2d8b51aec6a0da50a3b5bIlia Mirkin
424d78b533c29bcd607c5e2d8b51aec6a0da50a3b5bIlia Mirkin	_mesa_compute_compressed_pixelstore(dims, ti->TexFormat,
425d78b533c29bcd607c5e2d8b51aec6a0da50a3b5bIlia Mirkin					    width, height, depth,
426d78b533c29bcd607c5e2d8b51aec6a0da50a3b5bIlia Mirkin					    &ctx->Unpack, &store);
427d78b533c29bcd607c5e2d8b51aec6a0da50a3b5bIlia Mirkin
428d78b533c29bcd607c5e2d8b51aec6a0da50a3b5bIlia Mirkin	src += store.SkipBytes;
429d78b533c29bcd607c5e2d8b51aec6a0da50a3b5bIlia Mirkin
430d78b533c29bcd607c5e2d8b51aec6a0da50a3b5bIlia Mirkin	assert(store.CopySlices == 1);
431d78b533c29bcd607c5e2d8b51aec6a0da50a3b5bIlia Mirkin
432d78b533c29bcd607c5e2d8b51aec6a0da50a3b5bIlia Mirkin	/* copy rows of blocks */
433d78b533c29bcd607c5e2d8b51aec6a0da50a3b5bIlia Mirkin	for (i = 0; i < store.CopyRowsPerSlice; i++) {
434d78b533c29bcd607c5e2d8b51aec6a0da50a3b5bIlia Mirkin		memcpy(dst, src, store.CopyBytesPerRow);
435d78b533c29bcd607c5e2d8b51aec6a0da50a3b5bIlia Mirkin		dst += row_stride;
436d78b533c29bcd607c5e2d8b51aec6a0da50a3b5bIlia Mirkin		src += store.TotalBytesPerRow;
437d78b533c29bcd607c5e2d8b51aec6a0da50a3b5bIlia Mirkin	}
438d78b533c29bcd607c5e2d8b51aec6a0da50a3b5bIlia Mirkin}
439d78b533c29bcd607c5e2d8b51aec6a0da50a3b5bIlia Mirkin
440d78b533c29bcd607c5e2d8b51aec6a0da50a3b5bIlia Mirkinstatic void
44192c64624cd7533cde466dbec8722f7f72f275fd8Brian Paulnouveau_teximage(struct gl_context *ctx, GLint dims,
44292c64624cd7533cde466dbec8722f7f72f275fd8Brian Paul		 struct gl_texture_image *ti,
4436d5efe96ee710ca1dd5f745f74a5bbfa4fd42fd9Viktor Novotný		 GLsizei imageSize,
444bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		 GLenum format, GLenum type, const GLvoid *pixels,
4456d5efe96ee710ca1dd5f745f74a5bbfa4fd42fd9Viktor Novotný		 const struct gl_pixelstore_attrib *packing,
4466d5efe96ee710ca1dd5f745f74a5bbfa4fd42fd9Viktor Novotný		 GLboolean compressed)
447bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez{
44892c64624cd7533cde466dbec8722f7f72f275fd8Brian Paul	struct gl_texture_object *t = ti->TexObject;
44992c64624cd7533cde466dbec8722f7f72f275fd8Brian Paul	const GLuint level = ti->Level;
450bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	struct nouveau_surface *s = &to_nouveau_teximage(ti)->surface;
4516e0f9001fe3fb191c2928bd09aa9e9d05ddf4ea9Brian Paul	struct nouveau_teximage *nti = to_nouveau_teximage(ti);
452bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	int ret;
453c5af8891805fc4f590c1371c098cdbc704c44e00Pauli Nieminen	GLuint depth = compressed ? 1 : ti->Depth;
454bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
455bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	/* Allocate a new bo for the image. */
456323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez	nouveau_surface_alloc(ctx, s, LINEAR, get_teximage_placement(ti),
457c5af8891805fc4f590c1371c098cdbc704c44e00Pauli Nieminen			      ti->TexFormat, ti->Width, ti->Height);
4586e0f9001fe3fb191c2928bd09aa9e9d05ddf4ea9Brian Paul	nti->base.RowStride = s->pitch / s->cpp;
459bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
4606d5efe96ee710ca1dd5f745f74a5bbfa4fd42fd9Viktor Novotný	if (compressed)
4616d5efe96ee710ca1dd5f745f74a5bbfa4fd42fd9Viktor Novotný		pixels = _mesa_validate_pbo_compressed_teximage(ctx,
462261ee4d907cc2e06a578e1597f6a55f1997ab52cPaul Berry			dims, imageSize,
4636d5efe96ee710ca1dd5f745f74a5bbfa4fd42fd9Viktor Novotný			pixels, packing, "glCompressedTexImage");
4646d5efe96ee710ca1dd5f745f74a5bbfa4fd42fd9Viktor Novotný	else
4656d5efe96ee710ca1dd5f745f74a5bbfa4fd42fd9Viktor Novotný		pixels = _mesa_validate_pbo_teximage(ctx,
466c5af8891805fc4f590c1371c098cdbc704c44e00Pauli Nieminen			dims, ti->Width, ti->Height, depth, format, type,
4676d5efe96ee710ca1dd5f745f74a5bbfa4fd42fd9Viktor Novotný			pixels, packing, "glTexImage");
4686d5efe96ee710ca1dd5f745f74a5bbfa4fd42fd9Viktor Novotný
469323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez	if (pixels) {
470b78e48289f1dcdadfcab3da4ac0074ab16f430f0Eric Anholt		GLubyte *map;
471b78e48289f1dcdadfcab3da4ac0074ab16f430f0Eric Anholt		int row_stride;
472b78e48289f1dcdadfcab3da4ac0074ab16f430f0Eric Anholt
473323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez		/* Store the pixel data. */
474b78e48289f1dcdadfcab3da4ac0074ab16f430f0Eric Anholt		nouveau_map_texture_image(ctx, ti, 0,
475b78e48289f1dcdadfcab3da4ac0074ab16f430f0Eric Anholt					  0, 0, ti->Width, ti->Height,
476b78e48289f1dcdadfcab3da4ac0074ab16f430f0Eric Anholt					  GL_MAP_WRITE_BIT,
477b78e48289f1dcdadfcab3da4ac0074ab16f430f0Eric Anholt					  &map, &row_stride);
478323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez
479d78b533c29bcd607c5e2d8b51aec6a0da50a3b5bIlia Mirkin		if (compressed) {
480d78b533c29bcd607c5e2d8b51aec6a0da50a3b5bIlia Mirkin			nouveau_compressed_copy(ctx, dims, ti,
481d78b533c29bcd607c5e2d8b51aec6a0da50a3b5bIlia Mirkin						ti->Width, ti->Height, depth,
482d78b533c29bcd607c5e2d8b51aec6a0da50a3b5bIlia Mirkin						pixels, map, row_stride);
483d78b533c29bcd607c5e2d8b51aec6a0da50a3b5bIlia Mirkin		} else {
484d78b533c29bcd607c5e2d8b51aec6a0da50a3b5bIlia Mirkin			ret = _mesa_texstore(ctx, dims, ti->_BaseFormat,
485d78b533c29bcd607c5e2d8b51aec6a0da50a3b5bIlia Mirkin					     ti->TexFormat,
486d78b533c29bcd607c5e2d8b51aec6a0da50a3b5bIlia Mirkin					     row_stride,
487d78b533c29bcd607c5e2d8b51aec6a0da50a3b5bIlia Mirkin					     &map,
488d78b533c29bcd607c5e2d8b51aec6a0da50a3b5bIlia Mirkin					     ti->Width, ti->Height, depth,
489d78b533c29bcd607c5e2d8b51aec6a0da50a3b5bIlia Mirkin					     format, type, pixels, packing);
490d78b533c29bcd607c5e2d8b51aec6a0da50a3b5bIlia Mirkin			assert(ret);
491d78b533c29bcd607c5e2d8b51aec6a0da50a3b5bIlia Mirkin		}
492323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez
493b78e48289f1dcdadfcab3da4ac0074ab16f430f0Eric Anholt		nouveau_unmap_texture_image(ctx, ti, 0);
494323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez		_mesa_unmap_teximage_pbo(ctx, packing);
495323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez
496323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez		if (!validate_teximage(ctx, t, level, 0, 0, 0,
497c5af8891805fc4f590c1371c098cdbc704c44e00Pauli Nieminen				       ti->Width, ti->Height, depth))
498323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez			/* It doesn't fit, mark it as dirty. */
499323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez			texture_dirty(t);
500323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez	}
501bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
502323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez	if (level == t->BaseLevel) {
50398add55fffc29e0c40859fd5e9cec47fa1e352f5Francisco Jerez		if (!teximage_fits(t, level))
504323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez			relayout_texture(ctx, t);
505323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez		nouveau_texture_validate(ctx, t);
506323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez	}
507bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
508bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	context_dirty_i(ctx, TEX_OBJ, ctx->Texture.CurrentUnit);
509bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	context_dirty_i(ctx, TEX_ENV, ctx->Texture.CurrentUnit);
510bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez}
511bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
512bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
513bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerezstatic void
5148f5fffe75d2f8ae7c7ee706b53379a25bc673ae4Brian Paulnouveau_teximage_123d(struct gl_context *ctx, GLuint dims,
5158f5fffe75d2f8ae7c7ee706b53379a25bc673ae4Brian Paul                      struct gl_texture_image *ti,
5168f5fffe75d2f8ae7c7ee706b53379a25bc673ae4Brian Paul                      GLenum format, GLenum type, const GLvoid *pixels,
5178f5fffe75d2f8ae7c7ee706b53379a25bc673ae4Brian Paul                      const struct gl_pixelstore_attrib *packing)
518bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez{
519c5af8891805fc4f590c1371c098cdbc704c44e00Pauli Nieminen	nouveau_teximage(ctx, dims, ti, 0, format, type, pixels,
5206d5efe96ee710ca1dd5f745f74a5bbfa4fd42fd9Viktor Novotný			 packing, GL_FALSE);
5216d5efe96ee710ca1dd5f745f74a5bbfa4fd42fd9Viktor Novotný}
5226d5efe96ee710ca1dd5f745f74a5bbfa4fd42fd9Viktor Novotný
5236d5efe96ee710ca1dd5f745f74a5bbfa4fd42fd9Viktor Novotnýstatic void
524e8fdd0e0d5286f4a9c763ffde44decec51124ebcBrian Paulnouveau_compressed_teximage(struct gl_context *ctx, GLuint dims,
5256d5efe96ee710ca1dd5f745f74a5bbfa4fd42fd9Viktor Novotný		    struct gl_texture_image *ti,
5266d5efe96ee710ca1dd5f745f74a5bbfa4fd42fd9Viktor Novotný		    GLsizei imageSize, const GLvoid *data)
5276d5efe96ee710ca1dd5f745f74a5bbfa4fd42fd9Viktor Novotný{
528c5af8891805fc4f590c1371c098cdbc704c44e00Pauli Nieminen	nouveau_teximage(ctx, 2, ti, imageSize, 0, 0, data,
5296d5efe96ee710ca1dd5f745f74a5bbfa4fd42fd9Viktor Novotný			 &ctx->Unpack, GL_TRUE);
530bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez}
531bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
5327178d6ac590211cf123254688da1a540cce6c0a9Ilia Mirkinstatic GLboolean
5337178d6ac590211cf123254688da1a540cce6c0a9Ilia Mirkinnouveau_teximage_alloc(struct gl_context *ctx, struct gl_texture_image *ti)
5347178d6ac590211cf123254688da1a540cce6c0a9Ilia Mirkin{
5357178d6ac590211cf123254688da1a540cce6c0a9Ilia Mirkin	nouveau_teximage(ctx, 3, ti, 0, 0, 0, NULL,
536d78b533c29bcd607c5e2d8b51aec6a0da50a3b5bIlia Mirkin			 &ctx->DefaultPacking,
537d78b533c29bcd607c5e2d8b51aec6a0da50a3b5bIlia Mirkin			 _mesa_is_format_compressed(ti->TexFormat));
5387178d6ac590211cf123254688da1a540cce6c0a9Ilia Mirkin	return GL_TRUE;
5397178d6ac590211cf123254688da1a540cce6c0a9Ilia Mirkin}
5407178d6ac590211cf123254688da1a540cce6c0a9Ilia Mirkin
541bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerezstatic void
542da0cc82a093eb97212e989648da638a262ed3e84Brian Paulnouveau_texsubimage(struct gl_context *ctx, GLint dims,
543da0cc82a093eb97212e989648da638a262ed3e84Brian Paul		    struct gl_texture_image *ti,
544fc14fb9d1a897dbcf750b8158d6cb08388a422c4Francisco Jerez		    GLint xoffset, GLint yoffset, GLint zoffset,
545fc14fb9d1a897dbcf750b8158d6cb08388a422c4Francisco Jerez		    GLint width, GLint height, GLint depth,
5466d5efe96ee710ca1dd5f745f74a5bbfa4fd42fd9Viktor Novotný		    GLsizei imageSize,
547fc14fb9d1a897dbcf750b8158d6cb08388a422c4Francisco Jerez		    GLenum format, GLenum type, const void *pixels,
5486d5efe96ee710ca1dd5f745f74a5bbfa4fd42fd9Viktor Novotný		    const struct gl_pixelstore_attrib *packing,
5496d5efe96ee710ca1dd5f745f74a5bbfa4fd42fd9Viktor Novotný		    GLboolean compressed)
550fc14fb9d1a897dbcf750b8158d6cb08388a422c4Francisco Jerez{
551fc14fb9d1a897dbcf750b8158d6cb08388a422c4Francisco Jerez	int ret;
552fc14fb9d1a897dbcf750b8158d6cb08388a422c4Francisco Jerez
5536d5efe96ee710ca1dd5f745f74a5bbfa4fd42fd9Viktor Novotný	if (compressed)
5546d5efe96ee710ca1dd5f745f74a5bbfa4fd42fd9Viktor Novotný		pixels = _mesa_validate_pbo_compressed_teximage(ctx,
555261ee4d907cc2e06a578e1597f6a55f1997ab52cPaul Berry				dims, imageSize,
5566d5efe96ee710ca1dd5f745f74a5bbfa4fd42fd9Viktor Novotný				pixels, packing, "glCompressedTexSubImage");
5576d5efe96ee710ca1dd5f745f74a5bbfa4fd42fd9Viktor Novotný	else
5586d5efe96ee710ca1dd5f745f74a5bbfa4fd42fd9Viktor Novotný		pixels = _mesa_validate_pbo_teximage(ctx,
5596d5efe96ee710ca1dd5f745f74a5bbfa4fd42fd9Viktor Novotný				dims, width, height, depth, format, type,
5606d5efe96ee710ca1dd5f745f74a5bbfa4fd42fd9Viktor Novotný				pixels, packing, "glTexSubImage");
5616d5efe96ee710ca1dd5f745f74a5bbfa4fd42fd9Viktor Novotný
562fc14fb9d1a897dbcf750b8158d6cb08388a422c4Francisco Jerez	if (pixels) {
563b78e48289f1dcdadfcab3da4ac0074ab16f430f0Eric Anholt		GLubyte *map;
564b78e48289f1dcdadfcab3da4ac0074ab16f430f0Eric Anholt		int row_stride;
565b78e48289f1dcdadfcab3da4ac0074ab16f430f0Eric Anholt
566b78e48289f1dcdadfcab3da4ac0074ab16f430f0Eric Anholt		nouveau_map_texture_image(ctx, ti, 0,
567b78e48289f1dcdadfcab3da4ac0074ab16f430f0Eric Anholt					  xoffset, yoffset, width, height,
568b78e48289f1dcdadfcab3da4ac0074ab16f430f0Eric Anholt					  GL_MAP_WRITE_BIT, &map, &row_stride);
569fc14fb9d1a897dbcf750b8158d6cb08388a422c4Francisco Jerez
570d78b533c29bcd607c5e2d8b51aec6a0da50a3b5bIlia Mirkin		if (compressed) {
571d78b533c29bcd607c5e2d8b51aec6a0da50a3b5bIlia Mirkin			nouveau_compressed_copy(ctx, dims, ti,
572d78b533c29bcd607c5e2d8b51aec6a0da50a3b5bIlia Mirkin						width, height, depth,
573d78b533c29bcd607c5e2d8b51aec6a0da50a3b5bIlia Mirkin						pixels, map, row_stride);
574d78b533c29bcd607c5e2d8b51aec6a0da50a3b5bIlia Mirkin		} else {
575d78b533c29bcd607c5e2d8b51aec6a0da50a3b5bIlia Mirkin			ret = _mesa_texstore(ctx, dims, ti->_BaseFormat,
576d78b533c29bcd607c5e2d8b51aec6a0da50a3b5bIlia Mirkin					     ti->TexFormat,
577d78b533c29bcd607c5e2d8b51aec6a0da50a3b5bIlia Mirkin					     row_stride, &map,
578d78b533c29bcd607c5e2d8b51aec6a0da50a3b5bIlia Mirkin					     width, height, depth,
579d78b533c29bcd607c5e2d8b51aec6a0da50a3b5bIlia Mirkin					     format, type, pixels, packing);
580d78b533c29bcd607c5e2d8b51aec6a0da50a3b5bIlia Mirkin			assert(ret);
581d78b533c29bcd607c5e2d8b51aec6a0da50a3b5bIlia Mirkin		}
582fc14fb9d1a897dbcf750b8158d6cb08388a422c4Francisco Jerez
583b78e48289f1dcdadfcab3da4ac0074ab16f430f0Eric Anholt		nouveau_unmap_texture_image(ctx, ti, 0);
584fc14fb9d1a897dbcf750b8158d6cb08388a422c4Francisco Jerez		_mesa_unmap_teximage_pbo(ctx, packing);
585fc14fb9d1a897dbcf750b8158d6cb08388a422c4Francisco Jerez	}
586fc14fb9d1a897dbcf750b8158d6cb08388a422c4Francisco Jerez
587da0cc82a093eb97212e989648da638a262ed3e84Brian Paul	if (!to_nouveau_texture(ti->TexObject)->dirty)
588da0cc82a093eb97212e989648da638a262ed3e84Brian Paul		validate_teximage(ctx, ti->TexObject, ti->Level,
589da0cc82a093eb97212e989648da638a262ed3e84Brian Paul				  xoffset, yoffset, zoffset,
590fc14fb9d1a897dbcf750b8158d6cb08388a422c4Francisco Jerez				  width, height, depth);
591fc14fb9d1a897dbcf750b8158d6cb08388a422c4Francisco Jerez}
592fc14fb9d1a897dbcf750b8158d6cb08388a422c4Francisco Jerez
593fc14fb9d1a897dbcf750b8158d6cb08388a422c4Francisco Jerezstatic void
594e42d00b3f4503a0840575c8e5f4517a66c8af613Brian Paulnouveau_texsubimage_123d(struct gl_context *ctx, GLuint dims,
595e42d00b3f4503a0840575c8e5f4517a66c8af613Brian Paul                         struct gl_texture_image *ti,
596e42d00b3f4503a0840575c8e5f4517a66c8af613Brian Paul                         GLint xoffset, GLint yoffset, GLint zoffset,
597e42d00b3f4503a0840575c8e5f4517a66c8af613Brian Paul                         GLint width, GLint height, GLint depth,
598e42d00b3f4503a0840575c8e5f4517a66c8af613Brian Paul                         GLenum format, GLenum type, const void *pixels,
599e42d00b3f4503a0840575c8e5f4517a66c8af613Brian Paul                         const struct gl_pixelstore_attrib *packing)
600bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez{
601e42d00b3f4503a0840575c8e5f4517a66c8af613Brian Paul	nouveau_texsubimage(ctx, dims, ti, xoffset, yoffset, zoffset,
6026d5efe96ee710ca1dd5f745f74a5bbfa4fd42fd9Viktor Novotný			    width, height, depth, 0, format, type, pixels,
6036d5efe96ee710ca1dd5f745f74a5bbfa4fd42fd9Viktor Novotný			    packing, GL_FALSE);
604bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez}
605bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
606bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerezstatic void
607ec19bdd16c3d4070af69fd865042babe0a627595Brian Paulnouveau_compressed_texsubimage(struct gl_context *ctx, GLuint dims,
6086d5efe96ee710ca1dd5f745f74a5bbfa4fd42fd9Viktor Novotný		       struct gl_texture_image *ti,
609ec19bdd16c3d4070af69fd865042babe0a627595Brian Paul		       GLint xoffset, GLint yoffset, GLint zoffset,
610ec19bdd16c3d4070af69fd865042babe0a627595Brian Paul		       GLsizei width, GLint height, GLint depth,
6116d5efe96ee710ca1dd5f745f74a5bbfa4fd42fd9Viktor Novotný		       GLenum format,
6126d5efe96ee710ca1dd5f745f74a5bbfa4fd42fd9Viktor Novotný		       GLint imageSize, const void *data)
6136d5efe96ee710ca1dd5f745f74a5bbfa4fd42fd9Viktor Novotný{
614ec19bdd16c3d4070af69fd865042babe0a627595Brian Paul	nouveau_texsubimage(ctx, dims, ti, xoffset, yoffset, zoffset,
615ec19bdd16c3d4070af69fd865042babe0a627595Brian Paul			  width, height, depth, imageSize, format, 0, data,
6166d5efe96ee710ca1dd5f745f74a5bbfa4fd42fd9Viktor Novotný			  &ctx->Unpack, GL_TRUE);
617bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez}
618bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
619bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerezstatic void
620659d94b256fd6bcf19c8cdf261e2c0bb26e0faf2Fredrik Höglundnouveau_bind_texture(struct gl_context *ctx, GLuint texUnit,
621659d94b256fd6bcf19c8cdf261e2c0bb26e0faf2Fredrik Höglund                     GLenum target, struct gl_texture_object *t)
622bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez{
623659d94b256fd6bcf19c8cdf261e2c0bb26e0faf2Fredrik Höglund	context_dirty_i(ctx, TEX_OBJ, texUnit);
624659d94b256fd6bcf19c8cdf261e2c0bb26e0faf2Fredrik Höglund	context_dirty_i(ctx, TEX_ENV, texUnit);
625bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez}
626bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
62771fe9437169cfdafda8814aa814bb85429fb6cfcMark Muellerstatic mesa_format
6284a7e9b5df453055ed6eedce1ea5c1d4a2f810fa7Francisco Jerezget_texbuffer_format(struct gl_renderbuffer *rb, GLint format)
6294a7e9b5df453055ed6eedce1ea5c1d4a2f810fa7Francisco Jerez{
6304a7e9b5df453055ed6eedce1ea5c1d4a2f810fa7Francisco Jerez	struct nouveau_surface *s = &to_nouveau_renderbuffer(rb)->surface;
6314a7e9b5df453055ed6eedce1ea5c1d4a2f810fa7Francisco Jerez
6324a7e9b5df453055ed6eedce1ea5c1d4a2f810fa7Francisco Jerez	if (s->cpp < 4)
6334a7e9b5df453055ed6eedce1ea5c1d4a2f810fa7Francisco Jerez		return s->format;
6344a7e9b5df453055ed6eedce1ea5c1d4a2f810fa7Francisco Jerez	else if (format == __DRI_TEXTURE_FORMAT_RGBA)
635ef145ba4ded6aafb28e3bda02fb348e6b8bff12aMark Mueller		return MESA_FORMAT_B8G8R8A8_UNORM;
6364a7e9b5df453055ed6eedce1ea5c1d4a2f810fa7Francisco Jerez	else
637ef145ba4ded6aafb28e3bda02fb348e6b8bff12aMark Mueller		return MESA_FORMAT_B8G8R8X8_UNORM;
6384a7e9b5df453055ed6eedce1ea5c1d4a2f810fa7Francisco Jerez}
6394a7e9b5df453055ed6eedce1ea5c1d4a2f810fa7Francisco Jerez
6404a7e9b5df453055ed6eedce1ea5c1d4a2f810fa7Francisco Jerezvoid
6414a7e9b5df453055ed6eedce1ea5c1d4a2f810fa7Francisco Jereznouveau_set_texbuffer(__DRIcontext *dri_ctx,
6424a7e9b5df453055ed6eedce1ea5c1d4a2f810fa7Francisco Jerez		      GLint target, GLint format,
6434a7e9b5df453055ed6eedce1ea5c1d4a2f810fa7Francisco Jerez		      __DRIdrawable *draw)
6444a7e9b5df453055ed6eedce1ea5c1d4a2f810fa7Francisco Jerez{
6454a7e9b5df453055ed6eedce1ea5c1d4a2f810fa7Francisco Jerez	struct nouveau_context *nctx = dri_ctx->driverPrivate;
646f9995b30756140724f41daf963fa06167912be7fKristian Høgsberg	struct gl_context *ctx = &nctx->base;
6474a7e9b5df453055ed6eedce1ea5c1d4a2f810fa7Francisco Jerez	struct gl_framebuffer *fb = draw->driverPrivate;
6484a7e9b5df453055ed6eedce1ea5c1d4a2f810fa7Francisco Jerez	struct gl_renderbuffer *rb =
6494a7e9b5df453055ed6eedce1ea5c1d4a2f810fa7Francisco Jerez		fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer;
6504a7e9b5df453055ed6eedce1ea5c1d4a2f810fa7Francisco Jerez	struct gl_texture_object *t = _mesa_get_current_tex_object(ctx, target);
6514a7e9b5df453055ed6eedce1ea5c1d4a2f810fa7Francisco Jerez	struct gl_texture_image *ti;
6526e0f9001fe3fb191c2928bd09aa9e9d05ddf4ea9Brian Paul	struct nouveau_teximage *nti;
6534a7e9b5df453055ed6eedce1ea5c1d4a2f810fa7Francisco Jerez	struct nouveau_surface *s;
6544a7e9b5df453055ed6eedce1ea5c1d4a2f810fa7Francisco Jerez
6554a7e9b5df453055ed6eedce1ea5c1d4a2f810fa7Francisco Jerez	_mesa_lock_texture(ctx, t);
6564a7e9b5df453055ed6eedce1ea5c1d4a2f810fa7Francisco Jerez	ti = _mesa_get_tex_image(ctx, t, target, 0);
6576e0f9001fe3fb191c2928bd09aa9e9d05ddf4ea9Brian Paul	nti = to_nouveau_teximage(ti);
6584a7e9b5df453055ed6eedce1ea5c1d4a2f810fa7Francisco Jerez	s = &to_nouveau_teximage(ti)->surface;
6594a7e9b5df453055ed6eedce1ea5c1d4a2f810fa7Francisco Jerez
6604a7e9b5df453055ed6eedce1ea5c1d4a2f810fa7Francisco Jerez	/* Update the texture surface with the given drawable. */
6614a7e9b5df453055ed6eedce1ea5c1d4a2f810fa7Francisco Jerez	nouveau_update_renderbuffers(dri_ctx, draw);
6624a7e9b5df453055ed6eedce1ea5c1d4a2f810fa7Francisco Jerez	nouveau_surface_ref(&to_nouveau_renderbuffer(rb)->surface, s);
6634a7e9b5df453055ed6eedce1ea5c1d4a2f810fa7Francisco Jerez
66483e93b6008213ad86607027e8434ecaccc8b1a2cBrian Paul        s->format = get_texbuffer_format(rb, format);
66583e93b6008213ad86607027e8434ecaccc8b1a2cBrian Paul
6664a7e9b5df453055ed6eedce1ea5c1d4a2f810fa7Francisco Jerez	/* Update the image fields. */
667892a2542a3f0753a7064c710b96f077dd5490624Brian Paul	_mesa_init_teximage_fields(ctx, ti, s->width, s->height,
66883e93b6008213ad86607027e8434ecaccc8b1a2cBrian Paul				   1, 0, s->cpp, s->format);
6696e0f9001fe3fb191c2928bd09aa9e9d05ddf4ea9Brian Paul	nti->base.RowStride = s->pitch / s->cpp;
6704a7e9b5df453055ed6eedce1ea5c1d4a2f810fa7Francisco Jerez
6714a7e9b5df453055ed6eedce1ea5c1d4a2f810fa7Francisco Jerez	/* Try to validate it. */
6724a7e9b5df453055ed6eedce1ea5c1d4a2f810fa7Francisco Jerez	if (!validate_teximage(ctx, t, 0, 0, 0, 0, s->width, s->height, 1))
6734a7e9b5df453055ed6eedce1ea5c1d4a2f810fa7Francisco Jerez		nouveau_texture_reallocate(ctx, t);
6744a7e9b5df453055ed6eedce1ea5c1d4a2f810fa7Francisco Jerez
6754a7e9b5df453055ed6eedce1ea5c1d4a2f810fa7Francisco Jerez	context_dirty_i(ctx, TEX_OBJ, ctx->Texture.CurrentUnit);
6764a7e9b5df453055ed6eedce1ea5c1d4a2f810fa7Francisco Jerez	context_dirty_i(ctx, TEX_ENV, ctx->Texture.CurrentUnit);
6774a7e9b5df453055ed6eedce1ea5c1d4a2f810fa7Francisco Jerez
6784a7e9b5df453055ed6eedce1ea5c1d4a2f810fa7Francisco Jerez	_mesa_unlock_texture(ctx, t);
6794a7e9b5df453055ed6eedce1ea5c1d4a2f810fa7Francisco Jerez}
6804a7e9b5df453055ed6eedce1ea5c1d4a2f810fa7Francisco Jerez
681bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerezvoid
682bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jereznouveau_texture_functions_init(struct dd_function_table *functions)
683bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez{
684bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	functions->NewTextureObject = nouveau_texture_new;
685bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	functions->DeleteTexture = nouveau_texture_free;
686bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	functions->NewTextureImage = nouveau_teximage_new;
6870bb29949ba8a9e5a15dc0640dbb0a4e7990a1d57Eric Anholt	functions->FreeTextureImageBuffer = nouveau_teximage_free;
6887178d6ac590211cf123254688da1a540cce6c0a9Ilia Mirkin	functions->AllocTextureImageBuffer = nouveau_teximage_alloc;
689bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	functions->ChooseTextureFormat = nouveau_choose_tex_format;
6908f5fffe75d2f8ae7c7ee706b53379a25bc673ae4Brian Paul	functions->TexImage = nouveau_teximage_123d;
691e42d00b3f4503a0840575c8e5f4517a66c8af613Brian Paul	functions->TexSubImage = nouveau_texsubimage_123d;
692e8fdd0e0d5286f4a9c763ffde44decec51124ebcBrian Paul	functions->CompressedTexImage = nouveau_compressed_teximage;
693ec19bdd16c3d4070af69fd865042babe0a627595Brian Paul	functions->CompressedTexSubImage = nouveau_compressed_texsubimage;
694bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	functions->BindTexture = nouveau_bind_texture;
6955b257442a8a46fdabdaad54c5f18a44f02696590Eric Anholt	functions->MapTextureImage = nouveau_map_texture_image;
6965b257442a8a46fdabdaad54c5f18a44f02696590Eric Anholt	functions->UnmapTextureImage = nouveau_unmap_texture_image;
697bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez}
698