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