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