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