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