124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian/************************************************************************** 224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * 324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. 424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * All Rights Reserved. 524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * 624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * Permission is hereby granted, free of charge, to any person obtaining a 724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * copy of this software and associated documentation files (the 824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * "Software"), to deal in the Software without restriction, including 924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * without limitation the rights to use, copy, modify, merge, publish, 1024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * distribute, sub license, and/or sell copies of the Software, and to 1124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * permit persons to whom the Software is furnished to do so, subject to 1224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * the following conditions: 1324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * 1424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * The above copyright notice and this permission notice (including the 1524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * next paragraph) shall be included in all copies or substantial portions 1624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * of the Software. 1724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * 1824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 1924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 2024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 2124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR 2224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 2324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 2424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 2524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * 2624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian **************************************************************************/ 2724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 28f2c023291a1f2887294d2aac504f8b82857ad092Brian Paul#include "main/mfeatures.h" 297b24e58a0ca571d6230ef5076ea352253b81fe6eBrian Paul#include "main/bufferobj.h" 3024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#include "main/enums.h" 3165d2a266375cf32fd90c7fb77fb87993d3a652eaBrian Paul#include "main/fbobject.h" 3245e76d2665b38ba3787548310efc59e969124c01Brian Paul#include "main/formats.h" 3324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#include "main/image.h" 34f2c023291a1f2887294d2aac504f8b82857ad092Brian Paul#include "main/imports.h" 3524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#include "main/macros.h" 362440ff74d69a8caf49b05a960b4c7e282a96565eBrian#include "main/mipmap.h" 371c131752c3e07ef91f49d4970dafca6d26585334Brian Paul#include "main/pack.h" 38b70610b9823fc7dc3672735c11be1a75fbb1a2a4Brian Paul#include "main/pbo.h" 391c131752c3e07ef91f49d4970dafca6d26585334Brian Paul#include "main/pixeltransfer.h" 4024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#include "main/texcompress.h" 41a4bec69e7271eda0137874973aa8c7d44175fedfBrian Paul#include "main/texgetimage.h" 4224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#include "main/teximage.h" 4324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#include "main/texobj.h" 4424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#include "main/texstore.h" 4524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 46b02ef740b90029bc40629e5b81270a8cf77101d3Keith Whitwell#include "state_tracker/st_debug.h" 4724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#include "state_tracker/st_context.h" 48b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian#include "state_tracker/st_cb_fbo.h" 49b0427bedde80e3189524651a327235bdfddbc613José Fonseca#include "state_tracker/st_cb_flush.h" 5024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#include "state_tracker/st_cb_texture.h" 51f8ab24760d0d3f07e9ee81c98207ddf92dfe74daBrian#include "state_tracker/st_format.h" 52753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer#include "state_tracker/st_texture.h" 5362abcb9aacc33218d0143a743c738435794b32a9Brian#include "state_tracker/st_gen_mipmap.h" 54afd16512bc354cf1a7220cb9bf3ce445503c7af4Keith Whitwell#include "state_tracker/st_atom.h" 5524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 5624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#include "pipe/p_context.h" 57b245840b86cf877c9b8d666edf229364a84f1deaBrian#include "pipe/p_defines.h" 5828486880ca3ec39419ccee0cb1a3bedc9ef7117cJosé Fonseca#include "util/u_inlines.h" 598fc945cd847aa5d343a5f76eb2f9f2c9075cccddKeith Whitwell#include "pipe/p_shader_tokens.h" 604f25420bdd834e81a3e22733304efc5261c2998aBrian Paul#include "util/u_tile.h" 613c0dc8242b64518d5635263ba65b39afa919dd86Michel Dänzer#include "util/u_blit.h" 623400b668e35469d5dbba515e3a8b9d775fd2eff5Michal Krol#include "util/u_format.h" 6351b339af2e8b80575a24bb9146f031c9605180bbBrian Paul#include "util/u_surface.h" 648f55a95178069d5e8b18647e6b675fc403d68073Roland Scheidegger#include "util/u_sampler.h" 65c1785c19ca0716a7e85777242949a0c33e28988fPatrice Mandin#include "util/u_math.h" 664c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger#include "util/u_box.h" 6724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 6824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian#define DBG if (0) printf 6924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 7024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 711c5f27a18b775b3784fcd265d60e0affa0b31581Michel Dänzerstatic enum pipe_texture_target 725390a43ce06b27f6d54bc5f237aa305b6948f2afBriangl_target_to_pipe(GLenum target) 735390a43ce06b27f6d54bc5f237aa305b6948f2afBrian{ 745390a43ce06b27f6d54bc5f237aa305b6948f2afBrian switch (target) { 755390a43ce06b27f6d54bc5f237aa305b6948f2afBrian case GL_TEXTURE_1D: 765390a43ce06b27f6d54bc5f237aa305b6948f2afBrian return PIPE_TEXTURE_1D; 775390a43ce06b27f6d54bc5f237aa305b6948f2afBrian case GL_TEXTURE_2D: 788cd0873d319cefce74164147c9855e81f051d1e1Chia-I Wu case GL_TEXTURE_EXTERNAL_OES: 795390a43ce06b27f6d54bc5f237aa305b6948f2afBrian return PIPE_TEXTURE_2D; 807f15dca6d963b0a69131e8761c477064dba49307Luca Barbieri case GL_TEXTURE_RECTANGLE_NV: 817f15dca6d963b0a69131e8761c477064dba49307Luca Barbieri return PIPE_TEXTURE_RECT; 825390a43ce06b27f6d54bc5f237aa305b6948f2afBrian case GL_TEXTURE_3D: 835390a43ce06b27f6d54bc5f237aa305b6948f2afBrian return PIPE_TEXTURE_3D; 845390a43ce06b27f6d54bc5f237aa305b6948f2afBrian case GL_TEXTURE_CUBE_MAP_ARB: 855390a43ce06b27f6d54bc5f237aa305b6948f2afBrian return PIPE_TEXTURE_CUBE; 869b56a2cb626b254bcb7b7202e6babd1b5570208fBrian Paul case GL_TEXTURE_1D_ARRAY_EXT: 879b56a2cb626b254bcb7b7202e6babd1b5570208fBrian Paul return PIPE_TEXTURE_1D_ARRAY; 889b56a2cb626b254bcb7b7202e6babd1b5570208fBrian Paul case GL_TEXTURE_2D_ARRAY_EXT: 899b56a2cb626b254bcb7b7202e6babd1b5570208fBrian Paul return PIPE_TEXTURE_2D_ARRAY; 90874a2c0b7da62f4dd08dedcec221f55b22e40e95Brian Paul case GL_TEXTURE_BUFFER: 91874a2c0b7da62f4dd08dedcec221f55b22e40e95Brian Paul return PIPE_BUFFER; 925390a43ce06b27f6d54bc5f237aa305b6948f2afBrian default: 935390a43ce06b27f6d54bc5f237aa305b6948f2afBrian assert(0); 945390a43ce06b27f6d54bc5f237aa305b6948f2afBrian return 0; 955390a43ce06b27f6d54bc5f237aa305b6948f2afBrian } 965390a43ce06b27f6d54bc5f237aa305b6948f2afBrian} 975390a43ce06b27f6d54bc5f237aa305b6948f2afBrian 985390a43ce06b27f6d54bc5f237aa305b6948f2afBrian 994e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul/** called via ctx->Driver.NewTextureImage() */ 10024df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic struct gl_texture_image * 101f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergst_NewTextureImage(struct gl_context * ctx) 10224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 10324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian DBG("%s\n", __FUNCTION__); 10424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian (void) ctx; 105f1a59a6dd7b7b0523db191d82b3af1a841c6475dBrian Paul return (struct gl_texture_image *) ST_CALLOC_STRUCT(st_texture_image); 10624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 10724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 10824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 109146f536b3332b7a2022bb4ba5e2d1d2ec4bedd98Brian Paul/** called via ctx->Driver.DeleteTextureImage() */ 110146f536b3332b7a2022bb4ba5e2d1d2ec4bedd98Brian Paulstatic void 111146f536b3332b7a2022bb4ba5e2d1d2ec4bedd98Brian Paulst_DeleteTextureImage(struct gl_context * ctx, struct gl_texture_image *img) 112146f536b3332b7a2022bb4ba5e2d1d2ec4bedd98Brian Paul{ 113146f536b3332b7a2022bb4ba5e2d1d2ec4bedd98Brian Paul /* nothing special (yet) for st_texture_image */ 114146f536b3332b7a2022bb4ba5e2d1d2ec4bedd98Brian Paul _mesa_delete_texture_image(ctx, img); 115146f536b3332b7a2022bb4ba5e2d1d2ec4bedd98Brian Paul} 116146f536b3332b7a2022bb4ba5e2d1d2ec4bedd98Brian Paul 117146f536b3332b7a2022bb4ba5e2d1d2ec4bedd98Brian Paul 1184e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul/** called via ctx->Driver.NewTextureObject() */ 11924df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic struct gl_texture_object * 120f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergst_NewTextureObject(struct gl_context * ctx, GLuint name, GLenum target) 12124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 122f1a59a6dd7b7b0523db191d82b3af1a841c6475dBrian Paul struct st_texture_object *obj = ST_CALLOC_STRUCT(st_texture_object); 12324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 12424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian DBG("%s\n", __FUNCTION__); 12524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian _mesa_initialize_texture_object(&obj->base, name, target); 12624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 12724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian return &obj->base; 12824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 12924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 13030f46e7b4c9d6c6f8c1c01825b344b90adc93982Brian Paul/** called via ctx->Driver.DeleteTextureObject() */ 13124df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void 132f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergst_DeleteTextureObject(struct gl_context *ctx, 1336f715dcc219071e574e363a9db4365c9c31ebbd3Brian struct gl_texture_object *texObj) 13424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 13576c7ad2e7d387feefe58dc2116b613fe11a8b273Brian Paul struct st_context *st = st_context(ctx); 13624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian struct st_texture_object *stObj = st_texture_object(texObj); 137753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer if (stObj->pt) 138287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell pipe_resource_reference(&stObj->pt, NULL); 1392d6befd9d1e8dcf6495fe1b9cef12224046f3095Brian Paul if (stObj->sampler_view) { 1406835103878afd27a1d66d29d16cbfb0b1e894a94Brian Paul pipe_sampler_view_release(st->pipe, &stObj->sampler_view); 1412d6befd9d1e8dcf6495fe1b9cef12224046f3095Brian Paul } 14224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian _mesa_delete_texture_object(ctx, texObj); 14324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 14424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 14524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 1460bb29949ba8a9e5a15dc0640dbb0a4e7990a1d57Eric Anholt/** called via ctx->Driver.FreeTextureImageBuffer() */ 14724df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void 148a61e164ae09cc2aec5df483809a2c6d74e36bf99Brian Paulst_FreeTextureImageBuffer(struct gl_context *ctx, 149a61e164ae09cc2aec5df483809a2c6d74e36bf99Brian Paul struct gl_texture_image *texImage) 15024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 15124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian struct st_texture_image *stImage = st_texture_image(texImage); 15224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 15324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian DBG("%s\n", __FUNCTION__); 15424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 155753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer if (stImage->pt) { 156287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell pipe_resource_reference(&stImage->pt, NULL); 15724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 15824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 159aff65241c8bf6206c6dfcbe774b87991f965d46fBrian Paul if (stImage->TexData) { 160aff65241c8bf6206c6dfcbe774b87991f965d46fBrian Paul _mesa_align_free(stImage->TexData); 161aff65241c8bf6206c6dfcbe774b87991f965d46fBrian Paul stImage->TexData = NULL; 16224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 16324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 16424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 16524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 1660abb2659dda3ac7828cade6f9a999c511e33e905Brian Paul/** called via ctx->Driver.MapTextureImage() */ 1670abb2659dda3ac7828cade6f9a999c511e33e905Brian Paulstatic void 1680abb2659dda3ac7828cade6f9a999c511e33e905Brian Paulst_MapTextureImage(struct gl_context *ctx, 1690abb2659dda3ac7828cade6f9a999c511e33e905Brian Paul struct gl_texture_image *texImage, 1700abb2659dda3ac7828cade6f9a999c511e33e905Brian Paul GLuint slice, GLuint x, GLuint y, GLuint w, GLuint h, 1710abb2659dda3ac7828cade6f9a999c511e33e905Brian Paul GLbitfield mode, 1720abb2659dda3ac7828cade6f9a999c511e33e905Brian Paul GLubyte **mapOut, GLint *rowStrideOut) 1730abb2659dda3ac7828cade6f9a999c511e33e905Brian Paul{ 1740abb2659dda3ac7828cade6f9a999c511e33e905Brian Paul struct st_context *st = st_context(ctx); 1750abb2659dda3ac7828cade6f9a999c511e33e905Brian Paul struct st_texture_image *stImage = st_texture_image(texImage); 1760abb2659dda3ac7828cade6f9a999c511e33e905Brian Paul unsigned pipeMode; 1770abb2659dda3ac7828cade6f9a999c511e33e905Brian Paul GLubyte *map; 1780abb2659dda3ac7828cade6f9a999c511e33e905Brian Paul 1790abb2659dda3ac7828cade6f9a999c511e33e905Brian Paul pipeMode = 0x0; 1800abb2659dda3ac7828cade6f9a999c511e33e905Brian Paul if (mode & GL_MAP_READ_BIT) 1810abb2659dda3ac7828cade6f9a999c511e33e905Brian Paul pipeMode |= PIPE_TRANSFER_READ; 1820abb2659dda3ac7828cade6f9a999c511e33e905Brian Paul if (mode & GL_MAP_WRITE_BIT) 1830abb2659dda3ac7828cade6f9a999c511e33e905Brian Paul pipeMode |= PIPE_TRANSFER_WRITE; 18484c7c14697c82fe25586f8186b4f47d80a6f05f9Brian Paul if (mode & GL_MAP_INVALIDATE_RANGE_BIT) 18584c7c14697c82fe25586f8186b4f47d80a6f05f9Brian Paul pipeMode |= PIPE_TRANSFER_DISCARD_RANGE; 1860abb2659dda3ac7828cade6f9a999c511e33e905Brian Paul 1870abb2659dda3ac7828cade6f9a999c511e33e905Brian Paul map = st_texture_image_map(st, stImage, slice, pipeMode, x, y, w, h); 1880abb2659dda3ac7828cade6f9a999c511e33e905Brian Paul if (map) { 1890abb2659dda3ac7828cade6f9a999c511e33e905Brian Paul *mapOut = map; 1900abb2659dda3ac7828cade6f9a999c511e33e905Brian Paul *rowStrideOut = stImage->transfer->stride; 1910abb2659dda3ac7828cade6f9a999c511e33e905Brian Paul } 1920abb2659dda3ac7828cade6f9a999c511e33e905Brian Paul else { 1930abb2659dda3ac7828cade6f9a999c511e33e905Brian Paul *mapOut = NULL; 1940abb2659dda3ac7828cade6f9a999c511e33e905Brian Paul *rowStrideOut = 0; 1950abb2659dda3ac7828cade6f9a999c511e33e905Brian Paul } 1960abb2659dda3ac7828cade6f9a999c511e33e905Brian Paul} 1970abb2659dda3ac7828cade6f9a999c511e33e905Brian Paul 1980abb2659dda3ac7828cade6f9a999c511e33e905Brian Paul 1990abb2659dda3ac7828cade6f9a999c511e33e905Brian Paul/** called via ctx->Driver.UnmapTextureImage() */ 2000abb2659dda3ac7828cade6f9a999c511e33e905Brian Paulstatic void 2010abb2659dda3ac7828cade6f9a999c511e33e905Brian Paulst_UnmapTextureImage(struct gl_context *ctx, 2020abb2659dda3ac7828cade6f9a999c511e33e905Brian Paul struct gl_texture_image *texImage, 2030abb2659dda3ac7828cade6f9a999c511e33e905Brian Paul GLuint slice) 2040abb2659dda3ac7828cade6f9a999c511e33e905Brian Paul{ 2050abb2659dda3ac7828cade6f9a999c511e33e905Brian Paul struct st_context *st = st_context(ctx); 2060abb2659dda3ac7828cade6f9a999c511e33e905Brian Paul struct st_texture_image *stImage = st_texture_image(texImage); 2070abb2659dda3ac7828cade6f9a999c511e33e905Brian Paul st_texture_image_unmap(st, stImage); 2080abb2659dda3ac7828cade6f9a999c511e33e905Brian Paul} 2090abb2659dda3ac7828cade6f9a999c511e33e905Brian Paul 2100abb2659dda3ac7828cade6f9a999c511e33e905Brian Paul 2114e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul/** 2128283db88414f600e66510de713382c36899d4b03Brian Paul * Return default texture resource binding bitmask for the given format. 2131ad2484f03cbe9ae6bd4ebe50d6894e570d65952Brian Paul */ 2141ad2484f03cbe9ae6bd4ebe50d6894e570d65952Brian Paulstatic GLuint 2158283db88414f600e66510de713382c36899d4b03Brian Pauldefault_bindings(struct st_context *st, enum pipe_format format) 2161ad2484f03cbe9ae6bd4ebe50d6894e570d65952Brian Paul{ 2178283db88414f600e66510de713382c36899d4b03Brian Paul struct pipe_screen *screen = st->pipe->screen; 2188283db88414f600e66510de713382c36899d4b03Brian Paul const unsigned target = PIPE_TEXTURE_2D; 2198283db88414f600e66510de713382c36899d4b03Brian Paul unsigned bindings; 2208283db88414f600e66510de713382c36899d4b03Brian Paul 2218283db88414f600e66510de713382c36899d4b03Brian Paul if (util_format_is_depth_or_stencil(format)) 2228283db88414f600e66510de713382c36899d4b03Brian Paul bindings = PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_DEPTH_STENCIL; 2238283db88414f600e66510de713382c36899d4b03Brian Paul else 2248283db88414f600e66510de713382c36899d4b03Brian Paul bindings = PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET; 2258283db88414f600e66510de713382c36899d4b03Brian Paul 226e968975cb57eb854769292f7c6ff773c64a386c3Marek Olšák if (screen->is_format_supported(screen, format, target, 0, bindings)) 2278283db88414f600e66510de713382c36899d4b03Brian Paul return bindings; 228ba48811fa8cbe80c67cdbbb9b8180aaf64433c4eMarek Olšák else { 229ba48811fa8cbe80c67cdbbb9b8180aaf64433c4eMarek Olšák /* Try non-sRGB. */ 230ba48811fa8cbe80c67cdbbb9b8180aaf64433c4eMarek Olšák format = util_format_linear(format); 231ba48811fa8cbe80c67cdbbb9b8180aaf64433c4eMarek Olšák 232e968975cb57eb854769292f7c6ff773c64a386c3Marek Olšák if (screen->is_format_supported(screen, format, target, 0, bindings)) 233ba48811fa8cbe80c67cdbbb9b8180aaf64433c4eMarek Olšák return bindings; 234ba48811fa8cbe80c67cdbbb9b8180aaf64433c4eMarek Olšák else 235ba48811fa8cbe80c67cdbbb9b8180aaf64433c4eMarek Olšák return PIPE_BIND_SAMPLER_VIEW; 236ba48811fa8cbe80c67cdbbb9b8180aaf64433c4eMarek Olšák } 2371ad2484f03cbe9ae6bd4ebe50d6894e570d65952Brian Paul} 2381ad2484f03cbe9ae6bd4ebe50d6894e570d65952Brian Paul 2391ad2484f03cbe9ae6bd4ebe50d6894e570d65952Brian Paul 2401ad2484f03cbe9ae6bd4ebe50d6894e570d65952Brian Paul/** 2414cdcec08d14a0709b09dc82a35367b2bcc817957Brian Paul * Given the size of a mipmap image, try to compute the size of the level=0 2424cdcec08d14a0709b09dc82a35367b2bcc817957Brian Paul * mipmap image. 2434cdcec08d14a0709b09dc82a35367b2bcc817957Brian Paul * 2444cdcec08d14a0709b09dc82a35367b2bcc817957Brian Paul * Note that this isn't always accurate for odd-sized, non-POW textures. 2454cdcec08d14a0709b09dc82a35367b2bcc817957Brian Paul * For example, if level=1 and width=40 then the level=0 width may be 80 or 81. 2464cdcec08d14a0709b09dc82a35367b2bcc817957Brian Paul * 2474cdcec08d14a0709b09dc82a35367b2bcc817957Brian Paul * \return GL_TRUE for success, GL_FALSE for failure 2484cdcec08d14a0709b09dc82a35367b2bcc817957Brian Paul */ 2494cdcec08d14a0709b09dc82a35367b2bcc817957Brian Paulstatic GLboolean 2504cdcec08d14a0709b09dc82a35367b2bcc817957Brian Paulguess_base_level_size(GLenum target, 2514cdcec08d14a0709b09dc82a35367b2bcc817957Brian Paul GLuint width, GLuint height, GLuint depth, GLuint level, 2524cdcec08d14a0709b09dc82a35367b2bcc817957Brian Paul GLuint *width0, GLuint *height0, GLuint *depth0) 2534cdcec08d14a0709b09dc82a35367b2bcc817957Brian Paul{ 2544cdcec08d14a0709b09dc82a35367b2bcc817957Brian Paul assert(width >= 1); 2554cdcec08d14a0709b09dc82a35367b2bcc817957Brian Paul assert(height >= 1); 2564cdcec08d14a0709b09dc82a35367b2bcc817957Brian Paul assert(depth >= 1); 2574cdcec08d14a0709b09dc82a35367b2bcc817957Brian Paul 2584cdcec08d14a0709b09dc82a35367b2bcc817957Brian Paul if (level > 0) { 259d1dfe4e020e563606e7d987968682501829800dbMarek Olšák /* Guess the size of the base level. 260d1dfe4e020e563606e7d987968682501829800dbMarek Olšák * Depending on the image's size, we can't always make a guess here. 261d1dfe4e020e563606e7d987968682501829800dbMarek Olšák */ 262d1dfe4e020e563606e7d987968682501829800dbMarek Olšák switch (target) { 263d1dfe4e020e563606e7d987968682501829800dbMarek Olšák case GL_TEXTURE_1D: 264d1dfe4e020e563606e7d987968682501829800dbMarek Olšák case GL_TEXTURE_1D_ARRAY: 265d1dfe4e020e563606e7d987968682501829800dbMarek Olšák width <<= level; 266d1dfe4e020e563606e7d987968682501829800dbMarek Olšák break; 267d1dfe4e020e563606e7d987968682501829800dbMarek Olšák 268d1dfe4e020e563606e7d987968682501829800dbMarek Olšák case GL_TEXTURE_2D: 269d1dfe4e020e563606e7d987968682501829800dbMarek Olšák case GL_TEXTURE_2D_ARRAY: 270d1dfe4e020e563606e7d987968682501829800dbMarek Olšák /* We can't make a good guess here, because the base level dimensions 271d1dfe4e020e563606e7d987968682501829800dbMarek Olšák * can be non-square. 272d1dfe4e020e563606e7d987968682501829800dbMarek Olšák */ 273d1dfe4e020e563606e7d987968682501829800dbMarek Olšák if (width == 1 || height == 1) { 274d1dfe4e020e563606e7d987968682501829800dbMarek Olšák return GL_FALSE; 275d1dfe4e020e563606e7d987968682501829800dbMarek Olšák } 276d1dfe4e020e563606e7d987968682501829800dbMarek Olšák width <<= level; 277d1dfe4e020e563606e7d987968682501829800dbMarek Olšák height <<= level; 278d1dfe4e020e563606e7d987968682501829800dbMarek Olšák break; 279d1dfe4e020e563606e7d987968682501829800dbMarek Olšák 280d1dfe4e020e563606e7d987968682501829800dbMarek Olšák case GL_TEXTURE_CUBE_MAP: 281d1dfe4e020e563606e7d987968682501829800dbMarek Olšák case GL_TEXTURE_CUBE_MAP_ARRAY: 282d1dfe4e020e563606e7d987968682501829800dbMarek Olšák width <<= level; 283d1dfe4e020e563606e7d987968682501829800dbMarek Olšák height <<= level; 284d1dfe4e020e563606e7d987968682501829800dbMarek Olšák break; 285d1dfe4e020e563606e7d987968682501829800dbMarek Olšák 286d1dfe4e020e563606e7d987968682501829800dbMarek Olšák case GL_TEXTURE_3D: 287d1dfe4e020e563606e7d987968682501829800dbMarek Olšák /* We can't make a good guess here, because the base level dimensions 288d1dfe4e020e563606e7d987968682501829800dbMarek Olšák * can be non-cube. 289d1dfe4e020e563606e7d987968682501829800dbMarek Olšák */ 290d1dfe4e020e563606e7d987968682501829800dbMarek Olšák if (width == 1 || height == 1 || depth == 1) { 291d1dfe4e020e563606e7d987968682501829800dbMarek Olšák return GL_FALSE; 292d1dfe4e020e563606e7d987968682501829800dbMarek Olšák } 293d1dfe4e020e563606e7d987968682501829800dbMarek Olšák width <<= level; 294d1dfe4e020e563606e7d987968682501829800dbMarek Olšák height <<= level; 295d1dfe4e020e563606e7d987968682501829800dbMarek Olšák depth <<= level; 296d1dfe4e020e563606e7d987968682501829800dbMarek Olšák break; 297d1dfe4e020e563606e7d987968682501829800dbMarek Olšák 298d1dfe4e020e563606e7d987968682501829800dbMarek Olšák case GL_TEXTURE_RECTANGLE: 299d1dfe4e020e563606e7d987968682501829800dbMarek Olšák break; 300d1dfe4e020e563606e7d987968682501829800dbMarek Olšák 301d1dfe4e020e563606e7d987968682501829800dbMarek Olšák default: 302d1dfe4e020e563606e7d987968682501829800dbMarek Olšák assert(0); 3034cdcec08d14a0709b09dc82a35367b2bcc817957Brian Paul } 304d1dfe4e020e563606e7d987968682501829800dbMarek Olšák } 3054cdcec08d14a0709b09dc82a35367b2bcc817957Brian Paul 3064cdcec08d14a0709b09dc82a35367b2bcc817957Brian Paul *width0 = width; 3074cdcec08d14a0709b09dc82a35367b2bcc817957Brian Paul *height0 = height; 3084cdcec08d14a0709b09dc82a35367b2bcc817957Brian Paul *depth0 = depth; 3094cdcec08d14a0709b09dc82a35367b2bcc817957Brian Paul 3104cdcec08d14a0709b09dc82a35367b2bcc817957Brian Paul return GL_TRUE; 3114cdcec08d14a0709b09dc82a35367b2bcc817957Brian Paul} 3124cdcec08d14a0709b09dc82a35367b2bcc817957Brian Paul 3134cdcec08d14a0709b09dc82a35367b2bcc817957Brian Paul 3144cdcec08d14a0709b09dc82a35367b2bcc817957Brian Paul/** 315e648d4a1d1c0c5f70916e38366b863f0bec79a62Brian Paul * Try to allocate a pipe_resource object for the given st_texture_object. 316f52f5136e6eed23e55098681e5b082cc452136d6Brian * 317e648d4a1d1c0c5f70916e38366b863f0bec79a62Brian Paul * We use the given st_texture_image as a clue to determine the size of the 318e648d4a1d1c0c5f70916e38366b863f0bec79a62Brian Paul * mipmap image at level=0. 3192b53f4a9c674e9b02df8a06759e7a2340f257081Brian Paul * 3202b53f4a9c674e9b02df8a06759e7a2340f257081Brian Paul * \return GL_TRUE for success, GL_FALSE if out of memory. 32124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 3222b53f4a9c674e9b02df8a06759e7a2340f257081Brian Paulstatic GLboolean 323753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzerguess_and_alloc_texture(struct st_context *st, 324753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer struct st_texture_object *stObj, 325afc54983370033b65e3a7cbb29bd9c87156f0881Brian const struct st_texture_image *stImage) 32624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 3274cdcec08d14a0709b09dc82a35367b2bcc817957Brian Paul GLuint lastLevel, width, height, depth; 328e648d4a1d1c0c5f70916e38366b863f0bec79a62Brian Paul GLuint bindings; 3291dd8e2757852682af44b63193c89dff3c09c7703Brian Paul GLuint ptWidth, ptHeight, ptDepth, ptLayers; 330a1f95a8bf64f863289b6759caeec76d7e054400eRoland Scheidegger enum pipe_format fmt; 33124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 33224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian DBG("%s\n", __FUNCTION__); 33324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 334f52f5136e6eed23e55098681e5b082cc452136d6Brian assert(!stObj->pt); 335f52f5136e6eed23e55098681e5b082cc452136d6Brian 3364cdcec08d14a0709b09dc82a35367b2bcc817957Brian Paul if (!guess_base_level_size(stObj->base.Target, 3374cdcec08d14a0709b09dc82a35367b2bcc817957Brian Paul stImage->base.Width2, 3384cdcec08d14a0709b09dc82a35367b2bcc817957Brian Paul stImage->base.Height2, 3394cdcec08d14a0709b09dc82a35367b2bcc817957Brian Paul stImage->base.Depth2, 3406dbad425bc423eb7db7c99aab161955c7b4cdc4cBrian Paul stImage->base.Level, 3414cdcec08d14a0709b09dc82a35367b2bcc817957Brian Paul &width, &height, &depth)) { 3424cdcec08d14a0709b09dc82a35367b2bcc817957Brian Paul /* we can't determine the image size at level=0 */ 3434cdcec08d14a0709b09dc82a35367b2bcc817957Brian Paul stObj->width0 = stObj->height0 = stObj->depth0 = 0; 3444cdcec08d14a0709b09dc82a35367b2bcc817957Brian Paul /* this is not an out of memory error */ 3454cdcec08d14a0709b09dc82a35367b2bcc817957Brian Paul return GL_TRUE; 346e648d4a1d1c0c5f70916e38366b863f0bec79a62Brian Paul } 347e648d4a1d1c0c5f70916e38366b863f0bec79a62Brian Paul 348e648d4a1d1c0c5f70916e38366b863f0bec79a62Brian Paul /* At this point, (width x height x depth) is the expected size of 349e648d4a1d1c0c5f70916e38366b863f0bec79a62Brian Paul * the level=0 mipmap image. 350e648d4a1d1c0c5f70916e38366b863f0bec79a62Brian Paul */ 351296378b6c8b205048244746e260739448c4ee590Brian Paul 3524b7812919a5db2f72bd3b9f6d760ffeb469ee3e4Brian Paul /* Guess a reasonable value for lastLevel. With OpenGL we have no 3534b7812919a5db2f72bd3b9f6d760ffeb469ee3e4Brian Paul * idea how many mipmap levels will be in a texture until we start 3544b7812919a5db2f72bd3b9f6d760ffeb469ee3e4Brian Paul * to render with it. Make an educated guess here but be prepared 3554b7812919a5db2f72bd3b9f6d760ffeb469ee3e4Brian Paul * to re-allocating a texture buffer with space for more (or fewer) 3564b7812919a5db2f72bd3b9f6d760ffeb469ee3e4Brian Paul * mipmap levels later. 35724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 358ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul if ((stObj->base.Sampler.MinFilter == GL_NEAREST || 359ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul stObj->base.Sampler.MinFilter == GL_LINEAR || 3602a2236606fd6ae473a2f4db6ef6d3d5030261316José Fonseca stImage->base._BaseFormat == GL_DEPTH_COMPONENT || 3612a2236606fd6ae473a2f4db6ef6d3d5030261316José Fonseca stImage->base._BaseFormat == GL_DEPTH_STENCIL_EXT) && 36205bad193f56d48384097e37e47fae3fdda85f144Brian Paul !stObj->base.GenerateMipmap && 3636dbad425bc423eb7db7c99aab161955c7b4cdc4cBrian Paul stImage->base.Level == 0) { 36405bad193f56d48384097e37e47fae3fdda85f144Brian Paul /* only alloc space for a single mipmap level */ 365e648d4a1d1c0c5f70916e38366b863f0bec79a62Brian Paul lastLevel = 0; 36624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 36724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian else { 36805bad193f56d48384097e37e47fae3fdda85f144Brian Paul /* alloc space for a full mipmap */ 3697ca75b62cdd9ddc943ded3a6904b11f62162affbMarek Olšák lastLevel = _mesa_get_tex_max_num_levels(stObj->base.Target, 3707ca75b62cdd9ddc943ded3a6904b11f62162affbMarek Olšák width, height, depth) - 1; 37124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 37224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 373e648d4a1d1c0c5f70916e38366b863f0bec79a62Brian Paul /* Save the level=0 dimensions */ 374e648d4a1d1c0c5f70916e38366b863f0bec79a62Brian Paul stObj->width0 = width; 375e648d4a1d1c0c5f70916e38366b863f0bec79a62Brian Paul stObj->height0 = height; 376e648d4a1d1c0c5f70916e38366b863f0bec79a62Brian Paul stObj->depth0 = depth; 377e648d4a1d1c0c5f70916e38366b863f0bec79a62Brian Paul 3781f7c914ad0beea8a29c1a171c7cd1a12f2efe0faBrian Paul fmt = st_mesa_format_to_pipe_format(stImage->base.TexFormat); 3791ad2484f03cbe9ae6bd4ebe50d6894e570d65952Brian Paul 3808283db88414f600e66510de713382c36899d4b03Brian Paul bindings = default_bindings(st, fmt); 3811ad2484f03cbe9ae6bd4ebe50d6894e570d65952Brian Paul 3821dd8e2757852682af44b63193c89dff3c09c7703Brian Paul st_gl_texture_dims_to_pipe_dims(stObj->base.Target, 3831dd8e2757852682af44b63193c89dff3c09c7703Brian Paul width, height, depth, 3841dd8e2757852682af44b63193c89dff3c09c7703Brian Paul &ptWidth, &ptHeight, &ptDepth, &ptLayers); 3851dd8e2757852682af44b63193c89dff3c09c7703Brian Paul 386753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer stObj->pt = st_texture_create(st, 3875390a43ce06b27f6d54bc5f237aa305b6948f2afBrian gl_target_to_pipe(stObj->base.Target), 388a1f95a8bf64f863289b6759caeec76d7e054400eRoland Scheidegger fmt, 3895390a43ce06b27f6d54bc5f237aa305b6948f2afBrian lastLevel, 3901dd8e2757852682af44b63193c89dff3c09c7703Brian Paul ptWidth, 3911dd8e2757852682af44b63193c89dff3c09c7703Brian Paul ptHeight, 3921dd8e2757852682af44b63193c89dff3c09c7703Brian Paul ptDepth, 3931dd8e2757852682af44b63193c89dff3c09c7703Brian Paul ptLayers, 3948283db88414f600e66510de713382c36899d4b03Brian Paul bindings); 39524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 396c91b4edff978ee19afb4fe38ad69efc52db90691Vadim Girlin stObj->lastLevel = lastLevel; 397c91b4edff978ee19afb4fe38ad69efc52db90691Vadim Girlin 3982b53f4a9c674e9b02df8a06759e7a2340f257081Brian Paul DBG("%s returning %d\n", __FUNCTION__, (stObj->pt != NULL)); 3992b53f4a9c674e9b02df8a06759e7a2340f257081Brian Paul 4002b53f4a9c674e9b02df8a06759e7a2340f257081Brian Paul return stObj->pt != NULL; 40124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 40224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 40324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 404212b27d33f94eeb25ba9cbc58f9e41295a29d2c9Brian/** 4054e6bb0774ffa93141a3a8ec7bb47b190810b2a4bBrian Paul * Called via ctx->Driver.AllocTextureImageBuffer(). 4064e6bb0774ffa93141a3a8ec7bb47b190810b2a4bBrian Paul * If the texture object/buffer already has space for the indicated image, 4074e6bb0774ffa93141a3a8ec7bb47b190810b2a4bBrian Paul * we're done. Otherwise, allocate memory for the new texture image. 4084e6bb0774ffa93141a3a8ec7bb47b190810b2a4bBrian Paul */ 4094e6bb0774ffa93141a3a8ec7bb47b190810b2a4bBrian Paulstatic GLboolean 4104e6bb0774ffa93141a3a8ec7bb47b190810b2a4bBrian Paulst_AllocTextureImageBuffer(struct gl_context *ctx, 411c9a7dfcf92e6adb4b85338c2c8dbbfbaf39fbfe7Pauli Nieminen struct gl_texture_image *texImage) 4124e6bb0774ffa93141a3a8ec7bb47b190810b2a4bBrian Paul{ 4134e6bb0774ffa93141a3a8ec7bb47b190810b2a4bBrian Paul struct st_context *st = st_context(ctx); 4144e6bb0774ffa93141a3a8ec7bb47b190810b2a4bBrian Paul struct st_texture_image *stImage = st_texture_image(texImage); 4154e6bb0774ffa93141a3a8ec7bb47b190810b2a4bBrian Paul struct st_texture_object *stObj = st_texture_object(texImage->TexObject); 4164e6bb0774ffa93141a3a8ec7bb47b190810b2a4bBrian Paul const GLuint level = texImage->Level; 417c9a7dfcf92e6adb4b85338c2c8dbbfbaf39fbfe7Pauli Nieminen GLuint width = texImage->Width; 418c9a7dfcf92e6adb4b85338c2c8dbbfbaf39fbfe7Pauli Nieminen GLuint height = texImage->Height; 419c9a7dfcf92e6adb4b85338c2c8dbbfbaf39fbfe7Pauli Nieminen GLuint depth = texImage->Depth; 4204e6bb0774ffa93141a3a8ec7bb47b190810b2a4bBrian Paul 4214e6bb0774ffa93141a3a8ec7bb47b190810b2a4bBrian Paul DBG("%s\n", __FUNCTION__); 4224e6bb0774ffa93141a3a8ec7bb47b190810b2a4bBrian Paul 423aff65241c8bf6206c6dfcbe774b87991f965d46fBrian Paul assert(!stImage->TexData); 4244e6bb0774ffa93141a3a8ec7bb47b190810b2a4bBrian Paul assert(!stImage->pt); /* xxx this might be wrong */ 4254e6bb0774ffa93141a3a8ec7bb47b190810b2a4bBrian Paul 4264e6bb0774ffa93141a3a8ec7bb47b190810b2a4bBrian Paul /* Look if the parent texture object has space for this image */ 4274e6bb0774ffa93141a3a8ec7bb47b190810b2a4bBrian Paul if (stObj->pt && 4284e6bb0774ffa93141a3a8ec7bb47b190810b2a4bBrian Paul level <= stObj->pt->last_level && 4294e6bb0774ffa93141a3a8ec7bb47b190810b2a4bBrian Paul st_texture_match_image(stObj->pt, texImage)) { 4304e6bb0774ffa93141a3a8ec7bb47b190810b2a4bBrian Paul /* this image will fit in the existing texture object's memory */ 4314e6bb0774ffa93141a3a8ec7bb47b190810b2a4bBrian Paul pipe_resource_reference(&stImage->pt, stObj->pt); 4324e6bb0774ffa93141a3a8ec7bb47b190810b2a4bBrian Paul return GL_TRUE; 4334e6bb0774ffa93141a3a8ec7bb47b190810b2a4bBrian Paul } 4344e6bb0774ffa93141a3a8ec7bb47b190810b2a4bBrian Paul 4354e6bb0774ffa93141a3a8ec7bb47b190810b2a4bBrian Paul /* The parent texture object does not have space for this image */ 4364e6bb0774ffa93141a3a8ec7bb47b190810b2a4bBrian Paul 4374e6bb0774ffa93141a3a8ec7bb47b190810b2a4bBrian Paul pipe_resource_reference(&stObj->pt, NULL); 4386835103878afd27a1d66d29d16cbfb0b1e894a94Brian Paul pipe_sampler_view_release(st->pipe, &stObj->sampler_view); 4394e6bb0774ffa93141a3a8ec7bb47b190810b2a4bBrian Paul 4404e6bb0774ffa93141a3a8ec7bb47b190810b2a4bBrian Paul if (!guess_and_alloc_texture(st, stObj, stImage)) { 4414e6bb0774ffa93141a3a8ec7bb47b190810b2a4bBrian Paul /* Probably out of memory. 4424e6bb0774ffa93141a3a8ec7bb47b190810b2a4bBrian Paul * Try flushing any pending rendering, then retry. 4434e6bb0774ffa93141a3a8ec7bb47b190810b2a4bBrian Paul */ 4444e6bb0774ffa93141a3a8ec7bb47b190810b2a4bBrian Paul st_finish(st); 4454e6bb0774ffa93141a3a8ec7bb47b190810b2a4bBrian Paul if (!guess_and_alloc_texture(st, stObj, stImage)) { 4464e6bb0774ffa93141a3a8ec7bb47b190810b2a4bBrian Paul _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage"); 4474e6bb0774ffa93141a3a8ec7bb47b190810b2a4bBrian Paul return GL_FALSE; 4484e6bb0774ffa93141a3a8ec7bb47b190810b2a4bBrian Paul } 4494e6bb0774ffa93141a3a8ec7bb47b190810b2a4bBrian Paul } 4504e6bb0774ffa93141a3a8ec7bb47b190810b2a4bBrian Paul 4514e6bb0774ffa93141a3a8ec7bb47b190810b2a4bBrian Paul if (stObj->pt && 4524e6bb0774ffa93141a3a8ec7bb47b190810b2a4bBrian Paul st_texture_match_image(stObj->pt, texImage)) { 4534e6bb0774ffa93141a3a8ec7bb47b190810b2a4bBrian Paul /* The image will live in the object's mipmap memory */ 4544e6bb0774ffa93141a3a8ec7bb47b190810b2a4bBrian Paul pipe_resource_reference(&stImage->pt, stObj->pt); 4554e6bb0774ffa93141a3a8ec7bb47b190810b2a4bBrian Paul assert(stImage->pt); 4564e6bb0774ffa93141a3a8ec7bb47b190810b2a4bBrian Paul return GL_TRUE; 4574e6bb0774ffa93141a3a8ec7bb47b190810b2a4bBrian Paul } 4584e6bb0774ffa93141a3a8ec7bb47b190810b2a4bBrian Paul else { 4594e6bb0774ffa93141a3a8ec7bb47b190810b2a4bBrian Paul /* Create a new, temporary texture/resource/buffer to hold this 4605d67d4fbebb7c7d6582c4c92fc5cea4a8e6a60abBrian Paul * one texture image. Note that when we later access this image 4615d67d4fbebb7c7d6582c4c92fc5cea4a8e6a60abBrian Paul * (either for mapping or copying) we'll want to always specify 4625d67d4fbebb7c7d6582c4c92fc5cea4a8e6a60abBrian Paul * mipmap level=0, even if the image represents some other mipmap 4635d67d4fbebb7c7d6582c4c92fc5cea4a8e6a60abBrian Paul * level. 4644e6bb0774ffa93141a3a8ec7bb47b190810b2a4bBrian Paul */ 4654e6bb0774ffa93141a3a8ec7bb47b190810b2a4bBrian Paul enum pipe_format format = 4664e6bb0774ffa93141a3a8ec7bb47b190810b2a4bBrian Paul st_mesa_format_to_pipe_format(texImage->TexFormat); 4674e6bb0774ffa93141a3a8ec7bb47b190810b2a4bBrian Paul GLuint bindings = default_bindings(st, format); 4684e6bb0774ffa93141a3a8ec7bb47b190810b2a4bBrian Paul GLuint ptWidth, ptHeight, ptDepth, ptLayers; 4694e6bb0774ffa93141a3a8ec7bb47b190810b2a4bBrian Paul 4704e6bb0774ffa93141a3a8ec7bb47b190810b2a4bBrian Paul st_gl_texture_dims_to_pipe_dims(stObj->base.Target, 4714e6bb0774ffa93141a3a8ec7bb47b190810b2a4bBrian Paul width, height, depth, 4724e6bb0774ffa93141a3a8ec7bb47b190810b2a4bBrian Paul &ptWidth, &ptHeight, &ptDepth, &ptLayers); 4734e6bb0774ffa93141a3a8ec7bb47b190810b2a4bBrian Paul 4744e6bb0774ffa93141a3a8ec7bb47b190810b2a4bBrian Paul stImage->pt = st_texture_create(st, 4754e6bb0774ffa93141a3a8ec7bb47b190810b2a4bBrian Paul gl_target_to_pipe(stObj->base.Target), 4764e6bb0774ffa93141a3a8ec7bb47b190810b2a4bBrian Paul format, 4774e6bb0774ffa93141a3a8ec7bb47b190810b2a4bBrian Paul 0, /* lastLevel */ 4784e6bb0774ffa93141a3a8ec7bb47b190810b2a4bBrian Paul ptWidth, 4794e6bb0774ffa93141a3a8ec7bb47b190810b2a4bBrian Paul ptHeight, 4804e6bb0774ffa93141a3a8ec7bb47b190810b2a4bBrian Paul ptDepth, 4814e6bb0774ffa93141a3a8ec7bb47b190810b2a4bBrian Paul ptLayers, 4824e6bb0774ffa93141a3a8ec7bb47b190810b2a4bBrian Paul bindings); 4834e6bb0774ffa93141a3a8ec7bb47b190810b2a4bBrian Paul return stImage->pt != NULL; 4844e6bb0774ffa93141a3a8ec7bb47b190810b2a4bBrian Paul } 4854e6bb0774ffa93141a3a8ec7bb47b190810b2a4bBrian Paul} 4864e6bb0774ffa93141a3a8ec7bb47b190810b2a4bBrian Paul 48719840c46f38b7bfe04bfaa925a6f56b3777be6ffBrian Paul 48819840c46f38b7bfe04bfaa925a6f56b3777be6ffBrian Paul/** 48919840c46f38b7bfe04bfaa925a6f56b3777be6ffBrian Paul * Preparation prior to glTexImage. Basically check the 'surface_based' 49019840c46f38b7bfe04bfaa925a6f56b3777be6ffBrian Paul * field and switch to a "normal" tex image if necessary. 49119840c46f38b7bfe04bfaa925a6f56b3777be6ffBrian Paul */ 49219840c46f38b7bfe04bfaa925a6f56b3777be6ffBrian Paulstatic void 49319840c46f38b7bfe04bfaa925a6f56b3777be6ffBrian Paulprep_teximage(struct gl_context *ctx, struct gl_texture_image *texImage, 49419840c46f38b7bfe04bfaa925a6f56b3777be6ffBrian Paul GLenum format, GLenum type) 49519840c46f38b7bfe04bfaa925a6f56b3777be6ffBrian Paul{ 49619840c46f38b7bfe04bfaa925a6f56b3777be6ffBrian Paul struct gl_texture_object *texObj = texImage->TexObject; 49719840c46f38b7bfe04bfaa925a6f56b3777be6ffBrian Paul struct st_texture_object *stObj = st_texture_object(texObj); 49819840c46f38b7bfe04bfaa925a6f56b3777be6ffBrian Paul 49919840c46f38b7bfe04bfaa925a6f56b3777be6ffBrian Paul /* switch to "normal" */ 50019840c46f38b7bfe04bfaa925a6f56b3777be6ffBrian Paul if (stObj->surface_based) { 50119840c46f38b7bfe04bfaa925a6f56b3777be6ffBrian Paul const GLenum target = texObj->Target; 50219840c46f38b7bfe04bfaa925a6f56b3777be6ffBrian Paul const GLuint level = texImage->Level; 50319840c46f38b7bfe04bfaa925a6f56b3777be6ffBrian Paul gl_format texFormat; 50419840c46f38b7bfe04bfaa925a6f56b3777be6ffBrian Paul 50519840c46f38b7bfe04bfaa925a6f56b3777be6ffBrian Paul _mesa_clear_texture_object(ctx, texObj); 50619840c46f38b7bfe04bfaa925a6f56b3777be6ffBrian Paul pipe_resource_reference(&stObj->pt, NULL); 50719840c46f38b7bfe04bfaa925a6f56b3777be6ffBrian Paul 50819840c46f38b7bfe04bfaa925a6f56b3777be6ffBrian Paul /* oops, need to init this image again */ 50919840c46f38b7bfe04bfaa925a6f56b3777be6ffBrian Paul texFormat = _mesa_choose_texture_format(ctx, texObj, target, level, 510c5af8891805fc4f590c1371c098cdbc704c44e00Pauli Nieminen texImage->InternalFormat, format, 511c5af8891805fc4f590c1371c098cdbc704c44e00Pauli Nieminen type); 51219840c46f38b7bfe04bfaa925a6f56b3777be6ffBrian Paul 51319840c46f38b7bfe04bfaa925a6f56b3777be6ffBrian Paul _mesa_init_teximage_fields(ctx, texImage, 514c5af8891805fc4f590c1371c098cdbc704c44e00Pauli Nieminen texImage->Width, texImage->Height, 515c5af8891805fc4f590c1371c098cdbc704c44e00Pauli Nieminen texImage->Depth, texImage->Border, 516c5af8891805fc4f590c1371c098cdbc704c44e00Pauli Nieminen texImage->InternalFormat, texFormat); 51719840c46f38b7bfe04bfaa925a6f56b3777be6ffBrian Paul 51819840c46f38b7bfe04bfaa925a6f56b3777be6ffBrian Paul stObj->surface_based = GL_FALSE; 51919840c46f38b7bfe04bfaa925a6f56b3777be6ffBrian Paul } 52019840c46f38b7bfe04bfaa925a6f56b3777be6ffBrian Paul} 52119840c46f38b7bfe04bfaa925a6f56b3777be6ffBrian Paul 52219840c46f38b7bfe04bfaa925a6f56b3777be6ffBrian Paul 52324df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void 5248f5fffe75d2f8ae7c7ee706b53379a25bc673ae4Brian Paulst_TexImage(struct gl_context * ctx, GLuint dims, 5258f5fffe75d2f8ae7c7ee706b53379a25bc673ae4Brian Paul struct gl_texture_image *texImage, 5268f5fffe75d2f8ae7c7ee706b53379a25bc673ae4Brian Paul GLenum format, GLenum type, const void *pixels, 5278f5fffe75d2f8ae7c7ee706b53379a25bc673ae4Brian Paul const struct gl_pixelstore_attrib *unpack) 52824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 529c5af8891805fc4f590c1371c098cdbc704c44e00Pauli Nieminen prep_teximage(ctx, texImage, format, type); 530c5af8891805fc4f590c1371c098cdbc704c44e00Pauli Nieminen _mesa_store_teximage(ctx, dims, texImage, format, type, pixels, unpack); 53124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 53224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 53324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 53424df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void 535e8fdd0e0d5286f4a9c763ffde44decec51124ebcBrian Paulst_CompressedTexImage(struct gl_context *ctx, GLuint dims, 536e8fdd0e0d5286f4a9c763ffde44decec51124ebcBrian Paul struct gl_texture_image *texImage, 537e8fdd0e0d5286f4a9c763ffde44decec51124ebcBrian Paul GLsizei imageSize, const GLvoid *data) 53824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 539c5af8891805fc4f590c1371c098cdbc704c44e00Pauli Nieminen prep_teximage(ctx, texImage, GL_NONE, GL_NONE); 5405606bd574e264c4beda8eb1d10b48d17e9b8b497Pauli Nieminen _mesa_store_compressed_teximage(ctx, dims, texImage, imageSize, data); 54124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 54224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 54324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 54451b339af2e8b80575a24bb9146f031c9605180bbBrian Paul 54551b339af2e8b80575a24bb9146f031c9605180bbBrian Paul/** 54651b339af2e8b80575a24bb9146f031c9605180bbBrian Paul * glGetTexImage() helper: decompress a compressed texture by rendering 54751b339af2e8b80575a24bb9146f031c9605180bbBrian Paul * a textured quad. Store the results in the user's buffer. 54851b339af2e8b80575a24bb9146f031c9605180bbBrian Paul */ 54951b339af2e8b80575a24bb9146f031c9605180bbBrian Paulstatic void 5504368a657670f1f3f13d8497f749cb5439f91529eBrian Pauldecompress_with_blit(struct gl_context * ctx, 55151b339af2e8b80575a24bb9146f031c9605180bbBrian Paul GLenum format, GLenum type, GLvoid *pixels, 55251b339af2e8b80575a24bb9146f031c9605180bbBrian Paul struct gl_texture_image *texImage) 55351b339af2e8b80575a24bb9146f031c9605180bbBrian Paul{ 55476c7ad2e7d387feefe58dc2116b613fe11a8b273Brian Paul struct st_context *st = st_context(ctx); 55576c7ad2e7d387feefe58dc2116b613fe11a8b273Brian Paul struct pipe_context *pipe = st->pipe; 55651b339af2e8b80575a24bb9146f031c9605180bbBrian Paul struct st_texture_image *stImage = st_texture_image(texImage); 5574368a657670f1f3f13d8497f749cb5439f91529eBrian Paul struct st_texture_object *stObj = st_texture_object(texImage->TexObject); 5580315cb9f8f3ec38fa9594860754fb53a67cf4c23Brian Paul struct pipe_sampler_view *src_view; 55951b339af2e8b80575a24bb9146f031c9605180bbBrian Paul const GLuint width = texImage->Width; 56051b339af2e8b80575a24bb9146f031c9605180bbBrian Paul const GLuint height = texImage->Height; 56151b339af2e8b80575a24bb9146f031c9605180bbBrian Paul struct pipe_surface *dst_surface; 562287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell struct pipe_resource *dst_texture; 56351b339af2e8b80575a24bb9146f031c9605180bbBrian Paul struct pipe_transfer *tex_xfer; 564127328bfadaa5f080730fd41f404f1bc74f490d3Roland Scheidegger unsigned bind = (PIPE_BIND_RENDER_TARGET | /* util_blit may choose to render */ 565287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell PIPE_BIND_TRANSFER_READ); 56651b339af2e8b80575a24bb9146f031c9605180bbBrian Paul 56751b339af2e8b80575a24bb9146f031c9605180bbBrian Paul /* create temp / dest surface */ 5684c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger if (!util_create_rgba_surface(pipe, width, height, bind, 56951b339af2e8b80575a24bb9146f031c9605180bbBrian Paul &dst_texture, &dst_surface)) { 57051b339af2e8b80575a24bb9146f031c9605180bbBrian Paul _mesa_problem(ctx, "util_create_rgba_surface() failed " 57151b339af2e8b80575a24bb9146f031c9605180bbBrian Paul "in decompress_with_blit()"); 57251b339af2e8b80575a24bb9146f031c9605180bbBrian Paul return; 57351b339af2e8b80575a24bb9146f031c9605180bbBrian Paul } 57451b339af2e8b80575a24bb9146f031c9605180bbBrian Paul 5758d45bbc4221d83bc2bfd0295f56b0f6d35b16a99Marek Olšák /* Disable conditional rendering. */ 5768d45bbc4221d83bc2bfd0295f56b0f6d35b16a99Marek Olšák if (st->render_condition) { 5778d45bbc4221d83bc2bfd0295f56b0f6d35b16a99Marek Olšák pipe->render_condition(pipe, NULL, 0); 5788d45bbc4221d83bc2bfd0295f56b0f6d35b16a99Marek Olšák } 5798d45bbc4221d83bc2bfd0295f56b0f6d35b16a99Marek Olšák 5800315cb9f8f3ec38fa9594860754fb53a67cf4c23Brian Paul /* Create sampler view that limits fetches to the source mipmap level */ 5810315cb9f8f3ec38fa9594860754fb53a67cf4c23Brian Paul { 5820315cb9f8f3ec38fa9594860754fb53a67cf4c23Brian Paul struct pipe_sampler_view sv_temp; 5830315cb9f8f3ec38fa9594860754fb53a67cf4c23Brian Paul 5840315cb9f8f3ec38fa9594860754fb53a67cf4c23Brian Paul u_sampler_view_default_template(&sv_temp, stObj->pt, stObj->pt->format); 5850315cb9f8f3ec38fa9594860754fb53a67cf4c23Brian Paul 5865e7e7d96b341e937d3b795e94ac4a863c357f724Marek Olšák sv_temp.format = util_format_linear(sv_temp.format); 5870315cb9f8f3ec38fa9594860754fb53a67cf4c23Brian Paul sv_temp.u.tex.first_level = 5880315cb9f8f3ec38fa9594860754fb53a67cf4c23Brian Paul sv_temp.u.tex.last_level = texImage->Level; 5890315cb9f8f3ec38fa9594860754fb53a67cf4c23Brian Paul 5900315cb9f8f3ec38fa9594860754fb53a67cf4c23Brian Paul src_view = pipe->create_sampler_view(pipe, stObj->pt, &sv_temp); 5910315cb9f8f3ec38fa9594860754fb53a67cf4c23Brian Paul if (!src_view) { 5920315cb9f8f3ec38fa9594860754fb53a67cf4c23Brian Paul _mesa_error(ctx, GL_OUT_OF_MEMORY, "glGetTexImage"); 5930315cb9f8f3ec38fa9594860754fb53a67cf4c23Brian Paul return; 5940315cb9f8f3ec38fa9594860754fb53a67cf4c23Brian Paul } 5950315cb9f8f3ec38fa9594860754fb53a67cf4c23Brian Paul } 59620b92c9d1ed8802cf0acb1c24884d0cef2bce10eBrian Paul 59751b339af2e8b80575a24bb9146f031c9605180bbBrian Paul /* blit/render/decompress */ 59876c7ad2e7d387feefe58dc2116b613fe11a8b273Brian Paul util_blit_pixels_tex(st->blit, 599287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell src_view, /* pipe_resource (src) */ 60051b339af2e8b80575a24bb9146f031c9605180bbBrian Paul 0, 0, /* src x0, y0 */ 60151b339af2e8b80575a24bb9146f031c9605180bbBrian Paul width, height, /* src x1, y1 */ 60251b339af2e8b80575a24bb9146f031c9605180bbBrian Paul dst_surface, /* pipe_surface (dst) */ 60351b339af2e8b80575a24bb9146f031c9605180bbBrian Paul 0, 0, /* dst x0, y0 */ 60451b339af2e8b80575a24bb9146f031c9605180bbBrian Paul width, height, /* dst x1, y1 */ 60551b339af2e8b80575a24bb9146f031c9605180bbBrian Paul 0.0, /* z */ 60651b339af2e8b80575a24bb9146f031c9605180bbBrian Paul PIPE_TEX_MIPFILTER_NEAREST); 60751b339af2e8b80575a24bb9146f031c9605180bbBrian Paul 6088d45bbc4221d83bc2bfd0295f56b0f6d35b16a99Marek Olšák /* Restore conditional rendering state. */ 6098d45bbc4221d83bc2bfd0295f56b0f6d35b16a99Marek Olšák if (st->render_condition) { 6108d45bbc4221d83bc2bfd0295f56b0f6d35b16a99Marek Olšák pipe->render_condition(pipe, st->render_condition, 6118d45bbc4221d83bc2bfd0295f56b0f6d35b16a99Marek Olšák st->condition_mode); 6128d45bbc4221d83bc2bfd0295f56b0f6d35b16a99Marek Olšák } 6138d45bbc4221d83bc2bfd0295f56b0f6d35b16a99Marek Olšák 61451b339af2e8b80575a24bb9146f031c9605180bbBrian Paul /* map the dst_surface so we can read from it */ 6153e06803c2c6cf83009708b23d3ebafc0ea3dc525Brian Paul tex_xfer = pipe_get_transfer(pipe, 6164c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger dst_texture, 0, 0, 6174c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger PIPE_TRANSFER_READ, 6184c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger 0, 0, width, height); 61951b339af2e8b80575a24bb9146f031c9605180bbBrian Paul 6201b448c7a5cafa68eeead2a4c45f4362a9883383bBrian Paul pixels = _mesa_map_pbo_dest(ctx, &ctx->Pack, pixels); 62151b339af2e8b80575a24bb9146f031c9605180bbBrian Paul 6227b24e58a0ca571d6230ef5076ea352253b81fe6eBrian Paul /* copy/pack data into user buffer */ 623c9d0526084e87799f11bdb7322f257b88f1033c4Brian Paul if (_mesa_format_matches_format_and_type(stImage->base.TexFormat, 624c9d0526084e87799f11bdb7322f257b88f1033c4Brian Paul format, type, 625c9d0526084e87799f11bdb7322f257b88f1033c4Brian Paul ctx->Pack.SwapBytes)) { 6267b24e58a0ca571d6230ef5076ea352253b81fe6eBrian Paul /* memcpy */ 627b1ed72ebe2599ec178f51d86fd42f26486b9a19bMichal Krol const uint bytesPerRow = width * util_format_get_blocksize(stImage->pt->format); 628287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell ubyte *map = pipe_transfer_map(pipe, tex_xfer); 6297b24e58a0ca571d6230ef5076ea352253b81fe6eBrian Paul GLuint row; 6307b24e58a0ca571d6230ef5076ea352253b81fe6eBrian Paul for (row = 0; row < height; row++) { 6317b24e58a0ca571d6230ef5076ea352253b81fe6eBrian Paul GLvoid *dest = _mesa_image_address2d(&ctx->Pack, pixels, width, 6327b24e58a0ca571d6230ef5076ea352253b81fe6eBrian Paul height, format, type, row, 0); 6337b24e58a0ca571d6230ef5076ea352253b81fe6eBrian Paul memcpy(dest, map, bytesPerRow); 6347b24e58a0ca571d6230ef5076ea352253b81fe6eBrian Paul map += tex_xfer->stride; 6357b24e58a0ca571d6230ef5076ea352253b81fe6eBrian Paul } 636287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell pipe_transfer_unmap(pipe, tex_xfer); 63751b339af2e8b80575a24bb9146f031c9605180bbBrian Paul } 6387b24e58a0ca571d6230ef5076ea352253b81fe6eBrian Paul else { 6397b24e58a0ca571d6230ef5076ea352253b81fe6eBrian Paul /* format translation via floats */ 6407b24e58a0ca571d6230ef5076ea352253b81fe6eBrian Paul GLuint row; 64119789e403ca3d0171d18f3c862738225902315e9Andre Maasikas enum pipe_format pformat = util_format_linear(dst_texture->format); 6423e88e432244336518e1bbcf303ee53eae4df2a02Brian Paul GLfloat *rgba; 6433e88e432244336518e1bbcf303ee53eae4df2a02Brian Paul 6443e88e432244336518e1bbcf303ee53eae4df2a02Brian Paul rgba = (GLfloat *) malloc(width * 4 * sizeof(GLfloat)); 6453e88e432244336518e1bbcf303ee53eae4df2a02Brian Paul if (!rgba) { 6463e88e432244336518e1bbcf303ee53eae4df2a02Brian Paul _mesa_error(ctx, GL_OUT_OF_MEMORY, "glGetTexImage()"); 6473e88e432244336518e1bbcf303ee53eae4df2a02Brian Paul goto end; 6483e88e432244336518e1bbcf303ee53eae4df2a02Brian Paul } 6493e88e432244336518e1bbcf303ee53eae4df2a02Brian Paul 6507b24e58a0ca571d6230ef5076ea352253b81fe6eBrian Paul for (row = 0; row < height; row++) { 6517b24e58a0ca571d6230ef5076ea352253b81fe6eBrian Paul const GLbitfield transferOps = 0x0; /* bypassed for glGetTexImage() */ 6527b24e58a0ca571d6230ef5076ea352253b81fe6eBrian Paul GLvoid *dest = _mesa_image_address2d(&ctx->Pack, pixels, width, 6537b24e58a0ca571d6230ef5076ea352253b81fe6eBrian Paul height, format, type, row, 0); 6547b24e58a0ca571d6230ef5076ea352253b81fe6eBrian Paul 655b02ef740b90029bc40629e5b81270a8cf77101d3Keith Whitwell if (ST_DEBUG & DEBUG_FALLBACK) 656b02ef740b90029bc40629e5b81270a8cf77101d3Keith Whitwell debug_printf("%s: fallback format translation\n", __FUNCTION__); 657b02ef740b90029bc40629e5b81270a8cf77101d3Keith Whitwell 6587b24e58a0ca571d6230ef5076ea352253b81fe6eBrian Paul /* get float[4] rgba row from surface */ 6599d380f487a4f2628594821a4fed5fe587ce52031Brian Paul pipe_get_tile_rgba_format(pipe, tex_xfer, 0, row, width, 1, 66019789e403ca3d0171d18f3c862738225902315e9Andre Maasikas pformat, rgba); 6617b24e58a0ca571d6230ef5076ea352253b81fe6eBrian Paul 6627b24e58a0ca571d6230ef5076ea352253b81fe6eBrian Paul _mesa_pack_rgba_span_float(ctx, width, (GLfloat (*)[4]) rgba, format, 6637b24e58a0ca571d6230ef5076ea352253b81fe6eBrian Paul type, dest, &ctx->Pack, transferOps); 6647b24e58a0ca571d6230ef5076ea352253b81fe6eBrian Paul } 6653e88e432244336518e1bbcf303ee53eae4df2a02Brian Paul 6663e88e432244336518e1bbcf303ee53eae4df2a02Brian Paul free(rgba); 6677b24e58a0ca571d6230ef5076ea352253b81fe6eBrian Paul } 6687b24e58a0ca571d6230ef5076ea352253b81fe6eBrian Paul 6693e88e432244336518e1bbcf303ee53eae4df2a02Brian Paulend: 6701b448c7a5cafa68eeead2a4c45f4362a9883383bBrian Paul _mesa_unmap_pbo_dest(ctx, &ctx->Pack); 67151b339af2e8b80575a24bb9146f031c9605180bbBrian Paul 672287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell pipe->transfer_destroy(pipe, tex_xfer); 67363af29bfbe265318bcf5be69e420de361b900321Keith Whitwell 67451b339af2e8b80575a24bb9146f031c9605180bbBrian Paul /* destroy the temp / dest surface */ 67551b339af2e8b80575a24bb9146f031c9605180bbBrian Paul util_destroy_rgba_surface(dst_texture, dst_surface); 6760315cb9f8f3ec38fa9594860754fb53a67cf4c23Brian Paul 6776835103878afd27a1d66d29d16cbfb0b1e894a94Brian Paul pipe_sampler_view_release(pipe, &src_view); 67851b339af2e8b80575a24bb9146f031c9605180bbBrian Paul} 67951b339af2e8b80575a24bb9146f031c9605180bbBrian Paul 68051b339af2e8b80575a24bb9146f031c9605180bbBrian Paul 68151b339af2e8b80575a24bb9146f031c9605180bbBrian Paul 68224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian/** 6831a867385d56022e904ef0235cbed545057fcb998Brian Paul * Called via ctx->Driver.GetTexImage() 68424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 68524df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void 6864368a657670f1f3f13d8497f749cb5439f91529eBrian Paulst_GetTexImage(struct gl_context * ctx, 6878df7ca71125ee0ad74260378ff7e185dcf66f3bcBrian Paul GLenum format, GLenum type, GLvoid * pixels, 6888df7ca71125ee0ad74260378ff7e185dcf66f3bcBrian Paul struct gl_texture_image *texImage) 68924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 69024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian struct st_texture_image *stImage = st_texture_image(texImage); 69124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 6928df7ca71125ee0ad74260378ff7e185dcf66f3bcBrian Paul if (stImage->pt && util_format_is_s3tc(stImage->pt->format)) { 69351b339af2e8b80575a24bb9146f031c9605180bbBrian Paul /* Need to decompress the texture. 6941a867385d56022e904ef0235cbed545057fcb998Brian Paul * We'll do this by rendering a textured quad (which is hopefully 695068fcc029d58f97a7bdbaa01fdbafacbb37e9d68Brian Paul * faster than using the fallback code in texcompress.c). 69651b339af2e8b80575a24bb9146f031c9605180bbBrian Paul * Note that we only expect RGBA formats (no Z/depth formats). 69751b339af2e8b80575a24bb9146f031c9605180bbBrian Paul */ 6984368a657670f1f3f13d8497f749cb5439f91529eBrian Paul decompress_with_blit(ctx, format, type, pixels, texImage); 69951b339af2e8b80575a24bb9146f031c9605180bbBrian Paul } 7001a867385d56022e904ef0235cbed545057fcb998Brian Paul else { 7014368a657670f1f3f13d8497f749cb5439f91529eBrian Paul _mesa_get_teximage(ctx, format, type, pixels, texImage); 70224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 70324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 70424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 70524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 70624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian/** 7075facd7986ace899673499f396897469720476799Brian Paul * Do a CopyTexSubImage operation using a read transfer from the source, 7085facd7986ace899673499f396897469720476799Brian Paul * a write transfer to the destination and get_tile()/put_tile() to access 7095facd7986ace899673499f396897469720476799Brian Paul * the pixels/texels. 710c6717a86420d7141013165f7acd50b3c3f751756Brian * 711c6717a86420d7141013165f7acd50b3c3f751756Brian * Note: srcY=0=TOP of renderbuffer 712038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian */ 713038cb561eb094af2f2ba06e18e61246fc0c87c3cBrianstatic void 71456b57aa360a8bad0c4b68fbdf7c64ac33f9e7661Brian Paulfallback_copy_texsubimage(struct gl_context *ctx, 715038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian struct st_renderbuffer *strb, 716038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian struct st_texture_image *stImage, 717038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian GLenum baseFormat, 718038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian GLint destX, GLint destY, GLint destZ, 719038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian GLint srcX, GLint srcY, 720038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian GLsizei width, GLsizei height) 721038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian{ 72276c7ad2e7d387feefe58dc2116b613fe11a8b273Brian Paul struct st_context *st = st_context(ctx); 72376c7ad2e7d387feefe58dc2116b613fe11a8b273Brian Paul struct pipe_context *pipe = st->pipe; 7244617981ec72f7985941bee4b03c534d97ff96bc6Michel Dänzer struct pipe_transfer *src_trans; 7254617981ec72f7985941bee4b03c534d97ff96bc6Michel Dänzer GLvoid *texDest; 72671633abafc935c25da9731bab48c228ceb9b4097Michel Dänzer enum pipe_transfer_usage transfer_usage; 7274c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger 728b02ef740b90029bc40629e5b81270a8cf77101d3Keith Whitwell if (ST_DEBUG & DEBUG_FALLBACK) 729b02ef740b90029bc40629e5b81270a8cf77101d3Keith Whitwell debug_printf("%s: fallback processing\n", __FUNCTION__); 7304617981ec72f7985941bee4b03c534d97ff96bc6Michel Dänzer 7314617981ec72f7985941bee4b03c534d97ff96bc6Michel Dänzer if (st_fb_orientation(ctx->ReadBuffer) == Y_0_TOP) { 7327c8836e9ef49d938aa55a1c385b95c6371c301f1Michel Dänzer srcY = strb->Base.Height - srcY - height; 7334617981ec72f7985941bee4b03c534d97ff96bc6Michel Dänzer } 734f3048ad90ed2e4583f0f7aaf35a0f4aa581942ddBrian Paul 7353e06803c2c6cf83009708b23d3ebafc0ea3dc525Brian Paul src_trans = pipe_get_transfer(pipe, 7364c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger strb->texture, 73709e71cf7228232aa203915c9248c79cf26c5b917Brian Paul strb->rtt_level, 73809e71cf7228232aa203915c9248c79cf26c5b917Brian Paul strb->rtt_face + strb->rtt_slice, 7394c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger PIPE_TRANSFER_READ, 7404c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger srcX, srcY, 7414c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger width, height); 742038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian 7430197348641614188c400d7c616573bb7f1eea781Brian Paul if ((baseFormat == GL_DEPTH_COMPONENT || 7440197348641614188c400d7c616573bb7f1eea781Brian Paul baseFormat == GL_DEPTH_STENCIL) && 7450bed834be4a174d20b31a6cbcf066774bf749929Michal Krol util_format_is_depth_and_stencil(stImage->pt->format)) 74671633abafc935c25da9731bab48c228ceb9b4097Michel Dänzer transfer_usage = PIPE_TRANSFER_READ_WRITE; 74771633abafc935c25da9731bab48c228ceb9b4097Michel Dänzer else 74871633abafc935c25da9731bab48c228ceb9b4097Michel Dänzer transfer_usage = PIPE_TRANSFER_WRITE; 74971633abafc935c25da9731bab48c228ceb9b4097Michel Dänzer 7504c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger /* XXX this used to ignore destZ param */ 7514c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger texDest = st_texture_image_map(st, stImage, destZ, transfer_usage, 7524617981ec72f7985941bee4b03c534d97ff96bc6Michel Dänzer destX, destY, width, height); 753038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian 754105758105a790dd8466c6be8c232c3f215ca4deeBrian Paul if (baseFormat == GL_DEPTH_COMPONENT || 7550197348641614188c400d7c616573bb7f1eea781Brian Paul baseFormat == GL_DEPTH_STENCIL) { 756cc94863429d8a6cef8dbf861e78701a458d30f5aBrian Paul const GLboolean scaleOrBias = (ctx->Pixel.DepthScale != 1.0F || 757cc94863429d8a6cef8dbf861e78701a458d30f5aBrian Paul ctx->Pixel.DepthBias != 0.0F); 75827858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul GLint row, yStep; 7593e88e432244336518e1bbcf303ee53eae4df2a02Brian Paul uint *data; 760cc94863429d8a6cef8dbf861e78701a458d30f5aBrian Paul 76127858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul /* determine bottom-to-top vs. top-to-bottom order for src buffer */ 76227858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul if (st_fb_orientation(ctx->ReadBuffer) == Y_0_TOP) { 7637c8836e9ef49d938aa55a1c385b95c6371c301f1Michel Dänzer srcY = height - 1; 76427858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul yStep = -1; 76527858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul } 76627858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul else { 7674617981ec72f7985941bee4b03c534d97ff96bc6Michel Dänzer srcY = 0; 76827858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul yStep = 1; 76927858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul } 77027858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul 7713e88e432244336518e1bbcf303ee53eae4df2a02Brian Paul data = (uint *) malloc(width * sizeof(uint)); 7723e88e432244336518e1bbcf303ee53eae4df2a02Brian Paul 7733e88e432244336518e1bbcf303ee53eae4df2a02Brian Paul if (data) { 7743e88e432244336518e1bbcf303ee53eae4df2a02Brian Paul /* To avoid a large temp memory allocation, do copy row by row */ 7753e88e432244336518e1bbcf303ee53eae4df2a02Brian Paul for (row = 0; row < height; row++, srcY += yStep) { 7763e88e432244336518e1bbcf303ee53eae4df2a02Brian Paul pipe_get_tile_z(pipe, src_trans, 0, srcY, width, 1, data); 7773e88e432244336518e1bbcf303ee53eae4df2a02Brian Paul if (scaleOrBias) { 7783e88e432244336518e1bbcf303ee53eae4df2a02Brian Paul _mesa_scale_and_bias_depth_uint(ctx, width, data); 7793e88e432244336518e1bbcf303ee53eae4df2a02Brian Paul } 7803e88e432244336518e1bbcf303ee53eae4df2a02Brian Paul pipe_put_tile_z(pipe, stImage->transfer, 0, row, width, 1, data); 781cc94863429d8a6cef8dbf861e78701a458d30f5aBrian Paul } 782cc94863429d8a6cef8dbf861e78701a458d30f5aBrian Paul } 7833e88e432244336518e1bbcf303ee53eae4df2a02Brian Paul else { 7843e88e432244336518e1bbcf303ee53eae4df2a02Brian Paul _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexSubImage()"); 7853e88e432244336518e1bbcf303ee53eae4df2a02Brian Paul } 7863e88e432244336518e1bbcf303ee53eae4df2a02Brian Paul 7873e88e432244336518e1bbcf303ee53eae4df2a02Brian Paul free(data); 788cc94863429d8a6cef8dbf861e78701a458d30f5aBrian Paul } 789cc94863429d8a6cef8dbf861e78701a458d30f5aBrian Paul else { 790cc94863429d8a6cef8dbf861e78701a458d30f5aBrian Paul /* RGBA format */ 79127858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul GLfloat *tempSrc = 79232f2fd1c5d6088692551c80352b7d6fa35b0cd09Kristian Høgsberg (GLfloat *) malloc(width * height * 4 * sizeof(GLfloat)); 79327858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul 79427858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul if (tempSrc && texDest) { 79527858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul const GLint dims = 2; 7965facd7986ace899673499f396897469720476799Brian Paul const GLint dstRowStride = stImage->transfer->stride; 79727858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul struct gl_texture_image *texImage = &stImage->base; 79827858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul struct gl_pixelstore_attrib unpack = ctx->DefaultPacking; 79927858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul 80027858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul if (st_fb_orientation(ctx->ReadBuffer) == Y_0_TOP) { 80127858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul unpack.Invert = GL_TRUE; 802cc94863429d8a6cef8dbf861e78701a458d30f5aBrian Paul } 80327858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul 80427858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul /* get float/RGBA image from framebuffer */ 80527858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul /* XXX this usually involves a lot of int/float conversion. 80627858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul * try to avoid that someday. 80727858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul */ 8089d380f487a4f2628594821a4fed5fe587ce52031Brian Paul pipe_get_tile_rgba_format(pipe, src_trans, 0, 0, width, height, 8099d380f487a4f2628594821a4fed5fe587ce52031Brian Paul util_format_linear(strb->texture->format), 8109d380f487a4f2628594821a4fed5fe587ce52031Brian Paul tempSrc); 81127858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul 81227858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul /* Store into texture memory. 81327858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul * Note that this does some special things such as pixel transfer 81427858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul * ops and format conversion. In particular, if the dest tex format 81527858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul * is actually RGBA but the user created the texture as GL_RGB we 81627858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul * need to fill-in/override the alpha channel with 1.0. 81727858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul */ 8186480210b89dc8ae0990c450d27870c7b7930f251Brian Paul _mesa_texstore(ctx, dims, 8196480210b89dc8ae0990c450d27870c7b7930f251Brian Paul texImage->_BaseFormat, 8206480210b89dc8ae0990c450d27870c7b7930f251Brian Paul texImage->TexFormat, 8216480210b89dc8ae0990c450d27870c7b7930f251Brian Paul dstRowStride, 8225253cf98057dad54e25b4b8c36f8cf24f559314cBrian Paul (GLubyte **) &texDest, 8236480210b89dc8ae0990c450d27870c7b7930f251Brian Paul width, height, 1, 8246480210b89dc8ae0990c450d27870c7b7930f251Brian Paul GL_RGBA, GL_FLOAT, tempSrc, /* src */ 8256480210b89dc8ae0990c450d27870c7b7930f251Brian Paul &unpack); 82627858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul } 82727858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul else { 82827858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage"); 8295c83f1371978472fbe4bba8f686733c6b519874aBrian } 83027858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul 83127858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul if (tempSrc) 83232f2fd1c5d6088692551c80352b7d6fa35b0cd09Kristian Høgsberg free(tempSrc); 8335c83f1371978472fbe4bba8f686733c6b519874aBrian } 834d0279fc4b38c72356a341173317bcd45d9093f45Michel Dänzer 83576c7ad2e7d387feefe58dc2116b613fe11a8b273Brian Paul st_texture_image_unmap(st, stImage); 836287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell pipe->transfer_destroy(pipe, src_trans); 837038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian} 838038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian 839038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian 84065d2a266375cf32fd90c7fb77fb87993d3a652eaBrian Paul 84165d2a266375cf32fd90c7fb77fb87993d3a652eaBrian Paul/** 84265d2a266375cf32fd90c7fb77fb87993d3a652eaBrian Paul * If the format of the src renderbuffer and the format of the dest 84365d2a266375cf32fd90c7fb77fb87993d3a652eaBrian Paul * texture are compatible (in terms of blitting), return a TGSI writemask 84465d2a266375cf32fd90c7fb77fb87993d3a652eaBrian Paul * to be used during the blit. 84565d2a266375cf32fd90c7fb77fb87993d3a652eaBrian Paul * If the src/dest are incompatible, return 0. 84665d2a266375cf32fd90c7fb77fb87993d3a652eaBrian Paul */ 8478fc945cd847aa5d343a5f76eb2f9f2c9075cccddKeith Whitwellstatic unsigned 848f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergcompatible_src_dst_formats(struct gl_context *ctx, 84965d2a266375cf32fd90c7fb77fb87993d3a652eaBrian Paul const struct gl_renderbuffer *src, 8508fc945cd847aa5d343a5f76eb2f9f2c9075cccddKeith Whitwell const struct gl_texture_image *dst) 8518fc945cd847aa5d343a5f76eb2f9f2c9075cccddKeith Whitwell{ 85265d2a266375cf32fd90c7fb77fb87993d3a652eaBrian Paul /* Get logical base formats for the src and dest. 85365d2a266375cf32fd90c7fb77fb87993d3a652eaBrian Paul * That is, use the user-requested formats and not the actual, device- 85465d2a266375cf32fd90c7fb77fb87993d3a652eaBrian Paul * chosen formats. 85565d2a266375cf32fd90c7fb77fb87993d3a652eaBrian Paul * For example, the user may have requested an A8 texture but the 85665d2a266375cf32fd90c7fb77fb87993d3a652eaBrian Paul * driver may actually be using an RGBA texture format. When we 85765d2a266375cf32fd90c7fb77fb87993d3a652eaBrian Paul * copy/blit to that texture, we only want to copy the Alpha channel 85865d2a266375cf32fd90c7fb77fb87993d3a652eaBrian Paul * and not the RGB channels. 85965d2a266375cf32fd90c7fb77fb87993d3a652eaBrian Paul * 86065d2a266375cf32fd90c7fb77fb87993d3a652eaBrian Paul * Similarly, when the src FBO was created an RGB format may have been 86165d2a266375cf32fd90c7fb77fb87993d3a652eaBrian Paul * requested but the driver actually chose an RGBA format. In that case, 86265d2a266375cf32fd90c7fb77fb87993d3a652eaBrian Paul * we don't want to copy the undefined Alpha channel to the dest texture 86365d2a266375cf32fd90c7fb77fb87993d3a652eaBrian Paul * (it should be 1.0). 86465d2a266375cf32fd90c7fb77fb87993d3a652eaBrian Paul */ 86565d2a266375cf32fd90c7fb77fb87993d3a652eaBrian Paul const GLenum srcFormat = _mesa_base_fbo_format(ctx, src->InternalFormat); 86665d2a266375cf32fd90c7fb77fb87993d3a652eaBrian Paul const GLenum dstFormat = _mesa_base_tex_format(ctx, dst->InternalFormat); 8678fc945cd847aa5d343a5f76eb2f9f2c9075cccddKeith Whitwell 86865d2a266375cf32fd90c7fb77fb87993d3a652eaBrian Paul /** 86965d2a266375cf32fd90c7fb77fb87993d3a652eaBrian Paul * XXX when we have red-only and red/green renderbuffers we'll need 87065d2a266375cf32fd90c7fb77fb87993d3a652eaBrian Paul * to add more cases here (or implement a general-purpose routine that 87165d2a266375cf32fd90c7fb77fb87993d3a652eaBrian Paul * queries the existance of the R,G,B,A channels in the src and dest). 87265d2a266375cf32fd90c7fb77fb87993d3a652eaBrian Paul */ 87365d2a266375cf32fd90c7fb77fb87993d3a652eaBrian Paul if (srcFormat == dstFormat) { 8748fc945cd847aa5d343a5f76eb2f9f2c9075cccddKeith Whitwell /* This is the same as matching_base_formats, which should 8758fc945cd847aa5d343a5f76eb2f9f2c9075cccddKeith Whitwell * always pass, as it did previously. 8768fc945cd847aa5d343a5f76eb2f9f2c9075cccddKeith Whitwell */ 8778fc945cd847aa5d343a5f76eb2f9f2c9075cccddKeith Whitwell return TGSI_WRITEMASK_XYZW; 8788fc945cd847aa5d343a5f76eb2f9f2c9075cccddKeith Whitwell } 87965d2a266375cf32fd90c7fb77fb87993d3a652eaBrian Paul else if (srcFormat == GL_RGB && dstFormat == GL_RGBA) { 88065d2a266375cf32fd90c7fb77fb87993d3a652eaBrian Paul /* Make sure that A in the dest is 1. The actual src format 88165d2a266375cf32fd90c7fb77fb87993d3a652eaBrian Paul * may be RGBA and have undefined A values. 88265d2a266375cf32fd90c7fb77fb87993d3a652eaBrian Paul */ 88365d2a266375cf32fd90c7fb77fb87993d3a652eaBrian Paul return TGSI_WRITEMASK_XYZ; 88465d2a266375cf32fd90c7fb77fb87993d3a652eaBrian Paul } 88565d2a266375cf32fd90c7fb77fb87993d3a652eaBrian Paul else if (srcFormat == GL_RGBA && dstFormat == GL_RGB) { 88665d2a266375cf32fd90c7fb77fb87993d3a652eaBrian Paul /* Make sure that A in the dest is 1. The actual dst format 88765d2a266375cf32fd90c7fb77fb87993d3a652eaBrian Paul * may be RGBA and will need A=1 to provide proper alpha values 88865d2a266375cf32fd90c7fb77fb87993d3a652eaBrian Paul * when sampled later. 8898fc945cd847aa5d343a5f76eb2f9f2c9075cccddKeith Whitwell */ 89065d2a266375cf32fd90c7fb77fb87993d3a652eaBrian Paul return TGSI_WRITEMASK_XYZ; 8918fc945cd847aa5d343a5f76eb2f9f2c9075cccddKeith Whitwell } 8928fc945cd847aa5d343a5f76eb2f9f2c9075cccddKeith Whitwell else { 893b02ef740b90029bc40629e5b81270a8cf77101d3Keith Whitwell if (ST_DEBUG & DEBUG_FALLBACK) 894b02ef740b90029bc40629e5b81270a8cf77101d3Keith Whitwell debug_printf("%s failed for src %s, dst %s\n", 895b02ef740b90029bc40629e5b81270a8cf77101d3Keith Whitwell __FUNCTION__, 896b02ef740b90029bc40629e5b81270a8cf77101d3Keith Whitwell _mesa_lookup_enum_by_nr(srcFormat), 89765d2a266375cf32fd90c7fb77fb87993d3a652eaBrian Paul _mesa_lookup_enum_by_nr(dstFormat)); 898b02ef740b90029bc40629e5b81270a8cf77101d3Keith Whitwell 8998fc945cd847aa5d343a5f76eb2f9f2c9075cccddKeith Whitwell /* Otherwise fail. 9008fc945cd847aa5d343a5f76eb2f9f2c9075cccddKeith Whitwell */ 9018fc945cd847aa5d343a5f76eb2f9f2c9075cccddKeith Whitwell return 0; 9028fc945cd847aa5d343a5f76eb2f9f2c9075cccddKeith Whitwell } 9038fc945cd847aa5d343a5f76eb2f9f2c9075cccddKeith Whitwell} 9048fc945cd847aa5d343a5f76eb2f9f2c9075cccddKeith Whitwell 9058fc945cd847aa5d343a5f76eb2f9f2c9075cccddKeith Whitwell 9068fc945cd847aa5d343a5f76eb2f9f2c9075cccddKeith Whitwell 907038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian/** 9084e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul * Do a CopyTex[Sub]Image1/2/3D() using a hardware (blit) path if possible. 9094e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul * Note that the region to copy has already been clipped so we know we 9104e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul * won't read from outside the source renderbuffer's bounds. 911c6717a86420d7141013165f7acd50b3c3f751756Brian * 9124e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul * Note: srcY=0=Bottom of renderbuffer (GL convention) 91324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 914038cb561eb094af2f2ba06e18e61246fc0c87c3cBrianstatic void 915cd9ab2584f5e2a5eb0e96a948e6aedc9a33c886dBrian Paulst_CopyTexSubImage(struct gl_context *ctx, GLuint dims, 916cd9ab2584f5e2a5eb0e96a948e6aedc9a33c886dBrian Paul struct gl_texture_image *texImage, 917cd9ab2584f5e2a5eb0e96a948e6aedc9a33c886dBrian Paul GLint destX, GLint destY, GLint destZ, 918cd9ab2584f5e2a5eb0e96a948e6aedc9a33c886dBrian Paul struct gl_renderbuffer *rb, 919cd9ab2584f5e2a5eb0e96a948e6aedc9a33c886dBrian Paul GLint srcX, GLint srcY, GLsizei width, GLsizei height) 92024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 921038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian struct st_texture_image *stImage = st_texture_image(texImage); 9220197348641614188c400d7c616573bb7f1eea781Brian Paul const GLenum texBaseFormat = texImage->_BaseFormat; 923b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian struct gl_framebuffer *fb = ctx->ReadBuffer; 924b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian struct st_renderbuffer *strb; 92576c7ad2e7d387feefe58dc2116b613fe11a8b273Brian Paul struct st_context *st = st_context(ctx); 92676c7ad2e7d387feefe58dc2116b613fe11a8b273Brian Paul struct pipe_context *pipe = st->pipe; 9276f715dcc219071e574e363a9db4365c9c31ebbd3Brian struct pipe_screen *screen = pipe->screen; 92827858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul enum pipe_format dest_format, src_format; 92927858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul GLboolean matching_base_formats; 9305ba15d8d38d98cb7b625fa55e7d818ef9c6629ceMarek Olšák GLuint color_writemask, zs_writemask, sample_count; 9318fc945cd847aa5d343a5f76eb2f9f2c9075cccddKeith Whitwell struct pipe_surface *dest_surface = NULL; 9328fc945cd847aa5d343a5f76eb2f9f2c9075cccddKeith Whitwell GLboolean do_flip = (st_fb_orientation(ctx->ReadBuffer) == Y_0_TOP); 933d9582026631ae3cd667f6cd13040b93e42db3e44Henri Verbeet struct pipe_surface surf_tmpl; 934d9582026631ae3cd667f6cd13040b93e42db3e44Henri Verbeet unsigned int dst_usage; 935d9582026631ae3cd667f6cd13040b93e42db3e44Henri Verbeet GLint srcY0, srcY1; 93624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 937afd16512bc354cf1a7220cb9bf3ce445503c7af4Keith Whitwell /* make sure finalize_textures has been called? 938afd16512bc354cf1a7220cb9bf3ce445503c7af4Keith Whitwell */ 93976c7ad2e7d387feefe58dc2116b613fe11a8b273Brian Paul if (0) st_validate_state(st); 940afd16512bc354cf1a7220cb9bf3ce445503c7af4Keith Whitwell 941b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian /* determine if copying depth or color data */ 942105758105a790dd8466c6be8c232c3f215ca4deeBrian Paul if (texBaseFormat == GL_DEPTH_COMPONENT || 9430197348641614188c400d7c616573bb7f1eea781Brian Paul texBaseFormat == GL_DEPTH_STENCIL) { 94402d12719e356ee9e3348db67ae55ae790dad058fBrian Paul strb = st_renderbuffer(fb->Attachment[BUFFER_DEPTH].Renderbuffer); 94524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 946b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian else { 9474e070f10c0a2af8a563eadf7fdb09b11d9067a99Brian Paul /* texBaseFormat == GL_RGB, GL_RGBA, GL_ALPHA, etc */ 948b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian strb = st_renderbuffer(fb->_ColorReadBuffer); 949b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian } 950b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian 951afd16512bc354cf1a7220cb9bf3ce445503c7af4Keith Whitwell if (!strb || !strb->surface || !stImage->pt) { 952afd16512bc354cf1a7220cb9bf3ce445503c7af4Keith Whitwell debug_printf("%s: null strb or stImage\n", __FUNCTION__); 953afd16512bc354cf1a7220cb9bf3ce445503c7af4Keith Whitwell return; 954afd16512bc354cf1a7220cb9bf3ce445503c7af4Keith Whitwell } 955afd16512bc354cf1a7220cb9bf3ce445503c7af4Keith Whitwell 956127328bfadaa5f080730fd41f404f1bc74f490d3Roland Scheidegger sample_count = strb->surface->texture->nr_samples; 957127328bfadaa5f080730fd41f404f1bc74f490d3Roland Scheidegger /* I believe this would be legal, presumably would need to do a resolve 958127328bfadaa5f080730fd41f404f1bc74f490d3Roland Scheidegger for color, and for depth/stencil spec says to just use one of the 959127328bfadaa5f080730fd41f404f1bc74f490d3Roland Scheidegger depth/stencil samples per pixel? Need some transfer clarifications. */ 960127328bfadaa5f080730fd41f404f1bc74f490d3Roland Scheidegger assert(sample_count < 2); 961127328bfadaa5f080730fd41f404f1bc74f490d3Roland Scheidegger 962b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian assert(strb); 963b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian assert(strb->surface); 964753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer assert(stImage->pt); 965c6717a86420d7141013165f7acd50b3c3f751756Brian 966b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian src_format = strb->surface->format; 967753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer dest_format = stImage->pt->format; 968b27498c7cad7dae4e3b3ef9517b9c0aef58f73f6Brian 96927858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul /* 97027858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul * Determine if the src framebuffer and dest texture have the same 97127858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul * base format. We need this to detect a case such as the framebuffer 97227858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul * being GL_RGBA but the texture being GL_RGB. If the actual hardware 97327858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul * texture format stores RGBA we need to set A=1 (overriding the 97427858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul * framebuffer's alpha values). We can't do that with the blit or 97527858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul * textured-quad paths. 97627858226dc4eb3e64d980ba8530c2fd2e39218cfBrian Paul */ 97745e76d2665b38ba3787548310efc59e969124c01Brian Paul matching_base_formats = 97845e76d2665b38ba3787548310efc59e969124c01Brian Paul (_mesa_get_format_base_format(strb->Base.Format) == 97945e76d2665b38ba3787548310efc59e969124c01Brian Paul _mesa_get_format_base_format(texImage->TexFormat)); 980127328bfadaa5f080730fd41f404f1bc74f490d3Roland Scheidegger 981d9582026631ae3cd667f6cd13040b93e42db3e44Henri Verbeet if (ctx->_ImageTransferState) { 982d9582026631ae3cd667f6cd13040b93e42db3e44Henri Verbeet goto fallback; 983d9582026631ae3cd667f6cd13040b93e42db3e44Henri Verbeet } 98491e56c88972448079b5aafbc2b876d0ea0e28a39Marek Olšák 985a971476cc7913edde1944f33f164cd507199e1ddBrian Paul if (texImage->TexObject->Target == GL_TEXTURE_1D_ARRAY) { 986a971476cc7913edde1944f33f164cd507199e1ddBrian Paul /* 1D arrays might be thought of as 2D images but the actual layout 987a971476cc7913edde1944f33f164cd507199e1ddBrian Paul * might not be that way. At some points, we convert OpenGL's 1D 988a971476cc7913edde1944f33f164cd507199e1ddBrian Paul * array 'height' into gallium 'layers' and that prevents the blit 989a971476cc7913edde1944f33f164cd507199e1ddBrian Paul * utility code from doing the right thing. Simpy use the memcpy-based 990a971476cc7913edde1944f33f164cd507199e1ddBrian Paul * fallback. 991a971476cc7913edde1944f33f164cd507199e1ddBrian Paul */ 992a971476cc7913edde1944f33f164cd507199e1ddBrian Paul goto fallback; 993a971476cc7913edde1944f33f164cd507199e1ddBrian Paul } 994a971476cc7913edde1944f33f164cd507199e1ddBrian Paul 995d9582026631ae3cd667f6cd13040b93e42db3e44Henri Verbeet if (matching_base_formats && 996d9582026631ae3cd667f6cd13040b93e42db3e44Henri Verbeet src_format == dest_format && 997d9582026631ae3cd667f6cd13040b93e42db3e44Henri Verbeet !do_flip) { 998d9582026631ae3cd667f6cd13040b93e42db3e44Henri Verbeet /* use surface_copy() / blit */ 999d9582026631ae3cd667f6cd13040b93e42db3e44Henri Verbeet struct pipe_box src_box; 10009b04abe36812a34ba447e5b1f8d8e44a10510820Brian Paul unsigned dstLevel; 10019b04abe36812a34ba447e5b1f8d8e44a10510820Brian Paul 1002d9582026631ae3cd667f6cd13040b93e42db3e44Henri Verbeet u_box_2d_zslice(srcX, srcY, strb->surface->u.tex.first_layer, 1003d9582026631ae3cd667f6cd13040b93e42db3e44Henri Verbeet width, height, &src_box); 1004d9582026631ae3cd667f6cd13040b93e42db3e44Henri Verbeet 10059b04abe36812a34ba447e5b1f8d8e44a10510820Brian Paul /* If stImage->pt is an independent image (not a pointer into a full 10069b04abe36812a34ba447e5b1f8d8e44a10510820Brian Paul * mipmap) stImage->pt.last_level will be zero and we need to use that 10079b04abe36812a34ba447e5b1f8d8e44a10510820Brian Paul * as the dest level. 10089b04abe36812a34ba447e5b1f8d8e44a10510820Brian Paul */ 10099b04abe36812a34ba447e5b1f8d8e44a10510820Brian Paul dstLevel = MIN2(stImage->base.Level, stImage->pt->last_level); 10109b04abe36812a34ba447e5b1f8d8e44a10510820Brian Paul 1011d9582026631ae3cd667f6cd13040b93e42db3e44Henri Verbeet /* for resource_copy_region(), y=0=top, always */ 1012d9582026631ae3cd667f6cd13040b93e42db3e44Henri Verbeet pipe->resource_copy_region(pipe, 1013d9582026631ae3cd667f6cd13040b93e42db3e44Henri Verbeet /* dest */ 1014d9582026631ae3cd667f6cd13040b93e42db3e44Henri Verbeet stImage->pt, 10159b04abe36812a34ba447e5b1f8d8e44a10510820Brian Paul dstLevel, 1016d9582026631ae3cd667f6cd13040b93e42db3e44Henri Verbeet destX, destY, destZ + stImage->base.Face, 1017d9582026631ae3cd667f6cd13040b93e42db3e44Henri Verbeet /* src */ 1018d9582026631ae3cd667f6cd13040b93e42db3e44Henri Verbeet strb->texture, 1019d9582026631ae3cd667f6cd13040b93e42db3e44Henri Verbeet strb->surface->u.tex.level, 1020d9582026631ae3cd667f6cd13040b93e42db3e44Henri Verbeet &src_box); 1021d9582026631ae3cd667f6cd13040b93e42db3e44Henri Verbeet return; 1022d9582026631ae3cd667f6cd13040b93e42db3e44Henri Verbeet } 102391e56c88972448079b5aafbc2b876d0ea0e28a39Marek Olšák 1024d9582026631ae3cd667f6cd13040b93e42db3e44Henri Verbeet if (texBaseFormat == GL_DEPTH_STENCIL) { 1025d9582026631ae3cd667f6cd13040b93e42db3e44Henri Verbeet goto fallback; 1026d9582026631ae3cd667f6cd13040b93e42db3e44Henri Verbeet } 1027d9582026631ae3cd667f6cd13040b93e42db3e44Henri Verbeet 1028d9582026631ae3cd667f6cd13040b93e42db3e44Henri Verbeet if (texBaseFormat == GL_DEPTH_COMPONENT) { 10295ba15d8d38d98cb7b625fa55e7d818ef9c6629ceMarek Olšák color_writemask = 0; 10305ba15d8d38d98cb7b625fa55e7d818ef9c6629ceMarek Olšák zs_writemask = BLIT_WRITEMASK_Z; 1031d9582026631ae3cd667f6cd13040b93e42db3e44Henri Verbeet dst_usage = PIPE_BIND_DEPTH_STENCIL; 1032d9582026631ae3cd667f6cd13040b93e42db3e44Henri Verbeet } 1033d9582026631ae3cd667f6cd13040b93e42db3e44Henri Verbeet else { 10345ba15d8d38d98cb7b625fa55e7d818ef9c6629ceMarek Olšák color_writemask = compatible_src_dst_formats(ctx, &strb->Base, texImage); 10355ba15d8d38d98cb7b625fa55e7d818ef9c6629ceMarek Olšák zs_writemask = 0; 1036d9582026631ae3cd667f6cd13040b93e42db3e44Henri Verbeet dst_usage = PIPE_BIND_RENDER_TARGET; 1037d9582026631ae3cd667f6cd13040b93e42db3e44Henri Verbeet } 103879931e38abc62286151121a3f59127e296144551Michel Dänzer 10395ba15d8d38d98cb7b625fa55e7d818ef9c6629ceMarek Olšák if ((!color_writemask && !zs_writemask) || 1040d9582026631ae3cd667f6cd13040b93e42db3e44Henri Verbeet !screen->is_format_supported(screen, src_format, 1041d9582026631ae3cd667f6cd13040b93e42db3e44Henri Verbeet PIPE_TEXTURE_2D, sample_count, 1042d9582026631ae3cd667f6cd13040b93e42db3e44Henri Verbeet PIPE_BIND_SAMPLER_VIEW) || 1043d9582026631ae3cd667f6cd13040b93e42db3e44Henri Verbeet !screen->is_format_supported(screen, dest_format, 1044d9582026631ae3cd667f6cd13040b93e42db3e44Henri Verbeet PIPE_TEXTURE_2D, 0, 1045d9582026631ae3cd667f6cd13040b93e42db3e44Henri Verbeet dst_usage)) { 1046d9582026631ae3cd667f6cd13040b93e42db3e44Henri Verbeet goto fallback; 1047038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian } 1048cc94863429d8a6cef8dbf861e78701a458d30f5aBrian Paul 1049d9582026631ae3cd667f6cd13040b93e42db3e44Henri Verbeet if (do_flip) { 1050d9582026631ae3cd667f6cd13040b93e42db3e44Henri Verbeet srcY1 = strb->Base.Height - srcY - height; 1051d9582026631ae3cd667f6cd13040b93e42db3e44Henri Verbeet srcY0 = srcY1 + height; 1052d9582026631ae3cd667f6cd13040b93e42db3e44Henri Verbeet } 1053d9582026631ae3cd667f6cd13040b93e42db3e44Henri Verbeet else { 1054d9582026631ae3cd667f6cd13040b93e42db3e44Henri Verbeet srcY0 = srcY; 1055d9582026631ae3cd667f6cd13040b93e42db3e44Henri Verbeet srcY1 = srcY0 + height; 1056d9582026631ae3cd667f6cd13040b93e42db3e44Henri Verbeet } 1057d9582026631ae3cd667f6cd13040b93e42db3e44Henri Verbeet 1058d9582026631ae3cd667f6cd13040b93e42db3e44Henri Verbeet /* Disable conditional rendering. */ 1059d9582026631ae3cd667f6cd13040b93e42db3e44Henri Verbeet if (st->render_condition) { 1060d9582026631ae3cd667f6cd13040b93e42db3e44Henri Verbeet pipe->render_condition(pipe, NULL, 0); 1061d9582026631ae3cd667f6cd13040b93e42db3e44Henri Verbeet } 1062d9582026631ae3cd667f6cd13040b93e42db3e44Henri Verbeet 1063d9582026631ae3cd667f6cd13040b93e42db3e44Henri Verbeet memset(&surf_tmpl, 0, sizeof(surf_tmpl)); 1064d9582026631ae3cd667f6cd13040b93e42db3e44Henri Verbeet surf_tmpl.format = util_format_linear(stImage->pt->format); 1065d9582026631ae3cd667f6cd13040b93e42db3e44Henri Verbeet surf_tmpl.usage = dst_usage; 1066d9582026631ae3cd667f6cd13040b93e42db3e44Henri Verbeet surf_tmpl.u.tex.level = stImage->base.Level; 1067d9582026631ae3cd667f6cd13040b93e42db3e44Henri Verbeet surf_tmpl.u.tex.first_layer = stImage->base.Face + destZ; 1068d9582026631ae3cd667f6cd13040b93e42db3e44Henri Verbeet surf_tmpl.u.tex.last_layer = stImage->base.Face + destZ; 1069d9582026631ae3cd667f6cd13040b93e42db3e44Henri Verbeet 1070d9582026631ae3cd667f6cd13040b93e42db3e44Henri Verbeet dest_surface = pipe->create_surface(pipe, stImage->pt, 1071d9582026631ae3cd667f6cd13040b93e42db3e44Henri Verbeet &surf_tmpl); 107224e0a2633512afa3208969520b9e29a8b974275dMarek Olšák util_blit_pixels(st->blit, 107324e0a2633512afa3208969520b9e29a8b974275dMarek Olšák strb->texture, 107424e0a2633512afa3208969520b9e29a8b974275dMarek Olšák strb->surface->u.tex.level, 107524e0a2633512afa3208969520b9e29a8b974275dMarek Olšák srcX, srcY0, 107624e0a2633512afa3208969520b9e29a8b974275dMarek Olšák srcX + width, srcY1, 107724e0a2633512afa3208969520b9e29a8b974275dMarek Olšák strb->surface->u.tex.first_layer, 107824e0a2633512afa3208969520b9e29a8b974275dMarek Olšák dest_surface, 107924e0a2633512afa3208969520b9e29a8b974275dMarek Olšák destX, destY, 108024e0a2633512afa3208969520b9e29a8b974275dMarek Olšák destX + width, destY + height, 108124e0a2633512afa3208969520b9e29a8b974275dMarek Olšák 0.0, PIPE_TEX_MIPFILTER_NEAREST, 10825ba15d8d38d98cb7b625fa55e7d818ef9c6629ceMarek Olšák color_writemask, zs_writemask); 1083d9582026631ae3cd667f6cd13040b93e42db3e44Henri Verbeet pipe_surface_reference(&dest_surface, NULL); 1084d9582026631ae3cd667f6cd13040b93e42db3e44Henri Verbeet 1085d9582026631ae3cd667f6cd13040b93e42db3e44Henri Verbeet /* Restore conditional rendering state. */ 1086d9582026631ae3cd667f6cd13040b93e42db3e44Henri Verbeet if (st->render_condition) { 1087d9582026631ae3cd667f6cd13040b93e42db3e44Henri Verbeet pipe->render_condition(pipe, st->render_condition, 1088d9582026631ae3cd667f6cd13040b93e42db3e44Henri Verbeet st->condition_mode); 1089d9582026631ae3cd667f6cd13040b93e42db3e44Henri Verbeet } 1090d9582026631ae3cd667f6cd13040b93e42db3e44Henri Verbeet 1091d9582026631ae3cd667f6cd13040b93e42db3e44Henri Verbeet return; 1092d9582026631ae3cd667f6cd13040b93e42db3e44Henri Verbeet 1093d9582026631ae3cd667f6cd13040b93e42db3e44Henri Verbeetfallback: 109429725470478ecc8efa9f74fd9f7bee33d34058dfBrian Paul /* software fallback */ 109556b57aa360a8bad0c4b68fbdf7c64ac33f9e7661Brian Paul fallback_copy_texsubimage(ctx, 109629725470478ecc8efa9f74fd9f7bee33d34058dfBrian Paul strb, stImage, texBaseFormat, 109729725470478ecc8efa9f74fd9f7bee33d34058dfBrian Paul destX, destY, destZ, 109829725470478ecc8efa9f74fd9f7bee33d34058dfBrian Paul srcX, srcY, width, height); 109924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 110024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 110124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 1102e648d4a1d1c0c5f70916e38366b863f0bec79a62Brian Paul/** 1103e648d4a1d1c0c5f70916e38366b863f0bec79a62Brian Paul * Copy image data from stImage into the texture object 'stObj' at level 1104e648d4a1d1c0c5f70916e38366b863f0bec79a62Brian Paul * 'dstLevel'. 1105e648d4a1d1c0c5f70916e38366b863f0bec79a62Brian Paul */ 110624df8f895fe8807aa2ba058e71bd40adfc01d21eBrianstatic void 1107753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzercopy_image_data_to_texture(struct st_context *st, 1108753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer struct st_texture_object *stObj, 11094da1cdf78fa3b954840650fa46cf72da5daf149fBrian GLuint dstLevel, 1110753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer struct st_texture_image *stImage) 111124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 1112e648d4a1d1c0c5f70916e38366b863f0bec79a62Brian Paul /* debug checks */ 1113e648d4a1d1c0c5f70916e38366b863f0bec79a62Brian Paul { 1114e648d4a1d1c0c5f70916e38366b863f0bec79a62Brian Paul const struct gl_texture_image *dstImage = 11156dbad425bc423eb7db7c99aab161955c7b4cdc4cBrian Paul stObj->base.Image[stImage->base.Face][dstLevel]; 1116e648d4a1d1c0c5f70916e38366b863f0bec79a62Brian Paul assert(dstImage); 1117e648d4a1d1c0c5f70916e38366b863f0bec79a62Brian Paul assert(dstImage->Width == stImage->base.Width); 1118e648d4a1d1c0c5f70916e38366b863f0bec79a62Brian Paul assert(dstImage->Height == stImage->base.Height); 1119e648d4a1d1c0c5f70916e38366b863f0bec79a62Brian Paul assert(dstImage->Depth == stImage->base.Depth); 1120e648d4a1d1c0c5f70916e38366b863f0bec79a62Brian Paul } 1121e648d4a1d1c0c5f70916e38366b863f0bec79a62Brian Paul 1122753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer if (stImage->pt) { 112324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian /* Copy potentially with the blitter: 112424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 11255d67d4fbebb7c7d6582c4c92fc5cea4a8e6a60abBrian Paul GLuint src_level; 11268f772b34b0d59e369177c129a1d195917b288adfMichel Dänzer if (stImage->pt->last_level == 0) 11275d67d4fbebb7c7d6582c4c92fc5cea4a8e6a60abBrian Paul src_level = 0; 11285d67d4fbebb7c7d6582c4c92fc5cea4a8e6a60abBrian Paul else 11295d67d4fbebb7c7d6582c4c92fc5cea4a8e6a60abBrian Paul src_level = stImage->base.Level; 11305d67d4fbebb7c7d6582c4c92fc5cea4a8e6a60abBrian Paul 11318f772b34b0d59e369177c129a1d195917b288adfMichel Dänzer assert(src_level <= stImage->pt->last_level); 11328f772b34b0d59e369177c129a1d195917b288adfMichel Dänzer assert(u_minify(stImage->pt->width0, src_level) == stImage->base.Width); 11338e019506257b720a1a6ff668aef57bff445a1725Michel Dänzer assert(stImage->pt->target == PIPE_TEXTURE_1D_ARRAY || 11348e019506257b720a1a6ff668aef57bff445a1725Michel Dänzer u_minify(stImage->pt->height0, src_level) == stImage->base.Height); 11358e019506257b720a1a6ff668aef57bff445a1725Michel Dänzer assert(stImage->pt->target == PIPE_TEXTURE_2D_ARRAY || 11368e019506257b720a1a6ff668aef57bff445a1725Michel Dänzer u_minify(stImage->pt->depth0, src_level) == stImage->base.Depth); 11378f772b34b0d59e369177c129a1d195917b288adfMichel Dänzer 1138753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer st_texture_image_copy(st->pipe, 11394da1cdf78fa3b954840650fa46cf72da5daf149fBrian stObj->pt, dstLevel, /* dest texture, level */ 11405d67d4fbebb7c7d6582c4c92fc5cea4a8e6a60abBrian Paul stImage->pt, src_level, /* src texture, level */ 11416dbad425bc423eb7db7c99aab161955c7b4cdc4cBrian Paul stImage->base.Face); 114224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 1143287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell pipe_resource_reference(&stImage->pt, NULL); 114424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 1145aff65241c8bf6206c6dfcbe774b87991f965d46fBrian Paul else if (stImage->TexData) { 1146cf2439e2463ce925e3e256a25a505cf0586963f0Brian Paul /* Copy from malloc'd memory */ 1147cf2439e2463ce925e3e256a25a505cf0586963f0Brian Paul /* XXX this should be re-examined/tested with a compressed format */ 1148cf2439e2463ce925e3e256a25a505cf0586963f0Brian Paul GLuint blockSize = util_format_get_blocksize(stObj->pt->format); 1149cf2439e2463ce925e3e256a25a505cf0586963f0Brian Paul GLuint srcRowStride = stImage->base.Width * blockSize; 1150cf2439e2463ce925e3e256a25a505cf0586963f0Brian Paul GLuint srcSliceStride = stImage->base.Height * srcRowStride; 1151e50dd26ca6d0eb0d0f97c2780020ea16e3d4a687Thomas Hellstrom st_texture_image_data(st, 11525facd7986ace899673499f396897469720476799Brian Paul stObj->pt, 11536dbad425bc423eb7db7c99aab161955c7b4cdc4cBrian Paul stImage->base.Face, 11545facd7986ace899673499f396897469720476799Brian Paul dstLevel, 1155aff65241c8bf6206c6dfcbe774b87991f965d46fBrian Paul stImage->TexData, 1156cf2439e2463ce925e3e256a25a505cf0586963f0Brian Paul srcRowStride, 1157cf2439e2463ce925e3e256a25a505cf0586963f0Brian Paul srcSliceStride); 1158aff65241c8bf6206c6dfcbe774b87991f965d46fBrian Paul _mesa_align_free(stImage->TexData); 1159aff65241c8bf6206c6dfcbe774b87991f965d46fBrian Paul stImage->TexData = NULL; 116024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 116124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 1162287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell pipe_resource_reference(&stImage->pt, stObj->pt); 116324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 116424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 116524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 1166afc54983370033b65e3a7cbb29bd9c87156f0881Brian/** 1167afc54983370033b65e3a7cbb29bd9c87156f0881Brian * Called during state validation. When this function is finished, 1168afc54983370033b65e3a7cbb29bd9c87156f0881Brian * the texture object should be ready for rendering. 11693b3774b1227743147159676795b542c0eb7c2bdfBrian Paul * \return GL_TRUE for success, GL_FALSE for failure (out of mem) 117024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 117114b98343309fdcff3514f05020303f7b40e83a4aBrianGLboolean 1172f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergst_finalize_texture(struct gl_context *ctx, 1173c3af68dc5022715cc8f126b7df12f3f5248aefe7Keith Whitwell struct pipe_context *pipe, 1174295a87f6c211322faefc4ef7f88f02722973f5b6Brian Paul struct gl_texture_object *tObj) 117524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 117676c7ad2e7d387feefe58dc2116b613fe11a8b273Brian Paul struct st_context *st = st_context(ctx); 117714b98343309fdcff3514f05020303f7b40e83a4aBrian struct st_texture_object *stObj = st_texture_object(tObj); 1178afc54983370033b65e3a7cbb29bd9c87156f0881Brian const GLuint nr_faces = (stObj->base.Target == GL_TEXTURE_CUBE_MAP) ? 6 : 1; 1179e648d4a1d1c0c5f70916e38366b863f0bec79a62Brian Paul GLuint face; 118024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian struct st_texture_image *firstImage; 1181e648d4a1d1c0c5f70916e38366b863f0bec79a62Brian Paul enum pipe_format firstImageFormat; 11821dd8e2757852682af44b63193c89dff3c09c7703Brian Paul GLuint ptWidth, ptHeight, ptDepth, ptLayers; 118324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 1184f4a93e0665881dd58a95abb6525676bd1cc2e6afBrian Paul if (_mesa_is_texture_complete(tObj, &tObj->Sampler)) { 1185e3a6f57ad6c0e7bda5d45eb146194ed39f45abddBrian Paul /* The texture is complete and we know exactly how many mipmap levels 1186e3a6f57ad6c0e7bda5d45eb146194ed39f45abddBrian Paul * are present/needed. This is conditional because we may be called 1187e3a6f57ad6c0e7bda5d45eb146194ed39f45abddBrian Paul * from the st_generate_mipmap() function when the texture object is 1188e3a6f57ad6c0e7bda5d45eb146194ed39f45abddBrian Paul * incomplete. In that case, we'll have set stObj->lastLevel before 1189e3a6f57ad6c0e7bda5d45eb146194ed39f45abddBrian Paul * we get here. 1190e3a6f57ad6c0e7bda5d45eb146194ed39f45abddBrian Paul */ 1191ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul if (stObj->base.Sampler.MinFilter == GL_LINEAR || 1192ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul stObj->base.Sampler.MinFilter == GL_NEAREST) 1193ae2daacbac7242938cffe0e2409071e030e00863Cooper Yuan stObj->lastLevel = stObj->base.BaseLevel; 1194ae2daacbac7242938cffe0e2409071e030e00863Cooper Yuan else 1195e648d4a1d1c0c5f70916e38366b863f0bec79a62Brian Paul stObj->lastLevel = stObj->base._MaxLevel; 1196e3a6f57ad6c0e7bda5d45eb146194ed39f45abddBrian Paul } 119724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 11984da1cdf78fa3b954840650fa46cf72da5daf149fBrian firstImage = st_texture_image(stObj->base.Image[0][stObj->base.BaseLevel]); 1199e648d4a1d1c0c5f70916e38366b863f0bec79a62Brian Paul assert(firstImage); 120024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 1201753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer /* If both firstImage and stObj point to a texture which can contain 120224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * all active images, favour firstImage. Note that because of the 120324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * completeness requirement, we know that the image dimensions 120424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian * will match. 120524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 1206753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer if (firstImage->pt && 1207753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer firstImage->pt != stObj->pt && 120871b889f904fcba4fbc5aafff4cb62a7201f38075Fredrik Höglund (!stObj->pt || firstImage->pt->last_level >= stObj->pt->last_level)) { 1209287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell pipe_resource_reference(&stObj->pt, firstImage->pt); 12106835103878afd27a1d66d29d16cbfb0b1e894a94Brian Paul pipe_sampler_view_release(st->pipe, &stObj->sampler_view); 121124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 121224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 1213e648d4a1d1c0c5f70916e38366b863f0bec79a62Brian Paul /* Find gallium format for the Mesa texture */ 1214e648d4a1d1c0c5f70916e38366b863f0bec79a62Brian Paul firstImageFormat = st_mesa_format_to_pipe_format(firstImage->base.TexFormat); 12157dbafea860dace9bfad29760f8b756122bc9937aBrian Paul 12167dbafea860dace9bfad29760f8b756122bc9937aBrian Paul /* Find size of level=0 Gallium mipmap image, plus number of texture layers */ 12177dbafea860dace9bfad29760f8b756122bc9937aBrian Paul { 12187dbafea860dace9bfad29760f8b756122bc9937aBrian Paul GLuint width, height, depth; 12197dbafea860dace9bfad29760f8b756122bc9937aBrian Paul if (!guess_base_level_size(stObj->base.Target, 12207dbafea860dace9bfad29760f8b756122bc9937aBrian Paul firstImage->base.Width2, 12217dbafea860dace9bfad29760f8b756122bc9937aBrian Paul firstImage->base.Height2, 12227dbafea860dace9bfad29760f8b756122bc9937aBrian Paul firstImage->base.Depth2, 1223124fc96ddf2695b4eca1a9b373f33cb993de9f6aBrian Paul firstImage->base.Level, 12247dbafea860dace9bfad29760f8b756122bc9937aBrian Paul &width, &height, &depth)) { 12257dbafea860dace9bfad29760f8b756122bc9937aBrian Paul width = stObj->width0; 12267dbafea860dace9bfad29760f8b756122bc9937aBrian Paul height = stObj->height0; 12277dbafea860dace9bfad29760f8b756122bc9937aBrian Paul depth = stObj->depth0; 12287dbafea860dace9bfad29760f8b756122bc9937aBrian Paul } 12297dbafea860dace9bfad29760f8b756122bc9937aBrian Paul /* convert GL dims to Gallium dims */ 12307dbafea860dace9bfad29760f8b756122bc9937aBrian Paul st_gl_texture_dims_to_pipe_dims(stObj->base.Target, width, height, depth, 12317dbafea860dace9bfad29760f8b756122bc9937aBrian Paul &ptWidth, &ptHeight, &ptDepth, &ptLayers); 12327dbafea860dace9bfad29760f8b756122bc9937aBrian Paul } 123324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 1234ce509401738e7073de94a2b7fc41461c52a73da0Brian Paul /* If we already have a gallium texture, check that it matches the texture 1235ce509401738e7073de94a2b7fc41461c52a73da0Brian Paul * object's format, target, size, num_levels, etc. 123624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 1237809dd9089bae70cf35cea6a75258e700e7455738Brian Paul if (stObj->pt) { 1238809dd9089bae70cf35cea6a75258e700e7455738Brian Paul if (stObj->pt->target != gl_target_to_pipe(stObj->base.Target) || 1239a2817f6ae566b672f195cff22e14e2058d3617eaDave Airlie !st_sampler_compat_formats(stObj->pt->format, firstImageFormat) || 1240529b7b355d392b1534ccd8ff7b428dc21cbfdc21Brian Paul stObj->pt->last_level < stObj->lastLevel || 12411dd8e2757852682af44b63193c89dff3c09c7703Brian Paul stObj->pt->width0 != ptWidth || 12421dd8e2757852682af44b63193c89dff3c09c7703Brian Paul stObj->pt->height0 != ptHeight || 12431dd8e2757852682af44b63193c89dff3c09c7703Brian Paul stObj->pt->depth0 != ptDepth || 12441dd8e2757852682af44b63193c89dff3c09c7703Brian Paul stObj->pt->array_size != ptLayers) 1245311f77198e171e9ce8ddcce91fd6a894fff1f14fBrian Paul { 1246e648d4a1d1c0c5f70916e38366b863f0bec79a62Brian Paul /* The gallium texture does not match the Mesa texture so delete the 1247e648d4a1d1c0c5f70916e38366b863f0bec79a62Brian Paul * gallium texture now. We'll make a new one below. 1248e648d4a1d1c0c5f70916e38366b863f0bec79a62Brian Paul */ 1249287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell pipe_resource_reference(&stObj->pt, NULL); 12506835103878afd27a1d66d29d16cbfb0b1e894a94Brian Paul pipe_sampler_view_release(st->pipe, &stObj->sampler_view); 125176c7ad2e7d387feefe58dc2116b613fe11a8b273Brian Paul st->dirty.st |= ST_NEW_FRAMEBUFFER; 1252809dd9089bae70cf35cea6a75258e700e7455738Brian Paul } 125324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 125424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 1255ce509401738e7073de94a2b7fc41461c52a73da0Brian Paul /* May need to create a new gallium texture: 125624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 1257753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer if (!stObj->pt) { 1258e648d4a1d1c0c5f70916e38366b863f0bec79a62Brian Paul GLuint bindings = default_bindings(st, firstImageFormat); 12591ad2484f03cbe9ae6bd4ebe50d6894e570d65952Brian Paul 126076c7ad2e7d387feefe58dc2116b613fe11a8b273Brian Paul stObj->pt = st_texture_create(st, 12615390a43ce06b27f6d54bc5f237aa305b6948f2afBrian gl_target_to_pipe(stObj->base.Target), 1262e648d4a1d1c0c5f70916e38366b863f0bec79a62Brian Paul firstImageFormat, 1263b245840b86cf877c9b8d666edf229364a84f1deaBrian stObj->lastLevel, 12641dd8e2757852682af44b63193c89dff3c09c7703Brian Paul ptWidth, 12651dd8e2757852682af44b63193c89dff3c09c7703Brian Paul ptHeight, 12661dd8e2757852682af44b63193c89dff3c09c7703Brian Paul ptDepth, 12671dd8e2757852682af44b63193c89dff3c09c7703Brian Paul ptLayers, 12688283db88414f600e66510de713382c36899d4b03Brian Paul bindings); 1269a73ae3d5eb8419feab5aea26573aa41b72f941ebKeith Whitwell 12703b3774b1227743147159676795b542c0eb7c2bdfBrian Paul if (!stObj->pt) { 12713b3774b1227743147159676795b542c0eb7c2bdfBrian Paul _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage"); 12723b3774b1227743147159676795b542c0eb7c2bdfBrian Paul return GL_FALSE; 12733b3774b1227743147159676795b542c0eb7c2bdfBrian Paul } 127424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 127524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 1276753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer /* Pull in any images not in the object's texture: 127724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 127824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian for (face = 0; face < nr_faces; face++) { 12794da1cdf78fa3b954840650fa46cf72da5daf149fBrian GLuint level; 12809adebe172df9fbf9ba359d949e64ce07bbef77b7Brian Paul for (level = stObj->base.BaseLevel; level <= stObj->lastLevel; level++) { 128124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian struct st_texture_image *stImage = 1282e648d4a1d1c0c5f70916e38366b863f0bec79a62Brian Paul st_texture_image(stObj->base.Image[face][level]); 128324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 1284753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer /* Need to import images in main memory or held in other textures. 128524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian */ 1286a34b43b3f4817268ef4b3f186203b5fbafc7214eBrian if (stImage && stObj->pt != stImage->pt) { 1287b0524e49fc555ec8e5505e88c03e1993cdf3666bBrian Paul if (level == 0 || 1288b0524e49fc555ec8e5505e88c03e1993cdf3666bBrian Paul (stImage->base.Width == u_minify(stObj->width0, level) && 1289b0524e49fc555ec8e5505e88c03e1993cdf3666bBrian Paul stImage->base.Height == u_minify(stObj->height0, level) && 1290b0524e49fc555ec8e5505e88c03e1993cdf3666bBrian Paul stImage->base.Depth == u_minify(stObj->depth0, level))) { 1291a22aba4eae9b29db731487bce90e8292f7e82c72Brian Paul /* src image fits expected dest mipmap level size */ 1292a22aba4eae9b29db731487bce90e8292f7e82c72Brian Paul copy_image_data_to_texture(st, stObj, level, stImage); 1293a22aba4eae9b29db731487bce90e8292f7e82c72Brian Paul } 129424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 129524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 129624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian } 129724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 129824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian return GL_TRUE; 129924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 130024df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 130124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 13028f6d9e12be0be086ca2aab0b56dff8d2181addd9Brian Paul/** 1303e0a0496971dfd6c0f22b3870e6320128fa895d4dBrian Paul * Called via ctx->Driver.AllocTextureStorage() to allocate texture memory 1304e0a0496971dfd6c0f22b3870e6320128fa895d4dBrian Paul * for a whole mipmap stack. 1305e0a0496971dfd6c0f22b3870e6320128fa895d4dBrian Paul */ 1306e0a0496971dfd6c0f22b3870e6320128fa895d4dBrian Paulstatic GLboolean 1307e0a0496971dfd6c0f22b3870e6320128fa895d4dBrian Paulst_AllocTextureStorage(struct gl_context *ctx, 1308e0a0496971dfd6c0f22b3870e6320128fa895d4dBrian Paul struct gl_texture_object *texObj, 1309e0a0496971dfd6c0f22b3870e6320128fa895d4dBrian Paul GLsizei levels, GLsizei width, 1310e0a0496971dfd6c0f22b3870e6320128fa895d4dBrian Paul GLsizei height, GLsizei depth) 1311e0a0496971dfd6c0f22b3870e6320128fa895d4dBrian Paul{ 131246751edca9a95baff81771aa69986fa6e2422ed6Brian Paul const GLuint numFaces = _mesa_num_tex_faces(texObj->Target); 1313e0a0496971dfd6c0f22b3870e6320128fa895d4dBrian Paul struct st_context *st = st_context(ctx); 1314e0a0496971dfd6c0f22b3870e6320128fa895d4dBrian Paul struct st_texture_object *stObj = st_texture_object(texObj); 1315e0a0496971dfd6c0f22b3870e6320128fa895d4dBrian Paul GLuint ptWidth, ptHeight, ptDepth, ptLayers, bindings; 1316e0a0496971dfd6c0f22b3870e6320128fa895d4dBrian Paul enum pipe_format fmt; 1317e0a0496971dfd6c0f22b3870e6320128fa895d4dBrian Paul GLint level; 1318e0a0496971dfd6c0f22b3870e6320128fa895d4dBrian Paul 1319e0a0496971dfd6c0f22b3870e6320128fa895d4dBrian Paul assert(levels > 0); 1320e0a0496971dfd6c0f22b3870e6320128fa895d4dBrian Paul 1321e0a0496971dfd6c0f22b3870e6320128fa895d4dBrian Paul /* Save the level=0 dimensions */ 1322e0a0496971dfd6c0f22b3870e6320128fa895d4dBrian Paul stObj->width0 = width; 1323e0a0496971dfd6c0f22b3870e6320128fa895d4dBrian Paul stObj->height0 = height; 1324e0a0496971dfd6c0f22b3870e6320128fa895d4dBrian Paul stObj->depth0 = depth; 1325e0a0496971dfd6c0f22b3870e6320128fa895d4dBrian Paul stObj->lastLevel = levels - 1; 1326e0a0496971dfd6c0f22b3870e6320128fa895d4dBrian Paul 1327e0a0496971dfd6c0f22b3870e6320128fa895d4dBrian Paul fmt = st_mesa_format_to_pipe_format(texObj->Image[0][0]->TexFormat); 1328e0a0496971dfd6c0f22b3870e6320128fa895d4dBrian Paul 1329e0a0496971dfd6c0f22b3870e6320128fa895d4dBrian Paul bindings = default_bindings(st, fmt); 1330e0a0496971dfd6c0f22b3870e6320128fa895d4dBrian Paul 1331e0a0496971dfd6c0f22b3870e6320128fa895d4dBrian Paul st_gl_texture_dims_to_pipe_dims(texObj->Target, 1332e0a0496971dfd6c0f22b3870e6320128fa895d4dBrian Paul width, height, depth, 1333e0a0496971dfd6c0f22b3870e6320128fa895d4dBrian Paul &ptWidth, &ptHeight, &ptDepth, &ptLayers); 1334e0a0496971dfd6c0f22b3870e6320128fa895d4dBrian Paul 1335e0a0496971dfd6c0f22b3870e6320128fa895d4dBrian Paul stObj->pt = st_texture_create(st, 1336e0a0496971dfd6c0f22b3870e6320128fa895d4dBrian Paul gl_target_to_pipe(texObj->Target), 1337e0a0496971dfd6c0f22b3870e6320128fa895d4dBrian Paul fmt, 1338e0a0496971dfd6c0f22b3870e6320128fa895d4dBrian Paul levels, 1339e0a0496971dfd6c0f22b3870e6320128fa895d4dBrian Paul ptWidth, 1340e0a0496971dfd6c0f22b3870e6320128fa895d4dBrian Paul ptHeight, 1341e0a0496971dfd6c0f22b3870e6320128fa895d4dBrian Paul ptDepth, 1342e0a0496971dfd6c0f22b3870e6320128fa895d4dBrian Paul ptLayers, 1343e0a0496971dfd6c0f22b3870e6320128fa895d4dBrian Paul bindings); 1344e0a0496971dfd6c0f22b3870e6320128fa895d4dBrian Paul if (!stObj->pt) 1345e0a0496971dfd6c0f22b3870e6320128fa895d4dBrian Paul return GL_FALSE; 1346e0a0496971dfd6c0f22b3870e6320128fa895d4dBrian Paul 1347e0a0496971dfd6c0f22b3870e6320128fa895d4dBrian Paul /* Set image resource pointers */ 1348e0a0496971dfd6c0f22b3870e6320128fa895d4dBrian Paul for (level = 0; level < levels; level++) { 1349e0a0496971dfd6c0f22b3870e6320128fa895d4dBrian Paul GLuint face; 1350e0a0496971dfd6c0f22b3870e6320128fa895d4dBrian Paul for (face = 0; face < numFaces; face++) { 1351e0a0496971dfd6c0f22b3870e6320128fa895d4dBrian Paul struct st_texture_image *stImage = 1352e0a0496971dfd6c0f22b3870e6320128fa895d4dBrian Paul st_texture_image(texObj->Image[face][level]); 1353e0a0496971dfd6c0f22b3870e6320128fa895d4dBrian Paul pipe_resource_reference(&stImage->pt, stObj->pt); 1354e0a0496971dfd6c0f22b3870e6320128fa895d4dBrian Paul } 1355e0a0496971dfd6c0f22b3870e6320128fa895d4dBrian Paul } 1356e0a0496971dfd6c0f22b3870e6320128fa895d4dBrian Paul 1357e0a0496971dfd6c0f22b3870e6320128fa895d4dBrian Paul return GL_TRUE; 1358e0a0496971dfd6c0f22b3870e6320128fa895d4dBrian Paul} 1359e0a0496971dfd6c0f22b3870e6320128fa895d4dBrian Paul 1360e0a0496971dfd6c0f22b3870e6320128fa895d4dBrian Paul 1361e0a0496971dfd6c0f22b3870e6320128fa895d4dBrian Paul 13626da9234fd437f97267e7831f034c78b31156d939Brianvoid 13636da9234fd437f97267e7831f034c78b31156d939Brianst_init_texture_functions(struct dd_function_table *functions) 136424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian{ 136524df8f895fe8807aa2ba058e71bd40adfc01d21eBrian functions->ChooseTextureFormat = st_ChooseTextureFormat; 13668f5fffe75d2f8ae7c7ee706b53379a25bc673ae4Brian Paul functions->TexImage = st_TexImage; 1367e42d00b3f4503a0840575c8e5f4517a66c8af613Brian Paul functions->TexSubImage = _mesa_store_texsubimage; 1368ec19bdd16c3d4070af69fd865042babe0a627595Brian Paul functions->CompressedTexSubImage = _mesa_store_compressed_texsubimage; 1369cd9ab2584f5e2a5eb0e96a948e6aedc9a33c886dBrian Paul functions->CopyTexSubImage = st_CopyTexSubImage; 137062abcb9aacc33218d0143a743c738435794b32a9Brian functions->GenerateMipmap = st_generate_mipmap; 1371038cb561eb094af2f2ba06e18e61246fc0c87c3cBrian 137224df8f895fe8807aa2ba058e71bd40adfc01d21eBrian functions->GetTexImage = st_GetTexImage; 137324df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 137424df8f895fe8807aa2ba058e71bd40adfc01d21eBrian /* compressed texture functions */ 1375e8fdd0e0d5286f4a9c763ffde44decec51124ebcBrian Paul functions->CompressedTexImage = st_CompressedTexImage; 13768df7ca71125ee0ad74260378ff7e185dcf66f3bcBrian Paul functions->GetCompressedTexImage = _mesa_get_compressed_teximage; 137724df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 137824df8f895fe8807aa2ba058e71bd40adfc01d21eBrian functions->NewTextureObject = st_NewTextureObject; 137924df8f895fe8807aa2ba058e71bd40adfc01d21eBrian functions->NewTextureImage = st_NewTextureImage; 1380146f536b3332b7a2022bb4ba5e2d1d2ec4bedd98Brian Paul functions->DeleteTextureImage = st_DeleteTextureImage; 138124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian functions->DeleteTexture = st_DeleteTextureObject; 13824e6bb0774ffa93141a3a8ec7bb47b190810b2a4bBrian Paul functions->AllocTextureImageBuffer = st_AllocTextureImageBuffer; 13835401590815b0ef095e7881bbabce233bab07c1e6Eric Anholt functions->FreeTextureImageBuffer = st_FreeTextureImageBuffer; 13840abb2659dda3ac7828cade6f9a999c511e33e905Brian Paul functions->MapTextureImage = st_MapTextureImage; 13850abb2659dda3ac7828cade6f9a999c511e33e905Brian Paul functions->UnmapTextureImage = st_UnmapTextureImage; 138624df8f895fe8807aa2ba058e71bd40adfc01d21eBrian 1387f8549e8f4f8bdfebcb4e0a2754df59b3fe4fdff7Brian /* XXX Temporary until we can query pipe's texture sizes */ 1388f8549e8f4f8bdfebcb4e0a2754df59b3fe4fdff7Brian functions->TestProxyTexImage = _mesa_test_proxy_teximage; 1389e0a0496971dfd6c0f22b3870e6320128fa895d4dBrian Paul 1390e0a0496971dfd6c0f22b3870e6320128fa895d4dBrian Paul functions->AllocTextureStorage = st_AllocTextureStorage; 139124df8f895fe8807aa2ba058e71bd40adfc01d21eBrian} 1392