st_cb_texture.c revision b8030c6561e019e079b5be2fe64ec804df4bfa03
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 28f2c023291a1f2887294d2aac504f8b82857ad092Brian Paul#include "main/mfeatures.h" 297b24e58a0ca571d6230ef5076ea352253b81fe6eBrian Paul#include "main/bufferobj.h" 30d055b2c001a0fb233f98c10d124b43dd2448059eBrian#if FEATURE_convolve 3124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#include "main/convolve.h" 32b19e8f720bb2f4d360f5497b64901fc48321f172Brian Paul#endif 3324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#include "main/enums.h" 3465d2a266375cf32fd90c7fb77fb87993d3a652eaBrian Paul#include "main/fbobject.h" 3545e76d2665b38ba3787548310efc59e969124c01Brian Paul#include "main/formats.h" 3624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#include "main/image.h" 37f2c023291a1f2887294d2aac504f8b82857ad092Brian Paul#include "main/imports.h" 3824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#include "main/macros.h" 392440ff74d69a8caf49b05a960b4c7e282a96565eBrian#include "main/mipmap.h" 4024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#include "main/texcompress.h" 414ca9ba254462b9be55b78df1d50519e10b2f4d73Brian Paul#include "main/texfetch.h" 42a4bec69e7271eda0137874973aa8c7d44175fedfBrian Paul#include "main/texgetimage.h" 4324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#include "main/teximage.h" 4424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#include "main/texobj.h" 4524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#include "main/texstore.h" 4624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 47b02ef740b90029bc40629e5b81270a8cf77101d3Keith Whitwell#include "state_tracker/st_debug.h" 4824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#include "state_tracker/st_context.h" 49b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian#include "state_tracker/st_cb_fbo.h" 5024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#include "state_tracker/st_cb_texture.h" 51f8ab24760d0d3f07e9ee81c98207ddf92dfe74daBrian#include "state_tracker/st_format.h" 5202250c855fbec5299a2d6118fefa0523ec73654cMichel Dänzer#include "state_tracker/st_public.h" 53753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer#include "state_tracker/st_texture.h" 5462abcb9aacc33218d0143a743c738435794b32a9Brian#include "state_tracker/st_gen_mipmap.h" 55e50dd26ca6d0eb0d0f97c2780020ea16e3d4a687Thomas Hellstrom#include "state_tracker/st_inlines.h" 56afd16512bc354cf1a7220cb9bf3ce445503c7af4Keith Whitwell#include "state_tracker/st_atom.h" 5724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 5824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#include "pipe/p_context.h" 59b245840b86cf877c9b8d666edf229364a84f1deaBrian#include "pipe/p_defines.h" 6028486880ca3ec39419ccee0cb1a3bedc9ef7117cJosé Fonseca#include "util/u_inlines.h" 618fc945cd847aa5d343a5f76eb2f9f2c9075cccddKeith Whitwell#include "pipe/p_shader_tokens.h" 624f25420bdd834e81a3e22733304efc5261c2998aBrian Paul#include "util/u_tile.h" 633c0dc8242b64518d5635263ba65b39afa919dd86Michel Dänzer#include "util/u_blit.h" 643400b668e35469d5dbba515e3a8b9d775fd2eff5Michal Krol#include "util/u_format.h" 6551b339af2e8b80575a24bb9146f031c9605180bbBrian Paul#include "util/u_surface.h" 66c1785c19ca0716a7e85777242949a0c33e28988fPatrice Mandin#include "util/u_math.h" 6724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 6824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 6924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#define DBG if (0) printf 7024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 7124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 721c5f27a18b775b3784fcd265d60e0affa0b31581Michel Dänzerstatic enum pipe_texture_target 735390a43ce06b27f6d54bc5f237aa305b6948f2afBriangl_target_to_pipe(GLenum target) 745390a43ce06b27f6d54bc5f237aa305b6948f2afBrian{ 755390a43ce06b27f6d54bc5f237aa305b6948f2afBrian switch (target) { 765390a43ce06b27f6d54bc5f237aa305b6948f2afBrian case GL_TEXTURE_1D: 775390a43ce06b27f6d54bc5f237aa305b6948f2afBrian return PIPE_TEXTURE_1D; 785390a43ce06b27f6d54bc5f237aa305b6948f2afBrian 795390a43ce06b27f6d54bc5f237aa305b6948f2afBrian case GL_TEXTURE_2D: 805390a43ce06b27f6d54bc5f237aa305b6948f2afBrian case GL_TEXTURE_RECTANGLE_NV: 815390a43ce06b27f6d54bc5f237aa305b6948f2afBrian return PIPE_TEXTURE_2D; 825390a43ce06b27f6d54bc5f237aa305b6948f2afBrian 835390a43ce06b27f6d54bc5f237aa305b6948f2afBrian case GL_TEXTURE_3D: 845390a43ce06b27f6d54bc5f237aa305b6948f2afBrian return PIPE_TEXTURE_3D; 855390a43ce06b27f6d54bc5f237aa305b6948f2afBrian 865390a43ce06b27f6d54bc5f237aa305b6948f2afBrian case GL_TEXTURE_CUBE_MAP_ARB: 875390a43ce06b27f6d54bc5f237aa305b6948f2afBrian return PIPE_TEXTURE_CUBE; 885390a43ce06b27f6d54bc5f237aa305b6948f2afBrian 895390a43ce06b27f6d54bc5f237aa305b6948f2afBrian default: 905390a43ce06b27f6d54bc5f237aa305b6948f2afBrian assert(0); 915390a43ce06b27f6d54bc5f237aa305b6948f2afBrian return 0; 925390a43ce06b27f6d54bc5f237aa305b6948f2afBrian } 935390a43ce06b27f6d54bc5f237aa305b6948f2afBrian} 945390a43ce06b27f6d54bc5f237aa305b6948f2afBrian 955390a43ce06b27f6d54bc5f237aa305b6948f2afBrian 964e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul/** called via ctx->Driver.NewTextureImage() */ 9724df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic struct gl_texture_image * 9824df8f895fe8807aa2ba058e71bd40adfc01d21eBrianst_NewTextureImage(GLcontext * ctx) 9924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 10024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian DBG("%s\n", __FUNCTION__); 10124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian (void) ctx; 102f1a59a6dd7b7b0523db191d82b3af1a841c6475dBrian Paul return (struct gl_texture_image *) ST_CALLOC_STRUCT(st_texture_image); 10324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 10424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 10524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 1064e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul/** called via ctx->Driver.NewTextureObject() */ 10724df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic struct gl_texture_object * 10824df8f895fe8807aa2ba058e71bd40adfc01d21eBrianst_NewTextureObject(GLcontext * ctx, GLuint name, GLenum target) 10924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 110f1a59a6dd7b7b0523db191d82b3af1a841c6475dBrian Paul struct st_texture_object *obj = ST_CALLOC_STRUCT(st_texture_object); 11124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 11224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian DBG("%s\n", __FUNCTION__); 11324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian _mesa_initialize_texture_object(&obj->base, name, target); 11424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 11524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian return &obj->base; 11624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 11724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 1184e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul/** called via ctx->Driver.DeleteTextureImage() */ 11924df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void 12024df8f895fe8807aa2ba058e71bd40adfc01d21eBrianst_DeleteTextureObject(GLcontext *ctx, 1216f715dcc219071e574e363a9db4365c9c31ebbd3Brian struct gl_texture_object *texObj) 12224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 12324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian struct st_texture_object *stObj = st_texture_object(texObj); 124753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer if (stObj->pt) 125f8dce51083042b4d3fabf48524835290b6725682Brian Paul pipe_texture_reference(&stObj->pt, NULL); 126b8030c6561e019e079b5be2fe64ec804df4bfa03Michal Krol if (stObj->sampler_view) 127b8030c6561e019e079b5be2fe64ec804df4bfa03Michal Krol pipe_sampler_view_reference(&stObj->sampler_view, NULL); 12824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 12924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian _mesa_delete_texture_object(ctx, texObj); 13024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 13124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 13224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 1334e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul/** called via ctx->Driver.FreeTexImageData() */ 13424df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void 13524df8f895fe8807aa2ba058e71bd40adfc01d21eBrianst_FreeTextureImageData(GLcontext * ctx, struct gl_texture_image *texImage) 13624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 13724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian struct st_texture_image *stImage = st_texture_image(texImage); 13824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 13924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian DBG("%s\n", __FUNCTION__); 14024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 141753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer if (stImage->pt) { 142f8dce51083042b4d3fabf48524835290b6725682Brian Paul pipe_texture_reference(&stImage->pt, NULL); 14324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 14424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 14524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian if (texImage->Data) { 1468d6ef125ac6044438db5b89d6d310ccfc4b8140aBrian Paul _mesa_align_free(texImage->Data); 14724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian texImage->Data = NULL; 14824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 14924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 15024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 15124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 1524e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul/** 15324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * From linux kernel i386 header files, copes with odd sizes better 15424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * than COPY_DWORDS would: 15524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * XXX Put this in src/mesa/main/imports.h ??? 15624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 1571ea7f0fef055245fa18c0fbc3e54a866956c2507José Fonseca#if defined(PIPE_CC_GCC) && defined(PIPE_ARCH_X86) 15824df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic INLINE void * 15924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian__memcpy(void *to, const void *from, size_t n) 16024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 16124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian int d0, d1, d2; 16224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian __asm__ __volatile__("rep ; movsl\n\t" 16324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian "testb $2,%b4\n\t" 16424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian "je 1f\n\t" 16524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian "movsw\n" 16624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian "1:\ttestb $1,%b4\n\t" 16724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian "je 2f\n\t" 16824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian "movsb\n" "2:":"=&c"(d0), "=&D"(d1), "=&S"(d2) 16924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian :"0"(n / 4), "q"(n), "1"((long) to), "2"((long) from) 17024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian :"memory"); 17124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian return (to); 17224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 17324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#else 17424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#define __memcpy(a,b,c) memcpy(a,b,c) 17524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#endif 17624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 17724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 1784e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul/** 1794e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul * The system memcpy (at least on ubuntu 5.10) has problems copying 18024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * to agp (writecombined) memory from a source which isn't 64-byte 18124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * aligned - there is a 4x performance falloff. 18224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * 18324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * The x86 __memcpy is immune to this but is slightly slower 18424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * (10%-ish) than the system memcpy. 18524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * 18624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * The sse_memcpy seems to have a slight cliff at 64/32 bytes, but 18724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * isn't much faster than x86_memcpy for agp copies. 18824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * 18924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * TODO: switch dynamically. 19024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 19124df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void * 19224df8f895fe8807aa2ba058e71bd40adfc01d21eBriando_memcpy(void *dest, const void *src, size_t n) 19324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 194799f55803d15602b10d2bb97ff62792f05ce4de3Brian Paul if ((((unsigned long) src) & 63) || (((unsigned long) dest) & 63)) { 19524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian return __memcpy(dest, src, n); 19624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 19724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian else 19824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian return memcpy(dest, src, n); 19924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 20024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 20124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 202f52f5136e6eed23e55098681e5b082cc452136d6Brian/** 2031ad2484f03cbe9ae6bd4ebe50d6894e570d65952Brian Paul * Return default texture usage bitmask for the given texture format. 2041ad2484f03cbe9ae6bd4ebe50d6894e570d65952Brian Paul */ 2051ad2484f03cbe9ae6bd4ebe50d6894e570d65952Brian Paulstatic GLuint 2061ad2484f03cbe9ae6bd4ebe50d6894e570d65952Brian Pauldefault_usage(enum pipe_format fmt) 2071ad2484f03cbe9ae6bd4ebe50d6894e570d65952Brian Paul{ 2081ad2484f03cbe9ae6bd4ebe50d6894e570d65952Brian Paul GLuint usage = PIPE_TEXTURE_USAGE_SAMPLER; 209d28740c298968303500a8c43047ded2679e727acMichal Krol if (util_format_is_depth_or_stencil(fmt)) 2101ad2484f03cbe9ae6bd4ebe50d6894e570d65952Brian Paul usage |= PIPE_TEXTURE_USAGE_DEPTH_STENCIL; 2111ad2484f03cbe9ae6bd4ebe50d6894e570d65952Brian Paul else 2121ad2484f03cbe9ae6bd4ebe50d6894e570d65952Brian Paul usage |= PIPE_TEXTURE_USAGE_RENDER_TARGET; 2131ad2484f03cbe9ae6bd4ebe50d6894e570d65952Brian Paul return usage; 2141ad2484f03cbe9ae6bd4ebe50d6894e570d65952Brian Paul} 2151ad2484f03cbe9ae6bd4ebe50d6894e570d65952Brian Paul 2161ad2484f03cbe9ae6bd4ebe50d6894e570d65952Brian Paul 2171ad2484f03cbe9ae6bd4ebe50d6894e570d65952Brian Paul/** 218f52f5136e6eed23e55098681e5b082cc452136d6Brian * Allocate a pipe_texture object for the given st_texture_object using 219f52f5136e6eed23e55098681e5b082cc452136d6Brian * the given st_texture_image to guess the mipmap size/levels. 220f52f5136e6eed23e55098681e5b082cc452136d6Brian * 221f52f5136e6eed23e55098681e5b082cc452136d6Brian * [comments...] 222f52f5136e6eed23e55098681e5b082cc452136d6Brian * Otherwise, store it in memory if (Border != 0) or (any dimension == 22324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * 1). 22424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * 225753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer * Otherwise, if max_level >= level >= min_level, create texture with 226753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer * space for images from min_level down to max_level. 22724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * 228753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer * Otherwise, create texture with space for images from (level 0)..(1x1). 229753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer * Consider pruning this texture at a validation if the saving is worth it. 23024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 23124df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void 232753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzerguess_and_alloc_texture(struct st_context *st, 233753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer struct st_texture_object *stObj, 234afc54983370033b65e3a7cbb29bd9c87156f0881Brian const struct st_texture_image *stImage) 23524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 23624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLuint firstLevel; 23724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLuint lastLevel; 23845cc35e77600af8628393475405160e26d56d421Brian Paul GLuint width = stImage->base.Width2; /* size w/out border */ 23945cc35e77600af8628393475405160e26d56d421Brian Paul GLuint height = stImage->base.Height2; 24045cc35e77600af8628393475405160e26d56d421Brian Paul GLuint depth = stImage->base.Depth2; 241f12201567463c7aeb9b76c32f000d577a82e7f92Brian Paul GLuint i, usage; 242a1f95a8bf64f863289b6759caeec76d7e054400eRoland Scheidegger enum pipe_format fmt; 24324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 24424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian DBG("%s\n", __FUNCTION__); 24524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 246f52f5136e6eed23e55098681e5b082cc452136d6Brian assert(!stObj->pt); 247f52f5136e6eed23e55098681e5b082cc452136d6Brian 24845cc35e77600af8628393475405160e26d56d421Brian Paul if (stObj->pt && 2496c534b830c6f5427c391c5225c34561141c201baMichal Krol (GLint) stImage->level > stObj->base.BaseLevel && 25014b98343309fdcff3514f05020303f7b40e83a4aBrian (stImage->base.Width == 1 || 25114b98343309fdcff3514f05020303f7b40e83a4aBrian (stObj->base.Target != GL_TEXTURE_1D && 25214b98343309fdcff3514f05020303f7b40e83a4aBrian stImage->base.Height == 1) || 25314b98343309fdcff3514f05020303f7b40e83a4aBrian (stObj->base.Target == GL_TEXTURE_3D && 25414b98343309fdcff3514f05020303f7b40e83a4aBrian stImage->base.Depth == 1))) 25524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian return; 25624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 25724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian /* If this image disrespects BaseLevel, allocate from level zero. 25824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * Usually BaseLevel == 0, so it's unlikely to happen. 25924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 2606c534b830c6f5427c391c5225c34561141c201baMichal Krol if ((GLint) stImage->level < stObj->base.BaseLevel) 26124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian firstLevel = 0; 26224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian else 26314b98343309fdcff3514f05020303f7b40e83a4aBrian firstLevel = stObj->base.BaseLevel; 26424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 26524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 26624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian /* Figure out image dimensions at start level. 26724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 26814b98343309fdcff3514f05020303f7b40e83a4aBrian for (i = stImage->level; i > firstLevel; i--) { 26945cc35e77600af8628393475405160e26d56d421Brian Paul if (width != 1) 27045cc35e77600af8628393475405160e26d56d421Brian Paul width <<= 1; 27124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian if (height != 1) 27224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian height <<= 1; 27324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian if (depth != 1) 27424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian depth <<= 1; 27524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 27624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 277296378b6c8b205048244746e260739448c4ee590Brian Paul if (width == 0 || height == 0 || depth == 0) { 278296378b6c8b205048244746e260739448c4ee590Brian Paul /* no texture needed */ 279296378b6c8b205048244746e260739448c4ee590Brian Paul return; 280296378b6c8b205048244746e260739448c4ee590Brian Paul } 281296378b6c8b205048244746e260739448c4ee590Brian Paul 28224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian /* Guess a reasonable value for lastLevel. This is probably going 28324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * to be wrong fairly often and might mean that we have to look at 28424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * resizable buffers, or require that buffers implement lazy 28524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * pagetable arrangements. 28624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 28714b98343309fdcff3514f05020303f7b40e83a4aBrian if ((stObj->base.MinFilter == GL_NEAREST || 2882a2236606fd6ae473a2f4db6ef6d3d5030261316José Fonseca stObj->base.MinFilter == GL_LINEAR || 2892a2236606fd6ae473a2f4db6ef6d3d5030261316José Fonseca stImage->base._BaseFormat == GL_DEPTH_COMPONENT || 2902a2236606fd6ae473a2f4db6ef6d3d5030261316José Fonseca stImage->base._BaseFormat == GL_DEPTH_STENCIL_EXT) && 29105bad193f56d48384097e37e47fae3fdda85f144Brian Paul !stObj->base.GenerateMipmap && 29214b98343309fdcff3514f05020303f7b40e83a4aBrian stImage->level == firstLevel) { 29305bad193f56d48384097e37e47fae3fdda85f144Brian Paul /* only alloc space for a single mipmap level */ 29424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian lastLevel = firstLevel; 29524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 29624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian else { 29705bad193f56d48384097e37e47fae3fdda85f144Brian Paul /* alloc space for a full mipmap */ 298c1785c19ca0716a7e85777242949a0c33e28988fPatrice Mandin GLuint l2width = util_logbase2(width); 299c1785c19ca0716a7e85777242949a0c33e28988fPatrice Mandin GLuint l2height = util_logbase2(height); 300c1785c19ca0716a7e85777242949a0c33e28988fPatrice Mandin GLuint l2depth = util_logbase2(depth); 30124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian lastLevel = firstLevel + MAX2(MAX2(l2width, l2height), l2depth); 30224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 30324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 3041f7c914ad0beea8a29c1a171c7cd1a12f2efe0faBrian Paul fmt = st_mesa_format_to_pipe_format(stImage->base.TexFormat); 3051ad2484f03cbe9ae6bd4ebe50d6894e570d65952Brian Paul 3061ad2484f03cbe9ae6bd4ebe50d6894e570d65952Brian Paul usage = default_usage(fmt); 3071ad2484f03cbe9ae6bd4ebe50d6894e570d65952Brian Paul 308753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer stObj->pt = st_texture_create(st, 3095390a43ce06b27f6d54bc5f237aa305b6948f2afBrian gl_target_to_pipe(stObj->base.Target), 310a1f95a8bf64f863289b6759caeec76d7e054400eRoland Scheidegger fmt, 3115390a43ce06b27f6d54bc5f237aa305b6948f2afBrian lastLevel, 3125390a43ce06b27f6d54bc5f237aa305b6948f2afBrian width, 3135390a43ce06b27f6d54bc5f237aa305b6948f2afBrian height, 3145390a43ce06b27f6d54bc5f237aa305b6948f2afBrian depth, 3151ad2484f03cbe9ae6bd4ebe50d6894e570d65952Brian Paul usage); 31624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 317b8030c6561e019e079b5be2fe64ec804df4bfa03Michal Krol stObj->pipe = st->pipe; 318b8030c6561e019e079b5be2fe64ec804df4bfa03Michal Krol 31924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian DBG("%s - success\n", __FUNCTION__); 32024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 32124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 32224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 323212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian/** 324212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian * Adjust pixel unpack params and image dimensions to strip off the 325212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian * texture border. 326212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian * Gallium doesn't support texture borders. They've seldem been used 327212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian * and seldom been implemented correctly anyway. 328212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian * \param unpackNew returns the new pixel unpack parameters 329212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian */ 330212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brianstatic void 331212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brianstrip_texture_border(GLint border, 332212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian GLint *width, GLint *height, GLint *depth, 333212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian const struct gl_pixelstore_attrib *unpack, 334212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian struct gl_pixelstore_attrib *unpackNew) 335212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian{ 336212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian assert(border > 0); /* sanity check */ 337212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian 338212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian *unpackNew = *unpack; 339212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian 340212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian if (unpackNew->RowLength == 0) 341212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian unpackNew->RowLength = *width; 342212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian 343212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian if (depth && unpackNew->ImageHeight == 0) 344212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian unpackNew->ImageHeight = *height; 345212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian 346212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian unpackNew->SkipPixels += border; 347212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian if (height) 348212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian unpackNew->SkipRows += border; 349212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian if (depth) 350212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian unpackNew->SkipImages += border; 351212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian 352212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian assert(*width >= 3); 353212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian *width = *width - 2 * border; 354212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian if (height && *height >= 3) 355212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian *height = *height - 2 * border; 356212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian if (depth && *depth >= 3) 357212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian *depth = *depth - 2 * border; 358212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian} 359212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian 36024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 3614e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul/** 36255ed2a73653fb2fb9dee36c729c09177df2d5b4eJakob Bornecrantz * Try to do texture compression via rendering. If the Gallium driver 36355ed2a73653fb2fb9dee36c729c09177df2d5b4eJakob Bornecrantz * can render into a compressed surface this will allow us to do texture 36455ed2a73653fb2fb9dee36c729c09177df2d5b4eJakob Bornecrantz * compression. 36555ed2a73653fb2fb9dee36c729c09177df2d5b4eJakob Bornecrantz * \return GL_TRUE for success, GL_FALSE for failure 36655ed2a73653fb2fb9dee36c729c09177df2d5b4eJakob Bornecrantz */ 36755ed2a73653fb2fb9dee36c729c09177df2d5b4eJakob Bornecrantzstatic GLboolean 36855ed2a73653fb2fb9dee36c729c09177df2d5b4eJakob Bornecrantzcompress_with_blit(GLcontext * ctx, 36955ed2a73653fb2fb9dee36c729c09177df2d5b4eJakob Bornecrantz GLenum target, GLint level, 37055ed2a73653fb2fb9dee36c729c09177df2d5b4eJakob Bornecrantz GLint xoffset, GLint yoffset, GLint zoffset, 37155ed2a73653fb2fb9dee36c729c09177df2d5b4eJakob Bornecrantz GLint width, GLint height, GLint depth, 37255ed2a73653fb2fb9dee36c729c09177df2d5b4eJakob Bornecrantz GLenum format, GLenum type, const void *pixels, 37355ed2a73653fb2fb9dee36c729c09177df2d5b4eJakob Bornecrantz const struct gl_pixelstore_attrib *unpack, 37455ed2a73653fb2fb9dee36c729c09177df2d5b4eJakob Bornecrantz struct gl_texture_image *texImage) 37555ed2a73653fb2fb9dee36c729c09177df2d5b4eJakob Bornecrantz{ 37655ed2a73653fb2fb9dee36c729c09177df2d5b4eJakob Bornecrantz const GLuint dstImageOffsets[1] = {0}; 37755ed2a73653fb2fb9dee36c729c09177df2d5b4eJakob Bornecrantz struct st_texture_image *stImage = st_texture_image(texImage); 37855ed2a73653fb2fb9dee36c729c09177df2d5b4eJakob Bornecrantz struct pipe_screen *screen = ctx->st->pipe->screen; 3791f7c914ad0beea8a29c1a171c7cd1a12f2efe0faBrian Paul gl_format mesa_format; 38055ed2a73653fb2fb9dee36c729c09177df2d5b4eJakob Bornecrantz struct pipe_texture templ; 38155ed2a73653fb2fb9dee36c729c09177df2d5b4eJakob Bornecrantz struct pipe_texture *src_tex; 38255ed2a73653fb2fb9dee36c729c09177df2d5b4eJakob Bornecrantz struct pipe_surface *dst_surface; 38355ed2a73653fb2fb9dee36c729c09177df2d5b4eJakob Bornecrantz struct pipe_transfer *tex_xfer; 38455ed2a73653fb2fb9dee36c729c09177df2d5b4eJakob Bornecrantz void *map; 38555ed2a73653fb2fb9dee36c729c09177df2d5b4eJakob Bornecrantz 38655ed2a73653fb2fb9dee36c729c09177df2d5b4eJakob Bornecrantz if (!stImage->pt) { 38755ed2a73653fb2fb9dee36c729c09177df2d5b4eJakob Bornecrantz /* XXX: Can this happen? Should we assert? */ 38855ed2a73653fb2fb9dee36c729c09177df2d5b4eJakob Bornecrantz return GL_FALSE; 38955ed2a73653fb2fb9dee36c729c09177df2d5b4eJakob Bornecrantz } 39055ed2a73653fb2fb9dee36c729c09177df2d5b4eJakob Bornecrantz 39155ed2a73653fb2fb9dee36c729c09177df2d5b4eJakob Bornecrantz /* get destination surface (in the compressed texture) */ 39255ed2a73653fb2fb9dee36c729c09177df2d5b4eJakob Bornecrantz dst_surface = screen->get_tex_surface(screen, stImage->pt, 39355ed2a73653fb2fb9dee36c729c09177df2d5b4eJakob Bornecrantz stImage->face, stImage->level, 0, 39455ed2a73653fb2fb9dee36c729c09177df2d5b4eJakob Bornecrantz PIPE_BUFFER_USAGE_GPU_WRITE); 39555ed2a73653fb2fb9dee36c729c09177df2d5b4eJakob Bornecrantz if (!dst_surface) { 39655ed2a73653fb2fb9dee36c729c09177df2d5b4eJakob Bornecrantz /* can't render into this format (or other problem) */ 39755ed2a73653fb2fb9dee36c729c09177df2d5b4eJakob Bornecrantz return GL_FALSE; 39855ed2a73653fb2fb9dee36c729c09177df2d5b4eJakob Bornecrantz } 39955ed2a73653fb2fb9dee36c729c09177df2d5b4eJakob Bornecrantz 40055ed2a73653fb2fb9dee36c729c09177df2d5b4eJakob Bornecrantz /* Choose format for the temporary RGBA texture image. 40155ed2a73653fb2fb9dee36c729c09177df2d5b4eJakob Bornecrantz */ 40255ed2a73653fb2fb9dee36c729c09177df2d5b4eJakob Bornecrantz mesa_format = st_ChooseTextureFormat(ctx, GL_RGBA, format, type); 40355ed2a73653fb2fb9dee36c729c09177df2d5b4eJakob Bornecrantz assert(mesa_format); 40455ed2a73653fb2fb9dee36c729c09177df2d5b4eJakob Bornecrantz if (!mesa_format) 40555ed2a73653fb2fb9dee36c729c09177df2d5b4eJakob Bornecrantz return GL_FALSE; 40655ed2a73653fb2fb9dee36c729c09177df2d5b4eJakob Bornecrantz 40755ed2a73653fb2fb9dee36c729c09177df2d5b4eJakob Bornecrantz /* Create the temporary source texture 40855ed2a73653fb2fb9dee36c729c09177df2d5b4eJakob Bornecrantz */ 40955ed2a73653fb2fb9dee36c729c09177df2d5b4eJakob Bornecrantz memset(&templ, 0, sizeof(templ)); 41055ed2a73653fb2fb9dee36c729c09177df2d5b4eJakob Bornecrantz templ.target = PIPE_TEXTURE_2D; 4111f7c914ad0beea8a29c1a171c7cd1a12f2efe0faBrian Paul templ.format = st_mesa_format_to_pipe_format(mesa_format); 412683e35f726a182ed9fc6b6d5cb07146eebe14deaKeith Whitwell templ.width0 = width; 413683e35f726a182ed9fc6b6d5cb07146eebe14deaKeith Whitwell templ.height0 = height; 414683e35f726a182ed9fc6b6d5cb07146eebe14deaKeith Whitwell templ.depth0 = 1; 41555ed2a73653fb2fb9dee36c729c09177df2d5b4eJakob Bornecrantz templ.last_level = 0; 41655ed2a73653fb2fb9dee36c729c09177df2d5b4eJakob Bornecrantz templ.tex_usage = PIPE_TEXTURE_USAGE_SAMPLER; 41755ed2a73653fb2fb9dee36c729c09177df2d5b4eJakob Bornecrantz src_tex = screen->texture_create(screen, &templ); 41855ed2a73653fb2fb9dee36c729c09177df2d5b4eJakob Bornecrantz 41955ed2a73653fb2fb9dee36c729c09177df2d5b4eJakob Bornecrantz if (!src_tex) 42055ed2a73653fb2fb9dee36c729c09177df2d5b4eJakob Bornecrantz return GL_FALSE; 42155ed2a73653fb2fb9dee36c729c09177df2d5b4eJakob Bornecrantz 42255ed2a73653fb2fb9dee36c729c09177df2d5b4eJakob Bornecrantz /* Put user's tex data into the temporary texture 42355ed2a73653fb2fb9dee36c729c09177df2d5b4eJakob Bornecrantz */ 424e50dd26ca6d0eb0d0f97c2780020ea16e3d4a687Thomas Hellstrom tex_xfer = st_cond_flush_get_tex_transfer(st_context(ctx), src_tex, 4255ed7764fd6354da8e2be15d6fb724c2d6be9be4aKeith Whitwell 0, 0, 0, /* face, level are zero */ 426e50dd26ca6d0eb0d0f97c2780020ea16e3d4a687Thomas Hellstrom PIPE_TRANSFER_WRITE, 427e50dd26ca6d0eb0d0f97c2780020ea16e3d4a687Thomas Hellstrom 0, 0, width, height); /* x, y, w, h */ 42855ed2a73653fb2fb9dee36c729c09177df2d5b4eJakob Bornecrantz map = screen->transfer_map(screen, tex_xfer); 42955ed2a73653fb2fb9dee36c729c09177df2d5b4eJakob Bornecrantz 4306480210b89dc8ae0990c450d27870c7b7930f251Brian Paul _mesa_texstore(ctx, 2, GL_RGBA, mesa_format, 4316480210b89dc8ae0990c450d27870c7b7930f251Brian Paul map, /* dest ptr */ 4326480210b89dc8ae0990c450d27870c7b7930f251Brian Paul 0, 0, 0, /* dest x/y/z offset */ 4336480210b89dc8ae0990c450d27870c7b7930f251Brian Paul tex_xfer->stride, /* dest row stride (bytes) */ 4346480210b89dc8ae0990c450d27870c7b7930f251Brian Paul dstImageOffsets, /* image offsets (for 3D only) */ 4356480210b89dc8ae0990c450d27870c7b7930f251Brian Paul width, height, 1, /* size */ 4366480210b89dc8ae0990c450d27870c7b7930f251Brian Paul format, type, /* source format/type */ 4376480210b89dc8ae0990c450d27870c7b7930f251Brian Paul pixels, /* source data */ 4386480210b89dc8ae0990c450d27870c7b7930f251Brian Paul unpack); /* source data packing */ 43955ed2a73653fb2fb9dee36c729c09177df2d5b4eJakob Bornecrantz 44055ed2a73653fb2fb9dee36c729c09177df2d5b4eJakob Bornecrantz screen->transfer_unmap(screen, tex_xfer); 44155ed2a73653fb2fb9dee36c729c09177df2d5b4eJakob Bornecrantz screen->tex_transfer_destroy(tex_xfer); 44255ed2a73653fb2fb9dee36c729c09177df2d5b4eJakob Bornecrantz 44355ed2a73653fb2fb9dee36c729c09177df2d5b4eJakob Bornecrantz /* copy / compress image */ 44455ed2a73653fb2fb9dee36c729c09177df2d5b4eJakob Bornecrantz util_blit_pixels_tex(ctx->st->blit, 44555ed2a73653fb2fb9dee36c729c09177df2d5b4eJakob Bornecrantz src_tex, /* pipe_texture (src) */ 44655ed2a73653fb2fb9dee36c729c09177df2d5b4eJakob Bornecrantz 0, 0, /* src x0, y0 */ 44755ed2a73653fb2fb9dee36c729c09177df2d5b4eJakob Bornecrantz width, height, /* src x1, y1 */ 44855ed2a73653fb2fb9dee36c729c09177df2d5b4eJakob Bornecrantz dst_surface, /* pipe_surface (dst) */ 44955ed2a73653fb2fb9dee36c729c09177df2d5b4eJakob Bornecrantz xoffset, yoffset, /* dst x0, y0 */ 45055ed2a73653fb2fb9dee36c729c09177df2d5b4eJakob Bornecrantz xoffset + width, /* dst x1 */ 45155ed2a73653fb2fb9dee36c729c09177df2d5b4eJakob Bornecrantz yoffset + height, /* dst y1 */ 45255ed2a73653fb2fb9dee36c729c09177df2d5b4eJakob Bornecrantz 0.0, /* z */ 45355ed2a73653fb2fb9dee36c729c09177df2d5b4eJakob Bornecrantz PIPE_TEX_MIPFILTER_NEAREST); 45455ed2a73653fb2fb9dee36c729c09177df2d5b4eJakob Bornecrantz 45555ed2a73653fb2fb9dee36c729c09177df2d5b4eJakob Bornecrantz pipe_surface_reference(&dst_surface, NULL); 45655ed2a73653fb2fb9dee36c729c09177df2d5b4eJakob Bornecrantz pipe_texture_reference(&src_tex, NULL); 45755ed2a73653fb2fb9dee36c729c09177df2d5b4eJakob Bornecrantz 45855ed2a73653fb2fb9dee36c729c09177df2d5b4eJakob Bornecrantz return GL_TRUE; 45955ed2a73653fb2fb9dee36c729c09177df2d5b4eJakob Bornecrantz} 46055ed2a73653fb2fb9dee36c729c09177df2d5b4eJakob Bornecrantz 46155ed2a73653fb2fb9dee36c729c09177df2d5b4eJakob Bornecrantz 46255ed2a73653fb2fb9dee36c729c09177df2d5b4eJakob Bornecrantz/** 4634e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul * Do glTexImage1/2/3D(). 4644e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul */ 46524df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void 46624df8f895fe8807aa2ba058e71bd40adfc01d21eBrianst_TexImage(GLcontext * ctx, 467afc54983370033b65e3a7cbb29bd9c87156f0881Brian GLint dims, 468afc54983370033b65e3a7cbb29bd9c87156f0881Brian GLenum target, GLint level, 469afc54983370033b65e3a7cbb29bd9c87156f0881Brian GLint internalFormat, 470afc54983370033b65e3a7cbb29bd9c87156f0881Brian GLint width, GLint height, GLint depth, 471afc54983370033b65e3a7cbb29bd9c87156f0881Brian GLint border, 472afc54983370033b65e3a7cbb29bd9c87156f0881Brian GLenum format, GLenum type, const void *pixels, 473afc54983370033b65e3a7cbb29bd9c87156f0881Brian const struct gl_pixelstore_attrib *unpack, 474afc54983370033b65e3a7cbb29bd9c87156f0881Brian struct gl_texture_object *texObj, 475afc54983370033b65e3a7cbb29bd9c87156f0881Brian struct gl_texture_image *texImage, 47655ed2a73653fb2fb9dee36c729c09177df2d5b4eJakob Bornecrantz GLsizei imageSize, GLboolean compressed_src) 47724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 47855ed2a73653fb2fb9dee36c729c09177df2d5b4eJakob Bornecrantz struct pipe_screen *screen = ctx->st->pipe->screen; 47914b98343309fdcff3514f05020303f7b40e83a4aBrian struct st_texture_object *stObj = st_texture_object(texObj); 48014b98343309fdcff3514f05020303f7b40e83a4aBrian struct st_texture_image *stImage = st_texture_image(texImage); 481212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian GLint postConvWidth, postConvHeight; 48224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLint texelBytes, sizeInBytes; 4835a8e1ddf193bb25c5cf05b70088c64ede772d7e9Brian Paul GLuint dstRowStride = 0; 484212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian struct gl_pixelstore_attrib unpackNB; 4855a8e1ddf193bb25c5cf05b70088c64ede772d7e9Brian Paul enum pipe_transfer_usage transfer_usage = 0; 48624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 48724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian DBG("%s target %s level %d %dx%dx%d border %d\n", __FUNCTION__, 48824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian _mesa_lookup_enum_by_nr(target), level, width, height, depth, border); 48924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 49054a7115fc27c640e2b3f1a362e8e07aac220556dChia-I Wu /* switch to "normal" */ 49154a7115fc27c640e2b3f1a362e8e07aac220556dChia-I Wu if (stObj->surface_based) { 49254a7115fc27c640e2b3f1a362e8e07aac220556dChia-I Wu _mesa_clear_texture_object(ctx, texObj); 49354a7115fc27c640e2b3f1a362e8e07aac220556dChia-I Wu stObj->surface_based = GL_FALSE; 49454a7115fc27c640e2b3f1a362e8e07aac220556dChia-I Wu } 49554a7115fc27c640e2b3f1a362e8e07aac220556dChia-I Wu 496212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian /* gallium does not support texture borders, strip it off */ 497212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian if (border) { 4985facd7986ace899673499f396897469720476799Brian Paul strip_texture_border(border, &width, &height, &depth, unpack, &unpackNB); 499212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian unpack = &unpackNB; 50021989edd55409d72ee55187f4f9062496ca3fbf8Brian Paul texImage->Width = width; 50121989edd55409d72ee55187f4f9062496ca3fbf8Brian Paul texImage->Height = height; 50221989edd55409d72ee55187f4f9062496ca3fbf8Brian Paul texImage->Depth = depth; 50321989edd55409d72ee55187f4f9062496ca3fbf8Brian Paul texImage->Border = 0; 504212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian border = 0; 505212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian } 506212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian 507212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian postConvWidth = width; 508212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian postConvHeight = height; 509212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian 510cfe9e66f2bc596c43760911e7c1604bb32cdee28Brian stImage->face = _mesa_tex_target_to_face(target); 51114b98343309fdcff3514f05020303f7b40e83a4aBrian stImage->level = level; 51224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 513d055b2c001a0fb233f98c10d124b43dd2448059eBrian#if FEATURE_convolve 51424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian if (ctx->_ImageTransferState & IMAGE_CONVOLUTION_BIT) { 51524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian _mesa_adjust_image_for_convolution(ctx, dims, &postConvWidth, 51624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian &postConvHeight); 51724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 518b19e8f720bb2f4d360f5497b64901fc48321f172Brian Paul#endif 51924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 52024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian _mesa_set_fetch_functions(texImage, dims); 52124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 5221f7c914ad0beea8a29c1a171c7cd1a12f2efe0faBrian Paul if (_mesa_is_format_compressed(texImage->TexFormat)) { 52324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian /* must be a compressed format */ 52424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian texelBytes = 0; 525afc54983370033b65e3a7cbb29bd9c87156f0881Brian } 526afc54983370033b65e3a7cbb29bd9c87156f0881Brian else { 5271f7c914ad0beea8a29c1a171c7cd1a12f2efe0faBrian Paul texelBytes = _mesa_get_format_bytes(texImage->TexFormat); 52824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 52924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian /* Minimum pitch of 32 bytes */ 53024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian if (postConvWidth * texelBytes < 32) { 53124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian postConvWidth = 32 / texelBytes; 53224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian texImage->RowStride = postConvWidth; 53324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 53424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 5357585b4ceb8fed862c07f50af8030a6f0eb8a8321Brian /* we'll set RowStride elsewhere when the texture is a "mapped" state */ 5367585b4ceb8fed862c07f50af8030a6f0eb8a8321Brian /*assert(texImage->RowStride == postConvWidth);*/ 53724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 53824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 53924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian /* Release the reference to a potentially orphaned buffer. 54024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * Release any old malloced memory. 54124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 542753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer if (stImage->pt) { 543f8dce51083042b4d3fabf48524835290b6725682Brian Paul pipe_texture_reference(&stImage->pt, NULL); 54424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian assert(!texImage->Data); 54524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 54624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian else if (texImage->Data) { 54724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian _mesa_align_free(texImage->Data); 54824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 54924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 550bdf975e9ad25ee65d796a3c1ce3f2afbd2889c4eBrian Paul /* 551bdf975e9ad25ee65d796a3c1ce3f2afbd2889c4eBrian Paul * See if the new image is somehow incompatible with the existing 552bdf975e9ad25ee65d796a3c1ce3f2afbd2889c4eBrian Paul * mipmap. If so, free the old mipmap. 55324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 554a0509f7d28765c6ef8546eafba94aec46d9e7ed3Brian Paul if (stObj->pt) { 555a0509f7d28765c6ef8546eafba94aec46d9e7ed3Brian Paul if (stObj->teximage_realloc || 556d7b7b63bd7cca80e99ad9701f8b56ee365053647Michal Krol level > (GLint) stObj->pt->last_level || 557bdf975e9ad25ee65d796a3c1ce3f2afbd2889c4eBrian Paul !st_texture_match_image(stObj->pt, &stImage->base, 558bdf975e9ad25ee65d796a3c1ce3f2afbd2889c4eBrian Paul stImage->face, stImage->level)) { 559a0509f7d28765c6ef8546eafba94aec46d9e7ed3Brian Paul DBG("release it\n"); 560a0509f7d28765c6ef8546eafba94aec46d9e7ed3Brian Paul pipe_texture_reference(&stObj->pt, NULL); 561a0509f7d28765c6ef8546eafba94aec46d9e7ed3Brian Paul assert(!stObj->pt); 562a0509f7d28765c6ef8546eafba94aec46d9e7ed3Brian Paul stObj->teximage_realloc = FALSE; 563a0509f7d28765c6ef8546eafba94aec46d9e7ed3Brian Paul } 56424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 56524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 566bdf975e9ad25ee65d796a3c1ce3f2afbd2889c4eBrian Paul if (width == 0 || height == 0 || depth == 0) { 567bdf975e9ad25ee65d796a3c1ce3f2afbd2889c4eBrian Paul /* stop after freeing old image */ 568bdf975e9ad25ee65d796a3c1ce3f2afbd2889c4eBrian Paul return; 569bdf975e9ad25ee65d796a3c1ce3f2afbd2889c4eBrian Paul } 570bdf975e9ad25ee65d796a3c1ce3f2afbd2889c4eBrian Paul 571753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer if (!stObj->pt) { 572753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer guess_and_alloc_texture(ctx->st, stObj, stImage); 573753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer if (!stObj->pt) { 5748d249ca620f6995cc5824d95c29bda7043bbdf8cBrian Paul /* Probably out of memory. 5758d249ca620f6995cc5824d95c29bda7043bbdf8cBrian Paul * Try flushing any pending rendering, then retry. 5768d249ca620f6995cc5824d95c29bda7043bbdf8cBrian Paul */ 5778d249ca620f6995cc5824d95c29bda7043bbdf8cBrian Paul st_finish(ctx->st); 5788d249ca620f6995cc5824d95c29bda7043bbdf8cBrian Paul guess_and_alloc_texture(ctx->st, stObj, stImage); 5798d249ca620f6995cc5824d95c29bda7043bbdf8cBrian Paul if (!stObj->pt) { 5808d249ca620f6995cc5824d95c29bda7043bbdf8cBrian Paul _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage"); 5818d249ca620f6995cc5824d95c29bda7043bbdf8cBrian Paul return; 5828d249ca620f6995cc5824d95c29bda7043bbdf8cBrian Paul } 58324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 58424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 58524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 586753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer assert(!stImage->pt); 58724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 588753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer if (stObj->pt && 589753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer st_texture_match_image(stObj->pt, &stImage->base, 59014b98343309fdcff3514f05020303f7b40e83a4aBrian stImage->face, stImage->level)) { 59124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 5924da19dbcaa9f3e2d20fffd0145bf0bc756dd7542Brian pipe_texture_reference(&stImage->pt, stObj->pt); 593753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer assert(stImage->pt); 59424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 59524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 596753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer if (!stImage->pt) 597753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer DBG("XXX: Image did not fit into texture - storing in local memory!\n"); 59824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 599987d59bb83e9e08192563e5f1b52949c5511053cMichel Dänzer /* st_CopyTexImage calls this function with pixels == NULL, with 600753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer * the expectation that the texture will be set up but nothing 60124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * more will be done. This is where those calls return: 60224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 60355ed2a73653fb2fb9dee36c729c09177df2d5b4eJakob Bornecrantz if (compressed_src) { 60424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian pixels = _mesa_validate_pbo_compressed_teximage(ctx, imageSize, pixels, 60524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian unpack, 60624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian "glCompressedTexImage"); 6075facd7986ace899673499f396897469720476799Brian Paul } 6085facd7986ace899673499f396897469720476799Brian Paul else { 60924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian pixels = _mesa_validate_pbo_teximage(ctx, dims, width, height, 1, 61024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian format, type, 61124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian pixels, unpack, "glTexImage"); 61224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 613cfa1a0a609daefffc6f8c4087ed0bc34c2665ef4Brian Paul 614cfa1a0a609daefffc6f8c4087ed0bc34c2665ef4Brian Paul /* Note: we can't check for pixels==NULL until after we've allocated 615cfa1a0a609daefffc6f8c4087ed0bc34c2665ef4Brian Paul * memory for the texture. 616cfa1a0a609daefffc6f8c4087ed0bc34c2665ef4Brian Paul */ 61724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 61855ed2a73653fb2fb9dee36c729c09177df2d5b4eJakob Bornecrantz /* See if we can do texture compression with a blit/render. 61955ed2a73653fb2fb9dee36c729c09177df2d5b4eJakob Bornecrantz */ 62055ed2a73653fb2fb9dee36c729c09177df2d5b4eJakob Bornecrantz if (!compressed_src && 62155ed2a73653fb2fb9dee36c729c09177df2d5b4eJakob Bornecrantz !ctx->Mesa_DXTn && 62292863109af05acdb4ee5e42141c83ab0f18b7f88Brian Paul _mesa_is_format_compressed(texImage->TexFormat) && 62355ed2a73653fb2fb9dee36c729c09177df2d5b4eJakob Bornecrantz screen->is_format_supported(screen, 62455ed2a73653fb2fb9dee36c729c09177df2d5b4eJakob Bornecrantz stImage->pt->format, 62555ed2a73653fb2fb9dee36c729c09177df2d5b4eJakob Bornecrantz stImage->pt->target, 62655ed2a73653fb2fb9dee36c729c09177df2d5b4eJakob Bornecrantz PIPE_TEXTURE_USAGE_RENDER_TARGET, 0)) { 627cfa1a0a609daefffc6f8c4087ed0bc34c2665ef4Brian Paul if (!pixels) 628cfa1a0a609daefffc6f8c4087ed0bc34c2665ef4Brian Paul goto done; 629cfa1a0a609daefffc6f8c4087ed0bc34c2665ef4Brian Paul 63055ed2a73653fb2fb9dee36c729c09177df2d5b4eJakob Bornecrantz if (compress_with_blit(ctx, target, level, 0, 0, 0, width, height, depth, 63155ed2a73653fb2fb9dee36c729c09177df2d5b4eJakob Bornecrantz format, type, pixels, unpack, texImage)) { 632f989390af6f827d1ea36560381340148811836f3Jakob Bornecrantz goto done; 63355ed2a73653fb2fb9dee36c729c09177df2d5b4eJakob Bornecrantz } 63455ed2a73653fb2fb9dee36c729c09177df2d5b4eJakob Bornecrantz } 63555ed2a73653fb2fb9dee36c729c09177df2d5b4eJakob Bornecrantz 636753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer if (stImage->pt) { 63771633abafc935c25da9731bab48c228ceb9b4097Michel Dänzer if (format == GL_DEPTH_COMPONENT && 6380bed834be4a174d20b31a6cbcf066774bf749929Michal Krol util_format_is_depth_and_stencil(stImage->pt->format)) 63971633abafc935c25da9731bab48c228ceb9b4097Michel Dänzer transfer_usage = PIPE_TRANSFER_READ_WRITE; 64071633abafc935c25da9731bab48c228ceb9b4097Michel Dänzer else 64171633abafc935c25da9731bab48c228ceb9b4097Michel Dänzer transfer_usage = PIPE_TRANSFER_WRITE; 64271633abafc935c25da9731bab48c228ceb9b4097Michel Dänzer 643c9ed86a96483063f3d6789ed16645a3dca77d726Keith Whitwell texImage->Data = st_texture_image_map(ctx->st, stImage, 0, 64471633abafc935c25da9731bab48c228ceb9b4097Michel Dänzer transfer_usage, 0, 0, 6454617981ec72f7985941bee4b03c534d97ff96bc6Michel Dänzer stImage->base.Width, 6464617981ec72f7985941bee4b03c534d97ff96bc6Michel Dänzer stImage->base.Height); 64701397a66c77f8ebfe78b90ace59c095194a290cfJosé Fonseca if(stImage->transfer) 64801397a66c77f8ebfe78b90ace59c095194a290cfJosé Fonseca dstRowStride = stImage->transfer->stride; 64924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 65024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian else { 65124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian /* Allocate regular memory and store the image there temporarily. */ 652b6bdafdf2cf1110b4a5ca7cf9e1c3dcb124b800fBrian Paul if (_mesa_is_format_compressed(texImage->TexFormat)) { 65335efc6a1b3e3dada2cf9bd3a503c1b84f4bcb7f5Brian Paul sizeInBytes = _mesa_format_image_size(texImage->TexFormat, 65435efc6a1b3e3dada2cf9bd3a503c1b84f4bcb7f5Brian Paul texImage->Width, 65535efc6a1b3e3dada2cf9bd3a503c1b84f4bcb7f5Brian Paul texImage->Height, 65635efc6a1b3e3dada2cf9bd3a503c1b84f4bcb7f5Brian Paul texImage->Depth); 657253e7fee5dc7f0872987b214a6fa162db5e2aa19Brian Paul dstRowStride = _mesa_format_row_stride(texImage->TexFormat, width); 65824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian assert(dims != 3); 65924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 66024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian else { 66124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian dstRowStride = postConvWidth * texelBytes; 66224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian sizeInBytes = depth * dstRowStride * postConvHeight; 66324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 66424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 6658d6ef125ac6044438db5b89d6d310ccfc4b8140aBrian Paul texImage->Data = _mesa_align_malloc(sizeInBytes, 16); 66624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 66724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 6682a39dbe7364af5444b1eb43650dfc31ed09257dcBrian Paul if (!texImage->Data) { 6692a39dbe7364af5444b1eb43650dfc31ed09257dcBrian Paul _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage"); 6702a39dbe7364af5444b1eb43650dfc31ed09257dcBrian Paul return; 6712a39dbe7364af5444b1eb43650dfc31ed09257dcBrian Paul } 6722a39dbe7364af5444b1eb43650dfc31ed09257dcBrian Paul 673cfa1a0a609daefffc6f8c4087ed0bc34c2665ef4Brian Paul if (!pixels) 674cfa1a0a609daefffc6f8c4087ed0bc34c2665ef4Brian Paul goto done; 675cfa1a0a609daefffc6f8c4087ed0bc34c2665ef4Brian Paul 67624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian DBG("Upload image %dx%dx%d row_len %x pitch %x\n", 67724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian width, height, depth, width * texelBytes, dstRowStride); 67824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 67924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian /* Copy data. Would like to know when it's ok for us to eg. use 68024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * the blitter to copy. Or, use the hardware to do the format 68124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * conversion and copy: 68224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 68355ed2a73653fb2fb9dee36c729c09177df2d5b4eJakob Bornecrantz if (compressed_src) { 684eea6a7639f767b1d30b6ef1f91a9c49e3f3b78f0Luca Barbieri const GLuint srcImageStride = _mesa_format_row_stride(texImage->TexFormat, width); 685eea6a7639f767b1d30b6ef1f91a9c49e3f3b78f0Luca Barbieri if(dstRowStride == srcImageStride) 686eea6a7639f767b1d30b6ef1f91a9c49e3f3b78f0Luca Barbieri memcpy(texImage->Data, pixels, imageSize); 687eea6a7639f767b1d30b6ef1f91a9c49e3f3b78f0Luca Barbieri else 688eea6a7639f767b1d30b6ef1f91a9c49e3f3b78f0Luca Barbieri { 689eea6a7639f767b1d30b6ef1f91a9c49e3f3b78f0Luca Barbieri char *dst = texImage->Data; 690eea6a7639f767b1d30b6ef1f91a9c49e3f3b78f0Luca Barbieri const char *src = pixels; 6919328f3a670993167d7fb9a590f9e712467e77c7cLuca Barbieri GLuint i, bw, bh, lines; 6929328f3a670993167d7fb9a590f9e712467e77c7cLuca Barbieri _mesa_get_format_block_size(texImage->TexFormat, &bw, &bh); 6939328f3a670993167d7fb9a590f9e712467e77c7cLuca Barbieri lines = (height + bh - 1) / bh; 694eea6a7639f767b1d30b6ef1f91a9c49e3f3b78f0Luca Barbieri 6959328f3a670993167d7fb9a590f9e712467e77c7cLuca Barbieri for(i = 0; i < lines; ++i) 696eea6a7639f767b1d30b6ef1f91a9c49e3f3b78f0Luca Barbieri { 697eea6a7639f767b1d30b6ef1f91a9c49e3f3b78f0Luca Barbieri memcpy(dst, src, srcImageStride); 698eea6a7639f767b1d30b6ef1f91a9c49e3f3b78f0Luca Barbieri dst += dstRowStride; 699eea6a7639f767b1d30b6ef1f91a9c49e3f3b78f0Luca Barbieri src += srcImageStride; 700eea6a7639f767b1d30b6ef1f91a9c49e3f3b78f0Luca Barbieri } 701eea6a7639f767b1d30b6ef1f91a9c49e3f3b78f0Luca Barbieri } 70224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 703753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer else { 704eaca19edbbe7876079aa33d7f75d93601677081bBrian Paul const GLuint srcImageStride = 705eaca19edbbe7876079aa33d7f75d93601677081bBrian Paul _mesa_image_image_stride(unpack, width, height, format, type); 7065facd7986ace899673499f396897469720476799Brian Paul GLint i; 7075823f99d0fbc054b87aeb1bc15d413d3eadd27a8Brian const GLubyte *src = (const GLubyte *) pixels; 708753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer 709d11d903c1b81000d04f859dcc2da41dae024f146Brian Paul for (i = 0; i < depth; i++) { 7106480210b89dc8ae0990c450d27870c7b7930f251Brian Paul if (!_mesa_texstore(ctx, dims, 7116480210b89dc8ae0990c450d27870c7b7930f251Brian Paul texImage->_BaseFormat, 7126480210b89dc8ae0990c450d27870c7b7930f251Brian Paul texImage->TexFormat, 7136480210b89dc8ae0990c450d27870c7b7930f251Brian Paul texImage->Data, 7146480210b89dc8ae0990c450d27870c7b7930f251Brian Paul 0, 0, 0, /* dstX/Y/Zoffset */ 7156480210b89dc8ae0990c450d27870c7b7930f251Brian Paul dstRowStride, 7166480210b89dc8ae0990c450d27870c7b7930f251Brian Paul texImage->ImageOffsets, 7176480210b89dc8ae0990c450d27870c7b7930f251Brian Paul width, height, 1, 7186480210b89dc8ae0990c450d27870c7b7930f251Brian Paul format, type, src, unpack)) { 719753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage"); 720753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer } 721753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer 722d11d903c1b81000d04f859dcc2da41dae024f146Brian Paul if (stImage->pt && i + 1 < depth) { 723d11d903c1b81000d04f859dcc2da41dae024f146Brian Paul /* unmap this slice */ 724c9ed86a96483063f3d6789ed16645a3dca77d726Keith Whitwell st_texture_image_unmap(ctx->st, stImage); 725d11d903c1b81000d04f859dcc2da41dae024f146Brian Paul /* map next slice of 3D texture */ 726d11d903c1b81000d04f859dcc2da41dae024f146Brian Paul texImage->Data = st_texture_image_map(ctx->st, stImage, i + 1, 72771633abafc935c25da9731bab48c228ceb9b4097Michel Dänzer transfer_usage, 0, 0, 7284617981ec72f7985941bee4b03c534d97ff96bc6Michel Dänzer stImage->base.Width, 7294617981ec72f7985941bee4b03c534d97ff96bc6Michel Dänzer stImage->base.Height); 7305823f99d0fbc054b87aeb1bc15d413d3eadd27a8Brian src += srcImageStride; 731753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer } 732753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer } 73324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 73424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 73508d39251a79a964e4a3ac0d7d8a397c2b66a0808Brian Pauldone: 73624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian _mesa_unmap_teximage_pbo(ctx, unpack); 73724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 73855ed2a73653fb2fb9dee36c729c09177df2d5b4eJakob Bornecrantz if (stImage->pt && texImage->Data) { 739c9ed86a96483063f3d6789ed16645a3dca77d726Keith Whitwell st_texture_image_unmap(ctx->st, stImage); 74024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian texImage->Data = NULL; 74124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 74224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 74324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 74424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 74524df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void 74624df8f895fe8807aa2ba058e71bd40adfc01d21eBrianst_TexImage3D(GLcontext * ctx, 7474e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul GLenum target, GLint level, 7484e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul GLint internalFormat, 7494e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul GLint width, GLint height, GLint depth, 7504e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul GLint border, 7514e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul GLenum format, GLenum type, const void *pixels, 7524e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul const struct gl_pixelstore_attrib *unpack, 7534e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul struct gl_texture_object *texObj, 7544e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul struct gl_texture_image *texImage) 75524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 7565facd7986ace899673499f396897469720476799Brian Paul st_TexImage(ctx, 3, target, level, internalFormat, width, height, depth, 7575facd7986ace899673499f396897469720476799Brian Paul border, format, type, pixels, unpack, texObj, texImage, 7585facd7986ace899673499f396897469720476799Brian Paul 0, GL_FALSE); 75924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 76024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 76124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 76224df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void 76324df8f895fe8807aa2ba058e71bd40adfc01d21eBrianst_TexImage2D(GLcontext * ctx, 7644e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul GLenum target, GLint level, 7654e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul GLint internalFormat, 7664e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul GLint width, GLint height, GLint border, 7674e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul GLenum format, GLenum type, const void *pixels, 7684e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul const struct gl_pixelstore_attrib *unpack, 7694e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul struct gl_texture_object *texObj, 7704e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul struct gl_texture_image *texImage) 77124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 7725facd7986ace899673499f396897469720476799Brian Paul st_TexImage(ctx, 2, target, level, internalFormat, width, height, 1, border, 7735facd7986ace899673499f396897469720476799Brian Paul format, type, pixels, unpack, texObj, texImage, 0, GL_FALSE); 77424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 77524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 77624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 77724df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void 77824df8f895fe8807aa2ba058e71bd40adfc01d21eBrianst_TexImage1D(GLcontext * ctx, 7794e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul GLenum target, GLint level, 7804e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul GLint internalFormat, 7814e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul GLint width, GLint border, 7824e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul GLenum format, GLenum type, const void *pixels, 7834e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul const struct gl_pixelstore_attrib *unpack, 7844e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul struct gl_texture_object *texObj, 7854e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul struct gl_texture_image *texImage) 78624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 7875facd7986ace899673499f396897469720476799Brian Paul st_TexImage(ctx, 1, target, level, internalFormat, width, 1, 1, border, 7885facd7986ace899673499f396897469720476799Brian Paul format, type, pixels, unpack, texObj, texImage, 0, GL_FALSE); 78924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 79024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 79124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 79224df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void 7934e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paulst_CompressedTexImage2D(GLcontext *ctx, GLenum target, GLint level, 7944e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul GLint internalFormat, 7954e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul GLint width, GLint height, GLint border, 7964e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul GLsizei imageSize, const GLvoid *data, 7974e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul struct gl_texture_object *texObj, 7984e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul struct gl_texture_image *texImage) 79924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 8005facd7986ace899673499f396897469720476799Brian Paul st_TexImage(ctx, 2, target, level, internalFormat, width, height, 1, border, 8015facd7986ace899673499f396897469720476799Brian Paul 0, 0, data, &ctx->Unpack, texObj, texImage, imageSize, GL_TRUE); 80224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 80324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 80424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 80551b339af2e8b80575a24bb9146f031c9605180bbBrian Paul 80651b339af2e8b80575a24bb9146f031c9605180bbBrian Paul/** 80751b339af2e8b80575a24bb9146f031c9605180bbBrian Paul * glGetTexImage() helper: decompress a compressed texture by rendering 80851b339af2e8b80575a24bb9146f031c9605180bbBrian Paul * a textured quad. Store the results in the user's buffer. 80951b339af2e8b80575a24bb9146f031c9605180bbBrian Paul */ 81051b339af2e8b80575a24bb9146f031c9605180bbBrian Paulstatic void 81151b339af2e8b80575a24bb9146f031c9605180bbBrian Pauldecompress_with_blit(GLcontext * ctx, GLenum target, GLint level, 81251b339af2e8b80575a24bb9146f031c9605180bbBrian Paul GLenum format, GLenum type, GLvoid *pixels, 81351b339af2e8b80575a24bb9146f031c9605180bbBrian Paul struct gl_texture_object *texObj, 81451b339af2e8b80575a24bb9146f031c9605180bbBrian Paul struct gl_texture_image *texImage) 81551b339af2e8b80575a24bb9146f031c9605180bbBrian Paul{ 81651b339af2e8b80575a24bb9146f031c9605180bbBrian Paul struct pipe_screen *screen = ctx->st->pipe->screen; 81751b339af2e8b80575a24bb9146f031c9605180bbBrian Paul struct st_texture_image *stImage = st_texture_image(texImage); 81851b339af2e8b80575a24bb9146f031c9605180bbBrian Paul const GLuint width = texImage->Width; 81951b339af2e8b80575a24bb9146f031c9605180bbBrian Paul const GLuint height = texImage->Height; 82051b339af2e8b80575a24bb9146f031c9605180bbBrian Paul struct pipe_surface *dst_surface; 82151b339af2e8b80575a24bb9146f031c9605180bbBrian Paul struct pipe_texture *dst_texture; 82251b339af2e8b80575a24bb9146f031c9605180bbBrian Paul struct pipe_transfer *tex_xfer; 82351b339af2e8b80575a24bb9146f031c9605180bbBrian Paul 82451b339af2e8b80575a24bb9146f031c9605180bbBrian Paul /* create temp / dest surface */ 82551b339af2e8b80575a24bb9146f031c9605180bbBrian Paul if (!util_create_rgba_surface(screen, width, height, 82651b339af2e8b80575a24bb9146f031c9605180bbBrian Paul &dst_texture, &dst_surface)) { 82751b339af2e8b80575a24bb9146f031c9605180bbBrian Paul _mesa_problem(ctx, "util_create_rgba_surface() failed " 82851b339af2e8b80575a24bb9146f031c9605180bbBrian Paul "in decompress_with_blit()"); 82951b339af2e8b80575a24bb9146f031c9605180bbBrian Paul return; 83051b339af2e8b80575a24bb9146f031c9605180bbBrian Paul } 83151b339af2e8b80575a24bb9146f031c9605180bbBrian Paul 83251b339af2e8b80575a24bb9146f031c9605180bbBrian Paul /* blit/render/decompress */ 83351b339af2e8b80575a24bb9146f031c9605180bbBrian Paul util_blit_pixels_tex(ctx->st->blit, 83451b339af2e8b80575a24bb9146f031c9605180bbBrian Paul stImage->pt, /* pipe_texture (src) */ 83551b339af2e8b80575a24bb9146f031c9605180bbBrian Paul 0, 0, /* src x0, y0 */ 83651b339af2e8b80575a24bb9146f031c9605180bbBrian Paul width, height, /* src x1, y1 */ 83751b339af2e8b80575a24bb9146f031c9605180bbBrian Paul dst_surface, /* pipe_surface (dst) */ 83851b339af2e8b80575a24bb9146f031c9605180bbBrian Paul 0, 0, /* dst x0, y0 */ 83951b339af2e8b80575a24bb9146f031c9605180bbBrian Paul width, height, /* dst x1, y1 */ 84051b339af2e8b80575a24bb9146f031c9605180bbBrian Paul 0.0, /* z */ 84151b339af2e8b80575a24bb9146f031c9605180bbBrian Paul PIPE_TEX_MIPFILTER_NEAREST); 84251b339af2e8b80575a24bb9146f031c9605180bbBrian Paul 84351b339af2e8b80575a24bb9146f031c9605180bbBrian Paul /* map the dst_surface so we can read from it */ 844e50dd26ca6d0eb0d0f97c2780020ea16e3d4a687Thomas Hellstrom tex_xfer = st_cond_flush_get_tex_transfer(st_context(ctx), 845e50dd26ca6d0eb0d0f97c2780020ea16e3d4a687Thomas Hellstrom dst_texture, 0, 0, 0, 846e50dd26ca6d0eb0d0f97c2780020ea16e3d4a687Thomas Hellstrom PIPE_TRANSFER_READ, 847e50dd26ca6d0eb0d0f97c2780020ea16e3d4a687Thomas Hellstrom 0, 0, width, height); 84851b339af2e8b80575a24bb9146f031c9605180bbBrian Paul 8491b448c7a5cafa68eeead2a4c45f4362a9883383bBrian Paul pixels = _mesa_map_pbo_dest(ctx, &ctx->Pack, pixels); 85051b339af2e8b80575a24bb9146f031c9605180bbBrian Paul 8517b24e58a0ca571d6230ef5076ea352253b81fe6eBrian Paul /* copy/pack data into user buffer */ 8527b24e58a0ca571d6230ef5076ea352253b81fe6eBrian Paul if (st_equal_formats(stImage->pt->format, format, type)) { 8537b24e58a0ca571d6230ef5076ea352253b81fe6eBrian Paul /* memcpy */ 854b1ed72ebe2599ec178f51d86fd42f26486b9a19bMichal Krol const uint bytesPerRow = width * util_format_get_blocksize(stImage->pt->format); 8557b24e58a0ca571d6230ef5076ea352253b81fe6eBrian Paul ubyte *map = screen->transfer_map(screen, tex_xfer); 8567b24e58a0ca571d6230ef5076ea352253b81fe6eBrian Paul GLuint row; 8577b24e58a0ca571d6230ef5076ea352253b81fe6eBrian Paul for (row = 0; row < height; row++) { 8587b24e58a0ca571d6230ef5076ea352253b81fe6eBrian Paul GLvoid *dest = _mesa_image_address2d(&ctx->Pack, pixels, width, 8597b24e58a0ca571d6230ef5076ea352253b81fe6eBrian Paul height, format, type, row, 0); 8607b24e58a0ca571d6230ef5076ea352253b81fe6eBrian Paul memcpy(dest, map, bytesPerRow); 8617b24e58a0ca571d6230ef5076ea352253b81fe6eBrian Paul map += tex_xfer->stride; 8627b24e58a0ca571d6230ef5076ea352253b81fe6eBrian Paul } 8637b24e58a0ca571d6230ef5076ea352253b81fe6eBrian Paul screen->transfer_unmap(screen, tex_xfer); 86451b339af2e8b80575a24bb9146f031c9605180bbBrian Paul } 8657b24e58a0ca571d6230ef5076ea352253b81fe6eBrian Paul else { 8667b24e58a0ca571d6230ef5076ea352253b81fe6eBrian Paul /* format translation via floats */ 8677b24e58a0ca571d6230ef5076ea352253b81fe6eBrian Paul GLuint row; 8687b24e58a0ca571d6230ef5076ea352253b81fe6eBrian Paul for (row = 0; row < height; row++) { 8697b24e58a0ca571d6230ef5076ea352253b81fe6eBrian Paul const GLbitfield transferOps = 0x0; /* bypassed for glGetTexImage() */ 8707b24e58a0ca571d6230ef5076ea352253b81fe6eBrian Paul GLfloat rgba[4 * MAX_WIDTH]; 8717b24e58a0ca571d6230ef5076ea352253b81fe6eBrian Paul GLvoid *dest = _mesa_image_address2d(&ctx->Pack, pixels, width, 8727b24e58a0ca571d6230ef5076ea352253b81fe6eBrian Paul height, format, type, row, 0); 8737b24e58a0ca571d6230ef5076ea352253b81fe6eBrian Paul 874b02ef740b90029bc40629e5b81270a8cf77101d3Keith Whitwell if (ST_DEBUG & DEBUG_FALLBACK) 875b02ef740b90029bc40629e5b81270a8cf77101d3Keith Whitwell debug_printf("%s: fallback format translation\n", __FUNCTION__); 876b02ef740b90029bc40629e5b81270a8cf77101d3Keith Whitwell 8777b24e58a0ca571d6230ef5076ea352253b81fe6eBrian Paul /* get float[4] rgba row from surface */ 8787b24e58a0ca571d6230ef5076ea352253b81fe6eBrian Paul pipe_get_tile_rgba(tex_xfer, 0, row, width, 1, rgba); 8797b24e58a0ca571d6230ef5076ea352253b81fe6eBrian Paul 8807b24e58a0ca571d6230ef5076ea352253b81fe6eBrian Paul _mesa_pack_rgba_span_float(ctx, width, (GLfloat (*)[4]) rgba, format, 8817b24e58a0ca571d6230ef5076ea352253b81fe6eBrian Paul type, dest, &ctx->Pack, transferOps); 8827b24e58a0ca571d6230ef5076ea352253b81fe6eBrian Paul } 8837b24e58a0ca571d6230ef5076ea352253b81fe6eBrian Paul } 8847b24e58a0ca571d6230ef5076ea352253b81fe6eBrian Paul 8851b448c7a5cafa68eeead2a4c45f4362a9883383bBrian Paul _mesa_unmap_pbo_dest(ctx, &ctx->Pack); 88651b339af2e8b80575a24bb9146f031c9605180bbBrian Paul 88751b339af2e8b80575a24bb9146f031c9605180bbBrian Paul /* destroy the temp / dest surface */ 88851b339af2e8b80575a24bb9146f031c9605180bbBrian Paul util_destroy_rgba_surface(dst_texture, dst_surface); 88951b339af2e8b80575a24bb9146f031c9605180bbBrian Paul} 89051b339af2e8b80575a24bb9146f031c9605180bbBrian Paul 89151b339af2e8b80575a24bb9146f031c9605180bbBrian Paul 89251b339af2e8b80575a24bb9146f031c9605180bbBrian Paul 89324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian/** 89424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * Need to map texture image into memory before copying image data, 89524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * then unmap it. 89624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 89724df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void 89824df8f895fe8807aa2ba058e71bd40adfc01d21eBrianst_get_tex_image(GLcontext * ctx, GLenum target, GLint level, 89924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLenum format, GLenum type, GLvoid * pixels, 90024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian struct gl_texture_object *texObj, 90151b339af2e8b80575a24bb9146f031c9605180bbBrian Paul struct gl_texture_image *texImage, GLboolean compressed_dst) 90224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 90324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian struct st_texture_image *stImage = st_texture_image(texImage); 904eaca19edbbe7876079aa33d7f75d93601677081bBrian Paul const GLuint dstImageStride = 905eaca19edbbe7876079aa33d7f75d93601677081bBrian Paul _mesa_image_image_stride(&ctx->Pack, texImage->Width, texImage->Height, 906eaca19edbbe7876079aa33d7f75d93601677081bBrian Paul format, type); 9075facd7986ace899673499f396897469720476799Brian Paul GLuint depth, i; 9085823f99d0fbc054b87aeb1bc15d413d3eadd27a8Brian GLubyte *dest; 90924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 91051b339af2e8b80575a24bb9146f031c9605180bbBrian Paul if (stImage->pt && 9113400b668e35469d5dbba515e3a8b9d775fd2eff5Michal Krol util_format_is_compressed(stImage->pt->format) && 91251b339af2e8b80575a24bb9146f031c9605180bbBrian Paul !compressed_dst) { 91351b339af2e8b80575a24bb9146f031c9605180bbBrian Paul /* Need to decompress the texture. 91451b339af2e8b80575a24bb9146f031c9605180bbBrian Paul * We'll do this by rendering a textured quad. 91551b339af2e8b80575a24bb9146f031c9605180bbBrian Paul * Note that we only expect RGBA formats (no Z/depth formats). 91651b339af2e8b80575a24bb9146f031c9605180bbBrian Paul */ 91751b339af2e8b80575a24bb9146f031c9605180bbBrian Paul decompress_with_blit(ctx, target, level, format, type, pixels, 91851b339af2e8b80575a24bb9146f031c9605180bbBrian Paul texObj, texImage); 91951b339af2e8b80575a24bb9146f031c9605180bbBrian Paul return; 92051b339af2e8b80575a24bb9146f031c9605180bbBrian Paul } 92151b339af2e8b80575a24bb9146f031c9605180bbBrian Paul 92224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian /* Map */ 923753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer if (stImage->pt) { 92424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian /* Image is stored in hardware format in a buffer managed by the 92524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * kernel. Need to explicitly map and unmap it. 92624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 9274ed1de8b84b587d2be0c0e4ecb6b5f421195f562José Fonseca unsigned face = _mesa_tex_target_to_face(target); 9289b75627fab5bf2ea90f27ddd31b60c54895f6de6Thomas Hellstrom 9294ed1de8b84b587d2be0c0e4ecb6b5f421195f562José Fonseca st_teximage_flush_before_map(ctx->st, stImage->pt, face, level, 9309b75627fab5bf2ea90f27ddd31b60c54895f6de6Thomas Hellstrom PIPE_TRANSFER_READ); 9319b75627fab5bf2ea90f27ddd31b60c54895f6de6Thomas Hellstrom 932c9ed86a96483063f3d6789ed16645a3dca77d726Keith Whitwell texImage->Data = st_texture_image_map(ctx->st, stImage, 0, 9334617981ec72f7985941bee4b03c534d97ff96bc6Michel Dänzer PIPE_TRANSFER_READ, 0, 0, 9344617981ec72f7985941bee4b03c534d97ff96bc6Michel Dänzer stImage->base.Width, 9354617981ec72f7985941bee4b03c534d97ff96bc6Michel Dänzer stImage->base.Height); 936b1ed72ebe2599ec178f51d86fd42f26486b9a19bMichal Krol texImage->RowStride = stImage->transfer->stride / util_format_get_blocksize(stImage->pt->format); 93724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 93824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian else { 93924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian /* Otherwise, the image should actually be stored in 940753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer * texImage->Data. This is pretty confusing for 94124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * everybody, I'd much prefer to separate the two functions of 94224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * texImage->Data - storage for texture images in main memory 94324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * and access (ie mappings) of images. In other words, we'd 94424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * create a new texImage->Map field and leave Data simply for 94524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * storage. 94624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 947753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer assert(texImage->Data); 94824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 94924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 950753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer depth = texImage->Depth; 951753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer texImage->Depth = 1; 95224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 9535823f99d0fbc054b87aeb1bc15d413d3eadd27a8Brian dest = (GLubyte *) pixels; 9545823f99d0fbc054b87aeb1bc15d413d3eadd27a8Brian 955d11d903c1b81000d04f859dcc2da41dae024f146Brian Paul for (i = 0; i < depth; i++) { 95651b339af2e8b80575a24bb9146f031c9605180bbBrian Paul if (compressed_dst) { 9575823f99d0fbc054b87aeb1bc15d413d3eadd27a8Brian _mesa_get_compressed_teximage(ctx, target, level, dest, 958753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer texObj, texImage); 9595facd7986ace899673499f396897469720476799Brian Paul } 9605facd7986ace899673499f396897469720476799Brian Paul else { 9615823f99d0fbc054b87aeb1bc15d413d3eadd27a8Brian _mesa_get_teximage(ctx, target, level, format, type, dest, 962753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer texObj, texImage); 963753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer } 964753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer 965d11d903c1b81000d04f859dcc2da41dae024f146Brian Paul if (stImage->pt && i + 1 < depth) { 966d11d903c1b81000d04f859dcc2da41dae024f146Brian Paul /* unmap this slice */ 967c9ed86a96483063f3d6789ed16645a3dca77d726Keith Whitwell st_texture_image_unmap(ctx->st, stImage); 968d11d903c1b81000d04f859dcc2da41dae024f146Brian Paul /* map next slice of 3D texture */ 969d11d903c1b81000d04f859dcc2da41dae024f146Brian Paul texImage->Data = st_texture_image_map(ctx->st, stImage, i + 1, 9704617981ec72f7985941bee4b03c534d97ff96bc6Michel Dänzer PIPE_TRANSFER_READ, 0, 0, 9714617981ec72f7985941bee4b03c534d97ff96bc6Michel Dänzer stImage->base.Width, 9724617981ec72f7985941bee4b03c534d97ff96bc6Michel Dänzer stImage->base.Height); 9735823f99d0fbc054b87aeb1bc15d413d3eadd27a8Brian dest += dstImageStride; 974753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer } 97524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 976753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer 977753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer texImage->Depth = depth; 97824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 97924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian /* Unmap */ 980753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer if (stImage->pt) { 981c9ed86a96483063f3d6789ed16645a3dca77d726Keith Whitwell st_texture_image_unmap(ctx->st, stImage); 982753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer texImage->Data = NULL; 98324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 98424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 98524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 98624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 98724df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void 98824df8f895fe8807aa2ba058e71bd40adfc01d21eBrianst_GetTexImage(GLcontext * ctx, GLenum target, GLint level, 9894e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul GLenum format, GLenum type, GLvoid * pixels, 9904e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul struct gl_texture_object *texObj, 9914e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul struct gl_texture_image *texImage) 99224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 9935facd7986ace899673499f396897469720476799Brian Paul st_get_tex_image(ctx, target, level, format, type, pixels, texObj, texImage, 9945facd7986ace899673499f396897469720476799Brian Paul GL_FALSE); 99524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 99624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 99724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 99824df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void 99924df8f895fe8807aa2ba058e71bd40adfc01d21eBrianst_GetCompressedTexImage(GLcontext *ctx, GLenum target, GLint level, 10004e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul GLvoid *pixels, 100147bf26845712bea756526fc159bdb355ceaef9c2Brian Paul struct gl_texture_object *texObj, 100247bf26845712bea756526fc159bdb355ceaef9c2Brian Paul struct gl_texture_image *texImage) 100324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 10045facd7986ace899673499f396897469720476799Brian Paul st_get_tex_image(ctx, target, level, 0, 0, pixels, texObj, texImage, 10055facd7986ace899673499f396897469720476799Brian Paul GL_TRUE); 100624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 100724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 100824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 100924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 101024df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void 10115facd7986ace899673499f396897469720476799Brian Paulst_TexSubimage(GLcontext *ctx, GLint dims, GLenum target, GLint level, 10124e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul GLint xoffset, GLint yoffset, GLint zoffset, 10134e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul GLint width, GLint height, GLint depth, 10144e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul GLenum format, GLenum type, const void *pixels, 10154e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul const struct gl_pixelstore_attrib *packing, 10164e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul struct gl_texture_object *texObj, 10174e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul struct gl_texture_image *texImage) 101824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 101955ed2a73653fb2fb9dee36c729c09177df2d5b4eJakob Bornecrantz struct pipe_screen *screen = ctx->st->pipe->screen; 102024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian struct st_texture_image *stImage = st_texture_image(texImage); 102124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLuint dstRowStride; 1022eaca19edbbe7876079aa33d7f75d93601677081bBrian Paul const GLuint srcImageStride = 1023eaca19edbbe7876079aa33d7f75d93601677081bBrian Paul _mesa_image_image_stride(packing, width, height, format, type); 10245facd7986ace899673499f396897469720476799Brian Paul GLint i; 10255823f99d0fbc054b87aeb1bc15d413d3eadd27a8Brian const GLubyte *src; 1026a7427b0f7b2325b8dcc560d57cb894df25ebef93Brian Paul /* init to silence warning only: */ 1027a7427b0f7b2325b8dcc560d57cb894df25ebef93Brian Paul enum pipe_transfer_usage transfer_usage = PIPE_TRANSFER_WRITE; 102824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 102924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian DBG("%s target %s level %d offset %d,%d %dx%d\n", __FUNCTION__, 103024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian _mesa_lookup_enum_by_nr(target), 103124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian level, xoffset, yoffset, width, height); 103224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 103324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian pixels = 103424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian _mesa_validate_pbo_teximage(ctx, dims, width, height, depth, format, 103524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian type, pixels, packing, "glTexSubImage2D"); 103624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian if (!pixels) 103724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian return; 103824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 103955ed2a73653fb2fb9dee36c729c09177df2d5b4eJakob Bornecrantz /* See if we can do texture compression with a blit/render. 104055ed2a73653fb2fb9dee36c729c09177df2d5b4eJakob Bornecrantz */ 104155ed2a73653fb2fb9dee36c729c09177df2d5b4eJakob Bornecrantz if (!ctx->Mesa_DXTn && 104292863109af05acdb4ee5e42141c83ab0f18b7f88Brian Paul _mesa_is_format_compressed(texImage->TexFormat) && 104355ed2a73653fb2fb9dee36c729c09177df2d5b4eJakob Bornecrantz screen->is_format_supported(screen, 104455ed2a73653fb2fb9dee36c729c09177df2d5b4eJakob Bornecrantz stImage->pt->format, 104555ed2a73653fb2fb9dee36c729c09177df2d5b4eJakob Bornecrantz stImage->pt->target, 104655ed2a73653fb2fb9dee36c729c09177df2d5b4eJakob Bornecrantz PIPE_TEXTURE_USAGE_RENDER_TARGET, 0)) { 104755ed2a73653fb2fb9dee36c729c09177df2d5b4eJakob Bornecrantz if (compress_with_blit(ctx, target, level, 104855ed2a73653fb2fb9dee36c729c09177df2d5b4eJakob Bornecrantz xoffset, yoffset, zoffset, 104955ed2a73653fb2fb9dee36c729c09177df2d5b4eJakob Bornecrantz width, height, depth, 105055ed2a73653fb2fb9dee36c729c09177df2d5b4eJakob Bornecrantz format, type, pixels, packing, texImage)) { 1051f989390af6f827d1ea36560381340148811836f3Jakob Bornecrantz goto done; 105255ed2a73653fb2fb9dee36c729c09177df2d5b4eJakob Bornecrantz } 105355ed2a73653fb2fb9dee36c729c09177df2d5b4eJakob Bornecrantz } 105455ed2a73653fb2fb9dee36c729c09177df2d5b4eJakob Bornecrantz 105524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian /* Map buffer if necessary. Need to lock to prevent other contexts 105624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * from uploading the buffer under us. 105724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 1058753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer if (stImage->pt) { 10594ed1de8b84b587d2be0c0e4ecb6b5f421195f562José Fonseca unsigned face = _mesa_tex_target_to_face(target); 10604ed1de8b84b587d2be0c0e4ecb6b5f421195f562José Fonseca 106171633abafc935c25da9731bab48c228ceb9b4097Michel Dänzer if (format == GL_DEPTH_COMPONENT && 10620bed834be4a174d20b31a6cbcf066774bf749929Michal Krol util_format_is_depth_and_stencil(stImage->pt->format)) 106371633abafc935c25da9731bab48c228ceb9b4097Michel Dänzer transfer_usage = PIPE_TRANSFER_READ_WRITE; 106471633abafc935c25da9731bab48c228ceb9b4097Michel Dänzer else 106571633abafc935c25da9731bab48c228ceb9b4097Michel Dänzer transfer_usage = PIPE_TRANSFER_WRITE; 106671633abafc935c25da9731bab48c228ceb9b4097Michel Dänzer 10674ed1de8b84b587d2be0c0e4ecb6b5f421195f562José Fonseca st_teximage_flush_before_map(ctx->st, stImage->pt, face, level, 106871633abafc935c25da9731bab48c228ceb9b4097Michel Dänzer transfer_usage); 1069c9ed86a96483063f3d6789ed16645a3dca77d726Keith Whitwell texImage->Data = st_texture_image_map(ctx->st, stImage, zoffset, 107071633abafc935c25da9731bab48c228ceb9b4097Michel Dänzer transfer_usage, 10714617981ec72f7985941bee4b03c534d97ff96bc6Michel Dänzer xoffset, yoffset, 10729e84e7def152aa8080da59a78795d6434e687403Jakob Bornecrantz width, height); 1073753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer } 1074753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer 10759b44f5a7550d8ede2eda763770e927df4c15cc8eBrian Paul if (!texImage->Data) { 10769b44f5a7550d8ede2eda763770e927df4c15cc8eBrian Paul _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage"); 107708d39251a79a964e4a3ac0d7d8a397c2b66a0808Brian Paul goto done; 10789b44f5a7550d8ede2eda763770e927df4c15cc8eBrian Paul } 10799b44f5a7550d8ede2eda763770e927df4c15cc8eBrian Paul 10805823f99d0fbc054b87aeb1bc15d413d3eadd27a8Brian src = (const GLubyte *) pixels; 1081d7b7b63bd7cca80e99ad9701f8b56ee365053647Michal Krol dstRowStride = stImage->transfer->stride; 10825823f99d0fbc054b87aeb1bc15d413d3eadd27a8Brian 1083d11d903c1b81000d04f859dcc2da41dae024f146Brian Paul for (i = 0; i < depth; i++) { 10846480210b89dc8ae0990c450d27870c7b7930f251Brian Paul if (!_mesa_texstore(ctx, dims, texImage->_BaseFormat, 10856480210b89dc8ae0990c450d27870c7b7930f251Brian Paul texImage->TexFormat, 10866480210b89dc8ae0990c450d27870c7b7930f251Brian Paul texImage->Data, 10876480210b89dc8ae0990c450d27870c7b7930f251Brian Paul 0, 0, 0, 10886480210b89dc8ae0990c450d27870c7b7930f251Brian Paul dstRowStride, 10896480210b89dc8ae0990c450d27870c7b7930f251Brian Paul texImage->ImageOffsets, 10906480210b89dc8ae0990c450d27870c7b7930f251Brian Paul width, height, 1, 10916480210b89dc8ae0990c450d27870c7b7930f251Brian Paul format, type, src, packing)) { 10929b44f5a7550d8ede2eda763770e927df4c15cc8eBrian Paul _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage"); 1093753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer } 1094753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer 1095d11d903c1b81000d04f859dcc2da41dae024f146Brian Paul if (stImage->pt && i + 1 < depth) { 1096d11d903c1b81000d04f859dcc2da41dae024f146Brian Paul /* unmap this slice */ 1097c9ed86a96483063f3d6789ed16645a3dca77d726Keith Whitwell st_texture_image_unmap(ctx->st, stImage); 1098d11d903c1b81000d04f859dcc2da41dae024f146Brian Paul /* map next slice of 3D texture */ 1099d11d903c1b81000d04f859dcc2da41dae024f146Brian Paul texImage->Data = st_texture_image_map(ctx->st, stImage, 1100d11d903c1b81000d04f859dcc2da41dae024f146Brian Paul zoffset + i + 1, 110171633abafc935c25da9731bab48c228ceb9b4097Michel Dänzer transfer_usage, 11024617981ec72f7985941bee4b03c534d97ff96bc6Michel Dänzer xoffset, yoffset, 11039e84e7def152aa8080da59a78795d6434e687403Jakob Bornecrantz width, height); 11045823f99d0fbc054b87aeb1bc15d413d3eadd27a8Brian src += srcImageStride; 1105753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer } 110624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 110724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 110808d39251a79a964e4a3ac0d7d8a397c2b66a0808Brian Pauldone: 110924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian _mesa_unmap_teximage_pbo(ctx, packing); 111024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 11111e414df894fc70b7024eb38c812e582336014974Michel Dänzer if (stImage->pt && texImage->Data) { 1112c9ed86a96483063f3d6789ed16645a3dca77d726Keith Whitwell st_texture_image_unmap(ctx->st, stImage); 111324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian texImage->Data = NULL; 111424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 111524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 111624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 111724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 111824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 111924df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void 11205facd7986ace899673499f396897469720476799Brian Paulst_TexSubImage3D(GLcontext *ctx, GLenum target, GLint level, 11215facd7986ace899673499f396897469720476799Brian Paul GLint xoffset, GLint yoffset, GLint zoffset, 11225facd7986ace899673499f396897469720476799Brian Paul GLsizei width, GLsizei height, GLsizei depth, 11235facd7986ace899673499f396897469720476799Brian Paul GLenum format, GLenum type, const GLvoid *pixels, 11245facd7986ace899673499f396897469720476799Brian Paul const struct gl_pixelstore_attrib *packing, 11255facd7986ace899673499f396897469720476799Brian Paul struct gl_texture_object *texObj, 11265facd7986ace899673499f396897469720476799Brian Paul struct gl_texture_image *texImage) 112724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 11285facd7986ace899673499f396897469720476799Brian Paul st_TexSubimage(ctx, 3, target, level, xoffset, yoffset, zoffset, 11295facd7986ace899673499f396897469720476799Brian Paul width, height, depth, format, type, 11305facd7986ace899673499f396897469720476799Brian Paul pixels, packing, texObj, texImage); 113124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 113224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 113324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 113424df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void 11355facd7986ace899673499f396897469720476799Brian Paulst_TexSubImage2D(GLcontext *ctx, GLenum target, GLint level, 11365facd7986ace899673499f396897469720476799Brian Paul GLint xoffset, GLint yoffset, 11375facd7986ace899673499f396897469720476799Brian Paul GLsizei width, GLsizei height, 11385facd7986ace899673499f396897469720476799Brian Paul GLenum format, GLenum type, const GLvoid * pixels, 11395facd7986ace899673499f396897469720476799Brian Paul const struct gl_pixelstore_attrib *packing, 11405facd7986ace899673499f396897469720476799Brian Paul struct gl_texture_object *texObj, 11415facd7986ace899673499f396897469720476799Brian Paul struct gl_texture_image *texImage) 114224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 11435facd7986ace899673499f396897469720476799Brian Paul st_TexSubimage(ctx, 2, target, level, xoffset, yoffset, 0, 11445facd7986ace899673499f396897469720476799Brian Paul width, height, 1, format, type, 11455facd7986ace899673499f396897469720476799Brian Paul pixels, packing, texObj, texImage); 114624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 114724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 114824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 114924df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void 11505facd7986ace899673499f396897469720476799Brian Paulst_TexSubImage1D(GLcontext *ctx, GLenum target, GLint level, 11515facd7986ace899673499f396897469720476799Brian Paul GLint xoffset, GLsizei width, GLenum format, GLenum type, 11525facd7986ace899673499f396897469720476799Brian Paul const GLvoid * pixels, 11535facd7986ace899673499f396897469720476799Brian Paul const struct gl_pixelstore_attrib *packing, 11545facd7986ace899673499f396897469720476799Brian Paul struct gl_texture_object *texObj, 11555facd7986ace899673499f396897469720476799Brian Paul struct gl_texture_image *texImage) 115624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 11575facd7986ace899673499f396897469720476799Brian Paul st_TexSubimage(ctx, 1, target, level, xoffset, 0, 0, width, 1, 1, 1158b245840b86cf877c9b8d666edf229364a84f1deaBrian format, type, pixels, packing, texObj, texImage); 115924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 116024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 116124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 1162a4fd94a54a75a3418462c30f1240ab50b5f24090Jakob Bornecrantzstatic void 1163578230dbbffbf5317d6002d1023dcd62b57186f5Jakob Bornecrantzst_CompressedTexSubImage1D(GLcontext *ctx, GLenum target, GLint level, 1164578230dbbffbf5317d6002d1023dcd62b57186f5Jakob Bornecrantz GLint xoffset, GLsizei width, 1165578230dbbffbf5317d6002d1023dcd62b57186f5Jakob Bornecrantz GLenum format, 1166578230dbbffbf5317d6002d1023dcd62b57186f5Jakob Bornecrantz GLsizei imageSize, const GLvoid *data, 1167578230dbbffbf5317d6002d1023dcd62b57186f5Jakob Bornecrantz struct gl_texture_object *texObj, 1168578230dbbffbf5317d6002d1023dcd62b57186f5Jakob Bornecrantz struct gl_texture_image *texImage) 1169578230dbbffbf5317d6002d1023dcd62b57186f5Jakob Bornecrantz{ 1170578230dbbffbf5317d6002d1023dcd62b57186f5Jakob Bornecrantz assert(0); 1171578230dbbffbf5317d6002d1023dcd62b57186f5Jakob Bornecrantz} 1172578230dbbffbf5317d6002d1023dcd62b57186f5Jakob Bornecrantz 1173578230dbbffbf5317d6002d1023dcd62b57186f5Jakob Bornecrantz 1174578230dbbffbf5317d6002d1023dcd62b57186f5Jakob Bornecrantzstatic void 1175a4fd94a54a75a3418462c30f1240ab50b5f24090Jakob Bornecrantzst_CompressedTexSubImage2D(GLcontext *ctx, GLenum target, GLint level, 1176a4fd94a54a75a3418462c30f1240ab50b5f24090Jakob Bornecrantz GLint xoffset, GLint yoffset, 1177a4fd94a54a75a3418462c30f1240ab50b5f24090Jakob Bornecrantz GLsizei width, GLint height, 1178a4fd94a54a75a3418462c30f1240ab50b5f24090Jakob Bornecrantz GLenum format, 1179a4fd94a54a75a3418462c30f1240ab50b5f24090Jakob Bornecrantz GLsizei imageSize, const GLvoid *data, 1180a4fd94a54a75a3418462c30f1240ab50b5f24090Jakob Bornecrantz struct gl_texture_object *texObj, 1181a4fd94a54a75a3418462c30f1240ab50b5f24090Jakob Bornecrantz struct gl_texture_image *texImage) 1182a4fd94a54a75a3418462c30f1240ab50b5f24090Jakob Bornecrantz{ 1183a4fd94a54a75a3418462c30f1240ab50b5f24090Jakob Bornecrantz struct st_texture_image *stImage = st_texture_image(texImage); 1184a4fd94a54a75a3418462c30f1240ab50b5f24090Jakob Bornecrantz int srcBlockStride; 1185a4fd94a54a75a3418462c30f1240ab50b5f24090Jakob Bornecrantz int dstBlockStride; 1186a4fd94a54a75a3418462c30f1240ab50b5f24090Jakob Bornecrantz int y; 1187ac400ffce62be47fc77e8d10cabcd39b92b6c627Roland Scheidegger enum pipe_format pformat= stImage->pt->format; 1188a4fd94a54a75a3418462c30f1240ab50b5f24090Jakob Bornecrantz 1189a4fd94a54a75a3418462c30f1240ab50b5f24090Jakob Bornecrantz if (stImage->pt) { 11904ed1de8b84b587d2be0c0e4ecb6b5f421195f562José Fonseca unsigned face = _mesa_tex_target_to_face(target); 11914ed1de8b84b587d2be0c0e4ecb6b5f421195f562José Fonseca 11924ed1de8b84b587d2be0c0e4ecb6b5f421195f562José Fonseca st_teximage_flush_before_map(ctx->st, stImage->pt, face, level, 1193a4fd94a54a75a3418462c30f1240ab50b5f24090Jakob Bornecrantz PIPE_TRANSFER_WRITE); 1194a4fd94a54a75a3418462c30f1240ab50b5f24090Jakob Bornecrantz texImage->Data = st_texture_image_map(ctx->st, stImage, 0, 1195a4fd94a54a75a3418462c30f1240ab50b5f24090Jakob Bornecrantz PIPE_TRANSFER_WRITE, 1196a4fd94a54a75a3418462c30f1240ab50b5f24090Jakob Bornecrantz xoffset, yoffset, 1197a4fd94a54a75a3418462c30f1240ab50b5f24090Jakob Bornecrantz width, height); 1198a4fd94a54a75a3418462c30f1240ab50b5f24090Jakob Bornecrantz 1199b1ed72ebe2599ec178f51d86fd42f26486b9a19bMichal Krol srcBlockStride = util_format_get_stride(pformat, width); 1200a4fd94a54a75a3418462c30f1240ab50b5f24090Jakob Bornecrantz dstBlockStride = stImage->transfer->stride; 1201a4fd94a54a75a3418462c30f1240ab50b5f24090Jakob Bornecrantz } else { 1202a4fd94a54a75a3418462c30f1240ab50b5f24090Jakob Bornecrantz assert(stImage->pt); 1203a4fd94a54a75a3418462c30f1240ab50b5f24090Jakob Bornecrantz /* TODO find good values for block and strides */ 1204a4fd94a54a75a3418462c30f1240ab50b5f24090Jakob Bornecrantz /* TODO also adjust texImage->data for yoffset/xoffset */ 1205a4fd94a54a75a3418462c30f1240ab50b5f24090Jakob Bornecrantz return; 1206a4fd94a54a75a3418462c30f1240ab50b5f24090Jakob Bornecrantz } 1207a4fd94a54a75a3418462c30f1240ab50b5f24090Jakob Bornecrantz 1208a4fd94a54a75a3418462c30f1240ab50b5f24090Jakob Bornecrantz if (!texImage->Data) { 1209a4fd94a54a75a3418462c30f1240ab50b5f24090Jakob Bornecrantz _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexSubImage"); 1210a4fd94a54a75a3418462c30f1240ab50b5f24090Jakob Bornecrantz return; 1211a4fd94a54a75a3418462c30f1240ab50b5f24090Jakob Bornecrantz } 1212a4fd94a54a75a3418462c30f1240ab50b5f24090Jakob Bornecrantz 1213b1ed72ebe2599ec178f51d86fd42f26486b9a19bMichal Krol assert(xoffset % util_format_get_blockwidth(pformat) == 0); 1214b1ed72ebe2599ec178f51d86fd42f26486b9a19bMichal Krol assert(yoffset % util_format_get_blockheight(pformat) == 0); 1215b1ed72ebe2599ec178f51d86fd42f26486b9a19bMichal Krol assert(width % util_format_get_blockwidth(pformat) == 0); 1216b1ed72ebe2599ec178f51d86fd42f26486b9a19bMichal Krol assert(height % util_format_get_blockheight(pformat) == 0); 1217a4fd94a54a75a3418462c30f1240ab50b5f24090Jakob Bornecrantz 1218b1ed72ebe2599ec178f51d86fd42f26486b9a19bMichal Krol for (y = 0; y < height; y += util_format_get_blockheight(pformat)) { 1219a4fd94a54a75a3418462c30f1240ab50b5f24090Jakob Bornecrantz /* don't need to adjust for xoffset and yoffset as st_texture_image_map does that */ 1220b1ed72ebe2599ec178f51d86fd42f26486b9a19bMichal Krol const char *src = (const char*)data + srcBlockStride * util_format_get_nblocksy(pformat, y); 1221b1ed72ebe2599ec178f51d86fd42f26486b9a19bMichal Krol char *dst = (char*)texImage->Data + dstBlockStride * util_format_get_nblocksy(pformat, y); 1222b1ed72ebe2599ec178f51d86fd42f26486b9a19bMichal Krol memcpy(dst, src, util_format_get_stride(pformat, width)); 1223a4fd94a54a75a3418462c30f1240ab50b5f24090Jakob Bornecrantz } 1224a4fd94a54a75a3418462c30f1240ab50b5f24090Jakob Bornecrantz 1225a4fd94a54a75a3418462c30f1240ab50b5f24090Jakob Bornecrantz if (stImage->pt) { 1226a4fd94a54a75a3418462c30f1240ab50b5f24090Jakob Bornecrantz st_texture_image_unmap(ctx->st, stImage); 1227a4fd94a54a75a3418462c30f1240ab50b5f24090Jakob Bornecrantz texImage->Data = NULL; 1228a4fd94a54a75a3418462c30f1240ab50b5f24090Jakob Bornecrantz } 1229a4fd94a54a75a3418462c30f1240ab50b5f24090Jakob Bornecrantz} 1230a4fd94a54a75a3418462c30f1240ab50b5f24090Jakob Bornecrantz 1231a4fd94a54a75a3418462c30f1240ab50b5f24090Jakob Bornecrantz 1232578230dbbffbf5317d6002d1023dcd62b57186f5Jakob Bornecrantzstatic void 1233578230dbbffbf5317d6002d1023dcd62b57186f5Jakob Bornecrantzst_CompressedTexSubImage3D(GLcontext *ctx, GLenum target, GLint level, 1234578230dbbffbf5317d6002d1023dcd62b57186f5Jakob Bornecrantz GLint xoffset, GLint yoffset, GLint zoffset, 1235578230dbbffbf5317d6002d1023dcd62b57186f5Jakob Bornecrantz GLsizei width, GLint height, GLint depth, 1236578230dbbffbf5317d6002d1023dcd62b57186f5Jakob Bornecrantz GLenum format, 1237578230dbbffbf5317d6002d1023dcd62b57186f5Jakob Bornecrantz GLsizei imageSize, const GLvoid *data, 1238578230dbbffbf5317d6002d1023dcd62b57186f5Jakob Bornecrantz struct gl_texture_object *texObj, 1239578230dbbffbf5317d6002d1023dcd62b57186f5Jakob Bornecrantz struct gl_texture_image *texImage) 1240578230dbbffbf5317d6002d1023dcd62b57186f5Jakob Bornecrantz{ 1241578230dbbffbf5317d6002d1023dcd62b57186f5Jakob Bornecrantz assert(0); 1242578230dbbffbf5317d6002d1023dcd62b57186f5Jakob Bornecrantz} 1243578230dbbffbf5317d6002d1023dcd62b57186f5Jakob Bornecrantz 1244578230dbbffbf5317d6002d1023dcd62b57186f5Jakob Bornecrantz 124524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 124624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian/** 12475facd7986ace899673499f396897469720476799Brian Paul * Do a CopyTexSubImage operation using a read transfer from the source, 12485facd7986ace899673499f396897469720476799Brian Paul * a write transfer to the destination and get_tile()/put_tile() to access 12495facd7986ace899673499f396897469720476799Brian Paul * the pixels/texels. 1250c6717a86420d7141013165f7acd50b3c3f751756Brian * 1251c6717a86420d7141013165f7acd50b3c3f751756Brian * Note: srcY=0=TOP of renderbuffer 1252038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian */ 1253038cb561eb094af2f2ba06e18e61246fc0c87c3cBrianstatic void 12545facd7986ace899673499f396897469720476799Brian Paulfallback_copy_texsubimage(GLcontext *ctx, GLenum target, GLint level, 1255038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian struct st_renderbuffer *strb, 1256038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian struct st_texture_image *stImage, 1257038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian GLenum baseFormat, 1258038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian GLint destX, GLint destY, GLint destZ, 1259038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian GLint srcX, GLint srcY, 1260038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian GLsizei width, GLsizei height) 1261038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian{ 1262038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian struct pipe_context *pipe = ctx->st->pipe; 12636f715dcc219071e574e363a9db4365c9c31ebbd3Brian struct pipe_screen *screen = pipe->screen; 12644617981ec72f7985941bee4b03c534d97ff96bc6Michel Dänzer struct pipe_transfer *src_trans; 12654617981ec72f7985941bee4b03c534d97ff96bc6Michel Dänzer GLvoid *texDest; 126671633abafc935c25da9731bab48c228ceb9b4097Michel Dänzer enum pipe_transfer_usage transfer_usage; 1267b02ef740b90029bc40629e5b81270a8cf77101d3Keith Whitwell 1268b02ef740b90029bc40629e5b81270a8cf77101d3Keith Whitwell if (ST_DEBUG & DEBUG_FALLBACK) 1269b02ef740b90029bc40629e5b81270a8cf77101d3Keith Whitwell debug_printf("%s: fallback processing\n", __FUNCTION__); 12704617981ec72f7985941bee4b03c534d97ff96bc6Michel Dänzer 12714617981ec72f7985941bee4b03c534d97ff96bc6Michel Dänzer assert(width <= MAX_WIDTH); 1272038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian 12734617981ec72f7985941bee4b03c534d97ff96bc6Michel Dänzer if (st_fb_orientation(ctx->ReadBuffer) == Y_0_TOP) { 12747c8836e9ef49d938aa55a1c385b95c6371c301f1Michel Dänzer srcY = strb->Base.Height - srcY - height; 12754617981ec72f7985941bee4b03c534d97ff96bc6Michel Dänzer } 1276f3048ad90ed2e4583f0f7aaf35a0f4aa581942ddBrian Paul 1277e50dd26ca6d0eb0d0f97c2780020ea16e3d4a687Thomas Hellstrom src_trans = st_cond_flush_get_tex_transfer( st_context(ctx), 1278e50dd26ca6d0eb0d0f97c2780020ea16e3d4a687Thomas Hellstrom strb->texture, 1279e50dd26ca6d0eb0d0f97c2780020ea16e3d4a687Thomas Hellstrom 0, 0, 0, 1280e50dd26ca6d0eb0d0f97c2780020ea16e3d4a687Thomas Hellstrom PIPE_TRANSFER_READ, 1281e50dd26ca6d0eb0d0f97c2780020ea16e3d4a687Thomas Hellstrom srcX, srcY, 1282e50dd26ca6d0eb0d0f97c2780020ea16e3d4a687Thomas Hellstrom width, height); 1283038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian 12840197348641614188c400d7c616573bb7f1eea781Brian Paul if ((baseFormat == GL_DEPTH_COMPONENT || 12850197348641614188c400d7c616573bb7f1eea781Brian Paul baseFormat == GL_DEPTH_STENCIL) && 12860bed834be4a174d20b31a6cbcf066774bf749929Michal Krol util_format_is_depth_and_stencil(stImage->pt->format)) 128771633abafc935c25da9731bab48c228ceb9b4097Michel Dänzer transfer_usage = PIPE_TRANSFER_READ_WRITE; 128871633abafc935c25da9731bab48c228ceb9b4097Michel Dänzer else 128971633abafc935c25da9731bab48c228ceb9b4097Michel Dänzer transfer_usage = PIPE_TRANSFER_WRITE; 129071633abafc935c25da9731bab48c228ceb9b4097Michel Dänzer 12919b75627fab5bf2ea90f27ddd31b60c54895f6de6Thomas Hellstrom st_teximage_flush_before_map(ctx->st, stImage->pt, 0, 0, 129271633abafc935c25da9731bab48c228ceb9b4097Michel Dänzer transfer_usage); 12939b75627fab5bf2ea90f27ddd31b60c54895f6de6Thomas Hellstrom 129471633abafc935c25da9731bab48c228ceb9b4097Michel Dänzer texDest = st_texture_image_map(ctx->st, stImage, 0, transfer_usage, 12954617981ec72f7985941bee4b03c534d97ff96bc6Michel Dänzer destX, destY, width, height); 1296038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian 1297105758105a790dd8466c6be8c232c3f215ca4deeBrian Paul if (baseFormat == GL_DEPTH_COMPONENT || 12980197348641614188c400d7c616573bb7f1eea781Brian Paul baseFormat == GL_DEPTH_STENCIL) { 1299cc94863429d8a6cef8dbf861e78701a458d30f5aBrian Paul const GLboolean scaleOrBias = (ctx->Pixel.DepthScale != 1.0F || 1300cc94863429d8a6cef8dbf861e78701a458d30f5aBrian Paul ctx->Pixel.DepthBias != 0.0F); 130127858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul GLint row, yStep; 1302cc94863429d8a6cef8dbf861e78701a458d30f5aBrian Paul 130327858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul /* determine bottom-to-top vs. top-to-bottom order for src buffer */ 130427858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul if (st_fb_orientation(ctx->ReadBuffer) == Y_0_TOP) { 13057c8836e9ef49d938aa55a1c385b95c6371c301f1Michel Dänzer srcY = height - 1; 130627858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul yStep = -1; 130727858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul } 130827858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul else { 13094617981ec72f7985941bee4b03c534d97ff96bc6Michel Dänzer srcY = 0; 131027858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul yStep = 1; 131127858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul } 131227858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul 131327858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul /* To avoid a large temp memory allocation, do copy row by row */ 13144617981ec72f7985941bee4b03c534d97ff96bc6Michel Dänzer for (row = 0; row < height; row++, srcY += yStep) { 1315cc94863429d8a6cef8dbf861e78701a458d30f5aBrian Paul uint data[MAX_WIDTH]; 13164617981ec72f7985941bee4b03c534d97ff96bc6Michel Dänzer pipe_get_tile_z(src_trans, 0, srcY, width, 1, data); 1317cc94863429d8a6cef8dbf861e78701a458d30f5aBrian Paul if (scaleOrBias) { 1318cc94863429d8a6cef8dbf861e78701a458d30f5aBrian Paul _mesa_scale_and_bias_depth_uint(ctx, width, data); 1319cc94863429d8a6cef8dbf861e78701a458d30f5aBrian Paul } 13204617981ec72f7985941bee4b03c534d97ff96bc6Michel Dänzer pipe_put_tile_z(stImage->transfer, 0, row, width, 1, data); 1321cc94863429d8a6cef8dbf861e78701a458d30f5aBrian Paul } 1322cc94863429d8a6cef8dbf861e78701a458d30f5aBrian Paul } 1323cc94863429d8a6cef8dbf861e78701a458d30f5aBrian Paul else { 1324cc94863429d8a6cef8dbf861e78701a458d30f5aBrian Paul /* RGBA format */ 132527858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul GLfloat *tempSrc = 132632f2fd1c5d6088692551c80352b7d6fa35b0cd09Kristian Høgsberg (GLfloat *) malloc(width * height * 4 * sizeof(GLfloat)); 132727858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul 132827858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul if (tempSrc && texDest) { 132927858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul const GLint dims = 2; 13305facd7986ace899673499f396897469720476799Brian Paul const GLint dstRowStride = stImage->transfer->stride; 133127858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul struct gl_texture_image *texImage = &stImage->base; 133227858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul struct gl_pixelstore_attrib unpack = ctx->DefaultPacking; 133327858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul 133427858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul if (st_fb_orientation(ctx->ReadBuffer) == Y_0_TOP) { 133527858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul unpack.Invert = GL_TRUE; 1336cc94863429d8a6cef8dbf861e78701a458d30f5aBrian Paul } 133727858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul 133827858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul /* get float/RGBA image from framebuffer */ 133927858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul /* XXX this usually involves a lot of int/float conversion. 134027858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul * try to avoid that someday. 134127858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul */ 13424617981ec72f7985941bee4b03c534d97ff96bc6Michel Dänzer pipe_get_tile_rgba(src_trans, 0, 0, width, height, tempSrc); 134327858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul 134427858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul /* Store into texture memory. 134527858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul * Note that this does some special things such as pixel transfer 134627858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul * ops and format conversion. In particular, if the dest tex format 134727858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul * is actually RGBA but the user created the texture as GL_RGB we 134827858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul * need to fill-in/override the alpha channel with 1.0. 134927858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul */ 13506480210b89dc8ae0990c450d27870c7b7930f251Brian Paul _mesa_texstore(ctx, dims, 13516480210b89dc8ae0990c450d27870c7b7930f251Brian Paul texImage->_BaseFormat, 13526480210b89dc8ae0990c450d27870c7b7930f251Brian Paul texImage->TexFormat, 13536480210b89dc8ae0990c450d27870c7b7930f251Brian Paul texDest, 13546480210b89dc8ae0990c450d27870c7b7930f251Brian Paul 0, 0, 0, 13556480210b89dc8ae0990c450d27870c7b7930f251Brian Paul dstRowStride, 13566480210b89dc8ae0990c450d27870c7b7930f251Brian Paul texImage->ImageOffsets, 13576480210b89dc8ae0990c450d27870c7b7930f251Brian Paul width, height, 1, 13586480210b89dc8ae0990c450d27870c7b7930f251Brian Paul GL_RGBA, GL_FLOAT, tempSrc, /* src */ 13596480210b89dc8ae0990c450d27870c7b7930f251Brian Paul &unpack); 136027858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul } 136127858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul else { 136227858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage"); 13635c83f1371978472fbe4bba8f686733c6b519874aBrian } 136427858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul 136527858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul if (tempSrc) 136632f2fd1c5d6088692551c80352b7d6fa35b0cd09Kristian Høgsberg free(tempSrc); 13675c83f1371978472fbe4bba8f686733c6b519874aBrian } 1368d0279fc4b38c72356a341173317bcd45d9093f45Michel Dänzer 13694617981ec72f7985941bee4b03c534d97ff96bc6Michel Dänzer st_texture_image_unmap(ctx->st, stImage); 13705e27cd46c04a9e7b5904cc014bffd0f4daae31feMichel Dänzer screen->tex_transfer_destroy(src_trans); 1371038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian} 1372038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian 1373038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian 137465d2a266375cf32fd90c7fb77fb87993d3a652eaBrian Paul 137565d2a266375cf32fd90c7fb77fb87993d3a652eaBrian Paul/** 137665d2a266375cf32fd90c7fb77fb87993d3a652eaBrian Paul * If the format of the src renderbuffer and the format of the dest 137765d2a266375cf32fd90c7fb77fb87993d3a652eaBrian Paul * texture are compatible (in terms of blitting), return a TGSI writemask 137865d2a266375cf32fd90c7fb77fb87993d3a652eaBrian Paul * to be used during the blit. 137965d2a266375cf32fd90c7fb77fb87993d3a652eaBrian Paul * If the src/dest are incompatible, return 0. 138065d2a266375cf32fd90c7fb77fb87993d3a652eaBrian Paul */ 13818fc945cd847aa5d343a5f76eb2f9f2c9075cccddKeith Whitwellstatic unsigned 138265d2a266375cf32fd90c7fb77fb87993d3a652eaBrian Paulcompatible_src_dst_formats(GLcontext *ctx, 138365d2a266375cf32fd90c7fb77fb87993d3a652eaBrian Paul const struct gl_renderbuffer *src, 13848fc945cd847aa5d343a5f76eb2f9f2c9075cccddKeith Whitwell const struct gl_texture_image *dst) 13858fc945cd847aa5d343a5f76eb2f9f2c9075cccddKeith Whitwell{ 138665d2a266375cf32fd90c7fb77fb87993d3a652eaBrian Paul /* Get logical base formats for the src and dest. 138765d2a266375cf32fd90c7fb77fb87993d3a652eaBrian Paul * That is, use the user-requested formats and not the actual, device- 138865d2a266375cf32fd90c7fb77fb87993d3a652eaBrian Paul * chosen formats. 138965d2a266375cf32fd90c7fb77fb87993d3a652eaBrian Paul * For example, the user may have requested an A8 texture but the 139065d2a266375cf32fd90c7fb77fb87993d3a652eaBrian Paul * driver may actually be using an RGBA texture format. When we 139165d2a266375cf32fd90c7fb77fb87993d3a652eaBrian Paul * copy/blit to that texture, we only want to copy the Alpha channel 139265d2a266375cf32fd90c7fb77fb87993d3a652eaBrian Paul * and not the RGB channels. 139365d2a266375cf32fd90c7fb77fb87993d3a652eaBrian Paul * 139465d2a266375cf32fd90c7fb77fb87993d3a652eaBrian Paul * Similarly, when the src FBO was created an RGB format may have been 139565d2a266375cf32fd90c7fb77fb87993d3a652eaBrian Paul * requested but the driver actually chose an RGBA format. In that case, 139665d2a266375cf32fd90c7fb77fb87993d3a652eaBrian Paul * we don't want to copy the undefined Alpha channel to the dest texture 139765d2a266375cf32fd90c7fb77fb87993d3a652eaBrian Paul * (it should be 1.0). 139865d2a266375cf32fd90c7fb77fb87993d3a652eaBrian Paul */ 139965d2a266375cf32fd90c7fb77fb87993d3a652eaBrian Paul const GLenum srcFormat = _mesa_base_fbo_format(ctx, src->InternalFormat); 140065d2a266375cf32fd90c7fb77fb87993d3a652eaBrian Paul const GLenum dstFormat = _mesa_base_tex_format(ctx, dst->InternalFormat); 14018fc945cd847aa5d343a5f76eb2f9f2c9075cccddKeith Whitwell 140265d2a266375cf32fd90c7fb77fb87993d3a652eaBrian Paul /** 140365d2a266375cf32fd90c7fb77fb87993d3a652eaBrian Paul * XXX when we have red-only and red/green renderbuffers we'll need 140465d2a266375cf32fd90c7fb77fb87993d3a652eaBrian Paul * to add more cases here (or implement a general-purpose routine that 140565d2a266375cf32fd90c7fb77fb87993d3a652eaBrian Paul * queries the existance of the R,G,B,A channels in the src and dest). 140665d2a266375cf32fd90c7fb77fb87993d3a652eaBrian Paul */ 140765d2a266375cf32fd90c7fb77fb87993d3a652eaBrian Paul if (srcFormat == dstFormat) { 14088fc945cd847aa5d343a5f76eb2f9f2c9075cccddKeith Whitwell /* This is the same as matching_base_formats, which should 14098fc945cd847aa5d343a5f76eb2f9f2c9075cccddKeith Whitwell * always pass, as it did previously. 14108fc945cd847aa5d343a5f76eb2f9f2c9075cccddKeith Whitwell */ 14118fc945cd847aa5d343a5f76eb2f9f2c9075cccddKeith Whitwell return TGSI_WRITEMASK_XYZW; 14128fc945cd847aa5d343a5f76eb2f9f2c9075cccddKeith Whitwell } 141365d2a266375cf32fd90c7fb77fb87993d3a652eaBrian Paul else if (srcFormat == GL_RGB && dstFormat == GL_RGBA) { 141465d2a266375cf32fd90c7fb77fb87993d3a652eaBrian Paul /* Make sure that A in the dest is 1. The actual src format 141565d2a266375cf32fd90c7fb77fb87993d3a652eaBrian Paul * may be RGBA and have undefined A values. 141665d2a266375cf32fd90c7fb77fb87993d3a652eaBrian Paul */ 141765d2a266375cf32fd90c7fb77fb87993d3a652eaBrian Paul return TGSI_WRITEMASK_XYZ; 141865d2a266375cf32fd90c7fb77fb87993d3a652eaBrian Paul } 141965d2a266375cf32fd90c7fb77fb87993d3a652eaBrian Paul else if (srcFormat == GL_RGBA && dstFormat == GL_RGB) { 142065d2a266375cf32fd90c7fb77fb87993d3a652eaBrian Paul /* Make sure that A in the dest is 1. The actual dst format 142165d2a266375cf32fd90c7fb77fb87993d3a652eaBrian Paul * may be RGBA and will need A=1 to provide proper alpha values 142265d2a266375cf32fd90c7fb77fb87993d3a652eaBrian Paul * when sampled later. 14238fc945cd847aa5d343a5f76eb2f9f2c9075cccddKeith Whitwell */ 142465d2a266375cf32fd90c7fb77fb87993d3a652eaBrian Paul return TGSI_WRITEMASK_XYZ; 14258fc945cd847aa5d343a5f76eb2f9f2c9075cccddKeith Whitwell } 14268fc945cd847aa5d343a5f76eb2f9f2c9075cccddKeith Whitwell else { 1427b02ef740b90029bc40629e5b81270a8cf77101d3Keith Whitwell if (ST_DEBUG & DEBUG_FALLBACK) 1428b02ef740b90029bc40629e5b81270a8cf77101d3Keith Whitwell debug_printf("%s failed for src %s, dst %s\n", 1429b02ef740b90029bc40629e5b81270a8cf77101d3Keith Whitwell __FUNCTION__, 1430b02ef740b90029bc40629e5b81270a8cf77101d3Keith Whitwell _mesa_lookup_enum_by_nr(srcFormat), 143165d2a266375cf32fd90c7fb77fb87993d3a652eaBrian Paul _mesa_lookup_enum_by_nr(dstFormat)); 1432b02ef740b90029bc40629e5b81270a8cf77101d3Keith Whitwell 14338fc945cd847aa5d343a5f76eb2f9f2c9075cccddKeith Whitwell /* Otherwise fail. 14348fc945cd847aa5d343a5f76eb2f9f2c9075cccddKeith Whitwell */ 14358fc945cd847aa5d343a5f76eb2f9f2c9075cccddKeith Whitwell return 0; 14368fc945cd847aa5d343a5f76eb2f9f2c9075cccddKeith Whitwell } 14378fc945cd847aa5d343a5f76eb2f9f2c9075cccddKeith Whitwell} 14388fc945cd847aa5d343a5f76eb2f9f2c9075cccddKeith Whitwell 14398fc945cd847aa5d343a5f76eb2f9f2c9075cccddKeith Whitwell 14408fc945cd847aa5d343a5f76eb2f9f2c9075cccddKeith Whitwell 1441038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian/** 14424e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul * Do a CopyTex[Sub]Image1/2/3D() using a hardware (blit) path if possible. 14434e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul * Note that the region to copy has already been clipped so we know we 14444e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul * won't read from outside the source renderbuffer's bounds. 1445c6717a86420d7141013165f7acd50b3c3f751756Brian * 14464e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul * Note: srcY=0=Bottom of renderbuffer (GL convention) 144724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 1448038cb561eb094af2f2ba06e18e61246fc0c87c3cBrianstatic void 14494e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paulst_copy_texsubimage(GLcontext *ctx, 1450038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian GLenum target, GLint level, 1451038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian GLint destX, GLint destY, GLint destZ, 1452038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian GLint srcX, GLint srcY, 1453038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian GLsizei width, GLsizei height) 145424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 1455038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian struct gl_texture_unit *texUnit = 1456038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; 1457038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian struct gl_texture_object *texObj = 1458038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian _mesa_select_tex_object(ctx, texUnit, target); 1459038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian struct gl_texture_image *texImage = 1460038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian _mesa_select_tex_image(ctx, texObj, target, level); 1461038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian struct st_texture_image *stImage = st_texture_image(texImage); 14620197348641614188c400d7c616573bb7f1eea781Brian Paul const GLenum texBaseFormat = texImage->_BaseFormat; 1463b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian struct gl_framebuffer *fb = ctx->ReadBuffer; 1464b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian struct st_renderbuffer *strb; 1465b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian struct pipe_context *pipe = ctx->st->pipe; 14666f715dcc219071e574e363a9db4365c9c31ebbd3Brian struct pipe_screen *screen = pipe->screen; 146727858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul enum pipe_format dest_format, src_format; 1468cc94863429d8a6cef8dbf861e78701a458d30f5aBrian Paul GLboolean use_fallback = GL_TRUE; 146927858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul GLboolean matching_base_formats; 14708fc945cd847aa5d343a5f76eb2f9f2c9075cccddKeith Whitwell GLuint format_writemask; 14718fc945cd847aa5d343a5f76eb2f9f2c9075cccddKeith Whitwell struct pipe_surface *dest_surface = NULL; 14728fc945cd847aa5d343a5f76eb2f9f2c9075cccddKeith Whitwell GLboolean do_flip = (st_fb_orientation(ctx->ReadBuffer) == Y_0_TOP); 147324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 1474503632557e8904b775e1b6f3f84eb41bda3af122Keith Whitwell /* any rendering in progress must flushed before we grab the fb image */ 1475503632557e8904b775e1b6f3f84eb41bda3af122Keith Whitwell st_flush(ctx->st, PIPE_FLUSH_RENDER_CACHE, NULL); 1476503632557e8904b775e1b6f3f84eb41bda3af122Keith Whitwell 1477afd16512bc354cf1a7220cb9bf3ce445503c7af4Keith Whitwell /* make sure finalize_textures has been called? 1478afd16512bc354cf1a7220cb9bf3ce445503c7af4Keith Whitwell */ 1479afd16512bc354cf1a7220cb9bf3ce445503c7af4Keith Whitwell if (0) st_validate_state(ctx->st); 1480afd16512bc354cf1a7220cb9bf3ce445503c7af4Keith Whitwell 1481b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian /* determine if copying depth or color data */ 1482105758105a790dd8466c6be8c232c3f215ca4deeBrian Paul if (texBaseFormat == GL_DEPTH_COMPONENT || 14830197348641614188c400d7c616573bb7f1eea781Brian Paul texBaseFormat == GL_DEPTH_STENCIL) { 1484b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian strb = st_renderbuffer(fb->_DepthBuffer); 148524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 1486b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian else { 14874e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul /* texBaseFormat == GL_RGB, GL_RGBA, GL_ALPHA, etc */ 1488b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian strb = st_renderbuffer(fb->_ColorReadBuffer); 1489b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian } 1490b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian 1491afd16512bc354cf1a7220cb9bf3ce445503c7af4Keith Whitwell if (!strb || !strb->surface || !stImage->pt) { 1492afd16512bc354cf1a7220cb9bf3ce445503c7af4Keith Whitwell debug_printf("%s: null strb or stImage\n", __FUNCTION__); 1493afd16512bc354cf1a7220cb9bf3ce445503c7af4Keith Whitwell return; 1494afd16512bc354cf1a7220cb9bf3ce445503c7af4Keith Whitwell } 1495afd16512bc354cf1a7220cb9bf3ce445503c7af4Keith Whitwell 1496e90beb93a89f77bffce8ab3d54457ea65868e93cKeith Whitwell if (srcX < 0) { 1497e90beb93a89f77bffce8ab3d54457ea65868e93cKeith Whitwell width -= -srcX; 1498e90beb93a89f77bffce8ab3d54457ea65868e93cKeith Whitwell destX += -srcX; 1499e90beb93a89f77bffce8ab3d54457ea65868e93cKeith Whitwell srcX = 0; 1500e90beb93a89f77bffce8ab3d54457ea65868e93cKeith Whitwell } 1501e90beb93a89f77bffce8ab3d54457ea65868e93cKeith Whitwell 1502e90beb93a89f77bffce8ab3d54457ea65868e93cKeith Whitwell if (srcY < 0) { 1503e90beb93a89f77bffce8ab3d54457ea65868e93cKeith Whitwell height -= -srcY; 1504e90beb93a89f77bffce8ab3d54457ea65868e93cKeith Whitwell destY += -srcY; 1505e90beb93a89f77bffce8ab3d54457ea65868e93cKeith Whitwell srcY = 0; 1506e90beb93a89f77bffce8ab3d54457ea65868e93cKeith Whitwell } 1507e90beb93a89f77bffce8ab3d54457ea65868e93cKeith Whitwell 1508e90beb93a89f77bffce8ab3d54457ea65868e93cKeith Whitwell if (destX < 0) { 1509e90beb93a89f77bffce8ab3d54457ea65868e93cKeith Whitwell width -= -destX; 1510e90beb93a89f77bffce8ab3d54457ea65868e93cKeith Whitwell srcX += -destX; 1511e90beb93a89f77bffce8ab3d54457ea65868e93cKeith Whitwell destX = 0; 1512e90beb93a89f77bffce8ab3d54457ea65868e93cKeith Whitwell } 1513e90beb93a89f77bffce8ab3d54457ea65868e93cKeith Whitwell 1514e90beb93a89f77bffce8ab3d54457ea65868e93cKeith Whitwell if (destY < 0) { 1515e90beb93a89f77bffce8ab3d54457ea65868e93cKeith Whitwell height -= -destY; 1516e90beb93a89f77bffce8ab3d54457ea65868e93cKeith Whitwell srcY += -destY; 1517e90beb93a89f77bffce8ab3d54457ea65868e93cKeith Whitwell destY = 0; 1518e90beb93a89f77bffce8ab3d54457ea65868e93cKeith Whitwell } 1519e90beb93a89f77bffce8ab3d54457ea65868e93cKeith Whitwell 1520e90beb93a89f77bffce8ab3d54457ea65868e93cKeith Whitwell if (width < 0 || height < 0) 1521e90beb93a89f77bffce8ab3d54457ea65868e93cKeith Whitwell return; 1522e90beb93a89f77bffce8ab3d54457ea65868e93cKeith Whitwell 1523e90beb93a89f77bffce8ab3d54457ea65868e93cKeith Whitwell 1524b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian assert(strb); 1525b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian assert(strb->surface); 1526753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer assert(stImage->pt); 1527c6717a86420d7141013165f7acd50b3c3f751756Brian 1528b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian src_format = strb->surface->format; 1529753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer dest_format = stImage->pt->format; 1530b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian 153127858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul /* 153227858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul * Determine if the src framebuffer and dest texture have the same 153327858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul * base format. We need this to detect a case such as the framebuffer 153427858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul * being GL_RGBA but the texture being GL_RGB. If the actual hardware 153527858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul * texture format stores RGBA we need to set A=1 (overriding the 153627858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul * framebuffer's alpha values). We can't do that with the blit or 153727858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul * textured-quad paths. 153827858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul */ 153945e76d2665b38ba3787548310efc59e969124c01Brian Paul matching_base_formats = 154045e76d2665b38ba3787548310efc59e969124c01Brian Paul (_mesa_get_format_base_format(strb->Base.Format) == 154145e76d2665b38ba3787548310efc59e969124c01Brian Paul _mesa_get_format_base_format(texImage->TexFormat)); 154265d2a266375cf32fd90c7fb77fb87993d3a652eaBrian Paul format_writemask = compatible_src_dst_formats(ctx, &strb->Base, texImage); 154379931e38abc62286151121a3f59127e296144551Michel Dänzer 15448fc945cd847aa5d343a5f76eb2f9f2c9075cccddKeith Whitwell if (ctx->_ImageTransferState == 0x0) { 1545b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian 1546bb567357bc1366df7115e0daa68c2470e3bf6ba6Corbin Simpson if (pipe->surface_copy && 1547bb567357bc1366df7115e0daa68c2470e3bf6ba6Corbin Simpson matching_base_formats && 15488fc945cd847aa5d343a5f76eb2f9f2c9075cccddKeith Whitwell src_format == dest_format && 15498fc945cd847aa5d343a5f76eb2f9f2c9075cccddKeith Whitwell !do_flip) 15508fc945cd847aa5d343a5f76eb2f9f2c9075cccddKeith Whitwell { 15514e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul /* use surface_copy() / blit */ 1552f500f3a72c6be61ff9b8e1166f734e408d00adedJakob Bornecrantz 155327858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul dest_surface = screen->get_tex_surface(screen, stImage->pt, 155427858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul stImage->face, stImage->level, 155527858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul destZ, 155627858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul PIPE_BUFFER_USAGE_GPU_WRITE); 1557145a45e9d6807add8229f1fc9c63fbb6951b1b88Brian Paul 1558145a45e9d6807add8229f1fc9c63fbb6951b1b88Brian Paul /* for surface_copy(), y=0=top, always */ 1559a479bf62353b6517841e620122112e7565d2391cBrian Paul pipe->surface_copy(pipe, 1560a479bf62353b6517841e620122112e7565d2391cBrian Paul /* dest */ 1561a479bf62353b6517841e620122112e7565d2391cBrian Paul dest_surface, 1562a479bf62353b6517841e620122112e7565d2391cBrian Paul destX, destY, 1563a479bf62353b6517841e620122112e7565d2391cBrian Paul /* src */ 1564a479bf62353b6517841e620122112e7565d2391cBrian Paul strb->surface, 1565a479bf62353b6517841e620122112e7565d2391cBrian Paul srcX, srcY, 1566a479bf62353b6517841e620122112e7565d2391cBrian Paul /* size */ 1567a479bf62353b6517841e620122112e7565d2391cBrian Paul width, height); 1568a479bf62353b6517841e620122112e7565d2391cBrian Paul use_fallback = GL_FALSE; 1569cc94863429d8a6cef8dbf861e78701a458d30f5aBrian Paul } 15708fc945cd847aa5d343a5f76eb2f9f2c9075cccddKeith Whitwell else if (format_writemask && 1571e60ebebb392d1d4c47541766737b5a79685a24d5Brian Paul texBaseFormat != GL_DEPTH_COMPONENT && 1572e60ebebb392d1d4c47541766737b5a79685a24d5Brian Paul texBaseFormat != GL_DEPTH_STENCIL && 15738fc945cd847aa5d343a5f76eb2f9f2c9075cccddKeith Whitwell screen->is_format_supported(screen, src_format, 15748aafc03b260ab8923f1b373f7effa75bcdb40a72José Fonseca PIPE_TEXTURE_2D, 15758aafc03b260ab8923f1b373f7effa75bcdb40a72José Fonseca PIPE_TEXTURE_USAGE_SAMPLER, 15768aafc03b260ab8923f1b373f7effa75bcdb40a72José Fonseca 0) && 15774e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul screen->is_format_supported(screen, dest_format, 15788aafc03b260ab8923f1b373f7effa75bcdb40a72José Fonseca PIPE_TEXTURE_2D, 15798aafc03b260ab8923f1b373f7effa75bcdb40a72José Fonseca PIPE_TEXTURE_USAGE_RENDER_TARGET, 15808aafc03b260ab8923f1b373f7effa75bcdb40a72José Fonseca 0)) { 15814e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul /* draw textured quad to do the copy */ 1582eaca19edbbe7876079aa33d7f75d93601677081bBrian Paul GLint srcY0, srcY1; 158327858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul 158427858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul dest_surface = screen->get_tex_surface(screen, stImage->pt, 158527858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul stImage->face, stImage->level, 158627858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul destZ, 158727858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul PIPE_BUFFER_USAGE_GPU_WRITE); 158827858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul 1589a479bf62353b6517841e620122112e7565d2391cBrian Paul if (do_flip) { 1590a479bf62353b6517841e620122112e7565d2391cBrian Paul srcY1 = strb->Base.Height - srcY - height; 1591a479bf62353b6517841e620122112e7565d2391cBrian Paul srcY0 = srcY1 + height; 1592a479bf62353b6517841e620122112e7565d2391cBrian Paul } 1593a479bf62353b6517841e620122112e7565d2391cBrian Paul else { 1594a479bf62353b6517841e620122112e7565d2391cBrian Paul srcY0 = srcY; 1595a479bf62353b6517841e620122112e7565d2391cBrian Paul srcY1 = srcY0 + height; 1596a479bf62353b6517841e620122112e7565d2391cBrian Paul } 15978fc945cd847aa5d343a5f76eb2f9f2c9075cccddKeith Whitwell util_blit_pixels_writemask(ctx->st->blit, 15988fc945cd847aa5d343a5f76eb2f9f2c9075cccddKeith Whitwell strb->surface, 15998fc945cd847aa5d343a5f76eb2f9f2c9075cccddKeith Whitwell srcX, srcY0, 16008fc945cd847aa5d343a5f76eb2f9f2c9075cccddKeith Whitwell srcX + width, srcY1, 16018fc945cd847aa5d343a5f76eb2f9f2c9075cccddKeith Whitwell dest_surface, 16028fc945cd847aa5d343a5f76eb2f9f2c9075cccddKeith Whitwell destX, destY, 16038fc945cd847aa5d343a5f76eb2f9f2c9075cccddKeith Whitwell destX + width, destY + height, 16048fc945cd847aa5d343a5f76eb2f9f2c9075cccddKeith Whitwell 0.0, PIPE_TEX_MIPFILTER_NEAREST, 16058fc945cd847aa5d343a5f76eb2f9f2c9075cccddKeith Whitwell format_writemask); 1606cc94863429d8a6cef8dbf861e78701a458d30f5aBrian Paul use_fallback = GL_FALSE; 16073c0dc8242b64518d5635263ba65b39afa919dd86Michel Dänzer } 160879931e38abc62286151121a3f59127e296144551Michel Dänzer 160927858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul if (dest_surface) 161027858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul pipe_surface_reference(&dest_surface, NULL); 1611038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian } 1612cc94863429d8a6cef8dbf861e78701a458d30f5aBrian Paul 1613cc94863429d8a6cef8dbf861e78701a458d30f5aBrian Paul if (use_fallback) { 16144e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul /* software fallback */ 1615038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian fallback_copy_texsubimage(ctx, target, level, 16164e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul strb, stImage, texBaseFormat, 1617038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian destX, destY, destZ, 1618038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian srcX, srcY, width, height); 1619038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian } 162024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 162124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 162224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 1623038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian 162424df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void 162524df8f895fe8807aa2ba058e71bd40adfc01d21eBrianst_CopyTexImage1D(GLcontext * ctx, GLenum target, GLint level, 162624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLenum internalFormat, 162724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLint x, GLint y, GLsizei width, GLint border) 162824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 162924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian struct gl_texture_unit *texUnit = 163024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; 163124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian struct gl_texture_object *texObj = 163224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian _mesa_select_tex_object(ctx, texUnit, target); 163324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian struct gl_texture_image *texImage = 163424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian _mesa_select_tex_image(ctx, texObj, target, level); 163524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 1636753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer /* Setup or redefine the texture object, texture and texture 163724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * image. Don't populate yet. 163824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 163924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian ctx->Driver.TexImage1D(ctx, target, level, internalFormat, 164024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian width, border, 164124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GL_RGBA, CHAN_TYPE, NULL, 164224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian &ctx->DefaultPacking, texObj, texImage); 164324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 16444e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul st_copy_texsubimage(ctx, target, level, 16454e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul 0, 0, 0, /* destX,Y,Z */ 16464e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul x, y, width, 1); /* src X, Y, size */ 164724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 164824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 164924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 165024df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void 165124df8f895fe8807aa2ba058e71bd40adfc01d21eBrianst_CopyTexImage2D(GLcontext * ctx, GLenum target, GLint level, 165224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLenum internalFormat, 165324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLint x, GLint y, GLsizei width, GLsizei height, 165424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLint border) 165524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 165624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian struct gl_texture_unit *texUnit = 165724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; 165824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian struct gl_texture_object *texObj = 165924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian _mesa_select_tex_object(ctx, texUnit, target); 166024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian struct gl_texture_image *texImage = 166124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian _mesa_select_tex_image(ctx, texObj, target, level); 166224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 1663753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer /* Setup or redefine the texture object, texture and texture 166424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * image. Don't populate yet. 166524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 166624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian ctx->Driver.TexImage2D(ctx, target, level, internalFormat, 166724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian width, height, border, 166824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GL_RGBA, CHAN_TYPE, NULL, 166924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian &ctx->DefaultPacking, texObj, texImage); 167024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 16714e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul st_copy_texsubimage(ctx, target, level, 16724e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul 0, 0, 0, /* destX,Y,Z */ 16734e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul x, y, width, height); /* src X, Y, size */ 167424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 167524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 167624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 167724df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void 167824df8f895fe8807aa2ba058e71bd40adfc01d21eBrianst_CopyTexSubImage1D(GLcontext * ctx, GLenum target, GLint level, 167924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLint xoffset, GLint x, GLint y, GLsizei width) 168024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 1681038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian const GLint yoffset = 0, zoffset = 0; 1682038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian const GLsizei height = 1; 16834e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul st_copy_texsubimage(ctx, target, level, 16844e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul xoffset, yoffset, zoffset, /* destX,Y,Z */ 16854e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul x, y, width, height); /* src X, Y, size */ 168624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 168724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 168824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 168924df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void 169024df8f895fe8807aa2ba058e71bd40adfc01d21eBrianst_CopyTexSubImage2D(GLcontext * ctx, GLenum target, GLint level, 169124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLint xoffset, GLint yoffset, 169224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLint x, GLint y, GLsizei width, GLsizei height) 169324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 1694038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian const GLint zoffset = 0; 16954e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul st_copy_texsubimage(ctx, target, level, 16964e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul xoffset, yoffset, zoffset, /* destX,Y,Z */ 16974e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul x, y, width, height); /* src X, Y, size */ 1698038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian} 169924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 170024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 1701038cb561eb094af2f2ba06e18e61246fc0c87c3cBrianstatic void 1702038cb561eb094af2f2ba06e18e61246fc0c87c3cBrianst_CopyTexSubImage3D(GLcontext * ctx, GLenum target, GLint level, 1703038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian GLint xoffset, GLint yoffset, GLint zoffset, 1704038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian GLint x, GLint y, GLsizei width, GLsizei height) 1705038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian{ 17064e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul st_copy_texsubimage(ctx, target, level, 17074e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul xoffset, yoffset, zoffset, /* destX,Y,Z */ 17084e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul x, y, width, height); /* src X, Y, size */ 170924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 171024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 171124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 171224df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void 1713753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzercopy_image_data_to_texture(struct st_context *st, 1714753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer struct st_texture_object *stObj, 17154da1cdf78fa3b954840650fa46cf72da5daf149fBrian GLuint dstLevel, 1716753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer struct st_texture_image *stImage) 171724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 1718753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer if (stImage->pt) { 171924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian /* Copy potentially with the blitter: 172024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 1721753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer st_texture_image_copy(st->pipe, 17224da1cdf78fa3b954840650fa46cf72da5daf149fBrian stObj->pt, dstLevel, /* dest texture, level */ 17234da1cdf78fa3b954840650fa46cf72da5daf149fBrian stImage->pt, /* src texture */ 1724b628950662a97452e539bcc704bd2acee70f8355Brian Paul stImage->face); 172524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 1726f8dce51083042b4d3fabf48524835290b6725682Brian Paul pipe_texture_reference(&stImage->pt, NULL); 172724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 17284c50969334844bc9aa622176c3ebcbc733394f78Brian Paul else if (stImage->base.Data) { 172924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian /* More straightforward upload. 173024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 17319b75627fab5bf2ea90f27ddd31b60c54895f6de6Thomas Hellstrom st_teximage_flush_before_map(st, stObj->pt, stImage->face, dstLevel, 17329b75627fab5bf2ea90f27ddd31b60c54895f6de6Thomas Hellstrom PIPE_TRANSFER_WRITE); 17339b75627fab5bf2ea90f27ddd31b60c54895f6de6Thomas Hellstrom 1734e50dd26ca6d0eb0d0f97c2780020ea16e3d4a687Thomas Hellstrom st_texture_image_data(st, 17355facd7986ace899673499f396897469720476799Brian Paul stObj->pt, 17365facd7986ace899673499f396897469720476799Brian Paul stImage->face, 17375facd7986ace899673499f396897469720476799Brian Paul dstLevel, 17385facd7986ace899673499f396897469720476799Brian Paul stImage->base.Data, 17395facd7986ace899673499f396897469720476799Brian Paul stImage->base.RowStride * 1740b1ed72ebe2599ec178f51d86fd42f26486b9a19bMichal Krol util_format_get_blocksize(stObj->pt->format), 17415facd7986ace899673499f396897469720476799Brian Paul stImage->base.RowStride * 17425facd7986ace899673499f396897469720476799Brian Paul stImage->base.Height * 1743b1ed72ebe2599ec178f51d86fd42f26486b9a19bMichal Krol util_format_get_blocksize(stObj->pt->format)); 174424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian _mesa_align_free(stImage->base.Data); 174524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian stImage->base.Data = NULL; 174624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 174724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 17484da19dbcaa9f3e2d20fffd0145bf0bc756dd7542Brian pipe_texture_reference(&stImage->pt, stObj->pt); 174924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 175024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 175124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 1752afc54983370033b65e3a7cbb29bd9c87156f0881Brian/** 1753afc54983370033b65e3a7cbb29bd9c87156f0881Brian * Called during state validation. When this function is finished, 1754afc54983370033b65e3a7cbb29bd9c87156f0881Brian * the texture object should be ready for rendering. 17553b3774b1227743147159676795b542c0eb7c2bdfBrian Paul * \return GL_TRUE for success, GL_FALSE for failure (out of mem) 175624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 175714b98343309fdcff3514f05020303f7b40e83a4aBrianGLboolean 1758753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzerst_finalize_texture(GLcontext *ctx, 1759c3af68dc5022715cc8f126b7df12f3f5248aefe7Keith Whitwell struct pipe_context *pipe, 1760c3af68dc5022715cc8f126b7df12f3f5248aefe7Keith Whitwell struct gl_texture_object *tObj, 1761753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer GLboolean *needFlush) 176224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 176314b98343309fdcff3514f05020303f7b40e83a4aBrian struct st_texture_object *stObj = st_texture_object(tObj); 1764afc54983370033b65e3a7cbb29bd9c87156f0881Brian const GLuint nr_faces = (stObj->base.Target == GL_TEXTURE_CUBE_MAP) ? 6 : 1; 1765dc41d62250ce51f28e94f1d365836ac9f2ff8907Brian Paul GLuint blockSize, face; 176624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian struct st_texture_image *firstImage; 176724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 176824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian *needFlush = GL_FALSE; 176924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 1770e3a6f57ad6c0e7bda5d45eb146194ed39f45abddBrian Paul if (stObj->base._Complete) { 1771e3a6f57ad6c0e7bda5d45eb146194ed39f45abddBrian Paul /* The texture is complete and we know exactly how many mipmap levels 1772e3a6f57ad6c0e7bda5d45eb146194ed39f45abddBrian Paul * are present/needed. This is conditional because we may be called 1773e3a6f57ad6c0e7bda5d45eb146194ed39f45abddBrian Paul * from the st_generate_mipmap() function when the texture object is 1774e3a6f57ad6c0e7bda5d45eb146194ed39f45abddBrian Paul * incomplete. In that case, we'll have set stObj->lastLevel before 1775e3a6f57ad6c0e7bda5d45eb146194ed39f45abddBrian Paul * we get here. 1776e3a6f57ad6c0e7bda5d45eb146194ed39f45abddBrian Paul */ 1777ae2daacbac7242938cffe0e2409071e030e00863Cooper Yuan if (stObj->base.MinFilter == GL_LINEAR || 1778ae2daacbac7242938cffe0e2409071e030e00863Cooper Yuan stObj->base.MinFilter == GL_NEAREST) 1779ae2daacbac7242938cffe0e2409071e030e00863Cooper Yuan stObj->lastLevel = stObj->base.BaseLevel; 1780ae2daacbac7242938cffe0e2409071e030e00863Cooper Yuan else 1781ae2daacbac7242938cffe0e2409071e030e00863Cooper Yuan stObj->lastLevel = stObj->base._MaxLevel - stObj->base.BaseLevel; 1782e3a6f57ad6c0e7bda5d45eb146194ed39f45abddBrian Paul } 178324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 17844da1cdf78fa3b954840650fa46cf72da5daf149fBrian firstImage = st_texture_image(stObj->base.Image[0][stObj->base.BaseLevel]); 178524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 1786753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer /* If both firstImage and stObj point to a texture which can contain 178724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * all active images, favour firstImage. Note that because of the 178824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * completeness requirement, we know that the image dimensions 178924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * will match. 179024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 1791753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer if (firstImage->pt && 1792753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer firstImage->pt != stObj->pt && 1793753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer firstImage->pt->last_level >= stObj->lastLevel) { 17944da19dbcaa9f3e2d20fffd0145bf0bc756dd7542Brian pipe_texture_reference(&stObj->pt, firstImage->pt); 179524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 179624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 1797dc41d62250ce51f28e94f1d365836ac9f2ff8907Brian Paul /* bytes per pixel block (blocks are usually 1x1) */ 1798dc41d62250ce51f28e94f1d365836ac9f2ff8907Brian Paul blockSize = _mesa_get_format_bytes(firstImage->base.TexFormat); 179924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 1800ce509401738e7073de94a2b7fc41461c52a73da0Brian Paul /* If we already have a gallium texture, check that it matches the texture 1801ce509401738e7073de94a2b7fc41461c52a73da0Brian Paul * object's format, target, size, num_levels, etc. 180224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 1803809dd9089bae70cf35cea6a75258e700e7455738Brian Paul if (stObj->pt) { 1804809dd9089bae70cf35cea6a75258e700e7455738Brian Paul const enum pipe_format fmt = 18051f7c914ad0beea8a29c1a171c7cd1a12f2efe0faBrian Paul st_mesa_format_to_pipe_format(firstImage->base.TexFormat); 1806809dd9089bae70cf35cea6a75258e700e7455738Brian Paul if (stObj->pt->target != gl_target_to_pipe(stObj->base.Target) || 1807809dd9089bae70cf35cea6a75258e700e7455738Brian Paul stObj->pt->format != fmt || 1808809dd9089bae70cf35cea6a75258e700e7455738Brian Paul stObj->pt->last_level < stObj->lastLevel || 1809683e35f726a182ed9fc6b6d5cb07146eebe14deaKeith Whitwell stObj->pt->width0 != firstImage->base.Width2 || 1810683e35f726a182ed9fc6b6d5cb07146eebe14deaKeith Whitwell stObj->pt->height0 != firstImage->base.Height2 || 1811ac400ffce62be47fc77e8d10cabcd39b92b6c627Roland Scheidegger stObj->pt->depth0 != firstImage->base.Depth2) 1812311f77198e171e9ce8ddcce91fd6a894fff1f14fBrian Paul { 18135e27cd46c04a9e7b5904cc014bffd0f4daae31feMichel Dänzer pipe_texture_reference(&stObj->pt, NULL); 18141a82d9648b3db780e58e4966924157542d148c58Brian Paul ctx->st->dirty.st |= ST_NEW_FRAMEBUFFER; 1815809dd9089bae70cf35cea6a75258e700e7455738Brian Paul } 181624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 181724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 1818ce509401738e7073de94a2b7fc41461c52a73da0Brian Paul /* May need to create a new gallium texture: 181924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 1820753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer if (!stObj->pt) { 1821a1f95a8bf64f863289b6759caeec76d7e054400eRoland Scheidegger const enum pipe_format fmt = 18221f7c914ad0beea8a29c1a171c7cd1a12f2efe0faBrian Paul st_mesa_format_to_pipe_format(firstImage->base.TexFormat); 18231ad2484f03cbe9ae6bd4ebe50d6894e570d65952Brian Paul GLuint usage = default_usage(fmt); 18241ad2484f03cbe9ae6bd4ebe50d6894e570d65952Brian Paul 1825753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer stObj->pt = st_texture_create(ctx->st, 18265390a43ce06b27f6d54bc5f237aa305b6948f2afBrian gl_target_to_pipe(stObj->base.Target), 1827a1f95a8bf64f863289b6759caeec76d7e054400eRoland Scheidegger fmt, 1828b245840b86cf877c9b8d666edf229364a84f1deaBrian stObj->lastLevel, 182945cc35e77600af8628393475405160e26d56d421Brian Paul firstImage->base.Width2, 183045cc35e77600af8628393475405160e26d56d421Brian Paul firstImage->base.Height2, 183145cc35e77600af8628393475405160e26d56d421Brian Paul firstImage->base.Depth2, 18321ad2484f03cbe9ae6bd4ebe50d6894e570d65952Brian Paul usage); 1833a73ae3d5eb8419feab5aea26573aa41b72f941ebKeith Whitwell 18343b3774b1227743147159676795b542c0eb7c2bdfBrian Paul if (!stObj->pt) { 18353b3774b1227743147159676795b542c0eb7c2bdfBrian Paul _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage"); 18363b3774b1227743147159676795b542c0eb7c2bdfBrian Paul return GL_FALSE; 18373b3774b1227743147159676795b542c0eb7c2bdfBrian Paul } 183824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 183924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 1840753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer /* Pull in any images not in the object's texture: 184124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 184224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian for (face = 0; face < nr_faces; face++) { 18434da1cdf78fa3b954840650fa46cf72da5daf149fBrian GLuint level; 18444da1cdf78fa3b954840650fa46cf72da5daf149fBrian for (level = 0; level <= stObj->lastLevel; level++) { 184524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian struct st_texture_image *stImage = 18464da1cdf78fa3b954840650fa46cf72da5daf149fBrian st_texture_image(stObj->base.Image[face][stObj->base.BaseLevel + level]); 184724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 1848753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer /* Need to import images in main memory or held in other textures. 184924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 1850a34b43b3f4817268ef4b3f186203b5fbafc7214eBrian if (stImage && stObj->pt != stImage->pt) { 18514da1cdf78fa3b954840650fa46cf72da5daf149fBrian copy_image_data_to_texture(ctx->st, stObj, level, stImage); 185224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian *needFlush = GL_TRUE; 185324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 185424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 185524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 185624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 185724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian return GL_TRUE; 185824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 185924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 186024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 18618f6d9e12be0be086ca2aab0b56dff8d2181addd9Brian Paul/** 18628f6d9e12be0be086ca2aab0b56dff8d2181addd9Brian Paul * Returns pointer to a default/dummy texture. 18638f6d9e12be0be086ca2aab0b56dff8d2181addd9Brian Paul * This is typically used when the current shader has tex/sample instructions 18648f6d9e12be0be086ca2aab0b56dff8d2181addd9Brian Paul * but the user has not provided a (any) texture(s). 18658f6d9e12be0be086ca2aab0b56dff8d2181addd9Brian Paul */ 18668f6d9e12be0be086ca2aab0b56dff8d2181addd9Brian Paulstruct gl_texture_object * 18678f6d9e12be0be086ca2aab0b56dff8d2181addd9Brian Paulst_get_default_texture(struct st_context *st) 18688f6d9e12be0be086ca2aab0b56dff8d2181addd9Brian Paul{ 18698f6d9e12be0be086ca2aab0b56dff8d2181addd9Brian Paul if (!st->default_texture) { 18708f6d9e12be0be086ca2aab0b56dff8d2181addd9Brian Paul static const GLenum target = GL_TEXTURE_2D; 18718f6d9e12be0be086ca2aab0b56dff8d2181addd9Brian Paul GLubyte pixels[16][16][4]; 18728f6d9e12be0be086ca2aab0b56dff8d2181addd9Brian Paul struct gl_texture_object *texObj; 18738f6d9e12be0be086ca2aab0b56dff8d2181addd9Brian Paul struct gl_texture_image *texImg; 18742002e03a5232c54988161cb629966bdce19d35deBrian Paul GLuint i, j; 18758f6d9e12be0be086ca2aab0b56dff8d2181addd9Brian Paul 18762002e03a5232c54988161cb629966bdce19d35deBrian Paul /* The ARB_fragment_program spec says (0,0,0,1) should be returned 18772002e03a5232c54988161cb629966bdce19d35deBrian Paul * when attempting to sample incomplete textures. 18782002e03a5232c54988161cb629966bdce19d35deBrian Paul */ 18792002e03a5232c54988161cb629966bdce19d35deBrian Paul for (i = 0; i < 16; i++) { 18802002e03a5232c54988161cb629966bdce19d35deBrian Paul for (j = 0; j < 16; j++) { 18812002e03a5232c54988161cb629966bdce19d35deBrian Paul pixels[i][j][0] = 0; 18822002e03a5232c54988161cb629966bdce19d35deBrian Paul pixels[i][j][1] = 0; 18832002e03a5232c54988161cb629966bdce19d35deBrian Paul pixels[i][j][2] = 0; 18842002e03a5232c54988161cb629966bdce19d35deBrian Paul pixels[i][j][3] = 255; 18852002e03a5232c54988161cb629966bdce19d35deBrian Paul } 18862002e03a5232c54988161cb629966bdce19d35deBrian Paul } 1887a7b818d53a95b549bbff942a9cb91272e0799dd5Brian Paul 18888f6d9e12be0be086ca2aab0b56dff8d2181addd9Brian Paul texObj = st->ctx->Driver.NewTextureObject(st->ctx, 0, target); 18898f6d9e12be0be086ca2aab0b56dff8d2181addd9Brian Paul 18908f6d9e12be0be086ca2aab0b56dff8d2181addd9Brian Paul texImg = _mesa_get_tex_image(st->ctx, texObj, target, 0); 18918f6d9e12be0be086ca2aab0b56dff8d2181addd9Brian Paul 18928f6d9e12be0be086ca2aab0b56dff8d2181addd9Brian Paul _mesa_init_teximage_fields(st->ctx, target, texImg, 18938f6d9e12be0be086ca2aab0b56dff8d2181addd9Brian Paul 16, 16, 1, 0, /* w, h, d, border */ 18948f6d9e12be0be086ca2aab0b56dff8d2181addd9Brian Paul GL_RGBA); 18958f6d9e12be0be086ca2aab0b56dff8d2181addd9Brian Paul 18968f6d9e12be0be086ca2aab0b56dff8d2181addd9Brian Paul st_TexImage(st->ctx, 2, target, 18978f6d9e12be0be086ca2aab0b56dff8d2181addd9Brian Paul 0, GL_RGBA, /* level, intformat */ 18988f6d9e12be0be086ca2aab0b56dff8d2181addd9Brian Paul 16, 16, 1, 0, /* w, h, d, border */ 18998f6d9e12be0be086ca2aab0b56dff8d2181addd9Brian Paul GL_RGBA, GL_UNSIGNED_BYTE, pixels, 19008f6d9e12be0be086ca2aab0b56dff8d2181addd9Brian Paul &st->ctx->DefaultPacking, 19018f6d9e12be0be086ca2aab0b56dff8d2181addd9Brian Paul texObj, texImg, 19028f6d9e12be0be086ca2aab0b56dff8d2181addd9Brian Paul 0, 0); 19038f6d9e12be0be086ca2aab0b56dff8d2181addd9Brian Paul 19048f6d9e12be0be086ca2aab0b56dff8d2181addd9Brian Paul texObj->MinFilter = GL_NEAREST; 19058f6d9e12be0be086ca2aab0b56dff8d2181addd9Brian Paul texObj->MagFilter = GL_NEAREST; 19068f6d9e12be0be086ca2aab0b56dff8d2181addd9Brian Paul texObj->_Complete = GL_TRUE; 19078f6d9e12be0be086ca2aab0b56dff8d2181addd9Brian Paul 19088f6d9e12be0be086ca2aab0b56dff8d2181addd9Brian Paul st->default_texture = texObj; 19098f6d9e12be0be086ca2aab0b56dff8d2181addd9Brian Paul } 19108f6d9e12be0be086ca2aab0b56dff8d2181addd9Brian Paul return st->default_texture; 19118f6d9e12be0be086ca2aab0b56dff8d2181addd9Brian Paul} 19128f6d9e12be0be086ca2aab0b56dff8d2181addd9Brian Paul 19138f6d9e12be0be086ca2aab0b56dff8d2181addd9Brian Paul 19146da9234fd437f97267e7831f034c78b31156d939Brianvoid 19156da9234fd437f97267e7831f034c78b31156d939Brianst_init_texture_functions(struct dd_function_table *functions) 191624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 191724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian functions->ChooseTextureFormat = st_ChooseTextureFormat; 191824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian functions->TexImage1D = st_TexImage1D; 191924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian functions->TexImage2D = st_TexImage2D; 192024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian functions->TexImage3D = st_TexImage3D; 192124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian functions->TexSubImage1D = st_TexSubImage1D; 192224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian functions->TexSubImage2D = st_TexSubImage2D; 192324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian functions->TexSubImage3D = st_TexSubImage3D; 1924578230dbbffbf5317d6002d1023dcd62b57186f5Jakob Bornecrantz functions->CompressedTexSubImage1D = st_CompressedTexSubImage1D; 1925a4fd94a54a75a3418462c30f1240ab50b5f24090Jakob Bornecrantz functions->CompressedTexSubImage2D = st_CompressedTexSubImage2D; 1926578230dbbffbf5317d6002d1023dcd62b57186f5Jakob Bornecrantz functions->CompressedTexSubImage3D = st_CompressedTexSubImage3D; 192724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian functions->CopyTexImage1D = st_CopyTexImage1D; 192824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian functions->CopyTexImage2D = st_CopyTexImage2D; 192924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian functions->CopyTexSubImage1D = st_CopyTexSubImage1D; 193024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian functions->CopyTexSubImage2D = st_CopyTexSubImage2D; 1931038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian functions->CopyTexSubImage3D = st_CopyTexSubImage3D; 193262abcb9aacc33218d0143a743c738435794b32a9Brian functions->GenerateMipmap = st_generate_mipmap; 1933038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian 193424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian functions->GetTexImage = st_GetTexImage; 193524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 193624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian /* compressed texture functions */ 193724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian functions->CompressedTexImage2D = st_CompressedTexImage2D; 193824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian functions->GetCompressedTexImage = st_GetCompressedTexImage; 193924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 194024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian functions->NewTextureObject = st_NewTextureObject; 194124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian functions->NewTextureImage = st_NewTextureImage; 194224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian functions->DeleteTexture = st_DeleteTextureObject; 194324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian functions->FreeTexImageData = st_FreeTextureImageData; 194424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian functions->UpdateTexturePalette = 0; 194524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 194624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian functions->TextureMemCpy = do_memcpy; 1947f8549e8f4f8bdfebcb4e0a2754df59b3fe4fdff7Brian 1948f8549e8f4f8bdfebcb4e0a2754df59b3fe4fdff7Brian /* XXX Temporary until we can query pipe's texture sizes */ 1949f8549e8f4f8bdfebcb4e0a2754df59b3fe4fdff7Brian functions->TestProxyTexImage = _mesa_test_proxy_teximage; 195024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 1951