st_cb_texture.c revision 58e8dd6b9da69905c169cea07562c71a06a88270
1/**************************************************************************
2 *
3 * Copyright 2007 VMware, Inc.
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 VMWARE 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/texcompress_etc.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_format.h"
63#include "util/u_surface.h"
64#include "util/u_sampler.h"
65#include "util/u_math.h"
66#include "util/u_box.h"
67
68#define DBG if (0) printf
69
70
71enum pipe_texture_target
72gl_target_to_pipe(GLenum target)
73{
74   switch (target) {
75   case GL_TEXTURE_1D:
76   case GL_PROXY_TEXTURE_1D:
77      return PIPE_TEXTURE_1D;
78   case GL_TEXTURE_2D:
79   case GL_PROXY_TEXTURE_2D:
80   case GL_TEXTURE_EXTERNAL_OES:
81   case GL_TEXTURE_2D_MULTISAMPLE:
82   case GL_PROXY_TEXTURE_2D_MULTISAMPLE:
83      return PIPE_TEXTURE_2D;
84   case GL_TEXTURE_RECTANGLE_NV:
85   case GL_PROXY_TEXTURE_RECTANGLE_NV:
86      return PIPE_TEXTURE_RECT;
87   case GL_TEXTURE_3D:
88   case GL_PROXY_TEXTURE_3D:
89      return PIPE_TEXTURE_3D;
90   case GL_TEXTURE_CUBE_MAP_ARB:
91   case GL_PROXY_TEXTURE_CUBE_MAP_ARB:
92   case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
93   case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
94   case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
95   case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
96   case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
97   case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
98      return PIPE_TEXTURE_CUBE;
99   case GL_TEXTURE_1D_ARRAY_EXT:
100   case GL_PROXY_TEXTURE_1D_ARRAY_EXT:
101      return PIPE_TEXTURE_1D_ARRAY;
102   case GL_TEXTURE_2D_ARRAY_EXT:
103   case GL_PROXY_TEXTURE_2D_ARRAY_EXT:
104   case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
105   case GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY:
106      return PIPE_TEXTURE_2D_ARRAY;
107   case GL_TEXTURE_BUFFER:
108      return PIPE_BUFFER;
109   case GL_TEXTURE_CUBE_MAP_ARRAY:
110   case GL_PROXY_TEXTURE_CUBE_MAP_ARRAY:
111      return PIPE_TEXTURE_CUBE_ARRAY;
112   default:
113      assert(0);
114      return 0;
115   }
116}
117
118
119/** called via ctx->Driver.NewTextureImage() */
120static struct gl_texture_image *
121st_NewTextureImage(struct gl_context * ctx)
122{
123   DBG("%s\n", __FUNCTION__);
124   (void) ctx;
125   return (struct gl_texture_image *) ST_CALLOC_STRUCT(st_texture_image);
126}
127
128
129/** called via ctx->Driver.DeleteTextureImage() */
130static void
131st_DeleteTextureImage(struct gl_context * ctx, struct gl_texture_image *img)
132{
133   /* nothing special (yet) for st_texture_image */
134   _mesa_delete_texture_image(ctx, img);
135}
136
137
138/** called via ctx->Driver.NewTextureObject() */
139static struct gl_texture_object *
140st_NewTextureObject(struct gl_context * ctx, GLuint name, GLenum target)
141{
142   struct st_texture_object *obj = ST_CALLOC_STRUCT(st_texture_object);
143
144   DBG("%s\n", __FUNCTION__);
145   _mesa_initialize_texture_object(ctx, &obj->base, name, target);
146
147   return &obj->base;
148}
149
150/** called via ctx->Driver.DeleteTextureObject() */
151static void
152st_DeleteTextureObject(struct gl_context *ctx,
153                       struct gl_texture_object *texObj)
154{
155   struct st_context *st = st_context(ctx);
156   struct st_texture_object *stObj = st_texture_object(texObj);
157
158   pipe_resource_reference(&stObj->pt, NULL);
159   st_texture_release_all_sampler_views(st, stObj);
160   st_texture_free_sampler_views(stObj);
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   free(stImage->transfer);
182   stImage->transfer = NULL;
183   stImage->num_transfers = 0;
184}
185
186
187/** called via ctx->Driver.MapTextureImage() */
188static void
189st_MapTextureImage(struct gl_context *ctx,
190                   struct gl_texture_image *texImage,
191                   GLuint slice, GLuint x, GLuint y, GLuint w, GLuint h,
192                   GLbitfield mode,
193                   GLubyte **mapOut, GLint *rowStrideOut)
194{
195   struct st_context *st = st_context(ctx);
196   struct st_texture_image *stImage = st_texture_image(texImage);
197   unsigned pipeMode;
198   GLubyte *map;
199   struct pipe_transfer *transfer;
200
201   pipeMode = 0x0;
202   if (mode & GL_MAP_READ_BIT)
203      pipeMode |= PIPE_TRANSFER_READ;
204   if (mode & GL_MAP_WRITE_BIT)
205      pipeMode |= PIPE_TRANSFER_WRITE;
206   if (mode & GL_MAP_INVALIDATE_RANGE_BIT)
207      pipeMode |= PIPE_TRANSFER_DISCARD_RANGE;
208
209   map = st_texture_image_map(st, stImage, pipeMode, x, y, slice, w, h, 1,
210                              &transfer);
211   if (map) {
212      if (_mesa_is_format_etc2(texImage->TexFormat) ||
213          (texImage->TexFormat == MESA_FORMAT_ETC1_RGB8 && !st->has_etc1)) {
214         /* ETC isn't supported by gallium and it's represented
215          * by uncompressed formats. Only write transfers with precompressed
216          * data are supported by ES3, which makes this really simple.
217          *
218          * Just create a temporary storage where the ETC texture will
219          * be stored. It will be decompressed in the Unmap function.
220          */
221         unsigned z = transfer->box.z;
222         struct st_texture_image_transfer *itransfer = &stImage->transfer[z];
223
224         itransfer->temp_data =
225            malloc(_mesa_format_image_size(texImage->TexFormat, w, h, 1));
226         itransfer->temp_stride =
227            _mesa_format_row_stride(texImage->TexFormat, w);
228         itransfer->map = map;
229
230         *mapOut = itransfer->temp_data;
231         *rowStrideOut = itransfer->temp_stride;
232      }
233      else {
234         /* supported mapping */
235         *mapOut = map;
236         *rowStrideOut = transfer->stride;
237      }
238   }
239   else {
240      *mapOut = NULL;
241      *rowStrideOut = 0;
242   }
243}
244
245
246/** called via ctx->Driver.UnmapTextureImage() */
247static void
248st_UnmapTextureImage(struct gl_context *ctx,
249                     struct gl_texture_image *texImage,
250                     GLuint slice)
251{
252   struct st_context *st = st_context(ctx);
253   struct st_texture_image *stImage  = st_texture_image(texImage);
254
255   if (_mesa_is_format_etc2(texImage->TexFormat) ||
256       (texImage->TexFormat == MESA_FORMAT_ETC1_RGB8 && !st->has_etc1)) {
257      /* Decompress the ETC texture to the mapped one. */
258      unsigned z = slice + stImage->base.Face;
259      struct st_texture_image_transfer *itransfer = &stImage->transfer[z];
260      struct pipe_transfer *transfer = itransfer->transfer;
261
262      assert(z == transfer->box.z);
263
264      if (texImage->TexFormat == MESA_FORMAT_ETC1_RGB8) {
265         _mesa_etc1_unpack_rgba8888(itransfer->map, transfer->stride,
266                                    itransfer->temp_data,
267                                    itransfer->temp_stride,
268                                    transfer->box.width, transfer->box.height);
269      }
270      else {
271         _mesa_unpack_etc2_format(itransfer->map, transfer->stride,
272                                  itransfer->temp_data, itransfer->temp_stride,
273                                  transfer->box.width, transfer->box.height,
274                                  texImage->TexFormat);
275      }
276
277      free(itransfer->temp_data);
278      itransfer->temp_data = NULL;
279      itransfer->temp_stride = 0;
280      itransfer->map = 0;
281   }
282
283   st_texture_image_unmap(st, stImage, slice);
284}
285
286
287/**
288 * Return default texture resource binding bitmask for the given format.
289 */
290static GLuint
291default_bindings(struct st_context *st, enum pipe_format format)
292{
293   struct pipe_screen *screen = st->pipe->screen;
294   const unsigned target = PIPE_TEXTURE_2D;
295   unsigned bindings;
296
297   if (util_format_is_depth_or_stencil(format))
298      bindings = PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_DEPTH_STENCIL;
299   else
300      bindings = PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET;
301
302   if (screen->is_format_supported(screen, format, target, 0, bindings))
303      return bindings;
304   else {
305      /* Try non-sRGB. */
306      format = util_format_linear(format);
307
308      if (screen->is_format_supported(screen, format, target, 0, bindings))
309         return bindings;
310      else
311         return PIPE_BIND_SAMPLER_VIEW;
312   }
313}
314
315
316/**
317 * Given the size of a mipmap image, try to compute the size of the level=0
318 * mipmap image.
319 *
320 * Note that this isn't always accurate for odd-sized, non-POW textures.
321 * For example, if level=1 and width=40 then the level=0 width may be 80 or 81.
322 *
323 * \return GL_TRUE for success, GL_FALSE for failure
324 */
325static GLboolean
326guess_base_level_size(GLenum target,
327                      GLuint width, GLuint height, GLuint depth, GLuint level,
328                      GLuint *width0, GLuint *height0, GLuint *depth0)
329{
330   assert(width >= 1);
331   assert(height >= 1);
332   assert(depth >= 1);
333
334   if (level > 0) {
335      /* Guess the size of the base level.
336       * Depending on the image's size, we can't always make a guess here.
337       */
338      switch (target) {
339      case GL_TEXTURE_1D:
340      case GL_TEXTURE_1D_ARRAY:
341         width <<= level;
342         break;
343
344      case GL_TEXTURE_2D:
345      case GL_TEXTURE_2D_ARRAY:
346         /* We can't make a good guess here, because the base level dimensions
347          * can be non-square.
348          */
349         if (width == 1 || height == 1) {
350            return GL_FALSE;
351         }
352         width <<= level;
353         height <<= level;
354         break;
355
356      case GL_TEXTURE_CUBE_MAP:
357      case GL_TEXTURE_CUBE_MAP_ARRAY:
358         width <<= level;
359         height <<= level;
360         break;
361
362      case GL_TEXTURE_3D:
363         /* We can't make a good guess here, because the base level dimensions
364          * can be non-cube.
365          */
366         if (width == 1 || height == 1 || depth == 1) {
367            return GL_FALSE;
368         }
369         width <<= level;
370         height <<= level;
371         depth <<= level;
372         break;
373
374      case GL_TEXTURE_RECTANGLE:
375         break;
376
377      default:
378         assert(0);
379      }
380   }
381
382   *width0 = width;
383   *height0 = height;
384   *depth0 = depth;
385
386   return GL_TRUE;
387}
388
389
390/**
391 * Try to allocate a pipe_resource object for the given st_texture_object.
392 *
393 * We use the given st_texture_image as a clue to determine the size of the
394 * mipmap image at level=0.
395 *
396 * \return GL_TRUE for success, GL_FALSE if out of memory.
397 */
398static GLboolean
399guess_and_alloc_texture(struct st_context *st,
400			struct st_texture_object *stObj,
401			const struct st_texture_image *stImage)
402{
403   GLuint lastLevel, width, height, depth;
404   GLuint bindings;
405   GLuint ptWidth, ptHeight, ptDepth, ptLayers;
406   enum pipe_format fmt;
407
408   DBG("%s\n", __FUNCTION__);
409
410   assert(!stObj->pt);
411
412   if (!guess_base_level_size(stObj->base.Target,
413                              stImage->base.Width2,
414                              stImage->base.Height2,
415                              stImage->base.Depth2,
416                              stImage->base.Level,
417                              &width, &height, &depth)) {
418      /* we can't determine the image size at level=0 */
419      stObj->width0 = stObj->height0 = stObj->depth0 = 0;
420      /* this is not an out of memory error */
421      return GL_TRUE;
422   }
423
424   /* At this point, (width x height x depth) is the expected size of
425    * the level=0 mipmap image.
426    */
427
428   /* Guess a reasonable value for lastLevel.  With OpenGL we have no
429    * idea how many mipmap levels will be in a texture until we start
430    * to render with it.  Make an educated guess here but be prepared
431    * to re-allocating a texture buffer with space for more (or fewer)
432    * mipmap levels later.
433    */
434   if ((stObj->base.Sampler.MinFilter == GL_NEAREST ||
435        stObj->base.Sampler.MinFilter == GL_LINEAR ||
436        (stObj->base.BaseLevel == 0 &&
437         stObj->base.MaxLevel == 0) ||
438        stImage->base._BaseFormat == GL_DEPTH_COMPONENT ||
439        stImage->base._BaseFormat == GL_DEPTH_STENCIL_EXT) &&
440       !stObj->base.GenerateMipmap &&
441       stImage->base.Level == 0) {
442      /* only alloc space for a single mipmap level */
443      lastLevel = 0;
444   }
445   else {
446      /* alloc space for a full mipmap */
447      lastLevel = _mesa_get_tex_max_num_levels(stObj->base.Target,
448                                               width, height, depth) - 1;
449   }
450
451   /* Save the level=0 dimensions */
452   stObj->width0 = width;
453   stObj->height0 = height;
454   stObj->depth0 = depth;
455
456   fmt = st_mesa_format_to_pipe_format(st, stImage->base.TexFormat);
457
458   bindings = default_bindings(st, fmt);
459
460   st_gl_texture_dims_to_pipe_dims(stObj->base.Target,
461                                   width, height, depth,
462                                   &ptWidth, &ptHeight, &ptDepth, &ptLayers);
463
464   stObj->pt = st_texture_create(st,
465                                 gl_target_to_pipe(stObj->base.Target),
466                                 fmt,
467                                 lastLevel,
468                                 ptWidth,
469                                 ptHeight,
470                                 ptDepth,
471                                 ptLayers, 0,
472                                 bindings);
473
474   stObj->lastLevel = lastLevel;
475
476   DBG("%s returning %d\n", __FUNCTION__, (stObj->pt != NULL));
477
478   return stObj->pt != NULL;
479}
480
481
482/**
483 * Called via ctx->Driver.AllocTextureImageBuffer().
484 * If the texture object/buffer already has space for the indicated image,
485 * we're done.  Otherwise, allocate memory for the new texture image.
486 */
487static GLboolean
488st_AllocTextureImageBuffer(struct gl_context *ctx,
489                           struct gl_texture_image *texImage)
490{
491   struct st_context *st = st_context(ctx);
492   struct st_texture_image *stImage = st_texture_image(texImage);
493   struct st_texture_object *stObj = st_texture_object(texImage->TexObject);
494   const GLuint level = texImage->Level;
495   GLuint width = texImage->Width;
496   GLuint height = texImage->Height;
497   GLuint depth = texImage->Depth;
498
499   DBG("%s\n", __FUNCTION__);
500
501   assert(!stImage->TexData);
502   assert(!stImage->pt); /* xxx this might be wrong */
503
504   /* Look if the parent texture object has space for this image */
505   if (stObj->pt &&
506       level <= stObj->pt->last_level &&
507       st_texture_match_image(st, stObj->pt, texImage)) {
508      /* this image will fit in the existing texture object's memory */
509      pipe_resource_reference(&stImage->pt, stObj->pt);
510      return GL_TRUE;
511   }
512
513   /* The parent texture object does not have space for this image */
514
515   pipe_resource_reference(&stObj->pt, NULL);
516   st_texture_release_all_sampler_views(st, stObj);
517
518   if (!guess_and_alloc_texture(st, stObj, stImage)) {
519      /* Probably out of memory.
520       * Try flushing any pending rendering, then retry.
521       */
522      st_finish(st);
523      if (!guess_and_alloc_texture(st, stObj, stImage)) {
524         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage");
525         return GL_FALSE;
526      }
527   }
528
529   if (stObj->pt &&
530       st_texture_match_image(st, stObj->pt, texImage)) {
531      /* The image will live in the object's mipmap memory */
532      pipe_resource_reference(&stImage->pt, stObj->pt);
533      assert(stImage->pt);
534      return GL_TRUE;
535   }
536   else {
537      /* Create a new, temporary texture/resource/buffer to hold this
538       * one texture image.  Note that when we later access this image
539       * (either for mapping or copying) we'll want to always specify
540       * mipmap level=0, even if the image represents some other mipmap
541       * level.
542       */
543      enum pipe_format format =
544         st_mesa_format_to_pipe_format(st, texImage->TexFormat);
545      GLuint bindings = default_bindings(st, format);
546      GLuint ptWidth, ptHeight, ptDepth, ptLayers;
547
548      st_gl_texture_dims_to_pipe_dims(stObj->base.Target,
549                                      width, height, depth,
550                                      &ptWidth, &ptHeight, &ptDepth, &ptLayers);
551
552      stImage->pt = st_texture_create(st,
553                                      gl_target_to_pipe(stObj->base.Target),
554                                      format,
555                                      0, /* lastLevel */
556                                      ptWidth,
557                                      ptHeight,
558                                      ptDepth,
559                                      ptLayers, 0,
560                                      bindings);
561      return stImage->pt != NULL;
562   }
563}
564
565
566/**
567 * Preparation prior to glTexImage.  Basically check the 'surface_based'
568 * field and switch to a "normal" tex image if necessary.
569 */
570static void
571prep_teximage(struct gl_context *ctx, struct gl_texture_image *texImage,
572              GLenum format, GLenum type)
573{
574   struct gl_texture_object *texObj = texImage->TexObject;
575   struct st_texture_object *stObj = st_texture_object(texObj);
576
577   /* switch to "normal" */
578   if (stObj->surface_based) {
579      const GLenum target = texObj->Target;
580      const GLuint level = texImage->Level;
581      mesa_format texFormat;
582
583      _mesa_clear_texture_object(ctx, texObj);
584      pipe_resource_reference(&stObj->pt, NULL);
585
586      /* oops, need to init this image again */
587      texFormat = _mesa_choose_texture_format(ctx, texObj, target, level,
588                                              texImage->InternalFormat, format,
589                                              type);
590
591      _mesa_init_teximage_fields(ctx, texImage,
592                                 texImage->Width, texImage->Height,
593                                 texImage->Depth, texImage->Border,
594                                 texImage->InternalFormat, texFormat);
595
596      stObj->surface_based = GL_FALSE;
597   }
598}
599
600
601/**
602 * Return a writemask for the gallium blit. The parameters can be base
603 * formats or "format" from glDrawPixels/glTexImage/glGetTexImage.
604 */
605unsigned
606st_get_blit_mask(GLenum srcFormat, GLenum dstFormat)
607{
608   switch (dstFormat) {
609   case GL_DEPTH_STENCIL:
610      switch (srcFormat) {
611      case GL_DEPTH_STENCIL:
612         return PIPE_MASK_ZS;
613      case GL_DEPTH_COMPONENT:
614         return PIPE_MASK_Z;
615      case GL_STENCIL_INDEX:
616         return PIPE_MASK_S;
617      default:
618         assert(0);
619         return 0;
620      }
621
622   case GL_DEPTH_COMPONENT:
623      switch (srcFormat) {
624      case GL_DEPTH_STENCIL:
625      case GL_DEPTH_COMPONENT:
626         return PIPE_MASK_Z;
627      default:
628         assert(0);
629         return 0;
630      }
631
632   case GL_STENCIL_INDEX:
633      switch (srcFormat) {
634      case GL_STENCIL_INDEX:
635         return PIPE_MASK_S;
636      default:
637         assert(0);
638         return 0;
639      }
640
641   default:
642      return PIPE_MASK_RGBA;
643   }
644}
645
646
647static void
648st_TexSubImage(struct gl_context *ctx, GLuint dims,
649               struct gl_texture_image *texImage,
650               GLint xoffset, GLint yoffset, GLint zoffset,
651               GLint width, GLint height, GLint depth,
652               GLenum format, GLenum type, const void *pixels,
653               const struct gl_pixelstore_attrib *unpack)
654{
655   struct st_context *st = st_context(ctx);
656   struct st_texture_image *stImage = st_texture_image(texImage);
657   struct st_texture_object *stObj = st_texture_object(texImage->TexObject);
658   struct pipe_context *pipe = st->pipe;
659   struct pipe_screen *screen = pipe->screen;
660   struct pipe_resource *dst = stImage->pt;
661   struct pipe_resource *src = NULL;
662   struct pipe_resource src_templ;
663   struct pipe_transfer *transfer;
664   struct pipe_blit_info blit;
665   enum pipe_format src_format, dst_format;
666   mesa_format mesa_src_format;
667   GLenum gl_target = texImage->TexObject->Target;
668   unsigned bind;
669   GLubyte *map;
670
671   assert(!_mesa_is_format_etc2(texImage->TexFormat) &&
672          texImage->TexFormat != MESA_FORMAT_ETC1_RGB8);
673
674   if (!st->prefer_blit_based_texture_transfer) {
675      goto fallback;
676   }
677
678   if (!dst) {
679      goto fallback;
680   }
681
682   /* XXX Fallback for depth-stencil formats due to an incomplete stencil
683    * blit implementation in some drivers. */
684   if (format == GL_DEPTH_STENCIL) {
685      goto fallback;
686   }
687
688   /* If the base internal format and the texture format don't match,
689    * we can't use blit-based TexSubImage. */
690   if (texImage->_BaseFormat !=
691       _mesa_get_format_base_format(texImage->TexFormat)) {
692      goto fallback;
693   }
694
695   /* See if the texture format already matches the format and type,
696    * in which case the memcpy-based fast path will likely be used and
697    * we don't have to blit. */
698   if (_mesa_format_matches_format_and_type(texImage->TexFormat, format,
699                                            type, unpack->SwapBytes)) {
700      goto fallback;
701   }
702
703   if (format == GL_DEPTH_COMPONENT || format == GL_DEPTH_STENCIL)
704      bind = PIPE_BIND_DEPTH_STENCIL;
705   else
706      bind = PIPE_BIND_RENDER_TARGET;
707
708   /* See if the destination format is supported.
709    * For luminance and intensity, only the red channel is stored there. */
710   dst_format = util_format_linear(dst->format);
711   dst_format = util_format_luminance_to_red(dst_format);
712   dst_format = util_format_intensity_to_red(dst_format);
713
714   if (!dst_format ||
715       !screen->is_format_supported(screen, dst_format, dst->target,
716                                    dst->nr_samples, bind)) {
717      goto fallback;
718   }
719
720   /* Choose the source format. */
721   src_format = st_choose_matching_format(st, PIPE_BIND_SAMPLER_VIEW,
722                                          format, type, unpack->SwapBytes);
723   if (!src_format) {
724      goto fallback;
725   }
726
727   mesa_src_format = st_pipe_format_to_mesa_format(src_format);
728
729   /* There is no reason to do this if we cannot use memcpy for the temporary
730    * source texture at least. This also takes transfer ops into account,
731    * etc. */
732   if (!_mesa_texstore_can_use_memcpy(ctx,
733                             _mesa_get_format_base_format(mesa_src_format),
734                             mesa_src_format, format, type, unpack)) {
735      goto fallback;
736   }
737
738   /* TexSubImage only sets a single cubemap face. */
739   if (gl_target == GL_TEXTURE_CUBE_MAP) {
740      gl_target = GL_TEXTURE_2D;
741   }
742
743   /* Initialize the source texture description. */
744   memset(&src_templ, 0, sizeof(src_templ));
745   src_templ.target = gl_target_to_pipe(gl_target);
746   src_templ.format = src_format;
747   src_templ.bind = PIPE_BIND_SAMPLER_VIEW;
748   src_templ.usage = PIPE_USAGE_STAGING;
749
750   st_gl_texture_dims_to_pipe_dims(gl_target, width, height, depth,
751                                   &src_templ.width0, &src_templ.height0,
752                                   &src_templ.depth0, &src_templ.array_size);
753
754   /* Check for NPOT texture support. */
755   if (!screen->get_param(screen, PIPE_CAP_NPOT_TEXTURES) &&
756       (!util_is_power_of_two(src_templ.width0) ||
757        !util_is_power_of_two(src_templ.height0) ||
758        !util_is_power_of_two(src_templ.depth0))) {
759      goto fallback;
760   }
761
762   /* Create the source texture. */
763   src = screen->resource_create(screen, &src_templ);
764   if (!src) {
765      goto fallback;
766   }
767
768   /* Map source pixels. */
769   pixels = _mesa_validate_pbo_teximage(ctx, dims, width, height, depth,
770                                        format, type, pixels, unpack,
771                                        "glTexSubImage");
772   if (!pixels) {
773      /* This is a GL error. */
774      pipe_resource_reference(&src, NULL);
775      return;
776   }
777
778   /* From now on, we need the gallium representation of dimensions. */
779   if (gl_target == GL_TEXTURE_1D_ARRAY) {
780      zoffset = yoffset;
781      yoffset = 0;
782      depth = height;
783      height = 1;
784   }
785
786   map = pipe_transfer_map_3d(pipe, src, 0, PIPE_TRANSFER_WRITE, 0, 0, 0,
787                              width, height, depth, &transfer);
788   if (!map) {
789      _mesa_unmap_teximage_pbo(ctx, unpack);
790      pipe_resource_reference(&src, NULL);
791      goto fallback;
792   }
793
794   /* Upload pixels (just memcpy). */
795   {
796      const uint bytesPerRow = width * util_format_get_blocksize(src_format);
797      GLuint row, slice;
798
799      for (slice = 0; slice < (unsigned) depth; slice++) {
800         if (gl_target == GL_TEXTURE_1D_ARRAY) {
801            /* 1D array textures.
802             * We need to convert gallium coords to GL coords.
803             */
804            GLvoid *src = _mesa_image_address3d(unpack, pixels,
805                                                width, depth, format,
806                                                type, 0, slice, 0);
807            memcpy(map, src, bytesPerRow);
808         }
809         else {
810            ubyte *slice_map = map;
811
812            for (row = 0; row < (unsigned) height; row++) {
813               GLvoid *src = _mesa_image_address3d(unpack, pixels,
814                                                   width, height, format,
815                                                   type, slice, row, 0);
816               memcpy(slice_map, src, bytesPerRow);
817               slice_map += transfer->stride;
818            }
819         }
820         map += transfer->layer_stride;
821      }
822   }
823
824   pipe_transfer_unmap(pipe, transfer);
825   _mesa_unmap_teximage_pbo(ctx, unpack);
826
827   /* Blit. */
828   memset(&blit, 0, sizeof(blit));
829   blit.src.resource = src;
830   blit.src.level = 0;
831   blit.src.format = src_format;
832   blit.dst.resource = dst;
833   blit.dst.level = stObj->pt != stImage->pt ? 0 : texImage->TexObject->MinLevel + texImage->Level;
834   blit.dst.format = dst_format;
835   blit.src.box.x = blit.src.box.y = blit.src.box.z = 0;
836   blit.dst.box.x = xoffset;
837   blit.dst.box.y = yoffset;
838   blit.dst.box.z = zoffset + texImage->Face + texImage->TexObject->MinLayer;
839   blit.src.box.width = blit.dst.box.width = width;
840   blit.src.box.height = blit.dst.box.height = height;
841   blit.src.box.depth = blit.dst.box.depth = depth;
842   blit.mask = st_get_blit_mask(format, texImage->_BaseFormat);
843   blit.filter = PIPE_TEX_FILTER_NEAREST;
844   blit.scissor_enable = FALSE;
845
846   st->pipe->blit(st->pipe, &blit);
847
848   pipe_resource_reference(&src, NULL);
849   return;
850
851fallback:
852   _mesa_store_texsubimage(ctx, dims, texImage, xoffset, yoffset, zoffset,
853                           width, height, depth, format, type, pixels,
854                           unpack);
855}
856
857static void
858st_TexImage(struct gl_context * ctx, GLuint dims,
859            struct gl_texture_image *texImage,
860            GLenum format, GLenum type, const void *pixels,
861            const struct gl_pixelstore_attrib *unpack)
862{
863   assert(dims == 1 || dims == 2 || dims == 3);
864
865   prep_teximage(ctx, texImage, format, type);
866
867   if (texImage->Width == 0 || texImage->Height == 0 || texImage->Depth == 0)
868      return;
869
870   /* allocate storage for texture data */
871   if (!ctx->Driver.AllocTextureImageBuffer(ctx, texImage)) {
872      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage%uD", dims);
873      return;
874   }
875
876   st_TexSubImage(ctx, dims, texImage, 0, 0, 0,
877                  texImage->Width, texImage->Height, texImage->Depth,
878                  format, type, pixels, unpack);
879}
880
881
882static void
883st_CompressedTexImage(struct gl_context *ctx, GLuint dims,
884                      struct gl_texture_image *texImage,
885                      GLsizei imageSize, const GLvoid *data)
886{
887   prep_teximage(ctx, texImage, GL_NONE, GL_NONE);
888   _mesa_store_compressed_teximage(ctx, dims, texImage, imageSize, data);
889}
890
891
892
893
894/**
895 * Called via ctx->Driver.GetTexImage()
896 *
897 * This uses a blit to copy the texture to a texture format which matches
898 * the format and type combo and then a fast read-back is done using memcpy.
899 * We can do arbitrary X/Y/Z/W/0/1 swizzling here as long as there is
900 * a format which matches the swizzling.
901 *
902 * If such a format isn't available, it falls back to _mesa_get_teximage.
903 *
904 * NOTE: Drivers usually do a blit to convert between tiled and linear
905 *       texture layouts during texture uploads/downloads, so the blit
906 *       we do here should be free in such cases.
907 */
908static void
909st_GetTexImage(struct gl_context * ctx,
910               GLenum format, GLenum type, GLvoid * pixels,
911               struct gl_texture_image *texImage)
912{
913   struct st_context *st = st_context(ctx);
914   struct pipe_context *pipe = st->pipe;
915   struct pipe_screen *screen = pipe->screen;
916   GLuint width = texImage->Width;
917   GLuint height = texImage->Height;
918   GLuint depth = texImage->Depth;
919   struct st_texture_image *stImage = st_texture_image(texImage);
920   struct st_texture_object *stObj = st_texture_object(texImage->TexObject);
921   struct pipe_resource *src = stObj->pt;
922   struct pipe_resource *dst = NULL;
923   struct pipe_resource dst_templ;
924   enum pipe_format dst_format, src_format;
925   mesa_format mesa_format;
926   GLenum gl_target = texImage->TexObject->Target;
927   enum pipe_texture_target pipe_target;
928   struct pipe_blit_info blit;
929   unsigned bind = PIPE_BIND_TRANSFER_READ;
930   struct pipe_transfer *tex_xfer;
931   ubyte *map = NULL;
932   boolean done = FALSE;
933
934   assert(!_mesa_is_format_etc2(texImage->TexFormat) &&
935          texImage->TexFormat != MESA_FORMAT_ETC1_RGB8);
936
937   if (!st->prefer_blit_based_texture_transfer &&
938       !_mesa_is_format_compressed(texImage->TexFormat)) {
939      /* Try to avoid the fallback if we're doing texture decompression here */
940      goto fallback;
941   }
942
943   if (!stImage->pt || !src) {
944      goto fallback;
945   }
946
947   /* XXX Fallback to _mesa_get_teximage for depth-stencil formats
948    * due to an incomplete stencil blit implementation in some drivers. */
949   if (format == GL_DEPTH_STENCIL) {
950      goto fallback;
951   }
952
953   /* If the base internal format and the texture format don't match, we have
954    * to fall back to _mesa_get_teximage. */
955   if (texImage->_BaseFormat !=
956       _mesa_get_format_base_format(texImage->TexFormat)) {
957      goto fallback;
958   }
959
960   /* See if the texture format already matches the format and type,
961    * in which case the memcpy-based fast path will be used. */
962   if (_mesa_format_matches_format_and_type(texImage->TexFormat, format,
963                                            type, ctx->Pack.SwapBytes)) {
964      goto fallback;
965   }
966
967   /* Convert the source format to what is expected by GetTexImage
968    * and see if it's supported.
969    *
970    * This only applies to glGetTexImage:
971    * - Luminance must be returned as (L,0,0,1).
972    * - Luminance alpha must be returned as (L,0,0,A).
973    * - Intensity must be returned as (I,0,0,1)
974    */
975   if (stObj->surface_based)
976      src_format = util_format_linear(stObj->surface_format);
977   else
978      src_format = util_format_linear(src->format);
979   src_format = util_format_luminance_to_red(src_format);
980   src_format = util_format_intensity_to_red(src_format);
981
982   if (!src_format ||
983       !screen->is_format_supported(screen, src_format, src->target,
984                                    src->nr_samples,
985                                    PIPE_BIND_SAMPLER_VIEW)) {
986      goto fallback;
987   }
988
989   if (format == GL_DEPTH_COMPONENT || format == GL_DEPTH_STENCIL)
990      bind |= PIPE_BIND_DEPTH_STENCIL;
991   else
992      bind |= PIPE_BIND_RENDER_TARGET;
993
994   /* GetTexImage only returns a single face for cubemaps. */
995   if (gl_target == GL_TEXTURE_CUBE_MAP) {
996      gl_target = GL_TEXTURE_2D;
997   }
998   pipe_target = gl_target_to_pipe(gl_target);
999
1000   /* Choose the destination format by finding the best match
1001    * for the format+type combo. */
1002   dst_format = st_choose_matching_format(st, bind, format, type,
1003					  ctx->Pack.SwapBytes);
1004
1005   if (dst_format == PIPE_FORMAT_NONE) {
1006      GLenum dst_glformat;
1007
1008      /* Fall back to _mesa_get_teximage except for compressed formats,
1009       * where decompression with a blit is always preferred. */
1010      if (!util_format_is_compressed(src->format)) {
1011         goto fallback;
1012      }
1013
1014      /* Set the appropriate format for the decompressed texture.
1015       * Luminance and sRGB formats shouldn't appear here.*/
1016      switch (src_format) {
1017      case PIPE_FORMAT_DXT1_RGB:
1018      case PIPE_FORMAT_DXT1_RGBA:
1019      case PIPE_FORMAT_DXT3_RGBA:
1020      case PIPE_FORMAT_DXT5_RGBA:
1021      case PIPE_FORMAT_RGTC1_UNORM:
1022      case PIPE_FORMAT_RGTC2_UNORM:
1023      case PIPE_FORMAT_ETC1_RGB8:
1024      case PIPE_FORMAT_BPTC_RGBA_UNORM:
1025         dst_glformat = GL_RGBA8;
1026         break;
1027      case PIPE_FORMAT_RGTC1_SNORM:
1028      case PIPE_FORMAT_RGTC2_SNORM:
1029         if (!ctx->Extensions.EXT_texture_snorm)
1030            goto fallback;
1031         dst_glformat = GL_RGBA8_SNORM;
1032         break;
1033      case PIPE_FORMAT_BPTC_RGB_FLOAT:
1034      case PIPE_FORMAT_BPTC_RGB_UFLOAT:
1035         if (!ctx->Extensions.ARB_texture_float)
1036            goto fallback;
1037         dst_glformat = GL_RGBA32F;
1038         break;
1039      default:
1040         assert(0);
1041         goto fallback;
1042      }
1043
1044      dst_format = st_choose_format(st, dst_glformat, format, type,
1045                                    pipe_target, 0, bind, FALSE);
1046
1047      if (dst_format == PIPE_FORMAT_NONE) {
1048         /* unable to get an rgba format!?! */
1049         goto fallback;
1050      }
1051   }
1052
1053   /* create the destination texture */
1054   memset(&dst_templ, 0, sizeof(dst_templ));
1055   dst_templ.target = pipe_target;
1056   dst_templ.format = dst_format;
1057   dst_templ.bind = bind;
1058   dst_templ.usage = PIPE_USAGE_STAGING;
1059
1060   st_gl_texture_dims_to_pipe_dims(gl_target, width, height, depth,
1061                                   &dst_templ.width0, &dst_templ.height0,
1062                                   &dst_templ.depth0, &dst_templ.array_size);
1063
1064   dst = screen->resource_create(screen, &dst_templ);
1065   if (!dst) {
1066      goto fallback;
1067   }
1068
1069   /* From now on, we need the gallium representation of dimensions. */
1070   if (gl_target == GL_TEXTURE_1D_ARRAY) {
1071      depth = height;
1072      height = 1;
1073   }
1074
1075   memset(&blit, 0, sizeof(blit));
1076   blit.src.resource = src;
1077   blit.src.level = texImage->Level + texImage->TexObject->MinLevel;
1078   blit.src.format = src_format;
1079   blit.dst.resource = dst;
1080   blit.dst.level = 0;
1081   blit.dst.format = dst->format;
1082   blit.src.box.x = blit.dst.box.x = 0;
1083   blit.src.box.y = blit.dst.box.y = 0;
1084   blit.src.box.z = texImage->Face + texImage->TexObject->MinLayer;
1085   blit.dst.box.z = 0;
1086   blit.src.box.width = blit.dst.box.width = width;
1087   blit.src.box.height = blit.dst.box.height = height;
1088   blit.src.box.depth = blit.dst.box.depth = depth;
1089   blit.mask = st_get_blit_mask(texImage->_BaseFormat, format);
1090   blit.filter = PIPE_TEX_FILTER_NEAREST;
1091   blit.scissor_enable = FALSE;
1092
1093   /* blit/render/decompress */
1094   st->pipe->blit(st->pipe, &blit);
1095
1096   pixels = _mesa_map_pbo_dest(ctx, &ctx->Pack, pixels);
1097
1098   map = pipe_transfer_map_3d(pipe, dst, 0, PIPE_TRANSFER_READ,
1099                              0, 0, 0, width, height, depth, &tex_xfer);
1100   if (!map) {
1101      goto end;
1102   }
1103
1104   mesa_format = st_pipe_format_to_mesa_format(dst_format);
1105
1106   /* copy/pack data into user buffer */
1107   if (_mesa_format_matches_format_and_type(mesa_format, format, type,
1108                                            ctx->Pack.SwapBytes)) {
1109      /* memcpy */
1110      const uint bytesPerRow = width * util_format_get_blocksize(dst_format);
1111      GLuint row, slice;
1112
1113      for (slice = 0; slice < depth; slice++) {
1114         if (gl_target == GL_TEXTURE_1D_ARRAY) {
1115            /* 1D array textures.
1116             * We need to convert gallium coords to GL coords.
1117             */
1118            GLvoid *dest = _mesa_image_address3d(&ctx->Pack, pixels,
1119                                                 width, depth, format,
1120                                                 type, 0, slice, 0);
1121            memcpy(dest, map, bytesPerRow);
1122         }
1123         else {
1124            ubyte *slice_map = map;
1125
1126            for (row = 0; row < height; row++) {
1127               GLvoid *dest = _mesa_image_address3d(&ctx->Pack, pixels,
1128                                                    width, height, format,
1129                                                    type, slice, row, 0);
1130               memcpy(dest, slice_map, bytesPerRow);
1131               slice_map += tex_xfer->stride;
1132            }
1133         }
1134         map += tex_xfer->layer_stride;
1135      }
1136   }
1137   else {
1138      /* format translation via floats */
1139      GLuint row, slice;
1140      GLfloat *rgba;
1141
1142      assert(util_format_is_compressed(src->format));
1143
1144      rgba = malloc(width * 4 * sizeof(GLfloat));
1145      if (!rgba) {
1146         goto end;
1147      }
1148
1149      if (ST_DEBUG & DEBUG_FALLBACK)
1150         debug_printf("%s: fallback format translation\n", __FUNCTION__);
1151
1152      for (slice = 0; slice < depth; slice++) {
1153         if (gl_target == GL_TEXTURE_1D_ARRAY) {
1154            /* 1D array textures.
1155             * We need to convert gallium coords to GL coords.
1156             */
1157            GLvoid *dest = _mesa_image_address3d(&ctx->Pack, pixels,
1158                                                 width, depth, format,
1159                                                 type, 0, slice, 0);
1160
1161            /* get float[4] rgba row from surface */
1162            pipe_get_tile_rgba_format(tex_xfer, map, 0, 0, width, 1,
1163                                      dst_format, rgba);
1164
1165            _mesa_pack_rgba_span_float(ctx, width, (GLfloat (*)[4]) rgba, format,
1166                                       type, dest, &ctx->Pack, 0);
1167         }
1168         else {
1169            for (row = 0; row < height; row++) {
1170               GLvoid *dest = _mesa_image_address3d(&ctx->Pack, pixels,
1171                                                    width, height, format,
1172                                                    type, slice, row, 0);
1173
1174               /* get float[4] rgba row from surface */
1175               pipe_get_tile_rgba_format(tex_xfer, map, 0, row, width, 1,
1176                                         dst_format, rgba);
1177
1178               _mesa_pack_rgba_span_float(ctx, width, (GLfloat (*)[4]) rgba, format,
1179                                          type, dest, &ctx->Pack, 0);
1180            }
1181         }
1182         map += tex_xfer->layer_stride;
1183      }
1184
1185      free(rgba);
1186   }
1187   done = TRUE;
1188
1189end:
1190   if (map)
1191      pipe_transfer_unmap(pipe, tex_xfer);
1192
1193   _mesa_unmap_pbo_dest(ctx, &ctx->Pack);
1194   pipe_resource_reference(&dst, NULL);
1195
1196fallback:
1197   if (!done) {
1198      _mesa_get_teximage(ctx, format, type, pixels, texImage);
1199   }
1200}
1201
1202
1203/**
1204 * Do a CopyTexSubImage operation using a read transfer from the source,
1205 * a write transfer to the destination and get_tile()/put_tile() to access
1206 * the pixels/texels.
1207 *
1208 * Note: srcY=0=TOP of renderbuffer
1209 */
1210static void
1211fallback_copy_texsubimage(struct gl_context *ctx,
1212                          struct st_renderbuffer *strb,
1213                          struct st_texture_image *stImage,
1214                          GLenum baseFormat,
1215                          GLint destX, GLint destY, GLint slice,
1216                          GLint srcX, GLint srcY,
1217                          GLsizei width, GLsizei height)
1218{
1219   struct st_context *st = st_context(ctx);
1220   struct pipe_context *pipe = st->pipe;
1221   struct pipe_transfer *src_trans;
1222   GLubyte *texDest;
1223   enum pipe_transfer_usage transfer_usage;
1224   void *map;
1225   unsigned dst_width = width;
1226   unsigned dst_height = height;
1227   unsigned dst_depth = 1;
1228   struct pipe_transfer *transfer;
1229
1230   if (ST_DEBUG & DEBUG_FALLBACK)
1231      debug_printf("%s: fallback processing\n", __FUNCTION__);
1232
1233   if (st_fb_orientation(ctx->ReadBuffer) == Y_0_TOP) {
1234      srcY = strb->Base.Height - srcY - height;
1235   }
1236
1237   map = pipe_transfer_map(pipe,
1238                           strb->texture,
1239                           strb->surface->u.tex.level,
1240                           strb->surface->u.tex.first_layer,
1241                           PIPE_TRANSFER_READ,
1242                           srcX, srcY,
1243                           width, height, &src_trans);
1244
1245   if ((baseFormat == GL_DEPTH_COMPONENT ||
1246        baseFormat == GL_DEPTH_STENCIL) &&
1247       util_format_is_depth_and_stencil(stImage->pt->format))
1248      transfer_usage = PIPE_TRANSFER_READ_WRITE;
1249   else
1250      transfer_usage = PIPE_TRANSFER_WRITE;
1251
1252   texDest = st_texture_image_map(st, stImage, transfer_usage,
1253                                  destX, destY, slice,
1254                                  dst_width, dst_height, dst_depth,
1255                                  &transfer);
1256
1257   if (baseFormat == GL_DEPTH_COMPONENT ||
1258       baseFormat == GL_DEPTH_STENCIL) {
1259      const GLboolean scaleOrBias = (ctx->Pixel.DepthScale != 1.0F ||
1260                                     ctx->Pixel.DepthBias != 0.0F);
1261      GLint row, yStep;
1262      uint *data;
1263
1264      /* determine bottom-to-top vs. top-to-bottom order for src buffer */
1265      if (st_fb_orientation(ctx->ReadBuffer) == Y_0_TOP) {
1266         srcY = height - 1;
1267         yStep = -1;
1268      }
1269      else {
1270         srcY = 0;
1271         yStep = 1;
1272      }
1273
1274      data = malloc(width * sizeof(uint));
1275
1276      if (data) {
1277         /* To avoid a large temp memory allocation, do copy row by row */
1278         for (row = 0; row < height; row++, srcY += yStep) {
1279            pipe_get_tile_z(src_trans, map, 0, srcY, width, 1, data);
1280            if (scaleOrBias) {
1281               _mesa_scale_and_bias_depth_uint(ctx, width, data);
1282            }
1283
1284            if (stImage->pt->target == PIPE_TEXTURE_1D_ARRAY) {
1285               pipe_put_tile_z(transfer, texDest + row*transfer->layer_stride,
1286                               0, 0, width, 1, data);
1287            }
1288            else {
1289               pipe_put_tile_z(transfer, texDest, 0, row, width, 1, data);
1290            }
1291         }
1292      }
1293      else {
1294         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexSubImage()");
1295      }
1296
1297      free(data);
1298   }
1299   else {
1300      /* RGBA format */
1301      GLfloat *tempSrc =
1302         malloc(width * height * 4 * sizeof(GLfloat));
1303
1304      if (tempSrc && texDest) {
1305         const GLint dims = 2;
1306         GLint dstRowStride;
1307         struct gl_texture_image *texImage = &stImage->base;
1308         struct gl_pixelstore_attrib unpack = ctx->DefaultPacking;
1309
1310         if (st_fb_orientation(ctx->ReadBuffer) == Y_0_TOP) {
1311            unpack.Invert = GL_TRUE;
1312         }
1313
1314         if (stImage->pt->target == PIPE_TEXTURE_1D_ARRAY) {
1315            dstRowStride = transfer->layer_stride;
1316         }
1317         else {
1318            dstRowStride = transfer->stride;
1319         }
1320
1321         /* get float/RGBA image from framebuffer */
1322         /* XXX this usually involves a lot of int/float conversion.
1323          * try to avoid that someday.
1324          */
1325         pipe_get_tile_rgba_format(src_trans, map, 0, 0, width, height,
1326                                   util_format_linear(strb->texture->format),
1327                                   tempSrc);
1328
1329         /* Store into texture memory.
1330          * Note that this does some special things such as pixel transfer
1331          * ops and format conversion.  In particular, if the dest tex format
1332          * is actually RGBA but the user created the texture as GL_RGB we
1333          * need to fill-in/override the alpha channel with 1.0.
1334          */
1335         _mesa_texstore(ctx, dims,
1336                        texImage->_BaseFormat,
1337                        texImage->TexFormat,
1338                        dstRowStride,
1339                        &texDest,
1340                        width, height, 1,
1341                        GL_RGBA, GL_FLOAT, tempSrc, /* src */
1342                        &unpack);
1343      }
1344      else {
1345         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage");
1346      }
1347
1348      free(tempSrc);
1349   }
1350
1351   st_texture_image_unmap(st, stImage, slice);
1352   pipe->transfer_unmap(pipe, src_trans);
1353}
1354
1355
1356/**
1357 * Do a CopyTex[Sub]Image1/2/3D() using a hardware (blit) path if possible.
1358 * Note that the region to copy has already been clipped so we know we
1359 * won't read from outside the source renderbuffer's bounds.
1360 *
1361 * Note: srcY=0=Bottom of renderbuffer (GL convention)
1362 */
1363static void
1364st_CopyTexSubImage(struct gl_context *ctx, GLuint dims,
1365                   struct gl_texture_image *texImage,
1366                   GLint destX, GLint destY, GLint slice,
1367                   struct gl_renderbuffer *rb,
1368                   GLint srcX, GLint srcY, GLsizei width, GLsizei height)
1369{
1370   struct st_texture_image *stImage = st_texture_image(texImage);
1371   struct st_texture_object *stObj = st_texture_object(texImage->TexObject);
1372   struct st_renderbuffer *strb = st_renderbuffer(rb);
1373   struct st_context *st = st_context(ctx);
1374   struct pipe_context *pipe = st->pipe;
1375   struct pipe_screen *screen = pipe->screen;
1376   struct pipe_blit_info blit;
1377   enum pipe_format dst_format;
1378   GLboolean do_flip = (st_fb_orientation(ctx->ReadBuffer) == Y_0_TOP);
1379   unsigned bind;
1380   GLint srcY0, srcY1;
1381
1382   assert(!_mesa_is_format_etc2(texImage->TexFormat) &&
1383          texImage->TexFormat != MESA_FORMAT_ETC1_RGB8);
1384
1385   if (!strb || !strb->surface || !stImage->pt) {
1386      debug_printf("%s: null strb or stImage\n", __FUNCTION__);
1387      return;
1388   }
1389
1390   if (_mesa_texstore_needs_transfer_ops(ctx, texImage->_BaseFormat,
1391                                         texImage->TexFormat)) {
1392      goto fallback;
1393   }
1394
1395   /* The base internal format must match the mesa format, so make sure
1396    * e.g. an RGB internal format is really allocated as RGB and not as RGBA.
1397    */
1398   if (texImage->_BaseFormat !=
1399       _mesa_get_format_base_format(texImage->TexFormat) ||
1400       rb->_BaseFormat != _mesa_get_format_base_format(rb->Format)) {
1401      goto fallback;
1402   }
1403
1404   /* Choose the destination format to match the TexImage behavior. */
1405   dst_format = util_format_linear(stImage->pt->format);
1406   dst_format = util_format_luminance_to_red(dst_format);
1407   dst_format = util_format_intensity_to_red(dst_format);
1408
1409   /* See if the destination format is supported. */
1410   if (texImage->_BaseFormat == GL_DEPTH_STENCIL ||
1411       texImage->_BaseFormat == GL_DEPTH_COMPONENT) {
1412      bind = PIPE_BIND_DEPTH_STENCIL;
1413   }
1414   else {
1415      bind = PIPE_BIND_RENDER_TARGET;
1416   }
1417
1418   if (!dst_format ||
1419       !screen->is_format_supported(screen, dst_format, stImage->pt->target,
1420                                    stImage->pt->nr_samples, bind)) {
1421      goto fallback;
1422   }
1423
1424   /* Y flipping for the main framebuffer. */
1425   if (do_flip) {
1426      srcY1 = strb->Base.Height - srcY - height;
1427      srcY0 = srcY1 + height;
1428   }
1429   else {
1430      srcY0 = srcY;
1431      srcY1 = srcY0 + height;
1432   }
1433
1434   /* Blit the texture.
1435    * This supports flipping, format conversions, and downsampling.
1436    */
1437   memset(&blit, 0, sizeof(blit));
1438   blit.src.resource = strb->texture;
1439   blit.src.format = util_format_linear(strb->surface->format);
1440   blit.src.level = strb->surface->u.tex.level;
1441   blit.src.box.x = srcX;
1442   blit.src.box.y = srcY0;
1443   blit.src.box.z = strb->surface->u.tex.first_layer;
1444   blit.src.box.width = width;
1445   blit.src.box.height = srcY1 - srcY0;
1446   blit.src.box.depth = 1;
1447   blit.dst.resource = stImage->pt;
1448   blit.dst.format = dst_format;
1449   blit.dst.level = stObj->pt != stImage->pt ? 0 : texImage->Level + texImage->TexObject->MinLevel;
1450   blit.dst.box.x = destX;
1451   blit.dst.box.y = destY;
1452   blit.dst.box.z = stImage->base.Face + slice + texImage->TexObject->MinLayer;
1453   blit.dst.box.width = width;
1454   blit.dst.box.height = height;
1455   blit.dst.box.depth = 1;
1456   blit.mask = st_get_blit_mask(rb->_BaseFormat, texImage->_BaseFormat);
1457   blit.filter = PIPE_TEX_FILTER_NEAREST;
1458   pipe->blit(pipe, &blit);
1459   return;
1460
1461fallback:
1462   /* software fallback */
1463   fallback_copy_texsubimage(ctx,
1464                             strb, stImage, texImage->_BaseFormat,
1465                             destX, destY, slice,
1466                             srcX, srcY, width, height);
1467}
1468
1469
1470/**
1471 * Copy image data from stImage into the texture object 'stObj' at level
1472 * 'dstLevel'.
1473 */
1474static void
1475copy_image_data_to_texture(struct st_context *st,
1476			   struct st_texture_object *stObj,
1477                           GLuint dstLevel,
1478			   struct st_texture_image *stImage)
1479{
1480   /* debug checks */
1481   {
1482      const struct gl_texture_image *dstImage =
1483         stObj->base.Image[stImage->base.Face][dstLevel];
1484      assert(dstImage);
1485      assert(dstImage->Width == stImage->base.Width);
1486      assert(dstImage->Height == stImage->base.Height);
1487      assert(dstImage->Depth == stImage->base.Depth);
1488   }
1489
1490   if (stImage->pt) {
1491      /* Copy potentially with the blitter:
1492       */
1493      GLuint src_level;
1494      if (stImage->pt->last_level == 0)
1495         src_level = 0;
1496      else
1497         src_level = stImage->base.Level;
1498
1499      assert(src_level <= stImage->pt->last_level);
1500      assert(u_minify(stImage->pt->width0, src_level) == stImage->base.Width);
1501      assert(stImage->pt->target == PIPE_TEXTURE_1D_ARRAY ||
1502             u_minify(stImage->pt->height0, src_level) == stImage->base.Height);
1503      assert(stImage->pt->target == PIPE_TEXTURE_2D_ARRAY ||
1504             stImage->pt->target == PIPE_TEXTURE_CUBE_ARRAY ||
1505             u_minify(stImage->pt->depth0, src_level) == stImage->base.Depth);
1506
1507      st_texture_image_copy(st->pipe,
1508                            stObj->pt, dstLevel,  /* dest texture, level */
1509                            stImage->pt, src_level, /* src texture, level */
1510                            stImage->base.Face);
1511
1512      pipe_resource_reference(&stImage->pt, NULL);
1513   }
1514   else if (stImage->TexData) {
1515      /* Copy from malloc'd memory */
1516      /* XXX this should be re-examined/tested with a compressed format */
1517      GLuint blockSize = util_format_get_blocksize(stObj->pt->format);
1518      GLuint srcRowStride = stImage->base.Width * blockSize;
1519      GLuint srcSliceStride = stImage->base.Height * srcRowStride;
1520      st_texture_image_data(st,
1521                            stObj->pt,
1522                            stImage->base.Face,
1523                            dstLevel,
1524                            stImage->TexData,
1525                            srcRowStride,
1526                            srcSliceStride);
1527      _mesa_align_free(stImage->TexData);
1528      stImage->TexData = NULL;
1529   }
1530
1531   pipe_resource_reference(&stImage->pt, stObj->pt);
1532}
1533
1534
1535/**
1536 * Called during state validation.  When this function is finished,
1537 * the texture object should be ready for rendering.
1538 * \return GL_TRUE for success, GL_FALSE for failure (out of mem)
1539 */
1540GLboolean
1541st_finalize_texture(struct gl_context *ctx,
1542		    struct pipe_context *pipe,
1543		    struct gl_texture_object *tObj)
1544{
1545   struct st_context *st = st_context(ctx);
1546   struct st_texture_object *stObj = st_texture_object(tObj);
1547   const GLuint nr_faces = (stObj->base.Target == GL_TEXTURE_CUBE_MAP) ? 6 : 1;
1548   GLuint face;
1549   const struct st_texture_image *firstImage;
1550   enum pipe_format firstImageFormat;
1551   GLuint ptWidth, ptHeight, ptDepth, ptLayers, ptNumSamples;
1552
1553   if (tObj->Immutable)
1554      return GL_TRUE;
1555
1556   if (_mesa_is_texture_complete(tObj, &tObj->Sampler)) {
1557      /* The texture is complete and we know exactly how many mipmap levels
1558       * are present/needed.  This is conditional because we may be called
1559       * from the st_generate_mipmap() function when the texture object is
1560       * incomplete.  In that case, we'll have set stObj->lastLevel before
1561       * we get here.
1562       */
1563      if (stObj->base.Sampler.MinFilter == GL_LINEAR ||
1564          stObj->base.Sampler.MinFilter == GL_NEAREST)
1565         stObj->lastLevel = stObj->base.BaseLevel;
1566      else
1567         stObj->lastLevel = stObj->base._MaxLevel;
1568   }
1569
1570   if (tObj->Target == GL_TEXTURE_BUFFER) {
1571      struct st_buffer_object *st_obj = st_buffer_object(tObj->BufferObject);
1572
1573      if (!st_obj) {
1574         pipe_resource_reference(&stObj->pt, NULL);
1575         st_texture_release_all_sampler_views(st, stObj);
1576         return GL_TRUE;
1577      }
1578
1579      if (st_obj->buffer != stObj->pt) {
1580         pipe_resource_reference(&stObj->pt, st_obj->buffer);
1581         st_texture_release_all_sampler_views(st, stObj);
1582         stObj->width0 = stObj->pt->width0 / _mesa_get_format_bytes(tObj->_BufferObjectFormat);
1583         stObj->height0 = 1;
1584         stObj->depth0 = 1;
1585      }
1586      return GL_TRUE;
1587
1588   }
1589
1590   firstImage = st_texture_image_const(_mesa_base_tex_image(&stObj->base));
1591   assert(firstImage);
1592
1593   /* If both firstImage and stObj point to a texture which can contain
1594    * all active images, favour firstImage.  Note that because of the
1595    * completeness requirement, we know that the image dimensions
1596    * will match.
1597    */
1598   if (firstImage->pt &&
1599       firstImage->pt != stObj->pt &&
1600       (!stObj->pt || firstImage->pt->last_level >= stObj->pt->last_level)) {
1601      pipe_resource_reference(&stObj->pt, firstImage->pt);
1602      st_texture_release_all_sampler_views(st, stObj);
1603   }
1604
1605   /* If this texture comes from a window system, there is nothing else to do. */
1606   if (stObj->surface_based) {
1607      return GL_TRUE;
1608   }
1609
1610   /* Find gallium format for the Mesa texture */
1611   firstImageFormat =
1612      st_mesa_format_to_pipe_format(st, firstImage->base.TexFormat);
1613
1614   /* Find size of level=0 Gallium mipmap image, plus number of texture layers */
1615   {
1616      GLuint width, height, depth;
1617      if (!guess_base_level_size(stObj->base.Target,
1618                                 firstImage->base.Width2,
1619                                 firstImage->base.Height2,
1620                                 firstImage->base.Depth2,
1621                                 firstImage->base.Level,
1622                                 &width, &height, &depth)) {
1623         width = stObj->width0;
1624         height = stObj->height0;
1625         depth = stObj->depth0;
1626      }
1627      /* convert GL dims to Gallium dims */
1628      st_gl_texture_dims_to_pipe_dims(stObj->base.Target, width, height, depth,
1629                                      &ptWidth, &ptHeight, &ptDepth, &ptLayers);
1630      ptNumSamples = firstImage->base.NumSamples;
1631   }
1632
1633   /* If we already have a gallium texture, check that it matches the texture
1634    * object's format, target, size, num_levels, etc.
1635    */
1636   if (stObj->pt) {
1637      if (stObj->pt->target != gl_target_to_pipe(stObj->base.Target) ||
1638          stObj->pt->format != firstImageFormat ||
1639          stObj->pt->last_level < stObj->lastLevel ||
1640          stObj->pt->width0 != ptWidth ||
1641          stObj->pt->height0 != ptHeight ||
1642          stObj->pt->depth0 != ptDepth ||
1643          stObj->pt->nr_samples != ptNumSamples ||
1644          stObj->pt->array_size != ptLayers)
1645      {
1646         /* The gallium texture does not match the Mesa texture so delete the
1647          * gallium texture now.  We'll make a new one below.
1648          */
1649         pipe_resource_reference(&stObj->pt, NULL);
1650         st_texture_release_all_sampler_views(st, stObj);
1651         st->dirty.st |= ST_NEW_FRAMEBUFFER;
1652      }
1653   }
1654
1655   /* May need to create a new gallium texture:
1656    */
1657   if (!stObj->pt) {
1658      GLuint bindings = default_bindings(st, firstImageFormat);
1659
1660      stObj->pt = st_texture_create(st,
1661                                    gl_target_to_pipe(stObj->base.Target),
1662                                    firstImageFormat,
1663                                    stObj->lastLevel,
1664                                    ptWidth,
1665                                    ptHeight,
1666                                    ptDepth,
1667                                    ptLayers, ptNumSamples,
1668                                    bindings);
1669
1670      if (!stObj->pt) {
1671         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage");
1672         return GL_FALSE;
1673      }
1674   }
1675
1676   /* Pull in any images not in the object's texture:
1677    */
1678   for (face = 0; face < nr_faces; face++) {
1679      GLuint level;
1680      for (level = stObj->base.BaseLevel; level <= stObj->lastLevel; level++) {
1681         struct st_texture_image *stImage =
1682            st_texture_image(stObj->base.Image[face][level]);
1683
1684         /* Need to import images in main memory or held in other textures.
1685          */
1686         if (stImage && stObj->pt != stImage->pt) {
1687            if (level == 0 ||
1688                (stImage->base.Width == u_minify(stObj->width0, level) &&
1689                 stImage->base.Height == u_minify(stObj->height0, level) &&
1690                 stImage->base.Depth == u_minify(stObj->depth0, level))) {
1691               /* src image fits expected dest mipmap level size */
1692               copy_image_data_to_texture(st, stObj, level, stImage);
1693            }
1694         }
1695      }
1696   }
1697
1698   return GL_TRUE;
1699}
1700
1701
1702/**
1703 * Called via ctx->Driver.AllocTextureStorage() to allocate texture memory
1704 * for a whole mipmap stack.
1705 */
1706static GLboolean
1707st_AllocTextureStorage(struct gl_context *ctx,
1708                       struct gl_texture_object *texObj,
1709                       GLsizei levels, GLsizei width,
1710                       GLsizei height, GLsizei depth)
1711{
1712   const GLuint numFaces = _mesa_num_tex_faces(texObj->Target);
1713   struct gl_texture_image *texImage = texObj->Image[0][0];
1714   struct st_context *st = st_context(ctx);
1715   struct st_texture_object *stObj = st_texture_object(texObj);
1716   struct pipe_screen *screen = st->pipe->screen;
1717   GLuint ptWidth, ptHeight, ptDepth, ptLayers, bindings;
1718   enum pipe_format fmt;
1719   GLint level;
1720   GLuint num_samples = texImage->NumSamples;
1721
1722   assert(levels > 0);
1723
1724   /* Save the level=0 dimensions */
1725   stObj->width0 = width;
1726   stObj->height0 = height;
1727   stObj->depth0 = depth;
1728   stObj->lastLevel = levels - 1;
1729
1730   fmt = st_mesa_format_to_pipe_format(st, texImage->TexFormat);
1731
1732   bindings = default_bindings(st, fmt);
1733
1734   /* Raise the sample count if the requested one is unsupported. */
1735   if (num_samples > 1) {
1736      boolean found = FALSE;
1737
1738      for (; num_samples <= ctx->Const.MaxSamples; num_samples++) {
1739         if (screen->is_format_supported(screen, fmt, PIPE_TEXTURE_2D,
1740                                         num_samples,
1741                                         PIPE_BIND_SAMPLER_VIEW)) {
1742            /* Update the sample count in gl_texture_image as well. */
1743            texImage->NumSamples = num_samples;
1744            found = TRUE;
1745            break;
1746         }
1747      }
1748
1749      if (!found) {
1750         return GL_FALSE;
1751      }
1752   }
1753
1754   st_gl_texture_dims_to_pipe_dims(texObj->Target,
1755                                   width, height, depth,
1756                                   &ptWidth, &ptHeight, &ptDepth, &ptLayers);
1757
1758   stObj->pt = st_texture_create(st,
1759                                 gl_target_to_pipe(texObj->Target),
1760                                 fmt,
1761                                 levels - 1,
1762                                 ptWidth,
1763                                 ptHeight,
1764                                 ptDepth,
1765                                 ptLayers, num_samples,
1766                                 bindings);
1767   if (!stObj->pt)
1768      return GL_FALSE;
1769
1770   /* Set image resource pointers */
1771   for (level = 0; level < levels; level++) {
1772      GLuint face;
1773      for (face = 0; face < numFaces; face++) {
1774         struct st_texture_image *stImage =
1775            st_texture_image(texObj->Image[face][level]);
1776         pipe_resource_reference(&stImage->pt, stObj->pt);
1777      }
1778   }
1779
1780   return GL_TRUE;
1781}
1782
1783
1784static GLboolean
1785st_TestProxyTexImage(struct gl_context *ctx, GLenum target,
1786                     GLint level, mesa_format format,
1787                     GLint width, GLint height,
1788                     GLint depth, GLint border)
1789{
1790   struct st_context *st = st_context(ctx);
1791   struct pipe_context *pipe = st->pipe;
1792
1793   if (width == 0 || height == 0 || depth == 0) {
1794      /* zero-sized images are legal, and always fit! */
1795      return GL_TRUE;
1796   }
1797
1798   if (pipe->screen->can_create_resource) {
1799      /* Ask the gallium driver if the texture is too large */
1800      struct gl_texture_object *texObj =
1801         _mesa_get_current_tex_object(ctx, target);
1802      struct pipe_resource pt;
1803
1804      /* Setup the pipe_resource object
1805       */
1806      memset(&pt, 0, sizeof(pt));
1807
1808      pt.target = gl_target_to_pipe(target);
1809      pt.format = st_mesa_format_to_pipe_format(st, format);
1810
1811      st_gl_texture_dims_to_pipe_dims(target,
1812                                      width, height, depth,
1813                                      &pt.width0, &pt.height0,
1814                                      &pt.depth0, &pt.array_size);
1815
1816      if (level == 0 && (texObj->Sampler.MinFilter == GL_LINEAR ||
1817                         texObj->Sampler.MinFilter == GL_NEAREST)) {
1818         /* assume just one mipmap level */
1819         pt.last_level = 0;
1820      }
1821      else {
1822         /* assume a full set of mipmaps */
1823         pt.last_level = _mesa_logbase2(MAX3(width, height, depth));
1824      }
1825
1826      return pipe->screen->can_create_resource(pipe->screen, &pt);
1827   }
1828   else {
1829      /* Use core Mesa fallback */
1830      return _mesa_test_proxy_teximage(ctx, target, level, format,
1831                                       width, height, depth, border);
1832   }
1833}
1834
1835static GLboolean
1836st_TextureView(struct gl_context *ctx,
1837               struct gl_texture_object *texObj,
1838               struct gl_texture_object *origTexObj)
1839{
1840   struct st_texture_object *orig = st_texture_object(origTexObj);
1841   struct st_texture_object *tex = st_texture_object(texObj);
1842   struct gl_texture_image *image = texObj->Image[0][0];
1843
1844   const int numFaces = _mesa_num_tex_faces(texObj->Target);
1845   const int numLevels = texObj->NumLevels;
1846
1847   int face;
1848   int level;
1849
1850   pipe_resource_reference(&tex->pt, orig->pt);
1851
1852   /* Set image resource pointers */
1853   for (level = 0; level < numLevels; level++) {
1854      for (face = 0; face < numFaces; face++) {
1855         struct st_texture_image *stImage =
1856            st_texture_image(texObj->Image[face][level]);
1857         pipe_resource_reference(&stImage->pt, tex->pt);
1858      }
1859   }
1860
1861   tex->surface_based = GL_TRUE;
1862   tex->surface_format =
1863      st_mesa_format_to_pipe_format(st_context(ctx), image->TexFormat);
1864
1865   tex->width0 = image->Width;
1866   tex->height0 = image->Height;
1867   tex->depth0 = image->Depth;
1868   tex->lastLevel = numLevels - 1;
1869
1870   return GL_TRUE;
1871}
1872
1873
1874void
1875st_init_texture_functions(struct dd_function_table *functions)
1876{
1877   functions->ChooseTextureFormat = st_ChooseTextureFormat;
1878   functions->QuerySamplesForFormat = st_QuerySamplesForFormat;
1879   functions->TexImage = st_TexImage;
1880   functions->TexSubImage = st_TexSubImage;
1881   functions->CompressedTexSubImage = _mesa_store_compressed_texsubimage;
1882   functions->CopyTexSubImage = st_CopyTexSubImage;
1883   functions->GenerateMipmap = st_generate_mipmap;
1884
1885   functions->GetTexImage = st_GetTexImage;
1886
1887   /* compressed texture functions */
1888   functions->CompressedTexImage = st_CompressedTexImage;
1889   functions->GetCompressedTexImage = _mesa_get_compressed_teximage;
1890
1891   functions->NewTextureObject = st_NewTextureObject;
1892   functions->NewTextureImage = st_NewTextureImage;
1893   functions->DeleteTextureImage = st_DeleteTextureImage;
1894   functions->DeleteTexture = st_DeleteTextureObject;
1895   functions->AllocTextureImageBuffer = st_AllocTextureImageBuffer;
1896   functions->FreeTextureImageBuffer = st_FreeTextureImageBuffer;
1897   functions->MapTextureImage = st_MapTextureImage;
1898   functions->UnmapTextureImage = st_UnmapTextureImage;
1899
1900   /* XXX Temporary until we can query pipe's texture sizes */
1901   functions->TestProxyTexImage = st_TestProxyTexImage;
1902
1903   functions->AllocTextureStorage = st_AllocTextureStorage;
1904   functions->TextureView = st_TextureView;
1905}
1906