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