texstore.c revision d5bbbd41c431ad93c0867d5b0b234426d8570499
1d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul/* $Id: texstore.c,v 1.39 2002/09/16 17:57:14 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 32e75d2424e53d6023f4414e40694cd467e5392b96Brian Paul#include "colormac.h" 338e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul#include "context.h" 348e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul#include "convolve.h" 358e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul#include "image.h" 368e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul#include "macros.h" 378e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul#include "mem.h" 38371ef9c058b0d59bfb62689b64af1b29a2214d9eGareth Hughes#include "texformat.h" 398e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul#include "teximage.h" 408e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul#include "texstore.h" 417d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul#include "texutil.h" 428e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul 438e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul 448e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul/* 458e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * Given an internal texture format enum or 1, 2, 3, 4 return the 468e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * corresponding _base_ internal format: GL_ALPHA, GL_LUMINANCE, 478e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * GL_LUMANCE_ALPHA, GL_INTENSITY, GL_RGB, or GL_RGBA. Return the 488e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * number of components for the format. Return -1 if invalid enum. 496b406bf09dc18f4d84ccb636d043c990a30da4e1Gareth Hughes * 506b406bf09dc18f4d84ccb636d043c990a30da4e1Gareth Hughes * GH: Do we really need this? We have the number of bytes per texel 516b406bf09dc18f4d84ccb636d043c990a30da4e1Gareth Hughes * in the texture format structures, so why don't we just use that? 528e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul */ 538e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paulstatic GLint 548e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paulcomponents_in_intformat( GLint format ) 558e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul{ 568e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul switch (format) { 578e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul case GL_ALPHA: 588e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul case GL_ALPHA4: 598e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul case GL_ALPHA8: 608e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul case GL_ALPHA12: 618e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul case GL_ALPHA16: 628e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul return 1; 638e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul case 1: 648e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul case GL_LUMINANCE: 658e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul case GL_LUMINANCE4: 668e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul case GL_LUMINANCE8: 678e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul case GL_LUMINANCE12: 688e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul case GL_LUMINANCE16: 698e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul return 1; 708e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul case 2: 718e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul case GL_LUMINANCE_ALPHA: 728e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul case GL_LUMINANCE4_ALPHA4: 738e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul case GL_LUMINANCE6_ALPHA2: 748e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul case GL_LUMINANCE8_ALPHA8: 758e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul case GL_LUMINANCE12_ALPHA4: 768e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul case GL_LUMINANCE12_ALPHA12: 778e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul case GL_LUMINANCE16_ALPHA16: 788e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul return 2; 798e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul case GL_INTENSITY: 808e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul case GL_INTENSITY4: 818e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul case GL_INTENSITY8: 828e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul case GL_INTENSITY12: 838e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul case GL_INTENSITY16: 848e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul return 1; 858e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul case 3: 868e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul case GL_RGB: 878e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul case GL_R3_G3_B2: 888e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul case GL_RGB4: 898e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul case GL_RGB5: 908e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul case GL_RGB8: 918e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul case GL_RGB10: 928e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul case GL_RGB12: 938e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul case GL_RGB16: 948e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul return 3; 958e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul case 4: 968e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul case GL_RGBA: 978e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul case GL_RGBA2: 988e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul case GL_RGBA4: 998e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul case GL_RGB5_A1: 1008e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul case GL_RGBA8: 1018e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul case GL_RGB10_A2: 1028e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul case GL_RGBA12: 1038e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul case GL_RGBA16: 1048e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul return 4; 1058e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul case GL_COLOR_INDEX: 1068e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul case GL_COLOR_INDEX1_EXT: 1078e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul case GL_COLOR_INDEX2_EXT: 1088e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul case GL_COLOR_INDEX4_EXT: 1098e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul case GL_COLOR_INDEX8_EXT: 1108e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul case GL_COLOR_INDEX12_EXT: 1118e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul case GL_COLOR_INDEX16_EXT: 1128e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul return 1; 113f7e1dfeaefda8865252513bc4d880ea8640efe4dBrian Paul case GL_DEPTH_COMPONENT: 114f7e1dfeaefda8865252513bc4d880ea8640efe4dBrian Paul case GL_DEPTH_COMPONENT16_SGIX: 115f7e1dfeaefda8865252513bc4d880ea8640efe4dBrian Paul case GL_DEPTH_COMPONENT24_SGIX: 116f7e1dfeaefda8865252513bc4d880ea8640efe4dBrian Paul case GL_DEPTH_COMPONENT32_SGIX: 117f7e1dfeaefda8865252513bc4d880ea8640efe4dBrian Paul return 1; 1188e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul default: 1198e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul return -1; /* error */ 1208e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul } 1218e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul} 1228e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul 1238e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul 1248e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul/* 1258e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * This function is used to transfer the user's image data into a texture 1268e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * image buffer. We handle both full texture images and subtexture images. 1278e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * We also take care of all image transfer operations here, including 1288e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * convolution, scale/bias, colortables, etc. 1298e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * 1308e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * The destination texel channel type is always GLchan. 1318e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * 1328e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * A hardware driver may use this as a helper routine to unpack and 1338e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * apply pixel transfer ops into a temporary image buffer. Then, 1348e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * convert the temporary image into the special hardware format. 1358e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * 1368e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * Input: 1378e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * dimensions - 1, 2, or 3 1388e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * texFormat - GL_LUMINANCE, GL_INTENSITY, GL_LUMINANCE_ALPHA, GL_ALPHA, 1398e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * GL_RGB or GL_RGBA 14056671022f97cfbc199a47b3338125431e42030eeBrian Paul * texDestAddr - destination image address 1418e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * srcWidth, srcHeight, srcDepth - size (in pixels) of src and dest images 1428e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * dstXoffset, dstYoffset, dstZoffset - position to store the image within 1438e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * the destination 3D texture 14456671022f97cfbc199a47b3338125431e42030eeBrian Paul * dstRowStride, dstImageStride - dest image strides in bytes 1458e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * srcFormat - source image format (GL_ALPHA, GL_RED, GL_RGB, etc) 1468e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * srcType - GL_UNSIGNED_BYTE, GL_UNSIGNED_SHORT_5_6_5, GL_FLOAT, etc 1478e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * srcPacking - describes packing of incoming image. 1481c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul * transferOps - mask of pixel transfer operations 1498e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul */ 1507d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paulstatic void 1517d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paultransfer_teximage(GLcontext *ctx, GLuint dimensions, 1527d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul GLenum texDestFormat, GLvoid *texDestAddr, 1537d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul GLint srcWidth, GLint srcHeight, GLint srcDepth, 1547d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul GLint dstXoffset, GLint dstYoffset, GLint dstZoffset, 1557d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul GLint dstRowStride, GLint dstImageStride, 1567d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul GLenum srcFormat, GLenum srcType, 1577d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul const GLvoid *srcAddr, 1581c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul const struct gl_pixelstore_attrib *srcPacking, 1591c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul GLuint transferOps) 1608e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul{ 1618e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul GLint texComponents; 1628e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul 1638e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul ASSERT(ctx); 1648e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul ASSERT(dimensions >= 1 && dimensions <= 3); 16556671022f97cfbc199a47b3338125431e42030eeBrian Paul ASSERT(texDestAddr); 1668e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul ASSERT(srcWidth >= 1); 1678e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul ASSERT(srcHeight >= 1); 1688e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul ASSERT(srcDepth >= 1); 1698e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul ASSERT(dstXoffset >= 0); 1708e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul ASSERT(dstYoffset >= 0); 1718e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul ASSERT(dstZoffset >= 0); 1728e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul ASSERT(dstRowStride >= 0); 1738e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul ASSERT(dstImageStride >= 0); 1748e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul ASSERT(srcAddr); 1758e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul ASSERT(srcPacking); 1768e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul 1770299ad753224372c7a6147f598fdad33f576a714Brian Paul texComponents = components_in_intformat(texDestFormat); 1788e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul 1798e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul /* try common 2D texture cases first */ 1801c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul if (!transferOps && dimensions == 2 && srcType == CHAN_TYPE) { 1818e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul 1820299ad753224372c7a6147f598fdad33f576a714Brian Paul if (srcFormat == texDestFormat) { 1838e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul /* This will cover the common GL_RGB, GL_RGBA, GL_ALPHA, 1848e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * GL_LUMINANCE_ALPHA, etc. texture formats. Use memcpy(). 1858e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul */ 1868e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul const GLchan *src = (const GLchan *) _mesa_image_address( 1878e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul srcPacking, srcAddr, srcWidth, srcHeight, 1888e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul srcFormat, srcType, 0, 0, 0); 1898e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul const GLint srcRowStride = _mesa_image_row_stride(srcPacking, 1908e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul srcWidth, srcFormat, srcType); 1918e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul const GLint widthInBytes = srcWidth * texComponents * sizeof(GLchan); 192a1503b00f863a48a517939a42d512f9cfe77f79cBrian Paul GLchan *dst = (GLchan *) texDestAddr 193a1503b00f863a48a517939a42d512f9cfe77f79cBrian Paul + dstYoffset * (dstRowStride / sizeof(GLchan)) 194a1503b00f863a48a517939a42d512f9cfe77f79cBrian Paul + dstXoffset * texComponents; 1958e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul if (srcRowStride == widthInBytes && dstRowStride == widthInBytes) { 1968e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul MEMCPY(dst, src, srcHeight * widthInBytes); 1978e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul } 1988e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul else { 1998e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul GLint i; 2008e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul for (i = 0; i < srcHeight; i++) { 2018e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul MEMCPY(dst, src, widthInBytes); 202a1503b00f863a48a517939a42d512f9cfe77f79cBrian Paul src += (srcRowStride / sizeof(GLchan)); 203a1503b00f863a48a517939a42d512f9cfe77f79cBrian Paul dst += (dstRowStride / sizeof(GLchan)); 2048e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul } 2058e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul } 2068e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul return; /* all done */ 2078e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul } 2080299ad753224372c7a6147f598fdad33f576a714Brian Paul else if (srcFormat == GL_RGBA && texDestFormat == GL_RGB) { 2098e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul /* commonly used by Quake */ 2108e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul const GLchan *src = (const GLchan *) _mesa_image_address( 2118e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul srcPacking, srcAddr, srcWidth, srcHeight, 2128e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul srcFormat, srcType, 0, 0, 0); 2138e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul const GLint srcRowStride = _mesa_image_row_stride(srcPacking, 2148e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul srcWidth, srcFormat, srcType); 215a1503b00f863a48a517939a42d512f9cfe77f79cBrian Paul GLchan *dst = (GLchan *) texDestAddr 216a1503b00f863a48a517939a42d512f9cfe77f79cBrian Paul + dstYoffset * (dstRowStride / sizeof(GLchan)) 217a1503b00f863a48a517939a42d512f9cfe77f79cBrian Paul + dstXoffset * texComponents; 2188e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul GLint i, j; 2198e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul for (i = 0; i < srcHeight; i++) { 2208e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul const GLchan *s = src; 2218e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul GLchan *d = dst; 2228e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul for (j = 0; j < srcWidth; j++) { 2238e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul *d++ = *s++; /*red*/ 2248e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul *d++ = *s++; /*green*/ 2258e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul *d++ = *s++; /*blue*/ 2268e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul s++; /*alpha*/ 2278e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul } 228a1503b00f863a48a517939a42d512f9cfe77f79cBrian Paul src += (srcRowStride / sizeof(GLchan)); 229a1503b00f863a48a517939a42d512f9cfe77f79cBrian Paul dst += (dstRowStride / sizeof(GLchan)); 2308e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul } 2318e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul return; /* all done */ 2328e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul } 2338e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul } 2348e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul 2358e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul /* 2368e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * General case solutions 2378e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul */ 2380299ad753224372c7a6147f598fdad33f576a714Brian Paul if (texDestFormat == GL_COLOR_INDEX) { 2398e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul /* color index texture */ 2401ceda0f84fdfe07951071fdf4fa643d07f09a4d7Brian Paul const GLenum texType = CHAN_TYPE; 2418e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul GLint img, row; 24242f916de5cb3f4362e4682cdaa5eea00fe2de857Brian Paul GLchan *dest = (GLchan *) texDestAddr 24342f916de5cb3f4362e4682cdaa5eea00fe2de857Brian Paul + dstZoffset * (dstImageStride / sizeof(GLchan)) 244a1503b00f863a48a517939a42d512f9cfe77f79cBrian Paul + dstYoffset * (dstRowStride / sizeof(GLchan)) 245a1503b00f863a48a517939a42d512f9cfe77f79cBrian Paul + dstXoffset * texComponents; 2468e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul for (img = 0; img < srcDepth; img++) { 2478e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul GLchan *destRow = dest; 2488e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul for (row = 0; row < srcHeight; row++) { 2498e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul const GLvoid *src = _mesa_image_address(srcPacking, 2508e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, row, 0); 2518e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul _mesa_unpack_index_span(ctx, srcWidth, texType, destRow, 2521c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul srcType, src, srcPacking, transferOps); 253a1503b00f863a48a517939a42d512f9cfe77f79cBrian Paul destRow += (dstRowStride / sizeof(GLchan)); 2548e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul } 2558e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul dest += dstImageStride; 2568e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul } 2578e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul } 2580299ad753224372c7a6147f598fdad33f576a714Brian Paul else if (texDestFormat == GL_DEPTH_COMPONENT) { 259f7e1dfeaefda8865252513bc4d880ea8640efe4dBrian Paul /* Depth texture (shadow maps) */ 260f7e1dfeaefda8865252513bc4d880ea8640efe4dBrian Paul GLint img, row; 26156671022f97cfbc199a47b3338125431e42030eeBrian Paul GLubyte *dest = (GLubyte *) texDestAddr 26256671022f97cfbc199a47b3338125431e42030eeBrian Paul + dstZoffset * dstImageStride 263a1503b00f863a48a517939a42d512f9cfe77f79cBrian Paul + dstYoffset * (dstRowStride / sizeof(GLchan)) 264f7e1dfeaefda8865252513bc4d880ea8640efe4dBrian Paul + dstXoffset * texComponents; 265f7e1dfeaefda8865252513bc4d880ea8640efe4dBrian Paul for (img = 0; img < srcDepth; img++) { 26656671022f97cfbc199a47b3338125431e42030eeBrian Paul GLubyte *destRow = dest; 267f7e1dfeaefda8865252513bc4d880ea8640efe4dBrian Paul for (row = 0; row < srcHeight; row++) { 268f7e1dfeaefda8865252513bc4d880ea8640efe4dBrian Paul const GLvoid *src = _mesa_image_address(srcPacking, 269f7e1dfeaefda8865252513bc4d880ea8640efe4dBrian Paul srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, row, 0); 27056671022f97cfbc199a47b3338125431e42030eeBrian Paul _mesa_unpack_depth_span(ctx, srcWidth, (GLfloat *) destRow, 271e75d2424e53d6023f4414e40694cd467e5392b96Brian Paul srcType, src, srcPacking); 272a1503b00f863a48a517939a42d512f9cfe77f79cBrian Paul destRow += (dstRowStride / sizeof(GLchan)); 273f7e1dfeaefda8865252513bc4d880ea8640efe4dBrian Paul } 274f7e1dfeaefda8865252513bc4d880ea8640efe4dBrian Paul dest += dstImageStride; 275f7e1dfeaefda8865252513bc4d880ea8640efe4dBrian Paul } 276f7e1dfeaefda8865252513bc4d880ea8640efe4dBrian Paul } 2778e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul else { 2788e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul /* regular, color texture */ 2798e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul if ((dimensions == 1 && ctx->Pixel.Convolution1DEnabled) || 2808e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul (dimensions >= 2 && ctx->Pixel.Convolution2DEnabled) || 2818e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul (dimensions >= 2 && ctx->Pixel.Separable2DEnabled)) { 2828e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul /* 2838e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * Fill texture image with convolution 2848e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul */ 2858e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul GLint img, row; 2868e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul GLint convWidth = srcWidth, convHeight = srcHeight; 2878e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul GLfloat *tmpImage, *convImage; 2888e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul tmpImage = (GLfloat *) MALLOC(srcWidth * srcHeight * 4 * sizeof(GLfloat)); 2898e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul if (!tmpImage) { 29008836341788a9f9d638d9dc8328510ccd18ddeb5Brian Paul _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage"); 2918e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul return; 2928e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul } 2938e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul convImage = (GLfloat *) MALLOC(srcWidth * srcHeight * 4 * sizeof(GLfloat)); 2948e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul if (!convImage) { 29508836341788a9f9d638d9dc8328510ccd18ddeb5Brian Paul _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage"); 2968e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul FREE(tmpImage); 2978e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul return; 2988e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul } 2998e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul 3008e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul for (img = 0; img < srcDepth; img++) { 3018e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul const GLfloat *srcf; 3028e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul GLfloat *dstf = tmpImage; 3038e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul GLchan *dest; 3048e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul 3058e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul /* unpack and do transfer ops up to convolution */ 3068e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul for (row = 0; row < srcHeight; row++) { 3078e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul const GLvoid *src = _mesa_image_address(srcPacking, 3088e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul srcAddr, srcWidth, srcHeight, 3098e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul srcFormat, srcType, img, row, 0); 3108e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul _mesa_unpack_float_color_span(ctx, srcWidth, GL_RGBA, dstf, 3118e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul srcFormat, srcType, src, srcPacking, 3121c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul transferOps & IMAGE_PRE_CONVOLUTION_BITS, 3138e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul GL_TRUE); 3148e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul dstf += srcWidth * 4; 3158e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul } 3168e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul 3178e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul /* convolve */ 3188e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul if (dimensions == 1) { 3198e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul ASSERT(ctx->Pixel.Convolution1DEnabled); 3208e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul _mesa_convolve_1d_image(ctx, &convWidth, tmpImage, convImage); 3218e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul } 3228e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul else { 3238e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul if (ctx->Pixel.Convolution2DEnabled) { 3248e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul _mesa_convolve_2d_image(ctx, &convWidth, &convHeight, 3258e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul tmpImage, convImage); 3268e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul } 3278e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul else { 3288e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul ASSERT(ctx->Pixel.Separable2DEnabled); 3298e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul _mesa_convolve_sep_image(ctx, &convWidth, &convHeight, 3308e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul tmpImage, convImage); 3318e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul } 3328e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul } 3338e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul 3348e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul /* packing and transfer ops after convolution */ 3358e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul srcf = convImage; 33642f916de5cb3f4362e4682cdaa5eea00fe2de857Brian Paul dest = (GLchan *) texDestAddr 33742f916de5cb3f4362e4682cdaa5eea00fe2de857Brian Paul + (dstZoffset + img) * (dstImageStride / sizeof(GLchan)) 338a1503b00f863a48a517939a42d512f9cfe77f79cBrian Paul + dstYoffset * (dstRowStride / sizeof(GLchan)); 3398e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul for (row = 0; row < convHeight; row++) { 3408e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul _mesa_pack_float_rgba_span(ctx, convWidth, 3418e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul (const GLfloat (*)[4]) srcf, 3420299ad753224372c7a6147f598fdad33f576a714Brian Paul texDestFormat, CHAN_TYPE, 3438e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul dest, &_mesa_native_packing, 3441c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul transferOps 3458e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul & IMAGE_POST_CONVOLUTION_BITS); 3468e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul srcf += convWidth * 4; 347a1503b00f863a48a517939a42d512f9cfe77f79cBrian Paul dest += (dstRowStride / sizeof(GLchan)); 3488e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul } 3498e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul } 3508e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul 3518e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul FREE(convImage); 3528e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul FREE(tmpImage); 3538e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul } 3548e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul else { 3558e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul /* 3568e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * no convolution 3578e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul */ 3588e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul GLint img, row; 35942f916de5cb3f4362e4682cdaa5eea00fe2de857Brian Paul GLchan *dest = (GLchan *) texDestAddr 36042f916de5cb3f4362e4682cdaa5eea00fe2de857Brian Paul + dstZoffset * (dstImageStride / sizeof(GLchan)) 361a1503b00f863a48a517939a42d512f9cfe77f79cBrian Paul + dstYoffset * (dstRowStride / sizeof(GLchan)) 362a1503b00f863a48a517939a42d512f9cfe77f79cBrian Paul + dstXoffset * texComponents; 3638e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul for (img = 0; img < srcDepth; img++) { 3648e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul GLchan *destRow = dest; 3658e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul for (row = 0; row < srcHeight; row++) { 3668e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul const GLvoid *srcRow = _mesa_image_address(srcPacking, 3678e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul srcAddr, srcWidth, srcHeight, 3688e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul srcFormat, srcType, img, row, 0); 3690299ad753224372c7a6147f598fdad33f576a714Brian Paul _mesa_unpack_chan_color_span(ctx, srcWidth, texDestFormat, 3700299ad753224372c7a6147f598fdad33f576a714Brian Paul destRow, srcFormat, srcType, srcRow, 3711c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul srcPacking, transferOps); 372a1503b00f863a48a517939a42d512f9cfe77f79cBrian Paul destRow += (dstRowStride / sizeof(GLchan)); 3738e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul } 37442f916de5cb3f4362e4682cdaa5eea00fe2de857Brian Paul dest += dstImageStride / sizeof(GLchan); 3758e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul } 3768e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul } 3778e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul } 3788e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul} 3798e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul 3808e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul 3818e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul 3828e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul/* 3837d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul * Transfer a texture image from user space to <destAddr> applying all 3847d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul * needed image transfer operations and storing the result in the format 3857d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul * specified by <dstFormat>. <dstFormat> may be any format from texformat.h. 3867d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul * Input: 3871c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul * dimensions - 1, 2 or 3 3881c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul * baseInternalFormat - base format of the internal texture format 3891c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul * specified by the user. This is very important, see below. 3901c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul * dstFormat - destination image format 3911c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul * dstAddr - destination address 3921c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul * srcWidth, srcHeight, srcDepth - size of source iamge 3931c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul * dstX/Y/Zoffset - as specified by glTexSubImage 3947d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul * dstRowStride - stride between dest rows in bytes 39542f916de5cb3f4362e4682cdaa5eea00fe2de857Brian Paul * dstImageStride - stride between dest images in bytes 3961c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul * srcFormat, srcType - incoming image format and datatype 3971c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul * srcAddr - source image address 3981c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul * srcPacking - packing params of source image 3997d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul * 4007d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul * XXX this function is a bit more complicated than it should be. If 4017d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul * _mesa_convert_texsubimage[123]d could handle any dest/source formats 4027d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul * or if transfer_teximage() could store in any MESA_FORMAT_* format, we 4037d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul * could simplify things here. 4047d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul */ 4057d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paulvoid 4067d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul_mesa_transfer_teximage(GLcontext *ctx, GLuint dimensions, 4071c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul GLenum baseInternalFormat, 4087d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul const struct gl_texture_format *dstFormat, 4097d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul GLvoid *dstAddr, 4107d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul GLint srcWidth, GLint srcHeight, GLint srcDepth, 4117d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul GLint dstXoffset, GLint dstYoffset, GLint dstZoffset, 4127d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul GLint dstRowStride, GLint dstImageStride, 4137d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul GLenum srcFormat, GLenum srcType, 4147d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul const GLvoid *srcAddr, 4157d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul const struct gl_pixelstore_attrib *srcPacking) 4167d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul{ 4177d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul const GLint dstRowStridePixels = dstRowStride / dstFormat->TexelBytes; 4187d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul const GLint dstImageStridePixels = dstImageStride / dstFormat->TexelBytes; 4197d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul GLboolean makeTemp; 4201c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul GLuint transferOps = ctx->_ImageTransferState; 4211c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul GLboolean freeSourceData = GL_FALSE; 4221c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul GLint postConvWidth = srcWidth, postConvHeight = srcHeight; 4231c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul 424e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul assert(baseInternalFormat > 0); 425e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul 4261c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul if (transferOps & IMAGE_CONVOLUTION_BIT) { 4271c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul _mesa_adjust_image_for_convolution(ctx, dimensions, &postConvWidth, 4281c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul &postConvHeight); 4291c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul } 4301c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul 4311c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul /* 4321c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul * Consider this scenario: The user's source image is GL_RGB and the 4331c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul * requested internal format is GL_LUMINANCE. Now suppose the device 4341c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul * driver doesn't support GL_LUMINANCE and instead uses RGB16 as the 4351c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul * texture format. In that case we still need to do an intermediate 4361c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul * conversion to luminance format so that the incoming red channel gets 4371c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul * replicated into the dest red, green and blue channels. The following 4381c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul * code takes care of that. 4391c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul */ 4401c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul if (dstFormat->BaseFormat != baseInternalFormat) { 4411c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul /* Allocate storage for temporary image in the baseInternalFormat */ 4421c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul const GLint texelSize = _mesa_components_in_format(baseInternalFormat) 4431c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul * sizeof(GLchan); 4441c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul const GLint bytes = texelSize * postConvWidth * postConvHeight *srcDepth; 4451c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul const GLint tmpRowStride = texelSize * postConvWidth; 4461c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul const GLint tmpImgStride = texelSize * postConvWidth * postConvHeight; 4471c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul GLvoid *tmpImage = MALLOC(bytes); 4481c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul if (!tmpImage) 4491c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul return; 4501c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul transfer_teximage(ctx, dimensions, baseInternalFormat, tmpImage, 4511c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul srcWidth, srcHeight, srcDepth, 4521c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul 0, 0, 0, /* x/y/zoffset */ 4531c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul tmpRowStride, tmpImgStride, 4541c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul srcFormat, srcType, srcAddr, srcPacking, transferOps); 4551c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul 4561c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul /* this is our new source image */ 4571c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul srcWidth = postConvWidth; 4581c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul srcHeight = postConvHeight; 4591c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul srcFormat = baseInternalFormat; 4601c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul srcType = CHAN_TYPE; 4611c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul srcAddr = tmpImage; 4621c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul srcPacking = &_mesa_native_packing; 4631c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul freeSourceData = GL_TRUE; 4641c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul transferOps = 0; /* image transfer ops were completed */ 4651c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul } 4667d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul 4671c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul /* Let the optimized tex conversion functions take a crack at the 4681c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul * image conversion if the dest format is a h/w format. 4691c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul */ 4707d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul if (_mesa_is_hardware_tex_format(dstFormat)) { 4711c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul if (transferOps) { 4727d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul makeTemp = GL_TRUE; 4737d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul } 4747d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul else { 4757d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul if (dimensions == 1) { 4767d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul makeTemp = !_mesa_convert_texsubimage1d(dstFormat->MesaFormat, 4777d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul dstXoffset, 4787d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul srcWidth, 4797d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul srcFormat, srcType, 4807d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul srcPacking, srcAddr, 4817d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul dstAddr); 4827d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul } 4837d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul else if (dimensions == 2) { 4847d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul makeTemp = !_mesa_convert_texsubimage2d(dstFormat->MesaFormat, 4857d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul dstXoffset, dstYoffset, 4867d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul srcWidth, srcHeight, 4877d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul dstRowStridePixels, 4887d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul srcFormat, srcType, 4897d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul srcPacking, srcAddr, 4907d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul dstAddr); 4917d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul } 4927d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul else { 4937d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul assert(dimensions == 3); 4947d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul makeTemp = !_mesa_convert_texsubimage3d(dstFormat->MesaFormat, 4957d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul dstXoffset, dstYoffset, dstZoffset, 4967d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul srcWidth, srcHeight, srcDepth, 4977d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul dstRowStridePixels, dstImageStridePixels, 4987d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul srcFormat, srcType, 4997d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul srcPacking, srcAddr, dstAddr); 5007d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul } 5017d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul if (!makeTemp) { 5027d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul /* all done! */ 5031c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul if (freeSourceData) 5041c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul FREE((void *) srcAddr); 5057d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul return; 5067d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul } 5077d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul } 5087d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul } 5097d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul else { 5107d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul /* software texture format */ 5117d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul makeTemp = GL_FALSE; 5127d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul } 5137d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul 5147d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul if (makeTemp) { 5157d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul GLint postConvWidth = srcWidth, postConvHeight = srcHeight; 5167d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul GLenum tmpFormat; 5177d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul GLuint tmpComps, tmpTexelSize; 5187d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul GLint tmpRowStride, tmpImageStride; 5197d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul GLubyte *tmpImage; 5207d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul 5211c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul if (transferOps & IMAGE_CONVOLUTION_BIT) { 5227d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul _mesa_adjust_image_for_convolution(ctx, dimensions, &postConvWidth, 5237d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul &postConvHeight); 5247d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul } 5257d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul 5261c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul tmpFormat = dstFormat->BaseFormat; 5277d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul tmpComps = _mesa_components_in_format(tmpFormat); 52836f3712e85cafef1b038189678030f6ef4f8b7e9Brian Paul tmpTexelSize = tmpComps * sizeof(GLchan); 5297d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul tmpRowStride = postConvWidth * tmpTexelSize; 5307d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul tmpImageStride = postConvWidth * postConvHeight * tmpTexelSize; 5317d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul tmpImage = (GLubyte *) MALLOC(postConvWidth * postConvHeight * 5327d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul srcDepth * tmpTexelSize); 5331c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul if (!tmpImage) { 5341c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul if (freeSourceData) 5351c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul FREE((void *) srcAddr); 5367d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul return; 5371c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul } 5387d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul 5397d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul transfer_teximage(ctx, dimensions, tmpFormat, tmpImage, 5407d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul srcWidth, srcHeight, srcDepth, 5417d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul 0, 0, 0, /* x/y/zoffset */ 5427d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul tmpRowStride, tmpImageStride, 5431c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul srcFormat, srcType, srcAddr, srcPacking, transferOps); 5441c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul 5451c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul if (freeSourceData) 5461c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul FREE((void *) srcAddr); 5477d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul 5487d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul /* the temp image is our new source image */ 5497d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul srcWidth = postConvWidth; 5507d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul srcHeight = postConvHeight; 5517d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul srcFormat = tmpFormat; 5527d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul srcType = CHAN_TYPE; 5537d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul srcAddr = tmpImage; 5547d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul srcPacking = &_mesa_native_packing; 5551c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul freeSourceData = GL_TRUE; 5567d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul } 5577d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul 5587d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul if (_mesa_is_hardware_tex_format(dstFormat)) { 5597d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul assert(makeTemp); 5607d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul if (dimensions == 1) { 5617d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul GLboolean b; 5627d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul b = _mesa_convert_texsubimage1d(dstFormat->MesaFormat, 5637d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul dstXoffset, 5647d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul srcWidth, 5657d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul srcFormat, srcType, 5667d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul srcPacking, srcAddr, 5677d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul dstAddr); 5687d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul assert(b); 5697d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul } 5707d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul else if (dimensions == 2) { 5717d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul GLboolean b; 5727d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul b = _mesa_convert_texsubimage2d(dstFormat->MesaFormat, 5737d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul dstXoffset, dstYoffset, 5747d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul srcWidth, srcHeight, 5757d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul dstRowStridePixels, 5767d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul srcFormat, srcType, 5777d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul srcPacking, srcAddr, 5787d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul dstAddr); 5797d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul assert(b); 5807d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul } 5817d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul else { 5827d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul GLboolean b; 5837d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul b = _mesa_convert_texsubimage3d(dstFormat->MesaFormat, 5847d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul dstXoffset, dstYoffset, dstZoffset, 5857d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul srcWidth, srcHeight, srcDepth, 5867d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul dstRowStridePixels, dstImageStridePixels, 5877d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul srcFormat, srcType, 5887d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul srcPacking, srcAddr, dstAddr); 5897d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul assert(b); 5907d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul } 5917d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul } 5927d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul else { 5937d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul /* software format */ 5947d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul assert(!makeTemp); 5951c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul transfer_teximage(ctx, dimensions, dstFormat->BaseFormat, dstAddr, 5967d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul srcWidth, srcHeight, srcDepth, 5977d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul dstXoffset, dstYoffset, dstZoffset, 5987d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul dstRowStride, dstImageStride, 5991c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul srcFormat, srcType, srcAddr, srcPacking, transferOps); 6007d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul } 6011c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul 6021c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul if (freeSourceData) 6031c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul FREE((void *) srcAddr); /* the temp image */ 6047d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul} 6057d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul 6067d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul 6077d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul/* 6088e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * This is the software fallback for Driver.TexImage1D(). 6098e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * The texture image type will be GLchan. 6108e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * The texture image format will be GL_COLOR_INDEX, GL_INTENSITY, 6118e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * GL_LUMINANCE, GL_LUMINANCE_ALPHA, GL_ALPHA, GL_RGB or GL_RGBA. 6128e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * 6138e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul */ 6148e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paulvoid 6158e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul_mesa_store_teximage1d(GLcontext *ctx, GLenum target, GLint level, 6168e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul GLint internalFormat, 6178e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul GLint width, GLint border, 6188e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul GLenum format, GLenum type, const GLvoid *pixels, 6198e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul const struct gl_pixelstore_attrib *packing, 6208e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul struct gl_texture_object *texObj, 6218e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul struct gl_texture_image *texImage) 6228e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul{ 6238e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul GLint postConvWidth = width; 624e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul GLint texelBytes, sizeInBytes; 6258e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul 6268e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul if (ctx->_ImageTransferState & IMAGE_CONVOLUTION_BIT) { 6278e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul _mesa_adjust_image_for_convolution(ctx, 1, &postConvWidth, NULL); 6288e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul } 6298e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul 6307d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul /* choose the texture format */ 6317d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul assert(ctx->Driver.ChooseTextureFormat); 6327d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul texImage->TexFormat = (*ctx->Driver.ChooseTextureFormat)(ctx, 6337d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul internalFormat, format, type); 6347d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul assert(texImage->TexFormat); 6359228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul texImage->FetchTexel = texImage->TexFormat->FetchTexel1D; 6368e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul 63719d1e432612cf7db797da11793b13a6c1c6aac16Gareth Hughes texelBytes = texImage->TexFormat->TexelBytes; 63819d1e432612cf7db797da11793b13a6c1c6aac16Gareth Hughes 639e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul /* Compute image size, in bytes */ 640e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul if (texImage->IsCompressed) { 641e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul assert(ctx->Driver.CompressedTextureSize); 642e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul sizeInBytes = ctx->Driver.CompressedTextureSize(ctx, texImage); 643e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul assert(sizeInBytes > 0); 644e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul texImage->CompressedSize = sizeInBytes; 645e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul } 646e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul else { 647e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul sizeInBytes = postConvWidth * texelBytes; 648e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul } 649e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul 6508e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul /* allocate memory */ 651aeb4434563c4014a662ea334878b60d3031bb3c1Brian Paul texImage->Data = MESA_PBUFFER_ALLOC(sizeInBytes); 6527d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul if (!texImage->Data) { 6537d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage1D"); 6547d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul return; 6557d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul } 6568e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul 657f3b85c983f469875ac76081a61539a6c7b26777cBrian Paul if (pixels) { 658f3b85c983f469875ac76081a61539a6c7b26777cBrian Paul /* unpack image, apply transfer ops and store in texImage->Data */ 659f3b85c983f469875ac76081a61539a6c7b26777cBrian Paul _mesa_transfer_teximage(ctx, 1, 660f3b85c983f469875ac76081a61539a6c7b26777cBrian Paul _mesa_base_tex_format(ctx, internalFormat), 661f3b85c983f469875ac76081a61539a6c7b26777cBrian Paul texImage->TexFormat, texImage->Data, 662f3b85c983f469875ac76081a61539a6c7b26777cBrian Paul width, 1, 1, 0, 0, 0, 663f3b85c983f469875ac76081a61539a6c7b26777cBrian Paul 0, /* dstRowStride */ 664f3b85c983f469875ac76081a61539a6c7b26777cBrian Paul 0, /* dstImageStride */ 665f3b85c983f469875ac76081a61539a6c7b26777cBrian Paul format, type, pixels, packing); 666f3b85c983f469875ac76081a61539a6c7b26777cBrian Paul 667f3b85c983f469875ac76081a61539a6c7b26777cBrian Paul /* GL_SGIS_generate_mipmap */ 668f3b85c983f469875ac76081a61539a6c7b26777cBrian Paul if (level == texObj->BaseLevel && texObj->GenerateMipmap) { 669d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul _mesa_generate_mipmap(ctx, target, 670f3b85c983f469875ac76081a61539a6c7b26777cBrian Paul &ctx->Texture.Unit[ctx->Texture.CurrentUnit], 671f3b85c983f469875ac76081a61539a6c7b26777cBrian Paul texObj); 672f3b85c983f469875ac76081a61539a6c7b26777cBrian Paul } 6733893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul } 6748e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul} 6758e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul 6768e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul 6778e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul/* 6788e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * This is the software fallback for Driver.TexImage2D(). 6798e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * The texture image type will be GLchan. 6808e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * The texture image format will be GL_COLOR_INDEX, GL_INTENSITY, 6818e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * GL_LUMINANCE, GL_LUMINANCE_ALPHA, GL_ALPHA, GL_RGB or GL_RGBA. 6828e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * 683e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul * NOTE: if real texture compression is supported, this whole function 684e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul * will need to be overridden. 6858e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul */ 6868e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paulvoid 6878e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul_mesa_store_teximage2d(GLcontext *ctx, GLenum target, GLint level, 6888e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul GLint internalFormat, 6898e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul GLint width, GLint height, GLint border, 6908e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul GLenum format, GLenum type, const void *pixels, 6918e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul const struct gl_pixelstore_attrib *packing, 6928e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul struct gl_texture_object *texObj, 6938e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul struct gl_texture_image *texImage) 6948e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul{ 6958e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul GLint postConvWidth = width, postConvHeight = height; 696e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul GLint texelBytes, sizeInBytes; 6978e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul 6988e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul if (ctx->_ImageTransferState & IMAGE_CONVOLUTION_BIT) { 6998e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul _mesa_adjust_image_for_convolution(ctx, 2, &postConvWidth, 7008e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul &postConvHeight); 7018e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul } 7028e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul 7037d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul /* choose the texture format */ 7047d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul assert(ctx->Driver.ChooseTextureFormat); 7057d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul texImage->TexFormat = (*ctx->Driver.ChooseTextureFormat)(ctx, 7067d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul internalFormat, format, type); 7077d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul assert(texImage->TexFormat); 7083893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul texImage->FetchTexel = texImage->TexFormat->FetchTexel2D; 7092c3d34c905fa6b831a066afae83b938de05eb241Gareth Hughes 7102c3d34c905fa6b831a066afae83b938de05eb241Gareth Hughes texelBytes = texImage->TexFormat->TexelBytes; 7118e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul 712e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul /* Compute image size, in bytes */ 713e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul if (texImage->IsCompressed) { 714e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul assert(ctx->Driver.CompressedTextureSize); 715e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul sizeInBytes = ctx->Driver.CompressedTextureSize(ctx, texImage); 716e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul assert(sizeInBytes > 0); 717e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul texImage->CompressedSize = sizeInBytes; 718e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul } 719e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul else { 720e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul sizeInBytes = postConvWidth * postConvHeight * texelBytes; 721e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul } 722e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul 7238e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul /* allocate memory */ 724aeb4434563c4014a662ea334878b60d3031bb3c1Brian Paul texImage->Data = MESA_PBUFFER_ALLOC(sizeInBytes); 7257d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul if (!texImage->Data) { 7267d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D"); 7277d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul return; 7287d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul } 7298e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul 730f3b85c983f469875ac76081a61539a6c7b26777cBrian Paul if (pixels) { 731f3b85c983f469875ac76081a61539a6c7b26777cBrian Paul /* unpack image, apply transfer ops and store in texImage->Data */ 732f3b85c983f469875ac76081a61539a6c7b26777cBrian Paul _mesa_transfer_teximage(ctx, 2, 733f3b85c983f469875ac76081a61539a6c7b26777cBrian Paul _mesa_base_tex_format(ctx, internalFormat), 734f3b85c983f469875ac76081a61539a6c7b26777cBrian Paul texImage->TexFormat, texImage->Data, 735f3b85c983f469875ac76081a61539a6c7b26777cBrian Paul width, height, 1, 0, 0, 0, 736f3b85c983f469875ac76081a61539a6c7b26777cBrian Paul texImage->Width * texelBytes, 737f3b85c983f469875ac76081a61539a6c7b26777cBrian Paul 0, /* dstImageStride */ 738f3b85c983f469875ac76081a61539a6c7b26777cBrian Paul format, type, pixels, packing); 739f3b85c983f469875ac76081a61539a6c7b26777cBrian Paul 740f3b85c983f469875ac76081a61539a6c7b26777cBrian Paul /* GL_SGIS_generate_mipmap */ 741f3b85c983f469875ac76081a61539a6c7b26777cBrian Paul if (level == texObj->BaseLevel && texObj->GenerateMipmap) { 742d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul _mesa_generate_mipmap(ctx, target, 743f3b85c983f469875ac76081a61539a6c7b26777cBrian Paul &ctx->Texture.Unit[ctx->Texture.CurrentUnit], 744f3b85c983f469875ac76081a61539a6c7b26777cBrian Paul texObj); 745f3b85c983f469875ac76081a61539a6c7b26777cBrian Paul } 7463893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul } 7478e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul} 7488e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul 7498e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul 7508e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul 7518e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul/* 7528e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * This is the software fallback for Driver.TexImage3D(). 7538e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * The texture image type will be GLchan. 7548e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * The texture image format will be GL_COLOR_INDEX, GL_INTENSITY, 7558e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * GL_LUMINANCE, GL_LUMINANCE_ALPHA, GL_ALPHA, GL_RGB or GL_RGBA. 7568e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * 7578e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul */ 7588e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paulvoid 7598e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul_mesa_store_teximage3d(GLcontext *ctx, GLenum target, GLint level, 7608e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul GLint internalFormat, 7618e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul GLint width, GLint height, GLint depth, GLint border, 7628e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul GLenum format, GLenum type, const void *pixels, 7638e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul const struct gl_pixelstore_attrib *packing, 7648e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul struct gl_texture_object *texObj, 7658e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul struct gl_texture_image *texImage) 7668e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul{ 767e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul GLint texelBytes, sizeInBytes; 7688e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul 7697d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul /* choose the texture format */ 7707d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul assert(ctx->Driver.ChooseTextureFormat); 7717d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul texImage->TexFormat = (*ctx->Driver.ChooseTextureFormat)(ctx, 7727d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul internalFormat, format, type); 7737d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul assert(texImage->TexFormat); 7749228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul texImage->FetchTexel = texImage->TexFormat->FetchTexel3D; 7752c3d34c905fa6b831a066afae83b938de05eb241Gareth Hughes 776197c526d63e1d4ea96f29eece392cdc389770b38Brian Paul texelBytes = texImage->TexFormat->TexelBytes; 7778e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul 778e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul /* Compute image size, in bytes */ 779e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul if (texImage->IsCompressed) { 780e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul assert(ctx->Driver.CompressedTextureSize); 781e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul sizeInBytes = ctx->Driver.CompressedTextureSize(ctx, texImage); 782e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul assert(sizeInBytes > 0); 783e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul texImage->CompressedSize = sizeInBytes; 784e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul } 785e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul else { 786e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul sizeInBytes = width * height * depth * texelBytes; 787e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul } 788e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul 7898e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul /* allocate memory */ 790aeb4434563c4014a662ea334878b60d3031bb3c1Brian Paul texImage->Data = MESA_PBUFFER_ALLOC(sizeInBytes); 7917d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul if (!texImage->Data) { 7927d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage3D"); 7937d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul return; 7947d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul } 7958e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul 796f3b85c983f469875ac76081a61539a6c7b26777cBrian Paul if (pixels) { 797f3b85c983f469875ac76081a61539a6c7b26777cBrian Paul /* unpack image, apply transfer ops and store in texImage->Data */ 798f3b85c983f469875ac76081a61539a6c7b26777cBrian Paul _mesa_transfer_teximage(ctx, 3, 799f3b85c983f469875ac76081a61539a6c7b26777cBrian Paul _mesa_base_tex_format(ctx, internalFormat), 800f3b85c983f469875ac76081a61539a6c7b26777cBrian Paul texImage->TexFormat, texImage->Data, 801f3b85c983f469875ac76081a61539a6c7b26777cBrian Paul width, height, depth, 0, 0, 0, 802f3b85c983f469875ac76081a61539a6c7b26777cBrian Paul texImage->Width * texelBytes, 803f3b85c983f469875ac76081a61539a6c7b26777cBrian Paul texImage->Width * texImage->Height * texelBytes, 804f3b85c983f469875ac76081a61539a6c7b26777cBrian Paul format, type, pixels, packing); 805f3b85c983f469875ac76081a61539a6c7b26777cBrian Paul 806f3b85c983f469875ac76081a61539a6c7b26777cBrian Paul /* GL_SGIS_generate_mipmap */ 807f3b85c983f469875ac76081a61539a6c7b26777cBrian Paul if (level == texObj->BaseLevel && texObj->GenerateMipmap) { 808d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul _mesa_generate_mipmap(ctx, target, 809f3b85c983f469875ac76081a61539a6c7b26777cBrian Paul &ctx->Texture.Unit[ctx->Texture.CurrentUnit], 810f3b85c983f469875ac76081a61539a6c7b26777cBrian Paul texObj); 811f3b85c983f469875ac76081a61539a6c7b26777cBrian Paul } 8123893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul } 8138e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul} 8148e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul 8158e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul 8168e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul 8178e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul 8188e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul/* 8198e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * This is the software fallback for Driver.TexSubImage1D(). 8208e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul */ 8218e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paulvoid 8228e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul_mesa_store_texsubimage1d(GLcontext *ctx, GLenum target, GLint level, 8238e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul GLint xoffset, GLint width, 8248e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul GLenum format, GLenum type, const void *pixels, 8258e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul const struct gl_pixelstore_attrib *packing, 8268e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul struct gl_texture_object *texObj, 8278e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul struct gl_texture_image *texImage) 8288e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul{ 8291c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul _mesa_transfer_teximage(ctx, 1, 8301c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul _mesa_base_tex_format(ctx, texImage->IntFormat), 8311c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul texImage->TexFormat, texImage->Data, 8328e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul width, 1, 1, /* src size */ 8338e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul xoffset, 0, 0, /* dest offsets */ 8348e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul 0, /* dstRowStride */ 8358e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul 0, /* dstImageStride */ 8368e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul format, type, pixels, packing); 8373893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul 8383893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul /* GL_SGIS_generate_mipmap */ 8393893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul if (level == texObj->BaseLevel && texObj->GenerateMipmap) { 840d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul _mesa_generate_mipmap(ctx, target, 841d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul &ctx->Texture.Unit[ctx->Texture.CurrentUnit], 8423893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul texObj); 8433893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul } 8448e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul} 8458e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul 8468e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul 8478e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul/* 8488e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * This is the software fallback for Driver.TexSubImage2D(). 8498e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul */ 8508e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paulvoid 8518e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul_mesa_store_texsubimage2d(GLcontext *ctx, GLenum target, GLint level, 8528e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul GLint xoffset, GLint yoffset, 8538e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul GLint width, GLint height, 8548e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul GLenum format, GLenum type, const void *pixels, 8558e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul const struct gl_pixelstore_attrib *packing, 8568e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul struct gl_texture_object *texObj, 8578e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul struct gl_texture_image *texImage) 8588e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul{ 8591c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul _mesa_transfer_teximage(ctx, 2, 8601c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul _mesa_base_tex_format(ctx, texImage->IntFormat), 8611c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul texImage->TexFormat, texImage->Data, 8628e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul width, height, 1, /* src size */ 8638e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul xoffset, yoffset, 0, /* dest offsets */ 86438f28665bf9fb5b2464738ca5074848ec2777ae1Gareth Hughes texImage->Width * texImage->TexFormat->TexelBytes, 8658e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul 0, /* dstImageStride */ 8668e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul format, type, pixels, packing); 8673893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul 8683893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul /* GL_SGIS_generate_mipmap */ 8693893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul if (level == texObj->BaseLevel && texObj->GenerateMipmap) { 870d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul _mesa_generate_mipmap(ctx, target, 871d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul &ctx->Texture.Unit[ctx->Texture.CurrentUnit], 8723893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul texObj); 8733893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul } 8748e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul} 8758e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul 8768e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul 8778e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul/* 8788e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * This is the software fallback for Driver.TexSubImage3D(). 8798e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul */ 8808e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paulvoid 8818e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul_mesa_store_texsubimage3d(GLcontext *ctx, GLenum target, GLint level, 8828e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul GLint xoffset, GLint yoffset, GLint zoffset, 8838e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul GLint width, GLint height, GLint depth, 8848e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul GLenum format, GLenum type, const void *pixels, 8858e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul const struct gl_pixelstore_attrib *packing, 8868e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul struct gl_texture_object *texObj, 8878e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul struct gl_texture_image *texImage) 8888e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul{ 88938f28665bf9fb5b2464738ca5074848ec2777ae1Gareth Hughes const GLint texelBytes = texImage->TexFormat->TexelBytes; 8901c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul _mesa_transfer_teximage(ctx, 3, 8911c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul _mesa_base_tex_format(ctx, texImage->IntFormat), 8921c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul texImage->TexFormat, texImage->Data, 8938e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul width, height, depth, /* src size */ 8948e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul xoffset, yoffset, xoffset, /* dest offsets */ 89538f28665bf9fb5b2464738ca5074848ec2777ae1Gareth Hughes texImage->Width * texelBytes, 89638f28665bf9fb5b2464738ca5074848ec2777ae1Gareth Hughes texImage->Width * texImage->Height * texelBytes, 8978e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul format, type, pixels, packing); 8983893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul /* GL_SGIS_generate_mipmap */ 8993893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul if (level == texObj->BaseLevel && texObj->GenerateMipmap) { 900d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul _mesa_generate_mipmap(ctx, target, 901d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul &ctx->Texture.Unit[ctx->Texture.CurrentUnit], 9023893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul texObj); 9033893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul } 9048e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul} 9058e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul 9068e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul 9078e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul 9082aadbf41dfd4f63c6118d0ad2d8659d289cbe454Brian Paul 9092aadbf41dfd4f63c6118d0ad2d8659d289cbe454Brian Paul/* 9108e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * Fallback for Driver.CompressedTexImage1D() 9118e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul */ 9128e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paulvoid 9138e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul_mesa_store_compressed_teximage1d(GLcontext *ctx, GLenum target, GLint level, 9148e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul GLint internalFormat, 9158e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul GLint width, GLint border, 9168e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul GLsizei imageSize, const GLvoid *data, 9178e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul struct gl_texture_object *texObj, 9188e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul struct gl_texture_image *texImage) 9198e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul{ 9208e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul /* Nothing here. 9218e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * The device driver has to do it all. 9228e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul */ 9238e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul} 9248e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul 9258e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul 9268e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul 9278e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul/* 9288e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * Fallback for Driver.CompressedTexImage2D() 9298e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul */ 9308e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paulvoid 9318e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul_mesa_store_compressed_teximage2d(GLcontext *ctx, GLenum target, GLint level, 9328e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul GLint internalFormat, 9338e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul GLint width, GLint height, GLint border, 9348e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul GLsizei imageSize, const GLvoid *data, 9358e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul struct gl_texture_object *texObj, 9368e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul struct gl_texture_image *texImage) 9378e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul{ 9388e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul /* Nothing here. 9398e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * The device driver has to do it all. 9408e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul */ 9418e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul} 9428e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul 9438e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul 9448e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul 9458e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul/* 9468e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * Fallback for Driver.CompressedTexImage3D() 9478e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul */ 9488e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paulvoid 9498e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul_mesa_store_compressed_teximage3d(GLcontext *ctx, GLenum target, GLint level, 9508e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul GLint internalFormat, 9518e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul GLint width, GLint height, GLint depth, 9528e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul GLint border, 9538e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul GLsizei imageSize, const GLvoid *data, 9548e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul struct gl_texture_object *texObj, 9558e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul struct gl_texture_image *texImage) 9568e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul{ 9578e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul /* Nothing here. 9588e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * The device driver has to do it all. 9598e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul */ 9608e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul} 9618e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul 9628e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul 9638e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul 9648e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul/* 965e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul * Fallback for Driver.GetCompressedTexImage3D() 966e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul * This will probably work find for hardware drivers. That is, hardware 967e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul * drivers won't have to override this function, unless the compressed 968e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul * texture must first be fetched from the TRAM. 969e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul */ 970e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paulvoid 971e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul_mesa_get_compressed_teximage(GLcontext *ctx, GLenum target, 972e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul GLint level, void *image, 973e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul const struct gl_texture_object *texObj, 974e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul struct gl_texture_image *texImage) 975e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul{ 976e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul assert(texImage->IsCompressed); 977e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul assert(texImage->CompressedSize > 0); 978e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul MEMCPY(image, texImage->Data, texImage->CompressedSize); 979e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul} 980e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul 981e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul 982e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul 983e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul/* 9848e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * This is the fallback for Driver.TestProxyTexImage(). 9858e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul */ 9868e39ad2cd67d49be40ff0822f3269affdf83d601Brian PaulGLboolean 9878e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul_mesa_test_proxy_teximage(GLcontext *ctx, GLenum target, GLint level, 9888e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul GLint internalFormat, GLenum format, GLenum type, 9898e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul GLint width, GLint height, GLint depth, GLint border) 9908e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul{ 9918e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul struct gl_texture_unit *texUnit; 9928e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul struct gl_texture_object *texObj; 9938e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul struct gl_texture_image *texImage; 9948e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul 9958e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul (void) format; 9968e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul (void) type; 9978e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul 9988e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; 9998e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul texObj = _mesa_select_tex_object(ctx, texUnit, target); 10008e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul texImage = _mesa_select_tex_image(ctx, texUnit, target, level); 10018e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul 10028e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul /* We always pass. 10038e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * The core Mesa code will have already tested the image size, etc. 10049228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul * If a driver has more stringent texture limits to enforce it will 10058e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * have to override this function. 10068e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul */ 10077d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul /* choose the texture format */ 10087d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul assert(ctx->Driver.ChooseTextureFormat); 10097d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul texImage->TexFormat = (*ctx->Driver.ChooseTextureFormat)(ctx, 10107d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul internalFormat, format, type); 10117d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul assert(texImage->TexFormat); 10128e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul 10138e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul return GL_TRUE; 10148e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul} 10153893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul 10163893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul 10173893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul 10183893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul/* 10193893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul * Average together two rows of a source image to produce a single new 10203893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul * row in the dest image. It's legal for the two source rows to point 10219228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul * to the same data. The source width must be equal to either the 10229228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul * dest width or two times the dest width. 10233893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul */ 10243893e638e6521b9c070e01c0b31d22754ff97a88Brian Paulstatic void 10259228e17bb5bf219269daeed5cbfdd912c118e926Brian Pauldo_row(const struct gl_texture_format *format, GLint srcWidth, 10269228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLvoid *srcRowA, const GLvoid *srcRowB, 10279228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul GLint dstWidth, GLvoid *dstRow) 10283893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul{ 10299228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLuint k0 = (srcWidth == dstWidth) ? 0 : 1; 10309228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLuint colStride = (srcWidth == dstWidth) ? 1 : 2; 10319228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul 10329228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul assert(srcWidth == dstWidth || srcWidth == 2 * dstWidth); 10339228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul 10343893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul switch (format->MesaFormat) { 10353893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul case MESA_FORMAT_RGBA: 10363893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul { 10379228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul GLuint i, j, k; 10383893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul const GLchan (*rowA)[4] = (const GLchan (*)[4]) srcRowA; 10393893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul const GLchan (*rowB)[4] = (const GLchan (*)[4]) srcRowB; 10403893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul GLchan (*dst)[4] = (GLchan (*)[4]) dstRow; 10417c4268176eaaeb45003db4d5042a518b84c9f6dcKarl Schultz for (i = j = 0, k = k0; i < (GLuint) dstWidth; 10429228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul i++, j += colStride, k += colStride) { 10439228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul dst[i][0] = (rowA[j][0] + rowA[k][0] + 1044f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul rowB[j][0] + rowB[k][0]) / 4; 10459228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul dst[i][1] = (rowA[j][1] + rowA[k][1] + 1046f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul rowB[j][1] + rowB[k][1]) / 4; 10479228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul dst[i][2] = (rowA[j][2] + rowA[k][2] + 1048f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul rowB[j][2] + rowB[k][2]) / 4; 10499228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul dst[i][3] = (rowA[j][3] + rowA[k][3] + 1050f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul rowB[j][3] + rowB[k][3]) / 4; 10513893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul } 10523893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul } 10533893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul return; 10543893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul case MESA_FORMAT_RGB: 10553893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul { 10569228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul GLuint i, j, k; 10573893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul const GLchan (*rowA)[3] = (const GLchan (*)[3]) srcRowA; 10583893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul const GLchan (*rowB)[3] = (const GLchan (*)[3]) srcRowB; 10593893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul GLchan (*dst)[3] = (GLchan (*)[3]) dstRow; 10607c4268176eaaeb45003db4d5042a518b84c9f6dcKarl Schultz for (i = j = 0, k = k0; i < (GLuint) dstWidth; 10619228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul i++, j += colStride, k += colStride) { 10629228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul dst[i][0] = (rowA[j][0] + rowA[k][0] + 1063f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul rowB[j][0] + rowB[k][0]) / 4; 10649228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul dst[i][1] = (rowA[j][1] + rowA[k][1] + 1065f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul rowB[j][1] + rowB[k][1]) / 4; 10669228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul dst[i][2] = (rowA[j][2] + rowA[k][2] + 1067f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul rowB[j][2] + rowB[k][2]) / 4; 10683893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul } 10693893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul } 10703893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul return; 10713893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul case MESA_FORMAT_ALPHA: 10723893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul case MESA_FORMAT_LUMINANCE: 10733893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul case MESA_FORMAT_INTENSITY: 10743893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul case MESA_FORMAT_COLOR_INDEX: 10753893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul { 10769228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul GLuint i, j, k; 10773893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul const GLchan *rowA = (const GLchan *) srcRowA; 10783893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul const GLchan *rowB = (const GLchan *) srcRowB; 10793893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul GLchan *dst = (GLchan *) dstRow; 10807c4268176eaaeb45003db4d5042a518b84c9f6dcKarl Schultz for (i = j = 0, k = k0; i < (GLuint) dstWidth; 10819228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul i++, j += colStride, k += colStride) { 1082f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul dst[i] = (rowA[j] + rowA[k] + rowB[j] + rowB[k]) / 4; 10833893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul } 10843893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul } 10853893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul return; 10863893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul case MESA_FORMAT_LUMINANCE_ALPHA: 10873893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul { 10889228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul GLuint i, j, k; 10893893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul const GLchan (*rowA)[2] = (const GLchan (*)[2]) srcRowA; 10903893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul const GLchan (*rowB)[2] = (const GLchan (*)[2]) srcRowB; 10913893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul GLchan (*dst)[2] = (GLchan (*)[2]) dstRow; 10927c4268176eaaeb45003db4d5042a518b84c9f6dcKarl Schultz for (i = j = 0, k = k0; i < (GLuint) dstWidth; 10939228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul i++, j += colStride, k += colStride) { 10949228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul dst[i][0] = (rowA[j][0] + rowA[k][0] + 1095f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul rowB[j][0] + rowB[k][0]) / 4; 10969228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul dst[i][1] = (rowA[j][1] + rowA[k][1] + 1097f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul rowB[j][1] + rowB[k][1]) / 4; 10983893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul } 10993893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul } 11003893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul return; 11013893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul case MESA_FORMAT_DEPTH_COMPONENT: 11028bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul { 11039228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul GLuint i, j, k; 11048bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul const GLfloat *rowA = (const GLfloat *) srcRowA; 11058bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul const GLfloat *rowB = (const GLfloat *) srcRowB; 11068bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul GLfloat *dst = (GLfloat *) dstRow; 11077c4268176eaaeb45003db4d5042a518b84c9f6dcKarl Schultz for (i = j = 0, k = k0; i < (GLuint) dstWidth; 11089228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul i++, j += colStride, k += colStride) { 11099228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul dst[i] = (rowA[j] + rowA[k] + rowB[j] + rowB[k]) * 0.25F; 11108bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul } 11118bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul } 11128bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul return; 11138bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul /* Begin hardware formats */ 11148bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul case MESA_FORMAT_RGBA8888: 11158bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul case MESA_FORMAT_ARGB8888: 11168bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul { 11179228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul GLuint i, j, k; 11188bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul const GLubyte (*rowA)[4] = (const GLubyte (*)[4]) srcRowA; 11198bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul const GLubyte (*rowB)[4] = (const GLubyte (*)[4]) srcRowB; 11208bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul GLubyte (*dst)[4] = (GLubyte (*)[4]) dstRow; 11217c4268176eaaeb45003db4d5042a518b84c9f6dcKarl Schultz for (i = j = 0, k = k0; i < (GLuint) dstWidth; 11229228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul i++, j += colStride, k += colStride) { 11239228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul dst[i][0] = (rowA[j][0] + rowA[k][0] + 1124f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul rowB[j][0] + rowB[k][0]) / 4; 11259228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul dst[i][1] = (rowA[j][1] + rowA[k][1] + 1126f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul rowB[j][1] + rowB[k][1]) / 4; 11279228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul dst[i][2] = (rowA[j][2] + rowA[k][2] + 1128f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul rowB[j][2] + rowB[k][2]) / 4; 11299228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul dst[i][3] = (rowA[j][3] + rowA[k][3] + 1130f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul rowB[j][3] + rowB[k][3]) / 4; 11318bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul } 11328bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul } 11338bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul return; 11348bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul case MESA_FORMAT_RGB888: 11358bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul { 11369228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul GLuint i, j, k; 11378bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul const GLubyte (*rowA)[3] = (const GLubyte (*)[3]) srcRowA; 11388bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul const GLubyte (*rowB)[3] = (const GLubyte (*)[3]) srcRowB; 11398bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul GLubyte (*dst)[3] = (GLubyte (*)[3]) dstRow; 11407c4268176eaaeb45003db4d5042a518b84c9f6dcKarl Schultz for (i = j = 0, k = k0; i < (GLuint) dstWidth; 11419228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul i++, j += colStride, k += colStride) { 11429228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul dst[i][0] = (rowA[j][0] + rowA[k][0] + 1143f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul rowB[j][0] + rowB[k][0]) / 4; 11449228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul dst[i][1] = (rowA[j][1] + rowA[k][1] + 1145f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul rowB[j][1] + rowB[k][1]) / 4; 11469228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul dst[i][2] = (rowA[j][2] + rowA[k][2] + 1147f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul rowB[j][2] + rowB[k][2]) / 4; 11488bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul } 11498bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul } 11508bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul return; 11518bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul case MESA_FORMAT_RGB565: 11528bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul { 11539228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul GLuint i, j, k; 11548bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul const GLushort *rowA = (const GLushort *) srcRowA; 11558bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul const GLushort *rowB = (const GLushort *) srcRowB; 11568bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul GLushort *dst = (GLushort *) dstRow; 11577c4268176eaaeb45003db4d5042a518b84c9f6dcKarl Schultz for (i = j = 0, k = k0; i < (GLuint) dstWidth; 11589228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul i++, j += colStride, k += colStride) { 11599228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLint rowAr0 = rowA[j] & 0x1f; 11609228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLint rowAr1 = rowA[k] & 0x1f; 11619228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLint rowBr0 = rowB[j] & 0x1f; 11629228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLint rowBr1 = rowB[k] & 0x1f; 11639228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLint rowAg0 = (rowA[j] >> 5) & 0x3f; 11649228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLint rowAg1 = (rowA[k] >> 5) & 0x3f; 11659228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLint rowBg0 = (rowB[j] >> 5) & 0x3f; 11669228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLint rowBg1 = (rowB[k] >> 5) & 0x3f; 11679228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLint rowAb0 = (rowA[j] >> 11) & 0x1f; 11689228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLint rowAb1 = (rowA[k] >> 11) & 0x1f; 11699228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLint rowBb0 = (rowB[j] >> 11) & 0x1f; 11709228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLint rowBb1 = (rowB[k] >> 11) & 0x1f; 11718bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul const GLint red = (rowAr0 + rowAr1 + rowBr0 + rowBr1) >> 4; 11728bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul const GLint green = (rowAg0 + rowAg1 + rowBg0 + rowBg1) >> 4; 11738bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul const GLint blue = (rowAb0 + rowAb1 + rowBb0 + rowBb1) >> 4; 11748bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul dst[i] = (blue << 11) | (green << 5) | red; 11758bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul } 11768bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul } 11778bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul return; 11788bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul case MESA_FORMAT_ARGB4444: 11798bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul { 11809228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul GLuint i, j, k; 11818bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul const GLushort *rowA = (const GLushort *) srcRowA; 11828bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul const GLushort *rowB = (const GLushort *) srcRowB; 11838bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul GLushort *dst = (GLushort *) dstRow; 11847c4268176eaaeb45003db4d5042a518b84c9f6dcKarl Schultz for (i = j = 0, k = k0; i < (GLuint) dstWidth; 11859228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul i++, j += colStride, k += colStride) { 11869228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLint rowAr0 = rowA[j] & 0xf; 11879228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLint rowAr1 = rowA[k] & 0xf; 11889228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLint rowBr0 = rowB[j] & 0xf; 11899228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLint rowBr1 = rowB[k] & 0xf; 11909228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLint rowAg0 = (rowA[j] >> 4) & 0xf; 11919228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLint rowAg1 = (rowA[k] >> 4) & 0xf; 11929228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLint rowBg0 = (rowB[j] >> 4) & 0xf; 11939228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLint rowBg1 = (rowB[k] >> 4) & 0xf; 11949228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLint rowAb0 = (rowA[j] >> 8) & 0xf; 11959228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLint rowAb1 = (rowA[k] >> 8) & 0xf; 11969228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLint rowBb0 = (rowB[j] >> 8) & 0xf; 11979228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLint rowBb1 = (rowB[k] >> 8) & 0xf; 11989228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLint rowAa0 = (rowA[j] >> 12) & 0xf; 11999228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLint rowAa1 = (rowA[k] >> 12) & 0xf; 12009228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLint rowBa0 = (rowB[j] >> 12) & 0xf; 12019228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLint rowBa1 = (rowB[k] >> 12) & 0xf; 12028bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul const GLint red = (rowAr0 + rowAr1 + rowBr0 + rowBr1) >> 4; 12038bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul const GLint green = (rowAg0 + rowAg1 + rowBg0 + rowBg1) >> 4; 12048bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul const GLint blue = (rowAb0 + rowAb1 + rowBb0 + rowBb1) >> 4; 12058bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul const GLint alpha = (rowAa0 + rowAa1 + rowBa0 + rowBa1) >> 4; 12068bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul dst[i] = (alpha << 12) | (blue << 8) | (green << 4) | red; 12078bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul } 12088bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul } 12098bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul return; 12108bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul case MESA_FORMAT_ARGB1555: 12118bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul { 12129228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul GLuint i, j, k; 12138bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul const GLushort *rowA = (const GLushort *) srcRowA; 12148bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul const GLushort *rowB = (const GLushort *) srcRowB; 12158bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul GLushort *dst = (GLushort *) dstRow; 12167c4268176eaaeb45003db4d5042a518b84c9f6dcKarl Schultz for (i = j = 0, k = k0; i < (GLuint) dstWidth; 12179228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul i++, j += colStride, k += colStride) { 12189228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLint rowAr0 = rowA[j] & 0x1f; 12199228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLint rowAr1 = rowA[k] & 0x1f; 12209228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLint rowBr0 = rowB[j] & 0x1f; 12219228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLint rowBr1 = rowB[k] & 0xf; 12229228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLint rowAg0 = (rowA[j] >> 5) & 0x1f; 12239228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLint rowAg1 = (rowA[k] >> 5) & 0x1f; 12249228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLint rowBg0 = (rowB[j] >> 5) & 0x1f; 12259228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLint rowBg1 = (rowB[k] >> 5) & 0x1f; 12269228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLint rowAb0 = (rowA[j] >> 10) & 0x1f; 12279228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLint rowAb1 = (rowA[k] >> 10) & 0x1f; 12289228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLint rowBb0 = (rowB[j] >> 10) & 0x1f; 12299228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLint rowBb1 = (rowB[k] >> 10) & 0x1f; 12309228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLint rowAa0 = (rowA[j] >> 15) & 0x1; 12319228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLint rowAa1 = (rowA[k] >> 15) & 0x1; 12329228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLint rowBa0 = (rowB[j] >> 15) & 0x1; 12339228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLint rowBa1 = (rowB[k] >> 15) & 0x1; 12348bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul const GLint red = (rowAr0 + rowAr1 + rowBr0 + rowBr1) >> 4; 12358bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul const GLint green = (rowAg0 + rowAg1 + rowBg0 + rowBg1) >> 4; 12368bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul const GLint blue = (rowAb0 + rowAb1 + rowBb0 + rowBb1) >> 4; 12378bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul const GLint alpha = (rowAa0 + rowAa1 + rowBa0 + rowBa1) >> 4; 12388bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul dst[i] = (alpha << 15) | (blue << 10) | (green << 5) | red; 12398bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul } 12408bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul } 12418bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul return; 12428bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul case MESA_FORMAT_AL88: 12438bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul { 12449228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul GLuint i, j, k; 12458bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul const GLubyte (*rowA)[2] = (const GLubyte (*)[2]) srcRowA; 12468bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul const GLubyte (*rowB)[2] = (const GLubyte (*)[2]) srcRowB; 12478bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul GLubyte (*dst)[2] = (GLubyte (*)[2]) dstRow; 12487c4268176eaaeb45003db4d5042a518b84c9f6dcKarl Schultz for (i = j = 0, k = k0; i < (GLuint) dstWidth; 12499228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul i++, j += colStride, k += colStride) { 12509228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul dst[i][0] = (rowA[j][0] + rowA[k][0] + 12519228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul rowB[j][0] + rowB[k][0]) >> 2; 12529228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul dst[i][1] = (rowA[j][1] + rowA[k][1] + 12539228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul rowB[j][1] + rowB[k][1]) >> 2; 12548bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul } 12558bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul } 12568bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul return; 12578bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul case MESA_FORMAT_RGB332: 12588bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul { 12599228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul GLuint i, j, k; 12608bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul const GLubyte *rowA = (const GLubyte *) srcRowA; 12618bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul const GLubyte *rowB = (const GLubyte *) srcRowB; 12628bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul GLubyte *dst = (GLubyte *) dstRow; 12637c4268176eaaeb45003db4d5042a518b84c9f6dcKarl Schultz for (i = j = 0, k = k0; i < (GLuint) dstWidth; 12649228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul i++, j += colStride, k += colStride) { 12659228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLint rowAr0 = rowA[j] & 0x3; 12669228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLint rowAr1 = rowA[k] & 0x3; 12679228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLint rowBr0 = rowB[j] & 0x3; 12689228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLint rowBr1 = rowB[k] & 0x3; 12699228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLint rowAg0 = (rowA[j] >> 2) & 0x7; 12709228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLint rowAg1 = (rowA[k] >> 2) & 0x7; 12719228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLint rowBg0 = (rowB[j] >> 2) & 0x7; 12729228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLint rowBg1 = (rowB[k] >> 2) & 0x7; 12739228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLint rowAb0 = (rowA[j] >> 5) & 0x7; 12749228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLint rowAb1 = (rowA[k] >> 5) & 0x7; 12759228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLint rowBb0 = (rowB[j] >> 5) & 0x7; 12769228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLint rowBb1 = (rowB[k] >> 5) & 0x7; 12778bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul const GLint red = (rowAr0 + rowAr1 + rowBr0 + rowBr1) >> 4; 12788bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul const GLint green = (rowAg0 + rowAg1 + rowBg0 + rowBg1) >> 4; 12798bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul const GLint blue = (rowAb0 + rowAb1 + rowBb0 + rowBb1) >> 4; 12808bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul dst[i] = (blue << 5) | (green << 2) | red; 12818bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul } 12828bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul } 12838bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul return; 12848bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul case MESA_FORMAT_A8: 12858bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul case MESA_FORMAT_L8: 12868bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul case MESA_FORMAT_I8: 12878bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul case MESA_FORMAT_CI8: 12888bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul { 12899228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul GLuint i, j, k; 12908bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul const GLubyte *rowA = (const GLubyte *) srcRowA; 12918bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul const GLubyte *rowB = (const GLubyte *) srcRowB; 12928bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul GLubyte *dst = (GLubyte *) dstRow; 12937c4268176eaaeb45003db4d5042a518b84c9f6dcKarl Schultz for (i = j = 0, k = k0; i < (GLuint) dstWidth; 12949228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul i++, j += colStride, k += colStride) { 12959228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul dst[i] = (rowA[j] + rowA[k] + rowB[j] + rowB[k]) >> 2; 12968bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul } 12978bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul } 12988bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul return; 12993893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul default: 13003893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul _mesa_problem(NULL, "bad format in do_row()"); 13013893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul } 13023893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul} 13033893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul 13043893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul 13059228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul/* 13069228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul * These functions generate a 1/2-size mipmap image from a source image. 13079228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul * Texture borders are handled by copying or averaging the source image's 13089228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul * border texels, depending on the scale-down factor. 13099228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul */ 13103893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul 13113893e638e6521b9c070e01c0b31d22754ff97a88Brian Paulstatic void 13123893e638e6521b9c070e01c0b31d22754ff97a88Brian Paulmake_1d_mipmap(const struct gl_texture_format *format, GLint border, 13133893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul GLint srcWidth, const GLubyte *srcPtr, 13143893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul GLint dstWidth, GLubyte *dstPtr) 13153893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul{ 13163893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul const GLint bpt = format->TexelBytes; 13173893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul const GLubyte *src; 13183893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul GLubyte *dst; 13193893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul 13203893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul /* skip the border pixel, if any */ 13213893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul src = srcPtr + border * bpt; 13223893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul dst = dstPtr + border * bpt; 13233893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul 13243893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul /* we just duplicate the input row, kind of hack, saves code */ 13259228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul do_row(format, srcWidth - 2 * border, src, src, 13269228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul dstWidth - 2 * border, dst); 13273893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul 13283893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul if (border) { 13293893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul /* copy left-most pixel from source */ 13303893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul MEMCPY(dstPtr, srcPtr, bpt); 13313893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul /* copy right-most pixel from source */ 13323893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul MEMCPY(dstPtr + (dstWidth - 1) * bpt, 13333893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul srcPtr + (srcWidth - 1) * bpt, 13343893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul bpt); 13353893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul } 13363893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul} 13373893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul 13383893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul 13393893e638e6521b9c070e01c0b31d22754ff97a88Brian Paulstatic void 13403893e638e6521b9c070e01c0b31d22754ff97a88Brian Paulmake_2d_mipmap(const struct gl_texture_format *format, GLint border, 13413893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul GLint srcWidth, GLint srcHeight, const GLubyte *srcPtr, 13423893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul GLint dstWidth, GLint dstHeight, GLubyte *dstPtr) 13433893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul{ 13443893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul const GLint bpt = format->TexelBytes; 13459228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLint srcWidthNB = srcWidth - 2 * border; /* sizes w/out border */ 13469228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLint dstWidthNB = dstWidth - 2 * border; 13479228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLint dstHeightNB = dstHeight - 2 * border; 13483893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul const GLint srcRowStride = bpt * srcWidth; 13493893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul const GLint dstRowStride = bpt * dstWidth; 13503893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul const GLubyte *srcA, *srcB; 13513893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul GLubyte *dst; 13529228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul GLint row, colStride; 13539228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul 13549228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul colStride = (srcWidth == dstWidth) ? 1 : 2; 13553893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul 13563893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul /* Compute src and dst pointers, skipping any border */ 13573893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul srcA = srcPtr + border * ((srcWidth + 1) * bpt); 13583893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul if (srcHeight > 1) 13593893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul srcB = srcA + srcRowStride; 13603893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul else 13613893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul srcB = srcA; 13623893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul dst = dstPtr + border * ((dstWidth + 1) * bpt); 13633893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul 13649228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul for (row = 0; row < dstHeightNB; row++) { 13659228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul do_row(format, srcWidthNB, srcA, srcB, 13669228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul dstWidthNB, dst); 13673893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul srcA += 2 * srcRowStride; 13683893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul srcB += 2 * srcRowStride; 13693893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul dst += dstRowStride; 13703893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul } 13713893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul 13728bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul /* This is ugly but probably won't be used much */ 13733893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul if (border > 0) { 13743893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul /* fill in dest border */ 13753893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul /* lower-left border pixel */ 13763893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul MEMCPY(dstPtr, srcPtr, bpt); 13773893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul /* lower-right border pixel */ 13783893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul MEMCPY(dstPtr + (dstWidth - 1) * bpt, 13793893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul srcPtr + (srcWidth - 1) * bpt, bpt); 13803893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul /* upper-left border pixel */ 13813893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul MEMCPY(dstPtr + dstWidth * (dstHeight - 1) * bpt, 13823893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul srcPtr + srcWidth * (srcHeight - 1) * bpt, bpt); 13833893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul /* upper-right border pixel */ 13843893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul MEMCPY(dstPtr + (dstWidth * dstHeight - 1) * bpt, 13853893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul srcPtr + (srcWidth * srcHeight - 1) * bpt, bpt); 13863893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul /* lower border */ 13879228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul do_row(format, srcWidthNB, 13889228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul srcPtr + bpt, 13899228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul srcPtr + bpt, 13909228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul dstWidthNB, dstPtr + bpt); 13913893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul /* upper border */ 13929228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul do_row(format, srcWidthNB, 13933893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul srcPtr + (srcWidth * (srcHeight - 1) + 1) * bpt, 13943893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul srcPtr + (srcWidth * (srcHeight - 1) + 1) * bpt, 13959228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul dstWidthNB, 13963893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul dstPtr + (dstWidth * (dstHeight - 1) + 1) * bpt); 13973893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul /* left and right borders */ 13989228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul if (srcHeight == dstHeight) { 13999228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul /* copy border pixel from src to dst */ 14009228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul for (row = 1; row < srcHeight; row++) { 14019228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul MEMCPY(dstPtr + dstWidth * row * bpt, 14029228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul srcPtr + srcWidth * row * bpt, bpt); 14039228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul MEMCPY(dstPtr + (dstWidth * row + dstWidth - 1) * bpt, 14049228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul srcPtr + (srcWidth * row + srcWidth - 1) * bpt, bpt); 14059228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul } 14069228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul } 14079228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul else { 14089228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul /* average two src pixels each dest pixel */ 14099228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul for (row = 0; row < dstHeightNB; row += 2) { 14109228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul do_row(format, 1, 14119228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul srcPtr + (srcWidth * (row * 2 + 1)) * bpt, 14129228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul srcPtr + (srcWidth * (row * 2 + 2)) * bpt, 14139228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul 1, dstPtr + (dstWidth * row + 1) * bpt); 14149228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul do_row(format, 1, 14159228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul srcPtr + (srcWidth * (row * 2 + 1) + srcWidth - 1) * bpt, 14169228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul srcPtr + (srcWidth * (row * 2 + 2) + srcWidth - 1) * bpt, 14179228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul 1, dstPtr + (dstWidth * row + 1 + dstWidth - 1) * bpt); 14189228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul } 14193893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul } 14203893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul } 14213893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul} 14223893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul 14233893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul 14243893e638e6521b9c070e01c0b31d22754ff97a88Brian Paulstatic void 14253893e638e6521b9c070e01c0b31d22754ff97a88Brian Paulmake_3d_mipmap(const struct gl_texture_format *format, GLint border, 14263893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul GLint srcWidth, GLint srcHeight, GLint srcDepth, 14273893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul const GLubyte *srcPtr, 14283893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul GLint dstWidth, GLint dstHeight, GLint dstDepth, 14293893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul GLubyte *dstPtr) 14303893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul{ 14319228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLint bpt = format->TexelBytes; 14329228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLint srcWidthNB = srcWidth - 2 * border; /* sizes w/out border */ 14339228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLint srcDepthNB = srcDepth - 2 * border; 14349228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLint dstWidthNB = dstWidth - 2 * border; 14359228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLint dstHeightNB = dstHeight - 2 * border; 14369228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLint dstDepthNB = dstDepth - 2 * border; 14379228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul GLvoid *tmpRowA, *tmpRowB; 14383893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul GLint img, row; 14399228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul GLint bytesPerSrcImage, bytesPerDstImage; 14409228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul GLint bytesPerSrcRow, bytesPerDstRow; 14419228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul GLint srcImageOffset, srcRowOffset; 14423893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul 14435c749d9e3c7824c0ba5b22e37d0ea5cbd54d6d2dBrian Paul (void) srcDepthNB; /* silence warnings */ 14445c749d9e3c7824c0ba5b22e37d0ea5cbd54d6d2dBrian Paul 14459228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul /* Need two temporary row buffers */ 14469228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul tmpRowA = MALLOC(srcWidth * bpt); 14479228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul if (!tmpRowA) 14489228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul return; 14499228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul tmpRowB = MALLOC(srcWidth * bpt); 14509228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul if (!tmpRowB) { 14519228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul FREE(tmpRowA); 14523893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul return; 14533893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul } 14543893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul 14559228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul bytesPerSrcImage = srcWidth * srcHeight * bpt; 14569228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul bytesPerDstImage = dstWidth * dstHeight * bpt; 14579228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul 14589228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul bytesPerSrcRow = srcWidth * bpt; 14599228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul bytesPerDstRow = dstWidth * bpt; 14603893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul 14619228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul /* Offset between adjacent src images to be averaged together */ 14629228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul srcImageOffset = (srcDepth == dstDepth) ? 0 : bytesPerSrcImage; 14633893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul 14649228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul /* Offset between adjacent src rows to be averaged together */ 14659228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul srcRowOffset = (srcHeight == dstHeight) ? 0 : srcWidth * bpt; 14663893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul 14679228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul /* 14689228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul * Need to average together up to 8 src pixels for each dest pixel. 14699228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul * Break that down into 3 operations: 14709228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul * 1. take two rows from source image and average them together. 14719228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul * 2. take two rows from next source image and average them together. 14729228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul * 3. take the two averaged rows and average them for the final dst row. 14739228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul */ 14743893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul 14759228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul /* 14764e9676fb13f60ecdbc247b120031f18cd3febcb0Brian Paul _mesa_printf("mip3d %d x %d x %d -> %d x %d x %d\n", 14779228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul srcWidth, srcHeight, srcDepth, dstWidth, dstHeight, dstDepth); 14789228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul */ 14799228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul 14809228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul for (img = 0; img < dstDepthNB; img++) { 14819228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul /* first source image pointer, skipping border */ 14829228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLubyte *imgSrcA = srcPtr 14839228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul + (bytesPerSrcImage + bytesPerSrcRow + border) * bpt * border 14849228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul + img * (bytesPerSrcImage + srcImageOffset); 14859228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul /* second source image pointer, skipping border */ 14869228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLubyte *imgSrcB = imgSrcA + srcImageOffset; 14879228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul /* address of the dest image, skipping border */ 14889228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul GLubyte *imgDst = dstPtr 14899228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul + (bytesPerDstImage + bytesPerDstRow + border) * bpt * border 14909228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul + img * bytesPerDstImage; 14919228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul 14929228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul /* setup the four source row pointers and the dest row pointer */ 14939228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLubyte *srcImgARowA = imgSrcA; 14949228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLubyte *srcImgARowB = imgSrcA + srcRowOffset; 14959228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLubyte *srcImgBRowA = imgSrcB; 14969228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLubyte *srcImgBRowB = imgSrcB + srcRowOffset; 14979228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul GLubyte *dstImgRow = imgDst; 14989228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul 14999228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul for (row = 0; row < dstHeightNB; row++) { 15009228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul /* Average together two rows from first src image */ 15019228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul do_row(format, srcWidthNB, srcImgARowA, srcImgARowB, 15029228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul srcWidthNB, tmpRowA); 15039228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul /* Average together two rows from second src image */ 15049228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul do_row(format, srcWidthNB, srcImgBRowA, srcImgBRowB, 15059228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul srcWidthNB, tmpRowB); 15069228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul /* Average together the temp rows to make the final row */ 15079228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul do_row(format, srcWidthNB, tmpRowA, tmpRowB, 15089228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul dstWidthNB, dstImgRow); 15099228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul /* advance to next rows */ 15109228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul srcImgARowA += bytesPerSrcRow + srcRowOffset; 15119228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul srcImgARowB += bytesPerSrcRow + srcRowOffset; 15129228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul srcImgBRowA += bytesPerSrcRow + srcRowOffset; 15139228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul srcImgBRowB += bytesPerSrcRow + srcRowOffset; 15149228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul dstImgRow += bytesPerDstRow; 15153893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul } 15163893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul } 15173893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul 15183893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul FREE(tmpRowA); 15193893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul FREE(tmpRowB); 15209228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul 15219228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul /* Luckily we can leverage the make_2d_mipmap() function here! */ 15229228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul if (border > 0) { 15239228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul /* do front border image */ 15249228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul make_2d_mipmap(format, 1, srcWidth, srcHeight, srcPtr, 15259228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul dstWidth, dstHeight, dstPtr); 15269228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul /* do back border image */ 15279228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul make_2d_mipmap(format, 1, srcWidth, srcHeight, 15289228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul srcPtr + bytesPerSrcImage * (srcDepth - 1), 15299228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul dstWidth, dstHeight, 15309228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul dstPtr + bytesPerDstImage * (dstDepth - 1)); 15319228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul /* do four remaining border edges that span the image slices */ 15329228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul if (srcDepth == dstDepth) { 15339228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul /* just copy border pixels from src to dst */ 15349228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul for (img = 0; img < dstDepthNB; img++) { 15359228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLubyte *src; 15369228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul GLubyte *dst; 15379228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul 15389228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul /* do border along [img][row=0][col=0] */ 15399228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul src = srcPtr + (img + 1) * bytesPerSrcImage; 15409228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul dst = dstPtr + (img + 1) * bytesPerDstImage; 15419228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul MEMCPY(dst, src, bpt); 15429228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul 15439228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul /* do border along [img][row=dstHeight-1][col=0] */ 15449228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul src = srcPtr + (img * 2 + 1) * bytesPerSrcImage 15459228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul + (srcHeight - 1) * bytesPerSrcRow; 15469228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul dst = dstPtr + (img + 1) * bytesPerDstImage 15479228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul + (dstHeight - 1) * bytesPerDstRow; 15489228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul MEMCPY(dst, src, bpt); 15499228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul 15509228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul /* do border along [img][row=0][col=dstWidth-1] */ 15519228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul src = srcPtr + (img * 2 + 1) * bytesPerSrcImage 15529228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul + (srcWidth - 1) * bpt; 15539228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul dst = dstPtr + (img + 1) * bytesPerDstImage 15549228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul + (dstWidth - 1) * bpt; 15559228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul MEMCPY(dst, src, bpt); 15569228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul 15579228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul /* do border along [img][row=dstHeight-1][col=dstWidth-1] */ 15589228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul src = srcPtr + (img * 2 + 1) * bytesPerSrcImage 15599228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul + (bytesPerSrcImage - bpt); 15609228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul dst = dstPtr + (img + 1) * bytesPerDstImage 15619228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul + (bytesPerDstImage - bpt); 15629228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul MEMCPY(dst, src, bpt); 15639228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul } 15649228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul } 15659228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul else { 15669228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul /* average border pixels from adjacent src image pairs */ 15679228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul ASSERT(srcDepthNB == 2 * dstDepthNB); 15689228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul for (img = 0; img < dstDepthNB; img++) { 15699228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLubyte *src; 15709228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul GLubyte *dst; 15719228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul 15729228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul /* do border along [img][row=0][col=0] */ 15739228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul src = srcPtr + (img * 2 + 1) * bytesPerSrcImage; 15749228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul dst = dstPtr + (img + 1) * bytesPerDstImage; 15759228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul do_row(format, 1, src, src + srcImageOffset, 1, dst); 15769228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul 15779228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul /* do border along [img][row=dstHeight-1][col=0] */ 15789228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul src = srcPtr + (img * 2 + 1) * bytesPerSrcImage 15799228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul + (srcHeight - 1) * bytesPerSrcRow; 15809228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul dst = dstPtr + (img + 1) * bytesPerDstImage 15819228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul + (dstHeight - 1) * bytesPerDstRow; 15829228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul do_row(format, 1, src, src + srcImageOffset, 1, dst); 15839228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul 15849228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul /* do border along [img][row=0][col=dstWidth-1] */ 15859228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul src = srcPtr + (img * 2 + 1) * bytesPerSrcImage 15869228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul + (srcWidth - 1) * bpt; 15879228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul dst = dstPtr + (img + 1) * bytesPerDstImage 15889228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul + (dstWidth - 1) * bpt; 15899228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul do_row(format, 1, src, src + srcImageOffset, 1, dst); 15909228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul 15919228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul /* do border along [img][row=dstHeight-1][col=dstWidth-1] */ 15929228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul src = srcPtr + (img * 2 + 1) * bytesPerSrcImage 15939228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul + (bytesPerSrcImage - bpt); 15949228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul dst = dstPtr + (img + 1) * bytesPerDstImage 15959228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul + (bytesPerDstImage - bpt); 15969228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul do_row(format, 1, src, src + srcImageOffset, 1, dst); 15979228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul } 15989228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul } 15999228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul } 16003893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul} 16013893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul 16023893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul 16033893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul/* 16043893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul * For GL_SGIX_generate_mipmap: 16053893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul * Generate a complete set of mipmaps from texObj's base-level image. 16063893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul * Stop at texObj's MaxLevel or when we get to the 1x1 texture. 16073893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul */ 16083893e638e6521b9c070e01c0b31d22754ff97a88Brian Paulvoid 1609d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul_mesa_generate_mipmap(GLcontext *ctx, GLenum target, 16103893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul const struct gl_texture_unit *texUnit, 16113893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul struct gl_texture_object *texObj) 16123893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul{ 16137c4268176eaaeb45003db4d5042a518b84c9f6dcKarl Schultz GLint level; 1614cd1cefae9146fc14b35ee93a04bdb1b1590fba7bBrian Paul GLint maxLevels = 0; 16153893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul 16163893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul ASSERT(texObj); 16173893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul ASSERT(texObj->Image[texObj->BaseLevel]); 16183893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul 16198afe7de8deaf3c9613fd68b344de8c52b02b1879Brian Paul switch (texObj->Target) { 16208afe7de8deaf3c9613fd68b344de8c52b02b1879Brian Paul case GL_TEXTURE_1D: 1621cd1cefae9146fc14b35ee93a04bdb1b1590fba7bBrian Paul maxLevels = ctx->Const.MaxTextureLevels; 16223893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul break; 16238afe7de8deaf3c9613fd68b344de8c52b02b1879Brian Paul case GL_TEXTURE_2D: 1624cd1cefae9146fc14b35ee93a04bdb1b1590fba7bBrian Paul maxLevels = ctx->Const.MaxTextureLevels; 16253893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul break; 16268afe7de8deaf3c9613fd68b344de8c52b02b1879Brian Paul case GL_TEXTURE_3D: 1627cd1cefae9146fc14b35ee93a04bdb1b1590fba7bBrian Paul maxLevels = ctx->Const.Max3DTextureLevels; 16283893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul break; 16298afe7de8deaf3c9613fd68b344de8c52b02b1879Brian Paul case GL_TEXTURE_CUBE_MAP_ARB: 1630cd1cefae9146fc14b35ee93a04bdb1b1590fba7bBrian Paul maxLevels = ctx->Const.MaxCubeTextureLevels; 16313893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul break; 16328afe7de8deaf3c9613fd68b344de8c52b02b1879Brian Paul case GL_TEXTURE_RECTANGLE_NV: 16338afe7de8deaf3c9613fd68b344de8c52b02b1879Brian Paul maxLevels = 1; 16348afe7de8deaf3c9613fd68b344de8c52b02b1879Brian Paul break; 16353893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul default: 16363893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul _mesa_problem(ctx, 16373893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul "Bad texture object dimension in _mesa_generate_mipmaps"); 16383893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul return; 16393893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul } 16403893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul 16418bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul for (level = texObj->BaseLevel; level < texObj->MaxLevel 1642cd1cefae9146fc14b35ee93a04bdb1b1590fba7bBrian Paul && level < maxLevels - 1; level++) { 16439228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul /* generate image[level+1] from image[level] */ 16443893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul const struct gl_texture_image *srcImage; 16453893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul struct gl_texture_image *dstImage; 16463893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul GLint srcWidth, srcHeight, srcDepth; 16473893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul GLint dstWidth, dstHeight, dstDepth; 16483893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul GLint border, bytesPerTexel; 16493893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul GLint t; 16503893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul 16513893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul srcImage = texObj->Image[level]; 16523893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul ASSERT(srcImage); 16533893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul srcWidth = srcImage->Width; 16543893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul srcHeight = srcImage->Height; 16553893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul srcDepth = srcImage->Depth; 16563893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul border = srcImage->Border; 16573893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul bytesPerTexel = srcImage->TexFormat->TexelBytes; 16583893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul 16593893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul /* compute next (level+1) image size */ 16603893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul if (srcWidth - 2 * border > 1) { 16613893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul dstWidth = (srcWidth - 2 * border) / 2 + 2 * border; 16623893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul } 16633893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul else { 16643893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul dstWidth = srcWidth; /* can't go smaller */ 16653893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul } 16663893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul if (srcHeight - 2 * border > 1) { 16673893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul dstHeight = (srcHeight - 2 * border) / 2 + 2 * border; 16683893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul } 16693893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul else { 16703893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul dstHeight = srcHeight; /* can't go smaller */ 16713893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul } 16723893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul if (srcDepth - 2 * border > 1) { 16733893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul dstDepth = (srcDepth - 2 * border) / 2 + 2 * border; 16743893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul } 16753893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul else { 16763893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul dstDepth = srcDepth; /* can't go smaller */ 16773893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul } 16783893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul 16793893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul if (dstWidth == srcWidth && 16803893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul dstHeight == srcHeight && 16813893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul dstDepth == srcDepth) { 16823893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul /* all done */ 16833893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul return; 16843893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul } 16853893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul 1686d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul /* get dest gl_texture_image */ 1687d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul dstImage = _mesa_select_tex_image(ctx, texUnit, target, level+1); 1688d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul if (!dstImage) { 1689d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul dstImage = _mesa_alloc_texture_image(); 16903893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul if (!dstImage) { 16913893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul _mesa_error(ctx, GL_OUT_OF_MEMORY, "generating mipmaps"); 16923893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul return; 16933893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul } 1694d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul _mesa_set_tex_image(texObj, target, level + 1, dstImage); 1695d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul } 16963893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul 1697d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul /* Free old image data */ 1698d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul if (dstImage->Data) 1699d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul MESA_PBUFFER_FREE(dstImage->Data); 1700d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul 1701d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul /* initialize new image */ 1702d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul _mesa_init_teximage_fields(ctx, t, dstImage, dstWidth, dstHeight, 1703d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul dstDepth, border, srcImage->Format); 1704d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul dstImage->DriverData = NULL; 1705d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul dstImage->TexFormat = srcImage->TexFormat; 1706d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul dstImage->FetchTexel = srcImage->FetchTexel; 1707d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul ASSERT(dstImage->TexFormat); 1708d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul ASSERT(dstImage->FetchTexel); 1709d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul 1710d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul ASSERT(dstWidth * dstHeight * dstDepth * bytesPerTexel > 0); 1711d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul 1712d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul /* alloc new image buffer */ 1713d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul dstImage->Data = MESA_PBUFFER_ALLOC(dstWidth * dstHeight * dstDepth 1714d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul * bytesPerTexel); 1715d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul if (!dstImage->Data) { 1716d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul _mesa_error(ctx, GL_OUT_OF_MEMORY, "generating mipmaps"); 1717d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul return; 1718d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul } 1719d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul 1720d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul /* 1721d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul * We use simple 2x2 averaging to compute the next mipmap level. 1722d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul */ 1723d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul switch (target) { 1724d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul case GL_TEXTURE_1D: 1725d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul make_1d_mipmap(srcImage->TexFormat, border, 1726d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul srcWidth, (const GLubyte *) srcImage->Data, 1727d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul dstWidth, (GLubyte *) dstImage->Data); 1728d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul break; 1729d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul case GL_TEXTURE_2D: 1730d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB: 1731d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB: 1732d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB: 1733d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB: 1734d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB: 1735d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB: 1736d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul make_2d_mipmap(srcImage->TexFormat, border, 1737d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul srcWidth, srcHeight, (const GLubyte *) srcImage->Data, 1738d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul dstWidth, dstHeight, (GLubyte *) dstImage->Data); 1739d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul break; 1740d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul case GL_TEXTURE_3D: 1741d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul make_3d_mipmap(srcImage->TexFormat, border, 1742d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul srcWidth, srcHeight, srcDepth, 1743d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul (const GLubyte *) srcImage->Data, 1744d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul dstWidth, dstHeight, dstDepth, 1745d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul (GLubyte *) dstImage->Data); 1746d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul break; 1747d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul case GL_TEXTURE_RECTANGLE_NV: 1748d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul /* no mipmaps, do nothing */ 1749d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul break; 1750d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul default: 1751d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul _mesa_problem(ctx, "bad dimensions in _mesa_generate_mipmaps"); 1752d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul return; 1753d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul } 1754d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul } /* loop over mipmap levels */ 17553893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul} 1756