st_cb_texture.c revision a7b818d53a95b549bbff942a9cb91272e0799dd5
124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian/************************************************************************** 224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * 324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. 424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * All Rights Reserved. 524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * 624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * Permission is hereby granted, free of charge, to any person obtaining a 724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * copy of this software and associated documentation files (the 824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * "Software"), to deal in the Software without restriction, including 924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * without limitation the rights to use, copy, modify, merge, publish, 1024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * distribute, sub license, and/or sell copies of the Software, and to 1124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * permit persons to whom the Software is furnished to do so, subject to 1224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * the following conditions: 1324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * 1424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * The above copyright notice and this permission notice (including the 1524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * next paragraph) shall be included in all copies or substantial portions 1624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * of the Software. 1724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * 1824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 1924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 2024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 2124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR 2224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 2324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 2424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 2524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * 2624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian **************************************************************************/ 2724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 2824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#include "main/imports.h" 29b19e8f720bb2f4d360f5497b64901fc48321f172Brian Paul#if FEATURE_convolution 3024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#include "main/convolve.h" 31b19e8f720bb2f4d360f5497b64901fc48321f172Brian Paul#endif 3224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#include "main/enums.h" 3324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#include "main/image.h" 3424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#include "main/macros.h" 352440ff74d69a8caf49b05a960b4c7e282a96565eBrian#include "main/mipmap.h" 36cc94863429d8a6cef8dbf861e78701a458d30f5aBrian Paul#include "main/pixel.h" 3724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#include "main/texcompress.h" 3824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#include "main/texformat.h" 3924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#include "main/teximage.h" 4024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#include "main/texobj.h" 4124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#include "main/texstore.h" 4224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 4324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#include "state_tracker/st_context.h" 44b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian#include "state_tracker/st_cb_fbo.h" 4524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#include "state_tracker/st_cb_texture.h" 46f8ab24760d0d3f07e9ee81c98207ddf92dfe74daBrian#include "state_tracker/st_format.h" 4702250c855fbec5299a2d6118fefa0523ec73654cMichel Dänzer#include "state_tracker/st_public.h" 48753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer#include "state_tracker/st_texture.h" 4962abcb9aacc33218d0143a743c738435794b32a9Brian#include "state_tracker/st_gen_mipmap.h" 5024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 5124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#include "pipe/p_context.h" 52b245840b86cf877c9b8d666edf229364a84f1deaBrian#include "pipe/p_defines.h" 5311a80160fd60d1eb1541b49128c659526a5d8ac8Michel Dänzer#include "pipe/p_inlines.h" 546acd63a4980951727939c0dd545a0324965b3834José Fonseca#include "util/p_tile.h" 553c0dc8242b64518d5635263ba65b39afa919dd86Michel Dänzer#include "util/u_blit.h" 5624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 5724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 5824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#define DBG if (0) printf 5924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 6024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 6124df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic INLINE struct st_texture_image * 6224df8f895fe8807aa2ba058e71bd40adfc01d21eBrianst_texture_image(struct gl_texture_image *img) 6324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 6424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian return (struct st_texture_image *) img; 6524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 6624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 6724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 681c5f27a18b775b3784fcd265d60e0affa0b31581Michel Dänzerstatic enum pipe_texture_target 695390a43ce06b27f6d54bc5f237aa305b6948f2afBriangl_target_to_pipe(GLenum target) 705390a43ce06b27f6d54bc5f237aa305b6948f2afBrian{ 715390a43ce06b27f6d54bc5f237aa305b6948f2afBrian switch (target) { 725390a43ce06b27f6d54bc5f237aa305b6948f2afBrian case GL_TEXTURE_1D: 735390a43ce06b27f6d54bc5f237aa305b6948f2afBrian return PIPE_TEXTURE_1D; 745390a43ce06b27f6d54bc5f237aa305b6948f2afBrian 755390a43ce06b27f6d54bc5f237aa305b6948f2afBrian case GL_TEXTURE_2D: 765390a43ce06b27f6d54bc5f237aa305b6948f2afBrian case GL_TEXTURE_RECTANGLE_NV: 775390a43ce06b27f6d54bc5f237aa305b6948f2afBrian return PIPE_TEXTURE_2D; 785390a43ce06b27f6d54bc5f237aa305b6948f2afBrian 795390a43ce06b27f6d54bc5f237aa305b6948f2afBrian case GL_TEXTURE_3D: 805390a43ce06b27f6d54bc5f237aa305b6948f2afBrian return PIPE_TEXTURE_3D; 815390a43ce06b27f6d54bc5f237aa305b6948f2afBrian 825390a43ce06b27f6d54bc5f237aa305b6948f2afBrian case GL_TEXTURE_CUBE_MAP_ARB: 835390a43ce06b27f6d54bc5f237aa305b6948f2afBrian return PIPE_TEXTURE_CUBE; 845390a43ce06b27f6d54bc5f237aa305b6948f2afBrian 855390a43ce06b27f6d54bc5f237aa305b6948f2afBrian default: 865390a43ce06b27f6d54bc5f237aa305b6948f2afBrian assert(0); 875390a43ce06b27f6d54bc5f237aa305b6948f2afBrian return 0; 885390a43ce06b27f6d54bc5f237aa305b6948f2afBrian } 895390a43ce06b27f6d54bc5f237aa305b6948f2afBrian} 905390a43ce06b27f6d54bc5f237aa305b6948f2afBrian 915390a43ce06b27f6d54bc5f237aa305b6948f2afBrian 92afc54983370033b65e3a7cbb29bd9c87156f0881Brian/** 93afc54983370033b65e3a7cbb29bd9c87156f0881Brian * Return nominal bytes per texel for a compressed format, 0 for non-compressed 94afc54983370033b65e3a7cbb29bd9c87156f0881Brian * format. 95afc54983370033b65e3a7cbb29bd9c87156f0881Brian */ 9624df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic int 9714b98343309fdcff3514f05020303f7b40e83a4aBriancompressed_num_bytes(GLuint mesaFormat) 9824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 9924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian switch(mesaFormat) { 1005b51cc020efc5519bc7cc34f6fcb4138eab76e0aBrian Paul#if FEATURE_texture_fxt1 10124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian case MESA_FORMAT_RGB_FXT1: 10224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian case MESA_FORMAT_RGBA_FXT1: 1035b51cc020efc5519bc7cc34f6fcb4138eab76e0aBrian Paul#endif 1045b51cc020efc5519bc7cc34f6fcb4138eab76e0aBrian Paul#if FEATURE_texture_s3tc 10524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian case MESA_FORMAT_RGB_DXT1: 10624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian case MESA_FORMAT_RGBA_DXT1: 107afc54983370033b65e3a7cbb29bd9c87156f0881Brian return 2; 10824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian case MESA_FORMAT_RGBA_DXT3: 10924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian case MESA_FORMAT_RGBA_DXT5: 110afc54983370033b65e3a7cbb29bd9c87156f0881Brian return 4; 1115b51cc020efc5519bc7cc34f6fcb4138eab76e0aBrian Paul#endif 11224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian default: 113afc54983370033b65e3a7cbb29bd9c87156f0881Brian return 0; 11424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 11524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 11624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 11724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 1184e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul/** called via ctx->Driver.NewTextureImage() */ 11924df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic struct gl_texture_image * 12024df8f895fe8807aa2ba058e71bd40adfc01d21eBrianst_NewTextureImage(GLcontext * ctx) 12124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 12224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian DBG("%s\n", __FUNCTION__); 12324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian (void) ctx; 12424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian return (struct gl_texture_image *) CALLOC_STRUCT(st_texture_image); 12524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 12624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 12724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 1284e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul/** called via ctx->Driver.NewTextureObject() */ 12924df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic struct gl_texture_object * 13024df8f895fe8807aa2ba058e71bd40adfc01d21eBrianst_NewTextureObject(GLcontext * ctx, GLuint name, GLenum target) 13124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 13224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian struct st_texture_object *obj = CALLOC_STRUCT(st_texture_object); 13324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 13424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian DBG("%s\n", __FUNCTION__); 13524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian _mesa_initialize_texture_object(&obj->base, name, target); 13624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 13724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian return &obj->base; 13824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 13924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 1404e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul/** called via ctx->Driver.DeleteTextureImage() */ 14124df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void 14224df8f895fe8807aa2ba058e71bd40adfc01d21eBrianst_DeleteTextureObject(GLcontext *ctx, 1436f715dcc219071e574e363a9db4365c9c31ebbd3Brian struct gl_texture_object *texObj) 14424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 14524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian struct st_texture_object *stObj = st_texture_object(texObj); 146753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer if (stObj->pt) 147f8dce51083042b4d3fabf48524835290b6725682Brian Paul pipe_texture_reference(&stObj->pt, NULL); 14824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 14924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian _mesa_delete_texture_object(ctx, texObj); 15024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 15124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 15224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 1534e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul/** called via ctx->Driver.FreeTexImageData() */ 15424df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void 15524df8f895fe8807aa2ba058e71bd40adfc01d21eBrianst_FreeTextureImageData(GLcontext * ctx, struct gl_texture_image *texImage) 15624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 15724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian struct st_texture_image *stImage = st_texture_image(texImage); 15824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 15924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian DBG("%s\n", __FUNCTION__); 16024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 161753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer if (stImage->pt) { 162f8dce51083042b4d3fabf48524835290b6725682Brian Paul pipe_texture_reference(&stImage->pt, NULL); 16324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 16424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 16524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian if (texImage->Data) { 16624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian free(texImage->Data); 16724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian texImage->Data = NULL; 16824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 16924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 17024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 17124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 1724e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul/** 17324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * From linux kernel i386 header files, copes with odd sizes better 17424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * than COPY_DWORDS would: 17524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * XXX Put this in src/mesa/main/imports.h ??? 17624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 17724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#if defined(i386) || defined(__i386__) 17824df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic INLINE void * 17924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian__memcpy(void *to, const void *from, size_t n) 18024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 18124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian int d0, d1, d2; 18224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian __asm__ __volatile__("rep ; movsl\n\t" 18324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian "testb $2,%b4\n\t" 18424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian "je 1f\n\t" 18524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian "movsw\n" 18624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian "1:\ttestb $1,%b4\n\t" 18724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian "je 2f\n\t" 18824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian "movsb\n" "2:":"=&c"(d0), "=&D"(d1), "=&S"(d2) 18924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian :"0"(n / 4), "q"(n), "1"((long) to), "2"((long) from) 19024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian :"memory"); 19124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian return (to); 19224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 19324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#else 19424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#define __memcpy(a,b,c) memcpy(a,b,c) 19524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#endif 19624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 19724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 1984e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul/** 1994e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul * The system memcpy (at least on ubuntu 5.10) has problems copying 20024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * to agp (writecombined) memory from a source which isn't 64-byte 20124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * aligned - there is a 4x performance falloff. 20224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * 20324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * The x86 __memcpy is immune to this but is slightly slower 20424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * (10%-ish) than the system memcpy. 20524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * 20624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * The sse_memcpy seems to have a slight cliff at 64/32 bytes, but 20724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * isn't much faster than x86_memcpy for agp copies. 20824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * 20924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * TODO: switch dynamically. 21024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 21124df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void * 21224df8f895fe8807aa2ba058e71bd40adfc01d21eBriando_memcpy(void *dest, const void *src, size_t n) 21324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 21424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian if ((((unsigned) src) & 63) || (((unsigned) dest) & 63)) { 21524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian return __memcpy(dest, src, n); 21624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 21724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian else 21824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian return memcpy(dest, src, n); 21924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 22024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 22124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 22224df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic int 22324df8f895fe8807aa2ba058e71bd40adfc01d21eBrianlogbase2(int n) 22424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 2254e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul GLint i = 1, log2 = 0; 22624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian while (n > i) { 22724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian i *= 2; 22824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian log2++; 22924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 23024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian return log2; 23124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 23224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 23324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 234f52f5136e6eed23e55098681e5b082cc452136d6Brian/** 235f52f5136e6eed23e55098681e5b082cc452136d6Brian * Allocate a pipe_texture object for the given st_texture_object using 236f52f5136e6eed23e55098681e5b082cc452136d6Brian * the given st_texture_image to guess the mipmap size/levels. 237f52f5136e6eed23e55098681e5b082cc452136d6Brian * 238f52f5136e6eed23e55098681e5b082cc452136d6Brian * [comments...] 239f52f5136e6eed23e55098681e5b082cc452136d6Brian * Otherwise, store it in memory if (Border != 0) or (any dimension == 24024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * 1). 24124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * 242753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer * Otherwise, if max_level >= level >= min_level, create texture with 243753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer * space for images from min_level down to max_level. 24424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * 245753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer * Otherwise, create texture with space for images from (level 0)..(1x1). 246753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer * Consider pruning this texture at a validation if the saving is worth it. 24724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 24824df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void 249753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzerguess_and_alloc_texture(struct st_context *st, 250753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer struct st_texture_object *stObj, 251afc54983370033b65e3a7cbb29bd9c87156f0881Brian const struct st_texture_image *stImage) 25224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 25324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLuint firstLevel; 25424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLuint lastLevel; 25545cc35e77600af8628393475405160e26d56d421Brian Paul GLuint width = stImage->base.Width2; /* size w/out border */ 25645cc35e77600af8628393475405160e26d56d421Brian Paul GLuint height = stImage->base.Height2; 25745cc35e77600af8628393475405160e26d56d421Brian Paul GLuint depth = stImage->base.Depth2; 25824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLuint i, comp_byte = 0; 259a1f95a8bf64f863289b6759caeec76d7e054400eRoland Scheidegger enum pipe_format fmt; 26024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 26124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian DBG("%s\n", __FUNCTION__); 26224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 263f52f5136e6eed23e55098681e5b082cc452136d6Brian assert(!stObj->pt); 264f52f5136e6eed23e55098681e5b082cc452136d6Brian 26545cc35e77600af8628393475405160e26d56d421Brian Paul if (stObj->pt && 2666c534b830c6f5427c391c5225c34561141c201baMichal Krol (GLint) stImage->level > stObj->base.BaseLevel && 26714b98343309fdcff3514f05020303f7b40e83a4aBrian (stImage->base.Width == 1 || 26814b98343309fdcff3514f05020303f7b40e83a4aBrian (stObj->base.Target != GL_TEXTURE_1D && 26914b98343309fdcff3514f05020303f7b40e83a4aBrian stImage->base.Height == 1) || 27014b98343309fdcff3514f05020303f7b40e83a4aBrian (stObj->base.Target == GL_TEXTURE_3D && 27114b98343309fdcff3514f05020303f7b40e83a4aBrian stImage->base.Depth == 1))) 27224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian return; 27324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 27424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian /* If this image disrespects BaseLevel, allocate from level zero. 27524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * Usually BaseLevel == 0, so it's unlikely to happen. 27624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 2776c534b830c6f5427c391c5225c34561141c201baMichal Krol if ((GLint) stImage->level < stObj->base.BaseLevel) 27824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian firstLevel = 0; 27924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian else 28014b98343309fdcff3514f05020303f7b40e83a4aBrian firstLevel = stObj->base.BaseLevel; 28124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 28224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 28324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian /* Figure out image dimensions at start level. 28424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 28514b98343309fdcff3514f05020303f7b40e83a4aBrian for (i = stImage->level; i > firstLevel; i--) { 28645cc35e77600af8628393475405160e26d56d421Brian Paul if (width != 1) 28745cc35e77600af8628393475405160e26d56d421Brian Paul width <<= 1; 28824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian if (height != 1) 28924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian height <<= 1; 29024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian if (depth != 1) 29124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian depth <<= 1; 29224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 29324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 294296378b6c8b205048244746e260739448c4ee590Brian Paul if (width == 0 || height == 0 || depth == 0) { 295296378b6c8b205048244746e260739448c4ee590Brian Paul /* no texture needed */ 296296378b6c8b205048244746e260739448c4ee590Brian Paul return; 297296378b6c8b205048244746e260739448c4ee590Brian Paul } 298296378b6c8b205048244746e260739448c4ee590Brian Paul 29924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian /* Guess a reasonable value for lastLevel. This is probably going 30024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * to be wrong fairly often and might mean that we have to look at 30124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * resizable buffers, or require that buffers implement lazy 30224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * pagetable arrangements. 30324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 30414b98343309fdcff3514f05020303f7b40e83a4aBrian if ((stObj->base.MinFilter == GL_NEAREST || 30514b98343309fdcff3514f05020303f7b40e83a4aBrian stObj->base.MinFilter == GL_LINEAR) && 30614b98343309fdcff3514f05020303f7b40e83a4aBrian stImage->level == firstLevel) { 30724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian lastLevel = firstLevel; 30824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 30924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian else { 310f52f5136e6eed23e55098681e5b082cc452136d6Brian GLuint l2width = logbase2(width); 311f52f5136e6eed23e55098681e5b082cc452136d6Brian GLuint l2height = logbase2(height); 312f52f5136e6eed23e55098681e5b082cc452136d6Brian GLuint l2depth = logbase2(depth); 31324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian lastLevel = firstLevel + MAX2(MAX2(l2width, l2height), l2depth); 31424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 31524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 31614b98343309fdcff3514f05020303f7b40e83a4aBrian if (stImage->base.IsCompressed) 31714b98343309fdcff3514f05020303f7b40e83a4aBrian comp_byte = compressed_num_bytes(stImage->base.TexFormat->MesaFormat); 318f52f5136e6eed23e55098681e5b082cc452136d6Brian 319a1f95a8bf64f863289b6759caeec76d7e054400eRoland Scheidegger fmt = st_mesa_format_to_pipe_format(stImage->base.TexFormat->MesaFormat); 320753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer stObj->pt = st_texture_create(st, 3215390a43ce06b27f6d54bc5f237aa305b6948f2afBrian gl_target_to_pipe(stObj->base.Target), 322a1f95a8bf64f863289b6759caeec76d7e054400eRoland Scheidegger fmt, 3235390a43ce06b27f6d54bc5f237aa305b6948f2afBrian lastLevel, 3245390a43ce06b27f6d54bc5f237aa305b6948f2afBrian width, 3255390a43ce06b27f6d54bc5f237aa305b6948f2afBrian height, 3265390a43ce06b27f6d54bc5f237aa305b6948f2afBrian depth, 327a73ae3d5eb8419feab5aea26573aa41b72f941ebKeith Whitwell comp_byte, 328a1f95a8bf64f863289b6759caeec76d7e054400eRoland Scheidegger ( (pf_is_depth_stencil(fmt) ? 329a1f95a8bf64f863289b6759caeec76d7e054400eRoland Scheidegger PIPE_TEXTURE_USAGE_DEPTH_STENCIL : 330a1f95a8bf64f863289b6759caeec76d7e054400eRoland Scheidegger PIPE_TEXTURE_USAGE_RENDER_TARGET) | 331a73ae3d5eb8419feab5aea26573aa41b72f941ebKeith Whitwell PIPE_TEXTURE_USAGE_SAMPLER )); 33224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 33324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian DBG("%s - success\n", __FUNCTION__); 33424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 33524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 33624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 337212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian/** 338212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian * Adjust pixel unpack params and image dimensions to strip off the 339212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian * texture border. 340212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian * Gallium doesn't support texture borders. They've seldem been used 341212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian * and seldom been implemented correctly anyway. 342212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian * \param unpackNew returns the new pixel unpack parameters 343212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian */ 344212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brianstatic void 345212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brianstrip_texture_border(GLint border, 346212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian GLint *width, GLint *height, GLint *depth, 347212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian const struct gl_pixelstore_attrib *unpack, 348212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian struct gl_pixelstore_attrib *unpackNew) 349212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian{ 350212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian assert(border > 0); /* sanity check */ 351212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian 352212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian *unpackNew = *unpack; 353212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian 354212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian if (unpackNew->RowLength == 0) 355212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian unpackNew->RowLength = *width; 356212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian 357212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian if (depth && unpackNew->ImageHeight == 0) 358212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian unpackNew->ImageHeight = *height; 359212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian 360212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian unpackNew->SkipPixels += border; 361212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian if (height) 362212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian unpackNew->SkipRows += border; 363212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian if (depth) 364212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian unpackNew->SkipImages += border; 365212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian 366212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian assert(*width >= 3); 367212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian *width = *width - 2 * border; 368212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian if (height && *height >= 3) 369212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian *height = *height - 2 * border; 370212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian if (depth && *depth >= 3) 371212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian *depth = *depth - 2 * border; 372212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian} 373212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian 37424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 3754e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul/** 3764e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul * Do glTexImage1/2/3D(). 3774e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul */ 37824df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void 37924df8f895fe8807aa2ba058e71bd40adfc01d21eBrianst_TexImage(GLcontext * ctx, 380afc54983370033b65e3a7cbb29bd9c87156f0881Brian GLint dims, 381afc54983370033b65e3a7cbb29bd9c87156f0881Brian GLenum target, GLint level, 382afc54983370033b65e3a7cbb29bd9c87156f0881Brian GLint internalFormat, 383afc54983370033b65e3a7cbb29bd9c87156f0881Brian GLint width, GLint height, GLint depth, 384afc54983370033b65e3a7cbb29bd9c87156f0881Brian GLint border, 385afc54983370033b65e3a7cbb29bd9c87156f0881Brian GLenum format, GLenum type, const void *pixels, 386afc54983370033b65e3a7cbb29bd9c87156f0881Brian const struct gl_pixelstore_attrib *unpack, 387afc54983370033b65e3a7cbb29bd9c87156f0881Brian struct gl_texture_object *texObj, 388afc54983370033b65e3a7cbb29bd9c87156f0881Brian struct gl_texture_image *texImage, 389afc54983370033b65e3a7cbb29bd9c87156f0881Brian GLsizei imageSize, int compressed) 39024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 39114b98343309fdcff3514f05020303f7b40e83a4aBrian struct st_texture_object *stObj = st_texture_object(texObj); 39214b98343309fdcff3514f05020303f7b40e83a4aBrian struct st_texture_image *stImage = st_texture_image(texImage); 393212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian GLint postConvWidth, postConvHeight; 39424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLint texelBytes, sizeInBytes; 39524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLuint dstRowStride; 396212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian struct gl_pixelstore_attrib unpackNB; 39724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 39824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian DBG("%s target %s level %d %dx%dx%d border %d\n", __FUNCTION__, 39924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian _mesa_lookup_enum_by_nr(target), level, width, height, depth, border); 40024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 401212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian /* gallium does not support texture borders, strip it off */ 402212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian if (border) { 403212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian strip_texture_border(border, &width, &height, &depth, 404212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian unpack, &unpackNB); 405212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian unpack = &unpackNB; 40621989edd55409d72ee55187f4f9062496ca3fbf8Brian Paul texImage->Width = width; 40721989edd55409d72ee55187f4f9062496ca3fbf8Brian Paul texImage->Height = height; 40821989edd55409d72ee55187f4f9062496ca3fbf8Brian Paul texImage->Depth = depth; 40921989edd55409d72ee55187f4f9062496ca3fbf8Brian Paul texImage->Border = 0; 410212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian border = 0; 411212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian } 412212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian 413212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian postConvWidth = width; 414212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian postConvHeight = height; 415212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian 416cfe9e66f2bc596c43760911e7c1604bb32cdee28Brian stImage->face = _mesa_tex_target_to_face(target); 41714b98343309fdcff3514f05020303f7b40e83a4aBrian stImage->level = level; 41824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 419b19e8f720bb2f4d360f5497b64901fc48321f172Brian Paul#if FEATURE_convolution 42024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian if (ctx->_ImageTransferState & IMAGE_CONVOLUTION_BIT) { 42124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian _mesa_adjust_image_for_convolution(ctx, dims, &postConvWidth, 42224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian &postConvHeight); 42324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 424b19e8f720bb2f4d360f5497b64901fc48321f172Brian Paul#endif 42524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 42624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian /* choose the texture format */ 42724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian texImage->TexFormat = st_ChooseTextureFormat(ctx, internalFormat, 428afc54983370033b65e3a7cbb29bd9c87156f0881Brian format, type); 42924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 43024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian _mesa_set_fetch_functions(texImage, dims); 43124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 43224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian if (texImage->TexFormat->TexelBytes == 0) { 43324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian /* must be a compressed format */ 43424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian texelBytes = 0; 43524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian texImage->IsCompressed = GL_TRUE; 43624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian texImage->CompressedSize = 43724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian ctx->Driver.CompressedTextureSize(ctx, texImage->Width, 43824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian texImage->Height, texImage->Depth, 43924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian texImage->TexFormat->MesaFormat); 440afc54983370033b65e3a7cbb29bd9c87156f0881Brian } 441afc54983370033b65e3a7cbb29bd9c87156f0881Brian else { 44224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian texelBytes = texImage->TexFormat->TexelBytes; 44324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 44424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian /* Minimum pitch of 32 bytes */ 44524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian if (postConvWidth * texelBytes < 32) { 44624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian postConvWidth = 32 / texelBytes; 44724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian texImage->RowStride = postConvWidth; 44824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 44924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 4507585b4ceb8fed862c07f50af8030a6f0eb8a8321Brian /* we'll set RowStride elsewhere when the texture is a "mapped" state */ 4517585b4ceb8fed862c07f50af8030a6f0eb8a8321Brian /*assert(texImage->RowStride == postConvWidth);*/ 45224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 45324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 45424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian /* Release the reference to a potentially orphaned buffer. 45524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * Release any old malloced memory. 45624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 457753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer if (stImage->pt) { 458f8dce51083042b4d3fabf48524835290b6725682Brian Paul pipe_texture_reference(&stImage->pt, NULL); 45924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian assert(!texImage->Data); 46024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 46124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian else if (texImage->Data) { 46224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian _mesa_align_free(texImage->Data); 46324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 46424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 4654da1cdf78fa3b954840650fa46cf72da5daf149fBrian /* If this is the only mipmap level in the texture, could call 46624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * bmBufferData with NULL data to free the old block and avoid 46724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * waiting on any outstanding fences. 46824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 469753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer if (stObj->pt && 470d4074c509b5d28be0a2ec51d40329e1aed7047efMichel Dänzer (stObj->teximage_realloc || 471d4074c509b5d28be0a2ec51d40329e1aed7047efMichel Dänzer (/*stObj->pt->first_level == level &&*/ 472d4074c509b5d28be0a2ec51d40329e1aed7047efMichel Dänzer stObj->pt->last_level == level && 473d4074c509b5d28be0a2ec51d40329e1aed7047efMichel Dänzer stObj->pt->target != PIPE_TEXTURE_CUBE && 474d4074c509b5d28be0a2ec51d40329e1aed7047efMichel Dänzer !st_texture_match_image(stObj->pt, &stImage->base, 475d4074c509b5d28be0a2ec51d40329e1aed7047efMichel Dänzer stImage->face, stImage->level)))) { 47624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 47724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian DBG("release it\n"); 478f8dce51083042b4d3fabf48524835290b6725682Brian Paul pipe_texture_reference(&stObj->pt, NULL); 479753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer assert(!stObj->pt); 480d4074c509b5d28be0a2ec51d40329e1aed7047efMichel Dänzer stObj->teximage_realloc = FALSE; 48124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 48224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 483753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer if (!stObj->pt) { 484753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer guess_and_alloc_texture(ctx->st, stObj, stImage); 485753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer if (!stObj->pt) { 4863b3774b1227743147159676795b542c0eb7c2bdfBrian Paul _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage"); 4873b3774b1227743147159676795b542c0eb7c2bdfBrian Paul return; 48824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 48924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 49024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 491753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer assert(!stImage->pt); 49224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 493753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer if (stObj->pt && 494753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer st_texture_match_image(stObj->pt, &stImage->base, 49514b98343309fdcff3514f05020303f7b40e83a4aBrian stImage->face, stImage->level)) { 49624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 4974da19dbcaa9f3e2d20fffd0145bf0bc756dd7542Brian pipe_texture_reference(&stImage->pt, stObj->pt); 498753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer assert(stImage->pt); 49924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 50024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 501753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer if (!stImage->pt) 502753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer DBG("XXX: Image did not fit into texture - storing in local memory!\n"); 50324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 504987d59bb83e9e08192563e5f1b52949c5511053cMichel Dänzer /* st_CopyTexImage calls this function with pixels == NULL, with 505753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer * the expectation that the texture will be set up but nothing 50624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * more will be done. This is where those calls return: 50724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 50824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian if (compressed) { 50924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian pixels = _mesa_validate_pbo_compressed_teximage(ctx, imageSize, pixels, 51024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian unpack, 51124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian "glCompressedTexImage"); 51224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } else { 51324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian pixels = _mesa_validate_pbo_teximage(ctx, dims, width, height, 1, 51424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian format, type, 51524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian pixels, unpack, "glTexImage"); 51624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 51724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian if (!pixels) 51824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian return; 51924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 520753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer if (stImage->pt) { 521c9ed86a96483063f3d6789ed16645a3dca77d726Keith Whitwell texImage->Data = st_texture_image_map(ctx->st, stImage, 0, 522c9ed86a96483063f3d6789ed16645a3dca77d726Keith Whitwell PIPE_BUFFER_USAGE_CPU_WRITE); 5232a39dbe7364af5444b1eb43650dfc31ed09257dcBrian Paul if (stImage->surface) 5244ddd65967915ca4846f2831bc676c878a29dae4aJosé Fonseca dstRowStride = stImage->surface->stride; 52524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 52624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian else { 52724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian /* Allocate regular memory and store the image there temporarily. */ 52824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian if (texImage->IsCompressed) { 52924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian sizeInBytes = texImage->CompressedSize; 53024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian dstRowStride = 53124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian _mesa_compressed_row_stride(texImage->TexFormat->MesaFormat, width); 53224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian assert(dims != 3); 53324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 53424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian else { 53524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian dstRowStride = postConvWidth * texelBytes; 53624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian sizeInBytes = depth * dstRowStride * postConvHeight; 53724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 53824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 53924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian texImage->Data = malloc(sizeInBytes); 54024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 54124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 5422a39dbe7364af5444b1eb43650dfc31ed09257dcBrian Paul if (!texImage->Data) { 5432a39dbe7364af5444b1eb43650dfc31ed09257dcBrian Paul _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage"); 5442a39dbe7364af5444b1eb43650dfc31ed09257dcBrian Paul return; 5452a39dbe7364af5444b1eb43650dfc31ed09257dcBrian Paul } 5462a39dbe7364af5444b1eb43650dfc31ed09257dcBrian Paul 54724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian DBG("Upload image %dx%dx%d row_len %x pitch %x\n", 54824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian width, height, depth, width * texelBytes, dstRowStride); 54924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 55024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian /* Copy data. Would like to know when it's ok for us to eg. use 55124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * the blitter to copy. Or, use the hardware to do the format 55224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * conversion and copy: 55324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 55424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian if (compressed) { 555afc54983370033b65e3a7cbb29bd9c87156f0881Brian memcpy(texImage->Data, pixels, imageSize); 55624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 557753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer else { 558753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer GLuint srcImageStride = _mesa_image_image_stride(unpack, width, height, 559753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer format, type); 560753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer int i; 5615823f99d0fbc054b87aeb1bc15d413d3eadd27a8Brian const GLubyte *src = (const GLubyte *) pixels; 562753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer 563753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer for (i = 0; i++ < depth;) { 564753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer if (!texImage->TexFormat->StoreImage(ctx, dims, 565753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer texImage->_BaseFormat, 566753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer texImage->TexFormat, 567753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer texImage->Data, 568753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer 0, 0, 0, /* dstX/Y/Zoffset */ 569753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer dstRowStride, 570753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer texImage->ImageOffsets, 571753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer width, height, 1, 5725823f99d0fbc054b87aeb1bc15d413d3eadd27a8Brian format, type, src, unpack)) { 573753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage"); 574753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer } 575753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer 576753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer if (stImage->pt && i < depth) { 577c9ed86a96483063f3d6789ed16645a3dca77d726Keith Whitwell st_texture_image_unmap(ctx->st, stImage); 578c9ed86a96483063f3d6789ed16645a3dca77d726Keith Whitwell texImage->Data = st_texture_image_map(ctx->st, stImage, i, 579c9ed86a96483063f3d6789ed16645a3dca77d726Keith Whitwell PIPE_BUFFER_USAGE_CPU_WRITE); 5805823f99d0fbc054b87aeb1bc15d413d3eadd27a8Brian src += srcImageStride; 581753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer } 582753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer } 58324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 58424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 58524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian _mesa_unmap_teximage_pbo(ctx, unpack); 58624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 587753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer if (stImage->pt) { 588c9ed86a96483063f3d6789ed16645a3dca77d726Keith Whitwell st_texture_image_unmap(ctx->st, stImage); 58924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian texImage->Data = NULL; 59024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 59124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 59224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian if (level == texObj->BaseLevel && texObj->GenerateMipmap) { 59362abcb9aacc33218d0143a743c738435794b32a9Brian ctx->Driver.GenerateMipmap(ctx, target, texObj); 59424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 59524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 59624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 59724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 59824df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void 59924df8f895fe8807aa2ba058e71bd40adfc01d21eBrianst_TexImage3D(GLcontext * ctx, 6004e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul GLenum target, GLint level, 6014e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul GLint internalFormat, 6024e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul GLint width, GLint height, GLint depth, 6034e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul GLint border, 6044e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul GLenum format, GLenum type, const void *pixels, 6054e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul const struct gl_pixelstore_attrib *unpack, 6064e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul struct gl_texture_object *texObj, 6074e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul struct gl_texture_image *texImage) 60824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 60924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian st_TexImage(ctx, 3, target, level, 61024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian internalFormat, width, height, depth, border, 61124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian format, type, pixels, unpack, texObj, texImage, 0, 0); 61224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 61324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 61424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 61524df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void 61624df8f895fe8807aa2ba058e71bd40adfc01d21eBrianst_TexImage2D(GLcontext * ctx, 6174e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul GLenum target, GLint level, 6184e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul GLint internalFormat, 6194e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul GLint width, GLint height, GLint border, 6204e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul GLenum format, GLenum type, const void *pixels, 6214e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul const struct gl_pixelstore_attrib *unpack, 6224e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul struct gl_texture_object *texObj, 6234e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul struct gl_texture_image *texImage) 62424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 62524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian st_TexImage(ctx, 2, target, level, 62624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian internalFormat, width, height, 1, border, 62724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian format, type, pixels, unpack, texObj, texImage, 0, 0); 62824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 62924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 63024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 63124df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void 63224df8f895fe8807aa2ba058e71bd40adfc01d21eBrianst_TexImage1D(GLcontext * ctx, 6334e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul GLenum target, GLint level, 6344e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul GLint internalFormat, 6354e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul GLint width, GLint border, 6364e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul GLenum format, GLenum type, const void *pixels, 6374e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul const struct gl_pixelstore_attrib *unpack, 6384e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul struct gl_texture_object *texObj, 6394e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul struct gl_texture_image *texImage) 64024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 64124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian st_TexImage(ctx, 1, target, level, 64224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian internalFormat, width, 1, 1, border, 64324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian format, type, pixels, unpack, texObj, texImage, 0, 0); 64424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 64524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 64624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 64724df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void 6484e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paulst_CompressedTexImage2D(GLcontext *ctx, GLenum target, GLint level, 6494e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul GLint internalFormat, 6504e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul GLint width, GLint height, GLint border, 6514e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul GLsizei imageSize, const GLvoid *data, 6524e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul struct gl_texture_object *texObj, 6534e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul struct gl_texture_image *texImage) 65424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 65524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian st_TexImage(ctx, 2, target, level, 65624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian internalFormat, width, height, 1, border, 65724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 0, 0, data, &ctx->Unpack, texObj, texImage, imageSize, 1); 65824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 65924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 66024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 66124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian/** 66224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * Need to map texture image into memory before copying image data, 66324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * then unmap it. 66424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 66524df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void 66624df8f895fe8807aa2ba058e71bd40adfc01d21eBrianst_get_tex_image(GLcontext * ctx, GLenum target, GLint level, 66724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLenum format, GLenum type, GLvoid * pixels, 66824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian struct gl_texture_object *texObj, 66924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian struct gl_texture_image *texImage, int compressed) 67024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 67124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian struct st_texture_image *stImage = st_texture_image(texImage); 6724e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul GLuint dstImageStride = _mesa_image_image_stride(&ctx->Pack, 6734e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul texImage->Width, 6744e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul texImage->Height, 6754e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul format, type); 676753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer GLuint depth; 6776c534b830c6f5427c391c5225c34561141c201baMichal Krol GLuint i; 6785823f99d0fbc054b87aeb1bc15d413d3eadd27a8Brian GLubyte *dest; 67924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 68024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian /* Map */ 681753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer if (stImage->pt) { 68224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian /* Image is stored in hardware format in a buffer managed by the 68324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * kernel. Need to explicitly map and unmap it. 68424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 685c9ed86a96483063f3d6789ed16645a3dca77d726Keith Whitwell texImage->Data = st_texture_image_map(ctx->st, stImage, 0, 686c9ed86a96483063f3d6789ed16645a3dca77d726Keith Whitwell PIPE_BUFFER_USAGE_CPU_READ); 6874ddd65967915ca4846f2831bc676c878a29dae4aJosé Fonseca texImage->RowStride = stImage->surface->stride / stImage->pt->block.size; 68824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 68924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian else { 69024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian /* Otherwise, the image should actually be stored in 691753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer * texImage->Data. This is pretty confusing for 69224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * everybody, I'd much prefer to separate the two functions of 69324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * texImage->Data - storage for texture images in main memory 69424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * and access (ie mappings) of images. In other words, we'd 69524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * create a new texImage->Map field and leave Data simply for 69624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * storage. 69724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 698753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer assert(texImage->Data); 69924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 70024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 701753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer depth = texImage->Depth; 702753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer texImage->Depth = 1; 70324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 7045823f99d0fbc054b87aeb1bc15d413d3eadd27a8Brian dest = (GLubyte *) pixels; 7055823f99d0fbc054b87aeb1bc15d413d3eadd27a8Brian 706753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer for (i = 0; i++ < depth;) { 707753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer if (compressed) { 7085823f99d0fbc054b87aeb1bc15d413d3eadd27a8Brian _mesa_get_compressed_teximage(ctx, target, level, dest, 709753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer texObj, texImage); 710753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer } else { 7115823f99d0fbc054b87aeb1bc15d413d3eadd27a8Brian _mesa_get_teximage(ctx, target, level, format, type, dest, 712753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer texObj, texImage); 713753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer } 714753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer 715753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer if (stImage->pt && i < depth) { 716c9ed86a96483063f3d6789ed16645a3dca77d726Keith Whitwell st_texture_image_unmap(ctx->st, stImage); 717c9ed86a96483063f3d6789ed16645a3dca77d726Keith Whitwell texImage->Data = st_texture_image_map(ctx->st, stImage, i, 718c9ed86a96483063f3d6789ed16645a3dca77d726Keith Whitwell PIPE_BUFFER_USAGE_CPU_READ); 7195823f99d0fbc054b87aeb1bc15d413d3eadd27a8Brian dest += dstImageStride; 720753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer } 72124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 722753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer 723753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer texImage->Depth = depth; 72424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 72524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian /* Unmap */ 726753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer if (stImage->pt) { 727c9ed86a96483063f3d6789ed16645a3dca77d726Keith Whitwell st_texture_image_unmap(ctx->st, stImage); 728753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer texImage->Data = NULL; 72924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 73024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 73124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 73224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 73324df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void 73424df8f895fe8807aa2ba058e71bd40adfc01d21eBrianst_GetTexImage(GLcontext * ctx, GLenum target, GLint level, 7354e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul GLenum format, GLenum type, GLvoid * pixels, 7364e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul struct gl_texture_object *texObj, 7374e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul struct gl_texture_image *texImage) 73824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 73924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian st_get_tex_image(ctx, target, level, format, type, pixels, 74024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian texObj, texImage, 0); 74124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 74224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 74324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 74424df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void 74524df8f895fe8807aa2ba058e71bd40adfc01d21eBrianst_GetCompressedTexImage(GLcontext *ctx, GLenum target, GLint level, 7464e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul GLvoid *pixels, 7474e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul const struct gl_texture_object *texObj, 7484e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul const struct gl_texture_image *texImage) 74924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 75024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian st_get_tex_image(ctx, target, level, 0, 0, pixels, 75124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian (struct gl_texture_object *) texObj, 75224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian (struct gl_texture_image *) texImage, 1); 75324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 75424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 75524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 75624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 75724df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void 75824df8f895fe8807aa2ba058e71bd40adfc01d21eBrianst_TexSubimage(GLcontext * ctx, 7594e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul GLint dims, 7604e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul GLenum target, GLint level, 7614e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul GLint xoffset, GLint yoffset, GLint zoffset, 7624e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul GLint width, GLint height, GLint depth, 7634e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul GLenum format, GLenum type, const void *pixels, 7644e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul const struct gl_pixelstore_attrib *packing, 7654e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul struct gl_texture_object *texObj, 7664e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul struct gl_texture_image *texImage) 76724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 76824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian struct st_texture_image *stImage = st_texture_image(texImage); 76924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLuint dstRowStride; 770753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer GLuint srcImageStride = _mesa_image_image_stride(packing, width, height, 771753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer format, type); 772753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer int i; 7735823f99d0fbc054b87aeb1bc15d413d3eadd27a8Brian const GLubyte *src; 77424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 77524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian DBG("%s target %s level %d offset %d,%d %dx%d\n", __FUNCTION__, 77624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian _mesa_lookup_enum_by_nr(target), 77724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian level, xoffset, yoffset, width, height); 77824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 77924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian pixels = 78024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian _mesa_validate_pbo_teximage(ctx, dims, width, height, depth, format, 78124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian type, pixels, packing, "glTexSubImage2D"); 78224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian if (!pixels) 78324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian return; 78424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 78524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian /* Map buffer if necessary. Need to lock to prevent other contexts 78624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * from uploading the buffer under us. 78724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 788753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer if (stImage->pt) { 789c9ed86a96483063f3d6789ed16645a3dca77d726Keith Whitwell texImage->Data = st_texture_image_map(ctx->st, stImage, zoffset, 790c9ed86a96483063f3d6789ed16645a3dca77d726Keith Whitwell PIPE_BUFFER_USAGE_CPU_WRITE); 7912a39dbe7364af5444b1eb43650dfc31ed09257dcBrian Paul if (stImage->surface) 7924ddd65967915ca4846f2831bc676c878a29dae4aJosé Fonseca dstRowStride = stImage->surface->stride; 793753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer } 794753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer 7959b44f5a7550d8ede2eda763770e927df4c15cc8eBrian Paul if (!texImage->Data) { 7969b44f5a7550d8ede2eda763770e927df4c15cc8eBrian Paul _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage"); 7979b44f5a7550d8ede2eda763770e927df4c15cc8eBrian Paul return; 7989b44f5a7550d8ede2eda763770e927df4c15cc8eBrian Paul } 7999b44f5a7550d8ede2eda763770e927df4c15cc8eBrian Paul 8005823f99d0fbc054b87aeb1bc15d413d3eadd27a8Brian src = (const GLubyte *) pixels; 8015823f99d0fbc054b87aeb1bc15d413d3eadd27a8Brian 802753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer for (i = 0; i++ < depth;) { 803753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer if (!texImage->TexFormat->StoreImage(ctx, dims, texImage->_BaseFormat, 804753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer texImage->TexFormat, 805753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer texImage->Data, 806753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer xoffset, yoffset, 0, 807753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer dstRowStride, 808753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer texImage->ImageOffsets, 809753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer width, height, 1, 8105823f99d0fbc054b87aeb1bc15d413d3eadd27a8Brian format, type, src, packing)) { 8119b44f5a7550d8ede2eda763770e927df4c15cc8eBrian Paul _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage"); 812753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer } 813753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer 814753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer if (stImage->pt && i < depth) { 8159b44f5a7550d8ede2eda763770e927df4c15cc8eBrian Paul /* map next slice of 3D texture */ 816c9ed86a96483063f3d6789ed16645a3dca77d726Keith Whitwell st_texture_image_unmap(ctx->st, stImage); 817c9ed86a96483063f3d6789ed16645a3dca77d726Keith Whitwell texImage->Data = st_texture_image_map(ctx->st, stImage, zoffset + i, 818c9ed86a96483063f3d6789ed16645a3dca77d726Keith Whitwell PIPE_BUFFER_USAGE_CPU_WRITE); 8195823f99d0fbc054b87aeb1bc15d413d3eadd27a8Brian src += srcImageStride; 820753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer } 82124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 82224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 82324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian if (level == texObj->BaseLevel && texObj->GenerateMipmap) { 8243ccbaa977f96eaa849093875dd0944f744ee1e21Brian ctx->Driver.GenerateMipmap(ctx, target, texObj); 82524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 82624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 82724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian _mesa_unmap_teximage_pbo(ctx, packing); 82824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 829753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer if (stImage->pt) { 830c9ed86a96483063f3d6789ed16645a3dca77d726Keith Whitwell st_texture_image_unmap(ctx->st, stImage); 83124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian texImage->Data = NULL; 83224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 83324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 83424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 83524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 83624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 83724df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void 83824df8f895fe8807aa2ba058e71bd40adfc01d21eBrianst_TexSubImage3D(GLcontext * ctx, 83924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLenum target, 84024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLint level, 84124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLint xoffset, GLint yoffset, GLint zoffset, 84224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLsizei width, GLsizei height, GLsizei depth, 84324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLenum format, GLenum type, 84424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian const GLvoid * pixels, 84524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian const struct gl_pixelstore_attrib *packing, 84624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian struct gl_texture_object *texObj, 84724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian struct gl_texture_image *texImage) 84824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 849b245840b86cf877c9b8d666edf229364a84f1deaBrian st_TexSubimage(ctx, 3, target, level, 850b245840b86cf877c9b8d666edf229364a84f1deaBrian xoffset, yoffset, zoffset, 851b245840b86cf877c9b8d666edf229364a84f1deaBrian width, height, depth, 852b245840b86cf877c9b8d666edf229364a84f1deaBrian format, type, pixels, packing, texObj, texImage); 85324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 85424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 85524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 85624df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void 85724df8f895fe8807aa2ba058e71bd40adfc01d21eBrianst_TexSubImage2D(GLcontext * ctx, 85824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLenum target, 85924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLint level, 86024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLint xoffset, GLint yoffset, 86124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLsizei width, GLsizei height, 86224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLenum format, GLenum type, 86324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian const GLvoid * pixels, 86424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian const struct gl_pixelstore_attrib *packing, 86524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian struct gl_texture_object *texObj, 86624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian struct gl_texture_image *texImage) 86724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 868b245840b86cf877c9b8d666edf229364a84f1deaBrian st_TexSubimage(ctx, 2, target, level, 869b245840b86cf877c9b8d666edf229364a84f1deaBrian xoffset, yoffset, 0, 870b245840b86cf877c9b8d666edf229364a84f1deaBrian width, height, 1, 871b245840b86cf877c9b8d666edf229364a84f1deaBrian format, type, pixels, packing, texObj, texImage); 87224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 87324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 87424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 87524df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void 87624df8f895fe8807aa2ba058e71bd40adfc01d21eBrianst_TexSubImage1D(GLcontext * ctx, 87724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLenum target, 87824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLint level, 87924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLint xoffset, 88024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLsizei width, 88124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLenum format, GLenum type, 88224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian const GLvoid * pixels, 88324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian const struct gl_pixelstore_attrib *packing, 88424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian struct gl_texture_object *texObj, 88524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian struct gl_texture_image *texImage) 88624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 887b245840b86cf877c9b8d666edf229364a84f1deaBrian st_TexSubimage(ctx, 1, target, level, 888b245840b86cf877c9b8d666edf229364a84f1deaBrian xoffset, 0, 0, 889b245840b86cf877c9b8d666edf229364a84f1deaBrian width, 1, 1, 890b245840b86cf877c9b8d666edf229364a84f1deaBrian format, type, pixels, packing, texObj, texImage); 89124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 89224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 89324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 89424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 89524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian/** 896038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian * Return 0 for GL_TEXTURE_CUBE_MAP_POSITIVE_X, 897038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian * 1 for GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 898038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian * etc. 899038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian * XXX duplicated from main/teximage.c 900038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian */ 901038cb561eb094af2f2ba06e18e61246fc0c87c3cBrianstatic uint 902038cb561eb094af2f2ba06e18e61246fc0c87c3cBriantexture_face(GLenum target) 903038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian{ 904038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian if (target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB && 905038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB) 906038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian return (GLuint) target - (GLuint) GL_TEXTURE_CUBE_MAP_POSITIVE_X; 907038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian else 908038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian return 0; 909038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian} 910038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian 911038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian 912038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian 913038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian/** 914b859cdf6f191b4d8b56537c8dc30082a7e2d94b3Michel Dänzer * Do a CopyTexSubImage operation by mapping the source surface and 915b859cdf6f191b4d8b56537c8dc30082a7e2d94b3Michel Dänzer * dest surface and using get_tile()/put_tile() to access the pixels/texels. 916c6717a86420d7141013165f7acd50b3c3f751756Brian * 917c6717a86420d7141013165f7acd50b3c3f751756Brian * Note: srcY=0=TOP of renderbuffer 918038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian */ 919038cb561eb094af2f2ba06e18e61246fc0c87c3cBrianstatic void 920038cb561eb094af2f2ba06e18e61246fc0c87c3cBrianfallback_copy_texsubimage(GLcontext *ctx, 921038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian GLenum target, 922038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian GLint level, 923038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian struct st_renderbuffer *strb, 924038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian struct st_texture_image *stImage, 925038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian GLenum baseFormat, 926038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian GLint destX, GLint destY, GLint destZ, 927038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian GLint srcX, GLint srcY, 928038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian GLsizei width, GLsizei height) 929038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian{ 930038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian struct pipe_context *pipe = ctx->st->pipe; 9316f715dcc219071e574e363a9db4365c9c31ebbd3Brian struct pipe_screen *screen = pipe->screen; 932038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian const uint face = texture_face(target); 933753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer struct pipe_texture *pt = stImage->pt; 934038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian struct pipe_surface *src_surf, *dest_surf; 935038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian 936f3048ad90ed2e4583f0f7aaf35a0f4aa581942ddBrian Paul /* We'd use strb->surface, here but it's created for GPU read/write only */ 937f3048ad90ed2e4583f0f7aaf35a0f4aa581942ddBrian Paul src_surf = pipe->screen->get_tex_surface( pipe->screen, 938f3048ad90ed2e4583f0f7aaf35a0f4aa581942ddBrian Paul strb->texture, 939f3048ad90ed2e4583f0f7aaf35a0f4aa581942ddBrian Paul 0, 0, 0, 940f3048ad90ed2e4583f0f7aaf35a0f4aa581942ddBrian Paul PIPE_BUFFER_USAGE_CPU_READ); 941f3048ad90ed2e4583f0f7aaf35a0f4aa581942ddBrian Paul 942c9ed86a96483063f3d6789ed16645a3dca77d726Keith Whitwell dest_surf = screen->get_tex_surface(screen, pt, face, level, destZ, 943c9ed86a96483063f3d6789ed16645a3dca77d726Keith Whitwell PIPE_BUFFER_USAGE_CPU_WRITE); 944038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian 945cc94863429d8a6cef8dbf861e78701a458d30f5aBrian Paul assert(width <= MAX_WIDTH); 946038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian 947cc94863429d8a6cef8dbf861e78701a458d30f5aBrian Paul if (baseFormat == GL_DEPTH_COMPONENT) { 948cc94863429d8a6cef8dbf861e78701a458d30f5aBrian Paul const GLboolean scaleOrBias = (ctx->Pixel.DepthScale != 1.0F || 949cc94863429d8a6cef8dbf861e78701a458d30f5aBrian Paul ctx->Pixel.DepthBias != 0.0F); 95027858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul GLint row, yStep; 951cc94863429d8a6cef8dbf861e78701a458d30f5aBrian Paul 95227858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul /* determine bottom-to-top vs. top-to-bottom order for src buffer */ 95327858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul if (st_fb_orientation(ctx->ReadBuffer) == Y_0_TOP) { 95427858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul srcY = strb->Base.Height - 1 - srcY; 95527858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul yStep = -1; 95627858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul } 95727858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul else { 95827858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul yStep = 1; 95927858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul } 96027858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul 96127858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul /* To avoid a large temp memory allocation, do copy row by row */ 962275b09f2569c8bea5dcca1643c93aa6a43d7e2a2Brian Paul for (row = 0; row < height; row++, srcY += yStep, destY++) { 963cc94863429d8a6cef8dbf861e78701a458d30f5aBrian Paul uint data[MAX_WIDTH]; 96436dd89c8a7f2a911e8f7f18d1edcaf982a75a438José Fonseca pipe_get_tile_z(src_surf, srcX, srcY, width, 1, data); 965cc94863429d8a6cef8dbf861e78701a458d30f5aBrian Paul if (scaleOrBias) { 966cc94863429d8a6cef8dbf861e78701a458d30f5aBrian Paul _mesa_scale_and_bias_depth_uint(ctx, width, data); 967cc94863429d8a6cef8dbf861e78701a458d30f5aBrian Paul } 96836dd89c8a7f2a911e8f7f18d1edcaf982a75a438José Fonseca pipe_put_tile_z(dest_surf, destX, destY, width, 1, data); 969cc94863429d8a6cef8dbf861e78701a458d30f5aBrian Paul } 970cc94863429d8a6cef8dbf861e78701a458d30f5aBrian Paul } 971cc94863429d8a6cef8dbf861e78701a458d30f5aBrian Paul else { 972cc94863429d8a6cef8dbf861e78701a458d30f5aBrian Paul /* RGBA format */ 97327858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul GLfloat *tempSrc = 97427858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul (GLfloat *) _mesa_malloc(width * height * 4 * sizeof(GLfloat)); 97527858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul GLvoid *texDest = 97627858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul st_texture_image_map(ctx->st, stImage, 0,PIPE_BUFFER_USAGE_CPU_WRITE); 97727858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul 97827858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul if (tempSrc && texDest) { 97927858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul const GLint dims = 2; 98027858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul struct gl_texture_image *texImage = &stImage->base; 98127858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul GLint dstRowStride = stImage->surface->stride; 98227858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul struct gl_pixelstore_attrib unpack = ctx->DefaultPacking; 98327858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul 98427858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul if (st_fb_orientation(ctx->ReadBuffer) == Y_0_TOP) { 98527858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul /* need to invert src */ 98627858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul srcY = strb->Base.Height - srcY - height; 98727858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul unpack.Invert = GL_TRUE; 988cc94863429d8a6cef8dbf861e78701a458d30f5aBrian Paul } 98927858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul 99027858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul /* get float/RGBA image from framebuffer */ 99127858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul /* XXX this usually involves a lot of int/float conversion. 99227858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul * try to avoid that someday. 99327858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul */ 99427858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul pipe_get_tile_rgba(src_surf, srcX, srcY, width, height, tempSrc); 99527858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul 99627858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul /* Store into texture memory. 99727858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul * Note that this does some special things such as pixel transfer 99827858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul * ops and format conversion. In particular, if the dest tex format 99927858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul * is actually RGBA but the user created the texture as GL_RGB we 100027858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul * need to fill-in/override the alpha channel with 1.0. 100127858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul */ 100227858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul texImage->TexFormat->StoreImage(ctx, dims, 100327858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul texImage->_BaseFormat, 100427858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul texImage->TexFormat, 100527858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul texDest, 100627858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul destX, destY, destZ, 100727858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul dstRowStride, 100827858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul texImage->ImageOffsets, 100927858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul width, height, 1, 101027858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul GL_RGBA, GL_FLOAT, tempSrc, /* src */ 101127858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul &unpack); 101227858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul } 101327858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul else { 101427858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage"); 10155c83f1371978472fbe4bba8f686733c6b519874aBrian } 101627858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul 101727858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul if (tempSrc) 101827858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul _mesa_free(tempSrc); 101927858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul if (texDest) 102027858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul st_texture_image_unmap(ctx->st, stImage); 10215c83f1371978472fbe4bba8f686733c6b519874aBrian } 1022d0279fc4b38c72356a341173317bcd45d9093f45Michel Dänzer 1023d0279fc4b38c72356a341173317bcd45d9093f45Michel Dänzer screen->tex_surface_release(screen, &dest_surf); 1024f3048ad90ed2e4583f0f7aaf35a0f4aa581942ddBrian Paul screen->tex_surface_release(screen, &src_surf); 1025038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian} 1026038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian 1027038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian 1028038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian/** 10294e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul * Do a CopyTex[Sub]Image1/2/3D() using a hardware (blit) path if possible. 10304e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul * Note that the region to copy has already been clipped so we know we 10314e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul * won't read from outside the source renderbuffer's bounds. 1032c6717a86420d7141013165f7acd50b3c3f751756Brian * 10334e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul * Note: srcY=0=Bottom of renderbuffer (GL convention) 103424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 1035038cb561eb094af2f2ba06e18e61246fc0c87c3cBrianstatic void 10364e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paulst_copy_texsubimage(GLcontext *ctx, 1037038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian GLenum target, GLint level, 1038038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian GLint destX, GLint destY, GLint destZ, 1039038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian GLint srcX, GLint srcY, 1040038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian GLsizei width, GLsizei height) 104124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 1042038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian struct gl_texture_unit *texUnit = 1043038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; 1044038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian struct gl_texture_object *texObj = 1045038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian _mesa_select_tex_object(ctx, texUnit, target); 1046038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian struct gl_texture_image *texImage = 1047038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian _mesa_select_tex_image(ctx, texObj, target, level); 1048038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian struct st_texture_image *stImage = st_texture_image(texImage); 10494e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul const GLenum texBaseFormat = texImage->InternalFormat; 1050b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian struct gl_framebuffer *fb = ctx->ReadBuffer; 1051b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian struct st_renderbuffer *strb; 1052b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian struct pipe_context *pipe = ctx->st->pipe; 10536f715dcc219071e574e363a9db4365c9c31ebbd3Brian struct pipe_screen *screen = pipe->screen; 105427858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul enum pipe_format dest_format, src_format; 1055cc94863429d8a6cef8dbf861e78701a458d30f5aBrian Paul GLboolean use_fallback = GL_TRUE; 105627858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul GLboolean matching_base_formats; 105724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 105889e9d6b6db933c870443714c3d7c9539d117cddfBrian Paul st_flush(ctx->st, PIPE_FLUSH_RENDER_CACHE, NULL); 1059a479bf62353b6517841e620122112e7565d2391cBrian Paul 1060b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian /* determine if copying depth or color data */ 10614e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul if (texBaseFormat == GL_DEPTH_COMPONENT) { 1062b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian strb = st_renderbuffer(fb->_DepthBuffer); 106324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 10644e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul else if (texBaseFormat == GL_DEPTH_STENCIL_EXT) { 1065b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian strb = st_renderbuffer(fb->_StencilBuffer); 1066b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian } 1067b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian else { 10684e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul /* texBaseFormat == GL_RGB, GL_RGBA, GL_ALPHA, etc */ 1069b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian strb = st_renderbuffer(fb->_ColorReadBuffer); 1070b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian } 1071b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian 1072b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian assert(strb); 1073b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian assert(strb->surface); 1074753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer assert(stImage->pt); 1075c6717a86420d7141013165f7acd50b3c3f751756Brian 1076b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian src_format = strb->surface->format; 1077753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer dest_format = stImage->pt->format; 1078b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian 107927858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul /* 108027858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul * Determine if the src framebuffer and dest texture have the same 108127858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul * base format. We need this to detect a case such as the framebuffer 108227858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul * being GL_RGBA but the texture being GL_RGB. If the actual hardware 108327858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul * texture format stores RGBA we need to set A=1 (overriding the 108427858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul * framebuffer's alpha values). We can't do that with the blit or 108527858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul * textured-quad paths. 108627858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul */ 108727858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul matching_base_formats = (strb->Base._BaseFormat == texImage->_BaseFormat); 108879931e38abc62286151121a3f59127e296144551Michel Dänzer 108927858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul if (matching_base_formats && ctx->_ImageTransferState == 0x0) { 109027858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul /* try potential hardware path */ 109127858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul struct pipe_surface *dest_surface = NULL; 1092b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian 10933c0dc8242b64518d5635263ba65b39afa919dd86Michel Dänzer if (src_format == dest_format) { 10944e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul /* use surface_copy() / blit */ 1095a479bf62353b6517841e620122112e7565d2391cBrian Paul boolean do_flip = (st_fb_orientation(ctx->ReadBuffer) == Y_0_TOP); 109627858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul 109727858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul dest_surface = screen->get_tex_surface(screen, stImage->pt, 109827858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul stImage->face, stImage->level, 109927858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul destZ, 110027858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul PIPE_BUFFER_USAGE_GPU_WRITE); 1101a479bf62353b6517841e620122112e7565d2391cBrian Paul pipe->surface_copy(pipe, 1102a479bf62353b6517841e620122112e7565d2391cBrian Paul do_flip, 1103a479bf62353b6517841e620122112e7565d2391cBrian Paul /* dest */ 1104a479bf62353b6517841e620122112e7565d2391cBrian Paul dest_surface, 1105a479bf62353b6517841e620122112e7565d2391cBrian Paul destX, destY, 1106a479bf62353b6517841e620122112e7565d2391cBrian Paul /* src */ 1107a479bf62353b6517841e620122112e7565d2391cBrian Paul strb->surface, 1108a479bf62353b6517841e620122112e7565d2391cBrian Paul srcX, srcY, 1109a479bf62353b6517841e620122112e7565d2391cBrian Paul /* size */ 1110a479bf62353b6517841e620122112e7565d2391cBrian Paul width, height); 1111a479bf62353b6517841e620122112e7565d2391cBrian Paul use_fallback = GL_FALSE; 1112cc94863429d8a6cef8dbf861e78701a458d30f5aBrian Paul } 11134e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul else if (screen->is_format_supported(screen, src_format, 11148aafc03b260ab8923f1b373f7effa75bcdb40a72José Fonseca PIPE_TEXTURE_2D, 11158aafc03b260ab8923f1b373f7effa75bcdb40a72José Fonseca PIPE_TEXTURE_USAGE_SAMPLER, 11168aafc03b260ab8923f1b373f7effa75bcdb40a72José Fonseca 0) && 11174e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul screen->is_format_supported(screen, dest_format, 11188aafc03b260ab8923f1b373f7effa75bcdb40a72José Fonseca PIPE_TEXTURE_2D, 11198aafc03b260ab8923f1b373f7effa75bcdb40a72José Fonseca PIPE_TEXTURE_USAGE_RENDER_TARGET, 11208aafc03b260ab8923f1b373f7effa75bcdb40a72José Fonseca 0)) { 11214e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul /* draw textured quad to do the copy */ 1122a479bf62353b6517841e620122112e7565d2391cBrian Paul boolean do_flip = (st_fb_orientation(ctx->ReadBuffer) == Y_0_TOP); 1123a479bf62353b6517841e620122112e7565d2391cBrian Paul int srcY0, srcY1; 112427858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul 112527858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul dest_surface = screen->get_tex_surface(screen, stImage->pt, 112627858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul stImage->face, stImage->level, 112727858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul destZ, 112827858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul PIPE_BUFFER_USAGE_GPU_WRITE); 112927858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul 1130a479bf62353b6517841e620122112e7565d2391cBrian Paul if (do_flip) { 1131a479bf62353b6517841e620122112e7565d2391cBrian Paul srcY1 = strb->Base.Height - srcY - height; 1132a479bf62353b6517841e620122112e7565d2391cBrian Paul srcY0 = srcY1 + height; 1133a479bf62353b6517841e620122112e7565d2391cBrian Paul } 1134a479bf62353b6517841e620122112e7565d2391cBrian Paul else { 1135a479bf62353b6517841e620122112e7565d2391cBrian Paul srcY0 = srcY; 1136a479bf62353b6517841e620122112e7565d2391cBrian Paul srcY1 = srcY0 + height; 1137a479bf62353b6517841e620122112e7565d2391cBrian Paul } 11383c0dc8242b64518d5635263ba65b39afa919dd86Michel Dänzer util_blit_pixels(ctx->st->blit, 11393c0dc8242b64518d5635263ba65b39afa919dd86Michel Dänzer strb->surface, 1140a479bf62353b6517841e620122112e7565d2391cBrian Paul srcX, srcY0, 1141a479bf62353b6517841e620122112e7565d2391cBrian Paul srcX + width, srcY1, 11423c0dc8242b64518d5635263ba65b39afa919dd86Michel Dänzer dest_surface, 1143a479bf62353b6517841e620122112e7565d2391cBrian Paul destX, destY, 1144a479bf62353b6517841e620122112e7565d2391cBrian Paul destX + width, destY + height, 11453c0dc8242b64518d5635263ba65b39afa919dd86Michel Dänzer 0.0, PIPE_TEX_MIPFILTER_NEAREST); 1146cc94863429d8a6cef8dbf861e78701a458d30f5aBrian Paul use_fallback = GL_FALSE; 11473c0dc8242b64518d5635263ba65b39afa919dd86Michel Dänzer } 114879931e38abc62286151121a3f59127e296144551Michel Dänzer 114927858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul if (dest_surface) 115027858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul pipe_surface_reference(&dest_surface, NULL); 1151038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian } 1152cc94863429d8a6cef8dbf861e78701a458d30f5aBrian Paul 1153cc94863429d8a6cef8dbf861e78701a458d30f5aBrian Paul if (use_fallback) { 11544e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul /* software fallback */ 1155038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian fallback_copy_texsubimage(ctx, target, level, 11564e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul strb, stImage, texBaseFormat, 1157038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian destX, destY, destZ, 1158038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian srcX, srcY, width, height); 1159038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian } 1160038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian 116124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian if (level == texObj->BaseLevel && texObj->GenerateMipmap) { 11623ccbaa977f96eaa849093875dd0944f744ee1e21Brian ctx->Driver.GenerateMipmap(ctx, target, texObj); 116324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 116424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 116524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 116624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 1167038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian 116824df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void 116924df8f895fe8807aa2ba058e71bd40adfc01d21eBrianst_CopyTexImage1D(GLcontext * ctx, GLenum target, GLint level, 117024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLenum internalFormat, 117124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLint x, GLint y, GLsizei width, GLint border) 117224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 117324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian struct gl_texture_unit *texUnit = 117424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; 117524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian struct gl_texture_object *texObj = 117624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian _mesa_select_tex_object(ctx, texUnit, target); 117724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian struct gl_texture_image *texImage = 117824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian _mesa_select_tex_image(ctx, texObj, target, level); 117924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 1180038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian#if 0 118124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian if (border) 118224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian goto fail; 1183038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian#endif 118424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 1185753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer /* Setup or redefine the texture object, texture and texture 118624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * image. Don't populate yet. 118724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 118824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian ctx->Driver.TexImage1D(ctx, target, level, internalFormat, 118924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian width, border, 119024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GL_RGBA, CHAN_TYPE, NULL, 119124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian &ctx->DefaultPacking, texObj, texImage); 119224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 11934e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul st_copy_texsubimage(ctx, target, level, 11944e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul 0, 0, 0, /* destX,Y,Z */ 11954e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul x, y, width, 1); /* src X, Y, size */ 119624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 119724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 119824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 119924df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void 120024df8f895fe8807aa2ba058e71bd40adfc01d21eBrianst_CopyTexImage2D(GLcontext * ctx, GLenum target, GLint level, 120124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLenum internalFormat, 120224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLint x, GLint y, GLsizei width, GLsizei height, 120324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLint border) 120424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 120524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian struct gl_texture_unit *texUnit = 120624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; 120724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian struct gl_texture_object *texObj = 120824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian _mesa_select_tex_object(ctx, texUnit, target); 120924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian struct gl_texture_image *texImage = 121024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian _mesa_select_tex_image(ctx, texObj, target, level); 121124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 1212753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer /* Setup or redefine the texture object, texture and texture 121324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * image. Don't populate yet. 121424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 121524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian ctx->Driver.TexImage2D(ctx, target, level, internalFormat, 121624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian width, height, border, 121724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GL_RGBA, CHAN_TYPE, NULL, 121824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian &ctx->DefaultPacking, texObj, texImage); 121924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 12204e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul st_copy_texsubimage(ctx, target, level, 12214e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul 0, 0, 0, /* destX,Y,Z */ 12224e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul x, y, width, height); /* src X, Y, size */ 122324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 122424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 122524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 122624df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void 122724df8f895fe8807aa2ba058e71bd40adfc01d21eBrianst_CopyTexSubImage1D(GLcontext * ctx, GLenum target, GLint level, 122824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLint xoffset, GLint x, GLint y, GLsizei width) 122924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 1230038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian const GLint yoffset = 0, zoffset = 0; 1231038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian const GLsizei height = 1; 12324e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul st_copy_texsubimage(ctx, target, level, 12334e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul xoffset, yoffset, zoffset, /* destX,Y,Z */ 12344e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul x, y, width, height); /* src X, Y, size */ 123524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 123624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 123724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 123824df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void 123924df8f895fe8807aa2ba058e71bd40adfc01d21eBrianst_CopyTexSubImage2D(GLcontext * ctx, GLenum target, GLint level, 124024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLint xoffset, GLint yoffset, 124124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLint x, GLint y, GLsizei width, GLsizei height) 124224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 1243038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian const GLint zoffset = 0; 12444e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul st_copy_texsubimage(ctx, target, level, 12454e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul xoffset, yoffset, zoffset, /* destX,Y,Z */ 12464e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul x, y, width, height); /* src X, Y, size */ 1247038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian} 124824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 124924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 1250038cb561eb094af2f2ba06e18e61246fc0c87c3cBrianstatic void 1251038cb561eb094af2f2ba06e18e61246fc0c87c3cBrianst_CopyTexSubImage3D(GLcontext * ctx, GLenum target, GLint level, 1252038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian GLint xoffset, GLint yoffset, GLint zoffset, 1253038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian GLint x, GLint y, GLsizei width, GLsizei height) 1254038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian{ 12554e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul st_copy_texsubimage(ctx, target, level, 12564e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul xoffset, yoffset, zoffset, /* destX,Y,Z */ 12574e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul x, y, width, height); /* src X, Y, size */ 125824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 125924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 126024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 126124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian/** 126224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * Compute which mipmap levels that really need to be sent to the hardware. 126324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * This depends on the base image size, GL_TEXTURE_MIN_LOD, 126424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * GL_TEXTURE_MAX_LOD, GL_TEXTURE_BASE_LEVEL, and GL_TEXTURE_MAX_LEVEL. 126524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 126624df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void 126714b98343309fdcff3514f05020303f7b40e83a4aBriancalculate_first_last_level(struct st_texture_object *stObj) 126824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 126914b98343309fdcff3514f05020303f7b40e83a4aBrian struct gl_texture_object *tObj = &stObj->base; 127024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 127124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian /* These must be signed values. MinLod and MaxLod can be negative numbers, 127224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * and having firstLevel and lastLevel as signed prevents the need for 127324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * extra sign checks. 127424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 127524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian int firstLevel; 127624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian int lastLevel; 127724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 127824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian /* Yes, this looks overly complicated, but it's all needed. 127924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 128024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian switch (tObj->Target) { 128124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian case GL_TEXTURE_1D: 128224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian case GL_TEXTURE_2D: 128324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian case GL_TEXTURE_3D: 128424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian case GL_TEXTURE_CUBE_MAP: 128524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian if (tObj->MinFilter == GL_NEAREST || tObj->MinFilter == GL_LINEAR) { 128624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian /* GL_NEAREST and GL_LINEAR only care about GL_TEXTURE_BASE_LEVEL. 128724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 128824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian firstLevel = lastLevel = tObj->BaseLevel; 128924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 129024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian else { 12914da1cdf78fa3b954840650fa46cf72da5daf149fBrian firstLevel = 0; 12924e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul lastLevel = MIN2(tObj->MaxLevel, 12934e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul (int) tObj->Image[0][tObj->BaseLevel]->WidthLog2); 129424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 129524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian break; 129624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian case GL_TEXTURE_RECTANGLE_NV: 129724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian case GL_TEXTURE_4D_SGIS: 129824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian firstLevel = lastLevel = 0; 129924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian break; 130024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian default: 130124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian return; 130224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 130324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 130414b98343309fdcff3514f05020303f7b40e83a4aBrian stObj->lastLevel = lastLevel; 130524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 130624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 130724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 130824df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void 1309753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzercopy_image_data_to_texture(struct st_context *st, 1310753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer struct st_texture_object *stObj, 13114da1cdf78fa3b954840650fa46cf72da5daf149fBrian GLuint dstLevel, 1312753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer struct st_texture_image *stImage) 131324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 1314753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer if (stImage->pt) { 131524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian /* Copy potentially with the blitter: 131624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 1317753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer st_texture_image_copy(st->pipe, 13184da1cdf78fa3b954840650fa46cf72da5daf149fBrian stObj->pt, dstLevel, /* dest texture, level */ 13194da1cdf78fa3b954840650fa46cf72da5daf149fBrian stImage->pt, /* src texture */ 13204da1cdf78fa3b954840650fa46cf72da5daf149fBrian stImage->face 132128b315dc1aed36bebadfacbd55e481e7baacfcb5Brian ); 132224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 1323f8dce51083042b4d3fabf48524835290b6725682Brian Paul pipe_texture_reference(&stImage->pt, NULL); 132424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 13254c50969334844bc9aa622176c3ebcbc733394f78Brian Paul else if (stImage->base.Data) { 132624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian assert(stImage->base.Data != NULL); 132724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 132824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian /* More straightforward upload. 132924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 1330753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer st_texture_image_data(st->pipe, 1331753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer stObj->pt, 133224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian stImage->face, 1333c2497879f127251994064a0e0c24901782adae9eBrian Paul dstLevel, 133424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian stImage->base.Data, 13354ddd65967915ca4846f2831bc676c878a29dae4aJosé Fonseca stImage->base.RowStride * 13364ddd65967915ca4846f2831bc676c878a29dae4aJosé Fonseca stObj->pt->block.size, 133724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian stImage->base.RowStride * 13384ddd65967915ca4846f2831bc676c878a29dae4aJosé Fonseca stImage->base.Height * 13394ddd65967915ca4846f2831bc676c878a29dae4aJosé Fonseca stObj->pt->block.size); 134024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian _mesa_align_free(stImage->base.Data); 134124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian stImage->base.Data = NULL; 134224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 134324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 13444da19dbcaa9f3e2d20fffd0145bf0bc756dd7542Brian pipe_texture_reference(&stImage->pt, stObj->pt); 134524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 134624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 134724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 1348afc54983370033b65e3a7cbb29bd9c87156f0881Brian/** 1349afc54983370033b65e3a7cbb29bd9c87156f0881Brian * Called during state validation. When this function is finished, 1350afc54983370033b65e3a7cbb29bd9c87156f0881Brian * the texture object should be ready for rendering. 13513b3774b1227743147159676795b542c0eb7c2bdfBrian Paul * \return GL_TRUE for success, GL_FALSE for failure (out of mem) 135224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 135314b98343309fdcff3514f05020303f7b40e83a4aBrianGLboolean 1354753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzerst_finalize_texture(GLcontext *ctx, 1355c3af68dc5022715cc8f126b7df12f3f5248aefe7Keith Whitwell struct pipe_context *pipe, 1356c3af68dc5022715cc8f126b7df12f3f5248aefe7Keith Whitwell struct gl_texture_object *tObj, 1357753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer GLboolean *needFlush) 135824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 135914b98343309fdcff3514f05020303f7b40e83a4aBrian struct st_texture_object *stObj = st_texture_object(tObj); 1360afc54983370033b65e3a7cbb29bd9c87156f0881Brian const GLuint nr_faces = (stObj->base.Target == GL_TEXTURE_CUBE_MAP) ? 6 : 1; 136124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian int comp_byte = 0; 136224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian int cpp; 13634da1cdf78fa3b954840650fa46cf72da5daf149fBrian GLuint face; 136424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian struct st_texture_image *firstImage; 136524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 136624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian *needFlush = GL_FALSE; 136724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 136824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian /* We know/require this is true by now: 136924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 137014b98343309fdcff3514f05020303f7b40e83a4aBrian assert(stObj->base._Complete); 137124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 1372753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer /* What levels must the texture include at a minimum? 137324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 137414b98343309fdcff3514f05020303f7b40e83a4aBrian calculate_first_last_level(stObj); 13754da1cdf78fa3b954840650fa46cf72da5daf149fBrian firstImage = st_texture_image(stObj->base.Image[0][stObj->base.BaseLevel]); 137624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 1377753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer /* If both firstImage and stObj point to a texture which can contain 137824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * all active images, favour firstImage. Note that because of the 137924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * completeness requirement, we know that the image dimensions 138024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * will match. 138124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 1382753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer if (firstImage->pt && 1383753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer firstImage->pt != stObj->pt && 1384753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer firstImage->pt->last_level >= stObj->lastLevel) { 138524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 13864da19dbcaa9f3e2d20fffd0145bf0bc756dd7542Brian pipe_texture_reference(&stObj->pt, firstImage->pt); 138724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 138824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 13894ddd65967915ca4846f2831bc676c878a29dae4aJosé Fonseca /* FIXME: determine format block instead of cpp */ 139024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian if (firstImage->base.IsCompressed) { 139114b98343309fdcff3514f05020303f7b40e83a4aBrian comp_byte = compressed_num_bytes(firstImage->base.TexFormat->MesaFormat); 139224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian cpp = comp_byte; 139324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 13945cb0d749b07be4ecbf4d4d7cde18aecdfe2dba38Brian else { 13955cb0d749b07be4ecbf4d4d7cde18aecdfe2dba38Brian cpp = firstImage->base.TexFormat->TexelBytes; 13965cb0d749b07be4ecbf4d4d7cde18aecdfe2dba38Brian } 139724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 1398ce509401738e7073de94a2b7fc41461c52a73da0Brian Paul /* If we already have a gallium texture, check that it matches the texture 1399ce509401738e7073de94a2b7fc41461c52a73da0Brian Paul * object's format, target, size, num_levels, etc. 140024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 1401809dd9089bae70cf35cea6a75258e700e7455738Brian Paul if (stObj->pt) { 1402809dd9089bae70cf35cea6a75258e700e7455738Brian Paul const enum pipe_format fmt = 1403809dd9089bae70cf35cea6a75258e700e7455738Brian Paul st_mesa_format_to_pipe_format(firstImage->base.TexFormat->MesaFormat); 1404809dd9089bae70cf35cea6a75258e700e7455738Brian Paul if (stObj->pt->target != gl_target_to_pipe(stObj->base.Target) || 1405809dd9089bae70cf35cea6a75258e700e7455738Brian Paul stObj->pt->format != fmt || 1406809dd9089bae70cf35cea6a75258e700e7455738Brian Paul stObj->pt->last_level < stObj->lastLevel || 1407809dd9089bae70cf35cea6a75258e700e7455738Brian Paul stObj->pt->width[0] != firstImage->base.Width2 || 1408809dd9089bae70cf35cea6a75258e700e7455738Brian Paul stObj->pt->height[0] != firstImage->base.Height2 || 1409809dd9089bae70cf35cea6a75258e700e7455738Brian Paul stObj->pt->depth[0] != firstImage->base.Depth2 || 14104ddd65967915ca4846f2831bc676c878a29dae4aJosé Fonseca stObj->pt->block.size != cpp || 14114ddd65967915ca4846f2831bc676c878a29dae4aJosé Fonseca stObj->pt->block.width != 1 || 14124ddd65967915ca4846f2831bc676c878a29dae4aJosé Fonseca stObj->pt->block.height != 1 || 1413809dd9089bae70cf35cea6a75258e700e7455738Brian Paul stObj->pt->compressed != firstImage->base.IsCompressed) { 1414809dd9089bae70cf35cea6a75258e700e7455738Brian Paul pipe_texture_release(&stObj->pt); 14151a82d9648b3db780e58e4966924157542d148c58Brian Paul ctx->st->dirty.st |= ST_NEW_FRAMEBUFFER; 1416809dd9089bae70cf35cea6a75258e700e7455738Brian Paul } 141724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 141824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 1419ce509401738e7073de94a2b7fc41461c52a73da0Brian Paul /* May need to create a new gallium texture: 142024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 1421753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer if (!stObj->pt) { 1422a1f95a8bf64f863289b6759caeec76d7e054400eRoland Scheidegger const enum pipe_format fmt = 1423a1f95a8bf64f863289b6759caeec76d7e054400eRoland Scheidegger st_mesa_format_to_pipe_format(firstImage->base.TexFormat->MesaFormat); 1424753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer stObj->pt = st_texture_create(ctx->st, 14255390a43ce06b27f6d54bc5f237aa305b6948f2afBrian gl_target_to_pipe(stObj->base.Target), 1426a1f95a8bf64f863289b6759caeec76d7e054400eRoland Scheidegger fmt, 1427b245840b86cf877c9b8d666edf229364a84f1deaBrian stObj->lastLevel, 142845cc35e77600af8628393475405160e26d56d421Brian Paul firstImage->base.Width2, 142945cc35e77600af8628393475405160e26d56d421Brian Paul firstImage->base.Height2, 143045cc35e77600af8628393475405160e26d56d421Brian Paul firstImage->base.Depth2, 1431a73ae3d5eb8419feab5aea26573aa41b72f941ebKeith Whitwell comp_byte, 1432a1f95a8bf64f863289b6759caeec76d7e054400eRoland Scheidegger ( (pf_is_depth_stencil(fmt) ? 1433a1f95a8bf64f863289b6759caeec76d7e054400eRoland Scheidegger PIPE_TEXTURE_USAGE_DEPTH_STENCIL : 1434a1f95a8bf64f863289b6759caeec76d7e054400eRoland Scheidegger PIPE_TEXTURE_USAGE_RENDER_TARGET) | 1435a73ae3d5eb8419feab5aea26573aa41b72f941ebKeith Whitwell PIPE_TEXTURE_USAGE_SAMPLER )); 1436a73ae3d5eb8419feab5aea26573aa41b72f941ebKeith Whitwell 14373b3774b1227743147159676795b542c0eb7c2bdfBrian Paul if (!stObj->pt) { 14383b3774b1227743147159676795b542c0eb7c2bdfBrian Paul _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage"); 14393b3774b1227743147159676795b542c0eb7c2bdfBrian Paul return GL_FALSE; 14403b3774b1227743147159676795b542c0eb7c2bdfBrian Paul } 144124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 144224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 1443753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer /* Pull in any images not in the object's texture: 144424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 144524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian for (face = 0; face < nr_faces; face++) { 14464da1cdf78fa3b954840650fa46cf72da5daf149fBrian GLuint level; 14474da1cdf78fa3b954840650fa46cf72da5daf149fBrian for (level = 0; level <= stObj->lastLevel; level++) { 144824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian struct st_texture_image *stImage = 14494da1cdf78fa3b954840650fa46cf72da5daf149fBrian st_texture_image(stObj->base.Image[face][stObj->base.BaseLevel + level]); 145024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 1451753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer /* Need to import images in main memory or held in other textures. 145224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 1453a34b43b3f4817268ef4b3f186203b5fbafc7214eBrian if (stImage && stObj->pt != stImage->pt) { 14544da1cdf78fa3b954840650fa46cf72da5daf149fBrian copy_image_data_to_texture(ctx->st, stObj, level, stImage); 145524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian *needFlush = GL_TRUE; 145624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 145724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 145824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 145924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 146024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian return GL_TRUE; 146124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 146224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 146324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 14648f6d9e12be0be086ca2aab0b56dff8d2181addd9Brian Paul/** 14658f6d9e12be0be086ca2aab0b56dff8d2181addd9Brian Paul * Returns pointer to a default/dummy texture. 14668f6d9e12be0be086ca2aab0b56dff8d2181addd9Brian Paul * This is typically used when the current shader has tex/sample instructions 14678f6d9e12be0be086ca2aab0b56dff8d2181addd9Brian Paul * but the user has not provided a (any) texture(s). 14688f6d9e12be0be086ca2aab0b56dff8d2181addd9Brian Paul */ 14698f6d9e12be0be086ca2aab0b56dff8d2181addd9Brian Paulstruct gl_texture_object * 14708f6d9e12be0be086ca2aab0b56dff8d2181addd9Brian Paulst_get_default_texture(struct st_context *st) 14718f6d9e12be0be086ca2aab0b56dff8d2181addd9Brian Paul{ 14728f6d9e12be0be086ca2aab0b56dff8d2181addd9Brian Paul if (!st->default_texture) { 14738f6d9e12be0be086ca2aab0b56dff8d2181addd9Brian Paul static const GLenum target = GL_TEXTURE_2D; 14748f6d9e12be0be086ca2aab0b56dff8d2181addd9Brian Paul GLubyte pixels[16][16][4]; 14758f6d9e12be0be086ca2aab0b56dff8d2181addd9Brian Paul struct gl_texture_object *texObj; 14768f6d9e12be0be086ca2aab0b56dff8d2181addd9Brian Paul struct gl_texture_image *texImg; 14778f6d9e12be0be086ca2aab0b56dff8d2181addd9Brian Paul 1478a7b818d53a95b549bbff942a9cb91272e0799dd5Brian Paul /* init image to gray */ 1479a7b818d53a95b549bbff942a9cb91272e0799dd5Brian Paul memset(pixels, 127, sizeof(pixels)); 1480a7b818d53a95b549bbff942a9cb91272e0799dd5Brian Paul 14818f6d9e12be0be086ca2aab0b56dff8d2181addd9Brian Paul texObj = st->ctx->Driver.NewTextureObject(st->ctx, 0, target); 14828f6d9e12be0be086ca2aab0b56dff8d2181addd9Brian Paul 14838f6d9e12be0be086ca2aab0b56dff8d2181addd9Brian Paul texImg = _mesa_get_tex_image(st->ctx, texObj, target, 0); 14848f6d9e12be0be086ca2aab0b56dff8d2181addd9Brian Paul 14858f6d9e12be0be086ca2aab0b56dff8d2181addd9Brian Paul _mesa_init_teximage_fields(st->ctx, target, texImg, 14868f6d9e12be0be086ca2aab0b56dff8d2181addd9Brian Paul 16, 16, 1, 0, /* w, h, d, border */ 14878f6d9e12be0be086ca2aab0b56dff8d2181addd9Brian Paul GL_RGBA); 14888f6d9e12be0be086ca2aab0b56dff8d2181addd9Brian Paul 14898f6d9e12be0be086ca2aab0b56dff8d2181addd9Brian Paul st_TexImage(st->ctx, 2, target, 14908f6d9e12be0be086ca2aab0b56dff8d2181addd9Brian Paul 0, GL_RGBA, /* level, intformat */ 14918f6d9e12be0be086ca2aab0b56dff8d2181addd9Brian Paul 16, 16, 1, 0, /* w, h, d, border */ 14928f6d9e12be0be086ca2aab0b56dff8d2181addd9Brian Paul GL_RGBA, GL_UNSIGNED_BYTE, pixels, 14938f6d9e12be0be086ca2aab0b56dff8d2181addd9Brian Paul &st->ctx->DefaultPacking, 14948f6d9e12be0be086ca2aab0b56dff8d2181addd9Brian Paul texObj, texImg, 14958f6d9e12be0be086ca2aab0b56dff8d2181addd9Brian Paul 0, 0); 14968f6d9e12be0be086ca2aab0b56dff8d2181addd9Brian Paul 14978f6d9e12be0be086ca2aab0b56dff8d2181addd9Brian Paul texObj->MinFilter = GL_NEAREST; 14988f6d9e12be0be086ca2aab0b56dff8d2181addd9Brian Paul texObj->MagFilter = GL_NEAREST; 14998f6d9e12be0be086ca2aab0b56dff8d2181addd9Brian Paul texObj->_Complete = GL_TRUE; 15008f6d9e12be0be086ca2aab0b56dff8d2181addd9Brian Paul 15018f6d9e12be0be086ca2aab0b56dff8d2181addd9Brian Paul st->default_texture = texObj; 15028f6d9e12be0be086ca2aab0b56dff8d2181addd9Brian Paul } 15038f6d9e12be0be086ca2aab0b56dff8d2181addd9Brian Paul return st->default_texture; 15048f6d9e12be0be086ca2aab0b56dff8d2181addd9Brian Paul} 15058f6d9e12be0be086ca2aab0b56dff8d2181addd9Brian Paul 15068f6d9e12be0be086ca2aab0b56dff8d2181addd9Brian Paul 15076da9234fd437f97267e7831f034c78b31156d939Brianvoid 15086da9234fd437f97267e7831f034c78b31156d939Brianst_init_texture_functions(struct dd_function_table *functions) 150924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 151024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian functions->ChooseTextureFormat = st_ChooseTextureFormat; 151124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian functions->TexImage1D = st_TexImage1D; 151224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian functions->TexImage2D = st_TexImage2D; 151324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian functions->TexImage3D = st_TexImage3D; 151424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian functions->TexSubImage1D = st_TexSubImage1D; 151524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian functions->TexSubImage2D = st_TexSubImage2D; 151624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian functions->TexSubImage3D = st_TexSubImage3D; 151724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian functions->CopyTexImage1D = st_CopyTexImage1D; 151824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian functions->CopyTexImage2D = st_CopyTexImage2D; 151924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian functions->CopyTexSubImage1D = st_CopyTexSubImage1D; 152024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian functions->CopyTexSubImage2D = st_CopyTexSubImage2D; 1521038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian functions->CopyTexSubImage3D = st_CopyTexSubImage3D; 152262abcb9aacc33218d0143a743c738435794b32a9Brian functions->GenerateMipmap = st_generate_mipmap; 1523038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian 152424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian functions->GetTexImage = st_GetTexImage; 152524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 152624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian /* compressed texture functions */ 152724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian functions->CompressedTexImage2D = st_CompressedTexImage2D; 152824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian functions->GetCompressedTexImage = st_GetCompressedTexImage; 1529f32c51277498887b348133ebcd947dbc8acce756Roland Scheidegger functions->CompressedTextureSize = _mesa_compressed_texture_size; 153024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 153124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian functions->NewTextureObject = st_NewTextureObject; 153224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian functions->NewTextureImage = st_NewTextureImage; 153324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian functions->DeleteTexture = st_DeleteTextureObject; 153424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian functions->FreeTexImageData = st_FreeTextureImageData; 153524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian functions->UpdateTexturePalette = 0; 153624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 153724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian functions->TextureMemCpy = do_memcpy; 1538f8549e8f4f8bdfebcb4e0a2754df59b3fe4fdff7Brian 1539f8549e8f4f8bdfebcb4e0a2754df59b3fe4fdff7Brian /* XXX Temporary until we can query pipe's texture sizes */ 1540f8549e8f4f8bdfebcb4e0a2754df59b3fe4fdff7Brian functions->TestProxyTexImage = _mesa_test_proxy_teximage; 154124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 1542