st_cb_texture.c revision f0cc59d68a9f5231e8e2111393a1834858820735
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/bufferobj.h"
29#include "main/enums.h"
30#include "main/fbobject.h"
31#include "main/formats.h"
32#include "main/image.h"
33#include "main/imports.h"
34#include "main/macros.h"
35#include "main/mipmap.h"
36#include "main/pack.h"
37#include "main/pbo.h"
38#include "main/pixeltransfer.h"
39#include "main/texcompress.h"
40#include "main/texgetimage.h"
41#include "main/teximage.h"
42#include "main/texobj.h"
43#include "main/texstore.h"
44
45#include "state_tracker/st_debug.h"
46#include "state_tracker/st_context.h"
47#include "state_tracker/st_cb_fbo.h"
48#include "state_tracker/st_cb_flush.h"
49#include "state_tracker/st_cb_texture.h"
50#include "state_tracker/st_cb_bufferobjects.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_format.h"
62#include "util/u_surface.h"
63#include "util/u_sampler.h"
64#include "util/u_math.h"
65#include "util/u_box.h"
66
67#define DBG if (0) printf
68
69
70enum pipe_texture_target
71gl_target_to_pipe(GLenum target)
72{
73   switch (target) {
74   case GL_TEXTURE_1D:
75   case GL_PROXY_TEXTURE_1D:
76      return PIPE_TEXTURE_1D;
77   case GL_TEXTURE_2D:
78   case GL_PROXY_TEXTURE_2D:
79   case GL_TEXTURE_EXTERNAL_OES:
80   case GL_TEXTURE_2D_MULTISAMPLE:
81   case GL_PROXY_TEXTURE_2D_MULTISAMPLE:
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   case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
104   case GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY:
105      return PIPE_TEXTURE_2D_ARRAY;
106   case GL_TEXTURE_BUFFER:
107      return PIPE_BUFFER;
108   case GL_TEXTURE_CUBE_MAP_ARRAY:
109   case GL_PROXY_TEXTURE_CUBE_MAP_ARRAY:
110      return PIPE_TEXTURE_CUBE_ARRAY;
111   default:
112      assert(0);
113      return 0;
114   }
115}
116
117
118/** called via ctx->Driver.NewTextureImage() */
119static struct gl_texture_image *
120st_NewTextureImage(struct gl_context * ctx)
121{
122   DBG("%s\n", __FUNCTION__);
123   (void) ctx;
124   return (struct gl_texture_image *) ST_CALLOC_STRUCT(st_texture_image);
125}
126
127
128/** called via ctx->Driver.DeleteTextureImage() */
129static void
130st_DeleteTextureImage(struct gl_context * ctx, struct gl_texture_image *img)
131{
132   /* nothing special (yet) for st_texture_image */
133   _mesa_delete_texture_image(ctx, img);
134}
135
136
137/** called via ctx->Driver.NewTextureObject() */
138static struct gl_texture_object *
139st_NewTextureObject(struct gl_context * ctx, GLuint name, GLenum target)
140{
141   struct st_texture_object *obj = ST_CALLOC_STRUCT(st_texture_object);
142
143   DBG("%s\n", __FUNCTION__);
144   _mesa_initialize_texture_object(ctx, &obj->base, name, target);
145
146   return &obj->base;
147}
148
149/** called via ctx->Driver.DeleteTextureObject() */
150static void
151st_DeleteTextureObject(struct gl_context *ctx,
152                       struct gl_texture_object *texObj)
153{
154   struct st_context *st = st_context(ctx);
155   struct st_texture_object *stObj = st_texture_object(texObj);
156   if (stObj->pt)
157      pipe_resource_reference(&stObj->pt, NULL);
158   if (stObj->sampler_view) {
159      pipe_sampler_view_release(st->pipe, &stObj->sampler_view);
160   }
161   _mesa_delete_texture_object(ctx, texObj);
162}
163
164
165/** called via ctx->Driver.FreeTextureImageBuffer() */
166static void
167st_FreeTextureImageBuffer(struct gl_context *ctx,
168                          struct gl_texture_image *texImage)
169{
170   struct st_texture_image *stImage = st_texture_image(texImage);
171
172   DBG("%s\n", __FUNCTION__);
173
174   if (stImage->pt) {
175      pipe_resource_reference(&stImage->pt, NULL);
176   }
177
178   _mesa_align_free(stImage->TexData);
179   stImage->TexData = NULL;
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, pipeMode, x, y, slice, w, h, 1);
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, 0,
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, 0,
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
542/**
543 * Return a writemask for the gallium blit. The parameters can be base
544 * formats or "format" from glDrawPixels/glTexImage/glGetTexImage.
545 */
546unsigned
547st_get_blit_mask(GLenum srcFormat, GLenum dstFormat)
548{
549   switch (dstFormat) {
550   case GL_DEPTH_STENCIL:
551      switch (srcFormat) {
552      case GL_DEPTH_STENCIL:
553         return PIPE_MASK_ZS;
554      case GL_DEPTH_COMPONENT:
555         return PIPE_MASK_Z;
556      case GL_STENCIL_INDEX:
557         return PIPE_MASK_S;
558      default:
559         assert(0);
560         return 0;
561      }
562
563   case GL_DEPTH_COMPONENT:
564      switch (srcFormat) {
565      case GL_DEPTH_STENCIL:
566      case GL_DEPTH_COMPONENT:
567         return PIPE_MASK_Z;
568      default:
569         assert(0);
570         return 0;
571      }
572
573   case GL_STENCIL_INDEX:
574      switch (srcFormat) {
575      case GL_STENCIL_INDEX:
576         return PIPE_MASK_S;
577      default:
578         assert(0);
579         return 0;
580      }
581
582   default:
583      return PIPE_MASK_RGBA;
584   }
585}
586
587
588static void
589st_TexSubImage(struct gl_context *ctx, GLuint dims,
590               struct gl_texture_image *texImage,
591               GLint xoffset, GLint yoffset, GLint zoffset,
592               GLint width, GLint height, GLint depth,
593               GLenum format, GLenum type, const void *pixels,
594               const struct gl_pixelstore_attrib *unpack)
595{
596   struct st_context *st = st_context(ctx);
597   struct st_texture_image *stImage = st_texture_image(texImage);
598   struct st_texture_object *stObj = st_texture_object(texImage->TexObject);
599   struct pipe_context *pipe = st->pipe;
600   struct pipe_screen *screen = pipe->screen;
601   struct pipe_resource *dst = stImage->pt;
602   struct pipe_resource *src = NULL;
603   struct pipe_resource src_templ;
604   struct pipe_transfer *transfer;
605   struct pipe_blit_info blit;
606   enum pipe_format src_format, dst_format;
607   gl_format mesa_src_format;
608   GLenum gl_target = texImage->TexObject->Target;
609   unsigned bind;
610   GLubyte *map;
611
612   if (!st->prefer_blit_based_texture_transfer) {
613      goto fallback;
614   }
615
616   if (!dst) {
617      goto fallback;
618   }
619
620   /* XXX Fallback for depth-stencil formats due to an incomplete stencil
621    * blit implementation in some drivers. */
622   if (format == GL_DEPTH_STENCIL) {
623      goto fallback;
624   }
625
626   /* If the base internal format and the texture format don't match,
627    * we can't use blit-based TexSubImage. */
628   if (texImage->_BaseFormat !=
629       _mesa_get_format_base_format(texImage->TexFormat)) {
630      goto fallback;
631   }
632
633   /* See if the texture format already matches the format and type,
634    * in which case the memcpy-based fast path will likely be used and
635    * we don't have to blit. */
636   if (_mesa_format_matches_format_and_type(texImage->TexFormat, format,
637                                            type, unpack->SwapBytes)) {
638      goto fallback;
639   }
640
641   if (format == GL_DEPTH_COMPONENT || format == GL_DEPTH_STENCIL)
642      bind = PIPE_BIND_DEPTH_STENCIL;
643   else
644      bind = PIPE_BIND_RENDER_TARGET;
645
646   /* See if the destination format is supported.
647    * For luminance and intensity, only the red channel is stored there. */
648   dst_format = util_format_linear(dst->format);
649   dst_format = util_format_luminance_to_red(dst_format);
650   dst_format = util_format_intensity_to_red(dst_format);
651
652   if (!dst_format ||
653       !screen->is_format_supported(screen, dst_format, dst->target,
654                                    dst->nr_samples, bind)) {
655      goto fallback;
656   }
657
658   /* Choose the source format. */
659   src_format = st_choose_matching_format(screen, PIPE_BIND_SAMPLER_VIEW,
660                                          format, type, unpack->SwapBytes);
661   if (!src_format) {
662      goto fallback;
663   }
664
665   mesa_src_format = st_pipe_format_to_mesa_format(src_format);
666
667   /* There is no reason to do this if we cannot use memcpy for the temporary
668    * source texture at least. This also takes transfer ops into account,
669    * etc. */
670   if (!_mesa_texstore_can_use_memcpy(ctx,
671                             _mesa_get_format_base_format(mesa_src_format),
672                             mesa_src_format, format, type, unpack)) {
673      goto fallback;
674   }
675
676   /* TexSubImage only sets a single cubemap face. */
677   if (gl_target == GL_TEXTURE_CUBE_MAP) {
678      gl_target = GL_TEXTURE_2D;
679   }
680
681   /* Initialize the source texture description. */
682   memset(&src_templ, 0, sizeof(src_templ));
683   src_templ.target = gl_target_to_pipe(gl_target);
684   src_templ.format = src_format;
685   src_templ.bind = PIPE_BIND_SAMPLER_VIEW;
686   src_templ.usage = PIPE_USAGE_STAGING;
687
688   st_gl_texture_dims_to_pipe_dims(gl_target, width, height, depth,
689                                   &src_templ.width0, &src_templ.height0,
690                                   &src_templ.depth0, &src_templ.array_size);
691
692   /* Check for NPOT texture support. */
693   if (!screen->get_param(screen, PIPE_CAP_NPOT_TEXTURES) &&
694       (!util_is_power_of_two(src_templ.width0) ||
695        !util_is_power_of_two(src_templ.height0) ||
696        !util_is_power_of_two(src_templ.depth0))) {
697      goto fallback;
698   }
699
700   /* Create the source texture. */
701   src = screen->resource_create(screen, &src_templ);
702   if (!src) {
703      goto fallback;
704   }
705
706   /* Map source pixels. */
707   pixels = _mesa_validate_pbo_teximage(ctx, dims, width, height, depth,
708                                        format, type, pixels, unpack,
709                                        "glTexSubImage");
710   if (!pixels) {
711      /* This is a GL error. */
712      pipe_resource_reference(&src, NULL);
713      return;
714   }
715
716   /* From now on, we need the gallium representation of dimensions. */
717   if (gl_target == GL_TEXTURE_1D_ARRAY) {
718      depth = height;
719      height = 1;
720   }
721
722   map = pipe_transfer_map_3d(pipe, src, 0, PIPE_TRANSFER_WRITE, 0, 0, 0,
723                              width, height, depth, &transfer);
724   if (!map) {
725      _mesa_unmap_teximage_pbo(ctx, unpack);
726      pipe_resource_reference(&src, NULL);
727      goto fallback;
728   }
729
730   /* Upload pixels (just memcpy). */
731   {
732      const uint bytesPerRow = width * util_format_get_blocksize(src_format);
733      GLuint row, slice;
734
735      for (slice = 0; slice < (unsigned) depth; slice++) {
736         if (gl_target == GL_TEXTURE_1D_ARRAY) {
737            /* 1D array textures.
738             * We need to convert gallium coords to GL coords.
739             */
740            GLvoid *src = _mesa_image_address3d(unpack, pixels,
741                                                width, depth, format,
742                                                type, 0, slice, 0);
743            memcpy(map, src, bytesPerRow);
744         }
745         else {
746            ubyte *slice_map = map;
747
748            for (row = 0; row < (unsigned) height; row++) {
749               GLvoid *src = _mesa_image_address3d(unpack, pixels,
750                                                   width, height, format,
751                                                   type, slice, row, 0);
752               memcpy(slice_map, src, bytesPerRow);
753               slice_map += transfer->stride;
754            }
755         }
756         map += transfer->layer_stride;
757      }
758   }
759
760   pipe_transfer_unmap(pipe, transfer);
761   _mesa_unmap_teximage_pbo(ctx, unpack);
762
763   /* Blit. */
764   blit.src.resource = src;
765   blit.src.level = 0;
766   blit.src.format = src_format;
767   blit.dst.resource = dst;
768   blit.dst.level = stObj->pt != stImage->pt ? 0 : texImage->Level;
769   blit.dst.format = dst_format;
770   blit.src.box.x = blit.src.box.y = blit.src.box.z = 0;
771   blit.dst.box.x = xoffset;
772   blit.dst.box.y = yoffset;
773   blit.dst.box.z = zoffset + texImage->Face;
774   blit.src.box.width = blit.dst.box.width = width;
775   blit.src.box.height = blit.dst.box.height = height;
776   blit.src.box.depth = blit.dst.box.depth = depth;
777   blit.mask = st_get_blit_mask(format, texImage->_BaseFormat);
778   blit.filter = PIPE_TEX_FILTER_NEAREST;
779   blit.scissor_enable = FALSE;
780
781   st->pipe->blit(st->pipe, &blit);
782
783   pipe_resource_reference(&src, NULL);
784   return;
785
786fallback:
787   _mesa_store_texsubimage(ctx, dims, texImage, xoffset, yoffset, zoffset,
788                           width, height, depth, format, type, pixels,
789                           unpack);
790}
791
792static void
793st_TexImage(struct gl_context * ctx, GLuint dims,
794            struct gl_texture_image *texImage,
795            GLenum format, GLenum type, const void *pixels,
796            const struct gl_pixelstore_attrib *unpack)
797{
798   assert(dims == 1 || dims == 2 || dims == 3);
799
800   prep_teximage(ctx, texImage, format, type);
801
802   if (texImage->Width == 0 || texImage->Height == 0 || texImage->Depth == 0)
803      return;
804
805   /* allocate storage for texture data */
806   if (!ctx->Driver.AllocTextureImageBuffer(ctx, texImage)) {
807      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage%uD", dims);
808      return;
809   }
810
811   st_TexSubImage(ctx, dims, texImage, 0, 0, 0,
812                  texImage->Width, texImage->Height, texImage->Depth,
813                  format, type, pixels, unpack);
814}
815
816
817static void
818st_CompressedTexImage(struct gl_context *ctx, GLuint dims,
819                      struct gl_texture_image *texImage,
820                      GLsizei imageSize, const GLvoid *data)
821{
822   prep_teximage(ctx, texImage, GL_NONE, GL_NONE);
823   _mesa_store_compressed_teximage(ctx, dims, texImage, imageSize, data);
824}
825
826
827
828
829/**
830 * Called via ctx->Driver.GetTexImage()
831 *
832 * This uses a blit to copy the texture to a texture format which matches
833 * the format and type combo and then a fast read-back is done using memcpy.
834 * We can do arbitrary X/Y/Z/W/0/1 swizzling here as long as there is
835 * a format which matches the swizzling.
836 *
837 * If such a format isn't available, it falls back to _mesa_get_teximage.
838 *
839 * NOTE: Drivers usually do a blit to convert between tiled and linear
840 *       texture layouts during texture uploads/downloads, so the blit
841 *       we do here should be free in such cases.
842 */
843static void
844st_GetTexImage(struct gl_context * ctx,
845               GLenum format, GLenum type, GLvoid * pixels,
846               struct gl_texture_image *texImage)
847{
848   struct st_context *st = st_context(ctx);
849   struct pipe_context *pipe = st->pipe;
850   struct pipe_screen *screen = pipe->screen;
851   GLuint width = texImage->Width;
852   GLuint height = texImage->Height;
853   GLuint depth = texImage->Depth;
854   struct st_texture_image *stImage = st_texture_image(texImage);
855   struct pipe_resource *src = st_texture_object(texImage->TexObject)->pt;
856   struct pipe_resource *dst = NULL;
857   struct pipe_resource dst_templ;
858   enum pipe_format dst_format, src_format;
859   gl_format mesa_format;
860   GLenum gl_target = texImage->TexObject->Target;
861   enum pipe_texture_target pipe_target;
862   struct pipe_blit_info blit;
863   unsigned bind = PIPE_BIND_TRANSFER_READ;
864   struct pipe_transfer *tex_xfer;
865   ubyte *map = NULL;
866   boolean done = FALSE;
867
868   if (!st->prefer_blit_based_texture_transfer) {
869      goto fallback;
870   }
871
872   if (!stImage->pt || !src) {
873      goto fallback;
874   }
875
876   /* XXX Fallback to _mesa_get_teximage for depth-stencil formats
877    * due to an incomplete stencil blit implementation in some drivers. */
878   if (format == GL_DEPTH_STENCIL) {
879      goto fallback;
880   }
881
882   /* If the base internal format and the texture format don't match, we have
883    * to fall back to _mesa_get_teximage. */
884   if (texImage->_BaseFormat !=
885       _mesa_get_format_base_format(texImage->TexFormat)) {
886      goto fallback;
887   }
888
889   /* See if the texture format already matches the format and type,
890    * in which case the memcpy-based fast path will be used. */
891   if (_mesa_format_matches_format_and_type(texImage->TexFormat, format,
892                                            type, ctx->Pack.SwapBytes)) {
893      goto fallback;
894   }
895
896   /* Convert the source format to what is expected by GetTexImage
897    * and see if it's supported.
898    *
899    * This only applies to glGetTexImage:
900    * - Luminance must be returned as (L,0,0,1).
901    * - Luminance alpha must be returned as (L,0,0,A).
902    * - Intensity must be returned as (I,0,0,1)
903    */
904   src_format = util_format_linear(src->format);
905   src_format = util_format_luminance_to_red(src_format);
906   src_format = util_format_intensity_to_red(src_format);
907
908   if (!src_format ||
909       !screen->is_format_supported(screen, src_format, src->target,
910                                    src->nr_samples,
911                                    PIPE_BIND_SAMPLER_VIEW)) {
912      goto fallback;
913   }
914
915   if (format == GL_DEPTH_COMPONENT || format == GL_DEPTH_STENCIL)
916      bind |= PIPE_BIND_DEPTH_STENCIL;
917   else
918      bind |= PIPE_BIND_RENDER_TARGET;
919
920   /* GetTexImage only returns a single face for cubemaps. */
921   if (gl_target == GL_TEXTURE_CUBE_MAP) {
922      gl_target = GL_TEXTURE_2D;
923   }
924   pipe_target = gl_target_to_pipe(gl_target);
925
926   /* Choose the destination format by finding the best match
927    * for the format+type combo. */
928   dst_format = st_choose_matching_format(screen, bind, format, type,
929					  ctx->Pack.SwapBytes);
930
931   if (dst_format == PIPE_FORMAT_NONE) {
932      GLenum dst_glformat;
933
934      /* Fall back to _mesa_get_teximage except for compressed formats,
935       * where decompression with a blit is always preferred. */
936      if (!util_format_is_compressed(src->format)) {
937         goto fallback;
938      }
939
940      /* Set the appropriate format for the decompressed texture.
941       * Luminance and sRGB formats shouldn't appear here.*/
942      switch (src_format) {
943      case PIPE_FORMAT_DXT1_RGB:
944      case PIPE_FORMAT_DXT1_RGBA:
945      case PIPE_FORMAT_DXT3_RGBA:
946      case PIPE_FORMAT_DXT5_RGBA:
947      case PIPE_FORMAT_RGTC1_UNORM:
948      case PIPE_FORMAT_RGTC2_UNORM:
949      case PIPE_FORMAT_ETC1_RGB8:
950         dst_glformat = GL_RGBA8;
951         break;
952      case PIPE_FORMAT_RGTC1_SNORM:
953      case PIPE_FORMAT_RGTC2_SNORM:
954         if (!ctx->Extensions.EXT_texture_snorm)
955            goto fallback;
956         dst_glformat = GL_RGBA8_SNORM;
957         break;
958      /* TODO: for BPTC_*FLOAT, set RGBA32F and check for ARB_texture_float */
959      default:
960         assert(0);
961         goto fallback;
962      }
963
964      dst_format = st_choose_format(st, dst_glformat, format, type,
965                                    pipe_target, 0, bind, FALSE);
966
967      if (dst_format == PIPE_FORMAT_NONE) {
968         /* unable to get an rgba format!?! */
969         goto fallback;
970      }
971   }
972
973   /* create the destination texture */
974   memset(&dst_templ, 0, sizeof(dst_templ));
975   dst_templ.target = pipe_target;
976   dst_templ.format = dst_format;
977   dst_templ.bind = bind;
978   dst_templ.usage = PIPE_USAGE_STAGING;
979
980   st_gl_texture_dims_to_pipe_dims(gl_target, width, height, depth,
981                                   &dst_templ.width0, &dst_templ.height0,
982                                   &dst_templ.depth0, &dst_templ.array_size);
983
984   dst = screen->resource_create(screen, &dst_templ);
985   if (!dst) {
986      goto fallback;
987   }
988
989   /* From now on, we need the gallium representation of dimensions. */
990   if (gl_target == GL_TEXTURE_1D_ARRAY) {
991      depth = height;
992      height = 1;
993   }
994
995   blit.src.resource = src;
996   blit.src.level = texImage->Level;
997   blit.src.format = src_format;
998   blit.dst.resource = dst;
999   blit.dst.level = 0;
1000   blit.dst.format = dst->format;
1001   blit.src.box.x = blit.dst.box.x = 0;
1002   blit.src.box.y = blit.dst.box.y = 0;
1003   blit.src.box.z = texImage->Face;
1004   blit.dst.box.z = 0;
1005   blit.src.box.width = blit.dst.box.width = width;
1006   blit.src.box.height = blit.dst.box.height = height;
1007   blit.src.box.depth = blit.dst.box.depth = depth;
1008   blit.mask = st_get_blit_mask(texImage->_BaseFormat, format);
1009   blit.filter = PIPE_TEX_FILTER_NEAREST;
1010   blit.scissor_enable = FALSE;
1011
1012   /* blit/render/decompress */
1013   st->pipe->blit(st->pipe, &blit);
1014
1015   pixels = _mesa_map_pbo_dest(ctx, &ctx->Pack, pixels);
1016
1017   map = pipe_transfer_map_3d(pipe, dst, 0, PIPE_TRANSFER_READ,
1018                              0, 0, 0, width, height, depth, &tex_xfer);
1019   if (!map) {
1020      goto end;
1021   }
1022
1023   mesa_format = st_pipe_format_to_mesa_format(dst_format);
1024
1025   /* copy/pack data into user buffer */
1026   if (_mesa_format_matches_format_and_type(mesa_format, format, type,
1027                                            ctx->Pack.SwapBytes)) {
1028      /* memcpy */
1029      const uint bytesPerRow = width * util_format_get_blocksize(dst_format);
1030      GLuint row, slice;
1031
1032      for (slice = 0; slice < depth; slice++) {
1033         if (gl_target == GL_TEXTURE_1D_ARRAY) {
1034            /* 1D array textures.
1035             * We need to convert gallium coords to GL coords.
1036             */
1037            GLvoid *dest = _mesa_image_address3d(&ctx->Pack, pixels,
1038                                                 width, depth, format,
1039                                                 type, 0, slice, 0);
1040            memcpy(dest, map, bytesPerRow);
1041         }
1042         else {
1043            ubyte *slice_map = map;
1044
1045            for (row = 0; row < height; row++) {
1046               GLvoid *dest = _mesa_image_address3d(&ctx->Pack, pixels,
1047                                                    width, height, format,
1048                                                    type, slice, row, 0);
1049               memcpy(dest, slice_map, bytesPerRow);
1050               slice_map += tex_xfer->stride;
1051            }
1052         }
1053         map += tex_xfer->layer_stride;
1054      }
1055   }
1056   else {
1057      /* format translation via floats */
1058      GLuint row, slice;
1059      GLfloat *rgba;
1060
1061      assert(util_format_is_compressed(src->format));
1062
1063      rgba = malloc(width * 4 * sizeof(GLfloat));
1064      if (!rgba) {
1065         goto end;
1066      }
1067
1068      if (ST_DEBUG & DEBUG_FALLBACK)
1069         debug_printf("%s: fallback format translation\n", __FUNCTION__);
1070
1071      for (slice = 0; slice < depth; slice++) {
1072         if (gl_target == GL_TEXTURE_1D_ARRAY) {
1073            /* 1D array textures.
1074             * We need to convert gallium coords to GL coords.
1075             */
1076            GLvoid *dest = _mesa_image_address3d(&ctx->Pack, pixels,
1077                                                 width, depth, format,
1078                                                 type, 0, slice, 0);
1079
1080            /* get float[4] rgba row from surface */
1081            pipe_get_tile_rgba_format(tex_xfer, map, 0, 0, width, 1,
1082                                      dst_format, rgba);
1083
1084            _mesa_pack_rgba_span_float(ctx, width, (GLfloat (*)[4]) rgba, format,
1085                                       type, dest, &ctx->Pack, 0);
1086         }
1087         else {
1088            for (row = 0; row < height; row++) {
1089               GLvoid *dest = _mesa_image_address3d(&ctx->Pack, pixels,
1090                                                    width, height, format,
1091                                                    type, slice, row, 0);
1092
1093               /* get float[4] rgba row from surface */
1094               pipe_get_tile_rgba_format(tex_xfer, map, 0, row, width, 1,
1095                                         dst_format, rgba);
1096
1097               _mesa_pack_rgba_span_float(ctx, width, (GLfloat (*)[4]) rgba, format,
1098                                          type, dest, &ctx->Pack, 0);
1099            }
1100         }
1101         map += tex_xfer->layer_stride;
1102      }
1103
1104      free(rgba);
1105   }
1106   done = TRUE;
1107
1108end:
1109   if (map)
1110      pipe_transfer_unmap(pipe, tex_xfer);
1111
1112   _mesa_unmap_pbo_dest(ctx, &ctx->Pack);
1113   pipe_resource_reference(&dst, NULL);
1114
1115fallback:
1116   if (!done) {
1117      _mesa_get_teximage(ctx, format, type, pixels, texImage);
1118   }
1119}
1120
1121
1122/**
1123 * Do a CopyTexSubImage operation using a read transfer from the source,
1124 * a write transfer to the destination and get_tile()/put_tile() to access
1125 * the pixels/texels.
1126 *
1127 * Note: srcY=0=TOP of renderbuffer
1128 */
1129static void
1130fallback_copy_texsubimage(struct gl_context *ctx,
1131                          struct st_renderbuffer *strb,
1132                          struct st_texture_image *stImage,
1133                          GLenum baseFormat,
1134                          GLint destX, GLint destY, GLint slice,
1135                          GLint srcX, GLint srcY,
1136                          GLsizei width, GLsizei height)
1137{
1138   struct st_context *st = st_context(ctx);
1139   struct pipe_context *pipe = st->pipe;
1140   struct pipe_transfer *src_trans;
1141   GLubyte *texDest;
1142   enum pipe_transfer_usage transfer_usage;
1143   void *map;
1144   unsigned dst_width = width;
1145   unsigned dst_height = height;
1146   unsigned dst_depth = 1;
1147
1148   if (ST_DEBUG & DEBUG_FALLBACK)
1149      debug_printf("%s: fallback processing\n", __FUNCTION__);
1150
1151   if (st_fb_orientation(ctx->ReadBuffer) == Y_0_TOP) {
1152      srcY = strb->Base.Height - srcY - height;
1153   }
1154
1155   map = pipe_transfer_map(pipe,
1156                           strb->texture,
1157                           strb->surface->u.tex.level,
1158                           strb->surface->u.tex.first_layer,
1159                           PIPE_TRANSFER_READ,
1160                           srcX, srcY,
1161                           width, height, &src_trans);
1162
1163   if ((baseFormat == GL_DEPTH_COMPONENT ||
1164        baseFormat == GL_DEPTH_STENCIL) &&
1165       util_format_is_depth_and_stencil(stImage->pt->format))
1166      transfer_usage = PIPE_TRANSFER_READ_WRITE;
1167   else
1168      transfer_usage = PIPE_TRANSFER_WRITE;
1169
1170   texDest = st_texture_image_map(st, stImage, transfer_usage,
1171                                  destX, destY, slice,
1172                                  dst_width, dst_height, dst_depth);
1173
1174   if (baseFormat == GL_DEPTH_COMPONENT ||
1175       baseFormat == GL_DEPTH_STENCIL) {
1176      const GLboolean scaleOrBias = (ctx->Pixel.DepthScale != 1.0F ||
1177                                     ctx->Pixel.DepthBias != 0.0F);
1178      GLint row, yStep;
1179      uint *data;
1180
1181      /* determine bottom-to-top vs. top-to-bottom order for src buffer */
1182      if (st_fb_orientation(ctx->ReadBuffer) == Y_0_TOP) {
1183         srcY = height - 1;
1184         yStep = -1;
1185      }
1186      else {
1187         srcY = 0;
1188         yStep = 1;
1189      }
1190
1191      data = malloc(width * sizeof(uint));
1192
1193      if (data) {
1194         /* To avoid a large temp memory allocation, do copy row by row */
1195         for (row = 0; row < height; row++, srcY += yStep) {
1196            pipe_get_tile_z(src_trans, map, 0, srcY, width, 1, data);
1197            if (scaleOrBias) {
1198               _mesa_scale_and_bias_depth_uint(ctx, width, data);
1199            }
1200
1201            if (stImage->pt->target == PIPE_TEXTURE_1D_ARRAY) {
1202               pipe_put_tile_z(stImage->transfer,
1203                               texDest + row*stImage->transfer->layer_stride,
1204                               0, 0, width, 1, data);
1205            }
1206            else {
1207               pipe_put_tile_z(stImage->transfer, texDest, 0, row, width, 1,
1208                               data);
1209            }
1210         }
1211      }
1212      else {
1213         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexSubImage()");
1214      }
1215
1216      free(data);
1217   }
1218   else {
1219      /* RGBA format */
1220      GLfloat *tempSrc =
1221         malloc(width * height * 4 * sizeof(GLfloat));
1222
1223      if (tempSrc && texDest) {
1224         const GLint dims = 2;
1225         GLint dstRowStride;
1226         struct gl_texture_image *texImage = &stImage->base;
1227         struct gl_pixelstore_attrib unpack = ctx->DefaultPacking;
1228
1229         if (st_fb_orientation(ctx->ReadBuffer) == Y_0_TOP) {
1230            unpack.Invert = GL_TRUE;
1231         }
1232
1233         if (stImage->pt->target == PIPE_TEXTURE_1D_ARRAY) {
1234            dstRowStride = stImage->transfer->layer_stride;
1235         }
1236         else {
1237            dstRowStride = stImage->transfer->stride;
1238         }
1239
1240         /* get float/RGBA image from framebuffer */
1241         /* XXX this usually involves a lot of int/float conversion.
1242          * try to avoid that someday.
1243          */
1244         pipe_get_tile_rgba_format(src_trans, map, 0, 0, width, height,
1245                                   util_format_linear(strb->texture->format),
1246                                   tempSrc);
1247
1248         /* Store into texture memory.
1249          * Note that this does some special things such as pixel transfer
1250          * ops and format conversion.  In particular, if the dest tex format
1251          * is actually RGBA but the user created the texture as GL_RGB we
1252          * need to fill-in/override the alpha channel with 1.0.
1253          */
1254         _mesa_texstore(ctx, dims,
1255                        texImage->_BaseFormat,
1256                        texImage->TexFormat,
1257                        dstRowStride,
1258                        &texDest,
1259                        width, height, 1,
1260                        GL_RGBA, GL_FLOAT, tempSrc, /* src */
1261                        &unpack);
1262      }
1263      else {
1264         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage");
1265      }
1266
1267      free(tempSrc);
1268   }
1269
1270   st_texture_image_unmap(st, stImage);
1271   pipe->transfer_unmap(pipe, src_trans);
1272}
1273
1274
1275/**
1276 * Do a CopyTex[Sub]Image1/2/3D() using a hardware (blit) path if possible.
1277 * Note that the region to copy has already been clipped so we know we
1278 * won't read from outside the source renderbuffer's bounds.
1279 *
1280 * Note: srcY=0=Bottom of renderbuffer (GL convention)
1281 */
1282static void
1283st_CopyTexSubImage(struct gl_context *ctx, GLuint dims,
1284                   struct gl_texture_image *texImage,
1285                   GLint destX, GLint destY, GLint slice,
1286                   struct gl_renderbuffer *rb,
1287                   GLint srcX, GLint srcY, GLsizei width, GLsizei height)
1288{
1289   struct st_texture_image *stImage = st_texture_image(texImage);
1290   struct st_texture_object *stObj = st_texture_object(texImage->TexObject);
1291   struct st_renderbuffer *strb = st_renderbuffer(rb);
1292   struct st_context *st = st_context(ctx);
1293   struct pipe_context *pipe = st->pipe;
1294   struct pipe_screen *screen = pipe->screen;
1295   struct pipe_blit_info blit;
1296   enum pipe_format dst_format;
1297   GLboolean do_flip = (st_fb_orientation(ctx->ReadBuffer) == Y_0_TOP);
1298   unsigned bind;
1299   GLint srcY0, srcY1;
1300
1301   if (!strb || !strb->surface || !stImage->pt) {
1302      debug_printf("%s: null strb or stImage\n", __FUNCTION__);
1303      return;
1304   }
1305
1306   if (_mesa_texstore_needs_transfer_ops(ctx, texImage->_BaseFormat,
1307                                         texImage->TexFormat)) {
1308      goto fallback;
1309   }
1310
1311   /* The base internal format must match the mesa format, so make sure
1312    * e.g. an RGB internal format is really allocated as RGB and not as RGBA.
1313    */
1314   if (texImage->_BaseFormat !=
1315       _mesa_get_format_base_format(texImage->TexFormat) ||
1316       rb->_BaseFormat != _mesa_get_format_base_format(rb->Format)) {
1317      goto fallback;
1318   }
1319
1320   /* Choose the destination format to match the TexImage behavior. */
1321   dst_format = util_format_linear(stImage->pt->format);
1322   dst_format = util_format_luminance_to_red(dst_format);
1323   dst_format = util_format_intensity_to_red(dst_format);
1324
1325   /* See if the destination format is supported. */
1326   if (texImage->_BaseFormat == GL_DEPTH_STENCIL ||
1327       texImage->_BaseFormat == GL_DEPTH_COMPONENT) {
1328      bind = PIPE_BIND_DEPTH_STENCIL;
1329   }
1330   else {
1331      bind = PIPE_BIND_RENDER_TARGET;
1332   }
1333
1334   if (!dst_format ||
1335       !screen->is_format_supported(screen, dst_format, stImage->pt->target,
1336                                    stImage->pt->nr_samples, bind)) {
1337      goto fallback;
1338   }
1339
1340   /* Y flipping for the main framebuffer. */
1341   if (do_flip) {
1342      srcY1 = strb->Base.Height - srcY - height;
1343      srcY0 = srcY1 + height;
1344   }
1345   else {
1346      srcY0 = srcY;
1347      srcY1 = srcY0 + height;
1348   }
1349
1350   /* Blit the texture.
1351    * This supports flipping, format conversions, and downsampling.
1352    */
1353   memset(&blit, 0, sizeof(blit));
1354   blit.src.resource = strb->texture;
1355   blit.src.format = util_format_linear(strb->surface->format);
1356   blit.src.level = strb->surface->u.tex.level;
1357   blit.src.box.x = srcX;
1358   blit.src.box.y = srcY0;
1359   blit.src.box.z = strb->surface->u.tex.first_layer;
1360   blit.src.box.width = width;
1361   blit.src.box.height = srcY1 - srcY0;
1362   blit.src.box.depth = 1;
1363   blit.dst.resource = stImage->pt;
1364   blit.dst.format = dst_format;
1365   blit.dst.level = stObj->pt != stImage->pt ? 0 : texImage->Level;
1366   blit.dst.box.x = destX;
1367   blit.dst.box.y = destY;
1368   blit.dst.box.z = stImage->base.Face + slice;
1369   blit.dst.box.width = width;
1370   blit.dst.box.height = height;
1371   blit.dst.box.depth = 1;
1372   blit.mask = st_get_blit_mask(rb->_BaseFormat, texImage->_BaseFormat);
1373   blit.filter = PIPE_TEX_FILTER_NEAREST;
1374   pipe->blit(pipe, &blit);
1375   return;
1376
1377fallback:
1378   /* software fallback */
1379   fallback_copy_texsubimage(ctx,
1380                             strb, stImage, texImage->_BaseFormat,
1381                             destX, destY, slice,
1382                             srcX, srcY, width, height);
1383}
1384
1385
1386/**
1387 * Copy image data from stImage into the texture object 'stObj' at level
1388 * 'dstLevel'.
1389 */
1390static void
1391copy_image_data_to_texture(struct st_context *st,
1392			   struct st_texture_object *stObj,
1393                           GLuint dstLevel,
1394			   struct st_texture_image *stImage)
1395{
1396   /* debug checks */
1397   {
1398      const struct gl_texture_image *dstImage =
1399         stObj->base.Image[stImage->base.Face][dstLevel];
1400      assert(dstImage);
1401      assert(dstImage->Width == stImage->base.Width);
1402      assert(dstImage->Height == stImage->base.Height);
1403      assert(dstImage->Depth == stImage->base.Depth);
1404   }
1405
1406   if (stImage->pt) {
1407      /* Copy potentially with the blitter:
1408       */
1409      GLuint src_level;
1410      if (stImage->pt->last_level == 0)
1411         src_level = 0;
1412      else
1413         src_level = stImage->base.Level;
1414
1415      assert(src_level <= stImage->pt->last_level);
1416      assert(u_minify(stImage->pt->width0, src_level) == stImage->base.Width);
1417      assert(stImage->pt->target == PIPE_TEXTURE_1D_ARRAY ||
1418             u_minify(stImage->pt->height0, src_level) == stImage->base.Height);
1419      assert(stImage->pt->target == PIPE_TEXTURE_2D_ARRAY ||
1420             stImage->pt->target == PIPE_TEXTURE_CUBE_ARRAY ||
1421             u_minify(stImage->pt->depth0, src_level) == stImage->base.Depth);
1422
1423      st_texture_image_copy(st->pipe,
1424                            stObj->pt, dstLevel,  /* dest texture, level */
1425                            stImage->pt, src_level, /* src texture, level */
1426                            stImage->base.Face);
1427
1428      pipe_resource_reference(&stImage->pt, NULL);
1429   }
1430   else if (stImage->TexData) {
1431      /* Copy from malloc'd memory */
1432      /* XXX this should be re-examined/tested with a compressed format */
1433      GLuint blockSize = util_format_get_blocksize(stObj->pt->format);
1434      GLuint srcRowStride = stImage->base.Width * blockSize;
1435      GLuint srcSliceStride = stImage->base.Height * srcRowStride;
1436      st_texture_image_data(st,
1437                            stObj->pt,
1438                            stImage->base.Face,
1439                            dstLevel,
1440                            stImage->TexData,
1441                            srcRowStride,
1442                            srcSliceStride);
1443      _mesa_align_free(stImage->TexData);
1444      stImage->TexData = NULL;
1445   }
1446
1447   pipe_resource_reference(&stImage->pt, stObj->pt);
1448}
1449
1450
1451/**
1452 * Called during state validation.  When this function is finished,
1453 * the texture object should be ready for rendering.
1454 * \return GL_TRUE for success, GL_FALSE for failure (out of mem)
1455 */
1456GLboolean
1457st_finalize_texture(struct gl_context *ctx,
1458		    struct pipe_context *pipe,
1459		    struct gl_texture_object *tObj)
1460{
1461   struct st_context *st = st_context(ctx);
1462   struct st_texture_object *stObj = st_texture_object(tObj);
1463   const GLuint nr_faces = (stObj->base.Target == GL_TEXTURE_CUBE_MAP) ? 6 : 1;
1464   GLuint face;
1465   struct st_texture_image *firstImage;
1466   enum pipe_format firstImageFormat;
1467   GLuint ptWidth, ptHeight, ptDepth, ptLayers, ptNumSamples;
1468
1469   if (_mesa_is_texture_complete(tObj, &tObj->Sampler)) {
1470      /* The texture is complete and we know exactly how many mipmap levels
1471       * are present/needed.  This is conditional because we may be called
1472       * from the st_generate_mipmap() function when the texture object is
1473       * incomplete.  In that case, we'll have set stObj->lastLevel before
1474       * we get here.
1475       */
1476      if (stObj->base.Sampler.MinFilter == GL_LINEAR ||
1477          stObj->base.Sampler.MinFilter == GL_NEAREST)
1478         stObj->lastLevel = stObj->base.BaseLevel;
1479      else
1480         stObj->lastLevel = stObj->base._MaxLevel;
1481   }
1482
1483   if (tObj->Target == GL_TEXTURE_BUFFER) {
1484      struct st_buffer_object *st_obj = st_buffer_object(tObj->BufferObject);
1485
1486      if (st_obj->buffer != stObj->pt) {
1487         pipe_resource_reference(&stObj->pt, st_obj->buffer);
1488         pipe_sampler_view_release(st->pipe, &stObj->sampler_view);
1489         stObj->width0 = stObj->pt->width0 / _mesa_get_format_bytes(tObj->_BufferObjectFormat);
1490         stObj->height0 = 1;
1491         stObj->depth0 = 1;
1492      }
1493      return GL_TRUE;
1494
1495   }
1496
1497   firstImage = st_texture_image(stObj->base.Image[0][stObj->base.BaseLevel]);
1498   assert(firstImage);
1499
1500   /* If both firstImage and stObj point to a texture which can contain
1501    * all active images, favour firstImage.  Note that because of the
1502    * completeness requirement, we know that the image dimensions
1503    * will match.
1504    */
1505   if (firstImage->pt &&
1506       firstImage->pt != stObj->pt &&
1507       (!stObj->pt || firstImage->pt->last_level >= stObj->pt->last_level)) {
1508      pipe_resource_reference(&stObj->pt, firstImage->pt);
1509      pipe_sampler_view_release(st->pipe, &stObj->sampler_view);
1510   }
1511
1512   /* If this texture comes from a window system, there is nothing else to do. */
1513   if (stObj->surface_based) {
1514      return GL_TRUE;
1515   }
1516
1517   /* Find gallium format for the Mesa texture */
1518   firstImageFormat = st_mesa_format_to_pipe_format(firstImage->base.TexFormat);
1519
1520   /* Find size of level=0 Gallium mipmap image, plus number of texture layers */
1521   {
1522      GLuint width, height, depth;
1523      if (!guess_base_level_size(stObj->base.Target,
1524                                 firstImage->base.Width2,
1525                                 firstImage->base.Height2,
1526                                 firstImage->base.Depth2,
1527                                 firstImage->base.Level,
1528                                 &width, &height, &depth)) {
1529         width = stObj->width0;
1530         height = stObj->height0;
1531         depth = stObj->depth0;
1532      }
1533      /* convert GL dims to Gallium dims */
1534      st_gl_texture_dims_to_pipe_dims(stObj->base.Target, width, height, depth,
1535                                      &ptWidth, &ptHeight, &ptDepth, &ptLayers);
1536      ptNumSamples = firstImage->base.NumSamples;
1537   }
1538
1539   /* If we already have a gallium texture, check that it matches the texture
1540    * object's format, target, size, num_levels, etc.
1541    */
1542   if (stObj->pt) {
1543      if (stObj->pt->target != gl_target_to_pipe(stObj->base.Target) ||
1544          stObj->pt->format != firstImageFormat ||
1545          stObj->pt->last_level < stObj->lastLevel ||
1546          stObj->pt->width0 != ptWidth ||
1547          stObj->pt->height0 != ptHeight ||
1548          stObj->pt->depth0 != ptDepth ||
1549          stObj->pt->nr_samples != ptNumSamples ||
1550          stObj->pt->array_size != ptLayers)
1551      {
1552         /* The gallium texture does not match the Mesa texture so delete the
1553          * gallium texture now.  We'll make a new one below.
1554          */
1555         pipe_resource_reference(&stObj->pt, NULL);
1556         pipe_sampler_view_release(st->pipe, &stObj->sampler_view);
1557         st->dirty.st |= ST_NEW_FRAMEBUFFER;
1558      }
1559   }
1560
1561   /* May need to create a new gallium texture:
1562    */
1563   if (!stObj->pt) {
1564      GLuint bindings = default_bindings(st, firstImageFormat);
1565
1566      stObj->pt = st_texture_create(st,
1567                                    gl_target_to_pipe(stObj->base.Target),
1568                                    firstImageFormat,
1569                                    stObj->lastLevel,
1570                                    ptWidth,
1571                                    ptHeight,
1572                                    ptDepth,
1573                                    ptLayers, ptNumSamples,
1574                                    bindings);
1575
1576      if (!stObj->pt) {
1577         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage");
1578         return GL_FALSE;
1579      }
1580   }
1581
1582   /* Pull in any images not in the object's texture:
1583    */
1584   for (face = 0; face < nr_faces; face++) {
1585      GLuint level;
1586      for (level = stObj->base.BaseLevel; level <= stObj->lastLevel; level++) {
1587         struct st_texture_image *stImage =
1588            st_texture_image(stObj->base.Image[face][level]);
1589
1590         /* Need to import images in main memory or held in other textures.
1591          */
1592         if (stImage && stObj->pt != stImage->pt) {
1593            if (level == 0 ||
1594                (stImage->base.Width == u_minify(stObj->width0, level) &&
1595                 stImage->base.Height == u_minify(stObj->height0, level) &&
1596                 stImage->base.Depth == u_minify(stObj->depth0, level))) {
1597               /* src image fits expected dest mipmap level size */
1598               copy_image_data_to_texture(st, stObj, level, stImage);
1599            }
1600         }
1601      }
1602   }
1603
1604   return GL_TRUE;
1605}
1606
1607
1608/**
1609 * Called via ctx->Driver.AllocTextureStorage() to allocate texture memory
1610 * for a whole mipmap stack.
1611 */
1612static GLboolean
1613st_AllocTextureStorage(struct gl_context *ctx,
1614                       struct gl_texture_object *texObj,
1615                       GLsizei levels, GLsizei width,
1616                       GLsizei height, GLsizei depth)
1617{
1618   const GLuint numFaces = _mesa_num_tex_faces(texObj->Target);
1619   struct gl_texture_image *texImage = texObj->Image[0][0];
1620   struct st_context *st = st_context(ctx);
1621   struct st_texture_object *stObj = st_texture_object(texObj);
1622   struct pipe_screen *screen = st->pipe->screen;
1623   GLuint ptWidth, ptHeight, ptDepth, ptLayers, bindings;
1624   enum pipe_format fmt;
1625   GLint level;
1626   GLuint num_samples = texImage->NumSamples;
1627
1628   assert(levels > 0);
1629
1630   /* Save the level=0 dimensions */
1631   stObj->width0 = width;
1632   stObj->height0 = height;
1633   stObj->depth0 = depth;
1634   stObj->lastLevel = levels - 1;
1635
1636   fmt = st_mesa_format_to_pipe_format(texImage->TexFormat);
1637
1638   bindings = default_bindings(st, fmt);
1639
1640   /* Raise the sample count if the requested one is unsupported. */
1641   if (num_samples > 1) {
1642      boolean found = FALSE;
1643
1644      for (; num_samples <= ctx->Const.MaxSamples; num_samples++) {
1645         if (screen->is_format_supported(screen, fmt, PIPE_TEXTURE_2D,
1646                                         num_samples,
1647                                         PIPE_BIND_SAMPLER_VIEW)) {
1648            /* Update the sample count in gl_texture_image as well. */
1649            texImage->NumSamples = num_samples;
1650            found = TRUE;
1651            break;
1652         }
1653      }
1654
1655      if (!found) {
1656         return GL_FALSE;
1657      }
1658   }
1659
1660   st_gl_texture_dims_to_pipe_dims(texObj->Target,
1661                                   width, height, depth,
1662                                   &ptWidth, &ptHeight, &ptDepth, &ptLayers);
1663
1664   stObj->pt = st_texture_create(st,
1665                                 gl_target_to_pipe(texObj->Target),
1666                                 fmt,
1667                                 levels - 1,
1668                                 ptWidth,
1669                                 ptHeight,
1670                                 ptDepth,
1671                                 ptLayers, num_samples,
1672                                 bindings);
1673   if (!stObj->pt)
1674      return GL_FALSE;
1675
1676   /* Set image resource pointers */
1677   for (level = 0; level < levels; level++) {
1678      GLuint face;
1679      for (face = 0; face < numFaces; face++) {
1680         struct st_texture_image *stImage =
1681            st_texture_image(texObj->Image[face][level]);
1682         pipe_resource_reference(&stImage->pt, stObj->pt);
1683      }
1684   }
1685
1686   return GL_TRUE;
1687}
1688
1689
1690static GLboolean
1691st_TestProxyTexImage(struct gl_context *ctx, GLenum target,
1692                     GLint level, gl_format format,
1693                     GLint width, GLint height,
1694                     GLint depth, GLint border)
1695{
1696   struct st_context *st = st_context(ctx);
1697   struct pipe_context *pipe = st->pipe;
1698
1699   if (width == 0 || height == 0 || depth == 0) {
1700      /* zero-sized images are legal, and always fit! */
1701      return GL_TRUE;
1702   }
1703
1704   if (pipe->screen->can_create_resource) {
1705      /* Ask the gallium driver if the texture is too large */
1706      struct gl_texture_object *texObj =
1707         _mesa_get_current_tex_object(ctx, target);
1708      struct pipe_resource pt;
1709
1710      /* Setup the pipe_resource object
1711       */
1712      memset(&pt, 0, sizeof(pt));
1713
1714      pt.target = gl_target_to_pipe(target);
1715      pt.format = st_mesa_format_to_pipe_format(format);
1716
1717      st_gl_texture_dims_to_pipe_dims(target,
1718                                      width, height, depth,
1719                                      &pt.width0, &pt.height0,
1720                                      &pt.depth0, &pt.array_size);
1721
1722      if (level == 0 && (texObj->Sampler.MinFilter == GL_LINEAR ||
1723                         texObj->Sampler.MinFilter == GL_NEAREST)) {
1724         /* assume just one mipmap level */
1725         pt.last_level = 0;
1726      }
1727      else {
1728         /* assume a full set of mipmaps */
1729         pt.last_level = _mesa_logbase2(MAX3(width, height, depth));
1730      }
1731
1732      return pipe->screen->can_create_resource(pipe->screen, &pt);
1733   }
1734   else {
1735      /* Use core Mesa fallback */
1736      return _mesa_test_proxy_teximage(ctx, target, level, format,
1737                                       width, height, depth, border);
1738   }
1739}
1740
1741
1742void
1743st_init_texture_functions(struct dd_function_table *functions)
1744{
1745   functions->ChooseTextureFormat = st_ChooseTextureFormat;
1746   functions->QuerySamplesForFormat = st_QuerySamplesForFormat;
1747   functions->TexImage = st_TexImage;
1748   functions->TexSubImage = st_TexSubImage;
1749   functions->CompressedTexSubImage = _mesa_store_compressed_texsubimage;
1750   functions->CopyTexSubImage = st_CopyTexSubImage;
1751   functions->GenerateMipmap = st_generate_mipmap;
1752
1753   functions->GetTexImage = st_GetTexImage;
1754
1755   /* compressed texture functions */
1756   functions->CompressedTexImage = st_CompressedTexImage;
1757   functions->GetCompressedTexImage = _mesa_get_compressed_teximage;
1758
1759   functions->NewTextureObject = st_NewTextureObject;
1760   functions->NewTextureImage = st_NewTextureImage;
1761   functions->DeleteTextureImage = st_DeleteTextureImage;
1762   functions->DeleteTexture = st_DeleteTextureObject;
1763   functions->AllocTextureImageBuffer = st_AllocTextureImageBuffer;
1764   functions->FreeTextureImageBuffer = st_FreeTextureImageBuffer;
1765   functions->MapTextureImage = st_MapTextureImage;
1766   functions->UnmapTextureImage = st_UnmapTextureImage;
1767
1768   /* XXX Temporary until we can query pipe's texture sizes */
1769   functions->TestProxyTexImage = st_TestProxyTexImage;
1770
1771   functions->AllocTextureStorage = st_AllocTextureStorage;
1772}
1773