st_cb_texture.c revision 28b315dc1aed36bebadfacbd55e481e7baacfcb5
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" 3324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#include "main/texcompress.h" 3424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#include "main/texformat.h" 3524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#include "main/teximage.h" 3624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#include "main/texobj.h" 3724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#include "main/texstore.h" 3824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 3924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#include "state_tracker/st_context.h" 40b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian#include "state_tracker/st_cb_fbo.h" 4124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#include "state_tracker/st_cb_texture.h" 42f8ab24760d0d3f07e9ee81c98207ddf92dfe74daBrian#include "state_tracker/st_format.h" 4324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#include "state_tracker/st_mipmap_tree.h" 4424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 4524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#include "pipe/p_context.h" 46b245840b86cf877c9b8d666edf229364a84f1deaBrian#include "pipe/p_defines.h" 4724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 4824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 4924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#define DBG if (0) printf 5024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 5124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 5224df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstruct st_texture_object 5324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 5424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian struct gl_texture_object base; /* The "parent" object */ 5524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 5624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian /* The mipmap tree must include at least these levels once 5724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * validated: 5824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 5924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLuint firstLevel; 6024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLuint lastLevel; 6124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 6224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian /* Offset for firstLevel image: 6324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 6424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLuint textureOffset; 6524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 6624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian /* On validation any active images held in main memory or in other 6724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * regions will be copied to this region and the old storage freed. 6824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 6924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian struct pipe_mipmap_tree *mt; 7024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 7124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLboolean imageOverride; 7224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLint depthOverride; 7324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLuint pitchOverride; 7424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian}; 7524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 7624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 7724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 7824df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstruct st_texture_image 7924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 8024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian struct gl_texture_image base; 8124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 8224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian /* These aren't stored in gl_texture_image 8324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 8424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLuint level; 8524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLuint face; 8624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 8724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian /* If stImage->mt != NULL, image data is stored here. 8824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * Else if stImage->base.Data != NULL, image is stored there. 8924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * Else there is no image data. 9024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 9124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian struct pipe_mipmap_tree *mt; 9224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian}; 9324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 9424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 9524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 9624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 9724df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic INLINE struct st_texture_object * 9824df8f895fe8807aa2ba058e71bd40adfc01d21eBrianst_texture_object(struct gl_texture_object *obj) 9924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 10024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian return (struct st_texture_object *) obj; 10124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 10224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 10324df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic INLINE struct st_texture_image * 10424df8f895fe8807aa2ba058e71bd40adfc01d21eBrianst_texture_image(struct gl_texture_image *img) 10524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 10624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian return (struct st_texture_image *) img; 10724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 10824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 10924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 110d78dab126724e6e9d475289a086fb6f85adc3985Brianstruct pipe_mipmap_tree * 111d78dab126724e6e9d475289a086fb6f85adc3985Brianst_get_texobj_mipmap_tree(struct gl_texture_object *texObj) 112d78dab126724e6e9d475289a086fb6f85adc3985Brian{ 113d78dab126724e6e9d475289a086fb6f85adc3985Brian struct st_texture_object *stObj = st_texture_object(texObj); 114d78dab126724e6e9d475289a086fb6f85adc3985Brian return stObj->mt; 115d78dab126724e6e9d475289a086fb6f85adc3985Brian} 116d78dab126724e6e9d475289a086fb6f85adc3985Brian 117d78dab126724e6e9d475289a086fb6f85adc3985Brian 1185390a43ce06b27f6d54bc5f237aa305b6948f2afBrianstatic unsigned 1195390a43ce06b27f6d54bc5f237aa305b6948f2afBriangl_target_to_pipe(GLenum target) 1205390a43ce06b27f6d54bc5f237aa305b6948f2afBrian{ 1215390a43ce06b27f6d54bc5f237aa305b6948f2afBrian switch (target) { 1225390a43ce06b27f6d54bc5f237aa305b6948f2afBrian case GL_TEXTURE_1D: 1235390a43ce06b27f6d54bc5f237aa305b6948f2afBrian return PIPE_TEXTURE_1D; 1245390a43ce06b27f6d54bc5f237aa305b6948f2afBrian 1255390a43ce06b27f6d54bc5f237aa305b6948f2afBrian case GL_TEXTURE_2D: 1265390a43ce06b27f6d54bc5f237aa305b6948f2afBrian case GL_TEXTURE_RECTANGLE_NV: 1275390a43ce06b27f6d54bc5f237aa305b6948f2afBrian return PIPE_TEXTURE_2D; 1285390a43ce06b27f6d54bc5f237aa305b6948f2afBrian 1295390a43ce06b27f6d54bc5f237aa305b6948f2afBrian case GL_TEXTURE_3D: 1305390a43ce06b27f6d54bc5f237aa305b6948f2afBrian return PIPE_TEXTURE_3D; 1315390a43ce06b27f6d54bc5f237aa305b6948f2afBrian 1325390a43ce06b27f6d54bc5f237aa305b6948f2afBrian case GL_TEXTURE_CUBE_MAP_ARB: 1335390a43ce06b27f6d54bc5f237aa305b6948f2afBrian return PIPE_TEXTURE_CUBE; 1345390a43ce06b27f6d54bc5f237aa305b6948f2afBrian 1355390a43ce06b27f6d54bc5f237aa305b6948f2afBrian default: 1365390a43ce06b27f6d54bc5f237aa305b6948f2afBrian assert(0); 1375390a43ce06b27f6d54bc5f237aa305b6948f2afBrian return 0; 1385390a43ce06b27f6d54bc5f237aa305b6948f2afBrian } 1395390a43ce06b27f6d54bc5f237aa305b6948f2afBrian} 1405390a43ce06b27f6d54bc5f237aa305b6948f2afBrian 1415390a43ce06b27f6d54bc5f237aa305b6948f2afBrian 14224df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic int 14314b98343309fdcff3514f05020303f7b40e83a4aBriancompressed_num_bytes(GLuint mesaFormat) 14424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 14524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian int bytes = 0; 14624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian switch(mesaFormat) { 14724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 14824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian case MESA_FORMAT_RGB_FXT1: 14924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian case MESA_FORMAT_RGBA_FXT1: 15024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian case MESA_FORMAT_RGB_DXT1: 15124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian case MESA_FORMAT_RGBA_DXT1: 15224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian bytes = 2; 15324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian break; 15424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 15524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian case MESA_FORMAT_RGBA_DXT3: 15624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian case MESA_FORMAT_RGBA_DXT5: 15724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian bytes = 4; 15824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian default: 15924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian break; 16024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 16124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 16224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian return bytes; 16324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 16424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 16524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 16624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 16724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 16824df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic GLboolean 16924df8f895fe8807aa2ba058e71bd40adfc01d21eBrianst_IsTextureResident(GLcontext * ctx, struct gl_texture_object *texObj) 17024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 17124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#if 0 17224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian struct intel_context *intel = intel_context(ctx); 17324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian struct st_texture_object *stObj = st_texture_object(texObj); 17424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 17524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian return 17624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian stObj->mt && 17724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian stObj->mt->region && 17824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian intel_is_region_resident(intel, stObj->mt->region); 17924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#endif 18024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian return 1; 18124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 18224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 18324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 18424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 18524df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic struct gl_texture_image * 18624df8f895fe8807aa2ba058e71bd40adfc01d21eBrianst_NewTextureImage(GLcontext * ctx) 18724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 18824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian DBG("%s\n", __FUNCTION__); 18924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian (void) ctx; 19024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian return (struct gl_texture_image *) CALLOC_STRUCT(st_texture_image); 19124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 19224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 19324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 19424df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic struct gl_texture_object * 19524df8f895fe8807aa2ba058e71bd40adfc01d21eBrianst_NewTextureObject(GLcontext * ctx, GLuint name, GLenum target) 19624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 19724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian struct st_texture_object *obj = CALLOC_STRUCT(st_texture_object); 19824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 19924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian DBG("%s\n", __FUNCTION__); 20024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian _mesa_initialize_texture_object(&obj->base, name, target); 20124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 20224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian return &obj->base; 20324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 20424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 20524df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void 20624df8f895fe8807aa2ba058e71bd40adfc01d21eBrianst_DeleteTextureObject(GLcontext *ctx, 20724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian struct gl_texture_object *texObj) 20824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 20924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian struct pipe_context *pipe = ctx->st->pipe; 21024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian struct st_texture_object *stObj = st_texture_object(texObj); 21124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 21224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian if (stObj->mt) 21324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian st_miptree_release(pipe, &stObj->mt); 21424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 21524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian _mesa_delete_texture_object(ctx, texObj); 21624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 21724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 21824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 21924df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void 22024df8f895fe8807aa2ba058e71bd40adfc01d21eBrianst_FreeTextureImageData(GLcontext * ctx, struct gl_texture_image *texImage) 22124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 22224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian struct pipe_context *pipe = ctx->st->pipe; 22324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian struct st_texture_image *stImage = st_texture_image(texImage); 22424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 22524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian DBG("%s\n", __FUNCTION__); 22624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 22724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian if (stImage->mt) { 22824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian st_miptree_release(pipe, &stImage->mt); 22924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 23024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 23124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian if (texImage->Data) { 23224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian free(texImage->Data); 23324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian texImage->Data = NULL; 23424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 23524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 23624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 23724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 23824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 23924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 24024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian/* ================================================================ 24124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * From linux kernel i386 header files, copes with odd sizes better 24224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * than COPY_DWORDS would: 24324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * XXX Put this in src/mesa/main/imports.h ??? 24424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 24524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#if defined(i386) || defined(__i386__) 24624df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic INLINE void * 24724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian__memcpy(void *to, const void *from, size_t n) 24824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 24924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian int d0, d1, d2; 25024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian __asm__ __volatile__("rep ; movsl\n\t" 25124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian "testb $2,%b4\n\t" 25224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian "je 1f\n\t" 25324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian "movsw\n" 25424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian "1:\ttestb $1,%b4\n\t" 25524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian "je 2f\n\t" 25624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian "movsb\n" "2:":"=&c"(d0), "=&D"(d1), "=&S"(d2) 25724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian :"0"(n / 4), "q"(n), "1"((long) to), "2"((long) from) 25824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian :"memory"); 25924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian return (to); 26024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 26124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#else 26224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#define __memcpy(a,b,c) memcpy(a,b,c) 26324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#endif 26424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 26524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 26624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian/* The system memcpy (at least on ubuntu 5.10) has problems copying 26724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * to agp (writecombined) memory from a source which isn't 64-byte 26824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * aligned - there is a 4x performance falloff. 26924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * 27024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * The x86 __memcpy is immune to this but is slightly slower 27124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * (10%-ish) than the system memcpy. 27224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * 27324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * The sse_memcpy seems to have a slight cliff at 64/32 bytes, but 27424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * isn't much faster than x86_memcpy for agp copies. 27524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * 27624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * TODO: switch dynamically. 27724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 27824df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void * 27924df8f895fe8807aa2ba058e71bd40adfc01d21eBriando_memcpy(void *dest, const void *src, size_t n) 28024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 28124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian if ((((unsigned) src) & 63) || (((unsigned) dest) & 63)) { 28224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian return __memcpy(dest, src, n); 28324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 28424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian else 28524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian return memcpy(dest, src, n); 28624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 28724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 28824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 28924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian/* Functions to store texture images. Where possible, mipmap_tree's 29024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * will be created or further instantiated with image data, otherwise 29124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * images will be stored in malloc'd memory. A validation step is 29224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * required to pull those images into a mipmap tree, or otherwise 29324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * decide a fallback is required. 29424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 29524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 29624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 29724df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic int 29824df8f895fe8807aa2ba058e71bd40adfc01d21eBrianlogbase2(int n) 29924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 30024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLint i = 1; 30124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLint log2 = 0; 30224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 30324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian while (n > i) { 30424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian i *= 2; 30524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian log2++; 30624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 30724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 30824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian return log2; 30924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 31024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 31124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 31224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian/* Otherwise, store it in memory if (Border != 0) or (any dimension == 31324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * 1). 31424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * 31524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * Otherwise, if max_level >= level >= min_level, create tree with 31624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * space for textures from min_level down to max_level. 31724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * 31824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * Otherwise, create tree with space for textures from (level 31924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * 0)..(1x1). Consider pruning this tree at a validation if the 32024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * saving is worth it. 32124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 32224df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void 32324df8f895fe8807aa2ba058e71bd40adfc01d21eBrianguess_and_alloc_mipmap_tree(struct pipe_context *pipe, 32414b98343309fdcff3514f05020303f7b40e83a4aBrian struct st_texture_object *stObj, 32514b98343309fdcff3514f05020303f7b40e83a4aBrian struct st_texture_image *stImage) 32624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 32724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLuint firstLevel; 32824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLuint lastLevel; 32914b98343309fdcff3514f05020303f7b40e83a4aBrian GLuint width = stImage->base.Width; 33014b98343309fdcff3514f05020303f7b40e83a4aBrian GLuint height = stImage->base.Height; 33114b98343309fdcff3514f05020303f7b40e83a4aBrian GLuint depth = stImage->base.Depth; 33224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLuint l2width, l2height, l2depth; 33324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLuint i, comp_byte = 0; 33424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 33524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian DBG("%s\n", __FUNCTION__); 33624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 33714b98343309fdcff3514f05020303f7b40e83a4aBrian if (stImage->base.Border) 33824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian return; 33924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 34014b98343309fdcff3514f05020303f7b40e83a4aBrian if (stImage->level > stObj->base.BaseLevel && 34114b98343309fdcff3514f05020303f7b40e83a4aBrian (stImage->base.Width == 1 || 34214b98343309fdcff3514f05020303f7b40e83a4aBrian (stObj->base.Target != GL_TEXTURE_1D && 34314b98343309fdcff3514f05020303f7b40e83a4aBrian stImage->base.Height == 1) || 34414b98343309fdcff3514f05020303f7b40e83a4aBrian (stObj->base.Target == GL_TEXTURE_3D && 34514b98343309fdcff3514f05020303f7b40e83a4aBrian stImage->base.Depth == 1))) 34624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian return; 34724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 34824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian /* If this image disrespects BaseLevel, allocate from level zero. 34924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * Usually BaseLevel == 0, so it's unlikely to happen. 35024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 35114b98343309fdcff3514f05020303f7b40e83a4aBrian if (stImage->level < stObj->base.BaseLevel) 35224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian firstLevel = 0; 35324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian else 35414b98343309fdcff3514f05020303f7b40e83a4aBrian firstLevel = stObj->base.BaseLevel; 35524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 35624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 35724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian /* Figure out image dimensions at start level. 35824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 35914b98343309fdcff3514f05020303f7b40e83a4aBrian for (i = stImage->level; i > firstLevel; i--) { 36024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian width <<= 1; 36124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian if (height != 1) 36224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian height <<= 1; 36324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian if (depth != 1) 36424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian depth <<= 1; 36524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 36624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 36724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian /* Guess a reasonable value for lastLevel. This is probably going 36824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * to be wrong fairly often and might mean that we have to look at 36924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * resizable buffers, or require that buffers implement lazy 37024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * pagetable arrangements. 37124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 37214b98343309fdcff3514f05020303f7b40e83a4aBrian if ((stObj->base.MinFilter == GL_NEAREST || 37314b98343309fdcff3514f05020303f7b40e83a4aBrian stObj->base.MinFilter == GL_LINEAR) && 37414b98343309fdcff3514f05020303f7b40e83a4aBrian stImage->level == firstLevel) { 37524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian lastLevel = firstLevel; 37624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 37724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian else { 37824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian l2width = logbase2(width); 37924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian l2height = logbase2(height); 38024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian l2depth = logbase2(depth); 38124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian lastLevel = firstLevel + MAX2(MAX2(l2width, l2height), l2depth); 38224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 38324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 38414b98343309fdcff3514f05020303f7b40e83a4aBrian assert(!stObj->mt); 38514b98343309fdcff3514f05020303f7b40e83a4aBrian if (stImage->base.IsCompressed) 38614b98343309fdcff3514f05020303f7b40e83a4aBrian comp_byte = compressed_num_bytes(stImage->base.TexFormat->MesaFormat); 38714b98343309fdcff3514f05020303f7b40e83a4aBrian stObj->mt = st_miptree_create(pipe, 3885390a43ce06b27f6d54bc5f237aa305b6948f2afBrian gl_target_to_pipe(stObj->base.Target), 3895390a43ce06b27f6d54bc5f237aa305b6948f2afBrian stImage->base.InternalFormat, 3905390a43ce06b27f6d54bc5f237aa305b6948f2afBrian firstLevel, 3915390a43ce06b27f6d54bc5f237aa305b6948f2afBrian lastLevel, 3925390a43ce06b27f6d54bc5f237aa305b6948f2afBrian width, 3935390a43ce06b27f6d54bc5f237aa305b6948f2afBrian height, 3945390a43ce06b27f6d54bc5f237aa305b6948f2afBrian depth, 3955390a43ce06b27f6d54bc5f237aa305b6948f2afBrian stImage->base.TexFormat->TexelBytes, 3965390a43ce06b27f6d54bc5f237aa305b6948f2afBrian comp_byte); 39724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 398b245840b86cf877c9b8d666edf229364a84f1deaBrian stObj->mt->format 3999cf9aa1ea2c3f40a09316975410a4b0e202e82baBrian = st_mesa_format_to_pipe_format(stImage->base.TexFormat->MesaFormat); 400b245840b86cf877c9b8d666edf229364a84f1deaBrian 40124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian DBG("%s - success\n", __FUNCTION__); 40224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 40324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 40424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 40524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 40624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 40724df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic GLuint 40824df8f895fe8807aa2ba058e71bd40adfc01d21eBriantarget_to_face(GLenum target) 40924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 41024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian switch (target) { 41124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB: 41224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB: 41324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB: 41424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB: 41524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB: 41624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB: 41724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian return ((GLuint) target - (GLuint) GL_TEXTURE_CUBE_MAP_POSITIVE_X); 41824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian default: 41924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian return 0; 42024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 42124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 42224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 42324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 42424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 42524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian/* There are actually quite a few combinations this will work for, 42624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * more than what I've listed here. 42724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 42824df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic GLboolean 42924df8f895fe8807aa2ba058e71bd40adfc01d21eBriancheck_pbo_format(GLint internalFormat, 43024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLenum format, GLenum type, 43124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian const struct gl_texture_format *mesa_format) 43224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 43324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian switch (internalFormat) { 43424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian case 4: 43524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian case GL_RGBA: 43624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian return (format == GL_BGRA && 43724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian (type == GL_UNSIGNED_BYTE || 43824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian type == GL_UNSIGNED_INT_8_8_8_8_REV) && 43924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian mesa_format == &_mesa_texformat_argb8888); 44024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian case 3: 44124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian case GL_RGB: 44224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian return (format == GL_RGB && 44324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian type == GL_UNSIGNED_SHORT_5_6_5 && 44424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian mesa_format == &_mesa_texformat_rgb565); 44524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian case GL_YCBCR_MESA: 44624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian return (type == GL_UNSIGNED_SHORT_8_8_MESA || type == GL_UNSIGNED_BYTE); 44724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian default: 44824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian return GL_FALSE; 44924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 45024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 45124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 45224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 45324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian/* XXX: Do this for TexSubImage also: 45424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 45524df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic GLboolean 45624df8f895fe8807aa2ba058e71bd40adfc01d21eBriantry_pbo_upload(GLcontext *ctx, 45714b98343309fdcff3514f05020303f7b40e83a4aBrian struct st_texture_image *stImage, 45824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian const struct gl_pixelstore_attrib *unpack, 45924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLint internalFormat, 46024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLint width, GLint height, 46124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLenum format, GLenum type, const void *pixels) 46224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 46324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian return GL_FALSE; /* XXX fix flushing/locking/blitting below */ 46424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#if 000 46524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian struct intel_context *intel = intel_context(ctx); 46624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian struct intel_buffer_object *pbo = intel_buffer_object(unpack->BufferObj); 46724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLuint src_offset, src_stride; 46824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLuint dst_offset, dst_stride; 46924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 47024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian if (!pbo || 47124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian ctx._ImageTransferState || 47224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian unpack->SkipPixels || unpack->SkipRows) { 47324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian _mesa_printf("%s: failure 1\n", __FUNCTION__); 47424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian return GL_FALSE; 47524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 47624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 47724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian src_offset = (GLuint) pixels; 47824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 47924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian if (unpack->RowLength > 0) 48024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian src_stride = unpack->RowLength; 48124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian else 48224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian src_stride = width; 48324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 48414b98343309fdcff3514f05020303f7b40e83a4aBrian dst_offset = st_miptree_image_offset(stImage->mt, 48514b98343309fdcff3514f05020303f7b40e83a4aBrian stImage->face, 48614b98343309fdcff3514f05020303f7b40e83a4aBrian stImage->level); 48724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 48814b98343309fdcff3514f05020303f7b40e83a4aBrian dst_stride = stImage->mt->pitch; 48924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 49024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian { 49124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian struct _DriBufferObject *src_buffer = 49224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian intel_bufferobj_buffer(intel, pbo, INTEL_READ); 49324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 49424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian /* Temporary hack: cast to _DriBufferObject: 49524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 49624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian struct _DriBufferObject *dst_buffer = 49714b98343309fdcff3514f05020303f7b40e83a4aBrian (struct _DriBufferObject *)stImage->mt->region->buffer; 49824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 49924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 50024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian intelEmitCopyBlit(intel, 50114b98343309fdcff3514f05020303f7b40e83a4aBrian stImage->mt->cpp, 50224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian src_stride, src_buffer, src_offset, 50324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian dst_stride, dst_buffer, dst_offset, 50424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 0, 0, 0, 0, width, height, 50524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GL_COPY); 50624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 50724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 50824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian return GL_TRUE; 50924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#endif 51024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 51124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 51224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 51324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 51424df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic GLboolean 51524df8f895fe8807aa2ba058e71bd40adfc01d21eBriantry_pbo_zcopy(GLcontext *ctx, 51614b98343309fdcff3514f05020303f7b40e83a4aBrian struct st_texture_image *stImage, 51724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian const struct gl_pixelstore_attrib *unpack, 51824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLint internalFormat, 51924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLint width, GLint height, 52024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLenum format, GLenum type, const void *pixels) 52124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 52224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian return GL_FALSE; 52324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 52424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 52524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 52624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 52724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 52824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 52924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 53024df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void 53124df8f895fe8807aa2ba058e71bd40adfc01d21eBrianst_TexImage(GLcontext * ctx, 53224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLint dims, 53324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLenum target, GLint level, 53424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLint internalFormat, 53524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLint width, GLint height, GLint depth, 53624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLint border, 53724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLenum format, GLenum type, const void *pixels, 53824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian const struct gl_pixelstore_attrib *unpack, 53924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian struct gl_texture_object *texObj, 54024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian struct gl_texture_image *texImage, GLsizei imageSize, int compressed) 54124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 54224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian struct pipe_context *pipe = ctx->st->pipe; 54314b98343309fdcff3514f05020303f7b40e83a4aBrian struct st_texture_object *stObj = st_texture_object(texObj); 54414b98343309fdcff3514f05020303f7b40e83a4aBrian struct st_texture_image *stImage = st_texture_image(texImage); 54524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLint postConvWidth = width; 54624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLint postConvHeight = height; 54724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLint texelBytes, sizeInBytes; 54824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLuint dstRowStride; 54924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 55024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 55124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian DBG("%s target %s level %d %dx%dx%d border %d\n", __FUNCTION__, 55224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian _mesa_lookup_enum_by_nr(target), level, width, height, depth, border); 55324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 55414b98343309fdcff3514f05020303f7b40e83a4aBrian stImage->face = target_to_face(target); 55514b98343309fdcff3514f05020303f7b40e83a4aBrian stImage->level = level; 55624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 55724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian if (ctx->_ImageTransferState & IMAGE_CONVOLUTION_BIT) { 55824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian _mesa_adjust_image_for_convolution(ctx, dims, &postConvWidth, 55924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian &postConvHeight); 56024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 56124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 56224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian /* choose the texture format */ 56324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian texImage->TexFormat = st_ChooseTextureFormat(ctx, internalFormat, 56424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian format, type); 56524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 56624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian _mesa_set_fetch_functions(texImage, dims); 56724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 56824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian if (texImage->TexFormat->TexelBytes == 0) { 56924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian /* must be a compressed format */ 57024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian texelBytes = 0; 57124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian texImage->IsCompressed = GL_TRUE; 57224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian texImage->CompressedSize = 57324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian ctx->Driver.CompressedTextureSize(ctx, texImage->Width, 57424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian texImage->Height, texImage->Depth, 57524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian texImage->TexFormat->MesaFormat); 57624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } else { 57724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian texelBytes = texImage->TexFormat->TexelBytes; 57824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 57924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian /* Minimum pitch of 32 bytes */ 58024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian if (postConvWidth * texelBytes < 32) { 58124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian postConvWidth = 32 / texelBytes; 58224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian texImage->RowStride = postConvWidth; 58324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 58424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 58524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian assert(texImage->RowStride == postConvWidth); 58624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 58724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 58824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian /* Release the reference to a potentially orphaned buffer. 58924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * Release any old malloced memory. 59024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 59114b98343309fdcff3514f05020303f7b40e83a4aBrian if (stImage->mt) { 59214b98343309fdcff3514f05020303f7b40e83a4aBrian st_miptree_release(pipe, &stImage->mt); 59324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian assert(!texImage->Data); 59424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 59524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian else if (texImage->Data) { 59624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian _mesa_align_free(texImage->Data); 59724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 59824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 59924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian /* If this is the only texture image in the tree, could call 60024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * bmBufferData with NULL data to free the old block and avoid 60124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * waiting on any outstanding fences. 60224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 60314b98343309fdcff3514f05020303f7b40e83a4aBrian if (stObj->mt && 60414b98343309fdcff3514f05020303f7b40e83a4aBrian stObj->mt->first_level == level && 60514b98343309fdcff3514f05020303f7b40e83a4aBrian stObj->mt->last_level == level && 6065390a43ce06b27f6d54bc5f237aa305b6948f2afBrian stObj->mt->target != PIPE_TEXTURE_CUBE && 60714b98343309fdcff3514f05020303f7b40e83a4aBrian !st_miptree_match_image(stObj->mt, &stImage->base, 60814b98343309fdcff3514f05020303f7b40e83a4aBrian stImage->face, stImage->level)) { 60924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 61024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian DBG("release it\n"); 61114b98343309fdcff3514f05020303f7b40e83a4aBrian st_miptree_release(pipe, &stObj->mt); 61214b98343309fdcff3514f05020303f7b40e83a4aBrian assert(!stObj->mt); 61324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 61424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 61514b98343309fdcff3514f05020303f7b40e83a4aBrian if (!stObj->mt) { 61614b98343309fdcff3514f05020303f7b40e83a4aBrian guess_and_alloc_mipmap_tree(pipe, stObj, stImage); 61714b98343309fdcff3514f05020303f7b40e83a4aBrian if (!stObj->mt) { 61824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian DBG("guess_and_alloc_mipmap_tree: failed\n"); 61924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 62024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 62124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 62214b98343309fdcff3514f05020303f7b40e83a4aBrian assert(!stImage->mt); 62324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 62414b98343309fdcff3514f05020303f7b40e83a4aBrian if (stObj->mt && 62514b98343309fdcff3514f05020303f7b40e83a4aBrian st_miptree_match_image(stObj->mt, &stImage->base, 62614b98343309fdcff3514f05020303f7b40e83a4aBrian stImage->face, stImage->level)) { 62724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 62814b98343309fdcff3514f05020303f7b40e83a4aBrian st_miptree_reference(&stImage->mt, stObj->mt); 62914b98343309fdcff3514f05020303f7b40e83a4aBrian assert(stImage->mt); 63024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 63124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 63214b98343309fdcff3514f05020303f7b40e83a4aBrian if (!stImage->mt) 63324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian DBG("XXX: Image did not fit into tree - storing in local memory!\n"); 63424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 63524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#if 0 /* XXX FIX when st_buffer_objects are in place */ 63624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian /* PBO fastpaths: 63724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 63824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian if (dims <= 2 && 63914b98343309fdcff3514f05020303f7b40e83a4aBrian stImage->mt && 64024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian intel_buffer_object(unpack->BufferObj) && 64124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian check_pbo_format(internalFormat, format, 64214b98343309fdcff3514f05020303f7b40e83a4aBrian type, stImage->base.TexFormat)) { 64324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 64424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian DBG("trying pbo upload\n"); 64524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 64624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian /* Attempt to texture directly from PBO data (zero copy upload). 64724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * 64824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * Currently disable as it can lead to worse as well as better 64924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * performance (in particular when pipe_region_cow() is 65024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * required). 65124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 65214b98343309fdcff3514f05020303f7b40e83a4aBrian if (stObj->mt == stImage->mt && 65314b98343309fdcff3514f05020303f7b40e83a4aBrian stObj->mt->first_level == level && 65414b98343309fdcff3514f05020303f7b40e83a4aBrian stObj->mt->last_level == level) { 65524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 65614b98343309fdcff3514f05020303f7b40e83a4aBrian if (try_pbo_zcopy(intel, stImage, unpack, 65724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian internalFormat, 65824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian width, height, format, type, pixels)) { 65924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 66024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian DBG("pbo zcopy upload succeeded\n"); 66124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian return; 66224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 66324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 66424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 66524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 66624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian /* Otherwise, attempt to use the blitter for PBO image uploads. 66724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 66814b98343309fdcff3514f05020303f7b40e83a4aBrian if (try_pbo_upload(intel, stImage, unpack, 66924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian internalFormat, 67024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian width, height, format, type, pixels)) { 67124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian DBG("pbo upload succeeded\n"); 67224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian return; 67324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 67424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 67524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian DBG("pbo upload failed\n"); 67624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 67724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#else 67824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian (void) try_pbo_upload; 67924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian (void) check_pbo_format; 68024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian (void) try_pbo_zcopy; 68124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#endif 68224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 68324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 68424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian /* intelCopyTexImage calls this function with pixels == NULL, with 68524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * the expectation that the mipmap tree will be set up but nothing 68624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * more will be done. This is where those calls return: 68724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 68824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian if (compressed) { 68924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian pixels = _mesa_validate_pbo_compressed_teximage(ctx, imageSize, pixels, 69024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian unpack, 69124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian "glCompressedTexImage"); 69224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } else { 69324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian pixels = _mesa_validate_pbo_teximage(ctx, dims, width, height, 1, 69424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian format, type, 69524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian pixels, unpack, "glTexImage"); 69624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 69724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian if (!pixels) 69824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian return; 69924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 70014b98343309fdcff3514f05020303f7b40e83a4aBrian if (stImage->mt) { 70124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian texImage->Data = st_miptree_image_map(pipe, 70214b98343309fdcff3514f05020303f7b40e83a4aBrian stImage->mt, 70314b98343309fdcff3514f05020303f7b40e83a4aBrian stImage->face, 70414b98343309fdcff3514f05020303f7b40e83a4aBrian stImage->level, 70524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian &dstRowStride, 70614b98343309fdcff3514f05020303f7b40e83a4aBrian stImage->base.ImageOffsets); 70724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 70824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian else { 70924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian /* Allocate regular memory and store the image there temporarily. */ 71024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian if (texImage->IsCompressed) { 71124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian sizeInBytes = texImage->CompressedSize; 71224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian dstRowStride = 71324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian _mesa_compressed_row_stride(texImage->TexFormat->MesaFormat, width); 71424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian assert(dims != 3); 71524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 71624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian else { 71724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian dstRowStride = postConvWidth * texelBytes; 71824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian sizeInBytes = depth * dstRowStride * postConvHeight; 71924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 72024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 72124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian texImage->Data = malloc(sizeInBytes); 72224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 72324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 72424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian DBG("Upload image %dx%dx%d row_len %x pitch %x\n", 72524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian width, height, depth, width * texelBytes, dstRowStride); 72624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 72724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian /* Copy data. Would like to know when it's ok for us to eg. use 72824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * the blitter to copy. Or, use the hardware to do the format 72924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * conversion and copy: 73024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 73124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian if (compressed) { 73224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian memcpy(texImage->Data, pixels, imageSize); 73324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 73424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian else if (!texImage->TexFormat->StoreImage(ctx, dims, 73524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian texImage->_BaseFormat, 73624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian texImage->TexFormat, 73724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian texImage->Data, 73824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 0, 0, 0, /* dstX/Y/Zoffset */ 73924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian dstRowStride, 74024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian texImage->ImageOffsets, 74124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian width, height, depth, 74224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian format, type, pixels, unpack)) { 74324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage"); 74424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 74524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 74624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian _mesa_unmap_teximage_pbo(ctx, unpack); 74724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 74814b98343309fdcff3514f05020303f7b40e83a4aBrian if (stImage->mt) { 74914b98343309fdcff3514f05020303f7b40e83a4aBrian st_miptree_image_unmap(pipe, stImage->mt); 75024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian texImage->Data = NULL; 75124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 75224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 75324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#if 0 75424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian /* GL_SGIS_generate_mipmap -- this can be accelerated now. 75524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 75624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian if (level == texObj->BaseLevel && texObj->GenerateMipmap) { 75724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian intel_generate_mipmap(ctx, target, 75824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian &ctx->Texture.Unit[ctx->Texture.CurrentUnit], 75924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian texObj); 76024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 76124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#endif 76224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 76324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 76424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 76524df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void 76624df8f895fe8807aa2ba058e71bd40adfc01d21eBrianst_TexImage3D(GLcontext * ctx, 76724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLenum target, GLint level, 76824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLint internalFormat, 76924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLint width, GLint height, GLint depth, 77024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLint border, 77124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLenum format, GLenum type, const void *pixels, 77224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian const struct gl_pixelstore_attrib *unpack, 77324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian struct gl_texture_object *texObj, 77424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian struct gl_texture_image *texImage) 77524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 77624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian st_TexImage(ctx, 3, target, level, 77724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian internalFormat, width, height, depth, border, 77824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian format, type, pixels, unpack, texObj, texImage, 0, 0); 77924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 78024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 78124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 78224df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void 78324df8f895fe8807aa2ba058e71bd40adfc01d21eBrianst_TexImage2D(GLcontext * ctx, 78424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLenum target, GLint level, 78524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLint internalFormat, 78624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLint width, GLint height, GLint border, 78724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLenum format, GLenum type, const void *pixels, 78824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian const struct gl_pixelstore_attrib *unpack, 78924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian struct gl_texture_object *texObj, 79024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian struct gl_texture_image *texImage) 79124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 79224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian st_TexImage(ctx, 2, target, level, 79324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian internalFormat, width, height, 1, border, 79424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian format, type, pixels, unpack, texObj, texImage, 0, 0); 79524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 79624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 79724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 79824df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void 79924df8f895fe8807aa2ba058e71bd40adfc01d21eBrianst_TexImage1D(GLcontext * ctx, 80024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLenum target, GLint level, 80124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLint internalFormat, 80224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLint width, GLint border, 80324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLenum format, GLenum type, const void *pixels, 80424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian const struct gl_pixelstore_attrib *unpack, 80524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian struct gl_texture_object *texObj, 80624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian struct gl_texture_image *texImage) 80724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 80824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian st_TexImage(ctx, 1, target, level, 80924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian internalFormat, width, 1, 1, border, 81024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian format, type, pixels, unpack, texObj, texImage, 0, 0); 81124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 81224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 81324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 81424df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void 81524df8f895fe8807aa2ba058e71bd40adfc01d21eBrianst_CompressedTexImage2D( GLcontext *ctx, GLenum target, GLint level, 81624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLint internalFormat, 81724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLint width, GLint height, GLint border, 81824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLsizei imageSize, const GLvoid *data, 81924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian struct gl_texture_object *texObj, 82024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian struct gl_texture_image *texImage ) 82124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 82224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian st_TexImage(ctx, 2, target, level, 82324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian internalFormat, width, height, 1, border, 82424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 0, 0, data, &ctx->Unpack, texObj, texImage, imageSize, 1); 82524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 82624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 82724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 82824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian/** 82924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * Need to map texture image into memory before copying image data, 83024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * then unmap it. 83124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 83224df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void 83324df8f895fe8807aa2ba058e71bd40adfc01d21eBrianst_get_tex_image(GLcontext * ctx, GLenum target, GLint level, 83424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLenum format, GLenum type, GLvoid * pixels, 83524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian struct gl_texture_object *texObj, 83624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian struct gl_texture_image *texImage, int compressed) 83724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 83824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian /* 83924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian struct intel_context *intel = intel_context(ctx); 84024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 84124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian struct pipe_context *pipe = ctx->st->pipe; 84224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian struct st_texture_image *stImage = st_texture_image(texImage); 84324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 84424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian /* Map */ 84524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian if (stImage->mt) { 84624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian /* Image is stored in hardware format in a buffer managed by the 84724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * kernel. Need to explicitly map and unmap it. 84824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 84924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian stImage->base.Data = 85024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian st_miptree_image_map(pipe, 85124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian stImage->mt, 85224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian stImage->face, 85324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian stImage->level, 85424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian &stImage->base.RowStride, 85524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian stImage->base.ImageOffsets); 85624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian stImage->base.RowStride /= stImage->mt->cpp; 85724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 85824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian else { 85924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian /* Otherwise, the image should actually be stored in 86024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * stImage->base.Data. This is pretty confusing for 86124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * everybody, I'd much prefer to separate the two functions of 86224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * texImage->Data - storage for texture images in main memory 86324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * and access (ie mappings) of images. In other words, we'd 86424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * create a new texImage->Map field and leave Data simply for 86524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * storage. 86624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 86724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian assert(stImage->base.Data); 86824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 86924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 87024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 87124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian if (compressed) { 87224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian _mesa_get_compressed_teximage(ctx, target, level, pixels, 87324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian texObj, texImage); 87424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } else { 87524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian _mesa_get_teximage(ctx, target, level, format, type, pixels, 87624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian texObj, texImage); 87724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 87824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 87924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 88024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian /* Unmap */ 88124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian if (stImage->mt) { 88224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian st_miptree_image_unmap(pipe, stImage->mt); 88324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian stImage->base.Data = NULL; 88424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 88524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 88624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 88724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 88824df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void 88924df8f895fe8807aa2ba058e71bd40adfc01d21eBrianst_GetTexImage(GLcontext * ctx, GLenum target, GLint level, 89024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLenum format, GLenum type, GLvoid * pixels, 89124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian struct gl_texture_object *texObj, 89224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian struct gl_texture_image *texImage) 89324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 89424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian st_get_tex_image(ctx, target, level, format, type, pixels, 89524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian texObj, texImage, 0); 89624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 89724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 89824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 89924df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void 90024df8f895fe8807aa2ba058e71bd40adfc01d21eBrianst_GetCompressedTexImage(GLcontext *ctx, GLenum target, GLint level, 90124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLvoid *pixels, 90224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian const struct gl_texture_object *texObj, 90324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian const struct gl_texture_image *texImage) 90424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 90524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian st_get_tex_image(ctx, target, level, 0, 0, pixels, 90624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian (struct gl_texture_object *) texObj, 90724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian (struct gl_texture_image *) texImage, 1); 90824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 90924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 91024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 91124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 91224df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void 91324df8f895fe8807aa2ba058e71bd40adfc01d21eBrianst_TexSubimage(GLcontext * ctx, 91424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLint dims, 91524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLenum target, GLint level, 91624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLint xoffset, GLint yoffset, GLint zoffset, 91724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLint width, GLint height, GLint depth, 91824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLenum format, GLenum type, const void *pixels, 91924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian const struct gl_pixelstore_attrib *packing, 92024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian struct gl_texture_object *texObj, 92124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian struct gl_texture_image *texImage) 92224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 92324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian struct pipe_context *pipe = ctx->st->pipe; 92424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian struct st_texture_image *stImage = st_texture_image(texImage); 92524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLuint dstRowStride; 92624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 92724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian DBG("%s target %s level %d offset %d,%d %dx%d\n", __FUNCTION__, 92824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian _mesa_lookup_enum_by_nr(target), 92924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian level, xoffset, yoffset, width, height); 93024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 93124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian pixels = 93224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian _mesa_validate_pbo_teximage(ctx, dims, width, height, depth, format, 93324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian type, pixels, packing, "glTexSubImage2D"); 93424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian if (!pixels) 93524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian return; 93624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 93724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian /* Map buffer if necessary. Need to lock to prevent other contexts 93824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * from uploading the buffer under us. 93924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 94024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian if (stImage->mt) 94124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian texImage->Data = st_miptree_image_map(pipe, 94224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian stImage->mt, 94324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian stImage->face, 94424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian stImage->level, 94524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian &dstRowStride, 94624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian texImage->ImageOffsets); 94724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 94824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian assert(dstRowStride); 94924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 95024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian if (!texImage->TexFormat->StoreImage(ctx, dims, texImage->_BaseFormat, 95124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian texImage->TexFormat, 95224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian texImage->Data, 95324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian xoffset, yoffset, zoffset, 95424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian dstRowStride, 95524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian texImage->ImageOffsets, 95624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian width, height, depth, 95724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian format, type, pixels, packing)) { 95824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian _mesa_error(ctx, GL_OUT_OF_MEMORY, "intelTexSubImage"); 95924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 96024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 96124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#if 0 96224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian /* GL_SGIS_generate_mipmap */ 96324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian if (level == texObj->BaseLevel && texObj->GenerateMipmap) { 96424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian _mesa_generate_mipmap(ctx, target, 96524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian &ctx->Texture.Unit[ctx->Texture.CurrentUnit], 96624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian texObj); 96724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 96824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#endif 96924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 97024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian _mesa_unmap_teximage_pbo(ctx, packing); 97124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 97224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian if (stImage->mt) { 97324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian st_miptree_image_unmap(pipe, stImage->mt); 97424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian texImage->Data = NULL; 97524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 97624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 97724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 97824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 97924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 98024df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void 98124df8f895fe8807aa2ba058e71bd40adfc01d21eBrianst_TexSubImage3D(GLcontext * ctx, 98224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLenum target, 98324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLint level, 98424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLint xoffset, GLint yoffset, GLint zoffset, 98524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLsizei width, GLsizei height, GLsizei depth, 98624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLenum format, GLenum type, 98724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian const GLvoid * pixels, 98824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian const struct gl_pixelstore_attrib *packing, 98924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian struct gl_texture_object *texObj, 99024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian struct gl_texture_image *texImage) 99124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 992b245840b86cf877c9b8d666edf229364a84f1deaBrian st_TexSubimage(ctx, 3, target, level, 993b245840b86cf877c9b8d666edf229364a84f1deaBrian xoffset, yoffset, zoffset, 994b245840b86cf877c9b8d666edf229364a84f1deaBrian width, height, depth, 995b245840b86cf877c9b8d666edf229364a84f1deaBrian format, type, pixels, packing, texObj, texImage); 99624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 99724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 99824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 99924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 100024df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void 100124df8f895fe8807aa2ba058e71bd40adfc01d21eBrianst_TexSubImage2D(GLcontext * ctx, 100224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLenum target, 100324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLint level, 100424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLint xoffset, GLint yoffset, 100524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLsizei width, GLsizei height, 100624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLenum format, GLenum type, 100724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian const GLvoid * pixels, 100824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian const struct gl_pixelstore_attrib *packing, 100924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian struct gl_texture_object *texObj, 101024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian struct gl_texture_image *texImage) 101124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 1012b245840b86cf877c9b8d666edf229364a84f1deaBrian st_TexSubimage(ctx, 2, target, level, 1013b245840b86cf877c9b8d666edf229364a84f1deaBrian xoffset, yoffset, 0, 1014b245840b86cf877c9b8d666edf229364a84f1deaBrian width, height, 1, 1015b245840b86cf877c9b8d666edf229364a84f1deaBrian format, type, pixels, packing, texObj, texImage); 101624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 101724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 101824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 101924df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void 102024df8f895fe8807aa2ba058e71bd40adfc01d21eBrianst_TexSubImage1D(GLcontext * ctx, 102124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLenum target, 102224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLint level, 102324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLint xoffset, 102424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLsizei width, 102524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLenum format, GLenum type, 102624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian const GLvoid * pixels, 102724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian const struct gl_pixelstore_attrib *packing, 102824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian struct gl_texture_object *texObj, 102924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian struct gl_texture_image *texImage) 103024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 1031b245840b86cf877c9b8d666edf229364a84f1deaBrian st_TexSubimage(ctx, 1, target, level, 1032b245840b86cf877c9b8d666edf229364a84f1deaBrian xoffset, 0, 0, 1033b245840b86cf877c9b8d666edf229364a84f1deaBrian width, 1, 1, 1034b245840b86cf877c9b8d666edf229364a84f1deaBrian format, type, pixels, packing, texObj, texImage); 103524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 103624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 103724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 103824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 103924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian/** 1040038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian * Return 0 for GL_TEXTURE_CUBE_MAP_POSITIVE_X, 1041038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian * 1 for GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 1042038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian * etc. 1043038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian * XXX duplicated from main/teximage.c 1044038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian */ 1045038cb561eb094af2f2ba06e18e61246fc0c87c3cBrianstatic uint 1046038cb561eb094af2f2ba06e18e61246fc0c87c3cBriantexture_face(GLenum target) 1047038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian{ 1048038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian if (target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB && 1049038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB) 1050038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian return (GLuint) target - (GLuint) GL_TEXTURE_CUBE_MAP_POSITIVE_X; 1051038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian else 1052038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian return 0; 1053038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian} 1054038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian 1055038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian 1056038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian 1057038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian/** 1058038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian * Do a CopyTexSubImage operation by mapping the source region and 10595c83f1371978472fbe4bba8f686733c6b519874aBrian * dest region and using get_tile()/put_tile() to access the pixels/texels. 1060c6717a86420d7141013165f7acd50b3c3f751756Brian * 1061c6717a86420d7141013165f7acd50b3c3f751756Brian * Note: srcY=0=TOP of renderbuffer 1062038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian */ 1063038cb561eb094af2f2ba06e18e61246fc0c87c3cBrianstatic void 1064038cb561eb094af2f2ba06e18e61246fc0c87c3cBrianfallback_copy_texsubimage(GLcontext *ctx, 1065038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian GLenum target, 1066038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian GLint level, 1067038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian struct st_renderbuffer *strb, 1068038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian struct st_texture_image *stImage, 1069038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian GLenum baseFormat, 1070038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian GLint destX, GLint destY, GLint destZ, 1071038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian GLint srcX, GLint srcY, 1072038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian GLsizei width, GLsizei height) 1073038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian{ 1074038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian struct pipe_context *pipe = ctx->st->pipe; 1075038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian const uint face = texture_face(target); 1076038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian struct pipe_mipmap_tree *mt = stImage->mt; 1077038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian struct pipe_surface *src_surf, *dest_surf; 1078038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian GLfloat *data; 10795c83f1371978472fbe4bba8f686733c6b519874aBrian GLint row, yStep; 10805c83f1371978472fbe4bba8f686733c6b519874aBrian 10815c83f1371978472fbe4bba8f686733c6b519874aBrian /* determine bottom-to-top vs. top-to-bottom order */ 10825c83f1371978472fbe4bba8f686733c6b519874aBrian if (st_fb_orientation(ctx->ReadBuffer) == Y_0_TOP) { 10835c83f1371978472fbe4bba8f686733c6b519874aBrian destY = height - 1 - destY; 10845c83f1371978472fbe4bba8f686733c6b519874aBrian yStep = -1; 10855c83f1371978472fbe4bba8f686733c6b519874aBrian } 10865c83f1371978472fbe4bba8f686733c6b519874aBrian else { 10875c83f1371978472fbe4bba8f686733c6b519874aBrian yStep = 1; 10885c83f1371978472fbe4bba8f686733c6b519874aBrian } 1089038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian 1090038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian src_surf = strb->surface; 1091038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian 1092038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian dest_surf = pipe->get_tex_surface(pipe, mt, 1093038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian face, level, destZ); 1094038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian 1095c6717a86420d7141013165f7acd50b3c3f751756Brian (void) pipe->region_map(pipe, dest_surf->region); 1096c6717a86420d7141013165f7acd50b3c3f751756Brian (void) pipe->region_map(pipe, src_surf->region); 1097c6717a86420d7141013165f7acd50b3c3f751756Brian 10985c83f1371978472fbe4bba8f686733c6b519874aBrian /* buffer for one row */ 10995c83f1371978472fbe4bba8f686733c6b519874aBrian data = (GLfloat *) malloc(width * 4 * sizeof(GLfloat)); 1100038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian 11015c83f1371978472fbe4bba8f686733c6b519874aBrian /* do copy row by row */ 11025c83f1371978472fbe4bba8f686733c6b519874aBrian for (row = 0; row < height; row++) { 11035c83f1371978472fbe4bba8f686733c6b519874aBrian src_surf->get_tile(src_surf, srcX, srcY + row, width, 1, data); 11045c83f1371978472fbe4bba8f686733c6b519874aBrian 11055c83f1371978472fbe4bba8f686733c6b519874aBrian /* XXX we're ignoring convolution for now */ 11065c83f1371978472fbe4bba8f686733c6b519874aBrian if (ctx->_ImageTransferState) { 11075c83f1371978472fbe4bba8f686733c6b519874aBrian _mesa_apply_rgba_transfer_ops(ctx, 11085c83f1371978472fbe4bba8f686733c6b519874aBrian ctx->_ImageTransferState & ~IMAGE_CONVOLUTION_BIT, 11095c83f1371978472fbe4bba8f686733c6b519874aBrian width, (GLfloat (*)[4])data); 11105c83f1371978472fbe4bba8f686733c6b519874aBrian } 11115c83f1371978472fbe4bba8f686733c6b519874aBrian 11125c83f1371978472fbe4bba8f686733c6b519874aBrian dest_surf->put_tile(dest_surf, destX, destY, width, 1, data); 11135c83f1371978472fbe4bba8f686733c6b519874aBrian destY += yStep; 11145c83f1371978472fbe4bba8f686733c6b519874aBrian } 1115038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian 1116038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian 1117c6717a86420d7141013165f7acd50b3c3f751756Brian (void) pipe->region_unmap(pipe, dest_surf->region); 1118c6717a86420d7141013165f7acd50b3c3f751756Brian (void) pipe->region_unmap(pipe, src_surf->region); 1119c6717a86420d7141013165f7acd50b3c3f751756Brian 1120038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian free(data); 1121038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian} 1122038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian 1123038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian 1124038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian 1125038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian 1126038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian/** 1127b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian * Do a CopyTex[Sub]Image using an optimized hardware (blit) path. 1128b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian * Note that the region to copy has already been clip tested. 1129c6717a86420d7141013165f7acd50b3c3f751756Brian * 1130c6717a86420d7141013165f7acd50b3c3f751756Brian * Note: srcY=0=Bottom of renderbuffer 1131c6717a86420d7141013165f7acd50b3c3f751756Brian * 1132b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian * \return GL_TRUE if success, GL_FALSE if failure (use a fallback) 113324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 1134038cb561eb094af2f2ba06e18e61246fc0c87c3cBrianstatic void 113524df8f895fe8807aa2ba058e71bd40adfc01d21eBriando_copy_texsubimage(GLcontext *ctx, 1136038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian GLenum target, GLint level, 1137038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian GLint destX, GLint destY, GLint destZ, 1138038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian GLint srcX, GLint srcY, 1139038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian GLsizei width, GLsizei height) 114024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 1141038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian struct gl_texture_unit *texUnit = 1142038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; 1143038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian struct gl_texture_object *texObj = 1144038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian _mesa_select_tex_object(ctx, texUnit, target); 1145038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian struct gl_texture_image *texImage = 1146038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian _mesa_select_tex_image(ctx, texObj, target, level); 1147038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian struct st_texture_image *stImage = st_texture_image(texImage); 1148038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian GLenum baseFormat = texImage->InternalFormat; 1149b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian struct gl_framebuffer *fb = ctx->ReadBuffer; 1150b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian struct st_renderbuffer *strb; 1151b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian struct pipe_context *pipe = ctx->st->pipe; 1152b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian struct pipe_region *src_region, *dest_region; 1153b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian uint dest_offset, src_offset; 1154b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian uint dest_format, src_format; 115524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 1156038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian (void) texImage; 1157038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian 1158b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian /* determine if copying depth or color data */ 1159b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian if (baseFormat == GL_DEPTH_COMPONENT) { 1160b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian strb = st_renderbuffer(fb->_DepthBuffer); 116124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 1162b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian else if (baseFormat == GL_DEPTH_STENCIL_EXT) { 1163b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian strb = st_renderbuffer(fb->_StencilBuffer); 1164b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian } 1165b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian else { 1166b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian /* baseFormat == GL_RGB, GL_RGBA, GL_ALPHA, etc */ 1167b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian strb = st_renderbuffer(fb->_ColorReadBuffer); 1168b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian } 1169b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian 1170b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian assert(strb); 1171b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian assert(strb->surface); 1172b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian assert(stImage->mt); 1173c6717a86420d7141013165f7acd50b3c3f751756Brian 1174c6717a86420d7141013165f7acd50b3c3f751756Brian if (st_fb_orientation(ctx->ReadBuffer) == Y_0_TOP) { 1175c6717a86420d7141013165f7acd50b3c3f751756Brian srcY = strb->Base.Height - srcY - height; 1176c6717a86420d7141013165f7acd50b3c3f751756Brian } 117724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 1178b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian src_format = strb->surface->format; 1179b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian dest_format = stImage->mt->format; 1180b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian 1181b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian src_region = strb->surface->region; 1182b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian dest_region = stImage->mt->region; 1183b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian 1184038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian if (src_format == dest_format && 11855c83f1371978472fbe4bba8f686733c6b519874aBrian ctx->_ImageTransferState == 0x0 && 1186038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian src_region && 1187038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian dest_region && 1188038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian src_region->cpp == dest_region->cpp) { 1189038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian /* do blit-style copy */ 1190038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian src_offset = 0; 1191038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian dest_offset = st_miptree_image_offset(stImage->mt, 1192038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian stImage->face, 1193038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian stImage->level); 1194038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian 1195038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian /* XXX may need to invert image depending on window 1196038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian * vs. user-created FBO 1197038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian */ 1198b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian 119924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#if 0 1200038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian /* A bit of fiddling to get the blitter to work with -ve 1201038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian * pitches. But we get a nice inverted blit this way, so it's 1202038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian * worth it: 1203038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian */ 1204038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian intelEmitCopyBlit(intel, 1205038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian stImage->mt->cpp, 1206038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian -src->pitch, 1207038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian src->buffer, 1208038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian src->height * src->pitch * src->cpp, 1209038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian stImage->mt->pitch, 1210038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian stImage->mt->region->buffer, 1211038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian dest_offset, 1212038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian x, y + height, dstx, dsty, width, height, 1213038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian GL_COPY); /* ? */ 121424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#else 1215b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian 1216038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian pipe->region_copy(pipe, 1217038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian /* dest */ 1218038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian dest_region, 1219038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian dest_offset, 1220038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian destX, destY, 1221038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian /* src */ 1222038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian src_region, 1223038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian src_offset, 1224038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian srcX, srcY, 1225038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian /* size */ 1226038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian width, height); 122724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#endif 1228038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian } 1229038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian else { 1230038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian fallback_copy_texsubimage(ctx, target, level, 1231038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian strb, stImage, baseFormat, 1232038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian destX, destY, destZ, 1233038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian srcX, srcY, width, height); 1234038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian } 1235038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian 123624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 123724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#if 0 123824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian /* GL_SGIS_generate_mipmap -- this can be accelerated now. 123924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * XXX Add a ctx->Driver.GenerateMipmaps() function? 124024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 124124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian if (level == texObj->BaseLevel && texObj->GenerateMipmap) { 124224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian intel_generate_mipmap(ctx, target, 124324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian &ctx->Texture.Unit[ctx->Texture.CurrentUnit], 124424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian texObj); 124524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 124624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#endif 124724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 124824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 124924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 125024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 1251038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian 125224df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void 125324df8f895fe8807aa2ba058e71bd40adfc01d21eBrianst_CopyTexImage1D(GLcontext * ctx, GLenum target, GLint level, 125424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLenum internalFormat, 125524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLint x, GLint y, GLsizei width, GLint border) 125624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 125724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian struct gl_texture_unit *texUnit = 125824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; 125924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian struct gl_texture_object *texObj = 126024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian _mesa_select_tex_object(ctx, texUnit, target); 126124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian struct gl_texture_image *texImage = 126224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian _mesa_select_tex_image(ctx, texObj, target, level); 126324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 1264038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian#if 0 126524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian if (border) 126624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian goto fail; 1267038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian#endif 126824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 126924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian /* Setup or redefine the texture object, mipmap tree and texture 127024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * image. Don't populate yet. 127124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 127224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian ctx->Driver.TexImage1D(ctx, target, level, internalFormat, 127324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian width, border, 127424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GL_RGBA, CHAN_TYPE, NULL, 127524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian &ctx->DefaultPacking, texObj, texImage); 127624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 1277038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian do_copy_texsubimage(ctx, target, level, 1278038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian 0, 0, 0, 1279038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian x, y, width, 1); 128024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 128124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 128224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 128324df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void 128424df8f895fe8807aa2ba058e71bd40adfc01d21eBrianst_CopyTexImage2D(GLcontext * ctx, GLenum target, GLint level, 128524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLenum internalFormat, 128624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLint x, GLint y, GLsizei width, GLsizei height, 128724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLint border) 128824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 128924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian struct gl_texture_unit *texUnit = 129024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; 129124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian struct gl_texture_object *texObj = 129224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian _mesa_select_tex_object(ctx, texUnit, target); 129324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian struct gl_texture_image *texImage = 129424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian _mesa_select_tex_image(ctx, texObj, target, level); 129524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 1296038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian#if 0 129724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian if (border) 129824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian goto fail; 1299038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian#endif 130024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 130124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian /* Setup or redefine the texture object, mipmap tree and texture 130224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * image. Don't populate yet. 130324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 130424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian ctx->Driver.TexImage2D(ctx, target, level, internalFormat, 130524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian width, height, border, 130624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GL_RGBA, CHAN_TYPE, NULL, 130724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian &ctx->DefaultPacking, texObj, texImage); 130824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 130924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 1310038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian do_copy_texsubimage(ctx, target, level, 1311038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian 0, 0, 0, 1312038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian x, y, width, height); 131324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 131424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 131524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 131624df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void 131724df8f895fe8807aa2ba058e71bd40adfc01d21eBrianst_CopyTexSubImage1D(GLcontext * ctx, GLenum target, GLint level, 131824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLint xoffset, GLint x, GLint y, GLsizei width) 131924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 1320038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian const GLint yoffset = 0, zoffset = 0; 1321038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian const GLsizei height = 1; 1322038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian do_copy_texsubimage(ctx, target, level, 1323038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian xoffset, yoffset, zoffset, 1324038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian x, y, width, height); 132524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 132624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 132724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 132824df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void 132924df8f895fe8807aa2ba058e71bd40adfc01d21eBrianst_CopyTexSubImage2D(GLcontext * ctx, GLenum target, GLint level, 133024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLint xoffset, GLint yoffset, 133124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLint x, GLint y, GLsizei width, GLsizei height) 133224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 1333038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian const GLint zoffset = 0; 1334038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian do_copy_texsubimage(ctx, target, level, 1335038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian xoffset, yoffset, zoffset, 1336038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian x, y, width, height); 1337038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian} 133824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 133924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 1340038cb561eb094af2f2ba06e18e61246fc0c87c3cBrianstatic void 1341038cb561eb094af2f2ba06e18e61246fc0c87c3cBrianst_CopyTexSubImage3D(GLcontext * ctx, GLenum target, GLint level, 1342038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian GLint xoffset, GLint yoffset, GLint zoffset, 1343038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian GLint x, GLint y, GLsizei width, GLsizei height) 1344038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian{ 1345038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian do_copy_texsubimage(ctx, target, level, 1346038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian xoffset, yoffset, zoffset, 1347038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian x, y, width, height); 134824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 134924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 135024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 135124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 135224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 135324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian/** 135424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * Compute which mipmap levels that really need to be sent to the hardware. 135524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * This depends on the base image size, GL_TEXTURE_MIN_LOD, 135624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * GL_TEXTURE_MAX_LOD, GL_TEXTURE_BASE_LEVEL, and GL_TEXTURE_MAX_LEVEL. 135724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 135824df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void 135914b98343309fdcff3514f05020303f7b40e83a4aBriancalculate_first_last_level(struct st_texture_object *stObj) 136024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 136114b98343309fdcff3514f05020303f7b40e83a4aBrian struct gl_texture_object *tObj = &stObj->base; 136224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian const struct gl_texture_image *const baseImage = 136324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian tObj->Image[0][tObj->BaseLevel]; 136424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 136524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian /* These must be signed values. MinLod and MaxLod can be negative numbers, 136624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * and having firstLevel and lastLevel as signed prevents the need for 136724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * extra sign checks. 136824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 136924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian int firstLevel; 137024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian int lastLevel; 137124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 137224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian /* Yes, this looks overly complicated, but it's all needed. 137324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 137424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian switch (tObj->Target) { 137524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian case GL_TEXTURE_1D: 137624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian case GL_TEXTURE_2D: 137724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian case GL_TEXTURE_3D: 137824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian case GL_TEXTURE_CUBE_MAP: 137924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian if (tObj->MinFilter == GL_NEAREST || tObj->MinFilter == GL_LINEAR) { 138024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian /* GL_NEAREST and GL_LINEAR only care about GL_TEXTURE_BASE_LEVEL. 138124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 138224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian firstLevel = lastLevel = tObj->BaseLevel; 138324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 138424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian else { 138524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian firstLevel = tObj->BaseLevel + (GLint) (tObj->MinLod + 0.5); 138624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian firstLevel = MAX2(firstLevel, tObj->BaseLevel); 138724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian lastLevel = tObj->BaseLevel + (GLint) (tObj->MaxLod + 0.5); 138824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian lastLevel = MAX2(lastLevel, tObj->BaseLevel); 138924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian lastLevel = MIN2(lastLevel, tObj->BaseLevel + baseImage->MaxLog2); 139024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian lastLevel = MIN2(lastLevel, tObj->MaxLevel); 139124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian lastLevel = MAX2(firstLevel, lastLevel); /* need at least one level */ 139224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 139324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian break; 139424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian case GL_TEXTURE_RECTANGLE_NV: 139524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian case GL_TEXTURE_4D_SGIS: 139624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian firstLevel = lastLevel = 0; 139724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian break; 139824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian default: 139924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian return; 140024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 140124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 140224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian /* save these values */ 140314b98343309fdcff3514f05020303f7b40e83a4aBrian stObj->firstLevel = firstLevel; 140414b98343309fdcff3514f05020303f7b40e83a4aBrian stObj->lastLevel = lastLevel; 140524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 140624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 140724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 140824df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void 140924df8f895fe8807aa2ba058e71bd40adfc01d21eBriancopy_image_data_to_tree(struct pipe_context *pipe, 141014b98343309fdcff3514f05020303f7b40e83a4aBrian struct st_texture_object *stObj, 141124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian struct st_texture_image *stImage) 141224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 141324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian if (stImage->mt) { 141424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian /* Copy potentially with the blitter: 141524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 141624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian st_miptree_image_copy(pipe, 141728b315dc1aed36bebadfacbd55e481e7baacfcb5Brian stObj->mt, /* dest miptree */ 141828b315dc1aed36bebadfacbd55e481e7baacfcb5Brian stImage->face, stImage->level, 141928b315dc1aed36bebadfacbd55e481e7baacfcb5Brian stImage->mt /* src miptree */ 142028b315dc1aed36bebadfacbd55e481e7baacfcb5Brian ); 142124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 142224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian st_miptree_release(pipe, &stImage->mt); 142324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 142424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian else { 142524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian assert(stImage->base.Data != NULL); 142624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 142724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian /* More straightforward upload. 142824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 142924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian st_miptree_image_data(pipe, 143014b98343309fdcff3514f05020303f7b40e83a4aBrian stObj->mt, 143124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian stImage->face, 143224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian stImage->level, 143324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian stImage->base.Data, 143424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian stImage->base.RowStride, 143524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian stImage->base.RowStride * 143624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian stImage->base.Height); 143724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian _mesa_align_free(stImage->base.Data); 143824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian stImage->base.Data = NULL; 143924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 144024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 144114b98343309fdcff3514f05020303f7b40e83a4aBrian st_miptree_reference(&stImage->mt, stObj->mt); 144224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 144324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 144424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 144524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian/* 144624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 144714b98343309fdcff3514f05020303f7b40e83a4aBrianGLboolean 144824df8f895fe8807aa2ba058e71bd40adfc01d21eBrianst_finalize_mipmap_tree(GLcontext *ctx, 144924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian struct pipe_context *pipe, GLuint unit, 145024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLboolean *needFlush) 145124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 145224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian struct gl_texture_object *tObj = ctx->Texture.Unit[unit]._Current; 145314b98343309fdcff3514f05020303f7b40e83a4aBrian struct st_texture_object *stObj = st_texture_object(tObj); 145424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian int comp_byte = 0; 145524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian int cpp; 145624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 145724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLuint face, i; 145824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian GLuint nr_faces = 0; 145924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian struct st_texture_image *firstImage; 146024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 146124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian *needFlush = GL_FALSE; 146224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 146324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian /* We know/require this is true by now: 146424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 146514b98343309fdcff3514f05020303f7b40e83a4aBrian assert(stObj->base._Complete); 146624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 146724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian /* What levels must the tree include at a minimum? 146824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 146914b98343309fdcff3514f05020303f7b40e83a4aBrian calculate_first_last_level(stObj); 147024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian firstImage = 147114b98343309fdcff3514f05020303f7b40e83a4aBrian st_texture_image(stObj->base.Image[0][stObj->firstLevel]); 147224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 147324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian /* Fallback case: 147424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 147524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian if (firstImage->base.Border) { 147614b98343309fdcff3514f05020303f7b40e83a4aBrian if (stObj->mt) { 147714b98343309fdcff3514f05020303f7b40e83a4aBrian st_miptree_release(pipe, &stObj->mt); 147824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 147924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian return GL_FALSE; 148024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 148124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 148224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 148314b98343309fdcff3514f05020303f7b40e83a4aBrian /* If both firstImage and stObj have a tree which can contain 148424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * all active images, favour firstImage. Note that because of the 148524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * completeness requirement, we know that the image dimensions 148624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * will match. 148724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 148824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian if (firstImage->mt && 148914b98343309fdcff3514f05020303f7b40e83a4aBrian firstImage->mt != stObj->mt && 149014b98343309fdcff3514f05020303f7b40e83a4aBrian firstImage->mt->first_level <= stObj->firstLevel && 149114b98343309fdcff3514f05020303f7b40e83a4aBrian firstImage->mt->last_level >= stObj->lastLevel) { 149224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 149314b98343309fdcff3514f05020303f7b40e83a4aBrian if (stObj->mt) 149414b98343309fdcff3514f05020303f7b40e83a4aBrian st_miptree_release(pipe, &stObj->mt); 149524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 149614b98343309fdcff3514f05020303f7b40e83a4aBrian st_miptree_reference(&stObj->mt, firstImage->mt); 149724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 149824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 149924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian if (firstImage->base.IsCompressed) { 150014b98343309fdcff3514f05020303f7b40e83a4aBrian comp_byte = compressed_num_bytes(firstImage->base.TexFormat->MesaFormat); 150124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian cpp = comp_byte; 150224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 150324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian else cpp = firstImage->base.TexFormat->TexelBytes; 150424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 150524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian /* Check tree can hold all active levels. Check tree matches 150624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * target, imageFormat, etc. 150724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * 150824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * XXX: For some layouts (eg i945?), the test might have to be 150924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * first_level == firstLevel, as the tree isn't valid except at the 151024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * original start level. Hope to get around this by 151124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * programming minLod, maxLod, baseLevel into the hardware and 151224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * leaving the tree alone. 151324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 151414b98343309fdcff3514f05020303f7b40e83a4aBrian if (stObj->mt && 15155390a43ce06b27f6d54bc5f237aa305b6948f2afBrian (stObj->mt->target != gl_target_to_pipe(stObj->base.Target) || 151614b98343309fdcff3514f05020303f7b40e83a4aBrian stObj->mt->internal_format != firstImage->base.InternalFormat || 151714b98343309fdcff3514f05020303f7b40e83a4aBrian stObj->mt->first_level != stObj->firstLevel || 151814b98343309fdcff3514f05020303f7b40e83a4aBrian stObj->mt->last_level != stObj->lastLevel || 151914b98343309fdcff3514f05020303f7b40e83a4aBrian stObj->mt->width0 != firstImage->base.Width || 152014b98343309fdcff3514f05020303f7b40e83a4aBrian stObj->mt->height0 != firstImage->base.Height || 152114b98343309fdcff3514f05020303f7b40e83a4aBrian stObj->mt->depth0 != firstImage->base.Depth || 152214b98343309fdcff3514f05020303f7b40e83a4aBrian stObj->mt->cpp != cpp || 152314b98343309fdcff3514f05020303f7b40e83a4aBrian stObj->mt->compressed != firstImage->base.IsCompressed)) { 152414b98343309fdcff3514f05020303f7b40e83a4aBrian st_miptree_release(pipe, &stObj->mt); 152524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 152624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 152724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 152824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian /* May need to create a new tree: 152924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 153014b98343309fdcff3514f05020303f7b40e83a4aBrian if (!stObj->mt) { 153114b98343309fdcff3514f05020303f7b40e83a4aBrian stObj->mt = st_miptree_create(pipe, 15325390a43ce06b27f6d54bc5f237aa305b6948f2afBrian gl_target_to_pipe(stObj->base.Target), 1533b245840b86cf877c9b8d666edf229364a84f1deaBrian firstImage->base.InternalFormat, 1534b245840b86cf877c9b8d666edf229364a84f1deaBrian stObj->firstLevel, 1535b245840b86cf877c9b8d666edf229364a84f1deaBrian stObj->lastLevel, 1536b245840b86cf877c9b8d666edf229364a84f1deaBrian firstImage->base.Width, 1537b245840b86cf877c9b8d666edf229364a84f1deaBrian firstImage->base.Height, 1538b245840b86cf877c9b8d666edf229364a84f1deaBrian firstImage->base.Depth, 1539b245840b86cf877c9b8d666edf229364a84f1deaBrian cpp, 1540b245840b86cf877c9b8d666edf229364a84f1deaBrian comp_byte); 1541b245840b86cf877c9b8d666edf229364a84f1deaBrian 1542b245840b86cf877c9b8d666edf229364a84f1deaBrian stObj->mt->format 15439cf9aa1ea2c3f40a09316975410a4b0e202e82baBrian = st_mesa_format_to_pipe_format(firstImage->base.TexFormat->MesaFormat); 154424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 154524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 154624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian /* Pull in any images not in the object's tree: 154724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 154814b98343309fdcff3514f05020303f7b40e83a4aBrian nr_faces = (stObj->base.Target == GL_TEXTURE_CUBE_MAP) ? 6 : 1; 154924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian for (face = 0; face < nr_faces; face++) { 155014b98343309fdcff3514f05020303f7b40e83a4aBrian for (i = stObj->firstLevel; i <= stObj->lastLevel; i++) { 155124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian struct st_texture_image *stImage = 155214b98343309fdcff3514f05020303f7b40e83a4aBrian st_texture_image(stObj->base.Image[face][i]); 155324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 155424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian /* Need to import images in main memory or held in other trees. 155524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 155614b98343309fdcff3514f05020303f7b40e83a4aBrian if (stObj->mt != stImage->mt) { 155714b98343309fdcff3514f05020303f7b40e83a4aBrian copy_image_data_to_tree(pipe, stObj, stImage); 155824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian *needFlush = GL_TRUE; 155924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 156024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 156124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 156224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 156324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 156424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian return GL_TRUE; 156524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 156624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 156724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 156824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 156924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 15706da9234fd437f97267e7831f034c78b31156d939Brianvoid 15716da9234fd437f97267e7831f034c78b31156d939Brianst_init_texture_functions(struct dd_function_table *functions) 157224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 157324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian functions->ChooseTextureFormat = st_ChooseTextureFormat; 157424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian functions->TexImage1D = st_TexImage1D; 157524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian functions->TexImage2D = st_TexImage2D; 157624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian functions->TexImage3D = st_TexImage3D; 157724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian functions->TexSubImage1D = st_TexSubImage1D; 157824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian functions->TexSubImage2D = st_TexSubImage2D; 157924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian functions->TexSubImage3D = st_TexSubImage3D; 158024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian functions->CopyTexImage1D = st_CopyTexImage1D; 158124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian functions->CopyTexImage2D = st_CopyTexImage2D; 158224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian functions->CopyTexSubImage1D = st_CopyTexSubImage1D; 158324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian functions->CopyTexSubImage2D = st_CopyTexSubImage2D; 1584038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian functions->CopyTexSubImage3D = st_CopyTexSubImage3D; 1585038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian 158624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian functions->GetTexImage = st_GetTexImage; 158724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 158824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian /* compressed texture functions */ 158924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian functions->CompressedTexImage2D = st_CompressedTexImage2D; 159024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian functions->GetCompressedTexImage = st_GetCompressedTexImage; 159124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 159224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian functions->NewTextureObject = st_NewTextureObject; 159324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian functions->NewTextureImage = st_NewTextureImage; 159424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian functions->DeleteTexture = st_DeleteTextureObject; 159524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian functions->FreeTexImageData = st_FreeTextureImageData; 159624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian functions->UpdateTexturePalette = 0; 159724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian functions->IsTextureResident = st_IsTextureResident; 159824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 159924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian functions->TextureMemCpy = do_memcpy; 160024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 1601