2 * Copyright (C) 2009 Francisco Jerez.
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:
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.
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.
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"
34 #include "main/texobj.h"
35 #include "main/texstore.h"
36 #include "main/texformat.h"
37 #include "main/texcompress.h"
38 #include "main/texgetimage.h"
39 #include "main/mipmap.h"
40 #include "main/texfetch.h"
41 #include "main/teximage.h"
42 #include "drivers/common/meta.h"
44 static struct gl_texture_object
*
45 nouveau_texture_new(struct gl_context
*ctx
, GLuint name
, GLenum target
)
47 struct nouveau_texture
*nt
= CALLOC_STRUCT(nouveau_texture
);
49 _mesa_initialize_texture_object(&nt
->base
, name
, target
);
55 nouveau_texture_free(struct gl_context
*ctx
, struct gl_texture_object
*t
)
57 struct nouveau_texture
*nt
= to_nouveau_texture(t
);
60 for (i
= 0; i
< MAX_TEXTURE_LEVELS
; i
++)
61 nouveau_surface_ref(NULL
, &nt
->surfaces
[i
]);
63 _mesa_delete_texture_object(ctx
, t
);
66 static struct gl_texture_image
*
67 nouveau_teximage_new(struct gl_context
*ctx
)
69 struct nouveau_teximage
*nti
= CALLOC_STRUCT(nouveau_teximage
);
75 nouveau_teximage_free(struct gl_context
*ctx
, struct gl_texture_image
*ti
)
77 struct nouveau_teximage
*nti
= to_nouveau_teximage(ti
);
79 nouveau_surface_ref(NULL
, &nti
->surface
);
83 nouveau_teximage_map(struct gl_context
*ctx
, struct gl_texture_image
*ti
,
84 int access
, int x
, int y
, int w
, int h
)
86 struct nouveau_teximage
*nti
= to_nouveau_teximage(ti
);
87 struct nouveau_surface
*s
= &nti
->surface
;
88 struct nouveau_surface
*st
= &nti
->transfer
.surface
;
91 if (!(access
& GL_MAP_READ_BIT
) &&
92 nouveau_bo_pending(s
->bo
)) {
94 * Heuristic: use a bounce buffer to pipeline
98 st
->format
= s
->format
;
102 st
->pitch
= s
->pitch
;
106 ti
->Data
= nouveau_get_scratch(ctx
, st
->pitch
* h
,
107 &st
->bo
, &st
->offset
);
112 if (access
& GL_MAP_READ_BIT
)
113 flags
|= NOUVEAU_BO_RD
;
114 if (access
& GL_MAP_WRITE_BIT
)
115 flags
|= NOUVEAU_BO_WR
;
118 ret
= nouveau_bo_map(s
->bo
, flags
);
122 ti
->Data
= s
->bo
->map
+ y
* s
->pitch
+ x
* s
->cpp
;
128 nouveau_teximage_unmap(struct gl_context
*ctx
, struct gl_texture_image
*ti
)
130 struct nouveau_teximage
*nti
= to_nouveau_teximage(ti
);
131 struct nouveau_surface
*s
= &nti
->surface
;
132 struct nouveau_surface
*st
= &nti
->transfer
.surface
;
135 context_drv(ctx
)->surface_copy(ctx
, s
, st
, nti
->transfer
.x
,
136 nti
->transfer
.y
, 0, 0,
137 st
->width
, st
->height
);
138 nouveau_surface_ref(NULL
, st
);
141 nouveau_bo_unmap(s
->bo
);
148 nouveau_choose_tex_format(struct gl_context
*ctx
, GLint internalFormat
,
149 GLenum srcFormat
, GLenum srcType
)
151 switch (internalFormat
) {
160 case GL_COMPRESSED_RGBA
:
161 return MESA_FORMAT_ARGB8888
;
163 return MESA_FORMAT_ARGB1555
;
170 case GL_COMPRESSED_RGB
:
171 return MESA_FORMAT_XRGB8888
;
176 return MESA_FORMAT_RGB565
;
179 case GL_LUMINANCE_ALPHA
:
180 case GL_LUMINANCE4_ALPHA4
:
181 case GL_LUMINANCE6_ALPHA2
:
182 case GL_LUMINANCE12_ALPHA4
:
183 case GL_LUMINANCE12_ALPHA12
:
184 case GL_LUMINANCE16_ALPHA16
:
185 case GL_LUMINANCE8_ALPHA8
:
186 case GL_COMPRESSED_LUMINANCE_ALPHA
:
187 return MESA_FORMAT_ARGB8888
;
195 case GL_COMPRESSED_LUMINANCE
:
196 return MESA_FORMAT_L8
;
203 case GL_COMPRESSED_ALPHA
:
204 return MESA_FORMAT_A8
;
211 return MESA_FORMAT_I8
;
214 case GL_COLOR_INDEX1_EXT
:
215 case GL_COLOR_INDEX2_EXT
:
216 case GL_COLOR_INDEX4_EXT
:
217 case GL_COLOR_INDEX12_EXT
:
218 case GL_COLOR_INDEX16_EXT
:
219 case GL_COLOR_INDEX8_EXT
:
220 return MESA_FORMAT_CI8
;
228 teximage_fits(struct gl_texture_object
*t
, int level
)
230 struct nouveau_surface
*s
= &to_nouveau_texture(t
)->surfaces
[level
];
231 struct gl_texture_image
*ti
= t
->Image
[0][level
];
233 if (!ti
|| !to_nouveau_teximage(ti
)->surface
.bo
)
236 if (level
== t
->BaseLevel
&& (s
->offset
& 0x7f))
239 return t
->Target
== GL_TEXTURE_RECTANGLE
||
240 (s
->bo
&& s
->format
== ti
->TexFormat
&&
241 s
->width
== ti
->Width
&& s
->height
== ti
->Height
);
245 validate_teximage(struct gl_context
*ctx
, struct gl_texture_object
*t
,
246 int level
, int x
, int y
, int z
,
247 int width
, int height
, int depth
)
249 struct gl_texture_image
*ti
= t
->Image
[0][level
];
251 if (teximage_fits(t
, level
)) {
252 struct nouveau_surface
*ss
= to_nouveau_texture(t
)->surfaces
;
253 struct nouveau_surface
*s
= &to_nouveau_teximage(ti
)->surface
;
255 if (t
->Target
== GL_TEXTURE_RECTANGLE
)
256 nouveau_surface_ref(s
, &ss
[level
]);
258 context_drv(ctx
)->surface_copy(ctx
, &ss
[level
], s
,
269 get_last_level(struct gl_texture_object
*t
)
271 struct gl_texture_image
*base
= t
->Image
[0][t
->BaseLevel
];
273 if (t
->Sampler
.MinFilter
== GL_NEAREST
||
274 t
->Sampler
.MinFilter
== GL_LINEAR
|| !base
)
277 return MIN2(t
->BaseLevel
+ base
->MaxLog2
, t
->MaxLevel
);
281 relayout_texture(struct gl_context
*ctx
, struct gl_texture_object
*t
)
283 struct gl_texture_image
*base
= t
->Image
[0][t
->BaseLevel
];
285 if (base
&& t
->Target
!= GL_TEXTURE_RECTANGLE
) {
286 struct nouveau_surface
*ss
= to_nouveau_texture(t
)->surfaces
;
287 struct nouveau_surface
*s
= &to_nouveau_teximage(base
)->surface
;
288 int i
, ret
, last
= get_last_level(t
);
289 unsigned size
, offset
= 0,
293 /* Deallocate the old storage. */
294 for (i
= 0; i
< MAX_TEXTURE_LEVELS
; i
++)
295 nouveau_bo_ref(NULL
, &ss
[i
].bo
);
297 /* Relayout the mipmap tree. */
298 for (i
= t
->BaseLevel
; i
<= last
; i
++) {
299 size
= width
* height
* s
->cpp
;
301 /* Images larger than 16B have to be aligned. */
303 offset
= align(offset
, 64);
305 ss
[i
] = (struct nouveau_surface
) {
312 .pitch
= width
* s
->cpp
,
316 width
= MAX2(1, width
/ 2);
317 height
= MAX2(1, height
/ 2);
320 /* Get new storage. */
321 size
= align(offset
, 64);
323 ret
= nouveau_bo_new(context_dev(ctx
), NOUVEAU_BO_MAP
|
324 NOUVEAU_BO_GART
| NOUVEAU_BO_VRAM
,
325 0, size
, &ss
[last
].bo
);
328 for (i
= t
->BaseLevel
; i
< last
; i
++)
329 nouveau_bo_ref(ss
[last
].bo
, &ss
[i
].bo
);
334 nouveau_texture_validate(struct gl_context
*ctx
, struct gl_texture_object
*t
)
336 struct nouveau_texture
*nt
= to_nouveau_texture(t
);
337 int i
, last
= get_last_level(t
);
339 if (!teximage_fits(t
, t
->BaseLevel
) ||
340 !teximage_fits(t
, last
))
344 nt
->dirty
= GL_FALSE
;
346 /* Copy the teximages to the actual miptree. */
347 for (i
= t
->BaseLevel
; i
<= last
; i
++) {
348 struct nouveau_surface
*s
= &nt
->surfaces
[i
];
350 validate_teximage(ctx
, t
, i
, 0, 0, 0,
351 s
->width
, s
->height
, 1);
354 FIRE_RING(context_chan(ctx
));
361 nouveau_texture_reallocate(struct gl_context
*ctx
, struct gl_texture_object
*t
)
363 if (!teximage_fits(t
, t
->BaseLevel
) ||
364 !teximage_fits(t
, get_last_level(t
))) {
366 relayout_texture(ctx
, t
);
367 nouveau_texture_validate(ctx
, t
);
372 get_teximage_placement(struct gl_texture_image
*ti
)
374 if (ti
->TexFormat
== MESA_FORMAT_A8
||
375 ti
->TexFormat
== MESA_FORMAT_L8
||
376 ti
->TexFormat
== MESA_FORMAT_I8
)
377 /* 1 cpp formats will have to be swizzled by the CPU,
378 * so leave them in system RAM for now. */
379 return NOUVEAU_BO_MAP
;
381 return NOUVEAU_BO_GART
| NOUVEAU_BO_MAP
;
385 nouveau_teximage(struct gl_context
*ctx
, GLint dims
, GLenum target
, GLint level
,
386 GLint internalFormat
,
387 GLint width
, GLint height
, GLint depth
, GLint border
,
388 GLenum format
, GLenum type
, const GLvoid
*pixels
,
389 const struct gl_pixelstore_attrib
*packing
,
390 struct gl_texture_object
*t
,
391 struct gl_texture_image
*ti
)
393 struct nouveau_surface
*s
= &to_nouveau_teximage(ti
)->surface
;
396 /* Allocate a new bo for the image. */
397 nouveau_surface_alloc(ctx
, s
, LINEAR
, get_teximage_placement(ti
),
398 ti
->TexFormat
, width
, height
);
399 ti
->RowStride
= s
->pitch
/ s
->cpp
;
401 pixels
= _mesa_validate_pbo_teximage(ctx
, dims
, width
, height
, depth
,
402 format
, type
, pixels
, packing
,
405 /* Store the pixel data. */
406 nouveau_teximage_map(ctx
, ti
, GL_MAP_WRITE_BIT
,
407 0, 0, width
, height
);
409 ret
= _mesa_texstore(ctx
, dims
, ti
->_BaseFormat
,
410 ti
->TexFormat
, ti
->Data
,
413 width
, height
, depth
,
414 format
, type
, pixels
, packing
);
417 nouveau_teximage_unmap(ctx
, ti
);
418 _mesa_unmap_teximage_pbo(ctx
, packing
);
420 if (!validate_teximage(ctx
, t
, level
, 0, 0, 0,
421 width
, height
, depth
))
422 /* It doesn't fit, mark it as dirty. */
426 if (level
== t
->BaseLevel
) {
427 if (!teximage_fits(t
, level
))
428 relayout_texture(ctx
, t
);
429 nouveau_texture_validate(ctx
, t
);
432 context_dirty_i(ctx
, TEX_OBJ
, ctx
->Texture
.CurrentUnit
);
433 context_dirty_i(ctx
, TEX_ENV
, ctx
->Texture
.CurrentUnit
);
437 nouveau_teximage_1d(struct gl_context
*ctx
, GLenum target
, GLint level
,
438 GLint internalFormat
,
439 GLint width
, GLint border
,
440 GLenum format
, GLenum type
, const GLvoid
*pixels
,
441 const struct gl_pixelstore_attrib
*packing
,
442 struct gl_texture_object
*t
,
443 struct gl_texture_image
*ti
)
445 nouveau_teximage(ctx
, 1, target
, level
, internalFormat
,
446 width
, 1, 1, border
, format
, type
, pixels
,
451 nouveau_teximage_2d(struct gl_context
*ctx
, GLenum target
, GLint level
,
452 GLint internalFormat
,
453 GLint width
, GLint height
, GLint border
,
454 GLenum format
, GLenum type
, const GLvoid
*pixels
,
455 const struct gl_pixelstore_attrib
*packing
,
456 struct gl_texture_object
*t
,
457 struct gl_texture_image
*ti
)
459 nouveau_teximage(ctx
, 2, target
, level
, internalFormat
,
460 width
, height
, 1, border
, format
, type
, pixels
,
465 nouveau_teximage_3d(struct gl_context
*ctx
, GLenum target
, GLint level
,
466 GLint internalFormat
,
467 GLint width
, GLint height
, GLint depth
, GLint border
,
468 GLenum format
, GLenum type
, const GLvoid
*pixels
,
469 const struct gl_pixelstore_attrib
*packing
,
470 struct gl_texture_object
*t
,
471 struct gl_texture_image
*ti
)
473 nouveau_teximage(ctx
, 3, target
, level
, internalFormat
,
474 width
, height
, depth
, border
, format
, type
, pixels
,
479 nouveau_texsubimage(struct gl_context
*ctx
, GLint dims
, GLenum target
, GLint level
,
480 GLint xoffset
, GLint yoffset
, GLint zoffset
,
481 GLint width
, GLint height
, GLint depth
,
482 GLenum format
, GLenum type
, const void *pixels
,
483 const struct gl_pixelstore_attrib
*packing
,
484 struct gl_texture_object
*t
,
485 struct gl_texture_image
*ti
)
487 struct nouveau_surface
*s
= &to_nouveau_teximage(ti
)->surface
;
490 pixels
= _mesa_validate_pbo_teximage(ctx
, dims
, width
, height
, depth
,
491 format
, type
, pixels
, packing
,
494 nouveau_teximage_map(ctx
, ti
, GL_MAP_WRITE_BIT
,
495 xoffset
, yoffset
, width
, height
);
497 ret
= _mesa_texstore(ctx
, 3, ti
->_BaseFormat
, ti
->TexFormat
,
498 ti
->Data
, 0, 0, 0, s
->pitch
,
499 ti
->ImageOffsets
, width
, height
, depth
,
500 format
, type
, pixels
, packing
);
503 nouveau_teximage_unmap(ctx
, ti
);
504 _mesa_unmap_teximage_pbo(ctx
, packing
);
507 if (!to_nouveau_texture(t
)->dirty
)
508 validate_teximage(ctx
, t
, level
, xoffset
, yoffset
, zoffset
,
509 width
, height
, depth
);
513 nouveau_texsubimage_3d(struct gl_context
*ctx
, GLenum target
, GLint level
,
514 GLint xoffset
, GLint yoffset
, GLint zoffset
,
515 GLint width
, GLint height
, GLint depth
,
516 GLenum format
, GLenum type
, const void *pixels
,
517 const struct gl_pixelstore_attrib
*packing
,
518 struct gl_texture_object
*t
,
519 struct gl_texture_image
*ti
)
521 nouveau_texsubimage(ctx
, 3, target
, level
, xoffset
, yoffset
, zoffset
,
522 width
, height
, depth
, format
, type
, pixels
,
527 nouveau_texsubimage_2d(struct gl_context
*ctx
, GLenum target
, GLint level
,
528 GLint xoffset
, GLint yoffset
,
529 GLint width
, GLint height
,
530 GLenum format
, GLenum type
, const void *pixels
,
531 const struct gl_pixelstore_attrib
*packing
,
532 struct gl_texture_object
*t
,
533 struct gl_texture_image
*ti
)
535 nouveau_texsubimage(ctx
, 2, target
, level
, xoffset
, yoffset
, 0,
536 width
, height
, 1, format
, type
, pixels
,
541 nouveau_texsubimage_1d(struct gl_context
*ctx
, GLenum target
, GLint level
,
542 GLint xoffset
, GLint width
,
543 GLenum format
, GLenum type
, const void *pixels
,
544 const struct gl_pixelstore_attrib
*packing
,
545 struct gl_texture_object
*t
,
546 struct gl_texture_image
*ti
)
548 nouveau_texsubimage(ctx
, 1, target
, level
, xoffset
, 0, 0,
549 width
, 1, 1, format
, type
, pixels
,
554 nouveau_get_teximage(struct gl_context
*ctx
, GLenum target
, GLint level
,
555 GLenum format
, GLenum type
, GLvoid
*pixels
,
556 struct gl_texture_object
*t
,
557 struct gl_texture_image
*ti
)
559 nouveau_teximage_map(ctx
, ti
, GL_MAP_READ_BIT
,
560 0, 0, ti
->Width
, ti
->Height
);
561 _mesa_get_teximage(ctx
, target
, level
, format
, type
, pixels
,
563 nouveau_teximage_unmap(ctx
, ti
);
567 nouveau_bind_texture(struct gl_context
*ctx
, GLenum target
,
568 struct gl_texture_object
*t
)
570 context_dirty_i(ctx
, TEX_OBJ
, ctx
->Texture
.CurrentUnit
);
571 context_dirty_i(ctx
, TEX_ENV
, ctx
->Texture
.CurrentUnit
);
575 get_texbuffer_format(struct gl_renderbuffer
*rb
, GLint format
)
577 struct nouveau_surface
*s
= &to_nouveau_renderbuffer(rb
)->surface
;
581 else if (format
== __DRI_TEXTURE_FORMAT_RGBA
)
582 return MESA_FORMAT_ARGB8888
;
584 return MESA_FORMAT_XRGB8888
;
588 nouveau_set_texbuffer(__DRIcontext
*dri_ctx
,
589 GLint target
, GLint format
,
592 struct nouveau_context
*nctx
= dri_ctx
->driverPrivate
;
593 struct gl_context
*ctx
= &nctx
->base
;
594 struct gl_framebuffer
*fb
= draw
->driverPrivate
;
595 struct gl_renderbuffer
*rb
=
596 fb
->Attachment
[BUFFER_FRONT_LEFT
].Renderbuffer
;
597 struct gl_texture_object
*t
= _mesa_get_current_tex_object(ctx
, target
);
598 struct gl_texture_image
*ti
;
599 struct nouveau_surface
*s
;
601 _mesa_lock_texture(ctx
, t
);
602 ti
= _mesa_get_tex_image(ctx
, t
, target
, 0);
603 s
= &to_nouveau_teximage(ti
)->surface
;
605 /* Update the texture surface with the given drawable. */
606 nouveau_update_renderbuffers(dri_ctx
, draw
);
607 nouveau_surface_ref(&to_nouveau_renderbuffer(rb
)->surface
, s
);
609 s
->format
= get_texbuffer_format(rb
, format
);
611 /* Update the image fields. */
612 _mesa_init_teximage_fields(ctx
, target
, ti
, s
->width
, s
->height
,
613 1, 0, s
->cpp
, s
->format
);
614 ti
->RowStride
= s
->pitch
/ s
->cpp
;
616 /* Try to validate it. */
617 if (!validate_teximage(ctx
, t
, 0, 0, 0, 0, s
->width
, s
->height
, 1))
618 nouveau_texture_reallocate(ctx
, t
);
620 context_dirty_i(ctx
, TEX_OBJ
, ctx
->Texture
.CurrentUnit
);
621 context_dirty_i(ctx
, TEX_ENV
, ctx
->Texture
.CurrentUnit
);
623 _mesa_unlock_texture(ctx
, t
);
627 nouveau_texture_map(struct gl_context
*ctx
, struct gl_texture_object
*t
)
631 for (i
= t
->BaseLevel
; i
< t
->_MaxLevel
; i
++) {
632 struct gl_texture_image
*ti
= t
->Image
[0][i
];
635 nouveau_teximage_map(ctx
, ti
, GL_MAP_READ_BIT
,
636 0, 0, ti
->Width
, ti
->Height
);
641 nouveau_texture_unmap(struct gl_context
*ctx
, struct gl_texture_object
*t
)
645 for (i
= t
->BaseLevel
; i
< t
->_MaxLevel
; i
++) {
647 nouveau_teximage_unmap(ctx
, t
->Image
[0][i
]);
652 store_mipmap(struct gl_context
*ctx
, GLenum target
, int first
, int last
,
653 struct gl_texture_object
*t
)
655 struct gl_pixelstore_attrib packing
= {
656 .BufferObj
= ctx
->Shared
->NullBufferObj
,
659 GLenum format
= t
->Image
[0][t
->BaseLevel
]->TexFormat
;
660 unsigned base_format
, type
, comps
;
663 base_format
= _mesa_get_format_base_format(format
);
664 _mesa_format_to_type_and_comps(format
, &type
, &comps
);
666 for (i
= first
; i
<= last
; i
++) {
667 struct gl_texture_image
*ti
= t
->Image
[0][i
];
668 void *data
= ti
->Data
;
670 nouveau_teximage(ctx
, 3, target
, i
, ti
->InternalFormat
,
671 ti
->Width
, ti
->Height
, ti
->Depth
,
672 ti
->Border
, base_format
, type
, data
,
675 _mesa_free_texmemory(data
);
680 nouveau_generate_mipmap(struct gl_context
*ctx
, GLenum target
,
681 struct gl_texture_object
*t
)
683 if (_mesa_meta_check_generate_mipmap_fallback(ctx
, target
, t
)) {
684 struct gl_texture_image
*base
= t
->Image
[0][t
->BaseLevel
];
686 nouveau_teximage_map(ctx
, base
, GL_MAP_READ_BIT
,
687 0, 0, base
->Width
, base
->Height
);
688 _mesa_generate_mipmap(ctx
, target
, t
);
689 nouveau_teximage_unmap(ctx
, base
);
691 if (!_mesa_is_format_compressed(base
->TexFormat
)) {
692 store_mipmap(ctx
, target
, t
->BaseLevel
+ 1,
693 get_last_level(t
), t
);
697 _mesa_meta_GenerateMipmap(ctx
, target
, t
);
702 nouveau_texture_functions_init(struct dd_function_table
*functions
)
704 functions
->NewTextureObject
= nouveau_texture_new
;
705 functions
->DeleteTexture
= nouveau_texture_free
;
706 functions
->NewTextureImage
= nouveau_teximage_new
;
707 functions
->FreeTextureImageBuffer
= nouveau_teximage_free
;
708 functions
->ChooseTextureFormat
= nouveau_choose_tex_format
;
709 functions
->TexImage1D
= nouveau_teximage_1d
;
710 functions
->TexImage2D
= nouveau_teximage_2d
;
711 functions
->TexImage3D
= nouveau_teximage_3d
;
712 functions
->TexSubImage1D
= nouveau_texsubimage_1d
;
713 functions
->TexSubImage2D
= nouveau_texsubimage_2d
;
714 functions
->TexSubImage3D
= nouveau_texsubimage_3d
;
715 functions
->GetTexImage
= nouveau_get_teximage
;
716 functions
->BindTexture
= nouveau_bind_texture
;
717 functions
->MapTexture
= nouveau_texture_map
;
718 functions
->UnmapTexture
= nouveau_texture_unmap
;
719 functions
->GenerateMipmap
= nouveau_generate_mipmap
;