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