mesa: pass gl_format to _mesa_init_teximage_fields()
[mesa.git] / src / mesa / drivers / dri / nouveau / nouveau_texture.c
1 /*
2 * Copyright (C) 2009 Francisco Jerez.
3 * All Rights Reserved.
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining
6 * a copy of this software and associated documentation files (the
7 * "Software"), to deal in the Software without restriction, including
8 * without limitation the rights to use, copy, modify, merge, publish,
9 * distribute, sublicense, and/or sell copies of the Software, and to
10 * permit persons to whom the Software is furnished to do so, subject to
11 * the following conditions:
12 *
13 * The above copyright notice and this permission notice (including the
14 * next paragraph) shall be included in all copies or substantial
15 * portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
20 * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
21 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
22 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
23 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24 *
25 */
26
27 #include "nouveau_driver.h"
28 #include "nouveau_context.h"
29 #include "nouveau_texture.h"
30 #include "nouveau_fbo.h"
31 #include "nouveau_util.h"
32
33 #include "main/texobj.h"
34 #include "main/texstore.h"
35 #include "main/texformat.h"
36 #include "main/texcompress.h"
37 #include "main/texgetimage.h"
38 #include "main/mipmap.h"
39 #include "main/texfetch.h"
40 #include "main/teximage.h"
41 #include "drivers/common/meta.h"
42
43 static struct gl_texture_object *
44 nouveau_texture_new(struct gl_context *ctx, GLuint name, GLenum target)
45 {
46 struct nouveau_texture *nt = CALLOC_STRUCT(nouveau_texture);
47
48 _mesa_initialize_texture_object(&nt->base, name, target);
49
50 return &nt->base;
51 }
52
53 static void
54 nouveau_texture_free(struct gl_context *ctx, struct gl_texture_object *t)
55 {
56 struct nouveau_texture *nt = to_nouveau_texture(t);
57 int i;
58
59 for (i = 0; i < MAX_TEXTURE_LEVELS; i++)
60 nouveau_surface_ref(NULL, &nt->surfaces[i]);
61
62 _mesa_delete_texture_object(ctx, t);
63 }
64
65 static struct gl_texture_image *
66 nouveau_teximage_new(struct gl_context *ctx)
67 {
68 struct nouveau_teximage *nti = CALLOC_STRUCT(nouveau_teximage);
69
70 return &nti->base;
71 }
72
73 static void
74 nouveau_teximage_free(struct gl_context *ctx, struct gl_texture_image *ti)
75 {
76 struct nouveau_teximage *nti = to_nouveau_teximage(ti);
77
78 nouveau_surface_ref(NULL, &nti->surface);
79 }
80
81 static void
82 nouveau_teximage_map(struct gl_context *ctx, struct gl_texture_image *ti,
83 int access, int x, int y, int w, int h)
84 {
85 struct nouveau_teximage *nti = to_nouveau_teximage(ti);
86 struct nouveau_surface *s = &nti->surface;
87 struct nouveau_surface *st = &nti->transfer.surface;
88
89 if (s->bo) {
90 if (!(access & GL_MAP_READ_BIT) &&
91 nouveau_bo_pending(s->bo)) {
92 /*
93 * Heuristic: use a bounce buffer to pipeline
94 * teximage transfers.
95 */
96 st->layout = LINEAR;
97 st->format = s->format;
98 st->cpp = s->cpp;
99 st->width = w;
100 st->height = h;
101 st->pitch = s->pitch;
102 nti->transfer.x = x;
103 nti->transfer.y = y;
104
105 ti->Data = nouveau_get_scratch(ctx, st->pitch * h,
106 &st->bo, &st->offset);
107
108 } else {
109 int ret, flags = 0;
110
111 if (access & GL_MAP_READ_BIT)
112 flags |= NOUVEAU_BO_RD;
113 if (access & GL_MAP_WRITE_BIT)
114 flags |= NOUVEAU_BO_WR;
115
116 ret = nouveau_bo_map(s->bo, flags);
117 assert(!ret);
118
119 ti->Data = s->bo->map + y * s->pitch + x * s->cpp;
120 }
121 }
122 }
123
124 static void
125 nouveau_teximage_unmap(struct gl_context *ctx, struct gl_texture_image *ti)
126 {
127 struct nouveau_teximage *nti = to_nouveau_teximage(ti);
128 struct nouveau_surface *s = &nti->surface;
129 struct nouveau_surface *st = &nti->transfer.surface;
130
131 if (st->bo) {
132 context_drv(ctx)->surface_copy(ctx, s, st, nti->transfer.x,
133 nti->transfer.y, 0, 0,
134 st->width, st->height);
135 nouveau_surface_ref(NULL, st);
136
137 } else if (s->bo) {
138 nouveau_bo_unmap(s->bo);
139 }
140
141 ti->Data = NULL;
142 }
143
144 static gl_format
145 nouveau_choose_tex_format(struct gl_context *ctx, GLint internalFormat,
146 GLenum srcFormat, GLenum srcType)
147 {
148 switch (internalFormat) {
149 case 4:
150 case GL_RGBA:
151 case GL_RGBA2:
152 case GL_RGBA4:
153 case GL_RGBA8:
154 case GL_RGBA12:
155 case GL_RGBA16:
156 case GL_RGB10_A2:
157 case GL_COMPRESSED_RGBA:
158 return MESA_FORMAT_ARGB8888;
159 case GL_RGB5_A1:
160 return MESA_FORMAT_ARGB1555;
161
162 case GL_RGB:
163 case GL_RGB8:
164 case GL_RGB10:
165 case GL_RGB12:
166 case GL_RGB16:
167 case GL_COMPRESSED_RGB:
168 return MESA_FORMAT_XRGB8888;
169 case 3:
170 case GL_R3_G3_B2:
171 case GL_RGB4:
172 case GL_RGB5:
173 return MESA_FORMAT_RGB565;
174
175 case 2:
176 case GL_LUMINANCE_ALPHA:
177 case GL_LUMINANCE4_ALPHA4:
178 case GL_LUMINANCE6_ALPHA2:
179 case GL_LUMINANCE12_ALPHA4:
180 case GL_LUMINANCE12_ALPHA12:
181 case GL_LUMINANCE16_ALPHA16:
182 case GL_LUMINANCE8_ALPHA8:
183 case GL_COMPRESSED_LUMINANCE_ALPHA:
184 return MESA_FORMAT_ARGB8888;
185
186 case 1:
187 case GL_LUMINANCE:
188 case GL_LUMINANCE4:
189 case GL_LUMINANCE12:
190 case GL_LUMINANCE16:
191 case GL_LUMINANCE8:
192 case GL_COMPRESSED_LUMINANCE:
193 return MESA_FORMAT_L8;
194
195 case GL_ALPHA:
196 case GL_ALPHA4:
197 case GL_ALPHA12:
198 case GL_ALPHA16:
199 case GL_ALPHA8:
200 case GL_COMPRESSED_ALPHA:
201 return MESA_FORMAT_A8;
202
203 case GL_INTENSITY:
204 case GL_INTENSITY4:
205 case GL_INTENSITY12:
206 case GL_INTENSITY16:
207 case GL_INTENSITY8:
208 return MESA_FORMAT_I8;
209
210 case GL_COLOR_INDEX:
211 case GL_COLOR_INDEX1_EXT:
212 case GL_COLOR_INDEX2_EXT:
213 case GL_COLOR_INDEX4_EXT:
214 case GL_COLOR_INDEX12_EXT:
215 case GL_COLOR_INDEX16_EXT:
216 case GL_COLOR_INDEX8_EXT:
217 return MESA_FORMAT_CI8;
218
219 default:
220 assert(0);
221 }
222 }
223
224 static GLboolean
225 teximage_fits(struct gl_texture_object *t, int level)
226 {
227 struct nouveau_surface *s = &to_nouveau_texture(t)->surfaces[level];
228 struct gl_texture_image *ti = t->Image[0][level];
229
230 if (!ti || !to_nouveau_teximage(ti)->surface.bo)
231 return GL_FALSE;
232
233 if (level == t->BaseLevel && (s->offset & 0x7f))
234 return GL_FALSE;
235
236 return t->Target == GL_TEXTURE_RECTANGLE ||
237 (s->bo && s->format == ti->TexFormat &&
238 s->width == ti->Width && s->height == ti->Height);
239 }
240
241 static GLboolean
242 validate_teximage(struct gl_context *ctx, struct gl_texture_object *t,
243 int level, int x, int y, int z,
244 int width, int height, int depth)
245 {
246 struct gl_texture_image *ti = t->Image[0][level];
247
248 if (teximage_fits(t, level)) {
249 struct nouveau_surface *ss = to_nouveau_texture(t)->surfaces;
250 struct nouveau_surface *s = &to_nouveau_teximage(ti)->surface;
251
252 if (t->Target == GL_TEXTURE_RECTANGLE)
253 nouveau_surface_ref(s, &ss[level]);
254 else
255 context_drv(ctx)->surface_copy(ctx, &ss[level], s,
256 x, y, x, y,
257 width, height);
258
259 return GL_TRUE;
260 }
261
262 return GL_FALSE;
263 }
264
265 static int
266 get_last_level(struct gl_texture_object *t)
267 {
268 struct gl_texture_image *base = t->Image[0][t->BaseLevel];
269
270 if (t->MinFilter == GL_NEAREST ||
271 t->MinFilter == GL_LINEAR || !base)
272 return t->BaseLevel;
273 else
274 return MIN2(t->BaseLevel + base->MaxLog2, t->MaxLevel);
275 }
276
277 static void
278 relayout_texture(struct gl_context *ctx, struct gl_texture_object *t)
279 {
280 struct gl_texture_image *base = t->Image[0][t->BaseLevel];
281
282 if (base && t->Target != GL_TEXTURE_RECTANGLE) {
283 struct nouveau_surface *ss = to_nouveau_texture(t)->surfaces;
284 struct nouveau_surface *s = &to_nouveau_teximage(base)->surface;
285 int i, ret, last = get_last_level(t);
286 unsigned size, offset = 0,
287 width = s->width,
288 height = s->height;
289
290 /* Deallocate the old storage. */
291 for (i = 0; i < MAX_TEXTURE_LEVELS; i++)
292 nouveau_bo_ref(NULL, &ss[i].bo);
293
294 /* Relayout the mipmap tree. */
295 for (i = t->BaseLevel; i <= last; i++) {
296 size = width * height * s->cpp;
297
298 /* Images larger than 16B have to be aligned. */
299 if (size > 16)
300 offset = align(offset, 64);
301
302 ss[i] = (struct nouveau_surface) {
303 .offset = offset,
304 .layout = SWIZZLED,
305 .format = s->format,
306 .width = width,
307 .height = height,
308 .cpp = s->cpp,
309 .pitch = width * s->cpp,
310 };
311
312 offset += size;
313 width = MAX2(1, width / 2);
314 height = MAX2(1, height / 2);
315 }
316
317 /* Get new storage. */
318 size = align(offset, 64);
319
320 ret = nouveau_bo_new(context_dev(ctx), NOUVEAU_BO_MAP |
321 NOUVEAU_BO_GART | NOUVEAU_BO_VRAM,
322 0, size, &ss[last].bo);
323 assert(!ret);
324
325 for (i = t->BaseLevel; i < last; i++)
326 nouveau_bo_ref(ss[last].bo, &ss[i].bo);
327 }
328 }
329
330 GLboolean
331 nouveau_texture_validate(struct gl_context *ctx, struct gl_texture_object *t)
332 {
333 struct nouveau_texture *nt = to_nouveau_texture(t);
334 int i, last = get_last_level(t);
335
336 if (!teximage_fits(t, t->BaseLevel) ||
337 !teximage_fits(t, last))
338 return GL_FALSE;
339
340 if (nt->dirty) {
341 nt->dirty = GL_FALSE;
342
343 /* Copy the teximages to the actual miptree. */
344 for (i = t->BaseLevel; i <= last; i++) {
345 struct nouveau_surface *s = &nt->surfaces[i];
346
347 validate_teximage(ctx, t, i, 0, 0, 0,
348 s->width, s->height, 1);
349 }
350
351 FIRE_RING(context_chan(ctx));
352 }
353
354 return GL_TRUE;
355 }
356
357 void
358 nouveau_texture_reallocate(struct gl_context *ctx, struct gl_texture_object *t)
359 {
360 if (!teximage_fits(t, t->BaseLevel) ||
361 !teximage_fits(t, get_last_level(t))) {
362 texture_dirty(t);
363 relayout_texture(ctx, t);
364 nouveau_texture_validate(ctx, t);
365 }
366 }
367
368 static unsigned
369 get_teximage_placement(struct gl_texture_image *ti)
370 {
371 if (ti->TexFormat == MESA_FORMAT_A8 ||
372 ti->TexFormat == MESA_FORMAT_L8 ||
373 ti->TexFormat == MESA_FORMAT_I8)
374 /* 1 cpp formats will have to be swizzled by the CPU,
375 * so leave them in system RAM for now. */
376 return NOUVEAU_BO_MAP;
377 else
378 return NOUVEAU_BO_GART | NOUVEAU_BO_MAP;
379 }
380
381 static void
382 nouveau_teximage(struct gl_context *ctx, GLint dims, GLenum target, GLint level,
383 GLint internalFormat,
384 GLint width, GLint height, GLint depth, GLint border,
385 GLenum format, GLenum type, const GLvoid *pixels,
386 const struct gl_pixelstore_attrib *packing,
387 struct gl_texture_object *t,
388 struct gl_texture_image *ti)
389 {
390 struct nouveau_surface *s = &to_nouveau_teximage(ti)->surface;
391 int ret;
392
393 /* Allocate a new bo for the image. */
394 nouveau_surface_alloc(ctx, s, LINEAR, get_teximage_placement(ti),
395 ti->TexFormat, width, height);
396 ti->RowStride = s->pitch / s->cpp;
397
398 pixels = _mesa_validate_pbo_teximage(ctx, dims, width, height, depth,
399 format, type, pixels, packing,
400 "glTexImage");
401 if (pixels) {
402 /* Store the pixel data. */
403 nouveau_teximage_map(ctx, ti, GL_MAP_WRITE_BIT,
404 0, 0, width, height);
405
406 ret = _mesa_texstore(ctx, dims, ti->_BaseFormat,
407 ti->TexFormat, ti->Data,
408 0, 0, 0, s->pitch,
409 ti->ImageOffsets,
410 width, height, depth,
411 format, type, pixels, packing);
412 assert(ret);
413
414 nouveau_teximage_unmap(ctx, ti);
415 _mesa_unmap_teximage_pbo(ctx, packing);
416
417 if (!validate_teximage(ctx, t, level, 0, 0, 0,
418 width, height, depth))
419 /* It doesn't fit, mark it as dirty. */
420 texture_dirty(t);
421 }
422
423 if (level == t->BaseLevel) {
424 if (!teximage_fits(t, level))
425 relayout_texture(ctx, t);
426 nouveau_texture_validate(ctx, t);
427 }
428
429 context_dirty_i(ctx, TEX_OBJ, ctx->Texture.CurrentUnit);
430 context_dirty_i(ctx, TEX_ENV, ctx->Texture.CurrentUnit);
431 }
432
433 static void
434 nouveau_teximage_1d(struct gl_context *ctx, GLenum target, GLint level,
435 GLint internalFormat,
436 GLint width, GLint border,
437 GLenum format, GLenum type, const GLvoid *pixels,
438 const struct gl_pixelstore_attrib *packing,
439 struct gl_texture_object *t,
440 struct gl_texture_image *ti)
441 {
442 nouveau_teximage(ctx, 1, target, level, internalFormat,
443 width, 1, 1, border, format, type, pixels,
444 packing, t, ti);
445 }
446
447 static void
448 nouveau_teximage_2d(struct gl_context *ctx, GLenum target, GLint level,
449 GLint internalFormat,
450 GLint width, GLint height, GLint border,
451 GLenum format, GLenum type, const GLvoid *pixels,
452 const struct gl_pixelstore_attrib *packing,
453 struct gl_texture_object *t,
454 struct gl_texture_image *ti)
455 {
456 nouveau_teximage(ctx, 2, target, level, internalFormat,
457 width, height, 1, border, format, type, pixels,
458 packing, t, ti);
459 }
460
461 static void
462 nouveau_teximage_3d(struct gl_context *ctx, GLenum target, GLint level,
463 GLint internalFormat,
464 GLint width, GLint height, GLint depth, GLint border,
465 GLenum format, GLenum type, const GLvoid *pixels,
466 const struct gl_pixelstore_attrib *packing,
467 struct gl_texture_object *t,
468 struct gl_texture_image *ti)
469 {
470 nouveau_teximage(ctx, 3, target, level, internalFormat,
471 width, height, depth, border, format, type, pixels,
472 packing, t, ti);
473 }
474
475 static void
476 nouveau_texsubimage(struct gl_context *ctx, GLint dims, GLenum target, GLint level,
477 GLint xoffset, GLint yoffset, GLint zoffset,
478 GLint width, GLint height, GLint depth,
479 GLenum format, GLenum type, const void *pixels,
480 const struct gl_pixelstore_attrib *packing,
481 struct gl_texture_object *t,
482 struct gl_texture_image *ti)
483 {
484 struct nouveau_surface *s = &to_nouveau_teximage(ti)->surface;
485 int ret;
486
487 pixels = _mesa_validate_pbo_teximage(ctx, dims, width, height, depth,
488 format, type, pixels, packing,
489 "glTexSubImage");
490 if (pixels) {
491 nouveau_teximage_map(ctx, ti, GL_MAP_WRITE_BIT,
492 xoffset, yoffset, width, height);
493
494 ret = _mesa_texstore(ctx, 3, ti->_BaseFormat, ti->TexFormat,
495 ti->Data, 0, 0, 0, s->pitch,
496 ti->ImageOffsets, width, height, depth,
497 format, type, pixels, packing);
498 assert(ret);
499
500 nouveau_teximage_unmap(ctx, ti);
501 _mesa_unmap_teximage_pbo(ctx, packing);
502 }
503
504 if (!to_nouveau_texture(t)->dirty)
505 validate_teximage(ctx, t, level, xoffset, yoffset, zoffset,
506 width, height, depth);
507 }
508
509 static void
510 nouveau_texsubimage_3d(struct gl_context *ctx, GLenum target, GLint level,
511 GLint xoffset, GLint yoffset, GLint zoffset,
512 GLint width, GLint height, GLint depth,
513 GLenum format, GLenum type, const void *pixels,
514 const struct gl_pixelstore_attrib *packing,
515 struct gl_texture_object *t,
516 struct gl_texture_image *ti)
517 {
518 nouveau_texsubimage(ctx, 3, target, level, xoffset, yoffset, zoffset,
519 width, height, depth, format, type, pixels,
520 packing, t, ti);
521 }
522
523 static void
524 nouveau_texsubimage_2d(struct gl_context *ctx, GLenum target, GLint level,
525 GLint xoffset, GLint yoffset,
526 GLint width, GLint height,
527 GLenum format, GLenum type, const void *pixels,
528 const struct gl_pixelstore_attrib *packing,
529 struct gl_texture_object *t,
530 struct gl_texture_image *ti)
531 {
532 nouveau_texsubimage(ctx, 2, target, level, xoffset, yoffset, 0,
533 width, height, 1, format, type, pixels,
534 packing, t, ti);
535 }
536
537 static void
538 nouveau_texsubimage_1d(struct gl_context *ctx, GLenum target, GLint level,
539 GLint xoffset, GLint width,
540 GLenum format, GLenum type, const void *pixels,
541 const struct gl_pixelstore_attrib *packing,
542 struct gl_texture_object *t,
543 struct gl_texture_image *ti)
544 {
545 nouveau_texsubimage(ctx, 1, target, level, xoffset, 0, 0,
546 width, 1, 1, format, type, pixels,
547 packing, t, ti);
548 }
549
550 static void
551 nouveau_get_teximage(struct gl_context *ctx, GLenum target, GLint level,
552 GLenum format, GLenum type, GLvoid *pixels,
553 struct gl_texture_object *t,
554 struct gl_texture_image *ti)
555 {
556 nouveau_teximage_map(ctx, ti, GL_MAP_READ_BIT,
557 0, 0, ti->Width, ti->Height);
558 _mesa_get_teximage(ctx, target, level, format, type, pixels,
559 t, ti);
560 nouveau_teximage_unmap(ctx, ti);
561 }
562
563 static void
564 nouveau_bind_texture(struct gl_context *ctx, GLenum target,
565 struct gl_texture_object *t)
566 {
567 context_dirty_i(ctx, TEX_OBJ, ctx->Texture.CurrentUnit);
568 context_dirty_i(ctx, TEX_ENV, ctx->Texture.CurrentUnit);
569 }
570
571 static gl_format
572 get_texbuffer_format(struct gl_renderbuffer *rb, GLint format)
573 {
574 struct nouveau_surface *s = &to_nouveau_renderbuffer(rb)->surface;
575
576 if (s->cpp < 4)
577 return s->format;
578 else if (format == __DRI_TEXTURE_FORMAT_RGBA)
579 return MESA_FORMAT_ARGB8888;
580 else
581 return MESA_FORMAT_XRGB8888;
582 }
583
584 void
585 nouveau_set_texbuffer(__DRIcontext *dri_ctx,
586 GLint target, GLint format,
587 __DRIdrawable *draw)
588 {
589 struct nouveau_context *nctx = dri_ctx->driverPrivate;
590 struct gl_context *ctx = &nctx->base;
591 struct gl_framebuffer *fb = draw->driverPrivate;
592 struct gl_renderbuffer *rb =
593 fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer;
594 struct gl_texture_object *t = _mesa_get_current_tex_object(ctx, target);
595 struct gl_texture_image *ti;
596 struct nouveau_surface *s;
597
598 _mesa_lock_texture(ctx, t);
599 ti = _mesa_get_tex_image(ctx, t, target, 0);
600 s = &to_nouveau_teximage(ti)->surface;
601
602 /* Update the texture surface with the given drawable. */
603 nouveau_update_renderbuffers(dri_ctx, draw);
604 nouveau_surface_ref(&to_nouveau_renderbuffer(rb)->surface, s);
605
606 s->format = get_texbuffer_format(rb, format);
607
608 /* Update the image fields. */
609 _mesa_init_teximage_fields(ctx, target, ti, s->width, s->height,
610 1, 0, s->cpp, s->format);
611 ti->RowStride = s->pitch / s->cpp;
612
613 /* Try to validate it. */
614 if (!validate_teximage(ctx, t, 0, 0, 0, 0, s->width, s->height, 1))
615 nouveau_texture_reallocate(ctx, t);
616
617 context_dirty_i(ctx, TEX_OBJ, ctx->Texture.CurrentUnit);
618 context_dirty_i(ctx, TEX_ENV, ctx->Texture.CurrentUnit);
619
620 _mesa_unlock_texture(ctx, t);
621 }
622
623 static void
624 nouveau_texture_map(struct gl_context *ctx, struct gl_texture_object *t)
625 {
626 int i;
627
628 for (i = t->BaseLevel; i < t->_MaxLevel; i++) {
629 struct gl_texture_image *ti = t->Image[0][i];
630
631 if (ti)
632 nouveau_teximage_map(ctx, ti, GL_MAP_READ_BIT,
633 0, 0, ti->Width, ti->Height);
634 }
635 }
636
637 static void
638 nouveau_texture_unmap(struct gl_context *ctx, struct gl_texture_object *t)
639 {
640 int i;
641
642 for (i = t->BaseLevel; i < t->_MaxLevel; i++) {
643 if (t->Image[0][i])
644 nouveau_teximage_unmap(ctx, t->Image[0][i]);
645 }
646 }
647
648 static void
649 store_mipmap(struct gl_context *ctx, GLenum target, int first, int last,
650 struct gl_texture_object *t)
651 {
652 struct gl_pixelstore_attrib packing = {
653 .BufferObj = ctx->Shared->NullBufferObj,
654 .Alignment = 1
655 };
656 GLenum format = t->Image[0][t->BaseLevel]->TexFormat;
657 unsigned base_format, type, comps;
658 int i;
659
660 base_format = _mesa_get_format_base_format(format);
661 _mesa_format_to_type_and_comps(format, &type, &comps);
662
663 for (i = first; i <= last; i++) {
664 struct gl_texture_image *ti = t->Image[0][i];
665 void *data = ti->Data;
666
667 nouveau_teximage(ctx, 3, target, i, ti->InternalFormat,
668 ti->Width, ti->Height, ti->Depth,
669 ti->Border, base_format, type, data,
670 &packing, t, ti);
671
672 _mesa_free_texmemory(data);
673 }
674 }
675
676 static void
677 nouveau_generate_mipmap(struct gl_context *ctx, GLenum target,
678 struct gl_texture_object *t)
679 {
680 if (_mesa_meta_check_generate_mipmap_fallback(ctx, target, t)) {
681 struct gl_texture_image *base = t->Image[0][t->BaseLevel];
682
683 nouveau_teximage_map(ctx, base, GL_MAP_READ_BIT,
684 0, 0, base->Width, base->Height);
685 _mesa_generate_mipmap(ctx, target, t);
686 nouveau_teximage_unmap(ctx, base);
687
688 store_mipmap(ctx, target, t->BaseLevel + 1,
689 get_last_level(t), t);
690
691 } else {
692 _mesa_meta_GenerateMipmap(ctx, target, t);
693 }
694 }
695
696 void
697 nouveau_texture_functions_init(struct dd_function_table *functions)
698 {
699 functions->NewTextureObject = nouveau_texture_new;
700 functions->DeleteTexture = nouveau_texture_free;
701 functions->NewTextureImage = nouveau_teximage_new;
702 functions->FreeTexImageData = nouveau_teximage_free;
703 functions->ChooseTextureFormat = nouveau_choose_tex_format;
704 functions->TexImage1D = nouveau_teximage_1d;
705 functions->TexImage2D = nouveau_teximage_2d;
706 functions->TexImage3D = nouveau_teximage_3d;
707 functions->TexSubImage1D = nouveau_texsubimage_1d;
708 functions->TexSubImage2D = nouveau_texsubimage_2d;
709 functions->TexSubImage3D = nouveau_texsubimage_3d;
710 functions->GetTexImage = nouveau_get_teximage;
711 functions->BindTexture = nouveau_bind_texture;
712 functions->MapTexture = nouveau_texture_map;
713 functions->UnmapTexture = nouveau_texture_unmap;
714 functions->GenerateMipmap = nouveau_generate_mipmap;
715 }