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