texstore.c revision 2b012578ee519561365640e23272b71898378c45
18e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul/* 28e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * Mesa 3-D graphics library 34f295cee73bae1f687efe2dc062522b40d90b1e4Brian Paul * Version: 6.1 48e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * 54f295cee73bae1f687efe2dc062522b40d90b1e4Brian Paul * Copyright (C) 1999-2004 Brian Paul All Rights Reserved. 68e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * 78e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * Permission is hereby granted, free of charge, to any person obtaining a 88e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * copy of this software and associated documentation files (the "Software"), 98e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * to deal in the Software without restriction, including without limitation 108e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * the rights to use, copy, modify, merge, publish, distribute, sublicense, 118e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * and/or sell copies of the Software, and to permit persons to whom the 128e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * Software is furnished to do so, subject to the following conditions: 138e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * 148e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * The above copyright notice and this permission notice shall be included 158e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * in all copies or substantial portions of the Software. 168e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * 178e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 188e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 198e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 208e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 218e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 228e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 238e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul */ 248e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul 258e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul/* 268e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * Authors: 278e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * Brian Paul 288e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul */ 298e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul 3089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul/* 3189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * The GL texture image functions in teximage.c basically just do 3289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * error checking and data structure allocation. They in turn call 3389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * device driver functions which actually copy/convert/store the user's 3489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * texture image data. 3589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * 3689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * However, most device drivers will be able to use the fallback functions 3789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * in this file. That is, most drivers will have the following bit of 3889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * code: 3989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * ctx->Driver.TexImage1D = _mesa_store_teximage1d; 4089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * ctx->Driver.TexImage2D = _mesa_store_teximage2d; 4189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * ctx->Driver.TexImage3D = _mesa_store_teximage3d; 4289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * etc... 4389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * 4489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * Texture image processing is actually kind of complicated. We have to do: 4589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * Format/type conversions 4689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * pixel unpacking 4789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * pixel transfer (scale, bais, lookup, convolution!, etc) 4889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * 4989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * These functions can handle most everything, including processing full 5089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * images and sub-images. 5189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul */ 5289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul 5389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul 543c63452e64df7e10aa073c6c3b9492b1d7dabbb8Brian Paul#include "glheader.h" 557a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul#include "bufferobj.h" 56e75d2424e53d6023f4414e40694cd467e5392b96Brian Paul#include "colormac.h" 578e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul#include "context.h" 588e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul#include "convolve.h" 598e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul#include "image.h" 608e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul#include "macros.h" 613c63452e64df7e10aa073c6c3b9492b1d7dabbb8Brian Paul#include "imports.h" 6289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul#include "texcompress.h" 63371ef9c058b0d59bfb62689b64af1b29a2214d9eGareth Hughes#include "texformat.h" 648e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul#include "teximage.h" 658e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul#include "texstore.h" 668e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul 678e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul 68f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paulstatic const GLint ZERO = 1000, ONE = 1001; 69f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul 70f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul/** 71f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * When promoting texture formats (see below) we need to compute the 72f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * mapping of dest components back to source components. 73f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * This function does that. 74f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param logicalBaseFormat the logical format of the texture 75f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param textureBaseFormat the final texture format 76f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \return map[4] the four mapping values 77f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul */ 78f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paulstatic void 79f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paulcompute_component_mapping(GLenum logicalBaseFormat, GLenum textureBaseFormat, 80f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul GLint map[4]) 81f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul{ 82f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul /* compute mapping from dest components back to src components */ 83f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul switch (logicalBaseFormat) { 84f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul case GL_LUMINANCE: 85f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul map[0] = map[1] = map[2] = 0; 86f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul if (textureBaseFormat == GL_RGBA) 87f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul map[3] = ONE; 88f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul break; 89f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul case GL_ALPHA: 90f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul ASSERT(textureBaseFormat == GL_RGBA); 91f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul map[0] = map[1] = map[2] = ZERO; 92f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul map[3] = 0; 93f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul break; 94f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul case GL_INTENSITY: 95f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul map[0] = map[1] = map[2] = 0; 96f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul if (textureBaseFormat == GL_RGBA) 97f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul map[3] = 0; 98f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul break; 99f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul case GL_LUMINANCE_ALPHA: 100f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul ASSERT(textureBaseFormat == GL_RGBA); 101f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul map[0] = map[1] = map[2] = 0; 102f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul map[3] = 1; 103f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul break; 104f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul case GL_RGB: 105f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul ASSERT(textureBaseFormat == GL_RGBA); 106f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul map[0] = 0; 107f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul map[1] = 1; 108f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul map[2] = 2; 109f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul map[3] = ONE; 110f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul break; 111f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul default: 112f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul _mesa_problem(NULL, "Unexpected logicalBaseFormat"); 113f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul map[0] = map[1] = map[2] = map[3] = 0; 114f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul } 115f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul} 116f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul 117f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul 118f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul/** 119f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * Make a temporary (color) texture image with GLfloat components. 120f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * Apply all needed pixel unpacking and pixel transfer operations. 121f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * Note that there are both logicalBaseFormat and textureBaseFormat parameters. 122f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * Suppose the user specifies GL_LUMINANCE as the internal texture format 123f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * but the graphics hardware doesn't support luminance textures. So, might 124f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * use an RGB hardware format instead. 125f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * If logicalBaseFormat != textureBaseFormat we have some extra work to do. 126f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * 127f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param ctx the rendering context 128f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param dims image dimensions: 1, 2 or 3 129f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param logicalBaseFormat basic texture derived from the user's 130f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * internal texture format value 131f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param textureBaseFormat the actual basic format of the texture 132f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param srcWidth source image width 133f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param srcHeight source image height 134f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param srcDepth source image depth 135f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param srcFormat source image format 136f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param srcType source image type 137f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param srcAddr source image address 138f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param srcPacking source image pixel packing 139f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \return resulting image with format = textureBaseFormat and type = GLfloat. 140f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul */ 141f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paulstatic GLfloat * 142f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paulmake_temp_float_image(GLcontext *ctx, GLuint dims, 143f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul GLenum logicalBaseFormat, 144f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul GLenum textureBaseFormat, 145f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul GLint srcWidth, GLint srcHeight, GLint srcDepth, 146f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul GLenum srcFormat, GLenum srcType, 147f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul const GLvoid *srcAddr, 148f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul const struct gl_pixelstore_attrib *srcPacking) 149f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul{ 150f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul GLuint transferOps = ctx->_ImageTransferState; 151f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul GLfloat *tempImage; 152f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul 153f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul ASSERT(dims >= 1 && dims <= 3); 154f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul 155f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul ASSERT(logicalBaseFormat == GL_RGBA || 156f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul logicalBaseFormat == GL_RGB || 157f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul logicalBaseFormat == GL_LUMINANCE_ALPHA || 158f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul logicalBaseFormat == GL_LUMINANCE || 159f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul logicalBaseFormat == GL_ALPHA || 160f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul logicalBaseFormat == GL_INTENSITY || 161f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul logicalBaseFormat == GL_COLOR_INDEX || 162f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul logicalBaseFormat == GL_DEPTH_COMPONENT); 163f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul 164f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul ASSERT(textureBaseFormat == GL_RGBA || 165f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul textureBaseFormat == GL_RGB || 166f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul textureBaseFormat == GL_LUMINANCE_ALPHA || 167f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul textureBaseFormat == GL_LUMINANCE || 168f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul textureBaseFormat == GL_ALPHA || 169f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul textureBaseFormat == GL_INTENSITY || 170f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul textureBaseFormat == GL_COLOR_INDEX || 171f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul textureBaseFormat == GL_DEPTH_COMPONENT); 172f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul 173f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul /* conventional color image */ 174f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul 175f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul if ((dims == 1 && ctx->Pixel.Convolution1DEnabled) || 176f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul (dims >= 2 && ctx->Pixel.Convolution2DEnabled) || 177f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul (dims >= 2 && ctx->Pixel.Separable2DEnabled)) { 178f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul /* need image convolution */ 179f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul const GLuint preConvTransferOps 180f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul = (transferOps & IMAGE_PRE_CONVOLUTION_BITS) | IMAGE_CLAMP_BIT; 181f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul const GLuint postConvTransferOps 182f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul = (transferOps & IMAGE_POST_CONVOLUTION_BITS) | IMAGE_CLAMP_BIT; 183f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul GLint img, row; 184f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul GLint convWidth, convHeight; 185f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul GLfloat *convImage; 186f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul 187f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul /* pre-convolution image buffer (3D) */ 188f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul tempImage = (GLfloat *) _mesa_malloc(srcWidth * srcHeight * srcDepth 189f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * 4 * sizeof(GLfloat)); 190f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul if (!tempImage) 191f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul return NULL; 192f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul 193f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul /* post-convolution image buffer (2D) */ 194f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul convImage = (GLfloat *) _mesa_malloc(srcWidth * srcHeight 195f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * 4 * sizeof(GLfloat)); 196f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul if (!convImage) { 197f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul _mesa_free(tempImage); 198f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul return NULL; 199f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul } 200f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul 201f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul /* loop over 3D image slices */ 202f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul for (img = 0; img < srcDepth; img++) { 203f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul GLfloat *dst = tempImage + img * (srcWidth * srcHeight * 4); 204f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul 205f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul /* unpack and do transfer ops up to convolution */ 206f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul for (row = 0; row < srcHeight; row++) { 207f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul const GLvoid *src = _mesa_image_address(srcPacking, 208f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul srcAddr, srcWidth, srcHeight, 209f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul srcFormat, srcType, img, row, 0); 210f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul _mesa_unpack_color_span_float(ctx, srcWidth, GL_RGBA, dst, 211f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul srcFormat, srcType, src, 212f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul srcPacking, 213f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul preConvTransferOps); 214f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul dst += srcWidth * 4; 215f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul } 216f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul 217f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul /* do convolution */ 218f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul { 219f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul GLfloat *src = tempImage + img * (srcWidth * srcHeight * 4); 220f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul convWidth = srcWidth; 221f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul convHeight = srcHeight; 222f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul if (dims == 1) { 223f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul ASSERT(ctx->Pixel.Convolution1DEnabled); 224f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul _mesa_convolve_1d_image(ctx, &convWidth, src, convImage); 225f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul } 226f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul else { 227f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul if (ctx->Pixel.Convolution2DEnabled) { 228f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul _mesa_convolve_2d_image(ctx, &convWidth, &convHeight, 229f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul src, convImage); 230f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul } 231f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul else { 232f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul ASSERT(ctx->Pixel.Separable2DEnabled); 233f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul _mesa_convolve_sep_image(ctx, &convWidth, &convHeight, 234f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul src, convImage); 235f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul } 236f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul } 237f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul } 238f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul 239f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul /* do post-convolution transfer and pack into tempImage */ 240f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul { 2412b012578ee519561365640e23272b71898378c45Brian Paul const GLint logComponents 2422b012578ee519561365640e23272b71898378c45Brian Paul = _mesa_components_in_format(logicalBaseFormat); 243f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul const GLfloat *src = convImage; 244f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul GLfloat *dst = tempImage + img * (convWidth * convHeight * 4); 245f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul for (row = 0; row < convHeight; row++) { 246f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul _mesa_pack_rgba_span_float(ctx, convWidth, 247f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul (const GLfloat (*)[4]) src, 248f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul logicalBaseFormat, GL_FLOAT, 249f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul dst, &ctx->DefaultPacking, 250f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul postConvTransferOps); 251f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul src += convWidth * 4; 2522b012578ee519561365640e23272b71898378c45Brian Paul dst += convWidth * logComponents; 253f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul } 254f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul } 255f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul } /* loop over 3D image slices */ 256f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul 257f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul _mesa_free(convImage); 258f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul 259f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul /* might need these below */ 260f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul srcWidth = convWidth; 261f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul srcHeight = convHeight; 262f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul } 263f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul else { 264f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul /* no convolution */ 265f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul const GLint components = _mesa_components_in_format(logicalBaseFormat); 266f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul const GLint srcStride = _mesa_image_row_stride(srcPacking, 267f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul srcWidth, srcFormat, srcType); 268f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul GLfloat *dst; 269f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul GLint img, row; 270f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul 271f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul tempImage = (GLfloat *) _mesa_malloc(srcWidth * srcHeight * srcDepth 272f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * components * sizeof(GLfloat)); 273f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul if (!tempImage) 274f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul return NULL; 275f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul 276f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul dst = tempImage; 277f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul for (img = 0; img < srcDepth; img++) { 278f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul const GLubyte *src 279f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul = (const GLubyte *) _mesa_image_address(srcPacking, srcAddr, 280f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul srcWidth, srcHeight, 281f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul srcFormat, srcType, 282f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul img, 0, 0); 283f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul for (row = 0; row < srcHeight; row++) { 284f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul _mesa_unpack_color_span_float(ctx, srcWidth, logicalBaseFormat, 285f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul dst, srcFormat, srcType, src, 286f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul srcPacking, transferOps); 287f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul dst += srcWidth * components; 288f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul src += srcStride; 289f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul } 290f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul } 291f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul } 292f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul 293f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul if (logicalBaseFormat != textureBaseFormat) { 294f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul /* more work */ 295f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul GLint texComponents = _mesa_components_in_format(textureBaseFormat); 296f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul GLint logComponents = _mesa_components_in_format(logicalBaseFormat); 297f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul GLfloat *newImage; 298f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul GLint i, n; 299f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul GLint map[4]; 300f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul 301f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul /* we only promote up to RGB and RGBA formats for now */ 302f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul ASSERT(textureBaseFormat == GL_RGB || textureBaseFormat == GL_RGBA); 303f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul 304f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul /* The actual texture format should have at least as many components 305f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * as the logical texture format. 306f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul */ 307f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul ASSERT(texComponents >= logComponents); 308f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul 309f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul newImage = (GLfloat *) _mesa_malloc(srcWidth * srcHeight * srcDepth 310f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * texComponents * sizeof(GLfloat)); 311f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul if (!newImage) { 312f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul _mesa_free(tempImage); 313f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul return NULL; 314f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul } 315f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul 316f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul compute_component_mapping(logicalBaseFormat, textureBaseFormat, map); 317f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul 318f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul n = srcWidth * srcHeight * srcDepth; 319f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul for (i = 0; i < n; i++) { 320f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul GLint k; 321f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul for (k = 0; k < texComponents; k++) { 322f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul GLint j = map[k]; 323f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul if (j == ZERO) 324f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul newImage[i * texComponents + k] = 0.0F; 325f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul else if (j == ONE) 326f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul newImage[i * texComponents + k] = 1.0F; 327f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul else 328f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul newImage[i * texComponents + k] = tempImage[i * logComponents + j]; 329f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul } 330f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul } 331f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul 332f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul _mesa_free(tempImage); 333f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul tempImage = newImage; 334f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul } 335f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul 336f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul return tempImage; 337f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul} 338f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul 339f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul 340f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul/** 341f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * Make a temporary (color) texture image with GLchan components. 342f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * Apply all needed pixel unpacking and pixel transfer operations. 343f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * Note that there are both logicalBaseFormat and textureBaseFormat parameters. 344f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * Suppose the user specifies GL_LUMINANCE as the internal texture format 345f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * but the graphics hardware doesn't support luminance textures. So, might 346f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * use an RGB hardware format instead. 347f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * If logicalBaseFormat != textureBaseFormat we have some extra work to do. 348f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * 349f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param ctx the rendering context 350f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param dims image dimensions: 1, 2 or 3 351f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param logicalBaseFormat basic texture derived from the user's 352f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * internal texture format value 353f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param textureBaseFormat the actual basic format of the texture 354f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param srcWidth source image width 355f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param srcHeight source image height 356f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param srcDepth source image depth 357f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param srcFormat source image format 358f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param srcType source image type 359f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param srcAddr source image address 360f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param srcPacking source image pixel packing 361f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \return resulting image with format = textureBaseFormat and type = GLchan. 362f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul */ 3638f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian PaulGLchan * 3648f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul_mesa_make_temp_chan_image(GLcontext *ctx, GLuint dims, 3658f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul GLenum logicalBaseFormat, 3668f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul GLenum textureBaseFormat, 3678f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul GLint srcWidth, GLint srcHeight, GLint srcDepth, 3688f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul GLenum srcFormat, GLenum srcType, 3698f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul const GLvoid *srcAddr, 3708f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul const struct gl_pixelstore_attrib *srcPacking) 371f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul{ 372f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul GLuint transferOps = ctx->_ImageTransferState; 373f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul const GLint components = _mesa_components_in_format(logicalBaseFormat); 374f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul GLboolean freeSrcImage = GL_FALSE; 375f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul GLint img, row; 376f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul GLchan *tempImage, *dst; 377f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul 378f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul ASSERT(dims >= 1 && dims <= 3); 379f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul 380f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul ASSERT(logicalBaseFormat == GL_RGBA || 381f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul logicalBaseFormat == GL_RGB || 382f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul logicalBaseFormat == GL_LUMINANCE_ALPHA || 383f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul logicalBaseFormat == GL_LUMINANCE || 384f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul logicalBaseFormat == GL_ALPHA || 385f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul logicalBaseFormat == GL_INTENSITY); 386f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul 387f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul ASSERT(textureBaseFormat == GL_RGBA || 388f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul textureBaseFormat == GL_RGB || 389f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul textureBaseFormat == GL_LUMINANCE_ALPHA || 390f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul textureBaseFormat == GL_LUMINANCE || 391f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul textureBaseFormat == GL_ALPHA || 392f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul textureBaseFormat == GL_INTENSITY); 393f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul 394f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul if ((dims == 1 && ctx->Pixel.Convolution1DEnabled) || 395f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul (dims >= 2 && ctx->Pixel.Convolution2DEnabled) || 396f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul (dims >= 2 && ctx->Pixel.Separable2DEnabled)) { 397f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul /* get convolved image */ 398f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul GLfloat *convImage = make_temp_float_image(ctx, dims, 399f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul logicalBaseFormat, 400f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul logicalBaseFormat, 401f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul srcWidth, srcHeight, srcDepth, 402f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul srcFormat, srcType, 403f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul srcAddr, srcPacking); 404f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul if (!convImage) 405f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul return NULL; 406f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul /* the convolved image is our new source image */ 407f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul srcAddr = convImage; 408f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul srcFormat = logicalBaseFormat; 409f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul srcType = GL_FLOAT; 410f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul srcPacking = &ctx->DefaultPacking; 411f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight); 412f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul transferOps = 0; 413f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul freeSrcImage = GL_TRUE; 414f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul } 415f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul 416f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul /* unpack and transfer the source image */ 417f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul tempImage = (GLchan *) _mesa_malloc(srcWidth * srcHeight * srcDepth 418f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * components * sizeof(GLchan)); 419f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul if (!tempImage) 420f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul return NULL; 421f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul 422f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul dst = tempImage; 423f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul for (img = 0; img < srcDepth; img++) { 424f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul const GLint srcStride = _mesa_image_row_stride(srcPacking, 425f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul srcWidth, srcFormat, 426f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul srcType); 427f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul const GLubyte *src 428f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul = (const GLubyte *) _mesa_image_address(srcPacking, srcAddr, 429f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul srcWidth, srcHeight, 430f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul srcFormat, srcType, 431f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul img, 0, 0); 432f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul for (row = 0; row < srcHeight; row++) { 433f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul _mesa_unpack_color_span_chan(ctx, srcWidth, logicalBaseFormat, 434f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul dst, srcFormat, srcType, src, 435f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul srcPacking, transferOps); 436f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul dst += srcWidth * components; 437f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul src += srcStride; 438f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul } 439f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul } 440f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul 441f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul /* If we made a temporary image for convolution, free it here */ 442f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul if (freeSrcImage) { 443f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul _mesa_free((void *) srcAddr); 444f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul } 445f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul 446f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul if (logicalBaseFormat != textureBaseFormat) { 447f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul /* one more conversion step */ 448f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul GLint texComponents = _mesa_components_in_format(textureBaseFormat); 449f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul GLint logComponents = _mesa_components_in_format(logicalBaseFormat); 450f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul GLchan *newImage; 451f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul GLint i, n; 452f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul GLint map[4]; 453f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul 454f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul /* we only promote up to RGB and RGBA formats for now */ 455f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul ASSERT(textureBaseFormat == GL_RGB || textureBaseFormat == GL_RGBA); 456f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul 457f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul /* The actual texture format should have at least as many components 458f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * as the logical texture format. 459f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul */ 460f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul ASSERT(texComponents >= logComponents); 461f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul 462f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul newImage = (GLchan *) _mesa_malloc(srcWidth * srcHeight * srcDepth 463f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * texComponents * sizeof(GLchan)); 464f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul if (!newImage) { 465f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul _mesa_free(tempImage); 466f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul return NULL; 467f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul } 468f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul 469f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul compute_component_mapping(logicalBaseFormat, textureBaseFormat, map); 470f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul 471f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul n = srcWidth * srcHeight * srcDepth; 472f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul for (i = 0; i < n; i++) { 473f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul GLint k; 474f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul for (k = 0; k < texComponents; k++) { 475f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul GLint j = map[k]; 476f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul if (j == ZERO) 477f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul newImage[i * texComponents + k] = 0; 478f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul else if (j == ONE) 479f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul newImage[i * texComponents + k] = CHAN_MAX; 480f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul else 481f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul newImage[i * texComponents + k] = tempImage[i * logComponents + j]; 482f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul } 483f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul } 484f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul 485f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul _mesa_free(tempImage); 486f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul tempImage = newImage; 487f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul } 488f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul 489f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul return tempImage; 490f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul} 491f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul 492f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul 493f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul 494f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul/** 495f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * Teximage storage routine for when a simple memcpy will do. 496f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * No pixel transfer operations or special texel encodings allowed. 497f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * 1D, 2D and 3D images supported. 498f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul */ 499f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paulstatic void 500f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paulmemcpy_texture(const struct gl_texture_format *dstFormat, 501f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul GLvoid *dstAddr, 502f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul GLint dstXoffset, GLint dstYoffset, GLint dstZoffset, 503f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul GLint dstRowStride, GLint dstImageStride, 504f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul GLint srcWidth, GLint srcHeight, GLint srcDepth, 505f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul GLenum srcFormat, GLenum srcType, 506f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul const GLvoid *srcAddr, 507f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul const struct gl_pixelstore_attrib *srcPacking) 508f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul{ 509f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul const GLint srcRowStride = _mesa_image_row_stride(srcPacking, srcWidth, 510f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul srcFormat, srcType); 511f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul const GLint srcImageStride = _mesa_image_image_stride(srcPacking, 512f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul srcWidth, srcHeight, srcFormat, srcType); 513f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul const GLubyte *srcImage = (const GLubyte *) _mesa_image_address(srcPacking, 514f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul srcAddr, srcWidth, srcHeight, srcFormat, srcType, 0, 0, 0); 515f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul const GLint bytesPerRow = srcWidth * dstFormat->TexelBytes; 516f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul const GLint bytesPerImage = srcHeight * bytesPerRow; 517f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul const GLint bytesPerTexture = srcDepth * bytesPerImage; 518f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul GLubyte *dstImage = (GLubyte *) dstAddr 519f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul + dstZoffset * dstImageStride 520f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul + dstYoffset * dstRowStride 521f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul + dstXoffset * dstFormat->TexelBytes; 522f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul 523f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul if (dstRowStride == srcRowStride && 524f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul dstRowStride == bytesPerRow && 525f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul ((dstImageStride == srcImageStride && 526f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul dstImageStride == bytesPerImage) || 527f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul (srcDepth == 1))) { 528f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul /* one big memcpy */ 529f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul _mesa_memcpy(dstImage, srcImage, bytesPerTexture); 530f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul } 531f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul else { 532f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul GLint img, row; 533f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul for (img = 0; img < srcDepth; img++) { 534f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul const GLubyte *srcRow = srcImage; 535f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul GLubyte *dstRow = dstImage; 536f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul for (row = 0; row < srcHeight; row++) { 537f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul _mesa_memcpy(dstRow, srcRow, bytesPerRow); 538f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul dstRow += dstRowStride; 539f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul srcRow += srcRowStride; 540f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul } 541f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul srcImage += srcImageStride; 542f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul dstImage += dstImageStride; 543f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul } 544f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul } 545f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul} 546f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul 547f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul 548f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul 549f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul/** 550f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * Store an image in any of the formats: 551f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * _mesa_texformat_rgba 552f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * _mesa_texformat_rgb 553f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * _mesa_texformat_alpha 554f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * _mesa_texformat_luminance 555f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * _mesa_texformat_luminance_alpha 556f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * _mesa_texformat_intensity 557f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * 558f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param dims either 1 or 2 or 3 559f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param baseInternalFormat user-specified base internal format 560f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param dstFormat destination Mesa texture format 561f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param dstAddr destination image address 562f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param dstX/Y/Zoffset destination x/y/z offset (ala TexSubImage), in texels 563f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param dstRowStride destination image row stride, in bytes 564f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param dstImageStride destination image layer stride, in bytes 565f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param srcWidth/Height/Depth source image size, in pixels 566f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param srcFormat incoming image format 567f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param srcType incoming image data type 568f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param srcAddr source image address 569f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param srcPacking source image packing parameters 570f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul */ 571f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian PaulGLboolean 572f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul_mesa_texstore_rgba(GLcontext *ctx, GLuint dims, 573f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul GLenum baseInternalFormat, 574f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul const struct gl_texture_format *dstFormat, 575f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul GLvoid *dstAddr, 576f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul GLint dstXoffset, GLint dstYoffset, GLint dstZoffset, 577f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul GLint dstRowStride, GLint dstImageStride, 578f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul GLint srcWidth, GLint srcHeight, GLint srcDepth, 579f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul GLenum srcFormat, GLenum srcType, 580f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul const GLvoid *srcAddr, 581f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul const struct gl_pixelstore_attrib *srcPacking) 582f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul{ 583f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul const GLint components = _mesa_components_in_format(baseInternalFormat); 584f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul 585f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul ASSERT(dstFormat == &_mesa_texformat_rgba || 586f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul dstFormat == &_mesa_texformat_rgb || 587f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul dstFormat == &_mesa_texformat_alpha || 588f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul dstFormat == &_mesa_texformat_luminance || 589f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul dstFormat == &_mesa_texformat_luminance_alpha || 590f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul dstFormat == &_mesa_texformat_intensity); 591f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul ASSERT(baseInternalFormat == GL_RGBA || 592f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul baseInternalFormat == GL_RGB || 593f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul baseInternalFormat == GL_ALPHA || 594f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul baseInternalFormat == GL_LUMINANCE || 595f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul baseInternalFormat == GL_LUMINANCE_ALPHA || 596f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul baseInternalFormat == GL_INTENSITY); 597f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul ASSERT(dstFormat->TexelBytes == components * sizeof(GLchan)); 598f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul 599f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul if (!ctx->_ImageTransferState && 600f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul !srcPacking->SwapBytes && 601f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul baseInternalFormat == srcFormat && 602f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul srcType == CHAN_TYPE) { 603f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul /* simple memcpy path */ 604f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul memcpy_texture(dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset, 605f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul dstRowStride, dstImageStride, 606f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul srcWidth, srcHeight, srcDepth, srcFormat, srcType, 607f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul srcAddr, srcPacking); 608f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul } 609f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul else if (!ctx->_ImageTransferState && 610f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul !srcPacking->SwapBytes && 611f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul dstFormat == &_mesa_texformat_rgb && 612f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul srcFormat == GL_RGBA && 613f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul srcType == CHAN_TYPE) { 614f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul /* extract RGB from RGBA */ 615f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul int img, row, col; 616f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul GLchan *dstImage = (GLchan *) (GLubyte *) dstAddr 617f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul + dstZoffset * dstImageStride 618f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul + dstYoffset * dstRowStride 619f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul + dstXoffset * dstFormat->TexelBytes; 620f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul for (img = 0; img < srcDepth; img++) { 621f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul const GLint srcRowStride = _mesa_image_row_stride(srcPacking, 622f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul srcWidth, srcFormat, srcType); 623bdd15b5749b45929fa642c3e47997f52eb07fbe5Brian Paul GLchan *srcRow = (GLchan *) _mesa_image_address(srcPacking, srcAddr, 624bdd15b5749b45929fa642c3e47997f52eb07fbe5Brian Paul srcWidth, srcHeight, srcFormat, srcType, img, 0, 0); 625f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul GLchan *dstRow = dstImage; 626f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul for (row = 0; row < srcHeight; row++) { 627f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul for (col = 0; col < srcWidth; col++) { 628f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul dstRow[col * 3 + RCOMP] = srcRow[col * 4 + RCOMP]; 629f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul dstRow[col * 3 + GCOMP] = srcRow[col * 4 + GCOMP]; 630f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul dstRow[col * 3 + BCOMP] = srcRow[col * 4 + BCOMP]; 631f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul } 632f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul dstRow += dstRowStride; 633f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul srcRow = (GLchan *) ((GLubyte *) srcRow + srcRowStride); 634f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul } 635f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul dstImage += dstImageStride; 636f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul } 637f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul } 638f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul else { 639f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul /* general path */ 6408f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims, 641f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul baseInternalFormat, 642f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul dstFormat->BaseFormat, 643f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul srcWidth, srcHeight, srcDepth, 644f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul srcFormat, srcType, srcAddr, 645f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul srcPacking); 646f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul const GLchan *src = tempImage; 647f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul const GLint bytesPerRow = srcWidth * components * sizeof(GLchan); 648f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul GLubyte *dstImage = (GLubyte *) dstAddr 649f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul + dstZoffset * dstImageStride 650f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul + dstYoffset * dstRowStride 651f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul + dstXoffset * dstFormat->TexelBytes; 652f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul GLint img, row; 653f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul if (!tempImage) 654f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul return GL_FALSE; 655f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight); 656f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul for (img = 0; img < srcDepth; img++) { 657f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul GLubyte *dstRow = dstImage; 658f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul for (row = 0; row < srcHeight; row++) { 659f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul _mesa_memcpy(dstRow, src, bytesPerRow); 660f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul dstRow += dstRowStride; 661f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul src += srcWidth * components; 662f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul } 663f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul dstImage += dstImageStride; 664f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul } 665f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul 666f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul _mesa_free((void *) tempImage); 667f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul } 668f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul return GL_TRUE; 669f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul} 670f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul 671f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul 672f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul/** 673f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * Store a color index texture image 674f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul */ 675f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian PaulGLboolean 676f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul_mesa_texstore_color_index(STORE_PARAMS) 677f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul{ 678f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul ASSERT(dstFormat == &_mesa_texformat_color_index); 679f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul ASSERT(dstFormat->TexelBytes == 1 * sizeof(GLchan)); 680f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul 681f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul if (!ctx->_ImageTransferState && 682f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul !srcPacking->SwapBytes && 683f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul baseInternalFormat == GL_COLOR_INDEX && 684f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul srcFormat == GL_COLOR_INDEX && 685f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul srcType == CHAN_TYPE) { 686f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul /* simple memcpy path */ 687f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul memcpy_texture(dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset, 688f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul dstRowStride, dstImageStride, 689f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul srcWidth, srcHeight, srcDepth, srcFormat, srcType, 690f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul srcAddr, srcPacking); 691f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul } 692f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul else { 693f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul /* general path */ 694f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul GLubyte *dstImage = (GLubyte *) dstAddr 695f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul + dstZoffset * dstImageStride 696f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul + dstYoffset * dstRowStride 697f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul + dstXoffset * dstFormat->TexelBytes; 698f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul GLint img, row; 699f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul for (img = 0; img < srcDepth; img++) { 700f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul GLubyte *dstRow = dstImage; 701f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul for (row = 0; row < srcHeight; row++) { 702f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul const GLvoid *src = _mesa_image_address(srcPacking, 703f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, row, 0); 704f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul _mesa_unpack_index_span(ctx, srcWidth, CHAN_TYPE, dstRow, 705f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul srcType, src, srcPacking, 706f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul ctx->_ImageTransferState); 707f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul dstRow += dstRowStride; 708f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul } 709f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul dstImage += dstImageStride; 710f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul } 711f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul } 712f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul return GL_TRUE; 713f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul} 714f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul 715f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul 716f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul/** 717f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * Store a floating point depth component texture image. 718f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul */ 719f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian PaulGLboolean 720f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul_mesa_texstore_depth_component_float32(STORE_PARAMS) 721f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul{ 722f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul ASSERT(dstFormat == &_mesa_texformat_depth_component_float32); 723f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul ASSERT(dstFormat->TexelBytes == sizeof(GLfloat)); 724f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul 725f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul if (!ctx->_ImageTransferState && 726f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul !srcPacking->SwapBytes && 727f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul baseInternalFormat == GL_DEPTH_COMPONENT && 728f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul srcFormat == GL_DEPTH_COMPONENT && 729f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul srcType == GL_FLOAT) { 730f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul /* simple memcpy path */ 731f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul memcpy_texture(dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset, 732f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul dstRowStride, dstImageStride, 733f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul srcWidth, srcHeight, srcDepth, srcFormat, srcType, 734f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul srcAddr, srcPacking); 735f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul } 736f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul else { 737f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul /* general path */ 738f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul GLubyte *dstImage = (GLubyte *) dstAddr 739f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul + dstZoffset * dstImageStride 740f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul + dstYoffset * dstRowStride 741f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul + dstXoffset * dstFormat->TexelBytes; 742f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul GLint img, row; 743f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul for (img = 0; img < srcDepth; img++) { 744f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul GLubyte *dstRow = dstImage; 745f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul for (row = 0; row < srcHeight; row++) { 746f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul const GLvoid *src = _mesa_image_address(srcPacking, 747f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, row, 0); 748f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul _mesa_unpack_depth_span(ctx, srcWidth, (GLfloat *) dstRow, 749f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul srcType, src, srcPacking); 750f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul dstRow += dstRowStride; 751f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul } 752f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul dstImage += dstImageStride; 753f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul } 754f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul } 755f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul return GL_TRUE; 756f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul} 757f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul 758f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul 759f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul/** 760f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * Store a 16-bit integer depth component texture image. 761f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul */ 762f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian PaulGLboolean 763f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul_mesa_texstore_depth_component16(STORE_PARAMS) 764f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul{ 765f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul ASSERT(dstFormat == &_mesa_texformat_depth_component16); 766f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul ASSERT(dstFormat->TexelBytes == sizeof(GLushort)); 767f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul 768f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul if (!ctx->_ImageTransferState && 769f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul !srcPacking->SwapBytes && 770f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul baseInternalFormat == GL_DEPTH_COMPONENT && 771f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul srcFormat == GL_DEPTH_COMPONENT && 772f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul srcType == GL_UNSIGNED_SHORT) { 773f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul /* simple memcpy path */ 774f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul memcpy_texture(dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset, 775f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul dstRowStride, dstImageStride, 776f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul srcWidth, srcHeight, srcDepth, srcFormat, srcType, 777f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul srcAddr, srcPacking); 778f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul } 779f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul else { 780f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul /* general path */ 781f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul GLubyte *dstImage = (GLubyte *) dstAddr 782f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul + dstZoffset * dstImageStride 783f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul + dstYoffset * dstRowStride 784f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul + dstXoffset * dstFormat->TexelBytes; 785f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul GLint img, row, col; 786f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul for (img = 0; img < srcDepth; img++) { 787f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul GLubyte *dstRow = dstImage; 788f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul for (row = 0; row < srcHeight; row++) { 789f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul GLfloat depthTemp[MAX_WIDTH]; 790f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul const GLvoid *src = _mesa_image_address(srcPacking, 791f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, row, 0); 792f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul GLushort *dst16 = (GLushort *) dstRow; 793f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul _mesa_unpack_depth_span(ctx, srcWidth, depthTemp, 794f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul srcType, src, srcPacking); 795f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul for (col = 0; col < srcWidth; col++) { 796f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul dst16[col] = (GLushort) (depthTemp[col] * 65535.0F); 797f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul } 798f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul dstRow += dstRowStride; 799f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul } 800f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul dstImage += dstImageStride; 801f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul } 802f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul } 803f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul return GL_TRUE; 804f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul} 805f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul 806f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul 807f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul 808f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul 809f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul/** 810f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * Store an rgb565 texture image. 811f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul */ 812f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian PaulGLboolean 813f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul_mesa_texstore_rgb565(STORE_PARAMS) 814f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul{ 815f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul ASSERT(dstFormat == &_mesa_texformat_rgb565); 816f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul ASSERT(dstFormat->TexelBytes == 2); 817f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul 818f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul if (!ctx->_ImageTransferState && 819f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul !srcPacking->SwapBytes && 820f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul baseInternalFormat == GL_RGB && 821f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul srcFormat == GL_RGB && 822f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul srcType == GL_UNSIGNED_SHORT_5_6_5) { 823f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul /* simple memcpy path */ 824f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul memcpy_texture(dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset, 825f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul dstRowStride, dstImageStride, 826f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul srcWidth, srcHeight, srcDepth, srcFormat, srcType, 827f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul srcAddr, srcPacking); 828f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul } 829f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul else if (!ctx->_ImageTransferState && 830f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul !srcPacking->SwapBytes && 831f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul baseInternalFormat == GL_RGB && 832f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul srcFormat == GL_RGB && 833f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul srcType == GL_UNSIGNED_BYTE && 834f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul dims == 2) { 835f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul /* do optimized tex store */ 836f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul const GLint srcRowStride = _mesa_image_row_stride(srcPacking, srcWidth, 837f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul srcFormat, srcType); 838f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul const GLubyte *src = (const GLubyte *) 839f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul _mesa_image_address(srcPacking, srcAddr, srcWidth, srcHeight, 840f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul srcFormat, srcType, 0, 0, 0); 841f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul GLubyte *dst = (GLubyte *) dstAddr 842f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul + dstZoffset * dstImageStride 843f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul + dstYoffset * dstRowStride 844f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul + dstXoffset * dstFormat->TexelBytes; 845f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul GLint row, col; 846f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul for (row = 0; row < srcHeight; row++) { 847f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul const GLubyte *srcUB = (const GLubyte *) src; 848f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul GLushort *dstUS = (GLushort *) dst; 849f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul for (col = 0; col < srcWidth; col++) { 850f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul dstUS[col] = PACK_COLOR_565( srcUB[0], srcUB[1], srcUB[2] ); 851f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul srcUB += 3; 852f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul } 853f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul dst += dstRowStride; 854f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul src += srcRowStride; 855f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul } 856f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul } 857f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul else { 858f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul /* general path */ 8598f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims, 860f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul baseInternalFormat, 861f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul dstFormat->BaseFormat, 862f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul srcWidth, srcHeight, srcDepth, 863f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul srcFormat, srcType, srcAddr, 864f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul srcPacking); 865f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul const GLchan *src = tempImage; 866f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul GLubyte *dstImage = (GLubyte *) dstAddr 867f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul + dstZoffset * dstImageStride 868f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul + dstYoffset * dstRowStride 869f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul + dstXoffset * dstFormat->TexelBytes; 870f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul GLint img, row, col; 871f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul if (!tempImage) 872f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul return GL_FALSE; 873f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight); 874f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul for (img = 0; img < srcDepth; img++) { 875f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul GLubyte *dstRow = dstImage; 876f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul for (row = 0; row < srcHeight; row++) { 877f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul GLushort *dstUS = (GLushort *) dstRow; 878f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul for (col = 0; col < srcWidth; col++) { 879f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul dstUS[col] = PACK_COLOR_565( CHAN_TO_UBYTE(src[RCOMP]), 880f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul CHAN_TO_UBYTE(src[GCOMP]), 881f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul CHAN_TO_UBYTE(src[BCOMP]) ); 882f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul src += 3; 883f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul } 884f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul dstRow += dstRowStride; 885f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul } 886f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul dstImage += dstImageStride; 887f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul } 888f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul _mesa_free((void *) tempImage); 889f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul } 890f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul return GL_TRUE; 891f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul} 892f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul 893f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul 894f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian PaulGLboolean 895f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul_mesa_texstore_rgba8888(STORE_PARAMS) 896f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul{ 897f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul const GLuint ui = 1; 898f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul const GLubyte littleEndian = *((const GLubyte *) &ui); 899f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul 900f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul ASSERT(dstFormat == &_mesa_texformat_rgba8888); 901f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul ASSERT(dstFormat->TexelBytes == 4); 902f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul 903f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul if (!ctx->_ImageTransferState && 904f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul !srcPacking->SwapBytes && 905f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul baseInternalFormat == GL_RGBA && 906f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul srcFormat == GL_RGBA && 907f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul ((srcType == GL_UNSIGNED_INT_8_8_8_8_REV && littleEndian) || 908f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul (srcType == GL_UNSIGNED_INT_8_8_8_8 && !littleEndian))) { 909f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul /* simple memcpy path */ 910f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul memcpy_texture(dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset, 911f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul dstRowStride, dstImageStride, 912f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul srcWidth, srcHeight, srcDepth, srcFormat, srcType, 913f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul srcAddr, srcPacking); 914f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul } 915f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul else { 916f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul /* general path */ 9178f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims, 918f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul baseInternalFormat, 919f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul dstFormat->BaseFormat, 920f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul srcWidth, srcHeight, srcDepth, 921f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul srcFormat, srcType, srcAddr, 922f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul srcPacking); 923f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul const GLchan *src = tempImage; 924f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul GLubyte *dstImage = (GLubyte *) dstAddr 925f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul + dstZoffset * dstImageStride 926f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul + dstYoffset * dstRowStride 927f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul + dstXoffset * dstFormat->TexelBytes; 928f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul GLint img, row, col; 929f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul if (!tempImage) 930f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul return GL_FALSE; 931f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight); 932f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul for (img = 0; img < srcDepth; img++) { 933f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul GLubyte *dstRow = dstImage; 934f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul for (row = 0; row < srcHeight; row++) { 935f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul GLuint *dstUI = (GLuint *) dstRow; 936f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul for (col = 0; col < srcWidth; col++) { 937f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul dstUI[col] = PACK_COLOR_8888( CHAN_TO_UBYTE(src[RCOMP]), 938f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul CHAN_TO_UBYTE(src[GCOMP]), 939f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul CHAN_TO_UBYTE(src[BCOMP]), 940f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul CHAN_TO_UBYTE(src[ACOMP]) ); 941f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul src += 4; 942f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul } 943f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul dstRow += dstRowStride; 944f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul } 945f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul dstImage += dstImageStride; 946f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul } 947f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul _mesa_free((void *) tempImage); 948f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul } 949f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul return GL_TRUE; 950f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul} 951f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul 952f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul 953f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian PaulGLboolean 954f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul_mesa_texstore_argb8888(STORE_PARAMS) 955f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul{ 956f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul const GLuint ui = 1; 957f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul const GLubyte littleEndian = *((const GLubyte *) &ui); 958f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul 959f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul ASSERT(dstFormat == &_mesa_texformat_argb8888); 960f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul ASSERT(dstFormat->TexelBytes == 4); 961f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul 962f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul if (!ctx->_ImageTransferState && 963f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul !srcPacking->SwapBytes && 964f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul baseInternalFormat == GL_RGBA && 965f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul srcFormat == GL_BGRA && 966f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul ((srcType == GL_UNSIGNED_BYTE && littleEndian) || 967f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul (srcType == GL_UNSIGNED_INT_8_8_8_8_REV && littleEndian) || 968f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul (srcType == GL_UNSIGNED_INT_8_8_8_8 && !littleEndian))) { 969f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul /* simple memcpy path */ 970f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul memcpy_texture(dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset, 971f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul dstRowStride, dstImageStride, 972f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul srcWidth, srcHeight, srcDepth, srcFormat, srcType, 973f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul srcAddr, srcPacking); 974f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul } 975f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul else { 976f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul /* general path */ 9778f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims, 978f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul baseInternalFormat, 979f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul dstFormat->BaseFormat, 980f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul srcWidth, srcHeight, srcDepth, 981f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul srcFormat, srcType, srcAddr, 982f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul srcPacking); 983f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul const GLchan *src = tempImage; 984f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul GLubyte *dstImage = (GLubyte *) dstAddr 985f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul + dstZoffset * dstImageStride 986f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul + dstYoffset * dstRowStride 987f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul + dstXoffset * dstFormat->TexelBytes; 988f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul GLint img, row, col; 989f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul if (!tempImage) 990f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul return GL_FALSE; 991f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight); 992f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul for (img = 0; img < srcDepth; img++) { 993f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul GLubyte *dstRow = dstImage; 994f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul for (row = 0; row < srcHeight; row++) { 995f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul GLuint *dstUI = (GLuint *) dstRow; 996f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul for (col = 0; col < srcWidth; col++) { 997f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul dstUI[col] = PACK_COLOR_8888( CHAN_TO_UBYTE(src[ACOMP]), 998f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul CHAN_TO_UBYTE(src[RCOMP]), 999f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul CHAN_TO_UBYTE(src[GCOMP]), 1000f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul CHAN_TO_UBYTE(src[BCOMP]) ); 1001f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul src += 4; 1002f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul } 1003f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul dstRow += dstRowStride; 1004f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul } 1005f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul dstImage += dstImageStride; 1006f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul } 1007f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul _mesa_free((void *) tempImage); 1008f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul } 1009f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul return GL_TRUE; 1010f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul} 1011f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul 1012f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul 1013f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul 1014f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian PaulGLboolean 1015f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul_mesa_texstore_rgb888(STORE_PARAMS) 1016f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul{ 1017f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul const GLuint ui = 1; 1018f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul const GLubyte littleEndian = *((const GLubyte *) &ui); 1019f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul 1020f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul ASSERT(dstFormat == &_mesa_texformat_rgb888); 1021f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul ASSERT(dstFormat->TexelBytes == 3); 1022f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul 1023f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul if (!ctx->_ImageTransferState && 1024f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul !srcPacking->SwapBytes && 1025f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul baseInternalFormat == GL_RGB && 1026f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul srcFormat == GL_BGR && 1027f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul srcType == GL_UNSIGNED_BYTE && 1028f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul littleEndian) { 1029f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul /* simple memcpy path */ 1030f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul memcpy_texture(dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset, 1031f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul dstRowStride, dstImageStride, 1032f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul srcWidth, srcHeight, srcDepth, srcFormat, srcType, 1033f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul srcAddr, srcPacking); 1034f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul } 1035f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul else if (!ctx->_ImageTransferState && 1036f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul !srcPacking->SwapBytes && 1037f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul srcFormat == GL_RGBA && 1038f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul srcType == GL_UNSIGNED_BYTE) { 1039f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul /* extract BGR from RGBA */ 1040f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul int img, row, col; 1041f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul GLubyte *dstImage = (GLubyte *) dstAddr 1042f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul + dstZoffset * dstImageStride 1043f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul + dstYoffset * dstRowStride 1044f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul + dstXoffset * dstFormat->TexelBytes; 1045f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul for (img = 0; img < srcDepth; img++) { 1046f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul const GLint srcRowStride = _mesa_image_row_stride(srcPacking, 1047f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul srcWidth, srcFormat, srcType); 1048bdd15b5749b45929fa642c3e47997f52eb07fbe5Brian Paul GLubyte *srcRow = (GLubyte *) _mesa_image_address(srcPacking, srcAddr, 1049bdd15b5749b45929fa642c3e47997f52eb07fbe5Brian Paul srcWidth, srcHeight, srcFormat, srcType, img, 0, 0); 1050f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul GLubyte *dstRow = dstImage; 1051f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul for (row = 0; row < srcHeight; row++) { 1052f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul for (col = 0; col < srcWidth; col++) { 1053f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul dstRow[col * 3 + 0] = srcRow[col * 4 + BCOMP]; 1054f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul dstRow[col * 3 + 1] = srcRow[col * 4 + GCOMP]; 1055f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul dstRow[col * 3 + 2] = srcRow[col * 4 + RCOMP]; 1056f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul } 1057f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul dstRow += dstRowStride; 1058f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul srcRow += srcRowStride; 1059f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul } 1060f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul dstImage += dstImageStride; 1061f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul } 1062f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul } 1063f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul else { 1064f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul /* general path */ 10658f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims, 1066f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul baseInternalFormat, 1067f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul dstFormat->BaseFormat, 1068f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul srcWidth, srcHeight, srcDepth, 1069f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul srcFormat, srcType, srcAddr, 1070f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul srcPacking); 1071f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul const GLchan *src = (const GLubyte *) tempImage; 1072f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul GLubyte *dstImage = (GLubyte *) dstAddr 1073f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul + dstZoffset * dstImageStride 1074f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul + dstYoffset * dstRowStride 1075f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul + dstXoffset * dstFormat->TexelBytes; 1076f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul GLint img, row, col; 1077f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul if (!tempImage) 1078f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul return GL_FALSE; 1079f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight); 1080f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul for (img = 0; img < srcDepth; img++) { 1081f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul GLubyte *dstRow = dstImage; 1082f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul for (row = 0; row < srcHeight; row++) { 1083f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul#if 0 1084f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul if (littleEndian) { 1085f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul for (col = 0; col < srcWidth; col++) { 1086f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul dstRow[col * 3 + 0] = CHAN_TO_UBYTE(src[RCOMP]); 1087f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul dstRow[col * 3 + 1] = CHAN_TO_UBYTE(src[GCOMP]); 1088f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul dstRow[col * 3 + 2] = CHAN_TO_UBYTE(src[BCOMP]); 1089f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul srcUB += 3; 1090f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul } 1091f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul } 1092f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul else { 1093f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul for (col = 0; col < srcWidth; col++) { 1094f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul dstRow[col * 3 + 0] = srcUB[BCOMP]; 1095f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul dstRow[col * 3 + 1] = srcUB[GCOMP]; 1096f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul dstRow[col * 3 + 2] = srcUB[RCOMP]; 1097f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul srcUB += 3; 1098f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul } 1099f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul } 1100f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul#else 1101f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul for (col = 0; col < srcWidth; col++) { 1102f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul dstRow[col * 3 + 0] = CHAN_TO_UBYTE(src[BCOMP]); 1103f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul dstRow[col * 3 + 1] = CHAN_TO_UBYTE(src[GCOMP]); 1104f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul dstRow[col * 3 + 2] = CHAN_TO_UBYTE(src[RCOMP]); 1105f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul src += 3; 1106f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul } 1107f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul#endif 1108f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul dstRow += dstRowStride; 1109f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul } 1110f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul dstImage += dstImageStride; 1111f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul } 1112f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul _mesa_free((void *) tempImage); 1113f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul } 1114f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul return GL_TRUE; 1115f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul} 1116f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul 1117f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul 1118f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian PaulGLboolean 1119f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul_mesa_texstore_argb4444(STORE_PARAMS) 1120f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul{ 1121f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul const GLuint ui = 1; 1122f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul const GLubyte littleEndian = *((const GLubyte *) &ui); 1123f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul 1124f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul ASSERT(dstFormat == &_mesa_texformat_argb4444); 1125f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul ASSERT(dstFormat->TexelBytes == 2); 1126f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul 1127f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul if (!ctx->_ImageTransferState && 1128f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul !srcPacking->SwapBytes && 1129f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul baseInternalFormat == GL_RGBA && 1130f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul srcFormat == GL_BGRA && 1131f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul ((srcType == GL_UNSIGNED_SHORT_4_4_4_4_REV && littleEndian) || 1132f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul (srcType == GL_UNSIGNED_SHORT_4_4_4_4 && !littleEndian))) { 1133f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul /* simple memcpy path */ 1134f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul memcpy_texture(dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset, 1135f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul dstRowStride, dstImageStride, 1136f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul srcWidth, srcHeight, srcDepth, srcFormat, srcType, 1137f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul srcAddr, srcPacking); 1138f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul } 1139f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul else { 1140f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul /* general path */ 11418f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims, 1142f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul baseInternalFormat, 1143f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul dstFormat->BaseFormat, 1144f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul srcWidth, srcHeight, srcDepth, 1145f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul srcFormat, srcType, srcAddr, 1146f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul srcPacking); 1147f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul const GLchan *src = tempImage; 1148f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul GLubyte *dstImage = (GLubyte *) dstAddr 1149f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul + dstZoffset * dstImageStride 1150f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul + dstYoffset * dstRowStride 1151f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul + dstXoffset * dstFormat->TexelBytes; 1152f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul GLint img, row, col; 1153f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul if (!tempImage) 1154f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul return GL_FALSE; 1155f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight); 1156f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul for (img = 0; img < srcDepth; img++) { 1157f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul GLubyte *dstRow = dstImage; 1158f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul for (row = 0; row < srcHeight; row++) { 1159f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul GLushort *dstUS = (GLushort *) dstRow; 1160f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul for (col = 0; col < srcWidth; col++) { 1161f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul dstUS[col] = PACK_COLOR_4444( CHAN_TO_UBYTE(src[ACOMP]), 1162f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul CHAN_TO_UBYTE(src[RCOMP]), 1163f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul CHAN_TO_UBYTE(src[GCOMP]), 1164f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul CHAN_TO_UBYTE(src[BCOMP]) ); 1165f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul src += 4; 1166f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul } 1167f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul dstRow += dstRowStride; 1168f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul } 1169f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul dstImage += dstImageStride; 1170f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul } 1171f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul _mesa_free((void *) tempImage); 1172f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul } 1173f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul return GL_TRUE; 1174f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul} 1175f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul 1176f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul 1177f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian PaulGLboolean 1178f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul_mesa_texstore_argb1555(STORE_PARAMS) 1179f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul{ 1180f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul const GLuint ui = 1; 1181f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul const GLubyte littleEndian = *((const GLubyte *) &ui); 1182f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul 1183f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul ASSERT(dstFormat == &_mesa_texformat_argb1555); 1184f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul ASSERT(dstFormat->TexelBytes == 2); 1185f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul 1186f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul if (!ctx->_ImageTransferState && 1187f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul !srcPacking->SwapBytes && 1188f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul baseInternalFormat == GL_RGBA && 1189f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul srcFormat == GL_BGRA && 1190f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul ((srcType == GL_UNSIGNED_SHORT_1_5_5_5_REV && littleEndian) || 1191f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul (srcType == GL_UNSIGNED_SHORT_5_5_5_1 && !littleEndian))) { 1192f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul /* simple memcpy path */ 1193f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul memcpy_texture(dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset, 1194f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul dstRowStride, dstImageStride, 1195f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul srcWidth, srcHeight, srcDepth, srcFormat, srcType, 1196f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul srcAddr, srcPacking); 1197f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul } 1198f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul else { 1199f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul /* general path */ 12008f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims, 1201f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul baseInternalFormat, 1202f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul dstFormat->BaseFormat, 1203f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul srcWidth, srcHeight, srcDepth, 1204f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul srcFormat, srcType, srcAddr, 1205f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul srcPacking); 1206f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul const GLchan *src =tempImage; 1207f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul GLubyte *dstImage = (GLubyte *) dstAddr 1208f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul + dstZoffset * dstImageStride 1209f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul + dstYoffset * dstRowStride 1210f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul + dstXoffset * dstFormat->TexelBytes; 1211f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul GLint img, row, col; 1212f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul if (!tempImage) 1213f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul return GL_FALSE; 1214f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight); 1215f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul for (img = 0; img < srcDepth; img++) { 1216f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul GLubyte *dstRow = dstImage; 1217f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul for (row = 0; row < srcHeight; row++) { 1218f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul GLushort *dstUS = (GLushort *) dstRow; 1219f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul for (col = 0; col < srcWidth; col++) { 1220f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul dstUS[col] = PACK_COLOR_1555( CHAN_TO_UBYTE(src[ACOMP]), 1221f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul CHAN_TO_UBYTE(src[RCOMP]), 1222f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul CHAN_TO_UBYTE(src[GCOMP]), 1223f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul CHAN_TO_UBYTE(src[BCOMP]) ); 1224f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul src += 4; 1225f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul } 1226f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul dstRow += dstRowStride; 1227f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul } 1228f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul dstImage += dstImageStride; 1229f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul } 1230f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul _mesa_free((void *) tempImage); 1231f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul } 1232f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul return GL_TRUE; 1233f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul} 1234f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul 1235f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul 1236f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian PaulGLboolean 1237f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul_mesa_texstore_al88(STORE_PARAMS) 1238f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul{ 1239f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul const GLuint ui = 1; 1240f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul const GLubyte littleEndian = *((const GLubyte *) &ui); 1241f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul 1242f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul ASSERT(dstFormat == &_mesa_texformat_al88); 1243f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul ASSERT(dstFormat->TexelBytes == 2); 1244f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul 1245f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul if (!ctx->_ImageTransferState && 1246f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul !srcPacking->SwapBytes && 1247f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul baseInternalFormat == GL_LUMINANCE_ALPHA && 1248f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul srcFormat == GL_LUMINANCE_ALPHA && 1249f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul srcType == GL_UNSIGNED_BYTE && 1250f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul littleEndian) { 1251f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul /* simple memcpy path */ 1252f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul memcpy_texture(dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset, 1253f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul dstRowStride, dstImageStride, 1254f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul srcWidth, srcHeight, srcDepth, srcFormat, srcType, 1255f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul srcAddr, srcPacking); 1256f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul } 1257f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul else { 1258f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul /* general path */ 12598f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims, 1260f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul baseInternalFormat, 1261f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul dstFormat->BaseFormat, 1262f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul srcWidth, srcHeight, srcDepth, 1263f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul srcFormat, srcType, srcAddr, 1264f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul srcPacking); 1265f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul const GLchan *src = tempImage; 1266f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul GLubyte *dstImage = (GLubyte *) dstAddr 1267f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul + dstZoffset * dstImageStride 1268f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul + dstYoffset * dstRowStride 1269f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul + dstXoffset * dstFormat->TexelBytes; 1270f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul GLint img, row, col; 1271f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul if (!tempImage) 1272f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul return GL_FALSE; 1273f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight); 1274f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul for (img = 0; img < srcDepth; img++) { 1275f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul GLubyte *dstRow = dstImage; 1276f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul for (row = 0; row < srcHeight; row++) { 1277f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul GLushort *dstUS = (GLushort *) dstRow; 1278f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul for (col = 0; col < srcWidth; col++) { 1279f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul dstUS[col] = PACK_COLOR_88( CHAN_TO_UBYTE(src[ACOMP]), 1280f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul CHAN_TO_UBYTE(src[RCOMP]) ); 1281f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul src += 2; 1282f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul } 1283f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul dstRow += dstRowStride; 1284f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul } 1285f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul dstImage += dstImageStride; 1286f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul } 1287f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul _mesa_free((void *) tempImage); 1288f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul } 1289f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul return GL_TRUE; 1290f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul} 1291f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul 1292f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul 1293f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian PaulGLboolean 1294f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul_mesa_texstore_rgb332(STORE_PARAMS) 1295f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul{ 1296f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul ASSERT(dstFormat == &_mesa_texformat_rgb332); 1297f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul ASSERT(dstFormat->TexelBytes == 1); 1298f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul 1299f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul if (!ctx->_ImageTransferState && 1300f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul !srcPacking->SwapBytes && 1301f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul baseInternalFormat == GL_RGB && 1302f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul srcFormat == GL_RGB && srcType == GL_UNSIGNED_BYTE_3_3_2) { 1303f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul /* simple memcpy path */ 1304f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul memcpy_texture(dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset, 1305f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul dstRowStride, dstImageStride, 1306f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul srcWidth, srcHeight, srcDepth, srcFormat, srcType, 1307f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul srcAddr, srcPacking); 1308f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul } 1309f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul else { 1310f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul /* general path */ 13118f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims, 1312f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul baseInternalFormat, 1313f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul dstFormat->BaseFormat, 1314f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul srcWidth, srcHeight, srcDepth, 1315f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul srcFormat, srcType, srcAddr, 1316f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul srcPacking); 1317f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul const GLchan *src = tempImage; 1318f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul GLubyte *dstImage = (GLubyte *) dstAddr 1319f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul + dstZoffset * dstImageStride 1320f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul + dstYoffset * dstRowStride 1321f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul + dstXoffset * dstFormat->TexelBytes; 1322f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul GLint img, row, col; 1323f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul if (!tempImage) 1324f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul return GL_FALSE; 1325f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight); 1326f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul for (img = 0; img < srcDepth; img++) { 1327f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul GLubyte *dstRow = dstImage; 1328f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul for (row = 0; row < srcHeight; row++) { 1329f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul for (col = 0; col < srcWidth; col++) { 1330f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul dstRow[col] = PACK_COLOR_332( CHAN_TO_UBYTE(src[RCOMP]), 1331f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul CHAN_TO_UBYTE(src[GCOMP]), 1332f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul CHAN_TO_UBYTE(src[BCOMP]) ); 1333f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul src += 3; 1334f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul } 1335f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul dstRow += dstRowStride; 1336f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul } 1337f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul dstImage += dstImageStride; 1338f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul } 1339f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul _mesa_free((void *) tempImage); 1340f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul } 1341f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul return GL_TRUE; 1342f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul} 1343f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul 1344f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul 1345f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul 1346f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul/** 1347f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * Texstore for _mesa_texformat_a8, _mesa_texformat_l8, _mesa_texformat_i8. 1348f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul */ 1349f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian PaulGLboolean 1350f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul_mesa_texstore_a8(STORE_PARAMS) 1351f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul{ 1352f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul ASSERT(dstFormat == &_mesa_texformat_a8 || 1353f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul dstFormat == &_mesa_texformat_l8 || 1354f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul dstFormat == &_mesa_texformat_i8); 1355f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul ASSERT(dstFormat->TexelBytes == 1); 1356f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul 1357f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul if (!ctx->_ImageTransferState && 1358f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul !srcPacking->SwapBytes && 1359f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul baseInternalFormat == srcFormat && 1360f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul srcType == GL_UNSIGNED_BYTE) { 1361f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul /* simple memcpy path */ 1362f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul memcpy_texture(dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset, 1363f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul dstRowStride, dstImageStride, 1364f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul srcWidth, srcHeight, srcDepth, srcFormat, srcType, 1365f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul srcAddr, srcPacking); 1366f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul } 1367f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul else { 1368f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul /* general path */ 13698f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims, 1370f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul baseInternalFormat, 1371f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul dstFormat->BaseFormat, 1372f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul srcWidth, srcHeight, srcDepth, 1373f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul srcFormat, srcType, srcAddr, 1374f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul srcPacking); 1375f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul const GLchan *src = tempImage; 1376f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul GLubyte *dstImage = (GLubyte *) dstAddr 1377f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul + dstZoffset * dstImageStride 1378f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul + dstYoffset * dstRowStride 1379f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul + dstXoffset * dstFormat->TexelBytes; 1380f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul GLint img, row, col; 1381f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul if (!tempImage) 1382f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul return GL_FALSE; 1383f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight); 1384f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul for (img = 0; img < srcDepth; img++) { 1385f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul GLubyte *dstRow = dstImage; 1386f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul for (row = 0; row < srcHeight; row++) { 1387f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul for (col = 0; col < srcWidth; col++) { 1388f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul dstRow[col] = CHAN_TO_UBYTE(src[col]); 1389f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul } 1390f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul dstRow += dstRowStride; 1391f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul src += srcWidth; 1392f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul } 1393f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul dstImage += dstImageStride; 1394f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul } 1395f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul _mesa_free((void *) tempImage); 1396f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul } 1397f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul return GL_TRUE; 1398f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul} 1399f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul 1400f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul 1401f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul 1402f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian PaulGLboolean 1403f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul_mesa_texstore_ci8(STORE_PARAMS) 1404f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul{ 1405f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul ASSERT(dstFormat == &_mesa_texformat_ci8); 1406f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul ASSERT(dstFormat->TexelBytes == 1); 1407f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul ASSERT(baseInternalFormat == GL_COLOR_INDEX); 1408f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul 1409f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul if (!ctx->_ImageTransferState && 1410f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul !srcPacking->SwapBytes && 1411f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul srcFormat == GL_COLOR_INDEX && 1412f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul srcType == GL_UNSIGNED_BYTE) { 1413f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul /* simple memcpy path */ 1414f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul memcpy_texture(dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset, 1415f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul dstRowStride, dstImageStride, 1416f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul srcWidth, srcHeight, srcDepth, srcFormat, srcType, 1417f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul srcAddr, srcPacking); 1418f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul } 1419f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul else { 1420f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul /* general path */ 1421f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul GLubyte *dstImage = (GLubyte *) dstAddr 1422f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul + dstZoffset * dstImageStride 1423f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul + dstYoffset * dstRowStride 1424f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul + dstXoffset * dstFormat->TexelBytes; 1425f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul GLint img, row; 1426f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul for (img = 0; img < srcDepth; img++) { 1427f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul GLubyte *dstRow = dstImage; 1428f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul for (row = 0; row < srcHeight; row++) { 1429f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul const GLvoid *src = _mesa_image_address(srcPacking, 1430f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, row, 0); 1431f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul _mesa_unpack_index_span(ctx, srcWidth, GL_UNSIGNED_BYTE, dstRow, 1432f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul srcType, src, srcPacking, 1433f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul ctx->_ImageTransferState); 1434f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul dstRow += dstRowStride; 1435f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul } 1436f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul dstImage += dstImageStride; 1437f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul } 1438f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul } 1439f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul return GL_TRUE; 1440f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul} 1441f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul 1442f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul 1443f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul/** 1444f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * Texstore for _mesa_texformat_ycbcr or _mesa_texformat_ycbcr_rev. 1445f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul */ 1446f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian PaulGLboolean 1447f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul_mesa_texstore_ycbcr(STORE_PARAMS) 1448f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul{ 1449f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul const GLuint ui = 1; 1450f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul const GLubyte littleEndian = *((const GLubyte *) &ui); 1451f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul 1452f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul ASSERT((dstFormat == &_mesa_texformat_ycbcr) || 1453f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul (dstFormat == &_mesa_texformat_ycbcr_rev)); 1454f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul ASSERT(dstFormat->TexelBytes == 2); 1455f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul ASSERT(ctx->Extensions.MESA_ycbcr_texture); 1456f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul ASSERT(srcFormat == GL_YCBCR_MESA); 1457f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul ASSERT((srcType == GL_UNSIGNED_SHORT_8_8_MESA) || 1458f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul (srcType == GL_UNSIGNED_SHORT_8_8_REV_MESA)); 1459f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul ASSERT(baseInternalFormat == GL_YCBCR_MESA); 1460f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul 1461f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul /* always just memcpy since no pixel transfer ops apply */ 1462f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul memcpy_texture(dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset, 1463f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul dstRowStride, dstImageStride, 1464f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul srcWidth, srcHeight, srcDepth, srcFormat, srcType, 1465f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul srcAddr, srcPacking); 1466f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul 1467f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul /* Check if we need byte swapping */ 1468f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul /* XXX the logic here _might_ be wrong */ 1469f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul if (srcPacking->SwapBytes ^ 1470f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul (srcType == GL_UNSIGNED_SHORT_8_8_REV_MESA) ^ 1471f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul (dstFormat == &_mesa_texformat_ycbcr_rev) ^ 1472f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul !littleEndian) { 1473f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul GLushort *pImage = (GLushort *) ((GLubyte *) dstAddr 1474f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul + dstZoffset * dstImageStride 1475f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul + dstYoffset * dstRowStride 1476f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul + dstXoffset * dstFormat->TexelBytes); 1477f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul GLint img, row; 1478f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul for (img = 0; img < srcDepth; img++) { 1479f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul GLushort *pRow = pImage; 1480f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul for (row = 0; row < srcHeight; row++) { 1481f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul _mesa_swap2(pRow, srcWidth); 1482f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul pRow += dstRowStride; 1483f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul } 1484f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul pImage += dstImageStride; 1485f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul } 1486f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul } 1487f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul return GL_TRUE; 1488f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul} 1489f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul 1490f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul 1491f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul 1492f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul 1493f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul/** 1494f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * Store an image in any of the formats: 1495f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * _mesa_texformat_rgba_float32 1496f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * _mesa_texformat_rgb_float32 1497f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * _mesa_texformat_alpha_float32 1498f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * _mesa_texformat_luminance_float32 1499f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * _mesa_texformat_luminance_alpha_float32 1500f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * _mesa_texformat_intensity_float32 1501f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul */ 1502f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian PaulGLboolean 1503f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul_mesa_texstore_rgba_float32(STORE_PARAMS) 1504f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul{ 1505f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul const GLint components = _mesa_components_in_format(baseInternalFormat); 1506f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul 1507f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul ASSERT(dstFormat == &_mesa_texformat_rgba_float32 || 1508f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul dstFormat == &_mesa_texformat_rgb_float32 || 1509f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul dstFormat == &_mesa_texformat_alpha_float32 || 1510f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul dstFormat == &_mesa_texformat_luminance_float32 || 1511f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul dstFormat == &_mesa_texformat_luminance_alpha_float32 || 1512f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul dstFormat == &_mesa_texformat_intensity_float32); 1513f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul ASSERT(baseInternalFormat == GL_RGBA || 1514f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul baseInternalFormat == GL_RGB || 1515f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul baseInternalFormat == GL_ALPHA || 1516f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul baseInternalFormat == GL_LUMINANCE || 1517f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul baseInternalFormat == GL_LUMINANCE_ALPHA || 1518f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul baseInternalFormat == GL_INTENSITY); 1519f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul ASSERT(dstFormat->TexelBytes == components * sizeof(GLfloat)); 1520f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul 1521f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul if (!ctx->_ImageTransferState && 1522f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul !srcPacking->SwapBytes && 1523f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul baseInternalFormat == srcFormat && 1524f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul srcType == GL_FLOAT) { 1525f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul /* simple memcpy path */ 1526f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul memcpy_texture(dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset, 1527f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul dstRowStride, dstImageStride, 1528f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul srcWidth, srcHeight, srcDepth, srcFormat, srcType, 1529f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul srcAddr, srcPacking); 1530f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul } 1531f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul else { 1532f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul /* general path */ 1533f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul const GLfloat *tempImage = make_temp_float_image(ctx, dims, 1534f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul baseInternalFormat, 1535f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul dstFormat->BaseFormat, 1536f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul srcWidth, srcHeight, srcDepth, 1537f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul srcFormat, srcType, srcAddr, 1538f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul srcPacking); 1539f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul const GLfloat *src = tempImage; 1540f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul const GLint bytesPerRow = srcWidth * components * sizeof(GLfloat); 1541f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul GLubyte *dstImage = (GLubyte *) dstAddr 1542f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul + dstZoffset * dstImageStride 1543f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul + dstYoffset * dstRowStride 1544f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul + dstXoffset * dstFormat->TexelBytes; 1545f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul GLint img, row; 1546f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul if (!tempImage) 1547f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul return GL_FALSE; 1548f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight); 1549f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul for (img = 0; img < srcDepth; img++) { 1550f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul GLubyte *dst = dstImage; 1551f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul for (row = 0; row < srcHeight; row++) { 1552f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul _mesa_memcpy(dst, src, bytesPerRow); 1553f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul dst += dstRowStride; 1554f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul src += srcWidth * components; 1555f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul } 1556f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul dstImage += dstImageStride; 1557f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul } 1558f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul 1559f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul _mesa_free((void *) tempImage); 1560f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul } 1561f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul return GL_TRUE; 1562f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul} 1563f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul 1564f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul 1565f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul/** 1566f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * As above, but store 16-bit floats. 1567f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul */ 1568f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian PaulGLboolean 1569f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul_mesa_texstore_rgba_float16(STORE_PARAMS) 1570f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul{ 1571f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul const GLint components = _mesa_components_in_format(baseInternalFormat); 1572f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul 1573f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul ASSERT(dstFormat == &_mesa_texformat_rgba_float16 || 1574f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul dstFormat == &_mesa_texformat_rgb_float16 || 1575f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul dstFormat == &_mesa_texformat_alpha_float16 || 1576f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul dstFormat == &_mesa_texformat_luminance_float16 || 1577f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul dstFormat == &_mesa_texformat_luminance_alpha_float16 || 1578f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul dstFormat == &_mesa_texformat_intensity_float16); 1579f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul ASSERT(baseInternalFormat == GL_RGBA || 1580f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul baseInternalFormat == GL_RGB || 1581f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul baseInternalFormat == GL_ALPHA || 1582f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul baseInternalFormat == GL_LUMINANCE || 1583f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul baseInternalFormat == GL_LUMINANCE_ALPHA || 1584f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul baseInternalFormat == GL_INTENSITY); 1585f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul ASSERT(dstFormat->TexelBytes == components * sizeof(GLhalfARB)); 1586f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul 1587f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul if (!ctx->_ImageTransferState && 1588f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul !srcPacking->SwapBytes && 1589f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul baseInternalFormat == srcFormat && 1590f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul srcType == GL_HALF_FLOAT_ARB) { 1591f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul /* simple memcpy path */ 1592f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul memcpy_texture(dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset, 1593f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul dstRowStride, dstImageStride, 1594f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul srcWidth, srcHeight, srcDepth, srcFormat, srcType, 1595f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul srcAddr, srcPacking); 1596f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul } 1597f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul else { 1598f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul /* general path */ 1599f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul const GLfloat *tempImage = make_temp_float_image(ctx, dims, 1600f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul baseInternalFormat, 1601f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul dstFormat->BaseFormat, 1602f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul srcWidth, srcHeight, srcDepth, 1603f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul srcFormat, srcType, srcAddr, 1604f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul srcPacking); 1605f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul const GLfloat *src = tempImage; 1606f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul GLubyte *dstImage = (GLubyte *) dstAddr 1607f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul + dstZoffset * dstImageStride 1608f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul + dstYoffset * dstRowStride 1609f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul + dstXoffset * dstFormat->TexelBytes; 1610f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul GLint img, row; 1611f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul if (!tempImage) 1612f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul return GL_FALSE; 1613f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight); 1614f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul for (img = 0; img < srcDepth; img++) { 1615f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul GLubyte *dstRow = dstImage; 1616f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul for (row = 0; row < srcHeight; row++) { 1617f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul GLhalfARB *dstTexel = (GLhalfARB *) dstRow; 1618f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul GLint i; 1619f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul for (i = 0; i < srcWidth * components; i++) { 1620f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul dstTexel[i] = _mesa_float_to_half(src[i]); 1621f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul } 1622f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul dstRow += dstRowStride; 1623f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul src += srcWidth * components; 1624f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul } 1625f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul dstImage += dstImageStride; 1626f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul } 1627f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul 1628f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul _mesa_free((void *) tempImage); 1629f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul } 1630f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul return GL_TRUE; 1631f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul} 1632f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul 1633f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul 1634f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul 16357a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul/** 16367a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul * Validate acces to a PBO for texture data. 16377a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul * 16387a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul * \todo If the PBO is really resident in VRAM, this won't work; the 16397a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul * device driver should check for that and do the right thing. 16407a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul */ 16417a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paulstatic const GLvoid * 16427a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paulvalidate_pbo_teximage( GLsizei width, GLsizei height, GLsizei depth, 16437a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul GLenum format, GLenum type, const GLvoid *pixels, 16447a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul const struct gl_pixelstore_attrib *unpack ) 16457a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul{ 16467a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul if (unpack->BufferObj->Name == 0) { 16477a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul /* no PBO */ 16487a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul return pixels; 16497a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul } 16507a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul else if (_mesa_validate_pbo_access(unpack, width, height, depth, format, 16517a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul type, pixels)) { 16527a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul return ADD_POINTERS(unpack->BufferObj->Data, pixels); 16537a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul } 16547a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul /* bad access! */ 16557a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul return NULL; 16567a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul} 16577a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul 16587a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul 16597a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul/** 16607a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul * Validate that unpacking compressed texture image data from a PBO 16617a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul * won't go out of bounds. 16627a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul * 16637a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul * \todo If the PBO is really resident in VRAM, this won't work; the 16647a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul * device driver should check for that and do the right thing. 16657a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul */ 16667a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paulstatic const GLvoid * 16677a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paulvalidate_pbo_compressed_teximage(GLsizei imageSize, const GLvoid *pixels, 16687a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul const struct gl_pixelstore_attrib *packing) 16697a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul{ 16707a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul if (packing->BufferObj->Name == 0) { 16717a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul /* not using a PBO - return pointer unchanged */ 16727a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul return pixels; 16737a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul } 16747a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul else { 16757a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul /* using a PBO */ 16767a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul if ((const GLubyte *) pixels + imageSize > 16777a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul (const GLubyte *) packing->BufferObj->Size) { 16787a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul /* out of bounds read! */ 16797a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul return NULL; 16807a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul } 16817a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul /* OK! */ 16827a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul return ADD_POINTERS(packing->BufferObj->Data, pixels); 16837a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul } 16847a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul} 16857a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul 16867a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul 168789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul 16887d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul/* 168989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * This is the software fallback for Driver.TexImage1D() 1690f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * and Driver.CopyTexImage1D(). 16918e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul */ 16928e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paulvoid 16938e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul_mesa_store_teximage1d(GLcontext *ctx, GLenum target, GLint level, 16948e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul GLint internalFormat, 16958e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul GLint width, GLint border, 16968e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul GLenum format, GLenum type, const GLvoid *pixels, 16978e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul const struct gl_pixelstore_attrib *packing, 16988e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul struct gl_texture_object *texObj, 16998e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul struct gl_texture_image *texImage) 17008e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul{ 17018e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul GLint postConvWidth = width; 1702f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul GLint sizeInBytes; 17038e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul 17048e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul if (ctx->_ImageTransferState & IMAGE_CONVOLUTION_BIT) { 17058e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul _mesa_adjust_image_for_convolution(ctx, 1, &postConvWidth, NULL); 17068e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul } 17078e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul 17087d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul /* choose the texture format */ 17097d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul assert(ctx->Driver.ChooseTextureFormat); 1710f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul texImage->TexFormat = ctx->Driver.ChooseTextureFormat(ctx, internalFormat, 1711f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul format, type); 17127d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul assert(texImage->TexFormat); 17134f295cee73bae1f687efe2dc062522b40d90b1e4Brian Paul texImage->FetchTexelc = texImage->TexFormat->FetchTexel1D; 17144f295cee73bae1f687efe2dc062522b40d90b1e4Brian Paul texImage->FetchTexelf = texImage->TexFormat->FetchTexel1Df; 17158e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul 17168e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul /* allocate memory */ 171789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul if (texImage->IsCompressed) 171889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul sizeInBytes = texImage->CompressedSize; 171989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul else 1720f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul sizeInBytes = postConvWidth * texImage->TexFormat->TexelBytes; 1721aeb4434563c4014a662ea334878b60d3031bb3c1Brian Paul texImage->Data = MESA_PBUFFER_ALLOC(sizeInBytes); 17227d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul if (!texImage->Data) { 17237d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage1D"); 17247d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul return; 17257d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul } 17268e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul 17277a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul pixels = validate_pbo_teximage(width, 1, 1, format, type, pixels, packing); 172889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul if (!pixels) 172989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul return; 173089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul 1731f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul { 1732f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul const GLint dstRowStride = 0, dstImageStride = 0; 1733f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul GLboolean success; 1734f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul ASSERT(texImage->TexFormat->StoreImage); 1735f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul success = texImage->TexFormat->StoreImage(ctx, 1, texImage->Format, 1736f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul texImage->TexFormat, 1737f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul texImage->Data, 1738f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul 0, 0, 0, /* dstX/Y/Zoffset */ 1739f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul dstRowStride, dstImageStride, 1740f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul width, 1, 1, 1741f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul format, type, pixels, packing); 1742f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul if (!success) { 1743f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage1D"); 1744f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul return; 1745f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul } 1746f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul } 1747f3b85c983f469875ac76081a61539a6c7b26777cBrian Paul 174889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul /* GL_SGIS_generate_mipmap */ 174989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul if (level == texObj->BaseLevel && texObj->GenerateMipmap) { 175089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul _mesa_generate_mipmap(ctx, target, 175189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul &ctx->Texture.Unit[ctx->Texture.CurrentUnit], 175289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul texObj); 17533893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul } 17548e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul} 17558e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul 17568e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul 17578e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul/* 175889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * This is the software fallback for Driver.TexImage2D() 175989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * and Driver.CopyTexImage2D(). 1760f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * Reasons why a driver might override this function: 1761f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * - Special memory allocation needs 1762f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * - Unusual row/image strides 1763f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * - Special housekeeping 17648e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul */ 17658e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paulvoid 17668e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul_mesa_store_teximage2d(GLcontext *ctx, GLenum target, GLint level, 17678e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul GLint internalFormat, 17688e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul GLint width, GLint height, GLint border, 17698e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul GLenum format, GLenum type, const void *pixels, 17708e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul const struct gl_pixelstore_attrib *packing, 17718e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul struct gl_texture_object *texObj, 17728e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul struct gl_texture_image *texImage) 17738e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul{ 17748e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul GLint postConvWidth = width, postConvHeight = height; 1775e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul GLint texelBytes, sizeInBytes; 17768e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul 17778e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul if (ctx->_ImageTransferState & IMAGE_CONVOLUTION_BIT) { 17788e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul _mesa_adjust_image_for_convolution(ctx, 2, &postConvWidth, 17798e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul &postConvHeight); 17808e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul } 17818e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul 17827d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul /* choose the texture format */ 17837d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul assert(ctx->Driver.ChooseTextureFormat); 17847d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul texImage->TexFormat = (*ctx->Driver.ChooseTextureFormat)(ctx, 17857d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul internalFormat, format, type); 17867d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul assert(texImage->TexFormat); 17874f295cee73bae1f687efe2dc062522b40d90b1e4Brian Paul texImage->FetchTexelc = texImage->TexFormat->FetchTexel2D; 17884f295cee73bae1f687efe2dc062522b40d90b1e4Brian Paul texImage->FetchTexelf = texImage->TexFormat->FetchTexel2Df; 17892c3d34c905fa6b831a066afae83b938de05eb241Gareth Hughes 17902c3d34c905fa6b831a066afae83b938de05eb241Gareth Hughes texelBytes = texImage->TexFormat->TexelBytes; 17918e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul 17928e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul /* allocate memory */ 179389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul if (texImage->IsCompressed) 179489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul sizeInBytes = texImage->CompressedSize; 179589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul else 179689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul sizeInBytes = postConvWidth * postConvHeight * texelBytes; 1797aeb4434563c4014a662ea334878b60d3031bb3c1Brian Paul texImage->Data = MESA_PBUFFER_ALLOC(sizeInBytes); 17987d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul if (!texImage->Data) { 17997d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D"); 18007d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul return; 18017d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul } 18028e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul 18037a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul pixels = validate_pbo_teximage(width, height, 1, 18047a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul format, type, pixels, packing); 180589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul if (!pixels) 180689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul return; 180789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul 1808f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul { 1809f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul GLint dstRowStride, dstImageStride = 0; 1810f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul GLboolean success; 1811f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul if (texImage->IsCompressed) { 1812f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul dstRowStride = _mesa_compressed_row_stride(texImage->IntFormat,width); 1813f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul } 1814f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul else { 1815f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul dstRowStride = width * texImage->TexFormat->TexelBytes; 1816f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul } 1817f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul ASSERT(texImage->TexFormat->StoreImage); 1818f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul success = texImage->TexFormat->StoreImage(ctx, 2, texImage->Format, 1819f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul texImage->TexFormat, 1820f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul texImage->Data, 1821f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul 0, 0, 0, /* dstX/Y/Zoffset */ 1822f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul dstRowStride, dstImageStride, 1823f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul width, height, 1, 1824f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul format, type, pixels, packing); 1825f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul if (!success) { 1826f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D"); 1827f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul return; 1828f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul } 1829f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul } 1830f3b85c983f469875ac76081a61539a6c7b26777cBrian Paul 183189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul /* GL_SGIS_generate_mipmap */ 183289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul if (level == texObj->BaseLevel && texObj->GenerateMipmap) { 183389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul _mesa_generate_mipmap(ctx, target, 183489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul &ctx->Texture.Unit[ctx->Texture.CurrentUnit], 183589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul texObj); 18363893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul } 18378e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul} 18388e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul 18398e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul 18408e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul 18418e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul/* 184289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * This is the software fallback for Driver.TexImage3D() 184389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * and Driver.CopyTexImage3D(). 18448e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul */ 18458e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paulvoid 18468e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul_mesa_store_teximage3d(GLcontext *ctx, GLenum target, GLint level, 18478e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul GLint internalFormat, 18488e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul GLint width, GLint height, GLint depth, GLint border, 18498e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul GLenum format, GLenum type, const void *pixels, 18508e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul const struct gl_pixelstore_attrib *packing, 18518e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul struct gl_texture_object *texObj, 18528e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul struct gl_texture_image *texImage) 18538e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul{ 1854e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul GLint texelBytes, sizeInBytes; 18558e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul 18567d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul /* choose the texture format */ 18577d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul assert(ctx->Driver.ChooseTextureFormat); 18587d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul texImage->TexFormat = (*ctx->Driver.ChooseTextureFormat)(ctx, 18597d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul internalFormat, format, type); 18607d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul assert(texImage->TexFormat); 18614f295cee73bae1f687efe2dc062522b40d90b1e4Brian Paul texImage->FetchTexelc = texImage->TexFormat->FetchTexel3D; 18624f295cee73bae1f687efe2dc062522b40d90b1e4Brian Paul texImage->FetchTexelf = texImage->TexFormat->FetchTexel3Df; 18632c3d34c905fa6b831a066afae83b938de05eb241Gareth Hughes 1864197c526d63e1d4ea96f29eece392cdc389770b38Brian Paul texelBytes = texImage->TexFormat->TexelBytes; 18658e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul 18668e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul /* allocate memory */ 186789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul if (texImage->IsCompressed) 186889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul sizeInBytes = texImage->CompressedSize; 186989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul else 187089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul sizeInBytes = width * height * depth * texelBytes; 1871aeb4434563c4014a662ea334878b60d3031bb3c1Brian Paul texImage->Data = MESA_PBUFFER_ALLOC(sizeInBytes); 18727d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul if (!texImage->Data) { 18737d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage3D"); 18747d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul return; 18757d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul } 18768e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul 18777a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul pixels = validate_pbo_teximage(width, height, depth, 18787a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul format, type, pixels, packing); 187989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul if (!pixels) 188089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul return; 188189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul 188289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul /* unpack image, apply transfer ops and store in texImage->Data */ 1883f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul { 1884f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul GLint dstRowStride, dstImageStride; 1885f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul GLboolean success; 1886f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul if (texImage->IsCompressed) { 1887f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul dstRowStride = _mesa_compressed_row_stride(texImage->IntFormat,width); 1888f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul dstImageStride = 0; 1889f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul } 1890f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul else { 1891f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul dstRowStride = width * texImage->TexFormat->TexelBytes; 1892f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul dstImageStride = dstRowStride * height; 1893f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul } 1894f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul ASSERT(texImage->TexFormat->StoreImage); 1895f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul success = texImage->TexFormat->StoreImage(ctx, 3, texImage->Format, 1896f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul texImage->TexFormat, 1897f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul texImage->Data, 1898f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul 0, 0, 0, /* dstX/Y/Zoffset */ 1899f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul dstRowStride, dstImageStride, 1900f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul width, height, depth, 1901f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul format, type, pixels, packing); 1902f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul if (!success) { 1903f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage3D"); 1904f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul return; 1905f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul } 1906f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul } 1907f3b85c983f469875ac76081a61539a6c7b26777cBrian Paul 190889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul /* GL_SGIS_generate_mipmap */ 190989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul if (level == texObj->BaseLevel && texObj->GenerateMipmap) { 191089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul _mesa_generate_mipmap(ctx, target, 191189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul &ctx->Texture.Unit[ctx->Texture.CurrentUnit], 191289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul texObj); 19133893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul } 19148e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul} 19158e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul 19168e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul 19178e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul 19188e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul 19198e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul/* 192089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * This is the software fallback for Driver.TexSubImage1D() 192189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * and Driver.CopyTexSubImage1D(). 19228e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul */ 19238e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paulvoid 19248e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul_mesa_store_texsubimage1d(GLcontext *ctx, GLenum target, GLint level, 19258e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul GLint xoffset, GLint width, 19268e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul GLenum format, GLenum type, const void *pixels, 19278e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul const struct gl_pixelstore_attrib *packing, 19288e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul struct gl_texture_object *texObj, 19298e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul struct gl_texture_image *texImage) 19308e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul{ 19317a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul pixels = validate_pbo_teximage(width, 1, 1, 19327a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul format, type, pixels, packing); 19337a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul if (!pixels) 19347a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul return; 19357a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul 1936f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul { 1937f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul const GLint dstRowStride = 0, dstImageStride = 0; 1938f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul GLboolean success; 1939f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul ASSERT(texImage->TexFormat->StoreImage); 1940f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul success = texImage->TexFormat->StoreImage(ctx, 1, texImage->Format, 1941f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul texImage->TexFormat, 1942f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul texImage->Data, 1943f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul xoffset, 0, 0, /* offsets */ 1944f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul dstRowStride, dstImageStride, 1945f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul width, 1, 1, 1946f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul format, type, pixels, packing); 1947f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul if (!success) { 1948f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage1D"); 1949f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul return; 1950f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul } 1951f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul } 19523893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul 19533893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul /* GL_SGIS_generate_mipmap */ 19543893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul if (level == texObj->BaseLevel && texObj->GenerateMipmap) { 1955d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul _mesa_generate_mipmap(ctx, target, 1956d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul &ctx->Texture.Unit[ctx->Texture.CurrentUnit], 19573893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul texObj); 19583893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul } 19598e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul} 19608e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul 19618e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul 196289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul 1963f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul/** 196489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * This is the software fallback for Driver.TexSubImage2D() 196589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * and Driver.CopyTexSubImage2D(). 19668e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul */ 19678e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paulvoid 19688e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul_mesa_store_texsubimage2d(GLcontext *ctx, GLenum target, GLint level, 19698e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul GLint xoffset, GLint yoffset, 19708e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul GLint width, GLint height, 19718e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul GLenum format, GLenum type, const void *pixels, 19728e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul const struct gl_pixelstore_attrib *packing, 19738e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul struct gl_texture_object *texObj, 19748e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul struct gl_texture_image *texImage) 19758e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul{ 19767a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul pixels = validate_pbo_teximage(width, height, 1, 19777a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul format, type, pixels, packing); 19787a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul if (!pixels) 19797a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul return; 19807a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul 1981f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul { 1982f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul GLint dstRowStride = 0, dstImageStride = 0; 1983f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul GLboolean success; 1984f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul if (texImage->IsCompressed) { 1985f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul dstRowStride = _mesa_compressed_row_stride(texImage->IntFormat, 1986f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul texImage->Width); 1987f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul } 1988f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul else { 1989f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul dstRowStride = texImage->Width * texImage->TexFormat->TexelBytes; 1990f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul } 1991f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul ASSERT(texImage->TexFormat->StoreImage); 1992f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul success = texImage->TexFormat->StoreImage(ctx, 2, texImage->Format, 1993f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul texImage->TexFormat, 1994f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul texImage->Data, 1995f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul xoffset, yoffset, 0, 1996f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul dstRowStride, dstImageStride, 1997f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul width, height, 1, 1998f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul format, type, pixels, packing); 1999f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul if (!success) { 2000f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage2D"); 2001f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul return; 2002f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul } 2003f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul } 20043893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul 20053893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul /* GL_SGIS_generate_mipmap */ 20063893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul if (level == texObj->BaseLevel && texObj->GenerateMipmap) { 2007d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul _mesa_generate_mipmap(ctx, target, 2008d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul &ctx->Texture.Unit[ctx->Texture.CurrentUnit], 20093893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul texObj); 20103893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul } 20118e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul} 20128e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul 20138e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul 20148e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul/* 20158e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * This is the software fallback for Driver.TexSubImage3D(). 201689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * and Driver.CopyTexSubImage3D(). 20178e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul */ 20188e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paulvoid 20198e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul_mesa_store_texsubimage3d(GLcontext *ctx, GLenum target, GLint level, 20208e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul GLint xoffset, GLint yoffset, GLint zoffset, 20218e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul GLint width, GLint height, GLint depth, 20228e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul GLenum format, GLenum type, const void *pixels, 20238e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul const struct gl_pixelstore_attrib *packing, 20248e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul struct gl_texture_object *texObj, 20258e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul struct gl_texture_image *texImage) 20268e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul{ 2027f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul pixels = validate_pbo_teximage(width, height, depth, 2028f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul format, type, pixels, packing); 2029f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul if (!pixels) 2030f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul return; 2031f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul 2032f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul { 2033f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul GLint dstRowStride, dstImageStride; 2034f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul GLboolean success; 2035f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul if (texImage->IsCompressed) { 2036f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul dstRowStride = _mesa_compressed_row_stride(texImage->IntFormat, 2037f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul texImage->Width); 2038f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul dstImageStride = 0; /* XXX fix */ 2039f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul } 2040f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul else { 2041f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul dstRowStride = texImage->Width * texImage->TexFormat->TexelBytes; 2042f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul dstImageStride = dstRowStride * texImage->Height; 2043f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul } 2044f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul ASSERT(texImage->TexFormat->StoreImage); 2045f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul success = texImage->TexFormat->StoreImage(ctx, 3, texImage->Format, 2046f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul texImage->TexFormat, 2047f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul texImage->Data, 2048f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul xoffset, yoffset, zoffset, 2049f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul dstRowStride, dstImageStride, 2050f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul width, height, depth, 2051f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul format, type, pixels, packing); 2052f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul if (!success) { 2053f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage3D"); 2054f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul return; 2055f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul } 2056f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul } 20578f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul 20583893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul /* GL_SGIS_generate_mipmap */ 20593893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul if (level == texObj->BaseLevel && texObj->GenerateMipmap) { 2060d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul _mesa_generate_mipmap(ctx, target, 2061d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul &ctx->Texture.Unit[ctx->Texture.CurrentUnit], 20623893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul texObj); 20633893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul } 20648e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul} 20658e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul 20668e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul 20672aadbf41dfd4f63c6118d0ad2d8659d289cbe454Brian Paul/* 20688e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * Fallback for Driver.CompressedTexImage1D() 20698e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul */ 20708e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paulvoid 20718e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul_mesa_store_compressed_teximage1d(GLcontext *ctx, GLenum target, GLint level, 20728e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul GLint internalFormat, 20738e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul GLint width, GLint border, 20748e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul GLsizei imageSize, const GLvoid *data, 20758e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul struct gl_texture_object *texObj, 20768e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul struct gl_texture_image *texImage) 20778e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul{ 207889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul /* this space intentionally left blank */ 20798e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul} 20808e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul 20818e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul 20828e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul 20838e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul/* 20848e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * Fallback for Driver.CompressedTexImage2D() 20858e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul */ 20868e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paulvoid 20878e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul_mesa_store_compressed_teximage2d(GLcontext *ctx, GLenum target, GLint level, 20888e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul GLint internalFormat, 20898e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul GLint width, GLint height, GLint border, 20908e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul GLsizei imageSize, const GLvoid *data, 20918e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul struct gl_texture_object *texObj, 20928e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul struct gl_texture_image *texImage) 20938e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul{ 209489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul /* This is pretty simple, basically just do a memcpy without worrying 209589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * about the usual image unpacking or image transfer operations. 20968e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul */ 209789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul ASSERT(texObj); 209889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul ASSERT(texImage); 209989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul ASSERT(texImage->Width > 0); 210089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul ASSERT(texImage->Height > 0); 210189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul ASSERT(texImage->Depth == 1); 210289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul ASSERT(texImage->Data == NULL); /* was freed in glCompressedTexImage2DARB */ 210389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul 210489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul /* choose the texture format */ 210589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul assert(ctx->Driver.ChooseTextureFormat); 210689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul texImage->TexFormat = (*ctx->Driver.ChooseTextureFormat)(ctx, 210789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul internalFormat, 0, 0); 210889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul assert(texImage->TexFormat); 21094f295cee73bae1f687efe2dc062522b40d90b1e4Brian Paul texImage->FetchTexelc = texImage->TexFormat->FetchTexel2D; 21104f295cee73bae1f687efe2dc062522b40d90b1e4Brian Paul texImage->FetchTexelf = texImage->TexFormat->FetchTexel2Df; 211189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul 211289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul /* allocate storage */ 211389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul texImage->Data = MESA_PBUFFER_ALLOC(imageSize); 211489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul if (!texImage->Data) { 211589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexImage2DARB"); 211689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul return; 211789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul } 211889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul 21197a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul data = validate_pbo_compressed_teximage(imageSize, data, &ctx->Unpack); 21207a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul if (!data) 21217a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul return; 21227a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul 212389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul /* copy the data */ 21244039cb8ca82d59451a6de8902fe35e693cdca3baBrian Paul ASSERT(texImage->CompressedSize == (GLuint) imageSize); 212589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul MEMCPY(texImage->Data, data, imageSize); 21268f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul 21278f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul /* GL_SGIS_generate_mipmap */ 21288f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul if (level == texObj->BaseLevel && texObj->GenerateMipmap) { 21298f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul _mesa_generate_mipmap(ctx, target, 21308f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul &ctx->Texture.Unit[ctx->Texture.CurrentUnit], 21318f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul texObj); 21328f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul } 21338e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul} 21348e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul 21358e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul 21368e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul 21378e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul/* 21388e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * Fallback for Driver.CompressedTexImage3D() 21398e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul */ 21408e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paulvoid 21418e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul_mesa_store_compressed_teximage3d(GLcontext *ctx, GLenum target, GLint level, 21428e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul GLint internalFormat, 21438e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul GLint width, GLint height, GLint depth, 21448e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul GLint border, 21458e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul GLsizei imageSize, const GLvoid *data, 21468e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul struct gl_texture_object *texObj, 21478e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul struct gl_texture_image *texImage) 21488e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul{ 214989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul /* this space intentionally left blank */ 21508e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul} 21518e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul 21528e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul 21538e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul 215489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul/** 215589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * Fallback for Driver.CompressedTexSubImage1D() 2156e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul */ 2157e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paulvoid 215889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul_mesa_store_compressed_texsubimage1d(GLcontext *ctx, GLenum target, 215989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul GLint level, 216089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul GLint xoffset, GLsizei width, 216189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul GLenum format, 216289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul GLsizei imageSize, const GLvoid *data, 216389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul struct gl_texture_object *texObj, 216489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul struct gl_texture_image *texImage) 2165e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul{ 216689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul /* this space intentionally left blank */ 2167e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul} 2168e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul 2169e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul 217089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul/** 217189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * Fallback for Driver.CompressedTexSubImage2D() 217289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul */ 217389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paulvoid 217489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul_mesa_store_compressed_texsubimage2d(GLcontext *ctx, GLenum target, 217589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul GLint level, 217689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul GLint xoffset, GLint yoffset, 217789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul GLsizei width, GLsizei height, 217889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul GLenum format, 217989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul GLsizei imageSize, const GLvoid *data, 218089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul struct gl_texture_object *texObj, 218189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul struct gl_texture_image *texImage) 218289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul{ 218389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul GLint bytesPerRow, destRowStride, srcRowStride; 218489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul GLint i, rows; 218589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul GLubyte *dest; 218689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul const GLubyte *src; 218789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul 218889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul /* these should have been caught sooner */ 218989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul ASSERT((width & 3) == 0 || width == 2 || width == 1); 219089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul ASSERT((height & 3) == 0 || height == 2 || height == 1); 219189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul ASSERT((xoffset & 3) == 0); 219289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul ASSERT((yoffset & 3) == 0); 219389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul 21947a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul data = validate_pbo_compressed_teximage(imageSize, data, &ctx->Unpack); 21957a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul if (!data) 21967a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul return; 21977a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul 219889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul srcRowStride = _mesa_compressed_row_stride(texImage->IntFormat, width); 219989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul src = (const GLubyte *) data; 220089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul 220189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul destRowStride = _mesa_compressed_row_stride(texImage->IntFormat, 220289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul texImage->Width); 220389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul dest = _mesa_compressed_image_address(xoffset, yoffset, 0, 220489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul texImage->IntFormat, 2205f4418f4d1c6dfe06af760226c5303e653b25b879Brian Paul texImage->Width, 2206f4418f4d1c6dfe06af760226c5303e653b25b879Brian Paul (GLubyte*) texImage->Data); 220789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul 220889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul bytesPerRow = srcRowStride; 220989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul rows = height / 4; 221089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul 221189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul for (i = 0; i < rows; i++) { 221289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul MEMCPY(dest, src, bytesPerRow); 221389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul dest += destRowStride; 221489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul src += srcRowStride; 221589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul } 22168f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul 22178f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul /* GL_SGIS_generate_mipmap */ 22188f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul if (level == texObj->BaseLevel && texObj->GenerateMipmap) { 22198f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul _mesa_generate_mipmap(ctx, target, 22208f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul &ctx->Texture.Unit[ctx->Texture.CurrentUnit], 22218f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul texObj); 22228f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul } 222389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul} 222489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul 222589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul 222689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul/** 222789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * Fallback for Driver.CompressedTexSubImage3D() 222889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul */ 222989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paulvoid 223089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul_mesa_store_compressed_texsubimage3d(GLcontext *ctx, GLenum target, 223189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul GLint level, 223289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul GLint xoffset, GLint yoffset, GLint zoffset, 223389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul GLsizei width, GLsizei height, GLsizei depth, 223489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul GLenum format, 223589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul GLsizei imageSize, const GLvoid *data, 223689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul struct gl_texture_object *texObj, 223789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul struct gl_texture_image *texImage) 223889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul{ 223989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul /* this space intentionally left blank */ 224089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul} 224189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul 224289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul 22433893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul/* 22443893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul * Average together two rows of a source image to produce a single new 22453893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul * row in the dest image. It's legal for the two source rows to point 22469228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul * to the same data. The source width must be equal to either the 22479228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul * dest width or two times the dest width. 22483893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul */ 22493893e638e6521b9c070e01c0b31d22754ff97a88Brian Paulstatic void 22509228e17bb5bf219269daeed5cbfdd912c118e926Brian Pauldo_row(const struct gl_texture_format *format, GLint srcWidth, 22519228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLvoid *srcRowA, const GLvoid *srcRowB, 22529228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul GLint dstWidth, GLvoid *dstRow) 22533893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul{ 22549228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLuint k0 = (srcWidth == dstWidth) ? 0 : 1; 22559228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLuint colStride = (srcWidth == dstWidth) ? 1 : 2; 22569228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul 2257c515f90ec3adca875e93b4a705e14f4a0a1661b4Brian Paul /* This assertion is no longer valid with non-power-of-2 textures 22589228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul assert(srcWidth == dstWidth || srcWidth == 2 * dstWidth); 2259c515f90ec3adca875e93b4a705e14f4a0a1661b4Brian Paul */ 22609228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul 22613893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul switch (format->MesaFormat) { 22623893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul case MESA_FORMAT_RGBA: 22633893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul { 22649228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul GLuint i, j, k; 22653893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul const GLchan (*rowA)[4] = (const GLchan (*)[4]) srcRowA; 22663893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul const GLchan (*rowB)[4] = (const GLchan (*)[4]) srcRowB; 22673893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul GLchan (*dst)[4] = (GLchan (*)[4]) dstRow; 22687c4268176eaaeb45003db4d5042a518b84c9f6dcKarl Schultz for (i = j = 0, k = k0; i < (GLuint) dstWidth; 22699228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul i++, j += colStride, k += colStride) { 22709228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul dst[i][0] = (rowA[j][0] + rowA[k][0] + 2271f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul rowB[j][0] + rowB[k][0]) / 4; 22729228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul dst[i][1] = (rowA[j][1] + rowA[k][1] + 2273f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul rowB[j][1] + rowB[k][1]) / 4; 22749228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul dst[i][2] = (rowA[j][2] + rowA[k][2] + 2275f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul rowB[j][2] + rowB[k][2]) / 4; 22769228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul dst[i][3] = (rowA[j][3] + rowA[k][3] + 2277f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul rowB[j][3] + rowB[k][3]) / 4; 22783893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul } 22793893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul } 22803893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul return; 22813893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul case MESA_FORMAT_RGB: 22823893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul { 22839228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul GLuint i, j, k; 22843893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul const GLchan (*rowA)[3] = (const GLchan (*)[3]) srcRowA; 22853893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul const GLchan (*rowB)[3] = (const GLchan (*)[3]) srcRowB; 22863893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul GLchan (*dst)[3] = (GLchan (*)[3]) dstRow; 22877c4268176eaaeb45003db4d5042a518b84c9f6dcKarl Schultz for (i = j = 0, k = k0; i < (GLuint) dstWidth; 22889228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul i++, j += colStride, k += colStride) { 22899228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul dst[i][0] = (rowA[j][0] + rowA[k][0] + 2290f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul rowB[j][0] + rowB[k][0]) / 4; 22919228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul dst[i][1] = (rowA[j][1] + rowA[k][1] + 2292f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul rowB[j][1] + rowB[k][1]) / 4; 22939228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul dst[i][2] = (rowA[j][2] + rowA[k][2] + 2294f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul rowB[j][2] + rowB[k][2]) / 4; 22953893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul } 22963893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul } 22973893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul return; 22983893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul case MESA_FORMAT_ALPHA: 22993893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul case MESA_FORMAT_LUMINANCE: 23003893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul case MESA_FORMAT_INTENSITY: 23013893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul case MESA_FORMAT_COLOR_INDEX: 23023893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul { 23039228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul GLuint i, j, k; 23043893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul const GLchan *rowA = (const GLchan *) srcRowA; 23053893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul const GLchan *rowB = (const GLchan *) srcRowB; 23063893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul GLchan *dst = (GLchan *) dstRow; 23077c4268176eaaeb45003db4d5042a518b84c9f6dcKarl Schultz for (i = j = 0, k = k0; i < (GLuint) dstWidth; 23089228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul i++, j += colStride, k += colStride) { 2309f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul dst[i] = (rowA[j] + rowA[k] + rowB[j] + rowB[k]) / 4; 23103893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul } 23113893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul } 23123893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul return; 23133893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul case MESA_FORMAT_LUMINANCE_ALPHA: 23143893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul { 23159228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul GLuint i, j, k; 23163893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul const GLchan (*rowA)[2] = (const GLchan (*)[2]) srcRowA; 23173893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul const GLchan (*rowB)[2] = (const GLchan (*)[2]) srcRowB; 23183893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul GLchan (*dst)[2] = (GLchan (*)[2]) dstRow; 23197c4268176eaaeb45003db4d5042a518b84c9f6dcKarl Schultz for (i = j = 0, k = k0; i < (GLuint) dstWidth; 23209228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul i++, j += colStride, k += colStride) { 23219228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul dst[i][0] = (rowA[j][0] + rowA[k][0] + 2322f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul rowB[j][0] + rowB[k][0]) / 4; 23239228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul dst[i][1] = (rowA[j][1] + rowA[k][1] + 2324f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul rowB[j][1] + rowB[k][1]) / 4; 23253893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul } 23263893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul } 23273893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul return; 2328f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul case MESA_FORMAT_DEPTH_COMPONENT_FLOAT32: 23298bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul { 23309228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul GLuint i, j, k; 23318bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul const GLfloat *rowA = (const GLfloat *) srcRowA; 23328bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul const GLfloat *rowB = (const GLfloat *) srcRowB; 23338bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul GLfloat *dst = (GLfloat *) dstRow; 23347c4268176eaaeb45003db4d5042a518b84c9f6dcKarl Schultz for (i = j = 0, k = k0; i < (GLuint) dstWidth; 23359228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul i++, j += colStride, k += colStride) { 23369228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul dst[i] = (rowA[j] + rowA[k] + rowB[j] + rowB[k]) * 0.25F; 23378bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul } 23388bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul } 23398bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul return; 2340f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul case MESA_FORMAT_DEPTH_COMPONENT16: 2341f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul { 2342f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul GLuint i, j, k; 2343f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul const GLushort *rowA = (const GLushort *) srcRowA; 2344f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul const GLushort *rowB = (const GLushort *) srcRowB; 2345f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul GLushort *dst = (GLushort *) dstRow; 2346f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul for (i = j = 0, k = k0; i < (GLuint) dstWidth; 2347f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul i++, j += colStride, k += colStride) { 2348f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul dst[i] = (rowA[j] + rowA[k] + rowB[j] + rowB[k]) / 4; 2349f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul } 2350f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul } 2351f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul return; 23528bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul /* Begin hardware formats */ 23538bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul case MESA_FORMAT_RGBA8888: 23548bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul case MESA_FORMAT_ARGB8888: 23558bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul { 23569228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul GLuint i, j, k; 23578bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul const GLubyte (*rowA)[4] = (const GLubyte (*)[4]) srcRowA; 23588bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul const GLubyte (*rowB)[4] = (const GLubyte (*)[4]) srcRowB; 23598bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul GLubyte (*dst)[4] = (GLubyte (*)[4]) dstRow; 23607c4268176eaaeb45003db4d5042a518b84c9f6dcKarl Schultz for (i = j = 0, k = k0; i < (GLuint) dstWidth; 23619228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul i++, j += colStride, k += colStride) { 23629228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul dst[i][0] = (rowA[j][0] + rowA[k][0] + 2363f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul rowB[j][0] + rowB[k][0]) / 4; 23649228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul dst[i][1] = (rowA[j][1] + rowA[k][1] + 2365f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul rowB[j][1] + rowB[k][1]) / 4; 23669228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul dst[i][2] = (rowA[j][2] + rowA[k][2] + 2367f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul rowB[j][2] + rowB[k][2]) / 4; 23689228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul dst[i][3] = (rowA[j][3] + rowA[k][3] + 2369f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul rowB[j][3] + rowB[k][3]) / 4; 23708bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul } 23718bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul } 23728bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul return; 23738bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul case MESA_FORMAT_RGB888: 23748bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul { 23759228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul GLuint i, j, k; 23768bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul const GLubyte (*rowA)[3] = (const GLubyte (*)[3]) srcRowA; 23778bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul const GLubyte (*rowB)[3] = (const GLubyte (*)[3]) srcRowB; 23788bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul GLubyte (*dst)[3] = (GLubyte (*)[3]) dstRow; 23797c4268176eaaeb45003db4d5042a518b84c9f6dcKarl Schultz for (i = j = 0, k = k0; i < (GLuint) dstWidth; 23809228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul i++, j += colStride, k += colStride) { 23819228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul dst[i][0] = (rowA[j][0] + rowA[k][0] + 2382f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul rowB[j][0] + rowB[k][0]) / 4; 23839228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul dst[i][1] = (rowA[j][1] + rowA[k][1] + 2384f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul rowB[j][1] + rowB[k][1]) / 4; 23859228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul dst[i][2] = (rowA[j][2] + rowA[k][2] + 2386f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul rowB[j][2] + rowB[k][2]) / 4; 23878bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul } 23888bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul } 23898bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul return; 23908bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul case MESA_FORMAT_RGB565: 23918bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul { 23929228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul GLuint i, j, k; 23938bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul const GLushort *rowA = (const GLushort *) srcRowA; 23948bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul const GLushort *rowB = (const GLushort *) srcRowB; 23958bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul GLushort *dst = (GLushort *) dstRow; 23967c4268176eaaeb45003db4d5042a518b84c9f6dcKarl Schultz for (i = j = 0, k = k0; i < (GLuint) dstWidth; 23979228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul i++, j += colStride, k += colStride) { 23989228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLint rowAr0 = rowA[j] & 0x1f; 23999228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLint rowAr1 = rowA[k] & 0x1f; 24009228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLint rowBr0 = rowB[j] & 0x1f; 24019228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLint rowBr1 = rowB[k] & 0x1f; 24029228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLint rowAg0 = (rowA[j] >> 5) & 0x3f; 24039228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLint rowAg1 = (rowA[k] >> 5) & 0x3f; 24049228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLint rowBg0 = (rowB[j] >> 5) & 0x3f; 24059228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLint rowBg1 = (rowB[k] >> 5) & 0x3f; 24069228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLint rowAb0 = (rowA[j] >> 11) & 0x1f; 24079228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLint rowAb1 = (rowA[k] >> 11) & 0x1f; 24089228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLint rowBb0 = (rowB[j] >> 11) & 0x1f; 24099228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLint rowBb1 = (rowB[k] >> 11) & 0x1f; 241007d6a983595b7ee52c8448fc579d952ce36472b8Ian Romanick const GLint red = (rowAr0 + rowAr1 + rowBr0 + rowBr1) >> 2; 241107d6a983595b7ee52c8448fc579d952ce36472b8Ian Romanick const GLint green = (rowAg0 + rowAg1 + rowBg0 + rowBg1) >> 2; 241207d6a983595b7ee52c8448fc579d952ce36472b8Ian Romanick const GLint blue = (rowAb0 + rowAb1 + rowBb0 + rowBb1) >> 2; 24138bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul dst[i] = (blue << 11) | (green << 5) | red; 24148bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul } 24158bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul } 24168bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul return; 24178bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul case MESA_FORMAT_ARGB4444: 24188bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul { 24199228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul GLuint i, j, k; 24208bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul const GLushort *rowA = (const GLushort *) srcRowA; 24218bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul const GLushort *rowB = (const GLushort *) srcRowB; 24228bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul GLushort *dst = (GLushort *) dstRow; 24237c4268176eaaeb45003db4d5042a518b84c9f6dcKarl Schultz for (i = j = 0, k = k0; i < (GLuint) dstWidth; 24249228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul i++, j += colStride, k += colStride) { 24259228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLint rowAr0 = rowA[j] & 0xf; 24269228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLint rowAr1 = rowA[k] & 0xf; 24279228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLint rowBr0 = rowB[j] & 0xf; 24289228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLint rowBr1 = rowB[k] & 0xf; 24299228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLint rowAg0 = (rowA[j] >> 4) & 0xf; 24309228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLint rowAg1 = (rowA[k] >> 4) & 0xf; 24319228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLint rowBg0 = (rowB[j] >> 4) & 0xf; 24329228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLint rowBg1 = (rowB[k] >> 4) & 0xf; 24339228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLint rowAb0 = (rowA[j] >> 8) & 0xf; 24349228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLint rowAb1 = (rowA[k] >> 8) & 0xf; 24359228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLint rowBb0 = (rowB[j] >> 8) & 0xf; 24369228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLint rowBb1 = (rowB[k] >> 8) & 0xf; 24379228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLint rowAa0 = (rowA[j] >> 12) & 0xf; 24389228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLint rowAa1 = (rowA[k] >> 12) & 0xf; 24399228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLint rowBa0 = (rowB[j] >> 12) & 0xf; 24409228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLint rowBa1 = (rowB[k] >> 12) & 0xf; 244107d6a983595b7ee52c8448fc579d952ce36472b8Ian Romanick const GLint red = (rowAr0 + rowAr1 + rowBr0 + rowBr1) >> 2; 244207d6a983595b7ee52c8448fc579d952ce36472b8Ian Romanick const GLint green = (rowAg0 + rowAg1 + rowBg0 + rowBg1) >> 2; 244307d6a983595b7ee52c8448fc579d952ce36472b8Ian Romanick const GLint blue = (rowAb0 + rowAb1 + rowBb0 + rowBb1) >> 2; 244407d6a983595b7ee52c8448fc579d952ce36472b8Ian Romanick const GLint alpha = (rowAa0 + rowAa1 + rowBa0 + rowBa1) >> 2; 24458bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul dst[i] = (alpha << 12) | (blue << 8) | (green << 4) | red; 24468bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul } 24478bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul } 24488bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul return; 24498bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul case MESA_FORMAT_ARGB1555: 24508bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul { 24519228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul GLuint i, j, k; 24528bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul const GLushort *rowA = (const GLushort *) srcRowA; 24538bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul const GLushort *rowB = (const GLushort *) srcRowB; 24548bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul GLushort *dst = (GLushort *) dstRow; 24557c4268176eaaeb45003db4d5042a518b84c9f6dcKarl Schultz for (i = j = 0, k = k0; i < (GLuint) dstWidth; 24569228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul i++, j += colStride, k += colStride) { 24579228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLint rowAr0 = rowA[j] & 0x1f; 24589228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLint rowAr1 = rowA[k] & 0x1f; 24599228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLint rowBr0 = rowB[j] & 0x1f; 24609228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLint rowBr1 = rowB[k] & 0xf; 24619228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLint rowAg0 = (rowA[j] >> 5) & 0x1f; 24629228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLint rowAg1 = (rowA[k] >> 5) & 0x1f; 24639228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLint rowBg0 = (rowB[j] >> 5) & 0x1f; 24649228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLint rowBg1 = (rowB[k] >> 5) & 0x1f; 24659228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLint rowAb0 = (rowA[j] >> 10) & 0x1f; 24669228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLint rowAb1 = (rowA[k] >> 10) & 0x1f; 24679228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLint rowBb0 = (rowB[j] >> 10) & 0x1f; 24689228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLint rowBb1 = (rowB[k] >> 10) & 0x1f; 24699228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLint rowAa0 = (rowA[j] >> 15) & 0x1; 24709228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLint rowAa1 = (rowA[k] >> 15) & 0x1; 24719228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLint rowBa0 = (rowB[j] >> 15) & 0x1; 24729228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLint rowBa1 = (rowB[k] >> 15) & 0x1; 247307d6a983595b7ee52c8448fc579d952ce36472b8Ian Romanick const GLint red = (rowAr0 + rowAr1 + rowBr0 + rowBr1) >> 2; 247407d6a983595b7ee52c8448fc579d952ce36472b8Ian Romanick const GLint green = (rowAg0 + rowAg1 + rowBg0 + rowBg1) >> 2; 247507d6a983595b7ee52c8448fc579d952ce36472b8Ian Romanick const GLint blue = (rowAb0 + rowAb1 + rowBb0 + rowBb1) >> 2; 247607d6a983595b7ee52c8448fc579d952ce36472b8Ian Romanick const GLint alpha = (rowAa0 + rowAa1 + rowBa0 + rowBa1) >> 2; 24778bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul dst[i] = (alpha << 15) | (blue << 10) | (green << 5) | red; 24788bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul } 24798bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul } 24808bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul return; 24818bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul case MESA_FORMAT_AL88: 24828bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul { 24839228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul GLuint i, j, k; 24848bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul const GLubyte (*rowA)[2] = (const GLubyte (*)[2]) srcRowA; 24858bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul const GLubyte (*rowB)[2] = (const GLubyte (*)[2]) srcRowB; 24868bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul GLubyte (*dst)[2] = (GLubyte (*)[2]) dstRow; 24877c4268176eaaeb45003db4d5042a518b84c9f6dcKarl Schultz for (i = j = 0, k = k0; i < (GLuint) dstWidth; 24889228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul i++, j += colStride, k += colStride) { 24899228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul dst[i][0] = (rowA[j][0] + rowA[k][0] + 24909228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul rowB[j][0] + rowB[k][0]) >> 2; 24919228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul dst[i][1] = (rowA[j][1] + rowA[k][1] + 24929228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul rowB[j][1] + rowB[k][1]) >> 2; 24938bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul } 24948bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul } 24958bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul return; 24968bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul case MESA_FORMAT_RGB332: 24978bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul { 24989228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul GLuint i, j, k; 24998bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul const GLubyte *rowA = (const GLubyte *) srcRowA; 25008bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul const GLubyte *rowB = (const GLubyte *) srcRowB; 25018bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul GLubyte *dst = (GLubyte *) dstRow; 25027c4268176eaaeb45003db4d5042a518b84c9f6dcKarl Schultz for (i = j = 0, k = k0; i < (GLuint) dstWidth; 25039228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul i++, j += colStride, k += colStride) { 25049228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLint rowAr0 = rowA[j] & 0x3; 25059228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLint rowAr1 = rowA[k] & 0x3; 25069228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLint rowBr0 = rowB[j] & 0x3; 25079228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLint rowBr1 = rowB[k] & 0x3; 25089228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLint rowAg0 = (rowA[j] >> 2) & 0x7; 25099228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLint rowAg1 = (rowA[k] >> 2) & 0x7; 25109228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLint rowBg0 = (rowB[j] >> 2) & 0x7; 25119228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLint rowBg1 = (rowB[k] >> 2) & 0x7; 25129228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLint rowAb0 = (rowA[j] >> 5) & 0x7; 25139228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLint rowAb1 = (rowA[k] >> 5) & 0x7; 25149228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLint rowBb0 = (rowB[j] >> 5) & 0x7; 25159228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLint rowBb1 = (rowB[k] >> 5) & 0x7; 251607d6a983595b7ee52c8448fc579d952ce36472b8Ian Romanick const GLint red = (rowAr0 + rowAr1 + rowBr0 + rowBr1) >> 2; 251707d6a983595b7ee52c8448fc579d952ce36472b8Ian Romanick const GLint green = (rowAg0 + rowAg1 + rowBg0 + rowBg1) >> 2; 251807d6a983595b7ee52c8448fc579d952ce36472b8Ian Romanick const GLint blue = (rowAb0 + rowAb1 + rowBb0 + rowBb1) >> 2; 25198bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul dst[i] = (blue << 5) | (green << 2) | red; 25208bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul } 25218bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul } 25228bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul return; 25238bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul case MESA_FORMAT_A8: 25248bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul case MESA_FORMAT_L8: 25258bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul case MESA_FORMAT_I8: 25268bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul case MESA_FORMAT_CI8: 25278bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul { 25289228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul GLuint i, j, k; 25298bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul const GLubyte *rowA = (const GLubyte *) srcRowA; 25308bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul const GLubyte *rowB = (const GLubyte *) srcRowB; 25318bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul GLubyte *dst = (GLubyte *) dstRow; 25327c4268176eaaeb45003db4d5042a518b84c9f6dcKarl Schultz for (i = j = 0, k = k0; i < (GLuint) dstWidth; 25339228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul i++, j += colStride, k += colStride) { 25349228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul dst[i] = (rowA[j] + rowA[k] + rowB[j] + rowB[k]) >> 2; 25358bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul } 25368bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul } 25378bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul return; 2538f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul case MESA_FORMAT_RGBA_FLOAT32: 2539f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul { 2540f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul GLuint i, j, k; 2541f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul const GLfloat (*rowA)[4] = (const GLfloat (*)[4]) srcRowA; 2542f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul const GLfloat (*rowB)[4] = (const GLfloat (*)[4]) srcRowB; 2543f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul GLfloat (*dst)[4] = (GLfloat (*)[4]) dstRow; 2544f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul for (i = j = 0, k = k0; i < (GLuint) dstWidth; 2545f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul i++, j += colStride, k += colStride) { 2546f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul dst[i][0] = (rowA[j][0] + rowA[k][0] + 2547f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul rowB[j][0] + rowB[k][0]) * 0.25F; 2548f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul dst[i][1] = (rowA[j][1] + rowA[k][1] + 2549f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul rowB[j][1] + rowB[k][1]) * 0.25F; 2550f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul dst[i][2] = (rowA[j][2] + rowA[k][2] + 2551f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul rowB[j][2] + rowB[k][2]) * 0.25F; 2552f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul dst[i][3] = (rowA[j][3] + rowA[k][3] + 2553f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul rowB[j][3] + rowB[k][3]) * 0.25F; 2554f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul } 2555f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul } 2556f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul return; 2557f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul case MESA_FORMAT_RGBA_FLOAT16: 2558f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul { 2559f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul GLuint i, j, k, comp; 2560f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul const GLhalfARB (*rowA)[4] = (const GLhalfARB (*)[4]) srcRowA; 2561f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul const GLhalfARB (*rowB)[4] = (const GLhalfARB (*)[4]) srcRowB; 2562f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul GLhalfARB (*dst)[4] = (GLhalfARB (*)[4]) dstRow; 2563f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul for (i = j = 0, k = k0; i < (GLuint) dstWidth; 2564f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul i++, j += colStride, k += colStride) { 2565f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul for (comp = 0; comp < 4; comp++) { 2566f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul GLfloat aj, ak, bj, bk; 2567f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul aj = _mesa_half_to_float(rowA[j][comp]); 2568f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul ak = _mesa_half_to_float(rowA[k][comp]); 2569f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul bj = _mesa_half_to_float(rowB[j][comp]); 2570f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul bk = _mesa_half_to_float(rowB[k][comp]); 2571f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul dst[i][comp] = _mesa_float_to_half((aj + ak + bj + bk) * 0.25F); 2572f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul } 2573f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul } 2574f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul } 2575f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul return; 2576f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul case MESA_FORMAT_RGB_FLOAT32: 2577f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul { 2578f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul GLuint i, j, k; 2579f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul const GLfloat (*rowA)[3] = (const GLfloat (*)[3]) srcRowA; 2580f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul const GLfloat (*rowB)[3] = (const GLfloat (*)[3]) srcRowB; 2581f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul GLfloat (*dst)[3] = (GLfloat (*)[3]) dstRow; 2582f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul for (i = j = 0, k = k0; i < (GLuint) dstWidth; 2583f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul i++, j += colStride, k += colStride) { 2584f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul dst[i][0] = (rowA[j][0] + rowA[k][0] + 2585f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul rowB[j][0] + rowB[k][0]) * 0.25F; 2586f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul dst[i][1] = (rowA[j][1] + rowA[k][1] + 2587f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul rowB[j][1] + rowB[k][1]) * 0.25F; 2588f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul dst[i][2] = (rowA[j][2] + rowA[k][2] + 2589f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul rowB[j][2] + rowB[k][2]) * 0.25F; 2590f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul } 2591f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul } 2592f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul return; 2593f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul case MESA_FORMAT_RGB_FLOAT16: 2594f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul { 2595f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul GLuint i, j, k, comp; 2596f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul const GLhalfARB (*rowA)[3] = (const GLhalfARB (*)[3]) srcRowA; 2597f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul const GLhalfARB (*rowB)[3] = (const GLhalfARB (*)[3]) srcRowB; 2598f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul GLhalfARB (*dst)[3] = (GLhalfARB (*)[3]) dstRow; 2599f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul for (i = j = 0, k = k0; i < (GLuint) dstWidth; 2600f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul i++, j += colStride, k += colStride) { 2601f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul for (comp = 0; comp < 3; comp++) { 2602f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul GLfloat aj, ak, bj, bk; 2603f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul aj = _mesa_half_to_float(rowA[j][comp]); 2604f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul ak = _mesa_half_to_float(rowA[k][comp]); 2605f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul bj = _mesa_half_to_float(rowB[j][comp]); 2606f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul bk = _mesa_half_to_float(rowB[k][comp]); 2607f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul dst[i][comp] = _mesa_float_to_half((aj + ak + bj + bk) * 0.25F); 2608f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul } 2609f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul } 2610f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul } 2611f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul return; 2612f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul case MESA_FORMAT_LUMINANCE_ALPHA_FLOAT32: 2613f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul { 2614f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul GLuint i, j, k; 2615f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul const GLfloat (*rowA)[2] = (const GLfloat (*)[2]) srcRowA; 2616f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul const GLfloat (*rowB)[2] = (const GLfloat (*)[2]) srcRowB; 2617f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul GLfloat (*dst)[2] = (GLfloat (*)[2]) dstRow; 2618f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul for (i = j = 0, k = k0; i < (GLuint) dstWidth; 2619f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul i++, j += colStride, k += colStride) { 2620f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul dst[i][0] = (rowA[j][0] + rowA[k][0] + 2621f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul rowB[j][0] + rowB[k][0]) * 0.25F; 2622f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul dst[i][1] = (rowA[j][1] + rowA[k][1] + 2623f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul rowB[j][1] + rowB[k][1]) * 0.25F; 2624f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul } 2625f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul } 2626f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul return; 2627f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul case MESA_FORMAT_LUMINANCE_ALPHA_FLOAT16: 2628f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul { 2629f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul GLuint i, j, k, comp; 2630f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul const GLhalfARB (*rowA)[2] = (const GLhalfARB (*)[2]) srcRowA; 2631f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul const GLhalfARB (*rowB)[2] = (const GLhalfARB (*)[2]) srcRowB; 2632f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul GLhalfARB (*dst)[2] = (GLhalfARB (*)[2]) dstRow; 2633f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul for (i = j = 0, k = k0; i < (GLuint) dstWidth; 2634f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul i++, j += colStride, k += colStride) { 2635f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul for (comp = 0; comp < 2; comp++) { 2636f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul GLfloat aj, ak, bj, bk; 2637f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul aj = _mesa_half_to_float(rowA[j][comp]); 2638f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul ak = _mesa_half_to_float(rowA[k][comp]); 2639f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul bj = _mesa_half_to_float(rowB[j][comp]); 2640f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul bk = _mesa_half_to_float(rowB[k][comp]); 2641f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul dst[i][comp] = _mesa_float_to_half((aj + ak + bj + bk) * 0.25F); 2642f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul } 2643f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul } 2644f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul } 2645f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul return; 2646f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul case MESA_FORMAT_ALPHA_FLOAT32: 2647f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul case MESA_FORMAT_LUMINANCE_FLOAT32: 2648f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul case MESA_FORMAT_INTENSITY_FLOAT32: 2649f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul { 2650f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul GLuint i, j, k; 2651f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul const GLfloat *rowA = (const GLfloat *) srcRowA; 2652f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul const GLfloat *rowB = (const GLfloat *) srcRowB; 2653f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul GLfloat *dst = (GLfloat *) dstRow; 2654f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul for (i = j = 0, k = k0; i < (GLuint) dstWidth; 2655f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul i++, j += colStride, k += colStride) { 2656f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul dst[i] = (rowA[j] + rowA[k] + rowB[j] + rowB[k]) * 0.25F; 2657f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul } 2658f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul } 2659f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul return; 2660f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul case MESA_FORMAT_ALPHA_FLOAT16: 2661f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul case MESA_FORMAT_LUMINANCE_FLOAT16: 2662f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul case MESA_FORMAT_INTENSITY_FLOAT16: 2663f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul { 2664f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul GLuint i, j, k; 2665f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul const GLhalfARB *rowA = (const GLhalfARB *) srcRowA; 2666f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul const GLhalfARB *rowB = (const GLhalfARB *) srcRowB; 2667f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul GLhalfARB *dst = (GLhalfARB *) dstRow; 2668f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul for (i = j = 0, k = k0; i < (GLuint) dstWidth; 2669f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul i++, j += colStride, k += colStride) { 2670f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul GLfloat aj, ak, bj, bk; 2671f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul aj = _mesa_half_to_float(rowA[j]); 2672f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul ak = _mesa_half_to_float(rowA[k]); 2673f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul bj = _mesa_half_to_float(rowB[j]); 2674f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul bk = _mesa_half_to_float(rowB[k]); 2675f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul dst[i] = _mesa_float_to_half((aj + ak + bj + bk) * 0.25F); 2676f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul } 2677f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul } 2678f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul return; 2679f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul 26803893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul default: 26813893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul _mesa_problem(NULL, "bad format in do_row()"); 26823893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul } 26833893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul} 26843893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul 26853893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul 26869228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul/* 26879228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul * These functions generate a 1/2-size mipmap image from a source image. 26889228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul * Texture borders are handled by copying or averaging the source image's 26899228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul * border texels, depending on the scale-down factor. 26909228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul */ 26913893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul 26923893e638e6521b9c070e01c0b31d22754ff97a88Brian Paulstatic void 26933893e638e6521b9c070e01c0b31d22754ff97a88Brian Paulmake_1d_mipmap(const struct gl_texture_format *format, GLint border, 26943893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul GLint srcWidth, const GLubyte *srcPtr, 26953893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul GLint dstWidth, GLubyte *dstPtr) 26963893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul{ 26973893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul const GLint bpt = format->TexelBytes; 26983893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul const GLubyte *src; 26993893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul GLubyte *dst; 27003893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul 27013893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul /* skip the border pixel, if any */ 27023893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul src = srcPtr + border * bpt; 27033893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul dst = dstPtr + border * bpt; 27043893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul 27053893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul /* we just duplicate the input row, kind of hack, saves code */ 27069228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul do_row(format, srcWidth - 2 * border, src, src, 27079228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul dstWidth - 2 * border, dst); 27083893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul 27093893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul if (border) { 27103893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul /* copy left-most pixel from source */ 27113893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul MEMCPY(dstPtr, srcPtr, bpt); 27123893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul /* copy right-most pixel from source */ 27133893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul MEMCPY(dstPtr + (dstWidth - 1) * bpt, 27143893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul srcPtr + (srcWidth - 1) * bpt, 27153893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul bpt); 27163893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul } 27173893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul} 27183893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul 27193893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul 27203893e638e6521b9c070e01c0b31d22754ff97a88Brian Paulstatic void 27213893e638e6521b9c070e01c0b31d22754ff97a88Brian Paulmake_2d_mipmap(const struct gl_texture_format *format, GLint border, 27223893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul GLint srcWidth, GLint srcHeight, const GLubyte *srcPtr, 27233893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul GLint dstWidth, GLint dstHeight, GLubyte *dstPtr) 27243893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul{ 27253893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul const GLint bpt = format->TexelBytes; 27269228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLint srcWidthNB = srcWidth - 2 * border; /* sizes w/out border */ 27279228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLint dstWidthNB = dstWidth - 2 * border; 27289228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLint dstHeightNB = dstHeight - 2 * border; 27293893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul const GLint srcRowStride = bpt * srcWidth; 27303893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul const GLint dstRowStride = bpt * dstWidth; 27313893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul const GLubyte *srcA, *srcB; 27323893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul GLubyte *dst; 2733462183fe4cb6df6d90632d9e2cee881c8d26b1cbAlan Hourihane GLint row; 27343893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul 27353893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul /* Compute src and dst pointers, skipping any border */ 27363893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul srcA = srcPtr + border * ((srcWidth + 1) * bpt); 27373893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul if (srcHeight > 1) 27383893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul srcB = srcA + srcRowStride; 27393893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul else 27403893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul srcB = srcA; 27413893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul dst = dstPtr + border * ((dstWidth + 1) * bpt); 27423893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul 27439228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul for (row = 0; row < dstHeightNB; row++) { 27449228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul do_row(format, srcWidthNB, srcA, srcB, 27459228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul dstWidthNB, dst); 27463893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul srcA += 2 * srcRowStride; 27473893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul srcB += 2 * srcRowStride; 27483893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul dst += dstRowStride; 27493893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul } 27503893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul 27518bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul /* This is ugly but probably won't be used much */ 27523893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul if (border > 0) { 27533893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul /* fill in dest border */ 27543893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul /* lower-left border pixel */ 27553893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul MEMCPY(dstPtr, srcPtr, bpt); 27563893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul /* lower-right border pixel */ 27573893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul MEMCPY(dstPtr + (dstWidth - 1) * bpt, 27583893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul srcPtr + (srcWidth - 1) * bpt, bpt); 27593893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul /* upper-left border pixel */ 27603893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul MEMCPY(dstPtr + dstWidth * (dstHeight - 1) * bpt, 27613893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul srcPtr + srcWidth * (srcHeight - 1) * bpt, bpt); 27623893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul /* upper-right border pixel */ 27633893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul MEMCPY(dstPtr + (dstWidth * dstHeight - 1) * bpt, 27643893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul srcPtr + (srcWidth * srcHeight - 1) * bpt, bpt); 27653893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul /* lower border */ 27669228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul do_row(format, srcWidthNB, 27679228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul srcPtr + bpt, 27689228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul srcPtr + bpt, 27699228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul dstWidthNB, dstPtr + bpt); 27703893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul /* upper border */ 27719228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul do_row(format, srcWidthNB, 27723893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul srcPtr + (srcWidth * (srcHeight - 1) + 1) * bpt, 27733893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul srcPtr + (srcWidth * (srcHeight - 1) + 1) * bpt, 27749228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul dstWidthNB, 27753893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul dstPtr + (dstWidth * (dstHeight - 1) + 1) * bpt); 27763893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul /* left and right borders */ 27779228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul if (srcHeight == dstHeight) { 27789228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul /* copy border pixel from src to dst */ 27799228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul for (row = 1; row < srcHeight; row++) { 27809228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul MEMCPY(dstPtr + dstWidth * row * bpt, 27819228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul srcPtr + srcWidth * row * bpt, bpt); 27829228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul MEMCPY(dstPtr + (dstWidth * row + dstWidth - 1) * bpt, 27839228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul srcPtr + (srcWidth * row + srcWidth - 1) * bpt, bpt); 27849228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul } 27859228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul } 27869228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul else { 27879228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul /* average two src pixels each dest pixel */ 27889228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul for (row = 0; row < dstHeightNB; row += 2) { 27899228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul do_row(format, 1, 27909228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul srcPtr + (srcWidth * (row * 2 + 1)) * bpt, 27919228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul srcPtr + (srcWidth * (row * 2 + 2)) * bpt, 27929228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul 1, dstPtr + (dstWidth * row + 1) * bpt); 27939228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul do_row(format, 1, 27949228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul srcPtr + (srcWidth * (row * 2 + 1) + srcWidth - 1) * bpt, 27959228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul srcPtr + (srcWidth * (row * 2 + 2) + srcWidth - 1) * bpt, 27969228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul 1, dstPtr + (dstWidth * row + 1 + dstWidth - 1) * bpt); 27979228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul } 27983893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul } 27993893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul } 28003893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul} 28013893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul 28023893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul 28033893e638e6521b9c070e01c0b31d22754ff97a88Brian Paulstatic void 28043893e638e6521b9c070e01c0b31d22754ff97a88Brian Paulmake_3d_mipmap(const struct gl_texture_format *format, GLint border, 28053893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul GLint srcWidth, GLint srcHeight, GLint srcDepth, 28063893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul const GLubyte *srcPtr, 28073893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul GLint dstWidth, GLint dstHeight, GLint dstDepth, 28083893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul GLubyte *dstPtr) 28093893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul{ 28109228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLint bpt = format->TexelBytes; 28119228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLint srcWidthNB = srcWidth - 2 * border; /* sizes w/out border */ 28129228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLint srcDepthNB = srcDepth - 2 * border; 28139228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLint dstWidthNB = dstWidth - 2 * border; 28149228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLint dstHeightNB = dstHeight - 2 * border; 28159228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLint dstDepthNB = dstDepth - 2 * border; 28169228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul GLvoid *tmpRowA, *tmpRowB; 28173893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul GLint img, row; 28189228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul GLint bytesPerSrcImage, bytesPerDstImage; 28199228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul GLint bytesPerSrcRow, bytesPerDstRow; 28209228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul GLint srcImageOffset, srcRowOffset; 28213893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul 28225c749d9e3c7824c0ba5b22e37d0ea5cbd54d6d2dBrian Paul (void) srcDepthNB; /* silence warnings */ 28235c749d9e3c7824c0ba5b22e37d0ea5cbd54d6d2dBrian Paul 28249228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul /* Need two temporary row buffers */ 28259228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul tmpRowA = MALLOC(srcWidth * bpt); 28269228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul if (!tmpRowA) 28279228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul return; 28289228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul tmpRowB = MALLOC(srcWidth * bpt); 28299228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul if (!tmpRowB) { 28309228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul FREE(tmpRowA); 28313893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul return; 28323893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul } 28333893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul 28349228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul bytesPerSrcImage = srcWidth * srcHeight * bpt; 28359228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul bytesPerDstImage = dstWidth * dstHeight * bpt; 28369228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul 28379228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul bytesPerSrcRow = srcWidth * bpt; 28389228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul bytesPerDstRow = dstWidth * bpt; 28393893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul 28409228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul /* Offset between adjacent src images to be averaged together */ 28419228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul srcImageOffset = (srcDepth == dstDepth) ? 0 : bytesPerSrcImage; 28423893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul 28439228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul /* Offset between adjacent src rows to be averaged together */ 28449228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul srcRowOffset = (srcHeight == dstHeight) ? 0 : srcWidth * bpt; 28453893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul 28469228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul /* 28479228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul * Need to average together up to 8 src pixels for each dest pixel. 28489228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul * Break that down into 3 operations: 28499228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul * 1. take two rows from source image and average them together. 28509228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul * 2. take two rows from next source image and average them together. 28519228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul * 3. take the two averaged rows and average them for the final dst row. 28529228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul */ 28533893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul 28549228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul /* 28554e9676fb13f60ecdbc247b120031f18cd3febcb0Brian Paul _mesa_printf("mip3d %d x %d x %d -> %d x %d x %d\n", 28569228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul srcWidth, srcHeight, srcDepth, dstWidth, dstHeight, dstDepth); 28579228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul */ 28589228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul 28599228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul for (img = 0; img < dstDepthNB; img++) { 28609228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul /* first source image pointer, skipping border */ 28619228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLubyte *imgSrcA = srcPtr 28629228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul + (bytesPerSrcImage + bytesPerSrcRow + border) * bpt * border 28639228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul + img * (bytesPerSrcImage + srcImageOffset); 28649228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul /* second source image pointer, skipping border */ 28659228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLubyte *imgSrcB = imgSrcA + srcImageOffset; 28669228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul /* address of the dest image, skipping border */ 28679228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul GLubyte *imgDst = dstPtr 28689228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul + (bytesPerDstImage + bytesPerDstRow + border) * bpt * border 28699228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul + img * bytesPerDstImage; 28709228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul 28719228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul /* setup the four source row pointers and the dest row pointer */ 28729228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLubyte *srcImgARowA = imgSrcA; 28739228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLubyte *srcImgARowB = imgSrcA + srcRowOffset; 28749228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLubyte *srcImgBRowA = imgSrcB; 28759228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLubyte *srcImgBRowB = imgSrcB + srcRowOffset; 28769228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul GLubyte *dstImgRow = imgDst; 28779228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul 28789228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul for (row = 0; row < dstHeightNB; row++) { 28799228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul /* Average together two rows from first src image */ 28809228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul do_row(format, srcWidthNB, srcImgARowA, srcImgARowB, 28819228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul srcWidthNB, tmpRowA); 28829228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul /* Average together two rows from second src image */ 28839228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul do_row(format, srcWidthNB, srcImgBRowA, srcImgBRowB, 28849228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul srcWidthNB, tmpRowB); 28859228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul /* Average together the temp rows to make the final row */ 28869228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul do_row(format, srcWidthNB, tmpRowA, tmpRowB, 28879228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul dstWidthNB, dstImgRow); 28889228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul /* advance to next rows */ 28899228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul srcImgARowA += bytesPerSrcRow + srcRowOffset; 28909228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul srcImgARowB += bytesPerSrcRow + srcRowOffset; 28919228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul srcImgBRowA += bytesPerSrcRow + srcRowOffset; 28929228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul srcImgBRowB += bytesPerSrcRow + srcRowOffset; 28939228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul dstImgRow += bytesPerDstRow; 28943893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul } 28953893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul } 28963893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul 28973893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul FREE(tmpRowA); 28983893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul FREE(tmpRowB); 28999228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul 29009228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul /* Luckily we can leverage the make_2d_mipmap() function here! */ 29019228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul if (border > 0) { 29029228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul /* do front border image */ 29039228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul make_2d_mipmap(format, 1, srcWidth, srcHeight, srcPtr, 29049228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul dstWidth, dstHeight, dstPtr); 29059228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul /* do back border image */ 29069228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul make_2d_mipmap(format, 1, srcWidth, srcHeight, 29079228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul srcPtr + bytesPerSrcImage * (srcDepth - 1), 29089228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul dstWidth, dstHeight, 29099228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul dstPtr + bytesPerDstImage * (dstDepth - 1)); 29109228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul /* do four remaining border edges that span the image slices */ 29119228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul if (srcDepth == dstDepth) { 29129228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul /* just copy border pixels from src to dst */ 29139228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul for (img = 0; img < dstDepthNB; img++) { 29149228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLubyte *src; 29159228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul GLubyte *dst; 29169228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul 29179228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul /* do border along [img][row=0][col=0] */ 29189228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul src = srcPtr + (img + 1) * bytesPerSrcImage; 29199228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul dst = dstPtr + (img + 1) * bytesPerDstImage; 29209228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul MEMCPY(dst, src, bpt); 29219228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul 29229228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul /* do border along [img][row=dstHeight-1][col=0] */ 29239228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul src = srcPtr + (img * 2 + 1) * bytesPerSrcImage 29249228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul + (srcHeight - 1) * bytesPerSrcRow; 29259228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul dst = dstPtr + (img + 1) * bytesPerDstImage 29269228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul + (dstHeight - 1) * bytesPerDstRow; 29279228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul MEMCPY(dst, src, bpt); 29289228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul 29299228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul /* do border along [img][row=0][col=dstWidth-1] */ 29309228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul src = srcPtr + (img * 2 + 1) * bytesPerSrcImage 29319228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul + (srcWidth - 1) * bpt; 29329228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul dst = dstPtr + (img + 1) * bytesPerDstImage 29339228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul + (dstWidth - 1) * bpt; 29349228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul MEMCPY(dst, src, bpt); 29359228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul 29369228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul /* do border along [img][row=dstHeight-1][col=dstWidth-1] */ 29379228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul src = srcPtr + (img * 2 + 1) * bytesPerSrcImage 29389228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul + (bytesPerSrcImage - bpt); 29399228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul dst = dstPtr + (img + 1) * bytesPerDstImage 29409228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul + (bytesPerDstImage - bpt); 29419228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul MEMCPY(dst, src, bpt); 29429228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul } 29439228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul } 29449228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul else { 29459228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul /* average border pixels from adjacent src image pairs */ 29469228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul ASSERT(srcDepthNB == 2 * dstDepthNB); 29479228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul for (img = 0; img < dstDepthNB; img++) { 29489228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul const GLubyte *src; 29499228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul GLubyte *dst; 29509228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul 29519228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul /* do border along [img][row=0][col=0] */ 29529228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul src = srcPtr + (img * 2 + 1) * bytesPerSrcImage; 29539228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul dst = dstPtr + (img + 1) * bytesPerDstImage; 29549228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul do_row(format, 1, src, src + srcImageOffset, 1, dst); 29559228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul 29569228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul /* do border along [img][row=dstHeight-1][col=0] */ 29579228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul src = srcPtr + (img * 2 + 1) * bytesPerSrcImage 29589228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul + (srcHeight - 1) * bytesPerSrcRow; 29599228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul dst = dstPtr + (img + 1) * bytesPerDstImage 29609228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul + (dstHeight - 1) * bytesPerDstRow; 29619228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul do_row(format, 1, src, src + srcImageOffset, 1, dst); 29629228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul 29639228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul /* do border along [img][row=0][col=dstWidth-1] */ 29649228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul src = srcPtr + (img * 2 + 1) * bytesPerSrcImage 29659228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul + (srcWidth - 1) * bpt; 29669228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul dst = dstPtr + (img + 1) * bytesPerDstImage 29679228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul + (dstWidth - 1) * bpt; 29689228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul do_row(format, 1, src, src + srcImageOffset, 1, dst); 29699228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul 29709228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul /* do border along [img][row=dstHeight-1][col=dstWidth-1] */ 29719228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul src = srcPtr + (img * 2 + 1) * bytesPerSrcImage 29729228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul + (bytesPerSrcImage - bpt); 29739228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul dst = dstPtr + (img + 1) * bytesPerDstImage 29749228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul + (bytesPerDstImage - bpt); 29759228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul do_row(format, 1, src, src + srcImageOffset, 1, dst); 29769228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul } 29779228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul } 29789228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul } 29793893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul} 29803893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul 29813893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul 29823893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul/* 29833893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul * For GL_SGIX_generate_mipmap: 29843893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul * Generate a complete set of mipmaps from texObj's base-level image. 29853893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul * Stop at texObj's MaxLevel or when we get to the 1x1 texture. 29863893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul */ 29873893e638e6521b9c070e01c0b31d22754ff97a88Brian Paulvoid 2988d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul_mesa_generate_mipmap(GLcontext *ctx, GLenum target, 29893893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul const struct gl_texture_unit *texUnit, 29903893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul struct gl_texture_object *texObj) 29913893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul{ 29922ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul const struct gl_texture_image *srcImage; 29932ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul const struct gl_texture_format *convertFormat; 2994b3f717037dcba37b4ac32c9ec17061781414a8caBrian Paul const GLubyte *srcData = NULL; 2995b3f717037dcba37b4ac32c9ec17061781414a8caBrian Paul GLubyte *dstData = NULL; 2996ef31f60b12abc2109568fb8d9a2aaa70ec5c71ccBrian Paul GLint level, maxLevels; 29973893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul 29983893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul ASSERT(texObj); 299918fa367ac6e035341f5eb86ecc4231124b2921e3Keith Whitwell srcImage = texObj->Image[0][texObj->BaseLevel]; 30002ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul ASSERT(srcImage); 30013893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul 3002ef31f60b12abc2109568fb8d9a2aaa70ec5c71ccBrian Paul maxLevels = _mesa_max_texture_levels(ctx, texObj->Target); 3003ef31f60b12abc2109568fb8d9a2aaa70ec5c71ccBrian Paul ASSERT(maxLevels > 0); /* bad target */ 30043893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul 30052ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul /* Find convertFormat - the format that do_row() will process */ 30062ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul if (srcImage->IsCompressed) { 30072ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul /* setup for compressed textures */ 3008d3975341e743b3436a69dedd864ccedc56b0db03Karl Schultz GLuint row; 3009d3975341e743b3436a69dedd864ccedc56b0db03Karl Schultz GLint components, size; 30102ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul GLchan *dst; 30112ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul 30122ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul assert(texObj->Target == GL_TEXTURE_2D); 30132ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul 30142ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul if (srcImage->Format == GL_RGB) { 30152ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul convertFormat = &_mesa_texformat_rgb; 30162ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul components = 3; 30172ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul } 30182ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul else if (srcImage->Format == GL_RGBA) { 30192ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul convertFormat = &_mesa_texformat_rgba; 30202ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul components = 4; 30212ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul } 30222ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul else { 30232ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul _mesa_problem(ctx, "bad srcImage->Format in _mesa_generate_mipmaps"); 30242ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul return; 30252ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul } 30262ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul 30272ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul /* allocate storage for uncompressed GL_RGB or GL_RGBA images */ 30282ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul size = _mesa_bytes_per_pixel(srcImage->Format, CHAN_TYPE) 30292ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul * srcImage->Width * srcImage->Height * srcImage->Depth + 20; 30302ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul /* 20 extra bytes, just be safe when calling last FetchTexel */ 3031f4418f4d1c6dfe06af760226c5303e653b25b879Brian Paul srcData = (GLubyte *) MALLOC(size); 30322ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul if (!srcData) { 30332ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul _mesa_error(ctx, GL_OUT_OF_MEMORY, "generate mipmaps"); 30342ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul return; 30352ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul } 3036f4418f4d1c6dfe06af760226c5303e653b25b879Brian Paul dstData = (GLubyte *) MALLOC(size / 2); /* 1/4 would probably be OK */ 30372ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul if (!dstData) { 30382ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul _mesa_error(ctx, GL_OUT_OF_MEMORY, "generate mipmaps"); 30392ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul FREE((void *) srcData); 30402ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul return; 30412ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul } 30422ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul 30432ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul /* decompress base image here */ 30442ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul dst = (GLchan *) srcData; 30452ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul for (row = 0; row < srcImage->Height; row++) { 3046d3975341e743b3436a69dedd864ccedc56b0db03Karl Schultz GLuint col; 30472ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul for (col = 0; col < srcImage->Width; col++) { 30484f295cee73bae1f687efe2dc062522b40d90b1e4Brian Paul srcImage->FetchTexelc(srcImage, col, row, 0, dst); 30492ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul dst += components; 305089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul } 305189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul } 305289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul } 30532ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul else { 30542ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul /* uncompressed */ 30552ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul convertFormat = srcImage->TexFormat; 30562ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul } 305789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul 30588bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul for (level = texObj->BaseLevel; level < texObj->MaxLevel 3059cd1cefae9146fc14b35ee93a04bdb1b1590fba7bBrian Paul && level < maxLevels - 1; level++) { 30609228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul /* generate image[level+1] from image[level] */ 30613893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul const struct gl_texture_image *srcImage; 30623893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul struct gl_texture_image *dstImage; 30633893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul GLint srcWidth, srcHeight, srcDepth; 30643893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul GLint dstWidth, dstHeight, dstDepth; 30653893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul GLint border, bytesPerTexel; 30663893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul 306789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul /* get src image parameters */ 30683ac8105e9cbed4c531c38636f83065b2ef3ab002Brian Paul srcImage = _mesa_select_tex_image(ctx, texUnit, target, level); 30693893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul ASSERT(srcImage); 30703893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul srcWidth = srcImage->Width; 30713893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul srcHeight = srcImage->Height; 30723893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul srcDepth = srcImage->Depth; 30733893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul border = srcImage->Border; 30743893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul 30753893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul /* compute next (level+1) image size */ 30763893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul if (srcWidth - 2 * border > 1) { 30773893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul dstWidth = (srcWidth - 2 * border) / 2 + 2 * border; 30783893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul } 30793893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul else { 30803893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul dstWidth = srcWidth; /* can't go smaller */ 30813893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul } 30823893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul if (srcHeight - 2 * border > 1) { 30833893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul dstHeight = (srcHeight - 2 * border) / 2 + 2 * border; 30843893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul } 30853893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul else { 30863893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul dstHeight = srcHeight; /* can't go smaller */ 30873893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul } 30883893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul if (srcDepth - 2 * border > 1) { 30893893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul dstDepth = (srcDepth - 2 * border) / 2 + 2 * border; 30903893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul } 30913893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul else { 30923893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul dstDepth = srcDepth; /* can't go smaller */ 30933893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul } 30943893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul 30953893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul if (dstWidth == srcWidth && 30963893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul dstHeight == srcHeight && 30973893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul dstDepth == srcDepth) { 30983893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul /* all done */ 309989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul if (srcImage->IsCompressed) { 310089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul FREE((void *) srcData); 310189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul FREE(dstData); 310289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul } 31033893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul return; 31043893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul } 31053893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul 3106d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul /* get dest gl_texture_image */ 3107a3f137094cd965d27e1b088499dd609b81a91906Brian Paul dstImage = _mesa_get_tex_image(ctx, texUnit, target, level + 1); 3108d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul if (!dstImage) { 3109a3f137094cd965d27e1b088499dd609b81a91906Brian Paul _mesa_error(ctx, GL_OUT_OF_MEMORY, "generating mipmaps"); 3110a3f137094cd965d27e1b088499dd609b81a91906Brian Paul return; 3111d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul } 31123893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul 3113d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul /* Free old image data */ 3114d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul if (dstImage->Data) 3115d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul MESA_PBUFFER_FREE(dstImage->Data); 3116d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul 3117d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul /* initialize new image */ 3118e1cb2fb571ee47b59020db7627e554b7d227e454Brian Paul _mesa_init_teximage_fields(ctx, target, dstImage, dstWidth, dstHeight, 311989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul dstDepth, border, srcImage->IntFormat); 3120d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul dstImage->DriverData = NULL; 3121d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul dstImage->TexFormat = srcImage->TexFormat; 31224f295cee73bae1f687efe2dc062522b40d90b1e4Brian Paul dstImage->FetchTexelc = srcImage->FetchTexelc; 31234f295cee73bae1f687efe2dc062522b40d90b1e4Brian Paul dstImage->FetchTexelf = srcImage->FetchTexelf; 3124d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul ASSERT(dstImage->TexFormat); 31254f295cee73bae1f687efe2dc062522b40d90b1e4Brian Paul ASSERT(dstImage->FetchTexelc); 31264f295cee73bae1f687efe2dc062522b40d90b1e4Brian Paul ASSERT(dstImage->FetchTexelf); 3127d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul 312889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul /* Alloc new teximage data buffer. 312989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * Setup src and dest data pointers. 313089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul */ 313189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul if (dstImage->IsCompressed) { 313289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul ASSERT(dstImage->CompressedSize > 0); /* set by init_teximage_fields*/ 313389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul dstImage->Data = MESA_PBUFFER_ALLOC(dstImage->CompressedSize); 313489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul if (!dstImage->Data) { 313589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul _mesa_error(ctx, GL_OUT_OF_MEMORY, "generating mipmaps"); 313689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul return; 313789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul } 31382ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul /* srcData and dstData are already set */ 313989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul ASSERT(srcData); 314089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul ASSERT(dstData); 314189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul } 314289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul else { 314389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul bytesPerTexel = srcImage->TexFormat->TexelBytes; 314489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul ASSERT(dstWidth * dstHeight * dstDepth * bytesPerTexel > 0); 314589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul dstImage->Data = MESA_PBUFFER_ALLOC(dstWidth * dstHeight * dstDepth 314689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * bytesPerTexel); 314789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul if (!dstImage->Data) { 314889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul _mesa_error(ctx, GL_OUT_OF_MEMORY, "generating mipmaps"); 314989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul return; 315089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul } 315189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul srcData = (const GLubyte *) srcImage->Data; 315289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul dstData = (GLubyte *) dstImage->Data; 3153d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul } 3154d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul 3155d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul /* 3156d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul * We use simple 2x2 averaging to compute the next mipmap level. 3157d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul */ 3158d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul switch (target) { 315989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul case GL_TEXTURE_1D: 31602ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul make_1d_mipmap(convertFormat, border, 316189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul srcWidth, srcData, 316289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul dstWidth, dstData); 316389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul break; 316489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul case GL_TEXTURE_2D: 316589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB: 316689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB: 316789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB: 316889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB: 316989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB: 317089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB: 31712ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul make_2d_mipmap(convertFormat, border, 317289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul srcWidth, srcHeight, srcData, 317389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul dstWidth, dstHeight, dstData); 317489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul break; 317589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul case GL_TEXTURE_3D: 31762ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul make_3d_mipmap(convertFormat, border, 317789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul srcWidth, srcHeight, srcDepth, srcData, 317889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul dstWidth, dstHeight, dstDepth, dstData); 317989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul break; 318089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul case GL_TEXTURE_RECTANGLE_NV: 318189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul /* no mipmaps, do nothing */ 318289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul break; 318389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul default: 318489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul _mesa_problem(ctx, "bad dimensions in _mesa_generate_mipmaps"); 318589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul return; 3186d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul } 318789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul 318889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul if (dstImage->IsCompressed) { 318989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul GLubyte *temp; 31902ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul /* compress image from dstData into dstImage->Data */ 31912ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul const GLenum srcFormat = convertFormat->BaseFormat; 31922ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul GLint dstRowStride = _mesa_compressed_row_stride(srcImage->IntFormat, 31932ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul dstWidth); 31942ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul ASSERT(srcFormat == GL_RGB || srcFormat == GL_RGBA); 31958f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul dstImage->TexFormat->StoreImage(ctx, 2, dstImage->Format, 31968f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul dstImage->TexFormat, 31978f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul dstImage->Data, 31988f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul 0, 0, 0, /* dstX/Y/Zoffset */ 31998f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul dstRowStride, 0, /* strides */ 32008f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul dstWidth, dstHeight, 1, /* size */ 32018f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul srcFormat, CHAN_TYPE, 32028f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul dstData, /* src data, actually */ 32038f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul &ctx->DefaultPacking); 320489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul /* swap src and dest pointers */ 320589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul temp = (GLubyte *) srcData; 320689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul srcData = dstData; 320789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul dstData = temp; 320889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul } 320989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul 3210d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul } /* loop over mipmap levels */ 32113893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul} 321280fc5ea53e0f1dac9df529965687c159acae057fBrian Paul 321380fc5ea53e0f1dac9df529965687c159acae057fBrian Paul 321480fc5ea53e0f1dac9df529965687c159acae057fBrian Paul/** 321580fc5ea53e0f1dac9df529965687c159acae057fBrian Paul * Helper function for drivers which need to rescale texture images to 321680fc5ea53e0f1dac9df529965687c159acae057fBrian Paul * certain aspect ratios. 321780fc5ea53e0f1dac9df529965687c159acae057fBrian Paul * Nearest filtering only (for broken hardware that can't support 321880fc5ea53e0f1dac9df529965687c159acae057fBrian Paul * all aspect ratios). This can be made a lot faster, but I don't 321980fc5ea53e0f1dac9df529965687c159acae057fBrian Paul * really care enough... 322080fc5ea53e0f1dac9df529965687c159acae057fBrian Paul */ 322180fc5ea53e0f1dac9df529965687c159acae057fBrian Paulvoid _mesa_rescale_teximage2d( GLuint bytesPerPixel, GLuint dstRowStride, 322280fc5ea53e0f1dac9df529965687c159acae057fBrian Paul GLint srcWidth, GLint srcHeight, 322380fc5ea53e0f1dac9df529965687c159acae057fBrian Paul GLint dstWidth, GLint dstHeight, 322480fc5ea53e0f1dac9df529965687c159acae057fBrian Paul const GLvoid *srcImage, GLvoid *dstImage ) 322580fc5ea53e0f1dac9df529965687c159acae057fBrian Paul{ 322680fc5ea53e0f1dac9df529965687c159acae057fBrian Paul GLint row, col; 322780fc5ea53e0f1dac9df529965687c159acae057fBrian Paul 322880fc5ea53e0f1dac9df529965687c159acae057fBrian Paul#define INNER_LOOP( TYPE, HOP, WOP ) \ 322980fc5ea53e0f1dac9df529965687c159acae057fBrian Paul for ( row = 0 ; row < dstHeight ; row++ ) { \ 323080fc5ea53e0f1dac9df529965687c159acae057fBrian Paul GLint srcRow = row HOP hScale; \ 323180fc5ea53e0f1dac9df529965687c159acae057fBrian Paul for ( col = 0 ; col < dstWidth ; col++ ) { \ 323280fc5ea53e0f1dac9df529965687c159acae057fBrian Paul GLint srcCol = col WOP wScale; \ 323380fc5ea53e0f1dac9df529965687c159acae057fBrian Paul dst[col] = src[srcRow * srcWidth + srcCol]; \ 323480fc5ea53e0f1dac9df529965687c159acae057fBrian Paul } \ 323580fc5ea53e0f1dac9df529965687c159acae057fBrian Paul dst = (TYPE *) ((GLubyte *) dst + dstRowStride); \ 323680fc5ea53e0f1dac9df529965687c159acae057fBrian Paul } \ 323780fc5ea53e0f1dac9df529965687c159acae057fBrian Paul 323880fc5ea53e0f1dac9df529965687c159acae057fBrian Paul#define RESCALE_IMAGE( TYPE ) \ 323980fc5ea53e0f1dac9df529965687c159acae057fBrian Pauldo { \ 324080fc5ea53e0f1dac9df529965687c159acae057fBrian Paul const TYPE *src = (const TYPE *)srcImage; \ 324180fc5ea53e0f1dac9df529965687c159acae057fBrian Paul TYPE *dst = (TYPE *)dstImage; \ 324280fc5ea53e0f1dac9df529965687c159acae057fBrian Paul \ 324380fc5ea53e0f1dac9df529965687c159acae057fBrian Paul if ( srcHeight <= dstHeight ) { \ 324480fc5ea53e0f1dac9df529965687c159acae057fBrian Paul const GLint hScale = dstHeight / srcHeight; \ 324580fc5ea53e0f1dac9df529965687c159acae057fBrian Paul if ( srcWidth <= dstWidth ) { \ 324680fc5ea53e0f1dac9df529965687c159acae057fBrian Paul const GLint wScale = dstWidth / srcWidth; \ 324780fc5ea53e0f1dac9df529965687c159acae057fBrian Paul INNER_LOOP( TYPE, /, / ); \ 324880fc5ea53e0f1dac9df529965687c159acae057fBrian Paul } \ 324980fc5ea53e0f1dac9df529965687c159acae057fBrian Paul else { \ 325080fc5ea53e0f1dac9df529965687c159acae057fBrian Paul const GLint wScale = srcWidth / dstWidth; \ 325180fc5ea53e0f1dac9df529965687c159acae057fBrian Paul INNER_LOOP( TYPE, /, * ); \ 325280fc5ea53e0f1dac9df529965687c159acae057fBrian Paul } \ 325380fc5ea53e0f1dac9df529965687c159acae057fBrian Paul } \ 325480fc5ea53e0f1dac9df529965687c159acae057fBrian Paul else { \ 325580fc5ea53e0f1dac9df529965687c159acae057fBrian Paul const GLint hScale = srcHeight / dstHeight; \ 325680fc5ea53e0f1dac9df529965687c159acae057fBrian Paul if ( srcWidth <= dstWidth ) { \ 325780fc5ea53e0f1dac9df529965687c159acae057fBrian Paul const GLint wScale = dstWidth / srcWidth; \ 325880fc5ea53e0f1dac9df529965687c159acae057fBrian Paul INNER_LOOP( TYPE, *, / ); \ 325980fc5ea53e0f1dac9df529965687c159acae057fBrian Paul } \ 326080fc5ea53e0f1dac9df529965687c159acae057fBrian Paul else { \ 326180fc5ea53e0f1dac9df529965687c159acae057fBrian Paul const GLint wScale = srcWidth / dstWidth; \ 326280fc5ea53e0f1dac9df529965687c159acae057fBrian Paul INNER_LOOP( TYPE, *, * ); \ 326380fc5ea53e0f1dac9df529965687c159acae057fBrian Paul } \ 326480fc5ea53e0f1dac9df529965687c159acae057fBrian Paul } \ 326580fc5ea53e0f1dac9df529965687c159acae057fBrian Paul} while (0) 326680fc5ea53e0f1dac9df529965687c159acae057fBrian Paul 326780fc5ea53e0f1dac9df529965687c159acae057fBrian Paul switch ( bytesPerPixel ) { 326880fc5ea53e0f1dac9df529965687c159acae057fBrian Paul case 4: 326980fc5ea53e0f1dac9df529965687c159acae057fBrian Paul RESCALE_IMAGE( GLuint ); 327080fc5ea53e0f1dac9df529965687c159acae057fBrian Paul break; 327180fc5ea53e0f1dac9df529965687c159acae057fBrian Paul 327280fc5ea53e0f1dac9df529965687c159acae057fBrian Paul case 2: 327380fc5ea53e0f1dac9df529965687c159acae057fBrian Paul RESCALE_IMAGE( GLushort ); 327480fc5ea53e0f1dac9df529965687c159acae057fBrian Paul break; 327580fc5ea53e0f1dac9df529965687c159acae057fBrian Paul 327680fc5ea53e0f1dac9df529965687c159acae057fBrian Paul case 1: 327780fc5ea53e0f1dac9df529965687c159acae057fBrian Paul RESCALE_IMAGE( GLubyte ); 327880fc5ea53e0f1dac9df529965687c159acae057fBrian Paul break; 327980fc5ea53e0f1dac9df529965687c159acae057fBrian Paul default: 328080fc5ea53e0f1dac9df529965687c159acae057fBrian Paul _mesa_problem(NULL,"unexpected bytes/pixel in _mesa_rescale_teximage2d"); 328180fc5ea53e0f1dac9df529965687c159acae057fBrian Paul } 328280fc5ea53e0f1dac9df529965687c159acae057fBrian Paul} 328333ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca 328433ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca 328533ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca/** 328633ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca * Upscale an image by replication, not (typical) stretching. 328733ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca * We use this when the image width or height is less than a 328833ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca * certain size (4, 8) and we need to upscale an image. 328933ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca */ 329033ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borcavoid 329133ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca_mesa_upscale_teximage2d (GLsizei inWidth, GLsizei inHeight, 329233ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca GLsizei outWidth, GLsizei outHeight, 329333ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca GLint comps, const GLchan *src, GLint srcRowStride, 329433ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca GLchan *dest ) 329533ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca{ 329633ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca GLint i, j, k; 329733ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca 329833ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca ASSERT(outWidth >= inWidth); 329933ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca ASSERT(outHeight >= inHeight); 330033ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca ASSERT(inWidth == 1 || inWidth == 2 || inHeight == 1 || inHeight == 2); 330133ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca#if 0 330233ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca ASSERT((outWidth & 3) == 0); 330333ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca ASSERT((outHeight & 3) == 0); 330433ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca#endif 330533ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca 330633ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca for (i = 0; i < outHeight; i++) { 330733ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca const GLint ii = i % inHeight; 330833ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca for (j = 0; j < outWidth; j++) { 330933ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca const GLint jj = j % inWidth; 331033ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca for (k = 0; k < comps; k++) { 331133ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca dest[(i * outWidth + j) * comps + k] 331233ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca = src[ii * srcRowStride + jj * comps + k]; 331333ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca } 331433ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca } 331533ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca } 331633ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca} 3317