st_cb_texture.c revision 6acd63a4980951727939c0dd545a0324965b3834
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" 3424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#include "main/texcompress.h" 3524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#include "main/texformat.h" 3624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#include "main/teximage.h" 3724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#include "main/texobj.h" 3824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#include "main/texstore.h" 3924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 4024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#include "state_tracker/st_context.h" 41b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian#include "state_tracker/st_cb_fbo.h" 4224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#include "state_tracker/st_cb_texture.h" 43f8ab24760d0d3f07e9ee81c98207ddf92dfe74daBrian#include "state_tracker/st_format.h" 44753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer#include "state_tracker/st_texture.h" 4562abcb9aacc33218d0143a743c738435794b32a9Brian#include "state_tracker/st_gen_mipmap.h" 4624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 4724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#include "pipe/p_context.h" 48b245840b86cf877c9b8d666edf229364a84f1deaBrian#include "pipe/p_defines.h" 4911a80160fd60d1eb1541b49128c659526a5d8ac8Michel Dänzer#include "pipe/p_inlines.h" 506acd63a4980951727939c0dd545a0324965b3834José Fonseca#include "util/p_tile.h" 5124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 5224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 5324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#define DBG if (0) printf 5424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 5524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 5624df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstruct st_texture_object 5724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 5824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian struct gl_texture_object base; /* The "parent" object */ 5924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 604da1cdf78fa3b954840650fa46cf72da5daf149fBrian /* The texture must include at levels [0..lastLevel] once validated: 6124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 6224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLuint lastLevel; 6324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 6424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian /* On validation any active images held in main memory or in other 65b859cdf6f191b4d8b56537c8dc30082a7e2d94b3Michel Dänzer * textures will be copied to this texture and the old storage freed. 6624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 67753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer struct pipe_texture *pt; 6824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 6924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLboolean imageOverride; 7024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLint depthOverride; 7124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLuint pitchOverride; 7224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian}; 7324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 7424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 7524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 7624df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic INLINE struct st_texture_object * 7724df8f895fe8807aa2ba058e71bd40adfc01d21eBrianst_texture_object(struct gl_texture_object *obj) 7824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 7924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian return (struct st_texture_object *) obj; 8024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 8124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 82afc54983370033b65e3a7cbb29bd9c87156f0881Brian 8324df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic INLINE struct st_texture_image * 8424df8f895fe8807aa2ba058e71bd40adfc01d21eBrianst_texture_image(struct gl_texture_image *img) 8524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 8624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian return (struct st_texture_image *) img; 8724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 8824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 8924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 90753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzerstruct pipe_texture * 91753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzerst_get_texobj_texture(struct gl_texture_object *texObj) 92d78dab126724e6e9d475289a086fb6f85adc3985Brian{ 93d78dab126724e6e9d475289a086fb6f85adc3985Brian struct st_texture_object *stObj = st_texture_object(texObj); 94753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer return stObj->pt; 95d78dab126724e6e9d475289a086fb6f85adc3985Brian} 96d78dab126724e6e9d475289a086fb6f85adc3985Brian 97d78dab126724e6e9d475289a086fb6f85adc3985Brian 981c5f27a18b775b3784fcd265d60e0affa0b31581Michel Dänzerstatic enum pipe_texture_target 995390a43ce06b27f6d54bc5f237aa305b6948f2afBriangl_target_to_pipe(GLenum target) 1005390a43ce06b27f6d54bc5f237aa305b6948f2afBrian{ 1015390a43ce06b27f6d54bc5f237aa305b6948f2afBrian switch (target) { 1025390a43ce06b27f6d54bc5f237aa305b6948f2afBrian case GL_TEXTURE_1D: 1035390a43ce06b27f6d54bc5f237aa305b6948f2afBrian return PIPE_TEXTURE_1D; 1045390a43ce06b27f6d54bc5f237aa305b6948f2afBrian 1055390a43ce06b27f6d54bc5f237aa305b6948f2afBrian case GL_TEXTURE_2D: 1065390a43ce06b27f6d54bc5f237aa305b6948f2afBrian case GL_TEXTURE_RECTANGLE_NV: 1075390a43ce06b27f6d54bc5f237aa305b6948f2afBrian return PIPE_TEXTURE_2D; 1085390a43ce06b27f6d54bc5f237aa305b6948f2afBrian 1095390a43ce06b27f6d54bc5f237aa305b6948f2afBrian case GL_TEXTURE_3D: 1105390a43ce06b27f6d54bc5f237aa305b6948f2afBrian return PIPE_TEXTURE_3D; 1115390a43ce06b27f6d54bc5f237aa305b6948f2afBrian 1125390a43ce06b27f6d54bc5f237aa305b6948f2afBrian case GL_TEXTURE_CUBE_MAP_ARB: 1135390a43ce06b27f6d54bc5f237aa305b6948f2afBrian return PIPE_TEXTURE_CUBE; 1145390a43ce06b27f6d54bc5f237aa305b6948f2afBrian 1155390a43ce06b27f6d54bc5f237aa305b6948f2afBrian default: 1165390a43ce06b27f6d54bc5f237aa305b6948f2afBrian assert(0); 1175390a43ce06b27f6d54bc5f237aa305b6948f2afBrian return 0; 1185390a43ce06b27f6d54bc5f237aa305b6948f2afBrian } 1195390a43ce06b27f6d54bc5f237aa305b6948f2afBrian} 1205390a43ce06b27f6d54bc5f237aa305b6948f2afBrian 1215390a43ce06b27f6d54bc5f237aa305b6948f2afBrian 122afc54983370033b65e3a7cbb29bd9c87156f0881Brian/** 123afc54983370033b65e3a7cbb29bd9c87156f0881Brian * Return nominal bytes per texel for a compressed format, 0 for non-compressed 124afc54983370033b65e3a7cbb29bd9c87156f0881Brian * format. 125afc54983370033b65e3a7cbb29bd9c87156f0881Brian */ 12624df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic int 12714b98343309fdcff3514f05020303f7b40e83a4aBriancompressed_num_bytes(GLuint mesaFormat) 12824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 12924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian switch(mesaFormat) { 13024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian case MESA_FORMAT_RGB_FXT1: 13124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian case MESA_FORMAT_RGBA_FXT1: 13224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian case MESA_FORMAT_RGB_DXT1: 13324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian case MESA_FORMAT_RGBA_DXT1: 134afc54983370033b65e3a7cbb29bd9c87156f0881Brian return 2; 13524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian case MESA_FORMAT_RGBA_DXT3: 13624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian case MESA_FORMAT_RGBA_DXT5: 137afc54983370033b65e3a7cbb29bd9c87156f0881Brian return 4; 13824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian default: 139afc54983370033b65e3a7cbb29bd9c87156f0881Brian return 0; 14024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 14124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 14224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 14324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 14424df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic GLboolean 14524df8f895fe8807aa2ba058e71bd40adfc01d21eBrianst_IsTextureResident(GLcontext * ctx, struct gl_texture_object *texObj) 14624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 14724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#if 0 14824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian struct intel_context *intel = intel_context(ctx); 14924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian struct st_texture_object *stObj = st_texture_object(texObj); 15024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 15124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian return 152753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer stObj->pt && 153753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer stObj->pt->region && 154753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer intel_is_region_resident(intel, stObj->pt->region); 15524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#endif 15624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian return 1; 15724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 15824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 15924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 16024df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic struct gl_texture_image * 16124df8f895fe8807aa2ba058e71bd40adfc01d21eBrianst_NewTextureImage(GLcontext * ctx) 16224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 16324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian DBG("%s\n", __FUNCTION__); 16424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian (void) ctx; 16524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian return (struct gl_texture_image *) CALLOC_STRUCT(st_texture_image); 16624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 16724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 16824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 16924df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic struct gl_texture_object * 17024df8f895fe8807aa2ba058e71bd40adfc01d21eBrianst_NewTextureObject(GLcontext * ctx, GLuint name, GLenum target) 17124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 17224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian struct st_texture_object *obj = CALLOC_STRUCT(st_texture_object); 17324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 17424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian DBG("%s\n", __FUNCTION__); 17524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian _mesa_initialize_texture_object(&obj->base, name, target); 17624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 17724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian return &obj->base; 17824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 17924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 18024df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void 18124df8f895fe8807aa2ba058e71bd40adfc01d21eBrianst_DeleteTextureObject(GLcontext *ctx, 18224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian struct gl_texture_object *texObj) 18324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 18424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian struct st_texture_object *stObj = st_texture_object(texObj); 18524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 186753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer if (stObj->pt) 187753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer ctx->st->pipe->texture_release(ctx->st->pipe, &stObj->pt); 18824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 18924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian _mesa_delete_texture_object(ctx, texObj); 19024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 19124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 19224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 19324df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void 19424df8f895fe8807aa2ba058e71bd40adfc01d21eBrianst_FreeTextureImageData(GLcontext * ctx, struct gl_texture_image *texImage) 19524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 19624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian struct st_texture_image *stImage = st_texture_image(texImage); 19724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 19824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian DBG("%s\n", __FUNCTION__); 19924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 200753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer if (stImage->pt) { 201753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer ctx->st->pipe->texture_release(ctx->st->pipe, &stImage->pt); 20224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 20324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 20424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian if (texImage->Data) { 20524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian free(texImage->Data); 20624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian texImage->Data = NULL; 20724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 20824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 20924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 21024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 21124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian/* ================================================================ 21224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * From linux kernel i386 header files, copes with odd sizes better 21324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * than COPY_DWORDS would: 21424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * XXX Put this in src/mesa/main/imports.h ??? 21524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 21624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#if defined(i386) || defined(__i386__) 21724df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic INLINE void * 21824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian__memcpy(void *to, const void *from, size_t n) 21924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 22024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian int d0, d1, d2; 22124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian __asm__ __volatile__("rep ; movsl\n\t" 22224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian "testb $2,%b4\n\t" 22324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian "je 1f\n\t" 22424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian "movsw\n" 22524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian "1:\ttestb $1,%b4\n\t" 22624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian "je 2f\n\t" 22724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian "movsb\n" "2:":"=&c"(d0), "=&D"(d1), "=&S"(d2) 22824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian :"0"(n / 4), "q"(n), "1"((long) to), "2"((long) from) 22924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian :"memory"); 23024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian return (to); 23124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 23224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#else 23324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#define __memcpy(a,b,c) memcpy(a,b,c) 23424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#endif 23524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 23624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 23724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian/* The system memcpy (at least on ubuntu 5.10) has problems copying 23824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * to agp (writecombined) memory from a source which isn't 64-byte 23924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * aligned - there is a 4x performance falloff. 24024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * 24124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * The x86 __memcpy is immune to this but is slightly slower 24224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * (10%-ish) than the system memcpy. 24324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * 24424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * The sse_memcpy seems to have a slight cliff at 64/32 bytes, but 24524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * isn't much faster than x86_memcpy for agp copies. 24624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * 24724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * TODO: switch dynamically. 24824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 24924df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void * 25024df8f895fe8807aa2ba058e71bd40adfc01d21eBriando_memcpy(void *dest, const void *src, size_t n) 25124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 25224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian if ((((unsigned) src) & 63) || (((unsigned) dest) & 63)) { 25324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian return __memcpy(dest, src, n); 25424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 25524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian else 25624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian return memcpy(dest, src, n); 25724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 25824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 25924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 260753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer/* Functions to store texture images. Where possible, textures 26124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * will be created or further instantiated with image data, otherwise 26224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * images will be stored in malloc'd memory. A validation step is 263753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer * required to pull those images into a texture, or otherwise 26424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * decide a fallback is required. 26524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 26624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 26724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 26824df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic int 26924df8f895fe8807aa2ba058e71bd40adfc01d21eBrianlogbase2(int n) 27024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 27124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLint i = 1; 27224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLint log2 = 0; 27324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 27424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian while (n > i) { 27524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian i *= 2; 27624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian log2++; 27724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 27824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 27924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian return log2; 28024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 28124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 28224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 283f52f5136e6eed23e55098681e5b082cc452136d6Brian/** 284f52f5136e6eed23e55098681e5b082cc452136d6Brian * Allocate a pipe_texture object for the given st_texture_object using 285f52f5136e6eed23e55098681e5b082cc452136d6Brian * the given st_texture_image to guess the mipmap size/levels. 286f52f5136e6eed23e55098681e5b082cc452136d6Brian * 287f52f5136e6eed23e55098681e5b082cc452136d6Brian * [comments...] 288f52f5136e6eed23e55098681e5b082cc452136d6Brian * Otherwise, store it in memory if (Border != 0) or (any dimension == 28924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * 1). 29024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * 291753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer * Otherwise, if max_level >= level >= min_level, create texture with 292753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer * space for images from min_level down to max_level. 29324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * 294753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer * Otherwise, create texture with space for images from (level 0)..(1x1). 295753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer * Consider pruning this texture at a validation if the saving is worth it. 29624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 29724df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void 298753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzerguess_and_alloc_texture(struct st_context *st, 299753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer struct st_texture_object *stObj, 300afc54983370033b65e3a7cbb29bd9c87156f0881Brian const struct st_texture_image *stImage) 30124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 30224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLuint firstLevel; 30324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLuint lastLevel; 30414b98343309fdcff3514f05020303f7b40e83a4aBrian GLuint width = stImage->base.Width; 30514b98343309fdcff3514f05020303f7b40e83a4aBrian GLuint height = stImage->base.Height; 30614b98343309fdcff3514f05020303f7b40e83a4aBrian GLuint depth = stImage->base.Depth; 30724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLuint i, comp_byte = 0; 30824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 30924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian DBG("%s\n", __FUNCTION__); 31024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 311f52f5136e6eed23e55098681e5b082cc452136d6Brian assert(!stObj->pt); 312f52f5136e6eed23e55098681e5b082cc452136d6Brian 31314b98343309fdcff3514f05020303f7b40e83a4aBrian if (stImage->base.Border) 31424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian return; 31524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 31614b98343309fdcff3514f05020303f7b40e83a4aBrian if (stImage->level > stObj->base.BaseLevel && 31714b98343309fdcff3514f05020303f7b40e83a4aBrian (stImage->base.Width == 1 || 31814b98343309fdcff3514f05020303f7b40e83a4aBrian (stObj->base.Target != GL_TEXTURE_1D && 31914b98343309fdcff3514f05020303f7b40e83a4aBrian stImage->base.Height == 1) || 32014b98343309fdcff3514f05020303f7b40e83a4aBrian (stObj->base.Target == GL_TEXTURE_3D && 32114b98343309fdcff3514f05020303f7b40e83a4aBrian stImage->base.Depth == 1))) 32224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian return; 32324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 32424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian /* If this image disrespects BaseLevel, allocate from level zero. 32524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * Usually BaseLevel == 0, so it's unlikely to happen. 32624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 32714b98343309fdcff3514f05020303f7b40e83a4aBrian if (stImage->level < stObj->base.BaseLevel) 32824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian firstLevel = 0; 32924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian else 33014b98343309fdcff3514f05020303f7b40e83a4aBrian firstLevel = stObj->base.BaseLevel; 33124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 33224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 33324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian /* Figure out image dimensions at start level. 33424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 33514b98343309fdcff3514f05020303f7b40e83a4aBrian for (i = stImage->level; i > firstLevel; i--) { 33624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian width <<= 1; 33724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian if (height != 1) 33824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian height <<= 1; 33924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian if (depth != 1) 34024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian depth <<= 1; 34124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 34224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 34324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian /* Guess a reasonable value for lastLevel. This is probably going 34424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * to be wrong fairly often and might mean that we have to look at 34524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * resizable buffers, or require that buffers implement lazy 34624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * pagetable arrangements. 34724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 34814b98343309fdcff3514f05020303f7b40e83a4aBrian if ((stObj->base.MinFilter == GL_NEAREST || 34914b98343309fdcff3514f05020303f7b40e83a4aBrian stObj->base.MinFilter == GL_LINEAR) && 35014b98343309fdcff3514f05020303f7b40e83a4aBrian stImage->level == firstLevel) { 35124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian lastLevel = firstLevel; 35224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 35324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian else { 354f52f5136e6eed23e55098681e5b082cc452136d6Brian GLuint l2width = logbase2(width); 355f52f5136e6eed23e55098681e5b082cc452136d6Brian GLuint l2height = logbase2(height); 356f52f5136e6eed23e55098681e5b082cc452136d6Brian GLuint l2depth = logbase2(depth); 35724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian lastLevel = firstLevel + MAX2(MAX2(l2width, l2height), l2depth); 35824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 35924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 36014b98343309fdcff3514f05020303f7b40e83a4aBrian if (stImage->base.IsCompressed) 36114b98343309fdcff3514f05020303f7b40e83a4aBrian comp_byte = compressed_num_bytes(stImage->base.TexFormat->MesaFormat); 362f52f5136e6eed23e55098681e5b082cc452136d6Brian 363753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer stObj->pt = st_texture_create(st, 3645390a43ce06b27f6d54bc5f237aa305b6948f2afBrian gl_target_to_pipe(stObj->base.Target), 365753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer st_mesa_format_to_pipe_format(stImage->base.TexFormat->MesaFormat), 3665390a43ce06b27f6d54bc5f237aa305b6948f2afBrian lastLevel, 3675390a43ce06b27f6d54bc5f237aa305b6948f2afBrian width, 3685390a43ce06b27f6d54bc5f237aa305b6948f2afBrian height, 3695390a43ce06b27f6d54bc5f237aa305b6948f2afBrian depth, 3705390a43ce06b27f6d54bc5f237aa305b6948f2afBrian comp_byte); 37124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 37224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian DBG("%s - success\n", __FUNCTION__); 37324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 37424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 37524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 37624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian/* There are actually quite a few combinations this will work for, 37724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * more than what I've listed here. 37824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 37924df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic GLboolean 38024df8f895fe8807aa2ba058e71bd40adfc01d21eBriancheck_pbo_format(GLint internalFormat, 38124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLenum format, GLenum type, 38224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian const struct gl_texture_format *mesa_format) 38324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 38424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian switch (internalFormat) { 38524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian case 4: 38624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian case GL_RGBA: 38724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian return (format == GL_BGRA && 38824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian (type == GL_UNSIGNED_BYTE || 38924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian type == GL_UNSIGNED_INT_8_8_8_8_REV) && 39024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian mesa_format == &_mesa_texformat_argb8888); 39124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian case 3: 39224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian case GL_RGB: 39324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian return (format == GL_RGB && 39424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian type == GL_UNSIGNED_SHORT_5_6_5 && 39524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian mesa_format == &_mesa_texformat_rgb565); 39624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian case GL_YCBCR_MESA: 39724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian return (type == GL_UNSIGNED_SHORT_8_8_MESA || type == GL_UNSIGNED_BYTE); 39824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian default: 39924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian return GL_FALSE; 40024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 40124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 40224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 40324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 40424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian/* XXX: Do this for TexSubImage also: 40524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 40624df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic GLboolean 40724df8f895fe8807aa2ba058e71bd40adfc01d21eBriantry_pbo_upload(GLcontext *ctx, 40814b98343309fdcff3514f05020303f7b40e83a4aBrian struct st_texture_image *stImage, 40924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian const struct gl_pixelstore_attrib *unpack, 41024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLint internalFormat, 41124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLint width, GLint height, 41224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLenum format, GLenum type, const void *pixels) 41324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 41424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian return GL_FALSE; /* XXX fix flushing/locking/blitting below */ 41524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#if 000 41624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian struct intel_context *intel = intel_context(ctx); 41724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian struct intel_buffer_object *pbo = intel_buffer_object(unpack->BufferObj); 41824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLuint src_offset, src_stride; 41924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLuint dst_offset, dst_stride; 42024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 42124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian if (!pbo || 42224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian ctx._ImageTransferState || 42324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian unpack->SkipPixels || unpack->SkipRows) { 42424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian _mesa_printf("%s: failure 1\n", __FUNCTION__); 42524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian return GL_FALSE; 42624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 42724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 42824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian src_offset = (GLuint) pixels; 42924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 43024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian if (unpack->RowLength > 0) 43124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian src_stride = unpack->RowLength; 43224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian else 43324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian src_stride = width; 43424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 435753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer dst_offset = st_texture_image_offset(stImage->pt, 43614b98343309fdcff3514f05020303f7b40e83a4aBrian stImage->face, 43714b98343309fdcff3514f05020303f7b40e83a4aBrian stImage->level); 43824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 439753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer dst_stride = stImage->pt->pitch; 44024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 44124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian { 44224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian struct _DriBufferObject *src_buffer = 44324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian intel_bufferobj_buffer(intel, pbo, INTEL_READ); 44424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 44524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian /* Temporary hack: cast to _DriBufferObject: 44624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 44724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian struct _DriBufferObject *dst_buffer = 448753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer (struct _DriBufferObject *)stImage->pt->region->buffer; 44924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 45024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 45124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian intelEmitCopyBlit(intel, 452753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer stImage->pt->cpp, 45324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian src_stride, src_buffer, src_offset, 45424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian dst_stride, dst_buffer, dst_offset, 45524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 0, 0, 0, 0, width, height, 45624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GL_COPY); 45724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 45824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 45924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian return GL_TRUE; 46024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#endif 46124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 46224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 46324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 464212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian/** 465212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian * Adjust pixel unpack params and image dimensions to strip off the 466212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian * texture border. 467212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian * Gallium doesn't support texture borders. They've seldem been used 468212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian * and seldom been implemented correctly anyway. 469212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian * \param unpackNew returns the new pixel unpack parameters 470212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian */ 471212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brianstatic void 472212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brianstrip_texture_border(GLint border, 473212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian GLint *width, GLint *height, GLint *depth, 474212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian const struct gl_pixelstore_attrib *unpack, 475212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian struct gl_pixelstore_attrib *unpackNew) 476212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian{ 477212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian assert(border > 0); /* sanity check */ 478212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian 479212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian *unpackNew = *unpack; 480212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian 481212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian if (unpackNew->RowLength == 0) 482212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian unpackNew->RowLength = *width; 483212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian 484212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian if (depth && unpackNew->ImageHeight == 0) 485212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian unpackNew->ImageHeight = *height; 486212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian 487212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian unpackNew->SkipPixels += border; 488212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian if (height) 489212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian unpackNew->SkipRows += border; 490212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian if (depth) 491212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian unpackNew->SkipImages += border; 492212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian 493212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian assert(*width >= 3); 494212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian *width = *width - 2 * border; 495212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian if (height && *height >= 3) 496212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian *height = *height - 2 * border; 497212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian if (depth && *depth >= 3) 498212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian *depth = *depth - 2 * border; 499212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian} 500212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian 50124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 50224df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void 50324df8f895fe8807aa2ba058e71bd40adfc01d21eBrianst_TexImage(GLcontext * ctx, 504afc54983370033b65e3a7cbb29bd9c87156f0881Brian GLint dims, 505afc54983370033b65e3a7cbb29bd9c87156f0881Brian GLenum target, GLint level, 506afc54983370033b65e3a7cbb29bd9c87156f0881Brian GLint internalFormat, 507afc54983370033b65e3a7cbb29bd9c87156f0881Brian GLint width, GLint height, GLint depth, 508afc54983370033b65e3a7cbb29bd9c87156f0881Brian GLint border, 509afc54983370033b65e3a7cbb29bd9c87156f0881Brian GLenum format, GLenum type, const void *pixels, 510afc54983370033b65e3a7cbb29bd9c87156f0881Brian const struct gl_pixelstore_attrib *unpack, 511afc54983370033b65e3a7cbb29bd9c87156f0881Brian struct gl_texture_object *texObj, 512afc54983370033b65e3a7cbb29bd9c87156f0881Brian struct gl_texture_image *texImage, 513afc54983370033b65e3a7cbb29bd9c87156f0881Brian GLsizei imageSize, int compressed) 51424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 51514b98343309fdcff3514f05020303f7b40e83a4aBrian struct st_texture_object *stObj = st_texture_object(texObj); 51614b98343309fdcff3514f05020303f7b40e83a4aBrian struct st_texture_image *stImage = st_texture_image(texImage); 517212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian GLint postConvWidth, postConvHeight; 51824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLint texelBytes, sizeInBytes; 51924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLuint dstRowStride; 520212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian struct gl_pixelstore_attrib unpackNB; 52124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 52224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian DBG("%s target %s level %d %dx%dx%d border %d\n", __FUNCTION__, 52324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian _mesa_lookup_enum_by_nr(target), level, width, height, depth, border); 52424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 525212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian /* gallium does not support texture borders, strip it off */ 526212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian if (border) { 527212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian strip_texture_border(border, &width, &height, &depth, 528212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian unpack, &unpackNB); 529212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian unpack = &unpackNB; 530212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian border = 0; 531212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian } 532212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian 533212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian postConvWidth = width; 534212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian postConvHeight = height; 535212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian 536cfe9e66f2bc596c43760911e7c1604bb32cdee28Brian stImage->face = _mesa_tex_target_to_face(target); 53714b98343309fdcff3514f05020303f7b40e83a4aBrian stImage->level = level; 53824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 53924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian if (ctx->_ImageTransferState & IMAGE_CONVOLUTION_BIT) { 54024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian _mesa_adjust_image_for_convolution(ctx, dims, &postConvWidth, 54124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian &postConvHeight); 54224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 54324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 54424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian /* choose the texture format */ 54524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian texImage->TexFormat = st_ChooseTextureFormat(ctx, internalFormat, 546afc54983370033b65e3a7cbb29bd9c87156f0881Brian format, type); 54724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 54824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian _mesa_set_fetch_functions(texImage, dims); 54924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 55024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian if (texImage->TexFormat->TexelBytes == 0) { 55124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian /* must be a compressed format */ 55224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian texelBytes = 0; 55324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian texImage->IsCompressed = GL_TRUE; 55424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian texImage->CompressedSize = 55524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian ctx->Driver.CompressedTextureSize(ctx, texImage->Width, 55624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian texImage->Height, texImage->Depth, 55724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian texImage->TexFormat->MesaFormat); 558afc54983370033b65e3a7cbb29bd9c87156f0881Brian } 559afc54983370033b65e3a7cbb29bd9c87156f0881Brian else { 56024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian texelBytes = texImage->TexFormat->TexelBytes; 56124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 56224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian /* Minimum pitch of 32 bytes */ 56324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian if (postConvWidth * texelBytes < 32) { 56424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian postConvWidth = 32 / texelBytes; 56524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian texImage->RowStride = postConvWidth; 56624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 56724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 56824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian assert(texImage->RowStride == postConvWidth); 56924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 57024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 57124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian /* Release the reference to a potentially orphaned buffer. 57224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * Release any old malloced memory. 57324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 574753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer if (stImage->pt) { 575753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer ctx->st->pipe->texture_release(ctx->st->pipe, &stImage->pt); 57624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian assert(!texImage->Data); 57724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 57824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian else if (texImage->Data) { 57924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian _mesa_align_free(texImage->Data); 58024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 58124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 5824da1cdf78fa3b954840650fa46cf72da5daf149fBrian /* If this is the only mipmap level in the texture, could call 58324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * bmBufferData with NULL data to free the old block and avoid 58424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * waiting on any outstanding fences. 58524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 586753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer if (stObj->pt && 5874da1cdf78fa3b954840650fa46cf72da5daf149fBrian /*stObj->pt->first_level == level &&*/ 588753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer stObj->pt->last_level == level && 589753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer stObj->pt->target != PIPE_TEXTURE_CUBE && 590753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer !st_texture_match_image(stObj->pt, &stImage->base, 59114b98343309fdcff3514f05020303f7b40e83a4aBrian stImage->face, stImage->level)) { 59224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 59324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian DBG("release it\n"); 594753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer ctx->st->pipe->texture_release(ctx->st->pipe, &stObj->pt); 595753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer assert(!stObj->pt); 59624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 59724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 598753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer if (!stObj->pt) { 599753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer guess_and_alloc_texture(ctx->st, stObj, stImage); 600753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer if (!stObj->pt) { 601753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer DBG("guess_and_alloc_texture: failed\n"); 60224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 60324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 60424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 605753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer assert(!stImage->pt); 60624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 607753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer if (stObj->pt && 608753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer st_texture_match_image(stObj->pt, &stImage->base, 60914b98343309fdcff3514f05020303f7b40e83a4aBrian stImage->face, stImage->level)) { 61024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 611753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer pipe_texture_reference(ctx->st->pipe, &stImage->pt, stObj->pt); 612753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer assert(stImage->pt); 61324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 61424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 615753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer if (!stImage->pt) 616753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer DBG("XXX: Image did not fit into texture - storing in local memory!\n"); 61724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 61824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#if 0 /* XXX FIX when st_buffer_objects are in place */ 61924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian /* PBO fastpaths: 62024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 62124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian if (dims <= 2 && 622753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer stImage->pt && 62324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian intel_buffer_object(unpack->BufferObj) && 62424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian check_pbo_format(internalFormat, format, 625753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer type, texImage->TexFormat)) { 62624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 62724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian DBG("trying pbo upload\n"); 62824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 62924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 63024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 63124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian /* Otherwise, attempt to use the blitter for PBO image uploads. 63224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 63314b98343309fdcff3514f05020303f7b40e83a4aBrian if (try_pbo_upload(intel, stImage, unpack, 63424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian internalFormat, 63524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian width, height, format, type, pixels)) { 63624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian DBG("pbo upload succeeded\n"); 63724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian return; 63824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 63924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 64024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian DBG("pbo upload failed\n"); 64124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 64224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#else 64324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian (void) try_pbo_upload; 64424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian (void) check_pbo_format; 64524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#endif 64624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 64724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 648987d59bb83e9e08192563e5f1b52949c5511053cMichel Dänzer /* st_CopyTexImage calls this function with pixels == NULL, with 649753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer * the expectation that the texture will be set up but nothing 65024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * more will be done. This is where those calls return: 65124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 65224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian if (compressed) { 65324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian pixels = _mesa_validate_pbo_compressed_teximage(ctx, imageSize, pixels, 65424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian unpack, 65524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian "glCompressedTexImage"); 65624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } else { 65724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian pixels = _mesa_validate_pbo_teximage(ctx, dims, width, height, 1, 65824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian format, type, 65924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian pixels, unpack, "glTexImage"); 66024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 66124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian if (!pixels) 66224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian return; 66324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 664753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer if (stImage->pt) { 665753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer texImage->Data = st_texture_image_map(ctx->st, stImage, 0); 666753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer dstRowStride = stImage->surface->pitch * stImage->surface->cpp; 66724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 66824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian else { 66924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian /* Allocate regular memory and store the image there temporarily. */ 67024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian if (texImage->IsCompressed) { 67124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian sizeInBytes = texImage->CompressedSize; 67224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian dstRowStride = 67324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian _mesa_compressed_row_stride(texImage->TexFormat->MesaFormat, width); 67424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian assert(dims != 3); 67524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 67624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian else { 67724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian dstRowStride = postConvWidth * texelBytes; 67824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian sizeInBytes = depth * dstRowStride * postConvHeight; 67924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 68024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 68124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian texImage->Data = malloc(sizeInBytes); 68224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 68324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 68424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian DBG("Upload image %dx%dx%d row_len %x pitch %x\n", 68524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian width, height, depth, width * texelBytes, dstRowStride); 68624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 68724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian /* Copy data. Would like to know when it's ok for us to eg. use 68824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * the blitter to copy. Or, use the hardware to do the format 68924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * conversion and copy: 69024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 69124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian if (compressed) { 692afc54983370033b65e3a7cbb29bd9c87156f0881Brian memcpy(texImage->Data, pixels, imageSize); 69324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 694753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer else { 695753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer GLuint srcImageStride = _mesa_image_image_stride(unpack, width, height, 696753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer format, type); 697753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer int i; 6985823f99d0fbc054b87aeb1bc15d413d3eadd27a8Brian const GLubyte *src = (const GLubyte *) pixels; 699753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer 700753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer for (i = 0; i++ < depth;) { 701753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer if (!texImage->TexFormat->StoreImage(ctx, dims, 702753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer texImage->_BaseFormat, 703753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer texImage->TexFormat, 704753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer texImage->Data, 705753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer 0, 0, 0, /* dstX/Y/Zoffset */ 706753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer dstRowStride, 707753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer texImage->ImageOffsets, 708753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer width, height, 1, 7095823f99d0fbc054b87aeb1bc15d413d3eadd27a8Brian format, type, src, unpack)) { 710753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage"); 711753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer } 712753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer 713753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer if (stImage->pt && i < depth) { 714b859cdf6f191b4d8b56537c8dc30082a7e2d94b3Michel Dänzer st_texture_image_unmap(stImage); 715753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer texImage->Data = st_texture_image_map(ctx->st, stImage, i); 7165823f99d0fbc054b87aeb1bc15d413d3eadd27a8Brian src += srcImageStride; 717753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer } 718753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer } 71924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 72024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 72124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian _mesa_unmap_teximage_pbo(ctx, unpack); 72224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 723753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer if (stImage->pt) { 724b859cdf6f191b4d8b56537c8dc30082a7e2d94b3Michel Dänzer st_texture_image_unmap(stImage); 72524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian texImage->Data = NULL; 72624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 72724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 72862abcb9aacc33218d0143a743c738435794b32a9Brian#if 01 72924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian if (level == texObj->BaseLevel && texObj->GenerateMipmap) { 73062abcb9aacc33218d0143a743c738435794b32a9Brian ctx->Driver.GenerateMipmap(ctx, target, texObj); 73124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 73224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#endif 73324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 73424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 73524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 73624df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void 73724df8f895fe8807aa2ba058e71bd40adfc01d21eBrianst_TexImage3D(GLcontext * ctx, 73824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLenum target, GLint level, 73924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLint internalFormat, 74024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLint width, GLint height, GLint depth, 74124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLint border, 74224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLenum format, GLenum type, const void *pixels, 74324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian const struct gl_pixelstore_attrib *unpack, 74424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian struct gl_texture_object *texObj, 74524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian struct gl_texture_image *texImage) 74624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 74724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian st_TexImage(ctx, 3, target, level, 74824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian internalFormat, width, height, depth, border, 74924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian format, type, pixels, unpack, texObj, texImage, 0, 0); 75024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 75124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 75224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 75324df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void 75424df8f895fe8807aa2ba058e71bd40adfc01d21eBrianst_TexImage2D(GLcontext * ctx, 75524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLenum target, GLint level, 75624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLint internalFormat, 75724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLint width, GLint height, GLint border, 75824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLenum format, GLenum type, const void *pixels, 75924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian const struct gl_pixelstore_attrib *unpack, 76024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian struct gl_texture_object *texObj, 76124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian struct gl_texture_image *texImage) 76224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 76324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian st_TexImage(ctx, 2, target, level, 76424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian internalFormat, width, height, 1, border, 76524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian format, type, pixels, unpack, texObj, texImage, 0, 0); 76624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 76724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 76824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 76924df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void 77024df8f895fe8807aa2ba058e71bd40adfc01d21eBrianst_TexImage1D(GLcontext * ctx, 77124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLenum target, GLint level, 77224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLint internalFormat, 77324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLint width, GLint border, 77424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLenum format, GLenum type, const void *pixels, 77524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian const struct gl_pixelstore_attrib *unpack, 77624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian struct gl_texture_object *texObj, 77724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian struct gl_texture_image *texImage) 77824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 77924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian st_TexImage(ctx, 1, target, level, 78024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian internalFormat, width, 1, 1, border, 78124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian format, type, pixels, unpack, texObj, texImage, 0, 0); 78224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 78324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 78424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 78524df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void 78624df8f895fe8807aa2ba058e71bd40adfc01d21eBrianst_CompressedTexImage2D( GLcontext *ctx, GLenum target, GLint level, 78724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLint internalFormat, 78824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLint width, GLint height, GLint border, 78924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLsizei imageSize, const GLvoid *data, 79024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian struct gl_texture_object *texObj, 79124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian struct gl_texture_image *texImage ) 79224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 79324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian st_TexImage(ctx, 2, target, level, 79424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian internalFormat, width, height, 1, border, 79524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 0, 0, data, &ctx->Unpack, texObj, texImage, imageSize, 1); 79624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 79724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 79824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 79924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian/** 80024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * Need to map texture image into memory before copying image data, 80124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * then unmap it. 80224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 80324df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void 80424df8f895fe8807aa2ba058e71bd40adfc01d21eBrianst_get_tex_image(GLcontext * ctx, GLenum target, GLint level, 80524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLenum format, GLenum type, GLvoid * pixels, 80624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian struct gl_texture_object *texObj, 80724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian struct gl_texture_image *texImage, int compressed) 80824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 80924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian struct st_texture_image *stImage = st_texture_image(texImage); 810753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer GLuint dstImageStride = _mesa_image_image_stride(&ctx->Pack, texImage->Width, 811753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer texImage->Height, format, 812753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer type); 813753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer GLuint depth; 814753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer int i; 8155823f99d0fbc054b87aeb1bc15d413d3eadd27a8Brian GLubyte *dest; 81624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 81724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian /* Map */ 818753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer if (stImage->pt) { 81924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian /* Image is stored in hardware format in a buffer managed by the 82024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * kernel. Need to explicitly map and unmap it. 82124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 822753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer texImage->Data = st_texture_image_map(ctx->st, stImage, 0); 823753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer texImage->RowStride = stImage->surface->pitch; 82424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 82524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian else { 82624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian /* Otherwise, the image should actually be stored in 827753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer * texImage->Data. This is pretty confusing for 82824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * everybody, I'd much prefer to separate the two functions of 82924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * texImage->Data - storage for texture images in main memory 83024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * and access (ie mappings) of images. In other words, we'd 83124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * create a new texImage->Map field and leave Data simply for 83224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * storage. 83324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 834753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer assert(texImage->Data); 83524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 83624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 837753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer depth = texImage->Depth; 838753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer texImage->Depth = 1; 83924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 8405823f99d0fbc054b87aeb1bc15d413d3eadd27a8Brian dest = (GLubyte *) pixels; 8415823f99d0fbc054b87aeb1bc15d413d3eadd27a8Brian 842753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer for (i = 0; i++ < depth;) { 843753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer if (compressed) { 8445823f99d0fbc054b87aeb1bc15d413d3eadd27a8Brian _mesa_get_compressed_teximage(ctx, target, level, dest, 845753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer texObj, texImage); 846753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer } else { 8475823f99d0fbc054b87aeb1bc15d413d3eadd27a8Brian _mesa_get_teximage(ctx, target, level, format, type, dest, 848753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer texObj, texImage); 849753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer } 850753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer 851753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer if (stImage->pt && i < depth) { 852b859cdf6f191b4d8b56537c8dc30082a7e2d94b3Michel Dänzer st_texture_image_unmap(stImage); 853753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer texImage->Data = st_texture_image_map(ctx->st, stImage, i); 8545823f99d0fbc054b87aeb1bc15d413d3eadd27a8Brian dest += dstImageStride; 855753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer } 85624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 857753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer 858753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer texImage->Depth = depth; 85924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 86024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian /* Unmap */ 861753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer if (stImage->pt) { 862b859cdf6f191b4d8b56537c8dc30082a7e2d94b3Michel Dänzer st_texture_image_unmap(stImage); 863753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer texImage->Data = NULL; 86424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 86524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 86624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 86724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 86824df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void 86924df8f895fe8807aa2ba058e71bd40adfc01d21eBrianst_GetTexImage(GLcontext * ctx, GLenum target, GLint level, 87024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLenum format, GLenum type, GLvoid * pixels, 87124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian struct gl_texture_object *texObj, 87224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian struct gl_texture_image *texImage) 87324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 87424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian st_get_tex_image(ctx, target, level, format, type, pixels, 87524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian texObj, texImage, 0); 87624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 87724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 87824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 87924df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void 88024df8f895fe8807aa2ba058e71bd40adfc01d21eBrianst_GetCompressedTexImage(GLcontext *ctx, GLenum target, GLint level, 88124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLvoid *pixels, 88224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian const struct gl_texture_object *texObj, 88324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian const struct gl_texture_image *texImage) 88424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 88524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian st_get_tex_image(ctx, target, level, 0, 0, pixels, 88624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian (struct gl_texture_object *) texObj, 88724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian (struct gl_texture_image *) texImage, 1); 88824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 88924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 89024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 89124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 89224df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void 89324df8f895fe8807aa2ba058e71bd40adfc01d21eBrianst_TexSubimage(GLcontext * ctx, 89424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLint dims, 89524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLenum target, GLint level, 89624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLint xoffset, GLint yoffset, GLint zoffset, 89724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLint width, GLint height, GLint depth, 89824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLenum format, GLenum type, const void *pixels, 89924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian const struct gl_pixelstore_attrib *packing, 90024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian struct gl_texture_object *texObj, 90124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian struct gl_texture_image *texImage) 90224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 90324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian struct st_texture_image *stImage = st_texture_image(texImage); 90424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLuint dstRowStride; 905753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer GLuint srcImageStride = _mesa_image_image_stride(packing, width, height, 906753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer format, type); 907753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer int i; 9085823f99d0fbc054b87aeb1bc15d413d3eadd27a8Brian const GLubyte *src; 90924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 91024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian DBG("%s target %s level %d offset %d,%d %dx%d\n", __FUNCTION__, 91124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian _mesa_lookup_enum_by_nr(target), 91224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian level, xoffset, yoffset, width, height); 91324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 91424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian pixels = 91524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian _mesa_validate_pbo_teximage(ctx, dims, width, height, depth, format, 91624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian type, pixels, packing, "glTexSubImage2D"); 91724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian if (!pixels) 91824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian return; 91924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 92024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian /* Map buffer if necessary. Need to lock to prevent other contexts 92124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * from uploading the buffer under us. 92224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 923753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer if (stImage->pt) { 924753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer texImage->Data = st_texture_image_map(ctx->st, stImage, zoffset); 925753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer dstRowStride = stImage->surface->pitch * stImage->surface->cpp; 926753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer } 927753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer 9285823f99d0fbc054b87aeb1bc15d413d3eadd27a8Brian src = (const GLubyte *) pixels; 9295823f99d0fbc054b87aeb1bc15d413d3eadd27a8Brian 930753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer for (i = 0; i++ < depth;) { 931753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer if (!texImage->TexFormat->StoreImage(ctx, dims, texImage->_BaseFormat, 932753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer texImage->TexFormat, 933753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer texImage->Data, 934753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer xoffset, yoffset, 0, 935753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer dstRowStride, 936753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer texImage->ImageOffsets, 937753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer width, height, 1, 9385823f99d0fbc054b87aeb1bc15d413d3eadd27a8Brian format, type, src, packing)) { 939987d59bb83e9e08192563e5f1b52949c5511053cMichel Dänzer _mesa_error(ctx, GL_OUT_OF_MEMORY, "st_TexSubImage"); 940753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer } 941753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer 942753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer if (stImage->pt && i < depth) { 943b859cdf6f191b4d8b56537c8dc30082a7e2d94b3Michel Dänzer st_texture_image_unmap(stImage); 944753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer texImage->Data = st_texture_image_map(ctx->st, stImage, zoffset + i); 9455823f99d0fbc054b87aeb1bc15d413d3eadd27a8Brian src += srcImageStride; 946753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer } 94724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 94824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 94924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#if 0 95024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian /* GL_SGIS_generate_mipmap */ 95124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian if (level == texObj->BaseLevel && texObj->GenerateMipmap) { 95224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian _mesa_generate_mipmap(ctx, target, 95324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian &ctx->Texture.Unit[ctx->Texture.CurrentUnit], 95424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian texObj); 95524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 95624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#endif 95724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 95824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian _mesa_unmap_teximage_pbo(ctx, packing); 95924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 960753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer if (stImage->pt) { 961b859cdf6f191b4d8b56537c8dc30082a7e2d94b3Michel Dänzer st_texture_image_unmap(stImage); 96224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian texImage->Data = NULL; 96324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 96424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 96524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 96624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 96724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 96824df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void 96924df8f895fe8807aa2ba058e71bd40adfc01d21eBrianst_TexSubImage3D(GLcontext * ctx, 97024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLenum target, 97124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLint level, 97224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLint xoffset, GLint yoffset, GLint zoffset, 97324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLsizei width, GLsizei height, GLsizei depth, 97424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLenum format, GLenum type, 97524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian const GLvoid * pixels, 97624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian const struct gl_pixelstore_attrib *packing, 97724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian struct gl_texture_object *texObj, 97824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian struct gl_texture_image *texImage) 97924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 980b245840b86cf877c9b8d666edf229364a84f1deaBrian st_TexSubimage(ctx, 3, target, level, 981b245840b86cf877c9b8d666edf229364a84f1deaBrian xoffset, yoffset, zoffset, 982b245840b86cf877c9b8d666edf229364a84f1deaBrian width, height, depth, 983b245840b86cf877c9b8d666edf229364a84f1deaBrian format, type, pixels, packing, texObj, texImage); 98424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 98524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 98624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 98724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 98824df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void 98924df8f895fe8807aa2ba058e71bd40adfc01d21eBrianst_TexSubImage2D(GLcontext * ctx, 99024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLenum target, 99124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLint level, 99224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLint xoffset, GLint yoffset, 99324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLsizei width, GLsizei height, 99424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLenum format, GLenum type, 99524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian const GLvoid * pixels, 99624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian const struct gl_pixelstore_attrib *packing, 99724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian struct gl_texture_object *texObj, 99824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian struct gl_texture_image *texImage) 99924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 1000b245840b86cf877c9b8d666edf229364a84f1deaBrian st_TexSubimage(ctx, 2, target, level, 1001b245840b86cf877c9b8d666edf229364a84f1deaBrian xoffset, yoffset, 0, 1002b245840b86cf877c9b8d666edf229364a84f1deaBrian width, height, 1, 1003b245840b86cf877c9b8d666edf229364a84f1deaBrian format, type, pixels, packing, texObj, texImage); 100424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 100524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 100624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 100724df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void 100824df8f895fe8807aa2ba058e71bd40adfc01d21eBrianst_TexSubImage1D(GLcontext * ctx, 100924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLenum target, 101024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLint level, 101124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLint xoffset, 101224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLsizei width, 101324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLenum format, GLenum type, 101424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian const GLvoid * pixels, 101524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian const struct gl_pixelstore_attrib *packing, 101624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian struct gl_texture_object *texObj, 101724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian struct gl_texture_image *texImage) 101824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 1019b245840b86cf877c9b8d666edf229364a84f1deaBrian st_TexSubimage(ctx, 1, target, level, 1020b245840b86cf877c9b8d666edf229364a84f1deaBrian xoffset, 0, 0, 1021b245840b86cf877c9b8d666edf229364a84f1deaBrian width, 1, 1, 1022b245840b86cf877c9b8d666edf229364a84f1deaBrian format, type, pixels, packing, texObj, texImage); 102324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 102424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 102524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 102624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 102724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian/** 1028038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian * Return 0 for GL_TEXTURE_CUBE_MAP_POSITIVE_X, 1029038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian * 1 for GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 1030038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian * etc. 1031038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian * XXX duplicated from main/teximage.c 1032038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian */ 1033038cb561eb094af2f2ba06e18e61246fc0c87c3cBrianstatic uint 1034038cb561eb094af2f2ba06e18e61246fc0c87c3cBriantexture_face(GLenum target) 1035038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian{ 1036038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian if (target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB && 1037038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB) 1038038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian return (GLuint) target - (GLuint) GL_TEXTURE_CUBE_MAP_POSITIVE_X; 1039038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian else 1040038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian return 0; 1041038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian} 1042038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian 1043038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian 1044038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian 1045038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian/** 1046b859cdf6f191b4d8b56537c8dc30082a7e2d94b3Michel Dänzer * Do a CopyTexSubImage operation by mapping the source surface and 1047b859cdf6f191b4d8b56537c8dc30082a7e2d94b3Michel Dänzer * dest surface and using get_tile()/put_tile() to access the pixels/texels. 1048c6717a86420d7141013165f7acd50b3c3f751756Brian * 1049c6717a86420d7141013165f7acd50b3c3f751756Brian * Note: srcY=0=TOP of renderbuffer 1050038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian */ 1051038cb561eb094af2f2ba06e18e61246fc0c87c3cBrianstatic void 1052038cb561eb094af2f2ba06e18e61246fc0c87c3cBrianfallback_copy_texsubimage(GLcontext *ctx, 1053038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian GLenum target, 1054038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian GLint level, 1055038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian struct st_renderbuffer *strb, 1056038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian struct st_texture_image *stImage, 1057038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian GLenum baseFormat, 1058038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian GLint destX, GLint destY, GLint destZ, 1059038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian GLint srcX, GLint srcY, 1060038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian GLsizei width, GLsizei height) 1061038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian{ 1062038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian struct pipe_context *pipe = ctx->st->pipe; 1063038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian const uint face = texture_face(target); 1064753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer struct pipe_texture *pt = stImage->pt; 1065038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian struct pipe_surface *src_surf, *dest_surf; 1066038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian GLfloat *data; 10675c83f1371978472fbe4bba8f686733c6b519874aBrian GLint row, yStep; 10685c83f1371978472fbe4bba8f686733c6b519874aBrian 10695c83f1371978472fbe4bba8f686733c6b519874aBrian /* determine bottom-to-top vs. top-to-bottom order */ 10705c83f1371978472fbe4bba8f686733c6b519874aBrian if (st_fb_orientation(ctx->ReadBuffer) == Y_0_TOP) { 10715c83f1371978472fbe4bba8f686733c6b519874aBrian destY = height - 1 - destY; 10725c83f1371978472fbe4bba8f686733c6b519874aBrian yStep = -1; 10735c83f1371978472fbe4bba8f686733c6b519874aBrian } 10745c83f1371978472fbe4bba8f686733c6b519874aBrian else { 10755c83f1371978472fbe4bba8f686733c6b519874aBrian yStep = 1; 10765c83f1371978472fbe4bba8f686733c6b519874aBrian } 1077038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian 1078038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian src_surf = strb->surface; 1079038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian 1080753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer dest_surf = pipe->get_tex_surface(pipe, pt, 1081038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian face, level, destZ); 1082038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian 10835c83f1371978472fbe4bba8f686733c6b519874aBrian /* buffer for one row */ 10845c83f1371978472fbe4bba8f686733c6b519874aBrian data = (GLfloat *) malloc(width * 4 * sizeof(GLfloat)); 1085038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian 10865c83f1371978472fbe4bba8f686733c6b519874aBrian /* do copy row by row */ 10875c83f1371978472fbe4bba8f686733c6b519874aBrian for (row = 0; row < height; row++) { 10882014e0bacbd2661bf98d084120a109b1c0bf0df2Michel Dänzer pipe_get_tile_rgba(pipe, src_surf, srcX, srcY + row, width, 1, data); 10895c83f1371978472fbe4bba8f686733c6b519874aBrian 10905c83f1371978472fbe4bba8f686733c6b519874aBrian /* XXX we're ignoring convolution for now */ 10915c83f1371978472fbe4bba8f686733c6b519874aBrian if (ctx->_ImageTransferState) { 10925c83f1371978472fbe4bba8f686733c6b519874aBrian _mesa_apply_rgba_transfer_ops(ctx, 10935c83f1371978472fbe4bba8f686733c6b519874aBrian ctx->_ImageTransferState & ~IMAGE_CONVOLUTION_BIT, 10945c83f1371978472fbe4bba8f686733c6b519874aBrian width, (GLfloat (*)[4])data); 10955c83f1371978472fbe4bba8f686733c6b519874aBrian } 10965c83f1371978472fbe4bba8f686733c6b519874aBrian 10972014e0bacbd2661bf98d084120a109b1c0bf0df2Michel Dänzer pipe_put_tile_rgba(pipe, dest_surf, destX, destY, width, 1, data); 10985c83f1371978472fbe4bba8f686733c6b519874aBrian destY += yStep; 10995c83f1371978472fbe4bba8f686733c6b519874aBrian } 1100038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian 1101038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian free(data); 1102038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian} 1103038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian 1104038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian 1105038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian 1106038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian 1107038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian/** 1108b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian * Do a CopyTex[Sub]Image using an optimized hardware (blit) path. 1109b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian * Note that the region to copy has already been clip tested. 1110c6717a86420d7141013165f7acd50b3c3f751756Brian * 1111c6717a86420d7141013165f7acd50b3c3f751756Brian * Note: srcY=0=Bottom of renderbuffer 1112c6717a86420d7141013165f7acd50b3c3f751756Brian * 1113b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian * \return GL_TRUE if success, GL_FALSE if failure (use a fallback) 111424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 1115038cb561eb094af2f2ba06e18e61246fc0c87c3cBrianstatic void 111624df8f895fe8807aa2ba058e71bd40adfc01d21eBriando_copy_texsubimage(GLcontext *ctx, 1117038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian GLenum target, GLint level, 1118038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian GLint destX, GLint destY, GLint destZ, 1119038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian GLint srcX, GLint srcY, 1120038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian GLsizei width, GLsizei height) 112124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 1122038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian struct gl_texture_unit *texUnit = 1123038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; 1124038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian struct gl_texture_object *texObj = 1125038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian _mesa_select_tex_object(ctx, texUnit, target); 1126038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian struct gl_texture_image *texImage = 1127038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian _mesa_select_tex_image(ctx, texObj, target, level); 1128038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian struct st_texture_image *stImage = st_texture_image(texImage); 1129038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian GLenum baseFormat = texImage->InternalFormat; 1130b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian struct gl_framebuffer *fb = ctx->ReadBuffer; 1131b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian struct st_renderbuffer *strb; 1132b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian struct pipe_context *pipe = ctx->st->pipe; 1133753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer struct pipe_surface *dest_surface; 1134b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian uint dest_format, src_format; 1135e922adbe1d6c1764968377658ea92ae6de0585dbMichel Dänzer uint do_flip = FALSE; 113624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 1137038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian (void) texImage; 1138038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian 1139b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian /* determine if copying depth or color data */ 1140b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian if (baseFormat == GL_DEPTH_COMPONENT) { 1141b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian strb = st_renderbuffer(fb->_DepthBuffer); 114224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 1143b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian else if (baseFormat == GL_DEPTH_STENCIL_EXT) { 1144b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian strb = st_renderbuffer(fb->_StencilBuffer); 1145b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian } 1146b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian else { 1147b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian /* baseFormat == GL_RGB, GL_RGBA, GL_ALPHA, etc */ 1148b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian strb = st_renderbuffer(fb->_ColorReadBuffer); 1149b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian } 1150b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian 1151b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian assert(strb); 1152b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian assert(strb->surface); 1153753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer assert(stImage->pt); 1154c6717a86420d7141013165f7acd50b3c3f751756Brian 1155c6717a86420d7141013165f7acd50b3c3f751756Brian if (st_fb_orientation(ctx->ReadBuffer) == Y_0_TOP) { 1156c6717a86420d7141013165f7acd50b3c3f751756Brian srcY = strb->Base.Height - srcY - height; 1157e922adbe1d6c1764968377658ea92ae6de0585dbMichel Dänzer do_flip = TRUE; 1158c6717a86420d7141013165f7acd50b3c3f751756Brian } 115924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 1160b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian src_format = strb->surface->format; 1161753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer dest_format = stImage->pt->format; 1162b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian 1163753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer dest_surface = pipe->get_tex_surface(pipe, stImage->pt, stImage->face, 1164753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer stImage->level, destZ); 1165b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian 1166038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian if (src_format == dest_format && 11675c83f1371978472fbe4bba8f686733c6b519874aBrian ctx->_ImageTransferState == 0x0 && 1168b859cdf6f191b4d8b56537c8dc30082a7e2d94b3Michel Dänzer strb->surface->buffer && 1169b859cdf6f191b4d8b56537c8dc30082a7e2d94b3Michel Dänzer dest_surface->buffer && 1170753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer strb->surface->cpp == stImage->pt->cpp) { 1171038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian /* do blit-style copy */ 1172038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian 1173038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian /* XXX may need to invert image depending on window 1174038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian * vs. user-created FBO 1175038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian */ 1176b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian 117724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#if 0 1178038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian /* A bit of fiddling to get the blitter to work with -ve 1179038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian * pitches. But we get a nice inverted blit this way, so it's 1180038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian * worth it: 1181038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian */ 1182038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian intelEmitCopyBlit(intel, 1183753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer stImage->pt->cpp, 1184038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian -src->pitch, 1185038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian src->buffer, 1186038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian src->height * src->pitch * src->cpp, 1187753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer stImage->pt->pitch, 1188753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer stImage->pt->region->buffer, 1189038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian dest_offset, 1190038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian x, y + height, dstx, dsty, width, height, 1191038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian GL_COPY); /* ? */ 119224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#else 1193b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian 119411a80160fd60d1eb1541b49128c659526a5d8ac8Michel Dänzer pipe->surface_copy(pipe, 1195e922adbe1d6c1764968377658ea92ae6de0585dbMichel Dänzer do_flip, 119611a80160fd60d1eb1541b49128c659526a5d8ac8Michel Dänzer /* dest */ 119711a80160fd60d1eb1541b49128c659526a5d8ac8Michel Dänzer dest_surface, 119811a80160fd60d1eb1541b49128c659526a5d8ac8Michel Dänzer destX, destY, 119911a80160fd60d1eb1541b49128c659526a5d8ac8Michel Dänzer /* src */ 120011a80160fd60d1eb1541b49128c659526a5d8ac8Michel Dänzer strb->surface, 120111a80160fd60d1eb1541b49128c659526a5d8ac8Michel Dänzer srcX, srcY, 120211a80160fd60d1eb1541b49128c659526a5d8ac8Michel Dänzer /* size */ 120311a80160fd60d1eb1541b49128c659526a5d8ac8Michel Dänzer width, height); 120424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#endif 1205038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian } 1206038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian else { 1207038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian fallback_copy_texsubimage(ctx, target, level, 1208038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian strb, stImage, baseFormat, 1209038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian destX, destY, destZ, 1210038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian srcX, srcY, width, height); 1211038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian } 1212038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian 1213753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer pipe_surface_reference(&dest_surface, NULL); 121424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 121524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#if 0 121624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian /* GL_SGIS_generate_mipmap -- this can be accelerated now. 121724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * XXX Add a ctx->Driver.GenerateMipmaps() function? 121824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 121924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian if (level == texObj->BaseLevel && texObj->GenerateMipmap) { 122024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian intel_generate_mipmap(ctx, target, 122124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian &ctx->Texture.Unit[ctx->Texture.CurrentUnit], 122224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian texObj); 122324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 122424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#endif 122524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 122624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 122724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 122824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 1229038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian 123024df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void 123124df8f895fe8807aa2ba058e71bd40adfc01d21eBrianst_CopyTexImage1D(GLcontext * ctx, GLenum target, GLint level, 123224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLenum internalFormat, 123324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLint x, GLint y, GLsizei width, GLint border) 123424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 123524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian struct gl_texture_unit *texUnit = 123624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; 123724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian struct gl_texture_object *texObj = 123824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian _mesa_select_tex_object(ctx, texUnit, target); 123924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian struct gl_texture_image *texImage = 124024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian _mesa_select_tex_image(ctx, texObj, target, level); 124124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 1242038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian#if 0 124324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian if (border) 124424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian goto fail; 1245038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian#endif 124624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 1247753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer /* Setup or redefine the texture object, texture and texture 124824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * image. Don't populate yet. 124924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 125024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian ctx->Driver.TexImage1D(ctx, target, level, internalFormat, 125124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian width, border, 125224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GL_RGBA, CHAN_TYPE, NULL, 125324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian &ctx->DefaultPacking, texObj, texImage); 125424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 1255038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian do_copy_texsubimage(ctx, target, level, 1256038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian 0, 0, 0, 1257038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian x, y, width, 1); 125824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 125924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 126024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 126124df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void 126224df8f895fe8807aa2ba058e71bd40adfc01d21eBrianst_CopyTexImage2D(GLcontext * ctx, GLenum target, GLint level, 126324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLenum internalFormat, 126424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLint x, GLint y, GLsizei width, GLsizei height, 126524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLint border) 126624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 126724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian struct gl_texture_unit *texUnit = 126824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; 126924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian struct gl_texture_object *texObj = 127024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian _mesa_select_tex_object(ctx, texUnit, target); 127124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian struct gl_texture_image *texImage = 127224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian _mesa_select_tex_image(ctx, texObj, target, level); 127324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 1274038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian#if 0 127524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian if (border) 127624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian goto fail; 1277038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian#endif 127824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 1279753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer /* Setup or redefine the texture object, texture and texture 128024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * image. Don't populate yet. 128124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 128224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian ctx->Driver.TexImage2D(ctx, target, level, internalFormat, 128324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian width, height, border, 128424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GL_RGBA, CHAN_TYPE, NULL, 128524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian &ctx->DefaultPacking, texObj, texImage); 128624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 128724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 1288038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian do_copy_texsubimage(ctx, target, level, 1289038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian 0, 0, 0, 1290038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian x, y, width, height); 129124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 129224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 129324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 129424df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void 129524df8f895fe8807aa2ba058e71bd40adfc01d21eBrianst_CopyTexSubImage1D(GLcontext * ctx, GLenum target, GLint level, 129624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLint xoffset, GLint x, GLint y, GLsizei width) 129724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 1298038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian const GLint yoffset = 0, zoffset = 0; 1299038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian const GLsizei height = 1; 1300038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian do_copy_texsubimage(ctx, target, level, 1301038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian xoffset, yoffset, zoffset, 1302038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian x, y, width, height); 130324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 130424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 130524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 130624df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void 130724df8f895fe8807aa2ba058e71bd40adfc01d21eBrianst_CopyTexSubImage2D(GLcontext * ctx, GLenum target, GLint level, 130824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLint xoffset, GLint yoffset, 130924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLint x, GLint y, GLsizei width, GLsizei height) 131024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 1311038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian const GLint zoffset = 0; 1312038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian do_copy_texsubimage(ctx, target, level, 1313038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian xoffset, yoffset, zoffset, 1314038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian x, y, width, height); 1315038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian} 131624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 131724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 1318038cb561eb094af2f2ba06e18e61246fc0c87c3cBrianstatic void 1319038cb561eb094af2f2ba06e18e61246fc0c87c3cBrianst_CopyTexSubImage3D(GLcontext * ctx, GLenum target, GLint level, 1320038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian GLint xoffset, GLint yoffset, GLint zoffset, 1321038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian GLint x, GLint y, GLsizei width, GLsizei height) 1322038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian{ 1323038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian do_copy_texsubimage(ctx, target, level, 1324038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian xoffset, yoffset, zoffset, 1325038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian x, y, width, height); 132624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 132724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 132824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 132924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 133024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 133124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian/** 133224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * Compute which mipmap levels that really need to be sent to the hardware. 133324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * This depends on the base image size, GL_TEXTURE_MIN_LOD, 133424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * GL_TEXTURE_MAX_LOD, GL_TEXTURE_BASE_LEVEL, and GL_TEXTURE_MAX_LEVEL. 133524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 133624df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void 133714b98343309fdcff3514f05020303f7b40e83a4aBriancalculate_first_last_level(struct st_texture_object *stObj) 133824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 133914b98343309fdcff3514f05020303f7b40e83a4aBrian struct gl_texture_object *tObj = &stObj->base; 134024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian const struct gl_texture_image *const baseImage = 134124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian tObj->Image[0][tObj->BaseLevel]; 134224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 134324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian /* These must be signed values. MinLod and MaxLod can be negative numbers, 134424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * and having firstLevel and lastLevel as signed prevents the need for 134524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * extra sign checks. 134624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 134724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian int firstLevel; 134824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian int lastLevel; 134924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 135024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian /* Yes, this looks overly complicated, but it's all needed. 135124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 135224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian switch (tObj->Target) { 135324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian case GL_TEXTURE_1D: 135424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian case GL_TEXTURE_2D: 135524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian case GL_TEXTURE_3D: 135624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian case GL_TEXTURE_CUBE_MAP: 135724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian if (tObj->MinFilter == GL_NEAREST || tObj->MinFilter == GL_LINEAR) { 135824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian /* GL_NEAREST and GL_LINEAR only care about GL_TEXTURE_BASE_LEVEL. 135924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 136024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian firstLevel = lastLevel = tObj->BaseLevel; 136124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 136224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian else { 13634da1cdf78fa3b954840650fa46cf72da5daf149fBrian firstLevel = 0; 13644da1cdf78fa3b954840650fa46cf72da5daf149fBrian lastLevel = MIN2(tObj->MaxLevel - tObj->BaseLevel, baseImage->MaxLog2); 136524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 136624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian break; 136724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian case GL_TEXTURE_RECTANGLE_NV: 136824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian case GL_TEXTURE_4D_SGIS: 136924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian firstLevel = lastLevel = 0; 137024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian break; 137124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian default: 137224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian return; 137324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 137424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 137514b98343309fdcff3514f05020303f7b40e83a4aBrian stObj->lastLevel = lastLevel; 137624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 137724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 137824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 137924df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void 1380753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzercopy_image_data_to_texture(struct st_context *st, 1381753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer struct st_texture_object *stObj, 13824da1cdf78fa3b954840650fa46cf72da5daf149fBrian GLuint dstLevel, 1383753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer struct st_texture_image *stImage) 138424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 1385753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer if (stImage->pt) { 138624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian /* Copy potentially with the blitter: 138724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 1388753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer st_texture_image_copy(st->pipe, 13894da1cdf78fa3b954840650fa46cf72da5daf149fBrian stObj->pt, dstLevel, /* dest texture, level */ 13904da1cdf78fa3b954840650fa46cf72da5daf149fBrian stImage->pt, /* src texture */ 13914da1cdf78fa3b954840650fa46cf72da5daf149fBrian stImage->face 139228b315dc1aed36bebadfacbd55e481e7baacfcb5Brian ); 139324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 1394753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer st->pipe->texture_release(st->pipe, &stImage->pt); 139524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 139624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian else { 139724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian assert(stImage->base.Data != NULL); 139824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 139924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian /* More straightforward upload. 140024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 1401753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer st_texture_image_data(st->pipe, 1402753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer stObj->pt, 140324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian stImage->face, 140424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian stImage->level, 140524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian stImage->base.Data, 140624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian stImage->base.RowStride, 140724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian stImage->base.RowStride * 140824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian stImage->base.Height); 140924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian _mesa_align_free(stImage->base.Data); 141024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian stImage->base.Data = NULL; 141124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 141224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 1413753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer pipe_texture_reference(st->pipe, &stImage->pt, stObj->pt); 141424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 141524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 141624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 1417afc54983370033b65e3a7cbb29bd9c87156f0881Brian/** 1418afc54983370033b65e3a7cbb29bd9c87156f0881Brian * Called during state validation. When this function is finished, 1419afc54983370033b65e3a7cbb29bd9c87156f0881Brian * the texture object should be ready for rendering. 1420afc54983370033b65e3a7cbb29bd9c87156f0881Brian * \return GL_FALSE if a texture border is present, GL_TRUE otherwise 142124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 142214b98343309fdcff3514f05020303f7b40e83a4aBrianGLboolean 1423753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzerst_finalize_texture(GLcontext *ctx, 1424c3af68dc5022715cc8f126b7df12f3f5248aefe7Keith Whitwell struct pipe_context *pipe, 1425c3af68dc5022715cc8f126b7df12f3f5248aefe7Keith Whitwell struct gl_texture_object *tObj, 1426753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer GLboolean *needFlush) 142724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 142814b98343309fdcff3514f05020303f7b40e83a4aBrian struct st_texture_object *stObj = st_texture_object(tObj); 1429afc54983370033b65e3a7cbb29bd9c87156f0881Brian const GLuint nr_faces = (stObj->base.Target == GL_TEXTURE_CUBE_MAP) ? 6 : 1; 143024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian int comp_byte = 0; 143124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian int cpp; 14324da1cdf78fa3b954840650fa46cf72da5daf149fBrian GLuint face; 143324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian struct st_texture_image *firstImage; 143424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 143524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian *needFlush = GL_FALSE; 143624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 143724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian /* We know/require this is true by now: 143824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 143914b98343309fdcff3514f05020303f7b40e83a4aBrian assert(stObj->base._Complete); 144024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 1441753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer /* What levels must the texture include at a minimum? 144224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 144314b98343309fdcff3514f05020303f7b40e83a4aBrian calculate_first_last_level(stObj); 14444da1cdf78fa3b954840650fa46cf72da5daf149fBrian firstImage = st_texture_image(stObj->base.Image[0][stObj->base.BaseLevel]); 144524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 144624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian /* Fallback case: 144724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 144824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian if (firstImage->base.Border) { 1449753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer if (stObj->pt) { 1450753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer ctx->st->pipe->texture_release(ctx->st->pipe, &stObj->pt); 145124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 145224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian return GL_FALSE; 145324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 145424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 145524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 1456753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer /* If both firstImage and stObj point to a texture which can contain 145724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * all active images, favour firstImage. Note that because of the 145824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * completeness requirement, we know that the image dimensions 145924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * will match. 146024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 1461753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer if (firstImage->pt && 1462753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer firstImage->pt != stObj->pt && 1463753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer firstImage->pt->last_level >= stObj->lastLevel) { 146424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 1465753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer if (stObj->pt) 1466753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer ctx->st->pipe->texture_release(ctx->st->pipe, &stObj->pt); 146724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 1468753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer pipe_texture_reference(ctx->st->pipe, &stObj->pt, firstImage->pt); 146924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 147024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 147124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian if (firstImage->base.IsCompressed) { 147214b98343309fdcff3514f05020303f7b40e83a4aBrian comp_byte = compressed_num_bytes(firstImage->base.TexFormat->MesaFormat); 147324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian cpp = comp_byte; 147424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 14755cb0d749b07be4ecbf4d4d7cde18aecdfe2dba38Brian else { 14765cb0d749b07be4ecbf4d4d7cde18aecdfe2dba38Brian cpp = firstImage->base.TexFormat->TexelBytes; 14775cb0d749b07be4ecbf4d4d7cde18aecdfe2dba38Brian } 147824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 1479753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer /* Check texture can hold all active levels. Check texture matches 148024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * target, imageFormat, etc. 148124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 1482753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer if (stObj->pt && 1483753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer (stObj->pt->target != gl_target_to_pipe(stObj->base.Target) || 148488723b2fc84628c1bc1e0008b88602b85e8668beMichel Dänzer stObj->pt->format != 148588723b2fc84628c1bc1e0008b88602b85e8668beMichel Dänzer st_mesa_format_to_pipe_format(firstImage->base.TexFormat->MesaFormat) || 1486753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer stObj->pt->last_level != stObj->lastLevel || 1487753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer stObj->pt->width[0] != firstImage->base.Width || 1488753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer stObj->pt->height[0] != firstImage->base.Height || 1489753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer stObj->pt->depth[0] != firstImage->base.Depth || 1490753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer stObj->pt->cpp != cpp || 1491753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer stObj->pt->compressed != firstImage->base.IsCompressed)) { 1492753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer ctx->st->pipe->texture_release(ctx->st->pipe, &stObj->pt); 149324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 149424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 149524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 1496753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer /* May need to create a new texture: 149724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 1498753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer if (!stObj->pt) { 1499753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer stObj->pt = st_texture_create(ctx->st, 15005390a43ce06b27f6d54bc5f237aa305b6948f2afBrian gl_target_to_pipe(stObj->base.Target), 1501753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer st_mesa_format_to_pipe_format(firstImage->base.TexFormat->MesaFormat), 1502b245840b86cf877c9b8d666edf229364a84f1deaBrian stObj->lastLevel, 1503b245840b86cf877c9b8d666edf229364a84f1deaBrian firstImage->base.Width, 1504b245840b86cf877c9b8d666edf229364a84f1deaBrian firstImage->base.Height, 1505b245840b86cf877c9b8d666edf229364a84f1deaBrian firstImage->base.Depth, 1506b245840b86cf877c9b8d666edf229364a84f1deaBrian comp_byte); 150724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 150824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 1509753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer /* Pull in any images not in the object's texture: 151024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 151124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian for (face = 0; face < nr_faces; face++) { 15124da1cdf78fa3b954840650fa46cf72da5daf149fBrian GLuint level; 15134da1cdf78fa3b954840650fa46cf72da5daf149fBrian for (level = 0; level <= stObj->lastLevel; level++) { 151424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian struct st_texture_image *stImage = 15154da1cdf78fa3b954840650fa46cf72da5daf149fBrian st_texture_image(stObj->base.Image[face][stObj->base.BaseLevel + level]); 151624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 1517753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer /* Need to import images in main memory or held in other textures. 151824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 1519a34b43b3f4817268ef4b3f186203b5fbafc7214eBrian if (stImage && stObj->pt != stImage->pt) { 15204da1cdf78fa3b954840650fa46cf72da5daf149fBrian copy_image_data_to_texture(ctx->st, stObj, level, stImage); 152124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian *needFlush = GL_TRUE; 152224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 152324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 152424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 152524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 152624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 152724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian return GL_TRUE; 152824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 152924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 153024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 153124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 153224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 15336da9234fd437f97267e7831f034c78b31156d939Brianvoid 15346da9234fd437f97267e7831f034c78b31156d939Brianst_init_texture_functions(struct dd_function_table *functions) 153524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 153624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian functions->ChooseTextureFormat = st_ChooseTextureFormat; 153724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian functions->TexImage1D = st_TexImage1D; 153824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian functions->TexImage2D = st_TexImage2D; 153924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian functions->TexImage3D = st_TexImage3D; 154024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian functions->TexSubImage1D = st_TexSubImage1D; 154124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian functions->TexSubImage2D = st_TexSubImage2D; 154224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian functions->TexSubImage3D = st_TexSubImage3D; 154324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian functions->CopyTexImage1D = st_CopyTexImage1D; 154424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian functions->CopyTexImage2D = st_CopyTexImage2D; 154524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian functions->CopyTexSubImage1D = st_CopyTexSubImage1D; 154624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian functions->CopyTexSubImage2D = st_CopyTexSubImage2D; 1547038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian functions->CopyTexSubImage3D = st_CopyTexSubImage3D; 154862abcb9aacc33218d0143a743c738435794b32a9Brian functions->GenerateMipmap = st_generate_mipmap; 1549038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian 155024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian functions->GetTexImage = st_GetTexImage; 155124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 155224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian /* compressed texture functions */ 155324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian functions->CompressedTexImage2D = st_CompressedTexImage2D; 155424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian functions->GetCompressedTexImage = st_GetCompressedTexImage; 155524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 155624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian functions->NewTextureObject = st_NewTextureObject; 155724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian functions->NewTextureImage = st_NewTextureImage; 155824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian functions->DeleteTexture = st_DeleteTextureObject; 155924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian functions->FreeTexImageData = st_FreeTextureImageData; 156024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian functions->UpdateTexturePalette = 0; 156124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian functions->IsTextureResident = st_IsTextureResident; 156224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 156324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian functions->TextureMemCpy = do_memcpy; 1564f8549e8f4f8bdfebcb4e0a2754df59b3fe4fdff7Brian 1565f8549e8f4f8bdfebcb4e0a2754df59b3fe4fdff7Brian /* XXX Temporary until we can query pipe's texture sizes */ 1566f8549e8f4f8bdfebcb4e0a2754df59b3fe4fdff7Brian functions->TestProxyTexImage = _mesa_test_proxy_teximage; 156724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 1568