Tizen 2.0 Release
[profile/ivi/osmesa.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/pbo.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"
43
44 static struct gl_texture_object *
45 nouveau_texture_new(struct gl_context *ctx, GLuint name, GLenum target)
46 {
47         struct nouveau_texture *nt = CALLOC_STRUCT(nouveau_texture);
48
49         _mesa_initialize_texture_object(&nt->base, name, target);
50
51         return &nt->base;
52 }
53
54 static void
55 nouveau_texture_free(struct gl_context *ctx, struct gl_texture_object *t)
56 {
57         struct nouveau_texture *nt = to_nouveau_texture(t);
58         int i;
59
60         for (i = 0; i < MAX_TEXTURE_LEVELS; i++)
61                 nouveau_surface_ref(NULL, &nt->surfaces[i]);
62
63         _mesa_delete_texture_object(ctx, t);
64 }
65
66 static struct gl_texture_image *
67 nouveau_teximage_new(struct gl_context *ctx)
68 {
69         struct nouveau_teximage *nti = CALLOC_STRUCT(nouveau_teximage);
70
71         return &nti->base;
72 }
73
74 static void
75 nouveau_teximage_free(struct gl_context *ctx, struct gl_texture_image *ti)
76 {
77         struct nouveau_teximage *nti = to_nouveau_teximage(ti);
78
79         nouveau_surface_ref(NULL, &nti->surface);
80 }
81
82 static void
83 nouveau_teximage_map(struct gl_context *ctx, struct gl_texture_image *ti,
84                      int access, int x, int y, int w, int h)
85 {
86         struct nouveau_teximage *nti = to_nouveau_teximage(ti);
87         struct nouveau_surface *s = &nti->surface;
88         struct nouveau_surface *st = &nti->transfer.surface;
89
90         if (s->bo) {
91                 if (!(access & GL_MAP_READ_BIT) &&
92                     nouveau_bo_pending(s->bo)) {
93                         /*
94                          * Heuristic: use a bounce buffer to pipeline
95                          * teximage transfers.
96                          */
97                         st->layout = LINEAR;
98                         st->format = s->format;
99                         st->cpp = s->cpp;
100                         st->width = w;
101                         st->height = h;
102                         st->pitch = s->pitch;
103                         nti->transfer.x = x;
104                         nti->transfer.y = y;
105
106                         ti->Data = nouveau_get_scratch(ctx, st->pitch * h,
107                                                        &st->bo, &st->offset);
108
109                 } else {
110                         int ret, flags = 0;
111
112                         if (access & GL_MAP_READ_BIT)
113                                 flags |= NOUVEAU_BO_RD;
114                         if (access & GL_MAP_WRITE_BIT)
115                                 flags |= NOUVEAU_BO_WR;
116
117                         if (!s->bo->map) {
118                                 ret = nouveau_bo_map(s->bo, flags);
119                                 assert(!ret);
120                         }
121
122                         ti->Data = s->bo->map + y * s->pitch + x * s->cpp;
123                 }
124         }
125 }
126
127 static void
128 nouveau_teximage_unmap(struct gl_context *ctx, struct gl_texture_image *ti)
129 {
130         struct nouveau_teximage *nti = to_nouveau_teximage(ti);
131         struct nouveau_surface *s = &nti->surface;
132         struct nouveau_surface *st = &nti->transfer.surface;
133
134         if (st->bo) {
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);
139
140         } else if (s->bo) {
141                 nouveau_bo_unmap(s->bo);
142         }
143
144         ti->Data = NULL;
145 }
146
147 static gl_format
148 nouveau_choose_tex_format(struct gl_context *ctx, GLint internalFormat,
149                           GLenum srcFormat, GLenum srcType)
150 {
151         switch (internalFormat) {
152         case 4:
153         case GL_RGBA:
154         case GL_RGBA2:
155         case GL_RGBA4:
156         case GL_RGBA8:
157         case GL_RGBA12:
158         case GL_RGBA16:
159         case GL_RGB10_A2:
160         case GL_COMPRESSED_RGBA:
161                 return MESA_FORMAT_ARGB8888;
162         case GL_RGB5_A1:
163                 return MESA_FORMAT_ARGB1555;
164
165         case GL_RGB:
166         case GL_RGB8:
167         case GL_RGB10:
168         case GL_RGB12:
169         case GL_RGB16:
170         case GL_COMPRESSED_RGB:
171                 return MESA_FORMAT_XRGB8888;
172         case 3:
173         case GL_R3_G3_B2:
174         case GL_RGB4:
175         case GL_RGB5:
176                 return MESA_FORMAT_RGB565;
177
178         case 2:
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;
188
189         case 1:
190         case GL_LUMINANCE:
191         case GL_LUMINANCE4:
192         case GL_LUMINANCE12:
193         case GL_LUMINANCE16:
194         case GL_LUMINANCE8:
195         case GL_COMPRESSED_LUMINANCE:
196                 return MESA_FORMAT_L8;
197
198         case GL_ALPHA:
199         case GL_ALPHA4:
200         case GL_ALPHA12:
201         case GL_ALPHA16:
202         case GL_ALPHA8:
203         case GL_COMPRESSED_ALPHA:
204                 return MESA_FORMAT_A8;
205
206         case GL_INTENSITY:
207         case GL_INTENSITY4:
208         case GL_INTENSITY12:
209         case GL_INTENSITY16:
210         case GL_INTENSITY8:
211                 return MESA_FORMAT_I8;
212
213         case GL_COLOR_INDEX:
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;
221
222         default:
223                 assert(0);
224         }
225 }
226
227 static GLboolean
228 teximage_fits(struct gl_texture_object *t, int level)
229 {
230         struct nouveau_surface *s = &to_nouveau_texture(t)->surfaces[level];
231         struct gl_texture_image *ti = t->Image[0][level];
232
233         if (!ti || !to_nouveau_teximage(ti)->surface.bo)
234                 return GL_FALSE;
235
236         if (level == t->BaseLevel && (s->offset & 0x7f))
237                 return GL_FALSE;
238
239         return t->Target == GL_TEXTURE_RECTANGLE ||
240                 (s->bo && s->format == ti->TexFormat &&
241                  s->width == ti->Width && s->height == ti->Height);
242 }
243
244 static GLboolean
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)
248 {
249         struct gl_texture_image *ti = t->Image[0][level];
250
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;
254
255                 if (t->Target == GL_TEXTURE_RECTANGLE)
256                         nouveau_surface_ref(s, &ss[level]);
257                 else
258                         context_drv(ctx)->surface_copy(ctx, &ss[level], s,
259                                                        x, y, x, y,
260                                                        width, height);
261
262                 return GL_TRUE;
263         }
264
265         return GL_FALSE;
266 }
267
268 static int
269 get_last_level(struct gl_texture_object *t)
270 {
271         struct gl_texture_image *base = t->Image[0][t->BaseLevel];
272
273         if (t->Sampler.MinFilter == GL_NEAREST ||
274             t->Sampler.MinFilter == GL_LINEAR || !base)
275                 return t->BaseLevel;
276         else
277                 return MIN2(t->BaseLevel + base->MaxLog2, t->MaxLevel);
278 }
279
280 static void
281 relayout_texture(struct gl_context *ctx, struct gl_texture_object *t)
282 {
283         struct gl_texture_image *base = t->Image[0][t->BaseLevel];
284
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,
290                         width = s->width,
291                         height = s->height;
292
293                 /* Deallocate the old storage. */
294                 for (i = 0; i < MAX_TEXTURE_LEVELS; i++)
295                         nouveau_bo_ref(NULL, &ss[i].bo);
296
297                 /* Relayout the mipmap tree. */
298                 for (i = t->BaseLevel; i <= last; i++) {
299                         size = width * height * s->cpp;
300
301                         /* Images larger than 16B have to be aligned. */
302                         if (size > 16)
303                                 offset = align(offset, 64);
304
305                         ss[i] = (struct nouveau_surface) {
306                                 .offset = offset,
307                                 .layout = SWIZZLED,
308                                 .format = s->format,
309                                 .width = width,
310                                 .height = height,
311                                 .cpp = s->cpp,
312                                 .pitch = width * s->cpp,
313                         };
314
315                         offset += size;
316                         width = MAX2(1, width / 2);
317                         height = MAX2(1, height / 2);
318                 }
319
320                 /* Get new storage. */
321                 size = align(offset, 64);
322
323                 ret = nouveau_bo_new(context_dev(ctx), NOUVEAU_BO_MAP |
324                                      NOUVEAU_BO_GART | NOUVEAU_BO_VRAM,
325                                      0, size, &ss[last].bo);
326                 assert(!ret);
327
328                 for (i = t->BaseLevel; i < last; i++)
329                         nouveau_bo_ref(ss[last].bo, &ss[i].bo);
330         }
331 }
332
333 GLboolean
334 nouveau_texture_validate(struct gl_context *ctx, struct gl_texture_object *t)
335 {
336         struct nouveau_texture *nt = to_nouveau_texture(t);
337         int i, last = get_last_level(t);
338
339         if (!teximage_fits(t, t->BaseLevel) ||
340             !teximage_fits(t, last))
341                 return GL_FALSE;
342
343         if (nt->dirty) {
344                 nt->dirty = GL_FALSE;
345
346                 /* Copy the teximages to the actual miptree. */
347                 for (i = t->BaseLevel; i <= last; i++) {
348                         struct nouveau_surface *s = &nt->surfaces[i];
349
350                         validate_teximage(ctx, t, i, 0, 0, 0,
351                                           s->width, s->height, 1);
352                 }
353
354                 FIRE_RING(context_chan(ctx));
355         }
356
357         return GL_TRUE;
358 }
359
360 void
361 nouveau_texture_reallocate(struct gl_context *ctx, struct gl_texture_object *t)
362 {
363         if (!teximage_fits(t, t->BaseLevel) ||
364             !teximage_fits(t, get_last_level(t))) {
365                 texture_dirty(t);
366                 relayout_texture(ctx, t);
367                 nouveau_texture_validate(ctx, t);
368         }
369 }
370
371 static unsigned
372 get_teximage_placement(struct gl_texture_image *ti)
373 {
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;
380         else
381                 return NOUVEAU_BO_GART | NOUVEAU_BO_MAP;
382 }
383
384 static void
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)
392 {
393         struct nouveau_surface *s = &to_nouveau_teximage(ti)->surface;
394         int ret;
395
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;
400
401         pixels = _mesa_validate_pbo_teximage(ctx, dims, width, height, depth,
402                                              format, type, pixels, packing,
403                                              "glTexImage");
404         if (pixels) {
405                 /* Store the pixel data. */
406                 nouveau_teximage_map(ctx, ti, GL_MAP_WRITE_BIT,
407                                      0, 0, width, height);
408
409                 ret = _mesa_texstore(ctx, dims, ti->_BaseFormat,
410                                      ti->TexFormat, ti->Data,
411                                      0, 0, 0, s->pitch,
412                                      ti->ImageOffsets,
413                                      width, height, depth,
414                                      format, type, pixels, packing);
415                 assert(ret);
416
417                 nouveau_teximage_unmap(ctx, ti);
418                 _mesa_unmap_teximage_pbo(ctx, packing);
419
420                 if (!validate_teximage(ctx, t, level, 0, 0, 0,
421                                        width, height, depth))
422                         /* It doesn't fit, mark it as dirty. */
423                         texture_dirty(t);
424         }
425
426         if (level == t->BaseLevel) {
427                 if (!teximage_fits(t, level))
428                         relayout_texture(ctx, t);
429                 nouveau_texture_validate(ctx, t);
430         }
431
432         context_dirty_i(ctx, TEX_OBJ, ctx->Texture.CurrentUnit);
433         context_dirty_i(ctx, TEX_ENV, ctx->Texture.CurrentUnit);
434 }
435
436 static void
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)
444 {
445         nouveau_teximage(ctx, 1, target, level, internalFormat,
446                          width, 1, 1, border, format, type, pixels,
447                          packing, t, ti);
448 }
449
450 static void
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)
458 {
459         nouveau_teximage(ctx, 2, target, level, internalFormat,
460                          width, height, 1, border, format, type, pixels,
461                          packing, t, ti);
462 }
463
464 static void
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)
472 {
473         nouveau_teximage(ctx, 3, target, level, internalFormat,
474                          width, height, depth, border, format, type, pixels,
475                          packing, t, ti);
476 }
477
478 static void
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)
486 {
487         struct nouveau_surface *s = &to_nouveau_teximage(ti)->surface;
488         int ret;
489
490         pixels = _mesa_validate_pbo_teximage(ctx, dims, width, height, depth,
491                                              format, type, pixels, packing,
492                                              "glTexSubImage");
493         if (pixels) {
494                 nouveau_teximage_map(ctx, ti, GL_MAP_WRITE_BIT,
495                                      xoffset, yoffset, width, height);
496
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);
501                 assert(ret);
502
503                 nouveau_teximage_unmap(ctx, ti);
504                 _mesa_unmap_teximage_pbo(ctx, packing);
505         }
506
507         if (!to_nouveau_texture(t)->dirty)
508                 validate_teximage(ctx, t, level, xoffset, yoffset, zoffset,
509                                   width, height, depth);
510 }
511
512 static void
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)
520 {
521         nouveau_texsubimage(ctx, 3, target, level, xoffset, yoffset, zoffset,
522                             width, height, depth, format, type, pixels,
523                             packing, t, ti);
524 }
525
526 static void
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)
534 {
535         nouveau_texsubimage(ctx, 2, target, level, xoffset, yoffset, 0,
536                             width, height, 1, format, type, pixels,
537                             packing, t, ti);
538 }
539
540 static void
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)
547 {
548         nouveau_texsubimage(ctx, 1, target, level, xoffset, 0, 0,
549                             width, 1, 1, format, type, pixels,
550                             packing, t, ti);
551 }
552
553 static void
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)
558 {
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,
562                            t, ti);
563         nouveau_teximage_unmap(ctx, ti);
564 }
565
566 static void
567 nouveau_bind_texture(struct gl_context *ctx, GLenum target,
568                      struct gl_texture_object *t)
569 {
570         context_dirty_i(ctx, TEX_OBJ, ctx->Texture.CurrentUnit);
571         context_dirty_i(ctx, TEX_ENV, ctx->Texture.CurrentUnit);
572 }
573
574 static gl_format
575 get_texbuffer_format(struct gl_renderbuffer *rb, GLint format)
576 {
577         struct nouveau_surface *s = &to_nouveau_renderbuffer(rb)->surface;
578
579         if (s->cpp < 4)
580                 return s->format;
581         else if (format == __DRI_TEXTURE_FORMAT_RGBA)
582                 return MESA_FORMAT_ARGB8888;
583         else
584                 return MESA_FORMAT_XRGB8888;
585 }
586
587 void
588 nouveau_set_texbuffer(__DRIcontext *dri_ctx,
589                       GLint target, GLint format,
590                       __DRIdrawable *draw)
591 {
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;
600
601         _mesa_lock_texture(ctx, t);
602         ti = _mesa_get_tex_image(ctx, t, target, 0);
603         s = &to_nouveau_teximage(ti)->surface;
604
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);
608
609         s->format = get_texbuffer_format(rb, format);
610
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;
615
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);
619
620         context_dirty_i(ctx, TEX_OBJ, ctx->Texture.CurrentUnit);
621         context_dirty_i(ctx, TEX_ENV, ctx->Texture.CurrentUnit);
622
623         _mesa_unlock_texture(ctx, t);
624 }
625
626 static void
627 nouveau_texture_map(struct gl_context *ctx, struct gl_texture_object *t)
628 {
629         int i;
630
631         for (i = t->BaseLevel; i < t->_MaxLevel; i++) {
632                 struct gl_texture_image *ti = t->Image[0][i];
633
634                 if (ti)
635                         nouveau_teximage_map(ctx, ti, GL_MAP_READ_BIT,
636                                              0, 0, ti->Width, ti->Height);
637         }
638 }
639
640 static void
641 nouveau_texture_unmap(struct gl_context *ctx, struct gl_texture_object *t)
642 {
643         int i;
644
645         for (i = t->BaseLevel; i < t->_MaxLevel; i++) {
646                 if (t->Image[0][i])
647                         nouveau_teximage_unmap(ctx, t->Image[0][i]);
648         }
649 }
650
651 static void
652 store_mipmap(struct gl_context *ctx, GLenum target, int first, int last,
653              struct gl_texture_object *t)
654 {
655         struct gl_pixelstore_attrib packing = {
656                 .BufferObj = ctx->Shared->NullBufferObj,
657                 .Alignment = 1
658         };
659         GLenum format = t->Image[0][t->BaseLevel]->TexFormat;
660         unsigned base_format, type, comps;
661         int i;
662
663         base_format = _mesa_get_format_base_format(format);
664         _mesa_format_to_type_and_comps(format, &type, &comps);
665
666         for (i = first; i <= last; i++) {
667                 struct gl_texture_image *ti = t->Image[0][i];
668                 void *data = ti->Data;
669
670                 nouveau_teximage(ctx, 3, target, i, ti->InternalFormat,
671                                  ti->Width, ti->Height, ti->Depth,
672                                  ti->Border, base_format, type, data,
673                                  &packing, t, ti);
674
675                 _mesa_free_texmemory(data);
676         }
677 }
678
679 static void
680 nouveau_generate_mipmap(struct gl_context *ctx, GLenum target,
681                         struct gl_texture_object *t)
682 {
683         if (_mesa_meta_check_generate_mipmap_fallback(ctx, target, t)) {
684                 struct gl_texture_image *base = t->Image[0][t->BaseLevel];
685
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);
690
691                 if (!_mesa_is_format_compressed(base->TexFormat)) {
692                         store_mipmap(ctx, target, t->BaseLevel + 1,
693                                      get_last_level(t), t);
694                 }
695
696         } else {
697                 _mesa_meta_GenerateMipmap(ctx, target, t);
698         }
699 }
700
701 void
702 nouveau_texture_functions_init(struct dd_function_table *functions)
703 {
704         functions->NewTextureObject = nouveau_texture_new;
705         functions->DeleteTexture = nouveau_texture_free;
706         functions->NewTextureImage = nouveau_teximage_new;
707         functions->FreeTexImageData = 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;
720 }