st_cb_texture.c revision 28b315dc1aed36bebadfacbd55e481e7baacfcb5
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/imports.h"
29#include "main/convolve.h"
30#include "main/enums.h"
31#include "main/image.h"
32#include "main/macros.h"
33#include "main/texcompress.h"
34#include "main/texformat.h"
35#include "main/teximage.h"
36#include "main/texobj.h"
37#include "main/texstore.h"
38
39#include "state_tracker/st_context.h"
40#include "state_tracker/st_cb_fbo.h"
41#include "state_tracker/st_cb_texture.h"
42#include "state_tracker/st_format.h"
43#include "state_tracker/st_mipmap_tree.h"
44
45#include "pipe/p_context.h"
46#include "pipe/p_defines.h"
47
48
49#define DBG if (0) printf
50
51
52struct st_texture_object
53{
54   struct gl_texture_object base;       /* The "parent" object */
55
56   /* The mipmap tree must include at least these levels once
57    * validated:
58    */
59   GLuint firstLevel;
60   GLuint lastLevel;
61
62   /* Offset for firstLevel image:
63    */
64   GLuint textureOffset;
65
66   /* On validation any active images held in main memory or in other
67    * regions will be copied to this region and the old storage freed.
68    */
69   struct pipe_mipmap_tree *mt;
70
71   GLboolean imageOverride;
72   GLint depthOverride;
73   GLuint pitchOverride;
74};
75
76
77
78struct st_texture_image
79{
80   struct gl_texture_image base;
81
82   /* These aren't stored in gl_texture_image
83    */
84   GLuint level;
85   GLuint face;
86
87   /* If stImage->mt != NULL, image data is stored here.
88    * Else if stImage->base.Data != NULL, image is stored there.
89    * Else there is no image data.
90    */
91   struct pipe_mipmap_tree *mt;
92};
93
94
95
96
97static INLINE struct st_texture_object *
98st_texture_object(struct gl_texture_object *obj)
99{
100   return (struct st_texture_object *) obj;
101}
102
103static INLINE struct st_texture_image *
104st_texture_image(struct gl_texture_image *img)
105{
106   return (struct st_texture_image *) img;
107}
108
109
110struct pipe_mipmap_tree *
111st_get_texobj_mipmap_tree(struct gl_texture_object *texObj)
112{
113   struct st_texture_object *stObj = st_texture_object(texObj);
114   return stObj->mt;
115}
116
117
118static unsigned
119gl_target_to_pipe(GLenum target)
120{
121   switch (target) {
122   case GL_TEXTURE_1D:
123      return PIPE_TEXTURE_1D;
124
125   case GL_TEXTURE_2D:
126   case GL_TEXTURE_RECTANGLE_NV:
127      return PIPE_TEXTURE_2D;
128
129   case GL_TEXTURE_3D:
130      return PIPE_TEXTURE_3D;
131
132   case GL_TEXTURE_CUBE_MAP_ARB:
133      return PIPE_TEXTURE_CUBE;
134
135   default:
136      assert(0);
137      return 0;
138   }
139}
140
141
142static int
143compressed_num_bytes(GLuint mesaFormat)
144{
145   int bytes = 0;
146   switch(mesaFormat) {
147
148   case MESA_FORMAT_RGB_FXT1:
149   case MESA_FORMAT_RGBA_FXT1:
150   case MESA_FORMAT_RGB_DXT1:
151   case MESA_FORMAT_RGBA_DXT1:
152     bytes = 2;
153     break;
154
155   case MESA_FORMAT_RGBA_DXT3:
156   case MESA_FORMAT_RGBA_DXT5:
157     bytes = 4;
158   default:
159     break;
160   }
161
162   return bytes;
163}
164
165
166
167
168static GLboolean
169st_IsTextureResident(GLcontext * ctx, struct gl_texture_object *texObj)
170{
171#if 0
172   struct intel_context *intel = intel_context(ctx);
173   struct st_texture_object *stObj = st_texture_object(texObj);
174
175   return
176      stObj->mt &&
177      stObj->mt->region &&
178      intel_is_region_resident(intel, stObj->mt->region);
179#endif
180   return 1;
181}
182
183
184
185static struct gl_texture_image *
186st_NewTextureImage(GLcontext * ctx)
187{
188   DBG("%s\n", __FUNCTION__);
189   (void) ctx;
190   return (struct gl_texture_image *) CALLOC_STRUCT(st_texture_image);
191}
192
193
194static struct gl_texture_object *
195st_NewTextureObject(GLcontext * ctx, GLuint name, GLenum target)
196{
197   struct st_texture_object *obj = CALLOC_STRUCT(st_texture_object);
198
199   DBG("%s\n", __FUNCTION__);
200   _mesa_initialize_texture_object(&obj->base, name, target);
201
202   return &obj->base;
203}
204
205static void
206st_DeleteTextureObject(GLcontext *ctx,
207			 struct gl_texture_object *texObj)
208{
209   struct pipe_context *pipe = ctx->st->pipe;
210   struct st_texture_object *stObj = st_texture_object(texObj);
211
212   if (stObj->mt)
213      st_miptree_release(pipe, &stObj->mt);
214
215   _mesa_delete_texture_object(ctx, texObj);
216}
217
218
219static void
220st_FreeTextureImageData(GLcontext * ctx, struct gl_texture_image *texImage)
221{
222   struct pipe_context *pipe = ctx->st->pipe;
223   struct st_texture_image *stImage = st_texture_image(texImage);
224
225   DBG("%s\n", __FUNCTION__);
226
227   if (stImage->mt) {
228      st_miptree_release(pipe, &stImage->mt);
229   }
230
231   if (texImage->Data) {
232      free(texImage->Data);
233      texImage->Data = NULL;
234   }
235}
236
237
238
239
240/* ================================================================
241 * From linux kernel i386 header files, copes with odd sizes better
242 * than COPY_DWORDS would:
243 * XXX Put this in src/mesa/main/imports.h ???
244 */
245#if defined(i386) || defined(__i386__)
246static INLINE void *
247__memcpy(void *to, const void *from, size_t n)
248{
249   int d0, d1, d2;
250   __asm__ __volatile__("rep ; movsl\n\t"
251                        "testb $2,%b4\n\t"
252                        "je 1f\n\t"
253                        "movsw\n"
254                        "1:\ttestb $1,%b4\n\t"
255                        "je 2f\n\t"
256                        "movsb\n" "2:":"=&c"(d0), "=&D"(d1), "=&S"(d2)
257                        :"0"(n / 4), "q"(n), "1"((long) to), "2"((long) from)
258                        :"memory");
259   return (to);
260}
261#else
262#define __memcpy(a,b,c) memcpy(a,b,c)
263#endif
264
265
266/* The system memcpy (at least on ubuntu 5.10) has problems copying
267 * to agp (writecombined) memory from a source which isn't 64-byte
268 * aligned - there is a 4x performance falloff.
269 *
270 * The x86 __memcpy is immune to this but is slightly slower
271 * (10%-ish) than the system memcpy.
272 *
273 * The sse_memcpy seems to have a slight cliff at 64/32 bytes, but
274 * isn't much faster than x86_memcpy for agp copies.
275 *
276 * TODO: switch dynamically.
277 */
278static void *
279do_memcpy(void *dest, const void *src, size_t n)
280{
281   if ((((unsigned) src) & 63) || (((unsigned) dest) & 63)) {
282      return __memcpy(dest, src, n);
283   }
284   else
285      return memcpy(dest, src, n);
286}
287
288
289/* Functions to store texture images.  Where possible, mipmap_tree's
290 * will be created or further instantiated with image data, otherwise
291 * images will be stored in malloc'd memory.  A validation step is
292 * required to pull those images into a mipmap tree, or otherwise
293 * decide a fallback is required.
294 */
295
296
297static int
298logbase2(int n)
299{
300   GLint i = 1;
301   GLint log2 = 0;
302
303   while (n > i) {
304      i *= 2;
305      log2++;
306   }
307
308   return log2;
309}
310
311
312/* Otherwise, store it in memory if (Border != 0) or (any dimension ==
313 * 1).
314 *
315 * Otherwise, if max_level >= level >= min_level, create tree with
316 * space for textures from min_level down to max_level.
317 *
318 * Otherwise, create tree with space for textures from (level
319 * 0)..(1x1).  Consider pruning this tree at a validation if the
320 * saving is worth it.
321 */
322static void
323guess_and_alloc_mipmap_tree(struct pipe_context *pipe,
324                            struct st_texture_object *stObj,
325                            struct st_texture_image *stImage)
326{
327   GLuint firstLevel;
328   GLuint lastLevel;
329   GLuint width = stImage->base.Width;
330   GLuint height = stImage->base.Height;
331   GLuint depth = stImage->base.Depth;
332   GLuint l2width, l2height, l2depth;
333   GLuint i, comp_byte = 0;
334
335   DBG("%s\n", __FUNCTION__);
336
337   if (stImage->base.Border)
338      return;
339
340   if (stImage->level > stObj->base.BaseLevel &&
341       (stImage->base.Width == 1 ||
342        (stObj->base.Target != GL_TEXTURE_1D &&
343         stImage->base.Height == 1) ||
344        (stObj->base.Target == GL_TEXTURE_3D &&
345         stImage->base.Depth == 1)))
346      return;
347
348   /* If this image disrespects BaseLevel, allocate from level zero.
349    * Usually BaseLevel == 0, so it's unlikely to happen.
350    */
351   if (stImage->level < stObj->base.BaseLevel)
352      firstLevel = 0;
353   else
354      firstLevel = stObj->base.BaseLevel;
355
356
357   /* Figure out image dimensions at start level.
358    */
359   for (i = stImage->level; i > firstLevel; i--) {
360      width <<= 1;
361      if (height != 1)
362         height <<= 1;
363      if (depth != 1)
364         depth <<= 1;
365   }
366
367   /* Guess a reasonable value for lastLevel.  This is probably going
368    * to be wrong fairly often and might mean that we have to look at
369    * resizable buffers, or require that buffers implement lazy
370    * pagetable arrangements.
371    */
372   if ((stObj->base.MinFilter == GL_NEAREST ||
373        stObj->base.MinFilter == GL_LINEAR) &&
374       stImage->level == firstLevel) {
375      lastLevel = firstLevel;
376   }
377   else {
378      l2width = logbase2(width);
379      l2height = logbase2(height);
380      l2depth = logbase2(depth);
381      lastLevel = firstLevel + MAX2(MAX2(l2width, l2height), l2depth);
382   }
383
384   assert(!stObj->mt);
385   if (stImage->base.IsCompressed)
386      comp_byte = compressed_num_bytes(stImage->base.TexFormat->MesaFormat);
387   stObj->mt = st_miptree_create(pipe,
388                                 gl_target_to_pipe(stObj->base.Target),
389                                 stImage->base.InternalFormat,
390                                 firstLevel,
391                                 lastLevel,
392                                 width,
393                                 height,
394                                 depth,
395                                 stImage->base.TexFormat->TexelBytes,
396                                 comp_byte);
397
398   stObj->mt->format
399      = st_mesa_format_to_pipe_format(stImage->base.TexFormat->MesaFormat);
400
401   DBG("%s - success\n", __FUNCTION__);
402}
403
404
405
406
407static GLuint
408target_to_face(GLenum target)
409{
410   switch (target) {
411   case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB:
412   case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB:
413   case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB:
414   case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB:
415   case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB:
416   case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB:
417      return ((GLuint) target - (GLuint) GL_TEXTURE_CUBE_MAP_POSITIVE_X);
418   default:
419      return 0;
420   }
421}
422
423
424
425/* There are actually quite a few combinations this will work for,
426 * more than what I've listed here.
427 */
428static GLboolean
429check_pbo_format(GLint internalFormat,
430                 GLenum format, GLenum type,
431                 const struct gl_texture_format *mesa_format)
432{
433   switch (internalFormat) {
434   case 4:
435   case GL_RGBA:
436      return (format == GL_BGRA &&
437              (type == GL_UNSIGNED_BYTE ||
438               type == GL_UNSIGNED_INT_8_8_8_8_REV) &&
439              mesa_format == &_mesa_texformat_argb8888);
440   case 3:
441   case GL_RGB:
442      return (format == GL_RGB &&
443              type == GL_UNSIGNED_SHORT_5_6_5 &&
444              mesa_format == &_mesa_texformat_rgb565);
445   case GL_YCBCR_MESA:
446      return (type == GL_UNSIGNED_SHORT_8_8_MESA || type == GL_UNSIGNED_BYTE);
447   default:
448      return GL_FALSE;
449   }
450}
451
452
453/* XXX: Do this for TexSubImage also:
454 */
455static GLboolean
456try_pbo_upload(GLcontext *ctx,
457               struct st_texture_image *stImage,
458               const struct gl_pixelstore_attrib *unpack,
459               GLint internalFormat,
460               GLint width, GLint height,
461               GLenum format, GLenum type, const void *pixels)
462{
463   return GL_FALSE;  /* XXX fix flushing/locking/blitting below */
464#if 000
465   struct intel_context *intel = intel_context(ctx);
466   struct intel_buffer_object *pbo = intel_buffer_object(unpack->BufferObj);
467   GLuint src_offset, src_stride;
468   GLuint dst_offset, dst_stride;
469
470   if (!pbo ||
471       ctx._ImageTransferState ||
472       unpack->SkipPixels || unpack->SkipRows) {
473      _mesa_printf("%s: failure 1\n", __FUNCTION__);
474      return GL_FALSE;
475   }
476
477   src_offset = (GLuint) pixels;
478
479   if (unpack->RowLength > 0)
480      src_stride = unpack->RowLength;
481   else
482      src_stride = width;
483
484   dst_offset = st_miptree_image_offset(stImage->mt,
485                                           stImage->face,
486                                           stImage->level);
487
488   dst_stride = stImage->mt->pitch;
489
490   {
491      struct _DriBufferObject *src_buffer =
492         intel_bufferobj_buffer(intel, pbo, INTEL_READ);
493
494      /* Temporary hack: cast to _DriBufferObject:
495       */
496      struct _DriBufferObject *dst_buffer =
497         (struct _DriBufferObject *)stImage->mt->region->buffer;
498
499
500      intelEmitCopyBlit(intel,
501                        stImage->mt->cpp,
502                        src_stride, src_buffer, src_offset,
503                        dst_stride, dst_buffer, dst_offset,
504                        0, 0, 0, 0, width, height,
505			GL_COPY);
506   }
507
508   return GL_TRUE;
509#endif
510}
511
512
513
514static GLboolean
515try_pbo_zcopy(GLcontext *ctx,
516              struct st_texture_image *stImage,
517              const struct gl_pixelstore_attrib *unpack,
518              GLint internalFormat,
519              GLint width, GLint height,
520              GLenum format, GLenum type, const void *pixels)
521{
522   return GL_FALSE;
523}
524
525
526
527
528
529
530static void
531st_TexImage(GLcontext * ctx,
532              GLint dims,
533              GLenum target, GLint level,
534              GLint internalFormat,
535              GLint width, GLint height, GLint depth,
536              GLint border,
537              GLenum format, GLenum type, const void *pixels,
538              const struct gl_pixelstore_attrib *unpack,
539              struct gl_texture_object *texObj,
540              struct gl_texture_image *texImage, GLsizei imageSize, int compressed)
541{
542   struct pipe_context *pipe = ctx->st->pipe;
543   struct st_texture_object *stObj = st_texture_object(texObj);
544   struct st_texture_image *stImage = st_texture_image(texImage);
545   GLint postConvWidth = width;
546   GLint postConvHeight = height;
547   GLint texelBytes, sizeInBytes;
548   GLuint dstRowStride;
549
550
551   DBG("%s target %s level %d %dx%dx%d border %d\n", __FUNCTION__,
552       _mesa_lookup_enum_by_nr(target), level, width, height, depth, border);
553
554   stImage->face = target_to_face(target);
555   stImage->level = level;
556
557   if (ctx->_ImageTransferState & IMAGE_CONVOLUTION_BIT) {
558      _mesa_adjust_image_for_convolution(ctx, dims, &postConvWidth,
559                                         &postConvHeight);
560   }
561
562   /* choose the texture format */
563   texImage->TexFormat = st_ChooseTextureFormat(ctx, internalFormat,
564                                                  format, type);
565
566   _mesa_set_fetch_functions(texImage, dims);
567
568   if (texImage->TexFormat->TexelBytes == 0) {
569      /* must be a compressed format */
570      texelBytes = 0;
571      texImage->IsCompressed = GL_TRUE;
572      texImage->CompressedSize =
573	 ctx->Driver.CompressedTextureSize(ctx, texImage->Width,
574					   texImage->Height, texImage->Depth,
575					   texImage->TexFormat->MesaFormat);
576   } else {
577      texelBytes = texImage->TexFormat->TexelBytes;
578
579      /* Minimum pitch of 32 bytes */
580      if (postConvWidth * texelBytes < 32) {
581	 postConvWidth = 32 / texelBytes;
582	 texImage->RowStride = postConvWidth;
583      }
584
585      assert(texImage->RowStride == postConvWidth);
586   }
587
588   /* Release the reference to a potentially orphaned buffer.
589    * Release any old malloced memory.
590    */
591   if (stImage->mt) {
592      st_miptree_release(pipe, &stImage->mt);
593      assert(!texImage->Data);
594   }
595   else if (texImage->Data) {
596      _mesa_align_free(texImage->Data);
597   }
598
599   /* If this is the only texture image in the tree, could call
600    * bmBufferData with NULL data to free the old block and avoid
601    * waiting on any outstanding fences.
602    */
603   if (stObj->mt &&
604       stObj->mt->first_level == level &&
605       stObj->mt->last_level == level &&
606       stObj->mt->target != PIPE_TEXTURE_CUBE &&
607       !st_miptree_match_image(stObj->mt, &stImage->base,
608                                  stImage->face, stImage->level)) {
609
610      DBG("release it\n");
611      st_miptree_release(pipe, &stObj->mt);
612      assert(!stObj->mt);
613   }
614
615   if (!stObj->mt) {
616      guess_and_alloc_mipmap_tree(pipe, stObj, stImage);
617      if (!stObj->mt) {
618	 DBG("guess_and_alloc_mipmap_tree: failed\n");
619      }
620   }
621
622   assert(!stImage->mt);
623
624   if (stObj->mt &&
625       st_miptree_match_image(stObj->mt, &stImage->base,
626                                 stImage->face, stImage->level)) {
627
628      st_miptree_reference(&stImage->mt, stObj->mt);
629      assert(stImage->mt);
630   }
631
632   if (!stImage->mt)
633      DBG("XXX: Image did not fit into tree - storing in local memory!\n");
634
635#if 0 /* XXX FIX when st_buffer_objects are in place */
636   /* PBO fastpaths:
637    */
638   if (dims <= 2 &&
639       stImage->mt &&
640       intel_buffer_object(unpack->BufferObj) &&
641       check_pbo_format(internalFormat, format,
642                        type, stImage->base.TexFormat)) {
643
644      DBG("trying pbo upload\n");
645
646      /* Attempt to texture directly from PBO data (zero copy upload).
647       *
648       * Currently disable as it can lead to worse as well as better
649       * performance (in particular when pipe_region_cow() is
650       * required).
651       */
652      if (stObj->mt == stImage->mt &&
653          stObj->mt->first_level == level &&
654          stObj->mt->last_level == level) {
655
656         if (try_pbo_zcopy(intel, stImage, unpack,
657                           internalFormat,
658                           width, height, format, type, pixels)) {
659
660            DBG("pbo zcopy upload succeeded\n");
661            return;
662         }
663      }
664
665
666      /* Otherwise, attempt to use the blitter for PBO image uploads.
667       */
668      if (try_pbo_upload(intel, stImage, unpack,
669                         internalFormat,
670                         width, height, format, type, pixels)) {
671         DBG("pbo upload succeeded\n");
672         return;
673      }
674
675      DBG("pbo upload failed\n");
676   }
677#else
678   (void) try_pbo_upload;
679   (void) check_pbo_format;
680   (void) try_pbo_zcopy;
681#endif
682
683
684   /* intelCopyTexImage calls this function with pixels == NULL, with
685    * the expectation that the mipmap tree will be set up but nothing
686    * more will be done.  This is where those calls return:
687    */
688   if (compressed) {
689      pixels = _mesa_validate_pbo_compressed_teximage(ctx, imageSize, pixels,
690						      unpack,
691						      "glCompressedTexImage");
692   } else {
693      pixels = _mesa_validate_pbo_teximage(ctx, dims, width, height, 1,
694					   format, type,
695					   pixels, unpack, "glTexImage");
696   }
697   if (!pixels)
698      return;
699
700   if (stImage->mt) {
701      texImage->Data = st_miptree_image_map(pipe,
702                                               stImage->mt,
703                                               stImage->face,
704                                               stImage->level,
705                                               &dstRowStride,
706                                               stImage->base.ImageOffsets);
707   }
708   else {
709      /* Allocate regular memory and store the image there temporarily.   */
710      if (texImage->IsCompressed) {
711         sizeInBytes = texImage->CompressedSize;
712         dstRowStride =
713            _mesa_compressed_row_stride(texImage->TexFormat->MesaFormat, width);
714         assert(dims != 3);
715      }
716      else {
717         dstRowStride = postConvWidth * texelBytes;
718         sizeInBytes = depth * dstRowStride * postConvHeight;
719      }
720
721      texImage->Data = malloc(sizeInBytes);
722   }
723
724   DBG("Upload image %dx%dx%d row_len %x pitch %x\n",
725       width, height, depth, width * texelBytes, dstRowStride);
726
727   /* Copy data.  Would like to know when it's ok for us to eg. use
728    * the blitter to copy.  Or, use the hardware to do the format
729    * conversion and copy:
730    */
731   if (compressed) {
732     memcpy(texImage->Data, pixels, imageSize);
733   }
734   else if (!texImage->TexFormat->StoreImage(ctx, dims,
735                                             texImage->_BaseFormat,
736                                             texImage->TexFormat,
737                                             texImage->Data,
738                                             0, 0, 0, /* dstX/Y/Zoffset */
739                                             dstRowStride,
740                                             texImage->ImageOffsets,
741                                             width, height, depth,
742                                             format, type, pixels, unpack)) {
743      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage");
744   }
745
746   _mesa_unmap_teximage_pbo(ctx, unpack);
747
748   if (stImage->mt) {
749      st_miptree_image_unmap(pipe, stImage->mt);
750      texImage->Data = NULL;
751   }
752
753#if 0
754   /* GL_SGIS_generate_mipmap -- this can be accelerated now.
755    */
756   if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
757      intel_generate_mipmap(ctx, target,
758                            &ctx->Texture.Unit[ctx->Texture.CurrentUnit],
759                            texObj);
760   }
761#endif
762}
763
764
765static void
766st_TexImage3D(GLcontext * ctx,
767                GLenum target, GLint level,
768                GLint internalFormat,
769                GLint width, GLint height, GLint depth,
770                GLint border,
771                GLenum format, GLenum type, const void *pixels,
772                const struct gl_pixelstore_attrib *unpack,
773                struct gl_texture_object *texObj,
774                struct gl_texture_image *texImage)
775{
776   st_TexImage(ctx, 3, target, level,
777                 internalFormat, width, height, depth, border,
778                 format, type, pixels, unpack, texObj, texImage, 0, 0);
779}
780
781
782static void
783st_TexImage2D(GLcontext * ctx,
784                GLenum target, GLint level,
785                GLint internalFormat,
786                GLint width, GLint height, GLint border,
787                GLenum format, GLenum type, const void *pixels,
788                const struct gl_pixelstore_attrib *unpack,
789                struct gl_texture_object *texObj,
790                struct gl_texture_image *texImage)
791{
792   st_TexImage(ctx, 2, target, level,
793                 internalFormat, width, height, 1, border,
794                 format, type, pixels, unpack, texObj, texImage, 0, 0);
795}
796
797
798static void
799st_TexImage1D(GLcontext * ctx,
800                GLenum target, GLint level,
801                GLint internalFormat,
802                GLint width, GLint border,
803                GLenum format, GLenum type, const void *pixels,
804                const struct gl_pixelstore_attrib *unpack,
805                struct gl_texture_object *texObj,
806                struct gl_texture_image *texImage)
807{
808   st_TexImage(ctx, 1, target, level,
809                 internalFormat, width, 1, 1, border,
810                 format, type, pixels, unpack, texObj, texImage, 0, 0);
811}
812
813
814static void
815st_CompressedTexImage2D( GLcontext *ctx, GLenum target, GLint level,
816				GLint internalFormat,
817				GLint width, GLint height, GLint border,
818				GLsizei imageSize, const GLvoid *data,
819				struct gl_texture_object *texObj,
820				struct gl_texture_image *texImage )
821{
822   st_TexImage(ctx, 2, target, level,
823		 internalFormat, width, height, 1, border,
824		 0, 0, data, &ctx->Unpack, texObj, texImage, imageSize, 1);
825}
826
827
828/**
829 * Need to map texture image into memory before copying image data,
830 * then unmap it.
831 */
832static void
833st_get_tex_image(GLcontext * ctx, GLenum target, GLint level,
834                 GLenum format, GLenum type, GLvoid * pixels,
835                 struct gl_texture_object *texObj,
836                 struct gl_texture_image *texImage, int compressed)
837{
838   /*
839   struct intel_context *intel = intel_context(ctx);
840   */
841   struct pipe_context *pipe = ctx->st->pipe;
842   struct st_texture_image *stImage = st_texture_image(texImage);
843
844   /* Map */
845   if (stImage->mt) {
846      /* Image is stored in hardware format in a buffer managed by the
847       * kernel.  Need to explicitly map and unmap it.
848       */
849      stImage->base.Data =
850         st_miptree_image_map(pipe,
851                                 stImage->mt,
852                                 stImage->face,
853                                 stImage->level,
854                                 &stImage->base.RowStride,
855                                 stImage->base.ImageOffsets);
856      stImage->base.RowStride /= stImage->mt->cpp;
857   }
858   else {
859      /* Otherwise, the image should actually be stored in
860       * stImage->base.Data.  This is pretty confusing for
861       * everybody, I'd much prefer to separate the two functions of
862       * texImage->Data - storage for texture images in main memory
863       * and access (ie mappings) of images.  In other words, we'd
864       * create a new texImage->Map field and leave Data simply for
865       * storage.
866       */
867      assert(stImage->base.Data);
868   }
869
870
871   if (compressed) {
872      _mesa_get_compressed_teximage(ctx, target, level, pixels,
873				    texObj, texImage);
874   } else {
875      _mesa_get_teximage(ctx, target, level, format, type, pixels,
876			 texObj, texImage);
877   }
878
879
880   /* Unmap */
881   if (stImage->mt) {
882      st_miptree_image_unmap(pipe, stImage->mt);
883      stImage->base.Data = NULL;
884   }
885}
886
887
888static void
889st_GetTexImage(GLcontext * ctx, GLenum target, GLint level,
890                 GLenum format, GLenum type, GLvoid * pixels,
891                 struct gl_texture_object *texObj,
892                 struct gl_texture_image *texImage)
893{
894   st_get_tex_image(ctx, target, level, format, type, pixels,
895                    texObj, texImage, 0);
896}
897
898
899static void
900st_GetCompressedTexImage(GLcontext *ctx, GLenum target, GLint level,
901			   GLvoid *pixels,
902			   const struct gl_texture_object *texObj,
903			   const struct gl_texture_image *texImage)
904{
905   st_get_tex_image(ctx, target, level, 0, 0, pixels,
906                    (struct gl_texture_object *) texObj,
907                    (struct gl_texture_image *) texImage, 1);
908}
909
910
911
912static void
913st_TexSubimage(GLcontext * ctx,
914                 GLint dims,
915                 GLenum target, GLint level,
916                 GLint xoffset, GLint yoffset, GLint zoffset,
917                 GLint width, GLint height, GLint depth,
918                 GLenum format, GLenum type, const void *pixels,
919                 const struct gl_pixelstore_attrib *packing,
920                 struct gl_texture_object *texObj,
921                 struct gl_texture_image *texImage)
922{
923   struct pipe_context *pipe = ctx->st->pipe;
924   struct st_texture_image *stImage = st_texture_image(texImage);
925   GLuint dstRowStride;
926
927   DBG("%s target %s level %d offset %d,%d %dx%d\n", __FUNCTION__,
928       _mesa_lookup_enum_by_nr(target),
929       level, xoffset, yoffset, width, height);
930
931   pixels =
932      _mesa_validate_pbo_teximage(ctx, dims, width, height, depth, format,
933                                  type, pixels, packing, "glTexSubImage2D");
934   if (!pixels)
935      return;
936
937   /* Map buffer if necessary.  Need to lock to prevent other contexts
938    * from uploading the buffer under us.
939    */
940   if (stImage->mt)
941      texImage->Data = st_miptree_image_map(pipe,
942                                               stImage->mt,
943                                               stImage->face,
944                                               stImage->level,
945                                               &dstRowStride,
946                                               texImage->ImageOffsets);
947
948   assert(dstRowStride);
949
950   if (!texImage->TexFormat->StoreImage(ctx, dims, texImage->_BaseFormat,
951                                        texImage->TexFormat,
952                                        texImage->Data,
953                                        xoffset, yoffset, zoffset,
954                                        dstRowStride,
955                                        texImage->ImageOffsets,
956                                        width, height, depth,
957                                        format, type, pixels, packing)) {
958      _mesa_error(ctx, GL_OUT_OF_MEMORY, "intelTexSubImage");
959   }
960
961#if 0
962   /* GL_SGIS_generate_mipmap */
963   if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
964      _mesa_generate_mipmap(ctx, target,
965                            &ctx->Texture.Unit[ctx->Texture.CurrentUnit],
966                            texObj);
967   }
968#endif
969
970   _mesa_unmap_teximage_pbo(ctx, packing);
971
972   if (stImage->mt) {
973      st_miptree_image_unmap(pipe, stImage->mt);
974      texImage->Data = NULL;
975   }
976}
977
978
979
980static void
981st_TexSubImage3D(GLcontext * ctx,
982                   GLenum target,
983                   GLint level,
984                   GLint xoffset, GLint yoffset, GLint zoffset,
985                   GLsizei width, GLsizei height, GLsizei depth,
986                   GLenum format, GLenum type,
987                   const GLvoid * pixels,
988                   const struct gl_pixelstore_attrib *packing,
989                   struct gl_texture_object *texObj,
990                   struct gl_texture_image *texImage)
991{
992   st_TexSubimage(ctx, 3, target, level,
993                  xoffset, yoffset, zoffset,
994                  width, height, depth,
995                  format, type, pixels, packing, texObj, texImage);
996}
997
998
999
1000static void
1001st_TexSubImage2D(GLcontext * ctx,
1002                   GLenum target,
1003                   GLint level,
1004                   GLint xoffset, GLint yoffset,
1005                   GLsizei width, GLsizei height,
1006                   GLenum format, GLenum type,
1007                   const GLvoid * pixels,
1008                   const struct gl_pixelstore_attrib *packing,
1009                   struct gl_texture_object *texObj,
1010                   struct gl_texture_image *texImage)
1011{
1012   st_TexSubimage(ctx, 2, target, level,
1013                  xoffset, yoffset, 0,
1014                  width, height, 1,
1015                  format, type, pixels, packing, texObj, texImage);
1016}
1017
1018
1019static void
1020st_TexSubImage1D(GLcontext * ctx,
1021                   GLenum target,
1022                   GLint level,
1023                   GLint xoffset,
1024                   GLsizei width,
1025                   GLenum format, GLenum type,
1026                   const GLvoid * pixels,
1027                   const struct gl_pixelstore_attrib *packing,
1028                   struct gl_texture_object *texObj,
1029                   struct gl_texture_image *texImage)
1030{
1031   st_TexSubimage(ctx, 1, target, level,
1032                  xoffset, 0, 0,
1033                  width, 1, 1,
1034                  format, type, pixels, packing, texObj, texImage);
1035}
1036
1037
1038
1039/**
1040 * Return 0 for GL_TEXTURE_CUBE_MAP_POSITIVE_X,
1041 *        1 for GL_TEXTURE_CUBE_MAP_NEGATIVE_X,
1042 *        etc.
1043 * XXX duplicated from main/teximage.c
1044 */
1045static uint
1046texture_face(GLenum target)
1047{
1048   if (target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB &&
1049       target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB)
1050      return (GLuint) target - (GLuint) GL_TEXTURE_CUBE_MAP_POSITIVE_X;
1051   else
1052      return 0;
1053}
1054
1055
1056
1057/**
1058 * Do a CopyTexSubImage operation by mapping the source region and
1059 * dest region and using get_tile()/put_tile() to access the pixels/texels.
1060 *
1061 * Note: srcY=0=TOP of renderbuffer
1062 */
1063static void
1064fallback_copy_texsubimage(GLcontext *ctx,
1065                          GLenum target,
1066                          GLint level,
1067                          struct st_renderbuffer *strb,
1068                          struct st_texture_image *stImage,
1069                          GLenum baseFormat,
1070                          GLint destX, GLint destY, GLint destZ,
1071                          GLint srcX, GLint srcY,
1072                          GLsizei width, GLsizei height)
1073{
1074   struct pipe_context *pipe = ctx->st->pipe;
1075   const uint face = texture_face(target);
1076   struct pipe_mipmap_tree *mt = stImage->mt;
1077   struct pipe_surface *src_surf, *dest_surf;
1078   GLfloat *data;
1079   GLint row, yStep;
1080
1081   /* determine bottom-to-top vs. top-to-bottom order */
1082   if (st_fb_orientation(ctx->ReadBuffer) == Y_0_TOP) {
1083      destY = height - 1 - destY;
1084      yStep = -1;
1085   }
1086   else {
1087      yStep = 1;
1088   }
1089
1090   src_surf = strb->surface;
1091
1092   dest_surf = pipe->get_tex_surface(pipe, mt,
1093                                    face, level, destZ);
1094
1095   (void) pipe->region_map(pipe, dest_surf->region);
1096   (void) pipe->region_map(pipe, src_surf->region);
1097
1098   /* buffer for one row */
1099   data = (GLfloat *) malloc(width * 4 * sizeof(GLfloat));
1100
1101   /* do copy row by row */
1102   for (row = 0; row < height; row++) {
1103      src_surf->get_tile(src_surf, srcX, srcY + row, width, 1, data);
1104
1105      /* XXX we're ignoring convolution for now */
1106      if (ctx->_ImageTransferState) {
1107         _mesa_apply_rgba_transfer_ops(ctx,
1108                            ctx->_ImageTransferState & ~IMAGE_CONVOLUTION_BIT,
1109                            width, (GLfloat (*)[4])data);
1110      }
1111
1112      dest_surf->put_tile(dest_surf, destX, destY, width, 1, data);
1113      destY += yStep;
1114   }
1115
1116
1117   (void) pipe->region_unmap(pipe, dest_surf->region);
1118   (void) pipe->region_unmap(pipe, src_surf->region);
1119
1120   free(data);
1121}
1122
1123
1124
1125
1126/**
1127 * Do a CopyTex[Sub]Image using an optimized hardware (blit) path.
1128 * Note that the region to copy has already been clip tested.
1129 *
1130 * Note: srcY=0=Bottom of renderbuffer
1131 *
1132 * \return GL_TRUE if success, GL_FALSE if failure (use a fallback)
1133 */
1134static void
1135do_copy_texsubimage(GLcontext *ctx,
1136                    GLenum target, GLint level,
1137                    GLint destX, GLint destY, GLint destZ,
1138                    GLint srcX, GLint srcY,
1139                    GLsizei width, GLsizei height)
1140{
1141   struct gl_texture_unit *texUnit =
1142      &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
1143   struct gl_texture_object *texObj =
1144      _mesa_select_tex_object(ctx, texUnit, target);
1145   struct gl_texture_image *texImage =
1146      _mesa_select_tex_image(ctx, texObj, target, level);
1147   struct st_texture_image *stImage = st_texture_image(texImage);
1148   GLenum baseFormat = texImage->InternalFormat;
1149   struct gl_framebuffer *fb = ctx->ReadBuffer;
1150   struct st_renderbuffer *strb;
1151   struct pipe_context *pipe = ctx->st->pipe;
1152   struct pipe_region *src_region, *dest_region;
1153   uint dest_offset, src_offset;
1154   uint dest_format, src_format;
1155
1156   (void) texImage;
1157
1158   /* determine if copying depth or color data */
1159   if (baseFormat == GL_DEPTH_COMPONENT) {
1160      strb = st_renderbuffer(fb->_DepthBuffer);
1161   }
1162   else if (baseFormat == GL_DEPTH_STENCIL_EXT) {
1163      strb = st_renderbuffer(fb->_StencilBuffer);
1164   }
1165   else {
1166      /* baseFormat == GL_RGB, GL_RGBA, GL_ALPHA, etc */
1167      strb = st_renderbuffer(fb->_ColorReadBuffer);
1168   }
1169
1170   assert(strb);
1171   assert(strb->surface);
1172   assert(stImage->mt);
1173
1174   if (st_fb_orientation(ctx->ReadBuffer) == Y_0_TOP) {
1175      srcY = strb->Base.Height - srcY - height;
1176   }
1177
1178   src_format = strb->surface->format;
1179   dest_format = stImage->mt->format;
1180
1181   src_region = strb->surface->region;
1182   dest_region = stImage->mt->region;
1183
1184   if (src_format == dest_format &&
1185       ctx->_ImageTransferState == 0x0 &&
1186       src_region &&
1187       dest_region &&
1188       src_region->cpp == dest_region->cpp) {
1189      /* do blit-style copy */
1190      src_offset = 0;
1191      dest_offset = st_miptree_image_offset(stImage->mt,
1192                                            stImage->face,
1193                                            stImage->level);
1194
1195      /* XXX may need to invert image depending on window
1196       * vs. user-created FBO
1197       */
1198
1199#if 0
1200      /* A bit of fiddling to get the blitter to work with -ve
1201       * pitches.  But we get a nice inverted blit this way, so it's
1202       * worth it:
1203       */
1204      intelEmitCopyBlit(intel,
1205                        stImage->mt->cpp,
1206                        -src->pitch,
1207                        src->buffer,
1208                        src->height * src->pitch * src->cpp,
1209                        stImage->mt->pitch,
1210                        stImage->mt->region->buffer,
1211                        dest_offset,
1212                        x, y + height, dstx, dsty, width, height,
1213                        GL_COPY); /* ? */
1214#else
1215
1216      pipe->region_copy(pipe,
1217                        /* dest */
1218                        dest_region,
1219                        dest_offset,
1220                        destX, destY,
1221                        /* src */
1222                        src_region,
1223                        src_offset,
1224                        srcX, srcY,
1225                        /* size */
1226                        width, height);
1227#endif
1228   }
1229   else {
1230      fallback_copy_texsubimage(ctx, target, level,
1231                                strb, stImage, baseFormat,
1232                                destX, destY, destZ,
1233                                srcX, srcY, width, height);
1234   }
1235
1236
1237#if 0
1238   /* GL_SGIS_generate_mipmap -- this can be accelerated now.
1239    * XXX Add a ctx->Driver.GenerateMipmaps() function?
1240    */
1241   if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
1242      intel_generate_mipmap(ctx, target,
1243                            &ctx->Texture.Unit[ctx->Texture.CurrentUnit],
1244                            texObj);
1245   }
1246#endif
1247
1248}
1249
1250
1251
1252static void
1253st_CopyTexImage1D(GLcontext * ctx, GLenum target, GLint level,
1254                  GLenum internalFormat,
1255                  GLint x, GLint y, GLsizei width, GLint border)
1256{
1257   struct gl_texture_unit *texUnit =
1258      &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
1259   struct gl_texture_object *texObj =
1260      _mesa_select_tex_object(ctx, texUnit, target);
1261   struct gl_texture_image *texImage =
1262      _mesa_select_tex_image(ctx, texObj, target, level);
1263
1264#if 0
1265   if (border)
1266      goto fail;
1267#endif
1268
1269   /* Setup or redefine the texture object, mipmap tree and texture
1270    * image.  Don't populate yet.
1271    */
1272   ctx->Driver.TexImage1D(ctx, target, level, internalFormat,
1273                          width, border,
1274                          GL_RGBA, CHAN_TYPE, NULL,
1275                          &ctx->DefaultPacking, texObj, texImage);
1276
1277   do_copy_texsubimage(ctx, target, level,
1278                       0, 0, 0,
1279                       x, y, width, 1);
1280}
1281
1282
1283static void
1284st_CopyTexImage2D(GLcontext * ctx, GLenum target, GLint level,
1285                  GLenum internalFormat,
1286                  GLint x, GLint y, GLsizei width, GLsizei height,
1287                  GLint border)
1288{
1289   struct gl_texture_unit *texUnit =
1290      &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
1291   struct gl_texture_object *texObj =
1292      _mesa_select_tex_object(ctx, texUnit, target);
1293   struct gl_texture_image *texImage =
1294      _mesa_select_tex_image(ctx, texObj, target, level);
1295
1296#if 0
1297   if (border)
1298      goto fail;
1299#endif
1300
1301   /* Setup or redefine the texture object, mipmap tree and texture
1302    * image.  Don't populate yet.
1303    */
1304   ctx->Driver.TexImage2D(ctx, target, level, internalFormat,
1305                          width, height, border,
1306                          GL_RGBA, CHAN_TYPE, NULL,
1307                          &ctx->DefaultPacking, texObj, texImage);
1308
1309
1310   do_copy_texsubimage(ctx, target, level,
1311                       0, 0, 0,
1312                       x, y, width, height);
1313}
1314
1315
1316static void
1317st_CopyTexSubImage1D(GLcontext * ctx, GLenum target, GLint level,
1318                     GLint xoffset, GLint x, GLint y, GLsizei width)
1319{
1320   const GLint yoffset = 0, zoffset = 0;
1321   const GLsizei height = 1;
1322   do_copy_texsubimage(ctx, target, level,
1323                       xoffset, yoffset, zoffset,
1324                       x, y, width, height);
1325}
1326
1327
1328static void
1329st_CopyTexSubImage2D(GLcontext * ctx, GLenum target, GLint level,
1330                     GLint xoffset, GLint yoffset,
1331                     GLint x, GLint y, GLsizei width, GLsizei height)
1332{
1333   const GLint zoffset = 0;
1334   do_copy_texsubimage(ctx, target, level,
1335                       xoffset, yoffset, zoffset,
1336                       x, y, width, height);
1337}
1338
1339
1340static void
1341st_CopyTexSubImage3D(GLcontext * ctx, GLenum target, GLint level,
1342                     GLint xoffset, GLint yoffset, GLint zoffset,
1343                     GLint x, GLint y, GLsizei width, GLsizei height)
1344{
1345   do_copy_texsubimage(ctx, target, level,
1346                       xoffset, yoffset, zoffset,
1347                       x, y, width, height);
1348}
1349
1350
1351
1352
1353/**
1354 * Compute which mipmap levels that really need to be sent to the hardware.
1355 * This depends on the base image size, GL_TEXTURE_MIN_LOD,
1356 * GL_TEXTURE_MAX_LOD, GL_TEXTURE_BASE_LEVEL, and GL_TEXTURE_MAX_LEVEL.
1357 */
1358static void
1359calculate_first_last_level(struct st_texture_object *stObj)
1360{
1361   struct gl_texture_object *tObj = &stObj->base;
1362   const struct gl_texture_image *const baseImage =
1363      tObj->Image[0][tObj->BaseLevel];
1364
1365   /* These must be signed values.  MinLod and MaxLod can be negative numbers,
1366    * and having firstLevel and lastLevel as signed prevents the need for
1367    * extra sign checks.
1368    */
1369   int firstLevel;
1370   int lastLevel;
1371
1372   /* Yes, this looks overly complicated, but it's all needed.
1373    */
1374   switch (tObj->Target) {
1375   case GL_TEXTURE_1D:
1376   case GL_TEXTURE_2D:
1377   case GL_TEXTURE_3D:
1378   case GL_TEXTURE_CUBE_MAP:
1379      if (tObj->MinFilter == GL_NEAREST || tObj->MinFilter == GL_LINEAR) {
1380         /* GL_NEAREST and GL_LINEAR only care about GL_TEXTURE_BASE_LEVEL.
1381          */
1382         firstLevel = lastLevel = tObj->BaseLevel;
1383      }
1384      else {
1385         firstLevel = tObj->BaseLevel + (GLint) (tObj->MinLod + 0.5);
1386         firstLevel = MAX2(firstLevel, tObj->BaseLevel);
1387         lastLevel = tObj->BaseLevel + (GLint) (tObj->MaxLod + 0.5);
1388         lastLevel = MAX2(lastLevel, tObj->BaseLevel);
1389         lastLevel = MIN2(lastLevel, tObj->BaseLevel + baseImage->MaxLog2);
1390         lastLevel = MIN2(lastLevel, tObj->MaxLevel);
1391         lastLevel = MAX2(firstLevel, lastLevel);       /* need at least one level */
1392      }
1393      break;
1394   case GL_TEXTURE_RECTANGLE_NV:
1395   case GL_TEXTURE_4D_SGIS:
1396      firstLevel = lastLevel = 0;
1397      break;
1398   default:
1399      return;
1400   }
1401
1402   /* save these values */
1403   stObj->firstLevel = firstLevel;
1404   stObj->lastLevel = lastLevel;
1405}
1406
1407
1408static void
1409copy_image_data_to_tree(struct pipe_context *pipe,
1410                        struct st_texture_object *stObj,
1411                        struct st_texture_image *stImage)
1412{
1413   if (stImage->mt) {
1414      /* Copy potentially with the blitter:
1415       */
1416      st_miptree_image_copy(pipe,
1417                            stObj->mt,  /* dest miptree */
1418                            stImage->face, stImage->level,
1419                            stImage->mt /* src miptree */
1420                            );
1421
1422      st_miptree_release(pipe, &stImage->mt);
1423   }
1424   else {
1425      assert(stImage->base.Data != NULL);
1426
1427      /* More straightforward upload.
1428       */
1429      st_miptree_image_data(pipe,
1430                               stObj->mt,
1431                               stImage->face,
1432                               stImage->level,
1433                               stImage->base.Data,
1434                               stImage->base.RowStride,
1435                               stImage->base.RowStride *
1436                               stImage->base.Height);
1437      _mesa_align_free(stImage->base.Data);
1438      stImage->base.Data = NULL;
1439   }
1440
1441   st_miptree_reference(&stImage->mt, stObj->mt);
1442}
1443
1444
1445/*
1446 */
1447GLboolean
1448st_finalize_mipmap_tree(GLcontext *ctx,
1449                        struct pipe_context *pipe, GLuint unit,
1450                        GLboolean *needFlush)
1451{
1452   struct gl_texture_object *tObj = ctx->Texture.Unit[unit]._Current;
1453   struct st_texture_object *stObj = st_texture_object(tObj);
1454   int comp_byte = 0;
1455   int cpp;
1456
1457   GLuint face, i;
1458   GLuint nr_faces = 0;
1459   struct st_texture_image *firstImage;
1460
1461   *needFlush = GL_FALSE;
1462
1463   /* We know/require this is true by now:
1464    */
1465   assert(stObj->base._Complete);
1466
1467   /* What levels must the tree include at a minimum?
1468    */
1469   calculate_first_last_level(stObj);
1470   firstImage =
1471      st_texture_image(stObj->base.Image[0][stObj->firstLevel]);
1472
1473   /* Fallback case:
1474    */
1475   if (firstImage->base.Border) {
1476      if (stObj->mt) {
1477         st_miptree_release(pipe, &stObj->mt);
1478      }
1479      return GL_FALSE;
1480   }
1481
1482
1483   /* If both firstImage and stObj have a tree which can contain
1484    * all active images, favour firstImage.  Note that because of the
1485    * completeness requirement, we know that the image dimensions
1486    * will match.
1487    */
1488   if (firstImage->mt &&
1489       firstImage->mt != stObj->mt &&
1490       firstImage->mt->first_level <= stObj->firstLevel &&
1491       firstImage->mt->last_level >= stObj->lastLevel) {
1492
1493      if (stObj->mt)
1494         st_miptree_release(pipe, &stObj->mt);
1495
1496      st_miptree_reference(&stObj->mt, firstImage->mt);
1497   }
1498
1499   if (firstImage->base.IsCompressed) {
1500      comp_byte = compressed_num_bytes(firstImage->base.TexFormat->MesaFormat);
1501      cpp = comp_byte;
1502   }
1503   else cpp = firstImage->base.TexFormat->TexelBytes;
1504
1505   /* Check tree can hold all active levels.  Check tree matches
1506    * target, imageFormat, etc.
1507    *
1508    * XXX: For some layouts (eg i945?), the test might have to be
1509    * first_level == firstLevel, as the tree isn't valid except at the
1510    * original start level.  Hope to get around this by
1511    * programming minLod, maxLod, baseLevel into the hardware and
1512    * leaving the tree alone.
1513    */
1514   if (stObj->mt &&
1515       (stObj->mt->target != gl_target_to_pipe(stObj->base.Target) ||
1516	stObj->mt->internal_format != firstImage->base.InternalFormat ||
1517	stObj->mt->first_level != stObj->firstLevel ||
1518	stObj->mt->last_level != stObj->lastLevel ||
1519	stObj->mt->width0 != firstImage->base.Width ||
1520	stObj->mt->height0 != firstImage->base.Height ||
1521	stObj->mt->depth0 != firstImage->base.Depth ||
1522	stObj->mt->cpp != cpp ||
1523	stObj->mt->compressed != firstImage->base.IsCompressed)) {
1524      st_miptree_release(pipe, &stObj->mt);
1525   }
1526
1527
1528   /* May need to create a new tree:
1529    */
1530   if (!stObj->mt) {
1531      stObj->mt = st_miptree_create(pipe,
1532                                    gl_target_to_pipe(stObj->base.Target),
1533                                    firstImage->base.InternalFormat,
1534                                    stObj->firstLevel,
1535                                    stObj->lastLevel,
1536                                    firstImage->base.Width,
1537                                    firstImage->base.Height,
1538                                    firstImage->base.Depth,
1539                                    cpp,
1540                                    comp_byte);
1541
1542      stObj->mt->format
1543         = st_mesa_format_to_pipe_format(firstImage->base.TexFormat->MesaFormat);
1544   }
1545
1546   /* Pull in any images not in the object's tree:
1547    */
1548   nr_faces = (stObj->base.Target == GL_TEXTURE_CUBE_MAP) ? 6 : 1;
1549   for (face = 0; face < nr_faces; face++) {
1550      for (i = stObj->firstLevel; i <= stObj->lastLevel; i++) {
1551         struct st_texture_image *stImage =
1552            st_texture_image(stObj->base.Image[face][i]);
1553
1554         /* Need to import images in main memory or held in other trees.
1555          */
1556         if (stObj->mt != stImage->mt) {
1557            copy_image_data_to_tree(pipe, stObj, stImage);
1558	    *needFlush = GL_TRUE;
1559         }
1560      }
1561   }
1562
1563
1564   return GL_TRUE;
1565}
1566
1567
1568
1569
1570void
1571st_init_texture_functions(struct dd_function_table *functions)
1572{
1573   functions->ChooseTextureFormat = st_ChooseTextureFormat;
1574   functions->TexImage1D = st_TexImage1D;
1575   functions->TexImage2D = st_TexImage2D;
1576   functions->TexImage3D = st_TexImage3D;
1577   functions->TexSubImage1D = st_TexSubImage1D;
1578   functions->TexSubImage2D = st_TexSubImage2D;
1579   functions->TexSubImage3D = st_TexSubImage3D;
1580   functions->CopyTexImage1D = st_CopyTexImage1D;
1581   functions->CopyTexImage2D = st_CopyTexImage2D;
1582   functions->CopyTexSubImage1D = st_CopyTexSubImage1D;
1583   functions->CopyTexSubImage2D = st_CopyTexSubImage2D;
1584   functions->CopyTexSubImage3D = st_CopyTexSubImage3D;
1585
1586   functions->GetTexImage = st_GetTexImage;
1587
1588   /* compressed texture functions */
1589   functions->CompressedTexImage2D = st_CompressedTexImage2D;
1590   functions->GetCompressedTexImage = st_GetCompressedTexImage;
1591
1592   functions->NewTextureObject = st_NewTextureObject;
1593   functions->NewTextureImage = st_NewTextureImage;
1594   functions->DeleteTexture = st_DeleteTextureObject;
1595   functions->FreeTexImageData = st_FreeTextureImageData;
1596   functions->UpdateTexturePalette = 0;
1597   functions->IsTextureResident = st_IsTextureResident;
1598
1599   functions->TextureMemCpy = do_memcpy;
1600}
1601