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