st_cb_texture.c revision 2a39dbe7364af5444b1eb43650dfc31ed09257dc
124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian/************************************************************************** 224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * 324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. 424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * All Rights Reserved. 524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * 624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * Permission is hereby granted, free of charge, to any person obtaining a 724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * copy of this software and associated documentation files (the 824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * "Software"), to deal in the Software without restriction, including 924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * without limitation the rights to use, copy, modify, merge, publish, 1024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * distribute, sub license, and/or sell copies of the Software, and to 1124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * permit persons to whom the Software is furnished to do so, subject to 1224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * the following conditions: 1324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * 1424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * The above copyright notice and this permission notice (including the 1524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * next paragraph) shall be included in all copies or substantial portions 1624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * of the Software. 1724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * 1824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 1924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 2024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 2124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR 2224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 2324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 2424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 2524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * 2624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian **************************************************************************/ 2724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 2824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#include "main/imports.h" 2924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#include "main/convolve.h" 3024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#include "main/enums.h" 3124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#include "main/image.h" 3224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#include "main/macros.h" 332440ff74d69a8caf49b05a960b4c7e282a96565eBrian#include "main/mipmap.h" 34cc94863429d8a6cef8dbf861e78701a458d30f5aBrian Paul#include "main/pixel.h" 3524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#include "main/texcompress.h" 3624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#include "main/texformat.h" 3724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#include "main/teximage.h" 3824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#include "main/texobj.h" 3924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#include "main/texstore.h" 4024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 4124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#include "state_tracker/st_context.h" 42b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian#include "state_tracker/st_cb_fbo.h" 4324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#include "state_tracker/st_cb_texture.h" 44f8ab24760d0d3f07e9ee81c98207ddf92dfe74daBrian#include "state_tracker/st_format.h" 4502250c855fbec5299a2d6118fefa0523ec73654cMichel Dänzer#include "state_tracker/st_public.h" 46753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer#include "state_tracker/st_texture.h" 4762abcb9aacc33218d0143a743c738435794b32a9Brian#include "state_tracker/st_gen_mipmap.h" 4824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 4924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#include "pipe/p_context.h" 50b245840b86cf877c9b8d666edf229364a84f1deaBrian#include "pipe/p_defines.h" 5111a80160fd60d1eb1541b49128c659526a5d8ac8Michel Dänzer#include "pipe/p_inlines.h" 526acd63a4980951727939c0dd545a0324965b3834José Fonseca#include "util/p_tile.h" 533c0dc8242b64518d5635263ba65b39afa919dd86Michel Dänzer#include "util/u_blit.h" 5424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 5524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 5624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#define DBG if (0) printf 5724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 5824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 5924df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic INLINE struct st_texture_image * 6024df8f895fe8807aa2ba058e71bd40adfc01d21eBrianst_texture_image(struct gl_texture_image *img) 6124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 6224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian return (struct st_texture_image *) img; 6324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 6424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 6524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 661c5f27a18b775b3784fcd265d60e0affa0b31581Michel Dänzerstatic enum pipe_texture_target 675390a43ce06b27f6d54bc5f237aa305b6948f2afBriangl_target_to_pipe(GLenum target) 685390a43ce06b27f6d54bc5f237aa305b6948f2afBrian{ 695390a43ce06b27f6d54bc5f237aa305b6948f2afBrian switch (target) { 705390a43ce06b27f6d54bc5f237aa305b6948f2afBrian case GL_TEXTURE_1D: 715390a43ce06b27f6d54bc5f237aa305b6948f2afBrian return PIPE_TEXTURE_1D; 725390a43ce06b27f6d54bc5f237aa305b6948f2afBrian 735390a43ce06b27f6d54bc5f237aa305b6948f2afBrian case GL_TEXTURE_2D: 745390a43ce06b27f6d54bc5f237aa305b6948f2afBrian case GL_TEXTURE_RECTANGLE_NV: 755390a43ce06b27f6d54bc5f237aa305b6948f2afBrian return PIPE_TEXTURE_2D; 765390a43ce06b27f6d54bc5f237aa305b6948f2afBrian 775390a43ce06b27f6d54bc5f237aa305b6948f2afBrian case GL_TEXTURE_3D: 785390a43ce06b27f6d54bc5f237aa305b6948f2afBrian return PIPE_TEXTURE_3D; 795390a43ce06b27f6d54bc5f237aa305b6948f2afBrian 805390a43ce06b27f6d54bc5f237aa305b6948f2afBrian case GL_TEXTURE_CUBE_MAP_ARB: 815390a43ce06b27f6d54bc5f237aa305b6948f2afBrian return PIPE_TEXTURE_CUBE; 825390a43ce06b27f6d54bc5f237aa305b6948f2afBrian 835390a43ce06b27f6d54bc5f237aa305b6948f2afBrian default: 845390a43ce06b27f6d54bc5f237aa305b6948f2afBrian assert(0); 855390a43ce06b27f6d54bc5f237aa305b6948f2afBrian return 0; 865390a43ce06b27f6d54bc5f237aa305b6948f2afBrian } 875390a43ce06b27f6d54bc5f237aa305b6948f2afBrian} 885390a43ce06b27f6d54bc5f237aa305b6948f2afBrian 895390a43ce06b27f6d54bc5f237aa305b6948f2afBrian 90afc54983370033b65e3a7cbb29bd9c87156f0881Brian/** 91afc54983370033b65e3a7cbb29bd9c87156f0881Brian * Return nominal bytes per texel for a compressed format, 0 for non-compressed 92afc54983370033b65e3a7cbb29bd9c87156f0881Brian * format. 93afc54983370033b65e3a7cbb29bd9c87156f0881Brian */ 9424df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic int 9514b98343309fdcff3514f05020303f7b40e83a4aBriancompressed_num_bytes(GLuint mesaFormat) 9624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 9724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian switch(mesaFormat) { 9824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian case MESA_FORMAT_RGB_FXT1: 9924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian case MESA_FORMAT_RGBA_FXT1: 10024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian case MESA_FORMAT_RGB_DXT1: 10124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian case MESA_FORMAT_RGBA_DXT1: 102afc54983370033b65e3a7cbb29bd9c87156f0881Brian return 2; 10324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian case MESA_FORMAT_RGBA_DXT3: 10424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian case MESA_FORMAT_RGBA_DXT5: 105afc54983370033b65e3a7cbb29bd9c87156f0881Brian return 4; 10624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian default: 107afc54983370033b65e3a7cbb29bd9c87156f0881Brian return 0; 10824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 10924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 11024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 11124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 11224df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic GLboolean 11324df8f895fe8807aa2ba058e71bd40adfc01d21eBrianst_IsTextureResident(GLcontext * ctx, struct gl_texture_object *texObj) 11424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 11524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#if 0 11624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian struct intel_context *intel = intel_context(ctx); 11724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian struct st_texture_object *stObj = st_texture_object(texObj); 11824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 11924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian return 120753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer stObj->pt && 121753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer stObj->pt->region && 122753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer intel_is_region_resident(intel, stObj->pt->region); 12324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#endif 12424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian return 1; 12524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 12624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 12724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 12824df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic struct gl_texture_image * 12924df8f895fe8807aa2ba058e71bd40adfc01d21eBrianst_NewTextureImage(GLcontext * ctx) 13024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 13124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian DBG("%s\n", __FUNCTION__); 13224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian (void) ctx; 13324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian return (struct gl_texture_image *) CALLOC_STRUCT(st_texture_image); 13424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 13524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 13624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 13724df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic struct gl_texture_object * 13824df8f895fe8807aa2ba058e71bd40adfc01d21eBrianst_NewTextureObject(GLcontext * ctx, GLuint name, GLenum target) 13924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 14024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian struct st_texture_object *obj = CALLOC_STRUCT(st_texture_object); 14124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 14224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian DBG("%s\n", __FUNCTION__); 14324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian _mesa_initialize_texture_object(&obj->base, name, target); 14424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 14524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian return &obj->base; 14624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 14724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 14824df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void 14924df8f895fe8807aa2ba058e71bd40adfc01d21eBrianst_DeleteTextureObject(GLcontext *ctx, 1506f715dcc219071e574e363a9db4365c9c31ebbd3Brian struct gl_texture_object *texObj) 15124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 15224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian struct st_texture_object *stObj = st_texture_object(texObj); 153753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer if (stObj->pt) 1546f715dcc219071e574e363a9db4365c9c31ebbd3Brian pipe_texture_release(&stObj->pt); 15524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 15624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian _mesa_delete_texture_object(ctx, texObj); 15724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 15824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 15924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 16024df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void 16124df8f895fe8807aa2ba058e71bd40adfc01d21eBrianst_FreeTextureImageData(GLcontext * ctx, struct gl_texture_image *texImage) 16224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 16324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian struct st_texture_image *stImage = st_texture_image(texImage); 16424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 16524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian DBG("%s\n", __FUNCTION__); 16624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 167753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer if (stImage->pt) { 1686f715dcc219071e574e363a9db4365c9c31ebbd3Brian pipe_texture_release(&stImage->pt); 16924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 17024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 17124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian if (texImage->Data) { 17224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian free(texImage->Data); 17324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian texImage->Data = NULL; 17424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 17524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 17624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 17724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 17824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian/* ================================================================ 17924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * From linux kernel i386 header files, copes with odd sizes better 18024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * than COPY_DWORDS would: 18124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * XXX Put this in src/mesa/main/imports.h ??? 18224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 18324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#if defined(i386) || defined(__i386__) 18424df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic INLINE void * 18524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian__memcpy(void *to, const void *from, size_t n) 18624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 18724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian int d0, d1, d2; 18824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian __asm__ __volatile__("rep ; movsl\n\t" 18924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian "testb $2,%b4\n\t" 19024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian "je 1f\n\t" 19124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian "movsw\n" 19224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian "1:\ttestb $1,%b4\n\t" 19324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian "je 2f\n\t" 19424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian "movsb\n" "2:":"=&c"(d0), "=&D"(d1), "=&S"(d2) 19524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian :"0"(n / 4), "q"(n), "1"((long) to), "2"((long) from) 19624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian :"memory"); 19724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian return (to); 19824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 19924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#else 20024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#define __memcpy(a,b,c) memcpy(a,b,c) 20124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#endif 20224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 20324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 20424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian/* The system memcpy (at least on ubuntu 5.10) has problems copying 20524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * to agp (writecombined) memory from a source which isn't 64-byte 20624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * aligned - there is a 4x performance falloff. 20724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * 20824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * The x86 __memcpy is immune to this but is slightly slower 20924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * (10%-ish) than the system memcpy. 21024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * 21124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * The sse_memcpy seems to have a slight cliff at 64/32 bytes, but 21224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * isn't much faster than x86_memcpy for agp copies. 21324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * 21424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * TODO: switch dynamically. 21524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 21624df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void * 21724df8f895fe8807aa2ba058e71bd40adfc01d21eBriando_memcpy(void *dest, const void *src, size_t n) 21824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 21924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian if ((((unsigned) src) & 63) || (((unsigned) dest) & 63)) { 22024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian return __memcpy(dest, src, n); 22124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 22224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian else 22324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian return memcpy(dest, src, n); 22424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 22524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 22624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 227753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer/* Functions to store texture images. Where possible, textures 22824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * will be created or further instantiated with image data, otherwise 22924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * images will be stored in malloc'd memory. A validation step is 230753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer * required to pull those images into a texture, or otherwise 23124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * decide a fallback is required. 23224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 23324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 23424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 23524df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic int 23624df8f895fe8807aa2ba058e71bd40adfc01d21eBrianlogbase2(int n) 23724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 23824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLint i = 1; 23924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLint log2 = 0; 24024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 24124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian while (n > i) { 24224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian i *= 2; 24324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian log2++; 24424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 24524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 24624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian return log2; 24724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 24824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 24924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 250f52f5136e6eed23e55098681e5b082cc452136d6Brian/** 251f52f5136e6eed23e55098681e5b082cc452136d6Brian * Allocate a pipe_texture object for the given st_texture_object using 252f52f5136e6eed23e55098681e5b082cc452136d6Brian * the given st_texture_image to guess the mipmap size/levels. 253f52f5136e6eed23e55098681e5b082cc452136d6Brian * 254f52f5136e6eed23e55098681e5b082cc452136d6Brian * [comments...] 255f52f5136e6eed23e55098681e5b082cc452136d6Brian * Otherwise, store it in memory if (Border != 0) or (any dimension == 25624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * 1). 25724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * 258753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer * Otherwise, if max_level >= level >= min_level, create texture with 259753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer * space for images from min_level down to max_level. 26024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * 261753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer * Otherwise, create texture with space for images from (level 0)..(1x1). 262753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer * Consider pruning this texture at a validation if the saving is worth it. 26324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 26424df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void 265753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzerguess_and_alloc_texture(struct st_context *st, 266753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer struct st_texture_object *stObj, 267afc54983370033b65e3a7cbb29bd9c87156f0881Brian const struct st_texture_image *stImage) 26824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 26924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLuint firstLevel; 27024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLuint lastLevel; 27145cc35e77600af8628393475405160e26d56d421Brian Paul GLuint width = stImage->base.Width2; /* size w/out border */ 27245cc35e77600af8628393475405160e26d56d421Brian Paul GLuint height = stImage->base.Height2; 27345cc35e77600af8628393475405160e26d56d421Brian Paul GLuint depth = stImage->base.Depth2; 27424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLuint i, comp_byte = 0; 27524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 27624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian DBG("%s\n", __FUNCTION__); 27724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 278f52f5136e6eed23e55098681e5b082cc452136d6Brian assert(!stObj->pt); 279f52f5136e6eed23e55098681e5b082cc452136d6Brian 28045cc35e77600af8628393475405160e26d56d421Brian Paul if (stObj->pt && 28145cc35e77600af8628393475405160e26d56d421Brian Paul stImage->level > stObj->base.BaseLevel && 28214b98343309fdcff3514f05020303f7b40e83a4aBrian (stImage->base.Width == 1 || 28314b98343309fdcff3514f05020303f7b40e83a4aBrian (stObj->base.Target != GL_TEXTURE_1D && 28414b98343309fdcff3514f05020303f7b40e83a4aBrian stImage->base.Height == 1) || 28514b98343309fdcff3514f05020303f7b40e83a4aBrian (stObj->base.Target == GL_TEXTURE_3D && 28614b98343309fdcff3514f05020303f7b40e83a4aBrian stImage->base.Depth == 1))) 28724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian return; 28824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 28924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian /* If this image disrespects BaseLevel, allocate from level zero. 29024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * Usually BaseLevel == 0, so it's unlikely to happen. 29124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 29214b98343309fdcff3514f05020303f7b40e83a4aBrian if (stImage->level < stObj->base.BaseLevel) 29324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian firstLevel = 0; 29424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian else 29514b98343309fdcff3514f05020303f7b40e83a4aBrian firstLevel = stObj->base.BaseLevel; 29624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 29724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 29824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian /* Figure out image dimensions at start level. 29924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 30014b98343309fdcff3514f05020303f7b40e83a4aBrian for (i = stImage->level; i > firstLevel; i--) { 30145cc35e77600af8628393475405160e26d56d421Brian Paul if (width != 1) 30245cc35e77600af8628393475405160e26d56d421Brian Paul width <<= 1; 30324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian if (height != 1) 30424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian height <<= 1; 30524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian if (depth != 1) 30624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian depth <<= 1; 30724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 30824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 309296378b6c8b205048244746e260739448c4ee590Brian Paul if (width == 0 || height == 0 || depth == 0) { 310296378b6c8b205048244746e260739448c4ee590Brian Paul /* no texture needed */ 311296378b6c8b205048244746e260739448c4ee590Brian Paul return; 312296378b6c8b205048244746e260739448c4ee590Brian Paul } 313296378b6c8b205048244746e260739448c4ee590Brian Paul 31424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian /* Guess a reasonable value for lastLevel. This is probably going 31524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * to be wrong fairly often and might mean that we have to look at 31624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * resizable buffers, or require that buffers implement lazy 31724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * pagetable arrangements. 31824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 31914b98343309fdcff3514f05020303f7b40e83a4aBrian if ((stObj->base.MinFilter == GL_NEAREST || 32014b98343309fdcff3514f05020303f7b40e83a4aBrian stObj->base.MinFilter == GL_LINEAR) && 32114b98343309fdcff3514f05020303f7b40e83a4aBrian stImage->level == firstLevel) { 32224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian lastLevel = firstLevel; 32324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 32424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian else { 325f52f5136e6eed23e55098681e5b082cc452136d6Brian GLuint l2width = logbase2(width); 326f52f5136e6eed23e55098681e5b082cc452136d6Brian GLuint l2height = logbase2(height); 327f52f5136e6eed23e55098681e5b082cc452136d6Brian GLuint l2depth = logbase2(depth); 32824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian lastLevel = firstLevel + MAX2(MAX2(l2width, l2height), l2depth); 32924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 33024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 33114b98343309fdcff3514f05020303f7b40e83a4aBrian if (stImage->base.IsCompressed) 33214b98343309fdcff3514f05020303f7b40e83a4aBrian comp_byte = compressed_num_bytes(stImage->base.TexFormat->MesaFormat); 333f52f5136e6eed23e55098681e5b082cc452136d6Brian 334753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer stObj->pt = st_texture_create(st, 3355390a43ce06b27f6d54bc5f237aa305b6948f2afBrian gl_target_to_pipe(stObj->base.Target), 336753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer st_mesa_format_to_pipe_format(stImage->base.TexFormat->MesaFormat), 3375390a43ce06b27f6d54bc5f237aa305b6948f2afBrian lastLevel, 3385390a43ce06b27f6d54bc5f237aa305b6948f2afBrian width, 3395390a43ce06b27f6d54bc5f237aa305b6948f2afBrian height, 3405390a43ce06b27f6d54bc5f237aa305b6948f2afBrian depth, 341a73ae3d5eb8419feab5aea26573aa41b72f941ebKeith Whitwell comp_byte, 342a73ae3d5eb8419feab5aea26573aa41b72f941ebKeith Whitwell ( PIPE_TEXTURE_USAGE_RENDER_TARGET | 343a73ae3d5eb8419feab5aea26573aa41b72f941ebKeith Whitwell PIPE_TEXTURE_USAGE_SAMPLER )); 34424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 34524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian DBG("%s - success\n", __FUNCTION__); 34624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 34724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 34824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 34924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian/* There are actually quite a few combinations this will work for, 35024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * more than what I've listed here. 35124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 35224df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic GLboolean 35324df8f895fe8807aa2ba058e71bd40adfc01d21eBriancheck_pbo_format(GLint internalFormat, 35424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLenum format, GLenum type, 35524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian const struct gl_texture_format *mesa_format) 35624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 35724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian switch (internalFormat) { 35824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian case 4: 35924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian case GL_RGBA: 36024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian return (format == GL_BGRA && 36124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian (type == GL_UNSIGNED_BYTE || 36224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian type == GL_UNSIGNED_INT_8_8_8_8_REV) && 36324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian mesa_format == &_mesa_texformat_argb8888); 36424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian case 3: 36524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian case GL_RGB: 36624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian return (format == GL_RGB && 36724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian type == GL_UNSIGNED_SHORT_5_6_5 && 36824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian mesa_format == &_mesa_texformat_rgb565); 36924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian case GL_YCBCR_MESA: 37024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian return (type == GL_UNSIGNED_SHORT_8_8_MESA || type == GL_UNSIGNED_BYTE); 37124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian default: 37224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian return GL_FALSE; 37324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 37424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 37524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 37624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 37724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian/* XXX: Do this for TexSubImage also: 37824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 37924df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic GLboolean 38024df8f895fe8807aa2ba058e71bd40adfc01d21eBriantry_pbo_upload(GLcontext *ctx, 38114b98343309fdcff3514f05020303f7b40e83a4aBrian struct st_texture_image *stImage, 38224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian const struct gl_pixelstore_attrib *unpack, 38324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLint internalFormat, 38424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLint width, GLint height, 38524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLenum format, GLenum type, const void *pixels) 38624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 38724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian return GL_FALSE; /* XXX fix flushing/locking/blitting below */ 38824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#if 000 38924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian struct intel_context *intel = intel_context(ctx); 39024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian struct intel_buffer_object *pbo = intel_buffer_object(unpack->BufferObj); 39124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLuint src_offset, src_stride; 39224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLuint dst_offset, dst_stride; 39324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 39424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian if (!pbo || 39524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian ctx._ImageTransferState || 39624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian unpack->SkipPixels || unpack->SkipRows) { 39724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian _mesa_printf("%s: failure 1\n", __FUNCTION__); 39824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian return GL_FALSE; 39924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 40024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 40124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian src_offset = (GLuint) pixels; 40224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 40324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian if (unpack->RowLength > 0) 40424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian src_stride = unpack->RowLength; 40524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian else 40624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian src_stride = width; 40724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 408753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer dst_offset = st_texture_image_offset(stImage->pt, 40914b98343309fdcff3514f05020303f7b40e83a4aBrian stImage->face, 41014b98343309fdcff3514f05020303f7b40e83a4aBrian stImage->level); 41124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 412753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer dst_stride = stImage->pt->pitch; 41324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 41424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian { 41524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian struct _DriBufferObject *src_buffer = 41624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian intel_bufferobj_buffer(intel, pbo, INTEL_READ); 41724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 41824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian /* Temporary hack: cast to _DriBufferObject: 41924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 42024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian struct _DriBufferObject *dst_buffer = 421753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer (struct _DriBufferObject *)stImage->pt->region->buffer; 42224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 42324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 42424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian intelEmitCopyBlit(intel, 425753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer stImage->pt->cpp, 42624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian src_stride, src_buffer, src_offset, 42724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian dst_stride, dst_buffer, dst_offset, 42824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 0, 0, 0, 0, width, height, 42924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GL_COPY); 43024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 43124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 43224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian return GL_TRUE; 43324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#endif 43424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 43524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 43624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 437212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian/** 438212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian * Adjust pixel unpack params and image dimensions to strip off the 439212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian * texture border. 440212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian * Gallium doesn't support texture borders. They've seldem been used 441212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian * and seldom been implemented correctly anyway. 442212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian * \param unpackNew returns the new pixel unpack parameters 443212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian */ 444212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brianstatic void 445212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brianstrip_texture_border(GLint border, 446212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian GLint *width, GLint *height, GLint *depth, 447212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian const struct gl_pixelstore_attrib *unpack, 448212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian struct gl_pixelstore_attrib *unpackNew) 449212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian{ 450212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian assert(border > 0); /* sanity check */ 451212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian 452212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian *unpackNew = *unpack; 453212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian 454212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian if (unpackNew->RowLength == 0) 455212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian unpackNew->RowLength = *width; 456212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian 457212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian if (depth && unpackNew->ImageHeight == 0) 458212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian unpackNew->ImageHeight = *height; 459212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian 460212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian unpackNew->SkipPixels += border; 461212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian if (height) 462212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian unpackNew->SkipRows += border; 463212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian if (depth) 464212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian unpackNew->SkipImages += border; 465212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian 466212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian assert(*width >= 3); 467212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian *width = *width - 2 * border; 468212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian if (height && *height >= 3) 469212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian *height = *height - 2 * border; 470212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian if (depth && *depth >= 3) 471212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian *depth = *depth - 2 * border; 472212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian} 473212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian 47424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 47524df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void 47624df8f895fe8807aa2ba058e71bd40adfc01d21eBrianst_TexImage(GLcontext * ctx, 477afc54983370033b65e3a7cbb29bd9c87156f0881Brian GLint dims, 478afc54983370033b65e3a7cbb29bd9c87156f0881Brian GLenum target, GLint level, 479afc54983370033b65e3a7cbb29bd9c87156f0881Brian GLint internalFormat, 480afc54983370033b65e3a7cbb29bd9c87156f0881Brian GLint width, GLint height, GLint depth, 481afc54983370033b65e3a7cbb29bd9c87156f0881Brian GLint border, 482afc54983370033b65e3a7cbb29bd9c87156f0881Brian GLenum format, GLenum type, const void *pixels, 483afc54983370033b65e3a7cbb29bd9c87156f0881Brian const struct gl_pixelstore_attrib *unpack, 484afc54983370033b65e3a7cbb29bd9c87156f0881Brian struct gl_texture_object *texObj, 485afc54983370033b65e3a7cbb29bd9c87156f0881Brian struct gl_texture_image *texImage, 486afc54983370033b65e3a7cbb29bd9c87156f0881Brian GLsizei imageSize, int compressed) 48724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 48814b98343309fdcff3514f05020303f7b40e83a4aBrian struct st_texture_object *stObj = st_texture_object(texObj); 48914b98343309fdcff3514f05020303f7b40e83a4aBrian struct st_texture_image *stImage = st_texture_image(texImage); 490212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian GLint postConvWidth, postConvHeight; 49124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLint texelBytes, sizeInBytes; 49224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLuint dstRowStride; 493212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian struct gl_pixelstore_attrib unpackNB; 49424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 49524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian DBG("%s target %s level %d %dx%dx%d border %d\n", __FUNCTION__, 49624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian _mesa_lookup_enum_by_nr(target), level, width, height, depth, border); 49724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 498212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian /* gallium does not support texture borders, strip it off */ 499212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian if (border) { 500212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian strip_texture_border(border, &width, &height, &depth, 501212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian unpack, &unpackNB); 502212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian unpack = &unpackNB; 50321989edd55409d72ee55187f4f9062496ca3fbf8Brian Paul texImage->Width = width; 50421989edd55409d72ee55187f4f9062496ca3fbf8Brian Paul texImage->Height = height; 50521989edd55409d72ee55187f4f9062496ca3fbf8Brian Paul texImage->Depth = depth; 50621989edd55409d72ee55187f4f9062496ca3fbf8Brian Paul texImage->Border = 0; 507212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian border = 0; 508212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian } 509212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian 510212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian postConvWidth = width; 511212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian postConvHeight = height; 512212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian 513cfe9e66f2bc596c43760911e7c1604bb32cdee28Brian stImage->face = _mesa_tex_target_to_face(target); 51414b98343309fdcff3514f05020303f7b40e83a4aBrian stImage->level = level; 51524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 51624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian if (ctx->_ImageTransferState & IMAGE_CONVOLUTION_BIT) { 51724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian _mesa_adjust_image_for_convolution(ctx, dims, &postConvWidth, 51824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian &postConvHeight); 51924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 52024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 52124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian /* choose the texture format */ 52224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian texImage->TexFormat = st_ChooseTextureFormat(ctx, internalFormat, 523afc54983370033b65e3a7cbb29bd9c87156f0881Brian format, type); 52424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 52524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian _mesa_set_fetch_functions(texImage, dims); 52624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 52724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian if (texImage->TexFormat->TexelBytes == 0) { 52824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian /* must be a compressed format */ 52924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian texelBytes = 0; 53024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian texImage->IsCompressed = GL_TRUE; 53124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian texImage->CompressedSize = 53224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian ctx->Driver.CompressedTextureSize(ctx, texImage->Width, 53324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian texImage->Height, texImage->Depth, 53424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian texImage->TexFormat->MesaFormat); 535afc54983370033b65e3a7cbb29bd9c87156f0881Brian } 536afc54983370033b65e3a7cbb29bd9c87156f0881Brian else { 53724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian texelBytes = texImage->TexFormat->TexelBytes; 53824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 53924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian /* Minimum pitch of 32 bytes */ 54024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian if (postConvWidth * texelBytes < 32) { 54124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian postConvWidth = 32 / texelBytes; 54224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian texImage->RowStride = postConvWidth; 54324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 54424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 5457585b4ceb8fed862c07f50af8030a6f0eb8a8321Brian /* we'll set RowStride elsewhere when the texture is a "mapped" state */ 5467585b4ceb8fed862c07f50af8030a6f0eb8a8321Brian /*assert(texImage->RowStride == postConvWidth);*/ 54724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 54824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 54924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian /* Release the reference to a potentially orphaned buffer. 55024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * Release any old malloced memory. 55124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 552753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer if (stImage->pt) { 5536f715dcc219071e574e363a9db4365c9c31ebbd3Brian pipe_texture_release(&stImage->pt); 55424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian assert(!texImage->Data); 55524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 55624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian else if (texImage->Data) { 55724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian _mesa_align_free(texImage->Data); 55824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 55924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 5604da1cdf78fa3b954840650fa46cf72da5daf149fBrian /* If this is the only mipmap level in the texture, could call 56124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * bmBufferData with NULL data to free the old block and avoid 56224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * waiting on any outstanding fences. 56324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 564753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer if (stObj->pt && 565d4074c509b5d28be0a2ec51d40329e1aed7047efMichel Dänzer (stObj->teximage_realloc || 566d4074c509b5d28be0a2ec51d40329e1aed7047efMichel Dänzer (/*stObj->pt->first_level == level &&*/ 567d4074c509b5d28be0a2ec51d40329e1aed7047efMichel Dänzer stObj->pt->last_level == level && 568d4074c509b5d28be0a2ec51d40329e1aed7047efMichel Dänzer stObj->pt->target != PIPE_TEXTURE_CUBE && 569d4074c509b5d28be0a2ec51d40329e1aed7047efMichel Dänzer !st_texture_match_image(stObj->pt, &stImage->base, 570d4074c509b5d28be0a2ec51d40329e1aed7047efMichel Dänzer stImage->face, stImage->level)))) { 57124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 57224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian DBG("release it\n"); 5736f715dcc219071e574e363a9db4365c9c31ebbd3Brian pipe_texture_release(&stObj->pt); 574753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer assert(!stObj->pt); 575d4074c509b5d28be0a2ec51d40329e1aed7047efMichel Dänzer stObj->teximage_realloc = FALSE; 57624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 57724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 578753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer if (!stObj->pt) { 579753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer guess_and_alloc_texture(ctx->st, stObj, stImage); 580753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer if (!stObj->pt) { 5813b3774b1227743147159676795b542c0eb7c2bdfBrian Paul _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage"); 5823b3774b1227743147159676795b542c0eb7c2bdfBrian Paul return; 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 59924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#if 0 /* XXX FIX when st_buffer_objects are in place */ 60024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian /* PBO fastpaths: 60124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 60224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian if (dims <= 2 && 603753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer stImage->pt && 60424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian intel_buffer_object(unpack->BufferObj) && 60524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian check_pbo_format(internalFormat, format, 606753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer type, texImage->TexFormat)) { 60724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 60824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian DBG("trying pbo upload\n"); 60924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 61024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 61124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 61224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian /* Otherwise, attempt to use the blitter for PBO image uploads. 61324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 61414b98343309fdcff3514f05020303f7b40e83a4aBrian if (try_pbo_upload(intel, stImage, unpack, 61524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian internalFormat, 61624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian width, height, format, type, pixels)) { 61724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian DBG("pbo upload succeeded\n"); 61824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian return; 61924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 62024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 62124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian DBG("pbo upload failed\n"); 62224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 62324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#else 62424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian (void) try_pbo_upload; 62524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian (void) check_pbo_format; 62624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#endif 62724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 62824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 629987d59bb83e9e08192563e5f1b52949c5511053cMichel Dänzer /* st_CopyTexImage calls this function with pixels == NULL, with 630753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer * the expectation that the texture will be set up but nothing 63124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * more will be done. This is where those calls return: 63224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 63324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian if (compressed) { 63424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian pixels = _mesa_validate_pbo_compressed_teximage(ctx, imageSize, pixels, 63524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian unpack, 63624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian "glCompressedTexImage"); 63724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } else { 63824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian pixels = _mesa_validate_pbo_teximage(ctx, dims, width, height, 1, 63924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian format, type, 64024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian pixels, unpack, "glTexImage"); 64124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 64224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian if (!pixels) 64324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian return; 64424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 645753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer if (stImage->pt) { 646c9ed86a96483063f3d6789ed16645a3dca77d726Keith Whitwell texImage->Data = st_texture_image_map(ctx->st, stImage, 0, 647c9ed86a96483063f3d6789ed16645a3dca77d726Keith Whitwell PIPE_BUFFER_USAGE_CPU_WRITE); 6482a39dbe7364af5444b1eb43650dfc31ed09257dcBrian Paul if (stImage->surface) 6492a39dbe7364af5444b1eb43650dfc31ed09257dcBrian Paul dstRowStride = stImage->surface->pitch * stImage->surface->cpp; 65024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 65124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian else { 65224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian /* Allocate regular memory and store the image there temporarily. */ 65324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian if (texImage->IsCompressed) { 65424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian sizeInBytes = texImage->CompressedSize; 65524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian dstRowStride = 65624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian _mesa_compressed_row_stride(texImage->TexFormat->MesaFormat, width); 65724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian assert(dims != 3); 65824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 65924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian else { 66024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian dstRowStride = postConvWidth * texelBytes; 66124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian sizeInBytes = depth * dstRowStride * postConvHeight; 66224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 66324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 66424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian texImage->Data = malloc(sizeInBytes); 66524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 66624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 6672a39dbe7364af5444b1eb43650dfc31ed09257dcBrian Paul if (!texImage->Data) { 6682a39dbe7364af5444b1eb43650dfc31ed09257dcBrian Paul _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage"); 6692a39dbe7364af5444b1eb43650dfc31ed09257dcBrian Paul return; 6702a39dbe7364af5444b1eb43650dfc31ed09257dcBrian Paul } 6712a39dbe7364af5444b1eb43650dfc31ed09257dcBrian Paul 67224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian DBG("Upload image %dx%dx%d row_len %x pitch %x\n", 67324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian width, height, depth, width * texelBytes, dstRowStride); 67424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 67524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian /* Copy data. Would like to know when it's ok for us to eg. use 67624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * the blitter to copy. Or, use the hardware to do the format 67724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * conversion and copy: 67824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 67924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian if (compressed) { 680afc54983370033b65e3a7cbb29bd9c87156f0881Brian memcpy(texImage->Data, pixels, imageSize); 68124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 682753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer else { 683753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer GLuint srcImageStride = _mesa_image_image_stride(unpack, width, height, 684753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer format, type); 685753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer int i; 6865823f99d0fbc054b87aeb1bc15d413d3eadd27a8Brian const GLubyte *src = (const GLubyte *) pixels; 687753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer 688753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer for (i = 0; i++ < depth;) { 689753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer if (!texImage->TexFormat->StoreImage(ctx, dims, 690753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer texImage->_BaseFormat, 691753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer texImage->TexFormat, 692753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer texImage->Data, 693753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer 0, 0, 0, /* dstX/Y/Zoffset */ 694753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer dstRowStride, 695753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer texImage->ImageOffsets, 696753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer width, height, 1, 6975823f99d0fbc054b87aeb1bc15d413d3eadd27a8Brian format, type, src, unpack)) { 698753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage"); 699753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer } 700753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer 701753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer if (stImage->pt && i < depth) { 702c9ed86a96483063f3d6789ed16645a3dca77d726Keith Whitwell st_texture_image_unmap(ctx->st, stImage); 703c9ed86a96483063f3d6789ed16645a3dca77d726Keith Whitwell texImage->Data = st_texture_image_map(ctx->st, stImage, i, 704c9ed86a96483063f3d6789ed16645a3dca77d726Keith Whitwell PIPE_BUFFER_USAGE_CPU_WRITE); 7055823f99d0fbc054b87aeb1bc15d413d3eadd27a8Brian src += srcImageStride; 706753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer } 707753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer } 70824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 70924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 71024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian _mesa_unmap_teximage_pbo(ctx, unpack); 71124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 712753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer if (stImage->pt) { 713c9ed86a96483063f3d6789ed16645a3dca77d726Keith Whitwell st_texture_image_unmap(ctx->st, stImage); 71424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian texImage->Data = NULL; 71524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 71624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 71724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian if (level == texObj->BaseLevel && texObj->GenerateMipmap) { 71862abcb9aacc33218d0143a743c738435794b32a9Brian ctx->Driver.GenerateMipmap(ctx, target, texObj); 71924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 72024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 72124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 72224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 72324df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void 72424df8f895fe8807aa2ba058e71bd40adfc01d21eBrianst_TexImage3D(GLcontext * ctx, 72524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLenum target, GLint level, 72624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLint internalFormat, 72724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLint width, GLint height, GLint depth, 72824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLint border, 72924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLenum format, GLenum type, const void *pixels, 73024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian const struct gl_pixelstore_attrib *unpack, 73124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian struct gl_texture_object *texObj, 73224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian struct gl_texture_image *texImage) 73324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 73424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian st_TexImage(ctx, 3, target, level, 73524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian internalFormat, width, height, depth, border, 73624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian format, type, pixels, unpack, texObj, texImage, 0, 0); 73724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 73824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 73924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 74024df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void 74124df8f895fe8807aa2ba058e71bd40adfc01d21eBrianst_TexImage2D(GLcontext * ctx, 74224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLenum target, GLint level, 74324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLint internalFormat, 74424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLint width, GLint height, GLint border, 74524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLenum format, GLenum type, const void *pixels, 74624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian const struct gl_pixelstore_attrib *unpack, 74724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian struct gl_texture_object *texObj, 74824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian struct gl_texture_image *texImage) 74924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 75024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian st_TexImage(ctx, 2, target, level, 75124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian internalFormat, width, height, 1, border, 75224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian format, type, pixels, unpack, texObj, texImage, 0, 0); 75324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 75424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 75524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 75624df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void 75724df8f895fe8807aa2ba058e71bd40adfc01d21eBrianst_TexImage1D(GLcontext * ctx, 75824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLenum target, GLint level, 75924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLint internalFormat, 76024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLint width, GLint border, 76124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLenum format, GLenum type, const void *pixels, 76224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian const struct gl_pixelstore_attrib *unpack, 76324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian struct gl_texture_object *texObj, 76424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian struct gl_texture_image *texImage) 76524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 76624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian st_TexImage(ctx, 1, target, level, 76724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian internalFormat, width, 1, 1, border, 76824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian format, type, pixels, unpack, texObj, texImage, 0, 0); 76924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 77024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 77124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 77224df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void 77324df8f895fe8807aa2ba058e71bd40adfc01d21eBrianst_CompressedTexImage2D( GLcontext *ctx, GLenum target, GLint level, 77424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLint internalFormat, 77524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLint width, GLint height, GLint border, 77624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLsizei imageSize, const GLvoid *data, 77724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian struct gl_texture_object *texObj, 77824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian struct gl_texture_image *texImage ) 77924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 78024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian st_TexImage(ctx, 2, target, level, 78124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian internalFormat, width, height, 1, border, 78224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 0, 0, data, &ctx->Unpack, texObj, texImage, imageSize, 1); 78324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 78424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 78524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 78624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian/** 78724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * Need to map texture image into memory before copying image data, 78824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * then unmap it. 78924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 79024df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void 79124df8f895fe8807aa2ba058e71bd40adfc01d21eBrianst_get_tex_image(GLcontext * ctx, GLenum target, GLint level, 79224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLenum format, GLenum type, GLvoid * pixels, 79324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian struct gl_texture_object *texObj, 79424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian struct gl_texture_image *texImage, int compressed) 79524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 79624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian struct st_texture_image *stImage = st_texture_image(texImage); 797753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer GLuint dstImageStride = _mesa_image_image_stride(&ctx->Pack, texImage->Width, 798753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer texImage->Height, format, 799753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer type); 800753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer GLuint depth; 801753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer int i; 8025823f99d0fbc054b87aeb1bc15d413d3eadd27a8Brian GLubyte *dest; 80324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 80424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian /* Map */ 805753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer if (stImage->pt) { 80624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian /* Image is stored in hardware format in a buffer managed by the 80724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * kernel. Need to explicitly map and unmap it. 80824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 809c9ed86a96483063f3d6789ed16645a3dca77d726Keith Whitwell texImage->Data = st_texture_image_map(ctx->st, stImage, 0, 810c9ed86a96483063f3d6789ed16645a3dca77d726Keith Whitwell PIPE_BUFFER_USAGE_CPU_READ); 811753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer texImage->RowStride = stImage->surface->pitch; 81224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 81324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian else { 81424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian /* Otherwise, the image should actually be stored in 815753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer * texImage->Data. This is pretty confusing for 81624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * everybody, I'd much prefer to separate the two functions of 81724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * texImage->Data - storage for texture images in main memory 81824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * and access (ie mappings) of images. In other words, we'd 81924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * create a new texImage->Map field and leave Data simply for 82024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * storage. 82124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 822753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer assert(texImage->Data); 82324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 82424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 825753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer depth = texImage->Depth; 826753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer texImage->Depth = 1; 82724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 8285823f99d0fbc054b87aeb1bc15d413d3eadd27a8Brian dest = (GLubyte *) pixels; 8295823f99d0fbc054b87aeb1bc15d413d3eadd27a8Brian 830753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer for (i = 0; i++ < depth;) { 831753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer if (compressed) { 8325823f99d0fbc054b87aeb1bc15d413d3eadd27a8Brian _mesa_get_compressed_teximage(ctx, target, level, dest, 833753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer texObj, texImage); 834753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer } else { 8355823f99d0fbc054b87aeb1bc15d413d3eadd27a8Brian _mesa_get_teximage(ctx, target, level, format, type, dest, 836753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer texObj, texImage); 837753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer } 838753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer 839753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer if (stImage->pt && i < depth) { 840c9ed86a96483063f3d6789ed16645a3dca77d726Keith Whitwell st_texture_image_unmap(ctx->st, stImage); 841c9ed86a96483063f3d6789ed16645a3dca77d726Keith Whitwell texImage->Data = st_texture_image_map(ctx->st, stImage, i, 842c9ed86a96483063f3d6789ed16645a3dca77d726Keith Whitwell PIPE_BUFFER_USAGE_CPU_READ); 8435823f99d0fbc054b87aeb1bc15d413d3eadd27a8Brian dest += dstImageStride; 844753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer } 84524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 846753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer 847753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer texImage->Depth = depth; 84824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 84924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian /* Unmap */ 850753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer if (stImage->pt) { 851c9ed86a96483063f3d6789ed16645a3dca77d726Keith Whitwell st_texture_image_unmap(ctx->st, stImage); 852753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer texImage->Data = NULL; 85324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 85424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 85524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 85624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 85724df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void 85824df8f895fe8807aa2ba058e71bd40adfc01d21eBrianst_GetTexImage(GLcontext * ctx, GLenum target, GLint level, 85924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLenum format, GLenum type, GLvoid * pixels, 86024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian struct gl_texture_object *texObj, 86124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian struct gl_texture_image *texImage) 86224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 86324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian st_get_tex_image(ctx, target, level, format, type, pixels, 86424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian texObj, texImage, 0); 86524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 86624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 86724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 86824df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void 86924df8f895fe8807aa2ba058e71bd40adfc01d21eBrianst_GetCompressedTexImage(GLcontext *ctx, GLenum target, GLint level, 87024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLvoid *pixels, 87124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian const struct gl_texture_object *texObj, 87224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian const struct gl_texture_image *texImage) 87324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 87424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian st_get_tex_image(ctx, target, level, 0, 0, pixels, 87524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian (struct gl_texture_object *) texObj, 87624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian (struct gl_texture_image *) texImage, 1); 87724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 87824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 87924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 88024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 88124df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void 88224df8f895fe8807aa2ba058e71bd40adfc01d21eBrianst_TexSubimage(GLcontext * ctx, 88324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLint dims, 88424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLenum target, GLint level, 88524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLint xoffset, GLint yoffset, GLint zoffset, 88624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLint width, GLint height, GLint depth, 88724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLenum format, GLenum type, const void *pixels, 88824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian const struct gl_pixelstore_attrib *packing, 88924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian struct gl_texture_object *texObj, 89024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian struct gl_texture_image *texImage) 89124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 89224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian struct st_texture_image *stImage = st_texture_image(texImage); 89324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLuint dstRowStride; 894753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer GLuint srcImageStride = _mesa_image_image_stride(packing, width, height, 895753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer format, type); 896753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer int i; 8975823f99d0fbc054b87aeb1bc15d413d3eadd27a8Brian const GLubyte *src; 89824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 89924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian DBG("%s target %s level %d offset %d,%d %dx%d\n", __FUNCTION__, 90024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian _mesa_lookup_enum_by_nr(target), 90124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian level, xoffset, yoffset, width, height); 90224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 90324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian pixels = 90424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian _mesa_validate_pbo_teximage(ctx, dims, width, height, depth, format, 90524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian type, pixels, packing, "glTexSubImage2D"); 90624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian if (!pixels) 90724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian return; 90824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 90924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian /* Map buffer if necessary. Need to lock to prevent other contexts 91024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * from uploading the buffer under us. 91124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 912753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer if (stImage->pt) { 913c9ed86a96483063f3d6789ed16645a3dca77d726Keith Whitwell texImage->Data = st_texture_image_map(ctx->st, stImage, zoffset, 914c9ed86a96483063f3d6789ed16645a3dca77d726Keith Whitwell PIPE_BUFFER_USAGE_CPU_WRITE); 9152a39dbe7364af5444b1eb43650dfc31ed09257dcBrian Paul if (stImage->surface) 9162a39dbe7364af5444b1eb43650dfc31ed09257dcBrian Paul dstRowStride = stImage->surface->pitch * stImage->surface->cpp; 917753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer } 918753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer 9199b44f5a7550d8ede2eda763770e927df4c15cc8eBrian Paul if (!texImage->Data) { 9209b44f5a7550d8ede2eda763770e927df4c15cc8eBrian Paul _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage"); 9219b44f5a7550d8ede2eda763770e927df4c15cc8eBrian Paul return; 9229b44f5a7550d8ede2eda763770e927df4c15cc8eBrian Paul } 9239b44f5a7550d8ede2eda763770e927df4c15cc8eBrian Paul 9245823f99d0fbc054b87aeb1bc15d413d3eadd27a8Brian src = (const GLubyte *) pixels; 9255823f99d0fbc054b87aeb1bc15d413d3eadd27a8Brian 926753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer for (i = 0; i++ < depth;) { 927753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer if (!texImage->TexFormat->StoreImage(ctx, dims, texImage->_BaseFormat, 928753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer texImage->TexFormat, 929753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer texImage->Data, 930753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer xoffset, yoffset, 0, 931753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer dstRowStride, 932753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer texImage->ImageOffsets, 933753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer width, height, 1, 9345823f99d0fbc054b87aeb1bc15d413d3eadd27a8Brian format, type, src, packing)) { 9359b44f5a7550d8ede2eda763770e927df4c15cc8eBrian Paul _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage"); 936753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer } 937753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer 938753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer if (stImage->pt && i < depth) { 9399b44f5a7550d8ede2eda763770e927df4c15cc8eBrian Paul /* map next slice of 3D texture */ 940c9ed86a96483063f3d6789ed16645a3dca77d726Keith Whitwell st_texture_image_unmap(ctx->st, stImage); 941c9ed86a96483063f3d6789ed16645a3dca77d726Keith Whitwell texImage->Data = st_texture_image_map(ctx->st, stImage, zoffset + i, 942c9ed86a96483063f3d6789ed16645a3dca77d726Keith Whitwell PIPE_BUFFER_USAGE_CPU_WRITE); 9435823f99d0fbc054b87aeb1bc15d413d3eadd27a8Brian src += srcImageStride; 944753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer } 94524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 94624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 94724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian if (level == texObj->BaseLevel && texObj->GenerateMipmap) { 9483ccbaa977f96eaa849093875dd0944f744ee1e21Brian ctx->Driver.GenerateMipmap(ctx, target, texObj); 94924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 95024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 95124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian _mesa_unmap_teximage_pbo(ctx, packing); 95224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 953753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer if (stImage->pt) { 954c9ed86a96483063f3d6789ed16645a3dca77d726Keith Whitwell st_texture_image_unmap(ctx->st, stImage); 95524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian texImage->Data = NULL; 95624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 95724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 95824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 95924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 96024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 96124df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void 96224df8f895fe8807aa2ba058e71bd40adfc01d21eBrianst_TexSubImage3D(GLcontext * ctx, 96324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLenum target, 96424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLint level, 96524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLint xoffset, GLint yoffset, GLint zoffset, 96624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLsizei width, GLsizei height, GLsizei depth, 96724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLenum format, GLenum type, 96824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian const GLvoid * pixels, 96924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian const struct gl_pixelstore_attrib *packing, 97024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian struct gl_texture_object *texObj, 97124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian struct gl_texture_image *texImage) 97224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 973b245840b86cf877c9b8d666edf229364a84f1deaBrian st_TexSubimage(ctx, 3, target, level, 974b245840b86cf877c9b8d666edf229364a84f1deaBrian xoffset, yoffset, zoffset, 975b245840b86cf877c9b8d666edf229364a84f1deaBrian width, height, depth, 976b245840b86cf877c9b8d666edf229364a84f1deaBrian format, type, pixels, packing, texObj, texImage); 97724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 97824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 97924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 98024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 98124df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void 98224df8f895fe8807aa2ba058e71bd40adfc01d21eBrianst_TexSubImage2D(GLcontext * ctx, 98324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLenum target, 98424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLint level, 98524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLint xoffset, GLint yoffset, 98624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLsizei width, GLsizei height, 98724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLenum format, GLenum type, 98824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian const GLvoid * pixels, 98924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian const struct gl_pixelstore_attrib *packing, 99024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian struct gl_texture_object *texObj, 99124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian struct gl_texture_image *texImage) 99224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 993b245840b86cf877c9b8d666edf229364a84f1deaBrian st_TexSubimage(ctx, 2, target, level, 994b245840b86cf877c9b8d666edf229364a84f1deaBrian xoffset, yoffset, 0, 995b245840b86cf877c9b8d666edf229364a84f1deaBrian width, height, 1, 996b245840b86cf877c9b8d666edf229364a84f1deaBrian format, type, pixels, packing, texObj, texImage); 99724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 99824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 99924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 100024df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void 100124df8f895fe8807aa2ba058e71bd40adfc01d21eBrianst_TexSubImage1D(GLcontext * ctx, 100224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLenum target, 100324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLint level, 100424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLint xoffset, 100524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLsizei width, 100624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLenum format, GLenum type, 100724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian const GLvoid * pixels, 100824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian const struct gl_pixelstore_attrib *packing, 100924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian struct gl_texture_object *texObj, 101024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian struct gl_texture_image *texImage) 101124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 1012b245840b86cf877c9b8d666edf229364a84f1deaBrian st_TexSubimage(ctx, 1, target, level, 1013b245840b86cf877c9b8d666edf229364a84f1deaBrian xoffset, 0, 0, 1014b245840b86cf877c9b8d666edf229364a84f1deaBrian width, 1, 1, 1015b245840b86cf877c9b8d666edf229364a84f1deaBrian format, type, pixels, packing, texObj, texImage); 101624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 101724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 101824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 101924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 102024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian/** 1021038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian * Return 0 for GL_TEXTURE_CUBE_MAP_POSITIVE_X, 1022038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian * 1 for GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 1023038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian * etc. 1024038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian * XXX duplicated from main/teximage.c 1025038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian */ 1026038cb561eb094af2f2ba06e18e61246fc0c87c3cBrianstatic uint 1027038cb561eb094af2f2ba06e18e61246fc0c87c3cBriantexture_face(GLenum target) 1028038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian{ 1029038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian if (target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB && 1030038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB) 1031038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian return (GLuint) target - (GLuint) GL_TEXTURE_CUBE_MAP_POSITIVE_X; 1032038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian else 1033038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian return 0; 1034038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian} 1035038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian 1036038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian 1037038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian 1038038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian/** 1039b859cdf6f191b4d8b56537c8dc30082a7e2d94b3Michel Dänzer * Do a CopyTexSubImage operation by mapping the source surface and 1040b859cdf6f191b4d8b56537c8dc30082a7e2d94b3Michel Dänzer * dest surface and using get_tile()/put_tile() to access the pixels/texels. 1041c6717a86420d7141013165f7acd50b3c3f751756Brian * 1042c6717a86420d7141013165f7acd50b3c3f751756Brian * Note: srcY=0=TOP of renderbuffer 1043038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian */ 1044038cb561eb094af2f2ba06e18e61246fc0c87c3cBrianstatic void 1045038cb561eb094af2f2ba06e18e61246fc0c87c3cBrianfallback_copy_texsubimage(GLcontext *ctx, 1046038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian GLenum target, 1047038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian GLint level, 1048038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian struct st_renderbuffer *strb, 1049038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian struct st_texture_image *stImage, 1050038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian GLenum baseFormat, 1051038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian GLint destX, GLint destY, GLint destZ, 1052038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian GLint srcX, GLint srcY, 1053038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian GLsizei width, GLsizei height) 1054038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian{ 1055038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian struct pipe_context *pipe = ctx->st->pipe; 10566f715dcc219071e574e363a9db4365c9c31ebbd3Brian struct pipe_screen *screen = pipe->screen; 1057038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian const uint face = texture_face(target); 1058753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer struct pipe_texture *pt = stImage->pt; 1059038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian struct pipe_surface *src_surf, *dest_surf; 10605c83f1371978472fbe4bba8f686733c6b519874aBrian GLint row, yStep; 10615c83f1371978472fbe4bba8f686733c6b519874aBrian 106202250c855fbec5299a2d6118fefa0523ec73654cMichel Dänzer st_flush(ctx->st, PIPE_FLUSH_RENDER_CACHE, NULL); 106302250c855fbec5299a2d6118fefa0523ec73654cMichel Dänzer 10645c83f1371978472fbe4bba8f686733c6b519874aBrian /* determine bottom-to-top vs. top-to-bottom order */ 10655c83f1371978472fbe4bba8f686733c6b519874aBrian if (st_fb_orientation(ctx->ReadBuffer) == Y_0_TOP) { 10665c83f1371978472fbe4bba8f686733c6b519874aBrian destY = height - 1 - destY; 10675c83f1371978472fbe4bba8f686733c6b519874aBrian yStep = -1; 10685c83f1371978472fbe4bba8f686733c6b519874aBrian } 10695c83f1371978472fbe4bba8f686733c6b519874aBrian else { 10705c83f1371978472fbe4bba8f686733c6b519874aBrian yStep = 1; 10715c83f1371978472fbe4bba8f686733c6b519874aBrian } 1072038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian 1073038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian src_surf = strb->surface; 1074296378b6c8b205048244746e260739448c4ee590Brian Paul src_surf = screen->get_tex_surface(screen, strb->texture, face, level, destZ, 1075296378b6c8b205048244746e260739448c4ee590Brian Paul PIPE_BUFFER_USAGE_CPU_READ); 1076038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian 1077c9ed86a96483063f3d6789ed16645a3dca77d726Keith Whitwell dest_surf = screen->get_tex_surface(screen, pt, face, level, destZ, 1078c9ed86a96483063f3d6789ed16645a3dca77d726Keith Whitwell PIPE_BUFFER_USAGE_CPU_WRITE); 1079038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian 1080cc94863429d8a6cef8dbf861e78701a458d30f5aBrian Paul assert(width <= MAX_WIDTH); 1081038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian 1082cc94863429d8a6cef8dbf861e78701a458d30f5aBrian Paul /* 1083cc94863429d8a6cef8dbf861e78701a458d30f5aBrian Paul * To avoid a large temp memory allocation, do copy row by row. 1084cc94863429d8a6cef8dbf861e78701a458d30f5aBrian Paul */ 1085cc94863429d8a6cef8dbf861e78701a458d30f5aBrian Paul if (baseFormat == GL_DEPTH_COMPONENT) { 1086cc94863429d8a6cef8dbf861e78701a458d30f5aBrian Paul const GLboolean scaleOrBias = (ctx->Pixel.DepthScale != 1.0F || 1087cc94863429d8a6cef8dbf861e78701a458d30f5aBrian Paul ctx->Pixel.DepthBias != 0.0F); 1088cc94863429d8a6cef8dbf861e78701a458d30f5aBrian Paul 1089cc94863429d8a6cef8dbf861e78701a458d30f5aBrian Paul for (row = 0; row < height; row++, srcY++, destY += yStep) { 1090cc94863429d8a6cef8dbf861e78701a458d30f5aBrian Paul uint data[MAX_WIDTH]; 1091cc94863429d8a6cef8dbf861e78701a458d30f5aBrian Paul pipe_get_tile_z(pipe, src_surf, srcX, srcY, width, 1, data); 1092cc94863429d8a6cef8dbf861e78701a458d30f5aBrian Paul if (scaleOrBias) { 1093cc94863429d8a6cef8dbf861e78701a458d30f5aBrian Paul _mesa_scale_and_bias_depth_uint(ctx, width, data); 1094cc94863429d8a6cef8dbf861e78701a458d30f5aBrian Paul } 1095cc94863429d8a6cef8dbf861e78701a458d30f5aBrian Paul pipe_put_tile_z(pipe, dest_surf, destX, destY, width, 1, data); 1096cc94863429d8a6cef8dbf861e78701a458d30f5aBrian Paul } 1097cc94863429d8a6cef8dbf861e78701a458d30f5aBrian Paul } 1098cc94863429d8a6cef8dbf861e78701a458d30f5aBrian Paul else { 1099cc94863429d8a6cef8dbf861e78701a458d30f5aBrian Paul /* RGBA format */ 1100cc94863429d8a6cef8dbf861e78701a458d30f5aBrian Paul for (row = 0; row < height; row++, srcY++, destY += yStep) { 1101cc94863429d8a6cef8dbf861e78701a458d30f5aBrian Paul float data[4 * MAX_WIDTH]; 1102cc94863429d8a6cef8dbf861e78701a458d30f5aBrian Paul pipe_get_tile_rgba(pipe, src_surf, srcX, srcY, width, 1, data); 1103cc94863429d8a6cef8dbf861e78701a458d30f5aBrian Paul /* XXX we're ignoring convolution for now */ 1104cc94863429d8a6cef8dbf861e78701a458d30f5aBrian Paul if (ctx->_ImageTransferState) { 1105cc94863429d8a6cef8dbf861e78701a458d30f5aBrian Paul _mesa_apply_rgba_transfer_ops(ctx, 1106cc94863429d8a6cef8dbf861e78701a458d30f5aBrian Paul ctx->_ImageTransferState & ~IMAGE_CONVOLUTION_BIT, 1107cc94863429d8a6cef8dbf861e78701a458d30f5aBrian Paul width, (GLfloat (*)[4]) data); 1108cc94863429d8a6cef8dbf861e78701a458d30f5aBrian Paul } 1109cc94863429d8a6cef8dbf861e78701a458d30f5aBrian Paul pipe_put_tile_rgba(pipe, dest_surf, destX, destY, width, 1, data); 11105c83f1371978472fbe4bba8f686733c6b519874aBrian } 11115c83f1371978472fbe4bba8f686733c6b519874aBrian } 1112d0279fc4b38c72356a341173317bcd45d9093f45Michel Dänzer 1113d0279fc4b38c72356a341173317bcd45d9093f45Michel Dänzer screen->tex_surface_release(screen, &dest_surf); 1114296378b6c8b205048244746e260739448c4ee590Brian Paul screen->tex_surface_release(screen, &src_surf); 1115038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian} 1116038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian 1117038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian 1118038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian 1119038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian 1120038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian/** 1121b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian * Do a CopyTex[Sub]Image using an optimized hardware (blit) path. 1122b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian * Note that the region to copy has already been clip tested. 1123c6717a86420d7141013165f7acd50b3c3f751756Brian * 1124c6717a86420d7141013165f7acd50b3c3f751756Brian * Note: srcY=0=Bottom of renderbuffer 1125c6717a86420d7141013165f7acd50b3c3f751756Brian * 1126b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian * \return GL_TRUE if success, GL_FALSE if failure (use a fallback) 112724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 1128038cb561eb094af2f2ba06e18e61246fc0c87c3cBrianstatic void 112924df8f895fe8807aa2ba058e71bd40adfc01d21eBriando_copy_texsubimage(GLcontext *ctx, 1130038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian GLenum target, GLint level, 1131038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian GLint destX, GLint destY, GLint destZ, 1132038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian GLint srcX, GLint srcY, 1133038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian GLsizei width, GLsizei height) 113424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 1135038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian struct gl_texture_unit *texUnit = 1136038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; 1137038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian struct gl_texture_object *texObj = 1138038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian _mesa_select_tex_object(ctx, texUnit, target); 1139038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian struct gl_texture_image *texImage = 1140038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian _mesa_select_tex_image(ctx, texObj, target, level); 1141038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian struct st_texture_image *stImage = st_texture_image(texImage); 1142038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian GLenum baseFormat = texImage->InternalFormat; 1143b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian struct gl_framebuffer *fb = ctx->ReadBuffer; 1144b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian struct st_renderbuffer *strb; 1145b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian struct pipe_context *pipe = ctx->st->pipe; 11466f715dcc219071e574e363a9db4365c9c31ebbd3Brian struct pipe_screen *screen = pipe->screen; 1147b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian uint dest_format, src_format; 1148e922adbe1d6c1764968377658ea92ae6de0585dbMichel Dänzer uint do_flip = FALSE; 1149cc94863429d8a6cef8dbf861e78701a458d30f5aBrian Paul GLboolean use_fallback = GL_TRUE; 115024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 1151038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian (void) texImage; 1152038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian 1153b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian /* determine if copying depth or color data */ 1154b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian if (baseFormat == GL_DEPTH_COMPONENT) { 1155b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian strb = st_renderbuffer(fb->_DepthBuffer); 115624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 1157b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian else if (baseFormat == GL_DEPTH_STENCIL_EXT) { 1158b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian strb = st_renderbuffer(fb->_StencilBuffer); 1159b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian } 1160b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian else { 1161b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian /* baseFormat == GL_RGB, GL_RGBA, GL_ALPHA, etc */ 1162b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian strb = st_renderbuffer(fb->_ColorReadBuffer); 1163b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian } 1164b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian 1165b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian assert(strb); 1166b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian assert(strb->surface); 1167753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer assert(stImage->pt); 1168c6717a86420d7141013165f7acd50b3c3f751756Brian 1169c6717a86420d7141013165f7acd50b3c3f751756Brian if (st_fb_orientation(ctx->ReadBuffer) == Y_0_TOP) { 1170c6717a86420d7141013165f7acd50b3c3f751756Brian srcY = strb->Base.Height - srcY - height; 1171e922adbe1d6c1764968377658ea92ae6de0585dbMichel Dänzer do_flip = TRUE; 1172c6717a86420d7141013165f7acd50b3c3f751756Brian } 117324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 1174b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian src_format = strb->surface->format; 1175753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer dest_format = stImage->pt->format; 1176b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian 117779931e38abc62286151121a3f59127e296144551Michel Dänzer if (ctx->_ImageTransferState == 0x0) { 1178038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian /* do blit-style copy */ 1179038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian 1180038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian /* XXX may need to invert image depending on window 1181038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian * vs. user-created FBO 1182038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian */ 1183b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian 118424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#if 0 1185038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian /* A bit of fiddling to get the blitter to work with -ve 1186038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian * pitches. But we get a nice inverted blit this way, so it's 1187038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian * worth it: 1188038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian */ 1189038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian intelEmitCopyBlit(intel, 1190753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer stImage->pt->cpp, 1191038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian -src->pitch, 1192038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian src->buffer, 1193038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian src->height * src->pitch * src->cpp, 1194753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer stImage->pt->pitch, 1195753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer stImage->pt->region->buffer, 1196038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian dest_offset, 1197038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian x, y + height, dstx, dsty, width, height, 1198038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian GL_COPY); /* ? */ 119924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#else 120079931e38abc62286151121a3f59127e296144551Michel Dänzer struct pipe_surface *dest_surface; 120179931e38abc62286151121a3f59127e296144551Michel Dänzer 120279931e38abc62286151121a3f59127e296144551Michel Dänzer dest_surface = screen->get_tex_surface(screen, stImage->pt, stImage->face, 120379931e38abc62286151121a3f59127e296144551Michel Dänzer stImage->level, destZ, 120479931e38abc62286151121a3f59127e296144551Michel Dänzer PIPE_BUFFER_USAGE_GPU_WRITE); 120579931e38abc62286151121a3f59127e296144551Michel Dänzer 120679931e38abc62286151121a3f59127e296144551Michel Dänzer assert(strb->surface->buffer); 120779931e38abc62286151121a3f59127e296144551Michel Dänzer assert(dest_surface->buffer); 1208b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian 12093c0dc8242b64518d5635263ba65b39afa919dd86Michel Dänzer if (src_format == dest_format) { 12103c0dc8242b64518d5635263ba65b39afa919dd86Michel Dänzer pipe->surface_copy(pipe, 12113c0dc8242b64518d5635263ba65b39afa919dd86Michel Dänzer do_flip, 12123c0dc8242b64518d5635263ba65b39afa919dd86Michel Dänzer /* dest */ 12133c0dc8242b64518d5635263ba65b39afa919dd86Michel Dänzer dest_surface, 12143c0dc8242b64518d5635263ba65b39afa919dd86Michel Dänzer destX, destY, 12153c0dc8242b64518d5635263ba65b39afa919dd86Michel Dänzer /* src */ 12163c0dc8242b64518d5635263ba65b39afa919dd86Michel Dänzer strb->surface, 12173c0dc8242b64518d5635263ba65b39afa919dd86Michel Dänzer srcX, srcY, 12183c0dc8242b64518d5635263ba65b39afa919dd86Michel Dänzer /* size */ 12193c0dc8242b64518d5635263ba65b39afa919dd86Michel Dänzer width, height); 1220cc94863429d8a6cef8dbf861e78701a458d30f5aBrian Paul use_fallback = GL_FALSE; 1221cc94863429d8a6cef8dbf861e78701a458d30f5aBrian Paul } 1222cc94863429d8a6cef8dbf861e78701a458d30f5aBrian Paul else if (screen->is_format_supported(screen, strb->surface->format, 1223cc94863429d8a6cef8dbf861e78701a458d30f5aBrian Paul PIPE_TEXTURE) && 1224cc94863429d8a6cef8dbf861e78701a458d30f5aBrian Paul screen->is_format_supported(screen, dest_surface->format, 1225cc94863429d8a6cef8dbf861e78701a458d30f5aBrian Paul PIPE_SURFACE)) { 12263c0dc8242b64518d5635263ba65b39afa919dd86Michel Dänzer util_blit_pixels(ctx->st->blit, 12273c0dc8242b64518d5635263ba65b39afa919dd86Michel Dänzer strb->surface, 12283c0dc8242b64518d5635263ba65b39afa919dd86Michel Dänzer srcX, do_flip ? srcY + height : srcY, 12293c0dc8242b64518d5635263ba65b39afa919dd86Michel Dänzer srcX + width, do_flip ? srcY : srcY + height, 12303c0dc8242b64518d5635263ba65b39afa919dd86Michel Dänzer dest_surface, 12313c0dc8242b64518d5635263ba65b39afa919dd86Michel Dänzer destX, destY, destX + width, destY + height, 12323c0dc8242b64518d5635263ba65b39afa919dd86Michel Dänzer 0.0, PIPE_TEX_MIPFILTER_NEAREST); 1233cc94863429d8a6cef8dbf861e78701a458d30f5aBrian Paul use_fallback = GL_FALSE; 12343c0dc8242b64518d5635263ba65b39afa919dd86Michel Dänzer } 123579931e38abc62286151121a3f59127e296144551Michel Dänzer 123679931e38abc62286151121a3f59127e296144551Michel Dänzer pipe_surface_reference(&dest_surface, NULL); 123724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#endif 1238038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian } 1239cc94863429d8a6cef8dbf861e78701a458d30f5aBrian Paul 1240cc94863429d8a6cef8dbf861e78701a458d30f5aBrian Paul if (use_fallback) { 1241038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian fallback_copy_texsubimage(ctx, target, level, 1242038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian strb, stImage, baseFormat, 1243038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian destX, destY, destZ, 1244038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian srcX, srcY, width, height); 1245038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian } 1246038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian 124724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian if (level == texObj->BaseLevel && texObj->GenerateMipmap) { 12483ccbaa977f96eaa849093875dd0944f744ee1e21Brian ctx->Driver.GenerateMipmap(ctx, target, texObj); 124924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 125024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 125124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 125224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 1253038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian 125424df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void 125524df8f895fe8807aa2ba058e71bd40adfc01d21eBrianst_CopyTexImage1D(GLcontext * ctx, GLenum target, GLint level, 125624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLenum internalFormat, 125724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLint x, GLint y, GLsizei width, GLint border) 125824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 125924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian struct gl_texture_unit *texUnit = 126024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; 126124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian struct gl_texture_object *texObj = 126224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian _mesa_select_tex_object(ctx, texUnit, target); 126324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian struct gl_texture_image *texImage = 126424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian _mesa_select_tex_image(ctx, texObj, target, level); 126524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 1266038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian#if 0 126724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian if (border) 126824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian goto fail; 1269038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian#endif 127024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 1271753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer /* Setup or redefine the texture object, texture and texture 127224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * image. Don't populate yet. 127324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 127424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian ctx->Driver.TexImage1D(ctx, target, level, internalFormat, 127524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian width, border, 127624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GL_RGBA, CHAN_TYPE, NULL, 127724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian &ctx->DefaultPacking, texObj, texImage); 127824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 1279038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian do_copy_texsubimage(ctx, target, level, 1280038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian 0, 0, 0, 1281038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian x, y, width, 1); 128224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 128324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 128424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 128524df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void 128624df8f895fe8807aa2ba058e71bd40adfc01d21eBrianst_CopyTexImage2D(GLcontext * ctx, GLenum target, GLint level, 128724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLenum internalFormat, 128824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLint x, GLint y, GLsizei width, GLsizei height, 128924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLint border) 129024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 129124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian struct gl_texture_unit *texUnit = 129224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; 129324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian struct gl_texture_object *texObj = 129424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian _mesa_select_tex_object(ctx, texUnit, target); 129524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian struct gl_texture_image *texImage = 129624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian _mesa_select_tex_image(ctx, texObj, target, level); 129724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 1298038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian#if 0 129924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian if (border) 130024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian goto fail; 1301038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian#endif 130224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 1303753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer /* Setup or redefine the texture object, texture and texture 130424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * image. Don't populate yet. 130524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 130624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian ctx->Driver.TexImage2D(ctx, target, level, internalFormat, 130724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian width, height, border, 130824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GL_RGBA, CHAN_TYPE, NULL, 130924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian &ctx->DefaultPacking, texObj, texImage); 131024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 131124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 1312038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian do_copy_texsubimage(ctx, target, level, 1313038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian 0, 0, 0, 1314038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian x, y, width, height); 131524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 131624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 131724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 131824df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void 131924df8f895fe8807aa2ba058e71bd40adfc01d21eBrianst_CopyTexSubImage1D(GLcontext * ctx, GLenum target, GLint level, 132024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLint xoffset, GLint x, GLint y, GLsizei width) 132124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 1322038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian const GLint yoffset = 0, zoffset = 0; 1323038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian const GLsizei height = 1; 1324038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian do_copy_texsubimage(ctx, target, level, 1325038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian xoffset, yoffset, zoffset, 1326038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian x, y, width, height); 132724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 132824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 132924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 133024df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void 133124df8f895fe8807aa2ba058e71bd40adfc01d21eBrianst_CopyTexSubImage2D(GLcontext * ctx, GLenum target, GLint level, 133224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLint xoffset, GLint yoffset, 133324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLint x, GLint y, GLsizei width, GLsizei height) 133424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 1335038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian const GLint zoffset = 0; 1336038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian do_copy_texsubimage(ctx, target, level, 1337038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian xoffset, yoffset, zoffset, 1338038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian x, y, width, height); 1339038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian} 134024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 134124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 1342038cb561eb094af2f2ba06e18e61246fc0c87c3cBrianstatic void 1343038cb561eb094af2f2ba06e18e61246fc0c87c3cBrianst_CopyTexSubImage3D(GLcontext * ctx, GLenum target, GLint level, 1344038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian GLint xoffset, GLint yoffset, GLint zoffset, 1345038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian GLint x, GLint y, GLsizei width, GLsizei height) 1346038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian{ 1347038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian do_copy_texsubimage(ctx, target, level, 1348038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian xoffset, yoffset, zoffset, 1349038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian x, y, width, height); 135024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 135124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 135224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 135324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 135424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 135524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian/** 135624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * Compute which mipmap levels that really need to be sent to the hardware. 135724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * This depends on the base image size, GL_TEXTURE_MIN_LOD, 135824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * GL_TEXTURE_MAX_LOD, GL_TEXTURE_BASE_LEVEL, and GL_TEXTURE_MAX_LEVEL. 135924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 136024df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void 136114b98343309fdcff3514f05020303f7b40e83a4aBriancalculate_first_last_level(struct st_texture_object *stObj) 136224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 136314b98343309fdcff3514f05020303f7b40e83a4aBrian struct gl_texture_object *tObj = &stObj->base; 136424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 136524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian /* These must be signed values. MinLod and MaxLod can be negative numbers, 136624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * and having firstLevel and lastLevel as signed prevents the need for 136724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * extra sign checks. 136824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 136924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian int firstLevel; 137024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian int lastLevel; 137124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 137224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian /* Yes, this looks overly complicated, but it's all needed. 137324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 137424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian switch (tObj->Target) { 137524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian case GL_TEXTURE_1D: 137624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian case GL_TEXTURE_2D: 137724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian case GL_TEXTURE_3D: 137824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian case GL_TEXTURE_CUBE_MAP: 137924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian if (tObj->MinFilter == GL_NEAREST || tObj->MinFilter == GL_LINEAR) { 138024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian /* GL_NEAREST and GL_LINEAR only care about GL_TEXTURE_BASE_LEVEL. 138124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 138224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian firstLevel = lastLevel = tObj->BaseLevel; 138324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 138424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian else { 13854da1cdf78fa3b954840650fa46cf72da5daf149fBrian firstLevel = 0; 1386ffde4e03cf178719c06c300939f8f469d7fc5e9cBrian Paul lastLevel = MIN2(tObj->MaxLevel, tObj->Image[0][tObj->BaseLevel]->WidthLog2); 138724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 138824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian break; 138924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian case GL_TEXTURE_RECTANGLE_NV: 139024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian case GL_TEXTURE_4D_SGIS: 139124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian firstLevel = lastLevel = 0; 139224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian break; 139324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian default: 139424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian return; 139524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 139624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 139714b98343309fdcff3514f05020303f7b40e83a4aBrian stObj->lastLevel = lastLevel; 139824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 139924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 140024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 140124df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void 1402753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzercopy_image_data_to_texture(struct st_context *st, 1403753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer struct st_texture_object *stObj, 14044da1cdf78fa3b954840650fa46cf72da5daf149fBrian GLuint dstLevel, 1405753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer struct st_texture_image *stImage) 140624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 1407753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer if (stImage->pt) { 140824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian /* Copy potentially with the blitter: 140924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 1410753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer st_texture_image_copy(st->pipe, 14114da1cdf78fa3b954840650fa46cf72da5daf149fBrian stObj->pt, dstLevel, /* dest texture, level */ 14124da1cdf78fa3b954840650fa46cf72da5daf149fBrian stImage->pt, /* src texture */ 14134da1cdf78fa3b954840650fa46cf72da5daf149fBrian stImage->face 141428b315dc1aed36bebadfacbd55e481e7baacfcb5Brian ); 141524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 14166f715dcc219071e574e363a9db4365c9c31ebbd3Brian pipe_texture_release(&stImage->pt); 141724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 14184c50969334844bc9aa622176c3ebcbc733394f78Brian Paul else if (stImage->base.Data) { 141924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian assert(stImage->base.Data != NULL); 142024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 142124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian /* More straightforward upload. 142224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 1423753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer st_texture_image_data(st->pipe, 1424753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer stObj->pt, 142524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian stImage->face, 1426c2497879f127251994064a0e0c24901782adae9eBrian Paul dstLevel, 142724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian stImage->base.Data, 142824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian stImage->base.RowStride, 142924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian stImage->base.RowStride * 143024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian stImage->base.Height); 143124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian _mesa_align_free(stImage->base.Data); 143224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian stImage->base.Data = NULL; 143324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 143424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 14354da19dbcaa9f3e2d20fffd0145bf0bc756dd7542Brian pipe_texture_reference(&stImage->pt, stObj->pt); 143624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 143724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 143824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 1439afc54983370033b65e3a7cbb29bd9c87156f0881Brian/** 1440afc54983370033b65e3a7cbb29bd9c87156f0881Brian * Called during state validation. When this function is finished, 1441afc54983370033b65e3a7cbb29bd9c87156f0881Brian * the texture object should be ready for rendering. 14423b3774b1227743147159676795b542c0eb7c2bdfBrian Paul * \return GL_TRUE for success, GL_FALSE for failure (out of mem) 144324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 144414b98343309fdcff3514f05020303f7b40e83a4aBrianGLboolean 1445753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzerst_finalize_texture(GLcontext *ctx, 1446c3af68dc5022715cc8f126b7df12f3f5248aefe7Keith Whitwell struct pipe_context *pipe, 1447c3af68dc5022715cc8f126b7df12f3f5248aefe7Keith Whitwell struct gl_texture_object *tObj, 1448753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer GLboolean *needFlush) 144924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 145014b98343309fdcff3514f05020303f7b40e83a4aBrian struct st_texture_object *stObj = st_texture_object(tObj); 1451afc54983370033b65e3a7cbb29bd9c87156f0881Brian const GLuint nr_faces = (stObj->base.Target == GL_TEXTURE_CUBE_MAP) ? 6 : 1; 145224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian int comp_byte = 0; 145324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian int cpp; 14544da1cdf78fa3b954840650fa46cf72da5daf149fBrian GLuint face; 145524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian struct st_texture_image *firstImage; 145624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 145724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian *needFlush = GL_FALSE; 145824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 145924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian /* We know/require this is true by now: 146024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 146114b98343309fdcff3514f05020303f7b40e83a4aBrian assert(stObj->base._Complete); 146224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 1463753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer /* What levels must the texture include at a minimum? 146424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 146514b98343309fdcff3514f05020303f7b40e83a4aBrian calculate_first_last_level(stObj); 14664da1cdf78fa3b954840650fa46cf72da5daf149fBrian firstImage = st_texture_image(stObj->base.Image[0][stObj->base.BaseLevel]); 146724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 1468753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer /* If both firstImage and stObj point to a texture which can contain 146924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * all active images, favour firstImage. Note that because of the 147024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * completeness requirement, we know that the image dimensions 147124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * will match. 147224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 1473753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer if (firstImage->pt && 1474753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer firstImage->pt != stObj->pt && 1475753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer firstImage->pt->last_level >= stObj->lastLevel) { 147624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 1477753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer if (stObj->pt) 14786f715dcc219071e574e363a9db4365c9c31ebbd3Brian pipe_texture_release(&stObj->pt); 147924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 14804da19dbcaa9f3e2d20fffd0145bf0bc756dd7542Brian pipe_texture_reference(&stObj->pt, firstImage->pt); 148124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 148224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 148324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian if (firstImage->base.IsCompressed) { 148414b98343309fdcff3514f05020303f7b40e83a4aBrian comp_byte = compressed_num_bytes(firstImage->base.TexFormat->MesaFormat); 148524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian cpp = comp_byte; 148624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 14875cb0d749b07be4ecbf4d4d7cde18aecdfe2dba38Brian else { 14885cb0d749b07be4ecbf4d4d7cde18aecdfe2dba38Brian cpp = firstImage->base.TexFormat->TexelBytes; 14895cb0d749b07be4ecbf4d4d7cde18aecdfe2dba38Brian } 149024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 1491ce509401738e7073de94a2b7fc41461c52a73da0Brian Paul /* If we already have a gallium texture, check that it matches the texture 1492ce509401738e7073de94a2b7fc41461c52a73da0Brian Paul * object's format, target, size, num_levels, etc. 149324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 1494809dd9089bae70cf35cea6a75258e700e7455738Brian Paul if (stObj->pt) { 1495809dd9089bae70cf35cea6a75258e700e7455738Brian Paul const enum pipe_format fmt = 1496809dd9089bae70cf35cea6a75258e700e7455738Brian Paul st_mesa_format_to_pipe_format(firstImage->base.TexFormat->MesaFormat); 1497809dd9089bae70cf35cea6a75258e700e7455738Brian Paul if (stObj->pt->target != gl_target_to_pipe(stObj->base.Target) || 1498809dd9089bae70cf35cea6a75258e700e7455738Brian Paul stObj->pt->format != fmt || 1499809dd9089bae70cf35cea6a75258e700e7455738Brian Paul stObj->pt->last_level < stObj->lastLevel || 1500809dd9089bae70cf35cea6a75258e700e7455738Brian Paul stObj->pt->width[0] != firstImage->base.Width2 || 1501809dd9089bae70cf35cea6a75258e700e7455738Brian Paul stObj->pt->height[0] != firstImage->base.Height2 || 1502809dd9089bae70cf35cea6a75258e700e7455738Brian Paul stObj->pt->depth[0] != firstImage->base.Depth2 || 1503809dd9089bae70cf35cea6a75258e700e7455738Brian Paul stObj->pt->cpp != cpp || 1504809dd9089bae70cf35cea6a75258e700e7455738Brian Paul stObj->pt->compressed != firstImage->base.IsCompressed) { 1505809dd9089bae70cf35cea6a75258e700e7455738Brian Paul pipe_texture_release(&stObj->pt); 15061a82d9648b3db780e58e4966924157542d148c58Brian Paul ctx->st->dirty.st |= ST_NEW_FRAMEBUFFER; 1507809dd9089bae70cf35cea6a75258e700e7455738Brian Paul } 150824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 150924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 1510ce509401738e7073de94a2b7fc41461c52a73da0Brian Paul /* May need to create a new gallium texture: 151124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 1512753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer if (!stObj->pt) { 1513753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer stObj->pt = st_texture_create(ctx->st, 15145390a43ce06b27f6d54bc5f237aa305b6948f2afBrian gl_target_to_pipe(stObj->base.Target), 1515753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer st_mesa_format_to_pipe_format(firstImage->base.TexFormat->MesaFormat), 1516b245840b86cf877c9b8d666edf229364a84f1deaBrian stObj->lastLevel, 151745cc35e77600af8628393475405160e26d56d421Brian Paul firstImage->base.Width2, 151845cc35e77600af8628393475405160e26d56d421Brian Paul firstImage->base.Height2, 151945cc35e77600af8628393475405160e26d56d421Brian Paul firstImage->base.Depth2, 1520a73ae3d5eb8419feab5aea26573aa41b72f941ebKeith Whitwell comp_byte, 1521a73ae3d5eb8419feab5aea26573aa41b72f941ebKeith Whitwell 1522a73ae3d5eb8419feab5aea26573aa41b72f941ebKeith Whitwell ( PIPE_TEXTURE_USAGE_RENDER_TARGET | 1523a73ae3d5eb8419feab5aea26573aa41b72f941ebKeith Whitwell PIPE_TEXTURE_USAGE_SAMPLER )); 1524a73ae3d5eb8419feab5aea26573aa41b72f941ebKeith Whitwell 15253b3774b1227743147159676795b542c0eb7c2bdfBrian Paul if (!stObj->pt) { 15263b3774b1227743147159676795b542c0eb7c2bdfBrian Paul _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage"); 15273b3774b1227743147159676795b542c0eb7c2bdfBrian Paul return GL_FALSE; 15283b3774b1227743147159676795b542c0eb7c2bdfBrian Paul } 152924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 153024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 1531753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer /* Pull in any images not in the object's texture: 153224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 153324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian for (face = 0; face < nr_faces; face++) { 15344da1cdf78fa3b954840650fa46cf72da5daf149fBrian GLuint level; 15354da1cdf78fa3b954840650fa46cf72da5daf149fBrian for (level = 0; level <= stObj->lastLevel; level++) { 153624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian struct st_texture_image *stImage = 15374da1cdf78fa3b954840650fa46cf72da5daf149fBrian st_texture_image(stObj->base.Image[face][stObj->base.BaseLevel + level]); 153824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 1539753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer /* Need to import images in main memory or held in other textures. 154024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 1541a34b43b3f4817268ef4b3f186203b5fbafc7214eBrian if (stImage && stObj->pt != stImage->pt) { 15424da1cdf78fa3b954840650fa46cf72da5daf149fBrian copy_image_data_to_texture(ctx->st, stObj, level, stImage); 154324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian *needFlush = GL_TRUE; 154424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 154524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 154624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 154724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 154824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian return GL_TRUE; 154924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 155024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 155124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 155224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 155324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 15546da9234fd437f97267e7831f034c78b31156d939Brianvoid 15556da9234fd437f97267e7831f034c78b31156d939Brianst_init_texture_functions(struct dd_function_table *functions) 155624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 155724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian functions->ChooseTextureFormat = st_ChooseTextureFormat; 155824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian functions->TexImage1D = st_TexImage1D; 155924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian functions->TexImage2D = st_TexImage2D; 156024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian functions->TexImage3D = st_TexImage3D; 156124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian functions->TexSubImage1D = st_TexSubImage1D; 156224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian functions->TexSubImage2D = st_TexSubImage2D; 156324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian functions->TexSubImage3D = st_TexSubImage3D; 156424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian functions->CopyTexImage1D = st_CopyTexImage1D; 156524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian functions->CopyTexImage2D = st_CopyTexImage2D; 156624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian functions->CopyTexSubImage1D = st_CopyTexSubImage1D; 156724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian functions->CopyTexSubImage2D = st_CopyTexSubImage2D; 1568038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian functions->CopyTexSubImage3D = st_CopyTexSubImage3D; 156962abcb9aacc33218d0143a743c738435794b32a9Brian functions->GenerateMipmap = st_generate_mipmap; 1570038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian 157124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian functions->GetTexImage = st_GetTexImage; 157224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 157324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian /* compressed texture functions */ 157424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian functions->CompressedTexImage2D = st_CompressedTexImage2D; 157524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian functions->GetCompressedTexImage = st_GetCompressedTexImage; 1576f32c51277498887b348133ebcd947dbc8acce756Roland Scheidegger functions->CompressedTextureSize = _mesa_compressed_texture_size; 157724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 157824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian functions->NewTextureObject = st_NewTextureObject; 157924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian functions->NewTextureImage = st_NewTextureImage; 158024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian functions->DeleteTexture = st_DeleteTextureObject; 158124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian functions->FreeTexImageData = st_FreeTextureImageData; 158224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian functions->UpdateTexturePalette = 0; 158324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian functions->IsTextureResident = st_IsTextureResident; 158424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 158524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian functions->TextureMemCpy = do_memcpy; 1586f8549e8f4f8bdfebcb4e0a2754df59b3fe4fdff7Brian 1587f8549e8f4f8bdfebcb4e0a2754df59b3fe4fdff7Brian /* XXX Temporary until we can query pipe's texture sizes */ 1588f8549e8f4f8bdfebcb4e0a2754df59b3fe4fdff7Brian functions->TestProxyTexImage = _mesa_test_proxy_teximage; 158924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 1590