14b78d1253944e8140b892a5fd2a7a5441f5bb3b
[mesa.git] / src / mesa / state_tracker / st_cb_texture.c
1 /**************************************************************************
2 *
3 * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
4 * All Rights Reserved.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the
8 * "Software"), to deal in the Software without restriction, including
9 * without limitation the rights to use, copy, modify, merge, publish,
10 * distribute, sub license, and/or sell copies of the Software, and to
11 * permit persons to whom the Software is furnished to do so, subject to
12 * the following conditions:
13 *
14 * The above copyright notice and this permission notice (including the
15 * next paragraph) shall be included in all copies or substantial portions
16 * of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21 * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
22 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 *
26 **************************************************************************/
27
28 #include "main/mfeatures.h"
29 #include "main/bufferobj.h"
30 #if FEATURE_convolve
31 #include "main/convolve.h"
32 #endif
33 #include "main/enums.h"
34 #include "main/image.h"
35 #include "main/imports.h"
36 #include "main/macros.h"
37 #include "main/mipmap.h"
38 #include "main/pixel.h"
39 #include "main/texcompress.h"
40 #include "main/texformat.h"
41 #include "main/texgetimage.h"
42 #include "main/teximage.h"
43 #include "main/texobj.h"
44 #include "main/texstore.h"
45
46 #include "state_tracker/st_context.h"
47 #include "state_tracker/st_cb_fbo.h"
48 #include "state_tracker/st_cb_texture.h"
49 #include "state_tracker/st_format.h"
50 #include "state_tracker/st_public.h"
51 #include "state_tracker/st_texture.h"
52 #include "state_tracker/st_gen_mipmap.h"
53 #include "state_tracker/st_inlines.h"
54 #include "state_tracker/st_atom.h"
55
56 #include "pipe/p_context.h"
57 #include "pipe/p_defines.h"
58 #include "pipe/p_inlines.h"
59 #include "util/u_tile.h"
60 #include "util/u_blit.h"
61 #include "util/u_surface.h"
62
63
64 #define DBG if (0) printf
65
66
67 static enum pipe_texture_target
68 gl_target_to_pipe(GLenum target)
69 {
70 switch (target) {
71 case GL_TEXTURE_1D:
72 return PIPE_TEXTURE_1D;
73
74 case GL_TEXTURE_2D:
75 case GL_TEXTURE_RECTANGLE_NV:
76 return PIPE_TEXTURE_2D;
77
78 case GL_TEXTURE_3D:
79 return PIPE_TEXTURE_3D;
80
81 case GL_TEXTURE_CUBE_MAP_ARB:
82 return PIPE_TEXTURE_CUBE;
83
84 default:
85 assert(0);
86 return 0;
87 }
88 }
89
90
91 /**
92 * Return nominal bytes per texel for a compressed format, 0 for non-compressed
93 * format.
94 */
95 static GLuint
96 compressed_num_bytes(GLuint mesaFormat)
97 {
98 switch(mesaFormat) {
99 #if FEATURE_texture_fxt1
100 case MESA_FORMAT_RGB_FXT1:
101 case MESA_FORMAT_RGBA_FXT1:
102 #endif
103 #if FEATURE_texture_s3tc
104 case MESA_FORMAT_RGB_DXT1:
105 case MESA_FORMAT_RGBA_DXT1:
106 return 2;
107 case MESA_FORMAT_RGBA_DXT3:
108 case MESA_FORMAT_RGBA_DXT5:
109 return 4;
110 #endif
111 default:
112 return 0;
113 }
114 }
115
116
117 static GLboolean
118 is_compressed_mesa_format(const struct gl_texture_format *format)
119 {
120 switch (format->MesaFormat) {
121 case MESA_FORMAT_RGB_DXT1:
122 case MESA_FORMAT_RGBA_DXT1:
123 case MESA_FORMAT_RGBA_DXT3:
124 case MESA_FORMAT_RGBA_DXT5:
125 case MESA_FORMAT_SRGB_DXT1:
126 case MESA_FORMAT_SRGBA_DXT1:
127 case MESA_FORMAT_SRGBA_DXT3:
128 case MESA_FORMAT_SRGBA_DXT5:
129 return GL_TRUE;
130 default:
131 return GL_FALSE;
132 }
133 }
134
135
136 /** called via ctx->Driver.NewTextureImage() */
137 static struct gl_texture_image *
138 st_NewTextureImage(GLcontext * ctx)
139 {
140 DBG("%s\n", __FUNCTION__);
141 (void) ctx;
142 return (struct gl_texture_image *) ST_CALLOC_STRUCT(st_texture_image);
143 }
144
145
146 /** called via ctx->Driver.NewTextureObject() */
147 static struct gl_texture_object *
148 st_NewTextureObject(GLcontext * ctx, GLuint name, GLenum target)
149 {
150 struct st_texture_object *obj = ST_CALLOC_STRUCT(st_texture_object);
151
152 DBG("%s\n", __FUNCTION__);
153 _mesa_initialize_texture_object(&obj->base, name, target);
154
155 return &obj->base;
156 }
157
158 /** called via ctx->Driver.DeleteTextureImage() */
159 static void
160 st_DeleteTextureObject(GLcontext *ctx,
161 struct gl_texture_object *texObj)
162 {
163 struct st_texture_object *stObj = st_texture_object(texObj);
164 if (stObj->pt)
165 pipe_texture_reference(&stObj->pt, NULL);
166
167 _mesa_delete_texture_object(ctx, texObj);
168 }
169
170
171 /** called via ctx->Driver.FreeTexImageData() */
172 static void
173 st_FreeTextureImageData(GLcontext * ctx, struct gl_texture_image *texImage)
174 {
175 struct st_texture_image *stImage = st_texture_image(texImage);
176
177 DBG("%s\n", __FUNCTION__);
178
179 if (stImage->pt) {
180 pipe_texture_reference(&stImage->pt, NULL);
181 }
182
183 if (texImage->Data) {
184 _mesa_align_free(texImage->Data);
185 texImage->Data = NULL;
186 }
187 }
188
189
190 /**
191 * From linux kernel i386 header files, copes with odd sizes better
192 * than COPY_DWORDS would:
193 * XXX Put this in src/mesa/main/imports.h ???
194 */
195 #if defined(PIPE_CC_GCC) && defined(PIPE_ARCH_X86)
196 static INLINE void *
197 __memcpy(void *to, const void *from, size_t n)
198 {
199 int d0, d1, d2;
200 __asm__ __volatile__("rep ; movsl\n\t"
201 "testb $2,%b4\n\t"
202 "je 1f\n\t"
203 "movsw\n"
204 "1:\ttestb $1,%b4\n\t"
205 "je 2f\n\t"
206 "movsb\n" "2:":"=&c"(d0), "=&D"(d1), "=&S"(d2)
207 :"0"(n / 4), "q"(n), "1"((long) to), "2"((long) from)
208 :"memory");
209 return (to);
210 }
211 #else
212 #define __memcpy(a,b,c) memcpy(a,b,c)
213 #endif
214
215
216 /**
217 * The system memcpy (at least on ubuntu 5.10) has problems copying
218 * to agp (writecombined) memory from a source which isn't 64-byte
219 * aligned - there is a 4x performance falloff.
220 *
221 * The x86 __memcpy is immune to this but is slightly slower
222 * (10%-ish) than the system memcpy.
223 *
224 * The sse_memcpy seems to have a slight cliff at 64/32 bytes, but
225 * isn't much faster than x86_memcpy for agp copies.
226 *
227 * TODO: switch dynamically.
228 */
229 static void *
230 do_memcpy(void *dest, const void *src, size_t n)
231 {
232 if ((((unsigned long) src) & 63) || (((unsigned long) dest) & 63)) {
233 return __memcpy(dest, src, n);
234 }
235 else
236 return memcpy(dest, src, n);
237 }
238
239
240 static int
241 logbase2(int n)
242 {
243 GLint i = 1, log2 = 0;
244 while (n > i) {
245 i *= 2;
246 log2++;
247 }
248 return log2;
249 }
250
251
252 /**
253 * Return default texture usage bitmask for the given texture format.
254 */
255 static GLuint
256 default_usage(enum pipe_format fmt)
257 {
258 GLuint usage = PIPE_TEXTURE_USAGE_SAMPLER;
259 if (pf_is_depth_stencil(fmt))
260 usage |= PIPE_TEXTURE_USAGE_DEPTH_STENCIL;
261 else
262 usage |= PIPE_TEXTURE_USAGE_RENDER_TARGET;
263 return usage;
264 }
265
266
267 /**
268 * Allocate a pipe_texture object for the given st_texture_object using
269 * the given st_texture_image to guess the mipmap size/levels.
270 *
271 * [comments...]
272 * Otherwise, store it in memory if (Border != 0) or (any dimension ==
273 * 1).
274 *
275 * Otherwise, if max_level >= level >= min_level, create texture with
276 * space for images from min_level down to max_level.
277 *
278 * Otherwise, create texture with space for images from (level 0)..(1x1).
279 * Consider pruning this texture at a validation if the saving is worth it.
280 */
281 static void
282 guess_and_alloc_texture(struct st_context *st,
283 struct st_texture_object *stObj,
284 const struct st_texture_image *stImage)
285 {
286 GLuint firstLevel;
287 GLuint lastLevel;
288 GLuint width = stImage->base.Width2; /* size w/out border */
289 GLuint height = stImage->base.Height2;
290 GLuint depth = stImage->base.Depth2;
291 GLuint i, usage;
292 enum pipe_format fmt;
293
294 DBG("%s\n", __FUNCTION__);
295
296 assert(!stObj->pt);
297
298 if (stObj->pt &&
299 (GLint) stImage->level > stObj->base.BaseLevel &&
300 (stImage->base.Width == 1 ||
301 (stObj->base.Target != GL_TEXTURE_1D &&
302 stImage->base.Height == 1) ||
303 (stObj->base.Target == GL_TEXTURE_3D &&
304 stImage->base.Depth == 1)))
305 return;
306
307 /* If this image disrespects BaseLevel, allocate from level zero.
308 * Usually BaseLevel == 0, so it's unlikely to happen.
309 */
310 if ((GLint) stImage->level < stObj->base.BaseLevel)
311 firstLevel = 0;
312 else
313 firstLevel = stObj->base.BaseLevel;
314
315
316 /* Figure out image dimensions at start level.
317 */
318 for (i = stImage->level; i > firstLevel; i--) {
319 if (width != 1)
320 width <<= 1;
321 if (height != 1)
322 height <<= 1;
323 if (depth != 1)
324 depth <<= 1;
325 }
326
327 if (width == 0 || height == 0 || depth == 0) {
328 /* no texture needed */
329 return;
330 }
331
332 /* Guess a reasonable value for lastLevel. This is probably going
333 * to be wrong fairly often and might mean that we have to look at
334 * resizable buffers, or require that buffers implement lazy
335 * pagetable arrangements.
336 */
337 if ((stObj->base.MinFilter == GL_NEAREST ||
338 stObj->base.MinFilter == GL_LINEAR) &&
339 stImage->level == firstLevel) {
340 lastLevel = firstLevel;
341 }
342 else {
343 GLuint l2width = logbase2(width);
344 GLuint l2height = logbase2(height);
345 GLuint l2depth = logbase2(depth);
346 lastLevel = firstLevel + MAX2(MAX2(l2width, l2height), l2depth);
347 }
348
349 fmt = st_mesa_format_to_pipe_format(stImage->base.TexFormat->MesaFormat);
350
351 usage = default_usage(fmt);
352
353 stObj->pt = st_texture_create(st,
354 gl_target_to_pipe(stObj->base.Target),
355 fmt,
356 lastLevel,
357 width,
358 height,
359 depth,
360 usage);
361
362 DBG("%s - success\n", __FUNCTION__);
363 }
364
365
366 /**
367 * Adjust pixel unpack params and image dimensions to strip off the
368 * texture border.
369 * Gallium doesn't support texture borders. They've seldem been used
370 * and seldom been implemented correctly anyway.
371 * \param unpackNew returns the new pixel unpack parameters
372 */
373 static void
374 strip_texture_border(GLint border,
375 GLint *width, GLint *height, GLint *depth,
376 const struct gl_pixelstore_attrib *unpack,
377 struct gl_pixelstore_attrib *unpackNew)
378 {
379 assert(border > 0); /* sanity check */
380
381 *unpackNew = *unpack;
382
383 if (unpackNew->RowLength == 0)
384 unpackNew->RowLength = *width;
385
386 if (depth && unpackNew->ImageHeight == 0)
387 unpackNew->ImageHeight = *height;
388
389 unpackNew->SkipPixels += border;
390 if (height)
391 unpackNew->SkipRows += border;
392 if (depth)
393 unpackNew->SkipImages += border;
394
395 assert(*width >= 3);
396 *width = *width - 2 * border;
397 if (height && *height >= 3)
398 *height = *height - 2 * border;
399 if (depth && *depth >= 3)
400 *depth = *depth - 2 * border;
401 }
402
403
404 /**
405 * Try to do texture compression via rendering. If the Gallium driver
406 * can render into a compressed surface this will allow us to do texture
407 * compression.
408 * \return GL_TRUE for success, GL_FALSE for failure
409 */
410 static GLboolean
411 compress_with_blit(GLcontext * ctx,
412 GLenum target, GLint level,
413 GLint xoffset, GLint yoffset, GLint zoffset,
414 GLint width, GLint height, GLint depth,
415 GLenum format, GLenum type, const void *pixels,
416 const struct gl_pixelstore_attrib *unpack,
417 struct gl_texture_image *texImage)
418 {
419 const GLuint dstImageOffsets[1] = {0};
420 struct st_texture_image *stImage = st_texture_image(texImage);
421 struct pipe_screen *screen = ctx->st->pipe->screen;
422 const struct gl_texture_format *mesa_format;
423 struct pipe_texture templ;
424 struct pipe_texture *src_tex;
425 struct pipe_surface *dst_surface;
426 struct pipe_transfer *tex_xfer;
427 void *map;
428
429
430 if (!stImage->pt) {
431 /* XXX: Can this happen? Should we assert? */
432 return GL_FALSE;
433 }
434
435 /* get destination surface (in the compressed texture) */
436 dst_surface = screen->get_tex_surface(screen, stImage->pt,
437 stImage->face, stImage->level, 0,
438 PIPE_BUFFER_USAGE_GPU_WRITE);
439 if (!dst_surface) {
440 /* can't render into this format (or other problem) */
441 return GL_FALSE;
442 }
443
444 /* Choose format for the temporary RGBA texture image.
445 */
446 mesa_format = st_ChooseTextureFormat(ctx, GL_RGBA, format, type);
447 assert(mesa_format);
448 if (!mesa_format)
449 return GL_FALSE;
450
451 /* Create the temporary source texture
452 */
453 memset(&templ, 0, sizeof(templ));
454 templ.target = PIPE_TEXTURE_2D;
455 templ.format = st_mesa_format_to_pipe_format(mesa_format->MesaFormat);
456 pf_get_block(templ.format, &templ.block);
457 templ.width[0] = width;
458 templ.height[0] = height;
459 templ.depth[0] = 1;
460 templ.last_level = 0;
461 templ.tex_usage = PIPE_TEXTURE_USAGE_SAMPLER;
462 src_tex = screen->texture_create(screen, &templ);
463
464 if (!src_tex)
465 return GL_FALSE;
466
467 /* Put user's tex data into the temporary texture
468 */
469 tex_xfer = st_cond_flush_get_tex_transfer(st_context(ctx), src_tex,
470 0, 0, 0, /* face, level are zero */
471 PIPE_TRANSFER_WRITE,
472 0, 0, width, height); /* x, y, w, h */
473 map = screen->transfer_map(screen, tex_xfer);
474
475 mesa_format->StoreImage(ctx, 2, GL_RGBA, mesa_format,
476 map, /* dest ptr */
477 0, 0, 0, /* dest x/y/z offset */
478 tex_xfer->stride, /* dest row stride (bytes) */
479 dstImageOffsets, /* image offsets (for 3D only) */
480 width, height, 1, /* size */
481 format, type, /* source format/type */
482 pixels, /* source data */
483 unpack); /* source data packing */
484
485 screen->transfer_unmap(screen, tex_xfer);
486 screen->tex_transfer_destroy(tex_xfer);
487
488 /* copy / compress image */
489 util_blit_pixels_tex(ctx->st->blit,
490 src_tex, /* pipe_texture (src) */
491 0, 0, /* src x0, y0 */
492 width, height, /* src x1, y1 */
493 dst_surface, /* pipe_surface (dst) */
494 xoffset, yoffset, /* dst x0, y0 */
495 xoffset + width, /* dst x1 */
496 yoffset + height, /* dst y1 */
497 0.0, /* z */
498 PIPE_TEX_MIPFILTER_NEAREST);
499
500 pipe_surface_reference(&dst_surface, NULL);
501 pipe_texture_reference(&src_tex, NULL);
502
503 return GL_TRUE;
504 }
505
506
507 /**
508 * Do glTexImage1/2/3D().
509 */
510 static void
511 st_TexImage(GLcontext * ctx,
512 GLint dims,
513 GLenum target, GLint level,
514 GLint internalFormat,
515 GLint width, GLint height, GLint depth,
516 GLint border,
517 GLenum format, GLenum type, const void *pixels,
518 const struct gl_pixelstore_attrib *unpack,
519 struct gl_texture_object *texObj,
520 struct gl_texture_image *texImage,
521 GLsizei imageSize, GLboolean compressed_src)
522 {
523 struct pipe_screen *screen = ctx->st->pipe->screen;
524 struct st_texture_object *stObj = st_texture_object(texObj);
525 struct st_texture_image *stImage = st_texture_image(texImage);
526 GLint postConvWidth, postConvHeight;
527 GLint texelBytes, sizeInBytes;
528 GLuint dstRowStride;
529 struct gl_pixelstore_attrib unpackNB;
530
531 DBG("%s target %s level %d %dx%dx%d border %d\n", __FUNCTION__,
532 _mesa_lookup_enum_by_nr(target), level, width, height, depth, border);
533
534 /* gallium does not support texture borders, strip it off */
535 if (border) {
536 strip_texture_border(border, &width, &height, &depth, unpack, &unpackNB);
537 unpack = &unpackNB;
538 texImage->Width = width;
539 texImage->Height = height;
540 texImage->Depth = depth;
541 texImage->Border = 0;
542 border = 0;
543 }
544
545 postConvWidth = width;
546 postConvHeight = height;
547
548 stImage->face = _mesa_tex_target_to_face(target);
549 stImage->level = level;
550
551 #if FEATURE_convolve
552 if (ctx->_ImageTransferState & IMAGE_CONVOLUTION_BIT) {
553 _mesa_adjust_image_for_convolution(ctx, dims, &postConvWidth,
554 &postConvHeight);
555 }
556 #endif
557
558 /* choose the texture format */
559 texImage->TexFormat = st_ChooseTextureFormat(ctx, internalFormat,
560 format, type);
561
562 _mesa_set_fetch_functions(texImage, dims);
563
564 if (texImage->TexFormat->TexelBytes == 0) {
565 /* must be a compressed format */
566 texelBytes = 0;
567 texImage->IsCompressed = GL_TRUE;
568 texImage->CompressedSize =
569 ctx->Driver.CompressedTextureSize(ctx, texImage->Width,
570 texImage->Height, texImage->Depth,
571 texImage->TexFormat->MesaFormat);
572 }
573 else {
574 texelBytes = texImage->TexFormat->TexelBytes;
575
576 /* Minimum pitch of 32 bytes */
577 if (postConvWidth * texelBytes < 32) {
578 postConvWidth = 32 / texelBytes;
579 texImage->RowStride = postConvWidth;
580 }
581
582 /* we'll set RowStride elsewhere when the texture is a "mapped" state */
583 /*assert(texImage->RowStride == postConvWidth);*/
584 }
585
586 /* Release the reference to a potentially orphaned buffer.
587 * Release any old malloced memory.
588 */
589 if (stImage->pt) {
590 pipe_texture_reference(&stImage->pt, NULL);
591 assert(!texImage->Data);
592 }
593 else if (texImage->Data) {
594 _mesa_align_free(texImage->Data);
595 }
596
597 if (width == 0 || height == 0 || depth == 0) {
598 /* stop after freeing old image */
599 return;
600 }
601
602 /* If this is the only mipmap level in the texture, could call
603 * bmBufferData with NULL data to free the old block and avoid
604 * waiting on any outstanding fences.
605 */
606 if (stObj->pt) {
607 if (stObj->teximage_realloc ||
608 level > (GLint) stObj->pt->last_level ||
609 (stObj->pt->last_level == level &&
610 stObj->pt->target != PIPE_TEXTURE_CUBE &&
611 !st_texture_match_image(stObj->pt, &stImage->base,
612 stImage->face, stImage->level))) {
613 DBG("release it\n");
614 pipe_texture_reference(&stObj->pt, NULL);
615 assert(!stObj->pt);
616 stObj->teximage_realloc = FALSE;
617 }
618 }
619
620 if (!stObj->pt) {
621 guess_and_alloc_texture(ctx->st, stObj, stImage);
622 if (!stObj->pt) {
623 /* Probably out of memory.
624 * Try flushing any pending rendering, then retry.
625 */
626 st_finish(ctx->st);
627 guess_and_alloc_texture(ctx->st, stObj, stImage);
628 if (!stObj->pt) {
629 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage");
630 return;
631 }
632 }
633 }
634
635 assert(!stImage->pt);
636
637 if (stObj->pt &&
638 st_texture_match_image(stObj->pt, &stImage->base,
639 stImage->face, stImage->level)) {
640
641 pipe_texture_reference(&stImage->pt, stObj->pt);
642 assert(stImage->pt);
643 }
644
645 if (!stImage->pt)
646 DBG("XXX: Image did not fit into texture - storing in local memory!\n");
647
648 /* st_CopyTexImage calls this function with pixels == NULL, with
649 * the expectation that the texture will be set up but nothing
650 * more will be done. This is where those calls return:
651 */
652 if (compressed_src) {
653 pixels = _mesa_validate_pbo_compressed_teximage(ctx, imageSize, pixels,
654 unpack,
655 "glCompressedTexImage");
656 }
657 else {
658 pixels = _mesa_validate_pbo_teximage(ctx, dims, width, height, 1,
659 format, type,
660 pixels, unpack, "glTexImage");
661 }
662 if (!pixels)
663 return;
664
665 /* See if we can do texture compression with a blit/render.
666 */
667 if (!compressed_src &&
668 !ctx->Mesa_DXTn &&
669 is_compressed_mesa_format(texImage->TexFormat) &&
670 screen->is_format_supported(screen,
671 stImage->pt->format,
672 stImage->pt->target,
673 PIPE_TEXTURE_USAGE_RENDER_TARGET, 0)) {
674 if (compress_with_blit(ctx, target, level, 0, 0, 0, width, height, depth,
675 format, type, pixels, unpack, texImage)) {
676 goto done;
677 }
678 }
679
680 if (stImage->pt) {
681 texImage->Data = st_texture_image_map(ctx->st, stImage, 0,
682 PIPE_TRANSFER_WRITE, 0, 0,
683 stImage->base.Width,
684 stImage->base.Height);
685 if(stImage->transfer)
686 dstRowStride = stImage->transfer->stride;
687 }
688 else {
689 /* Allocate regular memory and store the image there temporarily. */
690 if (texImage->IsCompressed) {
691 sizeInBytes = texImage->CompressedSize;
692 dstRowStride =
693 _mesa_compressed_row_stride(texImage->TexFormat->MesaFormat, width);
694 assert(dims != 3);
695 }
696 else {
697 dstRowStride = postConvWidth * texelBytes;
698 sizeInBytes = depth * dstRowStride * postConvHeight;
699 }
700
701 texImage->Data = _mesa_align_malloc(sizeInBytes, 16);
702 }
703
704 if (!texImage->Data) {
705 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage");
706 return;
707 }
708
709 DBG("Upload image %dx%dx%d row_len %x pitch %x\n",
710 width, height, depth, width * texelBytes, dstRowStride);
711
712 /* Copy data. Would like to know when it's ok for us to eg. use
713 * the blitter to copy. Or, use the hardware to do the format
714 * conversion and copy:
715 */
716 if (compressed_src) {
717 memcpy(texImage->Data, pixels, imageSize);
718 }
719 else {
720 const GLuint srcImageStride =
721 _mesa_image_image_stride(unpack, width, height, format, type);
722 GLint i;
723 const GLubyte *src = (const GLubyte *) pixels;
724
725 for (i = 0; i < depth; i++) {
726 if (!texImage->TexFormat->StoreImage(ctx, dims,
727 texImage->_BaseFormat,
728 texImage->TexFormat,
729 texImage->Data,
730 0, 0, 0, /* dstX/Y/Zoffset */
731 dstRowStride,
732 texImage->ImageOffsets,
733 width, height, 1,
734 format, type, src, unpack)) {
735 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage");
736 }
737
738 if (stImage->pt && i + 1 < depth) {
739 /* unmap this slice */
740 st_texture_image_unmap(ctx->st, stImage);
741 /* map next slice of 3D texture */
742 texImage->Data = st_texture_image_map(ctx->st, stImage, i + 1,
743 PIPE_TRANSFER_WRITE, 0, 0,
744 stImage->base.Width,
745 stImage->base.Height);
746 src += srcImageStride;
747 }
748 }
749 }
750
751 _mesa_unmap_teximage_pbo(ctx, unpack);
752
753 done:
754 if (stImage->pt && texImage->Data) {
755 st_texture_image_unmap(ctx->st, stImage);
756 texImage->Data = NULL;
757 }
758
759 if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
760 ctx->Driver.GenerateMipmap(ctx, target, texObj);
761 }
762 }
763
764
765 static void
766 st_TexImage3D(GLcontext * ctx,
767 GLenum target, GLint level,
768 GLint internalFormat,
769 GLint width, GLint height, GLint depth,
770 GLint border,
771 GLenum format, GLenum type, const void *pixels,
772 const struct gl_pixelstore_attrib *unpack,
773 struct gl_texture_object *texObj,
774 struct gl_texture_image *texImage)
775 {
776 st_TexImage(ctx, 3, target, level, internalFormat, width, height, depth,
777 border, format, type, pixels, unpack, texObj, texImage,
778 0, GL_FALSE);
779 }
780
781
782 static void
783 st_TexImage2D(GLcontext * ctx,
784 GLenum target, GLint level,
785 GLint internalFormat,
786 GLint width, GLint height, GLint border,
787 GLenum format, GLenum type, const void *pixels,
788 const struct gl_pixelstore_attrib *unpack,
789 struct gl_texture_object *texObj,
790 struct gl_texture_image *texImage)
791 {
792 st_TexImage(ctx, 2, target, level, internalFormat, width, height, 1, border,
793 format, type, pixels, unpack, texObj, texImage, 0, GL_FALSE);
794 }
795
796
797 static void
798 st_TexImage1D(GLcontext * ctx,
799 GLenum target, GLint level,
800 GLint internalFormat,
801 GLint width, GLint border,
802 GLenum format, GLenum type, const void *pixels,
803 const struct gl_pixelstore_attrib *unpack,
804 struct gl_texture_object *texObj,
805 struct gl_texture_image *texImage)
806 {
807 st_TexImage(ctx, 1, target, level, internalFormat, width, 1, 1, border,
808 format, type, pixels, unpack, texObj, texImage, 0, GL_FALSE);
809 }
810
811
812 static void
813 st_CompressedTexImage2D(GLcontext *ctx, GLenum target, GLint level,
814 GLint internalFormat,
815 GLint width, GLint height, GLint border,
816 GLsizei imageSize, const GLvoid *data,
817 struct gl_texture_object *texObj,
818 struct gl_texture_image *texImage)
819 {
820 st_TexImage(ctx, 2, target, level, internalFormat, width, height, 1, border,
821 0, 0, data, &ctx->Unpack, texObj, texImage, imageSize, GL_TRUE);
822 }
823
824
825
826 /**
827 * glGetTexImage() helper: decompress a compressed texture by rendering
828 * a textured quad. Store the results in the user's buffer.
829 */
830 static void
831 decompress_with_blit(GLcontext * ctx, GLenum target, GLint level,
832 GLenum format, GLenum type, GLvoid *pixels,
833 struct gl_texture_object *texObj,
834 struct gl_texture_image *texImage)
835 {
836 struct pipe_screen *screen = ctx->st->pipe->screen;
837 struct st_texture_image *stImage = st_texture_image(texImage);
838 const GLuint width = texImage->Width;
839 const GLuint height = texImage->Height;
840 struct pipe_surface *dst_surface;
841 struct pipe_texture *dst_texture;
842 struct pipe_transfer *tex_xfer;
843
844 /* create temp / dest surface */
845 if (!util_create_rgba_surface(screen, width, height,
846 &dst_texture, &dst_surface)) {
847 _mesa_problem(ctx, "util_create_rgba_surface() failed "
848 "in decompress_with_blit()");
849 return;
850 }
851
852 /* blit/render/decompress */
853 util_blit_pixels_tex(ctx->st->blit,
854 stImage->pt, /* pipe_texture (src) */
855 0, 0, /* src x0, y0 */
856 width, height, /* src x1, y1 */
857 dst_surface, /* pipe_surface (dst) */
858 0, 0, /* dst x0, y0 */
859 width, height, /* dst x1, y1 */
860 0.0, /* z */
861 PIPE_TEX_MIPFILTER_NEAREST);
862
863 /* map the dst_surface so we can read from it */
864 tex_xfer = st_cond_flush_get_tex_transfer(st_context(ctx),
865 dst_texture, 0, 0, 0,
866 PIPE_TRANSFER_READ,
867 0, 0, width, height);
868
869 pixels = _mesa_map_readpix_pbo(ctx, &ctx->Pack, pixels);
870
871 /* copy/pack data into user buffer */
872 if (st_equal_formats(stImage->pt->format, format, type)) {
873 /* memcpy */
874 const uint bytesPerRow = width * pf_get_size(stImage->pt->format);
875 ubyte *map = screen->transfer_map(screen, tex_xfer);
876 GLuint row;
877 for (row = 0; row < height; row++) {
878 GLvoid *dest = _mesa_image_address2d(&ctx->Pack, pixels, width,
879 height, format, type, row, 0);
880 memcpy(dest, map, bytesPerRow);
881 map += tex_xfer->stride;
882 }
883 screen->transfer_unmap(screen, tex_xfer);
884 }
885 else {
886 /* format translation via floats */
887 GLuint row;
888 for (row = 0; row < height; row++) {
889 const GLbitfield transferOps = 0x0; /* bypassed for glGetTexImage() */
890 GLfloat rgba[4 * MAX_WIDTH];
891 GLvoid *dest = _mesa_image_address2d(&ctx->Pack, pixels, width,
892 height, format, type, row, 0);
893
894 /* get float[4] rgba row from surface */
895 pipe_get_tile_rgba(tex_xfer, 0, row, width, 1, rgba);
896
897 _mesa_pack_rgba_span_float(ctx, width, (GLfloat (*)[4]) rgba, format,
898 type, dest, &ctx->Pack, transferOps);
899 }
900 }
901
902 _mesa_unmap_readpix_pbo(ctx, &ctx->Pack);
903
904 /* destroy the temp / dest surface */
905 util_destroy_rgba_surface(dst_texture, dst_surface);
906 }
907
908
909
910 /**
911 * Need to map texture image into memory before copying image data,
912 * then unmap it.
913 */
914 static void
915 st_get_tex_image(GLcontext * ctx, GLenum target, GLint level,
916 GLenum format, GLenum type, GLvoid * pixels,
917 struct gl_texture_object *texObj,
918 struct gl_texture_image *texImage, GLboolean compressed_dst)
919 {
920 struct st_texture_image *stImage = st_texture_image(texImage);
921 const GLuint dstImageStride =
922 _mesa_image_image_stride(&ctx->Pack, texImage->Width, texImage->Height,
923 format, type);
924 GLuint depth, i;
925 GLubyte *dest;
926
927 if (stImage->pt &&
928 pf_is_compressed(stImage->pt->format) &&
929 !compressed_dst) {
930 /* Need to decompress the texture.
931 * We'll do this by rendering a textured quad.
932 * Note that we only expect RGBA formats (no Z/depth formats).
933 */
934 decompress_with_blit(ctx, target, level, format, type, pixels,
935 texObj, texImage);
936 return;
937 }
938
939 /* Map */
940 if (stImage->pt) {
941 /* Image is stored in hardware format in a buffer managed by the
942 * kernel. Need to explicitly map and unmap it.
943 */
944
945 st_teximage_flush_before_map(ctx->st, stImage->pt, 0, level,
946 PIPE_TRANSFER_READ);
947
948 texImage->Data = st_texture_image_map(ctx->st, stImage, 0,
949 PIPE_TRANSFER_READ, 0, 0,
950 stImage->base.Width,
951 stImage->base.Height);
952 texImage->RowStride = stImage->transfer->stride / stImage->pt->block.size;
953 }
954 else {
955 /* Otherwise, the image should actually be stored in
956 * texImage->Data. This is pretty confusing for
957 * everybody, I'd much prefer to separate the two functions of
958 * texImage->Data - storage for texture images in main memory
959 * and access (ie mappings) of images. In other words, we'd
960 * create a new texImage->Map field and leave Data simply for
961 * storage.
962 */
963 assert(texImage->Data);
964 }
965
966 depth = texImage->Depth;
967 texImage->Depth = 1;
968
969 dest = (GLubyte *) pixels;
970
971 for (i = 0; i < depth; i++) {
972 if (compressed_dst) {
973 _mesa_get_compressed_teximage(ctx, target, level, dest,
974 texObj, texImage);
975 }
976 else {
977 _mesa_get_teximage(ctx, target, level, format, type, dest,
978 texObj, texImage);
979 }
980
981 if (stImage->pt && i + 1 < depth) {
982 /* unmap this slice */
983 st_texture_image_unmap(ctx->st, stImage);
984 /* map next slice of 3D texture */
985 texImage->Data = st_texture_image_map(ctx->st, stImage, i + 1,
986 PIPE_TRANSFER_READ, 0, 0,
987 stImage->base.Width,
988 stImage->base.Height);
989 dest += dstImageStride;
990 }
991 }
992
993 texImage->Depth = depth;
994
995 /* Unmap */
996 if (stImage->pt) {
997 st_texture_image_unmap(ctx->st, stImage);
998 texImage->Data = NULL;
999 }
1000 }
1001
1002
1003 static void
1004 st_GetTexImage(GLcontext * ctx, GLenum target, GLint level,
1005 GLenum format, GLenum type, GLvoid * pixels,
1006 struct gl_texture_object *texObj,
1007 struct gl_texture_image *texImage)
1008 {
1009 st_get_tex_image(ctx, target, level, format, type, pixels, texObj, texImage,
1010 GL_FALSE);
1011 }
1012
1013
1014 static void
1015 st_GetCompressedTexImage(GLcontext *ctx, GLenum target, GLint level,
1016 GLvoid *pixels,
1017 struct gl_texture_object *texObj,
1018 struct gl_texture_image *texImage)
1019 {
1020 st_get_tex_image(ctx, target, level, 0, 0, pixels, texObj, texImage,
1021 GL_TRUE);
1022 }
1023
1024
1025
1026 static void
1027 st_TexSubimage(GLcontext *ctx, GLint dims, GLenum target, GLint level,
1028 GLint xoffset, GLint yoffset, GLint zoffset,
1029 GLint width, GLint height, GLint depth,
1030 GLenum format, GLenum type, const void *pixels,
1031 const struct gl_pixelstore_attrib *packing,
1032 struct gl_texture_object *texObj,
1033 struct gl_texture_image *texImage)
1034 {
1035 struct pipe_screen *screen = ctx->st->pipe->screen;
1036 struct st_texture_image *stImage = st_texture_image(texImage);
1037 GLuint dstRowStride;
1038 const GLuint srcImageStride =
1039 _mesa_image_image_stride(packing, width, height, format, type);
1040 GLint i;
1041 const GLubyte *src;
1042
1043 DBG("%s target %s level %d offset %d,%d %dx%d\n", __FUNCTION__,
1044 _mesa_lookup_enum_by_nr(target),
1045 level, xoffset, yoffset, width, height);
1046
1047 pixels =
1048 _mesa_validate_pbo_teximage(ctx, dims, width, height, depth, format,
1049 type, pixels, packing, "glTexSubImage2D");
1050 if (!pixels)
1051 return;
1052
1053 /* See if we can do texture compression with a blit/render.
1054 */
1055 if (!ctx->Mesa_DXTn &&
1056 is_compressed_mesa_format(texImage->TexFormat) &&
1057 screen->is_format_supported(screen,
1058 stImage->pt->format,
1059 stImage->pt->target,
1060 PIPE_TEXTURE_USAGE_RENDER_TARGET, 0)) {
1061 if (compress_with_blit(ctx, target, level,
1062 xoffset, yoffset, zoffset,
1063 width, height, depth,
1064 format, type, pixels, packing, texImage)) {
1065 goto done;
1066 }
1067 }
1068
1069 /* Map buffer if necessary. Need to lock to prevent other contexts
1070 * from uploading the buffer under us.
1071 */
1072 if (stImage->pt) {
1073 st_teximage_flush_before_map(ctx->st, stImage->pt, 0, level,
1074 PIPE_TRANSFER_WRITE);
1075 texImage->Data = st_texture_image_map(ctx->st, stImage, zoffset,
1076 PIPE_TRANSFER_WRITE,
1077 xoffset, yoffset,
1078 width, height);
1079 }
1080
1081 if (!texImage->Data) {
1082 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage");
1083 return;
1084 }
1085
1086 src = (const GLubyte *) pixels;
1087 dstRowStride = stImage->transfer->stride;
1088
1089 for (i = 0; i < depth; i++) {
1090 if (!texImage->TexFormat->StoreImage(ctx, dims, texImage->_BaseFormat,
1091 texImage->TexFormat,
1092 texImage->Data,
1093 0, 0, 0,
1094 dstRowStride,
1095 texImage->ImageOffsets,
1096 width, height, 1,
1097 format, type, src, packing)) {
1098 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage");
1099 }
1100
1101 if (stImage->pt && i + 1 < depth) {
1102 /* unmap this slice */
1103 st_texture_image_unmap(ctx->st, stImage);
1104 /* map next slice of 3D texture */
1105 texImage->Data = st_texture_image_map(ctx->st, stImage,
1106 zoffset + i + 1,
1107 PIPE_TRANSFER_WRITE,
1108 xoffset, yoffset,
1109 width, height);
1110 src += srcImageStride;
1111 }
1112 }
1113
1114 _mesa_unmap_teximage_pbo(ctx, packing);
1115
1116 done:
1117 if (stImage->pt) {
1118 st_texture_image_unmap(ctx->st, stImage);
1119 texImage->Data = NULL;
1120 }
1121
1122 if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
1123 ctx->Driver.GenerateMipmap(ctx, target, texObj);
1124 }
1125 }
1126
1127
1128
1129 static void
1130 st_TexSubImage3D(GLcontext *ctx, GLenum target, GLint level,
1131 GLint xoffset, GLint yoffset, GLint zoffset,
1132 GLsizei width, GLsizei height, GLsizei depth,
1133 GLenum format, GLenum type, const GLvoid *pixels,
1134 const struct gl_pixelstore_attrib *packing,
1135 struct gl_texture_object *texObj,
1136 struct gl_texture_image *texImage)
1137 {
1138 st_TexSubimage(ctx, 3, target, level, xoffset, yoffset, zoffset,
1139 width, height, depth, format, type,
1140 pixels, packing, texObj, texImage);
1141 }
1142
1143
1144 static void
1145 st_TexSubImage2D(GLcontext *ctx, GLenum target, GLint level,
1146 GLint xoffset, GLint yoffset,
1147 GLsizei width, GLsizei height,
1148 GLenum format, GLenum type, const GLvoid * pixels,
1149 const struct gl_pixelstore_attrib *packing,
1150 struct gl_texture_object *texObj,
1151 struct gl_texture_image *texImage)
1152 {
1153 st_TexSubimage(ctx, 2, target, level, xoffset, yoffset, 0,
1154 width, height, 1, format, type,
1155 pixels, packing, texObj, texImage);
1156 }
1157
1158
1159 static void
1160 st_TexSubImage1D(GLcontext *ctx, GLenum target, GLint level,
1161 GLint xoffset, GLsizei width, GLenum format, GLenum type,
1162 const GLvoid * pixels,
1163 const struct gl_pixelstore_attrib *packing,
1164 struct gl_texture_object *texObj,
1165 struct gl_texture_image *texImage)
1166 {
1167 st_TexSubimage(ctx, 1, target, level, xoffset, 0, 0, width, 1, 1,
1168 format, type, pixels, packing, texObj, texImage);
1169 }
1170
1171
1172
1173 /**
1174 * Do a CopyTexSubImage operation using a read transfer from the source,
1175 * a write transfer to the destination and get_tile()/put_tile() to access
1176 * the pixels/texels.
1177 *
1178 * Note: srcY=0=TOP of renderbuffer
1179 */
1180 static void
1181 fallback_copy_texsubimage(GLcontext *ctx, GLenum target, GLint level,
1182 struct st_renderbuffer *strb,
1183 struct st_texture_image *stImage,
1184 GLenum baseFormat,
1185 GLint destX, GLint destY, GLint destZ,
1186 GLint srcX, GLint srcY,
1187 GLsizei width, GLsizei height)
1188 {
1189 struct pipe_context *pipe = ctx->st->pipe;
1190 struct pipe_screen *screen = pipe->screen;
1191 struct pipe_transfer *src_trans;
1192 GLvoid *texDest;
1193
1194 assert(width <= MAX_WIDTH);
1195
1196 if (st_fb_orientation(ctx->ReadBuffer) == Y_0_TOP) {
1197 srcY = strb->Base.Height - srcY - height;
1198 }
1199
1200 src_trans = st_cond_flush_get_tex_transfer( st_context(ctx),
1201 strb->texture,
1202 0, 0, 0,
1203 PIPE_TRANSFER_READ,
1204 srcX, srcY,
1205 width, height);
1206
1207 st_teximage_flush_before_map(ctx->st, stImage->pt, 0, 0,
1208 PIPE_TRANSFER_WRITE);
1209
1210 texDest = st_texture_image_map(ctx->st, stImage, 0, PIPE_TRANSFER_WRITE,
1211 destX, destY, width, height);
1212
1213 if (baseFormat == GL_DEPTH_COMPONENT ||
1214 baseFormat == GL_DEPTH24_STENCIL8) {
1215 const GLboolean scaleOrBias = (ctx->Pixel.DepthScale != 1.0F ||
1216 ctx->Pixel.DepthBias != 0.0F);
1217 GLint row, yStep;
1218
1219 /* determine bottom-to-top vs. top-to-bottom order for src buffer */
1220 if (st_fb_orientation(ctx->ReadBuffer) == Y_0_TOP) {
1221 srcY = height - 1;
1222 yStep = -1;
1223 }
1224 else {
1225 srcY = 0;
1226 yStep = 1;
1227 }
1228
1229 /* To avoid a large temp memory allocation, do copy row by row */
1230 for (row = 0; row < height; row++, srcY += yStep) {
1231 uint data[MAX_WIDTH];
1232 pipe_get_tile_z(src_trans, 0, srcY, width, 1, data);
1233 if (scaleOrBias) {
1234 _mesa_scale_and_bias_depth_uint(ctx, width, data);
1235 }
1236 pipe_put_tile_z(stImage->transfer, 0, row, width, 1, data);
1237 }
1238 }
1239 else {
1240 /* RGBA format */
1241 GLfloat *tempSrc =
1242 (GLfloat *) _mesa_malloc(width * height * 4 * sizeof(GLfloat));
1243
1244 if (tempSrc && texDest) {
1245 const GLint dims = 2;
1246 const GLint dstRowStride = stImage->transfer->stride;
1247 struct gl_texture_image *texImage = &stImage->base;
1248 struct gl_pixelstore_attrib unpack = ctx->DefaultPacking;
1249
1250 if (st_fb_orientation(ctx->ReadBuffer) == Y_0_TOP) {
1251 unpack.Invert = GL_TRUE;
1252 }
1253
1254 /* get float/RGBA image from framebuffer */
1255 /* XXX this usually involves a lot of int/float conversion.
1256 * try to avoid that someday.
1257 */
1258 pipe_get_tile_rgba(src_trans, 0, 0, width, height, tempSrc);
1259
1260 /* Store into texture memory.
1261 * Note that this does some special things such as pixel transfer
1262 * ops and format conversion. In particular, if the dest tex format
1263 * is actually RGBA but the user created the texture as GL_RGB we
1264 * need to fill-in/override the alpha channel with 1.0.
1265 */
1266 texImage->TexFormat->StoreImage(ctx, dims,
1267 texImage->_BaseFormat,
1268 texImage->TexFormat,
1269 texDest,
1270 0, 0, 0,
1271 dstRowStride,
1272 texImage->ImageOffsets,
1273 width, height, 1,
1274 GL_RGBA, GL_FLOAT, tempSrc, /* src */
1275 &unpack);
1276 }
1277 else {
1278 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage");
1279 }
1280
1281 if (tempSrc)
1282 _mesa_free(tempSrc);
1283 }
1284
1285 st_texture_image_unmap(ctx->st, stImage);
1286 screen->tex_transfer_destroy(src_trans);
1287 }
1288
1289
1290 /**
1291 * Do a CopyTex[Sub]Image1/2/3D() using a hardware (blit) path if possible.
1292 * Note that the region to copy has already been clipped so we know we
1293 * won't read from outside the source renderbuffer's bounds.
1294 *
1295 * Note: srcY=0=Bottom of renderbuffer (GL convention)
1296 */
1297 static void
1298 st_copy_texsubimage(GLcontext *ctx,
1299 GLenum target, GLint level,
1300 GLint destX, GLint destY, GLint destZ,
1301 GLint srcX, GLint srcY,
1302 GLsizei width, GLsizei height)
1303 {
1304 struct gl_texture_unit *texUnit =
1305 &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
1306 struct gl_texture_object *texObj =
1307 _mesa_select_tex_object(ctx, texUnit, target);
1308 struct gl_texture_image *texImage =
1309 _mesa_select_tex_image(ctx, texObj, target, level);
1310 struct st_texture_image *stImage = st_texture_image(texImage);
1311 const GLenum texBaseFormat = texImage->InternalFormat;
1312 struct gl_framebuffer *fb = ctx->ReadBuffer;
1313 struct st_renderbuffer *strb;
1314 struct pipe_context *pipe = ctx->st->pipe;
1315 struct pipe_screen *screen = pipe->screen;
1316 enum pipe_format dest_format, src_format;
1317 GLboolean use_fallback = GL_TRUE;
1318 GLboolean matching_base_formats;
1319
1320 /* any rendering in progress must flushed before we grab the fb image */
1321 st_flush(ctx->st, PIPE_FLUSH_RENDER_CACHE, NULL);
1322
1323 /* make sure finalize_textures has been called?
1324 */
1325 if (0) st_validate_state(ctx->st);
1326
1327 /* determine if copying depth or color data */
1328 if (texBaseFormat == GL_DEPTH_COMPONENT ||
1329 texBaseFormat == GL_DEPTH24_STENCIL8) {
1330 strb = st_renderbuffer(fb->_DepthBuffer);
1331 }
1332 else if (texBaseFormat == GL_DEPTH_STENCIL_EXT) {
1333 strb = st_renderbuffer(fb->_StencilBuffer);
1334 }
1335 else {
1336 /* texBaseFormat == GL_RGB, GL_RGBA, GL_ALPHA, etc */
1337 strb = st_renderbuffer(fb->_ColorReadBuffer);
1338 }
1339
1340 if (!strb || !strb->surface || !stImage->pt) {
1341 debug_printf("%s: null strb or stImage\n", __FUNCTION__);
1342 return;
1343 }
1344
1345 if (srcX < 0) {
1346 width -= -srcX;
1347 destX += -srcX;
1348 srcX = 0;
1349 }
1350
1351 if (srcY < 0) {
1352 height -= -srcY;
1353 destY += -srcY;
1354 srcY = 0;
1355 }
1356
1357 if (destX < 0) {
1358 width -= -destX;
1359 srcX += -destX;
1360 destX = 0;
1361 }
1362
1363 if (destY < 0) {
1364 height -= -destY;
1365 srcY += -destY;
1366 destY = 0;
1367 }
1368
1369 if (width < 0 || height < 0)
1370 return;
1371
1372
1373 assert(strb);
1374 assert(strb->surface);
1375 assert(stImage->pt);
1376
1377 src_format = strb->surface->format;
1378 dest_format = stImage->pt->format;
1379
1380 /*
1381 * Determine if the src framebuffer and dest texture have the same
1382 * base format. We need this to detect a case such as the framebuffer
1383 * being GL_RGBA but the texture being GL_RGB. If the actual hardware
1384 * texture format stores RGBA we need to set A=1 (overriding the
1385 * framebuffer's alpha values). We can't do that with the blit or
1386 * textured-quad paths.
1387 */
1388 matching_base_formats = (strb->Base._BaseFormat == texImage->_BaseFormat);
1389
1390 if (matching_base_formats && ctx->_ImageTransferState == 0x0) {
1391 /* try potential hardware path */
1392 struct pipe_surface *dest_surface = NULL;
1393 boolean do_flip = (st_fb_orientation(ctx->ReadBuffer) == Y_0_TOP);
1394
1395 if (src_format == dest_format && !do_flip) {
1396 /* use surface_copy() / blit */
1397
1398 dest_surface = screen->get_tex_surface(screen, stImage->pt,
1399 stImage->face, stImage->level,
1400 destZ,
1401 PIPE_BUFFER_USAGE_GPU_WRITE);
1402
1403 /* for surface_copy(), y=0=top, always */
1404 pipe->surface_copy(pipe,
1405 /* dest */
1406 dest_surface,
1407 destX, destY,
1408 /* src */
1409 strb->surface,
1410 srcX, srcY,
1411 /* size */
1412 width, height);
1413 use_fallback = GL_FALSE;
1414 }
1415 else if (screen->is_format_supported(screen, src_format,
1416 PIPE_TEXTURE_2D,
1417 PIPE_TEXTURE_USAGE_SAMPLER,
1418 0) &&
1419 screen->is_format_supported(screen, dest_format,
1420 PIPE_TEXTURE_2D,
1421 PIPE_TEXTURE_USAGE_RENDER_TARGET,
1422 0)) {
1423 /* draw textured quad to do the copy */
1424 GLint srcY0, srcY1;
1425
1426 dest_surface = screen->get_tex_surface(screen, stImage->pt,
1427 stImage->face, stImage->level,
1428 destZ,
1429 PIPE_BUFFER_USAGE_GPU_WRITE);
1430
1431 if (do_flip) {
1432 srcY1 = strb->Base.Height - srcY - height;
1433 srcY0 = srcY1 + height;
1434 }
1435 else {
1436 srcY0 = srcY;
1437 srcY1 = srcY0 + height;
1438 }
1439 util_blit_pixels(ctx->st->blit,
1440 strb->surface,
1441 srcX, srcY0,
1442 srcX + width, srcY1,
1443 dest_surface,
1444 destX, destY,
1445 destX + width, destY + height,
1446 0.0, PIPE_TEX_MIPFILTER_NEAREST);
1447 use_fallback = GL_FALSE;
1448 }
1449
1450 if (dest_surface)
1451 pipe_surface_reference(&dest_surface, NULL);
1452 }
1453
1454 if (use_fallback) {
1455 /* software fallback */
1456 fallback_copy_texsubimage(ctx, target, level,
1457 strb, stImage, texBaseFormat,
1458 destX, destY, destZ,
1459 srcX, srcY, width, height);
1460 }
1461
1462 if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
1463 ctx->Driver.GenerateMipmap(ctx, target, texObj);
1464 }
1465 }
1466
1467
1468
1469 static void
1470 st_CopyTexImage1D(GLcontext * ctx, GLenum target, GLint level,
1471 GLenum internalFormat,
1472 GLint x, GLint y, GLsizei width, GLint border)
1473 {
1474 struct gl_texture_unit *texUnit =
1475 &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
1476 struct gl_texture_object *texObj =
1477 _mesa_select_tex_object(ctx, texUnit, target);
1478 struct gl_texture_image *texImage =
1479 _mesa_select_tex_image(ctx, texObj, target, level);
1480
1481 /* Setup or redefine the texture object, texture and texture
1482 * image. Don't populate yet.
1483 */
1484 ctx->Driver.TexImage1D(ctx, target, level, internalFormat,
1485 width, border,
1486 GL_RGBA, CHAN_TYPE, NULL,
1487 &ctx->DefaultPacking, texObj, texImage);
1488
1489 st_copy_texsubimage(ctx, target, level,
1490 0, 0, 0, /* destX,Y,Z */
1491 x, y, width, 1); /* src X, Y, size */
1492 }
1493
1494
1495 static void
1496 st_CopyTexImage2D(GLcontext * ctx, GLenum target, GLint level,
1497 GLenum internalFormat,
1498 GLint x, GLint y, GLsizei width, GLsizei height,
1499 GLint border)
1500 {
1501 struct gl_texture_unit *texUnit =
1502 &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
1503 struct gl_texture_object *texObj =
1504 _mesa_select_tex_object(ctx, texUnit, target);
1505 struct gl_texture_image *texImage =
1506 _mesa_select_tex_image(ctx, texObj, target, level);
1507
1508 /* Setup or redefine the texture object, texture and texture
1509 * image. Don't populate yet.
1510 */
1511 ctx->Driver.TexImage2D(ctx, target, level, internalFormat,
1512 width, height, border,
1513 GL_RGBA, CHAN_TYPE, NULL,
1514 &ctx->DefaultPacking, texObj, texImage);
1515
1516 st_copy_texsubimage(ctx, target, level,
1517 0, 0, 0, /* destX,Y,Z */
1518 x, y, width, height); /* src X, Y, size */
1519 }
1520
1521
1522 static void
1523 st_CopyTexSubImage1D(GLcontext * ctx, GLenum target, GLint level,
1524 GLint xoffset, GLint x, GLint y, GLsizei width)
1525 {
1526 const GLint yoffset = 0, zoffset = 0;
1527 const GLsizei height = 1;
1528 st_copy_texsubimage(ctx, target, level,
1529 xoffset, yoffset, zoffset, /* destX,Y,Z */
1530 x, y, width, height); /* src X, Y, size */
1531 }
1532
1533
1534 static void
1535 st_CopyTexSubImage2D(GLcontext * ctx, GLenum target, GLint level,
1536 GLint xoffset, GLint yoffset,
1537 GLint x, GLint y, GLsizei width, GLsizei height)
1538 {
1539 const GLint zoffset = 0;
1540 st_copy_texsubimage(ctx, target, level,
1541 xoffset, yoffset, zoffset, /* destX,Y,Z */
1542 x, y, width, height); /* src X, Y, size */
1543 }
1544
1545
1546 static void
1547 st_CopyTexSubImage3D(GLcontext * ctx, GLenum target, GLint level,
1548 GLint xoffset, GLint yoffset, GLint zoffset,
1549 GLint x, GLint y, GLsizei width, GLsizei height)
1550 {
1551 st_copy_texsubimage(ctx, target, level,
1552 xoffset, yoffset, zoffset, /* destX,Y,Z */
1553 x, y, width, height); /* src X, Y, size */
1554 }
1555
1556
1557 /**
1558 * Compute which mipmap levels that really need to be sent to the hardware.
1559 * This depends on the base image size, GL_TEXTURE_MIN_LOD,
1560 * GL_TEXTURE_MAX_LOD, GL_TEXTURE_BASE_LEVEL, and GL_TEXTURE_MAX_LEVEL.
1561 */
1562 static void
1563 calculate_first_last_level(struct st_texture_object *stObj)
1564 {
1565 struct gl_texture_object *tObj = &stObj->base;
1566
1567 /* These must be signed values. MinLod and MaxLod can be negative numbers,
1568 * and having firstLevel and lastLevel as signed prevents the need for
1569 * extra sign checks.
1570 */
1571 GLint firstLevel;
1572 GLint lastLevel;
1573
1574 /* Yes, this looks overly complicated, but it's all needed.
1575 */
1576 switch (tObj->Target) {
1577 case GL_TEXTURE_1D:
1578 case GL_TEXTURE_2D:
1579 case GL_TEXTURE_3D:
1580 case GL_TEXTURE_CUBE_MAP:
1581 if (tObj->MinFilter == GL_NEAREST || tObj->MinFilter == GL_LINEAR) {
1582 /* GL_NEAREST and GL_LINEAR only care about GL_TEXTURE_BASE_LEVEL.
1583 */
1584 firstLevel = lastLevel = tObj->BaseLevel;
1585 }
1586 else {
1587 firstLevel = 0;
1588 lastLevel = MIN2(tObj->MaxLevel,
1589 (int) tObj->Image[0][tObj->BaseLevel]->WidthLog2);
1590 }
1591 break;
1592 case GL_TEXTURE_RECTANGLE_NV:
1593 case GL_TEXTURE_4D_SGIS:
1594 firstLevel = lastLevel = 0;
1595 break;
1596 default:
1597 return;
1598 }
1599
1600 stObj->lastLevel = lastLevel;
1601 }
1602
1603
1604 static void
1605 copy_image_data_to_texture(struct st_context *st,
1606 struct st_texture_object *stObj,
1607 GLuint dstLevel,
1608 struct st_texture_image *stImage)
1609 {
1610 if (stImage->pt) {
1611 /* Copy potentially with the blitter:
1612 */
1613 st_texture_image_copy(st->pipe,
1614 stObj->pt, dstLevel, /* dest texture, level */
1615 stImage->pt, /* src texture */
1616 stImage->face
1617 );
1618
1619 pipe_texture_reference(&stImage->pt, NULL);
1620 }
1621 else if (stImage->base.Data) {
1622 assert(stImage->base.Data != NULL);
1623
1624 /* More straightforward upload.
1625 */
1626
1627 st_teximage_flush_before_map(st, stObj->pt, stImage->face, dstLevel,
1628 PIPE_TRANSFER_WRITE);
1629
1630
1631 st_texture_image_data(st,
1632 stObj->pt,
1633 stImage->face,
1634 dstLevel,
1635 stImage->base.Data,
1636 stImage->base.RowStride *
1637 stObj->pt->block.size,
1638 stImage->base.RowStride *
1639 stImage->base.Height *
1640 stObj->pt->block.size);
1641 _mesa_align_free(stImage->base.Data);
1642 stImage->base.Data = NULL;
1643 }
1644
1645 pipe_texture_reference(&stImage->pt, stObj->pt);
1646 }
1647
1648
1649 /**
1650 * Called during state validation. When this function is finished,
1651 * the texture object should be ready for rendering.
1652 * \return GL_TRUE for success, GL_FALSE for failure (out of mem)
1653 */
1654 GLboolean
1655 st_finalize_texture(GLcontext *ctx,
1656 struct pipe_context *pipe,
1657 struct gl_texture_object *tObj,
1658 GLboolean *needFlush)
1659 {
1660 struct st_texture_object *stObj = st_texture_object(tObj);
1661 const GLuint nr_faces = (stObj->base.Target == GL_TEXTURE_CUBE_MAP) ? 6 : 1;
1662 GLuint cpp, face;
1663 struct st_texture_image *firstImage;
1664
1665 *needFlush = GL_FALSE;
1666
1667 /* We know/require this is true by now:
1668 */
1669 assert(stObj->base._Complete);
1670
1671 /* What levels must the texture include at a minimum?
1672 */
1673 calculate_first_last_level(stObj);
1674 firstImage = st_texture_image(stObj->base.Image[0][stObj->base.BaseLevel]);
1675
1676 /* If both firstImage and stObj point to a texture which can contain
1677 * all active images, favour firstImage. Note that because of the
1678 * completeness requirement, we know that the image dimensions
1679 * will match.
1680 */
1681 if (firstImage->pt &&
1682 firstImage->pt != stObj->pt &&
1683 firstImage->pt->last_level >= stObj->lastLevel) {
1684 pipe_texture_reference(&stObj->pt, firstImage->pt);
1685 }
1686
1687 /* FIXME: determine format block instead of cpp */
1688 if (firstImage->base.IsCompressed) {
1689 cpp = compressed_num_bytes(firstImage->base.TexFormat->MesaFormat);
1690 }
1691 else {
1692 cpp = firstImage->base.TexFormat->TexelBytes;
1693 }
1694
1695 /* If we already have a gallium texture, check that it matches the texture
1696 * object's format, target, size, num_levels, etc.
1697 */
1698 if (stObj->pt) {
1699 const enum pipe_format fmt =
1700 st_mesa_format_to_pipe_format(firstImage->base.TexFormat->MesaFormat);
1701 if (stObj->pt->target != gl_target_to_pipe(stObj->base.Target) ||
1702 stObj->pt->format != fmt ||
1703 stObj->pt->last_level < stObj->lastLevel ||
1704 stObj->pt->width[0] != firstImage->base.Width2 ||
1705 stObj->pt->height[0] != firstImage->base.Height2 ||
1706 stObj->pt->depth[0] != firstImage->base.Depth2 ||
1707 /* Nominal bytes per pixel: */
1708 stObj->pt->block.size / stObj->pt->block.width != cpp)
1709 {
1710 pipe_texture_reference(&stObj->pt, NULL);
1711 ctx->st->dirty.st |= ST_NEW_FRAMEBUFFER;
1712 }
1713 }
1714
1715 /* May need to create a new gallium texture:
1716 */
1717 if (!stObj->pt) {
1718 const enum pipe_format fmt =
1719 st_mesa_format_to_pipe_format(firstImage->base.TexFormat->MesaFormat);
1720 GLuint usage = default_usage(fmt);
1721
1722 stObj->pt = st_texture_create(ctx->st,
1723 gl_target_to_pipe(stObj->base.Target),
1724 fmt,
1725 stObj->lastLevel,
1726 firstImage->base.Width2,
1727 firstImage->base.Height2,
1728 firstImage->base.Depth2,
1729 usage);
1730
1731 if (!stObj->pt) {
1732 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage");
1733 return GL_FALSE;
1734 }
1735 }
1736
1737 /* Pull in any images not in the object's texture:
1738 */
1739 for (face = 0; face < nr_faces; face++) {
1740 GLuint level;
1741 for (level = 0; level <= stObj->lastLevel; level++) {
1742 struct st_texture_image *stImage =
1743 st_texture_image(stObj->base.Image[face][stObj->base.BaseLevel + level]);
1744
1745 /* Need to import images in main memory or held in other textures.
1746 */
1747 if (stImage && stObj->pt != stImage->pt) {
1748 copy_image_data_to_texture(ctx->st, stObj, level, stImage);
1749 *needFlush = GL_TRUE;
1750 }
1751 }
1752 }
1753
1754 return GL_TRUE;
1755 }
1756
1757
1758 /**
1759 * Returns pointer to a default/dummy texture.
1760 * This is typically used when the current shader has tex/sample instructions
1761 * but the user has not provided a (any) texture(s).
1762 */
1763 struct gl_texture_object *
1764 st_get_default_texture(struct st_context *st)
1765 {
1766 if (!st->default_texture) {
1767 static const GLenum target = GL_TEXTURE_2D;
1768 GLubyte pixels[16][16][4];
1769 struct gl_texture_object *texObj;
1770 struct gl_texture_image *texImg;
1771 GLuint i, j;
1772
1773 /* The ARB_fragment_program spec says (0,0,0,1) should be returned
1774 * when attempting to sample incomplete textures.
1775 */
1776 for (i = 0; i < 16; i++) {
1777 for (j = 0; j < 16; j++) {
1778 pixels[i][j][0] = 0;
1779 pixels[i][j][1] = 0;
1780 pixels[i][j][2] = 0;
1781 pixels[i][j][3] = 255;
1782 }
1783 }
1784
1785 texObj = st->ctx->Driver.NewTextureObject(st->ctx, 0, target);
1786
1787 texImg = _mesa_get_tex_image(st->ctx, texObj, target, 0);
1788
1789 _mesa_init_teximage_fields(st->ctx, target, texImg,
1790 16, 16, 1, 0, /* w, h, d, border */
1791 GL_RGBA);
1792
1793 st_TexImage(st->ctx, 2, target,
1794 0, GL_RGBA, /* level, intformat */
1795 16, 16, 1, 0, /* w, h, d, border */
1796 GL_RGBA, GL_UNSIGNED_BYTE, pixels,
1797 &st->ctx->DefaultPacking,
1798 texObj, texImg,
1799 0, 0);
1800
1801 texObj->MinFilter = GL_NEAREST;
1802 texObj->MagFilter = GL_NEAREST;
1803 texObj->_Complete = GL_TRUE;
1804
1805 st->default_texture = texObj;
1806 }
1807 return st->default_texture;
1808 }
1809
1810
1811 void
1812 st_init_texture_functions(struct dd_function_table *functions)
1813 {
1814 functions->ChooseTextureFormat = st_ChooseTextureFormat;
1815 functions->TexImage1D = st_TexImage1D;
1816 functions->TexImage2D = st_TexImage2D;
1817 functions->TexImage3D = st_TexImage3D;
1818 functions->TexSubImage1D = st_TexSubImage1D;
1819 functions->TexSubImage2D = st_TexSubImage2D;
1820 functions->TexSubImage3D = st_TexSubImage3D;
1821 functions->CopyTexImage1D = st_CopyTexImage1D;
1822 functions->CopyTexImage2D = st_CopyTexImage2D;
1823 functions->CopyTexSubImage1D = st_CopyTexSubImage1D;
1824 functions->CopyTexSubImage2D = st_CopyTexSubImage2D;
1825 functions->CopyTexSubImage3D = st_CopyTexSubImage3D;
1826 functions->GenerateMipmap = st_generate_mipmap;
1827
1828 functions->GetTexImage = st_GetTexImage;
1829
1830 /* compressed texture functions */
1831 functions->CompressedTexImage2D = st_CompressedTexImage2D;
1832 functions->GetCompressedTexImage = st_GetCompressedTexImage;
1833 functions->CompressedTextureSize = _mesa_compressed_texture_size;
1834
1835 functions->NewTextureObject = st_NewTextureObject;
1836 functions->NewTextureImage = st_NewTextureImage;
1837 functions->DeleteTexture = st_DeleteTextureObject;
1838 functions->FreeTexImageData = st_FreeTextureImageData;
1839 functions->UpdateTexturePalette = 0;
1840
1841 functions->TextureMemCpy = do_memcpy;
1842
1843 /* XXX Temporary until we can query pipe's texture sizes */
1844 functions->TestProxyTexImage = _mesa_test_proxy_teximage;
1845 }