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