st_cb_texture.c revision 85cb4f299d8a0a0ebc8fe14d0ccd327375eda99e
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/pbo.h"
39#include "main/pixeltransfer.h"
40#include "main/texcompress.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_cb_bufferobjects.h"
52#include "state_tracker/st_format.h"
53#include "state_tracker/st_texture.h"
54#include "state_tracker/st_gen_mipmap.h"
55#include "state_tracker/st_atom.h"
56
57#include "pipe/p_context.h"
58#include "pipe/p_defines.h"
59#include "util/u_inlines.h"
60#include "pipe/p_shader_tokens.h"
61#include "util/u_tile.h"
62#include "util/u_blit.h"
63#include "util/u_format.h"
64#include "util/u_surface.h"
65#include "util/u_sampler.h"
66#include "util/u_math.h"
67#include "util/u_box.h"
68
69#define DBG if (0) printf
70
71
72static enum pipe_texture_target
73gl_target_to_pipe(GLenum target)
74{
75   switch (target) {
76   case GL_TEXTURE_1D:
77   case GL_PROXY_TEXTURE_1D:
78      return PIPE_TEXTURE_1D;
79   case GL_TEXTURE_2D:
80   case GL_PROXY_TEXTURE_2D:
81   case GL_TEXTURE_EXTERNAL_OES:
82      return PIPE_TEXTURE_2D;
83   case GL_TEXTURE_RECTANGLE_NV:
84   case GL_PROXY_TEXTURE_RECTANGLE_NV:
85      return PIPE_TEXTURE_RECT;
86   case GL_TEXTURE_3D:
87   case GL_PROXY_TEXTURE_3D:
88      return PIPE_TEXTURE_3D;
89   case GL_TEXTURE_CUBE_MAP_ARB:
90   case GL_PROXY_TEXTURE_CUBE_MAP_ARB:
91   case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
92   case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
93   case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
94   case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
95   case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
96   case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
97      return PIPE_TEXTURE_CUBE;
98   case GL_TEXTURE_1D_ARRAY_EXT:
99   case GL_PROXY_TEXTURE_1D_ARRAY_EXT:
100      return PIPE_TEXTURE_1D_ARRAY;
101   case GL_TEXTURE_2D_ARRAY_EXT:
102   case GL_PROXY_TEXTURE_2D_ARRAY_EXT:
103      return PIPE_TEXTURE_2D_ARRAY;
104   case GL_TEXTURE_BUFFER:
105      return PIPE_BUFFER;
106   case GL_TEXTURE_CUBE_MAP_ARRAY:
107   case GL_PROXY_TEXTURE_CUBE_MAP_ARRAY:
108      return PIPE_TEXTURE_CUBE_ARRAY;
109   default:
110      assert(0);
111      return 0;
112   }
113}
114
115
116/** called via ctx->Driver.NewTextureImage() */
117static struct gl_texture_image *
118st_NewTextureImage(struct gl_context * ctx)
119{
120   DBG("%s\n", __FUNCTION__);
121   (void) ctx;
122   return (struct gl_texture_image *) ST_CALLOC_STRUCT(st_texture_image);
123}
124
125
126/** called via ctx->Driver.DeleteTextureImage() */
127static void
128st_DeleteTextureImage(struct gl_context * ctx, struct gl_texture_image *img)
129{
130   /* nothing special (yet) for st_texture_image */
131   _mesa_delete_texture_image(ctx, img);
132}
133
134
135/** called via ctx->Driver.NewTextureObject() */
136static struct gl_texture_object *
137st_NewTextureObject(struct gl_context * ctx, GLuint name, GLenum target)
138{
139   struct st_texture_object *obj = ST_CALLOC_STRUCT(st_texture_object);
140
141   DBG("%s\n", __FUNCTION__);
142   _mesa_initialize_texture_object(&obj->base, name, target);
143
144   return &obj->base;
145}
146
147/** called via ctx->Driver.DeleteTextureObject() */
148static void
149st_DeleteTextureObject(struct gl_context *ctx,
150                       struct gl_texture_object *texObj)
151{
152   struct st_context *st = st_context(ctx);
153   struct st_texture_object *stObj = st_texture_object(texObj);
154   if (stObj->pt)
155      pipe_resource_reference(&stObj->pt, NULL);
156   if (stObj->sampler_view) {
157      pipe_sampler_view_release(st->pipe, &stObj->sampler_view);
158   }
159   _mesa_delete_texture_object(ctx, texObj);
160}
161
162
163/** called via ctx->Driver.FreeTextureImageBuffer() */
164static void
165st_FreeTextureImageBuffer(struct gl_context *ctx,
166                          struct gl_texture_image *texImage)
167{
168   struct st_texture_image *stImage = st_texture_image(texImage);
169
170   DBG("%s\n", __FUNCTION__);
171
172   if (stImage->pt) {
173      pipe_resource_reference(&stImage->pt, NULL);
174   }
175
176   if (stImage->TexData) {
177      _mesa_align_free(stImage->TexData);
178      stImage->TexData = NULL;
179   }
180}
181
182
183/** called via ctx->Driver.MapTextureImage() */
184static void
185st_MapTextureImage(struct gl_context *ctx,
186                   struct gl_texture_image *texImage,
187                   GLuint slice, GLuint x, GLuint y, GLuint w, GLuint h,
188                   GLbitfield mode,
189                   GLubyte **mapOut, GLint *rowStrideOut)
190{
191   struct st_context *st = st_context(ctx);
192   struct st_texture_image *stImage = st_texture_image(texImage);
193   unsigned pipeMode;
194   GLubyte *map;
195
196   pipeMode = 0x0;
197   if (mode & GL_MAP_READ_BIT)
198      pipeMode |= PIPE_TRANSFER_READ;
199   if (mode & GL_MAP_WRITE_BIT)
200      pipeMode |= PIPE_TRANSFER_WRITE;
201   if (mode & GL_MAP_INVALIDATE_RANGE_BIT)
202      pipeMode |= PIPE_TRANSFER_DISCARD_RANGE;
203
204   map = st_texture_image_map(st, stImage, slice, pipeMode, x, y, w, h);
205   if (map) {
206      *mapOut = map;
207      *rowStrideOut = stImage->transfer->stride;
208   }
209   else {
210      *mapOut = NULL;
211      *rowStrideOut = 0;
212   }
213}
214
215
216/** called via ctx->Driver.UnmapTextureImage() */
217static void
218st_UnmapTextureImage(struct gl_context *ctx,
219                     struct gl_texture_image *texImage,
220                     GLuint slice)
221{
222   struct st_context *st = st_context(ctx);
223   struct st_texture_image *stImage  = st_texture_image(texImage);
224   st_texture_image_unmap(st, stImage);
225}
226
227
228/**
229 * Return default texture resource binding bitmask for the given format.
230 */
231static GLuint
232default_bindings(struct st_context *st, enum pipe_format format)
233{
234   struct pipe_screen *screen = st->pipe->screen;
235   const unsigned target = PIPE_TEXTURE_2D;
236   unsigned bindings;
237
238   if (util_format_is_depth_or_stencil(format))
239      bindings = PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_DEPTH_STENCIL;
240   else
241      bindings = PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET;
242
243   if (screen->is_format_supported(screen, format, target, 0, bindings))
244      return bindings;
245   else {
246      /* Try non-sRGB. */
247      format = util_format_linear(format);
248
249      if (screen->is_format_supported(screen, format, target, 0, bindings))
250         return bindings;
251      else
252         return PIPE_BIND_SAMPLER_VIEW;
253   }
254}
255
256
257/**
258 * Given the size of a mipmap image, try to compute the size of the level=0
259 * mipmap image.
260 *
261 * Note that this isn't always accurate for odd-sized, non-POW textures.
262 * For example, if level=1 and width=40 then the level=0 width may be 80 or 81.
263 *
264 * \return GL_TRUE for success, GL_FALSE for failure
265 */
266static GLboolean
267guess_base_level_size(GLenum target,
268                      GLuint width, GLuint height, GLuint depth, GLuint level,
269                      GLuint *width0, GLuint *height0, GLuint *depth0)
270{
271   assert(width >= 1);
272   assert(height >= 1);
273   assert(depth >= 1);
274
275   if (level > 0) {
276      /* Guess the size of the base level.
277       * Depending on the image's size, we can't always make a guess here.
278       */
279      switch (target) {
280      case GL_TEXTURE_1D:
281      case GL_TEXTURE_1D_ARRAY:
282         width <<= level;
283         break;
284
285      case GL_TEXTURE_2D:
286      case GL_TEXTURE_2D_ARRAY:
287         /* We can't make a good guess here, because the base level dimensions
288          * can be non-square.
289          */
290         if (width == 1 || height == 1) {
291            return GL_FALSE;
292         }
293         width <<= level;
294         height <<= level;
295         break;
296
297      case GL_TEXTURE_CUBE_MAP:
298      case GL_TEXTURE_CUBE_MAP_ARRAY:
299         width <<= level;
300         height <<= level;
301         break;
302
303      case GL_TEXTURE_3D:
304         /* We can't make a good guess here, because the base level dimensions
305          * can be non-cube.
306          */
307         if (width == 1 || height == 1 || depth == 1) {
308            return GL_FALSE;
309         }
310         width <<= level;
311         height <<= level;
312         depth <<= level;
313         break;
314
315      case GL_TEXTURE_RECTANGLE:
316         break;
317
318      default:
319         assert(0);
320      }
321   }
322
323   *width0 = width;
324   *height0 = height;
325   *depth0 = depth;
326
327   return GL_TRUE;
328}
329
330
331/**
332 * Try to allocate a pipe_resource object for the given st_texture_object.
333 *
334 * We use the given st_texture_image as a clue to determine the size of the
335 * mipmap image at level=0.
336 *
337 * \return GL_TRUE for success, GL_FALSE if out of memory.
338 */
339static GLboolean
340guess_and_alloc_texture(struct st_context *st,
341			struct st_texture_object *stObj,
342			const struct st_texture_image *stImage)
343{
344   GLuint lastLevel, width, height, depth;
345   GLuint bindings;
346   GLuint ptWidth, ptHeight, ptDepth, ptLayers;
347   enum pipe_format fmt;
348
349   DBG("%s\n", __FUNCTION__);
350
351   assert(!stObj->pt);
352
353   if (!guess_base_level_size(stObj->base.Target,
354                              stImage->base.Width2,
355                              stImage->base.Height2,
356                              stImage->base.Depth2,
357                              stImage->base.Level,
358                              &width, &height, &depth)) {
359      /* we can't determine the image size at level=0 */
360      stObj->width0 = stObj->height0 = stObj->depth0 = 0;
361      /* this is not an out of memory error */
362      return GL_TRUE;
363   }
364
365   /* At this point, (width x height x depth) is the expected size of
366    * the level=0 mipmap image.
367    */
368
369   /* Guess a reasonable value for lastLevel.  With OpenGL we have no
370    * idea how many mipmap levels will be in a texture until we start
371    * to render with it.  Make an educated guess here but be prepared
372    * to re-allocating a texture buffer with space for more (or fewer)
373    * mipmap levels later.
374    */
375   if ((stObj->base.Sampler.MinFilter == GL_NEAREST ||
376        stObj->base.Sampler.MinFilter == GL_LINEAR ||
377        (stObj->base.BaseLevel == 0 &&
378         stObj->base.MaxLevel == 0) ||
379        stImage->base._BaseFormat == GL_DEPTH_COMPONENT ||
380        stImage->base._BaseFormat == GL_DEPTH_STENCIL_EXT) &&
381       !stObj->base.GenerateMipmap &&
382       stImage->base.Level == 0) {
383      /* only alloc space for a single mipmap level */
384      lastLevel = 0;
385   }
386   else {
387      /* alloc space for a full mipmap */
388      lastLevel = _mesa_get_tex_max_num_levels(stObj->base.Target,
389                                               width, height, depth) - 1;
390   }
391
392   /* Save the level=0 dimensions */
393   stObj->width0 = width;
394   stObj->height0 = height;
395   stObj->depth0 = depth;
396
397   fmt = st_mesa_format_to_pipe_format(stImage->base.TexFormat);
398
399   bindings = default_bindings(st, fmt);
400
401   st_gl_texture_dims_to_pipe_dims(stObj->base.Target,
402                                   width, height, depth,
403                                   &ptWidth, &ptHeight, &ptDepth, &ptLayers);
404
405   stObj->pt = st_texture_create(st,
406                                 gl_target_to_pipe(stObj->base.Target),
407                                 fmt,
408                                 lastLevel,
409                                 ptWidth,
410                                 ptHeight,
411                                 ptDepth,
412                                 ptLayers,
413                                 bindings);
414
415   stObj->lastLevel = lastLevel;
416
417   DBG("%s returning %d\n", __FUNCTION__, (stObj->pt != NULL));
418
419   return stObj->pt != NULL;
420}
421
422
423/**
424 * Called via ctx->Driver.AllocTextureImageBuffer().
425 * If the texture object/buffer already has space for the indicated image,
426 * we're done.  Otherwise, allocate memory for the new texture image.
427 */
428static GLboolean
429st_AllocTextureImageBuffer(struct gl_context *ctx,
430                           struct gl_texture_image *texImage)
431{
432   struct st_context *st = st_context(ctx);
433   struct st_texture_image *stImage = st_texture_image(texImage);
434   struct st_texture_object *stObj = st_texture_object(texImage->TexObject);
435   const GLuint level = texImage->Level;
436   GLuint width = texImage->Width;
437   GLuint height = texImage->Height;
438   GLuint depth = texImage->Depth;
439
440   DBG("%s\n", __FUNCTION__);
441
442   assert(!stImage->TexData);
443   assert(!stImage->pt); /* xxx this might be wrong */
444
445   /* Look if the parent texture object has space for this image */
446   if (stObj->pt &&
447       level <= stObj->pt->last_level &&
448       st_texture_match_image(stObj->pt, texImage)) {
449      /* this image will fit in the existing texture object's memory */
450      pipe_resource_reference(&stImage->pt, stObj->pt);
451      return GL_TRUE;
452   }
453
454   /* The parent texture object does not have space for this image */
455
456   pipe_resource_reference(&stObj->pt, NULL);
457   pipe_sampler_view_release(st->pipe, &stObj->sampler_view);
458
459   if (!guess_and_alloc_texture(st, stObj, stImage)) {
460      /* Probably out of memory.
461       * Try flushing any pending rendering, then retry.
462       */
463      st_finish(st);
464      if (!guess_and_alloc_texture(st, stObj, stImage)) {
465         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage");
466         return GL_FALSE;
467      }
468   }
469
470   if (stObj->pt &&
471       st_texture_match_image(stObj->pt, texImage)) {
472      /* The image will live in the object's mipmap memory */
473      pipe_resource_reference(&stImage->pt, stObj->pt);
474      assert(stImage->pt);
475      return GL_TRUE;
476   }
477   else {
478      /* Create a new, temporary texture/resource/buffer to hold this
479       * one texture image.  Note that when we later access this image
480       * (either for mapping or copying) we'll want to always specify
481       * mipmap level=0, even if the image represents some other mipmap
482       * level.
483       */
484      enum pipe_format format =
485         st_mesa_format_to_pipe_format(texImage->TexFormat);
486      GLuint bindings = default_bindings(st, format);
487      GLuint ptWidth, ptHeight, ptDepth, ptLayers;
488
489      st_gl_texture_dims_to_pipe_dims(stObj->base.Target,
490                                      width, height, depth,
491                                      &ptWidth, &ptHeight, &ptDepth, &ptLayers);
492
493      stImage->pt = st_texture_create(st,
494                                      gl_target_to_pipe(stObj->base.Target),
495                                      format,
496                                      0, /* lastLevel */
497                                      ptWidth,
498                                      ptHeight,
499                                      ptDepth,
500                                      ptLayers,
501                                      bindings);
502      return stImage->pt != NULL;
503   }
504}
505
506
507/**
508 * Preparation prior to glTexImage.  Basically check the 'surface_based'
509 * field and switch to a "normal" tex image if necessary.
510 */
511static void
512prep_teximage(struct gl_context *ctx, struct gl_texture_image *texImage,
513              GLenum format, GLenum type)
514{
515   struct gl_texture_object *texObj = texImage->TexObject;
516   struct st_texture_object *stObj = st_texture_object(texObj);
517
518   /* switch to "normal" */
519   if (stObj->surface_based) {
520      const GLenum target = texObj->Target;
521      const GLuint level = texImage->Level;
522      gl_format texFormat;
523
524      _mesa_clear_texture_object(ctx, texObj);
525      pipe_resource_reference(&stObj->pt, NULL);
526
527      /* oops, need to init this image again */
528      texFormat = _mesa_choose_texture_format(ctx, texObj, target, level,
529                                              texImage->InternalFormat, format,
530                                              type);
531
532      _mesa_init_teximage_fields(ctx, texImage,
533                                 texImage->Width, texImage->Height,
534                                 texImage->Depth, texImage->Border,
535                                 texImage->InternalFormat, texFormat);
536
537      stObj->surface_based = GL_FALSE;
538   }
539}
540
541
542static void
543st_TexImage(struct gl_context * ctx, GLuint dims,
544            struct gl_texture_image *texImage,
545            GLenum format, GLenum type, const void *pixels,
546            const struct gl_pixelstore_attrib *unpack)
547{
548   prep_teximage(ctx, texImage, format, type);
549   _mesa_store_teximage(ctx, dims, texImage, format, type, pixels, unpack);
550}
551
552
553static void
554st_CompressedTexImage(struct gl_context *ctx, GLuint dims,
555                      struct gl_texture_image *texImage,
556                      GLsizei imageSize, const GLvoid *data)
557{
558   prep_teximage(ctx, texImage, GL_NONE, GL_NONE);
559   _mesa_store_compressed_teximage(ctx, dims, texImage, imageSize, data);
560}
561
562
563
564/**
565 * glGetTexImage() helper: decompress a compressed texture by rendering
566 * a textured quad.  Store the results in the user's buffer.
567 */
568static void
569decompress_with_blit(struct gl_context * ctx,
570                     GLenum format, GLenum type, GLvoid *pixels,
571                     struct gl_texture_image *texImage)
572{
573   struct st_context *st = st_context(ctx);
574   struct pipe_context *pipe = st->pipe;
575   struct pipe_screen *screen = pipe->screen;
576   const GLuint width = texImage->Width;
577   const GLuint height = texImage->Height;
578   const GLuint depth = texImage->Depth;
579   struct pipe_resource *src = st_texture_object(texImage->TexObject)->pt;
580   struct pipe_resource *dst;
581   struct pipe_resource dst_templ;
582   enum pipe_format pipe_format;
583   gl_format mesa_format;
584   GLenum gl_target = texImage->TexObject->Target;
585   enum pipe_texture_target pipe_target;
586   struct pipe_blit_info blit;
587   unsigned bind = (PIPE_BIND_RENDER_TARGET | PIPE_BIND_TRANSFER_READ);
588   struct pipe_transfer *tex_xfer;
589   ubyte *map;
590
591   /* GetTexImage only returns a single face for cubemaps. */
592   if (gl_target == GL_TEXTURE_CUBE_MAP) {
593      gl_target = GL_TEXTURE_2D;
594   }
595
596   pipe_target = gl_target_to_pipe(gl_target);
597
598   /* Find the best match for the format+type combo. */
599   pipe_format = st_choose_format(pipe->screen, GL_RGBA8, format, type,
600                                  pipe_target, 0, bind);
601   if (pipe_format == PIPE_FORMAT_NONE) {
602      /* unable to get an rgba format!?! */
603      _mesa_problem(ctx, "%s: cannot find a supported format", __func__);
604      return;
605   }
606
607   /* create the destination texture */
608   memset(&dst_templ, 0, sizeof(dst_templ));
609   dst_templ.target = pipe_target;
610   dst_templ.format = pipe_format;
611   dst_templ.bind = bind;
612   dst_templ.usage = PIPE_USAGE_STAGING;
613
614   st_gl_texture_dims_to_pipe_dims(gl_target, width, height, depth,
615                                   &dst_templ.width0, &dst_templ.height0,
616                                   &dst_templ.depth0, &dst_templ.array_size);
617
618   dst = screen->resource_create(screen, &dst_templ);
619   if (!dst) {
620      _mesa_problem(ctx, "%s: cannot create a temporary texture", __func__);
621      return;
622   }
623
624   blit.src.resource = src;
625   blit.src.level = texImage->Level;
626   blit.src.format = util_format_linear(src->format);
627   blit.dst.resource = dst;
628   blit.dst.level = 0;
629   blit.dst.format = dst->format;
630   blit.src.box.x = blit.dst.box.x = 0;
631   blit.src.box.y = blit.dst.box.y = 0;
632   blit.src.box.z = texImage->Face;
633   blit.dst.box.z = 0;
634   blit.src.box.width = blit.dst.box.width = width;
635   blit.src.box.height = blit.dst.box.height = height;
636   blit.src.box.depth = blit.dst.box.depth = depth;
637   blit.mask = PIPE_MASK_RGBA;
638   blit.filter = PIPE_TEX_FILTER_NEAREST;
639   blit.scissor_enable = FALSE;
640
641   /* blit/render/decompress */
642   st->pipe->blit(st->pipe, &blit);
643
644   pixels = _mesa_map_pbo_dest(ctx, &ctx->Pack, pixels);
645
646   map = pipe_transfer_map_3d(pipe, dst, 0, PIPE_TRANSFER_READ,
647                              0, 0, 0, width, height, depth, &tex_xfer);
648   if (!map) {
649      goto end;
650   }
651
652   mesa_format = st_pipe_format_to_mesa_format(pipe_format);
653
654   /* copy/pack data into user buffer */
655   if (_mesa_format_matches_format_and_type(mesa_format, format, type,
656                                            ctx->Pack.SwapBytes)) {
657      /* memcpy */
658      const uint bytesPerRow = width * util_format_get_blocksize(pipe_format);
659      GLuint row, slice;
660
661      for (slice = 0; slice < depth; slice++) {
662         ubyte *slice_map = map;
663
664         for (row = 0; row < height; row++) {
665            GLvoid *dest = _mesa_image_address3d(&ctx->Pack, pixels,
666                                                 width, height, format,
667                                                 type, slice, row, 0);
668            memcpy(dest, slice_map, bytesPerRow);
669            slice_map += tex_xfer->stride;
670         }
671         map += tex_xfer->layer_stride;
672      }
673   }
674   else {
675      /* format translation via floats */
676      GLuint row, slice;
677      enum pipe_format pformat = util_format_linear(dst->format);
678      GLfloat *rgba;
679
680      rgba = malloc(width * 4 * sizeof(GLfloat));
681      if (!rgba) {
682         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glGetTexImage()");
683         goto end;
684      }
685
686      for (slice = 0; slice < depth; slice++) {
687         for (row = 0; row < height; row++) {
688            const GLbitfield transferOps = 0x0; /* bypassed for glGetTexImage() */
689            GLvoid *dest = _mesa_image_address3d(&ctx->Pack, pixels,
690                                                 width, height, format,
691                                                 type, slice, row, 0);
692
693            if (ST_DEBUG & DEBUG_FALLBACK)
694               debug_printf("%s: fallback format translation\n", __FUNCTION__);
695
696            /* get float[4] rgba row from surface */
697            pipe_get_tile_rgba_format(tex_xfer, map, 0, row, width, 1,
698                                      pformat, rgba);
699
700            _mesa_pack_rgba_span_float(ctx, width, (GLfloat (*)[4]) rgba, format,
701                                       type, dest, &ctx->Pack, transferOps);
702         }
703         map += tex_xfer->layer_stride;
704      }
705
706      free(rgba);
707   }
708
709end:
710   if (map)
711      pipe_transfer_unmap(pipe, tex_xfer);
712
713   _mesa_unmap_pbo_dest(ctx, &ctx->Pack);
714   pipe_resource_reference(&dst, NULL);
715}
716
717
718
719/**
720 * Called via ctx->Driver.GetTexImage()
721 */
722static void
723st_GetTexImage(struct gl_context * ctx,
724               GLenum format, GLenum type, GLvoid * pixels,
725               struct gl_texture_image *texImage)
726{
727   struct st_texture_image *stImage = st_texture_image(texImage);
728
729   if (stImage->pt && util_format_is_s3tc(stImage->pt->format)) {
730      /* Need to decompress the texture.
731       * We'll do this by rendering a textured quad (which is hopefully
732       * faster than using the fallback code in texcompress.c).
733       * Note that we only expect RGBA formats (no Z/depth formats).
734       */
735      decompress_with_blit(ctx, format, type, pixels, texImage);
736   }
737   else {
738      _mesa_get_teximage(ctx, format, type, pixels, texImage);
739   }
740}
741
742
743/**
744 * Do a CopyTexSubImage operation using a read transfer from the source,
745 * a write transfer to the destination and get_tile()/put_tile() to access
746 * the pixels/texels.
747 *
748 * Note: srcY=0=TOP of renderbuffer
749 */
750static void
751fallback_copy_texsubimage(struct gl_context *ctx,
752                          struct st_renderbuffer *strb,
753                          struct st_texture_image *stImage,
754                          GLenum baseFormat,
755                          GLint destX, GLint destY, GLint destZ,
756                          GLint srcX, GLint srcY,
757                          GLsizei width, GLsizei height)
758{
759   struct st_context *st = st_context(ctx);
760   struct pipe_context *pipe = st->pipe;
761   struct pipe_transfer *src_trans;
762   GLvoid *texDest;
763   enum pipe_transfer_usage transfer_usage;
764   void *map;
765
766   if (ST_DEBUG & DEBUG_FALLBACK)
767      debug_printf("%s: fallback processing\n", __FUNCTION__);
768
769   if (st_fb_orientation(ctx->ReadBuffer) == Y_0_TOP) {
770      srcY = strb->Base.Height - srcY - height;
771   }
772
773   map = pipe_transfer_map(pipe,
774                           strb->texture,
775                           strb->rtt_level,
776                           strb->rtt_face + strb->rtt_slice,
777                           PIPE_TRANSFER_READ,
778                           srcX, srcY,
779                           width, height, &src_trans);
780
781   if ((baseFormat == GL_DEPTH_COMPONENT ||
782        baseFormat == GL_DEPTH_STENCIL) &&
783       util_format_is_depth_and_stencil(stImage->pt->format))
784      transfer_usage = PIPE_TRANSFER_READ_WRITE;
785   else
786      transfer_usage = PIPE_TRANSFER_WRITE;
787
788   /* XXX this used to ignore destZ param */
789   texDest = st_texture_image_map(st, stImage, destZ, transfer_usage,
790                                  destX, destY, width, height);
791
792   if (baseFormat == GL_DEPTH_COMPONENT ||
793       baseFormat == GL_DEPTH_STENCIL) {
794      const GLboolean scaleOrBias = (ctx->Pixel.DepthScale != 1.0F ||
795                                     ctx->Pixel.DepthBias != 0.0F);
796      GLint row, yStep;
797      uint *data;
798
799      /* determine bottom-to-top vs. top-to-bottom order for src buffer */
800      if (st_fb_orientation(ctx->ReadBuffer) == Y_0_TOP) {
801         srcY = height - 1;
802         yStep = -1;
803      }
804      else {
805         srcY = 0;
806         yStep = 1;
807      }
808
809      data = malloc(width * sizeof(uint));
810
811      if (data) {
812         /* To avoid a large temp memory allocation, do copy row by row */
813         for (row = 0; row < height; row++, srcY += yStep) {
814            pipe_get_tile_z(src_trans, map, 0, srcY, width, 1, data);
815            if (scaleOrBias) {
816               _mesa_scale_and_bias_depth_uint(ctx, width, data);
817            }
818            pipe_put_tile_z(stImage->transfer, texDest, 0, row, width, 1,
819                            data);
820         }
821      }
822      else {
823         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexSubImage()");
824      }
825
826      free(data);
827   }
828   else {
829      /* RGBA format */
830      GLfloat *tempSrc =
831         malloc(width * height * 4 * sizeof(GLfloat));
832
833      if (tempSrc && texDest) {
834         const GLint dims = 2;
835         const GLint dstRowStride = stImage->transfer->stride;
836         struct gl_texture_image *texImage = &stImage->base;
837         struct gl_pixelstore_attrib unpack = ctx->DefaultPacking;
838
839         if (st_fb_orientation(ctx->ReadBuffer) == Y_0_TOP) {
840            unpack.Invert = GL_TRUE;
841         }
842
843         /* get float/RGBA image from framebuffer */
844         /* XXX this usually involves a lot of int/float conversion.
845          * try to avoid that someday.
846          */
847         pipe_get_tile_rgba_format(src_trans, map, 0, 0, width, height,
848                                   util_format_linear(strb->texture->format),
849                                   tempSrc);
850
851         /* Store into texture memory.
852          * Note that this does some special things such as pixel transfer
853          * ops and format conversion.  In particular, if the dest tex format
854          * is actually RGBA but the user created the texture as GL_RGB we
855          * need to fill-in/override the alpha channel with 1.0.
856          */
857         _mesa_texstore(ctx, dims,
858                        texImage->_BaseFormat,
859                        texImage->TexFormat,
860                        dstRowStride,
861                        (GLubyte **) &texDest,
862                        width, height, 1,
863                        GL_RGBA, GL_FLOAT, tempSrc, /* src */
864                        &unpack);
865      }
866      else {
867         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage");
868      }
869
870      free(tempSrc);
871   }
872
873   st_texture_image_unmap(st, stImage);
874   pipe->transfer_unmap(pipe, src_trans);
875}
876
877
878
879/**
880 * If the format of the src renderbuffer and the format of the dest
881 * texture are compatible (in terms of blitting), return a TGSI writemask
882 * to be used during the blit.
883 * If the src/dest are incompatible, return 0.
884 */
885static unsigned
886compatible_src_dst_formats(struct gl_context *ctx,
887                           const struct gl_renderbuffer *src,
888                           const struct gl_texture_image *dst)
889{
890   /* Get logical base formats for the src and dest.
891    * That is, use the user-requested formats and not the actual, device-
892    * chosen formats.
893    * For example, the user may have requested an A8 texture but the
894    * driver may actually be using an RGBA texture format.  When we
895    * copy/blit to that texture, we only want to copy the Alpha channel
896    * and not the RGB channels.
897    *
898    * Similarly, when the src FBO was created an RGB format may have been
899    * requested but the driver actually chose an RGBA format.  In that case,
900    * we don't want to copy the undefined Alpha channel to the dest texture
901    * (it should be 1.0).
902    */
903   const GLenum srcFormat = _mesa_base_fbo_format(ctx, src->InternalFormat);
904   const GLenum dstFormat = _mesa_base_tex_format(ctx, dst->InternalFormat);
905
906   /**
907    * XXX when we have red-only and red/green renderbuffers we'll need
908    * to add more cases here (or implement a general-purpose routine that
909    * queries the existance of the R,G,B,A channels in the src and dest).
910    */
911   if (srcFormat == dstFormat) {
912      /* This is the same as matching_base_formats, which should
913       * always pass, as it did previously.
914       */
915      return TGSI_WRITEMASK_XYZW;
916   }
917   else if (srcFormat == GL_RGB && dstFormat == GL_RGBA) {
918      /* Make sure that A in the dest is 1.  The actual src format
919       * may be RGBA and have undefined A values.
920       */
921      return TGSI_WRITEMASK_XYZ;
922   }
923   else if (srcFormat == GL_RGBA && dstFormat == GL_RGB) {
924      /* Make sure that A in the dest is 1.  The actual dst format
925       * may be RGBA and will need A=1 to provide proper alpha values
926       * when sampled later.
927       */
928      return TGSI_WRITEMASK_XYZ;
929   }
930   else {
931      if (ST_DEBUG & DEBUG_FALLBACK)
932         debug_printf("%s failed for src %s, dst %s\n",
933                      __FUNCTION__,
934                      _mesa_lookup_enum_by_nr(srcFormat),
935                      _mesa_lookup_enum_by_nr(dstFormat));
936
937      /* Otherwise fail.
938       */
939      return 0;
940   }
941}
942
943
944
945/**
946 * Do a CopyTex[Sub]Image1/2/3D() using a hardware (blit) path if possible.
947 * Note that the region to copy has already been clipped so we know we
948 * won't read from outside the source renderbuffer's bounds.
949 *
950 * Note: srcY=0=Bottom of renderbuffer (GL convention)
951 */
952static void
953st_CopyTexSubImage(struct gl_context *ctx, GLuint dims,
954                   struct gl_texture_image *texImage,
955                   GLint destX, GLint destY, GLint destZ,
956                   struct gl_renderbuffer *rb,
957                   GLint srcX, GLint srcY, GLsizei width, GLsizei height)
958{
959   struct st_texture_image *stImage = st_texture_image(texImage);
960   const GLenum texBaseFormat = texImage->_BaseFormat;
961   struct st_renderbuffer *strb = st_renderbuffer(rb);
962   struct st_context *st = st_context(ctx);
963   struct pipe_context *pipe = st->pipe;
964   struct pipe_screen *screen = pipe->screen;
965   enum pipe_format dest_format, src_format;
966   GLuint color_writemask;
967   struct pipe_surface *dest_surface = NULL;
968   GLboolean do_flip = (st_fb_orientation(ctx->ReadBuffer) == Y_0_TOP);
969   struct pipe_surface surf_tmpl;
970   unsigned dst_usage;
971   unsigned blit_mask;
972   GLint srcY0, srcY1;
973
974   /* make sure finalize_textures has been called?
975    */
976   if (0) st_validate_state(st);
977
978   if (!strb || !strb->surface || !stImage->pt) {
979      debug_printf("%s: null strb or stImage\n", __FUNCTION__);
980      return;
981   }
982
983   assert(strb);
984   assert(strb->surface);
985   assert(stImage->pt);
986
987   src_format = strb->surface->format;
988   dest_format = stImage->pt->format;
989
990   if (do_flip) {
991      srcY1 = strb->Base.Height - srcY - height;
992      srcY0 = srcY1 + height;
993   }
994   else {
995      srcY0 = srcY;
996      srcY1 = srcY0 + height;
997   }
998
999   if (ctx->_ImageTransferState) {
1000      goto fallback;
1001   }
1002
1003   /* Compressed and subsampled textures aren't supported for blitting. */
1004   if (!util_format_is_plain(dest_format)) {
1005      goto fallback;
1006   }
1007
1008   if (texImage->TexObject->Target == GL_TEXTURE_1D_ARRAY) {
1009      /* 1D arrays might be thought of as 2D images but the actual layout
1010       * might not be that way.  At some points, we convert OpenGL's 1D
1011       * array 'height' into gallium 'layers' and that prevents the blit
1012       * utility code from doing the right thing.  Simpy use the memcpy-based
1013       * fallback.
1014       */
1015      goto fallback;
1016   }
1017
1018   /* Set the blit writemask. */
1019   switch (texBaseFormat) {
1020   case GL_DEPTH_STENCIL:
1021      switch (strb->Base._BaseFormat) {
1022      case GL_DEPTH_STENCIL:
1023         blit_mask = PIPE_MASK_ZS;
1024         break;
1025      case GL_DEPTH_COMPONENT:
1026         blit_mask = PIPE_MASK_Z;
1027         break;
1028      case GL_STENCIL_INDEX:
1029         blit_mask = PIPE_MASK_S;
1030         break;
1031      default:
1032         assert(0);
1033         return;
1034      }
1035      dst_usage = PIPE_BIND_DEPTH_STENCIL;
1036      break;
1037
1038   case GL_DEPTH_COMPONENT:
1039      blit_mask = PIPE_MASK_Z;
1040      dst_usage = PIPE_BIND_DEPTH_STENCIL;
1041      break;
1042
1043   default:
1044      /* Colorbuffers.
1045       *
1046       * Determine if the src framebuffer and dest texture have the same
1047       * base format.  We need this to detect a case such as the framebuffer
1048       * being GL_RGBA but the texture being GL_RGB.  If the actual hardware
1049       * texture format stores RGBA we need to set A=1 (overriding the
1050       * framebuffer's alpha values).
1051       *
1052       * XXX util_blit_pixels doesn't support MSAA resolve, so always use
1053       *     pipe->blit
1054       */
1055      if (texBaseFormat == strb->Base._BaseFormat ||
1056          strb->texture->nr_samples > 1) {
1057         blit_mask = PIPE_MASK_RGBA;
1058      }
1059      else {
1060         blit_mask = 0;
1061      }
1062      dst_usage = PIPE_BIND_RENDER_TARGET;
1063   }
1064
1065   /* Blit the texture.
1066    * This supports flipping, format conversions, and downsampling.
1067    */
1068   if (blit_mask) {
1069      /* If stImage->pt is an independent image (not a pointer into a full
1070       * mipmap) stImage->pt.last_level will be zero and we need to use that
1071       * as the dest level.
1072       */
1073      unsigned dstLevel = MIN2(stImage->base.Level, stImage->pt->last_level);
1074      struct pipe_blit_info blit;
1075
1076      memset(&blit, 0, sizeof(blit));
1077      blit.src.resource = strb->texture;
1078      blit.src.format = src_format;
1079      blit.src.level = strb->surface->u.tex.level;
1080      blit.src.box.x = srcX;
1081      blit.src.box.y = srcY0;
1082      blit.src.box.z = strb->surface->u.tex.first_layer;
1083      blit.src.box.width = width;
1084      blit.src.box.height = srcY1 - srcY0;
1085      blit.src.box.depth = 1;
1086      blit.dst.resource = stImage->pt;
1087      blit.dst.format = dest_format;
1088      blit.dst.level = dstLevel;
1089      blit.dst.box.x = destX;
1090      blit.dst.box.y = destY;
1091      blit.dst.box.z = stImage->base.Face + destZ;
1092      blit.dst.box.width = width;
1093      blit.dst.box.height = height;
1094      blit.dst.box.depth = 1;
1095      blit.mask = blit_mask;
1096      blit.filter = PIPE_TEX_FILTER_NEAREST;
1097
1098      /* try resource_copy_region in case the format is not supported
1099       * for rendering */
1100      if (util_try_blit_via_copy_region(pipe, &blit)) {
1101         return; /* done */
1102      }
1103
1104      /* check the format support */
1105      if (!screen->is_format_supported(screen, src_format,
1106                                       PIPE_TEXTURE_2D, 0,
1107                                       PIPE_BIND_SAMPLER_VIEW) ||
1108          !screen->is_format_supported(screen, dest_format,
1109                                       PIPE_TEXTURE_2D, 0,
1110                                       dst_usage)) {
1111         goto fallback;
1112      }
1113
1114      pipe->blit(pipe, &blit);
1115      return;
1116   }
1117
1118   /* try u_blit */
1119   color_writemask = compatible_src_dst_formats(ctx, &strb->Base, texImage);
1120
1121   if (!color_writemask ||
1122       !screen->is_format_supported(screen, src_format,
1123                                    PIPE_TEXTURE_2D, 0,
1124                                    PIPE_BIND_SAMPLER_VIEW) ||
1125       !screen->is_format_supported(screen, dest_format,
1126                                    PIPE_TEXTURE_2D, 0,
1127                                    dst_usage)) {
1128      goto fallback;
1129   }
1130
1131   memset(&surf_tmpl, 0, sizeof(surf_tmpl));
1132   surf_tmpl.format = util_format_linear(stImage->pt->format);
1133   surf_tmpl.u.tex.level = stImage->base.Level;
1134   surf_tmpl.u.tex.first_layer = stImage->base.Face + destZ;
1135   surf_tmpl.u.tex.last_layer = stImage->base.Face + destZ;
1136
1137   dest_surface = pipe->create_surface(pipe, stImage->pt,
1138                                       &surf_tmpl);
1139   util_blit_pixels(st->blit,
1140                    strb->texture,
1141                    strb->surface->u.tex.level,
1142                    srcX, srcY0,
1143                    srcX + width, srcY1,
1144                    strb->surface->u.tex.first_layer,
1145                    dest_surface,
1146                    destX, destY,
1147                    destX + width, destY + height,
1148                    0.0, PIPE_TEX_MIPFILTER_NEAREST,
1149                    color_writemask, 0);
1150   pipe_surface_reference(&dest_surface, NULL);
1151   return;
1152
1153fallback:
1154   /* software fallback */
1155   fallback_copy_texsubimage(ctx,
1156                             strb, stImage, texBaseFormat,
1157                             destX, destY, destZ,
1158                             srcX, srcY, width, height);
1159}
1160
1161
1162/**
1163 * Copy image data from stImage into the texture object 'stObj' at level
1164 * 'dstLevel'.
1165 */
1166static void
1167copy_image_data_to_texture(struct st_context *st,
1168			   struct st_texture_object *stObj,
1169                           GLuint dstLevel,
1170			   struct st_texture_image *stImage)
1171{
1172   /* debug checks */
1173   {
1174      const struct gl_texture_image *dstImage =
1175         stObj->base.Image[stImage->base.Face][dstLevel];
1176      assert(dstImage);
1177      assert(dstImage->Width == stImage->base.Width);
1178      assert(dstImage->Height == stImage->base.Height);
1179      assert(dstImage->Depth == stImage->base.Depth);
1180   }
1181
1182   if (stImage->pt) {
1183      /* Copy potentially with the blitter:
1184       */
1185      GLuint src_level;
1186      if (stImage->pt->last_level == 0)
1187         src_level = 0;
1188      else
1189         src_level = stImage->base.Level;
1190
1191      assert(src_level <= stImage->pt->last_level);
1192      assert(u_minify(stImage->pt->width0, src_level) == stImage->base.Width);
1193      assert(stImage->pt->target == PIPE_TEXTURE_1D_ARRAY ||
1194             u_minify(stImage->pt->height0, src_level) == stImage->base.Height);
1195      assert(stImage->pt->target == PIPE_TEXTURE_2D_ARRAY ||
1196             stImage->pt->target == PIPE_TEXTURE_CUBE_ARRAY ||
1197             u_minify(stImage->pt->depth0, src_level) == stImage->base.Depth);
1198
1199      st_texture_image_copy(st->pipe,
1200                            stObj->pt, dstLevel,  /* dest texture, level */
1201                            stImage->pt, src_level, /* src texture, level */
1202                            stImage->base.Face);
1203
1204      pipe_resource_reference(&stImage->pt, NULL);
1205   }
1206   else if (stImage->TexData) {
1207      /* Copy from malloc'd memory */
1208      /* XXX this should be re-examined/tested with a compressed format */
1209      GLuint blockSize = util_format_get_blocksize(stObj->pt->format);
1210      GLuint srcRowStride = stImage->base.Width * blockSize;
1211      GLuint srcSliceStride = stImage->base.Height * srcRowStride;
1212      st_texture_image_data(st,
1213                            stObj->pt,
1214                            stImage->base.Face,
1215                            dstLevel,
1216                            stImage->TexData,
1217                            srcRowStride,
1218                            srcSliceStride);
1219      _mesa_align_free(stImage->TexData);
1220      stImage->TexData = NULL;
1221   }
1222
1223   pipe_resource_reference(&stImage->pt, stObj->pt);
1224}
1225
1226
1227/**
1228 * Called during state validation.  When this function is finished,
1229 * the texture object should be ready for rendering.
1230 * \return GL_TRUE for success, GL_FALSE for failure (out of mem)
1231 */
1232GLboolean
1233st_finalize_texture(struct gl_context *ctx,
1234		    struct pipe_context *pipe,
1235		    struct gl_texture_object *tObj)
1236{
1237   struct st_context *st = st_context(ctx);
1238   struct st_texture_object *stObj = st_texture_object(tObj);
1239   const GLuint nr_faces = (stObj->base.Target == GL_TEXTURE_CUBE_MAP) ? 6 : 1;
1240   GLuint face;
1241   struct st_texture_image *firstImage;
1242   enum pipe_format firstImageFormat;
1243   GLuint ptWidth, ptHeight, ptDepth, ptLayers;
1244
1245   if (_mesa_is_texture_complete(tObj, &tObj->Sampler)) {
1246      /* The texture is complete and we know exactly how many mipmap levels
1247       * are present/needed.  This is conditional because we may be called
1248       * from the st_generate_mipmap() function when the texture object is
1249       * incomplete.  In that case, we'll have set stObj->lastLevel before
1250       * we get here.
1251       */
1252      if (stObj->base.Sampler.MinFilter == GL_LINEAR ||
1253          stObj->base.Sampler.MinFilter == GL_NEAREST)
1254         stObj->lastLevel = stObj->base.BaseLevel;
1255      else
1256         stObj->lastLevel = stObj->base._MaxLevel;
1257   }
1258
1259   if (tObj->Target == GL_TEXTURE_BUFFER) {
1260      struct st_buffer_object *st_obj = st_buffer_object(tObj->BufferObject);
1261
1262      if (st_obj->buffer != stObj->pt) {
1263         pipe_resource_reference(&stObj->pt, st_obj->buffer);
1264         pipe_sampler_view_release(st->pipe, &stObj->sampler_view);
1265         stObj->width0 = stObj->pt->width0 / _mesa_get_format_bytes(tObj->_BufferObjectFormat);
1266         stObj->height0 = 1;
1267         stObj->depth0 = 1;
1268      }
1269      return GL_TRUE;
1270
1271   }
1272
1273   firstImage = st_texture_image(stObj->base.Image[0][stObj->base.BaseLevel]);
1274   assert(firstImage);
1275
1276   /* If both firstImage and stObj point to a texture which can contain
1277    * all active images, favour firstImage.  Note that because of the
1278    * completeness requirement, we know that the image dimensions
1279    * will match.
1280    */
1281   if (firstImage->pt &&
1282       firstImage->pt != stObj->pt &&
1283       (!stObj->pt || firstImage->pt->last_level >= stObj->pt->last_level)) {
1284      pipe_resource_reference(&stObj->pt, firstImage->pt);
1285      pipe_sampler_view_release(st->pipe, &stObj->sampler_view);
1286   }
1287
1288   /* Find gallium format for the Mesa texture */
1289   firstImageFormat = st_mesa_format_to_pipe_format(firstImage->base.TexFormat);
1290
1291   /* Find size of level=0 Gallium mipmap image, plus number of texture layers */
1292   {
1293      GLuint width, height, depth;
1294      if (!guess_base_level_size(stObj->base.Target,
1295                                 firstImage->base.Width2,
1296                                 firstImage->base.Height2,
1297                                 firstImage->base.Depth2,
1298                                 firstImage->base.Level,
1299                                 &width, &height, &depth)) {
1300         width = stObj->width0;
1301         height = stObj->height0;
1302         depth = stObj->depth0;
1303      }
1304      /* convert GL dims to Gallium dims */
1305      st_gl_texture_dims_to_pipe_dims(stObj->base.Target, width, height, depth,
1306                                      &ptWidth, &ptHeight, &ptDepth, &ptLayers);
1307   }
1308
1309   /* If we already have a gallium texture, check that it matches the texture
1310    * object's format, target, size, num_levels, etc.
1311    */
1312   if (stObj->pt) {
1313      if (stObj->pt->target != gl_target_to_pipe(stObj->base.Target) ||
1314          !st_sampler_compat_formats(stObj->pt->format, firstImageFormat) ||
1315          stObj->pt->last_level < stObj->lastLevel ||
1316          stObj->pt->width0 != ptWidth ||
1317          stObj->pt->height0 != ptHeight ||
1318          stObj->pt->depth0 != ptDepth ||
1319          stObj->pt->array_size != ptLayers)
1320      {
1321         /* The gallium texture does not match the Mesa texture so delete the
1322          * gallium texture now.  We'll make a new one below.
1323          */
1324         pipe_resource_reference(&stObj->pt, NULL);
1325         pipe_sampler_view_release(st->pipe, &stObj->sampler_view);
1326         st->dirty.st |= ST_NEW_FRAMEBUFFER;
1327      }
1328   }
1329
1330   /* May need to create a new gallium texture:
1331    */
1332   if (!stObj->pt) {
1333      GLuint bindings = default_bindings(st, firstImageFormat);
1334
1335      stObj->pt = st_texture_create(st,
1336                                    gl_target_to_pipe(stObj->base.Target),
1337                                    firstImageFormat,
1338                                    stObj->lastLevel,
1339                                    ptWidth,
1340                                    ptHeight,
1341                                    ptDepth,
1342                                    ptLayers,
1343                                    bindings);
1344
1345      if (!stObj->pt) {
1346         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage");
1347         return GL_FALSE;
1348      }
1349   }
1350
1351   /* Pull in any images not in the object's texture:
1352    */
1353   for (face = 0; face < nr_faces; face++) {
1354      GLuint level;
1355      for (level = stObj->base.BaseLevel; level <= stObj->lastLevel; level++) {
1356         struct st_texture_image *stImage =
1357            st_texture_image(stObj->base.Image[face][level]);
1358
1359         /* Need to import images in main memory or held in other textures.
1360          */
1361         if (stImage && stObj->pt != stImage->pt) {
1362            if (level == 0 ||
1363                (stImage->base.Width == u_minify(stObj->width0, level) &&
1364                 stImage->base.Height == u_minify(stObj->height0, level) &&
1365                 stImage->base.Depth == u_minify(stObj->depth0, level))) {
1366               /* src image fits expected dest mipmap level size */
1367               copy_image_data_to_texture(st, stObj, level, stImage);
1368            }
1369         }
1370      }
1371   }
1372
1373   return GL_TRUE;
1374}
1375
1376
1377/**
1378 * Called via ctx->Driver.AllocTextureStorage() to allocate texture memory
1379 * for a whole mipmap stack.
1380 */
1381static GLboolean
1382st_AllocTextureStorage(struct gl_context *ctx,
1383                       struct gl_texture_object *texObj,
1384                       GLsizei levels, GLsizei width,
1385                       GLsizei height, GLsizei depth)
1386{
1387   const GLuint numFaces = _mesa_num_tex_faces(texObj->Target);
1388   struct st_context *st = st_context(ctx);
1389   struct st_texture_object *stObj = st_texture_object(texObj);
1390   GLuint ptWidth, ptHeight, ptDepth, ptLayers, bindings;
1391   enum pipe_format fmt;
1392   GLint level;
1393
1394   assert(levels > 0);
1395
1396   /* Save the level=0 dimensions */
1397   stObj->width0 = width;
1398   stObj->height0 = height;
1399   stObj->depth0 = depth;
1400   stObj->lastLevel = levels - 1;
1401
1402   fmt = st_mesa_format_to_pipe_format(texObj->Image[0][0]->TexFormat);
1403
1404   bindings = default_bindings(st, fmt);
1405
1406   st_gl_texture_dims_to_pipe_dims(texObj->Target,
1407                                   width, height, depth,
1408                                   &ptWidth, &ptHeight, &ptDepth, &ptLayers);
1409
1410   stObj->pt = st_texture_create(st,
1411                                 gl_target_to_pipe(texObj->Target),
1412                                 fmt,
1413                                 levels,
1414                                 ptWidth,
1415                                 ptHeight,
1416                                 ptDepth,
1417                                 ptLayers,
1418                                 bindings);
1419   if (!stObj->pt)
1420      return GL_FALSE;
1421
1422   /* Set image resource pointers */
1423   for (level = 0; level < levels; level++) {
1424      GLuint face;
1425      for (face = 0; face < numFaces; face++) {
1426         struct st_texture_image *stImage =
1427            st_texture_image(texObj->Image[face][level]);
1428         pipe_resource_reference(&stImage->pt, stObj->pt);
1429      }
1430   }
1431
1432   return GL_TRUE;
1433}
1434
1435
1436static GLboolean
1437st_TestProxyTexImage(struct gl_context *ctx, GLenum target,
1438                     GLint level, gl_format format,
1439                     GLint width, GLint height,
1440                     GLint depth, GLint border)
1441{
1442   struct st_context *st = st_context(ctx);
1443   struct pipe_context *pipe = st->pipe;
1444
1445   if (width == 0 || height == 0 || depth == 0) {
1446      /* zero-sized images are legal, and always fit! */
1447      return GL_TRUE;
1448   }
1449
1450   if (pipe->screen->can_create_resource) {
1451      /* Ask the gallium driver if the texture is too large */
1452      struct gl_texture_object *texObj =
1453         _mesa_get_current_tex_object(ctx, target);
1454      struct pipe_resource pt;
1455
1456      /* Setup the pipe_resource object
1457       */
1458      memset(&pt, 0, sizeof(pt));
1459
1460      pt.target = gl_target_to_pipe(target);
1461      pt.format = st_mesa_format_to_pipe_format(format);
1462
1463      st_gl_texture_dims_to_pipe_dims(target,
1464                                      width, height, depth,
1465                                      &pt.width0, &pt.height0,
1466                                      &pt.depth0, &pt.array_size);
1467
1468      if (level == 0 && (texObj->Sampler.MinFilter == GL_LINEAR ||
1469                         texObj->Sampler.MinFilter == GL_NEAREST)) {
1470         /* assume just one mipmap level */
1471         pt.last_level = 0;
1472      }
1473      else {
1474         /* assume a full set of mipmaps */
1475         pt.last_level = _mesa_logbase2(MAX3(width, height, depth));
1476      }
1477
1478      return pipe->screen->can_create_resource(pipe->screen, &pt);
1479   }
1480   else {
1481      /* Use core Mesa fallback */
1482      return _mesa_test_proxy_teximage(ctx, target, level, format,
1483                                       width, height, depth, border);
1484   }
1485}
1486
1487
1488void
1489st_init_texture_functions(struct dd_function_table *functions)
1490{
1491   functions->ChooseTextureFormat = st_ChooseTextureFormat;
1492   functions->TexImage = st_TexImage;
1493   functions->TexSubImage = _mesa_store_texsubimage;
1494   functions->CompressedTexSubImage = _mesa_store_compressed_texsubimage;
1495   functions->CopyTexSubImage = st_CopyTexSubImage;
1496   functions->GenerateMipmap = st_generate_mipmap;
1497
1498   functions->GetTexImage = st_GetTexImage;
1499
1500   /* compressed texture functions */
1501   functions->CompressedTexImage = st_CompressedTexImage;
1502   functions->GetCompressedTexImage = _mesa_get_compressed_teximage;
1503
1504   functions->NewTextureObject = st_NewTextureObject;
1505   functions->NewTextureImage = st_NewTextureImage;
1506   functions->DeleteTextureImage = st_DeleteTextureImage;
1507   functions->DeleteTexture = st_DeleteTextureObject;
1508   functions->AllocTextureImageBuffer = st_AllocTextureImageBuffer;
1509   functions->FreeTextureImageBuffer = st_FreeTextureImageBuffer;
1510   functions->MapTextureImage = st_MapTextureImage;
1511   functions->UnmapTextureImage = st_UnmapTextureImage;
1512
1513   /* XXX Temporary until we can query pipe's texture sizes */
1514   functions->TestProxyTexImage = st_TestProxyTexImage;
1515
1516   functions->AllocTextureStorage = st_AllocTextureStorage;
1517}
1518