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