st_cb_texture.c revision 37607aeaf8b0fd35213635ba1c3743b6e059d48f
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" 544f25420bdd834e81a3e22733304efc5261c2998aBrian Paul#include "util/u_tile.h" 553c0dc8242b64518d5635263ba65b39afa919dd86Michel Dänzer#include "util/u_blit.h" 5624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 5724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 5824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#define DBG if (0) printf 5924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 6024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 611c5f27a18b775b3784fcd265d60e0affa0b31581Michel Dänzerstatic enum pipe_texture_target 625390a43ce06b27f6d54bc5f237aa305b6948f2afBriangl_target_to_pipe(GLenum target) 635390a43ce06b27f6d54bc5f237aa305b6948f2afBrian{ 645390a43ce06b27f6d54bc5f237aa305b6948f2afBrian switch (target) { 655390a43ce06b27f6d54bc5f237aa305b6948f2afBrian case GL_TEXTURE_1D: 665390a43ce06b27f6d54bc5f237aa305b6948f2afBrian return PIPE_TEXTURE_1D; 675390a43ce06b27f6d54bc5f237aa305b6948f2afBrian 685390a43ce06b27f6d54bc5f237aa305b6948f2afBrian case GL_TEXTURE_2D: 695390a43ce06b27f6d54bc5f237aa305b6948f2afBrian case GL_TEXTURE_RECTANGLE_NV: 705390a43ce06b27f6d54bc5f237aa305b6948f2afBrian return PIPE_TEXTURE_2D; 715390a43ce06b27f6d54bc5f237aa305b6948f2afBrian 725390a43ce06b27f6d54bc5f237aa305b6948f2afBrian case GL_TEXTURE_3D: 735390a43ce06b27f6d54bc5f237aa305b6948f2afBrian return PIPE_TEXTURE_3D; 745390a43ce06b27f6d54bc5f237aa305b6948f2afBrian 755390a43ce06b27f6d54bc5f237aa305b6948f2afBrian case GL_TEXTURE_CUBE_MAP_ARB: 765390a43ce06b27f6d54bc5f237aa305b6948f2afBrian return PIPE_TEXTURE_CUBE; 775390a43ce06b27f6d54bc5f237aa305b6948f2afBrian 785390a43ce06b27f6d54bc5f237aa305b6948f2afBrian default: 795390a43ce06b27f6d54bc5f237aa305b6948f2afBrian assert(0); 805390a43ce06b27f6d54bc5f237aa305b6948f2afBrian return 0; 815390a43ce06b27f6d54bc5f237aa305b6948f2afBrian } 825390a43ce06b27f6d54bc5f237aa305b6948f2afBrian} 835390a43ce06b27f6d54bc5f237aa305b6948f2afBrian 845390a43ce06b27f6d54bc5f237aa305b6948f2afBrian 85afc54983370033b65e3a7cbb29bd9c87156f0881Brian/** 86afc54983370033b65e3a7cbb29bd9c87156f0881Brian * Return nominal bytes per texel for a compressed format, 0 for non-compressed 87afc54983370033b65e3a7cbb29bd9c87156f0881Brian * format. 88afc54983370033b65e3a7cbb29bd9c87156f0881Brian */ 8924df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic int 9014b98343309fdcff3514f05020303f7b40e83a4aBriancompressed_num_bytes(GLuint mesaFormat) 9124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 9224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian switch(mesaFormat) { 935b51cc020efc5519bc7cc34f6fcb4138eab76e0aBrian Paul#if FEATURE_texture_fxt1 9424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian case MESA_FORMAT_RGB_FXT1: 9524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian case MESA_FORMAT_RGBA_FXT1: 965b51cc020efc5519bc7cc34f6fcb4138eab76e0aBrian Paul#endif 975b51cc020efc5519bc7cc34f6fcb4138eab76e0aBrian Paul#if FEATURE_texture_s3tc 9824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian case MESA_FORMAT_RGB_DXT1: 9924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian case MESA_FORMAT_RGBA_DXT1: 100afc54983370033b65e3a7cbb29bd9c87156f0881Brian return 2; 10124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian case MESA_FORMAT_RGBA_DXT3: 10224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian case MESA_FORMAT_RGBA_DXT5: 103afc54983370033b65e3a7cbb29bd9c87156f0881Brian return 4; 1045b51cc020efc5519bc7cc34f6fcb4138eab76e0aBrian Paul#endif 10524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian default: 106afc54983370033b65e3a7cbb29bd9c87156f0881Brian return 0; 10724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 10824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 10924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 11024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 1114e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul/** called via ctx->Driver.NewTextureImage() */ 11224df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic struct gl_texture_image * 11324df8f895fe8807aa2ba058e71bd40adfc01d21eBrianst_NewTextureImage(GLcontext * ctx) 11424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 11524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian DBG("%s\n", __FUNCTION__); 11624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian (void) ctx; 11724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian return (struct gl_texture_image *) CALLOC_STRUCT(st_texture_image); 11824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 11924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 12024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 1214e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul/** called via ctx->Driver.NewTextureObject() */ 12224df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic struct gl_texture_object * 12324df8f895fe8807aa2ba058e71bd40adfc01d21eBrianst_NewTextureObject(GLcontext * ctx, GLuint name, GLenum target) 12424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 12524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian struct st_texture_object *obj = CALLOC_STRUCT(st_texture_object); 12624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 12724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian DBG("%s\n", __FUNCTION__); 12824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian _mesa_initialize_texture_object(&obj->base, name, target); 12924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 13024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian return &obj->base; 13124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 13224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 1334e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul/** called via ctx->Driver.DeleteTextureImage() */ 13424df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void 13524df8f895fe8807aa2ba058e71bd40adfc01d21eBrianst_DeleteTextureObject(GLcontext *ctx, 1366f715dcc219071e574e363a9db4365c9c31ebbd3Brian struct gl_texture_object *texObj) 13724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 13824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian struct st_texture_object *stObj = st_texture_object(texObj); 139753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer if (stObj->pt) 140f8dce51083042b4d3fabf48524835290b6725682Brian Paul pipe_texture_reference(&stObj->pt, NULL); 14124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 14224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian _mesa_delete_texture_object(ctx, texObj); 14324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 14424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 14524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 1464e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul/** called via ctx->Driver.FreeTexImageData() */ 14724df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void 14824df8f895fe8807aa2ba058e71bd40adfc01d21eBrianst_FreeTextureImageData(GLcontext * ctx, struct gl_texture_image *texImage) 14924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 15024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian struct st_texture_image *stImage = st_texture_image(texImage); 15124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 15224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian DBG("%s\n", __FUNCTION__); 15324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 154753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer if (stImage->pt) { 155f8dce51083042b4d3fabf48524835290b6725682Brian Paul pipe_texture_reference(&stImage->pt, NULL); 15624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 15724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 15824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian if (texImage->Data) { 15924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian free(texImage->Data); 16024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian texImage->Data = NULL; 16124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 16224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 16324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 16424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 1654e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul/** 16624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * From linux kernel i386 header files, copes with odd sizes better 16724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * than COPY_DWORDS would: 16824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * XXX Put this in src/mesa/main/imports.h ??? 16924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 17024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#if defined(i386) || defined(__i386__) 17124df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic INLINE void * 17224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian__memcpy(void *to, const void *from, size_t n) 17324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 17424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian int d0, d1, d2; 17524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian __asm__ __volatile__("rep ; movsl\n\t" 17624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian "testb $2,%b4\n\t" 17724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian "je 1f\n\t" 17824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian "movsw\n" 17924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian "1:\ttestb $1,%b4\n\t" 18024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian "je 2f\n\t" 18124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian "movsb\n" "2:":"=&c"(d0), "=&D"(d1), "=&S"(d2) 18224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian :"0"(n / 4), "q"(n), "1"((long) to), "2"((long) from) 18324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian :"memory"); 18424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian return (to); 18524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 18624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#else 18724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#define __memcpy(a,b,c) memcpy(a,b,c) 18824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#endif 18924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 19024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 1914e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul/** 1924e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul * The system memcpy (at least on ubuntu 5.10) has problems copying 19324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * to agp (writecombined) memory from a source which isn't 64-byte 19424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * aligned - there is a 4x performance falloff. 19524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * 19624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * The x86 __memcpy is immune to this but is slightly slower 19724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * (10%-ish) than the system memcpy. 19824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * 19924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * The sse_memcpy seems to have a slight cliff at 64/32 bytes, but 20024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * isn't much faster than x86_memcpy for agp copies. 20124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * 20224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * TODO: switch dynamically. 20324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 20424df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void * 20524df8f895fe8807aa2ba058e71bd40adfc01d21eBriando_memcpy(void *dest, const void *src, size_t n) 20624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 20724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian if ((((unsigned) src) & 63) || (((unsigned) dest) & 63)) { 20824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian return __memcpy(dest, src, n); 20924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 21024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian else 21124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian return memcpy(dest, src, n); 21224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 21324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 21424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 21524df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic int 21624df8f895fe8807aa2ba058e71bd40adfc01d21eBrianlogbase2(int n) 21724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 2184e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul GLint i = 1, log2 = 0; 21924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian while (n > i) { 22024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian i *= 2; 22124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian log2++; 22224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 22324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian return log2; 22424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 22524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 22624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 227f52f5136e6eed23e55098681e5b082cc452136d6Brian/** 228f52f5136e6eed23e55098681e5b082cc452136d6Brian * Allocate a pipe_texture object for the given st_texture_object using 229f52f5136e6eed23e55098681e5b082cc452136d6Brian * the given st_texture_image to guess the mipmap size/levels. 230f52f5136e6eed23e55098681e5b082cc452136d6Brian * 231f52f5136e6eed23e55098681e5b082cc452136d6Brian * [comments...] 232f52f5136e6eed23e55098681e5b082cc452136d6Brian * Otherwise, store it in memory if (Border != 0) or (any dimension == 23324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * 1). 23424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * 235753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer * Otherwise, if max_level >= level >= min_level, create texture with 236753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer * space for images from min_level down to max_level. 23724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * 238753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer * Otherwise, create texture with space for images from (level 0)..(1x1). 239753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer * Consider pruning this texture at a validation if the saving is worth it. 24024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 24124df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void 242753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzerguess_and_alloc_texture(struct st_context *st, 243753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer struct st_texture_object *stObj, 244afc54983370033b65e3a7cbb29bd9c87156f0881Brian const struct st_texture_image *stImage) 24524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 24624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLuint firstLevel; 24724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLuint lastLevel; 24845cc35e77600af8628393475405160e26d56d421Brian Paul GLuint width = stImage->base.Width2; /* size w/out border */ 24945cc35e77600af8628393475405160e26d56d421Brian Paul GLuint height = stImage->base.Height2; 25045cc35e77600af8628393475405160e26d56d421Brian Paul GLuint depth = stImage->base.Depth2; 25124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLuint i, comp_byte = 0; 252a1f95a8bf64f863289b6759caeec76d7e054400eRoland Scheidegger enum pipe_format fmt; 25324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 25424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian DBG("%s\n", __FUNCTION__); 25524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 256f52f5136e6eed23e55098681e5b082cc452136d6Brian assert(!stObj->pt); 257f52f5136e6eed23e55098681e5b082cc452136d6Brian 25845cc35e77600af8628393475405160e26d56d421Brian Paul if (stObj->pt && 2596c534b830c6f5427c391c5225c34561141c201baMichal Krol (GLint) stImage->level > stObj->base.BaseLevel && 26014b98343309fdcff3514f05020303f7b40e83a4aBrian (stImage->base.Width == 1 || 26114b98343309fdcff3514f05020303f7b40e83a4aBrian (stObj->base.Target != GL_TEXTURE_1D && 26214b98343309fdcff3514f05020303f7b40e83a4aBrian stImage->base.Height == 1) || 26314b98343309fdcff3514f05020303f7b40e83a4aBrian (stObj->base.Target == GL_TEXTURE_3D && 26414b98343309fdcff3514f05020303f7b40e83a4aBrian stImage->base.Depth == 1))) 26524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian return; 26624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 26724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian /* If this image disrespects BaseLevel, allocate from level zero. 26824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * Usually BaseLevel == 0, so it's unlikely to happen. 26924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 2706c534b830c6f5427c391c5225c34561141c201baMichal Krol if ((GLint) stImage->level < stObj->base.BaseLevel) 27124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian firstLevel = 0; 27224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian else 27314b98343309fdcff3514f05020303f7b40e83a4aBrian firstLevel = stObj->base.BaseLevel; 27424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 27524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 27624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian /* Figure out image dimensions at start level. 27724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 27814b98343309fdcff3514f05020303f7b40e83a4aBrian for (i = stImage->level; i > firstLevel; i--) { 27945cc35e77600af8628393475405160e26d56d421Brian Paul if (width != 1) 28045cc35e77600af8628393475405160e26d56d421Brian Paul width <<= 1; 28124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian if (height != 1) 28224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian height <<= 1; 28324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian if (depth != 1) 28424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian depth <<= 1; 28524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 28624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 287296378b6c8b205048244746e260739448c4ee590Brian Paul if (width == 0 || height == 0 || depth == 0) { 288296378b6c8b205048244746e260739448c4ee590Brian Paul /* no texture needed */ 289296378b6c8b205048244746e260739448c4ee590Brian Paul return; 290296378b6c8b205048244746e260739448c4ee590Brian Paul } 291296378b6c8b205048244746e260739448c4ee590Brian Paul 29224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian /* Guess a reasonable value for lastLevel. This is probably going 29324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * to be wrong fairly often and might mean that we have to look at 29424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * resizable buffers, or require that buffers implement lazy 29524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * pagetable arrangements. 29624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 29714b98343309fdcff3514f05020303f7b40e83a4aBrian if ((stObj->base.MinFilter == GL_NEAREST || 29814b98343309fdcff3514f05020303f7b40e83a4aBrian stObj->base.MinFilter == GL_LINEAR) && 29914b98343309fdcff3514f05020303f7b40e83a4aBrian stImage->level == firstLevel) { 30024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian lastLevel = firstLevel; 30124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 30224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian else { 303f52f5136e6eed23e55098681e5b082cc452136d6Brian GLuint l2width = logbase2(width); 304f52f5136e6eed23e55098681e5b082cc452136d6Brian GLuint l2height = logbase2(height); 305f52f5136e6eed23e55098681e5b082cc452136d6Brian GLuint l2depth = logbase2(depth); 30624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian lastLevel = firstLevel + MAX2(MAX2(l2width, l2height), l2depth); 30724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 30824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 30914b98343309fdcff3514f05020303f7b40e83a4aBrian if (stImage->base.IsCompressed) 31014b98343309fdcff3514f05020303f7b40e83a4aBrian comp_byte = compressed_num_bytes(stImage->base.TexFormat->MesaFormat); 311f52f5136e6eed23e55098681e5b082cc452136d6Brian 312a1f95a8bf64f863289b6759caeec76d7e054400eRoland Scheidegger fmt = st_mesa_format_to_pipe_format(stImage->base.TexFormat->MesaFormat); 313753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer stObj->pt = st_texture_create(st, 3145390a43ce06b27f6d54bc5f237aa305b6948f2afBrian gl_target_to_pipe(stObj->base.Target), 315a1f95a8bf64f863289b6759caeec76d7e054400eRoland Scheidegger fmt, 3165390a43ce06b27f6d54bc5f237aa305b6948f2afBrian lastLevel, 3175390a43ce06b27f6d54bc5f237aa305b6948f2afBrian width, 3185390a43ce06b27f6d54bc5f237aa305b6948f2afBrian height, 3195390a43ce06b27f6d54bc5f237aa305b6948f2afBrian depth, 320a73ae3d5eb8419feab5aea26573aa41b72f941ebKeith Whitwell comp_byte, 321a1f95a8bf64f863289b6759caeec76d7e054400eRoland Scheidegger ( (pf_is_depth_stencil(fmt) ? 322a1f95a8bf64f863289b6759caeec76d7e054400eRoland Scheidegger PIPE_TEXTURE_USAGE_DEPTH_STENCIL : 323a1f95a8bf64f863289b6759caeec76d7e054400eRoland Scheidegger PIPE_TEXTURE_USAGE_RENDER_TARGET) | 324a73ae3d5eb8419feab5aea26573aa41b72f941ebKeith Whitwell PIPE_TEXTURE_USAGE_SAMPLER )); 32524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 32624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian DBG("%s - success\n", __FUNCTION__); 32724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 32824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 32924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 330212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian/** 331212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian * Adjust pixel unpack params and image dimensions to strip off the 332212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian * texture border. 333212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian * Gallium doesn't support texture borders. They've seldem been used 334212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian * and seldom been implemented correctly anyway. 335212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian * \param unpackNew returns the new pixel unpack parameters 336212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian */ 337212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brianstatic void 338212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brianstrip_texture_border(GLint border, 339212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian GLint *width, GLint *height, GLint *depth, 340212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian const struct gl_pixelstore_attrib *unpack, 341212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian struct gl_pixelstore_attrib *unpackNew) 342212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian{ 343212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian assert(border > 0); /* sanity check */ 344212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian 345212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian *unpackNew = *unpack; 346212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian 347212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian if (unpackNew->RowLength == 0) 348212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian unpackNew->RowLength = *width; 349212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian 350212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian if (depth && unpackNew->ImageHeight == 0) 351212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian unpackNew->ImageHeight = *height; 352212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian 353212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian unpackNew->SkipPixels += border; 354212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian if (height) 355212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian unpackNew->SkipRows += border; 356212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian if (depth) 357212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian unpackNew->SkipImages += border; 358212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian 359212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian assert(*width >= 3); 360212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian *width = *width - 2 * border; 361212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian if (height && *height >= 3) 362212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian *height = *height - 2 * border; 363212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian if (depth && *depth >= 3) 364212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian *depth = *depth - 2 * border; 365212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian} 366212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian 36724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 3684e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul/** 3694e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul * Do glTexImage1/2/3D(). 3704e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul */ 37124df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void 37224df8f895fe8807aa2ba058e71bd40adfc01d21eBrianst_TexImage(GLcontext * ctx, 373afc54983370033b65e3a7cbb29bd9c87156f0881Brian GLint dims, 374afc54983370033b65e3a7cbb29bd9c87156f0881Brian GLenum target, GLint level, 375afc54983370033b65e3a7cbb29bd9c87156f0881Brian GLint internalFormat, 376afc54983370033b65e3a7cbb29bd9c87156f0881Brian GLint width, GLint height, GLint depth, 377afc54983370033b65e3a7cbb29bd9c87156f0881Brian GLint border, 378afc54983370033b65e3a7cbb29bd9c87156f0881Brian GLenum format, GLenum type, const void *pixels, 379afc54983370033b65e3a7cbb29bd9c87156f0881Brian const struct gl_pixelstore_attrib *unpack, 380afc54983370033b65e3a7cbb29bd9c87156f0881Brian struct gl_texture_object *texObj, 381afc54983370033b65e3a7cbb29bd9c87156f0881Brian struct gl_texture_image *texImage, 382afc54983370033b65e3a7cbb29bd9c87156f0881Brian GLsizei imageSize, int compressed) 38324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 38414b98343309fdcff3514f05020303f7b40e83a4aBrian struct st_texture_object *stObj = st_texture_object(texObj); 38514b98343309fdcff3514f05020303f7b40e83a4aBrian struct st_texture_image *stImage = st_texture_image(texImage); 386212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian GLint postConvWidth, postConvHeight; 38724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLint texelBytes, sizeInBytes; 38824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLuint dstRowStride; 389212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian struct gl_pixelstore_attrib unpackNB; 39024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 39124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian DBG("%s target %s level %d %dx%dx%d border %d\n", __FUNCTION__, 39224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian _mesa_lookup_enum_by_nr(target), level, width, height, depth, border); 39324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 394212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian /* gallium does not support texture borders, strip it off */ 395212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian if (border) { 396212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian strip_texture_border(border, &width, &height, &depth, 397212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian unpack, &unpackNB); 398212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian unpack = &unpackNB; 39921989edd55409d72ee55187f4f9062496ca3fbf8Brian Paul texImage->Width = width; 40021989edd55409d72ee55187f4f9062496ca3fbf8Brian Paul texImage->Height = height; 40121989edd55409d72ee55187f4f9062496ca3fbf8Brian Paul texImage->Depth = depth; 40221989edd55409d72ee55187f4f9062496ca3fbf8Brian Paul texImage->Border = 0; 403212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian border = 0; 404212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian } 405212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian 406212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian postConvWidth = width; 407212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian postConvHeight = height; 408212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian 409cfe9e66f2bc596c43760911e7c1604bb32cdee28Brian stImage->face = _mesa_tex_target_to_face(target); 41014b98343309fdcff3514f05020303f7b40e83a4aBrian stImage->level = level; 41124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 412b19e8f720bb2f4d360f5497b64901fc48321f172Brian Paul#if FEATURE_convolution 41324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian if (ctx->_ImageTransferState & IMAGE_CONVOLUTION_BIT) { 41424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian _mesa_adjust_image_for_convolution(ctx, dims, &postConvWidth, 41524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian &postConvHeight); 41624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 417b19e8f720bb2f4d360f5497b64901fc48321f172Brian Paul#endif 41824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 41924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian /* choose the texture format */ 42024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian texImage->TexFormat = st_ChooseTextureFormat(ctx, internalFormat, 421afc54983370033b65e3a7cbb29bd9c87156f0881Brian format, type); 42224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 42324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian _mesa_set_fetch_functions(texImage, dims); 42424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 42524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian if (texImage->TexFormat->TexelBytes == 0) { 42624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian /* must be a compressed format */ 42724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian texelBytes = 0; 42824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian texImage->IsCompressed = GL_TRUE; 42924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian texImage->CompressedSize = 43024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian ctx->Driver.CompressedTextureSize(ctx, texImage->Width, 43124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian texImage->Height, texImage->Depth, 43224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian texImage->TexFormat->MesaFormat); 433afc54983370033b65e3a7cbb29bd9c87156f0881Brian } 434afc54983370033b65e3a7cbb29bd9c87156f0881Brian else { 43524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian texelBytes = texImage->TexFormat->TexelBytes; 43624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 43724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian /* Minimum pitch of 32 bytes */ 43824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian if (postConvWidth * texelBytes < 32) { 43924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian postConvWidth = 32 / texelBytes; 44024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian texImage->RowStride = postConvWidth; 44124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 44224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 4437585b4ceb8fed862c07f50af8030a6f0eb8a8321Brian /* we'll set RowStride elsewhere when the texture is a "mapped" state */ 4447585b4ceb8fed862c07f50af8030a6f0eb8a8321Brian /*assert(texImage->RowStride == postConvWidth);*/ 44524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 44624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 44724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian /* Release the reference to a potentially orphaned buffer. 44824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * Release any old malloced memory. 44924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 450753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer if (stImage->pt) { 451f8dce51083042b4d3fabf48524835290b6725682Brian Paul pipe_texture_reference(&stImage->pt, NULL); 45224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian assert(!texImage->Data); 45324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 45424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian else if (texImage->Data) { 45524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian _mesa_align_free(texImage->Data); 45624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 45724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 45837607aeaf8b0fd35213635ba1c3743b6e059d48fBrian Paul if (width == 0 || height == 0 || depth == 0) { 45937607aeaf8b0fd35213635ba1c3743b6e059d48fBrian Paul /* stop after freeing old image */ 46037607aeaf8b0fd35213635ba1c3743b6e059d48fBrian Paul return; 46137607aeaf8b0fd35213635ba1c3743b6e059d48fBrian Paul } 46237607aeaf8b0fd35213635ba1c3743b6e059d48fBrian Paul 4634da1cdf78fa3b954840650fa46cf72da5daf149fBrian /* If this is the only mipmap level in the texture, could call 46424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * bmBufferData with NULL data to free the old block and avoid 46524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * waiting on any outstanding fences. 46624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 467753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer if (stObj->pt && 468d4074c509b5d28be0a2ec51d40329e1aed7047efMichel Dänzer (stObj->teximage_realloc || 469d4074c509b5d28be0a2ec51d40329e1aed7047efMichel Dänzer (/*stObj->pt->first_level == level &&*/ 470d4074c509b5d28be0a2ec51d40329e1aed7047efMichel Dänzer stObj->pt->last_level == level && 471d4074c509b5d28be0a2ec51d40329e1aed7047efMichel Dänzer stObj->pt->target != PIPE_TEXTURE_CUBE && 472d4074c509b5d28be0a2ec51d40329e1aed7047efMichel Dänzer !st_texture_match_image(stObj->pt, &stImage->base, 473d4074c509b5d28be0a2ec51d40329e1aed7047efMichel Dänzer stImage->face, stImage->level)))) { 47424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 47524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian DBG("release it\n"); 476f8dce51083042b4d3fabf48524835290b6725682Brian Paul pipe_texture_reference(&stObj->pt, NULL); 477753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer assert(!stObj->pt); 478d4074c509b5d28be0a2ec51d40329e1aed7047efMichel Dänzer stObj->teximage_realloc = FALSE; 47924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 48024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 481753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer if (!stObj->pt) { 482753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer guess_and_alloc_texture(ctx->st, stObj, stImage); 483753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer if (!stObj->pt) { 4843b3774b1227743147159676795b542c0eb7c2bdfBrian Paul _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage"); 4853b3774b1227743147159676795b542c0eb7c2bdfBrian Paul return; 48624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 48724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 48824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 489753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer assert(!stImage->pt); 49024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 491753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer if (stObj->pt && 492753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer st_texture_match_image(stObj->pt, &stImage->base, 49314b98343309fdcff3514f05020303f7b40e83a4aBrian stImage->face, stImage->level)) { 49424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 4954da19dbcaa9f3e2d20fffd0145bf0bc756dd7542Brian pipe_texture_reference(&stImage->pt, stObj->pt); 496753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer assert(stImage->pt); 49724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 49824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 499753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer if (!stImage->pt) 500753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer DBG("XXX: Image did not fit into texture - storing in local memory!\n"); 50124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 502987d59bb83e9e08192563e5f1b52949c5511053cMichel Dänzer /* st_CopyTexImage calls this function with pixels == NULL, with 503753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer * the expectation that the texture will be set up but nothing 50424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * more will be done. This is where those calls return: 50524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 50624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian if (compressed) { 50724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian pixels = _mesa_validate_pbo_compressed_teximage(ctx, imageSize, pixels, 50824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian unpack, 50924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian "glCompressedTexImage"); 51024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } else { 51124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian pixels = _mesa_validate_pbo_teximage(ctx, dims, width, height, 1, 51224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian format, type, 51324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian pixels, unpack, "glTexImage"); 51424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 51524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian if (!pixels) 51624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian return; 51724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 518753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer if (stImage->pt) { 519c9ed86a96483063f3d6789ed16645a3dca77d726Keith Whitwell texImage->Data = st_texture_image_map(ctx->st, stImage, 0, 520c9ed86a96483063f3d6789ed16645a3dca77d726Keith Whitwell PIPE_BUFFER_USAGE_CPU_WRITE); 5212a39dbe7364af5444b1eb43650dfc31ed09257dcBrian Paul if (stImage->surface) 5224ddd65967915ca4846f2831bc676c878a29dae4aJosé Fonseca dstRowStride = stImage->surface->stride; 52324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 52424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian else { 52524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian /* Allocate regular memory and store the image there temporarily. */ 52624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian if (texImage->IsCompressed) { 52724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian sizeInBytes = texImage->CompressedSize; 52824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian dstRowStride = 52924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian _mesa_compressed_row_stride(texImage->TexFormat->MesaFormat, width); 53024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian assert(dims != 3); 53124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 53224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian else { 53324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian dstRowStride = postConvWidth * texelBytes; 53424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian sizeInBytes = depth * dstRowStride * postConvHeight; 53524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 53624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 53724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian texImage->Data = malloc(sizeInBytes); 53824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 53924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 5402a39dbe7364af5444b1eb43650dfc31ed09257dcBrian Paul if (!texImage->Data) { 5412a39dbe7364af5444b1eb43650dfc31ed09257dcBrian Paul _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage"); 5422a39dbe7364af5444b1eb43650dfc31ed09257dcBrian Paul return; 5432a39dbe7364af5444b1eb43650dfc31ed09257dcBrian Paul } 5442a39dbe7364af5444b1eb43650dfc31ed09257dcBrian Paul 54524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian DBG("Upload image %dx%dx%d row_len %x pitch %x\n", 54624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian width, height, depth, width * texelBytes, dstRowStride); 54724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 54824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian /* Copy data. Would like to know when it's ok for us to eg. use 54924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * the blitter to copy. Or, use the hardware to do the format 55024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * conversion and copy: 55124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 55224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian if (compressed) { 553afc54983370033b65e3a7cbb29bd9c87156f0881Brian memcpy(texImage->Data, pixels, imageSize); 55424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 555753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer else { 556753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer GLuint srcImageStride = _mesa_image_image_stride(unpack, width, height, 557753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer format, type); 558753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer int i; 5595823f99d0fbc054b87aeb1bc15d413d3eadd27a8Brian const GLubyte *src = (const GLubyte *) pixels; 560753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer 561753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer for (i = 0; i++ < depth;) { 562753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer if (!texImage->TexFormat->StoreImage(ctx, dims, 563753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer texImage->_BaseFormat, 564753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer texImage->TexFormat, 565753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer texImage->Data, 566753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer 0, 0, 0, /* dstX/Y/Zoffset */ 567753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer dstRowStride, 568753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer texImage->ImageOffsets, 569753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer width, height, 1, 5705823f99d0fbc054b87aeb1bc15d413d3eadd27a8Brian format, type, src, unpack)) { 571753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage"); 572753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer } 573753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer 574753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer if (stImage->pt && i < depth) { 575c9ed86a96483063f3d6789ed16645a3dca77d726Keith Whitwell st_texture_image_unmap(ctx->st, stImage); 576c9ed86a96483063f3d6789ed16645a3dca77d726Keith Whitwell texImage->Data = st_texture_image_map(ctx->st, stImage, i, 577c9ed86a96483063f3d6789ed16645a3dca77d726Keith Whitwell PIPE_BUFFER_USAGE_CPU_WRITE); 5785823f99d0fbc054b87aeb1bc15d413d3eadd27a8Brian src += srcImageStride; 579753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer } 580753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer } 58124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 58224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 58324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian _mesa_unmap_teximage_pbo(ctx, unpack); 58424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 585753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer if (stImage->pt) { 586c9ed86a96483063f3d6789ed16645a3dca77d726Keith Whitwell st_texture_image_unmap(ctx->st, stImage); 58724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian texImage->Data = NULL; 58824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 58924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 59024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian if (level == texObj->BaseLevel && texObj->GenerateMipmap) { 59162abcb9aacc33218d0143a743c738435794b32a9Brian ctx->Driver.GenerateMipmap(ctx, target, texObj); 59224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 59324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 59424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 59524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 59624df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void 59724df8f895fe8807aa2ba058e71bd40adfc01d21eBrianst_TexImage3D(GLcontext * ctx, 5984e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul GLenum target, GLint level, 5994e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul GLint internalFormat, 6004e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul GLint width, GLint height, GLint depth, 6014e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul GLint border, 6024e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul GLenum format, GLenum type, const void *pixels, 6034e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul const struct gl_pixelstore_attrib *unpack, 6044e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul struct gl_texture_object *texObj, 6054e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul struct gl_texture_image *texImage) 60624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 60724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian st_TexImage(ctx, 3, target, level, 60824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian internalFormat, width, height, depth, border, 60924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian format, type, pixels, unpack, texObj, texImage, 0, 0); 61024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 61124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 61224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 61324df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void 61424df8f895fe8807aa2ba058e71bd40adfc01d21eBrianst_TexImage2D(GLcontext * ctx, 6154e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul GLenum target, GLint level, 6164e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul GLint internalFormat, 6174e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul GLint width, GLint height, GLint border, 6184e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul GLenum format, GLenum type, const void *pixels, 6194e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul const struct gl_pixelstore_attrib *unpack, 6204e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul struct gl_texture_object *texObj, 6214e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul struct gl_texture_image *texImage) 62224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 62324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian st_TexImage(ctx, 2, target, level, 62424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian internalFormat, width, height, 1, border, 62524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian format, type, pixels, unpack, texObj, texImage, 0, 0); 62624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 62724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 62824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 62924df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void 63024df8f895fe8807aa2ba058e71bd40adfc01d21eBrianst_TexImage1D(GLcontext * ctx, 6314e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul GLenum target, GLint level, 6324e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul GLint internalFormat, 6334e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul GLint width, GLint border, 6344e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul GLenum format, GLenum type, const void *pixels, 6354e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul const struct gl_pixelstore_attrib *unpack, 6364e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul struct gl_texture_object *texObj, 6374e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul struct gl_texture_image *texImage) 63824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 63924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian st_TexImage(ctx, 1, target, level, 64024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian internalFormat, width, 1, 1, border, 64124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian format, type, pixels, unpack, texObj, texImage, 0, 0); 64224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 64324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 64424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 64524df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void 6464e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paulst_CompressedTexImage2D(GLcontext *ctx, GLenum target, GLint level, 6474e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul GLint internalFormat, 6484e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul GLint width, GLint height, GLint border, 6494e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul GLsizei imageSize, const GLvoid *data, 6504e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul struct gl_texture_object *texObj, 6514e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul struct gl_texture_image *texImage) 65224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 65324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian st_TexImage(ctx, 2, target, level, 65424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian internalFormat, width, height, 1, border, 65524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 0, 0, data, &ctx->Unpack, texObj, texImage, imageSize, 1); 65624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 65724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 65824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 65924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian/** 66024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * Need to map texture image into memory before copying image data, 66124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * then unmap it. 66224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 66324df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void 66424df8f895fe8807aa2ba058e71bd40adfc01d21eBrianst_get_tex_image(GLcontext * ctx, GLenum target, GLint level, 66524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLenum format, GLenum type, GLvoid * pixels, 66624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian struct gl_texture_object *texObj, 66724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian struct gl_texture_image *texImage, int compressed) 66824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 66924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian struct st_texture_image *stImage = st_texture_image(texImage); 6704e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul GLuint dstImageStride = _mesa_image_image_stride(&ctx->Pack, 6714e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul texImage->Width, 6724e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul texImage->Height, 6734e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul format, type); 674753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer GLuint depth; 6756c534b830c6f5427c391c5225c34561141c201baMichal Krol GLuint i; 6765823f99d0fbc054b87aeb1bc15d413d3eadd27a8Brian GLubyte *dest; 67724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 67824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian /* Map */ 679753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer if (stImage->pt) { 68024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian /* Image is stored in hardware format in a buffer managed by the 68124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * kernel. Need to explicitly map and unmap it. 68224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 683c9ed86a96483063f3d6789ed16645a3dca77d726Keith Whitwell texImage->Data = st_texture_image_map(ctx->st, stImage, 0, 684c9ed86a96483063f3d6789ed16645a3dca77d726Keith Whitwell PIPE_BUFFER_USAGE_CPU_READ); 6854ddd65967915ca4846f2831bc676c878a29dae4aJosé Fonseca texImage->RowStride = stImage->surface->stride / stImage->pt->block.size; 68624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 68724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian else { 68824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian /* Otherwise, the image should actually be stored in 689753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer * texImage->Data. This is pretty confusing for 69024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * everybody, I'd much prefer to separate the two functions of 69124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * texImage->Data - storage for texture images in main memory 69224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * and access (ie mappings) of images. In other words, we'd 69324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * create a new texImage->Map field and leave Data simply for 69424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * storage. 69524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 696753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer assert(texImage->Data); 69724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 69824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 699753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer depth = texImage->Depth; 700753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer texImage->Depth = 1; 70124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 7025823f99d0fbc054b87aeb1bc15d413d3eadd27a8Brian dest = (GLubyte *) pixels; 7035823f99d0fbc054b87aeb1bc15d413d3eadd27a8Brian 704753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer for (i = 0; i++ < depth;) { 705753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer if (compressed) { 7065823f99d0fbc054b87aeb1bc15d413d3eadd27a8Brian _mesa_get_compressed_teximage(ctx, target, level, dest, 707753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer texObj, texImage); 708753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer } else { 7095823f99d0fbc054b87aeb1bc15d413d3eadd27a8Brian _mesa_get_teximage(ctx, target, level, format, type, dest, 710753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer texObj, texImage); 711753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer } 712753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer 713753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer if (stImage->pt && i < depth) { 714c9ed86a96483063f3d6789ed16645a3dca77d726Keith Whitwell st_texture_image_unmap(ctx->st, stImage); 715c9ed86a96483063f3d6789ed16645a3dca77d726Keith Whitwell texImage->Data = st_texture_image_map(ctx->st, stImage, i, 716c9ed86a96483063f3d6789ed16645a3dca77d726Keith Whitwell PIPE_BUFFER_USAGE_CPU_READ); 7175823f99d0fbc054b87aeb1bc15d413d3eadd27a8Brian dest += dstImageStride; 718753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer } 71924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 720753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer 721753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer texImage->Depth = depth; 72224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 72324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian /* Unmap */ 724753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer if (stImage->pt) { 725c9ed86a96483063f3d6789ed16645a3dca77d726Keith Whitwell st_texture_image_unmap(ctx->st, stImage); 726753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer texImage->Data = NULL; 72724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 72824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 72924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 73024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 73124df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void 73224df8f895fe8807aa2ba058e71bd40adfc01d21eBrianst_GetTexImage(GLcontext * ctx, GLenum target, GLint level, 7334e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul GLenum format, GLenum type, GLvoid * pixels, 7344e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul struct gl_texture_object *texObj, 7354e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul struct gl_texture_image *texImage) 73624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 73724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian st_get_tex_image(ctx, target, level, format, type, pixels, 73824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian texObj, texImage, 0); 73924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 74024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 74124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 74224df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void 74324df8f895fe8807aa2ba058e71bd40adfc01d21eBrianst_GetCompressedTexImage(GLcontext *ctx, GLenum target, GLint level, 7444e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul GLvoid *pixels, 7454e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul const struct gl_texture_object *texObj, 7464e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul const struct gl_texture_image *texImage) 74724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 74824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian st_get_tex_image(ctx, target, level, 0, 0, pixels, 74924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian (struct gl_texture_object *) texObj, 75024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian (struct gl_texture_image *) texImage, 1); 75124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 75224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 75324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 75424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 75524df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void 75624df8f895fe8807aa2ba058e71bd40adfc01d21eBrianst_TexSubimage(GLcontext * ctx, 7574e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul GLint dims, 7584e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul GLenum target, GLint level, 7594e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul GLint xoffset, GLint yoffset, GLint zoffset, 7604e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul GLint width, GLint height, GLint depth, 7614e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul GLenum format, GLenum type, const void *pixels, 7624e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul const struct gl_pixelstore_attrib *packing, 7634e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul struct gl_texture_object *texObj, 7644e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul struct gl_texture_image *texImage) 76524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 76624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian struct st_texture_image *stImage = st_texture_image(texImage); 76724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLuint dstRowStride; 768753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer GLuint srcImageStride = _mesa_image_image_stride(packing, width, height, 769753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer format, type); 770753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer int i; 7715823f99d0fbc054b87aeb1bc15d413d3eadd27a8Brian const GLubyte *src; 77224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 77324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian DBG("%s target %s level %d offset %d,%d %dx%d\n", __FUNCTION__, 77424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian _mesa_lookup_enum_by_nr(target), 77524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian level, xoffset, yoffset, width, height); 77624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 77724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian pixels = 77824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian _mesa_validate_pbo_teximage(ctx, dims, width, height, depth, format, 77924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian type, pixels, packing, "glTexSubImage2D"); 78024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian if (!pixels) 78124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian return; 78224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 78324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian /* Map buffer if necessary. Need to lock to prevent other contexts 78424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * from uploading the buffer under us. 78524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 786753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer if (stImage->pt) { 787c9ed86a96483063f3d6789ed16645a3dca77d726Keith Whitwell texImage->Data = st_texture_image_map(ctx->st, stImage, zoffset, 788c9ed86a96483063f3d6789ed16645a3dca77d726Keith Whitwell PIPE_BUFFER_USAGE_CPU_WRITE); 7892a39dbe7364af5444b1eb43650dfc31ed09257dcBrian Paul if (stImage->surface) 7904ddd65967915ca4846f2831bc676c878a29dae4aJosé Fonseca dstRowStride = stImage->surface->stride; 791753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer } 792753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer 7939b44f5a7550d8ede2eda763770e927df4c15cc8eBrian Paul if (!texImage->Data) { 7949b44f5a7550d8ede2eda763770e927df4c15cc8eBrian Paul _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage"); 7959b44f5a7550d8ede2eda763770e927df4c15cc8eBrian Paul return; 7969b44f5a7550d8ede2eda763770e927df4c15cc8eBrian Paul } 7979b44f5a7550d8ede2eda763770e927df4c15cc8eBrian Paul 7985823f99d0fbc054b87aeb1bc15d413d3eadd27a8Brian src = (const GLubyte *) pixels; 7995823f99d0fbc054b87aeb1bc15d413d3eadd27a8Brian 800753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer for (i = 0; i++ < depth;) { 801753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer if (!texImage->TexFormat->StoreImage(ctx, dims, texImage->_BaseFormat, 802753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer texImage->TexFormat, 803753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer texImage->Data, 804753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer xoffset, yoffset, 0, 805753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer dstRowStride, 806753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer texImage->ImageOffsets, 807753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer width, height, 1, 8085823f99d0fbc054b87aeb1bc15d413d3eadd27a8Brian format, type, src, packing)) { 8099b44f5a7550d8ede2eda763770e927df4c15cc8eBrian Paul _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage"); 810753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer } 811753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer 812753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer if (stImage->pt && i < depth) { 8139b44f5a7550d8ede2eda763770e927df4c15cc8eBrian Paul /* map next slice of 3D texture */ 814c9ed86a96483063f3d6789ed16645a3dca77d726Keith Whitwell st_texture_image_unmap(ctx->st, stImage); 815c9ed86a96483063f3d6789ed16645a3dca77d726Keith Whitwell texImage->Data = st_texture_image_map(ctx->st, stImage, zoffset + i, 816c9ed86a96483063f3d6789ed16645a3dca77d726Keith Whitwell PIPE_BUFFER_USAGE_CPU_WRITE); 8175823f99d0fbc054b87aeb1bc15d413d3eadd27a8Brian src += srcImageStride; 818753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer } 81924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 82024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 82124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian if (level == texObj->BaseLevel && texObj->GenerateMipmap) { 8223ccbaa977f96eaa849093875dd0944f744ee1e21Brian ctx->Driver.GenerateMipmap(ctx, target, texObj); 82324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 82424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 82524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian _mesa_unmap_teximage_pbo(ctx, packing); 82624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 827753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer if (stImage->pt) { 828c9ed86a96483063f3d6789ed16645a3dca77d726Keith Whitwell st_texture_image_unmap(ctx->st, stImage); 82924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian texImage->Data = NULL; 83024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 83124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 83224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 83324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 83424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 83524df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void 83624df8f895fe8807aa2ba058e71bd40adfc01d21eBrianst_TexSubImage3D(GLcontext * ctx, 83724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLenum target, 83824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLint level, 83924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLint xoffset, GLint yoffset, GLint zoffset, 84024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLsizei width, GLsizei height, GLsizei depth, 84124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLenum format, GLenum type, 84224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian const GLvoid * pixels, 84324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian const struct gl_pixelstore_attrib *packing, 84424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian struct gl_texture_object *texObj, 84524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian struct gl_texture_image *texImage) 84624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 847b245840b86cf877c9b8d666edf229364a84f1deaBrian st_TexSubimage(ctx, 3, target, level, 848b245840b86cf877c9b8d666edf229364a84f1deaBrian xoffset, yoffset, zoffset, 849b245840b86cf877c9b8d666edf229364a84f1deaBrian width, height, depth, 850b245840b86cf877c9b8d666edf229364a84f1deaBrian format, type, pixels, packing, texObj, texImage); 85124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 85224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 85324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 85424df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void 85524df8f895fe8807aa2ba058e71bd40adfc01d21eBrianst_TexSubImage2D(GLcontext * ctx, 85624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLenum target, 85724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLint level, 85824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLint xoffset, GLint yoffset, 85924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLsizei width, GLsizei height, 86024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLenum format, GLenum type, 86124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian const GLvoid * pixels, 86224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian const struct gl_pixelstore_attrib *packing, 86324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian struct gl_texture_object *texObj, 86424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian struct gl_texture_image *texImage) 86524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 866b245840b86cf877c9b8d666edf229364a84f1deaBrian st_TexSubimage(ctx, 2, target, level, 867b245840b86cf877c9b8d666edf229364a84f1deaBrian xoffset, yoffset, 0, 868b245840b86cf877c9b8d666edf229364a84f1deaBrian width, height, 1, 869b245840b86cf877c9b8d666edf229364a84f1deaBrian format, type, pixels, packing, texObj, texImage); 87024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 87124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 87224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 87324df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void 87424df8f895fe8807aa2ba058e71bd40adfc01d21eBrianst_TexSubImage1D(GLcontext * ctx, 87524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLenum target, 87624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLint level, 87724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLint xoffset, 87824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLsizei width, 87924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLenum format, GLenum type, 88024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian const GLvoid * pixels, 88124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian const struct gl_pixelstore_attrib *packing, 88224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian struct gl_texture_object *texObj, 88324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian struct gl_texture_image *texImage) 88424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 885b245840b86cf877c9b8d666edf229364a84f1deaBrian st_TexSubimage(ctx, 1, target, level, 886b245840b86cf877c9b8d666edf229364a84f1deaBrian xoffset, 0, 0, 887b245840b86cf877c9b8d666edf229364a84f1deaBrian width, 1, 1, 888b245840b86cf877c9b8d666edf229364a84f1deaBrian format, type, pixels, packing, texObj, texImage); 88924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 89024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 89124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 89224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 89324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian/** 894038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian * Return 0 for GL_TEXTURE_CUBE_MAP_POSITIVE_X, 895038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian * 1 for GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 896038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian * etc. 897038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian * XXX duplicated from main/teximage.c 898038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian */ 899038cb561eb094af2f2ba06e18e61246fc0c87c3cBrianstatic uint 900038cb561eb094af2f2ba06e18e61246fc0c87c3cBriantexture_face(GLenum target) 901038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian{ 902038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian if (target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB && 903038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB) 904038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian return (GLuint) target - (GLuint) GL_TEXTURE_CUBE_MAP_POSITIVE_X; 905038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian else 906038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian return 0; 907038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian} 908038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian 909038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian 910038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian 911038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian/** 912b859cdf6f191b4d8b56537c8dc30082a7e2d94b3Michel Dänzer * Do a CopyTexSubImage operation by mapping the source surface and 913b859cdf6f191b4d8b56537c8dc30082a7e2d94b3Michel Dänzer * dest surface and using get_tile()/put_tile() to access the pixels/texels. 914c6717a86420d7141013165f7acd50b3c3f751756Brian * 915c6717a86420d7141013165f7acd50b3c3f751756Brian * Note: srcY=0=TOP of renderbuffer 916038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian */ 917038cb561eb094af2f2ba06e18e61246fc0c87c3cBrianstatic void 918038cb561eb094af2f2ba06e18e61246fc0c87c3cBrianfallback_copy_texsubimage(GLcontext *ctx, 919038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian GLenum target, 920038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian GLint level, 921038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian struct st_renderbuffer *strb, 922038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian struct st_texture_image *stImage, 923038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian GLenum baseFormat, 924038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian GLint destX, GLint destY, GLint destZ, 925038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian GLint srcX, GLint srcY, 926038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian GLsizei width, GLsizei height) 927038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian{ 928038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian struct pipe_context *pipe = ctx->st->pipe; 9296f715dcc219071e574e363a9db4365c9c31ebbd3Brian struct pipe_screen *screen = pipe->screen; 930038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian const uint face = texture_face(target); 931753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer struct pipe_texture *pt = stImage->pt; 932038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian struct pipe_surface *src_surf, *dest_surf; 933038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian 934f3048ad90ed2e4583f0f7aaf35a0f4aa581942ddBrian Paul /* We'd use strb->surface, here but it's created for GPU read/write only */ 935f3048ad90ed2e4583f0f7aaf35a0f4aa581942ddBrian Paul src_surf = pipe->screen->get_tex_surface( pipe->screen, 936f3048ad90ed2e4583f0f7aaf35a0f4aa581942ddBrian Paul strb->texture, 937f3048ad90ed2e4583f0f7aaf35a0f4aa581942ddBrian Paul 0, 0, 0, 938f3048ad90ed2e4583f0f7aaf35a0f4aa581942ddBrian Paul PIPE_BUFFER_USAGE_CPU_READ); 939f3048ad90ed2e4583f0f7aaf35a0f4aa581942ddBrian Paul 940c9ed86a96483063f3d6789ed16645a3dca77d726Keith Whitwell dest_surf = screen->get_tex_surface(screen, pt, face, level, destZ, 941c9ed86a96483063f3d6789ed16645a3dca77d726Keith Whitwell PIPE_BUFFER_USAGE_CPU_WRITE); 942038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian 943cc94863429d8a6cef8dbf861e78701a458d30f5aBrian Paul assert(width <= MAX_WIDTH); 944038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian 945cc94863429d8a6cef8dbf861e78701a458d30f5aBrian Paul if (baseFormat == GL_DEPTH_COMPONENT) { 946cc94863429d8a6cef8dbf861e78701a458d30f5aBrian Paul const GLboolean scaleOrBias = (ctx->Pixel.DepthScale != 1.0F || 947cc94863429d8a6cef8dbf861e78701a458d30f5aBrian Paul ctx->Pixel.DepthBias != 0.0F); 94827858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul GLint row, yStep; 949cc94863429d8a6cef8dbf861e78701a458d30f5aBrian Paul 95027858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul /* determine bottom-to-top vs. top-to-bottom order for src buffer */ 95127858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul if (st_fb_orientation(ctx->ReadBuffer) == Y_0_TOP) { 95227858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul srcY = strb->Base.Height - 1 - srcY; 95327858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul yStep = -1; 95427858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul } 95527858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul else { 95627858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul yStep = 1; 95727858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul } 95827858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul 95927858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul /* To avoid a large temp memory allocation, do copy row by row */ 960275b09f2569c8bea5dcca1643c93aa6a43d7e2a2Brian Paul for (row = 0; row < height; row++, srcY += yStep, destY++) { 961cc94863429d8a6cef8dbf861e78701a458d30f5aBrian Paul uint data[MAX_WIDTH]; 96236dd89c8a7f2a911e8f7f18d1edcaf982a75a438José Fonseca pipe_get_tile_z(src_surf, srcX, srcY, width, 1, data); 963cc94863429d8a6cef8dbf861e78701a458d30f5aBrian Paul if (scaleOrBias) { 964cc94863429d8a6cef8dbf861e78701a458d30f5aBrian Paul _mesa_scale_and_bias_depth_uint(ctx, width, data); 965cc94863429d8a6cef8dbf861e78701a458d30f5aBrian Paul } 96636dd89c8a7f2a911e8f7f18d1edcaf982a75a438José Fonseca pipe_put_tile_z(dest_surf, destX, destY, width, 1, data); 967cc94863429d8a6cef8dbf861e78701a458d30f5aBrian Paul } 968cc94863429d8a6cef8dbf861e78701a458d30f5aBrian Paul } 969cc94863429d8a6cef8dbf861e78701a458d30f5aBrian Paul else { 970cc94863429d8a6cef8dbf861e78701a458d30f5aBrian Paul /* RGBA format */ 97127858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul GLfloat *tempSrc = 97227858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul (GLfloat *) _mesa_malloc(width * height * 4 * sizeof(GLfloat)); 97327858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul GLvoid *texDest = 97427858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul st_texture_image_map(ctx->st, stImage, 0,PIPE_BUFFER_USAGE_CPU_WRITE); 97527858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul 97627858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul if (tempSrc && texDest) { 97727858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul const GLint dims = 2; 97827858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul struct gl_texture_image *texImage = &stImage->base; 97927858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul GLint dstRowStride = stImage->surface->stride; 98027858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul struct gl_pixelstore_attrib unpack = ctx->DefaultPacking; 98127858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul 98227858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul if (st_fb_orientation(ctx->ReadBuffer) == Y_0_TOP) { 98327858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul /* need to invert src */ 98427858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul srcY = strb->Base.Height - srcY - height; 98527858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul unpack.Invert = GL_TRUE; 986cc94863429d8a6cef8dbf861e78701a458d30f5aBrian Paul } 98727858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul 98827858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul /* get float/RGBA image from framebuffer */ 98927858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul /* XXX this usually involves a lot of int/float conversion. 99027858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul * try to avoid that someday. 99127858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul */ 99227858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul pipe_get_tile_rgba(src_surf, srcX, srcY, width, height, tempSrc); 99327858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul 99427858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul /* Store into texture memory. 99527858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul * Note that this does some special things such as pixel transfer 99627858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul * ops and format conversion. In particular, if the dest tex format 99727858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul * is actually RGBA but the user created the texture as GL_RGB we 99827858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul * need to fill-in/override the alpha channel with 1.0. 99927858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul */ 100027858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul texImage->TexFormat->StoreImage(ctx, dims, 100127858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul texImage->_BaseFormat, 100227858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul texImage->TexFormat, 100327858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul texDest, 100427858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul destX, destY, destZ, 100527858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul dstRowStride, 100627858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul texImage->ImageOffsets, 100727858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul width, height, 1, 100827858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul GL_RGBA, GL_FLOAT, tempSrc, /* src */ 100927858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul &unpack); 101027858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul } 101127858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul else { 101227858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage"); 10135c83f1371978472fbe4bba8f686733c6b519874aBrian } 101427858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul 101527858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul if (tempSrc) 101627858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul _mesa_free(tempSrc); 101727858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul if (texDest) 101827858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul st_texture_image_unmap(ctx->st, stImage); 10195c83f1371978472fbe4bba8f686733c6b519874aBrian } 1020d0279fc4b38c72356a341173317bcd45d9093f45Michel Dänzer 1021d0279fc4b38c72356a341173317bcd45d9093f45Michel Dänzer screen->tex_surface_release(screen, &dest_surf); 1022f3048ad90ed2e4583f0f7aaf35a0f4aa581942ddBrian Paul screen->tex_surface_release(screen, &src_surf); 1023038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian} 1024038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian 1025038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian 1026038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian/** 10274e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul * Do a CopyTex[Sub]Image1/2/3D() using a hardware (blit) path if possible. 10284e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul * Note that the region to copy has already been clipped so we know we 10294e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul * won't read from outside the source renderbuffer's bounds. 1030c6717a86420d7141013165f7acd50b3c3f751756Brian * 10314e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul * Note: srcY=0=Bottom of renderbuffer (GL convention) 103224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 1033038cb561eb094af2f2ba06e18e61246fc0c87c3cBrianstatic void 10344e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paulst_copy_texsubimage(GLcontext *ctx, 1035038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian GLenum target, GLint level, 1036038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian GLint destX, GLint destY, GLint destZ, 1037038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian GLint srcX, GLint srcY, 1038038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian GLsizei width, GLsizei height) 103924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 1040038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian struct gl_texture_unit *texUnit = 1041038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; 1042038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian struct gl_texture_object *texObj = 1043038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian _mesa_select_tex_object(ctx, texUnit, target); 1044038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian struct gl_texture_image *texImage = 1045038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian _mesa_select_tex_image(ctx, texObj, target, level); 1046038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian struct st_texture_image *stImage = st_texture_image(texImage); 10474e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul const GLenum texBaseFormat = texImage->InternalFormat; 1048b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian struct gl_framebuffer *fb = ctx->ReadBuffer; 1049b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian struct st_renderbuffer *strb; 1050b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian struct pipe_context *pipe = ctx->st->pipe; 10516f715dcc219071e574e363a9db4365c9c31ebbd3Brian struct pipe_screen *screen = pipe->screen; 105227858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul enum pipe_format dest_format, src_format; 1053cc94863429d8a6cef8dbf861e78701a458d30f5aBrian Paul GLboolean use_fallback = GL_TRUE; 105427858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul GLboolean matching_base_formats; 105524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 105689e9d6b6db933c870443714c3d7c9539d117cddfBrian Paul st_flush(ctx->st, PIPE_FLUSH_RENDER_CACHE, NULL); 1057a479bf62353b6517841e620122112e7565d2391cBrian Paul 1058b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian /* determine if copying depth or color data */ 10594e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul if (texBaseFormat == GL_DEPTH_COMPONENT) { 1060b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian strb = st_renderbuffer(fb->_DepthBuffer); 106124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 10624e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul else if (texBaseFormat == GL_DEPTH_STENCIL_EXT) { 1063b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian strb = st_renderbuffer(fb->_StencilBuffer); 1064b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian } 1065b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian else { 10664e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul /* texBaseFormat == GL_RGB, GL_RGBA, GL_ALPHA, etc */ 1067b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian strb = st_renderbuffer(fb->_ColorReadBuffer); 1068b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian } 1069b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian 1070b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian assert(strb); 1071b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian assert(strb->surface); 1072753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer assert(stImage->pt); 1073c6717a86420d7141013165f7acd50b3c3f751756Brian 1074b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian src_format = strb->surface->format; 1075753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer dest_format = stImage->pt->format; 1076b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian 107727858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul /* 107827858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul * Determine if the src framebuffer and dest texture have the same 107927858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul * base format. We need this to detect a case such as the framebuffer 108027858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul * being GL_RGBA but the texture being GL_RGB. If the actual hardware 108127858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul * texture format stores RGBA we need to set A=1 (overriding the 108227858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul * framebuffer's alpha values). We can't do that with the blit or 108327858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul * textured-quad paths. 108427858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul */ 108527858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul matching_base_formats = (strb->Base._BaseFormat == texImage->_BaseFormat); 108679931e38abc62286151121a3f59127e296144551Michel Dänzer 108727858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul if (matching_base_formats && ctx->_ImageTransferState == 0x0) { 108827858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul /* try potential hardware path */ 108927858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul struct pipe_surface *dest_surface = NULL; 1090b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian 10913c0dc8242b64518d5635263ba65b39afa919dd86Michel Dänzer if (src_format == dest_format) { 10924e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul /* use surface_copy() / blit */ 1093a479bf62353b6517841e620122112e7565d2391cBrian Paul boolean do_flip = (st_fb_orientation(ctx->ReadBuffer) == Y_0_TOP); 109427858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul 109527858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul dest_surface = screen->get_tex_surface(screen, stImage->pt, 109627858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul stImage->face, stImage->level, 109727858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul destZ, 109827858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul PIPE_BUFFER_USAGE_GPU_WRITE); 1099145a45e9d6807add8229f1fc9c63fbb6951b1b88Brian Paul if (do_flip) 1100145a45e9d6807add8229f1fc9c63fbb6951b1b88Brian Paul srcY = strb->surface->height - srcY - height; 1101145a45e9d6807add8229f1fc9c63fbb6951b1b88Brian Paul 1102145a45e9d6807add8229f1fc9c63fbb6951b1b88Brian Paul /* for surface_copy(), y=0=top, always */ 1103a479bf62353b6517841e620122112e7565d2391cBrian Paul pipe->surface_copy(pipe, 1104a479bf62353b6517841e620122112e7565d2391cBrian Paul do_flip, 1105a479bf62353b6517841e620122112e7565d2391cBrian Paul /* dest */ 1106a479bf62353b6517841e620122112e7565d2391cBrian Paul dest_surface, 1107a479bf62353b6517841e620122112e7565d2391cBrian Paul destX, destY, 1108a479bf62353b6517841e620122112e7565d2391cBrian Paul /* src */ 1109a479bf62353b6517841e620122112e7565d2391cBrian Paul strb->surface, 1110a479bf62353b6517841e620122112e7565d2391cBrian Paul srcX, srcY, 1111a479bf62353b6517841e620122112e7565d2391cBrian Paul /* size */ 1112a479bf62353b6517841e620122112e7565d2391cBrian Paul width, height); 1113a479bf62353b6517841e620122112e7565d2391cBrian Paul use_fallback = GL_FALSE; 1114cc94863429d8a6cef8dbf861e78701a458d30f5aBrian Paul } 11154e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul else if (screen->is_format_supported(screen, src_format, 11168aafc03b260ab8923f1b373f7effa75bcdb40a72José Fonseca PIPE_TEXTURE_2D, 11178aafc03b260ab8923f1b373f7effa75bcdb40a72José Fonseca PIPE_TEXTURE_USAGE_SAMPLER, 11188aafc03b260ab8923f1b373f7effa75bcdb40a72José Fonseca 0) && 11194e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul screen->is_format_supported(screen, dest_format, 11208aafc03b260ab8923f1b373f7effa75bcdb40a72José Fonseca PIPE_TEXTURE_2D, 11218aafc03b260ab8923f1b373f7effa75bcdb40a72José Fonseca PIPE_TEXTURE_USAGE_RENDER_TARGET, 11228aafc03b260ab8923f1b373f7effa75bcdb40a72José Fonseca 0)) { 11234e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul /* draw textured quad to do the copy */ 1124a479bf62353b6517841e620122112e7565d2391cBrian Paul boolean do_flip = (st_fb_orientation(ctx->ReadBuffer) == Y_0_TOP); 1125a479bf62353b6517841e620122112e7565d2391cBrian Paul int srcY0, srcY1; 112627858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul 112727858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul dest_surface = screen->get_tex_surface(screen, stImage->pt, 112827858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul stImage->face, stImage->level, 112927858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul destZ, 113027858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul PIPE_BUFFER_USAGE_GPU_WRITE); 113127858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul 1132a479bf62353b6517841e620122112e7565d2391cBrian Paul if (do_flip) { 1133a479bf62353b6517841e620122112e7565d2391cBrian Paul srcY1 = strb->Base.Height - srcY - height; 1134a479bf62353b6517841e620122112e7565d2391cBrian Paul srcY0 = srcY1 + height; 1135a479bf62353b6517841e620122112e7565d2391cBrian Paul } 1136a479bf62353b6517841e620122112e7565d2391cBrian Paul else { 1137a479bf62353b6517841e620122112e7565d2391cBrian Paul srcY0 = srcY; 1138a479bf62353b6517841e620122112e7565d2391cBrian Paul srcY1 = srcY0 + height; 1139a479bf62353b6517841e620122112e7565d2391cBrian Paul } 11403c0dc8242b64518d5635263ba65b39afa919dd86Michel Dänzer util_blit_pixels(ctx->st->blit, 11413c0dc8242b64518d5635263ba65b39afa919dd86Michel Dänzer strb->surface, 1142a479bf62353b6517841e620122112e7565d2391cBrian Paul srcX, srcY0, 1143a479bf62353b6517841e620122112e7565d2391cBrian Paul srcX + width, srcY1, 11443c0dc8242b64518d5635263ba65b39afa919dd86Michel Dänzer dest_surface, 1145a479bf62353b6517841e620122112e7565d2391cBrian Paul destX, destY, 1146a479bf62353b6517841e620122112e7565d2391cBrian Paul destX + width, destY + height, 11473c0dc8242b64518d5635263ba65b39afa919dd86Michel Dänzer 0.0, PIPE_TEX_MIPFILTER_NEAREST); 1148cc94863429d8a6cef8dbf861e78701a458d30f5aBrian Paul use_fallback = GL_FALSE; 11493c0dc8242b64518d5635263ba65b39afa919dd86Michel Dänzer } 115079931e38abc62286151121a3f59127e296144551Michel Dänzer 115127858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul if (dest_surface) 115227858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul pipe_surface_reference(&dest_surface, NULL); 1153038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian } 1154cc94863429d8a6cef8dbf861e78701a458d30f5aBrian Paul 1155cc94863429d8a6cef8dbf861e78701a458d30f5aBrian Paul if (use_fallback) { 11564e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul /* software fallback */ 1157038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian fallback_copy_texsubimage(ctx, target, level, 11584e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul strb, stImage, texBaseFormat, 1159038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian destX, destY, destZ, 1160038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian srcX, srcY, width, height); 1161038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian } 1162038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian 116324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian if (level == texObj->BaseLevel && texObj->GenerateMipmap) { 11643ccbaa977f96eaa849093875dd0944f744ee1e21Brian ctx->Driver.GenerateMipmap(ctx, target, texObj); 116524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 116624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 116724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 116824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 1169038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian 117024df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void 117124df8f895fe8807aa2ba058e71bd40adfc01d21eBrianst_CopyTexImage1D(GLcontext * ctx, GLenum target, GLint level, 117224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLenum internalFormat, 117324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLint x, GLint y, GLsizei width, GLint border) 117424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 117524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian struct gl_texture_unit *texUnit = 117624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; 117724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian struct gl_texture_object *texObj = 117824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian _mesa_select_tex_object(ctx, texUnit, target); 117924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian struct gl_texture_image *texImage = 118024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian _mesa_select_tex_image(ctx, texObj, target, level); 118124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 1182038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian#if 0 118324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian if (border) 118424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian goto fail; 1185038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian#endif 118624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 1187753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer /* Setup or redefine the texture object, texture and texture 118824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * image. Don't populate yet. 118924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 119024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian ctx->Driver.TexImage1D(ctx, target, level, internalFormat, 119124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian width, border, 119224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GL_RGBA, CHAN_TYPE, NULL, 119324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian &ctx->DefaultPacking, texObj, texImage); 119424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 11954e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul st_copy_texsubimage(ctx, target, level, 11964e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul 0, 0, 0, /* destX,Y,Z */ 11974e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul x, y, width, 1); /* src X, Y, size */ 119824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 119924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 120024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 120124df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void 120224df8f895fe8807aa2ba058e71bd40adfc01d21eBrianst_CopyTexImage2D(GLcontext * ctx, GLenum target, GLint level, 120324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLenum internalFormat, 120424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLint x, GLint y, GLsizei width, GLsizei height, 120524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLint border) 120624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 120724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian struct gl_texture_unit *texUnit = 120824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; 120924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian struct gl_texture_object *texObj = 121024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian _mesa_select_tex_object(ctx, texUnit, target); 121124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian struct gl_texture_image *texImage = 121224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian _mesa_select_tex_image(ctx, texObj, target, level); 121324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 1214753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer /* Setup or redefine the texture object, texture and texture 121524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * image. Don't populate yet. 121624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 121724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian ctx->Driver.TexImage2D(ctx, target, level, internalFormat, 121824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian width, height, border, 121924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GL_RGBA, CHAN_TYPE, NULL, 122024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian &ctx->DefaultPacking, texObj, texImage); 122124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 12224e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul st_copy_texsubimage(ctx, target, level, 12234e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul 0, 0, 0, /* destX,Y,Z */ 12244e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul x, y, width, height); /* src X, Y, size */ 122524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 122624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 122724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 122824df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void 122924df8f895fe8807aa2ba058e71bd40adfc01d21eBrianst_CopyTexSubImage1D(GLcontext * ctx, GLenum target, GLint level, 123024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLint xoffset, GLint x, GLint y, GLsizei width) 123124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 1232038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian const GLint yoffset = 0, zoffset = 0; 1233038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian const GLsizei height = 1; 12344e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul st_copy_texsubimage(ctx, target, level, 12354e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul xoffset, yoffset, zoffset, /* destX,Y,Z */ 12364e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul x, y, width, height); /* src X, Y, size */ 123724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 123824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 123924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 124024df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void 124124df8f895fe8807aa2ba058e71bd40adfc01d21eBrianst_CopyTexSubImage2D(GLcontext * ctx, GLenum target, GLint level, 124224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLint xoffset, GLint yoffset, 124324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLint x, GLint y, GLsizei width, GLsizei height) 124424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 1245038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian const GLint zoffset = 0; 12464e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul st_copy_texsubimage(ctx, target, level, 12474e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul xoffset, yoffset, zoffset, /* destX,Y,Z */ 12484e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul x, y, width, height); /* src X, Y, size */ 1249038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian} 125024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 125124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 1252038cb561eb094af2f2ba06e18e61246fc0c87c3cBrianstatic void 1253038cb561eb094af2f2ba06e18e61246fc0c87c3cBrianst_CopyTexSubImage3D(GLcontext * ctx, GLenum target, GLint level, 1254038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian GLint xoffset, GLint yoffset, GLint zoffset, 1255038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian GLint x, GLint y, GLsizei width, GLsizei height) 1256038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian{ 12574e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul st_copy_texsubimage(ctx, target, level, 12584e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul xoffset, yoffset, zoffset, /* destX,Y,Z */ 12594e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul x, y, width, height); /* src X, Y, size */ 126024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 126124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 126224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 126324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian/** 126424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * Compute which mipmap levels that really need to be sent to the hardware. 126524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * This depends on the base image size, GL_TEXTURE_MIN_LOD, 126624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * GL_TEXTURE_MAX_LOD, GL_TEXTURE_BASE_LEVEL, and GL_TEXTURE_MAX_LEVEL. 126724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 126824df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void 126914b98343309fdcff3514f05020303f7b40e83a4aBriancalculate_first_last_level(struct st_texture_object *stObj) 127024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 127114b98343309fdcff3514f05020303f7b40e83a4aBrian struct gl_texture_object *tObj = &stObj->base; 127224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 127324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian /* These must be signed values. MinLod and MaxLod can be negative numbers, 127424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * and having firstLevel and lastLevel as signed prevents the need for 127524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * extra sign checks. 127624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 127724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian int firstLevel; 127824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian int lastLevel; 127924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 128024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian /* Yes, this looks overly complicated, but it's all needed. 128124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 128224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian switch (tObj->Target) { 128324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian case GL_TEXTURE_1D: 128424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian case GL_TEXTURE_2D: 128524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian case GL_TEXTURE_3D: 128624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian case GL_TEXTURE_CUBE_MAP: 128724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian if (tObj->MinFilter == GL_NEAREST || tObj->MinFilter == GL_LINEAR) { 128824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian /* GL_NEAREST and GL_LINEAR only care about GL_TEXTURE_BASE_LEVEL. 128924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 129024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian firstLevel = lastLevel = tObj->BaseLevel; 129124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 129224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian else { 12934da1cdf78fa3b954840650fa46cf72da5daf149fBrian firstLevel = 0; 12944e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul lastLevel = MIN2(tObj->MaxLevel, 12954e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul (int) tObj->Image[0][tObj->BaseLevel]->WidthLog2); 129624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 129724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian break; 129824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian case GL_TEXTURE_RECTANGLE_NV: 129924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian case GL_TEXTURE_4D_SGIS: 130024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian firstLevel = lastLevel = 0; 130124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian break; 130224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian default: 130324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian return; 130424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 130524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 130614b98343309fdcff3514f05020303f7b40e83a4aBrian stObj->lastLevel = lastLevel; 130724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 130824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 130924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 131024df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void 1311753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzercopy_image_data_to_texture(struct st_context *st, 1312753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer struct st_texture_object *stObj, 13134da1cdf78fa3b954840650fa46cf72da5daf149fBrian GLuint dstLevel, 1314753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer struct st_texture_image *stImage) 131524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 1316753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer if (stImage->pt) { 131724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian /* Copy potentially with the blitter: 131824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 1319753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer st_texture_image_copy(st->pipe, 13204da1cdf78fa3b954840650fa46cf72da5daf149fBrian stObj->pt, dstLevel, /* dest texture, level */ 13214da1cdf78fa3b954840650fa46cf72da5daf149fBrian stImage->pt, /* src texture */ 13224da1cdf78fa3b954840650fa46cf72da5daf149fBrian stImage->face 132328b315dc1aed36bebadfacbd55e481e7baacfcb5Brian ); 132424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 1325f8dce51083042b4d3fabf48524835290b6725682Brian Paul pipe_texture_reference(&stImage->pt, NULL); 132624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 13274c50969334844bc9aa622176c3ebcbc733394f78Brian Paul else if (stImage->base.Data) { 132824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian assert(stImage->base.Data != NULL); 132924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 133024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian /* More straightforward upload. 133124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 1332753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer st_texture_image_data(st->pipe, 1333753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer stObj->pt, 133424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian stImage->face, 1335c2497879f127251994064a0e0c24901782adae9eBrian Paul dstLevel, 133624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian stImage->base.Data, 13374ddd65967915ca4846f2831bc676c878a29dae4aJosé Fonseca stImage->base.RowStride * 13384ddd65967915ca4846f2831bc676c878a29dae4aJosé Fonseca stObj->pt->block.size, 133924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian stImage->base.RowStride * 13404ddd65967915ca4846f2831bc676c878a29dae4aJosé Fonseca stImage->base.Height * 13414ddd65967915ca4846f2831bc676c878a29dae4aJosé Fonseca stObj->pt->block.size); 134224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian _mesa_align_free(stImage->base.Data); 134324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian stImage->base.Data = NULL; 134424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 134524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 13464da19dbcaa9f3e2d20fffd0145bf0bc756dd7542Brian pipe_texture_reference(&stImage->pt, stObj->pt); 134724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 134824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 134924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 1350afc54983370033b65e3a7cbb29bd9c87156f0881Brian/** 1351afc54983370033b65e3a7cbb29bd9c87156f0881Brian * Called during state validation. When this function is finished, 1352afc54983370033b65e3a7cbb29bd9c87156f0881Brian * the texture object should be ready for rendering. 13533b3774b1227743147159676795b542c0eb7c2bdfBrian Paul * \return GL_TRUE for success, GL_FALSE for failure (out of mem) 135424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 135514b98343309fdcff3514f05020303f7b40e83a4aBrianGLboolean 1356753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzerst_finalize_texture(GLcontext *ctx, 1357c3af68dc5022715cc8f126b7df12f3f5248aefe7Keith Whitwell struct pipe_context *pipe, 1358c3af68dc5022715cc8f126b7df12f3f5248aefe7Keith Whitwell struct gl_texture_object *tObj, 1359753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer GLboolean *needFlush) 136024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 136114b98343309fdcff3514f05020303f7b40e83a4aBrian struct st_texture_object *stObj = st_texture_object(tObj); 1362afc54983370033b65e3a7cbb29bd9c87156f0881Brian const GLuint nr_faces = (stObj->base.Target == GL_TEXTURE_CUBE_MAP) ? 6 : 1; 136324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian int comp_byte = 0; 136424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian int cpp; 13654da1cdf78fa3b954840650fa46cf72da5daf149fBrian GLuint face; 136624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian struct st_texture_image *firstImage; 136724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 136824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian *needFlush = GL_FALSE; 136924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 137024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian /* We know/require this is true by now: 137124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 137214b98343309fdcff3514f05020303f7b40e83a4aBrian assert(stObj->base._Complete); 137324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 1374753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer /* What levels must the texture include at a minimum? 137524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 137614b98343309fdcff3514f05020303f7b40e83a4aBrian calculate_first_last_level(stObj); 13774da1cdf78fa3b954840650fa46cf72da5daf149fBrian firstImage = st_texture_image(stObj->base.Image[0][stObj->base.BaseLevel]); 137824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 1379753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer /* If both firstImage and stObj point to a texture which can contain 138024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * all active images, favour firstImage. Note that because of the 138124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * completeness requirement, we know that the image dimensions 138224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * will match. 138324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 1384753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer if (firstImage->pt && 1385753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer firstImage->pt != stObj->pt && 1386753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer firstImage->pt->last_level >= stObj->lastLevel) { 138724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 13884da19dbcaa9f3e2d20fffd0145bf0bc756dd7542Brian pipe_texture_reference(&stObj->pt, firstImage->pt); 138924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 139024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 13914ddd65967915ca4846f2831bc676c878a29dae4aJosé Fonseca /* FIXME: determine format block instead of cpp */ 139224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian if (firstImage->base.IsCompressed) { 139314b98343309fdcff3514f05020303f7b40e83a4aBrian comp_byte = compressed_num_bytes(firstImage->base.TexFormat->MesaFormat); 139424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian cpp = comp_byte; 139524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 13965cb0d749b07be4ecbf4d4d7cde18aecdfe2dba38Brian else { 13975cb0d749b07be4ecbf4d4d7cde18aecdfe2dba38Brian cpp = firstImage->base.TexFormat->TexelBytes; 13985cb0d749b07be4ecbf4d4d7cde18aecdfe2dba38Brian } 139924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 1400ce509401738e7073de94a2b7fc41461c52a73da0Brian Paul /* If we already have a gallium texture, check that it matches the texture 1401ce509401738e7073de94a2b7fc41461c52a73da0Brian Paul * object's format, target, size, num_levels, etc. 140224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 1403809dd9089bae70cf35cea6a75258e700e7455738Brian Paul if (stObj->pt) { 1404809dd9089bae70cf35cea6a75258e700e7455738Brian Paul const enum pipe_format fmt = 1405809dd9089bae70cf35cea6a75258e700e7455738Brian Paul st_mesa_format_to_pipe_format(firstImage->base.TexFormat->MesaFormat); 1406809dd9089bae70cf35cea6a75258e700e7455738Brian Paul if (stObj->pt->target != gl_target_to_pipe(stObj->base.Target) || 1407809dd9089bae70cf35cea6a75258e700e7455738Brian Paul stObj->pt->format != fmt || 1408809dd9089bae70cf35cea6a75258e700e7455738Brian Paul stObj->pt->last_level < stObj->lastLevel || 1409809dd9089bae70cf35cea6a75258e700e7455738Brian Paul stObj->pt->width[0] != firstImage->base.Width2 || 1410809dd9089bae70cf35cea6a75258e700e7455738Brian Paul stObj->pt->height[0] != firstImage->base.Height2 || 1411809dd9089bae70cf35cea6a75258e700e7455738Brian Paul stObj->pt->depth[0] != firstImage->base.Depth2 || 14124ddd65967915ca4846f2831bc676c878a29dae4aJosé Fonseca stObj->pt->block.size != cpp || 14134ddd65967915ca4846f2831bc676c878a29dae4aJosé Fonseca stObj->pt->block.width != 1 || 14144ddd65967915ca4846f2831bc676c878a29dae4aJosé Fonseca stObj->pt->block.height != 1 || 1415809dd9089bae70cf35cea6a75258e700e7455738Brian Paul stObj->pt->compressed != firstImage->base.IsCompressed) { 1416809dd9089bae70cf35cea6a75258e700e7455738Brian Paul pipe_texture_release(&stObj->pt); 14171a82d9648b3db780e58e4966924157542d148c58Brian Paul ctx->st->dirty.st |= ST_NEW_FRAMEBUFFER; 1418809dd9089bae70cf35cea6a75258e700e7455738Brian Paul } 141924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 142024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 1421ce509401738e7073de94a2b7fc41461c52a73da0Brian Paul /* May need to create a new gallium texture: 142224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 1423753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer if (!stObj->pt) { 1424a1f95a8bf64f863289b6759caeec76d7e054400eRoland Scheidegger const enum pipe_format fmt = 1425a1f95a8bf64f863289b6759caeec76d7e054400eRoland Scheidegger st_mesa_format_to_pipe_format(firstImage->base.TexFormat->MesaFormat); 1426753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer stObj->pt = st_texture_create(ctx->st, 14275390a43ce06b27f6d54bc5f237aa305b6948f2afBrian gl_target_to_pipe(stObj->base.Target), 1428a1f95a8bf64f863289b6759caeec76d7e054400eRoland Scheidegger fmt, 1429b245840b86cf877c9b8d666edf229364a84f1deaBrian stObj->lastLevel, 143045cc35e77600af8628393475405160e26d56d421Brian Paul firstImage->base.Width2, 143145cc35e77600af8628393475405160e26d56d421Brian Paul firstImage->base.Height2, 143245cc35e77600af8628393475405160e26d56d421Brian Paul firstImage->base.Depth2, 1433a73ae3d5eb8419feab5aea26573aa41b72f941ebKeith Whitwell comp_byte, 1434a1f95a8bf64f863289b6759caeec76d7e054400eRoland Scheidegger ( (pf_is_depth_stencil(fmt) ? 1435a1f95a8bf64f863289b6759caeec76d7e054400eRoland Scheidegger PIPE_TEXTURE_USAGE_DEPTH_STENCIL : 1436a1f95a8bf64f863289b6759caeec76d7e054400eRoland Scheidegger PIPE_TEXTURE_USAGE_RENDER_TARGET) | 1437a73ae3d5eb8419feab5aea26573aa41b72f941ebKeith Whitwell PIPE_TEXTURE_USAGE_SAMPLER )); 1438a73ae3d5eb8419feab5aea26573aa41b72f941ebKeith Whitwell 14393b3774b1227743147159676795b542c0eb7c2bdfBrian Paul if (!stObj->pt) { 14403b3774b1227743147159676795b542c0eb7c2bdfBrian Paul _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage"); 14413b3774b1227743147159676795b542c0eb7c2bdfBrian Paul return GL_FALSE; 14423b3774b1227743147159676795b542c0eb7c2bdfBrian Paul } 144324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 144424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 1445753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer /* Pull in any images not in the object's texture: 144624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 144724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian for (face = 0; face < nr_faces; face++) { 14484da1cdf78fa3b954840650fa46cf72da5daf149fBrian GLuint level; 14494da1cdf78fa3b954840650fa46cf72da5daf149fBrian for (level = 0; level <= stObj->lastLevel; level++) { 145024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian struct st_texture_image *stImage = 14514da1cdf78fa3b954840650fa46cf72da5daf149fBrian st_texture_image(stObj->base.Image[face][stObj->base.BaseLevel + level]); 145224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 1453753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer /* Need to import images in main memory or held in other textures. 145424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 1455a34b43b3f4817268ef4b3f186203b5fbafc7214eBrian if (stImage && stObj->pt != stImage->pt) { 14564da1cdf78fa3b954840650fa46cf72da5daf149fBrian copy_image_data_to_texture(ctx->st, stObj, level, stImage); 145724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian *needFlush = GL_TRUE; 145824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 145924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 146024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 146124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 146224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian return GL_TRUE; 146324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 146424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 146524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 14668f6d9e12be0be086ca2aab0b56dff8d2181addd9Brian Paul/** 14678f6d9e12be0be086ca2aab0b56dff8d2181addd9Brian Paul * Returns pointer to a default/dummy texture. 14688f6d9e12be0be086ca2aab0b56dff8d2181addd9Brian Paul * This is typically used when the current shader has tex/sample instructions 14698f6d9e12be0be086ca2aab0b56dff8d2181addd9Brian Paul * but the user has not provided a (any) texture(s). 14708f6d9e12be0be086ca2aab0b56dff8d2181addd9Brian Paul */ 14718f6d9e12be0be086ca2aab0b56dff8d2181addd9Brian Paulstruct gl_texture_object * 14728f6d9e12be0be086ca2aab0b56dff8d2181addd9Brian Paulst_get_default_texture(struct st_context *st) 14738f6d9e12be0be086ca2aab0b56dff8d2181addd9Brian Paul{ 14748f6d9e12be0be086ca2aab0b56dff8d2181addd9Brian Paul if (!st->default_texture) { 14758f6d9e12be0be086ca2aab0b56dff8d2181addd9Brian Paul static const GLenum target = GL_TEXTURE_2D; 14768f6d9e12be0be086ca2aab0b56dff8d2181addd9Brian Paul GLubyte pixels[16][16][4]; 14778f6d9e12be0be086ca2aab0b56dff8d2181addd9Brian Paul struct gl_texture_object *texObj; 14788f6d9e12be0be086ca2aab0b56dff8d2181addd9Brian Paul struct gl_texture_image *texImg; 14798f6d9e12be0be086ca2aab0b56dff8d2181addd9Brian Paul 1480a7b818d53a95b549bbff942a9cb91272e0799dd5Brian Paul /* init image to gray */ 1481a7b818d53a95b549bbff942a9cb91272e0799dd5Brian Paul memset(pixels, 127, sizeof(pixels)); 1482a7b818d53a95b549bbff942a9cb91272e0799dd5Brian Paul 14838f6d9e12be0be086ca2aab0b56dff8d2181addd9Brian Paul texObj = st->ctx->Driver.NewTextureObject(st->ctx, 0, target); 14848f6d9e12be0be086ca2aab0b56dff8d2181addd9Brian Paul 14858f6d9e12be0be086ca2aab0b56dff8d2181addd9Brian Paul texImg = _mesa_get_tex_image(st->ctx, texObj, target, 0); 14868f6d9e12be0be086ca2aab0b56dff8d2181addd9Brian Paul 14878f6d9e12be0be086ca2aab0b56dff8d2181addd9Brian Paul _mesa_init_teximage_fields(st->ctx, target, texImg, 14888f6d9e12be0be086ca2aab0b56dff8d2181addd9Brian Paul 16, 16, 1, 0, /* w, h, d, border */ 14898f6d9e12be0be086ca2aab0b56dff8d2181addd9Brian Paul GL_RGBA); 14908f6d9e12be0be086ca2aab0b56dff8d2181addd9Brian Paul 14918f6d9e12be0be086ca2aab0b56dff8d2181addd9Brian Paul st_TexImage(st->ctx, 2, target, 14928f6d9e12be0be086ca2aab0b56dff8d2181addd9Brian Paul 0, GL_RGBA, /* level, intformat */ 14938f6d9e12be0be086ca2aab0b56dff8d2181addd9Brian Paul 16, 16, 1, 0, /* w, h, d, border */ 14948f6d9e12be0be086ca2aab0b56dff8d2181addd9Brian Paul GL_RGBA, GL_UNSIGNED_BYTE, pixels, 14958f6d9e12be0be086ca2aab0b56dff8d2181addd9Brian Paul &st->ctx->DefaultPacking, 14968f6d9e12be0be086ca2aab0b56dff8d2181addd9Brian Paul texObj, texImg, 14978f6d9e12be0be086ca2aab0b56dff8d2181addd9Brian Paul 0, 0); 14988f6d9e12be0be086ca2aab0b56dff8d2181addd9Brian Paul 14998f6d9e12be0be086ca2aab0b56dff8d2181addd9Brian Paul texObj->MinFilter = GL_NEAREST; 15008f6d9e12be0be086ca2aab0b56dff8d2181addd9Brian Paul texObj->MagFilter = GL_NEAREST; 15018f6d9e12be0be086ca2aab0b56dff8d2181addd9Brian Paul texObj->_Complete = GL_TRUE; 15028f6d9e12be0be086ca2aab0b56dff8d2181addd9Brian Paul 15038f6d9e12be0be086ca2aab0b56dff8d2181addd9Brian Paul st->default_texture = texObj; 15048f6d9e12be0be086ca2aab0b56dff8d2181addd9Brian Paul } 15058f6d9e12be0be086ca2aab0b56dff8d2181addd9Brian Paul return st->default_texture; 15068f6d9e12be0be086ca2aab0b56dff8d2181addd9Brian Paul} 15078f6d9e12be0be086ca2aab0b56dff8d2181addd9Brian Paul 15088f6d9e12be0be086ca2aab0b56dff8d2181addd9Brian Paul 15096da9234fd437f97267e7831f034c78b31156d939Brianvoid 15106da9234fd437f97267e7831f034c78b31156d939Brianst_init_texture_functions(struct dd_function_table *functions) 151124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 151224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian functions->ChooseTextureFormat = st_ChooseTextureFormat; 151324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian functions->TexImage1D = st_TexImage1D; 151424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian functions->TexImage2D = st_TexImage2D; 151524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian functions->TexImage3D = st_TexImage3D; 151624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian functions->TexSubImage1D = st_TexSubImage1D; 151724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian functions->TexSubImage2D = st_TexSubImage2D; 151824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian functions->TexSubImage3D = st_TexSubImage3D; 151924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian functions->CopyTexImage1D = st_CopyTexImage1D; 152024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian functions->CopyTexImage2D = st_CopyTexImage2D; 152124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian functions->CopyTexSubImage1D = st_CopyTexSubImage1D; 152224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian functions->CopyTexSubImage2D = st_CopyTexSubImage2D; 1523038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian functions->CopyTexSubImage3D = st_CopyTexSubImage3D; 152462abcb9aacc33218d0143a743c738435794b32a9Brian functions->GenerateMipmap = st_generate_mipmap; 1525038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian 152624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian functions->GetTexImage = st_GetTexImage; 152724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 152824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian /* compressed texture functions */ 152924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian functions->CompressedTexImage2D = st_CompressedTexImage2D; 153024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian functions->GetCompressedTexImage = st_GetCompressedTexImage; 1531f32c51277498887b348133ebcd947dbc8acce756Roland Scheidegger functions->CompressedTextureSize = _mesa_compressed_texture_size; 153224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 153324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian functions->NewTextureObject = st_NewTextureObject; 153424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian functions->NewTextureImage = st_NewTextureImage; 153524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian functions->DeleteTexture = st_DeleteTextureObject; 153624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian functions->FreeTexImageData = st_FreeTextureImageData; 153724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian functions->UpdateTexturePalette = 0; 153824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 153924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian functions->TextureMemCpy = do_memcpy; 1540f8549e8f4f8bdfebcb4e0a2754df59b3fe4fdff7Brian 1541f8549e8f4f8bdfebcb4e0a2754df59b3fe4fdff7Brian /* XXX Temporary until we can query pipe's texture sizes */ 1542f8549e8f4f8bdfebcb4e0a2754df59b3fe4fdff7Brian functions->TestProxyTexImage = _mesa_test_proxy_teximage; 154324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 1544