st_cb_texture.c revision b19e8f720bb2f4d360f5497b64901fc48321f172
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"
29b19e8f720bb2f4d360f5497b64901fc48321f172Brian Paul#if FEATURE_convolution
3024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#include "main/convolve.h"
31b19e8f720bb2f4d360f5497b64901fc48321f172Brian Paul#endif
3224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#include "main/enums.h"
3324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#include "main/image.h"
3424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#include "main/macros.h"
352440ff74d69a8caf49b05a960b4c7e282a96565eBrian#include "main/mipmap.h"
36cc94863429d8a6cef8dbf861e78701a458d30f5aBrian Paul#include "main/pixel.h"
3724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#include "main/texcompress.h"
3824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#include "main/texformat.h"
3924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#include "main/teximage.h"
4024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#include "main/texobj.h"
4124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#include "main/texstore.h"
4224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
4324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#include "state_tracker/st_context.h"
44b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian#include "state_tracker/st_cb_fbo.h"
4524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#include "state_tracker/st_cb_texture.h"
46f8ab24760d0d3f07e9ee81c98207ddf92dfe74daBrian#include "state_tracker/st_format.h"
4702250c855fbec5299a2d6118fefa0523ec73654cMichel Dänzer#include "state_tracker/st_public.h"
48753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer#include "state_tracker/st_texture.h"
4962abcb9aacc33218d0143a743c738435794b32a9Brian#include "state_tracker/st_gen_mipmap.h"
5024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
5124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#include "pipe/p_context.h"
52b245840b86cf877c9b8d666edf229364a84f1deaBrian#include "pipe/p_defines.h"
5311a80160fd60d1eb1541b49128c659526a5d8ac8Michel Dänzer#include "pipe/p_inlines.h"
546acd63a4980951727939c0dd545a0324965b3834José Fonseca#include "util/p_tile.h"
553c0dc8242b64518d5635263ba65b39afa919dd86Michel Dänzer#include "util/u_blit.h"
5624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
5724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
5824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#define DBG if (0) printf
5924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
6024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
6124df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic INLINE struct st_texture_image *
6224df8f895fe8807aa2ba058e71bd40adfc01d21eBrianst_texture_image(struct gl_texture_image *img)
6324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{
6424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   return (struct st_texture_image *) img;
6524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian}
6624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
6724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
681c5f27a18b775b3784fcd265d60e0affa0b31581Michel Dänzerstatic enum pipe_texture_target
695390a43ce06b27f6d54bc5f237aa305b6948f2afBriangl_target_to_pipe(GLenum target)
705390a43ce06b27f6d54bc5f237aa305b6948f2afBrian{
715390a43ce06b27f6d54bc5f237aa305b6948f2afBrian   switch (target) {
725390a43ce06b27f6d54bc5f237aa305b6948f2afBrian   case GL_TEXTURE_1D:
735390a43ce06b27f6d54bc5f237aa305b6948f2afBrian      return PIPE_TEXTURE_1D;
745390a43ce06b27f6d54bc5f237aa305b6948f2afBrian
755390a43ce06b27f6d54bc5f237aa305b6948f2afBrian   case GL_TEXTURE_2D:
765390a43ce06b27f6d54bc5f237aa305b6948f2afBrian   case GL_TEXTURE_RECTANGLE_NV:
775390a43ce06b27f6d54bc5f237aa305b6948f2afBrian      return PIPE_TEXTURE_2D;
785390a43ce06b27f6d54bc5f237aa305b6948f2afBrian
795390a43ce06b27f6d54bc5f237aa305b6948f2afBrian   case GL_TEXTURE_3D:
805390a43ce06b27f6d54bc5f237aa305b6948f2afBrian      return PIPE_TEXTURE_3D;
815390a43ce06b27f6d54bc5f237aa305b6948f2afBrian
825390a43ce06b27f6d54bc5f237aa305b6948f2afBrian   case GL_TEXTURE_CUBE_MAP_ARB:
835390a43ce06b27f6d54bc5f237aa305b6948f2afBrian      return PIPE_TEXTURE_CUBE;
845390a43ce06b27f6d54bc5f237aa305b6948f2afBrian
855390a43ce06b27f6d54bc5f237aa305b6948f2afBrian   default:
865390a43ce06b27f6d54bc5f237aa305b6948f2afBrian      assert(0);
875390a43ce06b27f6d54bc5f237aa305b6948f2afBrian      return 0;
885390a43ce06b27f6d54bc5f237aa305b6948f2afBrian   }
895390a43ce06b27f6d54bc5f237aa305b6948f2afBrian}
905390a43ce06b27f6d54bc5f237aa305b6948f2afBrian
915390a43ce06b27f6d54bc5f237aa305b6948f2afBrian
92afc54983370033b65e3a7cbb29bd9c87156f0881Brian/**
93afc54983370033b65e3a7cbb29bd9c87156f0881Brian * Return nominal bytes per texel for a compressed format, 0 for non-compressed
94afc54983370033b65e3a7cbb29bd9c87156f0881Brian * format.
95afc54983370033b65e3a7cbb29bd9c87156f0881Brian */
9624df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic int
9714b98343309fdcff3514f05020303f7b40e83a4aBriancompressed_num_bytes(GLuint mesaFormat)
9824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{
9924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   switch(mesaFormat) {
10024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   case MESA_FORMAT_RGB_FXT1:
10124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   case MESA_FORMAT_RGBA_FXT1:
10224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   case MESA_FORMAT_RGB_DXT1:
10324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   case MESA_FORMAT_RGBA_DXT1:
104afc54983370033b65e3a7cbb29bd9c87156f0881Brian      return 2;
10524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   case MESA_FORMAT_RGBA_DXT3:
10624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   case MESA_FORMAT_RGBA_DXT5:
107afc54983370033b65e3a7cbb29bd9c87156f0881Brian      return 4;
10824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   default:
109afc54983370033b65e3a7cbb29bd9c87156f0881Brian      return 0;
11024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   }
11124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian}
11224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
11324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
11424df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic GLboolean
11524df8f895fe8807aa2ba058e71bd40adfc01d21eBrianst_IsTextureResident(GLcontext * ctx, struct gl_texture_object *texObj)
11624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{
11724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#if 0
11824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   struct intel_context *intel = intel_context(ctx);
11924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   struct st_texture_object *stObj = st_texture_object(texObj);
12024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
12124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   return
122753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer      stObj->pt &&
123753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer      stObj->pt->region &&
124753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer      intel_is_region_resident(intel, stObj->pt->region);
12524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#endif
12624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   return 1;
12724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian}
12824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
12924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
13024df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic struct gl_texture_image *
13124df8f895fe8807aa2ba058e71bd40adfc01d21eBrianst_NewTextureImage(GLcontext * ctx)
13224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{
13324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   DBG("%s\n", __FUNCTION__);
13424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   (void) ctx;
13524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   return (struct gl_texture_image *) CALLOC_STRUCT(st_texture_image);
13624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian}
13724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
13824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
13924df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic struct gl_texture_object *
14024df8f895fe8807aa2ba058e71bd40adfc01d21eBrianst_NewTextureObject(GLcontext * ctx, GLuint name, GLenum target)
14124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{
14224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   struct st_texture_object *obj = CALLOC_STRUCT(st_texture_object);
14324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
14424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   DBG("%s\n", __FUNCTION__);
14524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   _mesa_initialize_texture_object(&obj->base, name, target);
14624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
14724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   return &obj->base;
14824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian}
14924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
15024df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void
15124df8f895fe8807aa2ba058e71bd40adfc01d21eBrianst_DeleteTextureObject(GLcontext *ctx,
1526f715dcc219071e574e363a9db4365c9c31ebbd3Brian                       struct gl_texture_object *texObj)
15324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{
15424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   struct st_texture_object *stObj = st_texture_object(texObj);
155753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer   if (stObj->pt)
156f8dce51083042b4d3fabf48524835290b6725682Brian Paul      pipe_texture_reference(&stObj->pt, NULL);
15724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
15824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   _mesa_delete_texture_object(ctx, texObj);
15924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian}
16024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
16124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
16224df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void
16324df8f895fe8807aa2ba058e71bd40adfc01d21eBrianst_FreeTextureImageData(GLcontext * ctx, struct gl_texture_image *texImage)
16424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{
16524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   struct st_texture_image *stImage = st_texture_image(texImage);
16624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
16724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   DBG("%s\n", __FUNCTION__);
16824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
169753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer   if (stImage->pt) {
170f8dce51083042b4d3fabf48524835290b6725682Brian Paul      pipe_texture_reference(&stImage->pt, NULL);
17124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   }
17224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
17324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   if (texImage->Data) {
17424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      free(texImage->Data);
17524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      texImage->Data = NULL;
17624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   }
17724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian}
17824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
17924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
18024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian/* ================================================================
18124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * From linux kernel i386 header files, copes with odd sizes better
18224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * than COPY_DWORDS would:
18324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * XXX Put this in src/mesa/main/imports.h ???
18424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */
18524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#if defined(i386) || defined(__i386__)
18624df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic INLINE void *
18724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian__memcpy(void *to, const void *from, size_t n)
18824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{
18924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   int d0, d1, d2;
19024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   __asm__ __volatile__("rep ; movsl\n\t"
19124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                        "testb $2,%b4\n\t"
19224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                        "je 1f\n\t"
19324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                        "movsw\n"
19424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                        "1:\ttestb $1,%b4\n\t"
19524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                        "je 2f\n\t"
19624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                        "movsb\n" "2:":"=&c"(d0), "=&D"(d1), "=&S"(d2)
19724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                        :"0"(n / 4), "q"(n), "1"((long) to), "2"((long) from)
19824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                        :"memory");
19924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   return (to);
20024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian}
20124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#else
20224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#define __memcpy(a,b,c) memcpy(a,b,c)
20324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#endif
20424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
20524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
20624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian/* The system memcpy (at least on ubuntu 5.10) has problems copying
20724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * to agp (writecombined) memory from a source which isn't 64-byte
20824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * aligned - there is a 4x performance falloff.
20924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian *
21024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * The x86 __memcpy is immune to this but is slightly slower
21124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * (10%-ish) than the system memcpy.
21224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian *
21324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * The sse_memcpy seems to have a slight cliff at 64/32 bytes, but
21424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * isn't much faster than x86_memcpy for agp copies.
21524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian *
21624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * TODO: switch dynamically.
21724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */
21824df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void *
21924df8f895fe8807aa2ba058e71bd40adfc01d21eBriando_memcpy(void *dest, const void *src, size_t n)
22024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{
22124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   if ((((unsigned) src) & 63) || (((unsigned) dest) & 63)) {
22224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      return __memcpy(dest, src, n);
22324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   }
22424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   else
22524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      return memcpy(dest, src, n);
22624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian}
22724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
22824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
229753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer/* Functions to store texture images.  Where possible, textures
23024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * will be created or further instantiated with image data, otherwise
23124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * images will be stored in malloc'd memory.  A validation step is
232753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer * required to pull those images into a texture, or otherwise
23324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * decide a fallback is required.
23424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */
23524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
23624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
23724df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic int
23824df8f895fe8807aa2ba058e71bd40adfc01d21eBrianlogbase2(int n)
23924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{
24024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   GLint i = 1;
24124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   GLint log2 = 0;
24224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
24324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   while (n > i) {
24424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      i *= 2;
24524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      log2++;
24624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   }
24724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
24824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   return log2;
24924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian}
25024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
25124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
252f52f5136e6eed23e55098681e5b082cc452136d6Brian/**
253f52f5136e6eed23e55098681e5b082cc452136d6Brian * Allocate a pipe_texture object for the given st_texture_object using
254f52f5136e6eed23e55098681e5b082cc452136d6Brian * the given st_texture_image to guess the mipmap size/levels.
255f52f5136e6eed23e55098681e5b082cc452136d6Brian *
256f52f5136e6eed23e55098681e5b082cc452136d6Brian * [comments...]
257f52f5136e6eed23e55098681e5b082cc452136d6Brian * Otherwise, store it in memory if (Border != 0) or (any dimension ==
25824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * 1).
25924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian *
260753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer * Otherwise, if max_level >= level >= min_level, create texture with
261753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer * space for images from min_level down to max_level.
26224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian *
263753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer * Otherwise, create texture with space for images from (level 0)..(1x1).
264753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer * Consider pruning this texture at a validation if the saving is worth it.
26524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */
26624df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void
267753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzerguess_and_alloc_texture(struct st_context *st,
268753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer			struct st_texture_object *stObj,
269afc54983370033b65e3a7cbb29bd9c87156f0881Brian			const struct st_texture_image *stImage)
27024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{
27124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   GLuint firstLevel;
27224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   GLuint lastLevel;
27345cc35e77600af8628393475405160e26d56d421Brian Paul   GLuint width = stImage->base.Width2;  /* size w/out border */
27445cc35e77600af8628393475405160e26d56d421Brian Paul   GLuint height = stImage->base.Height2;
27545cc35e77600af8628393475405160e26d56d421Brian Paul   GLuint depth = stImage->base.Depth2;
27624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   GLuint i, comp_byte = 0;
277a1f95a8bf64f863289b6759caeec76d7e054400eRoland Scheidegger   enum pipe_format fmt;
27824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
27924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   DBG("%s\n", __FUNCTION__);
28024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
281f52f5136e6eed23e55098681e5b082cc452136d6Brian   assert(!stObj->pt);
282f52f5136e6eed23e55098681e5b082cc452136d6Brian
28345cc35e77600af8628393475405160e26d56d421Brian Paul   if (stObj->pt &&
28445cc35e77600af8628393475405160e26d56d421Brian Paul       stImage->level > stObj->base.BaseLevel &&
28514b98343309fdcff3514f05020303f7b40e83a4aBrian       (stImage->base.Width == 1 ||
28614b98343309fdcff3514f05020303f7b40e83a4aBrian        (stObj->base.Target != GL_TEXTURE_1D &&
28714b98343309fdcff3514f05020303f7b40e83a4aBrian         stImage->base.Height == 1) ||
28814b98343309fdcff3514f05020303f7b40e83a4aBrian        (stObj->base.Target == GL_TEXTURE_3D &&
28914b98343309fdcff3514f05020303f7b40e83a4aBrian         stImage->base.Depth == 1)))
29024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      return;
29124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
29224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   /* If this image disrespects BaseLevel, allocate from level zero.
29324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian    * Usually BaseLevel == 0, so it's unlikely to happen.
29424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian    */
29514b98343309fdcff3514f05020303f7b40e83a4aBrian   if (stImage->level < stObj->base.BaseLevel)
29624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      firstLevel = 0;
29724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   else
29814b98343309fdcff3514f05020303f7b40e83a4aBrian      firstLevel = stObj->base.BaseLevel;
29924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
30024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
30124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   /* Figure out image dimensions at start level.
30224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian    */
30314b98343309fdcff3514f05020303f7b40e83a4aBrian   for (i = stImage->level; i > firstLevel; i--) {
30445cc35e77600af8628393475405160e26d56d421Brian Paul      if (width != 1)
30545cc35e77600af8628393475405160e26d56d421Brian Paul         width <<= 1;
30624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      if (height != 1)
30724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian         height <<= 1;
30824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      if (depth != 1)
30924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian         depth <<= 1;
31024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   }
31124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
312296378b6c8b205048244746e260739448c4ee590Brian Paul   if (width == 0 || height == 0 || depth == 0) {
313296378b6c8b205048244746e260739448c4ee590Brian Paul      /* no texture needed */
314296378b6c8b205048244746e260739448c4ee590Brian Paul      return;
315296378b6c8b205048244746e260739448c4ee590Brian Paul   }
316296378b6c8b205048244746e260739448c4ee590Brian Paul
31724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   /* Guess a reasonable value for lastLevel.  This is probably going
31824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian    * to be wrong fairly often and might mean that we have to look at
31924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian    * resizable buffers, or require that buffers implement lazy
32024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian    * pagetable arrangements.
32124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian    */
32214b98343309fdcff3514f05020303f7b40e83a4aBrian   if ((stObj->base.MinFilter == GL_NEAREST ||
32314b98343309fdcff3514f05020303f7b40e83a4aBrian        stObj->base.MinFilter == GL_LINEAR) &&
32414b98343309fdcff3514f05020303f7b40e83a4aBrian       stImage->level == firstLevel) {
32524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      lastLevel = firstLevel;
32624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   }
32724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   else {
328f52f5136e6eed23e55098681e5b082cc452136d6Brian      GLuint l2width = logbase2(width);
329f52f5136e6eed23e55098681e5b082cc452136d6Brian      GLuint l2height = logbase2(height);
330f52f5136e6eed23e55098681e5b082cc452136d6Brian      GLuint l2depth = logbase2(depth);
33124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      lastLevel = firstLevel + MAX2(MAX2(l2width, l2height), l2depth);
33224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   }
33324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
33414b98343309fdcff3514f05020303f7b40e83a4aBrian   if (stImage->base.IsCompressed)
33514b98343309fdcff3514f05020303f7b40e83a4aBrian      comp_byte = compressed_num_bytes(stImage->base.TexFormat->MesaFormat);
336f52f5136e6eed23e55098681e5b082cc452136d6Brian
337a1f95a8bf64f863289b6759caeec76d7e054400eRoland Scheidegger   fmt = st_mesa_format_to_pipe_format(stImage->base.TexFormat->MesaFormat);
338753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer   stObj->pt = st_texture_create(st,
3395390a43ce06b27f6d54bc5f237aa305b6948f2afBrian                                 gl_target_to_pipe(stObj->base.Target),
340a1f95a8bf64f863289b6759caeec76d7e054400eRoland Scheidegger                                 fmt,
3415390a43ce06b27f6d54bc5f237aa305b6948f2afBrian                                 lastLevel,
3425390a43ce06b27f6d54bc5f237aa305b6948f2afBrian                                 width,
3435390a43ce06b27f6d54bc5f237aa305b6948f2afBrian                                 height,
3445390a43ce06b27f6d54bc5f237aa305b6948f2afBrian                                 depth,
345a73ae3d5eb8419feab5aea26573aa41b72f941ebKeith Whitwell                                 comp_byte,
346a1f95a8bf64f863289b6759caeec76d7e054400eRoland Scheidegger                                 ( (pf_is_depth_stencil(fmt) ?
347a1f95a8bf64f863289b6759caeec76d7e054400eRoland Scheidegger                                   PIPE_TEXTURE_USAGE_DEPTH_STENCIL :
348a1f95a8bf64f863289b6759caeec76d7e054400eRoland Scheidegger                                   PIPE_TEXTURE_USAGE_RENDER_TARGET) |
349a73ae3d5eb8419feab5aea26573aa41b72f941ebKeith Whitwell                                   PIPE_TEXTURE_USAGE_SAMPLER ));
35024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
35124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   DBG("%s - success\n", __FUNCTION__);
35224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian}
35324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
35424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
35524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian/* There are actually quite a few combinations this will work for,
35624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * more than what I've listed here.
35724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */
35824df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic GLboolean
35924df8f895fe8807aa2ba058e71bd40adfc01d21eBriancheck_pbo_format(GLint internalFormat,
36024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                 GLenum format, GLenum type,
36124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                 const struct gl_texture_format *mesa_format)
36224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{
36324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   switch (internalFormat) {
36424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   case 4:
36524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   case GL_RGBA:
36624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      return (format == GL_BGRA &&
36724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian              (type == GL_UNSIGNED_BYTE ||
36824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian               type == GL_UNSIGNED_INT_8_8_8_8_REV) &&
36924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian              mesa_format == &_mesa_texformat_argb8888);
37024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   case 3:
37124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   case GL_RGB:
37224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      return (format == GL_RGB &&
37324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian              type == GL_UNSIGNED_SHORT_5_6_5 &&
37424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian              mesa_format == &_mesa_texformat_rgb565);
37524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   case GL_YCBCR_MESA:
37624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      return (type == GL_UNSIGNED_SHORT_8_8_MESA || type == GL_UNSIGNED_BYTE);
37724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   default:
37824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      return GL_FALSE;
37924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   }
38024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian}
38124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
38224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
38324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian/* XXX: Do this for TexSubImage also:
38424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */
38524df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic GLboolean
38624df8f895fe8807aa2ba058e71bd40adfc01d21eBriantry_pbo_upload(GLcontext *ctx,
38714b98343309fdcff3514f05020303f7b40e83a4aBrian               struct st_texture_image *stImage,
38824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian               const struct gl_pixelstore_attrib *unpack,
38924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian               GLint internalFormat,
39024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian               GLint width, GLint height,
39124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian               GLenum format, GLenum type, const void *pixels)
39224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{
39324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   return GL_FALSE;  /* XXX fix flushing/locking/blitting below */
39424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#if 000
39524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   struct intel_context *intel = intel_context(ctx);
39624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   struct intel_buffer_object *pbo = intel_buffer_object(unpack->BufferObj);
39724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   GLuint src_offset, src_stride;
39824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   GLuint dst_offset, dst_stride;
39924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
40024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   if (!pbo ||
40124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian       ctx._ImageTransferState ||
40224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian       unpack->SkipPixels || unpack->SkipRows) {
40324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      _mesa_printf("%s: failure 1\n", __FUNCTION__);
40424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      return GL_FALSE;
40524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   }
40624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
40724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   src_offset = (GLuint) pixels;
40824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
40924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   if (unpack->RowLength > 0)
41024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      src_stride = unpack->RowLength;
41124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   else
41224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      src_stride = width;
41324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
414753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer   dst_offset = st_texture_image_offset(stImage->pt,
41514b98343309fdcff3514f05020303f7b40e83a4aBrian                                           stImage->face,
41614b98343309fdcff3514f05020303f7b40e83a4aBrian                                           stImage->level);
41724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
418753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer   dst_stride = stImage->pt->pitch;
41924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
42024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   {
42124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      struct _DriBufferObject *src_buffer =
42224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian         intel_bufferobj_buffer(intel, pbo, INTEL_READ);
42324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
42424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      /* Temporary hack: cast to _DriBufferObject:
42524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian       */
42624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      struct _DriBufferObject *dst_buffer =
427753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer         (struct _DriBufferObject *)stImage->pt->region->buffer;
42824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
42924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
43024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      intelEmitCopyBlit(intel,
431753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer                        stImage->pt->cpp,
43224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                        src_stride, src_buffer, src_offset,
43324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                        dst_stride, dst_buffer, dst_offset,
43424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                        0, 0, 0, 0, width, height,
43524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian			GL_COPY);
43624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   }
43724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
43824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   return GL_TRUE;
43924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#endif
44024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian}
44124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
44224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
443212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian/**
444212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian * Adjust pixel unpack params and image dimensions to strip off the
445212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian * texture border.
446212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian * Gallium doesn't support texture borders.  They've seldem been used
447212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian * and seldom been implemented correctly anyway.
448212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian * \param unpackNew  returns the new pixel unpack parameters
449212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian */
450212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brianstatic void
451212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brianstrip_texture_border(GLint border,
452212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian                     GLint *width, GLint *height, GLint *depth,
453212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian                     const struct gl_pixelstore_attrib *unpack,
454212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian                     struct gl_pixelstore_attrib *unpackNew)
455212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian{
456212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian   assert(border > 0);  /* sanity check */
457212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian
458212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian   *unpackNew = *unpack;
459212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian
460212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian   if (unpackNew->RowLength == 0)
461212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian      unpackNew->RowLength = *width;
462212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian
463212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian   if (depth && unpackNew->ImageHeight == 0)
464212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian      unpackNew->ImageHeight = *height;
465212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian
466212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian   unpackNew->SkipPixels += border;
467212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian   if (height)
468212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian      unpackNew->SkipRows += border;
469212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian   if (depth)
470212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian      unpackNew->SkipImages += border;
471212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian
472212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian   assert(*width >= 3);
473212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian   *width = *width - 2 * border;
474212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian   if (height && *height >= 3)
475212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian      *height = *height - 2 * border;
476212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian   if (depth && *depth >= 3)
477212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian      *depth = *depth - 2 * border;
478212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian}
479212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian
48024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
48124df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void
48224df8f895fe8807aa2ba058e71bd40adfc01d21eBrianst_TexImage(GLcontext * ctx,
483afc54983370033b65e3a7cbb29bd9c87156f0881Brian            GLint dims,
484afc54983370033b65e3a7cbb29bd9c87156f0881Brian            GLenum target, GLint level,
485afc54983370033b65e3a7cbb29bd9c87156f0881Brian            GLint internalFormat,
486afc54983370033b65e3a7cbb29bd9c87156f0881Brian            GLint width, GLint height, GLint depth,
487afc54983370033b65e3a7cbb29bd9c87156f0881Brian            GLint border,
488afc54983370033b65e3a7cbb29bd9c87156f0881Brian            GLenum format, GLenum type, const void *pixels,
489afc54983370033b65e3a7cbb29bd9c87156f0881Brian            const struct gl_pixelstore_attrib *unpack,
490afc54983370033b65e3a7cbb29bd9c87156f0881Brian            struct gl_texture_object *texObj,
491afc54983370033b65e3a7cbb29bd9c87156f0881Brian            struct gl_texture_image *texImage,
492afc54983370033b65e3a7cbb29bd9c87156f0881Brian            GLsizei imageSize, int compressed)
49324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{
49414b98343309fdcff3514f05020303f7b40e83a4aBrian   struct st_texture_object *stObj = st_texture_object(texObj);
49514b98343309fdcff3514f05020303f7b40e83a4aBrian   struct st_texture_image *stImage = st_texture_image(texImage);
496212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian   GLint postConvWidth, postConvHeight;
49724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   GLint texelBytes, sizeInBytes;
49824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   GLuint dstRowStride;
499212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian   struct gl_pixelstore_attrib unpackNB;
50024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
50124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   DBG("%s target %s level %d %dx%dx%d border %d\n", __FUNCTION__,
50224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian       _mesa_lookup_enum_by_nr(target), level, width, height, depth, border);
50324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
504212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian   /* gallium does not support texture borders, strip it off */
505212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian   if (border) {
506212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian      strip_texture_border(border, &width, &height, &depth,
507212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian                           unpack, &unpackNB);
508212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian      unpack = &unpackNB;
50921989edd55409d72ee55187f4f9062496ca3fbf8Brian Paul      texImage->Width = width;
51021989edd55409d72ee55187f4f9062496ca3fbf8Brian Paul      texImage->Height = height;
51121989edd55409d72ee55187f4f9062496ca3fbf8Brian Paul      texImage->Depth = depth;
51221989edd55409d72ee55187f4f9062496ca3fbf8Brian Paul      texImage->Border = 0;
513212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian      border = 0;
514212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian   }
515212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian
516212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian   postConvWidth = width;
517212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian   postConvHeight = height;
518212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian
519cfe9e66f2bc596c43760911e7c1604bb32cdee28Brian   stImage->face = _mesa_tex_target_to_face(target);
52014b98343309fdcff3514f05020303f7b40e83a4aBrian   stImage->level = level;
52124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
522b19e8f720bb2f4d360f5497b64901fc48321f172Brian Paul#if FEATURE_convolution
52324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   if (ctx->_ImageTransferState & IMAGE_CONVOLUTION_BIT) {
52424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      _mesa_adjust_image_for_convolution(ctx, dims, &postConvWidth,
52524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                                         &postConvHeight);
52624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   }
527b19e8f720bb2f4d360f5497b64901fc48321f172Brian Paul#endif
52824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
52924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   /* choose the texture format */
53024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   texImage->TexFormat = st_ChooseTextureFormat(ctx, internalFormat,
531afc54983370033b65e3a7cbb29bd9c87156f0881Brian                                                format, type);
53224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
53324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   _mesa_set_fetch_functions(texImage, dims);
53424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
53524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   if (texImage->TexFormat->TexelBytes == 0) {
53624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      /* must be a compressed format */
53724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      texelBytes = 0;
53824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      texImage->IsCompressed = GL_TRUE;
53924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      texImage->CompressedSize =
54024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian	 ctx->Driver.CompressedTextureSize(ctx, texImage->Width,
54124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian					   texImage->Height, texImage->Depth,
54224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian					   texImage->TexFormat->MesaFormat);
543afc54983370033b65e3a7cbb29bd9c87156f0881Brian   }
544afc54983370033b65e3a7cbb29bd9c87156f0881Brian   else {
54524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      texelBytes = texImage->TexFormat->TexelBytes;
54624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
54724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      /* Minimum pitch of 32 bytes */
54824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      if (postConvWidth * texelBytes < 32) {
54924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian	 postConvWidth = 32 / texelBytes;
55024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian	 texImage->RowStride = postConvWidth;
55124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      }
55224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
5537585b4ceb8fed862c07f50af8030a6f0eb8a8321Brian      /* we'll set RowStride elsewhere when the texture is a "mapped" state */
5547585b4ceb8fed862c07f50af8030a6f0eb8a8321Brian      /*assert(texImage->RowStride == postConvWidth);*/
55524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   }
55624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
55724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   /* Release the reference to a potentially orphaned buffer.
55824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian    * Release any old malloced memory.
55924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian    */
560753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer   if (stImage->pt) {
561f8dce51083042b4d3fabf48524835290b6725682Brian Paul      pipe_texture_reference(&stImage->pt, NULL);
56224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      assert(!texImage->Data);
56324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   }
56424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   else if (texImage->Data) {
56524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      _mesa_align_free(texImage->Data);
56624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   }
56724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
5684da1cdf78fa3b954840650fa46cf72da5daf149fBrian   /* If this is the only mipmap level in the texture, could call
56924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian    * bmBufferData with NULL data to free the old block and avoid
57024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian    * waiting on any outstanding fences.
57124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian    */
572753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer   if (stObj->pt &&
573d4074c509b5d28be0a2ec51d40329e1aed7047efMichel Dänzer       (stObj->teximage_realloc ||
574d4074c509b5d28be0a2ec51d40329e1aed7047efMichel Dänzer        (/*stObj->pt->first_level == level &&*/
575d4074c509b5d28be0a2ec51d40329e1aed7047efMichel Dänzer         stObj->pt->last_level == level &&
576d4074c509b5d28be0a2ec51d40329e1aed7047efMichel Dänzer         stObj->pt->target != PIPE_TEXTURE_CUBE &&
577d4074c509b5d28be0a2ec51d40329e1aed7047efMichel Dänzer         !st_texture_match_image(stObj->pt, &stImage->base,
578d4074c509b5d28be0a2ec51d40329e1aed7047efMichel Dänzer                                 stImage->face, stImage->level)))) {
57924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
58024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      DBG("release it\n");
581f8dce51083042b4d3fabf48524835290b6725682Brian Paul      pipe_texture_reference(&stObj->pt, NULL);
582753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer      assert(!stObj->pt);
583d4074c509b5d28be0a2ec51d40329e1aed7047efMichel Dänzer      stObj->teximage_realloc = FALSE;
58424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   }
58524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
586753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer   if (!stObj->pt) {
587753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer      guess_and_alloc_texture(ctx->st, stObj, stImage);
588753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer      if (!stObj->pt) {
5893b3774b1227743147159676795b542c0eb7c2bdfBrian Paul         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage");
5903b3774b1227743147159676795b542c0eb7c2bdfBrian Paul         return;
59124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      }
59224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   }
59324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
594753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer   assert(!stImage->pt);
59524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
596753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer   if (stObj->pt &&
597753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer       st_texture_match_image(stObj->pt, &stImage->base,
59814b98343309fdcff3514f05020303f7b40e83a4aBrian                                 stImage->face, stImage->level)) {
59924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
6004da19dbcaa9f3e2d20fffd0145bf0bc756dd7542Brian      pipe_texture_reference(&stImage->pt, stObj->pt);
601753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer      assert(stImage->pt);
60224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   }
60324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
604753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer   if (!stImage->pt)
605753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer      DBG("XXX: Image did not fit into texture - storing in local memory!\n");
60624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
60724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#if 0 /* XXX FIX when st_buffer_objects are in place */
60824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   /* PBO fastpaths:
60924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian    */
61024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   if (dims <= 2 &&
611753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer       stImage->pt &&
61224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian       intel_buffer_object(unpack->BufferObj) &&
61324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian       check_pbo_format(internalFormat, format,
614753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer                        type, texImage->TexFormat)) {
61524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
61624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      DBG("trying pbo upload\n");
61724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
61824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
61924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
62024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      /* Otherwise, attempt to use the blitter for PBO image uploads.
62124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian       */
62214b98343309fdcff3514f05020303f7b40e83a4aBrian      if (try_pbo_upload(intel, stImage, unpack,
62324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                         internalFormat,
62424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                         width, height, format, type, pixels)) {
62524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian         DBG("pbo upload succeeded\n");
62624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian         return;
62724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      }
62824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
62924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      DBG("pbo upload failed\n");
63024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   }
63124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#else
63224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   (void) try_pbo_upload;
63324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   (void) check_pbo_format;
63424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#endif
63524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
63624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
637987d59bb83e9e08192563e5f1b52949c5511053cMichel Dänzer   /* st_CopyTexImage calls this function with pixels == NULL, with
638753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer    * the expectation that the texture will be set up but nothing
63924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian    * more will be done.  This is where those calls return:
64024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian    */
64124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   if (compressed) {
64224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      pixels = _mesa_validate_pbo_compressed_teximage(ctx, imageSize, pixels,
64324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian						      unpack,
64424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian						      "glCompressedTexImage");
64524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   } else {
64624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      pixels = _mesa_validate_pbo_teximage(ctx, dims, width, height, 1,
64724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian					   format, type,
64824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian					   pixels, unpack, "glTexImage");
64924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   }
65024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   if (!pixels)
65124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      return;
65224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
653753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer   if (stImage->pt) {
654c9ed86a96483063f3d6789ed16645a3dca77d726Keith Whitwell      texImage->Data = st_texture_image_map(ctx->st, stImage, 0,
655c9ed86a96483063f3d6789ed16645a3dca77d726Keith Whitwell                                            PIPE_BUFFER_USAGE_CPU_WRITE);
6562a39dbe7364af5444b1eb43650dfc31ed09257dcBrian Paul      if (stImage->surface)
6572a39dbe7364af5444b1eb43650dfc31ed09257dcBrian Paul         dstRowStride = stImage->surface->pitch * stImage->surface->cpp;
65824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   }
65924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   else {
66024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      /* Allocate regular memory and store the image there temporarily.   */
66124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      if (texImage->IsCompressed) {
66224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian         sizeInBytes = texImage->CompressedSize;
66324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian         dstRowStride =
66424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian            _mesa_compressed_row_stride(texImage->TexFormat->MesaFormat, width);
66524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian         assert(dims != 3);
66624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      }
66724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      else {
66824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian         dstRowStride = postConvWidth * texelBytes;
66924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian         sizeInBytes = depth * dstRowStride * postConvHeight;
67024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      }
67124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
67224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      texImage->Data = malloc(sizeInBytes);
67324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   }
67424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
6752a39dbe7364af5444b1eb43650dfc31ed09257dcBrian Paul   if (!texImage->Data) {
6762a39dbe7364af5444b1eb43650dfc31ed09257dcBrian Paul      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage");
6772a39dbe7364af5444b1eb43650dfc31ed09257dcBrian Paul      return;
6782a39dbe7364af5444b1eb43650dfc31ed09257dcBrian Paul   }
6792a39dbe7364af5444b1eb43650dfc31ed09257dcBrian Paul
68024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   DBG("Upload image %dx%dx%d row_len %x pitch %x\n",
68124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian       width, height, depth, width * texelBytes, dstRowStride);
68224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
68324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   /* Copy data.  Would like to know when it's ok for us to eg. use
68424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian    * the blitter to copy.  Or, use the hardware to do the format
68524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian    * conversion and copy:
68624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian    */
68724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   if (compressed) {
688afc54983370033b65e3a7cbb29bd9c87156f0881Brian      memcpy(texImage->Data, pixels, imageSize);
68924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   }
690753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer   else {
691753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer      GLuint srcImageStride = _mesa_image_image_stride(unpack, width, height,
692753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer						       format, type);
693753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer      int i;
6945823f99d0fbc054b87aeb1bc15d413d3eadd27a8Brian      const GLubyte *src = (const GLubyte *) pixels;
695753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer
696753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer      for (i = 0; i++ < depth;) {
697753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer	 if (!texImage->TexFormat->StoreImage(ctx, dims,
698753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer					      texImage->_BaseFormat,
699753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer					      texImage->TexFormat,
700753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer					      texImage->Data,
701753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer					      0, 0, 0, /* dstX/Y/Zoffset */
702753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer					      dstRowStride,
703753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer					      texImage->ImageOffsets,
704753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer					      width, height, 1,
7055823f99d0fbc054b87aeb1bc15d413d3eadd27a8Brian					      format, type, src, unpack)) {
706753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer	    _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage");
707753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer	 }
708753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer
709753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer	 if (stImage->pt && i < depth) {
710c9ed86a96483063f3d6789ed16645a3dca77d726Keith Whitwell	    st_texture_image_unmap(ctx->st, stImage);
711c9ed86a96483063f3d6789ed16645a3dca77d726Keith Whitwell	    texImage->Data = st_texture_image_map(ctx->st, stImage, i,
712c9ed86a96483063f3d6789ed16645a3dca77d726Keith Whitwell                                                  PIPE_BUFFER_USAGE_CPU_WRITE);
7135823f99d0fbc054b87aeb1bc15d413d3eadd27a8Brian	    src += srcImageStride;
714753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer	 }
715753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer      }
71624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   }
71724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
71824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   _mesa_unmap_teximage_pbo(ctx, unpack);
71924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
720753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer   if (stImage->pt) {
721c9ed86a96483063f3d6789ed16645a3dca77d726Keith Whitwell      st_texture_image_unmap(ctx->st, stImage);
72224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      texImage->Data = NULL;
72324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   }
72424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
72524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
72662abcb9aacc33218d0143a743c738435794b32a9Brian      ctx->Driver.GenerateMipmap(ctx, target, texObj);
72724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   }
72824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian}
72924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
73024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
73124df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void
73224df8f895fe8807aa2ba058e71bd40adfc01d21eBrianst_TexImage3D(GLcontext * ctx,
73324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                GLenum target, GLint level,
73424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                GLint internalFormat,
73524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                GLint width, GLint height, GLint depth,
73624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                GLint border,
73724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                GLenum format, GLenum type, const void *pixels,
73824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                const struct gl_pixelstore_attrib *unpack,
73924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                struct gl_texture_object *texObj,
74024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                struct gl_texture_image *texImage)
74124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{
74224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   st_TexImage(ctx, 3, target, level,
74324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                 internalFormat, width, height, depth, border,
74424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                 format, type, pixels, unpack, texObj, texImage, 0, 0);
74524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian}
74624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
74724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
74824df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void
74924df8f895fe8807aa2ba058e71bd40adfc01d21eBrianst_TexImage2D(GLcontext * ctx,
75024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                GLenum target, GLint level,
75124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                GLint internalFormat,
75224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                GLint width, GLint height, GLint border,
75324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                GLenum format, GLenum type, const void *pixels,
75424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                const struct gl_pixelstore_attrib *unpack,
75524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                struct gl_texture_object *texObj,
75624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                struct gl_texture_image *texImage)
75724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{
75824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   st_TexImage(ctx, 2, target, level,
75924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                 internalFormat, width, height, 1, border,
76024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                 format, type, pixels, unpack, texObj, texImage, 0, 0);
76124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian}
76224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
76324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
76424df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void
76524df8f895fe8807aa2ba058e71bd40adfc01d21eBrianst_TexImage1D(GLcontext * ctx,
76624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                GLenum target, GLint level,
76724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                GLint internalFormat,
76824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                GLint width, GLint border,
76924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                GLenum format, GLenum type, const void *pixels,
77024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                const struct gl_pixelstore_attrib *unpack,
77124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                struct gl_texture_object *texObj,
77224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                struct gl_texture_image *texImage)
77324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{
77424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   st_TexImage(ctx, 1, target, level,
77524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                 internalFormat, width, 1, 1, border,
77624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                 format, type, pixels, unpack, texObj, texImage, 0, 0);
77724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian}
77824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
77924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
78024df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void
78124df8f895fe8807aa2ba058e71bd40adfc01d21eBrianst_CompressedTexImage2D( GLcontext *ctx, GLenum target, GLint level,
78224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian				GLint internalFormat,
78324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian				GLint width, GLint height, GLint border,
78424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian				GLsizei imageSize, const GLvoid *data,
78524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian				struct gl_texture_object *texObj,
78624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian				struct gl_texture_image *texImage )
78724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{
78824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   st_TexImage(ctx, 2, target, level,
78924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian		 internalFormat, width, height, 1, border,
79024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian		 0, 0, data, &ctx->Unpack, texObj, texImage, imageSize, 1);
79124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian}
79224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
79324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
79424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian/**
79524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * Need to map texture image into memory before copying image data,
79624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * then unmap it.
79724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */
79824df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void
79924df8f895fe8807aa2ba058e71bd40adfc01d21eBrianst_get_tex_image(GLcontext * ctx, GLenum target, GLint level,
80024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                 GLenum format, GLenum type, GLvoid * pixels,
80124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                 struct gl_texture_object *texObj,
80224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                 struct gl_texture_image *texImage, int compressed)
80324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{
80424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   struct st_texture_image *stImage = st_texture_image(texImage);
805753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer   GLuint dstImageStride = _mesa_image_image_stride(&ctx->Pack, texImage->Width,
806753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer						    texImage->Height, format,
807753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer						    type);
808753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer   GLuint depth;
809753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer   int i;
8105823f99d0fbc054b87aeb1bc15d413d3eadd27a8Brian   GLubyte *dest;
81124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
81224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   /* Map */
813753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer   if (stImage->pt) {
81424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      /* Image is stored in hardware format in a buffer managed by the
81524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian       * kernel.  Need to explicitly map and unmap it.
81624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian       */
817c9ed86a96483063f3d6789ed16645a3dca77d726Keith Whitwell      texImage->Data = st_texture_image_map(ctx->st, stImage, 0,
818c9ed86a96483063f3d6789ed16645a3dca77d726Keith Whitwell                                            PIPE_BUFFER_USAGE_CPU_READ);
819753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer      texImage->RowStride = stImage->surface->pitch;
82024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   }
82124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   else {
82224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      /* Otherwise, the image should actually be stored in
823753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer       * texImage->Data.  This is pretty confusing for
82424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian       * everybody, I'd much prefer to separate the two functions of
82524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian       * texImage->Data - storage for texture images in main memory
82624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian       * and access (ie mappings) of images.  In other words, we'd
82724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian       * create a new texImage->Map field and leave Data simply for
82824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian       * storage.
82924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian       */
830753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer      assert(texImage->Data);
83124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   }
83224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
833753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer   depth = texImage->Depth;
834753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer   texImage->Depth = 1;
83524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
8365823f99d0fbc054b87aeb1bc15d413d3eadd27a8Brian   dest = (GLubyte *) pixels;
8375823f99d0fbc054b87aeb1bc15d413d3eadd27a8Brian
838753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer   for (i = 0; i++ < depth;) {
839753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer      if (compressed) {
8405823f99d0fbc054b87aeb1bc15d413d3eadd27a8Brian	 _mesa_get_compressed_teximage(ctx, target, level, dest,
841753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer				       texObj, texImage);
842753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer      } else {
8435823f99d0fbc054b87aeb1bc15d413d3eadd27a8Brian	 _mesa_get_teximage(ctx, target, level, format, type, dest,
844753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer			    texObj, texImage);
845753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer      }
846753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer
847753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer      if (stImage->pt && i < depth) {
848c9ed86a96483063f3d6789ed16645a3dca77d726Keith Whitwell	 st_texture_image_unmap(ctx->st, stImage);
849c9ed86a96483063f3d6789ed16645a3dca77d726Keith Whitwell	 texImage->Data = st_texture_image_map(ctx->st, stImage, i,
850c9ed86a96483063f3d6789ed16645a3dca77d726Keith Whitwell                                               PIPE_BUFFER_USAGE_CPU_READ);
8515823f99d0fbc054b87aeb1bc15d413d3eadd27a8Brian	 dest += dstImageStride;
852753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer      }
85324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   }
854753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer
855753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer   texImage->Depth = depth;
85624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
85724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   /* Unmap */
858753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer   if (stImage->pt) {
859c9ed86a96483063f3d6789ed16645a3dca77d726Keith Whitwell      st_texture_image_unmap(ctx->st, stImage);
860753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer      texImage->Data = NULL;
86124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   }
86224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian}
86324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
86424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
86524df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void
86624df8f895fe8807aa2ba058e71bd40adfc01d21eBrianst_GetTexImage(GLcontext * ctx, GLenum target, GLint level,
86724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                 GLenum format, GLenum type, GLvoid * pixels,
86824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                 struct gl_texture_object *texObj,
86924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                 struct gl_texture_image *texImage)
87024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{
87124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   st_get_tex_image(ctx, target, level, format, type, pixels,
87224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                    texObj, texImage, 0);
87324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian}
87424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
87524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
87624df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void
87724df8f895fe8807aa2ba058e71bd40adfc01d21eBrianst_GetCompressedTexImage(GLcontext *ctx, GLenum target, GLint level,
87824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian			   GLvoid *pixels,
87924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian			   const struct gl_texture_object *texObj,
88024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian			   const struct gl_texture_image *texImage)
88124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{
88224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   st_get_tex_image(ctx, target, level, 0, 0, pixels,
88324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                    (struct gl_texture_object *) texObj,
88424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                    (struct gl_texture_image *) texImage, 1);
88524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian}
88624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
88724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
88824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
88924df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void
89024df8f895fe8807aa2ba058e71bd40adfc01d21eBrianst_TexSubimage(GLcontext * ctx,
89124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                 GLint dims,
89224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                 GLenum target, GLint level,
89324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                 GLint xoffset, GLint yoffset, GLint zoffset,
89424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                 GLint width, GLint height, GLint depth,
89524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                 GLenum format, GLenum type, const void *pixels,
89624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                 const struct gl_pixelstore_attrib *packing,
89724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                 struct gl_texture_object *texObj,
89824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                 struct gl_texture_image *texImage)
89924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{
90024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   struct st_texture_image *stImage = st_texture_image(texImage);
90124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   GLuint dstRowStride;
902753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer   GLuint srcImageStride = _mesa_image_image_stride(packing, width, height,
903753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer						    format, type);
904753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer   int i;
9055823f99d0fbc054b87aeb1bc15d413d3eadd27a8Brian   const GLubyte *src;
90624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
90724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   DBG("%s target %s level %d offset %d,%d %dx%d\n", __FUNCTION__,
90824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian       _mesa_lookup_enum_by_nr(target),
90924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian       level, xoffset, yoffset, width, height);
91024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
91124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   pixels =
91224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      _mesa_validate_pbo_teximage(ctx, dims, width, height, depth, format,
91324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                                  type, pixels, packing, "glTexSubImage2D");
91424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   if (!pixels)
91524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      return;
91624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
91724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   /* Map buffer if necessary.  Need to lock to prevent other contexts
91824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian    * from uploading the buffer under us.
91924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian    */
920753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer   if (stImage->pt) {
921c9ed86a96483063f3d6789ed16645a3dca77d726Keith Whitwell      texImage->Data = st_texture_image_map(ctx->st, stImage, zoffset,
922c9ed86a96483063f3d6789ed16645a3dca77d726Keith Whitwell                                            PIPE_BUFFER_USAGE_CPU_WRITE);
9232a39dbe7364af5444b1eb43650dfc31ed09257dcBrian Paul      if (stImage->surface)
9242a39dbe7364af5444b1eb43650dfc31ed09257dcBrian Paul         dstRowStride = stImage->surface->pitch * stImage->surface->cpp;
925753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer   }
926753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer
9279b44f5a7550d8ede2eda763770e927df4c15cc8eBrian Paul   if (!texImage->Data) {
9289b44f5a7550d8ede2eda763770e927df4c15cc8eBrian Paul      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage");
9299b44f5a7550d8ede2eda763770e927df4c15cc8eBrian Paul      return;
9309b44f5a7550d8ede2eda763770e927df4c15cc8eBrian Paul   }
9319b44f5a7550d8ede2eda763770e927df4c15cc8eBrian Paul
9325823f99d0fbc054b87aeb1bc15d413d3eadd27a8Brian   src = (const GLubyte *) pixels;
9335823f99d0fbc054b87aeb1bc15d413d3eadd27a8Brian
934753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer   for (i = 0; i++ < depth;) {
935753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer      if (!texImage->TexFormat->StoreImage(ctx, dims, texImage->_BaseFormat,
936753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer					   texImage->TexFormat,
937753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer					   texImage->Data,
938753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer					   xoffset, yoffset, 0,
939753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer					   dstRowStride,
940753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer					   texImage->ImageOffsets,
941753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer					   width, height, 1,
9425823f99d0fbc054b87aeb1bc15d413d3eadd27a8Brian					   format, type, src, packing)) {
9439b44f5a7550d8ede2eda763770e927df4c15cc8eBrian Paul	 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage");
944753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer      }
945753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer
946753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer      if (stImage->pt && i < depth) {
9479b44f5a7550d8ede2eda763770e927df4c15cc8eBrian Paul         /* map next slice of 3D texture */
948c9ed86a96483063f3d6789ed16645a3dca77d726Keith Whitwell	 st_texture_image_unmap(ctx->st, stImage);
949c9ed86a96483063f3d6789ed16645a3dca77d726Keith Whitwell	 texImage->Data = st_texture_image_map(ctx->st, stImage, zoffset + i,
950c9ed86a96483063f3d6789ed16645a3dca77d726Keith Whitwell                                               PIPE_BUFFER_USAGE_CPU_WRITE);
9515823f99d0fbc054b87aeb1bc15d413d3eadd27a8Brian	 src += srcImageStride;
952753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer      }
95324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   }
95424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
95524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
9563ccbaa977f96eaa849093875dd0944f744ee1e21Brian      ctx->Driver.GenerateMipmap(ctx, target, texObj);
95724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   }
95824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
95924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   _mesa_unmap_teximage_pbo(ctx, packing);
96024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
961753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer   if (stImage->pt) {
962c9ed86a96483063f3d6789ed16645a3dca77d726Keith Whitwell      st_texture_image_unmap(ctx->st, stImage);
96324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      texImage->Data = NULL;
96424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   }
96524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian}
96624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
96724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
96824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
96924df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void
97024df8f895fe8807aa2ba058e71bd40adfc01d21eBrianst_TexSubImage3D(GLcontext * ctx,
97124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                   GLenum target,
97224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                   GLint level,
97324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                   GLint xoffset, GLint yoffset, GLint zoffset,
97424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                   GLsizei width, GLsizei height, GLsizei depth,
97524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                   GLenum format, GLenum type,
97624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                   const GLvoid * pixels,
97724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                   const struct gl_pixelstore_attrib *packing,
97824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                   struct gl_texture_object *texObj,
97924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                   struct gl_texture_image *texImage)
98024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{
981b245840b86cf877c9b8d666edf229364a84f1deaBrian   st_TexSubimage(ctx, 3, target, level,
982b245840b86cf877c9b8d666edf229364a84f1deaBrian                  xoffset, yoffset, zoffset,
983b245840b86cf877c9b8d666edf229364a84f1deaBrian                  width, height, depth,
984b245840b86cf877c9b8d666edf229364a84f1deaBrian                  format, type, pixels, packing, texObj, texImage);
98524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian}
98624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
98724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
98824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
98924df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void
99024df8f895fe8807aa2ba058e71bd40adfc01d21eBrianst_TexSubImage2D(GLcontext * ctx,
99124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                   GLenum target,
99224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                   GLint level,
99324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                   GLint xoffset, GLint yoffset,
99424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                   GLsizei width, GLsizei height,
99524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                   GLenum format, GLenum type,
99624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                   const GLvoid * pixels,
99724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                   const struct gl_pixelstore_attrib *packing,
99824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                   struct gl_texture_object *texObj,
99924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                   struct gl_texture_image *texImage)
100024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{
1001b245840b86cf877c9b8d666edf229364a84f1deaBrian   st_TexSubimage(ctx, 2, target, level,
1002b245840b86cf877c9b8d666edf229364a84f1deaBrian                  xoffset, yoffset, 0,
1003b245840b86cf877c9b8d666edf229364a84f1deaBrian                  width, height, 1,
1004b245840b86cf877c9b8d666edf229364a84f1deaBrian                  format, type, pixels, packing, texObj, texImage);
100524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian}
100624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
100724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
100824df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void
100924df8f895fe8807aa2ba058e71bd40adfc01d21eBrianst_TexSubImage1D(GLcontext * ctx,
101024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                   GLenum target,
101124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                   GLint level,
101224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                   GLint xoffset,
101324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                   GLsizei width,
101424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                   GLenum format, GLenum type,
101524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                   const GLvoid * pixels,
101624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                   const struct gl_pixelstore_attrib *packing,
101724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                   struct gl_texture_object *texObj,
101824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                   struct gl_texture_image *texImage)
101924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{
1020b245840b86cf877c9b8d666edf229364a84f1deaBrian   st_TexSubimage(ctx, 1, target, level,
1021b245840b86cf877c9b8d666edf229364a84f1deaBrian                  xoffset, 0, 0,
1022b245840b86cf877c9b8d666edf229364a84f1deaBrian                  width, 1, 1,
1023b245840b86cf877c9b8d666edf229364a84f1deaBrian                  format, type, pixels, packing, texObj, texImage);
102424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian}
102524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
102624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
102724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
102824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian/**
1029038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian * Return 0 for GL_TEXTURE_CUBE_MAP_POSITIVE_X,
1030038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian *        1 for GL_TEXTURE_CUBE_MAP_NEGATIVE_X,
1031038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian *        etc.
1032038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian * XXX duplicated from main/teximage.c
1033038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian */
1034038cb561eb094af2f2ba06e18e61246fc0c87c3cBrianstatic uint
1035038cb561eb094af2f2ba06e18e61246fc0c87c3cBriantexture_face(GLenum target)
1036038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian{
1037038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian   if (target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB &&
1038038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian       target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB)
1039038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian      return (GLuint) target - (GLuint) GL_TEXTURE_CUBE_MAP_POSITIVE_X;
1040038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian   else
1041038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian      return 0;
1042038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian}
1043038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian
1044038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian
1045038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian
1046038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian/**
1047b859cdf6f191b4d8b56537c8dc30082a7e2d94b3Michel Dänzer * Do a CopyTexSubImage operation by mapping the source surface and
1048b859cdf6f191b4d8b56537c8dc30082a7e2d94b3Michel Dänzer * dest surface and using get_tile()/put_tile() to access the pixels/texels.
1049c6717a86420d7141013165f7acd50b3c3f751756Brian *
1050c6717a86420d7141013165f7acd50b3c3f751756Brian * Note: srcY=0=TOP of renderbuffer
1051038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian */
1052038cb561eb094af2f2ba06e18e61246fc0c87c3cBrianstatic void
1053038cb561eb094af2f2ba06e18e61246fc0c87c3cBrianfallback_copy_texsubimage(GLcontext *ctx,
1054038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian                          GLenum target,
1055038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian                          GLint level,
1056038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian                          struct st_renderbuffer *strb,
1057038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian                          struct st_texture_image *stImage,
1058038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian                          GLenum baseFormat,
1059038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian                          GLint destX, GLint destY, GLint destZ,
1060038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian                          GLint srcX, GLint srcY,
1061038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian                          GLsizei width, GLsizei height)
1062038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian{
1063038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian   struct pipe_context *pipe = ctx->st->pipe;
10646f715dcc219071e574e363a9db4365c9c31ebbd3Brian   struct pipe_screen *screen = pipe->screen;
1065038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian   const uint face = texture_face(target);
1066753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer   struct pipe_texture *pt = stImage->pt;
1067038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian   struct pipe_surface *src_surf, *dest_surf;
10685c83f1371978472fbe4bba8f686733c6b519874aBrian   GLint row, yStep;
10695c83f1371978472fbe4bba8f686733c6b519874aBrian
107002250c855fbec5299a2d6118fefa0523ec73654cMichel Dänzer   st_flush(ctx->st, PIPE_FLUSH_RENDER_CACHE, NULL);
107102250c855fbec5299a2d6118fefa0523ec73654cMichel Dänzer
10725c83f1371978472fbe4bba8f686733c6b519874aBrian   /* determine bottom-to-top vs. top-to-bottom order */
10735c83f1371978472fbe4bba8f686733c6b519874aBrian   if (st_fb_orientation(ctx->ReadBuffer) == Y_0_TOP) {
10745c83f1371978472fbe4bba8f686733c6b519874aBrian      destY = height - 1 - destY;
10755c83f1371978472fbe4bba8f686733c6b519874aBrian      yStep = -1;
10765c83f1371978472fbe4bba8f686733c6b519874aBrian   }
10775c83f1371978472fbe4bba8f686733c6b519874aBrian   else {
10785c83f1371978472fbe4bba8f686733c6b519874aBrian      yStep = 1;
10795c83f1371978472fbe4bba8f686733c6b519874aBrian   }
1080038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian
1081038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian   src_surf = strb->surface;
1082296378b6c8b205048244746e260739448c4ee590Brian Paul   src_surf = screen->get_tex_surface(screen, strb->texture, face, level, destZ,
1083296378b6c8b205048244746e260739448c4ee590Brian Paul                                       PIPE_BUFFER_USAGE_CPU_READ);
1084038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian
1085c9ed86a96483063f3d6789ed16645a3dca77d726Keith Whitwell   dest_surf = screen->get_tex_surface(screen, pt, face, level, destZ,
1086c9ed86a96483063f3d6789ed16645a3dca77d726Keith Whitwell                                       PIPE_BUFFER_USAGE_CPU_WRITE);
1087038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian
1088cc94863429d8a6cef8dbf861e78701a458d30f5aBrian Paul   assert(width <= MAX_WIDTH);
1089038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian
1090cc94863429d8a6cef8dbf861e78701a458d30f5aBrian Paul   /*
1091cc94863429d8a6cef8dbf861e78701a458d30f5aBrian Paul    * To avoid a large temp memory allocation, do copy row by row.
1092cc94863429d8a6cef8dbf861e78701a458d30f5aBrian Paul    */
1093cc94863429d8a6cef8dbf861e78701a458d30f5aBrian Paul   if (baseFormat == GL_DEPTH_COMPONENT) {
1094cc94863429d8a6cef8dbf861e78701a458d30f5aBrian Paul      const GLboolean scaleOrBias = (ctx->Pixel.DepthScale != 1.0F ||
1095cc94863429d8a6cef8dbf861e78701a458d30f5aBrian Paul                                     ctx->Pixel.DepthBias != 0.0F);
1096cc94863429d8a6cef8dbf861e78701a458d30f5aBrian Paul
1097cc94863429d8a6cef8dbf861e78701a458d30f5aBrian Paul      for (row = 0; row < height; row++, srcY++, destY += yStep) {
1098cc94863429d8a6cef8dbf861e78701a458d30f5aBrian Paul         uint data[MAX_WIDTH];
1099cc94863429d8a6cef8dbf861e78701a458d30f5aBrian Paul         pipe_get_tile_z(pipe, src_surf, srcX, srcY, width, 1, data);
1100cc94863429d8a6cef8dbf861e78701a458d30f5aBrian Paul         if (scaleOrBias) {
1101cc94863429d8a6cef8dbf861e78701a458d30f5aBrian Paul            _mesa_scale_and_bias_depth_uint(ctx, width, data);
1102cc94863429d8a6cef8dbf861e78701a458d30f5aBrian Paul         }
1103cc94863429d8a6cef8dbf861e78701a458d30f5aBrian Paul         pipe_put_tile_z(pipe, dest_surf, destX, destY, width, 1, data);
1104cc94863429d8a6cef8dbf861e78701a458d30f5aBrian Paul      }
1105cc94863429d8a6cef8dbf861e78701a458d30f5aBrian Paul   }
1106cc94863429d8a6cef8dbf861e78701a458d30f5aBrian Paul   else {
1107cc94863429d8a6cef8dbf861e78701a458d30f5aBrian Paul      /* RGBA format */
1108cc94863429d8a6cef8dbf861e78701a458d30f5aBrian Paul      for (row = 0; row < height; row++, srcY++, destY += yStep) {
1109cc94863429d8a6cef8dbf861e78701a458d30f5aBrian Paul         float data[4 * MAX_WIDTH];
1110cc94863429d8a6cef8dbf861e78701a458d30f5aBrian Paul         pipe_get_tile_rgba(pipe, src_surf, srcX, srcY, width, 1, data);
1111cc94863429d8a6cef8dbf861e78701a458d30f5aBrian Paul         /* XXX we're ignoring convolution for now */
1112cc94863429d8a6cef8dbf861e78701a458d30f5aBrian Paul         if (ctx->_ImageTransferState) {
1113cc94863429d8a6cef8dbf861e78701a458d30f5aBrian Paul            _mesa_apply_rgba_transfer_ops(ctx,
1114cc94863429d8a6cef8dbf861e78701a458d30f5aBrian Paul                          ctx->_ImageTransferState & ~IMAGE_CONVOLUTION_BIT,
1115cc94863429d8a6cef8dbf861e78701a458d30f5aBrian Paul                          width, (GLfloat (*)[4]) data);
1116cc94863429d8a6cef8dbf861e78701a458d30f5aBrian Paul         }
1117cc94863429d8a6cef8dbf861e78701a458d30f5aBrian Paul         pipe_put_tile_rgba(pipe, dest_surf, destX, destY, width, 1, data);
11185c83f1371978472fbe4bba8f686733c6b519874aBrian      }
11195c83f1371978472fbe4bba8f686733c6b519874aBrian   }
1120d0279fc4b38c72356a341173317bcd45d9093f45Michel Dänzer
1121d0279fc4b38c72356a341173317bcd45d9093f45Michel Dänzer   screen->tex_surface_release(screen, &dest_surf);
1122296378b6c8b205048244746e260739448c4ee590Brian Paul   screen->tex_surface_release(screen, &src_surf);
1123038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian}
1124038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian
1125038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian
1126038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian
1127038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian
1128038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian/**
1129b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian * Do a CopyTex[Sub]Image using an optimized hardware (blit) path.
1130b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian * Note that the region to copy has already been clip tested.
1131c6717a86420d7141013165f7acd50b3c3f751756Brian *
1132c6717a86420d7141013165f7acd50b3c3f751756Brian * Note: srcY=0=Bottom of renderbuffer
1133c6717a86420d7141013165f7acd50b3c3f751756Brian *
1134b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian * \return GL_TRUE if success, GL_FALSE if failure (use a fallback)
113524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */
1136038cb561eb094af2f2ba06e18e61246fc0c87c3cBrianstatic void
113724df8f895fe8807aa2ba058e71bd40adfc01d21eBriando_copy_texsubimage(GLcontext *ctx,
1138038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian                    GLenum target, GLint level,
1139038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian                    GLint destX, GLint destY, GLint destZ,
1140038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian                    GLint srcX, GLint srcY,
1141038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian                    GLsizei width, GLsizei height)
114224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{
1143038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian   struct gl_texture_unit *texUnit =
1144038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian      &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
1145038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian   struct gl_texture_object *texObj =
1146038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian      _mesa_select_tex_object(ctx, texUnit, target);
1147038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian   struct gl_texture_image *texImage =
1148038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian      _mesa_select_tex_image(ctx, texObj, target, level);
1149038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian   struct st_texture_image *stImage = st_texture_image(texImage);
1150038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian   GLenum baseFormat = texImage->InternalFormat;
1151b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian   struct gl_framebuffer *fb = ctx->ReadBuffer;
1152b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian   struct st_renderbuffer *strb;
1153b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian   struct pipe_context *pipe = ctx->st->pipe;
11546f715dcc219071e574e363a9db4365c9c31ebbd3Brian   struct pipe_screen *screen = pipe->screen;
1155b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian   uint dest_format, src_format;
1156e922adbe1d6c1764968377658ea92ae6de0585dbMichel Dänzer   uint do_flip = FALSE;
1157cc94863429d8a6cef8dbf861e78701a458d30f5aBrian Paul   GLboolean use_fallback = GL_TRUE;
115824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
1159038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian   (void) texImage;
1160038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian
1161b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian   /* determine if copying depth or color data */
1162b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian   if (baseFormat == GL_DEPTH_COMPONENT) {
1163b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian      strb = st_renderbuffer(fb->_DepthBuffer);
116424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   }
1165b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian   else if (baseFormat == GL_DEPTH_STENCIL_EXT) {
1166b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian      strb = st_renderbuffer(fb->_StencilBuffer);
1167b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian   }
1168b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian   else {
1169b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian      /* baseFormat == GL_RGB, GL_RGBA, GL_ALPHA, etc */
1170b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian      strb = st_renderbuffer(fb->_ColorReadBuffer);
1171b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian   }
1172b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian
1173b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian   assert(strb);
1174b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian   assert(strb->surface);
1175753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer   assert(stImage->pt);
1176c6717a86420d7141013165f7acd50b3c3f751756Brian
1177c6717a86420d7141013165f7acd50b3c3f751756Brian   if (st_fb_orientation(ctx->ReadBuffer) == Y_0_TOP) {
1178c6717a86420d7141013165f7acd50b3c3f751756Brian      srcY = strb->Base.Height - srcY - height;
1179e922adbe1d6c1764968377658ea92ae6de0585dbMichel Dänzer      do_flip = TRUE;
1180c6717a86420d7141013165f7acd50b3c3f751756Brian   }
118124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
1182b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian   src_format = strb->surface->format;
1183753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer   dest_format = stImage->pt->format;
1184b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian
118579931e38abc62286151121a3f59127e296144551Michel Dänzer   if (ctx->_ImageTransferState == 0x0) {
1186038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian      /* do blit-style copy */
1187038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian
1188038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian      /* XXX may need to invert image depending on window
1189038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian       * vs. user-created FBO
1190038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian       */
1191b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian
119224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#if 0
1193038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian      /* A bit of fiddling to get the blitter to work with -ve
1194038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian       * pitches.  But we get a nice inverted blit this way, so it's
1195038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian       * worth it:
1196038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian       */
1197038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian      intelEmitCopyBlit(intel,
1198753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer                        stImage->pt->cpp,
1199038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian                        -src->pitch,
1200038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian                        src->buffer,
1201038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian                        src->height * src->pitch * src->cpp,
1202753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer                        stImage->pt->pitch,
1203753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer                        stImage->pt->region->buffer,
1204038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian                        dest_offset,
1205038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian                        x, y + height, dstx, dsty, width, height,
1206038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian                        GL_COPY); /* ? */
120724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#else
120879931e38abc62286151121a3f59127e296144551Michel Dänzer      struct pipe_surface *dest_surface;
120979931e38abc62286151121a3f59127e296144551Michel Dänzer
121079931e38abc62286151121a3f59127e296144551Michel Dänzer      dest_surface = screen->get_tex_surface(screen, stImage->pt, stImage->face,
121179931e38abc62286151121a3f59127e296144551Michel Dänzer                                             stImage->level, destZ,
121279931e38abc62286151121a3f59127e296144551Michel Dänzer                                             PIPE_BUFFER_USAGE_GPU_WRITE);
121379931e38abc62286151121a3f59127e296144551Michel Dänzer
121479931e38abc62286151121a3f59127e296144551Michel Dänzer      assert(strb->surface->buffer);
121579931e38abc62286151121a3f59127e296144551Michel Dänzer      assert(dest_surface->buffer);
1216b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian
12173c0dc8242b64518d5635263ba65b39afa919dd86Michel Dänzer      if (src_format == dest_format) {
12183c0dc8242b64518d5635263ba65b39afa919dd86Michel Dänzer          pipe->surface_copy(pipe,
12193c0dc8242b64518d5635263ba65b39afa919dd86Michel Dänzer			     do_flip,
12203c0dc8242b64518d5635263ba65b39afa919dd86Michel Dänzer			     /* dest */
12213c0dc8242b64518d5635263ba65b39afa919dd86Michel Dänzer			     dest_surface,
12223c0dc8242b64518d5635263ba65b39afa919dd86Michel Dänzer			     destX, destY,
12233c0dc8242b64518d5635263ba65b39afa919dd86Michel Dänzer			     /* src */
12243c0dc8242b64518d5635263ba65b39afa919dd86Michel Dänzer			     strb->surface,
12253c0dc8242b64518d5635263ba65b39afa919dd86Michel Dänzer			     srcX, srcY,
12263c0dc8242b64518d5635263ba65b39afa919dd86Michel Dänzer			     /* size */
12273c0dc8242b64518d5635263ba65b39afa919dd86Michel Dänzer			     width, height);
1228cc94863429d8a6cef8dbf861e78701a458d30f5aBrian Paul          use_fallback = GL_FALSE;
1229cc94863429d8a6cef8dbf861e78701a458d30f5aBrian Paul      }
1230cc94863429d8a6cef8dbf861e78701a458d30f5aBrian Paul      else if (screen->is_format_supported(screen, strb->surface->format,
1231cc94863429d8a6cef8dbf861e78701a458d30f5aBrian Paul                                           PIPE_TEXTURE) &&
1232cc94863429d8a6cef8dbf861e78701a458d30f5aBrian Paul               screen->is_format_supported(screen, dest_surface->format,
1233cc94863429d8a6cef8dbf861e78701a458d30f5aBrian Paul                                           PIPE_SURFACE)) {
12343c0dc8242b64518d5635263ba65b39afa919dd86Michel Dänzer         util_blit_pixels(ctx->st->blit,
12353c0dc8242b64518d5635263ba65b39afa919dd86Michel Dänzer                          strb->surface,
12363c0dc8242b64518d5635263ba65b39afa919dd86Michel Dänzer                          srcX, do_flip ? srcY + height : srcY,
12373c0dc8242b64518d5635263ba65b39afa919dd86Michel Dänzer                          srcX + width, do_flip ? srcY : srcY + height,
12383c0dc8242b64518d5635263ba65b39afa919dd86Michel Dänzer                          dest_surface,
12393c0dc8242b64518d5635263ba65b39afa919dd86Michel Dänzer                          destX, destY, destX + width, destY + height,
12403c0dc8242b64518d5635263ba65b39afa919dd86Michel Dänzer                          0.0, PIPE_TEX_MIPFILTER_NEAREST);
1241cc94863429d8a6cef8dbf861e78701a458d30f5aBrian Paul         use_fallback = GL_FALSE;
12423c0dc8242b64518d5635263ba65b39afa919dd86Michel Dänzer      }
124379931e38abc62286151121a3f59127e296144551Michel Dänzer
124479931e38abc62286151121a3f59127e296144551Michel Dänzer      pipe_surface_reference(&dest_surface, NULL);
124524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#endif
1246038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian   }
1247cc94863429d8a6cef8dbf861e78701a458d30f5aBrian Paul
1248cc94863429d8a6cef8dbf861e78701a458d30f5aBrian Paul   if (use_fallback) {
1249038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian      fallback_copy_texsubimage(ctx, target, level,
1250038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian                                strb, stImage, baseFormat,
1251038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian                                destX, destY, destZ,
1252038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian                                srcX, srcY, width, height);
1253038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian   }
1254038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian
125524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
12563ccbaa977f96eaa849093875dd0944f744ee1e21Brian      ctx->Driver.GenerateMipmap(ctx, target, texObj);
125724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   }
125824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian}
125924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
126024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
1261038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian
126224df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void
126324df8f895fe8807aa2ba058e71bd40adfc01d21eBrianst_CopyTexImage1D(GLcontext * ctx, GLenum target, GLint level,
126424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                  GLenum internalFormat,
126524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                  GLint x, GLint y, GLsizei width, GLint border)
126624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{
126724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   struct gl_texture_unit *texUnit =
126824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
126924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   struct gl_texture_object *texObj =
127024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      _mesa_select_tex_object(ctx, texUnit, target);
127124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   struct gl_texture_image *texImage =
127224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      _mesa_select_tex_image(ctx, texObj, target, level);
127324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
1274038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian#if 0
127524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   if (border)
127624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      goto fail;
1277038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian#endif
127824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
1279753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer   /* Setup or redefine the texture object, texture and texture
128024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian    * image.  Don't populate yet.
128124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian    */
128224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   ctx->Driver.TexImage1D(ctx, target, level, internalFormat,
128324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                          width, border,
128424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                          GL_RGBA, CHAN_TYPE, NULL,
128524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                          &ctx->DefaultPacking, texObj, texImage);
128624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
1287038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian   do_copy_texsubimage(ctx, target, level,
1288038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian                       0, 0, 0,
1289038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian                       x, y, width, 1);
129024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian}
129124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
129224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
129324df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void
129424df8f895fe8807aa2ba058e71bd40adfc01d21eBrianst_CopyTexImage2D(GLcontext * ctx, GLenum target, GLint level,
129524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                  GLenum internalFormat,
129624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                  GLint x, GLint y, GLsizei width, GLsizei height,
129724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                  GLint border)
129824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{
129924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   struct gl_texture_unit *texUnit =
130024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
130124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   struct gl_texture_object *texObj =
130224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      _mesa_select_tex_object(ctx, texUnit, target);
130324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   struct gl_texture_image *texImage =
130424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      _mesa_select_tex_image(ctx, texObj, target, level);
130524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
1306038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian#if 0
130724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   if (border)
130824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      goto fail;
1309038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian#endif
131024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
1311753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer   /* Setup or redefine the texture object, texture and texture
131224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian    * image.  Don't populate yet.
131324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian    */
131424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   ctx->Driver.TexImage2D(ctx, target, level, internalFormat,
131524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                          width, height, border,
131624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                          GL_RGBA, CHAN_TYPE, NULL,
131724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                          &ctx->DefaultPacking, texObj, texImage);
131824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
131924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
1320038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian   do_copy_texsubimage(ctx, target, level,
1321038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian                       0, 0, 0,
1322038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian                       x, y, width, height);
132324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian}
132424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
132524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
132624df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void
132724df8f895fe8807aa2ba058e71bd40adfc01d21eBrianst_CopyTexSubImage1D(GLcontext * ctx, GLenum target, GLint level,
132824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                     GLint xoffset, GLint x, GLint y, GLsizei width)
132924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{
1330038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian   const GLint yoffset = 0, zoffset = 0;
1331038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian   const GLsizei height = 1;
1332038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian   do_copy_texsubimage(ctx, target, level,
1333038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian                       xoffset, yoffset, zoffset,
1334038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian                       x, y, width, height);
133524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian}
133624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
133724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
133824df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void
133924df8f895fe8807aa2ba058e71bd40adfc01d21eBrianst_CopyTexSubImage2D(GLcontext * ctx, GLenum target, GLint level,
134024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                     GLint xoffset, GLint yoffset,
134124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                     GLint x, GLint y, GLsizei width, GLsizei height)
134224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{
1343038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian   const GLint zoffset = 0;
1344038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian   do_copy_texsubimage(ctx, target, level,
1345038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian                       xoffset, yoffset, zoffset,
1346038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian                       x, y, width, height);
1347038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian}
134824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
134924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
1350038cb561eb094af2f2ba06e18e61246fc0c87c3cBrianstatic void
1351038cb561eb094af2f2ba06e18e61246fc0c87c3cBrianst_CopyTexSubImage3D(GLcontext * ctx, GLenum target, GLint level,
1352038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian                     GLint xoffset, GLint yoffset, GLint zoffset,
1353038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian                     GLint x, GLint y, GLsizei width, GLsizei height)
1354038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian{
1355038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian   do_copy_texsubimage(ctx, target, level,
1356038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian                       xoffset, yoffset, zoffset,
1357038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian                       x, y, width, height);
135824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian}
135924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
136024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
136124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
136224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
136324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian/**
136424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * Compute which mipmap levels that really need to be sent to the hardware.
136524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * This depends on the base image size, GL_TEXTURE_MIN_LOD,
136624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * GL_TEXTURE_MAX_LOD, GL_TEXTURE_BASE_LEVEL, and GL_TEXTURE_MAX_LEVEL.
136724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */
136824df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void
136914b98343309fdcff3514f05020303f7b40e83a4aBriancalculate_first_last_level(struct st_texture_object *stObj)
137024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{
137114b98343309fdcff3514f05020303f7b40e83a4aBrian   struct gl_texture_object *tObj = &stObj->base;
137224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
137324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   /* These must be signed values.  MinLod and MaxLod can be negative numbers,
137424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian    * and having firstLevel and lastLevel as signed prevents the need for
137524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian    * extra sign checks.
137624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian    */
137724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   int firstLevel;
137824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   int lastLevel;
137924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
138024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   /* Yes, this looks overly complicated, but it's all needed.
138124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian    */
138224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   switch (tObj->Target) {
138324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   case GL_TEXTURE_1D:
138424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   case GL_TEXTURE_2D:
138524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   case GL_TEXTURE_3D:
138624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   case GL_TEXTURE_CUBE_MAP:
138724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      if (tObj->MinFilter == GL_NEAREST || tObj->MinFilter == GL_LINEAR) {
138824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian         /* GL_NEAREST and GL_LINEAR only care about GL_TEXTURE_BASE_LEVEL.
138924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian          */
139024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian         firstLevel = lastLevel = tObj->BaseLevel;
139124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      }
139224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      else {
13934da1cdf78fa3b954840650fa46cf72da5daf149fBrian         firstLevel = 0;
1394ffde4e03cf178719c06c300939f8f469d7fc5e9cBrian Paul         lastLevel = MIN2(tObj->MaxLevel, tObj->Image[0][tObj->BaseLevel]->WidthLog2);
139524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      }
139624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      break;
139724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   case GL_TEXTURE_RECTANGLE_NV:
139824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   case GL_TEXTURE_4D_SGIS:
139924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      firstLevel = lastLevel = 0;
140024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      break;
140124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   default:
140224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      return;
140324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   }
140424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
140514b98343309fdcff3514f05020303f7b40e83a4aBrian   stObj->lastLevel = lastLevel;
140624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian}
140724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
140824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
140924df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void
1410753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzercopy_image_data_to_texture(struct st_context *st,
1411753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer			   struct st_texture_object *stObj,
14124da1cdf78fa3b954840650fa46cf72da5daf149fBrian                           GLuint dstLevel,
1413753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer			   struct st_texture_image *stImage)
141424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{
1415753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer   if (stImage->pt) {
141624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      /* Copy potentially with the blitter:
141724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian       */
1418753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer      st_texture_image_copy(st->pipe,
14194da1cdf78fa3b954840650fa46cf72da5daf149fBrian                            stObj->pt, dstLevel,  /* dest texture, level */
14204da1cdf78fa3b954840650fa46cf72da5daf149fBrian                            stImage->pt, /* src texture */
14214da1cdf78fa3b954840650fa46cf72da5daf149fBrian                            stImage->face
142228b315dc1aed36bebadfacbd55e481e7baacfcb5Brian                            );
142324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
1424f8dce51083042b4d3fabf48524835290b6725682Brian Paul      pipe_texture_reference(&stImage->pt, NULL);
142524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   }
14264c50969334844bc9aa622176c3ebcbc733394f78Brian Paul   else if (stImage->base.Data) {
142724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      assert(stImage->base.Data != NULL);
142824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
142924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      /* More straightforward upload.
143024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian       */
1431753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer      st_texture_image_data(st->pipe,
1432753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer                               stObj->pt,
143324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                               stImage->face,
1434c2497879f127251994064a0e0c24901782adae9eBrian Paul                               dstLevel,
143524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                               stImage->base.Data,
143624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                               stImage->base.RowStride,
143724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                               stImage->base.RowStride *
143824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian                               stImage->base.Height);
143924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      _mesa_align_free(stImage->base.Data);
144024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      stImage->base.Data = NULL;
144124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   }
144224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
14434da19dbcaa9f3e2d20fffd0145bf0bc756dd7542Brian   pipe_texture_reference(&stImage->pt, stObj->pt);
144424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian}
144524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
144624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
1447afc54983370033b65e3a7cbb29bd9c87156f0881Brian/**
1448afc54983370033b65e3a7cbb29bd9c87156f0881Brian * Called during state validation.  When this function is finished,
1449afc54983370033b65e3a7cbb29bd9c87156f0881Brian * the texture object should be ready for rendering.
14503b3774b1227743147159676795b542c0eb7c2bdfBrian Paul * \return GL_TRUE for success, GL_FALSE for failure (out of mem)
145124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */
145214b98343309fdcff3514f05020303f7b40e83a4aBrianGLboolean
1453753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzerst_finalize_texture(GLcontext *ctx,
1454c3af68dc5022715cc8f126b7df12f3f5248aefe7Keith Whitwell		    struct pipe_context *pipe,
1455c3af68dc5022715cc8f126b7df12f3f5248aefe7Keith Whitwell		    struct gl_texture_object *tObj,
1456753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer		    GLboolean *needFlush)
145724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{
145814b98343309fdcff3514f05020303f7b40e83a4aBrian   struct st_texture_object *stObj = st_texture_object(tObj);
1459afc54983370033b65e3a7cbb29bd9c87156f0881Brian   const GLuint nr_faces = (stObj->base.Target == GL_TEXTURE_CUBE_MAP) ? 6 : 1;
146024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   int comp_byte = 0;
146124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   int cpp;
14624da1cdf78fa3b954840650fa46cf72da5daf149fBrian   GLuint face;
146324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   struct st_texture_image *firstImage;
146424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
146524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   *needFlush = GL_FALSE;
146624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
146724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   /* We know/require this is true by now:
146824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian    */
146914b98343309fdcff3514f05020303f7b40e83a4aBrian   assert(stObj->base._Complete);
147024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
1471753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer   /* What levels must the texture include at a minimum?
147224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian    */
147314b98343309fdcff3514f05020303f7b40e83a4aBrian   calculate_first_last_level(stObj);
14744da1cdf78fa3b954840650fa46cf72da5daf149fBrian   firstImage = st_texture_image(stObj->base.Image[0][stObj->base.BaseLevel]);
147524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
1476753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer   /* If both firstImage and stObj point to a texture which can contain
147724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian    * all active images, favour firstImage.  Note that because of the
147824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian    * completeness requirement, we know that the image dimensions
147924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian    * will match.
148024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian    */
1481753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer   if (firstImage->pt &&
1482753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer       firstImage->pt != stObj->pt &&
1483753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer       firstImage->pt->last_level >= stObj->lastLevel) {
148424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
14854da19dbcaa9f3e2d20fffd0145bf0bc756dd7542Brian      pipe_texture_reference(&stObj->pt, firstImage->pt);
148624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   }
148724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
148824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   if (firstImage->base.IsCompressed) {
148914b98343309fdcff3514f05020303f7b40e83a4aBrian      comp_byte = compressed_num_bytes(firstImage->base.TexFormat->MesaFormat);
149024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      cpp = comp_byte;
149124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   }
14925cb0d749b07be4ecbf4d4d7cde18aecdfe2dba38Brian   else {
14935cb0d749b07be4ecbf4d4d7cde18aecdfe2dba38Brian      cpp = firstImage->base.TexFormat->TexelBytes;
14945cb0d749b07be4ecbf4d4d7cde18aecdfe2dba38Brian   }
149524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
1496ce509401738e7073de94a2b7fc41461c52a73da0Brian Paul   /* If we already have a gallium texture, check that it matches the texture
1497ce509401738e7073de94a2b7fc41461c52a73da0Brian Paul    * object's format, target, size, num_levels, etc.
149824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian    */
1499809dd9089bae70cf35cea6a75258e700e7455738Brian Paul   if (stObj->pt) {
1500809dd9089bae70cf35cea6a75258e700e7455738Brian Paul      const enum pipe_format fmt =
1501809dd9089bae70cf35cea6a75258e700e7455738Brian Paul         st_mesa_format_to_pipe_format(firstImage->base.TexFormat->MesaFormat);
1502809dd9089bae70cf35cea6a75258e700e7455738Brian Paul      if (stObj->pt->target != gl_target_to_pipe(stObj->base.Target) ||
1503809dd9089bae70cf35cea6a75258e700e7455738Brian Paul          stObj->pt->format != fmt ||
1504809dd9089bae70cf35cea6a75258e700e7455738Brian Paul          stObj->pt->last_level < stObj->lastLevel ||
1505809dd9089bae70cf35cea6a75258e700e7455738Brian Paul          stObj->pt->width[0] != firstImage->base.Width2 ||
1506809dd9089bae70cf35cea6a75258e700e7455738Brian Paul          stObj->pt->height[0] != firstImage->base.Height2 ||
1507809dd9089bae70cf35cea6a75258e700e7455738Brian Paul          stObj->pt->depth[0] != firstImage->base.Depth2 ||
1508809dd9089bae70cf35cea6a75258e700e7455738Brian Paul          stObj->pt->cpp != cpp ||
1509809dd9089bae70cf35cea6a75258e700e7455738Brian Paul          stObj->pt->compressed != firstImage->base.IsCompressed) {
1510809dd9089bae70cf35cea6a75258e700e7455738Brian Paul         pipe_texture_release(&stObj->pt);
15111a82d9648b3db780e58e4966924157542d148c58Brian Paul         ctx->st->dirty.st |= ST_NEW_FRAMEBUFFER;
1512809dd9089bae70cf35cea6a75258e700e7455738Brian Paul      }
151324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   }
151424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
1515ce509401738e7073de94a2b7fc41461c52a73da0Brian Paul   /* May need to create a new gallium texture:
151624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian    */
1517753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer   if (!stObj->pt) {
1518a1f95a8bf64f863289b6759caeec76d7e054400eRoland Scheidegger      const enum pipe_format fmt =
1519a1f95a8bf64f863289b6759caeec76d7e054400eRoland Scheidegger         st_mesa_format_to_pipe_format(firstImage->base.TexFormat->MesaFormat);
1520753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer      stObj->pt = st_texture_create(ctx->st,
15215390a43ce06b27f6d54bc5f237aa305b6948f2afBrian                                    gl_target_to_pipe(stObj->base.Target),
1522a1f95a8bf64f863289b6759caeec76d7e054400eRoland Scheidegger                                    fmt,
1523b245840b86cf877c9b8d666edf229364a84f1deaBrian                                    stObj->lastLevel,
152445cc35e77600af8628393475405160e26d56d421Brian Paul                                    firstImage->base.Width2,
152545cc35e77600af8628393475405160e26d56d421Brian Paul                                    firstImage->base.Height2,
152645cc35e77600af8628393475405160e26d56d421Brian Paul                                    firstImage->base.Depth2,
1527a73ae3d5eb8419feab5aea26573aa41b72f941ebKeith Whitwell                                    comp_byte,
1528a1f95a8bf64f863289b6759caeec76d7e054400eRoland Scheidegger                                    ( (pf_is_depth_stencil(fmt) ?
1529a1f95a8bf64f863289b6759caeec76d7e054400eRoland Scheidegger                                      PIPE_TEXTURE_USAGE_DEPTH_STENCIL :
1530a1f95a8bf64f863289b6759caeec76d7e054400eRoland Scheidegger                                      PIPE_TEXTURE_USAGE_RENDER_TARGET) |
1531a73ae3d5eb8419feab5aea26573aa41b72f941ebKeith Whitwell                                      PIPE_TEXTURE_USAGE_SAMPLER ));
1532a73ae3d5eb8419feab5aea26573aa41b72f941ebKeith Whitwell
15333b3774b1227743147159676795b542c0eb7c2bdfBrian Paul      if (!stObj->pt) {
15343b3774b1227743147159676795b542c0eb7c2bdfBrian Paul         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage");
15353b3774b1227743147159676795b542c0eb7c2bdfBrian Paul         return GL_FALSE;
15363b3774b1227743147159676795b542c0eb7c2bdfBrian Paul      }
153724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   }
153824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
1539753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer   /* Pull in any images not in the object's texture:
154024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian    */
154124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   for (face = 0; face < nr_faces; face++) {
15424da1cdf78fa3b954840650fa46cf72da5daf149fBrian      GLuint level;
15434da1cdf78fa3b954840650fa46cf72da5daf149fBrian      for (level = 0; level <= stObj->lastLevel; level++) {
154424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian         struct st_texture_image *stImage =
15454da1cdf78fa3b954840650fa46cf72da5daf149fBrian            st_texture_image(stObj->base.Image[face][stObj->base.BaseLevel + level]);
154624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
1547753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer         /* Need to import images in main memory or held in other textures.
154824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian          */
1549a34b43b3f4817268ef4b3f186203b5fbafc7214eBrian         if (stImage && stObj->pt != stImage->pt) {
15504da1cdf78fa3b954840650fa46cf72da5daf149fBrian            copy_image_data_to_texture(ctx->st, stObj, level, stImage);
155124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian	    *needFlush = GL_TRUE;
155224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian         }
155324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian      }
155424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   }
155524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
155624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   return GL_TRUE;
155724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian}
155824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
155924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
156024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
156124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
15626da9234fd437f97267e7831f034c78b31156d939Brianvoid
15636da9234fd437f97267e7831f034c78b31156d939Brianst_init_texture_functions(struct dd_function_table *functions)
156424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{
156524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   functions->ChooseTextureFormat = st_ChooseTextureFormat;
156624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   functions->TexImage1D = st_TexImage1D;
156724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   functions->TexImage2D = st_TexImage2D;
156824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   functions->TexImage3D = st_TexImage3D;
156924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   functions->TexSubImage1D = st_TexSubImage1D;
157024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   functions->TexSubImage2D = st_TexSubImage2D;
157124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   functions->TexSubImage3D = st_TexSubImage3D;
157224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   functions->CopyTexImage1D = st_CopyTexImage1D;
157324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   functions->CopyTexImage2D = st_CopyTexImage2D;
157424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   functions->CopyTexSubImage1D = st_CopyTexSubImage1D;
157524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   functions->CopyTexSubImage2D = st_CopyTexSubImage2D;
1576038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian   functions->CopyTexSubImage3D = st_CopyTexSubImage3D;
157762abcb9aacc33218d0143a743c738435794b32a9Brian   functions->GenerateMipmap = st_generate_mipmap;
1578038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian
157924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   functions->GetTexImage = st_GetTexImage;
158024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
158124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   /* compressed texture functions */
158224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   functions->CompressedTexImage2D = st_CompressedTexImage2D;
158324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   functions->GetCompressedTexImage = st_GetCompressedTexImage;
1584f32c51277498887b348133ebcd947dbc8acce756Roland Scheidegger   functions->CompressedTextureSize = _mesa_compressed_texture_size;
158524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
158624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   functions->NewTextureObject = st_NewTextureObject;
158724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   functions->NewTextureImage = st_NewTextureImage;
158824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   functions->DeleteTexture = st_DeleteTextureObject;
158924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   functions->FreeTexImageData = st_FreeTextureImageData;
159024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   functions->UpdateTexturePalette = 0;
159124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   functions->IsTextureResident = st_IsTextureResident;
159224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian
159324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian   functions->TextureMemCpy = do_memcpy;
1594f8549e8f4f8bdfebcb4e0a2754df59b3fe4fdff7Brian
1595f8549e8f4f8bdfebcb4e0a2754df59b3fe4fdff7Brian   /* XXX Temporary until we can query pipe's texture sizes */
1596f8549e8f4f8bdfebcb4e0a2754df59b3fe4fdff7Brian   functions->TestProxyTexImage = _mesa_test_proxy_teximage;
159724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian}
1598