38b89de92e3ebd2b598fd618291a5bb004e867aa
[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/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
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 = ti->Data + 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 ti->Data = 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 case GL_COLOR_INDEX:
293 case GL_COLOR_INDEX1_EXT:
294 case GL_COLOR_INDEX2_EXT:
295 case GL_COLOR_INDEX4_EXT:
296 case GL_COLOR_INDEX12_EXT:
297 case GL_COLOR_INDEX16_EXT:
298 case GL_COLOR_INDEX8_EXT:
299 return MESA_FORMAT_CI8;
300
301 default:
302 assert(0);
303 }
304 }
305
306 static GLboolean
307 teximage_fits(struct gl_texture_object *t, int level)
308 {
309 struct nouveau_surface *s = &to_nouveau_texture(t)->surfaces[level];
310 struct gl_texture_image *ti = t->Image[0][level];
311
312 if (!ti || !to_nouveau_teximage(ti)->surface.bo)
313 return GL_FALSE;
314
315 if (level == t->BaseLevel && (s->offset & 0x7f))
316 return GL_FALSE;
317
318 return t->Target == GL_TEXTURE_RECTANGLE ||
319 (s->bo && s->format == ti->TexFormat &&
320 s->width == ti->Width && s->height == ti->Height);
321 }
322
323 static GLboolean
324 validate_teximage(struct gl_context *ctx, struct gl_texture_object *t,
325 int level, int x, int y, int z,
326 int width, int height, int depth)
327 {
328 struct gl_texture_image *ti = t->Image[0][level];
329
330 if (teximage_fits(t, level)) {
331 struct nouveau_surface *ss = to_nouveau_texture(t)->surfaces;
332 struct nouveau_surface *s = &to_nouveau_teximage(ti)->surface;
333
334 if (t->Target == GL_TEXTURE_RECTANGLE)
335 nouveau_surface_ref(s, &ss[level]);
336 else
337 context_drv(ctx)->surface_copy(ctx, &ss[level], s,
338 x, y, x, y,
339 width, height);
340
341 return GL_TRUE;
342 }
343
344 return GL_FALSE;
345 }
346
347 static int
348 get_last_level(struct gl_texture_object *t)
349 {
350 struct gl_texture_image *base = t->Image[0][t->BaseLevel];
351
352 if (t->Sampler.MinFilter == GL_NEAREST ||
353 t->Sampler.MinFilter == GL_LINEAR || !base)
354 return t->BaseLevel;
355 else
356 return MIN2(t->BaseLevel + base->MaxLog2, t->MaxLevel);
357 }
358
359 static void
360 relayout_texture(struct gl_context *ctx, struct gl_texture_object *t)
361 {
362 struct gl_texture_image *base = t->Image[0][t->BaseLevel];
363
364 if (base && t->Target != GL_TEXTURE_RECTANGLE) {
365 struct nouveau_surface *ss = to_nouveau_texture(t)->surfaces;
366 struct nouveau_surface *s = &to_nouveau_teximage(base)->surface;
367 int i, ret, last = get_last_level(t);
368 unsigned size, offset = 0,
369 width = s->width,
370 height = s->height;
371
372 /* Deallocate the old storage. */
373 for (i = 0; i < MAX_TEXTURE_LEVELS; i++)
374 nouveau_bo_ref(NULL, &ss[i].bo);
375
376 /* Relayout the mipmap tree. */
377 for (i = t->BaseLevel; i <= last; i++) {
378 size = width * height * s->cpp;
379
380 /* Images larger than 16B have to be aligned. */
381 if (size > 16)
382 offset = align(offset, 64);
383
384 ss[i] = (struct nouveau_surface) {
385 .offset = offset,
386 .layout = SWIZZLED,
387 .format = s->format,
388 .width = width,
389 .height = height,
390 .cpp = s->cpp,
391 .pitch = width * s->cpp,
392 };
393
394 offset += size;
395 width = MAX2(1, width / 2);
396 height = MAX2(1, height / 2);
397 }
398
399 /* Get new storage. */
400 size = align(offset, 64);
401
402 ret = nouveau_bo_new(context_dev(ctx), NOUVEAU_BO_MAP |
403 NOUVEAU_BO_GART | NOUVEAU_BO_VRAM,
404 0, size, &ss[last].bo);
405 assert(!ret);
406
407 for (i = t->BaseLevel; i < last; i++)
408 nouveau_bo_ref(ss[last].bo, &ss[i].bo);
409 }
410 }
411
412 GLboolean
413 nouveau_texture_validate(struct gl_context *ctx, struct gl_texture_object *t)
414 {
415 struct nouveau_texture *nt = to_nouveau_texture(t);
416 int i, last = get_last_level(t);
417
418 if (!teximage_fits(t, t->BaseLevel) ||
419 !teximage_fits(t, last))
420 return GL_FALSE;
421
422 if (nt->dirty) {
423 nt->dirty = GL_FALSE;
424
425 /* Copy the teximages to the actual miptree. */
426 for (i = t->BaseLevel; i <= last; i++) {
427 struct nouveau_surface *s = &nt->surfaces[i];
428
429 validate_teximage(ctx, t, i, 0, 0, 0,
430 s->width, s->height, 1);
431 }
432
433 FIRE_RING(context_chan(ctx));
434 }
435
436 return GL_TRUE;
437 }
438
439 void
440 nouveau_texture_reallocate(struct gl_context *ctx, struct gl_texture_object *t)
441 {
442 if (!teximage_fits(t, t->BaseLevel) ||
443 !teximage_fits(t, get_last_level(t))) {
444 texture_dirty(t);
445 relayout_texture(ctx, t);
446 nouveau_texture_validate(ctx, t);
447 }
448 }
449
450 static unsigned
451 get_teximage_placement(struct gl_texture_image *ti)
452 {
453 if (ti->TexFormat == MESA_FORMAT_A8 ||
454 ti->TexFormat == MESA_FORMAT_L8 ||
455 ti->TexFormat == MESA_FORMAT_I8)
456 /* 1 cpp formats will have to be swizzled by the CPU,
457 * so leave them in system RAM for now. */
458 return NOUVEAU_BO_MAP;
459 else
460 return NOUVEAU_BO_GART | NOUVEAU_BO_MAP;
461 }
462
463 static void
464 nouveau_teximage(struct gl_context *ctx, GLint dims, GLenum target, GLint level,
465 GLint internalFormat,
466 GLint width, GLint height, GLint depth, GLint border,
467 GLenum format, GLenum type, const GLvoid *pixels,
468 const struct gl_pixelstore_attrib *packing,
469 struct gl_texture_object *t,
470 struct gl_texture_image *ti)
471 {
472 struct nouveau_surface *s = &to_nouveau_teximage(ti)->surface;
473 int ret;
474
475 /* Allocate a new bo for the image. */
476 nouveau_surface_alloc(ctx, s, LINEAR, get_teximage_placement(ti),
477 ti->TexFormat, width, height);
478 ti->RowStride = s->pitch / s->cpp;
479
480 pixels = _mesa_validate_pbo_teximage(ctx, dims, width, height, depth,
481 format, type, pixels, packing,
482 "glTexImage");
483 if (pixels) {
484 /* Store the pixel data. */
485 nouveau_teximage_map(ctx, ti, GL_MAP_WRITE_BIT,
486 0, 0, width, height);
487
488 ret = _mesa_texstore(ctx, dims, ti->_BaseFormat,
489 ti->TexFormat, ti->Data,
490 0, 0, 0, s->pitch,
491 ti->ImageOffsets,
492 width, height, depth,
493 format, type, pixels, packing);
494 assert(ret);
495
496 nouveau_teximage_unmap(ctx, ti);
497 _mesa_unmap_teximage_pbo(ctx, packing);
498
499 if (!validate_teximage(ctx, t, level, 0, 0, 0,
500 width, height, depth))
501 /* It doesn't fit, mark it as dirty. */
502 texture_dirty(t);
503 }
504
505 if (level == t->BaseLevel) {
506 if (!teximage_fits(t, level))
507 relayout_texture(ctx, t);
508 nouveau_texture_validate(ctx, t);
509 }
510
511 context_dirty_i(ctx, TEX_OBJ, ctx->Texture.CurrentUnit);
512 context_dirty_i(ctx, TEX_ENV, ctx->Texture.CurrentUnit);
513 }
514
515 static void
516 nouveau_teximage_1d(struct gl_context *ctx, GLenum target, GLint level,
517 GLint internalFormat,
518 GLint width, GLint border,
519 GLenum format, GLenum type, const GLvoid *pixels,
520 const struct gl_pixelstore_attrib *packing,
521 struct gl_texture_object *t,
522 struct gl_texture_image *ti)
523 {
524 nouveau_teximage(ctx, 1, target, level, internalFormat,
525 width, 1, 1, border, format, type, pixels,
526 packing, t, ti);
527 }
528
529 static void
530 nouveau_teximage_2d(struct gl_context *ctx, GLenum target, GLint level,
531 GLint internalFormat,
532 GLint width, GLint height, GLint border,
533 GLenum format, GLenum type, const GLvoid *pixels,
534 const struct gl_pixelstore_attrib *packing,
535 struct gl_texture_object *t,
536 struct gl_texture_image *ti)
537 {
538 nouveau_teximage(ctx, 2, target, level, internalFormat,
539 width, height, 1, border, format, type, pixels,
540 packing, t, ti);
541 }
542
543 static void
544 nouveau_teximage_3d(struct gl_context *ctx, GLenum target, GLint level,
545 GLint internalFormat,
546 GLint width, GLint height, GLint depth, GLint border,
547 GLenum format, GLenum type, const GLvoid *pixels,
548 const struct gl_pixelstore_attrib *packing,
549 struct gl_texture_object *t,
550 struct gl_texture_image *ti)
551 {
552 nouveau_teximage(ctx, 3, target, level, internalFormat,
553 width, height, depth, border, format, type, pixels,
554 packing, t, ti);
555 }
556
557 static void
558 nouveau_texsubimage(struct gl_context *ctx, GLint dims, GLenum target, GLint level,
559 GLint xoffset, GLint yoffset, GLint zoffset,
560 GLint width, GLint height, GLint depth,
561 GLenum format, GLenum type, const void *pixels,
562 const struct gl_pixelstore_attrib *packing,
563 struct gl_texture_object *t,
564 struct gl_texture_image *ti)
565 {
566 struct nouveau_surface *s = &to_nouveau_teximage(ti)->surface;
567 int ret;
568
569 pixels = _mesa_validate_pbo_teximage(ctx, dims, width, height, depth,
570 format, type, pixels, packing,
571 "glTexSubImage");
572 if (pixels) {
573 nouveau_teximage_map(ctx, ti, GL_MAP_WRITE_BIT,
574 xoffset, yoffset, width, height);
575
576 ret = _mesa_texstore(ctx, 3, ti->_BaseFormat, ti->TexFormat,
577 ti->Data, 0, 0, 0, s->pitch,
578 ti->ImageOffsets, width, height, depth,
579 format, type, pixels, packing);
580 assert(ret);
581
582 nouveau_teximage_unmap(ctx, ti);
583 _mesa_unmap_teximage_pbo(ctx, packing);
584 }
585
586 if (!to_nouveau_texture(t)->dirty)
587 validate_teximage(ctx, t, level, xoffset, yoffset, zoffset,
588 width, height, depth);
589 }
590
591 static void
592 nouveau_texsubimage_3d(struct gl_context *ctx, GLenum target, GLint level,
593 GLint xoffset, GLint yoffset, GLint zoffset,
594 GLint width, GLint height, GLint depth,
595 GLenum format, GLenum type, const void *pixels,
596 const struct gl_pixelstore_attrib *packing,
597 struct gl_texture_object *t,
598 struct gl_texture_image *ti)
599 {
600 nouveau_texsubimage(ctx, 3, target, level, xoffset, yoffset, zoffset,
601 width, height, depth, format, type, pixels,
602 packing, t, ti);
603 }
604
605 static void
606 nouveau_texsubimage_2d(struct gl_context *ctx, GLenum target, GLint level,
607 GLint xoffset, GLint yoffset,
608 GLint width, GLint height,
609 GLenum format, GLenum type, const void *pixels,
610 const struct gl_pixelstore_attrib *packing,
611 struct gl_texture_object *t,
612 struct gl_texture_image *ti)
613 {
614 nouveau_texsubimage(ctx, 2, target, level, xoffset, yoffset, 0,
615 width, height, 1, format, type, pixels,
616 packing, t, ti);
617 }
618
619 static void
620 nouveau_texsubimage_1d(struct gl_context *ctx, GLenum target, GLint level,
621 GLint xoffset, GLint width,
622 GLenum format, GLenum type, const void *pixels,
623 const struct gl_pixelstore_attrib *packing,
624 struct gl_texture_object *t,
625 struct gl_texture_image *ti)
626 {
627 nouveau_texsubimage(ctx, 1, target, level, xoffset, 0, 0,
628 width, 1, 1, format, type, pixels,
629 packing, t, ti);
630 }
631
632 static void
633 nouveau_get_teximage(struct gl_context *ctx, GLenum target, GLint level,
634 GLenum format, GLenum type, GLvoid *pixels,
635 struct gl_texture_object *t,
636 struct gl_texture_image *ti)
637 {
638 nouveau_teximage_map(ctx, ti, GL_MAP_READ_BIT,
639 0, 0, ti->Width, ti->Height);
640 _mesa_get_teximage(ctx, target, level, format, type, pixels,
641 t, ti);
642 nouveau_teximage_unmap(ctx, ti);
643 }
644
645 static void
646 nouveau_bind_texture(struct gl_context *ctx, GLenum target,
647 struct gl_texture_object *t)
648 {
649 context_dirty_i(ctx, TEX_OBJ, ctx->Texture.CurrentUnit);
650 context_dirty_i(ctx, TEX_ENV, ctx->Texture.CurrentUnit);
651 }
652
653 static gl_format
654 get_texbuffer_format(struct gl_renderbuffer *rb, GLint format)
655 {
656 struct nouveau_surface *s = &to_nouveau_renderbuffer(rb)->surface;
657
658 if (s->cpp < 4)
659 return s->format;
660 else if (format == __DRI_TEXTURE_FORMAT_RGBA)
661 return MESA_FORMAT_ARGB8888;
662 else
663 return MESA_FORMAT_XRGB8888;
664 }
665
666 void
667 nouveau_set_texbuffer(__DRIcontext *dri_ctx,
668 GLint target, GLint format,
669 __DRIdrawable *draw)
670 {
671 struct nouveau_context *nctx = dri_ctx->driverPrivate;
672 struct gl_context *ctx = &nctx->base;
673 struct gl_framebuffer *fb = draw->driverPrivate;
674 struct gl_renderbuffer *rb =
675 fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer;
676 struct gl_texture_object *t = _mesa_get_current_tex_object(ctx, target);
677 struct gl_texture_image *ti;
678 struct nouveau_surface *s;
679
680 _mesa_lock_texture(ctx, t);
681 ti = _mesa_get_tex_image(ctx, t, target, 0);
682 s = &to_nouveau_teximage(ti)->surface;
683
684 /* Update the texture surface with the given drawable. */
685 nouveau_update_renderbuffers(dri_ctx, draw);
686 nouveau_surface_ref(&to_nouveau_renderbuffer(rb)->surface, s);
687
688 s->format = get_texbuffer_format(rb, format);
689
690 /* Update the image fields. */
691 _mesa_init_teximage_fields(ctx, target, ti, s->width, s->height,
692 1, 0, s->cpp, s->format);
693 ti->RowStride = s->pitch / s->cpp;
694
695 /* Try to validate it. */
696 if (!validate_teximage(ctx, t, 0, 0, 0, 0, s->width, s->height, 1))
697 nouveau_texture_reallocate(ctx, t);
698
699 context_dirty_i(ctx, TEX_OBJ, ctx->Texture.CurrentUnit);
700 context_dirty_i(ctx, TEX_ENV, ctx->Texture.CurrentUnit);
701
702 _mesa_unlock_texture(ctx, t);
703 }
704
705 static void
706 nouveau_texture_map(struct gl_context *ctx, struct gl_texture_object *t)
707 {
708 int i;
709
710 for (i = t->BaseLevel; i < t->_MaxLevel; i++) {
711 struct gl_texture_image *ti = t->Image[0][i];
712
713 if (ti)
714 nouveau_teximage_map(ctx, ti, GL_MAP_READ_BIT,
715 0, 0, ti->Width, ti->Height);
716 }
717 }
718
719 static void
720 nouveau_texture_unmap(struct gl_context *ctx, struct gl_texture_object *t)
721 {
722 int i;
723
724 for (i = t->BaseLevel; i < t->_MaxLevel; i++) {
725 if (t->Image[0][i])
726 nouveau_teximage_unmap(ctx, t->Image[0][i]);
727 }
728 }
729
730 static void
731 store_mipmap(struct gl_context *ctx, GLenum target, int first, int last,
732 struct gl_texture_object *t)
733 {
734 struct gl_pixelstore_attrib packing = {
735 .BufferObj = ctx->Shared->NullBufferObj,
736 .Alignment = 1
737 };
738 GLenum format = t->Image[0][t->BaseLevel]->TexFormat;
739 unsigned base_format, type, comps;
740 int i;
741
742 base_format = _mesa_get_format_base_format(format);
743 _mesa_format_to_type_and_comps(format, &type, &comps);
744
745 for (i = first; i <= last; i++) {
746 struct gl_texture_image *ti = t->Image[0][i];
747 void *data = ti->Data;
748
749 nouveau_teximage(ctx, 3, target, i, ti->InternalFormat,
750 ti->Width, ti->Height, ti->Depth,
751 ti->Border, base_format, type, data,
752 &packing, t, ti);
753
754 _mesa_free_texmemory(data);
755 }
756 }
757
758 static void
759 nouveau_generate_mipmap(struct gl_context *ctx, GLenum target,
760 struct gl_texture_object *t)
761 {
762 if (_mesa_meta_check_generate_mipmap_fallback(ctx, target, t)) {
763 struct gl_texture_image *base = t->Image[0][t->BaseLevel];
764
765 nouveau_teximage_map(ctx, base, GL_MAP_READ_BIT,
766 0, 0, base->Width, base->Height);
767 _mesa_generate_mipmap(ctx, target, t);
768 nouveau_teximage_unmap(ctx, base);
769
770 if (!_mesa_is_format_compressed(base->TexFormat)) {
771 store_mipmap(ctx, target, t->BaseLevel + 1,
772 get_last_level(t), t);
773 }
774
775 } else {
776 _mesa_meta_GenerateMipmap(ctx, target, t);
777 }
778 }
779
780 void
781 nouveau_texture_functions_init(struct dd_function_table *functions)
782 {
783 functions->NewTextureObject = nouveau_texture_new;
784 functions->DeleteTexture = nouveau_texture_free;
785 functions->NewTextureImage = nouveau_teximage_new;
786 functions->FreeTextureImageBuffer = nouveau_teximage_free;
787 functions->ChooseTextureFormat = nouveau_choose_tex_format;
788 functions->TexImage1D = nouveau_teximage_1d;
789 functions->TexImage2D = nouveau_teximage_2d;
790 functions->TexImage3D = nouveau_teximage_3d;
791 functions->TexSubImage1D = nouveau_texsubimage_1d;
792 functions->TexSubImage2D = nouveau_texsubimage_2d;
793 functions->TexSubImage3D = nouveau_texsubimage_3d;
794 functions->GetTexImage = nouveau_get_teximage;
795 functions->BindTexture = nouveau_bind_texture;
796 functions->MapTexture = nouveau_texture_map;
797 functions->UnmapTexture = nouveau_texture_unmap;
798 functions->MapTextureImage = nouveau_map_texture_image;
799 functions->UnmapTextureImage = nouveau_unmap_texture_image;
800 functions->GenerateMipmap = nouveau_generate_mipmap;
801 }