nouveau_texture.c revision e96a52e9933eea7264a42983db1428368bcb4962
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
33bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez#include "main/texobj.h"
34bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez#include "main/texstore.h"
35bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez#include "main/texformat.h"
36bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez#include "main/texcompress.h"
37bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez#include "main/texgetimage.h"
38bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez#include "main/mipmap.h"
39bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez#include "main/texfetch.h"
404a7e9b5df453055ed6eedce1ea5c1d4a2f810fa7Francisco Jerez#include "main/teximage.h"
41e96a52e9933eea7264a42983db1428368bcb4962Francisco Jerez#include "drivers/common/meta.h"
42bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
43bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerezstatic struct gl_texture_object *
44bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jereznouveau_texture_new(GLcontext *ctx, GLuint name, GLenum target)
45bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez{
46bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	struct nouveau_texture *nt = CALLOC_STRUCT(nouveau_texture);
47bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
48bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	_mesa_initialize_texture_object(&nt->base, name, target);
49bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
50bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	return &nt->base;
51bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez}
52bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
53bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerezstatic void
54bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jereznouveau_texture_free(GLcontext *ctx, struct gl_texture_object *t)
55bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez{
56bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	struct nouveau_texture *nt = to_nouveau_texture(t);
57bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	int i;
58bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
59bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	for (i = 0; i < MAX_TEXTURE_LEVELS; i++)
60bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		nouveau_surface_ref(NULL, &nt->surfaces[i]);
61bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
62bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	_mesa_delete_texture_object(ctx, t);
63bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez}
64bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
65bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerezstatic struct gl_texture_image *
66bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jereznouveau_teximage_new(GLcontext *ctx)
67bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez{
68bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	struct nouveau_teximage *nti = CALLOC_STRUCT(nouveau_teximage);
69bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
70bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	return &nti->base;
71bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez}
72bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
73bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerezstatic void
74bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jereznouveau_teximage_free(GLcontext *ctx, struct gl_texture_image *ti)
75bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez{
76bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	struct nouveau_teximage *nti = to_nouveau_teximage(ti);
77bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
78bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	nouveau_surface_ref(NULL, &nti->surface);
79bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez}
80bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
81bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerezstatic void
82bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jereznouveau_teximage_map(GLcontext *ctx, struct gl_texture_image *ti)
83bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez{
84bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	struct nouveau_surface *s = &to_nouveau_teximage(ti)->surface;
85bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	int ret;
86bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
877432ffbdfa52b51b720bdde5cd50c497862b8806Francisco Jerez	if (s->bo) {
887432ffbdfa52b51b720bdde5cd50c497862b8806Francisco Jerez		ret = nouveau_bo_map(s->bo, NOUVEAU_BO_RDWR);
897432ffbdfa52b51b720bdde5cd50c497862b8806Francisco Jerez		assert(!ret);
90bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
917432ffbdfa52b51b720bdde5cd50c497862b8806Francisco Jerez		ti->Data = s->bo->map;
927432ffbdfa52b51b720bdde5cd50c497862b8806Francisco Jerez	}
93bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez}
94bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
95bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerezstatic void
96bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jereznouveau_teximage_unmap(GLcontext *ctx, struct gl_texture_image *ti)
97bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez{
98bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	struct nouveau_surface *s = &to_nouveau_teximage(ti)->surface;
99bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
1007432ffbdfa52b51b720bdde5cd50c497862b8806Francisco Jerez	if (s->bo)
1017432ffbdfa52b51b720bdde5cd50c497862b8806Francisco Jerez		nouveau_bo_unmap(s->bo);
102bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	ti->Data = NULL;
103bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez}
104bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
105bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerezstatic gl_format
106bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jereznouveau_choose_tex_format(GLcontext *ctx, GLint internalFormat,
107bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez			  GLenum srcFormat, GLenum srcType)
108bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez{
109bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	switch (internalFormat) {
110bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	case 4:
111bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	case GL_RGBA:
11251e8a66fa197de7e17fb94d901a4cf26f0812670Francisco Jerez	case GL_RGBA2:
11351e8a66fa197de7e17fb94d901a4cf26f0812670Francisco Jerez	case GL_RGBA4:
11451e8a66fa197de7e17fb94d901a4cf26f0812670Francisco Jerez	case GL_RGBA8:
115bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	case GL_RGBA12:
116bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	case GL_RGBA16:
11751e8a66fa197de7e17fb94d901a4cf26f0812670Francisco Jerez	case GL_RGB10_A2:
11851e8a66fa197de7e17fb94d901a4cf26f0812670Francisco Jerez		return MESA_FORMAT_ARGB8888;
11951e8a66fa197de7e17fb94d901a4cf26f0812670Francisco Jerez	case GL_RGB5_A1:
12051e8a66fa197de7e17fb94d901a4cf26f0812670Francisco Jerez		return MESA_FORMAT_ARGB1555;
12151e8a66fa197de7e17fb94d901a4cf26f0812670Francisco Jerez
122bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	case GL_RGB:
123bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	case GL_RGB8:
124bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	case GL_RGB10:
125bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	case GL_RGB12:
126bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	case GL_RGB16:
12751e8a66fa197de7e17fb94d901a4cf26f0812670Francisco Jerez		return MESA_FORMAT_XRGB8888;
128bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	case 3:
129bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	case GL_R3_G3_B2:
130bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	case GL_RGB4:
131bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	case GL_RGB5:
132bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		return MESA_FORMAT_RGB565;
133bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
134bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	case 2:
135bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	case GL_LUMINANCE_ALPHA:
136bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	case GL_LUMINANCE4_ALPHA4:
137bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	case GL_LUMINANCE6_ALPHA2:
138bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	case GL_LUMINANCE12_ALPHA4:
139bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	case GL_LUMINANCE12_ALPHA12:
140bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	case GL_LUMINANCE16_ALPHA16:
141bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	case GL_LUMINANCE8_ALPHA8:
142bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		return MESA_FORMAT_ARGB8888;
143bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
14451e8a66fa197de7e17fb94d901a4cf26f0812670Francisco Jerez	case 1:
14551e8a66fa197de7e17fb94d901a4cf26f0812670Francisco Jerez	case GL_LUMINANCE:
14651e8a66fa197de7e17fb94d901a4cf26f0812670Francisco Jerez	case GL_LUMINANCE4:
14751e8a66fa197de7e17fb94d901a4cf26f0812670Francisco Jerez	case GL_LUMINANCE12:
14851e8a66fa197de7e17fb94d901a4cf26f0812670Francisco Jerez	case GL_LUMINANCE16:
14951e8a66fa197de7e17fb94d901a4cf26f0812670Francisco Jerez	case GL_LUMINANCE8:
15051e8a66fa197de7e17fb94d901a4cf26f0812670Francisco Jerez		return MESA_FORMAT_L8;
15151e8a66fa197de7e17fb94d901a4cf26f0812670Francisco Jerez
15251e8a66fa197de7e17fb94d901a4cf26f0812670Francisco Jerez	case GL_ALPHA:
15351e8a66fa197de7e17fb94d901a4cf26f0812670Francisco Jerez	case GL_ALPHA4:
15451e8a66fa197de7e17fb94d901a4cf26f0812670Francisco Jerez	case GL_ALPHA12:
15551e8a66fa197de7e17fb94d901a4cf26f0812670Francisco Jerez	case GL_ALPHA16:
15651e8a66fa197de7e17fb94d901a4cf26f0812670Francisco Jerez	case GL_ALPHA8:
15751e8a66fa197de7e17fb94d901a4cf26f0812670Francisco Jerez		return MESA_FORMAT_A8;
15851e8a66fa197de7e17fb94d901a4cf26f0812670Francisco Jerez
159bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	case GL_INTENSITY:
160bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	case GL_INTENSITY4:
161bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	case GL_INTENSITY12:
162bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	case GL_INTENSITY16:
163bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	case GL_INTENSITY8:
16459ddf8ca635465dea1d455c384f5905b65dc6979Francisco Jerez		return MESA_FORMAT_I8;
165bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
166bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	case GL_COLOR_INDEX:
167bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	case GL_COLOR_INDEX1_EXT:
168bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	case GL_COLOR_INDEX2_EXT:
169bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	case GL_COLOR_INDEX4_EXT:
170bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	case GL_COLOR_INDEX12_EXT:
171bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	case GL_COLOR_INDEX16_EXT:
172bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	case GL_COLOR_INDEX8_EXT:
173bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		return MESA_FORMAT_CI8;
174bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
175bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	default:
176bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		assert(0);
177bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	}
178bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez}
179bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
180323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerezstatic GLboolean
18150be9bc6ce8582b3d3cd4fa47976cbeac28b8c26Xavier Chantryteximage_fits(struct gl_texture_object *t, int level)
182323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez{
183323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez	struct nouveau_surface *s = &to_nouveau_texture(t)->surfaces[level];
18450be9bc6ce8582b3d3cd4fa47976cbeac28b8c26Xavier Chantry	struct gl_texture_image *ti = t->Image[0][level];
185323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez
18650be9bc6ce8582b3d3cd4fa47976cbeac28b8c26Xavier Chantry	return ti && (t->Target == GL_TEXTURE_RECTANGLE ||
18750be9bc6ce8582b3d3cd4fa47976cbeac28b8c26Xavier Chantry		      (s->bo && s->width == ti->Width &&
18850be9bc6ce8582b3d3cd4fa47976cbeac28b8c26Xavier Chantry		       s->height == ti->Height &&
18950be9bc6ce8582b3d3cd4fa47976cbeac28b8c26Xavier Chantry		       s->format == ti->TexFormat));
190323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez}
191323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez
192323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerezstatic GLboolean
193323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerezvalidate_teximage(GLcontext *ctx, struct gl_texture_object *t,
194323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez		  int level, int x, int y, int z,
195323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez		  int width, int height, int depth)
196323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez{
197323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez	struct gl_texture_image *ti = t->Image[0][level];
198323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez
19950be9bc6ce8582b3d3cd4fa47976cbeac28b8c26Xavier Chantry	if (teximage_fits(t, level)) {
200323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez		struct nouveau_surface *ss = to_nouveau_texture(t)->surfaces;
201323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez		struct nouveau_surface *s = &to_nouveau_teximage(ti)->surface;
202323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez
203a7b8d105a6efe4056633f7129f80aac1f13cc246Francisco Jerez		if (t->Target == GL_TEXTURE_RECTANGLE)
204a7b8d105a6efe4056633f7129f80aac1f13cc246Francisco Jerez			nouveau_surface_ref(s, &ss[level]);
205a7b8d105a6efe4056633f7129f80aac1f13cc246Francisco Jerez		else
206a7b8d105a6efe4056633f7129f80aac1f13cc246Francisco Jerez			context_drv(ctx)->surface_copy(ctx, &ss[level], s,
207a7b8d105a6efe4056633f7129f80aac1f13cc246Francisco Jerez						       x, y, x, y,
208a7b8d105a6efe4056633f7129f80aac1f13cc246Francisco Jerez						       width, height);
209323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez
210323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez		return GL_TRUE;
211323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez	}
212323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez
213323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez	return GL_FALSE;
214323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez}
215323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez
216323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerezstatic int
217323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerezget_last_level(struct gl_texture_object *t)
218323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez{
219323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez	struct gl_texture_image *base = t->Image[0][t->BaseLevel];
220323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez
221323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez	if (t->MinFilter == GL_NEAREST ||
222323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez	    t->MinFilter == GL_LINEAR || !base)
223323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez		return t->BaseLevel;
224323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez	else
225323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez		return MIN2(t->BaseLevel + base->MaxLog2, t->MaxLevel);
226323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez}
227323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez
228323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerezstatic void
229323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerezrelayout_texture(GLcontext *ctx, struct gl_texture_object *t)
230323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez{
231323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez	struct gl_texture_image *base = t->Image[0][t->BaseLevel];
232323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez
233a7b8d105a6efe4056633f7129f80aac1f13cc246Francisco Jerez	if (base && t->Target != GL_TEXTURE_RECTANGLE) {
234323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez		struct nouveau_surface *ss = to_nouveau_texture(t)->surfaces;
235323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez		struct nouveau_surface *s = &to_nouveau_teximage(base)->surface;
236323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez		int i, ret, last = get_last_level(t);
237323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez		unsigned size, offset = 0,
238323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez			width = s->width,
239323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez			height = s->height;
240323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez
241323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez		/* Deallocate the old storage. */
242323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez		for (i = 0; i < MAX_TEXTURE_LEVELS; i++)
243323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez			nouveau_bo_ref(NULL, &ss[i].bo);
244323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez
245323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez		/* Relayout the mipmap tree. */
246323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez		for (i = t->BaseLevel; i <= last; i++) {
247323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez			size = width * height * s->cpp;
248323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez
249323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez			/* Images larger than 16B have to be aligned. */
250323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez			if (size > 16)
251323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez				offset = align(offset, 64);
252323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez
253323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez			ss[i] = (struct nouveau_surface) {
254323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez				.offset = offset,
255323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez				.layout = SWIZZLED,
256323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez				.format = s->format,
257323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez				.width = width,
258323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez				.height = height,
259323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez				.cpp = s->cpp,
260323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez				.pitch = width * s->cpp,
261323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez			};
262323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez
263323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez			offset += size;
264323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez			width = MAX2(1, width / 2);
265323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez			height = MAX2(1, height / 2);
266323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez		}
267323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez
268323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez		/* Get new storage. */
269323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez		size = align(offset, 64);
270323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez
271323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez		ret = nouveau_bo_new(context_dev(ctx), NOUVEAU_BO_MAP |
272323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez				     NOUVEAU_BO_GART | NOUVEAU_BO_VRAM,
273323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez				     0, size, &ss[last].bo);
274323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez		assert(!ret);
275323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez
276323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez		for (i = t->BaseLevel; i < last; i++)
277323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez			nouveau_bo_ref(ss[last].bo, &ss[i].bo);
278323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez	}
279323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez}
280323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez
281323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco JerezGLboolean
282323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jereznouveau_texture_validate(GLcontext *ctx, struct gl_texture_object *t)
283323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez{
284323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez	struct nouveau_texture *nt = to_nouveau_texture(t);
285323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez	int i, last = get_last_level(t);
286323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez
287fc14fb9d1a897dbcf750b8158d6cb08388a422c4Francisco Jerez	if (!teximage_fits(t, t->BaseLevel) ||
288fc14fb9d1a897dbcf750b8158d6cb08388a422c4Francisco Jerez	    !teximage_fits(t, last))
289323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez		return GL_FALSE;
290323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez
291323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez	if (nt->dirty) {
292323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez		nt->dirty = GL_FALSE;
293323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez
294323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez		/* Copy the teximages to the actual miptree. */
295323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez		for (i = t->BaseLevel; i <= last; i++) {
296323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez			struct nouveau_surface *s = &nt->surfaces[i];
297323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez
298323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez			validate_teximage(ctx, t, i, 0, 0, 0,
299323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez					  s->width, s->height, 1);
300323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez		}
3013c0eab714816618314324ac02712fa59e5ed385aFrancisco Jerez
3023c0eab714816618314324ac02712fa59e5ed385aFrancisco Jerez		FIRE_RING(context_chan(ctx));
303323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez	}
304323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez
305323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez	return GL_TRUE;
306323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez}
307323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez
308323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerezvoid
309323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jereznouveau_texture_reallocate(GLcontext *ctx, struct gl_texture_object *t)
310323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez{
31150be9bc6ce8582b3d3cd4fa47976cbeac28b8c26Xavier Chantry	if (!teximage_fits(t, t->BaseLevel) ||
31250be9bc6ce8582b3d3cd4fa47976cbeac28b8c26Xavier Chantry	    !teximage_fits(t, get_last_level(t))) {
31350be9bc6ce8582b3d3cd4fa47976cbeac28b8c26Xavier Chantry		texture_dirty(t);
31450be9bc6ce8582b3d3cd4fa47976cbeac28b8c26Xavier Chantry		relayout_texture(ctx, t);
31550be9bc6ce8582b3d3cd4fa47976cbeac28b8c26Xavier Chantry		nouveau_texture_validate(ctx, t);
31650be9bc6ce8582b3d3cd4fa47976cbeac28b8c26Xavier Chantry	}
317323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez}
318323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez
319323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerezstatic unsigned
320323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerezget_teximage_placement(struct gl_texture_image *ti)
321323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez{
322323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez	if (ti->TexFormat == MESA_FORMAT_A8 ||
323323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez	    ti->TexFormat == MESA_FORMAT_L8 ||
324323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez	    ti->TexFormat == MESA_FORMAT_I8)
325323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez		/* 1 cpp formats will have to be swizzled by the CPU,
326323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez		 * so leave them in system RAM for now. */
327323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez		return NOUVEAU_BO_MAP;
328323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez	else
329323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez		return NOUVEAU_BO_GART | NOUVEAU_BO_MAP;
330323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez}
331323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez
332bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerezstatic void
333bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jereznouveau_teximage(GLcontext *ctx, GLint dims, GLenum target, GLint level,
334bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		 GLint internalFormat,
335bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		 GLint width, GLint height, GLint depth, GLint border,
336bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		 GLenum format, GLenum type, const GLvoid *pixels,
337bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		 const struct gl_pixelstore_attrib *packing,
338bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		 struct gl_texture_object *t,
339bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		 struct gl_texture_image *ti)
340bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez{
341bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	struct nouveau_surface *s = &to_nouveau_teximage(ti)->surface;
342bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	int ret;
343bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
344bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	/* Allocate a new bo for the image. */
345323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez	nouveau_surface_alloc(ctx, s, LINEAR, get_teximage_placement(ti),
346323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez			      ti->TexFormat, width, height);
347bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	ti->RowStride = s->pitch / s->cpp;
348bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
349bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	pixels = _mesa_validate_pbo_teximage(ctx, dims, width, height, depth,
350bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez					     format, type, pixels, packing,
351bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez					     "glTexImage");
352323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez	if (pixels) {
353323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez		/* Store the pixel data. */
354323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez		nouveau_teximage_map(ctx, ti);
355323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez
356323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez		ret = _mesa_texstore(ctx, dims, ti->_BaseFormat,
357323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez				     ti->TexFormat, ti->Data,
358323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez				     0, 0, 0, s->pitch,
359323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez				     ti->ImageOffsets,
360323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez				     width, height, depth,
361323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez				     format, type, pixels, packing);
362323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez		assert(ret);
363323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez
364323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez		nouveau_teximage_unmap(ctx, ti);
365323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez		_mesa_unmap_teximage_pbo(ctx, packing);
366323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez
367323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez		if (!validate_teximage(ctx, t, level, 0, 0, 0,
368323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez				       width, height, depth))
369323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez			/* It doesn't fit, mark it as dirty. */
370323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez			texture_dirty(t);
371323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez	}
372bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
373323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez	if (level == t->BaseLevel) {
37450be9bc6ce8582b3d3cd4fa47976cbeac28b8c26Xavier Chantry		if (!teximage_fits(t, level))
375323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez			relayout_texture(ctx, t);
376323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez		nouveau_texture_validate(ctx, t);
377323e6bbb052f37f91c7340e16c2352bb780a43d8Francisco Jerez	}
378bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
379bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	context_dirty_i(ctx, TEX_OBJ, ctx->Texture.CurrentUnit);
380bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	context_dirty_i(ctx, TEX_ENV, ctx->Texture.CurrentUnit);
381bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez}
382bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
383bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerezstatic void
384bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jereznouveau_teximage_1d(GLcontext *ctx, GLenum target, GLint level,
385bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		    GLint internalFormat,
386bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		    GLint width, GLint border,
387bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		    GLenum format, GLenum type, const GLvoid *pixels,
388bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		    const struct gl_pixelstore_attrib *packing,
389bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		    struct gl_texture_object *t,
390bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		    struct gl_texture_image *ti)
391bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez{
392bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	nouveau_teximage(ctx, 1, target, level, internalFormat,
393bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez			 width, 1, 1, border, format, type, pixels,
394bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez			 packing, t, ti);
395bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez}
396bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
397bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerezstatic void
398bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jereznouveau_teximage_2d(GLcontext *ctx, GLenum target, GLint level,
399bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		    GLint internalFormat,
400bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		    GLint width, GLint height, GLint border,
401bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		    GLenum format, GLenum type, const GLvoid *pixels,
402bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		    const struct gl_pixelstore_attrib *packing,
403bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		    struct gl_texture_object *t,
404bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		    struct gl_texture_image *ti)
405bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez{
406bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	nouveau_teximage(ctx, 2, target, level, internalFormat,
407bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez			 width, height, 1, border, format, type, pixels,
408bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez			 packing, t, ti);
409bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez}
410bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
411bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerezstatic void
412bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jereznouveau_teximage_3d(GLcontext *ctx, GLenum target, GLint level,
413bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		    GLint internalFormat,
414bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		    GLint width, GLint height, GLint depth, GLint border,
415bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		    GLenum format, GLenum type, const GLvoid *pixels,
416bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		    const struct gl_pixelstore_attrib *packing,
417bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		    struct gl_texture_object *t,
418bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		    struct gl_texture_image *ti)
419bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez{
420bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	nouveau_teximage(ctx, 3, target, level, internalFormat,
421bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez			 width, height, depth, border, format, type, pixels,
422bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez			 packing, t, ti);
423bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez}
424bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
425bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerezstatic void
426fc14fb9d1a897dbcf750b8158d6cb08388a422c4Francisco Jereznouveau_texsubimage(GLcontext *ctx, GLint dims, GLenum target, GLint level,
427fc14fb9d1a897dbcf750b8158d6cb08388a422c4Francisco Jerez		    GLint xoffset, GLint yoffset, GLint zoffset,
428fc14fb9d1a897dbcf750b8158d6cb08388a422c4Francisco Jerez		    GLint width, GLint height, GLint depth,
429fc14fb9d1a897dbcf750b8158d6cb08388a422c4Francisco Jerez		    GLenum format, GLenum type, const void *pixels,
430fc14fb9d1a897dbcf750b8158d6cb08388a422c4Francisco Jerez		    const struct gl_pixelstore_attrib *packing,
431fc14fb9d1a897dbcf750b8158d6cb08388a422c4Francisco Jerez		    struct gl_texture_object *t,
432fc14fb9d1a897dbcf750b8158d6cb08388a422c4Francisco Jerez		    struct gl_texture_image *ti)
433fc14fb9d1a897dbcf750b8158d6cb08388a422c4Francisco Jerez{
434fc14fb9d1a897dbcf750b8158d6cb08388a422c4Francisco Jerez	struct nouveau_surface *s = &to_nouveau_teximage(ti)->surface;
435fc14fb9d1a897dbcf750b8158d6cb08388a422c4Francisco Jerez	int ret;
436fc14fb9d1a897dbcf750b8158d6cb08388a422c4Francisco Jerez
437fc14fb9d1a897dbcf750b8158d6cb08388a422c4Francisco Jerez	pixels = _mesa_validate_pbo_teximage(ctx, dims, width, height, depth,
438fc14fb9d1a897dbcf750b8158d6cb08388a422c4Francisco Jerez					     format, type, pixels, packing,
439fc14fb9d1a897dbcf750b8158d6cb08388a422c4Francisco Jerez					     "glTexSubImage");
440fc14fb9d1a897dbcf750b8158d6cb08388a422c4Francisco Jerez	if (pixels) {
441fc14fb9d1a897dbcf750b8158d6cb08388a422c4Francisco Jerez		nouveau_teximage_map(ctx, ti);
442fc14fb9d1a897dbcf750b8158d6cb08388a422c4Francisco Jerez
443fc14fb9d1a897dbcf750b8158d6cb08388a422c4Francisco Jerez		ret = _mesa_texstore(ctx, 3, ti->_BaseFormat, ti->TexFormat,
444fc14fb9d1a897dbcf750b8158d6cb08388a422c4Francisco Jerez				     ti->Data, xoffset, yoffset, zoffset,
445fc14fb9d1a897dbcf750b8158d6cb08388a422c4Francisco Jerez				     s->pitch, ti->ImageOffsets,
446fc14fb9d1a897dbcf750b8158d6cb08388a422c4Francisco Jerez				     width, height, depth, format, type,
447fc14fb9d1a897dbcf750b8158d6cb08388a422c4Francisco Jerez				     pixels, packing);
448fc14fb9d1a897dbcf750b8158d6cb08388a422c4Francisco Jerez		assert(ret);
449fc14fb9d1a897dbcf750b8158d6cb08388a422c4Francisco Jerez
450fc14fb9d1a897dbcf750b8158d6cb08388a422c4Francisco Jerez		nouveau_teximage_unmap(ctx, ti);
451fc14fb9d1a897dbcf750b8158d6cb08388a422c4Francisco Jerez		_mesa_unmap_teximage_pbo(ctx, packing);
452fc14fb9d1a897dbcf750b8158d6cb08388a422c4Francisco Jerez	}
453fc14fb9d1a897dbcf750b8158d6cb08388a422c4Francisco Jerez
454fc14fb9d1a897dbcf750b8158d6cb08388a422c4Francisco Jerez	if (!to_nouveau_texture(t)->dirty)
455fc14fb9d1a897dbcf750b8158d6cb08388a422c4Francisco Jerez		validate_teximage(ctx, t, level, xoffset, yoffset, zoffset,
456fc14fb9d1a897dbcf750b8158d6cb08388a422c4Francisco Jerez				  width, height, depth);
457fc14fb9d1a897dbcf750b8158d6cb08388a422c4Francisco Jerez}
458fc14fb9d1a897dbcf750b8158d6cb08388a422c4Francisco Jerez
459fc14fb9d1a897dbcf750b8158d6cb08388a422c4Francisco Jerezstatic void
460bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jereznouveau_texsubimage_3d(GLcontext *ctx, GLenum target, GLint level,
461bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		       GLint xoffset, GLint yoffset, GLint zoffset,
462bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		       GLint width, GLint height, GLint depth,
463bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		       GLenum format, GLenum type, const void *pixels,
464bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		       const struct gl_pixelstore_attrib *packing,
465bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		       struct gl_texture_object *t,
466bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		       struct gl_texture_image *ti)
467bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez{
468fc14fb9d1a897dbcf750b8158d6cb08388a422c4Francisco Jerez	nouveau_texsubimage(ctx, 3, target, level, xoffset, yoffset, zoffset,
469fc14fb9d1a897dbcf750b8158d6cb08388a422c4Francisco Jerez			    width, height, depth, format, type, pixels,
470fc14fb9d1a897dbcf750b8158d6cb08388a422c4Francisco Jerez			    packing, t, ti);
471bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez}
472bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
473bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerezstatic void
474bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jereznouveau_texsubimage_2d(GLcontext *ctx, GLenum target, GLint level,
475bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		       GLint xoffset, GLint yoffset,
476bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		       GLint width, GLint height,
477bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		       GLenum format, GLenum type, const void *pixels,
478bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		       const struct gl_pixelstore_attrib *packing,
479bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		       struct gl_texture_object *t,
480bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		       struct gl_texture_image *ti)
481bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez{
482fc14fb9d1a897dbcf750b8158d6cb08388a422c4Francisco Jerez	nouveau_texsubimage(ctx, 2, target, level, xoffset, yoffset, 0,
483fc14fb9d1a897dbcf750b8158d6cb08388a422c4Francisco Jerez			    width, height, 1, format, type, pixels,
484fc14fb9d1a897dbcf750b8158d6cb08388a422c4Francisco Jerez			    packing, t, ti);
485bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez}
486bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
487bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerezstatic void
488bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jereznouveau_texsubimage_1d(GLcontext *ctx, GLenum target, GLint level,
489bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		       GLint xoffset, GLint width,
490bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		       GLenum format, GLenum type, const void *pixels,
491bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		       const struct gl_pixelstore_attrib *packing,
492bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		       struct gl_texture_object *t,
493bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		       struct gl_texture_image *ti)
494bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez{
495fc14fb9d1a897dbcf750b8158d6cb08388a422c4Francisco Jerez	nouveau_texsubimage(ctx, 1, target, level, xoffset, 0, 0,
496fc14fb9d1a897dbcf750b8158d6cb08388a422c4Francisco Jerez			    width, 1, 1, format, type, pixels,
497fc14fb9d1a897dbcf750b8158d6cb08388a422c4Francisco Jerez			    packing, t, ti);
498bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez}
499bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
500bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerezstatic void
501bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jereznouveau_get_teximage(GLcontext *ctx, GLenum target, GLint level,
502bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		     GLenum format, GLenum type, GLvoid *pixels,
503bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		     struct gl_texture_object *t,
504bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		     struct gl_texture_image *ti)
505bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez{
506bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	nouveau_teximage_map(ctx, ti);
507bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	_mesa_get_teximage(ctx, target, level, format, type, pixels,
508bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez			   t, ti);
509bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	nouveau_teximage_unmap(ctx, ti);
510bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez}
511bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
512bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerezstatic void
513bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jereznouveau_bind_texture(GLcontext *ctx, GLenum target,
514bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		     struct gl_texture_object *t)
515bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez{
516bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	context_dirty_i(ctx, TEX_OBJ, ctx->Texture.CurrentUnit);
517bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	context_dirty_i(ctx, TEX_ENV, ctx->Texture.CurrentUnit);
518bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez}
519bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
5204a7e9b5df453055ed6eedce1ea5c1d4a2f810fa7Francisco Jerezstatic gl_format
5214a7e9b5df453055ed6eedce1ea5c1d4a2f810fa7Francisco Jerezget_texbuffer_format(struct gl_renderbuffer *rb, GLint format)
5224a7e9b5df453055ed6eedce1ea5c1d4a2f810fa7Francisco Jerez{
5234a7e9b5df453055ed6eedce1ea5c1d4a2f810fa7Francisco Jerez	struct nouveau_surface *s = &to_nouveau_renderbuffer(rb)->surface;
5244a7e9b5df453055ed6eedce1ea5c1d4a2f810fa7Francisco Jerez
5254a7e9b5df453055ed6eedce1ea5c1d4a2f810fa7Francisco Jerez	if (s->cpp < 4)
5264a7e9b5df453055ed6eedce1ea5c1d4a2f810fa7Francisco Jerez		return s->format;
5274a7e9b5df453055ed6eedce1ea5c1d4a2f810fa7Francisco Jerez	else if (format == __DRI_TEXTURE_FORMAT_RGBA)
5284a7e9b5df453055ed6eedce1ea5c1d4a2f810fa7Francisco Jerez		return MESA_FORMAT_ARGB8888;
5294a7e9b5df453055ed6eedce1ea5c1d4a2f810fa7Francisco Jerez	else
5304a7e9b5df453055ed6eedce1ea5c1d4a2f810fa7Francisco Jerez		return MESA_FORMAT_XRGB8888;
5314a7e9b5df453055ed6eedce1ea5c1d4a2f810fa7Francisco Jerez}
5324a7e9b5df453055ed6eedce1ea5c1d4a2f810fa7Francisco Jerez
5334a7e9b5df453055ed6eedce1ea5c1d4a2f810fa7Francisco Jerezvoid
5344a7e9b5df453055ed6eedce1ea5c1d4a2f810fa7Francisco Jereznouveau_set_texbuffer(__DRIcontext *dri_ctx,
5354a7e9b5df453055ed6eedce1ea5c1d4a2f810fa7Francisco Jerez		      GLint target, GLint format,
5364a7e9b5df453055ed6eedce1ea5c1d4a2f810fa7Francisco Jerez		      __DRIdrawable *draw)
5374a7e9b5df453055ed6eedce1ea5c1d4a2f810fa7Francisco Jerez{
5384a7e9b5df453055ed6eedce1ea5c1d4a2f810fa7Francisco Jerez	struct nouveau_context *nctx = dri_ctx->driverPrivate;
5394a7e9b5df453055ed6eedce1ea5c1d4a2f810fa7Francisco Jerez	GLcontext *ctx = &nctx->base;
5404a7e9b5df453055ed6eedce1ea5c1d4a2f810fa7Francisco Jerez	struct gl_framebuffer *fb = draw->driverPrivate;
5414a7e9b5df453055ed6eedce1ea5c1d4a2f810fa7Francisco Jerez	struct gl_renderbuffer *rb =
5424a7e9b5df453055ed6eedce1ea5c1d4a2f810fa7Francisco Jerez		fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer;
5434a7e9b5df453055ed6eedce1ea5c1d4a2f810fa7Francisco Jerez	struct gl_texture_object *t = _mesa_get_current_tex_object(ctx, target);
5444a7e9b5df453055ed6eedce1ea5c1d4a2f810fa7Francisco Jerez	struct gl_texture_image *ti;
5454a7e9b5df453055ed6eedce1ea5c1d4a2f810fa7Francisco Jerez	struct nouveau_surface *s;
5464a7e9b5df453055ed6eedce1ea5c1d4a2f810fa7Francisco Jerez
5474a7e9b5df453055ed6eedce1ea5c1d4a2f810fa7Francisco Jerez	_mesa_lock_texture(ctx, t);
5484a7e9b5df453055ed6eedce1ea5c1d4a2f810fa7Francisco Jerez	ti = _mesa_get_tex_image(ctx, t, target, 0);
5494a7e9b5df453055ed6eedce1ea5c1d4a2f810fa7Francisco Jerez	s = &to_nouveau_teximage(ti)->surface;
5504a7e9b5df453055ed6eedce1ea5c1d4a2f810fa7Francisco Jerez
5514a7e9b5df453055ed6eedce1ea5c1d4a2f810fa7Francisco Jerez	/* Update the texture surface with the given drawable. */
5524a7e9b5df453055ed6eedce1ea5c1d4a2f810fa7Francisco Jerez	nouveau_update_renderbuffers(dri_ctx, draw);
5534a7e9b5df453055ed6eedce1ea5c1d4a2f810fa7Francisco Jerez	nouveau_surface_ref(&to_nouveau_renderbuffer(rb)->surface, s);
5544a7e9b5df453055ed6eedce1ea5c1d4a2f810fa7Francisco Jerez
5554a7e9b5df453055ed6eedce1ea5c1d4a2f810fa7Francisco Jerez	/* Update the image fields. */
5564a7e9b5df453055ed6eedce1ea5c1d4a2f810fa7Francisco Jerez	_mesa_init_teximage_fields(ctx, target, ti, s->width, s->height,
5574a7e9b5df453055ed6eedce1ea5c1d4a2f810fa7Francisco Jerez				   1, 0, s->cpp);
5584a7e9b5df453055ed6eedce1ea5c1d4a2f810fa7Francisco Jerez	ti->RowStride = s->pitch / s->cpp;
5594a7e9b5df453055ed6eedce1ea5c1d4a2f810fa7Francisco Jerez	ti->TexFormat = s->format = get_texbuffer_format(rb, format);
5604a7e9b5df453055ed6eedce1ea5c1d4a2f810fa7Francisco Jerez
5614a7e9b5df453055ed6eedce1ea5c1d4a2f810fa7Francisco Jerez	/* Try to validate it. */
5624a7e9b5df453055ed6eedce1ea5c1d4a2f810fa7Francisco Jerez	if (!validate_teximage(ctx, t, 0, 0, 0, 0, s->width, s->height, 1))
5634a7e9b5df453055ed6eedce1ea5c1d4a2f810fa7Francisco Jerez		nouveau_texture_reallocate(ctx, t);
5644a7e9b5df453055ed6eedce1ea5c1d4a2f810fa7Francisco Jerez
5654a7e9b5df453055ed6eedce1ea5c1d4a2f810fa7Francisco Jerez	context_dirty_i(ctx, TEX_OBJ, ctx->Texture.CurrentUnit);
5664a7e9b5df453055ed6eedce1ea5c1d4a2f810fa7Francisco Jerez	context_dirty_i(ctx, TEX_ENV, ctx->Texture.CurrentUnit);
5674a7e9b5df453055ed6eedce1ea5c1d4a2f810fa7Francisco Jerez
5684a7e9b5df453055ed6eedce1ea5c1d4a2f810fa7Francisco Jerez	_mesa_unlock_texture(ctx, t);
5694a7e9b5df453055ed6eedce1ea5c1d4a2f810fa7Francisco Jerez}
5704a7e9b5df453055ed6eedce1ea5c1d4a2f810fa7Francisco Jerez
571bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerezstatic void
572bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jereznouveau_texture_map(GLcontext *ctx, struct gl_texture_object *t)
573bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez{
574bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	int i;
575bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
576bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	for (i = t->BaseLevel; i < t->_MaxLevel; i++) {
577bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		if (t->Image[0][i])
578bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez			nouveau_teximage_map(ctx, t->Image[0][i]);
579bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	}
580bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez}
581bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
582bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerezstatic void
583bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jereznouveau_texture_unmap(GLcontext *ctx, struct gl_texture_object *t)
584bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez{
585bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	int i;
586bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
587bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	for (i = t->BaseLevel; i < t->_MaxLevel; i++) {
588bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		if (t->Image[0][i])
589bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez			nouveau_teximage_unmap(ctx, t->Image[0][i]);
590bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	}
591bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez}
592bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
593e96a52e9933eea7264a42983db1428368bcb4962Francisco Jerezstatic void
594e96a52e9933eea7264a42983db1428368bcb4962Francisco Jerezstore_mipmap(GLcontext *ctx, GLenum target, int first, int last,
595e96a52e9933eea7264a42983db1428368bcb4962Francisco Jerez	     struct gl_texture_object *t)
596e96a52e9933eea7264a42983db1428368bcb4962Francisco Jerez{
597e96a52e9933eea7264a42983db1428368bcb4962Francisco Jerez	struct gl_pixelstore_attrib packing = {
598e96a52e9933eea7264a42983db1428368bcb4962Francisco Jerez		.BufferObj = ctx->Shared->NullBufferObj,
599e96a52e9933eea7264a42983db1428368bcb4962Francisco Jerez		.Alignment = 1
600e96a52e9933eea7264a42983db1428368bcb4962Francisco Jerez	};
601e96a52e9933eea7264a42983db1428368bcb4962Francisco Jerez	GLenum format = t->Image[0][first]->TexFormat;
602e96a52e9933eea7264a42983db1428368bcb4962Francisco Jerez	unsigned base_format, type, comps;
603e96a52e9933eea7264a42983db1428368bcb4962Francisco Jerez	int i;
604e96a52e9933eea7264a42983db1428368bcb4962Francisco Jerez
605e96a52e9933eea7264a42983db1428368bcb4962Francisco Jerez	base_format = _mesa_get_format_base_format(format);
606e96a52e9933eea7264a42983db1428368bcb4962Francisco Jerez	_mesa_format_to_type_and_comps(format, &type, &comps);
607e96a52e9933eea7264a42983db1428368bcb4962Francisco Jerez
608e96a52e9933eea7264a42983db1428368bcb4962Francisco Jerez	for (i = first; i <= last; i++) {
609e96a52e9933eea7264a42983db1428368bcb4962Francisco Jerez		struct gl_texture_image *ti = t->Image[0][i];
610e96a52e9933eea7264a42983db1428368bcb4962Francisco Jerez		void *data = ti->Data;
611e96a52e9933eea7264a42983db1428368bcb4962Francisco Jerez
612e96a52e9933eea7264a42983db1428368bcb4962Francisco Jerez		nouveau_teximage(ctx, 3, target, i, ti->InternalFormat,
613e96a52e9933eea7264a42983db1428368bcb4962Francisco Jerez				 ti->Width, ti->Height, ti->Depth,
614e96a52e9933eea7264a42983db1428368bcb4962Francisco Jerez				 ti->Border, base_format, type, data,
615e96a52e9933eea7264a42983db1428368bcb4962Francisco Jerez				 &packing, t, ti);
616e96a52e9933eea7264a42983db1428368bcb4962Francisco Jerez
617e96a52e9933eea7264a42983db1428368bcb4962Francisco Jerez		_mesa_free_texmemory(data);
618e96a52e9933eea7264a42983db1428368bcb4962Francisco Jerez	}
619e96a52e9933eea7264a42983db1428368bcb4962Francisco Jerez}
620e96a52e9933eea7264a42983db1428368bcb4962Francisco Jerez
621e96a52e9933eea7264a42983db1428368bcb4962Francisco Jerezstatic void
622e96a52e9933eea7264a42983db1428368bcb4962Francisco Jereznouveau_generate_mipmap(GLcontext *ctx, GLenum target,
623e96a52e9933eea7264a42983db1428368bcb4962Francisco Jerez			struct gl_texture_object *t)
624e96a52e9933eea7264a42983db1428368bcb4962Francisco Jerez{
625e96a52e9933eea7264a42983db1428368bcb4962Francisco Jerez	if (_mesa_meta_check_generate_mipmap_fallback(ctx, target, t)) {
626e96a52e9933eea7264a42983db1428368bcb4962Francisco Jerez		struct gl_texture_image *base = t->Image[0][t->BaseLevel];
627e96a52e9933eea7264a42983db1428368bcb4962Francisco Jerez
628e96a52e9933eea7264a42983db1428368bcb4962Francisco Jerez		nouveau_teximage_map(ctx, base);
629e96a52e9933eea7264a42983db1428368bcb4962Francisco Jerez		_mesa_generate_mipmap(ctx, target, t);
630e96a52e9933eea7264a42983db1428368bcb4962Francisco Jerez		nouveau_teximage_unmap(ctx, base);
631e96a52e9933eea7264a42983db1428368bcb4962Francisco Jerez
632e96a52e9933eea7264a42983db1428368bcb4962Francisco Jerez		store_mipmap(ctx, target, t->BaseLevel + 1,
633e96a52e9933eea7264a42983db1428368bcb4962Francisco Jerez			     get_last_level(t), t);
634e96a52e9933eea7264a42983db1428368bcb4962Francisco Jerez
635e96a52e9933eea7264a42983db1428368bcb4962Francisco Jerez	} else {
636e96a52e9933eea7264a42983db1428368bcb4962Francisco Jerez		_mesa_meta_GenerateMipmap(ctx, target, t);
637e96a52e9933eea7264a42983db1428368bcb4962Francisco Jerez	}
638e96a52e9933eea7264a42983db1428368bcb4962Francisco Jerez}
639e96a52e9933eea7264a42983db1428368bcb4962Francisco Jerez
640bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerezvoid
641bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jereznouveau_texture_functions_init(struct dd_function_table *functions)
642bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez{
643bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	functions->NewTextureObject = nouveau_texture_new;
644bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	functions->DeleteTexture = nouveau_texture_free;
645bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	functions->NewTextureImage = nouveau_teximage_new;
646bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	functions->FreeTexImageData = nouveau_teximage_free;
647bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	functions->ChooseTextureFormat = nouveau_choose_tex_format;
648bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	functions->TexImage1D = nouveau_teximage_1d;
649bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	functions->TexImage2D = nouveau_teximage_2d;
650bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	functions->TexImage3D = nouveau_teximage_3d;
651bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	functions->TexSubImage1D = nouveau_texsubimage_1d;
652bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	functions->TexSubImage2D = nouveau_texsubimage_2d;
653bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	functions->TexSubImage3D = nouveau_texsubimage_3d;
654bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	functions->GetTexImage = nouveau_get_teximage;
655bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	functions->BindTexture = nouveau_bind_texture;
656bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	functions->MapTexture = nouveau_texture_map;
657bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	functions->UnmapTexture = nouveau_texture_unmap;
658e96a52e9933eea7264a42983db1428368bcb4962Francisco Jerez	functions->GenerateMipmap = nouveau_generate_mipmap;
659bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez}
660