texstore.c revision 2ce0654ebabc7fc6a2881f51e496e4e1f7533087
12ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul/* $Id: texstore.c,v 1.43 2002/10/18 17:41:45 brianp Exp $ */ 28e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul 38e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul/* 48e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * Mesa 3-D graphics library 542f916de5cb3f4362e4682cdaa5eea00fe2de857Brian Paul * Version: 4.1 68e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * 7aeb4434563c4014a662ea334878b60d3031bb3c1Brian Paul * Copyright (C) 1999-2002 Brian Paul All Rights Reserved. 88e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * 98e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * Permission is hereby granted, free of charge, to any person obtaining a 108e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * copy of this software and associated documentation files (the "Software"), 118e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * to deal in the Software without restriction, including without limitation 128e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * the rights to use, copy, modify, merge, publish, distribute, sublicense, 138e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * and/or sell copies of the Software, and to permit persons to whom the 148e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * Software is furnished to do so, subject to the following conditions: 158e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * 168e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * The above copyright notice and this permission notice shall be included 178e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * in all copies or substantial portions of the Software. 188e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * 198e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 208e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 218e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 228e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 238e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 248e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 258e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul */ 268e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul 278e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul/* 288e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * Authors: 298e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * Brian Paul 308e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul */ 318e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul 3289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul/* 3389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * The GL texture image functions in teximage.c basically just do 3489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * error checking and data structure allocation. They in turn call 3589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * device driver functions which actually copy/convert/store the user's 3689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * texture image data. 3789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * 3889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * However, most device drivers will be able to use the fallback functions 3989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * in this file. That is, most drivers will have the following bit of 4089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * code: 4189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * ctx->Driver.TexImage1D = _mesa_store_teximage1d; 4289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * ctx->Driver.TexImage2D = _mesa_store_teximage2d; 4389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * ctx->Driver.TexImage3D = _mesa_store_teximage3d; 4489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * etc... 4589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * 4689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * Texture image processing is actually kind of complicated. We have to do: 4789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * Format/type conversions 4889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * pixel unpacking 4989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * pixel transfer (scale, bais, lookup, convolution!, etc) 5089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * 5189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * These functions can handle most everything, including processing full 5289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * images and sub-images. 5389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul */ 5489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul 5589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul 5689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul 57e75d2424e53d6023f4414e40694cd467e5392b96Brian Paul#include "colormac.h" 588e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul#include "context.h" 598e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul#include "convolve.h" 608e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul#include "image.h" 618e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul#include "macros.h" 628e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul#include "mem.h" 6389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul#include "texcompress.h" 64371ef9c058b0d59bfb62689b64af1b29a2214d9eGareth Hughes#include "texformat.h" 658e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul#include "teximage.h" 668e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul#include "texstore.h" 677d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul#include "texutil.h" 688e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul 698e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul 708e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul/* 718e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * Given an internal texture format enum or 1, 2, 3, 4 return the 728e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * corresponding _base_ internal format: GL_ALPHA, GL_LUMINANCE, 738e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * GL_LUMANCE_ALPHA, GL_INTENSITY, GL_RGB, or GL_RGBA. Return the 748e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * number of components for the format. Return -1 if invalid enum. 758e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul */ 768e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paulstatic GLint 778e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paulcomponents_in_intformat( GLint format ) 788e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul{ 798e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul switch (format) { 808e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul case GL_ALPHA: 818e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul case GL_ALPHA4: 828e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul case GL_ALPHA8: 838e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul case GL_ALPHA12: 848e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul case GL_ALPHA16: 858e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul return 1; 868e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul case 1: 878e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul case GL_LUMINANCE: 888e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul case GL_LUMINANCE4: 898e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul case GL_LUMINANCE8: 908e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul case GL_LUMINANCE12: 918e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul case GL_LUMINANCE16: 928e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul return 1; 938e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul case 2: 948e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul case GL_LUMINANCE_ALPHA: 958e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul case GL_LUMINANCE4_ALPHA4: 968e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul case GL_LUMINANCE6_ALPHA2: 978e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul case GL_LUMINANCE8_ALPHA8: 988e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul case GL_LUMINANCE12_ALPHA4: 998e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul case GL_LUMINANCE12_ALPHA12: 1008e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul case GL_LUMINANCE16_ALPHA16: 1018e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul return 2; 1028e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul case GL_INTENSITY: 1038e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul case GL_INTENSITY4: 1048e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul case GL_INTENSITY8: 1058e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul case GL_INTENSITY12: 1068e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul case GL_INTENSITY16: 1078e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul return 1; 1088e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul case 3: 1098e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul case GL_RGB: 1108e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul case GL_R3_G3_B2: 1118e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul case GL_RGB4: 1128e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul case GL_RGB5: 1138e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul case GL_RGB8: 1148e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul case GL_RGB10: 1158e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul case GL_RGB12: 1168e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul case GL_RGB16: 1178e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul return 3; 1188e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul case 4: 1198e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul case GL_RGBA: 1208e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul case GL_RGBA2: 1218e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul case GL_RGBA4: 1228e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul case GL_RGB5_A1: 1238e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul case GL_RGBA8: 1248e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul case GL_RGB10_A2: 1258e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul case GL_RGBA12: 1268e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul case GL_RGBA16: 1278e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul return 4; 1288e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul case GL_COLOR_INDEX: 1298e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul case GL_COLOR_INDEX1_EXT: 1308e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul case GL_COLOR_INDEX2_EXT: 1318e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul case GL_COLOR_INDEX4_EXT: 1328e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul case GL_COLOR_INDEX8_EXT: 1338e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul case GL_COLOR_INDEX12_EXT: 1348e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul case GL_COLOR_INDEX16_EXT: 1358e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul return 1; 136f7e1dfeaefda8865252513bc4d880ea8640efe4dBrian Paul case GL_DEPTH_COMPONENT: 137f7e1dfeaefda8865252513bc4d880ea8640efe4dBrian Paul case GL_DEPTH_COMPONENT16_SGIX: 138f7e1dfeaefda8865252513bc4d880ea8640efe4dBrian Paul case GL_DEPTH_COMPONENT24_SGIX: 139f7e1dfeaefda8865252513bc4d880ea8640efe4dBrian Paul case GL_DEPTH_COMPONENT32_SGIX: 140f7e1dfeaefda8865252513bc4d880ea8640efe4dBrian Paul return 1; 141c5b995066020191982b2315fc45d05e068eee761Brian Paul case GL_YCBCR_MESA: 142c5b995066020191982b2315fc45d05e068eee761Brian Paul return 2; /* Y + (Cb or Cr) */ 1438e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul default: 1448e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul return -1; /* error */ 1458e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul } 1468e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul} 1478e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul 1488e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul 1498e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul/* 1508e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * This function is used to transfer the user's image data into a texture 1518e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * image buffer. We handle both full texture images and subtexture images. 1528e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * We also take care of all image transfer operations here, including 1538e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * convolution, scale/bias, colortables, etc. 1548e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * 15589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * The destination texel type is always GLchan. 15689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * The destination texel format is one of the 6 basic types. 1578e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * 1588e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * A hardware driver may use this as a helper routine to unpack and 1598e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * apply pixel transfer ops into a temporary image buffer. Then, 1608e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * convert the temporary image into the special hardware format. 1618e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * 1628e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * Input: 1638e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * dimensions - 1, 2, or 3 16489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * texDestFormat - GL_LUMINANCE, GL_INTENSITY, GL_LUMINANCE_ALPHA, GL_ALPHA, 16589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * GL_RGB or GL_RGBA (the destination format) 16656671022f97cfbc199a47b3338125431e42030eeBrian Paul * texDestAddr - destination image address 1678e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * srcWidth, srcHeight, srcDepth - size (in pixels) of src and dest images 1688e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * dstXoffset, dstYoffset, dstZoffset - position to store the image within 1698e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * the destination 3D texture 17056671022f97cfbc199a47b3338125431e42030eeBrian Paul * dstRowStride, dstImageStride - dest image strides in bytes 1718e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * srcFormat - source image format (GL_ALPHA, GL_RED, GL_RGB, etc) 1728e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * srcType - GL_UNSIGNED_BYTE, GL_UNSIGNED_SHORT_5_6_5, GL_FLOAT, etc 1738e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * srcPacking - describes packing of incoming image. 1741c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul * transferOps - mask of pixel transfer operations 1758e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul */ 1767d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paulstatic void 1777d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paultransfer_teximage(GLcontext *ctx, GLuint dimensions, 1787d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul GLenum texDestFormat, GLvoid *texDestAddr, 1797d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul GLint srcWidth, GLint srcHeight, GLint srcDepth, 1807d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul GLint dstXoffset, GLint dstYoffset, GLint dstZoffset, 1817d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul GLint dstRowStride, GLint dstImageStride, 1827d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul GLenum srcFormat, GLenum srcType, 1837d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul const GLvoid *srcAddr, 1841c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul const struct gl_pixelstore_attrib *srcPacking, 1851c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul GLuint transferOps) 1868e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul{ 1878e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul GLint texComponents; 1888e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul 1898e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul ASSERT(ctx); 1908e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul ASSERT(dimensions >= 1 && dimensions <= 3); 19189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul ASSERT(texDestFormat == GL_LUMINANCE || 19289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul texDestFormat == GL_INTENSITY || 19389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul texDestFormat == GL_LUMINANCE_ALPHA || 19489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul texDestFormat == GL_ALPHA || 19589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul texDestFormat == GL_RGB || 19689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul texDestFormat == GL_RGBA); 19756671022f97cfbc199a47b3338125431e42030eeBrian Paul ASSERT(texDestAddr); 1988e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul ASSERT(srcWidth >= 1); 1998e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul ASSERT(srcHeight >= 1); 2008e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul ASSERT(srcDepth >= 1); 2018e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul ASSERT(dstXoffset >= 0); 2028e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul ASSERT(dstYoffset >= 0); 2038e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul ASSERT(dstZoffset >= 0); 2048e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul ASSERT(dstRowStride >= 0); 2058e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul ASSERT(dstImageStride >= 0); 2068e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul ASSERT(srcAddr); 2078e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul ASSERT(srcPacking); 2088e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul 2090299ad753224372c7a6147f598fdad33f576a714Brian Paul texComponents = components_in_intformat(texDestFormat); 2108e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul 2118e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul /* try common 2D texture cases first */ 2121c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul if (!transferOps && dimensions == 2 && srcType == CHAN_TYPE) { 2138e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul 2140299ad753224372c7a6147f598fdad33f576a714Brian Paul if (srcFormat == texDestFormat) { 2158e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul /* This will cover the common GL_RGB, GL_RGBA, GL_ALPHA, 2168e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * GL_LUMINANCE_ALPHA, etc. texture formats. Use memcpy(). 2178e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul */ 2188e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul const GLchan *src = (const GLchan *) _mesa_image_address( 2198e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul srcPacking, srcAddr, srcWidth, srcHeight, 2208e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul srcFormat, srcType, 0, 0, 0); 2218e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul const GLint srcRowStride = _mesa_image_row_stride(srcPacking, 2228e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul srcWidth, srcFormat, srcType); 2238e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul const GLint widthInBytes = srcWidth * texComponents * sizeof(GLchan); 224a1503b00f863a48a517939a42d512f9cfe77f79cBrian Paul GLchan *dst = (GLchan *) texDestAddr 225a1503b00f863a48a517939a42d512f9cfe77f79cBrian Paul + dstYoffset * (dstRowStride / sizeof(GLchan)) 226a1503b00f863a48a517939a42d512f9cfe77f79cBrian Paul + dstXoffset * texComponents; 2278e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul if (srcRowStride == widthInBytes && dstRowStride == widthInBytes) { 2288e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul MEMCPY(dst, src, srcHeight * widthInBytes); 2298e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul } 2308e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul else { 2318e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul GLint i; 2328e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul for (i = 0; i < srcHeight; i++) { 2338e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul MEMCPY(dst, src, widthInBytes); 234a1503b00f863a48a517939a42d512f9cfe77f79cBrian Paul src += (srcRowStride / sizeof(GLchan)); 235a1503b00f863a48a517939a42d512f9cfe77f79cBrian Paul dst += (dstRowStride / sizeof(GLchan)); 2368e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul } 2378e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul } 2388e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul return; /* all done */ 2398e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul } 2400299ad753224372c7a6147f598fdad33f576a714Brian Paul else if (srcFormat == GL_RGBA && texDestFormat == GL_RGB) { 2418e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul /* commonly used by Quake */ 2428e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul const GLchan *src = (const GLchan *) _mesa_image_address( 2438e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul srcPacking, srcAddr, srcWidth, srcHeight, 2448e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul srcFormat, srcType, 0, 0, 0); 2458e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul const GLint srcRowStride = _mesa_image_row_stride(srcPacking, 2468e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul srcWidth, srcFormat, srcType); 247a1503b00f863a48a517939a42d512f9cfe77f79cBrian Paul GLchan *dst = (GLchan *) texDestAddr 248a1503b00f863a48a517939a42d512f9cfe77f79cBrian Paul + dstYoffset * (dstRowStride / sizeof(GLchan)) 249a1503b00f863a48a517939a42d512f9cfe77f79cBrian Paul + dstXoffset * texComponents; 2508e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul GLint i, j; 2518e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul for (i = 0; i < srcHeight; i++) { 2528e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul const GLchan *s = src; 2538e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul GLchan *d = dst; 2548e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul for (j = 0; j < srcWidth; j++) { 2558e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul *d++ = *s++; /*red*/ 2568e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul *d++ = *s++; /*green*/ 2578e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul *d++ = *s++; /*blue*/ 2588e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul s++; /*alpha*/ 2598e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul } 260a1503b00f863a48a517939a42d512f9cfe77f79cBrian Paul src += (srcRowStride / sizeof(GLchan)); 261a1503b00f863a48a517939a42d512f9cfe77f79cBrian Paul dst += (dstRowStride / sizeof(GLchan)); 2628e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul } 2638e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul return; /* all done */ 2648e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul } 2658e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul } 2668e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul 2678e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul /* 2688e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * General case solutions 2698e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul */ 2700299ad753224372c7a6147f598fdad33f576a714Brian Paul if (texDestFormat == GL_COLOR_INDEX) { 2718e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul /* color index texture */ 2721ceda0f84fdfe07951071fdf4fa643d07f09a4d7Brian Paul const GLenum texType = CHAN_TYPE; 2738e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul GLint img, row; 27442f916de5cb3f4362e4682cdaa5eea00fe2de857Brian Paul GLchan *dest = (GLchan *) texDestAddr 27542f916de5cb3f4362e4682cdaa5eea00fe2de857Brian Paul + dstZoffset * (dstImageStride / sizeof(GLchan)) 276a1503b00f863a48a517939a42d512f9cfe77f79cBrian Paul + dstYoffset * (dstRowStride / sizeof(GLchan)) 277a1503b00f863a48a517939a42d512f9cfe77f79cBrian Paul + dstXoffset * texComponents; 2788e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul for (img = 0; img < srcDepth; img++) { 2798e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul GLchan *destRow = dest; 2808e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul for (row = 0; row < srcHeight; row++) { 2818e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul const GLvoid *src = _mesa_image_address(srcPacking, 2828e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, row, 0); 2838e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul _mesa_unpack_index_span(ctx, srcWidth, texType, destRow, 2841c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul srcType, src, srcPacking, transferOps); 285a1503b00f863a48a517939a42d512f9cfe77f79cBrian Paul destRow += (dstRowStride / sizeof(GLchan)); 2868e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul } 2878e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul dest += dstImageStride; 2888e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul } 2898e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul } 290c5b995066020191982b2315fc45d05e068eee761Brian Paul else if (texDestFormat == GL_YCBCR_MESA) { 291c5b995066020191982b2315fc45d05e068eee761Brian Paul /* YCbCr texture */ 292c5b995066020191982b2315fc45d05e068eee761Brian Paul GLint img, row; 293c5b995066020191982b2315fc45d05e068eee761Brian Paul GLushort *dest = (GLushort *) texDestAddr 294c5b995066020191982b2315fc45d05e068eee761Brian Paul + dstZoffset * (dstImageStride / sizeof(GLushort)) 295c5b995066020191982b2315fc45d05e068eee761Brian Paul + dstYoffset * (dstRowStride / sizeof(GLushort)) 296c5b995066020191982b2315fc45d05e068eee761Brian Paul + dstXoffset * texComponents; 297c5b995066020191982b2315fc45d05e068eee761Brian Paul ASSERT(ctx->Extensions.MESA_ycbcr_texture); 298c5b995066020191982b2315fc45d05e068eee761Brian Paul printf("copy ycbcr\n"); 299c5b995066020191982b2315fc45d05e068eee761Brian Paul for (img = 0; img < srcDepth; img++) { 300c5b995066020191982b2315fc45d05e068eee761Brian Paul GLushort *destRow = dest; 301c5b995066020191982b2315fc45d05e068eee761Brian Paul for (row = 0; row < srcHeight; row++) { 302c5b995066020191982b2315fc45d05e068eee761Brian Paul const GLvoid *srcRow = _mesa_image_address(srcPacking, 303c5b995066020191982b2315fc45d05e068eee761Brian Paul srcAddr, srcWidth, srcHeight, 304c5b995066020191982b2315fc45d05e068eee761Brian Paul srcFormat, srcType, img, row, 0); 305c5b995066020191982b2315fc45d05e068eee761Brian Paul MEMCPY(destRow, srcRow, srcWidth * sizeof(GLushort)); 306c5b995066020191982b2315fc45d05e068eee761Brian Paul destRow += (dstRowStride / sizeof(GLushort)); 307c5b995066020191982b2315fc45d05e068eee761Brian Paul } 308c5b995066020191982b2315fc45d05e068eee761Brian Paul dest += dstImageStride / sizeof(GLushort); 309c5b995066020191982b2315fc45d05e068eee761Brian Paul } 310c5b995066020191982b2315fc45d05e068eee761Brian Paul } 3110299ad753224372c7a6147f598fdad33f576a714Brian Paul else if (texDestFormat == GL_DEPTH_COMPONENT) { 312f7e1dfeaefda8865252513bc4d880ea8640efe4dBrian Paul /* Depth texture (shadow maps) */ 313f7e1dfeaefda8865252513bc4d880ea8640efe4dBrian Paul GLint img, row; 31456671022f97cfbc199a47b3338125431e42030eeBrian Paul GLubyte *dest = (GLubyte *) texDestAddr 31556671022f97cfbc199a47b3338125431e42030eeBrian Paul + dstZoffset * dstImageStride 316a1503b00f863a48a517939a42d512f9cfe77f79cBrian Paul + dstYoffset * (dstRowStride / sizeof(GLchan)) 317f7e1dfeaefda8865252513bc4d880ea8640efe4dBrian Paul + dstXoffset * texComponents; 318f7e1dfeaefda8865252513bc4d880ea8640efe4dBrian Paul for (img = 0; img < srcDepth; img++) { 31956671022f97cfbc199a47b3338125431e42030eeBrian Paul GLubyte *destRow = dest; 320f7e1dfeaefda8865252513bc4d880ea8640efe4dBrian Paul for (row = 0; row < srcHeight; row++) { 321f7e1dfeaefda8865252513bc4d880ea8640efe4dBrian Paul const GLvoid *src = _mesa_image_address(srcPacking, 322f7e1dfeaefda8865252513bc4d880ea8640efe4dBrian Paul srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, row, 0); 32356671022f97cfbc199a47b3338125431e42030eeBrian Paul _mesa_unpack_depth_span(ctx, srcWidth, (GLfloat *) destRow, 324e75d2424e53d6023f4414e40694cd467e5392b96Brian Paul srcType, src, srcPacking); 325a1503b00f863a48a517939a42d512f9cfe77f79cBrian Paul destRow += (dstRowStride / sizeof(GLchan)); 326f7e1dfeaefda8865252513bc4d880ea8640efe4dBrian Paul } 327f7e1dfeaefda8865252513bc4d880ea8640efe4dBrian Paul dest += dstImageStride; 328f7e1dfeaefda8865252513bc4d880ea8640efe4dBrian Paul } 329f7e1dfeaefda8865252513bc4d880ea8640efe4dBrian Paul } 3308e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul else { 3318e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul /* regular, color texture */ 3328e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul if ((dimensions == 1 && ctx->Pixel.Convolution1DEnabled) || 3338e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul (dimensions >= 2 && ctx->Pixel.Convolution2DEnabled) || 3348e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul (dimensions >= 2 && ctx->Pixel.Separable2DEnabled)) { 3358e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul /* 3368e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * Fill texture image with convolution 3378e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul */ 3388e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul GLint img, row; 3398e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul GLint convWidth = srcWidth, convHeight = srcHeight; 3408e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul GLfloat *tmpImage, *convImage; 3418e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul tmpImage = (GLfloat *) MALLOC(srcWidth * srcHeight * 4 * sizeof(GLfloat)); 3428e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul if (!tmpImage) { 34308836341788a9f9d638d9dc8328510ccd18ddeb5Brian Paul _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage"); 3448e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul return; 3458e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul } 3468e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul convImage = (GLfloat *) MALLOC(srcWidth * srcHeight * 4 * sizeof(GLfloat)); 3478e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul if (!convImage) { 34808836341788a9f9d638d9dc8328510ccd18ddeb5Brian Paul _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage"); 3498e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul FREE(tmpImage); 3508e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul return; 3518e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul } 3528e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul 3538e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul for (img = 0; img < srcDepth; img++) { 3548e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul const GLfloat *srcf; 3558e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul GLfloat *dstf = tmpImage; 3568e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul GLchan *dest; 3578e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul 3588e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul /* unpack and do transfer ops up to convolution */ 3598e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul for (row = 0; row < srcHeight; row++) { 3608e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul const GLvoid *src = _mesa_image_address(srcPacking, 3618e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul srcAddr, srcWidth, srcHeight, 3628e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul srcFormat, srcType, img, row, 0); 3638e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul _mesa_unpack_float_color_span(ctx, srcWidth, GL_RGBA, dstf, 3648e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul srcFormat, srcType, src, srcPacking, 3651c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul transferOps & IMAGE_PRE_CONVOLUTION_BITS, 3668e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul GL_TRUE); 3678e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul dstf += srcWidth * 4; 3688e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul } 3698e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul 3708e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul /* convolve */ 3718e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul if (dimensions == 1) { 3728e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul ASSERT(ctx->Pixel.Convolution1DEnabled); 3738e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul _mesa_convolve_1d_image(ctx, &convWidth, tmpImage, convImage); 3748e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul } 3758e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul else { 3768e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul if (ctx->Pixel.Convolution2DEnabled) { 3778e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul _mesa_convolve_2d_image(ctx, &convWidth, &convHeight, 3788e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul tmpImage, convImage); 3798e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul } 3808e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul else { 3818e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul ASSERT(ctx->Pixel.Separable2DEnabled); 3828e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul _mesa_convolve_sep_image(ctx, &convWidth, &convHeight, 3838e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul tmpImage, convImage); 3848e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul } 3858e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul } 3868e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul 3878e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul /* packing and transfer ops after convolution */ 3888e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul srcf = convImage; 38942f916de5cb3f4362e4682cdaa5eea00fe2de857Brian Paul dest = (GLchan *) texDestAddr 39042f916de5cb3f4362e4682cdaa5eea00fe2de857Brian Paul + (dstZoffset + img) * (dstImageStride / sizeof(GLchan)) 391a1503b00f863a48a517939a42d512f9cfe77f79cBrian Paul + dstYoffset * (dstRowStride / sizeof(GLchan)); 3928e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul for (row = 0; row < convHeight; row++) { 3938e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul _mesa_pack_float_rgba_span(ctx, convWidth, 3948e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul (const GLfloat (*)[4]) srcf, 3950299ad753224372c7a6147f598fdad33f576a714Brian Paul texDestFormat, CHAN_TYPE, 3968e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul dest, &_mesa_native_packing, 3971c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul transferOps 3988e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul & IMAGE_POST_CONVOLUTION_BITS); 3998e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul srcf += convWidth * 4; 400a1503b00f863a48a517939a42d512f9cfe77f79cBrian Paul dest += (dstRowStride / sizeof(GLchan)); 4018e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul } 4028e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul } 4038e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul 4048e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul FREE(convImage); 4058e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul FREE(tmpImage); 4068e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul } 4078e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul else { 4088e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul /* 4098e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * no convolution 4108e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul */ 4118e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul GLint img, row; 41242f916de5cb3f4362e4682cdaa5eea00fe2de857Brian Paul GLchan *dest = (GLchan *) texDestAddr 41342f916de5cb3f4362e4682cdaa5eea00fe2de857Brian Paul + dstZoffset * (dstImageStride / sizeof(GLchan)) 414a1503b00f863a48a517939a42d512f9cfe77f79cBrian Paul + dstYoffset * (dstRowStride / sizeof(GLchan)) 415a1503b00f863a48a517939a42d512f9cfe77f79cBrian Paul + dstXoffset * texComponents; 4168e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul for (img = 0; img < srcDepth; img++) { 4178e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul GLchan *destRow = dest; 4188e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul for (row = 0; row < srcHeight; row++) { 4198e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul const GLvoid *srcRow = _mesa_image_address(srcPacking, 4208e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul srcAddr, srcWidth, srcHeight, 4218e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul srcFormat, srcType, img, row, 0); 4220299ad753224372c7a6147f598fdad33f576a714Brian Paul _mesa_unpack_chan_color_span(ctx, srcWidth, texDestFormat, 4230299ad753224372c7a6147f598fdad33f576a714Brian Paul destRow, srcFormat, srcType, srcRow, 4241c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul srcPacking, transferOps); 425a1503b00f863a48a517939a42d512f9cfe77f79cBrian Paul destRow += (dstRowStride / sizeof(GLchan)); 4268e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul } 42742f916de5cb3f4362e4682cdaa5eea00fe2de857Brian Paul dest += dstImageStride / sizeof(GLchan); 4288e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul } 4298e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul } 4308e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul } 4318e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul} 4328e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul 4338e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul 4348e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul 4358e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul/* 4367d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul * Transfer a texture image from user space to <destAddr> applying all 4377d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul * needed image transfer operations and storing the result in the format 4387d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul * specified by <dstFormat>. <dstFormat> may be any format from texformat.h. 4397d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul * Input: 4401c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul * dimensions - 1, 2 or 3 4411c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul * baseInternalFormat - base format of the internal texture format 4421c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul * specified by the user. This is very important, see below. 4431c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul * dstFormat - destination image format 4441c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul * dstAddr - destination address 4451c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul * srcWidth, srcHeight, srcDepth - size of source iamge 4461c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul * dstX/Y/Zoffset - as specified by glTexSubImage 4477d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul * dstRowStride - stride between dest rows in bytes 44842f916de5cb3f4362e4682cdaa5eea00fe2de857Brian Paul * dstImageStride - stride between dest images in bytes 4491c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul * srcFormat, srcType - incoming image format and datatype 4501c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul * srcAddr - source image address 4511c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul * srcPacking - packing params of source image 4527d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul * 4537d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul * XXX this function is a bit more complicated than it should be. If 4547d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul * _mesa_convert_texsubimage[123]d could handle any dest/source formats 4557d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul * or if transfer_teximage() could store in any MESA_FORMAT_* format, we 4567d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul * could simplify things here. 4577d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul */ 4587d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paulvoid 4597d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul_mesa_transfer_teximage(GLcontext *ctx, GLuint dimensions, 4601c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul GLenum baseInternalFormat, 4617d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul const struct gl_texture_format *dstFormat, 4627d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul GLvoid *dstAddr, 4637d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul GLint srcWidth, GLint srcHeight, GLint srcDepth, 4647d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul GLint dstXoffset, GLint dstYoffset, GLint dstZoffset, 4657d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul GLint dstRowStride, GLint dstImageStride, 4667d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul GLenum srcFormat, GLenum srcType, 4677d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul const GLvoid *srcAddr, 4687d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul const struct gl_pixelstore_attrib *srcPacking) 4697d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul{ 4707d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul const GLint dstRowStridePixels = dstRowStride / dstFormat->TexelBytes; 4717d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul const GLint dstImageStridePixels = dstImageStride / dstFormat->TexelBytes; 4727d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul GLboolean makeTemp; 4731c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul GLuint transferOps = ctx->_ImageTransferState; 4741c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul GLboolean freeSourceData = GL_FALSE; 4751c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul GLint postConvWidth = srcWidth, postConvHeight = srcHeight; 4761c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul 477e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul assert(baseInternalFormat > 0); 47889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul ASSERT(baseInternalFormat == GL_LUMINANCE || 47989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul baseInternalFormat == GL_INTENSITY || 48089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul baseInternalFormat == GL_LUMINANCE_ALPHA || 48189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul baseInternalFormat == GL_ALPHA || 48289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul baseInternalFormat == GL_RGB || 48389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul baseInternalFormat == GL_RGBA); 484e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul 4851c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul if (transferOps & IMAGE_CONVOLUTION_BIT) { 4861c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul _mesa_adjust_image_for_convolution(ctx, dimensions, &postConvWidth, 4871c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul &postConvHeight); 4881c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul } 4891c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul 4901c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul /* 4911c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul * Consider this scenario: The user's source image is GL_RGB and the 4921c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul * requested internal format is GL_LUMINANCE. Now suppose the device 4931c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul * driver doesn't support GL_LUMINANCE and instead uses RGB16 as the 4941c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul * texture format. In that case we still need to do an intermediate 4951c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul * conversion to luminance format so that the incoming red channel gets 4961c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul * replicated into the dest red, green and blue channels. The following 4971c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul * code takes care of that. 4981c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul */ 4991c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul if (dstFormat->BaseFormat != baseInternalFormat) { 5001c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul /* Allocate storage for temporary image in the baseInternalFormat */ 5011c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul const GLint texelSize = _mesa_components_in_format(baseInternalFormat) 5021c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul * sizeof(GLchan); 5031c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul const GLint bytes = texelSize * postConvWidth * postConvHeight *srcDepth; 5041c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul const GLint tmpRowStride = texelSize * postConvWidth; 5051c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul const GLint tmpImgStride = texelSize * postConvWidth * postConvHeight; 5061c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul GLvoid *tmpImage = MALLOC(bytes); 5071c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul if (!tmpImage) 5081c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul return; 5091c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul transfer_teximage(ctx, dimensions, baseInternalFormat, tmpImage, 5101c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul srcWidth, srcHeight, srcDepth, 5111c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul 0, 0, 0, /* x/y/zoffset */ 5121c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul tmpRowStride, tmpImgStride, 5131c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul srcFormat, srcType, srcAddr, srcPacking, transferOps); 5141c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul 5151c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul /* this is our new source image */ 5161c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul srcWidth = postConvWidth; 5171c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul srcHeight = postConvHeight; 5181c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul srcFormat = baseInternalFormat; 5191c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul srcType = CHAN_TYPE; 5201c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul srcAddr = tmpImage; 5211c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul srcPacking = &_mesa_native_packing; 5221c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul freeSourceData = GL_TRUE; 5231c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul transferOps = 0; /* image transfer ops were completed */ 5241c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul } 5257d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul 5261c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul /* Let the optimized tex conversion functions take a crack at the 5271c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul * image conversion if the dest format is a h/w format. 5281c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul */ 5297d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul if (_mesa_is_hardware_tex_format(dstFormat)) { 5301c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul if (transferOps) { 5317d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul makeTemp = GL_TRUE; 5327d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul } 5337d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul else { 5347d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul if (dimensions == 1) { 5357d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul makeTemp = !_mesa_convert_texsubimage1d(dstFormat->MesaFormat, 5367d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul dstXoffset, 5377d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul srcWidth, 5387d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul srcFormat, srcType, 5397d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul srcPacking, srcAddr, 5407d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul dstAddr); 5417d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul } 5427d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul else if (dimensions == 2) { 5437d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul makeTemp = !_mesa_convert_texsubimage2d(dstFormat->MesaFormat, 5447d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul dstXoffset, dstYoffset, 5457d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul srcWidth, srcHeight, 5467d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul dstRowStridePixels, 5477d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul srcFormat, srcType, 5487d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul srcPacking, srcAddr, 5497d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul dstAddr); 5507d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul } 5517d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul else { 5527d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul assert(dimensions == 3); 5537d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul makeTemp = !_mesa_convert_texsubimage3d(dstFormat->MesaFormat, 5547d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul dstXoffset, dstYoffset, dstZoffset, 5557d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul srcWidth, srcHeight, srcDepth, 5567d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul dstRowStridePixels, dstImageStridePixels, 5577d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul srcFormat, srcType, 5587d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul srcPacking, srcAddr, dstAddr); 5597d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul } 5607d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul if (!makeTemp) { 5617d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul /* all done! */ 5621c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul if (freeSourceData) 5631c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul FREE((void *) srcAddr); 5647d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul return; 5657d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul } 5667d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul } 5677d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul } 5687d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul else { 5697d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul /* software texture format */ 5707d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul makeTemp = GL_FALSE; 5717d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul } 5727d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul 5737d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul if (makeTemp) { 5747d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul GLint postConvWidth = srcWidth, postConvHeight = srcHeight; 5757d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul GLenum tmpFormat; 5767d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul GLuint tmpComps, tmpTexelSize; 5777d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul GLint tmpRowStride, tmpImageStride; 5787d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul GLubyte *tmpImage; 5797d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul 5801c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul if (transferOps & IMAGE_CONVOLUTION_BIT) { 5817d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul _mesa_adjust_image_for_convolution(ctx, dimensions, &postConvWidth, 5827d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul &postConvHeight); 5837d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul } 5847d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul 5851c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul tmpFormat = dstFormat->BaseFormat; 5867d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul tmpComps = _mesa_components_in_format(tmpFormat); 58736f3712e85cafef1b038189678030f6ef4f8b7e9Brian Paul tmpTexelSize = tmpComps * sizeof(GLchan); 5887d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul tmpRowStride = postConvWidth * tmpTexelSize; 5897d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul tmpImageStride = postConvWidth * postConvHeight * tmpTexelSize; 5907d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul tmpImage = (GLubyte *) MALLOC(postConvWidth * postConvHeight * 5917d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul srcDepth * tmpTexelSize); 5921c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul if (!tmpImage) { 5931c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul if (freeSourceData) 5941c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul FREE((void *) srcAddr); 5957d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul return; 5961c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul } 5977d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul 5987d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul transfer_teximage(ctx, dimensions, tmpFormat, tmpImage, 5997d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul srcWidth, srcHeight, srcDepth, 6007d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul 0, 0, 0, /* x/y/zoffset */ 6017d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul tmpRowStride, tmpImageStride, 6021c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul srcFormat, srcType, srcAddr, srcPacking, transferOps); 6031c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul 6041c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul if (freeSourceData) 6051c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul FREE((void *) srcAddr); 6067d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul 6077d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul /* the temp image is our new source image */ 6087d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul srcWidth = postConvWidth; 6097d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul srcHeight = postConvHeight; 6107d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul srcFormat = tmpFormat; 6117d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul srcType = CHAN_TYPE; 6127d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul srcAddr = tmpImage; 6137d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul srcPacking = &_mesa_native_packing; 6141c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul freeSourceData = GL_TRUE; 6157d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul } 6167d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul 6177d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul if (_mesa_is_hardware_tex_format(dstFormat)) { 6187d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul assert(makeTemp); 6197d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul if (dimensions == 1) { 6207d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul GLboolean b; 6217d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul b = _mesa_convert_texsubimage1d(dstFormat->MesaFormat, 6227d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul dstXoffset, 6237d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul srcWidth, 6247d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul srcFormat, srcType, 6257d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul srcPacking, srcAddr, 6267d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul dstAddr); 6277d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul assert(b); 6287d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul } 6297d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul else if (dimensions == 2) { 6307d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul GLboolean b; 6317d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul b = _mesa_convert_texsubimage2d(dstFormat->MesaFormat, 6327d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul dstXoffset, dstYoffset, 6337d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul srcWidth, srcHeight, 6347d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul dstRowStridePixels, 6357d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul srcFormat, srcType, 6367d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul srcPacking, srcAddr, 6377d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul dstAddr); 6387d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul assert(b); 6397d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul } 6407d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul else { 6417d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul GLboolean b; 6427d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul b = _mesa_convert_texsubimage3d(dstFormat->MesaFormat, 6437d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul dstXoffset, dstYoffset, dstZoffset, 6447d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul srcWidth, srcHeight, srcDepth, 6457d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul dstRowStridePixels, dstImageStridePixels, 6467d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul srcFormat, srcType, 6477d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul srcPacking, srcAddr, dstAddr); 6487d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul assert(b); 6497d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul } 6507d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul } 6517d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul else { 6527d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul /* software format */ 6537d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul assert(!makeTemp); 6541c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul transfer_teximage(ctx, dimensions, dstFormat->BaseFormat, dstAddr, 6557d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul srcWidth, srcHeight, srcDepth, 6567d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul dstXoffset, dstYoffset, dstZoffset, 6577d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul dstRowStride, dstImageStride, 6581c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul srcFormat, srcType, srcAddr, srcPacking, transferOps); 6597d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul } 6601c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul 6611c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul if (freeSourceData) 6621c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul FREE((void *) srcAddr); /* the temp image */ 6637d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul} 6647d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul 6657d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul 66689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul 66789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul/** 66889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * Given a user's uncompressed texture image, this function takes care of 66989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * pixel unpacking, pixel transfer, format conversion and compression. 67089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul */ 67189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paulstatic void 67289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paultransfer_compressed_teximage(GLcontext *ctx, GLuint dimensions, 67389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul GLsizei width, GLsizei height, GLsizei depth, 67489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul GLenum srcFormat, GLenum srcType, 67589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul const struct gl_pixelstore_attrib *unpacking, 67689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul const GLvoid *source, 6772ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul const struct gl_texture_format *dstFormat, 6782ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul GLubyte *dest, 67989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul GLint dstRowStride) 68089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul{ 68189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul GLchan *tempImage = NULL; 68289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul GLint srcRowStride; 68389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul GLenum baseFormat; 68489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul 68589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul ASSERT(dimensions == 2); 6862ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul /* TexelBytes is zero if and only if it's a compressed format */ 6872ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul ASSERT(dstFormat->TexelBytes == 0); 68889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul 6892ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul baseFormat = dstFormat->BaseFormat; 69089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul 69189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul if (srcFormat != baseFormat || srcType != CHAN_TYPE || 69289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul ctx->_ImageTransferState != 0 || unpacking->SwapBytes) { 69389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul /* need to convert user's image to texImage->Format, GLchan */ 69489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul GLint comps = components_in_intformat(baseFormat); 69589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul GLint postConvWidth = width, postConvHeight = height; 69689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul 69789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul /* XXX convolution untested */ 69889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul if (ctx->_ImageTransferState & IMAGE_CONVOLUTION_BIT) { 69989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul _mesa_adjust_image_for_convolution(ctx, dimensions, &postConvWidth, 70089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul &postConvHeight); 70189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul } 70289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul 70389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul tempImage = (GLchan*) MALLOC(width * height * comps * sizeof(GLchan)); 70489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul if (!tempImage) { 70589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D"); 70689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul return; 70789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul } 70889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul transfer_teximage(ctx, dimensions, 70989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul baseFormat, /* dest format */ 71089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul tempImage, /* dst address */ 71189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul width, height, depth, /* src size */ 71289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul 0, 0, 0, /* x/y/zoffset */ 71389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul comps * width, /* dst row stride */ 71489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul comps * width * height, /* dst image stride */ 71589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul srcFormat, srcType, /* src format, type */ 71689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul source, unpacking, /* src and src packing */ 71789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul ctx->_ImageTransferState); 71889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul source = tempImage; 71989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul width = postConvWidth; 72089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul height = postConvHeight; 72189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul srcRowStride = width; 72289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul } 72389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul else { 72489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul if (unpacking->RowLength) 72589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul srcRowStride = unpacking->RowLength; 72689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul else 72789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul srcRowStride = width; 72889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul } 72989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul 73089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul _mesa_compress_teximage(ctx, width, height, baseFormat, 73189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul (const GLchan *) source, srcRowStride, 73289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul dstFormat, dest, dstRowStride); 73389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul if (tempImage) { 73489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul FREE(tempImage); 73589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul } 73689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul} 73789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul 73889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul 73989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul 7407d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul/* 74189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * This is the software fallback for Driver.TexImage1D() 74289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * and Driver.CopyTexImage2D(). 7438e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * The texture image type will be GLchan. 7448e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * The texture image format will be GL_COLOR_INDEX, GL_INTENSITY, 7458e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * GL_LUMINANCE, GL_LUMINANCE_ALPHA, GL_ALPHA, GL_RGB or GL_RGBA. 7468e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul */ 7478e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paulvoid 7488e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul_mesa_store_teximage1d(GLcontext *ctx, GLenum target, GLint level, 7498e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul GLint internalFormat, 7508e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul GLint width, GLint border, 7518e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul GLenum format, GLenum type, const GLvoid *pixels, 7528e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul const struct gl_pixelstore_attrib *packing, 7538e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul struct gl_texture_object *texObj, 7548e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul struct gl_texture_image *texImage) 7558e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul{ 7568e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul GLint postConvWidth = width; 757e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul GLint texelBytes, sizeInBytes; 7588e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul 7598e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul if (ctx->_ImageTransferState & IMAGE_CONVOLUTION_BIT) { 7608e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul _mesa_adjust_image_for_convolution(ctx, 1, &postConvWidth, NULL); 7618e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul } 7628e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul 7637d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul /* choose the texture format */ 7647d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul assert(ctx->Driver.ChooseTextureFormat); 7657d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul texImage->TexFormat = (*ctx->Driver.ChooseTextureFormat)(ctx, 7667d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul internalFormat, format, type); 7677d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul assert(texImage->TexFormat); 7689228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul texImage->FetchTexel = texImage->TexFormat->FetchTexel1D; 7698e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul 77019d1e432612cf7db797da11793b13a6c1c6aac16Gareth Hughes texelBytes = texImage->TexFormat->TexelBytes; 77119d1e432612cf7db797da11793b13a6c1c6aac16Gareth Hughes 7728e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul /* allocate memory */ 77389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul if (texImage->IsCompressed) 77489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul sizeInBytes = texImage->CompressedSize; 77589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul else 77689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul sizeInBytes = postConvWidth * texelBytes; 777aeb4434563c4014a662ea334878b60d3031bb3c1Brian Paul texImage->Data = MESA_PBUFFER_ALLOC(sizeInBytes); 7787d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul if (!texImage->Data) { 7797d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage1D"); 7807d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul return; 7817d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul } 7828e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul 78389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul if (!pixels) 78489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul return; 78589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul 78689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul /* unpack image, apply transfer ops and store in texImage->Data */ 78789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul if (texImage->IsCompressed) { 78889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul GLint dstRowStride = _mesa_compressed_row_stride(texImage->IntFormat, 78989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul width); 79089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul transfer_compressed_teximage(ctx, 1, width, 1, 1, 79189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul format, type, packing, 7922ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul pixels, texImage->TexFormat, 79389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul (GLubyte *) texImage->Data, dstRowStride); 79489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul } 79589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul else { 796f3b85c983f469875ac76081a61539a6c7b26777cBrian Paul _mesa_transfer_teximage(ctx, 1, 79789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul texImage->Format, /* base format */ 798f3b85c983f469875ac76081a61539a6c7b26777cBrian Paul texImage->TexFormat, texImage->Data, 79989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul width, 1, 1, /* src size */ 80089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul 0, 0, 0, /* dstX/Y/Zoffset */ 801f3b85c983f469875ac76081a61539a6c7b26777cBrian Paul 0, /* dstRowStride */ 802f3b85c983f469875ac76081a61539a6c7b26777cBrian Paul 0, /* dstImageStride */ 803f3b85c983f469875ac76081a61539a6c7b26777cBrian Paul format, type, pixels, packing); 80489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul } 805f3b85c983f469875ac76081a61539a6c7b26777cBrian Paul 80689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul /* GL_SGIS_generate_mipmap */ 80789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul if (level == texObj->BaseLevel && texObj->GenerateMipmap) { 80889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul _mesa_generate_mipmap(ctx, target, 80989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul &ctx->Texture.Unit[ctx->Texture.CurrentUnit], 81089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul texObj); 8113893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul } 8128e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul} 8138e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul 8148e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul 8158e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul/* 81689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * This is the software fallback for Driver.TexImage2D() 81789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * and Driver.CopyTexImage2D(). 8188e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * The texture image type will be GLchan. 8198e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * The texture image format will be GL_COLOR_INDEX, GL_INTENSITY, 8208e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * GL_LUMINANCE, GL_LUMINANCE_ALPHA, GL_ALPHA, GL_RGB or GL_RGBA. 8218e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul */ 8228e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paulvoid 8238e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul_mesa_store_teximage2d(GLcontext *ctx, GLenum target, GLint level, 8248e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul GLint internalFormat, 8258e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul GLint width, GLint height, GLint border, 8268e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul GLenum format, GLenum type, const void *pixels, 8278e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul const struct gl_pixelstore_attrib *packing, 8288e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul struct gl_texture_object *texObj, 8298e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul struct gl_texture_image *texImage) 8308e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul{ 8318e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul GLint postConvWidth = width, postConvHeight = height; 832e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul GLint texelBytes, sizeInBytes; 8338e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul 8348e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul if (ctx->_ImageTransferState & IMAGE_CONVOLUTION_BIT) { 8358e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul _mesa_adjust_image_for_convolution(ctx, 2, &postConvWidth, 8368e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul &postConvHeight); 8378e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul } 8388e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul 8397d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul /* choose the texture format */ 8407d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul assert(ctx->Driver.ChooseTextureFormat); 8417d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul texImage->TexFormat = (*ctx->Driver.ChooseTextureFormat)(ctx, 8427d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul internalFormat, format, type); 8437d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul assert(texImage->TexFormat); 8443893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul texImage->FetchTexel = texImage->TexFormat->FetchTexel2D; 8452c3d34c905fa6b831a066afae83b938de05eb241Gareth Hughes 8462c3d34c905fa6b831a066afae83b938de05eb241Gareth Hughes texelBytes = texImage->TexFormat->TexelBytes; 8478e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul 8488e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul /* allocate memory */ 84989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul if (texImage->IsCompressed) 85089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul sizeInBytes = texImage->CompressedSize; 85189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul else 85289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul sizeInBytes = postConvWidth * postConvHeight * texelBytes; 853aeb4434563c4014a662ea334878b60d3031bb3c1Brian Paul texImage->Data = MESA_PBUFFER_ALLOC(sizeInBytes); 8547d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul if (!texImage->Data) { 8557d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D"); 8567d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul return; 8577d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul } 8588e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul 85989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul if (!pixels) 86089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul return; 86189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul 86289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul /* unpack image, apply transfer ops and store in texImage->Data */ 86389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul if (texImage->IsCompressed) { 86489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul GLint dstRowStride = _mesa_compressed_row_stride(texImage->IntFormat, 86589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul width); 86689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul transfer_compressed_teximage(ctx, 2, width, height, 1, 86789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul format, type, packing, 8682ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul pixels, texImage->TexFormat, 86989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul (GLubyte *) texImage->Data, dstRowStride); 87089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul } 87189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul else { 872f3b85c983f469875ac76081a61539a6c7b26777cBrian Paul _mesa_transfer_teximage(ctx, 2, 87389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul texImage->Format, 874f3b85c983f469875ac76081a61539a6c7b26777cBrian Paul texImage->TexFormat, texImage->Data, 87589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul width, height, 1, /* src size */ 87689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul 0, 0, 0, /* dstX/Y/Zoffset */ 87789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul texImage->Width * texelBytes, /* dstRowStride */ 878f3b85c983f469875ac76081a61539a6c7b26777cBrian Paul 0, /* dstImageStride */ 879f3b85c983f469875ac76081a61539a6c7b26777cBrian Paul format, type, pixels, packing); 88089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul } 881f3b85c983f469875ac76081a61539a6c7b26777cBrian Paul 88289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul /* GL_SGIS_generate_mipmap */ 88389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul if (level == texObj->BaseLevel && texObj->GenerateMipmap) { 88489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul _mesa_generate_mipmap(ctx, target, 88589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul &ctx->Texture.Unit[ctx->Texture.CurrentUnit], 88689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul texObj); 8873893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul } 8888e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul} 8898e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul 8908e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul 8918e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul 8928e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul/* 89389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * This is the software fallback for Driver.TexImage3D() 89489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * and Driver.CopyTexImage3D(). 8958e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * The texture image type will be GLchan. 8968e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * The texture image format will be GL_COLOR_INDEX, GL_INTENSITY, 8978e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * GL_LUMINANCE, GL_LUMINANCE_ALPHA, GL_ALPHA, GL_RGB or GL_RGBA. 8988e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul */ 8998e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paulvoid 9008e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul_mesa_store_teximage3d(GLcontext *ctx, GLenum target, GLint level, 9018e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul GLint internalFormat, 9028e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul GLint width, GLint height, GLint depth, GLint border, 9038e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul GLenum format, GLenum type, const void *pixels, 9048e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul const struct gl_pixelstore_attrib *packing, 9058e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul struct gl_texture_object *texObj, 9068e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul struct gl_texture_image *texImage) 9078e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul{ 908e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul GLint texelBytes, sizeInBytes; 9098e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul 9107d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul /* choose the texture format */ 9117d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul assert(ctx->Driver.ChooseTextureFormat); 9127d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul texImage->TexFormat = (*ctx->Driver.ChooseTextureFormat)(ctx, 9137d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul internalFormat, format, type); 9147d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul assert(texImage->TexFormat); 9159228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul texImage->FetchTexel = texImage->TexFormat->FetchTexel3D; 9162c3d34c905fa6b831a066afae83b938de05eb241Gareth Hughes 917197c526d63e1d4ea96f29eece392cdc389770b38Brian Paul texelBytes = texImage->TexFormat->TexelBytes; 9188e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul 9198e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul /* allocate memory */ 92089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul if (texImage->IsCompressed) 92189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul sizeInBytes = texImage->CompressedSize; 92289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul else 92389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul sizeInBytes = width * height * depth * texelBytes; 924aeb4434563c4014a662ea334878b60d3031bb3c1Brian Paul texImage->Data = MESA_PBUFFER_ALLOC(sizeInBytes); 9257d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul if (!texImage->Data) { 9267d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage3D"); 9277d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul return; 9287d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul } 9298e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul 93089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul if (!pixels) 93189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul return; 93289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul 93389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul /* unpack image, apply transfer ops and store in texImage->Data */ 93489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul if (texImage->IsCompressed) { 93589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul GLint dstRowStride = _mesa_compressed_row_stride(texImage->IntFormat, 93689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul width); 93789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul transfer_compressed_teximage(ctx, 3, width, height, depth, 93889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul format, type, packing, 9392ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul pixels, texImage->TexFormat, 94089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul (GLubyte *) texImage->Data, dstRowStride); 94189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul } 94289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul else { 943f3b85c983f469875ac76081a61539a6c7b26777cBrian Paul _mesa_transfer_teximage(ctx, 3, 94489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul texImage->Format, 945f3b85c983f469875ac76081a61539a6c7b26777cBrian Paul texImage->TexFormat, texImage->Data, 94689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul width, height, depth, /* src size */ 94789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul 0, 0, 0, /* dstX/Y/Zoffset */ 94889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul texImage->Width * texelBytes, /* dstRowStride */ 949f3b85c983f469875ac76081a61539a6c7b26777cBrian Paul texImage->Width * texImage->Height * texelBytes, 950f3b85c983f469875ac76081a61539a6c7b26777cBrian Paul format, type, pixels, packing); 95189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul } 952f3b85c983f469875ac76081a61539a6c7b26777cBrian Paul 95389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul /* GL_SGIS_generate_mipmap */ 95489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul if (level == texObj->BaseLevel && texObj->GenerateMipmap) { 95589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul _mesa_generate_mipmap(ctx, target, 95689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul &ctx->Texture.Unit[ctx->Texture.CurrentUnit], 95789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul texObj); 9583893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul } 9598e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul} 9608e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul 9618e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul 9628e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul 9638e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul 9648e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul/* 96589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * This is the software fallback for Driver.TexSubImage1D() 96689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * and Driver.CopyTexSubImage1D(). 9678e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul */ 9688e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paulvoid 9698e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul_mesa_store_texsubimage1d(GLcontext *ctx, GLenum target, GLint level, 9708e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul GLint xoffset, GLint width, 9718e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul GLenum format, GLenum type, const void *pixels, 9728e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul const struct gl_pixelstore_attrib *packing, 9738e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul struct gl_texture_object *texObj, 9748e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul struct gl_texture_image *texImage) 9758e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul{ 97689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul if (texImage->IsCompressed) { 97789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul GLint dstRowStride = _mesa_compressed_row_stride(texImage->IntFormat, 97889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul texImage->Width); 97989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul GLubyte *dest = _mesa_compressed_image_address(xoffset, 0, 0, 98089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul texImage->IntFormat, 98189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul texImage->Width, 98289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul texImage->Data); 98389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul transfer_compressed_teximage(ctx, 1, /* dimensions */ 98489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul width, 1, 1, /* size to replace */ 98589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul format, type, /* source format/type */ 98689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul packing, /* source packing */ 98789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul pixels, /* source data */ 9882ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul texImage->TexFormat,/* dest format */ 98989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul dest, dstRowStride); 99089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul } 99189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul else { 99289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul _mesa_transfer_teximage(ctx, 1, 99389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul texImage->Format, 99489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul texImage->TexFormat, texImage->Data, 99589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul width, 1, 1, /* src size */ 99689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul xoffset, 0, 0, /* dest offsets */ 99789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul 0, /* dstRowStride */ 99889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul 0, /* dstImageStride */ 99989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul format, type, pixels, packing); 100089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul } 10013893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul 10023893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul /* GL_SGIS_generate_mipmap */ 10033893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul if (level == texObj->BaseLevel && texObj->GenerateMipmap) { 1004d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul _mesa_generate_mipmap(ctx, target, 1005d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul &ctx->Texture.Unit[ctx->Texture.CurrentUnit], 10063893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul texObj); 10073893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul } 10088e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul} 10098e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul 10108e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul 101189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul 10128e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul/* 101389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * This is the software fallback for Driver.TexSubImage2D() 101489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * and Driver.CopyTexSubImage2D(). 10158e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul */ 10168e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paulvoid 10178e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul_mesa_store_texsubimage2d(GLcontext *ctx, GLenum target, GLint level, 10188e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul GLint xoffset, GLint yoffset, 10198e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul GLint width, GLint height, 10208e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul GLenum format, GLenum type, const void *pixels, 10218e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul const struct gl_pixelstore_attrib *packing, 10228e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul struct gl_texture_object *texObj, 10238e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul struct gl_texture_image *texImage) 10248e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul{ 102589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul if (texImage->IsCompressed) { 102689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul GLint dstRowStride = _mesa_compressed_row_stride(texImage->IntFormat, 102789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul texImage->Width); 102889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul GLubyte *dest = _mesa_compressed_image_address(xoffset, yoffset, 0, 102989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul texImage->IntFormat, 103089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul texImage->Width, 103189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul texImage->Data); 103289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul transfer_compressed_teximage(ctx, 2, /* dimensions */ 103389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul width, height, 1, /* size to replace */ 103489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul format, type, /* source format/type */ 103589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul packing, /* source packing */ 103689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul pixels, /* source data */ 10372ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul texImage->TexFormat,/* dest format */ 103889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul dest, dstRowStride); 103989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul } 104089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul else { 104189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul _mesa_transfer_teximage(ctx, 2, 104289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul texImage->Format, 104389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul texImage->TexFormat, texImage->Data, 104489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul width, height, 1, /* src size */ 104589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul xoffset, yoffset, 0, /* dest offsets */ 104689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul texImage->Width *texImage->TexFormat->TexelBytes, 104789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul 0, /* dstImageStride */ 104889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul format, type, pixels, packing); 104989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul } 10503893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul 10513893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul /* GL_SGIS_generate_mipmap */ 10523893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul if (level == texObj->BaseLevel && texObj->GenerateMipmap) { 1053d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul _mesa_generate_mipmap(ctx, target, 1054d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul &ctx->Texture.Unit[ctx->Texture.CurrentUnit], 10553893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul texObj); 10563893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul } 10578e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul} 10588e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul 10598e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul 10608e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul/* 10618e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * This is the software fallback for Driver.TexSubImage3D(). 106289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * and Driver.CopyTexSubImage3D(). 10638e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul */ 10648e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paulvoid 10658e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul_mesa_store_texsubimage3d(GLcontext *ctx, GLenum target, GLint level, 10668e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul GLint xoffset, GLint yoffset, GLint zoffset, 10678e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul GLint width, GLint height, GLint depth, 10688e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul GLenum format, GLenum type, const void *pixels, 10698e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul const struct gl_pixelstore_attrib *packing, 10708e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul struct gl_texture_object *texObj, 10718e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul struct gl_texture_image *texImage) 10728e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul{ 107389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul if (texImage->IsCompressed) { 107489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul GLint dstRowStride = _mesa_compressed_row_stride(texImage->IntFormat, 107589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul texImage->Width); 107689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul GLubyte *dest = _mesa_compressed_image_address(xoffset, yoffset, zoffset, 107789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul texImage->IntFormat, 107889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul texImage->Width, 107989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul texImage->Data); 108089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul transfer_compressed_teximage(ctx, 3, /* dimensions */ 108189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul width, height, depth,/* size to replace */ 108289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul format, type, /* source format/type */ 108389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul packing, /* source packing */ 108489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul pixels, /* source data */ 10852ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul texImage->TexFormat,/* dest format */ 108689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul dest, dstRowStride); 108789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul } 108889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul else { 108989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul const GLint texelBytes = texImage->TexFormat->TexelBytes; 109089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul _mesa_transfer_teximage(ctx, 3, 109189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul texImage->Format, 10921c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul texImage->TexFormat, texImage->Data, 10938e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul width, height, depth, /* src size */ 10948e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul xoffset, yoffset, xoffset, /* dest offsets */ 109589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul texImage->Width * texelBytes, /* dst row stride */ 109638f28665bf9fb5b2464738ca5074848ec2777ae1Gareth Hughes texImage->Width * texImage->Height * texelBytes, 10978e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul format, type, pixels, packing); 109889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul } 109989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul 11003893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul /* GL_SGIS_generate_mipmap */ 11013893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul if (level == texObj->BaseLevel && texObj->GenerateMipmap) { 1102d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul _mesa_generate_mipmap(ctx, target, 1103d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul &ctx->Texture.Unit[ctx->Texture.CurrentUnit], 11043893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul texObj); 11053893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul } 11068e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul} 11078e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul 11088e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul 11098e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul 11102aadbf41dfd4f63c6118d0ad2d8659d289cbe454Brian Paul 11112aadbf41dfd4f63c6118d0ad2d8659d289cbe454Brian Paul/* 11128e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * Fallback for Driver.CompressedTexImage1D() 11138e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul */ 11148e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paulvoid 11158e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul_mesa_store_compressed_teximage1d(GLcontext *ctx, GLenum target, GLint level, 11168e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul GLint internalFormat, 11178e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul GLint width, GLint border, 11188e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul GLsizei imageSize, const GLvoid *data, 11198e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul struct gl_texture_object *texObj, 11208e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul struct gl_texture_image *texImage) 11218e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul{ 112289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul /* this space intentionally left blank */ 11238e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul} 11248e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul 11258e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul 11268e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul 11278e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul/* 11288e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * Fallback for Driver.CompressedTexImage2D() 11298e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul */ 11308e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paulvoid 11318e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul_mesa_store_compressed_teximage2d(GLcontext *ctx, GLenum target, GLint level, 11328e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul GLint internalFormat, 11338e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul GLint width, GLint height, GLint border, 11348e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul GLsizei imageSize, const GLvoid *data, 11358e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul struct gl_texture_object *texObj, 11368e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul struct gl_texture_image *texImage) 11378e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul{ 113889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul /* This is pretty simple, basically just do a memcpy without worrying 113989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * about the usual image unpacking or image transfer operations. 11408e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul */ 114189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul ASSERT(texObj); 114289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul ASSERT(texImage); 114389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul ASSERT(texImage->Width > 0); 114489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul ASSERT(texImage->Height > 0); 114589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul ASSERT(texImage->Depth == 1); 114689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul ASSERT(texImage->Data == NULL); /* was freed in glCompressedTexImage2DARB */ 114789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul 114889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul /* choose the texture format */ 114989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul assert(ctx->Driver.ChooseTextureFormat); 115089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul texImage->TexFormat = (*ctx->Driver.ChooseTextureFormat)(ctx, 115189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul internalFormat, 0, 0); 115289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul assert(texImage->TexFormat); 115389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul texImage->FetchTexel = texImage->TexFormat->FetchTexel2D; 115489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul 115589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul /* allocate storage */ 115689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul texImage->Data = MESA_PBUFFER_ALLOC(imageSize); 115789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul if (!texImage->Data) { 115889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexImage2DARB"); 115989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul return; 116089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul } 116189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul 116289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul /* copy the data */ 116389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul ASSERT(texImage->CompressedSize == imageSize); 116489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul MEMCPY(texImage->Data, data, imageSize); 11658e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul} 11668e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul 11678e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul 11688e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul 11698e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul/* 11708e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * Fallback for Driver.CompressedTexImage3D() 11718e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul */ 11728e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paulvoid 11738e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul_mesa_store_compressed_teximage3d(GLcontext *ctx, GLenum target, GLint level, 11748e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul GLint internalFormat, 11758e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul GLint width, GLint height, GLint depth, 11768e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul GLint border, 11778e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul GLsizei imageSize, const GLvoid *data, 11788e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul struct gl_texture_object *texObj, 11798e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul struct gl_texture_image *texImage) 11808e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul{ 118189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul /* this space intentionally left blank */ 11828e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul} 11838e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul 11848e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul 11858e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul 118689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul/** 118789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * Fallback for Driver.CompressedTexSubImage1D() 1188e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul */ 1189e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paulvoid 119089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul_mesa_store_compressed_texsubimage1d(GLcontext *ctx, GLenum target, 119189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul GLint level, 119289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul GLint xoffset, GLsizei width, 119389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul GLenum format, 119489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul GLsizei imageSize, const GLvoid *data, 119589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul struct gl_texture_object *texObj, 119689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul struct gl_texture_image *texImage) 1197e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul{ 119889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul /* this space intentionally left blank */ 1199e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul} 1200e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul 1201e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul 120289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul/** 120389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * Fallback for Driver.CompressedTexSubImage2D() 120489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul */ 120589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paulvoid 120689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul_mesa_store_compressed_texsubimage2d(GLcontext *ctx, GLenum target, 120789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul GLint level, 120889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul GLint xoffset, GLint yoffset, 120989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul GLsizei width, GLsizei height, 121089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul GLenum format, 121189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul GLsizei imageSize, const GLvoid *data, 121289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul struct gl_texture_object *texObj, 121389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul struct gl_texture_image *texImage) 121489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul{ 121589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul GLint bytesPerRow, destRowStride, srcRowStride; 121689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul GLint i, rows; 121789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul GLubyte *dest; 121889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul const GLubyte *src; 121989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul 122089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul /* these should have been caught sooner */ 122189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul ASSERT((width & 3) == 0 || width == 2 || width == 1); 122289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul ASSERT((height & 3) == 0 || height == 2 || height == 1); 122389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul ASSERT((xoffset & 3) == 0); 122489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul ASSERT((yoffset & 3) == 0); 122589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul 122689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul srcRowStride = _mesa_compressed_row_stride(texImage->IntFormat, width); 122789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul src = (const GLubyte *) data; 122889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul 122989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul destRowStride = _mesa_compressed_row_stride(texImage->IntFormat, 123089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul texImage->Width); 123189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul dest = _mesa_compressed_image_address(xoffset, yoffset, 0, 123289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul texImage->IntFormat, 123389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul texImage->Width, texImage->Data); 123489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul 123589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul bytesPerRow = srcRowStride; 123689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul rows = height / 4; 123789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul 123889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul for (i = 0; i < rows; i++) { 123989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul MEMCPY(dest, src, bytesPerRow); 124089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul dest += destRowStride; 124189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul src += srcRowStride; 124289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul } 124389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul} 124489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul 124589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul 124689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul/** 124789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * Fallback for Driver.CompressedTexSubImage3D() 124889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul */ 124989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paulvoid 125089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul_mesa_store_compressed_texsubimage3d(GLcontext *ctx, GLenum target, 125189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul GLint level, 125289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul GLint xoffset, GLint yoffset, GLint zoffset, 125389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul GLsizei width, GLsizei height, GLsizei depth, 125489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul GLenum format, 125589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul GLsizei imageSize, const GLvoid *data, 125689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul struct gl_texture_object *texObj, 125789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul struct gl_texture_image *texImage) 125889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul{ 125989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul /* this space intentionally left blank */ 126089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul} 126189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul 126289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul 126389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul 126489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul 1265e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul 1266e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul/* 12678e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * This is the fallback for Driver.TestProxyTexImage(). 12688e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul */ 12698e39ad2cd67d49be40ff0822f3269affdf83d601Brian PaulGLboolean 12708e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul_mesa_test_proxy_teximage(GLcontext *ctx, GLenum target, GLint level, 12718e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul GLint internalFormat, GLenum format, GLenum type, 12728e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul GLint width, GLint height, GLint depth, GLint border) 12738e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul{ 12748e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul struct gl_texture_unit *texUnit; 12758e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul struct gl_texture_object *texObj; 12768e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul struct gl_texture_image *texImage; 12778e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul 12788e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul (void) format; 12798e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul (void) type; 12808e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul 12818e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; 12828e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul texObj = _mesa_select_tex_object(ctx, texUnit, target); 12838e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul texImage = _mesa_select_tex_image(ctx, texUnit, target, level); 12848e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul 12858e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul /* We always pass. 12868e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * The core Mesa code will have already tested the image size, etc. 12879228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul * If a driver has more stringent texture limits to enforce it will 12888e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * have to override this function. 12898e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul */ 12907d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul /* choose the texture format */ 12917d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul assert(ctx->Driver.ChooseTextureFormat); 12927d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul texImage->TexFormat = (*ctx->Driver.ChooseTextureFormat)(ctx, 12937d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul internalFormat, format, type); 12947d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul assert(texImage->TexFormat); 12958e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul 12968e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul return GL_TRUE; 12978e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul} 12983893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul 12993893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul 13003893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul 13013893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul/* 13023893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul * Average together two rows of a source image to produce a single new 13033893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul * row in the dest image. It's legal for the two source rows to point 13049228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul * to the same data. The source width must be equal to either the 13059228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul * dest width or two times the dest width. 13063893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul */ 13073893e638e6521b9c070e01c0b31d22754ff97a88Brian Paulstatic void 13089228e17bb5bf219269daeed5cbfdd912c118e926Brian Pauldo_row(const struct gl_texture_format *format, GLint srcWidth, 13099228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLvoid *srcRowA, const GLvoid *srcRowB, 13109228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul GLint dstWidth, GLvoid *dstRow) 13113893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul{ 13129228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLuint k0 = (srcWidth == dstWidth) ? 0 : 1; 13139228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLuint colStride = (srcWidth == dstWidth) ? 1 : 2; 13149228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul 13159228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul assert(srcWidth == dstWidth || srcWidth == 2 * dstWidth); 13169228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul 13173893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul switch (format->MesaFormat) { 13183893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul case MESA_FORMAT_RGBA: 13193893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul { 13209228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul GLuint i, j, k; 13213893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul const GLchan (*rowA)[4] = (const GLchan (*)[4]) srcRowA; 13223893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul const GLchan (*rowB)[4] = (const GLchan (*)[4]) srcRowB; 13233893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul GLchan (*dst)[4] = (GLchan (*)[4]) dstRow; 13247c4268176eaaeb45003db4d5042a518b84c9f6dcKarl Schultz for (i = j = 0, k = k0; i < (GLuint) dstWidth; 13259228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul i++, j += colStride, k += colStride) { 13269228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul dst[i][0] = (rowA[j][0] + rowA[k][0] + 1327f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul rowB[j][0] + rowB[k][0]) / 4; 13289228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul dst[i][1] = (rowA[j][1] + rowA[k][1] + 1329f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul rowB[j][1] + rowB[k][1]) / 4; 13309228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul dst[i][2] = (rowA[j][2] + rowA[k][2] + 1331f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul rowB[j][2] + rowB[k][2]) / 4; 13329228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul dst[i][3] = (rowA[j][3] + rowA[k][3] + 1333f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul rowB[j][3] + rowB[k][3]) / 4; 13343893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul } 13353893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul } 13363893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul return; 13373893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul case MESA_FORMAT_RGB: 13383893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul { 13399228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul GLuint i, j, k; 13403893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul const GLchan (*rowA)[3] = (const GLchan (*)[3]) srcRowA; 13413893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul const GLchan (*rowB)[3] = (const GLchan (*)[3]) srcRowB; 13423893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul GLchan (*dst)[3] = (GLchan (*)[3]) dstRow; 13437c4268176eaaeb45003db4d5042a518b84c9f6dcKarl Schultz for (i = j = 0, k = k0; i < (GLuint) dstWidth; 13449228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul i++, j += colStride, k += colStride) { 13459228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul dst[i][0] = (rowA[j][0] + rowA[k][0] + 1346f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul rowB[j][0] + rowB[k][0]) / 4; 13479228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul dst[i][1] = (rowA[j][1] + rowA[k][1] + 1348f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul rowB[j][1] + rowB[k][1]) / 4; 13499228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul dst[i][2] = (rowA[j][2] + rowA[k][2] + 1350f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul rowB[j][2] + rowB[k][2]) / 4; 13513893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul } 13523893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul } 13533893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul return; 13543893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul case MESA_FORMAT_ALPHA: 13553893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul case MESA_FORMAT_LUMINANCE: 13563893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul case MESA_FORMAT_INTENSITY: 13573893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul case MESA_FORMAT_COLOR_INDEX: 13583893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul { 13599228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul GLuint i, j, k; 13603893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul const GLchan *rowA = (const GLchan *) srcRowA; 13613893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul const GLchan *rowB = (const GLchan *) srcRowB; 13623893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul GLchan *dst = (GLchan *) dstRow; 13637c4268176eaaeb45003db4d5042a518b84c9f6dcKarl Schultz for (i = j = 0, k = k0; i < (GLuint) dstWidth; 13649228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul i++, j += colStride, k += colStride) { 1365f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul dst[i] = (rowA[j] + rowA[k] + rowB[j] + rowB[k]) / 4; 13663893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul } 13673893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul } 13683893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul return; 13693893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul case MESA_FORMAT_LUMINANCE_ALPHA: 13703893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul { 13719228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul GLuint i, j, k; 13723893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul const GLchan (*rowA)[2] = (const GLchan (*)[2]) srcRowA; 13733893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul const GLchan (*rowB)[2] = (const GLchan (*)[2]) srcRowB; 13743893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul GLchan (*dst)[2] = (GLchan (*)[2]) dstRow; 13757c4268176eaaeb45003db4d5042a518b84c9f6dcKarl Schultz for (i = j = 0, k = k0; i < (GLuint) dstWidth; 13769228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul i++, j += colStride, k += colStride) { 13779228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul dst[i][0] = (rowA[j][0] + rowA[k][0] + 1378f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul rowB[j][0] + rowB[k][0]) / 4; 13799228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul dst[i][1] = (rowA[j][1] + rowA[k][1] + 1380f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul rowB[j][1] + rowB[k][1]) / 4; 13813893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul } 13823893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul } 13833893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul return; 13843893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul case MESA_FORMAT_DEPTH_COMPONENT: 13858bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul { 13869228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul GLuint i, j, k; 13878bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul const GLfloat *rowA = (const GLfloat *) srcRowA; 13888bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul const GLfloat *rowB = (const GLfloat *) srcRowB; 13898bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul GLfloat *dst = (GLfloat *) dstRow; 13907c4268176eaaeb45003db4d5042a518b84c9f6dcKarl Schultz for (i = j = 0, k = k0; i < (GLuint) dstWidth; 13919228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul i++, j += colStride, k += colStride) { 13929228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul dst[i] = (rowA[j] + rowA[k] + rowB[j] + rowB[k]) * 0.25F; 13938bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul } 13948bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul } 13958bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul return; 13968bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul /* Begin hardware formats */ 13978bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul case MESA_FORMAT_RGBA8888: 13988bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul case MESA_FORMAT_ARGB8888: 13998bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul { 14009228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul GLuint i, j, k; 14018bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul const GLubyte (*rowA)[4] = (const GLubyte (*)[4]) srcRowA; 14028bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul const GLubyte (*rowB)[4] = (const GLubyte (*)[4]) srcRowB; 14038bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul GLubyte (*dst)[4] = (GLubyte (*)[4]) dstRow; 14047c4268176eaaeb45003db4d5042a518b84c9f6dcKarl Schultz for (i = j = 0, k = k0; i < (GLuint) dstWidth; 14059228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul i++, j += colStride, k += colStride) { 14069228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul dst[i][0] = (rowA[j][0] + rowA[k][0] + 1407f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul rowB[j][0] + rowB[k][0]) / 4; 14089228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul dst[i][1] = (rowA[j][1] + rowA[k][1] + 1409f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul rowB[j][1] + rowB[k][1]) / 4; 14109228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul dst[i][2] = (rowA[j][2] + rowA[k][2] + 1411f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul rowB[j][2] + rowB[k][2]) / 4; 14129228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul dst[i][3] = (rowA[j][3] + rowA[k][3] + 1413f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul rowB[j][3] + rowB[k][3]) / 4; 14148bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul } 14158bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul } 14168bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul return; 14178bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul case MESA_FORMAT_RGB888: 14188bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul { 14199228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul GLuint i, j, k; 14208bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul const GLubyte (*rowA)[3] = (const GLubyte (*)[3]) srcRowA; 14218bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul const GLubyte (*rowB)[3] = (const GLubyte (*)[3]) srcRowB; 14228bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul GLubyte (*dst)[3] = (GLubyte (*)[3]) dstRow; 14237c4268176eaaeb45003db4d5042a518b84c9f6dcKarl Schultz for (i = j = 0, k = k0; i < (GLuint) dstWidth; 14249228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul i++, j += colStride, k += colStride) { 14259228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul dst[i][0] = (rowA[j][0] + rowA[k][0] + 1426f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul rowB[j][0] + rowB[k][0]) / 4; 14279228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul dst[i][1] = (rowA[j][1] + rowA[k][1] + 1428f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul rowB[j][1] + rowB[k][1]) / 4; 14299228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul dst[i][2] = (rowA[j][2] + rowA[k][2] + 1430f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul rowB[j][2] + rowB[k][2]) / 4; 14318bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul } 14328bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul } 14338bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul return; 14348bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul case MESA_FORMAT_RGB565: 14358bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul { 14369228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul GLuint i, j, k; 14378bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul const GLushort *rowA = (const GLushort *) srcRowA; 14388bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul const GLushort *rowB = (const GLushort *) srcRowB; 14398bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul GLushort *dst = (GLushort *) dstRow; 14407c4268176eaaeb45003db4d5042a518b84c9f6dcKarl Schultz for (i = j = 0, k = k0; i < (GLuint) dstWidth; 14419228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul i++, j += colStride, k += colStride) { 14429228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLint rowAr0 = rowA[j] & 0x1f; 14439228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLint rowAr1 = rowA[k] & 0x1f; 14449228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLint rowBr0 = rowB[j] & 0x1f; 14459228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLint rowBr1 = rowB[k] & 0x1f; 14469228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLint rowAg0 = (rowA[j] >> 5) & 0x3f; 14479228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLint rowAg1 = (rowA[k] >> 5) & 0x3f; 14489228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLint rowBg0 = (rowB[j] >> 5) & 0x3f; 14499228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLint rowBg1 = (rowB[k] >> 5) & 0x3f; 14509228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLint rowAb0 = (rowA[j] >> 11) & 0x1f; 14519228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLint rowAb1 = (rowA[k] >> 11) & 0x1f; 14529228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLint rowBb0 = (rowB[j] >> 11) & 0x1f; 14539228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLint rowBb1 = (rowB[k] >> 11) & 0x1f; 14548bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul const GLint red = (rowAr0 + rowAr1 + rowBr0 + rowBr1) >> 4; 14558bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul const GLint green = (rowAg0 + rowAg1 + rowBg0 + rowBg1) >> 4; 14568bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul const GLint blue = (rowAb0 + rowAb1 + rowBb0 + rowBb1) >> 4; 14578bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul dst[i] = (blue << 11) | (green << 5) | red; 14588bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul } 14598bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul } 14608bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul return; 14618bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul case MESA_FORMAT_ARGB4444: 14628bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul { 14639228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul GLuint i, j, k; 14648bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul const GLushort *rowA = (const GLushort *) srcRowA; 14658bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul const GLushort *rowB = (const GLushort *) srcRowB; 14668bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul GLushort *dst = (GLushort *) dstRow; 14677c4268176eaaeb45003db4d5042a518b84c9f6dcKarl Schultz for (i = j = 0, k = k0; i < (GLuint) dstWidth; 14689228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul i++, j += colStride, k += colStride) { 14699228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLint rowAr0 = rowA[j] & 0xf; 14709228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLint rowAr1 = rowA[k] & 0xf; 14719228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLint rowBr0 = rowB[j] & 0xf; 14729228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLint rowBr1 = rowB[k] & 0xf; 14739228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLint rowAg0 = (rowA[j] >> 4) & 0xf; 14749228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLint rowAg1 = (rowA[k] >> 4) & 0xf; 14759228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLint rowBg0 = (rowB[j] >> 4) & 0xf; 14769228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLint rowBg1 = (rowB[k] >> 4) & 0xf; 14779228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLint rowAb0 = (rowA[j] >> 8) & 0xf; 14789228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLint rowAb1 = (rowA[k] >> 8) & 0xf; 14799228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLint rowBb0 = (rowB[j] >> 8) & 0xf; 14809228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLint rowBb1 = (rowB[k] >> 8) & 0xf; 14819228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLint rowAa0 = (rowA[j] >> 12) & 0xf; 14829228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLint rowAa1 = (rowA[k] >> 12) & 0xf; 14839228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLint rowBa0 = (rowB[j] >> 12) & 0xf; 14849228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLint rowBa1 = (rowB[k] >> 12) & 0xf; 14858bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul const GLint red = (rowAr0 + rowAr1 + rowBr0 + rowBr1) >> 4; 14868bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul const GLint green = (rowAg0 + rowAg1 + rowBg0 + rowBg1) >> 4; 14878bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul const GLint blue = (rowAb0 + rowAb1 + rowBb0 + rowBb1) >> 4; 14888bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul const GLint alpha = (rowAa0 + rowAa1 + rowBa0 + rowBa1) >> 4; 14898bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul dst[i] = (alpha << 12) | (blue << 8) | (green << 4) | red; 14908bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul } 14918bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul } 14928bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul return; 14938bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul case MESA_FORMAT_ARGB1555: 14948bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul { 14959228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul GLuint i, j, k; 14968bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul const GLushort *rowA = (const GLushort *) srcRowA; 14978bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul const GLushort *rowB = (const GLushort *) srcRowB; 14988bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul GLushort *dst = (GLushort *) dstRow; 14997c4268176eaaeb45003db4d5042a518b84c9f6dcKarl Schultz for (i = j = 0, k = k0; i < (GLuint) dstWidth; 15009228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul i++, j += colStride, k += colStride) { 15019228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLint rowAr0 = rowA[j] & 0x1f; 15029228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLint rowAr1 = rowA[k] & 0x1f; 15039228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLint rowBr0 = rowB[j] & 0x1f; 15049228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLint rowBr1 = rowB[k] & 0xf; 15059228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLint rowAg0 = (rowA[j] >> 5) & 0x1f; 15069228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLint rowAg1 = (rowA[k] >> 5) & 0x1f; 15079228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLint rowBg0 = (rowB[j] >> 5) & 0x1f; 15089228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLint rowBg1 = (rowB[k] >> 5) & 0x1f; 15099228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLint rowAb0 = (rowA[j] >> 10) & 0x1f; 15109228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLint rowAb1 = (rowA[k] >> 10) & 0x1f; 15119228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLint rowBb0 = (rowB[j] >> 10) & 0x1f; 15129228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLint rowBb1 = (rowB[k] >> 10) & 0x1f; 15139228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLint rowAa0 = (rowA[j] >> 15) & 0x1; 15149228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLint rowAa1 = (rowA[k] >> 15) & 0x1; 15159228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLint rowBa0 = (rowB[j] >> 15) & 0x1; 15169228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLint rowBa1 = (rowB[k] >> 15) & 0x1; 15178bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul const GLint red = (rowAr0 + rowAr1 + rowBr0 + rowBr1) >> 4; 15188bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul const GLint green = (rowAg0 + rowAg1 + rowBg0 + rowBg1) >> 4; 15198bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul const GLint blue = (rowAb0 + rowAb1 + rowBb0 + rowBb1) >> 4; 15208bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul const GLint alpha = (rowAa0 + rowAa1 + rowBa0 + rowBa1) >> 4; 15218bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul dst[i] = (alpha << 15) | (blue << 10) | (green << 5) | red; 15228bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul } 15238bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul } 15248bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul return; 15258bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul case MESA_FORMAT_AL88: 15268bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul { 15279228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul GLuint i, j, k; 15288bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul const GLubyte (*rowA)[2] = (const GLubyte (*)[2]) srcRowA; 15298bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul const GLubyte (*rowB)[2] = (const GLubyte (*)[2]) srcRowB; 15308bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul GLubyte (*dst)[2] = (GLubyte (*)[2]) dstRow; 15317c4268176eaaeb45003db4d5042a518b84c9f6dcKarl Schultz for (i = j = 0, k = k0; i < (GLuint) dstWidth; 15329228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul i++, j += colStride, k += colStride) { 15339228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul dst[i][0] = (rowA[j][0] + rowA[k][0] + 15349228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul rowB[j][0] + rowB[k][0]) >> 2; 15359228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul dst[i][1] = (rowA[j][1] + rowA[k][1] + 15369228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul rowB[j][1] + rowB[k][1]) >> 2; 15378bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul } 15388bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul } 15398bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul return; 15408bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul case MESA_FORMAT_RGB332: 15418bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul { 15429228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul GLuint i, j, k; 15438bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul const GLubyte *rowA = (const GLubyte *) srcRowA; 15448bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul const GLubyte *rowB = (const GLubyte *) srcRowB; 15458bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul GLubyte *dst = (GLubyte *) dstRow; 15467c4268176eaaeb45003db4d5042a518b84c9f6dcKarl Schultz for (i = j = 0, k = k0; i < (GLuint) dstWidth; 15479228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul i++, j += colStride, k += colStride) { 15489228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLint rowAr0 = rowA[j] & 0x3; 15499228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLint rowAr1 = rowA[k] & 0x3; 15509228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLint rowBr0 = rowB[j] & 0x3; 15519228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLint rowBr1 = rowB[k] & 0x3; 15529228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLint rowAg0 = (rowA[j] >> 2) & 0x7; 15539228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLint rowAg1 = (rowA[k] >> 2) & 0x7; 15549228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLint rowBg0 = (rowB[j] >> 2) & 0x7; 15559228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLint rowBg1 = (rowB[k] >> 2) & 0x7; 15569228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLint rowAb0 = (rowA[j] >> 5) & 0x7; 15579228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLint rowAb1 = (rowA[k] >> 5) & 0x7; 15589228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLint rowBb0 = (rowB[j] >> 5) & 0x7; 15599228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLint rowBb1 = (rowB[k] >> 5) & 0x7; 15608bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul const GLint red = (rowAr0 + rowAr1 + rowBr0 + rowBr1) >> 4; 15618bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul const GLint green = (rowAg0 + rowAg1 + rowBg0 + rowBg1) >> 4; 15628bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul const GLint blue = (rowAb0 + rowAb1 + rowBb0 + rowBb1) >> 4; 15638bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul dst[i] = (blue << 5) | (green << 2) | red; 15648bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul } 15658bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul } 15668bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul return; 15678bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul case MESA_FORMAT_A8: 15688bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul case MESA_FORMAT_L8: 15698bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul case MESA_FORMAT_I8: 15708bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul case MESA_FORMAT_CI8: 15718bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul { 15729228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul GLuint i, j, k; 15738bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul const GLubyte *rowA = (const GLubyte *) srcRowA; 15748bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul const GLubyte *rowB = (const GLubyte *) srcRowB; 15758bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul GLubyte *dst = (GLubyte *) dstRow; 15767c4268176eaaeb45003db4d5042a518b84c9f6dcKarl Schultz for (i = j = 0, k = k0; i < (GLuint) dstWidth; 15779228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul i++, j += colStride, k += colStride) { 15789228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul dst[i] = (rowA[j] + rowA[k] + rowB[j] + rowB[k]) >> 2; 15798bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul } 15808bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul } 15818bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul return; 15823893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul default: 15833893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul _mesa_problem(NULL, "bad format in do_row()"); 15843893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul } 15853893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul} 15863893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul 15873893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul 15889228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul/* 15899228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul * These functions generate a 1/2-size mipmap image from a source image. 15909228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul * Texture borders are handled by copying or averaging the source image's 15919228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul * border texels, depending on the scale-down factor. 15929228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul */ 15933893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul 15943893e638e6521b9c070e01c0b31d22754ff97a88Brian Paulstatic void 15953893e638e6521b9c070e01c0b31d22754ff97a88Brian Paulmake_1d_mipmap(const struct gl_texture_format *format, GLint border, 15963893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul GLint srcWidth, const GLubyte *srcPtr, 15973893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul GLint dstWidth, GLubyte *dstPtr) 15983893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul{ 15993893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul const GLint bpt = format->TexelBytes; 16003893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul const GLubyte *src; 16013893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul GLubyte *dst; 16023893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul 16033893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul /* skip the border pixel, if any */ 16043893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul src = srcPtr + border * bpt; 16053893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul dst = dstPtr + border * bpt; 16063893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul 16073893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul /* we just duplicate the input row, kind of hack, saves code */ 16089228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul do_row(format, srcWidth - 2 * border, src, src, 16099228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul dstWidth - 2 * border, dst); 16103893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul 16113893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul if (border) { 16123893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul /* copy left-most pixel from source */ 16133893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul MEMCPY(dstPtr, srcPtr, bpt); 16143893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul /* copy right-most pixel from source */ 16153893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul MEMCPY(dstPtr + (dstWidth - 1) * bpt, 16163893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul srcPtr + (srcWidth - 1) * bpt, 16173893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul bpt); 16183893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul } 16193893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul} 16203893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul 16213893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul 16223893e638e6521b9c070e01c0b31d22754ff97a88Brian Paulstatic void 16233893e638e6521b9c070e01c0b31d22754ff97a88Brian Paulmake_2d_mipmap(const struct gl_texture_format *format, GLint border, 16243893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul GLint srcWidth, GLint srcHeight, const GLubyte *srcPtr, 16253893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul GLint dstWidth, GLint dstHeight, GLubyte *dstPtr) 16263893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul{ 16273893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul const GLint bpt = format->TexelBytes; 16289228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLint srcWidthNB = srcWidth - 2 * border; /* sizes w/out border */ 16299228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLint dstWidthNB = dstWidth - 2 * border; 16309228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLint dstHeightNB = dstHeight - 2 * border; 16313893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul const GLint srcRowStride = bpt * srcWidth; 16323893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul const GLint dstRowStride = bpt * dstWidth; 16333893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul const GLubyte *srcA, *srcB; 16343893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul GLubyte *dst; 16359228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul GLint row, colStride; 16369228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul 16379228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul colStride = (srcWidth == dstWidth) ? 1 : 2; 16383893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul 16393893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul /* Compute src and dst pointers, skipping any border */ 16403893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul srcA = srcPtr + border * ((srcWidth + 1) * bpt); 16413893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul if (srcHeight > 1) 16423893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul srcB = srcA + srcRowStride; 16433893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul else 16443893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul srcB = srcA; 16453893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul dst = dstPtr + border * ((dstWidth + 1) * bpt); 16463893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul 16479228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul for (row = 0; row < dstHeightNB; row++) { 16489228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul do_row(format, srcWidthNB, srcA, srcB, 16499228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul dstWidthNB, dst); 16503893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul srcA += 2 * srcRowStride; 16513893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul srcB += 2 * srcRowStride; 16523893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul dst += dstRowStride; 16533893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul } 16543893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul 16558bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul /* This is ugly but probably won't be used much */ 16563893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul if (border > 0) { 16573893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul /* fill in dest border */ 16583893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul /* lower-left border pixel */ 16593893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul MEMCPY(dstPtr, srcPtr, bpt); 16603893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul /* lower-right border pixel */ 16613893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul MEMCPY(dstPtr + (dstWidth - 1) * bpt, 16623893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul srcPtr + (srcWidth - 1) * bpt, bpt); 16633893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul /* upper-left border pixel */ 16643893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul MEMCPY(dstPtr + dstWidth * (dstHeight - 1) * bpt, 16653893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul srcPtr + srcWidth * (srcHeight - 1) * bpt, bpt); 16663893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul /* upper-right border pixel */ 16673893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul MEMCPY(dstPtr + (dstWidth * dstHeight - 1) * bpt, 16683893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul srcPtr + (srcWidth * srcHeight - 1) * bpt, bpt); 16693893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul /* lower border */ 16709228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul do_row(format, srcWidthNB, 16719228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul srcPtr + bpt, 16729228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul srcPtr + bpt, 16739228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul dstWidthNB, dstPtr + bpt); 16743893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul /* upper border */ 16759228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul do_row(format, srcWidthNB, 16763893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul srcPtr + (srcWidth * (srcHeight - 1) + 1) * bpt, 16773893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul srcPtr + (srcWidth * (srcHeight - 1) + 1) * bpt, 16789228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul dstWidthNB, 16793893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul dstPtr + (dstWidth * (dstHeight - 1) + 1) * bpt); 16803893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul /* left and right borders */ 16819228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul if (srcHeight == dstHeight) { 16829228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul /* copy border pixel from src to dst */ 16839228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul for (row = 1; row < srcHeight; row++) { 16849228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul MEMCPY(dstPtr + dstWidth * row * bpt, 16859228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul srcPtr + srcWidth * row * bpt, bpt); 16869228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul MEMCPY(dstPtr + (dstWidth * row + dstWidth - 1) * bpt, 16879228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul srcPtr + (srcWidth * row + srcWidth - 1) * bpt, bpt); 16889228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul } 16899228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul } 16909228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul else { 16919228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul /* average two src pixels each dest pixel */ 16929228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul for (row = 0; row < dstHeightNB; row += 2) { 16939228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul do_row(format, 1, 16949228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul srcPtr + (srcWidth * (row * 2 + 1)) * bpt, 16959228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul srcPtr + (srcWidth * (row * 2 + 2)) * bpt, 16969228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul 1, dstPtr + (dstWidth * row + 1) * bpt); 16979228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul do_row(format, 1, 16989228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul srcPtr + (srcWidth * (row * 2 + 1) + srcWidth - 1) * bpt, 16999228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul srcPtr + (srcWidth * (row * 2 + 2) + srcWidth - 1) * bpt, 17009228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul 1, dstPtr + (dstWidth * row + 1 + dstWidth - 1) * bpt); 17019228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul } 17023893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul } 17033893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul } 17043893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul} 17053893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul 17063893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul 17073893e638e6521b9c070e01c0b31d22754ff97a88Brian Paulstatic void 17083893e638e6521b9c070e01c0b31d22754ff97a88Brian Paulmake_3d_mipmap(const struct gl_texture_format *format, GLint border, 17093893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul GLint srcWidth, GLint srcHeight, GLint srcDepth, 17103893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul const GLubyte *srcPtr, 17113893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul GLint dstWidth, GLint dstHeight, GLint dstDepth, 17123893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul GLubyte *dstPtr) 17133893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul{ 17149228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLint bpt = format->TexelBytes; 17159228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLint srcWidthNB = srcWidth - 2 * border; /* sizes w/out border */ 17169228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLint srcDepthNB = srcDepth - 2 * border; 17179228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLint dstWidthNB = dstWidth - 2 * border; 17189228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLint dstHeightNB = dstHeight - 2 * border; 17199228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLint dstDepthNB = dstDepth - 2 * border; 17209228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul GLvoid *tmpRowA, *tmpRowB; 17213893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul GLint img, row; 17229228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul GLint bytesPerSrcImage, bytesPerDstImage; 17239228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul GLint bytesPerSrcRow, bytesPerDstRow; 17249228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul GLint srcImageOffset, srcRowOffset; 17253893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul 17265c749d9e3c7824c0ba5b22e37d0ea5cbd54d6d2dBrian Paul (void) srcDepthNB; /* silence warnings */ 17275c749d9e3c7824c0ba5b22e37d0ea5cbd54d6d2dBrian Paul 17289228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul /* Need two temporary row buffers */ 17299228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul tmpRowA = MALLOC(srcWidth * bpt); 17309228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul if (!tmpRowA) 17319228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul return; 17329228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul tmpRowB = MALLOC(srcWidth * bpt); 17339228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul if (!tmpRowB) { 17349228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul FREE(tmpRowA); 17353893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul return; 17363893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul } 17373893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul 17389228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul bytesPerSrcImage = srcWidth * srcHeight * bpt; 17399228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul bytesPerDstImage = dstWidth * dstHeight * bpt; 17409228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul 17419228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul bytesPerSrcRow = srcWidth * bpt; 17429228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul bytesPerDstRow = dstWidth * bpt; 17433893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul 17449228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul /* Offset between adjacent src images to be averaged together */ 17459228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul srcImageOffset = (srcDepth == dstDepth) ? 0 : bytesPerSrcImage; 17463893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul 17479228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul /* Offset between adjacent src rows to be averaged together */ 17489228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul srcRowOffset = (srcHeight == dstHeight) ? 0 : srcWidth * bpt; 17493893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul 17509228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul /* 17519228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul * Need to average together up to 8 src pixels for each dest pixel. 17529228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul * Break that down into 3 operations: 17539228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul * 1. take two rows from source image and average them together. 17549228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul * 2. take two rows from next source image and average them together. 17559228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul * 3. take the two averaged rows and average them for the final dst row. 17569228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul */ 17573893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul 17589228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul /* 17594e9676fb13f60ecdbc247b120031f18cd3febcb0Brian Paul _mesa_printf("mip3d %d x %d x %d -> %d x %d x %d\n", 17609228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul srcWidth, srcHeight, srcDepth, dstWidth, dstHeight, dstDepth); 17619228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul */ 17629228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul 17639228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul for (img = 0; img < dstDepthNB; img++) { 17649228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul /* first source image pointer, skipping border */ 17659228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLubyte *imgSrcA = srcPtr 17669228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul + (bytesPerSrcImage + bytesPerSrcRow + border) * bpt * border 17679228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul + img * (bytesPerSrcImage + srcImageOffset); 17689228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul /* second source image pointer, skipping border */ 17699228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLubyte *imgSrcB = imgSrcA + srcImageOffset; 17709228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul /* address of the dest image, skipping border */ 17719228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul GLubyte *imgDst = dstPtr 17729228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul + (bytesPerDstImage + bytesPerDstRow + border) * bpt * border 17739228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul + img * bytesPerDstImage; 17749228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul 17759228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul /* setup the four source row pointers and the dest row pointer */ 17769228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLubyte *srcImgARowA = imgSrcA; 17779228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLubyte *srcImgARowB = imgSrcA + srcRowOffset; 17789228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLubyte *srcImgBRowA = imgSrcB; 17799228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLubyte *srcImgBRowB = imgSrcB + srcRowOffset; 17809228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul GLubyte *dstImgRow = imgDst; 17819228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul 17829228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul for (row = 0; row < dstHeightNB; row++) { 17839228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul /* Average together two rows from first src image */ 17849228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul do_row(format, srcWidthNB, srcImgARowA, srcImgARowB, 17859228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul srcWidthNB, tmpRowA); 17869228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul /* Average together two rows from second src image */ 17879228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul do_row(format, srcWidthNB, srcImgBRowA, srcImgBRowB, 17889228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul srcWidthNB, tmpRowB); 17899228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul /* Average together the temp rows to make the final row */ 17909228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul do_row(format, srcWidthNB, tmpRowA, tmpRowB, 17919228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul dstWidthNB, dstImgRow); 17929228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul /* advance to next rows */ 17939228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul srcImgARowA += bytesPerSrcRow + srcRowOffset; 17949228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul srcImgARowB += bytesPerSrcRow + srcRowOffset; 17959228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul srcImgBRowA += bytesPerSrcRow + srcRowOffset; 17969228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul srcImgBRowB += bytesPerSrcRow + srcRowOffset; 17979228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul dstImgRow += bytesPerDstRow; 17983893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul } 17993893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul } 18003893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul 18013893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul FREE(tmpRowA); 18023893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul FREE(tmpRowB); 18039228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul 18049228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul /* Luckily we can leverage the make_2d_mipmap() function here! */ 18059228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul if (border > 0) { 18069228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul /* do front border image */ 18079228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul make_2d_mipmap(format, 1, srcWidth, srcHeight, srcPtr, 18089228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul dstWidth, dstHeight, dstPtr); 18099228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul /* do back border image */ 18109228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul make_2d_mipmap(format, 1, srcWidth, srcHeight, 18119228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul srcPtr + bytesPerSrcImage * (srcDepth - 1), 18129228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul dstWidth, dstHeight, 18139228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul dstPtr + bytesPerDstImage * (dstDepth - 1)); 18149228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul /* do four remaining border edges that span the image slices */ 18159228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul if (srcDepth == dstDepth) { 18169228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul /* just copy border pixels from src to dst */ 18179228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul for (img = 0; img < dstDepthNB; img++) { 18189228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLubyte *src; 18199228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul GLubyte *dst; 18209228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul 18219228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul /* do border along [img][row=0][col=0] */ 18229228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul src = srcPtr + (img + 1) * bytesPerSrcImage; 18239228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul dst = dstPtr + (img + 1) * bytesPerDstImage; 18249228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul MEMCPY(dst, src, bpt); 18259228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul 18269228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul /* do border along [img][row=dstHeight-1][col=0] */ 18279228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul src = srcPtr + (img * 2 + 1) * bytesPerSrcImage 18289228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul + (srcHeight - 1) * bytesPerSrcRow; 18299228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul dst = dstPtr + (img + 1) * bytesPerDstImage 18309228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul + (dstHeight - 1) * bytesPerDstRow; 18319228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul MEMCPY(dst, src, bpt); 18329228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul 18339228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul /* do border along [img][row=0][col=dstWidth-1] */ 18349228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul src = srcPtr + (img * 2 + 1) * bytesPerSrcImage 18359228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul + (srcWidth - 1) * bpt; 18369228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul dst = dstPtr + (img + 1) * bytesPerDstImage 18379228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul + (dstWidth - 1) * bpt; 18389228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul MEMCPY(dst, src, bpt); 18399228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul 18409228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul /* do border along [img][row=dstHeight-1][col=dstWidth-1] */ 18419228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul src = srcPtr + (img * 2 + 1) * bytesPerSrcImage 18429228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul + (bytesPerSrcImage - bpt); 18439228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul dst = dstPtr + (img + 1) * bytesPerDstImage 18449228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul + (bytesPerDstImage - bpt); 18459228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul MEMCPY(dst, src, bpt); 18469228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul } 18479228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul } 18489228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul else { 18499228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul /* average border pixels from adjacent src image pairs */ 18509228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul ASSERT(srcDepthNB == 2 * dstDepthNB); 18519228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul for (img = 0; img < dstDepthNB; img++) { 18529228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLubyte *src; 18539228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul GLubyte *dst; 18549228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul 18559228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul /* do border along [img][row=0][col=0] */ 18569228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul src = srcPtr + (img * 2 + 1) * bytesPerSrcImage; 18579228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul dst = dstPtr + (img + 1) * bytesPerDstImage; 18589228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul do_row(format, 1, src, src + srcImageOffset, 1, dst); 18599228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul 18609228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul /* do border along [img][row=dstHeight-1][col=0] */ 18619228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul src = srcPtr + (img * 2 + 1) * bytesPerSrcImage 18629228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul + (srcHeight - 1) * bytesPerSrcRow; 18639228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul dst = dstPtr + (img + 1) * bytesPerDstImage 18649228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul + (dstHeight - 1) * bytesPerDstRow; 18659228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul do_row(format, 1, src, src + srcImageOffset, 1, dst); 18669228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul 18679228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul /* do border along [img][row=0][col=dstWidth-1] */ 18689228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul src = srcPtr + (img * 2 + 1) * bytesPerSrcImage 18699228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul + (srcWidth - 1) * bpt; 18709228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul dst = dstPtr + (img + 1) * bytesPerDstImage 18719228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul + (dstWidth - 1) * bpt; 18729228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul do_row(format, 1, src, src + srcImageOffset, 1, dst); 18739228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul 18749228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul /* do border along [img][row=dstHeight-1][col=dstWidth-1] */ 18759228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul src = srcPtr + (img * 2 + 1) * bytesPerSrcImage 18769228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul + (bytesPerSrcImage - bpt); 18779228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul dst = dstPtr + (img + 1) * bytesPerDstImage 18789228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul + (bytesPerDstImage - bpt); 18799228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul do_row(format, 1, src, src + srcImageOffset, 1, dst); 18809228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul } 18819228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul } 18829228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul } 18833893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul} 18843893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul 18853893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul 18863893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul/* 18873893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul * For GL_SGIX_generate_mipmap: 18883893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul * Generate a complete set of mipmaps from texObj's base-level image. 18893893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul * Stop at texObj's MaxLevel or when we get to the 1x1 texture. 18903893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul */ 18913893e638e6521b9c070e01c0b31d22754ff97a88Brian Paulvoid 1892d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul_mesa_generate_mipmap(GLcontext *ctx, GLenum target, 18933893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul const struct gl_texture_unit *texUnit, 18943893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul struct gl_texture_object *texObj) 18953893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul{ 18962ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul const struct gl_texture_image *srcImage; 18972ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul const struct gl_texture_format *convertFormat; 189889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul const GLubyte *srcData; 189989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul GLubyte *dstData; 19007c4268176eaaeb45003db4d5042a518b84c9f6dcKarl Schultz GLint level; 1901cd1cefae9146fc14b35ee93a04bdb1b1590fba7bBrian Paul GLint maxLevels = 0; 19023893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul 19033893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul ASSERT(texObj); 19042ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul srcImage = texObj->Image[texObj->BaseLevel]; 19052ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul ASSERT(srcImage); 19063893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul 19078afe7de8deaf3c9613fd68b344de8c52b02b1879Brian Paul switch (texObj->Target) { 19088afe7de8deaf3c9613fd68b344de8c52b02b1879Brian Paul case GL_TEXTURE_1D: 1909cd1cefae9146fc14b35ee93a04bdb1b1590fba7bBrian Paul maxLevels = ctx->Const.MaxTextureLevels; 19103893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul break; 19118afe7de8deaf3c9613fd68b344de8c52b02b1879Brian Paul case GL_TEXTURE_2D: 1912cd1cefae9146fc14b35ee93a04bdb1b1590fba7bBrian Paul maxLevels = ctx->Const.MaxTextureLevels; 19133893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul break; 19148afe7de8deaf3c9613fd68b344de8c52b02b1879Brian Paul case GL_TEXTURE_3D: 1915cd1cefae9146fc14b35ee93a04bdb1b1590fba7bBrian Paul maxLevels = ctx->Const.Max3DTextureLevels; 19163893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul break; 19178afe7de8deaf3c9613fd68b344de8c52b02b1879Brian Paul case GL_TEXTURE_CUBE_MAP_ARB: 1918cd1cefae9146fc14b35ee93a04bdb1b1590fba7bBrian Paul maxLevels = ctx->Const.MaxCubeTextureLevels; 19193893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul break; 19208afe7de8deaf3c9613fd68b344de8c52b02b1879Brian Paul case GL_TEXTURE_RECTANGLE_NV: 19218afe7de8deaf3c9613fd68b344de8c52b02b1879Brian Paul maxLevels = 1; 19228afe7de8deaf3c9613fd68b344de8c52b02b1879Brian Paul break; 19233893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul default: 19243893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul _mesa_problem(ctx, 19253893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul "Bad texture object dimension in _mesa_generate_mipmaps"); 19263893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul return; 19273893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul } 19283893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul 19292ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul /* Find convertFormat - the format that do_row() will process */ 19302ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul if (srcImage->IsCompressed) { 19312ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul /* setup for compressed textures */ 19322ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul GLint row, components, size; 19332ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul GLchan *dst; 19342ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul 19352ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul assert(texObj->Target == GL_TEXTURE_2D); 19362ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul 19372ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul if (srcImage->Format == GL_RGB) { 19382ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul convertFormat = &_mesa_texformat_rgb; 19392ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul components = 3; 19402ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul } 19412ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul else if (srcImage->Format == GL_RGBA) { 19422ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul convertFormat = &_mesa_texformat_rgba; 19432ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul components = 4; 19442ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul } 19452ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul else { 19462ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul _mesa_problem(ctx, "bad srcImage->Format in _mesa_generate_mipmaps"); 19472ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul return; 19482ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul } 19492ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul 19502ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul /* allocate storage for uncompressed GL_RGB or GL_RGBA images */ 19512ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul size = _mesa_bytes_per_pixel(srcImage->Format, CHAN_TYPE) 19522ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul * srcImage->Width * srcImage->Height * srcImage->Depth + 20; 19532ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul /* 20 extra bytes, just be safe when calling last FetchTexel */ 19542ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul srcData = MALLOC(size); 19552ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul if (!srcData) { 19562ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul _mesa_error(ctx, GL_OUT_OF_MEMORY, "generate mipmaps"); 19572ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul return; 19582ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul } 19592ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul dstData = MALLOC(size / 2); /* 1/4 would probably be OK */ 19602ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul if (!dstData) { 19612ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul _mesa_error(ctx, GL_OUT_OF_MEMORY, "generate mipmaps"); 19622ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul FREE((void *) srcData); 19632ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul return; 19642ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul } 19652ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul 19662ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul /* decompress base image here */ 19672ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul dst = (GLchan *) srcData; 19682ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul for (row = 0; row < srcImage->Height; row++) { 19692ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul GLint col; 19702ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul for (col = 0; col < srcImage->Width; col++) { 19712ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul (*srcImage->FetchTexel)(srcImage, col, row, 0, (GLvoid *) dst); 19722ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul dst += components; 197389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul } 197489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul } 197589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul } 19762ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul else { 19772ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul /* uncompressed */ 19782ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul convertFormat = srcImage->TexFormat; 19792ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul } 198089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul 19818bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul for (level = texObj->BaseLevel; level < texObj->MaxLevel 1982cd1cefae9146fc14b35ee93a04bdb1b1590fba7bBrian Paul && level < maxLevels - 1; level++) { 19839228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul /* generate image[level+1] from image[level] */ 19843893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul const struct gl_texture_image *srcImage; 19853893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul struct gl_texture_image *dstImage; 19863893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul GLint srcWidth, srcHeight, srcDepth; 19873893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul GLint dstWidth, dstHeight, dstDepth; 19883893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul GLint border, bytesPerTexel; 19893893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul 199089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul /* get src image parameters */ 19913893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul srcImage = texObj->Image[level]; 19923893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul ASSERT(srcImage); 19933893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul srcWidth = srcImage->Width; 19943893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul srcHeight = srcImage->Height; 19953893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul srcDepth = srcImage->Depth; 19963893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul border = srcImage->Border; 19973893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul 19983893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul /* compute next (level+1) image size */ 19993893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul if (srcWidth - 2 * border > 1) { 20003893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul dstWidth = (srcWidth - 2 * border) / 2 + 2 * border; 20013893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul } 20023893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul else { 20033893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul dstWidth = srcWidth; /* can't go smaller */ 20043893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul } 20053893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul if (srcHeight - 2 * border > 1) { 20063893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul dstHeight = (srcHeight - 2 * border) / 2 + 2 * border; 20073893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul } 20083893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul else { 20093893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul dstHeight = srcHeight; /* can't go smaller */ 20103893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul } 20113893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul if (srcDepth - 2 * border > 1) { 20123893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul dstDepth = (srcDepth - 2 * border) / 2 + 2 * border; 20133893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul } 20143893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul else { 20153893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul dstDepth = srcDepth; /* can't go smaller */ 20163893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul } 20173893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul 20183893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul if (dstWidth == srcWidth && 20193893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul dstHeight == srcHeight && 20203893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul dstDepth == srcDepth) { 20213893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul /* all done */ 202289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul if (srcImage->IsCompressed) { 202389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul FREE((void *) srcData); 202489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul FREE(dstData); 202589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul } 20263893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul return; 20273893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul } 20283893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul 2029d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul /* get dest gl_texture_image */ 2030d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul dstImage = _mesa_select_tex_image(ctx, texUnit, target, level+1); 2031d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul if (!dstImage) { 2032d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul dstImage = _mesa_alloc_texture_image(); 20333893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul if (!dstImage) { 20343893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul _mesa_error(ctx, GL_OUT_OF_MEMORY, "generating mipmaps"); 20353893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul return; 20363893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul } 2037d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul _mesa_set_tex_image(texObj, target, level + 1, dstImage); 2038d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul } 20393893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul 2040d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul /* Free old image data */ 2041d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul if (dstImage->Data) 2042d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul MESA_PBUFFER_FREE(dstImage->Data); 2043d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul 2044d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul /* initialize new image */ 2045e1cb2fb571ee47b59020db7627e554b7d227e454Brian Paul _mesa_init_teximage_fields(ctx, target, dstImage, dstWidth, dstHeight, 204689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul dstDepth, border, srcImage->IntFormat); 2047d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul dstImage->DriverData = NULL; 2048d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul dstImage->TexFormat = srcImage->TexFormat; 2049d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul dstImage->FetchTexel = srcImage->FetchTexel; 2050d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul ASSERT(dstImage->TexFormat); 2051d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul ASSERT(dstImage->FetchTexel); 2052d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul 205389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul /* Alloc new teximage data buffer. 205489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * Setup src and dest data pointers. 205589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul */ 205689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul if (dstImage->IsCompressed) { 205789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul ASSERT(dstImage->CompressedSize > 0); /* set by init_teximage_fields*/ 205889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul dstImage->Data = MESA_PBUFFER_ALLOC(dstImage->CompressedSize); 205989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul if (!dstImage->Data) { 206089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul _mesa_error(ctx, GL_OUT_OF_MEMORY, "generating mipmaps"); 206189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul return; 206289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul } 20632ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul /* srcData and dstData are already set */ 206489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul ASSERT(srcData); 206589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul ASSERT(dstData); 206689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul } 206789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul else { 206889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul bytesPerTexel = srcImage->TexFormat->TexelBytes; 206989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul ASSERT(dstWidth * dstHeight * dstDepth * bytesPerTexel > 0); 207089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul dstImage->Data = MESA_PBUFFER_ALLOC(dstWidth * dstHeight * dstDepth 207189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * bytesPerTexel); 207289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul if (!dstImage->Data) { 207389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul _mesa_error(ctx, GL_OUT_OF_MEMORY, "generating mipmaps"); 207489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul return; 207589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul } 207689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul srcData = (const GLubyte *) srcImage->Data; 207789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul dstData = (GLubyte *) dstImage->Data; 2078d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul } 2079d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul 2080d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul /* 2081d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul * We use simple 2x2 averaging to compute the next mipmap level. 2082d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul */ 2083d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul switch (target) { 208489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul case GL_TEXTURE_1D: 20852ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul make_1d_mipmap(convertFormat, border, 208689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul srcWidth, srcData, 208789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul dstWidth, dstData); 208889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul break; 208989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul case GL_TEXTURE_2D: 209089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB: 209189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB: 209289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB: 209389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB: 209489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB: 209589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB: 20962ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul make_2d_mipmap(convertFormat, border, 209789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul srcWidth, srcHeight, srcData, 209889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul dstWidth, dstHeight, dstData); 209989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul break; 210089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul case GL_TEXTURE_3D: 21012ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul make_3d_mipmap(convertFormat, border, 210289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul srcWidth, srcHeight, srcDepth, srcData, 210389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul dstWidth, dstHeight, dstDepth, dstData); 210489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul break; 210589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul case GL_TEXTURE_RECTANGLE_NV: 210689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul /* no mipmaps, do nothing */ 210789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul break; 210889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul default: 210989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul _mesa_problem(ctx, "bad dimensions in _mesa_generate_mipmaps"); 211089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul return; 2111d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul } 211289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul 211389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul if (dstImage->IsCompressed) { 211489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul GLubyte *temp; 21152ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul /* compress image from dstData into dstImage->Data */ 21162ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul const GLenum srcFormat = convertFormat->BaseFormat; 21172ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul GLint dstRowStride = _mesa_compressed_row_stride(srcImage->IntFormat, 21182ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul dstWidth); 21192ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul ASSERT(srcFormat == GL_RGB || srcFormat == GL_RGBA); 21202ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul _mesa_compress_teximage(ctx, 21212ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul dstWidth, dstHeight, /* size */ 21222ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul srcFormat, /* source format */ 21232ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul dstData, /* source buffer */ 21242ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul dstWidth, /* source row stride */ 21252ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul dstImage->TexFormat, /* dest format */ 21262ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul dstImage->Data, /* dest buffer */ 21272ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul dstRowStride ); /* dest row stride */ 212889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul 212989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul /* swap src and dest pointers */ 213089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul temp = (GLubyte *) srcData; 213189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul srcData = dstData; 213289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul dstData = temp; 213389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul } 213489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul 2135d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul } /* loop over mipmap levels */ 21363893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul} 2137