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