9254a9e7bec2d56c0d0d2b6d9bb0bb5007c11fcc
[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(struct gl_context *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(struct gl_context *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(struct gl_context *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(struct gl_context *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(struct gl_context *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(struct gl_context *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(struct gl_context *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 case GL_COMPRESSED_RGBA:
119 return MESA_FORMAT_ARGB8888;
120 case GL_RGB5_A1:
121 return MESA_FORMAT_ARGB1555;
122
123 case GL_RGB:
124 case GL_RGB8:
125 case GL_RGB10:
126 case GL_RGB12:
127 case GL_RGB16:
128 case GL_COMPRESSED_RGB:
129 return MESA_FORMAT_XRGB8888;
130 case 3:
131 case GL_R3_G3_B2:
132 case GL_RGB4:
133 case GL_RGB5:
134 return MESA_FORMAT_RGB565;
135
136 case 2:
137 case GL_LUMINANCE_ALPHA:
138 case GL_LUMINANCE4_ALPHA4:
139 case GL_LUMINANCE6_ALPHA2:
140 case GL_LUMINANCE12_ALPHA4:
141 case GL_LUMINANCE12_ALPHA12:
142 case GL_LUMINANCE16_ALPHA16:
143 case GL_LUMINANCE8_ALPHA8:
144 case GL_COMPRESSED_LUMINANCE_ALPHA:
145 return MESA_FORMAT_ARGB8888;
146
147 case 1:
148 case GL_LUMINANCE:
149 case GL_LUMINANCE4:
150 case GL_LUMINANCE12:
151 case GL_LUMINANCE16:
152 case GL_LUMINANCE8:
153 case GL_COMPRESSED_LUMINANCE:
154 return MESA_FORMAT_L8;
155
156 case GL_ALPHA:
157 case GL_ALPHA4:
158 case GL_ALPHA12:
159 case GL_ALPHA16:
160 case GL_ALPHA8:
161 case GL_COMPRESSED_ALPHA:
162 return MESA_FORMAT_A8;
163
164 case GL_INTENSITY:
165 case GL_INTENSITY4:
166 case GL_INTENSITY12:
167 case GL_INTENSITY16:
168 case GL_INTENSITY8:
169 return MESA_FORMAT_I8;
170
171 case GL_COLOR_INDEX:
172 case GL_COLOR_INDEX1_EXT:
173 case GL_COLOR_INDEX2_EXT:
174 case GL_COLOR_INDEX4_EXT:
175 case GL_COLOR_INDEX12_EXT:
176 case GL_COLOR_INDEX16_EXT:
177 case GL_COLOR_INDEX8_EXT:
178 return MESA_FORMAT_CI8;
179
180 default:
181 assert(0);
182 }
183 }
184
185 static GLboolean
186 teximage_fits(struct gl_texture_object *t, int level)
187 {
188 struct nouveau_surface *s = &to_nouveau_texture(t)->surfaces[level];
189 struct gl_texture_image *ti = t->Image[0][level];
190
191 if (!ti || !to_nouveau_teximage(ti)->surface.bo)
192 return GL_FALSE;
193
194 if (level == t->BaseLevel && (s->offset & 0x7f))
195 return GL_FALSE;
196
197 return t->Target == GL_TEXTURE_RECTANGLE ||
198 (s->bo && s->format == ti->TexFormat &&
199 s->width == ti->Width && s->height == ti->Height);
200 }
201
202 static GLboolean
203 validate_teximage(struct gl_context *ctx, struct gl_texture_object *t,
204 int level, int x, int y, int z,
205 int width, int height, int depth)
206 {
207 struct gl_texture_image *ti = t->Image[0][level];
208
209 if (teximage_fits(t, level)) {
210 struct nouveau_surface *ss = to_nouveau_texture(t)->surfaces;
211 struct nouveau_surface *s = &to_nouveau_teximage(ti)->surface;
212
213 if (t->Target == GL_TEXTURE_RECTANGLE)
214 nouveau_surface_ref(s, &ss[level]);
215 else
216 context_drv(ctx)->surface_copy(ctx, &ss[level], s,
217 x, y, x, y,
218 width, height);
219
220 return GL_TRUE;
221 }
222
223 return GL_FALSE;
224 }
225
226 static int
227 get_last_level(struct gl_texture_object *t)
228 {
229 struct gl_texture_image *base = t->Image[0][t->BaseLevel];
230
231 if (t->MinFilter == GL_NEAREST ||
232 t->MinFilter == GL_LINEAR || !base)
233 return t->BaseLevel;
234 else
235 return MIN2(t->BaseLevel + base->MaxLog2, t->MaxLevel);
236 }
237
238 static void
239 relayout_texture(struct gl_context *ctx, struct gl_texture_object *t)
240 {
241 struct gl_texture_image *base = t->Image[0][t->BaseLevel];
242
243 if (base && t->Target != GL_TEXTURE_RECTANGLE) {
244 struct nouveau_surface *ss = to_nouveau_texture(t)->surfaces;
245 struct nouveau_surface *s = &to_nouveau_teximage(base)->surface;
246 int i, ret, last = get_last_level(t);
247 unsigned size, offset = 0,
248 width = s->width,
249 height = s->height;
250
251 /* Deallocate the old storage. */
252 for (i = 0; i < MAX_TEXTURE_LEVELS; i++)
253 nouveau_bo_ref(NULL, &ss[i].bo);
254
255 /* Relayout the mipmap tree. */
256 for (i = t->BaseLevel; i <= last; i++) {
257 size = width * height * s->cpp;
258
259 /* Images larger than 16B have to be aligned. */
260 if (size > 16)
261 offset = align(offset, 64);
262
263 ss[i] = (struct nouveau_surface) {
264 .offset = offset,
265 .layout = SWIZZLED,
266 .format = s->format,
267 .width = width,
268 .height = height,
269 .cpp = s->cpp,
270 .pitch = width * s->cpp,
271 };
272
273 offset += size;
274 width = MAX2(1, width / 2);
275 height = MAX2(1, height / 2);
276 }
277
278 /* Get new storage. */
279 size = align(offset, 64);
280
281 ret = nouveau_bo_new(context_dev(ctx), NOUVEAU_BO_MAP |
282 NOUVEAU_BO_GART | NOUVEAU_BO_VRAM,
283 0, size, &ss[last].bo);
284 assert(!ret);
285
286 for (i = t->BaseLevel; i < last; i++)
287 nouveau_bo_ref(ss[last].bo, &ss[i].bo);
288 }
289 }
290
291 GLboolean
292 nouveau_texture_validate(struct gl_context *ctx, struct gl_texture_object *t)
293 {
294 struct nouveau_texture *nt = to_nouveau_texture(t);
295 int i, last = get_last_level(t);
296
297 if (!teximage_fits(t, t->BaseLevel) ||
298 !teximage_fits(t, last))
299 return GL_FALSE;
300
301 if (nt->dirty) {
302 nt->dirty = GL_FALSE;
303
304 /* Copy the teximages to the actual miptree. */
305 for (i = t->BaseLevel; i <= last; i++) {
306 struct nouveau_surface *s = &nt->surfaces[i];
307
308 validate_teximage(ctx, t, i, 0, 0, 0,
309 s->width, s->height, 1);
310 }
311
312 FIRE_RING(context_chan(ctx));
313 }
314
315 return GL_TRUE;
316 }
317
318 void
319 nouveau_texture_reallocate(struct gl_context *ctx, struct gl_texture_object *t)
320 {
321 if (!teximage_fits(t, t->BaseLevel) ||
322 !teximage_fits(t, get_last_level(t))) {
323 texture_dirty(t);
324 relayout_texture(ctx, t);
325 nouveau_texture_validate(ctx, t);
326 }
327 }
328
329 static unsigned
330 get_teximage_placement(struct gl_texture_image *ti)
331 {
332 if (ti->TexFormat == MESA_FORMAT_A8 ||
333 ti->TexFormat == MESA_FORMAT_L8 ||
334 ti->TexFormat == MESA_FORMAT_I8)
335 /* 1 cpp formats will have to be swizzled by the CPU,
336 * so leave them in system RAM for now. */
337 return NOUVEAU_BO_MAP;
338 else
339 return NOUVEAU_BO_GART | NOUVEAU_BO_MAP;
340 }
341
342 static void
343 nouveau_teximage(struct gl_context *ctx, GLint dims, GLenum target, GLint level,
344 GLint internalFormat,
345 GLint width, GLint height, GLint depth, GLint border,
346 GLenum format, GLenum type, const GLvoid *pixels,
347 const struct gl_pixelstore_attrib *packing,
348 struct gl_texture_object *t,
349 struct gl_texture_image *ti)
350 {
351 struct nouveau_surface *s = &to_nouveau_teximage(ti)->surface;
352 int ret;
353
354 /* Allocate a new bo for the image. */
355 nouveau_surface_alloc(ctx, s, LINEAR, get_teximage_placement(ti),
356 ti->TexFormat, width, height);
357 ti->RowStride = s->pitch / s->cpp;
358
359 pixels = _mesa_validate_pbo_teximage(ctx, dims, width, height, depth,
360 format, type, pixels, packing,
361 "glTexImage");
362 if (pixels) {
363 /* Store the pixel data. */
364 nouveau_teximage_map(ctx, ti);
365
366 ret = _mesa_texstore(ctx, dims, ti->_BaseFormat,
367 ti->TexFormat, ti->Data,
368 0, 0, 0, s->pitch,
369 ti->ImageOffsets,
370 width, height, depth,
371 format, type, pixels, packing);
372 assert(ret);
373
374 nouveau_teximage_unmap(ctx, ti);
375 _mesa_unmap_teximage_pbo(ctx, packing);
376
377 if (!validate_teximage(ctx, t, level, 0, 0, 0,
378 width, height, depth))
379 /* It doesn't fit, mark it as dirty. */
380 texture_dirty(t);
381 }
382
383 if (level == t->BaseLevel) {
384 if (!teximage_fits(t, level))
385 relayout_texture(ctx, t);
386 nouveau_texture_validate(ctx, t);
387 }
388
389 context_dirty_i(ctx, TEX_OBJ, ctx->Texture.CurrentUnit);
390 context_dirty_i(ctx, TEX_ENV, ctx->Texture.CurrentUnit);
391 }
392
393 static void
394 nouveau_teximage_1d(struct gl_context *ctx, GLenum target, GLint level,
395 GLint internalFormat,
396 GLint width, GLint border,
397 GLenum format, GLenum type, const GLvoid *pixels,
398 const struct gl_pixelstore_attrib *packing,
399 struct gl_texture_object *t,
400 struct gl_texture_image *ti)
401 {
402 nouveau_teximage(ctx, 1, target, level, internalFormat,
403 width, 1, 1, border, format, type, pixels,
404 packing, t, ti);
405 }
406
407 static void
408 nouveau_teximage_2d(struct gl_context *ctx, GLenum target, GLint level,
409 GLint internalFormat,
410 GLint width, GLint height, GLint border,
411 GLenum format, GLenum type, const GLvoid *pixels,
412 const struct gl_pixelstore_attrib *packing,
413 struct gl_texture_object *t,
414 struct gl_texture_image *ti)
415 {
416 nouveau_teximage(ctx, 2, target, level, internalFormat,
417 width, height, 1, border, format, type, pixels,
418 packing, t, ti);
419 }
420
421 static void
422 nouveau_teximage_3d(struct gl_context *ctx, GLenum target, GLint level,
423 GLint internalFormat,
424 GLint width, GLint height, GLint depth, GLint border,
425 GLenum format, GLenum type, const GLvoid *pixels,
426 const struct gl_pixelstore_attrib *packing,
427 struct gl_texture_object *t,
428 struct gl_texture_image *ti)
429 {
430 nouveau_teximage(ctx, 3, target, level, internalFormat,
431 width, height, depth, border, format, type, pixels,
432 packing, t, ti);
433 }
434
435 static void
436 nouveau_texsubimage(struct gl_context *ctx, GLint dims, GLenum target, GLint level,
437 GLint xoffset, GLint yoffset, GLint zoffset,
438 GLint width, GLint height, GLint depth,
439 GLenum format, GLenum type, const void *pixels,
440 const struct gl_pixelstore_attrib *packing,
441 struct gl_texture_object *t,
442 struct gl_texture_image *ti)
443 {
444 struct nouveau_surface *s = &to_nouveau_teximage(ti)->surface;
445 int ret;
446
447 pixels = _mesa_validate_pbo_teximage(ctx, dims, width, height, depth,
448 format, type, pixels, packing,
449 "glTexSubImage");
450 if (pixels) {
451 nouveau_teximage_map(ctx, ti);
452
453 ret = _mesa_texstore(ctx, 3, ti->_BaseFormat, ti->TexFormat,
454 ti->Data, xoffset, yoffset, zoffset,
455 s->pitch, ti->ImageOffsets,
456 width, height, depth, format, type,
457 pixels, packing);
458 assert(ret);
459
460 nouveau_teximage_unmap(ctx, ti);
461 _mesa_unmap_teximage_pbo(ctx, packing);
462 }
463
464 if (!to_nouveau_texture(t)->dirty)
465 validate_teximage(ctx, t, level, xoffset, yoffset, zoffset,
466 width, height, depth);
467 }
468
469 static void
470 nouveau_texsubimage_3d(struct gl_context *ctx, GLenum target, GLint level,
471 GLint xoffset, GLint yoffset, GLint zoffset,
472 GLint width, GLint height, GLint depth,
473 GLenum format, GLenum type, const void *pixels,
474 const struct gl_pixelstore_attrib *packing,
475 struct gl_texture_object *t,
476 struct gl_texture_image *ti)
477 {
478 nouveau_texsubimage(ctx, 3, target, level, xoffset, yoffset, zoffset,
479 width, height, depth, format, type, pixels,
480 packing, t, ti);
481 }
482
483 static void
484 nouveau_texsubimage_2d(struct gl_context *ctx, GLenum target, GLint level,
485 GLint xoffset, GLint yoffset,
486 GLint width, GLint height,
487 GLenum format, GLenum type, const void *pixels,
488 const struct gl_pixelstore_attrib *packing,
489 struct gl_texture_object *t,
490 struct gl_texture_image *ti)
491 {
492 nouveau_texsubimage(ctx, 2, target, level, xoffset, yoffset, 0,
493 width, height, 1, format, type, pixels,
494 packing, t, ti);
495 }
496
497 static void
498 nouveau_texsubimage_1d(struct gl_context *ctx, GLenum target, GLint level,
499 GLint xoffset, GLint width,
500 GLenum format, GLenum type, const void *pixels,
501 const struct gl_pixelstore_attrib *packing,
502 struct gl_texture_object *t,
503 struct gl_texture_image *ti)
504 {
505 nouveau_texsubimage(ctx, 1, target, level, xoffset, 0, 0,
506 width, 1, 1, format, type, pixels,
507 packing, t, ti);
508 }
509
510 static void
511 nouveau_get_teximage(struct gl_context *ctx, GLenum target, GLint level,
512 GLenum format, GLenum type, GLvoid *pixels,
513 struct gl_texture_object *t,
514 struct gl_texture_image *ti)
515 {
516 nouveau_teximage_map(ctx, ti);
517 _mesa_get_teximage(ctx, target, level, format, type, pixels,
518 t, ti);
519 nouveau_teximage_unmap(ctx, ti);
520 }
521
522 static void
523 nouveau_bind_texture(struct gl_context *ctx, GLenum target,
524 struct gl_texture_object *t)
525 {
526 context_dirty_i(ctx, TEX_OBJ, ctx->Texture.CurrentUnit);
527 context_dirty_i(ctx, TEX_ENV, ctx->Texture.CurrentUnit);
528 }
529
530 static gl_format
531 get_texbuffer_format(struct gl_renderbuffer *rb, GLint format)
532 {
533 struct nouveau_surface *s = &to_nouveau_renderbuffer(rb)->surface;
534
535 if (s->cpp < 4)
536 return s->format;
537 else if (format == __DRI_TEXTURE_FORMAT_RGBA)
538 return MESA_FORMAT_ARGB8888;
539 else
540 return MESA_FORMAT_XRGB8888;
541 }
542
543 void
544 nouveau_set_texbuffer(__DRIcontext *dri_ctx,
545 GLint target, GLint format,
546 __DRIdrawable *draw)
547 {
548 struct nouveau_context *nctx = dri_ctx->driverPrivate;
549 struct gl_context *ctx = &nctx->base;
550 struct gl_framebuffer *fb = draw->driverPrivate;
551 struct gl_renderbuffer *rb =
552 fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer;
553 struct gl_texture_object *t = _mesa_get_current_tex_object(ctx, target);
554 struct gl_texture_image *ti;
555 struct nouveau_surface *s;
556
557 _mesa_lock_texture(ctx, t);
558 ti = _mesa_get_tex_image(ctx, t, target, 0);
559 s = &to_nouveau_teximage(ti)->surface;
560
561 /* Update the texture surface with the given drawable. */
562 nouveau_update_renderbuffers(dri_ctx, draw);
563 nouveau_surface_ref(&to_nouveau_renderbuffer(rb)->surface, s);
564
565 /* Update the image fields. */
566 _mesa_init_teximage_fields(ctx, target, ti, s->width, s->height,
567 1, 0, s->cpp);
568 ti->RowStride = s->pitch / s->cpp;
569 ti->TexFormat = s->format = get_texbuffer_format(rb, format);
570
571 /* Try to validate it. */
572 if (!validate_teximage(ctx, t, 0, 0, 0, 0, s->width, s->height, 1))
573 nouveau_texture_reallocate(ctx, t);
574
575 context_dirty_i(ctx, TEX_OBJ, ctx->Texture.CurrentUnit);
576 context_dirty_i(ctx, TEX_ENV, ctx->Texture.CurrentUnit);
577
578 _mesa_unlock_texture(ctx, t);
579 }
580
581 static void
582 nouveau_texture_map(struct gl_context *ctx, struct gl_texture_object *t)
583 {
584 int i;
585
586 for (i = t->BaseLevel; i < t->_MaxLevel; i++) {
587 if (t->Image[0][i])
588 nouveau_teximage_map(ctx, t->Image[0][i]);
589 }
590 }
591
592 static void
593 nouveau_texture_unmap(struct gl_context *ctx, struct gl_texture_object *t)
594 {
595 int i;
596
597 for (i = t->BaseLevel; i < t->_MaxLevel; i++) {
598 if (t->Image[0][i])
599 nouveau_teximage_unmap(ctx, t->Image[0][i]);
600 }
601 }
602
603 static void
604 store_mipmap(struct gl_context *ctx, GLenum target, int first, int last,
605 struct gl_texture_object *t)
606 {
607 struct gl_pixelstore_attrib packing = {
608 .BufferObj = ctx->Shared->NullBufferObj,
609 .Alignment = 1
610 };
611 GLenum format = t->Image[0][t->BaseLevel]->TexFormat;
612 unsigned base_format, type, comps;
613 int i;
614
615 base_format = _mesa_get_format_base_format(format);
616 _mesa_format_to_type_and_comps(format, &type, &comps);
617
618 for (i = first; i <= last; i++) {
619 struct gl_texture_image *ti = t->Image[0][i];
620 void *data = ti->Data;
621
622 nouveau_teximage(ctx, 3, target, i, ti->InternalFormat,
623 ti->Width, ti->Height, ti->Depth,
624 ti->Border, base_format, type, data,
625 &packing, t, ti);
626
627 _mesa_free_texmemory(data);
628 }
629 }
630
631 static void
632 nouveau_generate_mipmap(struct gl_context *ctx, GLenum target,
633 struct gl_texture_object *t)
634 {
635 if (_mesa_meta_check_generate_mipmap_fallback(ctx, target, t)) {
636 struct gl_texture_image *base = t->Image[0][t->BaseLevel];
637
638 nouveau_teximage_map(ctx, base);
639 _mesa_generate_mipmap(ctx, target, t);
640 nouveau_teximage_unmap(ctx, base);
641
642 store_mipmap(ctx, target, t->BaseLevel + 1,
643 get_last_level(t), t);
644
645 } else {
646 _mesa_meta_GenerateMipmap(ctx, target, t);
647 }
648 }
649
650 void
651 nouveau_texture_functions_init(struct dd_function_table *functions)
652 {
653 functions->NewTextureObject = nouveau_texture_new;
654 functions->DeleteTexture = nouveau_texture_free;
655 functions->NewTextureImage = nouveau_teximage_new;
656 functions->FreeTexImageData = nouveau_teximage_free;
657 functions->ChooseTextureFormat = nouveau_choose_tex_format;
658 functions->TexImage1D = nouveau_teximage_1d;
659 functions->TexImage2D = nouveau_teximage_2d;
660 functions->TexImage3D = nouveau_teximage_3d;
661 functions->TexSubImage1D = nouveau_texsubimage_1d;
662 functions->TexSubImage2D = nouveau_texsubimage_2d;
663 functions->TexSubImage3D = nouveau_texsubimage_3d;
664 functions->GetTexImage = nouveau_get_teximage;
665 functions->BindTexture = nouveau_bind_texture;
666 functions->MapTexture = nouveau_texture_map;
667 functions->UnmapTexture = nouveau_texture_unmap;
668 functions->GenerateMipmap = nouveau_generate_mipmap;
669 }