st_cb_texture.c revision 28b315dc1aed36bebadfacbd55e481e7baacfcb5
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"
40b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian#include "state_tracker/st_cb_fbo.h"
4124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#include "state_tracker/st_cb_texture.h"
42f8ab24760d0d3f07e9ee81c98207ddf92dfe74daBrian#include "state_tracker/st_format.h"
4324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#include "state_tracker/st_mipmap_tree.h"
4424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
4524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#include "pipe/p_context.h"
46b245840b86cf877c9b8d666edf229364a84f1deaBrian#include "pipe/p_defines.h"
4724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
4824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
4924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#define DBG if (0) printf
5024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
5124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
5224df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstruct st_texture_object
5324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{
5424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   struct gl_texture_object base;       /* The "parent" object */
5524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
5624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   /* The mipmap tree must include at least these levels once
5724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian    * validated:
5824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian    */
5924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   GLuint firstLevel;
6024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   GLuint lastLevel;
6124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
6224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   /* Offset for firstLevel image:
6324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian    */
6424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   GLuint textureOffset;
6524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
6624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   /* On validation any active images held in main memory or in other
6724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian    * regions will be copied to this region and the old storage freed.
6824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian    */
6924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   struct pipe_mipmap_tree *mt;
7024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
7124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   GLboolean imageOverride;
7224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   GLint depthOverride;
7324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   GLuint pitchOverride;
7424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian};
7524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
7624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
7724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
7824df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstruct st_texture_image
7924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{
8024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   struct gl_texture_image base;
8124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
8224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   /* These aren't stored in gl_texture_image
8324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian    */
8424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   GLuint level;
8524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   GLuint face;
8624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
8724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   /* If stImage->mt != NULL, image data is stored here.
8824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian    * Else if stImage->base.Data != NULL, image is stored there.
8924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian    * Else there is no image data.
9024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian    */
9124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   struct pipe_mipmap_tree *mt;
9224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian};
9324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
9424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
9524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
9624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
9724df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic INLINE struct st_texture_object *
9824df8f895fe8807aa2ba058e71bd40adfc01d21eBrianst_texture_object(struct gl_texture_object *obj)
9924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{
10024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   return (struct st_texture_object *) obj;
10124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian}
10224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
10324df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic INLINE struct st_texture_image *
10424df8f895fe8807aa2ba058e71bd40adfc01d21eBrianst_texture_image(struct gl_texture_image *img)
10524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{
10624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   return (struct st_texture_image *) img;
10724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian}
10824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
10924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
110d78dab126724e6e9d475289a086fb6f85adc3985Brianstruct pipe_mipmap_tree *
111d78dab126724e6e9d475289a086fb6f85adc3985Brianst_get_texobj_mipmap_tree(struct gl_texture_object *texObj)
112d78dab126724e6e9d475289a086fb6f85adc3985Brian{
113d78dab126724e6e9d475289a086fb6f85adc3985Brian   struct st_texture_object *stObj = st_texture_object(texObj);
114d78dab126724e6e9d475289a086fb6f85adc3985Brian   return stObj->mt;
115d78dab126724e6e9d475289a086fb6f85adc3985Brian}
116d78dab126724e6e9d475289a086fb6f85adc3985Brian
117d78dab126724e6e9d475289a086fb6f85adc3985Brian
1185390a43ce06b27f6d54bc5f237aa305b6948f2afBrianstatic unsigned
1195390a43ce06b27f6d54bc5f237aa305b6948f2afBriangl_target_to_pipe(GLenum target)
1205390a43ce06b27f6d54bc5f237aa305b6948f2afBrian{
1215390a43ce06b27f6d54bc5f237aa305b6948f2afBrian   switch (target) {
1225390a43ce06b27f6d54bc5f237aa305b6948f2afBrian   case GL_TEXTURE_1D:
1235390a43ce06b27f6d54bc5f237aa305b6948f2afBrian      return PIPE_TEXTURE_1D;
1245390a43ce06b27f6d54bc5f237aa305b6948f2afBrian
1255390a43ce06b27f6d54bc5f237aa305b6948f2afBrian   case GL_TEXTURE_2D:
1265390a43ce06b27f6d54bc5f237aa305b6948f2afBrian   case GL_TEXTURE_RECTANGLE_NV:
1275390a43ce06b27f6d54bc5f237aa305b6948f2afBrian      return PIPE_TEXTURE_2D;
1285390a43ce06b27f6d54bc5f237aa305b6948f2afBrian
1295390a43ce06b27f6d54bc5f237aa305b6948f2afBrian   case GL_TEXTURE_3D:
1305390a43ce06b27f6d54bc5f237aa305b6948f2afBrian      return PIPE_TEXTURE_3D;
1315390a43ce06b27f6d54bc5f237aa305b6948f2afBrian
1325390a43ce06b27f6d54bc5f237aa305b6948f2afBrian   case GL_TEXTURE_CUBE_MAP_ARB:
1335390a43ce06b27f6d54bc5f237aa305b6948f2afBrian      return PIPE_TEXTURE_CUBE;
1345390a43ce06b27f6d54bc5f237aa305b6948f2afBrian
1355390a43ce06b27f6d54bc5f237aa305b6948f2afBrian   default:
1365390a43ce06b27f6d54bc5f237aa305b6948f2afBrian      assert(0);
1375390a43ce06b27f6d54bc5f237aa305b6948f2afBrian      return 0;
1385390a43ce06b27f6d54bc5f237aa305b6948f2afBrian   }
1395390a43ce06b27f6d54bc5f237aa305b6948f2afBrian}
1405390a43ce06b27f6d54bc5f237aa305b6948f2afBrian
1415390a43ce06b27f6d54bc5f237aa305b6948f2afBrian
14224df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic int
14314b98343309fdcff3514f05020303f7b40e83a4aBriancompressed_num_bytes(GLuint mesaFormat)
14424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{
14524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   int bytes = 0;
14624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   switch(mesaFormat) {
14724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
14824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   case MESA_FORMAT_RGB_FXT1:
14924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   case MESA_FORMAT_RGBA_FXT1:
15024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   case MESA_FORMAT_RGB_DXT1:
15124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   case MESA_FORMAT_RGBA_DXT1:
15224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian     bytes = 2;
15324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian     break;
15424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
15524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   case MESA_FORMAT_RGBA_DXT3:
15624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   case MESA_FORMAT_RGBA_DXT5:
15724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian     bytes = 4;
15824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   default:
15924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian     break;
16024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   }
16124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
16224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   return bytes;
16324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian}
16424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
16524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
16624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
16724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
16824df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic GLboolean
16924df8f895fe8807aa2ba058e71bd40adfc01d21eBrianst_IsTextureResident(GLcontext * ctx, struct gl_texture_object *texObj)
17024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{
17124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#if 0
17224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   struct intel_context *intel = intel_context(ctx);
17324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   struct st_texture_object *stObj = st_texture_object(texObj);
17424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
17524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   return
17624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      stObj->mt &&
17724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      stObj->mt->region &&
17824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      intel_is_region_resident(intel, stObj->mt->region);
17924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#endif
18024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   return 1;
18124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian}
18224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
18324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
18424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
18524df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic struct gl_texture_image *
18624df8f895fe8807aa2ba058e71bd40adfc01d21eBrianst_NewTextureImage(GLcontext * ctx)
18724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{
18824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   DBG("%s\n", __FUNCTION__);
18924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   (void) ctx;
19024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   return (struct gl_texture_image *) CALLOC_STRUCT(st_texture_image);
19124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian}
19224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
19324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
19424df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic struct gl_texture_object *
19524df8f895fe8807aa2ba058e71bd40adfc01d21eBrianst_NewTextureObject(GLcontext * ctx, GLuint name, GLenum target)
19624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{
19724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   struct st_texture_object *obj = CALLOC_STRUCT(st_texture_object);
19824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
19924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   DBG("%s\n", __FUNCTION__);
20024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   _mesa_initialize_texture_object(&obj->base, name, target);
20124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
20224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   return &obj->base;
20324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian}
20424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
20524df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void
20624df8f895fe8807aa2ba058e71bd40adfc01d21eBrianst_DeleteTextureObject(GLcontext *ctx,
20724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian			 struct gl_texture_object *texObj)
20824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{
20924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   struct pipe_context *pipe = ctx->st->pipe;
21024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   struct st_texture_object *stObj = st_texture_object(texObj);
21124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
21224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   if (stObj->mt)
21324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      st_miptree_release(pipe, &stObj->mt);
21424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
21524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   _mesa_delete_texture_object(ctx, texObj);
21624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian}
21724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
21824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
21924df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void
22024df8f895fe8807aa2ba058e71bd40adfc01d21eBrianst_FreeTextureImageData(GLcontext * ctx, struct gl_texture_image *texImage)
22124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{
22224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   struct pipe_context *pipe = ctx->st->pipe;
22324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   struct st_texture_image *stImage = st_texture_image(texImage);
22424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
22524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   DBG("%s\n", __FUNCTION__);
22624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
22724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   if (stImage->mt) {
22824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      st_miptree_release(pipe, &stImage->mt);
22924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   }
23024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
23124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   if (texImage->Data) {
23224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      free(texImage->Data);
23324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      texImage->Data = NULL;
23424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   }
23524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian}
23624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
23724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
23824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
23924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
24024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian/* ================================================================
24124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * From linux kernel i386 header files, copes with odd sizes better
24224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * than COPY_DWORDS would:
24324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * XXX Put this in src/mesa/main/imports.h ???
24424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */
24524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#if defined(i386) || defined(__i386__)
24624df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic INLINE void *
24724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian__memcpy(void *to, const void *from, size_t n)
24824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{
24924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   int d0, d1, d2;
25024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   __asm__ __volatile__("rep ; movsl\n\t"
25124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                        "testb $2,%b4\n\t"
25224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                        "je 1f\n\t"
25324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                        "movsw\n"
25424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                        "1:\ttestb $1,%b4\n\t"
25524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                        "je 2f\n\t"
25624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                        "movsb\n" "2:":"=&c"(d0), "=&D"(d1), "=&S"(d2)
25724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                        :"0"(n / 4), "q"(n), "1"((long) to), "2"((long) from)
25824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                        :"memory");
25924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   return (to);
26024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian}
26124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#else
26224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#define __memcpy(a,b,c) memcpy(a,b,c)
26324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#endif
26424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
26524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
26624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian/* The system memcpy (at least on ubuntu 5.10) has problems copying
26724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * to agp (writecombined) memory from a source which isn't 64-byte
26824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * aligned - there is a 4x performance falloff.
26924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian *
27024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * The x86 __memcpy is immune to this but is slightly slower
27124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * (10%-ish) than the system memcpy.
27224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian *
27324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * The sse_memcpy seems to have a slight cliff at 64/32 bytes, but
27424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * isn't much faster than x86_memcpy for agp copies.
27524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian *
27624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * TODO: switch dynamically.
27724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */
27824df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void *
27924df8f895fe8807aa2ba058e71bd40adfc01d21eBriando_memcpy(void *dest, const void *src, size_t n)
28024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{
28124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   if ((((unsigned) src) & 63) || (((unsigned) dest) & 63)) {
28224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      return __memcpy(dest, src, n);
28324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   }
28424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   else
28524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      return memcpy(dest, src, n);
28624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian}
28724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
28824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
28924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian/* Functions to store texture images.  Where possible, mipmap_tree's
29024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * will be created or further instantiated with image data, otherwise
29124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * images will be stored in malloc'd memory.  A validation step is
29224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * required to pull those images into a mipmap tree, or otherwise
29324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * decide a fallback is required.
29424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */
29524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
29624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
29724df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic int
29824df8f895fe8807aa2ba058e71bd40adfc01d21eBrianlogbase2(int n)
29924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{
30024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   GLint i = 1;
30124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   GLint log2 = 0;
30224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
30324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   while (n > i) {
30424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      i *= 2;
30524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      log2++;
30624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   }
30724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
30824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   return log2;
30924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian}
31024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
31124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
31224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian/* Otherwise, store it in memory if (Border != 0) or (any dimension ==
31324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * 1).
31424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian *
31524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * Otherwise, if max_level >= level >= min_level, create tree with
31624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * space for textures from min_level down to max_level.
31724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian *
31824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * Otherwise, create tree with space for textures from (level
31924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * 0)..(1x1).  Consider pruning this tree at a validation if the
32024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * saving is worth it.
32124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */
32224df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void
32324df8f895fe8807aa2ba058e71bd40adfc01d21eBrianguess_and_alloc_mipmap_tree(struct pipe_context *pipe,
32414b98343309fdcff3514f05020303f7b40e83a4aBrian                            struct st_texture_object *stObj,
32514b98343309fdcff3514f05020303f7b40e83a4aBrian                            struct st_texture_image *stImage)
32624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{
32724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   GLuint firstLevel;
32824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   GLuint lastLevel;
32914b98343309fdcff3514f05020303f7b40e83a4aBrian   GLuint width = stImage->base.Width;
33014b98343309fdcff3514f05020303f7b40e83a4aBrian   GLuint height = stImage->base.Height;
33114b98343309fdcff3514f05020303f7b40e83a4aBrian   GLuint depth = stImage->base.Depth;
33224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   GLuint l2width, l2height, l2depth;
33324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   GLuint i, comp_byte = 0;
33424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
33524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   DBG("%s\n", __FUNCTION__);
33624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
33714b98343309fdcff3514f05020303f7b40e83a4aBrian   if (stImage->base.Border)
33824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      return;
33924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
34014b98343309fdcff3514f05020303f7b40e83a4aBrian   if (stImage->level > stObj->base.BaseLevel &&
34114b98343309fdcff3514f05020303f7b40e83a4aBrian       (stImage->base.Width == 1 ||
34214b98343309fdcff3514f05020303f7b40e83a4aBrian        (stObj->base.Target != GL_TEXTURE_1D &&
34314b98343309fdcff3514f05020303f7b40e83a4aBrian         stImage->base.Height == 1) ||
34414b98343309fdcff3514f05020303f7b40e83a4aBrian        (stObj->base.Target == GL_TEXTURE_3D &&
34514b98343309fdcff3514f05020303f7b40e83a4aBrian         stImage->base.Depth == 1)))
34624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      return;
34724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
34824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   /* If this image disrespects BaseLevel, allocate from level zero.
34924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian    * Usually BaseLevel == 0, so it's unlikely to happen.
35024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian    */
35114b98343309fdcff3514f05020303f7b40e83a4aBrian   if (stImage->level < stObj->base.BaseLevel)
35224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      firstLevel = 0;
35324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   else
35414b98343309fdcff3514f05020303f7b40e83a4aBrian      firstLevel = stObj->base.BaseLevel;
35524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
35624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
35724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   /* Figure out image dimensions at start level.
35824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian    */
35914b98343309fdcff3514f05020303f7b40e83a4aBrian   for (i = stImage->level; i > firstLevel; i--) {
36024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      width <<= 1;
36124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      if (height != 1)
36224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian         height <<= 1;
36324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      if (depth != 1)
36424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian         depth <<= 1;
36524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   }
36624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
36724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   /* Guess a reasonable value for lastLevel.  This is probably going
36824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian    * to be wrong fairly often and might mean that we have to look at
36924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian    * resizable buffers, or require that buffers implement lazy
37024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian    * pagetable arrangements.
37124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian    */
37214b98343309fdcff3514f05020303f7b40e83a4aBrian   if ((stObj->base.MinFilter == GL_NEAREST ||
37314b98343309fdcff3514f05020303f7b40e83a4aBrian        stObj->base.MinFilter == GL_LINEAR) &&
37414b98343309fdcff3514f05020303f7b40e83a4aBrian       stImage->level == firstLevel) {
37524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      lastLevel = firstLevel;
37624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   }
37724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   else {
37824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      l2width = logbase2(width);
37924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      l2height = logbase2(height);
38024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      l2depth = logbase2(depth);
38124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      lastLevel = firstLevel + MAX2(MAX2(l2width, l2height), l2depth);
38224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   }
38324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
38414b98343309fdcff3514f05020303f7b40e83a4aBrian   assert(!stObj->mt);
38514b98343309fdcff3514f05020303f7b40e83a4aBrian   if (stImage->base.IsCompressed)
38614b98343309fdcff3514f05020303f7b40e83a4aBrian      comp_byte = compressed_num_bytes(stImage->base.TexFormat->MesaFormat);
38714b98343309fdcff3514f05020303f7b40e83a4aBrian   stObj->mt = st_miptree_create(pipe,
3885390a43ce06b27f6d54bc5f237aa305b6948f2afBrian                                 gl_target_to_pipe(stObj->base.Target),
3895390a43ce06b27f6d54bc5f237aa305b6948f2afBrian                                 stImage->base.InternalFormat,
3905390a43ce06b27f6d54bc5f237aa305b6948f2afBrian                                 firstLevel,
3915390a43ce06b27f6d54bc5f237aa305b6948f2afBrian                                 lastLevel,
3925390a43ce06b27f6d54bc5f237aa305b6948f2afBrian                                 width,
3935390a43ce06b27f6d54bc5f237aa305b6948f2afBrian                                 height,
3945390a43ce06b27f6d54bc5f237aa305b6948f2afBrian                                 depth,
3955390a43ce06b27f6d54bc5f237aa305b6948f2afBrian                                 stImage->base.TexFormat->TexelBytes,
3965390a43ce06b27f6d54bc5f237aa305b6948f2afBrian                                 comp_byte);
39724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
398b245840b86cf877c9b8d666edf229364a84f1deaBrian   stObj->mt->format
3999cf9aa1ea2c3f40a09316975410a4b0e202e82baBrian      = st_mesa_format_to_pipe_format(stImage->base.TexFormat->MesaFormat);
400b245840b86cf877c9b8d666edf229364a84f1deaBrian
40124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   DBG("%s - success\n", __FUNCTION__);
40224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian}
40324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
40424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
40524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
40624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
40724df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic GLuint
40824df8f895fe8807aa2ba058e71bd40adfc01d21eBriantarget_to_face(GLenum target)
40924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{
41024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   switch (target) {
41124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB:
41224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB:
41324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB:
41424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB:
41524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB:
41624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB:
41724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      return ((GLuint) target - (GLuint) GL_TEXTURE_CUBE_MAP_POSITIVE_X);
41824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   default:
41924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      return 0;
42024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   }
42124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian}
42224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
42324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
42424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
42524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian/* There are actually quite a few combinations this will work for,
42624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * more than what I've listed here.
42724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */
42824df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic GLboolean
42924df8f895fe8807aa2ba058e71bd40adfc01d21eBriancheck_pbo_format(GLint internalFormat,
43024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                 GLenum format, GLenum type,
43124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                 const struct gl_texture_format *mesa_format)
43224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{
43324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   switch (internalFormat) {
43424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   case 4:
43524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   case GL_RGBA:
43624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      return (format == GL_BGRA &&
43724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian              (type == GL_UNSIGNED_BYTE ||
43824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian               type == GL_UNSIGNED_INT_8_8_8_8_REV) &&
43924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian              mesa_format == &_mesa_texformat_argb8888);
44024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   case 3:
44124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   case GL_RGB:
44224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      return (format == GL_RGB &&
44324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian              type == GL_UNSIGNED_SHORT_5_6_5 &&
44424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian              mesa_format == &_mesa_texformat_rgb565);
44524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   case GL_YCBCR_MESA:
44624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      return (type == GL_UNSIGNED_SHORT_8_8_MESA || type == GL_UNSIGNED_BYTE);
44724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   default:
44824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      return GL_FALSE;
44924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   }
45024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian}
45124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
45224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
45324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian/* XXX: Do this for TexSubImage also:
45424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */
45524df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic GLboolean
45624df8f895fe8807aa2ba058e71bd40adfc01d21eBriantry_pbo_upload(GLcontext *ctx,
45714b98343309fdcff3514f05020303f7b40e83a4aBrian               struct st_texture_image *stImage,
45824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian               const struct gl_pixelstore_attrib *unpack,
45924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian               GLint internalFormat,
46024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian               GLint width, GLint height,
46124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian               GLenum format, GLenum type, const void *pixels)
46224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{
46324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   return GL_FALSE;  /* XXX fix flushing/locking/blitting below */
46424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#if 000
46524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   struct intel_context *intel = intel_context(ctx);
46624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   struct intel_buffer_object *pbo = intel_buffer_object(unpack->BufferObj);
46724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   GLuint src_offset, src_stride;
46824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   GLuint dst_offset, dst_stride;
46924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
47024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   if (!pbo ||
47124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian       ctx._ImageTransferState ||
47224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian       unpack->SkipPixels || unpack->SkipRows) {
47324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      _mesa_printf("%s: failure 1\n", __FUNCTION__);
47424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      return GL_FALSE;
47524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   }
47624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
47724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   src_offset = (GLuint) pixels;
47824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
47924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   if (unpack->RowLength > 0)
48024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      src_stride = unpack->RowLength;
48124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   else
48224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      src_stride = width;
48324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
48414b98343309fdcff3514f05020303f7b40e83a4aBrian   dst_offset = st_miptree_image_offset(stImage->mt,
48514b98343309fdcff3514f05020303f7b40e83a4aBrian                                           stImage->face,
48614b98343309fdcff3514f05020303f7b40e83a4aBrian                                           stImage->level);
48724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
48814b98343309fdcff3514f05020303f7b40e83a4aBrian   dst_stride = stImage->mt->pitch;
48924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
49024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   {
49124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      struct _DriBufferObject *src_buffer =
49224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian         intel_bufferobj_buffer(intel, pbo, INTEL_READ);
49324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
49424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      /* Temporary hack: cast to _DriBufferObject:
49524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian       */
49624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      struct _DriBufferObject *dst_buffer =
49714b98343309fdcff3514f05020303f7b40e83a4aBrian         (struct _DriBufferObject *)stImage->mt->region->buffer;
49824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
49924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
50024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      intelEmitCopyBlit(intel,
50114b98343309fdcff3514f05020303f7b40e83a4aBrian                        stImage->mt->cpp,
50224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                        src_stride, src_buffer, src_offset,
50324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                        dst_stride, dst_buffer, dst_offset,
50424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                        0, 0, 0, 0, width, height,
50524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian			GL_COPY);
50624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   }
50724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
50824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   return GL_TRUE;
50924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#endif
51024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian}
51124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
51224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
51324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
51424df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic GLboolean
51524df8f895fe8807aa2ba058e71bd40adfc01d21eBriantry_pbo_zcopy(GLcontext *ctx,
51614b98343309fdcff3514f05020303f7b40e83a4aBrian              struct st_texture_image *stImage,
51724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian              const struct gl_pixelstore_attrib *unpack,
51824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian              GLint internalFormat,
51924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian              GLint width, GLint height,
52024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian              GLenum format, GLenum type, const void *pixels)
52124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{
52224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   return GL_FALSE;
52324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian}
52424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
52524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
52624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
52724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
52824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
52924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
53024df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void
53124df8f895fe8807aa2ba058e71bd40adfc01d21eBrianst_TexImage(GLcontext * ctx,
53224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian              GLint dims,
53324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian              GLenum target, GLint level,
53424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian              GLint internalFormat,
53524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian              GLint width, GLint height, GLint depth,
53624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian              GLint border,
53724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian              GLenum format, GLenum type, const void *pixels,
53824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian              const struct gl_pixelstore_attrib *unpack,
53924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian              struct gl_texture_object *texObj,
54024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian              struct gl_texture_image *texImage, GLsizei imageSize, int compressed)
54124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{
54224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   struct pipe_context *pipe = ctx->st->pipe;
54314b98343309fdcff3514f05020303f7b40e83a4aBrian   struct st_texture_object *stObj = st_texture_object(texObj);
54414b98343309fdcff3514f05020303f7b40e83a4aBrian   struct st_texture_image *stImage = st_texture_image(texImage);
54524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   GLint postConvWidth = width;
54624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   GLint postConvHeight = height;
54724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   GLint texelBytes, sizeInBytes;
54824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   GLuint dstRowStride;
54924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
55024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
55124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   DBG("%s target %s level %d %dx%dx%d border %d\n", __FUNCTION__,
55224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian       _mesa_lookup_enum_by_nr(target), level, width, height, depth, border);
55324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
55414b98343309fdcff3514f05020303f7b40e83a4aBrian   stImage->face = target_to_face(target);
55514b98343309fdcff3514f05020303f7b40e83a4aBrian   stImage->level = level;
55624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
55724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   if (ctx->_ImageTransferState & IMAGE_CONVOLUTION_BIT) {
55824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      _mesa_adjust_image_for_convolution(ctx, dims, &postConvWidth,
55924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                                         &postConvHeight);
56024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   }
56124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
56224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   /* choose the texture format */
56324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   texImage->TexFormat = st_ChooseTextureFormat(ctx, internalFormat,
56424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                                                  format, type);
56524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
56624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   _mesa_set_fetch_functions(texImage, dims);
56724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
56824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   if (texImage->TexFormat->TexelBytes == 0) {
56924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      /* must be a compressed format */
57024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      texelBytes = 0;
57124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      texImage->IsCompressed = GL_TRUE;
57224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      texImage->CompressedSize =
57324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian	 ctx->Driver.CompressedTextureSize(ctx, texImage->Width,
57424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian					   texImage->Height, texImage->Depth,
57524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian					   texImage->TexFormat->MesaFormat);
57624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   } else {
57724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      texelBytes = texImage->TexFormat->TexelBytes;
57824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
57924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      /* Minimum pitch of 32 bytes */
58024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      if (postConvWidth * texelBytes < 32) {
58124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian	 postConvWidth = 32 / texelBytes;
58224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian	 texImage->RowStride = postConvWidth;
58324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      }
58424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
58524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      assert(texImage->RowStride == postConvWidth);
58624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   }
58724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
58824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   /* Release the reference to a potentially orphaned buffer.
58924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian    * Release any old malloced memory.
59024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian    */
59114b98343309fdcff3514f05020303f7b40e83a4aBrian   if (stImage->mt) {
59214b98343309fdcff3514f05020303f7b40e83a4aBrian      st_miptree_release(pipe, &stImage->mt);
59324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      assert(!texImage->Data);
59424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   }
59524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   else if (texImage->Data) {
59624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      _mesa_align_free(texImage->Data);
59724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   }
59824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
59924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   /* If this is the only texture image in the tree, could call
60024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian    * bmBufferData with NULL data to free the old block and avoid
60124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian    * waiting on any outstanding fences.
60224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian    */
60314b98343309fdcff3514f05020303f7b40e83a4aBrian   if (stObj->mt &&
60414b98343309fdcff3514f05020303f7b40e83a4aBrian       stObj->mt->first_level == level &&
60514b98343309fdcff3514f05020303f7b40e83a4aBrian       stObj->mt->last_level == level &&
6065390a43ce06b27f6d54bc5f237aa305b6948f2afBrian       stObj->mt->target != PIPE_TEXTURE_CUBE &&
60714b98343309fdcff3514f05020303f7b40e83a4aBrian       !st_miptree_match_image(stObj->mt, &stImage->base,
60814b98343309fdcff3514f05020303f7b40e83a4aBrian                                  stImage->face, stImage->level)) {
60924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
61024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      DBG("release it\n");
61114b98343309fdcff3514f05020303f7b40e83a4aBrian      st_miptree_release(pipe, &stObj->mt);
61214b98343309fdcff3514f05020303f7b40e83a4aBrian      assert(!stObj->mt);
61324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   }
61424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
61514b98343309fdcff3514f05020303f7b40e83a4aBrian   if (!stObj->mt) {
61614b98343309fdcff3514f05020303f7b40e83a4aBrian      guess_and_alloc_mipmap_tree(pipe, stObj, stImage);
61714b98343309fdcff3514f05020303f7b40e83a4aBrian      if (!stObj->mt) {
61824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian	 DBG("guess_and_alloc_mipmap_tree: failed\n");
61924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      }
62024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   }
62124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
62214b98343309fdcff3514f05020303f7b40e83a4aBrian   assert(!stImage->mt);
62324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
62414b98343309fdcff3514f05020303f7b40e83a4aBrian   if (stObj->mt &&
62514b98343309fdcff3514f05020303f7b40e83a4aBrian       st_miptree_match_image(stObj->mt, &stImage->base,
62614b98343309fdcff3514f05020303f7b40e83a4aBrian                                 stImage->face, stImage->level)) {
62724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
62814b98343309fdcff3514f05020303f7b40e83a4aBrian      st_miptree_reference(&stImage->mt, stObj->mt);
62914b98343309fdcff3514f05020303f7b40e83a4aBrian      assert(stImage->mt);
63024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   }
63124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
63214b98343309fdcff3514f05020303f7b40e83a4aBrian   if (!stImage->mt)
63324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      DBG("XXX: Image did not fit into tree - storing in local memory!\n");
63424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
63524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#if 0 /* XXX FIX when st_buffer_objects are in place */
63624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   /* PBO fastpaths:
63724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian    */
63824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   if (dims <= 2 &&
63914b98343309fdcff3514f05020303f7b40e83a4aBrian       stImage->mt &&
64024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian       intel_buffer_object(unpack->BufferObj) &&
64124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian       check_pbo_format(internalFormat, format,
64214b98343309fdcff3514f05020303f7b40e83a4aBrian                        type, stImage->base.TexFormat)) {
64324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
64424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      DBG("trying pbo upload\n");
64524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
64624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      /* Attempt to texture directly from PBO data (zero copy upload).
64724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian       *
64824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian       * Currently disable as it can lead to worse as well as better
64924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian       * performance (in particular when pipe_region_cow() is
65024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian       * required).
65124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian       */
65214b98343309fdcff3514f05020303f7b40e83a4aBrian      if (stObj->mt == stImage->mt &&
65314b98343309fdcff3514f05020303f7b40e83a4aBrian          stObj->mt->first_level == level &&
65414b98343309fdcff3514f05020303f7b40e83a4aBrian          stObj->mt->last_level == level) {
65524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
65614b98343309fdcff3514f05020303f7b40e83a4aBrian         if (try_pbo_zcopy(intel, stImage, unpack,
65724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                           internalFormat,
65824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                           width, height, format, type, pixels)) {
65924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
66024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian            DBG("pbo zcopy upload succeeded\n");
66124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian            return;
66224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian         }
66324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      }
66424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
66524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
66624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      /* Otherwise, attempt to use the blitter for PBO image uploads.
66724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian       */
66814b98343309fdcff3514f05020303f7b40e83a4aBrian      if (try_pbo_upload(intel, stImage, unpack,
66924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                         internalFormat,
67024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                         width, height, format, type, pixels)) {
67124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian         DBG("pbo upload succeeded\n");
67224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian         return;
67324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      }
67424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
67524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      DBG("pbo upload failed\n");
67624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   }
67724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#else
67824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   (void) try_pbo_upload;
67924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   (void) check_pbo_format;
68024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   (void) try_pbo_zcopy;
68124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#endif
68224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
68324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
68424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   /* intelCopyTexImage calls this function with pixels == NULL, with
68524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian    * the expectation that the mipmap tree will be set up but nothing
68624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian    * more will be done.  This is where those calls return:
68724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian    */
68824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   if (compressed) {
68924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      pixels = _mesa_validate_pbo_compressed_teximage(ctx, imageSize, pixels,
69024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian						      unpack,
69124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian						      "glCompressedTexImage");
69224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   } else {
69324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      pixels = _mesa_validate_pbo_teximage(ctx, dims, width, height, 1,
69424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian					   format, type,
69524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian					   pixels, unpack, "glTexImage");
69624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   }
69724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   if (!pixels)
69824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      return;
69924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
70014b98343309fdcff3514f05020303f7b40e83a4aBrian   if (stImage->mt) {
70124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      texImage->Data = st_miptree_image_map(pipe,
70214b98343309fdcff3514f05020303f7b40e83a4aBrian                                               stImage->mt,
70314b98343309fdcff3514f05020303f7b40e83a4aBrian                                               stImage->face,
70414b98343309fdcff3514f05020303f7b40e83a4aBrian                                               stImage->level,
70524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                                               &dstRowStride,
70614b98343309fdcff3514f05020303f7b40e83a4aBrian                                               stImage->base.ImageOffsets);
70724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   }
70824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   else {
70924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      /* Allocate regular memory and store the image there temporarily.   */
71024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      if (texImage->IsCompressed) {
71124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian         sizeInBytes = texImage->CompressedSize;
71224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian         dstRowStride =
71324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian            _mesa_compressed_row_stride(texImage->TexFormat->MesaFormat, width);
71424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian         assert(dims != 3);
71524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      }
71624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      else {
71724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian         dstRowStride = postConvWidth * texelBytes;
71824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian         sizeInBytes = depth * dstRowStride * postConvHeight;
71924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      }
72024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
72124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      texImage->Data = malloc(sizeInBytes);
72224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   }
72324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
72424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   DBG("Upload image %dx%dx%d row_len %x pitch %x\n",
72524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian       width, height, depth, width * texelBytes, dstRowStride);
72624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
72724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   /* Copy data.  Would like to know when it's ok for us to eg. use
72824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian    * the blitter to copy.  Or, use the hardware to do the format
72924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian    * conversion and copy:
73024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian    */
73124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   if (compressed) {
73224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian     memcpy(texImage->Data, pixels, imageSize);
73324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   }
73424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   else if (!texImage->TexFormat->StoreImage(ctx, dims,
73524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                                             texImage->_BaseFormat,
73624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                                             texImage->TexFormat,
73724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                                             texImage->Data,
73824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                                             0, 0, 0, /* dstX/Y/Zoffset */
73924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                                             dstRowStride,
74024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                                             texImage->ImageOffsets,
74124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                                             width, height, depth,
74224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                                             format, type, pixels, unpack)) {
74324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage");
74424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   }
74524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
74624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   _mesa_unmap_teximage_pbo(ctx, unpack);
74724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
74814b98343309fdcff3514f05020303f7b40e83a4aBrian   if (stImage->mt) {
74914b98343309fdcff3514f05020303f7b40e83a4aBrian      st_miptree_image_unmap(pipe, stImage->mt);
75024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      texImage->Data = NULL;
75124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   }
75224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
75324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#if 0
75424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   /* GL_SGIS_generate_mipmap -- this can be accelerated now.
75524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian    */
75624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
75724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      intel_generate_mipmap(ctx, target,
75824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                            &ctx->Texture.Unit[ctx->Texture.CurrentUnit],
75924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                            texObj);
76024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   }
76124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#endif
76224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian}
76324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
76424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
76524df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void
76624df8f895fe8807aa2ba058e71bd40adfc01d21eBrianst_TexImage3D(GLcontext * ctx,
76724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                GLenum target, GLint level,
76824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                GLint internalFormat,
76924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                GLint width, GLint height, GLint depth,
77024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                GLint border,
77124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                GLenum format, GLenum type, const void *pixels,
77224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                const struct gl_pixelstore_attrib *unpack,
77324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                struct gl_texture_object *texObj,
77424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                struct gl_texture_image *texImage)
77524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{
77624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   st_TexImage(ctx, 3, target, level,
77724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                 internalFormat, width, height, depth, border,
77824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                 format, type, pixels, unpack, texObj, texImage, 0, 0);
77924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian}
78024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
78124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
78224df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void
78324df8f895fe8807aa2ba058e71bd40adfc01d21eBrianst_TexImage2D(GLcontext * ctx,
78424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                GLenum target, GLint level,
78524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                GLint internalFormat,
78624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                GLint width, GLint height, GLint border,
78724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                GLenum format, GLenum type, const void *pixels,
78824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                const struct gl_pixelstore_attrib *unpack,
78924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                struct gl_texture_object *texObj,
79024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                struct gl_texture_image *texImage)
79124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{
79224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   st_TexImage(ctx, 2, target, level,
79324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                 internalFormat, width, height, 1, border,
79424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                 format, type, pixels, unpack, texObj, texImage, 0, 0);
79524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian}
79624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
79724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
79824df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void
79924df8f895fe8807aa2ba058e71bd40adfc01d21eBrianst_TexImage1D(GLcontext * ctx,
80024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                GLenum target, GLint level,
80124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                GLint internalFormat,
80224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                GLint width, GLint border,
80324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                GLenum format, GLenum type, const void *pixels,
80424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                const struct gl_pixelstore_attrib *unpack,
80524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                struct gl_texture_object *texObj,
80624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                struct gl_texture_image *texImage)
80724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{
80824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   st_TexImage(ctx, 1, target, level,
80924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                 internalFormat, width, 1, 1, border,
81024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                 format, type, pixels, unpack, texObj, texImage, 0, 0);
81124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian}
81224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
81324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
81424df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void
81524df8f895fe8807aa2ba058e71bd40adfc01d21eBrianst_CompressedTexImage2D( GLcontext *ctx, GLenum target, GLint level,
81624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian				GLint internalFormat,
81724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian				GLint width, GLint height, GLint border,
81824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian				GLsizei imageSize, const GLvoid *data,
81924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian				struct gl_texture_object *texObj,
82024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian				struct gl_texture_image *texImage )
82124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{
82224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   st_TexImage(ctx, 2, target, level,
82324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian		 internalFormat, width, height, 1, border,
82424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian		 0, 0, data, &ctx->Unpack, texObj, texImage, imageSize, 1);
82524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian}
82624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
82724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
82824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian/**
82924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * Need to map texture image into memory before copying image data,
83024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * then unmap it.
83124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */
83224df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void
83324df8f895fe8807aa2ba058e71bd40adfc01d21eBrianst_get_tex_image(GLcontext * ctx, GLenum target, GLint level,
83424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                 GLenum format, GLenum type, GLvoid * pixels,
83524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                 struct gl_texture_object *texObj,
83624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                 struct gl_texture_image *texImage, int compressed)
83724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{
83824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   /*
83924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   struct intel_context *intel = intel_context(ctx);
84024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   */
84124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   struct pipe_context *pipe = ctx->st->pipe;
84224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   struct st_texture_image *stImage = st_texture_image(texImage);
84324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
84424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   /* Map */
84524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   if (stImage->mt) {
84624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      /* Image is stored in hardware format in a buffer managed by the
84724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian       * kernel.  Need to explicitly map and unmap it.
84824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian       */
84924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      stImage->base.Data =
85024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian         st_miptree_image_map(pipe,
85124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                                 stImage->mt,
85224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                                 stImage->face,
85324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                                 stImage->level,
85424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                                 &stImage->base.RowStride,
85524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                                 stImage->base.ImageOffsets);
85624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      stImage->base.RowStride /= stImage->mt->cpp;
85724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   }
85824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   else {
85924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      /* Otherwise, the image should actually be stored in
86024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian       * stImage->base.Data.  This is pretty confusing for
86124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian       * everybody, I'd much prefer to separate the two functions of
86224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian       * texImage->Data - storage for texture images in main memory
86324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian       * and access (ie mappings) of images.  In other words, we'd
86424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian       * create a new texImage->Map field and leave Data simply for
86524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian       * storage.
86624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian       */
86724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      assert(stImage->base.Data);
86824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   }
86924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
87024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
87124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   if (compressed) {
87224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      _mesa_get_compressed_teximage(ctx, target, level, pixels,
87324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian				    texObj, texImage);
87424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   } else {
87524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      _mesa_get_teximage(ctx, target, level, format, type, pixels,
87624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian			 texObj, texImage);
87724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   }
87824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
87924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
88024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   /* Unmap */
88124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   if (stImage->mt) {
88224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      st_miptree_image_unmap(pipe, stImage->mt);
88324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      stImage->base.Data = NULL;
88424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   }
88524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian}
88624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
88724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
88824df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void
88924df8f895fe8807aa2ba058e71bd40adfc01d21eBrianst_GetTexImage(GLcontext * ctx, GLenum target, GLint level,
89024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                 GLenum format, GLenum type, GLvoid * pixels,
89124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                 struct gl_texture_object *texObj,
89224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                 struct gl_texture_image *texImage)
89324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{
89424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   st_get_tex_image(ctx, target, level, format, type, pixels,
89524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                    texObj, texImage, 0);
89624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian}
89724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
89824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
89924df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void
90024df8f895fe8807aa2ba058e71bd40adfc01d21eBrianst_GetCompressedTexImage(GLcontext *ctx, GLenum target, GLint level,
90124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian			   GLvoid *pixels,
90224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian			   const struct gl_texture_object *texObj,
90324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian			   const struct gl_texture_image *texImage)
90424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{
90524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   st_get_tex_image(ctx, target, level, 0, 0, pixels,
90624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                    (struct gl_texture_object *) texObj,
90724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                    (struct gl_texture_image *) texImage, 1);
90824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian}
90924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
91024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
91124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
91224df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void
91324df8f895fe8807aa2ba058e71bd40adfc01d21eBrianst_TexSubimage(GLcontext * ctx,
91424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                 GLint dims,
91524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                 GLenum target, GLint level,
91624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                 GLint xoffset, GLint yoffset, GLint zoffset,
91724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                 GLint width, GLint height, GLint depth,
91824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                 GLenum format, GLenum type, const void *pixels,
91924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                 const struct gl_pixelstore_attrib *packing,
92024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                 struct gl_texture_object *texObj,
92124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                 struct gl_texture_image *texImage)
92224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{
92324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   struct pipe_context *pipe = ctx->st->pipe;
92424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   struct st_texture_image *stImage = st_texture_image(texImage);
92524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   GLuint dstRowStride;
92624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
92724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   DBG("%s target %s level %d offset %d,%d %dx%d\n", __FUNCTION__,
92824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian       _mesa_lookup_enum_by_nr(target),
92924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian       level, xoffset, yoffset, width, height);
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   /* Map buffer if necessary.  Need to lock to prevent other contexts
93824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian    * from uploading the buffer under us.
93924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian    */
94024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   if (stImage->mt)
94124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      texImage->Data = st_miptree_image_map(pipe,
94224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                                               stImage->mt,
94324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                                               stImage->face,
94424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                                               stImage->level,
94524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                                               &dstRowStride,
94624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                                               texImage->ImageOffsets);
94724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
94824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   assert(dstRowStride);
94924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
95024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   if (!texImage->TexFormat->StoreImage(ctx, dims, texImage->_BaseFormat,
95124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                                        texImage->TexFormat,
95224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                                        texImage->Data,
95324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                                        xoffset, yoffset, zoffset,
95424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                                        dstRowStride,
95524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                                        texImage->ImageOffsets,
95624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                                        width, height, depth,
95724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                                        format, type, pixels, packing)) {
95824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      _mesa_error(ctx, GL_OUT_OF_MEMORY, "intelTexSubImage");
95924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   }
96024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
96124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#if 0
96224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   /* GL_SGIS_generate_mipmap */
96324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
96424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      _mesa_generate_mipmap(ctx, target,
96524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                            &ctx->Texture.Unit[ctx->Texture.CurrentUnit],
96624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                            texObj);
96724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   }
96824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#endif
96924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
97024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   _mesa_unmap_teximage_pbo(ctx, packing);
97124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
97224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   if (stImage->mt) {
97324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      st_miptree_image_unmap(pipe, stImage->mt);
97424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      texImage->Data = NULL;
97524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   }
97624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian}
97724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
97824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
97924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
98024df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void
98124df8f895fe8807aa2ba058e71bd40adfc01d21eBrianst_TexSubImage3D(GLcontext * ctx,
98224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                   GLenum target,
98324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                   GLint level,
98424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                   GLint xoffset, GLint yoffset, GLint zoffset,
98524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                   GLsizei width, GLsizei height, GLsizei depth,
98624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                   GLenum format, GLenum type,
98724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                   const GLvoid * pixels,
98824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                   const struct gl_pixelstore_attrib *packing,
98924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                   struct gl_texture_object *texObj,
99024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                   struct gl_texture_image *texImage)
99124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{
992b245840b86cf877c9b8d666edf229364a84f1deaBrian   st_TexSubimage(ctx, 3, target, level,
993b245840b86cf877c9b8d666edf229364a84f1deaBrian                  xoffset, yoffset, zoffset,
994b245840b86cf877c9b8d666edf229364a84f1deaBrian                  width, height, depth,
995b245840b86cf877c9b8d666edf229364a84f1deaBrian                  format, type, pixels, packing, texObj, texImage);
99624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian}
99724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
99824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
99924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
100024df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void
100124df8f895fe8807aa2ba058e71bd40adfc01d21eBrianst_TexSubImage2D(GLcontext * ctx,
100224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                   GLenum target,
100324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                   GLint level,
100424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                   GLint xoffset, GLint yoffset,
100524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                   GLsizei width, GLsizei height,
100624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                   GLenum format, GLenum type,
100724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                   const GLvoid * pixels,
100824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                   const struct gl_pixelstore_attrib *packing,
100924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                   struct gl_texture_object *texObj,
101024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                   struct gl_texture_image *texImage)
101124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{
1012b245840b86cf877c9b8d666edf229364a84f1deaBrian   st_TexSubimage(ctx, 2, target, level,
1013b245840b86cf877c9b8d666edf229364a84f1deaBrian                  xoffset, yoffset, 0,
1014b245840b86cf877c9b8d666edf229364a84f1deaBrian                  width, height, 1,
1015b245840b86cf877c9b8d666edf229364a84f1deaBrian                  format, type, pixels, packing, texObj, texImage);
101624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian}
101724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
101824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
101924df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void
102024df8f895fe8807aa2ba058e71bd40adfc01d21eBrianst_TexSubImage1D(GLcontext * ctx,
102124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                   GLenum target,
102224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                   GLint level,
102324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                   GLint xoffset,
102424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                   GLsizei width,
102524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                   GLenum format, GLenum type,
102624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                   const GLvoid * pixels,
102724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                   const struct gl_pixelstore_attrib *packing,
102824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                   struct gl_texture_object *texObj,
102924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                   struct gl_texture_image *texImage)
103024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{
1031b245840b86cf877c9b8d666edf229364a84f1deaBrian   st_TexSubimage(ctx, 1, target, level,
1032b245840b86cf877c9b8d666edf229364a84f1deaBrian                  xoffset, 0, 0,
1033b245840b86cf877c9b8d666edf229364a84f1deaBrian                  width, 1, 1,
1034b245840b86cf877c9b8d666edf229364a84f1deaBrian                  format, type, pixels, packing, texObj, texImage);
103524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian}
103624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
103724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
103824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
103924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian/**
1040038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian * Return 0 for GL_TEXTURE_CUBE_MAP_POSITIVE_X,
1041038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian *        1 for GL_TEXTURE_CUBE_MAP_NEGATIVE_X,
1042038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian *        etc.
1043038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian * XXX duplicated from main/teximage.c
1044038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian */
1045038cb561eb094af2f2ba06e18e61246fc0c87c3cBrianstatic uint
1046038cb561eb094af2f2ba06e18e61246fc0c87c3cBriantexture_face(GLenum target)
1047038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian{
1048038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian   if (target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB &&
1049038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian       target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB)
1050038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian      return (GLuint) target - (GLuint) GL_TEXTURE_CUBE_MAP_POSITIVE_X;
1051038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian   else
1052038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian      return 0;
1053038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian}
1054038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian
1055038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian
1056038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian
1057038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian/**
1058038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian * Do a CopyTexSubImage operation by mapping the source region and
10595c83f1371978472fbe4bba8f686733c6b519874aBrian * dest region and using get_tile()/put_tile() to access the pixels/texels.
1060c6717a86420d7141013165f7acd50b3c3f751756Brian *
1061c6717a86420d7141013165f7acd50b3c3f751756Brian * Note: srcY=0=TOP of renderbuffer
1062038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian */
1063038cb561eb094af2f2ba06e18e61246fc0c87c3cBrianstatic void
1064038cb561eb094af2f2ba06e18e61246fc0c87c3cBrianfallback_copy_texsubimage(GLcontext *ctx,
1065038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian                          GLenum target,
1066038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian                          GLint level,
1067038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian                          struct st_renderbuffer *strb,
1068038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian                          struct st_texture_image *stImage,
1069038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian                          GLenum baseFormat,
1070038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian                          GLint destX, GLint destY, GLint destZ,
1071038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian                          GLint srcX, GLint srcY,
1072038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian                          GLsizei width, GLsizei height)
1073038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian{
1074038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian   struct pipe_context *pipe = ctx->st->pipe;
1075038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian   const uint face = texture_face(target);
1076038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian   struct pipe_mipmap_tree *mt = stImage->mt;
1077038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian   struct pipe_surface *src_surf, *dest_surf;
1078038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian   GLfloat *data;
10795c83f1371978472fbe4bba8f686733c6b519874aBrian   GLint row, yStep;
10805c83f1371978472fbe4bba8f686733c6b519874aBrian
10815c83f1371978472fbe4bba8f686733c6b519874aBrian   /* determine bottom-to-top vs. top-to-bottom order */
10825c83f1371978472fbe4bba8f686733c6b519874aBrian   if (st_fb_orientation(ctx->ReadBuffer) == Y_0_TOP) {
10835c83f1371978472fbe4bba8f686733c6b519874aBrian      destY = height - 1 - destY;
10845c83f1371978472fbe4bba8f686733c6b519874aBrian      yStep = -1;
10855c83f1371978472fbe4bba8f686733c6b519874aBrian   }
10865c83f1371978472fbe4bba8f686733c6b519874aBrian   else {
10875c83f1371978472fbe4bba8f686733c6b519874aBrian      yStep = 1;
10885c83f1371978472fbe4bba8f686733c6b519874aBrian   }
1089038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian
1090038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian   src_surf = strb->surface;
1091038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian
1092038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian   dest_surf = pipe->get_tex_surface(pipe, mt,
1093038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian                                    face, level, destZ);
1094038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian
1095c6717a86420d7141013165f7acd50b3c3f751756Brian   (void) pipe->region_map(pipe, dest_surf->region);
1096c6717a86420d7141013165f7acd50b3c3f751756Brian   (void) pipe->region_map(pipe, src_surf->region);
1097c6717a86420d7141013165f7acd50b3c3f751756Brian
10985c83f1371978472fbe4bba8f686733c6b519874aBrian   /* buffer for one row */
10995c83f1371978472fbe4bba8f686733c6b519874aBrian   data = (GLfloat *) malloc(width * 4 * sizeof(GLfloat));
1100038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian
11015c83f1371978472fbe4bba8f686733c6b519874aBrian   /* do copy row by row */
11025c83f1371978472fbe4bba8f686733c6b519874aBrian   for (row = 0; row < height; row++) {
11035c83f1371978472fbe4bba8f686733c6b519874aBrian      src_surf->get_tile(src_surf, srcX, srcY + row, width, 1, data);
11045c83f1371978472fbe4bba8f686733c6b519874aBrian
11055c83f1371978472fbe4bba8f686733c6b519874aBrian      /* XXX we're ignoring convolution for now */
11065c83f1371978472fbe4bba8f686733c6b519874aBrian      if (ctx->_ImageTransferState) {
11075c83f1371978472fbe4bba8f686733c6b519874aBrian         _mesa_apply_rgba_transfer_ops(ctx,
11085c83f1371978472fbe4bba8f686733c6b519874aBrian                            ctx->_ImageTransferState & ~IMAGE_CONVOLUTION_BIT,
11095c83f1371978472fbe4bba8f686733c6b519874aBrian                            width, (GLfloat (*)[4])data);
11105c83f1371978472fbe4bba8f686733c6b519874aBrian      }
11115c83f1371978472fbe4bba8f686733c6b519874aBrian
11125c83f1371978472fbe4bba8f686733c6b519874aBrian      dest_surf->put_tile(dest_surf, destX, destY, width, 1, data);
11135c83f1371978472fbe4bba8f686733c6b519874aBrian      destY += yStep;
11145c83f1371978472fbe4bba8f686733c6b519874aBrian   }
1115038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian
1116038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian
1117c6717a86420d7141013165f7acd50b3c3f751756Brian   (void) pipe->region_unmap(pipe, dest_surf->region);
1118c6717a86420d7141013165f7acd50b3c3f751756Brian   (void) pipe->region_unmap(pipe, src_surf->region);
1119c6717a86420d7141013165f7acd50b3c3f751756Brian
1120038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian   free(data);
1121038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian}
1122038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian
1123038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian
1124038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian
1125038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian
1126038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian/**
1127b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian * Do a CopyTex[Sub]Image using an optimized hardware (blit) path.
1128b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian * Note that the region to copy has already been clip tested.
1129c6717a86420d7141013165f7acd50b3c3f751756Brian *
1130c6717a86420d7141013165f7acd50b3c3f751756Brian * Note: srcY=0=Bottom of renderbuffer
1131c6717a86420d7141013165f7acd50b3c3f751756Brian *
1132b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian * \return GL_TRUE if success, GL_FALSE if failure (use a fallback)
113324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */
1134038cb561eb094af2f2ba06e18e61246fc0c87c3cBrianstatic void
113524df8f895fe8807aa2ba058e71bd40adfc01d21eBriando_copy_texsubimage(GLcontext *ctx,
1136038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian                    GLenum target, GLint level,
1137038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian                    GLint destX, GLint destY, GLint destZ,
1138038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian                    GLint srcX, GLint srcY,
1139038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian                    GLsizei width, GLsizei height)
114024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{
1141038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian   struct gl_texture_unit *texUnit =
1142038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian      &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
1143038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian   struct gl_texture_object *texObj =
1144038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian      _mesa_select_tex_object(ctx, texUnit, target);
1145038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian   struct gl_texture_image *texImage =
1146038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian      _mesa_select_tex_image(ctx, texObj, target, level);
1147038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian   struct st_texture_image *stImage = st_texture_image(texImage);
1148038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian   GLenum baseFormat = texImage->InternalFormat;
1149b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian   struct gl_framebuffer *fb = ctx->ReadBuffer;
1150b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian   struct st_renderbuffer *strb;
1151b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian   struct pipe_context *pipe = ctx->st->pipe;
1152b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian   struct pipe_region *src_region, *dest_region;
1153b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian   uint dest_offset, src_offset;
1154b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian   uint dest_format, src_format;
115524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
1156038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian   (void) texImage;
1157038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian
1158b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian   /* determine if copying depth or color data */
1159b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian   if (baseFormat == GL_DEPTH_COMPONENT) {
1160b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian      strb = st_renderbuffer(fb->_DepthBuffer);
116124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   }
1162b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian   else if (baseFormat == GL_DEPTH_STENCIL_EXT) {
1163b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian      strb = st_renderbuffer(fb->_StencilBuffer);
1164b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian   }
1165b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian   else {
1166b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian      /* baseFormat == GL_RGB, GL_RGBA, GL_ALPHA, etc */
1167b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian      strb = st_renderbuffer(fb->_ColorReadBuffer);
1168b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian   }
1169b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian
1170b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian   assert(strb);
1171b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian   assert(strb->surface);
1172b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian   assert(stImage->mt);
1173c6717a86420d7141013165f7acd50b3c3f751756Brian
1174c6717a86420d7141013165f7acd50b3c3f751756Brian   if (st_fb_orientation(ctx->ReadBuffer) == Y_0_TOP) {
1175c6717a86420d7141013165f7acd50b3c3f751756Brian      srcY = strb->Base.Height - srcY - height;
1176c6717a86420d7141013165f7acd50b3c3f751756Brian   }
117724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
1178b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian   src_format = strb->surface->format;
1179b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian   dest_format = stImage->mt->format;
1180b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian
1181b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian   src_region = strb->surface->region;
1182b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian   dest_region = stImage->mt->region;
1183b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian
1184038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian   if (src_format == dest_format &&
11855c83f1371978472fbe4bba8f686733c6b519874aBrian       ctx->_ImageTransferState == 0x0 &&
1186038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian       src_region &&
1187038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian       dest_region &&
1188038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian       src_region->cpp == dest_region->cpp) {
1189038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian      /* do blit-style copy */
1190038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian      src_offset = 0;
1191038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian      dest_offset = st_miptree_image_offset(stImage->mt,
1192038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian                                            stImage->face,
1193038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian                                            stImage->level);
1194038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian
1195038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian      /* XXX may need to invert image depending on window
1196038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian       * vs. user-created FBO
1197038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian       */
1198b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian
119924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#if 0
1200038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian      /* A bit of fiddling to get the blitter to work with -ve
1201038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian       * pitches.  But we get a nice inverted blit this way, so it's
1202038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian       * worth it:
1203038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian       */
1204038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian      intelEmitCopyBlit(intel,
1205038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian                        stImage->mt->cpp,
1206038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian                        -src->pitch,
1207038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian                        src->buffer,
1208038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian                        src->height * src->pitch * src->cpp,
1209038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian                        stImage->mt->pitch,
1210038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian                        stImage->mt->region->buffer,
1211038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian                        dest_offset,
1212038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian                        x, y + height, dstx, dsty, width, height,
1213038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian                        GL_COPY); /* ? */
121424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#else
1215b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian
1216038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian      pipe->region_copy(pipe,
1217038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian                        /* dest */
1218038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian                        dest_region,
1219038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian                        dest_offset,
1220038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian                        destX, destY,
1221038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian                        /* src */
1222038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian                        src_region,
1223038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian                        src_offset,
1224038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian                        srcX, srcY,
1225038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian                        /* size */
1226038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian                        width, height);
122724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#endif
1228038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian   }
1229038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian   else {
1230038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian      fallback_copy_texsubimage(ctx, target, level,
1231038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian                                strb, stImage, baseFormat,
1232038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian                                destX, destY, destZ,
1233038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian                                srcX, srcY, width, height);
1234038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian   }
1235038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian
123624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
123724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#if 0
123824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   /* GL_SGIS_generate_mipmap -- this can be accelerated now.
123924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian    * XXX Add a ctx->Driver.GenerateMipmaps() function?
124024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian    */
124124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
124224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      intel_generate_mipmap(ctx, target,
124324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                            &ctx->Texture.Unit[ctx->Texture.CurrentUnit],
124424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                            texObj);
124524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   }
124624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#endif
124724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
124824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian}
124924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
125024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
1251038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian
125224df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void
125324df8f895fe8807aa2ba058e71bd40adfc01d21eBrianst_CopyTexImage1D(GLcontext * ctx, GLenum target, GLint level,
125424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                  GLenum internalFormat,
125524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                  GLint x, GLint y, GLsizei width, GLint border)
125624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{
125724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   struct gl_texture_unit *texUnit =
125824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
125924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   struct gl_texture_object *texObj =
126024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      _mesa_select_tex_object(ctx, texUnit, target);
126124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   struct gl_texture_image *texImage =
126224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      _mesa_select_tex_image(ctx, texObj, target, level);
126324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
1264038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian#if 0
126524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   if (border)
126624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      goto fail;
1267038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian#endif
126824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
126924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   /* Setup or redefine the texture object, mipmap tree and texture
127024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian    * image.  Don't populate yet.
127124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian    */
127224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   ctx->Driver.TexImage1D(ctx, target, level, internalFormat,
127324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                          width, border,
127424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                          GL_RGBA, CHAN_TYPE, NULL,
127524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                          &ctx->DefaultPacking, texObj, texImage);
127624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
1277038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian   do_copy_texsubimage(ctx, target, level,
1278038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian                       0, 0, 0,
1279038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian                       x, y, width, 1);
128024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian}
128124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
128224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
128324df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void
128424df8f895fe8807aa2ba058e71bd40adfc01d21eBrianst_CopyTexImage2D(GLcontext * ctx, GLenum target, GLint level,
128524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                  GLenum internalFormat,
128624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                  GLint x, GLint y, GLsizei width, GLsizei height,
128724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                  GLint border)
128824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{
128924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   struct gl_texture_unit *texUnit =
129024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
129124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   struct gl_texture_object *texObj =
129224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      _mesa_select_tex_object(ctx, texUnit, target);
129324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   struct gl_texture_image *texImage =
129424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      _mesa_select_tex_image(ctx, texObj, target, level);
129524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
1296038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian#if 0
129724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   if (border)
129824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      goto fail;
1299038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian#endif
130024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
130124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   /* Setup or redefine the texture object, mipmap tree and texture
130224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian    * image.  Don't populate yet.
130324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian    */
130424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   ctx->Driver.TexImage2D(ctx, target, level, internalFormat,
130524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                          width, height, border,
130624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                          GL_RGBA, CHAN_TYPE, NULL,
130724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                          &ctx->DefaultPacking, texObj, texImage);
130824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
130924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
1310038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian   do_copy_texsubimage(ctx, target, level,
1311038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian                       0, 0, 0,
1312038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian                       x, y, width, height);
131324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian}
131424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
131524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
131624df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void
131724df8f895fe8807aa2ba058e71bd40adfc01d21eBrianst_CopyTexSubImage1D(GLcontext * ctx, GLenum target, GLint level,
131824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                     GLint xoffset, GLint x, GLint y, GLsizei width)
131924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{
1320038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian   const GLint yoffset = 0, zoffset = 0;
1321038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian   const GLsizei height = 1;
1322038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian   do_copy_texsubimage(ctx, target, level,
1323038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian                       xoffset, yoffset, zoffset,
1324038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian                       x, y, width, height);
132524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian}
132624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
132724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
132824df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void
132924df8f895fe8807aa2ba058e71bd40adfc01d21eBrianst_CopyTexSubImage2D(GLcontext * ctx, GLenum target, GLint level,
133024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                     GLint xoffset, GLint yoffset,
133124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                     GLint x, GLint y, GLsizei width, GLsizei height)
133224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{
1333038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian   const GLint zoffset = 0;
1334038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian   do_copy_texsubimage(ctx, target, level,
1335038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian                       xoffset, yoffset, zoffset,
1336038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian                       x, y, width, height);
1337038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian}
133824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
133924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
1340038cb561eb094af2f2ba06e18e61246fc0c87c3cBrianstatic void
1341038cb561eb094af2f2ba06e18e61246fc0c87c3cBrianst_CopyTexSubImage3D(GLcontext * ctx, GLenum target, GLint level,
1342038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian                     GLint xoffset, GLint yoffset, GLint zoffset,
1343038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian                     GLint x, GLint y, GLsizei width, GLsizei height)
1344038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian{
1345038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian   do_copy_texsubimage(ctx, target, level,
1346038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian                       xoffset, yoffset, zoffset,
1347038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian                       x, y, width, height);
134824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian}
134924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
135024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
135124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
135224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
135324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian/**
135424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * Compute which mipmap levels that really need to be sent to the hardware.
135524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * This depends on the base image size, GL_TEXTURE_MIN_LOD,
135624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * GL_TEXTURE_MAX_LOD, GL_TEXTURE_BASE_LEVEL, and GL_TEXTURE_MAX_LEVEL.
135724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */
135824df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void
135914b98343309fdcff3514f05020303f7b40e83a4aBriancalculate_first_last_level(struct st_texture_object *stObj)
136024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{
136114b98343309fdcff3514f05020303f7b40e83a4aBrian   struct gl_texture_object *tObj = &stObj->base;
136224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   const struct gl_texture_image *const baseImage =
136324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      tObj->Image[0][tObj->BaseLevel];
136424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
136524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   /* These must be signed values.  MinLod and MaxLod can be negative numbers,
136624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian    * and having firstLevel and lastLevel as signed prevents the need for
136724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian    * extra sign checks.
136824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian    */
136924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   int firstLevel;
137024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   int lastLevel;
137124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
137224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   /* Yes, this looks overly complicated, but it's all needed.
137324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian    */
137424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   switch (tObj->Target) {
137524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   case GL_TEXTURE_1D:
137624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   case GL_TEXTURE_2D:
137724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   case GL_TEXTURE_3D:
137824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   case GL_TEXTURE_CUBE_MAP:
137924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      if (tObj->MinFilter == GL_NEAREST || tObj->MinFilter == GL_LINEAR) {
138024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian         /* GL_NEAREST and GL_LINEAR only care about GL_TEXTURE_BASE_LEVEL.
138124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian          */
138224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian         firstLevel = lastLevel = tObj->BaseLevel;
138324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      }
138424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      else {
138524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian         firstLevel = tObj->BaseLevel + (GLint) (tObj->MinLod + 0.5);
138624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian         firstLevel = MAX2(firstLevel, tObj->BaseLevel);
138724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian         lastLevel = tObj->BaseLevel + (GLint) (tObj->MaxLod + 0.5);
138824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian         lastLevel = MAX2(lastLevel, tObj->BaseLevel);
138924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian         lastLevel = MIN2(lastLevel, tObj->BaseLevel + baseImage->MaxLog2);
139024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian         lastLevel = MIN2(lastLevel, tObj->MaxLevel);
139124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian         lastLevel = MAX2(firstLevel, lastLevel);       /* need at least one level */
139224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      }
139324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      break;
139424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   case GL_TEXTURE_RECTANGLE_NV:
139524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   case GL_TEXTURE_4D_SGIS:
139624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      firstLevel = lastLevel = 0;
139724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      break;
139824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   default:
139924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      return;
140024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   }
140124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
140224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   /* save these values */
140314b98343309fdcff3514f05020303f7b40e83a4aBrian   stObj->firstLevel = firstLevel;
140414b98343309fdcff3514f05020303f7b40e83a4aBrian   stObj->lastLevel = lastLevel;
140524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian}
140624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
140724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
140824df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void
140924df8f895fe8807aa2ba058e71bd40adfc01d21eBriancopy_image_data_to_tree(struct pipe_context *pipe,
141014b98343309fdcff3514f05020303f7b40e83a4aBrian                        struct st_texture_object *stObj,
141124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                        struct st_texture_image *stImage)
141224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{
141324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   if (stImage->mt) {
141424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      /* Copy potentially with the blitter:
141524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian       */
141624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      st_miptree_image_copy(pipe,
141728b315dc1aed36bebadfacbd55e481e7baacfcb5Brian                            stObj->mt,  /* dest miptree */
141828b315dc1aed36bebadfacbd55e481e7baacfcb5Brian                            stImage->face, stImage->level,
141928b315dc1aed36bebadfacbd55e481e7baacfcb5Brian                            stImage->mt /* src miptree */
142028b315dc1aed36bebadfacbd55e481e7baacfcb5Brian                            );
142124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
142224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      st_miptree_release(pipe, &stImage->mt);
142324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   }
142424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   else {
142524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      assert(stImage->base.Data != NULL);
142624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
142724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      /* More straightforward upload.
142824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian       */
142924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      st_miptree_image_data(pipe,
143014b98343309fdcff3514f05020303f7b40e83a4aBrian                               stObj->mt,
143124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                               stImage->face,
143224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                               stImage->level,
143324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                               stImage->base.Data,
143424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                               stImage->base.RowStride,
143524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                               stImage->base.RowStride *
143624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                               stImage->base.Height);
143724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      _mesa_align_free(stImage->base.Data);
143824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      stImage->base.Data = NULL;
143924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   }
144024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
144114b98343309fdcff3514f05020303f7b40e83a4aBrian   st_miptree_reference(&stImage->mt, stObj->mt);
144224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian}
144324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
144424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
144524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian/*
144624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */
144714b98343309fdcff3514f05020303f7b40e83a4aBrianGLboolean
144824df8f895fe8807aa2ba058e71bd40adfc01d21eBrianst_finalize_mipmap_tree(GLcontext *ctx,
144924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                        struct pipe_context *pipe, GLuint unit,
145024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                        GLboolean *needFlush)
145124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{
145224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   struct gl_texture_object *tObj = ctx->Texture.Unit[unit]._Current;
145314b98343309fdcff3514f05020303f7b40e83a4aBrian   struct st_texture_object *stObj = st_texture_object(tObj);
145424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   int comp_byte = 0;
145524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   int cpp;
145624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
145724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   GLuint face, i;
145824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   GLuint nr_faces = 0;
145924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   struct st_texture_image *firstImage;
146024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
146124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   *needFlush = GL_FALSE;
146224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
146324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   /* We know/require this is true by now:
146424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian    */
146514b98343309fdcff3514f05020303f7b40e83a4aBrian   assert(stObj->base._Complete);
146624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
146724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   /* What levels must the tree include at a minimum?
146824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian    */
146914b98343309fdcff3514f05020303f7b40e83a4aBrian   calculate_first_last_level(stObj);
147024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   firstImage =
147114b98343309fdcff3514f05020303f7b40e83a4aBrian      st_texture_image(stObj->base.Image[0][stObj->firstLevel]);
147224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
147324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   /* Fallback case:
147424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian    */
147524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   if (firstImage->base.Border) {
147614b98343309fdcff3514f05020303f7b40e83a4aBrian      if (stObj->mt) {
147714b98343309fdcff3514f05020303f7b40e83a4aBrian         st_miptree_release(pipe, &stObj->mt);
147824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      }
147924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      return GL_FALSE;
148024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   }
148124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
148224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
148314b98343309fdcff3514f05020303f7b40e83a4aBrian   /* If both firstImage and stObj have a tree which can contain
148424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian    * all active images, favour firstImage.  Note that because of the
148524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian    * completeness requirement, we know that the image dimensions
148624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian    * will match.
148724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian    */
148824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   if (firstImage->mt &&
148914b98343309fdcff3514f05020303f7b40e83a4aBrian       firstImage->mt != stObj->mt &&
149014b98343309fdcff3514f05020303f7b40e83a4aBrian       firstImage->mt->first_level <= stObj->firstLevel &&
149114b98343309fdcff3514f05020303f7b40e83a4aBrian       firstImage->mt->last_level >= stObj->lastLevel) {
149224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
149314b98343309fdcff3514f05020303f7b40e83a4aBrian      if (stObj->mt)
149414b98343309fdcff3514f05020303f7b40e83a4aBrian         st_miptree_release(pipe, &stObj->mt);
149524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
149614b98343309fdcff3514f05020303f7b40e83a4aBrian      st_miptree_reference(&stObj->mt, firstImage->mt);
149724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   }
149824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
149924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   if (firstImage->base.IsCompressed) {
150014b98343309fdcff3514f05020303f7b40e83a4aBrian      comp_byte = compressed_num_bytes(firstImage->base.TexFormat->MesaFormat);
150124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      cpp = comp_byte;
150224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   }
150324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   else cpp = firstImage->base.TexFormat->TexelBytes;
150424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
150524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   /* Check tree can hold all active levels.  Check tree matches
150624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian    * target, imageFormat, etc.
150724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian    *
150824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian    * XXX: For some layouts (eg i945?), the test might have to be
150924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian    * first_level == firstLevel, as the tree isn't valid except at the
151024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian    * original start level.  Hope to get around this by
151124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian    * programming minLod, maxLod, baseLevel into the hardware and
151224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian    * leaving the tree alone.
151324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian    */
151414b98343309fdcff3514f05020303f7b40e83a4aBrian   if (stObj->mt &&
15155390a43ce06b27f6d54bc5f237aa305b6948f2afBrian       (stObj->mt->target != gl_target_to_pipe(stObj->base.Target) ||
151614b98343309fdcff3514f05020303f7b40e83a4aBrian	stObj->mt->internal_format != firstImage->base.InternalFormat ||
151714b98343309fdcff3514f05020303f7b40e83a4aBrian	stObj->mt->first_level != stObj->firstLevel ||
151814b98343309fdcff3514f05020303f7b40e83a4aBrian	stObj->mt->last_level != stObj->lastLevel ||
151914b98343309fdcff3514f05020303f7b40e83a4aBrian	stObj->mt->width0 != firstImage->base.Width ||
152014b98343309fdcff3514f05020303f7b40e83a4aBrian	stObj->mt->height0 != firstImage->base.Height ||
152114b98343309fdcff3514f05020303f7b40e83a4aBrian	stObj->mt->depth0 != firstImage->base.Depth ||
152214b98343309fdcff3514f05020303f7b40e83a4aBrian	stObj->mt->cpp != cpp ||
152314b98343309fdcff3514f05020303f7b40e83a4aBrian	stObj->mt->compressed != firstImage->base.IsCompressed)) {
152414b98343309fdcff3514f05020303f7b40e83a4aBrian      st_miptree_release(pipe, &stObj->mt);
152524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   }
152624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
152724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
152824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   /* May need to create a new tree:
152924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian    */
153014b98343309fdcff3514f05020303f7b40e83a4aBrian   if (!stObj->mt) {
153114b98343309fdcff3514f05020303f7b40e83a4aBrian      stObj->mt = st_miptree_create(pipe,
15325390a43ce06b27f6d54bc5f237aa305b6948f2afBrian                                    gl_target_to_pipe(stObj->base.Target),
1533b245840b86cf877c9b8d666edf229364a84f1deaBrian                                    firstImage->base.InternalFormat,
1534b245840b86cf877c9b8d666edf229364a84f1deaBrian                                    stObj->firstLevel,
1535b245840b86cf877c9b8d666edf229364a84f1deaBrian                                    stObj->lastLevel,
1536b245840b86cf877c9b8d666edf229364a84f1deaBrian                                    firstImage->base.Width,
1537b245840b86cf877c9b8d666edf229364a84f1deaBrian                                    firstImage->base.Height,
1538b245840b86cf877c9b8d666edf229364a84f1deaBrian                                    firstImage->base.Depth,
1539b245840b86cf877c9b8d666edf229364a84f1deaBrian                                    cpp,
1540b245840b86cf877c9b8d666edf229364a84f1deaBrian                                    comp_byte);
1541b245840b86cf877c9b8d666edf229364a84f1deaBrian
1542b245840b86cf877c9b8d666edf229364a84f1deaBrian      stObj->mt->format
15439cf9aa1ea2c3f40a09316975410a4b0e202e82baBrian         = st_mesa_format_to_pipe_format(firstImage->base.TexFormat->MesaFormat);
154424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   }
154524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
154624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   /* Pull in any images not in the object's tree:
154724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian    */
154814b98343309fdcff3514f05020303f7b40e83a4aBrian   nr_faces = (stObj->base.Target == GL_TEXTURE_CUBE_MAP) ? 6 : 1;
154924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   for (face = 0; face < nr_faces; face++) {
155014b98343309fdcff3514f05020303f7b40e83a4aBrian      for (i = stObj->firstLevel; i <= stObj->lastLevel; i++) {
155124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian         struct st_texture_image *stImage =
155214b98343309fdcff3514f05020303f7b40e83a4aBrian            st_texture_image(stObj->base.Image[face][i]);
155324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
155424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian         /* Need to import images in main memory or held in other trees.
155524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian          */
155614b98343309fdcff3514f05020303f7b40e83a4aBrian         if (stObj->mt != stImage->mt) {
155714b98343309fdcff3514f05020303f7b40e83a4aBrian            copy_image_data_to_tree(pipe, stObj, stImage);
155824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian	    *needFlush = GL_TRUE;
155924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian         }
156024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      }
156124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   }
156224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
156324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
156424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   return GL_TRUE;
156524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian}
156624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
156724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
156824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
156924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
15706da9234fd437f97267e7831f034c78b31156d939Brianvoid
15716da9234fd437f97267e7831f034c78b31156d939Brianst_init_texture_functions(struct dd_function_table *functions)
157224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{
157324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   functions->ChooseTextureFormat = st_ChooseTextureFormat;
157424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   functions->TexImage1D = st_TexImage1D;
157524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   functions->TexImage2D = st_TexImage2D;
157624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   functions->TexImage3D = st_TexImage3D;
157724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   functions->TexSubImage1D = st_TexSubImage1D;
157824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   functions->TexSubImage2D = st_TexSubImage2D;
157924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   functions->TexSubImage3D = st_TexSubImage3D;
158024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   functions->CopyTexImage1D = st_CopyTexImage1D;
158124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   functions->CopyTexImage2D = st_CopyTexImage2D;
158224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   functions->CopyTexSubImage1D = st_CopyTexSubImage1D;
158324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   functions->CopyTexSubImage2D = st_CopyTexSubImage2D;
1584038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian   functions->CopyTexSubImage3D = st_CopyTexSubImage3D;
1585038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian
158624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   functions->GetTexImage = st_GetTexImage;
158724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
158824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   /* compressed texture functions */
158924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   functions->CompressedTexImage2D = st_CompressedTexImage2D;
159024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   functions->GetCompressedTexImage = st_GetCompressedTexImage;
159124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
159224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   functions->NewTextureObject = st_NewTextureObject;
159324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   functions->NewTextureImage = st_NewTextureImage;
159424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   functions->DeleteTexture = st_DeleteTextureObject;
159524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   functions->FreeTexImageData = st_FreeTextureImageData;
159624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   functions->UpdateTexturePalette = 0;
159724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   functions->IsTextureResident = st_IsTextureResident;
159824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
159924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   functions->TextureMemCpy = do_memcpy;
160024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian}
1601