st_cb_texture.c revision 9cf9aa1ea2c3f40a09316975410a4b0e202e82ba
124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian/**************************************************************************
224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian *
324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * All Rights Reserved.
524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian *
624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * Permission is hereby granted, free of charge, to any person obtaining a
724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * copy of this software and associated documentation files (the
824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * "Software"), to deal in the Software without restriction, including
924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * without limitation the rights to use, copy, modify, merge, publish,
1024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * distribute, sub license, and/or sell copies of the Software, and to
1124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * permit persons to whom the Software is furnished to do so, subject to
1224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * the following conditions:
1324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian *
1424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * The above copyright notice and this permission notice (including the
1524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * next paragraph) shall be included in all copies or substantial portions
1624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * of the Software.
1724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian *
1824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
1924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
2024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
2124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
2224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
2324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
2424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
2524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian *
2624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian **************************************************************************/
2724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
2824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#include "main/imports.h"
2924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#include "main/convolve.h"
3024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#include "main/enums.h"
3124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#include "main/image.h"
3224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#include "main/macros.h"
3324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#include "main/texcompress.h"
3424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#include "main/texformat.h"
3524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#include "main/teximage.h"
3624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#include "main/texobj.h"
3724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#include "main/texstore.h"
3824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
3924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#include "state_tracker/st_context.h"
4024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#include "state_tracker/st_cb_texture.h"
41f8ab24760d0d3f07e9ee81c98207ddf92dfe74daBrian#include "state_tracker/st_format.h"
4224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#include "state_tracker/st_mipmap_tree.h"
4324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
4424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#include "pipe/p_context.h"
45b245840b86cf877c9b8d666edf229364a84f1deaBrian#include "pipe/p_defines.h"
4624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
4724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
4824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#define DBG if (0) printf
4924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
5024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
5124df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstruct st_texture_object
5224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{
5324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   struct gl_texture_object base;       /* The "parent" object */
5424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
5524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   /* The mipmap tree must include at least these levels once
5624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian    * validated:
5724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian    */
5824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   GLuint firstLevel;
5924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   GLuint lastLevel;
6024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
6124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   /* Offset for firstLevel image:
6224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian    */
6324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   GLuint textureOffset;
6424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
6524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   /* On validation any active images held in main memory or in other
6624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian    * regions will be copied to this region and the old storage freed.
6724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian    */
6824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   struct pipe_mipmap_tree *mt;
6924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
7024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   GLboolean imageOverride;
7124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   GLint depthOverride;
7224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   GLuint pitchOverride;
7324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian};
7424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
7524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
7624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
7724df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstruct st_texture_image
7824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{
7924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   struct gl_texture_image base;
8024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
8124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   /* These aren't stored in gl_texture_image
8224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian    */
8324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   GLuint level;
8424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   GLuint face;
8524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
8624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   /* If stImage->mt != NULL, image data is stored here.
8724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian    * Else if stImage->base.Data != NULL, image is stored there.
8824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian    * Else there is no image data.
8924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian    */
9024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   struct pipe_mipmap_tree *mt;
9124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian};
9224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
9324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
9424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
9524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
9624df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic INLINE struct st_texture_object *
9724df8f895fe8807aa2ba058e71bd40adfc01d21eBrianst_texture_object(struct gl_texture_object *obj)
9824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{
9924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   return (struct st_texture_object *) obj;
10024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian}
10124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
10224df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic INLINE struct st_texture_image *
10324df8f895fe8807aa2ba058e71bd40adfc01d21eBrianst_texture_image(struct gl_texture_image *img)
10424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{
10524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   return (struct st_texture_image *) img;
10624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian}
10724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
10824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
109d78dab126724e6e9d475289a086fb6f85adc3985Brianstruct pipe_mipmap_tree *
110d78dab126724e6e9d475289a086fb6f85adc3985Brianst_get_texobj_mipmap_tree(struct gl_texture_object *texObj)
111d78dab126724e6e9d475289a086fb6f85adc3985Brian{
112d78dab126724e6e9d475289a086fb6f85adc3985Brian   struct st_texture_object *stObj = st_texture_object(texObj);
113d78dab126724e6e9d475289a086fb6f85adc3985Brian   return stObj->mt;
114d78dab126724e6e9d475289a086fb6f85adc3985Brian}
115d78dab126724e6e9d475289a086fb6f85adc3985Brian
116d78dab126724e6e9d475289a086fb6f85adc3985Brian
11724df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic int
11814b98343309fdcff3514f05020303f7b40e83a4aBriancompressed_num_bytes(GLuint mesaFormat)
11924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{
12024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   int bytes = 0;
12124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   switch(mesaFormat) {
12224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
12324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   case MESA_FORMAT_RGB_FXT1:
12424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   case MESA_FORMAT_RGBA_FXT1:
12524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   case MESA_FORMAT_RGB_DXT1:
12624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   case MESA_FORMAT_RGBA_DXT1:
12724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian     bytes = 2;
12824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian     break;
12924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
13024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   case MESA_FORMAT_RGBA_DXT3:
13124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   case MESA_FORMAT_RGBA_DXT5:
13224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian     bytes = 4;
13324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   default:
13424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian     break;
13524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   }
13624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
13724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   return bytes;
13824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian}
13924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
14024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
14124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
14224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
14324df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic GLboolean
14424df8f895fe8807aa2ba058e71bd40adfc01d21eBrianst_IsTextureResident(GLcontext * ctx, struct gl_texture_object *texObj)
14524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{
14624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#if 0
14724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   struct intel_context *intel = intel_context(ctx);
14824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   struct st_texture_object *stObj = st_texture_object(texObj);
14924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
15024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   return
15124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      stObj->mt &&
15224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      stObj->mt->region &&
15324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      intel_is_region_resident(intel, stObj->mt->region);
15424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#endif
15524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   return 1;
15624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian}
15724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
15824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
15924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
16024df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic struct gl_texture_image *
16124df8f895fe8807aa2ba058e71bd40adfc01d21eBrianst_NewTextureImage(GLcontext * ctx)
16224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{
16324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   DBG("%s\n", __FUNCTION__);
16424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   (void) ctx;
16524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   return (struct gl_texture_image *) CALLOC_STRUCT(st_texture_image);
16624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian}
16724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
16824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
16924df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic struct gl_texture_object *
17024df8f895fe8807aa2ba058e71bd40adfc01d21eBrianst_NewTextureObject(GLcontext * ctx, GLuint name, GLenum target)
17124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{
17224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   struct st_texture_object *obj = CALLOC_STRUCT(st_texture_object);
17324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
17424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   DBG("%s\n", __FUNCTION__);
17524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   _mesa_initialize_texture_object(&obj->base, name, target);
17624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
17724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   return &obj->base;
17824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian}
17924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
18024df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void
18124df8f895fe8807aa2ba058e71bd40adfc01d21eBrianst_DeleteTextureObject(GLcontext *ctx,
18224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian			 struct gl_texture_object *texObj)
18324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{
18424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   struct pipe_context *pipe = ctx->st->pipe;
18524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   struct st_texture_object *stObj = st_texture_object(texObj);
18624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
18724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   if (stObj->mt)
18824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      st_miptree_release(pipe, &stObj->mt);
18924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
19024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   _mesa_delete_texture_object(ctx, texObj);
19124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian}
19224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
19324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
19424df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void
19524df8f895fe8807aa2ba058e71bd40adfc01d21eBrianst_FreeTextureImageData(GLcontext * ctx, struct gl_texture_image *texImage)
19624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{
19724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   struct pipe_context *pipe = ctx->st->pipe;
19824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   struct st_texture_image *stImage = st_texture_image(texImage);
19924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
20024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   DBG("%s\n", __FUNCTION__);
20124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
20224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   if (stImage->mt) {
20324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      st_miptree_release(pipe, &stImage->mt);
20424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   }
20524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
20624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   if (texImage->Data) {
20724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      free(texImage->Data);
20824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      texImage->Data = NULL;
20924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   }
21024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian}
21124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
21224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
21324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
21424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
21524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian/* ================================================================
21624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * From linux kernel i386 header files, copes with odd sizes better
21724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * than COPY_DWORDS would:
21824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * XXX Put this in src/mesa/main/imports.h ???
21924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */
22024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#if defined(i386) || defined(__i386__)
22124df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic INLINE void *
22224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian__memcpy(void *to, const void *from, size_t n)
22324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{
22424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   int d0, d1, d2;
22524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   __asm__ __volatile__("rep ; movsl\n\t"
22624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                        "testb $2,%b4\n\t"
22724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                        "je 1f\n\t"
22824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                        "movsw\n"
22924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                        "1:\ttestb $1,%b4\n\t"
23024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                        "je 2f\n\t"
23124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                        "movsb\n" "2:":"=&c"(d0), "=&D"(d1), "=&S"(d2)
23224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                        :"0"(n / 4), "q"(n), "1"((long) to), "2"((long) from)
23324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                        :"memory");
23424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   return (to);
23524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian}
23624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#else
23724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#define __memcpy(a,b,c) memcpy(a,b,c)
23824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#endif
23924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
24024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
24124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian/* The system memcpy (at least on ubuntu 5.10) has problems copying
24224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * to agp (writecombined) memory from a source which isn't 64-byte
24324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * aligned - there is a 4x performance falloff.
24424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian *
24524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * The x86 __memcpy is immune to this but is slightly slower
24624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * (10%-ish) than the system memcpy.
24724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian *
24824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * The sse_memcpy seems to have a slight cliff at 64/32 bytes, but
24924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * isn't much faster than x86_memcpy for agp copies.
25024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian *
25124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * TODO: switch dynamically.
25224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */
25324df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void *
25424df8f895fe8807aa2ba058e71bd40adfc01d21eBriando_memcpy(void *dest, const void *src, size_t n)
25524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{
25624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   if ((((unsigned) src) & 63) || (((unsigned) dest) & 63)) {
25724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      return __memcpy(dest, src, n);
25824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   }
25924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   else
26024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      return memcpy(dest, src, n);
26124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian}
26224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
26324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
26424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian/* Functions to store texture images.  Where possible, mipmap_tree's
26524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * will be created or further instantiated with image data, otherwise
26624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * images will be stored in malloc'd memory.  A validation step is
26724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * required to pull those images into a mipmap tree, or otherwise
26824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * decide a fallback is required.
26924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */
27024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
27124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
27224df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic int
27324df8f895fe8807aa2ba058e71bd40adfc01d21eBrianlogbase2(int n)
27424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{
27524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   GLint i = 1;
27624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   GLint log2 = 0;
27724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
27824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   while (n > i) {
27924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      i *= 2;
28024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      log2++;
28124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   }
28224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
28324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   return log2;
28424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian}
28524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
28624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
28724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian/* Otherwise, store it in memory if (Border != 0) or (any dimension ==
28824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * 1).
28924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian *
29024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * Otherwise, if max_level >= level >= min_level, create tree with
29124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * space for textures from min_level down to max_level.
29224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian *
29324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * Otherwise, create tree with space for textures from (level
29424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * 0)..(1x1).  Consider pruning this tree at a validation if the
29524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * saving is worth it.
29624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */
29724df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void
29824df8f895fe8807aa2ba058e71bd40adfc01d21eBrianguess_and_alloc_mipmap_tree(struct pipe_context *pipe,
29914b98343309fdcff3514f05020303f7b40e83a4aBrian                            struct st_texture_object *stObj,
30014b98343309fdcff3514f05020303f7b40e83a4aBrian                            struct st_texture_image *stImage)
30124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{
30224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   GLuint firstLevel;
30324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   GLuint lastLevel;
30414b98343309fdcff3514f05020303f7b40e83a4aBrian   GLuint width = stImage->base.Width;
30514b98343309fdcff3514f05020303f7b40e83a4aBrian   GLuint height = stImage->base.Height;
30614b98343309fdcff3514f05020303f7b40e83a4aBrian   GLuint depth = stImage->base.Depth;
30724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   GLuint l2width, l2height, l2depth;
30824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   GLuint i, comp_byte = 0;
30924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
31024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   DBG("%s\n", __FUNCTION__);
31124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
31214b98343309fdcff3514f05020303f7b40e83a4aBrian   if (stImage->base.Border)
31324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      return;
31424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
31514b98343309fdcff3514f05020303f7b40e83a4aBrian   if (stImage->level > stObj->base.BaseLevel &&
31614b98343309fdcff3514f05020303f7b40e83a4aBrian       (stImage->base.Width == 1 ||
31714b98343309fdcff3514f05020303f7b40e83a4aBrian        (stObj->base.Target != GL_TEXTURE_1D &&
31814b98343309fdcff3514f05020303f7b40e83a4aBrian         stImage->base.Height == 1) ||
31914b98343309fdcff3514f05020303f7b40e83a4aBrian        (stObj->base.Target == GL_TEXTURE_3D &&
32014b98343309fdcff3514f05020303f7b40e83a4aBrian         stImage->base.Depth == 1)))
32124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      return;
32224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
32324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   /* If this image disrespects BaseLevel, allocate from level zero.
32424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian    * Usually BaseLevel == 0, so it's unlikely to happen.
32524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian    */
32614b98343309fdcff3514f05020303f7b40e83a4aBrian   if (stImage->level < stObj->base.BaseLevel)
32724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      firstLevel = 0;
32824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   else
32914b98343309fdcff3514f05020303f7b40e83a4aBrian      firstLevel = stObj->base.BaseLevel;
33024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
33124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
33224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   /* Figure out image dimensions at start level.
33324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian    */
33414b98343309fdcff3514f05020303f7b40e83a4aBrian   for (i = stImage->level; i > firstLevel; i--) {
33524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      width <<= 1;
33624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      if (height != 1)
33724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian         height <<= 1;
33824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      if (depth != 1)
33924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian         depth <<= 1;
34024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   }
34124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
34224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   /* Guess a reasonable value for lastLevel.  This is probably going
34324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian    * to be wrong fairly often and might mean that we have to look at
34424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian    * resizable buffers, or require that buffers implement lazy
34524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian    * pagetable arrangements.
34624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian    */
34714b98343309fdcff3514f05020303f7b40e83a4aBrian   if ((stObj->base.MinFilter == GL_NEAREST ||
34814b98343309fdcff3514f05020303f7b40e83a4aBrian        stObj->base.MinFilter == GL_LINEAR) &&
34914b98343309fdcff3514f05020303f7b40e83a4aBrian       stImage->level == firstLevel) {
35024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      lastLevel = firstLevel;
35124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   }
35224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   else {
35324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      l2width = logbase2(width);
35424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      l2height = logbase2(height);
35524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      l2depth = logbase2(depth);
35624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      lastLevel = firstLevel + MAX2(MAX2(l2width, l2height), l2depth);
35724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   }
35824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
35914b98343309fdcff3514f05020303f7b40e83a4aBrian   assert(!stObj->mt);
36014b98343309fdcff3514f05020303f7b40e83a4aBrian   if (stImage->base.IsCompressed)
36114b98343309fdcff3514f05020303f7b40e83a4aBrian      comp_byte = compressed_num_bytes(stImage->base.TexFormat->MesaFormat);
36214b98343309fdcff3514f05020303f7b40e83a4aBrian   stObj->mt = st_miptree_create(pipe,
36314b98343309fdcff3514f05020303f7b40e83a4aBrian                                       stObj->base.Target,
36414b98343309fdcff3514f05020303f7b40e83a4aBrian                                       stImage->base.InternalFormat,
36524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                                       firstLevel,
36624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                                       lastLevel,
36724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                                       width,
36824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                                       height,
36924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                                       depth,
37014b98343309fdcff3514f05020303f7b40e83a4aBrian                                       stImage->base.TexFormat->TexelBytes,
37124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                                       comp_byte);
37224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
373b245840b86cf877c9b8d666edf229364a84f1deaBrian   stObj->mt->format
3749cf9aa1ea2c3f40a09316975410a4b0e202e82baBrian      = st_mesa_format_to_pipe_format(stImage->base.TexFormat->MesaFormat);
375b245840b86cf877c9b8d666edf229364a84f1deaBrian
37624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   DBG("%s - success\n", __FUNCTION__);
37724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian}
37824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
37924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
38024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
38124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
38224df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic GLuint
38324df8f895fe8807aa2ba058e71bd40adfc01d21eBriantarget_to_face(GLenum target)
38424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{
38524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   switch (target) {
38624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB:
38724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB:
38824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB:
38924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB:
39024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB:
39124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB:
39224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      return ((GLuint) target - (GLuint) GL_TEXTURE_CUBE_MAP_POSITIVE_X);
39324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   default:
39424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      return 0;
39524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   }
39624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian}
39724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
39824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
39924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
40024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian/* There are actually quite a few combinations this will work for,
40124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * more than what I've listed here.
40224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */
40324df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic GLboolean
40424df8f895fe8807aa2ba058e71bd40adfc01d21eBriancheck_pbo_format(GLint internalFormat,
40524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                 GLenum format, GLenum type,
40624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                 const struct gl_texture_format *mesa_format)
40724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{
40824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   switch (internalFormat) {
40924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   case 4:
41024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   case GL_RGBA:
41124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      return (format == GL_BGRA &&
41224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian              (type == GL_UNSIGNED_BYTE ||
41324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian               type == GL_UNSIGNED_INT_8_8_8_8_REV) &&
41424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian              mesa_format == &_mesa_texformat_argb8888);
41524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   case 3:
41624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   case GL_RGB:
41724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      return (format == GL_RGB &&
41824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian              type == GL_UNSIGNED_SHORT_5_6_5 &&
41924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian              mesa_format == &_mesa_texformat_rgb565);
42024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   case GL_YCBCR_MESA:
42124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      return (type == GL_UNSIGNED_SHORT_8_8_MESA || type == GL_UNSIGNED_BYTE);
42224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   default:
42324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      return GL_FALSE;
42424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   }
42524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian}
42624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
42724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
42824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian/* XXX: Do this for TexSubImage also:
42924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */
43024df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic GLboolean
43124df8f895fe8807aa2ba058e71bd40adfc01d21eBriantry_pbo_upload(GLcontext *ctx,
43214b98343309fdcff3514f05020303f7b40e83a4aBrian               struct st_texture_image *stImage,
43324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian               const struct gl_pixelstore_attrib *unpack,
43424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian               GLint internalFormat,
43524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian               GLint width, GLint height,
43624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian               GLenum format, GLenum type, const void *pixels)
43724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{
43824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   return GL_FALSE;  /* XXX fix flushing/locking/blitting below */
43924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#if 000
44024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   struct intel_context *intel = intel_context(ctx);
44124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   struct intel_buffer_object *pbo = intel_buffer_object(unpack->BufferObj);
44224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   GLuint src_offset, src_stride;
44324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   GLuint dst_offset, dst_stride;
44424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
44524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   if (!pbo ||
44624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian       ctx._ImageTransferState ||
44724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian       unpack->SkipPixels || unpack->SkipRows) {
44824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      _mesa_printf("%s: failure 1\n", __FUNCTION__);
44924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      return GL_FALSE;
45024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   }
45124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
45224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   src_offset = (GLuint) pixels;
45324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
45424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   if (unpack->RowLength > 0)
45524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      src_stride = unpack->RowLength;
45624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   else
45724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      src_stride = width;
45824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
45914b98343309fdcff3514f05020303f7b40e83a4aBrian   dst_offset = st_miptree_image_offset(stImage->mt,
46014b98343309fdcff3514f05020303f7b40e83a4aBrian                                           stImage->face,
46114b98343309fdcff3514f05020303f7b40e83a4aBrian                                           stImage->level);
46224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
46314b98343309fdcff3514f05020303f7b40e83a4aBrian   dst_stride = stImage->mt->pitch;
46424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
46524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   intelFlush(&intel->ctx);
46624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   LOCK_HARDWARE(intel);
46724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   {
46824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      struct _DriBufferObject *src_buffer =
46924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian         intel_bufferobj_buffer(intel, pbo, INTEL_READ);
47024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
47124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      /* Temporary hack: cast to _DriBufferObject:
47224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian       */
47324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      struct _DriBufferObject *dst_buffer =
47414b98343309fdcff3514f05020303f7b40e83a4aBrian         (struct _DriBufferObject *)stImage->mt->region->buffer;
47524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
47624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
47724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      intelEmitCopyBlit(intel,
47814b98343309fdcff3514f05020303f7b40e83a4aBrian                        stImage->mt->cpp,
47924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                        src_stride, src_buffer, src_offset,
48024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                        dst_stride, dst_buffer, dst_offset,
48124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                        0, 0, 0, 0, width, height,
48224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian			GL_COPY);
48324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
48424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      intel_batchbuffer_flush(intel->batch);
48524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   }
48624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   UNLOCK_HARDWARE(intel);
48724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
48824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   return GL_TRUE;
48924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#endif
49024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian}
49124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
49224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
49324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
49424df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic GLboolean
49524df8f895fe8807aa2ba058e71bd40adfc01d21eBriantry_pbo_zcopy(GLcontext *ctx,
49614b98343309fdcff3514f05020303f7b40e83a4aBrian              struct st_texture_image *stImage,
49724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian              const struct gl_pixelstore_attrib *unpack,
49824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian              GLint internalFormat,
49924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian              GLint width, GLint height,
50024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian              GLenum format, GLenum type, const void *pixels)
50124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{
50224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   return GL_FALSE;
50324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian}
50424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
50524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
50624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
50724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
50824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
50924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
51024df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void
51124df8f895fe8807aa2ba058e71bd40adfc01d21eBrianst_TexImage(GLcontext * ctx,
51224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian              GLint dims,
51324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian              GLenum target, GLint level,
51424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian              GLint internalFormat,
51524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian              GLint width, GLint height, GLint depth,
51624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian              GLint border,
51724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian              GLenum format, GLenum type, const void *pixels,
51824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian              const struct gl_pixelstore_attrib *unpack,
51924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian              struct gl_texture_object *texObj,
52024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian              struct gl_texture_image *texImage, GLsizei imageSize, int compressed)
52124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{
52224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   struct pipe_context *pipe = ctx->st->pipe;
52314b98343309fdcff3514f05020303f7b40e83a4aBrian   struct st_texture_object *stObj = st_texture_object(texObj);
52414b98343309fdcff3514f05020303f7b40e83a4aBrian   struct st_texture_image *stImage = st_texture_image(texImage);
52524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   GLint postConvWidth = width;
52624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   GLint postConvHeight = height;
52724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   GLint texelBytes, sizeInBytes;
52824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   GLuint dstRowStride;
52924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
53024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
53124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   DBG("%s target %s level %d %dx%dx%d border %d\n", __FUNCTION__,
53224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian       _mesa_lookup_enum_by_nr(target), level, width, height, depth, border);
53324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
53424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#if 0
53524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   intelFlush(ctx);
53624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#endif
53724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
53814b98343309fdcff3514f05020303f7b40e83a4aBrian   stImage->face = target_to_face(target);
53914b98343309fdcff3514f05020303f7b40e83a4aBrian   stImage->level = level;
54024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
54124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   if (ctx->_ImageTransferState & IMAGE_CONVOLUTION_BIT) {
54224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      _mesa_adjust_image_for_convolution(ctx, dims, &postConvWidth,
54324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                                         &postConvHeight);
54424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   }
54524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
54624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   /* choose the texture format */
54724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   texImage->TexFormat = st_ChooseTextureFormat(ctx, internalFormat,
54824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                                                  format, type);
54924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
55024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   _mesa_set_fetch_functions(texImage, dims);
55124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
55224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   if (texImage->TexFormat->TexelBytes == 0) {
55324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      /* must be a compressed format */
55424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      texelBytes = 0;
55524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      texImage->IsCompressed = GL_TRUE;
55624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      texImage->CompressedSize =
55724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian	 ctx->Driver.CompressedTextureSize(ctx, texImage->Width,
55824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian					   texImage->Height, texImage->Depth,
55924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian					   texImage->TexFormat->MesaFormat);
56024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   } else {
56124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      texelBytes = texImage->TexFormat->TexelBytes;
56224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
56324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      /* Minimum pitch of 32 bytes */
56424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      if (postConvWidth * texelBytes < 32) {
56524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian	 postConvWidth = 32 / texelBytes;
56624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian	 texImage->RowStride = postConvWidth;
56724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      }
56824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
56924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      assert(texImage->RowStride == postConvWidth);
57024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   }
57124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
57224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   /* Release the reference to a potentially orphaned buffer.
57324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian    * Release any old malloced memory.
57424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian    */
57514b98343309fdcff3514f05020303f7b40e83a4aBrian   if (stImage->mt) {
57614b98343309fdcff3514f05020303f7b40e83a4aBrian      st_miptree_release(pipe, &stImage->mt);
57724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      assert(!texImage->Data);
57824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   }
57924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   else if (texImage->Data) {
58024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      _mesa_align_free(texImage->Data);
58124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   }
58224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
58324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   /* If this is the only texture image in the tree, could call
58424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian    * bmBufferData with NULL data to free the old block and avoid
58524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian    * waiting on any outstanding fences.
58624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian    */
58714b98343309fdcff3514f05020303f7b40e83a4aBrian   if (stObj->mt &&
58814b98343309fdcff3514f05020303f7b40e83a4aBrian       stObj->mt->first_level == level &&
58914b98343309fdcff3514f05020303f7b40e83a4aBrian       stObj->mt->last_level == level &&
59014b98343309fdcff3514f05020303f7b40e83a4aBrian       stObj->mt->target != GL_TEXTURE_CUBE_MAP_ARB &&
59114b98343309fdcff3514f05020303f7b40e83a4aBrian       !st_miptree_match_image(stObj->mt, &stImage->base,
59214b98343309fdcff3514f05020303f7b40e83a4aBrian                                  stImage->face, stImage->level)) {
59324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
59424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      DBG("release it\n");
59514b98343309fdcff3514f05020303f7b40e83a4aBrian      st_miptree_release(pipe, &stObj->mt);
59614b98343309fdcff3514f05020303f7b40e83a4aBrian      assert(!stObj->mt);
59724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   }
59824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
59914b98343309fdcff3514f05020303f7b40e83a4aBrian   if (!stObj->mt) {
60014b98343309fdcff3514f05020303f7b40e83a4aBrian      guess_and_alloc_mipmap_tree(pipe, stObj, stImage);
60114b98343309fdcff3514f05020303f7b40e83a4aBrian      if (!stObj->mt) {
60224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian	 DBG("guess_and_alloc_mipmap_tree: failed\n");
60324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      }
60424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   }
60524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
60614b98343309fdcff3514f05020303f7b40e83a4aBrian   assert(!stImage->mt);
60724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
60814b98343309fdcff3514f05020303f7b40e83a4aBrian   if (stObj->mt &&
60914b98343309fdcff3514f05020303f7b40e83a4aBrian       st_miptree_match_image(stObj->mt, &stImage->base,
61014b98343309fdcff3514f05020303f7b40e83a4aBrian                                 stImage->face, stImage->level)) {
61124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
61214b98343309fdcff3514f05020303f7b40e83a4aBrian      st_miptree_reference(&stImage->mt, stObj->mt);
61314b98343309fdcff3514f05020303f7b40e83a4aBrian      assert(stImage->mt);
61424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   }
61524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
61614b98343309fdcff3514f05020303f7b40e83a4aBrian   if (!stImage->mt)
61724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      DBG("XXX: Image did not fit into tree - storing in local memory!\n");
61824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
61924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#if 0 /* XXX FIX when st_buffer_objects are in place */
62024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   /* PBO fastpaths:
62124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian    */
62224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   if (dims <= 2 &&
62314b98343309fdcff3514f05020303f7b40e83a4aBrian       stImage->mt &&
62424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian       intel_buffer_object(unpack->BufferObj) &&
62524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian       check_pbo_format(internalFormat, format,
62614b98343309fdcff3514f05020303f7b40e83a4aBrian                        type, stImage->base.TexFormat)) {
62724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
62824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      DBG("trying pbo upload\n");
62924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
63024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      /* Attempt to texture directly from PBO data (zero copy upload).
63124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian       *
63224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian       * Currently disable as it can lead to worse as well as better
63324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian       * performance (in particular when pipe_region_cow() is
63424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian       * required).
63524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian       */
63614b98343309fdcff3514f05020303f7b40e83a4aBrian      if (stObj->mt == stImage->mt &&
63714b98343309fdcff3514f05020303f7b40e83a4aBrian          stObj->mt->first_level == level &&
63814b98343309fdcff3514f05020303f7b40e83a4aBrian          stObj->mt->last_level == level) {
63924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
64014b98343309fdcff3514f05020303f7b40e83a4aBrian         if (try_pbo_zcopy(intel, stImage, unpack,
64124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                           internalFormat,
64224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                           width, height, format, type, pixels)) {
64324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
64424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian            DBG("pbo zcopy upload succeeded\n");
64524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian            return;
64624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian         }
64724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      }
64824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
64924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
65024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      /* Otherwise, attempt to use the blitter for PBO image uploads.
65124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian       */
65214b98343309fdcff3514f05020303f7b40e83a4aBrian      if (try_pbo_upload(intel, stImage, unpack,
65324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                         internalFormat,
65424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                         width, height, format, type, pixels)) {
65524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian         DBG("pbo upload succeeded\n");
65624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian         return;
65724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      }
65824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
65924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      DBG("pbo upload failed\n");
66024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   }
66124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#else
66224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   (void) try_pbo_upload;
66324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   (void) check_pbo_format;
66424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   (void) try_pbo_zcopy;
66524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#endif
66624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
66724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
66824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   /* intelCopyTexImage calls this function with pixels == NULL, with
66924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian    * the expectation that the mipmap tree will be set up but nothing
67024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian    * more will be done.  This is where those calls return:
67124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian    */
67224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   if (compressed) {
67324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      pixels = _mesa_validate_pbo_compressed_teximage(ctx, imageSize, pixels,
67424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian						      unpack,
67524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian						      "glCompressedTexImage");
67624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   } else {
67724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      pixels = _mesa_validate_pbo_teximage(ctx, dims, width, height, 1,
67824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian					   format, type,
67924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian					   pixels, unpack, "glTexImage");
68024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   }
68124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   if (!pixels)
68224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      return;
68324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
68424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
68514b98343309fdcff3514f05020303f7b40e83a4aBrian   if (stImage->mt)
68614b98343309fdcff3514f05020303f7b40e83a4aBrian      pipe->region_idle(pipe, stImage->mt->region);
68724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
68824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#if 0
68924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   LOCK_HARDWARE(intel);
69024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#endif
69124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
69214b98343309fdcff3514f05020303f7b40e83a4aBrian   if (stImage->mt) {
69324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      texImage->Data = st_miptree_image_map(pipe,
69414b98343309fdcff3514f05020303f7b40e83a4aBrian                                               stImage->mt,
69514b98343309fdcff3514f05020303f7b40e83a4aBrian                                               stImage->face,
69614b98343309fdcff3514f05020303f7b40e83a4aBrian                                               stImage->level,
69724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                                               &dstRowStride,
69814b98343309fdcff3514f05020303f7b40e83a4aBrian                                               stImage->base.ImageOffsets);
69924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   }
70024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   else {
70124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      /* Allocate regular memory and store the image there temporarily.   */
70224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      if (texImage->IsCompressed) {
70324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian         sizeInBytes = texImage->CompressedSize;
70424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian         dstRowStride =
70524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian            _mesa_compressed_row_stride(texImage->TexFormat->MesaFormat, width);
70624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian         assert(dims != 3);
70724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      }
70824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      else {
70924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian         dstRowStride = postConvWidth * texelBytes;
71024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian         sizeInBytes = depth * dstRowStride * postConvHeight;
71124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      }
71224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
71324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      texImage->Data = malloc(sizeInBytes);
71424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   }
71524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
71624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   DBG("Upload image %dx%dx%d row_len %x pitch %x\n",
71724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian       width, height, depth, width * texelBytes, dstRowStride);
71824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
71924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   /* Copy data.  Would like to know when it's ok for us to eg. use
72024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian    * the blitter to copy.  Or, use the hardware to do the format
72124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian    * conversion and copy:
72224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian    */
72324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   if (compressed) {
72424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian     memcpy(texImage->Data, pixels, imageSize);
72524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   }
72624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   else if (!texImage->TexFormat->StoreImage(ctx, dims,
72724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                                             texImage->_BaseFormat,
72824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                                             texImage->TexFormat,
72924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                                             texImage->Data,
73024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                                             0, 0, 0, /* dstX/Y/Zoffset */
73124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                                             dstRowStride,
73224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                                             texImage->ImageOffsets,
73324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                                             width, height, depth,
73424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                                             format, type, pixels, unpack)) {
73524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage");
73624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   }
73724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
73824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   _mesa_unmap_teximage_pbo(ctx, unpack);
73924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
74014b98343309fdcff3514f05020303f7b40e83a4aBrian   if (stImage->mt) {
74114b98343309fdcff3514f05020303f7b40e83a4aBrian      st_miptree_image_unmap(pipe, stImage->mt);
74224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      texImage->Data = NULL;
74324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   }
74424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
74524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#if 0
74624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   UNLOCK_HARDWARE(intel);
74724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#endif
74824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
74924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#if 0
75024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   /* GL_SGIS_generate_mipmap -- this can be accelerated now.
75124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian    */
75224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
75324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      intel_generate_mipmap(ctx, target,
75424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                            &ctx->Texture.Unit[ctx->Texture.CurrentUnit],
75524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                            texObj);
75624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   }
75724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#endif
75824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian}
75924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
76024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
76124df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void
76224df8f895fe8807aa2ba058e71bd40adfc01d21eBrianst_TexImage3D(GLcontext * ctx,
76324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                GLenum target, GLint level,
76424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                GLint internalFormat,
76524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                GLint width, GLint height, GLint depth,
76624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                GLint border,
76724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                GLenum format, GLenum type, const void *pixels,
76824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                const struct gl_pixelstore_attrib *unpack,
76924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                struct gl_texture_object *texObj,
77024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                struct gl_texture_image *texImage)
77124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{
77224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   st_TexImage(ctx, 3, target, level,
77324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                 internalFormat, width, height, depth, border,
77424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                 format, type, pixels, unpack, texObj, texImage, 0, 0);
77524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian}
77624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
77724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
77824df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void
77924df8f895fe8807aa2ba058e71bd40adfc01d21eBrianst_TexImage2D(GLcontext * ctx,
78024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                GLenum target, GLint level,
78124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                GLint internalFormat,
78224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                GLint width, GLint height, GLint border,
78324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                GLenum format, GLenum type, const void *pixels,
78424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                const struct gl_pixelstore_attrib *unpack,
78524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                struct gl_texture_object *texObj,
78624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                struct gl_texture_image *texImage)
78724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{
78824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   st_TexImage(ctx, 2, target, level,
78924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                 internalFormat, width, height, 1, border,
79024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                 format, type, pixels, unpack, texObj, texImage, 0, 0);
79124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian}
79224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
79324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
79424df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void
79524df8f895fe8807aa2ba058e71bd40adfc01d21eBrianst_TexImage1D(GLcontext * ctx,
79624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                GLenum target, GLint level,
79724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                GLint internalFormat,
79824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                GLint width, GLint border,
79924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                GLenum format, GLenum type, const void *pixels,
80024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                const struct gl_pixelstore_attrib *unpack,
80124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                struct gl_texture_object *texObj,
80224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                struct gl_texture_image *texImage)
80324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{
80424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   st_TexImage(ctx, 1, target, level,
80524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                 internalFormat, width, 1, 1, border,
80624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                 format, type, pixels, unpack, texObj, texImage, 0, 0);
80724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian}
80824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
80924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
81024df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void
81124df8f895fe8807aa2ba058e71bd40adfc01d21eBrianst_CompressedTexImage2D( GLcontext *ctx, GLenum target, GLint level,
81224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian				GLint internalFormat,
81324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian				GLint width, GLint height, GLint border,
81424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian				GLsizei imageSize, const GLvoid *data,
81524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian				struct gl_texture_object *texObj,
81624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian				struct gl_texture_image *texImage )
81724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{
81824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   st_TexImage(ctx, 2, target, level,
81924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian		 internalFormat, width, height, 1, border,
82024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian		 0, 0, data, &ctx->Unpack, texObj, texImage, imageSize, 1);
82124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian}
82224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
82324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
82424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian/**
82524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * Need to map texture image into memory before copying image data,
82624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * then unmap it.
82724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */
82824df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void
82924df8f895fe8807aa2ba058e71bd40adfc01d21eBrianst_get_tex_image(GLcontext * ctx, GLenum target, GLint level,
83024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                 GLenum format, GLenum type, GLvoid * pixels,
83124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                 struct gl_texture_object *texObj,
83224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                 struct gl_texture_image *texImage, int compressed)
83324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{
83424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   /*
83524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   struct intel_context *intel = intel_context(ctx);
83624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   */
83724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   struct pipe_context *pipe = ctx->st->pipe;
83824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   struct st_texture_image *stImage = st_texture_image(texImage);
83924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
84024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   /* Map */
84124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   if (stImage->mt) {
84224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      /* Image is stored in hardware format in a buffer managed by the
84324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian       * kernel.  Need to explicitly map and unmap it.
84424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian       */
84524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      stImage->base.Data =
84624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian         st_miptree_image_map(pipe,
84724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                                 stImage->mt,
84824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                                 stImage->face,
84924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                                 stImage->level,
85024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                                 &stImage->base.RowStride,
85124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                                 stImage->base.ImageOffsets);
85224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      stImage->base.RowStride /= stImage->mt->cpp;
85324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   }
85424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   else {
85524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      /* Otherwise, the image should actually be stored in
85624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian       * stImage->base.Data.  This is pretty confusing for
85724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian       * everybody, I'd much prefer to separate the two functions of
85824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian       * texImage->Data - storage for texture images in main memory
85924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian       * and access (ie mappings) of images.  In other words, we'd
86024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian       * create a new texImage->Map field and leave Data simply for
86124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian       * storage.
86224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian       */
86324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      assert(stImage->base.Data);
86424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   }
86524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
86624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
86724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   if (compressed) {
86824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      _mesa_get_compressed_teximage(ctx, target, level, pixels,
86924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian				    texObj, texImage);
87024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   } else {
87124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      _mesa_get_teximage(ctx, target, level, format, type, pixels,
87224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian			 texObj, texImage);
87324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   }
87424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
87524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
87624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   /* Unmap */
87724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   if (stImage->mt) {
87824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      st_miptree_image_unmap(pipe, stImage->mt);
87924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      stImage->base.Data = NULL;
88024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   }
88124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian}
88224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
88324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
88424df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void
88524df8f895fe8807aa2ba058e71bd40adfc01d21eBrianst_GetTexImage(GLcontext * ctx, GLenum target, GLint level,
88624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                 GLenum format, GLenum type, GLvoid * pixels,
88724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                 struct gl_texture_object *texObj,
88824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                 struct gl_texture_image *texImage)
88924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{
89024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   st_get_tex_image(ctx, target, level, format, type, pixels,
89124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                    texObj, texImage, 0);
89224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian}
89324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
89424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
89524df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void
89624df8f895fe8807aa2ba058e71bd40adfc01d21eBrianst_GetCompressedTexImage(GLcontext *ctx, GLenum target, GLint level,
89724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian			   GLvoid *pixels,
89824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian			   const struct gl_texture_object *texObj,
89924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian			   const struct gl_texture_image *texImage)
90024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{
90124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   st_get_tex_image(ctx, target, level, 0, 0, pixels,
90224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                    (struct gl_texture_object *) texObj,
90324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                    (struct gl_texture_image *) texImage, 1);
90424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian}
90524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
90624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
90724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
90824df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void
90924df8f895fe8807aa2ba058e71bd40adfc01d21eBrianst_TexSubimage(GLcontext * ctx,
91024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                 GLint dims,
91124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                 GLenum target, GLint level,
91224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                 GLint xoffset, GLint yoffset, GLint zoffset,
91324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                 GLint width, GLint height, GLint depth,
91424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                 GLenum format, GLenum type, const void *pixels,
91524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                 const struct gl_pixelstore_attrib *packing,
91624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                 struct gl_texture_object *texObj,
91724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                 struct gl_texture_image *texImage)
91824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{
91924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   struct pipe_context *pipe = ctx->st->pipe;
92024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   struct st_texture_image *stImage = st_texture_image(texImage);
92124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   GLuint dstRowStride;
92224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
92324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   DBG("%s target %s level %d offset %d,%d %dx%d\n", __FUNCTION__,
92424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian       _mesa_lookup_enum_by_nr(target),
92524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian       level, xoffset, yoffset, width, height);
92624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
92724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#if 0
92824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   intelFlush(ctx);
92924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#endif
93024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
93124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   pixels =
93224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      _mesa_validate_pbo_teximage(ctx, dims, width, height, depth, format,
93324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                                  type, pixels, packing, "glTexSubImage2D");
93424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   if (!pixels)
93524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      return;
93624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
93724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   if (stImage->mt)
93824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      pipe->region_idle(pipe, stImage->mt->region);
93924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
94024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#if 0
94124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   LOCK_HARDWARE(intel);
94224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#endif
94324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
94424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   /* Map buffer if necessary.  Need to lock to prevent other contexts
94524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian    * from uploading the buffer under us.
94624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian    */
94724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   if (stImage->mt)
94824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      texImage->Data = st_miptree_image_map(pipe,
94924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                                               stImage->mt,
95024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                                               stImage->face,
95124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                                               stImage->level,
95224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                                               &dstRowStride,
95324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                                               texImage->ImageOffsets);
95424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
95524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   assert(dstRowStride);
95624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
95724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   if (!texImage->TexFormat->StoreImage(ctx, dims, texImage->_BaseFormat,
95824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                                        texImage->TexFormat,
95924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                                        texImage->Data,
96024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                                        xoffset, yoffset, zoffset,
96124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                                        dstRowStride,
96224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                                        texImage->ImageOffsets,
96324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                                        width, height, depth,
96424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                                        format, type, pixels, packing)) {
96524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      _mesa_error(ctx, GL_OUT_OF_MEMORY, "intelTexSubImage");
96624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   }
96724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
96824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#if 0
96924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   /* GL_SGIS_generate_mipmap */
97024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
97124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      _mesa_generate_mipmap(ctx, target,
97224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                            &ctx->Texture.Unit[ctx->Texture.CurrentUnit],
97324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                            texObj);
97424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   }
97524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#endif
97624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
97724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   _mesa_unmap_teximage_pbo(ctx, packing);
97824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
97924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   if (stImage->mt) {
98024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      st_miptree_image_unmap(pipe, stImage->mt);
98124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      texImage->Data = NULL;
98224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   }
98324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
98424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#if 0
98524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   UNLOCK_HARDWARE(intel);
98624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#endif
98724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian}
98824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
98924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
99024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
99124df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void
99224df8f895fe8807aa2ba058e71bd40adfc01d21eBrianst_TexSubImage3D(GLcontext * ctx,
99324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                   GLenum target,
99424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                   GLint level,
99524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                   GLint xoffset, GLint yoffset, GLint zoffset,
99624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                   GLsizei width, GLsizei height, GLsizei depth,
99724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                   GLenum format, GLenum type,
99824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                   const GLvoid * pixels,
99924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                   const struct gl_pixelstore_attrib *packing,
100024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                   struct gl_texture_object *texObj,
100124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                   struct gl_texture_image *texImage)
100224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{
1003b245840b86cf877c9b8d666edf229364a84f1deaBrian   st_TexSubimage(ctx, 3, target, level,
1004b245840b86cf877c9b8d666edf229364a84f1deaBrian                  xoffset, yoffset, zoffset,
1005b245840b86cf877c9b8d666edf229364a84f1deaBrian                  width, height, depth,
1006b245840b86cf877c9b8d666edf229364a84f1deaBrian                  format, type, pixels, packing, texObj, texImage);
100724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian}
100824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
100924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
101024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
101124df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void
101224df8f895fe8807aa2ba058e71bd40adfc01d21eBrianst_TexSubImage2D(GLcontext * ctx,
101324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                   GLenum target,
101424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                   GLint level,
101524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                   GLint xoffset, GLint yoffset,
101624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                   GLsizei width, GLsizei height,
101724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                   GLenum format, GLenum type,
101824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                   const GLvoid * pixels,
101924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                   const struct gl_pixelstore_attrib *packing,
102024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                   struct gl_texture_object *texObj,
102124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                   struct gl_texture_image *texImage)
102224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{
1023b245840b86cf877c9b8d666edf229364a84f1deaBrian   st_TexSubimage(ctx, 2, target, level,
1024b245840b86cf877c9b8d666edf229364a84f1deaBrian                  xoffset, yoffset, 0,
1025b245840b86cf877c9b8d666edf229364a84f1deaBrian                  width, height, 1,
1026b245840b86cf877c9b8d666edf229364a84f1deaBrian                  format, type, pixels, packing, texObj, texImage);
102724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian}
102824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
102924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
103024df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void
103124df8f895fe8807aa2ba058e71bd40adfc01d21eBrianst_TexSubImage1D(GLcontext * ctx,
103224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                   GLenum target,
103324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                   GLint level,
103424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                   GLint xoffset,
103524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                   GLsizei width,
103624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                   GLenum format, GLenum type,
103724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                   const GLvoid * pixels,
103824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                   const struct gl_pixelstore_attrib *packing,
103924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                   struct gl_texture_object *texObj,
104024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                   struct gl_texture_image *texImage)
104124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{
1042b245840b86cf877c9b8d666edf229364a84f1deaBrian   st_TexSubimage(ctx, 1, target, level,
1043b245840b86cf877c9b8d666edf229364a84f1deaBrian                  xoffset, 0, 0,
1044b245840b86cf877c9b8d666edf229364a84f1deaBrian                  width, 1, 1,
1045b245840b86cf877c9b8d666edf229364a84f1deaBrian                  format, type, pixels, packing, texObj, texImage);
104624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian}
104724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
104824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
104924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
105024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian/**
105124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * Get the pipe_region which is the source for any glCopyTex[Sub]Image call.
105224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian *
105324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * Do the best we can using the blitter.  A future project is to use
105424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * the texture engine and fragment programs for these copies.
105524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */
105624df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic const struct pipe_region *
105724df8f895fe8807aa2ba058e71bd40adfc01d21eBrianget_teximage_source(GLcontext *ctx, GLenum internalFormat)
105824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{
105924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#if 00
106024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   struct intel_renderbuffer *irb;
106124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
106224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   DBG("%s %s\n", __FUNCTION__,
106324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian       _mesa_lookup_enum_by_nr(internalFormat));
106424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
106524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   switch (internalFormat) {
106624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   case GL_DEPTH_COMPONENT:
106724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   case GL_DEPTH_COMPONENT16_ARB:
106824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      irb = intel_get_renderbuffer(intel->ctx.ReadBuffer, BUFFER_DEPTH);
106924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      if (irb && irb->region && irb->region->cpp == 2)
107024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian         return irb->region;
107124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      return NULL;
107224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   case GL_DEPTH24_STENCIL8_EXT:
107324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   case GL_DEPTH_STENCIL_EXT:
107424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      irb = intel_get_renderbuffer(intel->ctx.ReadBuffer, BUFFER_DEPTH);
107524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      if (irb && irb->region && irb->region->cpp == 4)
107624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian         return irb->region;
107724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      return NULL;
107824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   case GL_RGBA:
107924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   case GL_RGBA8:
108024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      return intel_readbuf_region(intel);
108124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   case GL_RGB:
108224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      if (intel->intelScreen->front.cpp == 2)
108324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian         return intel_readbuf_region(intel);
108424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      return NULL;
108524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   default:
108624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      return NULL;
108724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   }
108824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#else
108924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   return NULL;
109024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#endif
109124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian}
109224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
109324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
109424df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic GLboolean
109524df8f895fe8807aa2ba058e71bd40adfc01d21eBriando_copy_texsubimage(GLcontext *ctx,
109624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                    struct st_texture_image *stImage,
109724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                    GLenum internalFormat,
109824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                    GLint dstx, GLint dsty,
109924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                    GLint x, GLint y, GLsizei width, GLsizei height)
110024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{
110124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   const struct pipe_region *src =
110224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      get_teximage_source(ctx, internalFormat);
110324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
110424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   if (!stImage->mt || !src) {
11056da9234fd437f97267e7831f034c78b31156d939Brian      DBG("%s fail %p %p\n", __FUNCTION__, (void *) stImage->mt, (void *) src);
110624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      return GL_FALSE;
110724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   }
110824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
110924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#if 00 /* XXX FIX flush/locking */
111024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   intelFlush(ctx);
111124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   /* XXX still need the lock ? */
111224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   LOCK_HARDWARE(intel);
111324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#endif
111424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
111524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   {
111624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      GLuint image_offset = st_miptree_image_offset(stImage->mt,
111724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                                                       stImage->face,
111824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                                                       stImage->level);
111924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      const GLint orig_x = x;
112024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      const GLint orig_y = y;
112124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      const struct gl_framebuffer *fb = ctx->DrawBuffer;
112224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
112324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      if (_mesa_clip_to_region(fb->_Xmin, fb->_Ymin, fb->_Xmax, fb->_Ymax,
112424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                               &x, &y, &width, &height)) {
112524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian         /* Update dst for clipped src.  Need to also clip the source rect.
112624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian          */
112724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian         dstx += x - orig_x;
112824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian         dsty += y - orig_y;
112924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
113024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian         if (!(ctx->ReadBuffer->Name == 0)) {
113124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian	    /* XXX this looks bogus ? */
113224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian	    /* FBO: invert Y */
113324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian	    y = ctx->ReadBuffer->Height - y - 1;
113424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian         }
113524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
113624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian         /* A bit of fiddling to get the blitter to work with -ve
113724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian          * pitches.  But we get a nice inverted blit this way, so it's
113824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian          * worth it:
113924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian          */
114024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#if 0
114124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian         intelEmitCopyBlit(intel,
114224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                           stImage->mt->cpp,
114324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                           -src->pitch,
114424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                           src->buffer,
114524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                           src->height * src->pitch * src->cpp,
114624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                           stImage->mt->pitch,
114724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                           stImage->mt->region->buffer,
114824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                           image_offset,
114924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                           x, y + height, dstx, dsty, width, height,
115024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian			   GL_COPY); /* ? */
115124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian         intel_batchbuffer_flush(intel->batch);
115224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#else
115324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian         /* XXX use pipe->region_copy() ??? */
115424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian         (void) image_offset;
115524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#endif
115624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      }
115724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   }
115824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
115924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#if 0
116024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   UNLOCK_HARDWARE(intel);
116124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#endif
116224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
116324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#if 0
116424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   /* GL_SGIS_generate_mipmap -- this can be accelerated now.
116524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian    * XXX Add a ctx->Driver.GenerateMipmaps() function?
116624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian    */
116724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
116824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      intel_generate_mipmap(ctx, target,
116924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                            &ctx->Texture.Unit[ctx->Texture.CurrentUnit],
117024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                            texObj);
117124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   }
117224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#endif
117324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
117424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   return GL_TRUE;
117524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian}
117624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
117724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
117824df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void
117924df8f895fe8807aa2ba058e71bd40adfc01d21eBrianst_CopyTexImage1D(GLcontext * ctx, GLenum target, GLint level,
118024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                  GLenum internalFormat,
118124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                  GLint x, GLint y, GLsizei width, GLint border)
118224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{
118324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   struct gl_texture_unit *texUnit =
118424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
118524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   struct gl_texture_object *texObj =
118624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      _mesa_select_tex_object(ctx, texUnit, target);
118724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   struct gl_texture_image *texImage =
118824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      _mesa_select_tex_image(ctx, texObj, target, level);
118924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
119024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   if (border)
119124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      goto fail;
119224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
119324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   /* Setup or redefine the texture object, mipmap tree and texture
119424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian    * image.  Don't populate yet.
119524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian    */
119624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   ctx->Driver.TexImage1D(ctx, target, level, internalFormat,
119724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                          width, border,
119824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                          GL_RGBA, CHAN_TYPE, NULL,
119924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                          &ctx->DefaultPacking, texObj, texImage);
120024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
120124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   if (!do_copy_texsubimage(ctx,
120224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                            st_texture_image(texImage),
120324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                            internalFormat, 0, 0, x, y, width, 1))
120424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      goto fail;
120524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
120624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   return;
120724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
120824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian fail:
120924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#if 0
121024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   _swrast_copy_teximage1d(ctx, target, level, internalFormat, x, y,
121124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                           width, border);
121224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#endif
121324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   ;
121424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian}
121524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
121624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
121724df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void
121824df8f895fe8807aa2ba058e71bd40adfc01d21eBrianst_CopyTexImage2D(GLcontext * ctx, GLenum target, GLint level,
121924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                  GLenum internalFormat,
122024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                  GLint x, GLint y, GLsizei width, GLsizei height,
122124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                  GLint border)
122224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{
122324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   struct gl_texture_unit *texUnit =
122424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
122524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   struct gl_texture_object *texObj =
122624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      _mesa_select_tex_object(ctx, texUnit, target);
122724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   struct gl_texture_image *texImage =
122824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      _mesa_select_tex_image(ctx, texObj, target, level);
122924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
123024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   if (border)
123124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      goto fail;
123224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
123324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   /* Setup or redefine the texture object, mipmap tree and texture
123424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian    * image.  Don't populate yet.
123524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian    */
123624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   ctx->Driver.TexImage2D(ctx, target, level, internalFormat,
123724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                          width, height, border,
123824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                          GL_RGBA, CHAN_TYPE, NULL,
123924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                          &ctx->DefaultPacking, texObj, texImage);
124024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
124124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
124224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   if (!do_copy_texsubimage(ctx,
124324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                            st_texture_image(texImage),
124424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                            internalFormat, 0, 0, x, y, width, height))
124524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      goto fail;
124624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
124724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   return;
124824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
124924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian fail:
125024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#if 0
125124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   _swrast_copy_teximage2d(ctx, target, level, internalFormat, x, y,
125224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                           width, height, border);
125324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#endif
125424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   assert(0);
125524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian}
125624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
125724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
125824df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void
125924df8f895fe8807aa2ba058e71bd40adfc01d21eBrianst_CopyTexSubImage1D(GLcontext * ctx, GLenum target, GLint level,
126024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                     GLint xoffset, GLint x, GLint y, GLsizei width)
126124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{
126224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   struct gl_texture_unit *texUnit =
126324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
126424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   struct gl_texture_object *texObj =
126524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      _mesa_select_tex_object(ctx, texUnit, target);
126624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   struct gl_texture_image *texImage =
126724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      _mesa_select_tex_image(ctx, texObj, target, level);
126824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   GLenum internalFormat = texImage->InternalFormat;
126924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
127024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   /* XXX need to check <border> as in above function? */
127124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
127224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   /* Need to check texture is compatible with source format.
127324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian    */
127424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
127524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   if (!do_copy_texsubimage(ctx,
127624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                            st_texture_image(texImage),
127724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                            internalFormat, xoffset, 0, x, y, width, 1)) {
127824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#if 0
127924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      _swrast_copy_texsubimage1d(ctx, target, level, xoffset, x, y, width);
128024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#endif
128124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      assert(0);
128224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   }
128324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian}
128424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
128524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
128624df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void
128724df8f895fe8807aa2ba058e71bd40adfc01d21eBrianst_CopyTexSubImage2D(GLcontext * ctx, GLenum target, GLint level,
128824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                     GLint xoffset, GLint yoffset,
128924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                     GLint x, GLint y, GLsizei width, GLsizei height)
129024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{
129124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   struct gl_texture_unit *texUnit =
129224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
129324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   struct gl_texture_object *texObj =
129424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      _mesa_select_tex_object(ctx, texUnit, target);
129524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   struct gl_texture_image *texImage =
129624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      _mesa_select_tex_image(ctx, texObj, target, level);
129724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   GLenum internalFormat = texImage->InternalFormat;
129824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
129924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
130024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   /* Need to check texture is compatible with source format.
130124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian    */
130224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
130324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   if (!do_copy_texsubimage(ctx,
130424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                            st_texture_image(texImage),
130524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                            internalFormat,
130624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                            xoffset, yoffset, x, y, width, height)) {
130724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#if 0
130824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      _swrast_copy_texsubimage2d(ctx, target, level,
130924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                                 xoffset, yoffset, x, y, width, height);
131024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#endif
131124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      assert(0);
131224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   }
131324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian}
131424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
131524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
131624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
131724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
131824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian/**
131924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * Compute which mipmap levels that really need to be sent to the hardware.
132024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * This depends on the base image size, GL_TEXTURE_MIN_LOD,
132124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * GL_TEXTURE_MAX_LOD, GL_TEXTURE_BASE_LEVEL, and GL_TEXTURE_MAX_LEVEL.
132224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */
132324df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void
132414b98343309fdcff3514f05020303f7b40e83a4aBriancalculate_first_last_level(struct st_texture_object *stObj)
132524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{
132614b98343309fdcff3514f05020303f7b40e83a4aBrian   struct gl_texture_object *tObj = &stObj->base;
132724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   const struct gl_texture_image *const baseImage =
132824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      tObj->Image[0][tObj->BaseLevel];
132924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
133024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   /* These must be signed values.  MinLod and MaxLod can be negative numbers,
133124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian    * and having firstLevel and lastLevel as signed prevents the need for
133224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian    * extra sign checks.
133324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian    */
133424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   int firstLevel;
133524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   int lastLevel;
133624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
133724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   /* Yes, this looks overly complicated, but it's all needed.
133824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian    */
133924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   switch (tObj->Target) {
134024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   case GL_TEXTURE_1D:
134124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   case GL_TEXTURE_2D:
134224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   case GL_TEXTURE_3D:
134324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   case GL_TEXTURE_CUBE_MAP:
134424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      if (tObj->MinFilter == GL_NEAREST || tObj->MinFilter == GL_LINEAR) {
134524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian         /* GL_NEAREST and GL_LINEAR only care about GL_TEXTURE_BASE_LEVEL.
134624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian          */
134724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian         firstLevel = lastLevel = tObj->BaseLevel;
134824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      }
134924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      else {
135024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian         firstLevel = tObj->BaseLevel + (GLint) (tObj->MinLod + 0.5);
135124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian         firstLevel = MAX2(firstLevel, tObj->BaseLevel);
135224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian         lastLevel = tObj->BaseLevel + (GLint) (tObj->MaxLod + 0.5);
135324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian         lastLevel = MAX2(lastLevel, tObj->BaseLevel);
135424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian         lastLevel = MIN2(lastLevel, tObj->BaseLevel + baseImage->MaxLog2);
135524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian         lastLevel = MIN2(lastLevel, tObj->MaxLevel);
135624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian         lastLevel = MAX2(firstLevel, lastLevel);       /* need at least one level */
135724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      }
135824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      break;
135924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   case GL_TEXTURE_RECTANGLE_NV:
136024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   case GL_TEXTURE_4D_SGIS:
136124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      firstLevel = lastLevel = 0;
136224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      break;
136324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   default:
136424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      return;
136524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   }
136624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
136724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   /* save these values */
136814b98343309fdcff3514f05020303f7b40e83a4aBrian   stObj->firstLevel = firstLevel;
136914b98343309fdcff3514f05020303f7b40e83a4aBrian   stObj->lastLevel = lastLevel;
137024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian}
137124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
137224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
137324df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void
137424df8f895fe8807aa2ba058e71bd40adfc01d21eBriancopy_image_data_to_tree(struct pipe_context *pipe,
137514b98343309fdcff3514f05020303f7b40e83a4aBrian                        struct st_texture_object *stObj,
137624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                        struct st_texture_image *stImage)
137724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{
137824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   if (stImage->mt) {
137924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      /* Copy potentially with the blitter:
138024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian       */
138124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      st_miptree_image_copy(pipe,
138214b98343309fdcff3514f05020303f7b40e83a4aBrian                               stObj->mt,
138324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                               stImage->face,
138424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                               stImage->level, stImage->mt);
138524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
138624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      st_miptree_release(pipe, &stImage->mt);
138724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   }
138824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   else {
138924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      assert(stImage->base.Data != NULL);
139024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
139124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      /* More straightforward upload.
139224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian       */
139324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      st_miptree_image_data(pipe,
139414b98343309fdcff3514f05020303f7b40e83a4aBrian                               stObj->mt,
139524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                               stImage->face,
139624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                               stImage->level,
139724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                               stImage->base.Data,
139824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                               stImage->base.RowStride,
139924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                               stImage->base.RowStride *
140024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                               stImage->base.Height);
140124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      _mesa_align_free(stImage->base.Data);
140224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      stImage->base.Data = NULL;
140324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   }
140424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
140514b98343309fdcff3514f05020303f7b40e83a4aBrian   st_miptree_reference(&stImage->mt, stObj->mt);
140624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian}
140724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
140824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
140924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian/*
141024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */
141114b98343309fdcff3514f05020303f7b40e83a4aBrianGLboolean
141224df8f895fe8807aa2ba058e71bd40adfc01d21eBrianst_finalize_mipmap_tree(GLcontext *ctx,
141324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                        struct pipe_context *pipe, GLuint unit,
141424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                        GLboolean *needFlush)
141524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{
141624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   struct gl_texture_object *tObj = ctx->Texture.Unit[unit]._Current;
141714b98343309fdcff3514f05020303f7b40e83a4aBrian   struct st_texture_object *stObj = st_texture_object(tObj);
141824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   int comp_byte = 0;
141924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   int cpp;
142024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
142124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   GLuint face, i;
142224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   GLuint nr_faces = 0;
142324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   struct st_texture_image *firstImage;
142424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
142524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   *needFlush = GL_FALSE;
142624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
142724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   /* We know/require this is true by now:
142824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian    */
142914b98343309fdcff3514f05020303f7b40e83a4aBrian   assert(stObj->base._Complete);
143024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
143124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   /* What levels must the tree include at a minimum?
143224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian    */
143314b98343309fdcff3514f05020303f7b40e83a4aBrian   calculate_first_last_level(stObj);
143424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   firstImage =
143514b98343309fdcff3514f05020303f7b40e83a4aBrian      st_texture_image(stObj->base.Image[0][stObj->firstLevel]);
143624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
143724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   /* Fallback case:
143824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian    */
143924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   if (firstImage->base.Border) {
144014b98343309fdcff3514f05020303f7b40e83a4aBrian      if (stObj->mt) {
144114b98343309fdcff3514f05020303f7b40e83a4aBrian         st_miptree_release(pipe, &stObj->mt);
144224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      }
144324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      return GL_FALSE;
144424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   }
144524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
144624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
144714b98343309fdcff3514f05020303f7b40e83a4aBrian   /* If both firstImage and stObj have a tree which can contain
144824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian    * all active images, favour firstImage.  Note that because of the
144924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian    * completeness requirement, we know that the image dimensions
145024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian    * will match.
145124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian    */
145224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   if (firstImage->mt &&
145314b98343309fdcff3514f05020303f7b40e83a4aBrian       firstImage->mt != stObj->mt &&
145414b98343309fdcff3514f05020303f7b40e83a4aBrian       firstImage->mt->first_level <= stObj->firstLevel &&
145514b98343309fdcff3514f05020303f7b40e83a4aBrian       firstImage->mt->last_level >= stObj->lastLevel) {
145624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
145714b98343309fdcff3514f05020303f7b40e83a4aBrian      if (stObj->mt)
145814b98343309fdcff3514f05020303f7b40e83a4aBrian         st_miptree_release(pipe, &stObj->mt);
145924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
146014b98343309fdcff3514f05020303f7b40e83a4aBrian      st_miptree_reference(&stObj->mt, firstImage->mt);
146124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   }
146224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
146324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   if (firstImage->base.IsCompressed) {
146414b98343309fdcff3514f05020303f7b40e83a4aBrian      comp_byte = compressed_num_bytes(firstImage->base.TexFormat->MesaFormat);
146524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      cpp = comp_byte;
146624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   }
146724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   else cpp = firstImage->base.TexFormat->TexelBytes;
146824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
146924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   /* Check tree can hold all active levels.  Check tree matches
147024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian    * target, imageFormat, etc.
147124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian    *
147224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian    * XXX: For some layouts (eg i945?), the test might have to be
147324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian    * first_level == firstLevel, as the tree isn't valid except at the
147424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian    * original start level.  Hope to get around this by
147524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian    * programming minLod, maxLod, baseLevel into the hardware and
147624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian    * leaving the tree alone.
147724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian    */
147814b98343309fdcff3514f05020303f7b40e83a4aBrian   if (stObj->mt &&
147914b98343309fdcff3514f05020303f7b40e83a4aBrian       (stObj->mt->target != stObj->base.Target ||
148014b98343309fdcff3514f05020303f7b40e83a4aBrian	stObj->mt->internal_format != firstImage->base.InternalFormat ||
148114b98343309fdcff3514f05020303f7b40e83a4aBrian	stObj->mt->first_level != stObj->firstLevel ||
148214b98343309fdcff3514f05020303f7b40e83a4aBrian	stObj->mt->last_level != stObj->lastLevel ||
148314b98343309fdcff3514f05020303f7b40e83a4aBrian	stObj->mt->width0 != firstImage->base.Width ||
148414b98343309fdcff3514f05020303f7b40e83a4aBrian	stObj->mt->height0 != firstImage->base.Height ||
148514b98343309fdcff3514f05020303f7b40e83a4aBrian	stObj->mt->depth0 != firstImage->base.Depth ||
148614b98343309fdcff3514f05020303f7b40e83a4aBrian	stObj->mt->cpp != cpp ||
148714b98343309fdcff3514f05020303f7b40e83a4aBrian	stObj->mt->compressed != firstImage->base.IsCompressed)) {
148814b98343309fdcff3514f05020303f7b40e83a4aBrian      st_miptree_release(pipe, &stObj->mt);
148924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   }
149024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
149124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
149224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   /* May need to create a new tree:
149324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian    */
149414b98343309fdcff3514f05020303f7b40e83a4aBrian   if (!stObj->mt) {
149514b98343309fdcff3514f05020303f7b40e83a4aBrian      stObj->mt = st_miptree_create(pipe,
1496b245840b86cf877c9b8d666edf229364a84f1deaBrian                                    stObj->base.Target,
1497b245840b86cf877c9b8d666edf229364a84f1deaBrian                                    firstImage->base.InternalFormat,
1498b245840b86cf877c9b8d666edf229364a84f1deaBrian                                    stObj->firstLevel,
1499b245840b86cf877c9b8d666edf229364a84f1deaBrian                                    stObj->lastLevel,
1500b245840b86cf877c9b8d666edf229364a84f1deaBrian                                    firstImage->base.Width,
1501b245840b86cf877c9b8d666edf229364a84f1deaBrian                                    firstImage->base.Height,
1502b245840b86cf877c9b8d666edf229364a84f1deaBrian                                    firstImage->base.Depth,
1503b245840b86cf877c9b8d666edf229364a84f1deaBrian                                    cpp,
1504b245840b86cf877c9b8d666edf229364a84f1deaBrian                                    comp_byte);
1505b245840b86cf877c9b8d666edf229364a84f1deaBrian
1506b245840b86cf877c9b8d666edf229364a84f1deaBrian      stObj->mt->format
15079cf9aa1ea2c3f40a09316975410a4b0e202e82baBrian         = st_mesa_format_to_pipe_format(firstImage->base.TexFormat->MesaFormat);
150824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   }
150924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
151024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   /* Pull in any images not in the object's tree:
151124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian    */
151214b98343309fdcff3514f05020303f7b40e83a4aBrian   nr_faces = (stObj->base.Target == GL_TEXTURE_CUBE_MAP) ? 6 : 1;
151324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   for (face = 0; face < nr_faces; face++) {
151414b98343309fdcff3514f05020303f7b40e83a4aBrian      for (i = stObj->firstLevel; i <= stObj->lastLevel; i++) {
151524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian         struct st_texture_image *stImage =
151614b98343309fdcff3514f05020303f7b40e83a4aBrian            st_texture_image(stObj->base.Image[face][i]);
151724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
151824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian         /* Need to import images in main memory or held in other trees.
151924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian          */
152014b98343309fdcff3514f05020303f7b40e83a4aBrian         if (stObj->mt != stImage->mt) {
152114b98343309fdcff3514f05020303f7b40e83a4aBrian            copy_image_data_to_tree(pipe, stObj, stImage);
152224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian	    *needFlush = GL_TRUE;
152324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian         }
152424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      }
152524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   }
152624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
152724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   /**
152824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   if (need_flush)
152924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      intel_batchbuffer_flush(intel->batch);
153024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   **/
153124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
153224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   return GL_TRUE;
153324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian}
153424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
153524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
153624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#if 0 /* unused? */
153724df8f895fe8807aa2ba058e71bd40adfc01d21eBrianvoid
153824df8f895fe8807aa2ba058e71bd40adfc01d21eBrianst_tex_map_images(struct pipe_context *pipe,
153914b98343309fdcff3514f05020303f7b40e83a4aBrian                  struct st_texture_object *stObj)
154024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{
154114b98343309fdcff3514f05020303f7b40e83a4aBrian   GLuint nr_faces = (stObj->base.Target == GL_TEXTURE_CUBE_MAP) ? 6 : 1;
154224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   GLuint face, i;
154324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
154424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   DBG("%s\n", __FUNCTION__);
154524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
154624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   for (face = 0; face < nr_faces; face++) {
154714b98343309fdcff3514f05020303f7b40e83a4aBrian      for (i = stObj->firstLevel; i <= stObj->lastLevel; i++) {
154824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian         struct st_texture_image *stImage =
154914b98343309fdcff3514f05020303f7b40e83a4aBrian            st_texture_image(stObj->base.Image[face][i]);
155024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
155124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian         if (stImage->mt) {
1552b245840b86cf877c9b8d666edf229364a84f1deaBrian            stImage->base.Data
1553b245840b86cf877c9b8d666edf229364a84f1deaBrian               = st_miptree_image_map(pipe,
1554b245840b86cf877c9b8d666edf229364a84f1deaBrian                                      stImage->mt,
1555b245840b86cf877c9b8d666edf229364a84f1deaBrian                                      stImage->face,
1556b245840b86cf877c9b8d666edf229364a84f1deaBrian                                      stImage->level,
1557b245840b86cf877c9b8d666edf229364a84f1deaBrian                                      &stImage->base.RowStride,
1558b245840b86cf877c9b8d666edf229364a84f1deaBrian                                      stImage->base.ImageOffsets);
155924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian            /* convert stride to texels, not bytes */
156024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian            stImage->base.RowStride /= stImage->mt->cpp;
156124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian/*             stImage->base.ImageStride /= stImage->mt->cpp; */
156224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian         }
156324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      }
156424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   }
156524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian}
156624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
156724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
156824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
156924df8f895fe8807aa2ba058e71bd40adfc01d21eBrianvoid
157024df8f895fe8807aa2ba058e71bd40adfc01d21eBrianst_tex_unmap_images(struct pipe_context *pipe,
157114b98343309fdcff3514f05020303f7b40e83a4aBrian                    struct st_texture_object *stObj)
157224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{
157314b98343309fdcff3514f05020303f7b40e83a4aBrian   GLuint nr_faces = (stObj->base.Target == GL_TEXTURE_CUBE_MAP) ? 6 : 1;
157424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   GLuint face, i;
157524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
157624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   for (face = 0; face < nr_faces; face++) {
157714b98343309fdcff3514f05020303f7b40e83a4aBrian      for (i = stObj->firstLevel; i <= stObj->lastLevel; i++) {
157824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian         struct st_texture_image *stImage =
157914b98343309fdcff3514f05020303f7b40e83a4aBrian            st_texture_image(stObj->base.Image[face][i]);
158024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
158124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian         if (stImage->mt) {
158224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian            st_miptree_image_unmap(pipe, stImage->mt);
158324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian            stImage->base.Data = NULL;
158424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian         }
158524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      }
158624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   }
158724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian}
158824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#endif
158924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
159024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
159124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
159224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
15936da9234fd437f97267e7831f034c78b31156d939Brianvoid
15946da9234fd437f97267e7831f034c78b31156d939Brianst_init_texture_functions(struct dd_function_table *functions)
159524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{
159624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   functions->ChooseTextureFormat = st_ChooseTextureFormat;
159724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   functions->TexImage1D = st_TexImage1D;
159824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   functions->TexImage2D = st_TexImage2D;
159924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   functions->TexImage3D = st_TexImage3D;
160024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   functions->TexSubImage1D = st_TexSubImage1D;
160124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   functions->TexSubImage2D = st_TexSubImage2D;
160224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   functions->TexSubImage3D = st_TexSubImage3D;
160324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   functions->CopyTexImage1D = st_CopyTexImage1D;
160424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   functions->CopyTexImage2D = st_CopyTexImage2D;
160524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   functions->CopyTexSubImage1D = st_CopyTexSubImage1D;
160624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   functions->CopyTexSubImage2D = st_CopyTexSubImage2D;
160724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   functions->GetTexImage = st_GetTexImage;
160824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
160924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   /* compressed texture functions */
161024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   functions->CompressedTexImage2D = st_CompressedTexImage2D;
161124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   functions->GetCompressedTexImage = st_GetCompressedTexImage;
161224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
161324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   functions->NewTextureObject = st_NewTextureObject;
161424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   functions->NewTextureImage = st_NewTextureImage;
161524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   functions->DeleteTexture = st_DeleteTextureObject;
161624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   functions->FreeTexImageData = st_FreeTextureImageData;
161724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   functions->UpdateTexturePalette = 0;
161824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   functions->IsTextureResident = st_IsTextureResident;
161924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
162024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   functions->TextureMemCpy = do_memcpy;
162124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian}
1622